<!--
  Compiz option code generator

  Copyright : (C) 2007 by Dennis Kasprzyk
  E-mail    : onestone@beryl-project.org
 
 
  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.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output  method="text"/>

<!-- String conversion helper functions -->

    <xsl:template name="print">
        <xsl:param name="text"/>
	<xsl:value-of select="translate($text,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
    </xsl:template>

    <xsl:template name="PRINT">
        <xsl:param name="text"/>
	<xsl:value-of select="translate($text,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    </xsl:template>

    <xsl:template name="Print">
        <xsl:param name="text"/>
	<xsl:call-template name="PRINT">
	    <xsl:with-param name="text">
		<xsl:value-of select="substring($text,1,1)"/>
	    </xsl:with-param>
	</xsl:call-template>
	<xsl:call-template name="print">
	    <xsl:with-param name="text">
		<xsl:value-of select="substring($text,2)"/>
	    </xsl:with-param>
	</xsl:call-template>
    </xsl:template>

    <xsl:template name="PrintCamel">
        <xsl:param name="text"/>
        <xsl:variable name="textconv">
            <xsl:value-of select="translate($text,' +-/\','_____')"/>
        </xsl:variable>
	<xsl:if test="string-length($textconv)">
	    <xsl:if test="contains($textconv,'_')">
		<xsl:call-template name="Print">
		    <xsl:with-param name="text">
			<xsl:value-of select="substring-before($textconv,'_')"/>
		    </xsl:with-param>
		</xsl:call-template>
		<xsl:call-template name="PrintCamel">
		    <xsl:with-param name="text">
			<xsl:value-of select="substring-after($textconv,'_')"/>
		    </xsl:with-param>
		</xsl:call-template>
	    </xsl:if>
	    <xsl:if test="not(contains($textconv,'_'))">
	       <xsl:call-template name="Print">
		    <xsl:with-param name="text">
			<xsl:value-of select="$textconv"/>
		    </xsl:with-param>
		</xsl:call-template>
	    </xsl:if>
	</xsl:if>
    </xsl:template>

    <xsl:template name="saveCName">
        <xsl:param name="text"/>
        <xsl:variable name="textFirst">
            <xsl:value-of select="translate(substring($text,1,1),'0123456789 +-','zottffssen___')"/>
        </xsl:variable>
        <xsl:value-of select="concat($textFirst,substring($text,2))"/>
    </xsl:template>

<!-- Plugin name variables -->

    <xsl:variable name="pName">
        <xsl:value-of select="/compiz/plugin[@useBcop = 'true']/@name"/>
    </xsl:variable>

    <xsl:variable name="pCName">
        <xsl:call-template name="saveCName">
	    <xsl:with-param name="text">
		<xsl:value-of select="$pName"/>
	    </xsl:with-param>
	</xsl:call-template>
    </xsl:variable>

    <xsl:variable name="plugin">
        <xsl:call-template name="print">
	    <xsl:with-param name="text">
		<xsl:value-of select="$pCName"/>
	    </xsl:with-param>
	</xsl:call-template>
    </xsl:variable>

    <xsl:variable name="Plugin">
        <xsl:call-template name="Print">
	    <xsl:with-param name="text">
		<xsl:value-of select="$pCName"/>
	    </xsl:with-param>
	</xsl:call-template>
    </xsl:variable>

    <xsl:variable name="PLUGIN">
        <xsl:call-template name="PRINT">
	    <xsl:with-param name="text">
		<xsl:value-of select="$pCName"/>
	    </xsl:with-param>
	</xsl:call-template>
    </xsl:variable>

<!-- external parameters that could be passed to this document -->

    <xsl:param name="header">false</xsl:param>
    <xsl:param name="source">false</xsl:param>
    <xsl:param name="filename"><xsl:value-of select="$pName"/><xsl:text>_options.h</xsl:text></xsl:param>
    <xsl:param name="metaname"><xsl:value-of select="$pName"/></xsl:param>


<!-- global helper functions -->

    <xsl:template name="license">
<xsl:text>/*
 * This file is autogenerated with bcop:
 * The Compiz option code generator
 *
 * 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.
 *
 */

</xsl:text>
    </xsl:template>

    <xsl:template name="printOptionsEnumName">
        <xsl:value-of select="$Plugin"/>
        <xsl:call-template name="screenOrDisplay"/>
        <xsl:text>Option</xsl:text>
        <xsl:call-template name="PrintCamel">
	    <xsl:with-param name="text">
		<xsl:value-of select="@name"/>
	    </xsl:with-param>
	</xsl:call-template>
    </xsl:template>

    <xsl:template name="printOptionName">
        <xsl:call-template name="PrintCamel">
	    <xsl:with-param name="text">
		<xsl:value-of select="@name"/>
	    </xsl:with-param>
	</xsl:call-template>
    </xsl:template>

    <xsl:template name="screenOrDisplay">
        <xsl:if test="ancestor::display">
            <xsl:text>Display</xsl:text>
        </xsl:if>
        <xsl:if test="ancestor::screen">
            <xsl:text>Screen</xsl:text>
        </xsl:if>
    </xsl:template>

    <xsl:template name="baseType">
        <xsl:if test="ancestor::display">
            <xsl:text>CompDisplay *d</xsl:text>
        </xsl:if>
        <xsl:if test="ancestor::screen">
            <xsl:text>CompScreen *s</xsl:text>
        </xsl:if>
    </xsl:template>
    
<!-- *** main block *** -->
    
    <xsl:template  match="/compiz">
        <xsl:if test="plugin[@useBcop = 'true']">
            <xsl:if test="$header = 'true'">
                <xsl:call-template name="hfile"/>
            </xsl:if>
            <xsl:if test="$source = 'true'">
                <xsl:call-template name="cfile"/>
            </xsl:if>
        </xsl:if>
    </xsl:template>

<!-- *** c source file generation *** -->

    <xsl:template name="cfile">
        <xsl:call-template name="license"/>
        <xsl:text>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

#include &lt;compiz-core.h&gt;

</xsl:text>
        <xsl:text>#include "</xsl:text>
        <xsl:value-of select="$filename"/>
        <xsl:text>"

static int </xsl:text>
       <xsl:value-of select="$Plugin"/>
       <xsl:text>OptionsDisplayPrivateIndex;

static CompMetadata </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsMetadata;

static CompPluginVTable *</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable = NULL;
CompPluginVTable </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsVTable;

#define </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_DISPLAY(d) PLUGIN_DISPLAY(d, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>Options, o)
#define </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_SCREEN(s) PLUGIN_SCREEN(s, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>Options, o)

typedef struct _</xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsDisplay
{
    int screenPrivateIndex;

</xsl:text>
        <xsl:if test="plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:text>    CompOption opt[</xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>DisplayOptionNum];
    </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>DisplayOptionChangeNotifyProc notify[</xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>DisplayOptionNum];
</xsl:text>
            <xsl:for-each select="plugin[@name=$pName]/display/descendant-or-self::option[@type = 'list' and ./desc/value and ./type/text() = 'int']">
                <xsl:text>    unsigned int </xsl:text>
                <xsl:value-of select="@name"/>
                <xsl:text>;
</xsl:text>
            </xsl:for-each>    
        </xsl:if>
        <xsl:text>} </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsDisplay;

typedef struct _</xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsScreen
{
</xsl:text>
        <xsl:if test="plugin[@name=$pName]/screen/descendant-or-self::option">
            <xsl:text>    CompOption opt[</xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>ScreenOptionNum];
    </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>ScreenOptionChangeNotifyProc notify[</xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>ScreenOptionNum];
</xsl:text>
            <xsl:for-each select="plugin[@name=$pName]/screen/descendant-or-self::option[@type = 'list' and ./desc/value and ./type/text() = 'int']">
                <xsl:text>    unsigned int </xsl:text>
                <xsl:value-of select="@name"/>
                <xsl:text>;
</xsl:text>
            </xsl:for-each>
        </xsl:if>
        <xsl:text>} </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsScreen;

</xsl:text>
        <xsl:call-template name="printFunctions"/>
        <xsl:if test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:call-template name="initDisplayOptions"/>
            <xsl:call-template name="setDisplayOptions"/>
            <xsl:call-template name="getDisplayOptions"/>
        </xsl:if>
        <xsl:if test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
	    <xsl:call-template name="initScreenOptions"/>
	    <xsl:call-template name="setScreenOptions"/>
	    <xsl:call-template name="getScreenOptions"/>
	</xsl:if>
	<xsl:call-template name="initFiniScreen"/>
	<xsl:call-template name="initFiniDisplay"/>
	<xsl:call-template name="initFini"/>
	<xsl:call-template name="initFiniObject"/>
	<xsl:call-template name="getSetObject"/>
	<xsl:call-template name="getVTable"/>
    </xsl:template>

<!-- helper functions -->
    
    <xsl:template name="initPrivate">
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_</xsl:text>
        <xsl:if test="ancestor::display">
            <xsl:text>DISPLAY(d);
</xsl:text>
        </xsl:if>
        <xsl:if test="ancestor::screen">
            <xsl:text>SCREEN(s);
</xsl:text>
        </xsl:if>
    </xsl:template>

    <xsl:template name="privateName">
        <xsl:if test="ancestor::display">
            <xsl:text>od</xsl:text>
        </xsl:if>
        <xsl:if test="ancestor::screen">
            <xsl:text>os</xsl:text>
        </xsl:if>
    </xsl:template>

<!-- print get/set functions -->

    <xsl:template name="printFunctions">
        <xsl:for-each select="/compiz/plugin[@name=$pName]/descendant-or-self::option">
            <xsl:choose>
                <xsl:when test="@type='int'">
                    <xsl:text>int </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.i;
}

</xsl:text>
                </xsl:when>
                <xsl:when test="@type='float'">
                    <xsl:text>float </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.f;
}

</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='bool'">
                    <xsl:text>Bool </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.b;
}

</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='string'">
                    <xsl:text>char * </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.s;
}

</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='match'">
                    <xsl:text>CompMatch * </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return &amp;</xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.match;
}

</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='color'">
                    <xsl:text>unsigned short * </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                                        <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.c;
}

unsigned short </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Red (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.c[0];
}

unsigned short </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Green (</xsl:text>
		    <xsl:call-template name="baseType"/>
                    <xsl:text>)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.c[1];
}

unsigned short </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Blue (</xsl:text>
		    <xsl:call-template name="baseType"/>
                    <xsl:text>)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.c[2];
}

unsigned short </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Alpha (</xsl:text>
		    <xsl:call-template name="baseType"/>
                    <xsl:text>)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.c[3];
}

</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='action' or @type='key' or @type='button' or @type='edge' or @type='bell'">
                    <xsl:text>CompAction * </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return &amp;</xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.action;
}

void </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Set</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Initiate (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>, CompActionCallBackProc init)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.action.initiate = init;
}

void </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Set</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Terminate (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>, CompActionCallBackProc term)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.action.terminate = term;
}

</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='list'">
                    <xsl:text>CompListValue * </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return &amp;</xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>].value.list;
}

</xsl:text>
                    <xsl:if test="./type[text() = 'int']/../desc/value">
                        <xsl:text>unsigned int </xsl:text>
                        <xsl:value-of select="$plugin"/>
			<xsl:text>Get</xsl:text>
			<xsl:call-template name="printOptionName"/>
			<xsl:text>Mask (</xsl:text>
			<xsl:call-template name="baseType"/>
			<xsl:text>)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>-></xsl:text>
                    <xsl:value-of select="@name"/>
                    <xsl:text>;
}

</xsl:text>
                    </xsl:if>
                </xsl:when>
            </xsl:choose>
            <xsl:text>CompOption * </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>Get</xsl:text>
            <xsl:call-template name="printOptionName"/>
            <xsl:text>Option (</xsl:text>
            <xsl:call-template name="baseType"/>
            <xsl:text>)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    return &amp;</xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->opt[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>];
}

void </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>Set</xsl:text>
            <xsl:call-template name="printOptionName"/>
            <xsl:text>Notify (</xsl:text>
            <xsl:call-template name="baseType"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:call-template name="screenOrDisplay"/>
            <xsl:text>OptionChangeNotifyProc notify)
{
    </xsl:text>
                    <xsl:call-template name="initPrivate"/>
                    <xsl:text>    </xsl:text>
                    <xsl:call-template name="privateName"/>
                    <xsl:text>->notify[</xsl:text>
                    <xsl:call-template name="printOptionsEnumName"/>
                    <xsl:text>] = notify;
}

</xsl:text>
        </xsl:for-each>
        <xsl:if test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:text>CompOption * </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>GetDisplayOption (CompDisplay *d, </xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>DisplayOptions num)
{
    </xsl:text>
            <xsl:value-of select="$PLUGIN"/>
            <xsl:text>_OPTIONS_DISPLAY(d);
    return &amp;od->opt[num];
}

</xsl:text>
        </xsl:if>
        <xsl:if test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
            <xsl:text>CompOption * </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>GetScreenOption (CompScreen *s, </xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>ScreenOptions num)
{
    </xsl:text>
            <xsl:value-of select="$PLUGIN"/>
            <xsl:text>_OPTIONS_SCREEN(s);
    return &amp;os->opt[num];
}

</xsl:text>
        </xsl:if>
    </xsl:template>

<!-- initialze option functions generation -->

    <xsl:template name="initDisplayOptions">
        <xsl:text>static const CompMetadataOptionInfo </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsDisplayOptionInfo[] = {
</xsl:text>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:call-template name="initOption"/>
        </xsl:for-each>
        <xsl:text>};

</xsl:text>
    </xsl:template>

    <xsl:template name="initScreenOptions">
        <xsl:text>static const CompMetadataOptionInfo </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsScreenOptionInfo[] = {
</xsl:text>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
            <xsl:call-template name="initOption"/>
        </xsl:for-each>
        <xsl:text>};

</xsl:text>
    </xsl:template>
    <xsl:template name="initOption">
        <xsl:text>    { "</xsl:text>
        <xsl:value-of select="@name"/>
        <xsl:text>", "</xsl:text>
        <xsl:value-of select="@type"/>
        <xsl:text>", </xsl:text>
        <xsl:choose>
            <xsl:when test="(@type = 'int' or @type = 'float') and (./min/text() and ./max/text())">
                <xsl:text>"&lt;min&gt;</xsl:text>
                <xsl:value-of select="./min/text()"/>
                <xsl:text>&lt;/min&gt;&lt;max&gt;</xsl:text>
                <xsl:value-of select="./max/text()"/>
                <xsl:text>&lt;/max&gt;", </xsl:text>
            </xsl:when>
            <xsl:when test="@type = 'list' and ./type/text()">
                <xsl:text>"&lt;type&gt;</xsl:text>
                <xsl:value-of select="./type/text()"/>
                <xsl:text>&lt;/type&gt;", </xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>0, </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:text>0, 0 },
</xsl:text>
    </xsl:template>

<!-- get option functions generation -->

    <xsl:template name="getDisplayOptions">
        <xsl:text>static CompOption * </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsGetDisplayOptions (CompPlugin *plugin, CompDisplay *d, int *count)
{
    </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_DISPLAY(d);
    if (!od)
    {
        *count = 0;
        return NULL;
    }
    *count = </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>DisplayOptionNum;
    return od->opt;
}

</xsl:text>
    </xsl:template>

    <xsl:template name="getScreenOptions">
        <xsl:text>static CompOption * </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsGetScreenOptions (CompPlugin *plugin, CompScreen *s, int *count)
{
    </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_SCREEN(s);
    if (!os)
    {
        *count = 0;
        return NULL;
    }
    *count = </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>ScreenOptionNum;
    return os->opt;
}

</xsl:text>
    </xsl:template>

<!-- set option function generation -->

    <xsl:template name="setDisplayOptions">
        <xsl:text>static Bool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsSetDisplayOption (CompPlugin *plugin, CompDisplay *d, const char *name, CompOptionValue *value)
{
    </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_DISPLAY(d);
    CompOption *o;
    int        index;

    o = compFindOption (od->opt, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>DisplayOptionNum, name, &amp;index);

    if (!o)
        return FALSE;

    switch (index)
    {
</xsl:text>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:call-template name="setOption"/>
        </xsl:for-each>
        <xsl:text>    default:
        break;
    }
    return FALSE;
}

</xsl:text>
    </xsl:template>

    <xsl:template name="setScreenOptions">
        <xsl:text>static Bool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsSetScreenOption (CompPlugin *plugin, CompScreen *s, const char *name, CompOptionValue *value)
{
    </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_SCREEN(s);
    CompOption *o;
    int        index;

    o = compFindOption (os->opt, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>ScreenOptionNum, name, &amp;index);

    if (!o)
        return FALSE;

    switch (index)
    {
</xsl:text>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
            <xsl:call-template name="setOption"/>
        </xsl:for-each>
        <xsl:text>    default:
        break;
    }
    return FALSE;
}

</xsl:text>
    </xsl:template>

    <xsl:template name="setOption">
        <xsl:text>     case </xsl:text>
        <xsl:call-template name="printOptionsEnumName"/>
        <xsl:text>:
        if (</xsl:text>
        <xsl:choose>
            <xsl:when test="ancestor::display">
                <xsl:text>compSetDisplayOption (d, o, value))</xsl:text>
            </xsl:when>
	    <xsl:when test="ancestor::screen">
                <xsl:text>compSetScreenOption (s, o, value))</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>compSetOption (o, value))</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:text>
        {
</xsl:text>
        <xsl:if test="@type = 'list' and ./desc/value and ./type/text() = 'int'">
            <xsl:text>            int i;
            </xsl:text>
            <xsl:call-template name="privateName"/>
            <xsl:text>-></xsl:text>
            <xsl:value-of select="@name"/>
            <xsl:text> = 0;
            for (i = 0; i &lt; o->value.list.nValue; i++)
                </xsl:text>
            <xsl:call-template name="privateName"/>
            <xsl:text>-></xsl:text>
            <xsl:value-of select="@name"/>
            <xsl:text> |= (1 &lt;&lt; o->value.list.value[i].i);
</xsl:text>
        </xsl:if>
        <xsl:text>            if (</xsl:text>
        <xsl:call-template name="privateName"/>
        <xsl:text>->notify[</xsl:text>
        <xsl:call-template name="printOptionsEnumName"/>
        <xsl:text>])
                (*</xsl:text>
        <xsl:call-template name="privateName"/>
        <xsl:text>->notify[</xsl:text>
        <xsl:call-template name="printOptionsEnumName"/>
        <xsl:text>]) (</xsl:text>
         <xsl:if test="ancestor::display">
            <xsl:text>d</xsl:text>
        </xsl:if>
        <xsl:if test="ancestor::screen">
            <xsl:text>s</xsl:text>
        </xsl:if>
        <xsl:text>, o, </xsl:text>
        <xsl:call-template name="printOptionsEnumName"/>
        <xsl:text>);
            return TRUE;
        }
        break;
</xsl:text>
    </xsl:template>


<!-- init/fini screen -->

    <xsl:template name="initFiniScreen">
        <xsl:text>static Bool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitScreen (CompPlugin *p, CompScreen *s)
{
    </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsScreen *os;
    </xsl:text>
        <xsl:if test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option[@type = 'list']/desc/value and
        /compiz/plugin[@name=$pName]/screen/descendant-or-self::option[@type = 'list']/type/text() = 'int'">
            <xsl:text>CompOption *o;
    int i;
    </xsl:text>
        </xsl:if>
        <xsl:text>
    </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_DISPLAY (s->display);

    os = calloc (1, sizeof(</xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsScreen));
    if (!os)
        return FALSE;

    s->base.privates[od->screenPrivateIndex].ptr = os;

    </xsl:text>
        <xsl:if test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
            <xsl:text>if (!compInitScreenOptionsFromMetadata (s, &amp;</xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsMetadata, </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsScreenOptionInfo, os->opt, </xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>ScreenOptionNum))
    {
        free (os);
        return FALSE;
    }
</xsl:text>
        </xsl:if>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
        <xsl:if test="@type = 'list' and ./desc/value and ./type/text() = 'int'">
            <xsl:text>    o = &amp;os->opt[</xsl:text>
            <xsl:call-template name="printOptionsEnumName"/>
            <xsl:text>];
    </xsl:text>
            <xsl:call-template name="privateName"/>
            <xsl:text>-></xsl:text>
            <xsl:value-of select="@name"/>
            <xsl:text> = 0;
    for (i = 0; i &lt; o->value.list.nValue; i++)
        </xsl:text>
            <xsl:call-template name="privateName"/>
            <xsl:text>-></xsl:text>
            <xsl:value-of select="@name"/>
            <xsl:text> |= (1 &lt;&lt; o->value.list.value[i].i);

</xsl:text>
        </xsl:if>
        
        </xsl:for-each>

        <xsl:text>
    return TRUE;
}

static void </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniScreen (CompPlugin *p, CompScreen *s)
{
    </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_SCREEN (s);
    </xsl:text>
    <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_DISPLAY (s->display);

</xsl:text>
        <xsl:if test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
            <xsl:text>
    compFiniScreenOptions (s, os->opt, </xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>ScreenOptionNum);

</xsl:text>
        </xsl:if>
        <xsl:text>    free (os);
    s->base.privates[od->screenPrivateIndex].ptr = NULL;
}

</xsl:text>
    </xsl:template>

<!-- init/fini display -->

    <xsl:template name="initFiniDisplay">
        <xsl:text>static Bool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitDisplay (CompPlugin *p, CompDisplay *d)
{
    </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsDisplay *od;
   </xsl:text>
        <xsl:if test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option[@type = 'list']/desc/value and
        /compiz/plugin[@name=$pName]/display/descendant-or-self::option[@type = 'list']/type/text() = 'int'">
            <xsl:text>CompOption *o;
    int i;
    </xsl:text>
        </xsl:if>
        <xsl:text>
    </xsl:text>
        <xsl:text>
    od = calloc (1, sizeof(</xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsDisplay));
    if (!od)
        return FALSE;

    od->screenPrivateIndex = allocateScreenPrivateIndex(d);
    if (od->screenPrivateIndex &lt; 0)
    {
        free(od);
        return FALSE;
    }

    d->base.privates[</xsl:text>
    <xsl:value-of select="$Plugin"/>
    <xsl:text>OptionsDisplayPrivateIndex].ptr = od;

    </xsl:text>
        <xsl:if test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:text>if (!compInitDisplayOptionsFromMetadata (d, &amp;</xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsMetadata, </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsDisplayOptionInfo, od->opt, </xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>DisplayOptionNum))
    {
        free (od);
        return FALSE;
    }
</xsl:text>
        </xsl:if>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
        <xsl:if test="@type = 'list' and ./desc/value and ./type/text() = 'int'">
            <xsl:text>    o = &amp;od->opt[</xsl:text>
            <xsl:call-template name="printOptionsEnumName"/>
            <xsl:text>];
    </xsl:text>
            <xsl:call-template name="privateName"/>
            <xsl:text>-></xsl:text>
            <xsl:value-of select="@name"/>
            <xsl:text> = 0;
    for (i = 0; i &lt; o->value.list.nValue; i++)
        </xsl:text>
            <xsl:call-template name="privateName"/>
            <xsl:text>-></xsl:text>
            <xsl:value-of select="@name"/>
            <xsl:text> |= (1 &lt;&lt; o->value.list.value[i].i);

</xsl:text>
        </xsl:if>
        
        </xsl:for-each>
        <xsl:text>
    return TRUE;
}

static void </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniDisplay (CompPlugin *p, CompDisplay *d)
{
    </xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_DISPLAY (d);

    freeScreenPrivateIndex(d, od->screenPrivateIndex);
</xsl:text>
       <xsl:if test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:text>
    compFiniDisplayOptions (d, od->opt, </xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:text>DisplayOptionNum);

</xsl:text>
        </xsl:if>
        <xsl:text>    free (od);
    d->base.privates[</xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsDisplayPrivateIndex].ptr = NULL;
}

</xsl:text>
    </xsl:template>

<!-- init/fini plugin -->

    <xsl:template name="initFini">
        <xsl:text>static Bool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInit (CompPlugin *p)
{
    </xsl:text>
    <xsl:value-of select="$Plugin"/>
    <xsl:text>OptionsDisplayPrivateIndex = allocateDisplayPrivateIndex();
    if (</xsl:text>
    <xsl:value-of select="$Plugin"/>
    <xsl:text>OptionsDisplayPrivateIndex &lt; 0)
        return FALSE;

    if (!compInitPluginMetadataFromInfo (&amp;</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsMetadata, "</xsl:text>
        <xsl:value-of select="$pName"/>
        <xsl:text>",</xsl:text>
        <xsl:choose>
            <xsl:when test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
                <xsl:value-of select="$plugin"/>
                <xsl:text>OptionsDisplayOptionInfo, </xsl:text>
                <xsl:value-of select="$Plugin"/>
                <xsl:text>DisplayOptionNum, </xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>0, 0, </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:choose>
            <xsl:when test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
                <xsl:value-of select="$plugin"/>
                <xsl:text>OptionsScreenOptionInfo, </xsl:text>
                <xsl:value-of select="$Plugin"/>
                <xsl:text>ScreenOptionNum</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>0, 0</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
<xsl:text>))
        return FALSE;

    compAddMetadataFromFile (&amp;</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsMetadata, "</xsl:text>
        <xsl:value-of select="$metaname"/>
        <xsl:text>");
    if (</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable &amp;&amp; </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->init)
        return </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->init (p);
    return TRUE;
}

static void </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFini (CompPlugin *p)
{
    if (</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable &amp;&amp; </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->fini)
        </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->fini (p);

    if (</xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsDisplayPrivateIndex >= 0)
        freeDisplayPrivateIndex (</xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>OptionsDisplayPrivateIndex);

    compFiniMetadata (&amp;</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsMetadata);
}

</xsl:text>
    </xsl:template>

<!-- init/fini object plugin -->

    <xsl:template name="initFiniObject">
        <xsl:text>static CompBool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitObject (CompPlugin *p, CompObject *o)
{
    static InitPluginObjectProc dispTab[] = {
        (InitPluginObjectProc) 0,
        (InitPluginObjectProc) </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitDisplay,
        (InitPluginObjectProc) </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitScreen
    };

    RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
}

static void </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniObject (CompPlugin *p, CompObject *o)
{
    static FiniPluginObjectProc dispTab[] = {
        (FiniPluginObjectProc) 0,
        (FiniPluginObjectProc) </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniDisplay,
        (FiniPluginObjectProc) </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniScreen
    };

    DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
}

static CompBool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitObjectWrapper (CompPlugin *p, CompObject *o)
{
    CompBool rv = TRUE;
    rv = </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitObject (p, o);
    if (</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->initObject)
        rv &amp;= </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->initObject (p, o);
    return rv;
}

static void </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniObjectWrapper (CompPlugin *p, CompObject *o)
{
    if (</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->finiObject)
        </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable->finiObject (p, o);
    </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniObject (p, o);
}

</xsl:text>
    </xsl:template>

<!-- get/set object options -->

    <xsl:template name="getSetObject">
        <xsl:text>static CompOption * </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsGetObjectOptions (CompPlugin *p, CompObject *o, int *count)
{
    static GetPluginObjectOptionsProc dispTab[] = {
        (GetPluginObjectOptionsProc) 0,
        </xsl:text>
        <xsl:if test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
	    <xsl:text>    (GetPluginObjectOptionsProc) </xsl:text>
	    <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsGetDisplayOptions,
    </xsl:text>
        </xsl:if>
        <xsl:if test="not(/compiz/plugin[@name=$pName]/display/descendant-or-self::option)">
	    <xsl:text>    (GetPluginObjectOptionsProc) 0,
    </xsl:text>
        </xsl:if>
        <xsl:if test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
	    <xsl:text>    (GetPluginObjectOptionsProc) </xsl:text>
	    <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsGetScreenOptions
    </xsl:text>
        </xsl:if>
        <xsl:text>};

    *count = 0;
    RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab),
		     NULL, (p, o, count));
}

static CompBool </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsSetObjectOption (CompPlugin *p, CompObject *o, const char *name, CompOptionValue *value)
{
    static SetPluginObjectOptionProc dispTab[] = {
        (SetPluginObjectOptionProc) 0,
    </xsl:text>
        <xsl:if test="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
	    <xsl:text>    (SetPluginObjectOptionProc) </xsl:text>
	    <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsSetDisplayOption,
    </xsl:text>
        </xsl:if>
        <xsl:if test="not(/compiz/plugin[@name=$pName]/display/descendant-or-self::option)">
	    <xsl:text>    (SetPluginObjectOptionProc) 0,
    </xsl:text>
        </xsl:if>
        <xsl:if test="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
	<xsl:text>    (SetPluginObjectOptionProc) </xsl:text>
	    <xsl:value-of select="$plugin"/>
            <xsl:text>OptionsSetScreenOption
    </xsl:text>
        </xsl:if>
        <xsl:text>};

    RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), FALSE,
		     (p, o, name, value));
}

</xsl:text>
    </xsl:template>

<!-- vtable generation -->

    <xsl:template name="getVTable">
        <xsl:text>static CompMetadata *
</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsGetMetadata (CompPlugin *plugin)
{
    return &amp;</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsMetadata;
}

</xsl:text>
        <xsl:text>CompPluginVTable *getCompPluginInfo20070830 (void)
{
    if (!</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable)
    {
        </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable = </xsl:text>
        <xsl:text>getCompPluginInfo ();
        memcpy(&amp;</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsVTable, </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>PluginVTable, sizeof(CompPluginVTable));
        </xsl:text>

        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsVTable.getMetadata = </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsGetMetadata;
        </xsl:text>

        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsVTable.init = </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInit;
        </xsl:text>

        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsVTable.fini = </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFini;
        </xsl:text>

        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsVTable.initObject = </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsInitObjectWrapper;
        </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsVTable.finiObject = </xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>OptionsFiniObjectWrapper;
        </xsl:text>

	<xsl:value-of select="$plugin"/>
	<xsl:text>OptionsVTable.getObjectOptions = </xsl:text>
	<xsl:value-of select="$plugin"/>
	<xsl:text>OptionsGetObjectOptions;
	</xsl:text>
	<xsl:value-of select="$plugin"/>
	<xsl:text>OptionsVTable.setObjectOption = </xsl:text>
	<xsl:value-of select="$plugin"/>
	<xsl:text>OptionsSetObjectOption;
	</xsl:text>
        <xsl:text>
    }
    return &amp;</xsl:text>
    <xsl:value-of select="$plugin"/>
    <xsl:text>OptionsVTable;
}

</xsl:text>
    </xsl:template>


<!-- *** header file generation *** -->

    <xsl:template name="hfile">
        <xsl:call-template name="license"/>
        <xsl:text>#ifndef _</xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_H
#define _</xsl:text>
        <xsl:value-of select="$PLUGIN"/>
        <xsl:text>_OPTIONS_H

#include &lt;compiz-common.h&gt;

COMPIZ_BEGIN_DECLS

CompPluginVTable * getCompPluginInfo (void);

</xsl:text>
        <xsl:call-template name="printDisplayOptionsEnum"/>
        <xsl:call-template name="printScreenOptionsEnum"/>
        <xsl:call-template name="printOptionEnums"/>
        <xsl:call-template name="printOptionMasks"/>
        <xsl:call-template name="printFunctionDefinitions"/>
        <xsl:text>#ifndef GENERIC_PRIVATE_DEFINES
#define GENERIC_PRIVATE_DEFINES

#define GET_PLUGIN_CORE(object, plugin) \
    ((plugin##Core *) (object)->base.privates[plugin##CorePrivateIndex].ptr)
#define PLUGIN_CORE(object, plugin, prefix) \
    plugin##Core * prefix##c = GET_PLUGIN_CORE (object, plugin)

#define GET_PLUGIN_DISPLAY(object, plugin) \
    ((plugin##Display *) \
	(object)->base.privates[plugin##DisplayPrivateIndex].ptr)
#define PLUGIN_DISPLAY(object, plugin, prefix) \
    plugin##Display * prefix##d = GET_PLUGIN_DISPLAY (object, plugin)

#define GET_PLUGIN_SCREEN(object, parent, plugin) \
    ((plugin##Screen *) \
	(object)->base.privates[(parent)->screenPrivateIndex].ptr)
#define PLUGIN_SCREEN(object, plugin, prefix) \
    plugin##Screen * prefix##s = \
	GET_PLUGIN_SCREEN (object, \
	GET_PLUGIN_DISPLAY ((object)->display, plugin), plugin)

#define GET_PLUGIN_WINDOW(object, parent, plugin) \
    ((plugin##Window *) \
	(object)->base.privates[(parent)->windowPrivateIndex].ptr)
#define PLUGIN_WINDOW(object, plugin, prefix) \
    plugin##Window * prefix##w = \
	GET_PLUGIN_WINDOW  (object, \
	GET_PLUGIN_SCREEN  ((object)->screen, \
	GET_PLUGIN_DISPLAY ((object)->screen->display, plugin), plugin), plugin)

#endif

COMPIZ_END_DECLS

#endif
</xsl:text>
    </xsl:template>

<!-- enums for screen/display options -->

    <xsl:template name="printDisplayOptionsEnum">
<xsl:text>typedef enum
{
</xsl:text>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/display/descendant-or-self::option">
            <xsl:text>    </xsl:text>
            <xsl:call-template name="printOptionsEnumName"/>
            <xsl:text>,
</xsl:text>
        </xsl:for-each>
        <xsl:text>    </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>DisplayOptionNum
</xsl:text>
<xsl:text>} </xsl:text>
        <xsl:value-of select="$Plugin"/>
<xsl:text>DisplayOptions;

typedef void (*</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>DisplayOptionChangeNotifyProc) (CompDisplay *display, CompOption *opt, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>DisplayOptions num);

CompOption *</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>GetDisplayOption (CompDisplay *d, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>DisplayOptions num);

</xsl:text>
    </xsl:template>
    
    <xsl:template name="printScreenOptionsEnum">
<xsl:text>typedef enum
{
</xsl:text>
        <xsl:for-each select="/compiz/plugin[@name=$pName]/screen/descendant-or-self::option">
            <xsl:text>    </xsl:text>
            <xsl:call-template name="printOptionsEnumName"/>
            <xsl:text>,
</xsl:text>
        </xsl:for-each>
        <xsl:text>    </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>ScreenOptionNum
</xsl:text>
<xsl:text>} </xsl:text>
        <xsl:value-of select="$Plugin"/>
<xsl:text>ScreenOptions;

typedef void (*</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>ScreenOptionChangeNotifyProc) (CompScreen *screen, CompOption *opt, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>ScreenOptions num);

CompOption *</xsl:text>
        <xsl:value-of select="$plugin"/>
        <xsl:text>GetScreenOption (CompScreen *s, </xsl:text>
        <xsl:value-of select="$Plugin"/>
        <xsl:text>ScreenOptions num);

</xsl:text>
    </xsl:template>

<!-- generate enums/masks for restricted string options -->

    <xsl:template name="printOptionEnums">
                <xsl:for-each select="/compiz/plugin[@name=$pName]/descendant-or-self::option[(@type = 'int' or (@type = 'list' and ./type/text() = 'int')) and ./desc/value]">
            <xsl:text>typedef enum
{
</xsl:text>
            <xsl:for-each select="desc/*[(name() = 'name' and not(@xml:lang)) or name() = '_name']">
                <xsl:text>    </xsl:text>
                <xsl:call-template name="PrintCamel">
		    <xsl:with-param name="text">
			<xsl:value-of select="../../@name"/>
		    </xsl:with-param>
		</xsl:call-template>
                <xsl:call-template name="PrintCamel">
		    <xsl:with-param name="text">
			<xsl:value-of select="text()"/>
		    </xsl:with-param>
	        </xsl:call-template>
	        <xsl:text> = </xsl:text>
	        <xsl:value-of select="../value/text()"/>
	        <xsl:text>,
</xsl:text>
            </xsl:for-each>
            <xsl:text>} </xsl:text>
            <xsl:value-of select="$Plugin"/>
            <xsl:call-template name="printOptionName"/>
            <xsl:text>Enum;

</xsl:text>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="printOptionMasks">
        <xsl:for-each select="/compiz/plugin[@name=$pName]/descendant-or-self::option[@type = 'list' and ./desc/value and ./type/text() = 'int']">
            <xsl:for-each select="desc/*[(name() = 'name' and not(@xml:lang)) or name() = '_name']">
                <xsl:text>#define </xsl:text>
                <xsl:call-template name="PrintCamel">
		    <xsl:with-param name="text">
			<xsl:value-of select="../../@name"/>
		    </xsl:with-param>
		</xsl:call-template>
                <xsl:call-template name="PrintCamel">
		    <xsl:with-param name="text">
			<xsl:value-of select="text()"/>
		    </xsl:with-param>
	        </xsl:call-template>
	        <xsl:text>Mask (1 &lt;&lt; </xsl:text>
	        <xsl:value-of select="../value/text()"/>
	        <xsl:text>)
</xsl:text>
            </xsl:for-each>
            <xsl:text>

</xsl:text>
        </xsl:for-each>
    </xsl:template>

<!-- generate get/set function definitions -->

    <xsl:template name="printFunctionDefinitions">
        <xsl:for-each select="/compiz/plugin[@name=$pName]/descendant-or-self::option">
            <xsl:choose>
                <xsl:when test="@type='int'">
                    <xsl:text>int              </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
</xsl:text>
                </xsl:when>
                <xsl:when test="@type='float'">
                    <xsl:text>float            </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='bool'">
                    <xsl:text>Bool             </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='string'">
                    <xsl:text>char *           </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='match'">
                    <xsl:text>CompMatch *      </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='color'">
                    <xsl:text>unsigned short * </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
unsigned short   </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Red (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>);
unsigned short   </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Green (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>);
unsigned short   </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Blue (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>);
unsigned short   </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Get</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Alpha (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>);
</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='action' or @type='key' or @type='button' or @type='edge' or @type='bell'">
                    <xsl:text>CompAction *     </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
void             </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Set</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Initiate (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>, CompActionCallBackProc init);
void             </xsl:text>
                    <xsl:value-of select="$plugin"/>
		    <xsl:text>Set</xsl:text>
		    <xsl:call-template name="printOptionName"/>
		    <xsl:text>Terminate (</xsl:text>
		    <xsl:call-template name="baseType"/>
		    <xsl:text>, CompActionCallBackProc term);
</xsl:text>
                </xsl:when>
                 <xsl:when test="@type='list'">
                    <xsl:text>CompListValue *  </xsl:text>
                    <xsl:call-template name="printGetFunctionDef"/>
                    <xsl:text>;
</xsl:text>
                    <xsl:if test="./type[text() = 'int']/../desc/value">
                        <xsl:text>unsigned int     </xsl:text>
                        <xsl:value-of select="$plugin"/>
			<xsl:text>Get</xsl:text>
			<xsl:call-template name="printOptionName"/>
			<xsl:text>Mask (</xsl:text>
			<xsl:call-template name="baseType"/>
			<xsl:text>);
</xsl:text>
                    </xsl:if>
                </xsl:when>
            </xsl:choose>
            <xsl:text>CompOption *     </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>Get</xsl:text>
            <xsl:call-template name="printOptionName"/>
            <xsl:text>Option (</xsl:text>
            <xsl:call-template name="baseType"/>
            <xsl:text>);
void             </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:text>Set</xsl:text>
            <xsl:call-template name="printOptionName"/>
            <xsl:text>Notify (</xsl:text>
            <xsl:call-template name="baseType"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="$plugin"/>
            <xsl:call-template name="screenOrDisplay"/>
            <xsl:text>OptionChangeNotifyProc notify);

</xsl:text>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="printGetFunctionDef">
	<xsl:value-of select="$plugin"/>
	<xsl:text>Get</xsl:text>
        <xsl:call-template name="printOptionName"/>
        <xsl:text> (</xsl:text>
	<xsl:call-template name="baseType"/>
	<xsl:text>)</xsl:text>
    </xsl:template>

</xsl:stylesheet>
