All pastes #182732 Raw Edit

Anonymous

public c v1 · immutable
#182732 ·published 2006-09-26 09:08 UTC
rendered paste body
/* * Copyright © 2005 Novell, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies * and that both that copyright notice and this permission notice * appear in supporting documentation, and that the name of * Novell, Inc. not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * Novell, Inc. makes no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: David Reveman <davidr@novell.com> *//* * source HEAVILY modified by Quinn, released under GPL */#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <beryl.h>#include <glib.h>#include <glib/gprintf.h>#include <glib/gstdio.h>#include <errno.h>#define KEY_CHANGE_TIMEOUT 250static int displayPrivateIndex;enum _foo{    CSM_DISPLAY_OPTION_RELOAD,    CSM_DISPLAY_OPTION_NUM};typedef struct _CSMDisplay{    int screenPrivateIndex;    GKeyFile *schemaFile;       // defaults in here    GKeyFile *settingsFile;     // user settinge here    CompTimeoutHandle timeoutHandle;    InitPluginForDisplayProc initPluginForDisplay;    SetDisplayOptionProc setDisplayOption;    SetDisplayOptionForPluginProc setDisplayOptionForPlugin;    CompOption opt[CSM_DISPLAY_OPTION_NUM];} CSMDisplay;typedef struct _CSMScreen{    InitPluginForScreenProc initPluginForScreen;    SetScreenOptionProc setScreenOption;    SetScreenOptionForPluginProc setScreenOptionForPlugin;} CSMScreen;#define GET_CSM_DISPLAY(d)				      \    ((CSMDisplay *) (d)->privates[displayPrivateIndex].ptr)#define CSM_DISPLAY(d)		     \    CSMDisplay *gd = GET_CSM_DISPLAY (d)#define GET_CSM_SCREEN(s, gd)				         \    ((CSMScreen *) (s)->privates[(gd)->screenPrivateIndex].ptr)#define CSM_SCREEN(s)						           \    CSMScreen *gs = GET_CSM_SCREEN (s, GET_CSM_DISPLAY (s->display))#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))static gboolean set_load_option(GKeyFile * schemaFile, gchar * sect, gchar * dval, CompOption * o,CompOptionValue * v,        CompDisplay * cd);static void set_save_option(GKeyFile * schemaFile, gchar * sect, gchar * dval, CompOption * o,        CompDisplay * cd);static gboolean set_load_option(GKeyFile * schemaFile, gchar * sect, gchar * dval, CompOption * o,CompOptionValue * v,        CompDisplay * cd){    GError * e = NULL;    gboolean b;    gint i;    gchar * s;    gdouble f;    switch(o->type)    {        case CompOptionTypeBool:            b=g_key_file_get_boolean(schemaFile,sect,dval,&e);            if (!e)            {                v->b=b;                return TRUE;            }            break;        case CompOptionTypeInt:            i=g_key_file_get_integer(schemaFile,sect,dval,&e);            if (!e)            {                v->i=i;                return TRUE;            }            break;        case CompOptionTypeString:            s=g_key_file_get_string(schemaFile,sect,dval,&e);            if (s)            {                if (v->s)                    free(v->s);                v->s=s;                return TRUE;            }            break;        case CompOptionTypeFloat:            s=g_key_file_get_string(schemaFile,sect,dval,&e);            if (s)            {                f=g_ascii_strtod(s,NULL);                g_free(s);                v->f=f;                return TRUE;            }            break;        case CompOptionTypeColor:            {                gint * c;                gsize l=0;                c=g_key_file_get_integer_list(schemaFile,sect,dval,&l,&e);                if (!e && l>=4)                {                    v->c[0]=c[0];                    v->c[1]=c[1];                    v->c[2]=c[2];                    v->c[3]=c[3];                    g_free(c);                    return TRUE;                }            }            break;        case CompOptionTypeAction:            {                gint * d;                gsize l=0;                d=g_key_file_get_integer_list(schemaFile,sect,dval,&l,&e);                if (!e && l>=6)                {                    v->action=o->value.action;                    v->action.type=CompBindingTypeNone;                    v->action.button.modifiers=d[0];                    v->action.button.button=d[1];                    if (d[1]!=0)                        v->action.type|=CompBindingTypeButton;                    v->action.key.modifiers=d[2];                    v->action.key.keycode=0;                    if (d[3]!=0)                    {                        v->action.key.keycode=XKeysymToKeycode(cd->display,d[3]);                        v->action.type|=CompBindingTypeKey;                    }                    v->action.edgeMask=d[4];                    v->action.bell=d[5]==1?TRUE:FALSE;                    g_free(d);                    return TRUE;                }            }            break;        case CompOptionTypeList:            {                gint i;                v->list.type = o->value.list.type;                switch(o->value.list.type)                {                    gsize l=0;                    case CompOptionTypeBool:                    {                        gboolean * d = g_key_file_get_boolean_list(                                schemaFile,sect,dval,&l,&e);                        if (!e)                        {                            if (v->list.nValue && v->list.value)                            {                                v->list.nValue=0;                                free(v->list.value);                            }                            v->list.nValue=l;                            v->list.value=malloc(sizeof(CompOptionValue)*l);                            for (i=0;i<l;i++)                                v->list.value[i].b=d[i];                            g_free(d);                            return TRUE;                        }                    }                    break;                    case CompOptionTypeInt:                    {                        gint * d = g_key_file_get_integer_list(                                schemaFile,sect,dval,&l,&e);                        if (!e)                        {                            if (v->list.nValue && v->list.value)                            {                                v->list.nValue=0;                                free(v->list.value);                            }                            v->list.nValue=l;                            v->list.value=malloc(sizeof(CompOptionValue)*l);                            for (i=0;i<l;i++)                                v->list.value[i].i=d[i];                            g_free(d);                            return TRUE;                        }                    }                    break;                    case CompOptionTypeString:                    {                        gchar ** d = g_key_file_get_string_list(schemaFile,sect,                                dval,&l,&e);                        if (!e)                        {                            if (v->list.nValue && v->list.value)                            {                                v->list.nValue=0;                                free(v->list.value);                            }                            v->list.nValue=l;                            v->list.value=malloc(sizeof(CompOptionValue)*l);                            for(i=0;i<l;i++)                            {                                if (!d[i])                                    v->list.value[i].s=strdup("");                                else                                    v->list.value[i].s=strdup(d[i]);                            }                            g_strfreev(d);                            return TRUE;                        }                    }                    break;                    case CompOptionTypeFloat:                    {                        gchar ** d = g_key_file_get_string_list(schemaFile,sect,                                dval,&l,&e);                        if (!e)                        {                            if (v->list.nValue && v->list.value)                            {                                v->list.nValue=0;                                free(v->list.value);                            }                            v->list.nValue=l;                            v->list.value=malloc(sizeof(CompOptionValue)*l);                            for(i=0;i<l;i++)                                v->list.value[i].f=g_ascii_strtod(d[i],NULL);                            g_strfreev(d);                            return TRUE;                        }                    }                    break;                    case CompOptionTypeAction:                    {                        gint * d = g_key_file_get_integer_list(                                schemaFile,sect,dval,&l,&e);                        if (!e && l%6==0)                        {                            if (v->list.nValue && v->list.value)                            {                                v->list.nValue=0;                                free(v->list.value);                            }                            v->list.nValue=l/6;                            v->list.value=malloc(sizeof(CompOptionValue)*l);                            for(i=0;i<(l/6);i++)                            {                                v->list.value[i].action.button.modifiers=d[i*6];                                v->list.value[i].action.button.button=d[i*6+1];                                v->list.value[i].action.key.modifiers=d[i*6+2];                                v->list.value[i].action.key.keycode=                                    XKeysymToKeycode(cd->display,d[i*6+3]);                                v->list.value[i].action.edgeMask=d[i*6+4];                                v->list.value[i].action.bell=d[i*6+5]==1?TRUE:FALSE;                            }                            g_free(d);                            return TRUE;                        }                    }                    break;                    case CompOptionTypeColor:                    {                        gint * d = g_key_file_get_integer_list(                                schemaFile,sect,dval,&l,&e);                        if (!e && l%4==0)                        {                            if (v->list.nValue && v->list.value)                            {                                v->list.nValue=0;                                free(v->list.value);                            }                            v->list.nValue=l/4;                            v->list.value=malloc(sizeof(CompOptionValue)*l);                            for(i=0;i<(l/4);i++)                            {                                v->list.value[i].c[0]=d[i*4];                                v->list.value[i].c[1]=d[i*4+1];                                v->list.value[i].c[2]=d[i*4+2];                                v->list.value[i].c[3]=d[i*4+3];                            }                            g_free(d);                        }                        return TRUE;                    }                    break;                    case CompOptionTypeList:                    g_error("List type is not a valid list type");                }            }    }    return FALSE;}static void set_save_option(GKeyFile * schemaFile, gchar * sect, gchar * dval, CompOption * o,        CompDisplay * cd){    switch(o->type)    {        case CompOptionTypeBool:            g_key_file_set_boolean(schemaFile,sect,dval,o->value.b);            break;        case CompOptionTypeInt:            g_key_file_set_integer(schemaFile,sect,dval,o->value.i);            break;        case CompOptionTypeString:            g_key_file_set_string(schemaFile,sect,dval,o->value.s);            break;        case CompOptionTypeFloat:            {                gchar s[G_ASCII_DTOSTR_BUF_SIZE];                g_ascii_dtostr(s,G_ASCII_DTOSTR_BUF_SIZE,o->value.f);                g_key_file_set_string(schemaFile,sect,dval,s);            }            break;        case CompOptionTypeColor:            {                gint c[4];                c[0]=o->value.c[0];                c[1]=o->value.c[1];                c[2]=o->value.c[2];                c[3]=o->value.c[3];                g_key_file_set_integer_list(schemaFile,sect,dval,c,4);            }            break;        case CompOptionTypeAction:            {                //format...                //string list                //button;key;edge;bell;                //button-format                //  modifiers(int);button(int);                //key-format                //  modifiers(int);keysym(int);                //edge-format                //  edgemask(int)                //bell-format                //  on_bell(int)                gint d[6];                d[0]=o->value.action.button.modifiers;                d[1]=(o->value.action.type & CompBindingTypeButton)?                    o->value.action.button.button:0;                d[2]=o->value.action.key.modifiers;                d[3]=(o->value.action.type & CompBindingTypeKey)?                    XKeycodeToKeysym(cd->display,o->value.action.key.keycode,0)                    :0;                d[4]=o->value.action.edgeMask;                d[5]=o->value.action.bell?1:0;                g_key_file_set_integer_list(schemaFile,sect,dval,d,6);            }            break;        case CompOptionTypeList:            {                gint i;                switch(o->value.list.type)                {                    case CompOptionTypeBool:                        {                            gboolean * d = malloc(sizeof(gboolean)*o->value.list.nValue);                            for (i=0;i<o->value.list.nValue;i++)                                d[i]=o->value.list.value[i].b;                            g_key_file_set_boolean_list(schemaFile,sect,dval,d,o->value.list.nValue);                            free(d);                        }                        break;                    case CompOptionTypeInt:                        {                            gint * d = malloc(sizeof(gint)*o->value.list.nValue);                            for (i=0;i<o->value.list.nValue;i++)                                d[i]=o->value.list.value[i].i;                            g_key_file_set_integer_list(schemaFile,sect,dval,d,o->value.list.nValue);                            free(d);                        }                        break;                    case CompOptionTypeString:                        {                            gchar ** d = malloc(sizeof(gchar *)*o->value.list.nValue);                            for(i=0;i<o->value.list.nValue;i++)                                d[i]=o->value.list.value[i].s;                            g_key_file_set_string_list(schemaFile,sect,dval,                                    (const gchar **)d,o->value.list.nValue);                            free(d);                        }                        break;                    case CompOptionTypeFloat:                        {                            gchar ** d = malloc(sizeof(gchar *)*o->value.list.nValue);                            for (i=0;i<o->value.list.nValue;i++)                            {                                d[i]=malloc(G_ASCII_DTOSTR_BUF_SIZE);                                g_ascii_dtostr(d[i],G_ASCII_DTOSTR_BUF_SIZE,                                        o->value.list.value[i].f);                            }                            g_key_file_set_string_list(schemaFile,sect,dval,                                    (const gchar **) d,o->value.list.nValue);                            for (i=0;i<o->value.list.nValue;i++)                                free(d[i]);                            free(d);                        }                        break;                    case CompOptionTypeAction:                        {                            gint * d = malloc(sizeof(gint)*o->value.list.nValue*6);                            for(i=0;i<o->value.list.nValue;i++)                            {                                d[i*6]=o->value.list.value[i].action.button.modifiers;                                d[i*6+1]=(o->value.list.value[i].action.type & CompBindingTypeButton)                                    ?o->value.list.value[i].action.button.button:0;                                d[i*6+2]=o->value.list.value[i].action.key.modifiers;                                d[i*6+3]=(o->value.list.value[i].action.type & CompBindingTypeKey)                                    ?XKeycodeToKeysym(cd->display,                                            o->value.list.value[i].action.key.keycode,0):0;                                d[i*6+4]=o->value.list.value[i].action.edgeMask;                                d[i*6+5]=o->value.list.value[i].action.bell?1:0;                            }                            g_key_file_set_integer_list(schemaFile,sect,dval,d,                                    o->value.list.nValue*6);                            free(d);                        }                        break;                    case CompOptionTypeColor:                        {                            gint * d = malloc(sizeof(gint)*o->value.list.nValue*4);                            for(i=0;i<o->value.list.nValue;i++)                            {                                gint j;                                for(j=0;j<4;j++)                                {                                    d[i*4+j]=o->value.list.value[i].c[j];                                }                            }                            g_key_file_set_integer_list(schemaFile,sect,dval,d,                                    o->value.list.nValue*4);                            free(d);                        }                        break;                    case CompOptionTypeList:                        g_error("List type is not a valid list type");                }            }    }}static CompOption *setGetDisplayOptions (CompDisplay * display, int *count){    if (display)    {        CSM_DISPLAY (display);            *count = NUM_OPTIONS (gd);        return gd->opt;    }    else    {        *count=0;        return NULL;    }}static gbooleanset_compare_option (CompOption * o, CompOption * p){    //check if o == p    if (o->type != p->type)        return FALSE;    if (o->type == CompOptionTypeList &&        (o->value.list.type != p->value.list.type ||         o->value.list.nValue != p->value.list.nValue))        return FALSE;    switch (o->type)    {    case CompOptionTypeString:        if (!o->value.s || !p->value.s            || strcmp (o->value.s, p->value.s) != 0)            return FALSE;       // if only one is NULL this isn't quite right, but it        //shouldn't happen        break;    case CompOptionTypeFloat:        if (o->value.f != p->value.f)            return FALSE;        break;    case CompOptionTypeInt:        if (o->value.i != p->value.i)            return FALSE;        break;    case CompOptionTypeColor:    {        gint i;        for (i = 0; i < 4; i++)            if (o->value.c[i] != p->value.c[i])                return FALSE;    }        break;    case CompOptionTypeBool:        if (o->value.b != p->value.b)            return FALSE;        break;    case CompOptionTypeAction:        if (o->value.action.type != p->value.action.type)            return FALSE;        if (o->value.action.button.button != p->value.action.button.button)            return FALSE;        if (o->value.action.button.modifiers !=            p->value.action.button.modifiers)            return FALSE;        if (o->value.action.key.keycode != p->value.action.key.keycode)            return FALSE;        if (o->value.action.key.modifiers != p->value.action.key.modifiers)            return FALSE;        if (o->value.action.edgeMask != p->value.action.edgeMask)            return FALSE;        if (o->value.action.bell != p->value.action.bell)            return FALSE;        break;    case CompOptionTypeList:    {        gint i;        for (i = 0; i < o->value.list.nValue; i++)        {            CompOption a, b;            a.type = o->value.list.type;            b.type = p->value.list.type;            a.value = o->value.list.value[i];            b.value = p->value.list.value[i];            if (!set_compare_option (&a, &b))                return FALSE;        }    }    }    return TRUE;}static voidsetSetOption (CompDisplay * d,              CompOption * o, gboolean screen, gchar * plugin){    gchar *key;    gchar *key2;    CompOption p;    CSM_DISPLAY (d);    if (!screen)        key = g_strconcat ("a_", o->name, NULL);    else        key = g_strconcat ("s_", o->name, NULL);    key2 = g_strconcat ("d_", key, NULL);    if (!plugin)        plugin = "_";    p.name = o->name;    p.type = o->type;    if (o->type == CompOptionTypeString)        p.value.s = NULL;    if (o->type == CompOptionTypeList)    {        p.value.list.type = o->value.list.type;        p.value.list.nValue = 0;        p.value.list.value = 0;    }    p.rest = o->rest;    if ((!set_load_option (gd->settingsFile, plugin, key, o, &p.value, d)         && !set_load_option (gd->schemaFile, plugin, key2, o, &p.value, d))        || !set_compare_option (o, &p))    {        /*if (screen && strcmp(screen,"allscreens")!=0)           {           if (plugin)           d->screens->setScreenOptionForPlugin(d->screens,plugin,p.name,&(p.value));           else           d->screens->setScreenOption(d->screens,p.name,&(p.value));           }           else           {           if (plugin)           d->setDisplayOptionForPlugin(d,plugin,p.name,&(p.value));           else           d->setDisplayOption(d,p.name,&(p.value));           } */        set_save_option (gd->settingsFile, plugin, key, &p, d);        {            gchar *fnam = g_strconcat (g_get_home_dir (),                                       "/.beryl/settings", NULL);            gchar *set = g_key_file_to_data (gd->settingsFile, NULL, NULL);            if (set)            {                FILE *f = fopen (fnam, "w");                if (!f)                    g_warning (strerror (errno));                else                {                    fprintf (f, "%s", set);                    fclose (f);                }                g_free (set);            }            g_free (fnam);        }    }    if (p.type == CompOptionTypeList && p.value.list.nValue        && p.value.list.value)    {        if (p.value.list.type == CompOptionTypeString)        {            gint i;            for (i = 0; i < p.value.list.nValue; i++)                free (p.value.list.value[i].s);        }        free (p.value.list.value);    }    if (p.type == CompOptionTypeString)        free (p.value.s);    g_free (key);    g_free (key2);}static voidsetInitOption (CompDisplay * d,               CompOption * o, gboolean screen, gchar * plugin){    gchar *key, *key2;    CompScreen *s = d->screens;    CompOptionValue *v = malloc (sizeof (CompOptionValue));    gboolean stat;    CSM_DISPLAY (d);    bzero (v, sizeof (CompOptionValue));    if (!plugin)        plugin = "_";    if (!screen)        key = g_strconcat ("a_", o->name, NULL);    else        key = g_strconcat ("s_", o->name, NULL);    key2 = g_strconcat ("d_", key, NULL);    stat = set_load_option (gd->settingsFile, plugin, key, o, v, d);    if (!stat)        stat = set_load_option (gd->schemaFile, plugin, key2, o, v, d);    if (!stat)    {        g_warning ("bailing, couldn't find a val for %s in \n"                   "[%s]->%s or\n"                   "[%s]->%s", o->name, plugin, key, plugin, key2);        return;    }    if (screen)    {        if (strcmp (plugin, "_") != 0)        {            s->setScreenOptionForPlugin (s, plugin, o->name, v);        }        else        {            s->setScreenOption (s, o->name, v);        }    }    else    {        if (strcmp (plugin, "_") != 0)        {            d->setDisplayOptionForPlugin (d, plugin, o->name, v);        }        else        {            d->setDisplayOption (d, o->name, v);        }    }    free (v);}static BoolreloadProc (CompDisplay * d,            CompAction * action,            CompActionState state, CompOption * option, int nOption){    CSM_DISPLAY (d);    gchar *sect, *opt;    CompOption *o = NULL;    CompPlugin *p;    CompScreen *s = NULL;    int oc = 0;    GError *e = NULL;    opt = g_strconcat (g_get_home_dir (), "/.beryl/settings", NULL);    g_key_file_free (gd->settingsFile);    gd->settingsFile = g_key_file_new ();    g_key_file_load_from_file (gd->settingsFile, opt, 0, &e);    if (e)        g_warning ("couldn't load settings file!");    g_free (opt);    sect = getStringOptionNamed (option, nOption, "section", 0);    if (!sect)        return TRUE;    opt = getStringOptionNamed (option, nOption, "option", 0);    if (!opt)        return TRUE;    if (strlen (opt) < 3)        return TRUE;    if (opt[0] == 's')    {        s = d->screens;    }    p = findActivePlugin (sect);    if (p)    {        if (s)        {            if (p->vTable->getScreenOptions)                o = (*p->vTable->getScreenOptions) (s, &oc);        }        else        {            if (p->vTable->getDisplayOptions)                o = (*p->vTable->getDisplayOptions) (d, &oc);        }    }    else    {        if (s)            o = compGetScreenOptions (s, &oc);        else            o = compGetDisplayOptions (d, &oc);    }    o = compFindOption (o, oc, opt + 2, 0);    if (o)    {        g_message ("Reloading for [%s]->%s(%s)", sect, opt, o->name);        setInitOption (d, o, opt[0] == 's', sect);        return FALSE;    }    else        g_warning ("Couldn't find [%s]->%s", sect, opt);    return TRUE;}static BoolsetSetDisplayOption (CompDisplay * d, char *name, CompOptionValue * value){    Bool status;    CSM_DISPLAY (d);    UNWRAP (gd, d, setDisplayOption);    status = (*d->setDisplayOption) (d, name, value);    WRAP (gd, d, setDisplayOption, setSetDisplayOption);    if (status)    {        CompOption *option;        int nOption;        option = compGetDisplayOptions (d, &nOption);        setSetOption (d, compFindOption (option, nOption, name, 0), FALSE, 0);    }    return status;}static BoolsetSetDisplayOptionForPlugin (CompDisplay * d,                              char *plugin,                              char *name, CompOptionValue * value){    Bool status;    CSM_DISPLAY (d);    UNWRAP (gd, d, setDisplayOptionForPlugin);    status = (*d->setDisplayOptionForPlugin) (d, plugin, name, value);    WRAP (gd, d, setDisplayOptionForPlugin, setSetDisplayOptionForPlugin);    if (status)    {        CompPlugin *p;        p = findActivePlugin (plugin);        if (p && p->vTable->getDisplayOptions)        {            CompOption *option;            int nOption;            option = (*p->vTable->getDisplayOptions) (d, &nOption);            setSetOption (d, compFindOption (option, nOption, name, 0),                          FALSE, plugin);        }    }    return status;}static BoolsetSetScreenOption (CompScreen * s, char *name, CompOptionValue * value){    Bool status;    CSM_SCREEN (s);    UNWRAP (gs, s, setScreenOption);    status = (*s->setScreenOption) (s, name, value);    WRAP (gs, s, setScreenOption, setSetScreenOption);    if (status)    {        CompOption *option;        int nOption;        option = compGetScreenOptions (s, &nOption);        setSetOption (s->display, compFindOption (option, nOption, name, 0),                      TRUE, 0);    }    return status;}static BoolsetSetScreenOptionForPlugin (CompScreen * s,                             char *plugin,                             char *name, CompOptionValue * value){    Bool status;    CSM_SCREEN (s);    UNWRAP (gs, s, setScreenOptionForPlugin);    status = (*s->setScreenOptionForPlugin) (s, plugin, name, value);    WRAP (gs, s, setScreenOptionForPlugin, setSetScreenOptionForPlugin);    if (status)    {        CompPlugin *p;        p = findActivePlugin (plugin);        if (p && p->vTable->getScreenOptions)        {            CompOption *option;            int nOption;            option = (*p->vTable->getScreenOptions) (s, &nOption);            setSetOption (s->display,                          compFindOption (option, nOption, name, 0),                          TRUE, plugin);        }    }    return status;}static BoolsetInitPluginForDisplay (CompPlugin * p, CompDisplay * d){    Bool status;    CSM_DISPLAY (d);    UNWRAP (gd, d, initPluginForDisplay);    status = (*d->initPluginForDisplay) (p, d);    WRAP (gd, d, initPluginForDisplay, setInitPluginForDisplay);    if (status && p->vTable->getDisplayOptions)    {        CompOption *option;        int nOption;        option = (*p->vTable->getDisplayOptions) (d, &nOption);        while (nOption--)            setInitOption (d, option++, FALSE, p->vTable->name);    }    return status;}static BoolsetInitPluginForScreen (CompPlugin * p, CompScreen * s){    Bool status;    CSM_SCREEN (s);    UNWRAP (gs, s, initPluginForScreen);    status = (*s->initPluginForScreen) (p, s);    WRAP (gs, s, initPluginForScreen, setInitPluginForScreen);    if (status && p->vTable->getScreenOptions)    {        CompOption *option;        int nOption;        option = (*p->vTable->getScreenOptions) (s, &nOption);        while (nOption--)            setInitOption (s->display, option++, TRUE, p->vTable->name);    }    return status;}static BoolsetTimeout (void *closure){    while (g_main_pending ())        g_main_iteration (FALSE);    return TRUE;}static voidsetDisplayInitOptions (CSMDisplay * gd){    CompOption *o;    o = &gd->opt[CSM_DISPLAY_OPTION_RELOAD];    o->name = "reload";    o->shortDesc = N_("Reload");    o->longDesc = N_("DBUS Signal Target for Reload");    o->type = CompOptionTypeAction;    o->value.action.initiate = reloadProc;    o->value.action.terminate = 0;    o->value.action.bell = FALSE;    o->value.action.edgeMask = 0;    o->value.action.state = 0;    o->value.action.type = CompBindingTypeNone;}static voidimport_key_file (GKeyFile * dest, gchar * source){    GKeyFile *f = g_key_file_new ();    gchar **gr;    gint i;    g_key_file_load_from_file (f, source, 0, NULL);    gr = g_key_file_get_groups (f, NULL);    for (i = 0; gr && gr[i]; i++)    {        gint j;        gchar **ke;        ke = g_key_file_get_keys (f, gr[i], NULL, NULL);        for (j = 0; ke && ke[j]; j++)            g_key_file_set_value (dest, gr[i], ke[j],                                  g_key_file_get_value (f, gr[i], ke[j],                                                        NULL));        g_strfreev (ke);    }    g_strfreev (gr);    g_key_file_free (f);}static voidload_schema_files (CSMDisplay * gd){    GDir *d;    gchar *dpos;    gd->schemaFile = g_key_file_new ();    import_key_file (gd->schemaFile, DATADIR "/beryl/settings");    d = g_dir_open (DATADIR "/beryl/", 0, NULL);    if (d)    {        const gchar *e;        while ((e = g_dir_read_name (d)))        {            gchar *xfile;            if (g_str_has_suffix (e, ".settings"))            {                xfile =                    g_strconcat (DATADIR "/beryl/", e,                                 NULL);                import_key_file (gd->schemaFile, xfile);                g_free (xfile);            }        }        g_dir_close (d);    }    dpos = g_strconcat (g_get_home_dir (), "/.beryl/plugins/", NULL);    d = g_dir_open (dpos, 0, NULL);    if (d)    {        const gchar *e;        while ((e = g_dir_read_name (d)))        {            gchar *xfile;            if (g_str_has_suffix (e, ".settings"))            {                xfile =                    g_strconcat (g_get_home_dir (), "/.beryl/plugins/", e,                                 NULL);                import_key_file (gd->schemaFile, xfile);                g_free (xfile);            }        }        g_dir_close (d);    }    g_free (dpos);}static BoolsetInitDisplay (CompPlugin * p, CompDisplay * d){    CompOption *option;    int nOption;    CSMDisplay *gd;    gchar *smmser;    gd = malloc (sizeof (CSMDisplay));    if (!gd)        return FALSE;    setDisplayInitOptions (gd);    gd->screenPrivateIndex = allocateScreenPrivateIndex (d);    if (gd->screenPrivateIndex < 0)    {        free (gd);        return FALSE;    }    WRAP (gd, d, initPluginForDisplay, setInitPluginForDisplay);    WRAP (gd, d, setDisplayOption, setSetDisplayOption);    WRAP (gd, d, setDisplayOptionForPlugin, setSetDisplayOptionForPlugin);    d->privates[displayPrivateIndex].ptr = gd;    load_schema_files (gd);    gd->settingsFile = g_key_file_new ();    smmser = g_strconcat (g_get_home_dir (), "/.beryl", NULL);    g_mkdir_with_parents (smmser, 00755);    g_chmod (smmser, 00755);    g_free (smmser);    smmser = g_strconcat (g_get_home_dir (), "/.beryl/settings", NULL);    g_key_file_load_from_file (gd->settingsFile, smmser, 0, NULL);    g_free (smmser);    option = compGetDisplayOptions (d, &nOption);    while (nOption--)        setInitOption (d, option++, FALSE, 0);    gd->timeoutHandle = compAddTimeout (KEY_CHANGE_TIMEOUT, setTimeout, 0);    return TRUE;}static voidsetFiniDisplay (CompPlugin * p, CompDisplay * d){    CSM_DISPLAY (d);    g_key_file_free (gd->schemaFile);    g_key_file_free (gd->settingsFile);    compRemoveTimeout (gd->timeoutHandle);    freeScreenPrivateIndex (d, gd->screenPrivateIndex);    free (gd);}static BoolsetInitScreen (CompPlugin * p, CompScreen * s){    CompOption *option;    int nOption;    CSMScreen *gs;    CSM_DISPLAY (s->display);    gs = malloc (sizeof (CSMScreen));    if (!gs)        return FALSE;    WRAP (gs, s, initPluginForScreen, setInitPluginForScreen);    WRAP (gs, s, setScreenOption, setSetScreenOption);    WRAP (gs, s, setScreenOptionForPlugin, setSetScreenOptionForPlugin);    s->privates[gd->screenPrivateIndex].ptr = gs;    option = compGetScreenOptions (s, &nOption);    while (nOption--)        setInitOption (s->display, option++, TRUE, 0);    return TRUE;}static voidsetFiniScreen (CompPlugin * p, CompScreen * s){    CSM_SCREEN (s);    UNWRAP (gs, s, initPluginForScreen);    UNWRAP (gs, s, setScreenOption);    UNWRAP (gs, s, setScreenOptionForPlugin);    free (gs);}static BoolsetInit (CompPlugin * p){    displayPrivateIndex = allocateDisplayPrivateIndex ();    if (displayPrivateIndex < 0)        return FALSE;    return TRUE;}static voidsetFini (CompPlugin * p){    if (displayPrivateIndex >= 0)        freeDisplayPrivateIndex (displayPrivateIndex);}CompPluginDep setDeps[] = {    {CompPluginRuleAfter, "dbus"}    ,    {CompPluginRuleBefore, "decoration"}    ,    {CompPluginRuleBefore, "wobbly"}    ,    {CompPluginRuleBefore, "fade"}    ,    {CompPluginRuleBefore, "cube"}    ,    {CompPluginRuleBefore, "scale"}};CompPluginVTable setVTable = {    "settings",    "Settings Manager",    "Use beryl-settings to configure me!",    setInit,    setFini,    setInitDisplay,    setFiniDisplay,    setInitScreen,    setFiniScreen,    0,                          /* InitWindow */    0,                          /* FiniWindow */    setGetDisplayOptions,       /* GetDisplayOptions */// not forever    0,                          /* SetDisplayOption */    0,                          /* GetScreenOptions */    0,                          /* SetScreenOption */    setDeps,    sizeof (setDeps) / sizeof (setDeps[0]),    BERYL_ABI_INFO};CompPluginVTable *getCompPluginInfo (void){    return &setVTable;}