rendered paste body[svn] / beryl-settings / trunk / src / main.c Project Root: cvssvnsvn: beryl-settings/trunk/src/main.cFile: [svn] / beryl-settings / trunk / src / main.c (download) (as text)Revision: 272, Tue Sep 26 16:08:28 2006 UTC (12 hours, 24 minutes ago) by cyberorgFile size: 81923 byte(s)Preparing for internationalisation, test french(partial) and portugese ones/* * Copyright (C) 2006 Quinn Storm <livinglatexkali@gmail.com> * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <gtk/gtk.h>#include <glib/gstdio.h>#define DBUS_API_SUBJECT_TO_CHANGE#include <dbus/dbus.h>#include <dbus/dbus-glib.h>#include <dbus/dbus-glib-lowlevel.h>#include <string.h>#include <malloc.h>#include <beryl.h>#include <stdlib.h>//locale stuff#include<libintl.h>#include<locale.h>#define _(String) gettext (String)#define gettext_noop(String) String#define N_(String) gettext_noop (String)typedef enum _SETOptionType{ SETString, SETColor, SETInt, SETBool, SETFloat, SETAction, SETList, SETMAX} SETOptionType;gchar * SETOptionTypes[]={ "string", "color", "int", "bool", "float", "action", "list",};typedef union _SETOptionValue SETOptionValue;union _SETOptionValue{ gchar * s; gint i; gdouble f; SETOptionValue * l; gint c[4]; gint a[6]; gboolean b;};typedef struct _SETNumericWidgets{ GtkSpinButton * s; GtkHScale * h;} SETNumericWidgets;gint nModifiers[]={ ShiftMask, ControlMask, CompAltMask, CompSuperMask, CompHyperMask, CompMetaMask, CompModeSwitchMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask,};gchar * modifiers[]={ "Shift", "Control", "Alt", "Super", "Hyper", "Meta", "Mode", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5",};#define NMODIFIERS (sizeof(modifiers)/sizeof(gchar *))#define MODROWS 2gchar * edges[]={ "Left", "Right", "Top", "Bottom", "Top-Left", "Top-Right", "Bottom-Left", "Bottom-Right",};// intuitive layout of edge checkboxes in the tablegint edgecols[]= { 0, 2, 1, 1, 0, 2, 0, 2,};gint edgerows[]= { 1, 1, 0, 2, 0, 0, 2, 2,};typedef struct _SETActionWidgets{ GtkCheckButton * kmod[NMODIFIERS]; // modifiers for key GtkEntry * key; // keysym(string in entrybox) GtkCheckButton * bmod[NMODIFIERS]; // modifiers for mouse button GtkEntry * but; // mouse button GtkCheckButton * b; // bell GtkCheckButton * e[SCREEN_EDGE_NUM]; // edges (checklist)} SETActionWidgets;typedef struct _SETStringListWidgets{ GtkListStore * backing; GtkTreeView * view; GtkButton * add; GtkButton * rem; GtkButton * bro; GtkButton * up; GtkButton * dn;} SETStringListWidgets;typedef struct _SETStringBrowseWidgets{ GtkEntry * e; GtkButton * b;} SETStringBrowseWidgets;typedef union _SETOptionWidgets{ GtkWidget * w; GtkCheckButton * b; SETStringBrowseWidgets sb; SETNumericWidgets n; SETActionWidgets a; GtkWidget ** l; SETStringListWidgets s;} SETOptionWidgets;typedef union _SETOptionRestrictions{ gchar ** s; // NULL terminated list of possible strings, NULL for anything goes gint i[2]; // min, max gdouble f[3]; // min, max, prec gboolean a[4]; // button, key, edge, bell} SETOptionRestrictions;typedef struct _SETOption{ gchar * name; gchar * section; gchar * sdesc; gchar * ldesc; SETOptionType type; SETOptionType listtype; SETOptionValue value; SETOptionValue defaultValue; SETOptionRestrictions rest; gchar ** hints; // NULL terminated list of hints gint nValue; gint nDValue; SETOptionWidgets widgets; gboolean defined;} SETOption;typedef struct _SETGroupWidget{ gchar * group; GtkWidget * widget; gboolean hasany;} SETGroupWidget;typedef struct _SETPage{ gchar * name; GtkWidget * widget;} SETPage;typedef struct _SETResetOption{ SETOption * o; gint resetType; // for action options, 0=button,1=key,2=edge,3=bell} SETResetOption;SETPage * SETOptionPages;GSList * SETOptions=NULL;GSList * reloadOptions=NULL;GKeyFile * schemaFile;GKeyFile * settingsFile;GtkListStore * pluginList;GtkTreeView * SETPluginList;GtkWidget * pluginContainer;GtkWidget * infoLabel;GtkWidget * infoContainer;gint nPages=0;gint nOthers=0;gchar ** oplugs=NULL;GtkWidget * mainWindow;static gboolean suspend_signals=FALSE;enum _SETPluginListEntry{ PluginName, ShortDesc, LongDesc, Markup, PluginIcon, PluginEnabled, PluginCanEnable, PluginEntryCount};DBusConnection *dbcon;void send_option_changed_signal(gchar * section, gchar * option){ DBusMessage * mesg; const char * sstring="section"; const char * ostring="option"; mesg = dbus_message_new_method_call("org.freedesktop.beryl", "/org/freedesktop/beryl/settings/allscreens/reload", "org.freedesktop.beryl","activate"); dbus_message_append_args(mesg, DBUS_TYPE_STRING,&sstring, DBUS_TYPE_STRING,§ion, DBUS_TYPE_STRING,&ostring, DBUS_TYPE_STRING,&option, DBUS_TYPE_INVALID); dbus_connection_send(dbcon,mesg,NULL); dbus_message_unref(mesg);}gboolean dequeue_sig(gpointer p){ if (reloadOptions) { SETOption * o = reloadOptions->data; reloadOptions=g_slist_remove_all(reloadOptions,o); send_option_changed_signal(o->section,o->name); } return TRUE;}void queue_option_changed(SETOption * o){ if (!g_slist_find(reloadOptions,o)) reloadOptions=g_slist_append(reloadOptions,o);}void import_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);}void load_schema_files(){ GDir * d; gchar * dpos; gchar * temp1; settingsFile = g_key_file_new(); temp1=g_strconcat(g_get_home_dir(),"/.beryl/settings",NULL); g_key_file_load_from_file(settingsFile,temp1,0,NULL); g_free(temp1); schemaFile = g_key_file_new(); import_key_file(schemaFile,DATADIR "/beryl/settings"); import_key_file(schemaFile,DATADIR "/beryl/hints"); 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(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(schemaFile,xfile); g_free(xfile); } } g_dir_close(d); } g_free(dpos);}SETOptionType string_to_type(gchar * optype){ gint i; for (i=0;i<SETMAX;i++) { if (strcmp(SETOptionTypes[i],optype)==0) return i; } return SETMAX;}void free_option_value(SETOption * o){ if (o->type == SETString) { if (o->value.s) g_free(o->value.s); o->value.s=NULL; } if (o->type == SETList && o->value.l) { gint i; if (o->listtype==SETString) for(i=0;i<o->nValue;i++) { if (o->value.l[i].s) g_free(o->value.l[i].s); } free(o->value.l); o->value.l=NULL; o->nValue=0; }}void copy_option_from_default(SETOption * o){ memcpy(&o->value,&o->defaultValue,sizeof(SETOptionValue)); if (o->type == SETString) o->value.s=g_strdup(o->defaultValue.s); if (o->type == SETList) { gint i; o->nValue=o->nDValue; if (o->nValue) { o->value.l=malloc(sizeof(SETOptionValue)*o->nValue); memcpy(o->value.l,o->defaultValue.l,sizeof(SETOptionValue)*o->nValue); if (o->listtype==SETString) for(i=0;i<o->nValue;i++) o->value.l[i].s=g_strdup(o->defaultValue.l[i].s); } }}void load_option(SETOption *o, gboolean dfl){ gchar * dkey = dfl?g_strconcat("d_",o->name,NULL):g_strdup(o->name); SETOptionValue * v = dfl?(&o->defaultValue):(&o->value); GKeyFile * f = dfl?schemaFile:settingsFile; GError * e = NULL; gint * nv = dfl?(&o->nDValue):(&o->nValue); gboolean useDfl=FALSE; if (!dfl) free_option_value(o); // default values never need freed :-P switch(o->type) { case SETString: { gchar * s; s=g_key_file_get_string(f,o->section,dkey,NULL); if (!s) { useDfl=TRUE; break; } if (o->rest.s && !dfl) { gboolean allowed=FALSE; gchar * e; gint i; for (i=0;(e=o->rest.s[i]);i++) { if (strcmp(e,s)==0) allowed=TRUE; } if (!allowed) { g_free(s); s=g_strdup(o->defaultValue.s); } if (o->value.s) g_free(o->value.s); v->s=s; } else v->s=s; } break; case SETBool: { gboolean b; b=g_key_file_get_boolean(f,o->section,dkey,&e); if (e) { useDfl=TRUE; break; } v->b=b; } break; case SETInt: { gint i; i=g_key_file_get_integer(f,o->section,dkey,&e); if (e) { useDfl=TRUE; break; } v->i=MAX(i,o->rest.i[0]); v->i=MIN(v->i,o->rest.i[1]); } break; case SETFloat: { gchar * s; gdouble fl; s=g_key_file_get_string(f,o->section,dkey,NULL); if (!s) { useDfl=TRUE; break; } fl=g_ascii_strtod(s,NULL); g_free(s); v->f=MAX(fl,o->rest.f[0]); v->f=MIN(v->f,o->rest.f[1]); //not bothering with prec for right now. } break; case SETColor: { gint * i; gsize l=0; i=g_key_file_get_integer_list(f,o->section,dkey,&l,&e); if (e || l!=4) { if (!e) g_free(i); useDfl=TRUE; break; } v->c[0]=i[0]; v->c[1]=i[1]; v->c[2]=i[2]; v->c[3]=i[3]; if (!e && l==4) g_free(i); } break; case SETAction: { gint * i; gsize l=0; i=g_key_file_get_integer_list(f,o->section,dkey,&l,&e); if (e || l!=6) { if (!e) g_free(i); useDfl=TRUE; break; } v->a[0]=i[0]; v->a[1]=i[1]; v->a[2]=i[2]; v->a[3]=i[3]; v->a[4]=i[4]; v->a[5]=i[5]; if (!e && l==6) g_free(i); } break; case SETList: { gsize l=0; switch(o->listtype) { case SETString: { gint i; gchar ** s=g_key_file_get_string_list(f,o->section,dkey,&l,&e); if (e) { useDfl=TRUE; break; } //prune invalid values from s if (o->rest.s) { for (i=0;i<l && s[i];i++) { gchar * e; gint j; gboolean keep=FALSE; for (j=0;(e=o->rest.s[j]);j++) { if (strcmp(s[i],e)==0) keep=TRUE; } if (!keep) { g_free(s[i]); // I think this is ok memmove(s+i,s+i+1, sizeof(gchar *)*(l-i)); // one beyond l for the NULL l--; i--; } } } *nv=l; if (l) v->l=malloc(l*sizeof(SETOptionValue)); else v->l=NULL; for (i=0;i<l;i++) { v->l[i].s=g_strdup(s[i]); } g_strfreev(s); } break; case SETBool: { gint i; gboolean * b; b=g_key_file_get_boolean_list(f,o->section,dkey,&l,&e); if (e) { useDfl=TRUE; break; } *nv=l; if (l) v->l=malloc(sizeof(SETOptionValue)*l); else v->l=NULL; for (i=0;i<l;i++) { v->l[i].b=b[i]; } g_free(b); } case SETInt: { gint i; gint * b; b=g_key_file_get_integer_list(f,o->section,dkey,&l,&e); if (e) { useDfl=TRUE; break; } *nv=l; if (l) v->l=malloc(sizeof(SETOptionValue)*l); else v->l=NULL; for (i=0;i<l;i++) { v->l[i].i=b[i]; } g_free(b); } break; case SETFloat: { gint i; gchar ** s; s=g_key_file_get_string_list(f,o->section,dkey,&l,&e); if (e) { useDfl=TRUE; break; } *nv=l; if (l) v->l=malloc(sizeof(SETOptionValue)*l); else v->l=NULL; for (i=0;i<l;i++) { v->l[i].f=g_ascii_strtod(s[i],NULL); } g_strfreev(s); } break; case SETColor: { gint i; gint * b; b=g_key_file_get_integer_list(schemaFile,o->section,o->name,&l,&e); if (e || l%4!=0) { useDfl=TRUE; break; } *nv=l/4; if (l/4) v->l=malloc(sizeof(SETOptionValue)*l/4); else v->l=NULL; for (i=0;i<l/4;i++) { v->l[i].c[0]=b[i*4]; v->l[i].c[1]=b[i*4+1]; v->l[i].c[2]=b[i*4+2]; v->l[i].c[3]=b[i*4+3]; } g_free(b); } break; case SETAction: { gint i; gint * b; b=g_key_file_get_integer_list(f,o->section,dkey,&l,&e); if (e || l%6!=0) { useDfl=TRUE; break; } *nv=l/6; if (l/6) v->l=malloc(sizeof(SETOptionValue)*l/6); else v->l=NULL; for (i=0;i<l/6;i++) { v->l[i].a[0]=b[i*6]; v->l[i].a[1]=b[i*6+1]; v->l[i].a[2]=b[i*6+2]; v->l[i].a[3]=b[i*6+3]; v->l[i].a[4]=b[i*6+4]; v->l[i].a[5]=b[i*6+5]; } g_free(b); } break; default: g_error("invalid t_ for %s",o->name); } } break; default: g_error("invalid o_ for %s",o->name); } if (useDfl && dfl) g_error("no d_ for %s",o->name); else if (useDfl) copy_option_from_default(o); g_free(dkey);}void init_option(gchar * group, gchar * option){ SETOption * o; gchar * val; gchar * key; gboolean screen; if (g_str_has_prefix(option,"s_")) screen=TRUE; else if (g_str_has_prefix(option,"a_")) screen=FALSE; else return; o = malloc(sizeof(SETOption)); bzero(o,sizeof(SETOption)); o->name = g_strdup(option); o->section=g_strdup(group); key = g_strconcat("h_",option,NULL); o->hints = g_key_file_get_string_list(schemaFile,o->section,key,NULL,NULL); g_free(key); key = g_strconcat("o_",option,NULL); val = g_key_file_get_string(schemaFile,group,key,NULL); if (!val) g_error("missing o_ for %s",option); // SHOULD be impossible o->type = string_to_type(val); g_free(val); g_free(key); key=g_strconcat("n_",option,NULL); val = g_key_file_get_string(schemaFile,group,key,NULL); if (!val) g_warning("missing n_ for %s",option); else o->sdesc=val; g_free(key); key=g_strconcat("l_",option,NULL); val = g_key_file_get_string(schemaFile,group,key,NULL); if (!val) g_warning("missing l_ for %s",option); else o->ldesc = val; g_free(key); if (o->type==SETList) { key=g_strconcat("t_",option,NULL); val=g_key_file_get_string(schemaFile,group,key,NULL); if (!val) g_error("list option with no t_ %s",option); o->listtype=string_to_type(val); g_free(val); g_free(key); } if (o->type==SETString || (o->type==SETList && o->listtype==SETString)) { key=g_strconcat("s_",option,NULL); o->rest.s=g_key_file_get_string_list(schemaFile,group,key,NULL,NULL); g_free(key); } else if (o->type==SETInt) { gint * i; gsize l; GError * e = NULL; key=g_strconcat("s_",option,NULL); i=g_key_file_get_integer_list(schemaFile,group,key,&l,&e); if (!e && l==2) { o->rest.i[0]=i[0]; o->rest.i[1]=i[1]; } else { g_error("int option with no or invalid s_ %s",option); } } else if (o->type==SETFloat) { gchar ** s; gsize l; GError * e = NULL; key=g_strconcat("s_",option,NULL); s=g_key_file_get_string_list(schemaFile,group,key,&l,&e); if (s) { if (!e && l==3) { o->rest.f[0]=g_ascii_strtod(s[0],NULL); o->rest.f[1]=g_ascii_strtod(s[1],NULL); o->rest.f[2]=g_ascii_strtod(s[2],NULL); } else g_error ("float option with no or invalid s_ %s",option); g_strfreev(s); } else g_error ("float option with no or invalid s_ %s",option); } else if (o->type==SETAction) { gboolean * b; gsize l; GError * e = NULL; key=g_strconcat("s_",option,NULL); b=g_key_file_get_boolean_list(schemaFile,group,key,&l,&e); if (!e && l==4) { o->rest.a[0]=b[0]; o->rest.a[1]=b[1]; o->rest.a[2]=b[2]; o->rest.a[3]=b[3]; } else g_error("action option with no or invalid s_ %s",option); } load_option(o,TRUE); // load defaults load_option(o,FALSE); SETOptions=g_slist_append(SETOptions,o);}void load_options_for(gchar * group){ gsize nKeys; gint i; gchar ** keys = g_key_file_get_keys(schemaFile,group,&nKeys,NULL); for (i=0;i<nKeys;i++) { if (g_str_has_prefix(keys[i],"o_")) { init_option(group,keys[i]+2); } } g_strfreev(keys);}void save_option(SETOption * o){ gint i; gchar fb[G_ASCII_DTOSTR_BUF_SIZE]; gchar * fn; switch(o->type) { case SETBool: g_key_file_set_boolean(settingsFile,o->section,o->name,o->value.b); break; case SETInt: g_key_file_set_integer(settingsFile,o->section,o->name,o->value.i); break; case SETString: g_key_file_set_string(settingsFile,o->section,o->name,o->value.s); break; case SETColor: g_key_file_set_integer_list(settingsFile,o->section,o->name,o->value.c,4); break; case SETAction: g_key_file_set_integer_list(settingsFile,o->section,o->name,o->value.a,6); break; case SETFloat: g_ascii_dtostr(fb,G_ASCII_DTOSTR_BUF_SIZE,o->value.f); g_key_file_set_string(settingsFile,o->section,o->name,fb); break; case SETList: switch(o->listtype) { case SETBool: { gboolean * b = malloc(sizeof(gboolean)*o->nValue); for(i=0;i<o->nValue;i++) b[i]=o->value.l[i].b; g_key_file_set_boolean_list(settingsFile,o->section,o->name,b,o->nValue); free(b); } break; case SETInt: { gint * b = malloc(sizeof(gint)*o->nValue); for(i=0;i<o->nValue;i++) b[i]=o->value.l[i].i; g_key_file_set_integer_list(settingsFile,o->section,o->name,b,o->nValue); free(b); } break; case SETColor: { gint * b = malloc(sizeof(gint)*o->nValue*4); for(i=0;i<o->nValue;i++) { b[i*4]=o->value.l[i].c[0]; b[i*4+1]=o->value.l[i].c[1]; b[i*4+2]=o->value.l[i].c[2]; b[i*4+3]=o->value.l[i].c[3]; } g_key_file_set_integer_list(settingsFile,o->section,o->name,b,o->nValue*4); free(b); } break; case SETAction: { gint * b = malloc(sizeof(gint)*o->nValue*6); for(i=0;i<o->nValue;i++) { b[i*6]=o->value.l[i].a[0]; b[i*6+1]=o->value.l[i].a[1]; b[i*6+2]=o->value.l[i].a[2]; b[i*6+3]=o->value.l[i].a[3]; b[i*6+4]=o->value.l[i].a[4]; b[i*6+5]=o->value.l[i].a[5]; } g_key_file_set_integer_list(settingsFile,o->section,o->name,b,o->nValue*6); free(b); } break; case SETString: { gchar ** s = malloc(sizeof(gchar *)*o->nValue); for(i=0;i<o->nValue;i++) s[i]=o->value.l[i].s; g_key_file_set_string_list(settingsFile,o->section,o->name,(const gchar **)s,o->nValue); free(s); } break; case SETFloat: { gchar ** s = malloc(sizeof(gchar)*o->nValue); for(i=0;i<o->nValue;i++) { s[i]=malloc(G_ASCII_DTOSTR_BUF_SIZE); g_ascii_dtostr(s[i],G_ASCII_DTOSTR_BUF_SIZE,o->value.l[i].f); } g_key_file_set_string_list(settingsFile,o->section,o->name,(const gchar **)s,o->nValue); for(i=0;i<o->nValue;i++) free(s[i]); free(s); } break; default: g_error("Bad list type"); } break; default: g_error("invalid type in save option."); } fn = g_strconcat(g_get_home_dir(),"/.beryl/settings",NULL); g_file_set_contents(fn,g_key_file_to_data(settingsFile,NULL,NULL),-1,NULL); queue_option_changed(o);}void cb_option(GtkWidget * w, SETOption * o){ if (suspend_signals) return; switch(o->type) { case SETBool: if (o->value.b==gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o->widgets.b))) return; o->value.b=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o->widgets.b)); break; case SETInt: case SETFloat: { gdouble f; if (GTK_WIDGET(w)==GTK_WIDGET(o->widgets.n.s)) { f=gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); } else { f=gtk_range_get_value(GTK_RANGE(w)); } if (o->type==SETInt) { if ((gint)f==o->value.i) return; o->value.i=(gint)f; } else { if (f==o->value.f) return; o->value.f=f; } gtk_range_set_value(GTK_RANGE(o->widgets.n.h),f); gtk_spin_button_set_value(GTK_SPIN_BUTTON(o->widgets.n.s),f); } break; case SETString: { const gchar * s; if (o->rest.s && o->rest.s[0]) s = gtk_combo_box_get_active_text(GTK_COMBO_BOX(o->widgets.w)); else s = gtk_entry_get_text(GTK_ENTRY(o->widgets.w)); if (strcmp(s,o->value.s)==0) return; o->value.s=g_strdup(s); } break; case SETColor: { GdkColor c; gint a; gtk_color_button_get_color(GTK_COLOR_BUTTON(o->widgets.w),&c); a=gtk_color_button_get_alpha(GTK_COLOR_BUTTON(o->widgets.w)); if (c.red!=o->value.c[0] || c.green!=o->value.c[1] || c.blue!=o->value.c[2] || a!=o->value.c[3]) { o->value.c[0]=c.red; o->value.c[1]=c.green; o->value.c[2]=c.blue; o->value.c[3]=a; } else return; } break; case SETAction: { gint a[6]={0,0,0,0,0,0}; gint i; if (o->rest.a[0]) { a[0]=0; for(i=0;i<NMODIFIERS;i++) if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o->widgets.a.bmod[i]))) a[0]|=nModifiers[i]; a[1]=atoi(gtk_entry_get_text(GTK_ENTRY(o->widgets.a.but))); } if (o->rest.a[1]) { a[2]=0; for(i=0;i<NMODIFIERS;i++) if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o->widgets.a.kmod[i]))) a[2]|=nModifiers[i]; a[3]=XStringToKeysym(gtk_entry_get_text(GTK_ENTRY(o->widgets.a.key))); if (a[3]==NoSymbol) a[3]=0; } if (o->rest.a[2]) { a[4]=0; for(i=0;i<SCREEN_EDGE_NUM;i++) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o->widgets.a.e[i]))) a[4]|=1<<i; } } if (o->rest.a[3]) { a[5]=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o->widgets.a.b))?1:0; } if ((!o->rest.a[0] || (o->value.a[0]==a[0] && o->value.a[1]==a[1])) && (!o->rest.a[1] || (o->value.a[2]==a[2] && o->value.a[3]==a[3])) && (!o->rest.a[2] || o->value.a[4]==a[4]) && (!o->rest.a[3] || o->value.a[5]==a[5])) return; for (i=0;i<6;i++) o->value.a[i]=a[i]; } break; case SETList: { if (o->listtype==SETString && o->rest.s && o->rest.s[0]) { //multiple-choice gint i; gint ns=0; gchar ** s; i=0; while(o->rest.s[i]) i++; s=malloc(sizeof(gchar *)*i); for (i=0;o->rest.s[i];i++) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(o->widgets.l[i]))) s[ns++]=o->rest.s[i]; } for (i=0;i<o->nValue;i++) g_free(o->value.l[i].s); free(o->value.l); o->value.l=malloc(sizeof(SETOptionValue)*ns); o->nValue=ns; for (i=0;i<ns;i++) o->value.l[i].s=g_strdup(s[i]); free(s); //that should work } } break; default: g_warning("Unhandled type for %s",o->name); } save_option(o);}void set_info_pane(GtkWidget * w, gchar * labelMarkup){ if (strcmp(labelMarkup,"")==0) { gtk_widget_hide(infoContainer); } else { gtk_window_set_resizable(GTK_WINDOW(mainWindow),FALSE); gtk_label_set_markup(GTK_LABEL(infoLabel),labelMarkup); gtk_widget_show_all(infoContainer); gtk_window_set_resizable(GTK_WINDOW(mainWindow),TRUE); }}gchar * getmark(SETOption * o){ return g_markup_printf_escaped( "<b>%s</b>\n" "<small><i>(%s/%s)</i></small>\n" "<small>%s</small>", o->sdesc, o->section, o->name+2, o->ldesc );}GtkWidget * my_label_new(gchar * t){ GtkWidget * w = gtk_label_new(t); gtk_misc_set_alignment(GTK_MISC(w),0,0); return w;}void set_widgets_from_option(SETOption * o){ suspend_signals=TRUE; switch(o->type) { case SETBool: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(o->widgets.w),o->value.b); break; case SETString: if (o->rest.s && o->rest.s[0]) { gint i; for (i=0;o->rest.s[i];i++) { if (strcmp(o->rest.s[i],o->value.s)==0) gtk_combo_box_set_active(GTK_COMBO_BOX(o->widgets.w),i); } } else gtk_entry_set_text(GTK_ENTRY(o->widgets.w),o->value.s); break; case SETInt: case SETFloat: gtk_range_set_value(GTK_RANGE(o->widgets.n.h), (o->type==SETInt?o->value.i:o->value.f)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(o->widgets.n.s), (o->type==SETInt?o->value.i:o->value.f)); break; case SETColor: { GdkColor c; c.red=o->value.c[0]; c.green=o->value.c[1]; c.blue=o->value.c[2]; gtk_color_button_set_color(GTK_COLOR_BUTTON(o->widgets.w),&c); gtk_color_button_set_alpha(GTK_COLOR_BUTTON(o->widgets.w), o->value.c[3]); } break; case SETAction: if (o->rest.a[0]) { gint i; for(i=0;i<NMODIFIERS;i++) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(o->widgets.a.bmod[i]), (o->value.a[0] & nModifiers[i])); } gtk_entry_set_text(GTK_ENTRY(o->widgets.a.but),o->value.a[1]? g_strdup_printf("%d",o->value.a[1]):"Disabled"); } if (o->rest.a[1]) { gint i; gchar * s; for(i=0;i<NMODIFIERS;i++) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(o->widgets.a.kmod[i]), (o->value.a[2] & nModifiers[i])); } s=XKeysymToString(o->value.a[3]); if (!s) { o->value.a[2]=0; s="Disabled"; } gtk_entry_set_text(GTK_ENTRY(o->widgets.a.key),s); } if (o->rest.a[2]) { gint i; for (i=0;i<SCREEN_EDGE_NUM;i++) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(o->widgets.a.e[i]) ,(o->value.a[4]&(1<<i))?TRUE:FALSE); } } if (o->rest.a[3]) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(o->widgets.a.b),o->value.a[5]); } break; case SETList: if (o->listtype==SETString && o->rest.s && o->rest.s[0]) { gint i,j; for (i=0;o->rest.s[i];i++) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(o->widgets.l[i]),FALSE); for (j=0;j<o->nValue;j++) { if (strcmp(o->value.l[j].s,o->rest.s[i])==0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(o->widgets.l[i]),TRUE); } } } else if (o->listtype==SETString) { gint i; gtk_list_store_clear(o->widgets.s.backing); for (i=0;i<o->nValue;i++) { GtkTreeIter it; gtk_list_store_append(o->widgets.s.backing,&it); gtk_list_store_set(o->widgets.s.backing,&it,0,o->value.l[i].s,-1); } } default: break; } suspend_signals=FALSE;}void reset_option(GtkWidget * but, SETResetOption * ro){ SETOption * o = ro->o; if (o->type==SETAction) { switch(ro->resetType) { case 0: o->value.a[0]=o->defaultValue.a[0]; o->value.a[1]=o->defaultValue.a[1]; break; case 1: o->value.a[2]=o->defaultValue.a[2]; o->value.a[3]=o->defaultValue.a[3]; break; case 2: o->value.a[4]=o->defaultValue.a[4]; break; case 3: o->value.a[5]=o->defaultValue.a[5]; break; } } else copy_option_from_default(o); set_widgets_from_option(o); save_option(o);}gboolean has_hint(SETOption * o, const gchar * hint){ gint i; for (i=0;o->hints && o->hints[i];i++) { if (strcmp(o->hints[i],hint)==0) return TRUE; } return FALSE;} static voidcb_preview (GtkFileChooser *file_chooser, gpointer data){ GtkWidget *preview; char *filename; GdkPixbuf *pixbuf; gboolean have_preview; preview = GTK_WIDGET (data); filename = gtk_file_chooser_get_preview_filename (file_chooser); pixbuf = NULL; have_preview = FALSE; if (filename) { pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL); have_preview = (pixbuf != NULL); g_free (filename); if (pixbuf) gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf); } if (pixbuf) g_object_unref (pixbuf); gtk_file_chooser_set_preview_widget_active (file_chooser, have_preview);}void modify_sl(SETOption * o){ //re-write the o->nValue/o->value.l based on o->widgets.s.backing gint i; GtkTreeIter it; if (suspend_signals) return; if (o->nValue) { for (i=0;i<o->nValue;i++) { g_free(o->value.l[i].s); } free(o->value.l); } //now we have to figure out how many rows... o->nValue=gtk_tree_model_iter_n_children(GTK_TREE_MODEL(o->widgets.s.backing),NULL); if (o->nValue) { o->value.l=malloc(sizeof(SETOptionValue)*o->nValue); for (i=0;i<o->nValue;i++) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(o->widgets.s.backing),&it,NULL,i); gtk_tree_model_get(GTK_TREE_MODEL(o->widgets.s.backing),&it,0,&o->value.l[i].s,-1); } } else { o->value.l=NULL; } save_option(o);}void cb_browse(GtkWidget * w, SETOption * o){ //make up a file widget GtkWidget * fd; gchar * titl=g_strconcat(_("Browse for "),o->sdesc,NULL); fd = gtk_file_chooser_dialog_new(titl,GTK_WINDOW(mainWindow), has_hint(o,"directory")?GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,NULL); g_free(titl); if (has_hint(o,"image")) { GtkFileFilter * f; GtkWidget * pr; f = gtk_file_filter_new(); if (has_hint(o,"pngonly")) { gtk_file_filter_set_name(f,"PNG Images"); } else { gtk_file_filter_set_name(f,_("Beryl Image Types (PNG,SVG)")); gtk_file_filter_add_mime_type(f,"image/svg"); gtk_file_filter_add_pattern(f,"*.svg"); gtk_file_filter_add_pattern(f,"*.SVG"); } gtk_file_filter_add_mime_type(f,"image/png"); gtk_file_filter_add_pattern(f,"*.png"); gtk_file_filter_add_pattern(f,"*.PNG"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fd),f); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fd),f); pr = gtk_image_new(); gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(fd),pr); g_signal_connect(fd,_("update-preview"),G_CALLBACK(cb_preview),pr); } if (o->type == SETString) if (g_file_test(gtk_entry_get_text(o->widgets.sb.e),G_FILE_TEST_EXISTS)) gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fd),gtk_entry_get_text(o->widgets.sb.e)); if (gtk_dialog_run(GTK_DIALOG(fd))==GTK_RESPONSE_ACCEPT) { gchar * s; s=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fd)); if (o->type == SETString) gtk_entry_set_text(o->widgets.sb.e,s); else { GtkTreeIter it; GtkTreeSelection * se = gtk_tree_view_get_selection(o->widgets.s.view); if (suspend_signals) return; gtk_tree_selection_unselect_all(se); gtk_list_store_append(o->widgets.s.backing,&it); gtk_list_store_set(o->widgets.s.backing,&it,0,s,-1); gtk_tree_selection_select_iter(se,&it); modify_sl(o); } g_free(s); } gtk_widget_destroy(fd);}GtkWidget * make_info_button_full(SETOption * o,gint rt){ GtkWidget * but; GtkWidget * img; GtkWidget * hb; SETResetOption * ro = malloc(sizeof(SETResetOption)); gboolean str=((o->type==SETAction && rt!=3) || o->type==SETList); if (str) hb = gtk_vbox_new(FALSE,2); else hb = gtk_hbox_new(TRUE,2); but = gtk_button_new(); img = gtk_image_new_from_stock(GTK_STOCK_INFO,GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER(but),img); g_signal_connect(but,"clicked",G_CALLBACK(set_info_pane),getmark(o)); gtk_box_pack_start(GTK_BOX(hb),but,str,str,0); but = gtk_button_new(); img = gtk_image_new_from_stock(GTK_STOCK_CLEAR,GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER(but),img); ro->o=o; ro->resetType=rt; g_signal_connect(but,"clicked",G_CALLBACK(reset_option),ro); gtk_box_pack_start(GTK_BOX(hb),but,str,str,0); return hb;}GtkWidget * make_info_button(SETOption * o){ return make_info_button_full(o,0);}void do_if_toggle_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if (o->type==SETBool && strcmp(o->section,w->group)==0) { GtkWidget * cbox; GtkWidget * box; box = gtk_hbox_new(FALSE,2); cbox = gtk_check_button_new_with_label(o->sdesc); gtk_box_pack_start(GTK_BOX(w->widget),box,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(box),make_info_button(o),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(box),cbox,TRUE,TRUE,0); o->widgets.w=cbox; g_signal_connect(cbox,"toggled",G_CALLBACK(cb_option),o); o->defined=TRUE; set_widgets_from_option(o); w->hasany=TRUE; }}void do_if_numeric_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if ((o->type==SETInt || o->type==SETFloat) && strcmp(o->section,w->group)==0) { GtkWidget * slid; GtkWidget * spun; GtkWidget * box; GtkWidget * slidbox; gdouble min = (o->type==SETInt?o->rest.i[0]:o->rest.f[0]); gdouble max = (o->type==SETInt?o->rest.i[1]:o->rest.f[1]); gdouble pre = (o->type==SETInt?1:o->rest.f[2]); slid = gtk_hscale_new_with_range(min,max,pre); spun = gtk_spin_button_new_with_range(min,max,pre); box = gtk_hbox_new(FALSE,2); slidbox = gtk_vbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(w->widget),box,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(box),make_info_button(o),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(box),slidbox,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(box),spun,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(slidbox),my_label_new(o->sdesc),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(slidbox),slid,FALSE,FALSE,0); o->widgets.n.h=GTK_HSCALE(slid); o->widgets.n.s=GTK_SPIN_BUTTON(spun); gtk_scale_set_draw_value(GTK_SCALE(slid),FALSE); gtk_range_set_update_policy(GTK_RANGE(slid),GTK_UPDATE_DISCONTINUOUS); gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spun),GTK_UPDATE_IF_VALID); g_signal_connect(slid,"value-changed",G_CALLBACK(cb_option),o); g_signal_connect(spun,"value-changed",G_CALLBACK(cb_option),o); o->defined=TRUE; set_widgets_from_option(o); w->hasany=TRUE; }}void do_if_string_choice_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if ((o->type==SETString) && strcmp(o->section,w->group)==0 && o->rest.s && o->rest.s[0]) { GtkWidget * hbox = gtk_hbox_new(FALSE,2); GtkWidget * vbox = gtk_vbox_new(FALSE,2); gint i; gtk_box_pack_start(GTK_BOX(w->widget),hbox,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),make_info_button(o),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),vbox,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(vbox),my_label_new(o->sdesc),FALSE,FALSE,0); o->widgets.w=gtk_combo_box_new_text(); for (i=0;o->rest.s[i];i++) { gtk_combo_box_append_text(GTK_COMBO_BOX(o->widgets.w),o->rest.s[i]); } set_widgets_from_option(o); g_signal_connect(o->widgets.w,"changed",G_CALLBACK(cb_option),o); gtk_box_pack_start(GTK_BOX(vbox),o->widgets.w,FALSE,FALSE,0); o->defined=TRUE; w->hasany=TRUE; }}void do_if_string_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if ((o->type==SETString) && strcmp(o->section,w->group)==0 && (!o->rest.s || !o->rest.s[0])) { GtkWidget * hbox = gtk_hbox_new(FALSE,2); GtkWidget * vbox = gtk_vbox_new(FALSE,2); GtkWidget * hbox2 = gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(w->widget),hbox,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),make_info_button(o),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),vbox,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(vbox),my_label_new(o->sdesc),FALSE,FALSE,0); o->widgets.w = gtk_entry_new(); if (!o->value.s) o->value.s=g_strdup(""); // wuh? set_widgets_from_option(o); g_signal_connect(o->widgets.w,"changed",G_CALLBACK(cb_option),o); gtk_box_pack_start(GTK_BOX(hbox2),o->widgets.w,TRUE,TRUE,0); if (has_hint(o,"file")) { o->widgets.sb.b=GTK_BUTTON(gtk_button_new_with_label(_("Browse"))); gtk_button_set_image(o->widgets.sb.b,gtk_image_new_from_stock(GTK_STOCK_OPEN,GTK_ICON_SIZE_BUTTON)); gtk_box_pack_start(GTK_BOX(hbox2),GTK_WIDGET(o->widgets.sb.b),FALSE,FALSE,0); g_signal_connect(o->widgets.sb.b,"clicked",G_CALLBACK(cb_browse),o); } gtk_box_pack_start(GTK_BOX(vbox),hbox2,FALSE,FALSE,0); o->defined=TRUE; w->hasany=TRUE; }}void do_if_color_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if ((o->type==SETColor) && strcmp(o->section,w->group)==0) { GtkWidget * hbox; GtkWidget * cbut; hbox = gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(w->widget),hbox,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),make_info_button(o),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),my_label_new(o->sdesc),TRUE,TRUE,0); cbut=gtk_color_button_new(); gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(cbut),TRUE); gtk_box_pack_start(GTK_BOX(hbox),cbut,FALSE,FALSE,0); o->widgets.w=cbut; g_signal_connect(cbut,"color-set",G_CALLBACK(cb_option),o); o->defined=TRUE; set_widgets_from_option(o); w->hasany=TRUE; }}void do_if_action_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if ((o->type==SETAction) && strcmp(o->section,w->group)==0) { if (!o->rest.a[0] && !o->rest.a[1] && !o->rest.a[2] && !o->rest.a[3]) { o->defined=TRUE; return; //these are dbus-only calls } o->defined=TRUE; w->hasany=TRUE; set_widgets_from_option(o); }}void do_if_bell_group(SETOption * o, SETGroupWidget * w){ if ((o->type==SETAction) && strcmp(o->section,w->group)==0) { if (o->rest.a[3]) { GtkWidget * hbox = gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(w->widget),hbox,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),make_info_button_full(o,3),FALSE,FALSE,0); o->widgets.a.b=GTK_CHECK_BUTTON(gtk_check_button_new_with_label( g_strconcat(o->sdesc," on System Bell",NULL))); gtk_box_pack_start(GTK_BOX(hbox),GTK_WIDGET(o->widgets.a.b),TRUE,TRUE,0); g_signal_connect(o->widgets.a.b,"toggled",G_CALLBACK(cb_option),o); w->hasany=TRUE; } }}void make_key_button_stuff(SETOption * o, SETGroupWidget * w, gint p){ GtkEntry * entry; GtkCheckButton ** mods; gint i; GtkWidget * tab; GtkWidget * vbox2; GtkWidget * hbox2; GtkWidget * hbox; GtkWidget * fram; if (p==1) mods=o->widgets.a.kmod; else mods=o->widgets.a.bmod; fram = gtk_frame_new(o->sdesc); gtk_box_pack_start(GTK_BOX(w->widget),fram,FALSE,FALSE,0); hbox = gtk_hbox_new(FALSE,2); gtk_container_add(GTK_CONTAINER(fram),hbox); gtk_box_pack_start(GTK_BOX(hbox),make_info_button_full(o,p),FALSE,FALSE,0); vbox2 = gtk_vbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(hbox),vbox2,TRUE,TRUE,0); entry = GTK_ENTRY(gtk_entry_new()); if (p==1) o->widgets.a.key=entry; else o->widgets.a.but=entry; gtk_entry_set_width_chars(entry,8); hbox2=gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(vbox2),hbox2,FALSE,FALSE,0); if (o->value.a[3]==0) o->value.a[2]=0; tab = gtk_table_new(0,0,FALSE); gtk_box_pack_start(GTK_BOX(hbox2),my_label_new(_("Modifier Keys:")),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox2),tab,TRUE,TRUE,0); for(i=0;i<NMODIFIERS;i++) { gint col = (i%(NMODIFIERS/MODROWS)); gint row = (i/(NMODIFIERS/MODROWS)); mods[i]=GTK_CHECK_BUTTON(gtk_check_button_new_with_label(modifiers[i])); g_signal_connect(mods[i],"toggled",G_CALLBACK(cb_option),o); gtk_table_attach_defaults(GTK_TABLE(tab),GTK_WIDGET(mods[i]), col,col+1,row,row+1); } hbox2=gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(vbox2),hbox2,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox2),gtk_label_new(p==1?_("Key Name:"):_("Button Number:")),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox2),GTK_WIDGET(entry),TRUE,TRUE,0); g_signal_connect(entry,"changed",G_CALLBACK(cb_option),o);}void do_if_key_group(SETOption * o, SETGroupWidget * w){ if ((o->type==SETAction) && strcmp(o->section,w->group)==0) { if (o->rest.a[1]) { make_key_button_stuff(o,w,1); w->hasany=TRUE; } }}void do_if_button_group(SETOption * o, SETGroupWidget * w){ if ((o->type==SETAction) && strcmp(o->section,w->group)==0) { if (o->rest.a[0]) { make_key_button_stuff(o,w,0); w->hasany=TRUE; } }}void do_if_edge_group(SETOption * o, SETGroupWidget * w){ if ((o->type==SETAction) && strcmp(o->section,w->group)==0) { if (o->rest.a[2]) { gint i; GtkWidget * fram2; GtkWidget * tab; GtkWidget * hbox; fram2=gtk_frame_new(o->sdesc); tab=gtk_table_new(0,0,FALSE); gtk_box_pack_start(GTK_BOX(w->widget),fram2,FALSE,FALSE,0); hbox = gtk_hbox_new(FALSE,2); gtk_container_add(GTK_CONTAINER(fram2),hbox); gtk_box_pack_start(GTK_BOX(hbox),make_info_button_full(o,2),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),tab,TRUE,TRUE,0); for (i=0;i<SCREEN_EDGE_NUM;i++) { o->widgets.a.e[i]=GTK_CHECK_BUTTON(gtk_check_button_new_with_label(edges[i])); gtk_table_attach_defaults(GTK_TABLE(tab),GTK_WIDGET(o->widgets.a.e[i]),edgecols[i],edgecols[i]+1,edgerows[i],edgerows[i]+1); g_signal_connect(o->widgets.a.e[i],"toggled",G_CALLBACK(cb_option),o); } w->hasany=TRUE; } }}#define OPT_PER_LINE 3void do_if_option_list_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if (strcmp(o->section,w->group)==0 && o->type==SETList && o->listtype==SETString && o->rest.s && o->rest.s[0]) { GtkWidget * hbox, *vbox, *tabl, *fram; gint i, l=-1, c=0; hbox = gtk_hbox_new(FALSE,2); fram = gtk_frame_new(o->sdesc); gtk_box_pack_start(GTK_BOX(w->widget),fram,FALSE,FALSE,0); gtk_container_add(GTK_CONTAINER(fram),hbox); gtk_box_pack_start(GTK_BOX(hbox),make_info_button(o),FALSE,FALSE,0); vbox = gtk_vbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(hbox),vbox,TRUE,TRUE,0); tabl=gtk_table_new(OPT_PER_LINE,1,TRUE); gtk_box_pack_start(GTK_BOX(vbox),tabl,FALSE,FALSE,0); i=0; while(o->rest.s[i]) i++; o->widgets.l=malloc(sizeof(GtkWidget *)*i); for (i=0;o->rest.s[i];i++) { GtkWidget * cbut; if (i%OPT_PER_LINE==0) { l++; c=0; } else c++; cbut = gtk_check_button_new_with_label(o->rest.s[i]); gtk_table_attach_defaults(GTK_TABLE(tabl),cbut,c,c+1,l,l+1); o->widgets.l[i]=cbut; g_signal_connect(cbut,"toggled",G_CALLBACK(cb_option),o); } set_widgets_from_option(o); o->defined=TRUE; w->hasany=TRUE; }}void cb_sl_edited(GtkWidget * w, gchar * treepath, gchar * value, SETOption * o){ GtkTreeIter it; if (suspend_signals) return; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(o->widgets.s.backing),&it,treepath); gtk_list_store_set(o->widgets.s.backing,&it,0,value,-1); //modify_sl(o);}void cb_sl_select(GtkTreeSelection * sel, SETOption * o){ GtkTreeIter it; GtkTreeModel * mod; gboolean p; p=gtk_tree_selection_get_selected(sel,&mod,&it); gtk_widget_set_sensitive(GTK_WIDGET(o->widgets.s.rem),p); gtk_widget_set_sensitive(GTK_WIDGET(o->widgets.s.up),p); gtk_widget_set_sensitive(GTK_WIDGET(o->widgets.s.dn),p);}void cb_sl_add(GtkWidget * w, SETOption * o){ GtkTreeIter it; GtkTreeSelection * s = gtk_tree_view_get_selection(o->widgets.s.view); if (suspend_signals) return; gtk_tree_selection_unselect_all(s); gtk_list_store_append(o->widgets.s.backing,&it); gtk_list_store_set(o->widgets.s.backing,&it,0,"<New Value>",-1); gtk_tree_selection_select_iter(s,&it);}void cb_sl_rem(GtkWidget * w, SETOption * o){ GtkTreeIter it; GtkTreeModel * mod; GtkTreeSelection * s = gtk_tree_view_get_selection(o->widgets.s.view); if (suspend_signals) return; if (gtk_tree_selection_get_selected(s,&mod,&it)) gtk_list_store_remove(GTK_LIST_STORE(mod),&it);}void cb_row_changed(GtkWidget * w, GtkTreePath * p, GtkTreeIter * i, SETOption *o){ if (suspend_signals) return; modify_sl(o);}void cb_row_del(GtkWidget * w, GtkTreePath * p, SETOption *o){ if (suspend_signals) return; modify_sl(o);}void move_item(SETOption * o, gboolean up){ GtkTreeIter it; GtkTreeModel * mod; GtkTreeSelection * s = gtk_tree_view_get_selection(o->widgets.s.view); if (suspend_signals) return; if (gtk_tree_selection_get_selected(s,&mod,&it)) { GtkTreeIter nit; if (up) { gchar * s = gtk_tree_model_get_string_from_iter(mod,&it); GtkTreePath * p = gtk_tree_path_new_from_string(s); g_free(s); if (!gtk_tree_path_prev(p)) { g_free(p); return; } s=gtk_tree_path_to_string(p); gtk_tree_model_get_iter_from_string(mod,&nit,s); g_free(s); } else { nit=it; if (!gtk_tree_model_iter_next(mod,&nit)) return; } gtk_list_store_swap(GTK_LIST_STORE(mod),&it,&nit); }}void cb_move_up(GtkWidget * w, SETOption * o){ move_item(o,TRUE);}void cb_move_dn(GtkWidget * w, SETOption * o){ move_item(o,FALSE);}void do_if_string_list_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if (strcmp(o->section,w->group)==0 && o->type==SETList && o->listtype==SETString && (!o->rest.s || !o->rest.s[0])) { GtkWidget * hbox; GtkCellRenderer * celr; GtkWidget * fram; GtkTreeViewColumn * col; GtkScrolledWindow * win; GtkWidget * vbox; if (strcmp(o->section,"_")==0 && strcmp(o->name,"a_active_plugins")==0) { o->defined=TRUE; return; } fram = gtk_frame_new(o->sdesc); hbox = gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(w->widget),fram,FALSE,FALSE,0); gtk_container_add(GTK_CONTAINER(fram),hbox); gtk_box_pack_start(GTK_BOX(hbox),make_info_button(o),FALSE,FALSE,0); o->widgets.s.backing=gtk_list_store_new(1,G_TYPE_STRING); celr = GTK_CELL_RENDERER(gtk_cell_renderer_text_new()); g_signal_connect(celr,"edited",G_CALLBACK(cb_sl_edited),o); g_object_set(celr,"editable",TRUE,NULL); col = gtk_tree_view_column_new_with_attributes(o->sdesc,GTK_CELL_RENDERER(celr),"text",0,NULL); o->widgets.s.view=GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(o->widgets.s.backing))); gtk_tree_view_set_reorderable(o->widgets.s.view,TRUE); gtk_tree_view_set_headers_visible(o->widgets.s.view,FALSE); gtk_tree_view_append_column(o->widgets.s.view,col); win = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL,NULL)); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(win),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(win),GTK_WIDGET(o->widgets.s.view)); gtk_box_pack_start(GTK_BOX(hbox),GTK_WIDGET(win),TRUE,TRUE,0); o->widgets.s.add=GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_ADD)); if (has_hint(o,"file")) { o->widgets.s.bro=GTK_BUTTON(gtk_button_new_with_label(_("Browse"))); gtk_button_set_image(o->widgets.s.bro,gtk_image_new_from_stock( GTK_STOCK_OPEN,GTK_ICON_SIZE_BUTTON)); g_signal_connect(o->widgets.s.bro,"clicked",G_CALLBACK(cb_browse),o); } o->widgets.s.rem=GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_DELETE)); vbox = gtk_vbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(hbox),vbox,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET( o->widgets.s.up=GTK_BUTTON(gtk_button_new())),FALSE,FALSE,0); gtk_box_pack_end(GTK_BOX(vbox),GTK_WIDGET( o->widgets.s.dn=GTK_BUTTON(gtk_button_new())),FALSE,FALSE,0); gtk_container_add(GTK_CONTAINER(o->widgets.s.up), gtk_image_new_from_stock(GTK_STOCK_GO_UP,GTK_ICON_SIZE_BUTTON)); gtk_container_add(GTK_CONTAINER(o->widgets.s.dn), gtk_image_new_from_stock(GTK_STOCK_GO_DOWN,GTK_ICON_SIZE_BUTTON)); gtk_widget_set_sensitive(GTK_WIDGET(o->widgets.s.rem),FALSE); gtk_widget_set_sensitive(GTK_WIDGET(o->widgets.s.up),FALSE); gtk_widget_set_sensitive(GTK_WIDGET(o->widgets.s.dn),FALSE); vbox = gtk_vbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(hbox),vbox,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(o->widgets.s.add),FALSE,FALSE,0); if (has_hint(o,"file")) gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(o->widgets.s.bro),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(o->widgets.s.rem),FALSE,FALSE,0); g_signal_connect(gtk_tree_view_get_selection(o->widgets.s.view),"changed", G_CALLBACK(cb_sl_select),o); g_signal_connect(o->widgets.s.add,"clicked",G_CALLBACK(cb_sl_add),o); g_signal_connect(o->widgets.s.rem,"clicked",G_CALLBACK(cb_sl_rem),o); g_signal_connect(o->widgets.s.up,"clicked",G_CALLBACK(cb_move_up),o); g_signal_connect(o->widgets.s.dn,"clicked",G_CALLBACK(cb_move_dn),o); gtk_tree_view_set_rules_hint(o->widgets.s.view,TRUE); set_widgets_from_option(o); g_signal_connect(o->widgets.s.backing,"row-changed",G_CALLBACK(cb_row_changed),o); g_signal_connect(o->widgets.s.backing,"row-inserted",G_CALLBACK(cb_row_changed),o); g_signal_connect(o->widgets.s.backing,"row-deleted",G_CALLBACK(cb_row_del),o); o->defined=TRUE; w->hasany=TRUE; }}void do_if_command_string_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if (has_hint(o,"command")) do_if_string_group(o,w);}void do_if_simple_string_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if (!has_hint(o,"file") && !has_hint(o,"command")) do_if_string_group(o,w);}void do_if_file_string_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if (has_hint(o,"file")) { do_if_string_group(o,w); do_if_string_list_group(o,w); }}void do_if_undefined_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; if (strcmp(o->section,w->group)==0 && !(o->defined)) { //undefined GtkWidget * hbox; hbox=gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(w->widget),hbox,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),make_info_button(o),FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),my_label_new(o->sdesc),TRUE,TRUE,0); o->widgets.w=hbox; w->hasany=TRUE; }}void do_if_choice_option_group(SETOption * o, SETGroupWidget * w){ if (o->defined) return; do_if_toggle_group(o,w); do_if_string_choice_group(o,w); do_if_option_list_group(o,w); do_if_bell_group(o,w);}void setup_actions(gchar * group){ SETGroupWidget z; z.group=group; z.widget=NULL; z.hasany=FALSE; g_slist_foreach(SETOptions,(GFunc)do_if_action_group,&z);}void do_page(gchar * group,GFunc func,gchar * label, GtkWidget * notebook){ SETGroupWidget z; GtkWidget * scrol = gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrol) ,GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); GtkWidget * vbox = gtk_vbox_new(FALSE,6); gtk_container_set_border_width(GTK_CONTAINER(vbox),4); z.group=group; z.widget=vbox; z.hasany=FALSE; g_slist_foreach(SETOptions,func,&z); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrol),vbox); if (z.hasany) gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrol,gtk_label_new(label));}void do_option_page(gchar * group, GtkWidget * notebook){ load_options_for(group); //okay now we can lay out a notebook gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook),TRUE); do_page(group,(GFunc)do_if_choice_option_group,_("Choices"),notebook); do_page(group,(GFunc)do_if_numeric_group,_("Numeric Values"),notebook); do_page(group,(GFunc)do_if_command_string_group,_("Commands"),notebook); do_page(group,(GFunc)do_if_simple_string_group,_("Strings"),notebook); do_page(group,(GFunc)do_if_file_string_group,_("Filenames"),notebook); do_page(group,(GFunc)do_if_color_group,_("Colors"),notebook); do_page(group,(GFunc)do_if_key_group,_("Keyboard"),notebook); do_page(group,(GFunc)do_if_button_group,_("Mouse"),notebook); do_page(group,(GFunc)do_if_edge_group,_("Screen Edges & Corners"),notebook); do_page(group,(GFunc)do_if_string_list_group,_("String Lists"),notebook); setup_actions(group); //gtk_notebook_append_page(GTK_NOTEBOOK(notebook), // do_page(group,(GFunc)do_if_undefined_group),gtk_label_new("Unhandled"));}void set_plugin_active(gchar * plugin,gboolean active){ GtkTreeIter it; gboolean k; for(k=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pluginList),&it);k; k=gtk_tree_model_iter_next(GTK_TREE_MODEL(pluginList),&it)) { gchar * pl; gtk_tree_model_get(GTK_TREE_MODEL(pluginList),&it,PluginName,&pl,-1); if (strcmp(pl,plugin)==0) gtk_list_store_set(pluginList,&it,PluginEnabled,active,-1); g_free(pl); }}gboolean get_plugin_active(gchar * plugin){ GtkTreeIter it; gboolean k,b; if (strcmp(plugin,"dbus")==0) return TRUE; if (strcmp(plugin,"settings")==0) return TRUE; b=FALSE; for(k=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pluginList),&it);k; k=gtk_tree_model_iter_next(GTK_TREE_MODEL(pluginList),&it)) { gchar * pl; gtk_tree_model_get(GTK_TREE_MODEL(pluginList),&it,PluginName,&pl,-1); if (strcmp(pl,plugin)==0) { gtk_tree_model_get(GTK_TREE_MODEL(pluginList),&it,PluginEnabled,&b,-1); } g_free(pl); } return b;}void doing_active_plugins(SETOption * o, gpointer p){ if (strcmp(o->name,"a_active_plugins")==0 && strcmp(o->section,"_")==0) { //o is of type list[string] gint i; for(i=0;i<o->nValue;i++) { //set the plugins active //by first finding them... GtkTreeIter it; gboolean k; for(k=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pluginList),&it);k; k=gtk_tree_model_iter_next(GTK_TREE_MODEL(pluginList),&it)) { gchar * pl; gtk_tree_model_get(GTK_TREE_MODEL(pluginList),&it,PluginName,&pl,-1); if (strcmp(pl,o->value.l[i].s)==0 || strcmp(pl,"_")==0) // yeah sets it more than once, I know gtk_list_store_set(pluginList,&it,PluginEnabled,TRUE,-1); if (strcmp(pl,"_")==0) gtk_list_store_set(pluginList,&it,PluginCanEnable,FALSE,-1); g_free(pl); } } }}void do_active_plugins(){ g_slist_foreach(SETOptions,(GFunc)doing_active_plugins,NULL);}void cb_showpage(GtkWidget * w, GtkWidget * p){ gint i; GtkTreeIter it; GtkTreeSelection * Select; Select=GTK_TREE_SELECTION(w); GtkTreeModel * mod; gchar * nam; if (gtk_bin_get_child(GTK_BIN(p))) { gtk_container_remove(GTK_CONTAINER(p),gtk_bin_get_child(GTK_BIN(p))); } if (gtk_tree_selection_get_selected(Select,&mod,&it)) { gtk_tree_model_get(mod,&it,PluginName,&nam,-1); } else return; if (!nam) return; for (i=0;i<nPages;i++) { if (strcmp(SETOptionPages[i].name,nam)==0) { gtk_container_add(GTK_CONTAINER(p),SETOptionPages[i].widget); gtk_widget_show_all(SETOptionPages[i].widget); return; } } g_free(nam);}void beryl_settings_deactivate_plugin(gchar * plugin);void beryl_settings_activate_plugin(gchar * plugin);void beryl_settings_deactivate_plugin(gchar * plugin){ gint i; for (i=0;i<nPages;i++) { gchar ** rq; gsize nrq; gint j; if (strcmp(SETOptionPages[i].name,"_")==0) continue; rq=g_key_file_get_string_list(schemaFile,SETOptionPages[i].name,"d_p_requires",&nrq,NULL); if (!rq) g_error("plugin %s has no d_p_requires",SETOptionPages[i].name); for (j=0;j<nrq;j++) { if (strcmp(rq[j],plugin)==0) beryl_settings_deactivate_plugin(SETOptionPages[i].name); } g_strfreev(rq); } set_plugin_active(plugin,FALSE);}void beryl_settings_activate_plugin(gchar * plugin){ //activate all the plugin's deps gchar ** rq; gsize nrq; gint i; if (strcmp(plugin,"dbus")==0) return; rq=g_key_file_get_string_list(schemaFile,plugin,"d_p_requires",&nrq,NULL); if (!rq) g_error("plugin %s has no d_p_requires",plugin); for (i=0;i<nrq;i++) beryl_settings_activate_plugin(rq[i]); g_strfreev(rq); set_plugin_active(plugin,TRUE);}void do_unlisted_plugins(){ gchar ** alist; gsize lal=0; gint i,j; gint sothers; alist=g_key_file_get_string_list(schemaFile,"_","h_a_active_plugins",&lal,NULL); if (!alist) g_error("can't find d_a_active_plugins"); //nPages should be = lal+others-2+1 //so, others=nPages-lal+2-1 //=nPages-lal+1 nOthers=nPages-lal+1; oplugs=malloc(sizeof(gchar *)*nOthers); sothers=0; for (i=0;i<nPages;i++) { gboolean found=FALSE; if (strcmp(SETOptionPages[i].name,"_")==0) continue; for(j=0;j<lal;j++) { if (strcmp(alist[j],SETOptionPages[i].name)==0) found=TRUE; } if (!found) oplugs[sothers++]=SETOptionPages[i].name; } g_strfreev(alist);}void cb_toggled(GtkCellRendererToggle * t, gchar * path, gpointer d){ GtkTreeIter it; gboolean b; gchar * pn; gsize lal; gint i; gchar ** alist; gchar ** blist; // append any plugins like bench to make this list GtkTreePath * p = gtk_tree_path_new_from_string(path); if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(pluginList),&it,p)) g_error("invalid toggle"); gtk_tree_path_free(p); gtk_tree_model_get(GTK_TREE_MODEL(pluginList),&it,PluginEnabled,&b,PluginName,&pn,-1); if (b) beryl_settings_deactivate_plugin(pn); else beryl_settings_activate_plugin(pn); g_free(pn); alist=g_key_file_get_string_list(schemaFile,"_","h_a_active_plugins",&lal,NULL); if (!alist) g_error("can't find d_a_active_plugins"); blist=malloc(sizeof(gchar*)*(lal+nOthers)); memcpy(blist,alist,sizeof(gchar *)*lal); blist[lal+nOthers-1]=blist[lal-1]; // move bench to the end for (i=0;i<nOthers;i++) { blist[i+lal-1]=oplugs[i]; } lal+=nOthers; for (i=0;i<lal;i++) { if (!get_plugin_active(blist[i])) { memmove(blist+i,blist+(i+1),sizeof(gchar *)*(lal-i-1)); i--; lal--; } } g_key_file_set_string_list(settingsFile,"_","a_active_plugins",(const gchar **)blist,lal); pn=g_strconcat(g_get_home_dir(),"/.beryl/settings",NULL); g_file_set_contents(pn,g_key_file_to_data(settingsFile,NULL,NULL),-1,NULL); free(blist); g_strfreev(alist); send_option_changed_signal("_","a_active_plugins");}void cb_main_destroy(GtkWidget * w, gpointer p){ gtk_main_quit();}void layout_main_window(){ GType SETPluginListTypes[]= { G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, }; GtkBox * box; GtkBox * ebox; GtkBox * bbox; GtkTreeViewColumn * col; GtkScrolledWindow * win; gchar ** groups; gint page; GtkCellRenderer * rend; gsize nGroups=0; gint i; ebox = GTK_BOX(gtk_vbox_new(FALSE,2)); box = GTK_BOX(gtk_hbox_new(FALSE,2)); gtk_box_pack_start(ebox,GTK_WIDGET(box),TRUE,TRUE,0); gtk_container_add(GTK_CONTAINER(mainWindow),GTK_WIDGET(ebox)); win = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL,NULL)); gtk_scrolled_window_set_policy(win,GTK_POLICY_NEVER,GTK_POLICY_AUTOMATIC); pluginList = gtk_list_store_newv(PluginEntryCount,SETPluginListTypes); SETPluginList = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(pluginList))); gtk_container_add(GTK_CONTAINER(win),GTK_WIDGET(SETPluginList)); gtk_tree_view_set_headers_visible(SETPluginList,FALSE); gtk_tree_view_set_rules_hint(SETPluginList,TRUE); rend = gtk_cell_renderer_pixbuf_new(); col = gtk_tree_view_column_new_with_attributes("Icon",rend,"pixbuf",PluginIcon,NULL); gtk_tree_view_append_column(SETPluginList,col); rend = gtk_cell_renderer_text_new(); g_object_set(G_OBJECT(rend),"wrap-mode",PANGO_WRAP_WORD,"wrap-width",160,NULL); col = gtk_tree_view_column_new_with_attributes("Name",rend, "markup",Markup,NULL); gtk_tree_view_append_column(SETPluginList,col); rend = gtk_cell_renderer_toggle_new(); //g_object_set(rend,"mode",GTK_CELL_RENDERER_MODE_EDITABLE,NULL); col = gtk_tree_view_column_new_with_attributes("Active",rend,"activatable",PluginCanEnable, "active",PluginEnabled,NULL); gtk_tree_view_append_column(SETPluginList,col); groups=g_key_file_get_groups(schemaFile,&nGroups); SETOptionPages = malloc(sizeof(SETPage)*nGroups-1); // dbus hack nPages=nGroups-1; page=0; for(i=0;i<nGroups;i++) { GtkTreeIter t; gchar * shortdesc; gchar * longdesc; gchar * mark; if (strcmp(groups[i],"dbus")==0) continue; GdkPixbuf * p; p = gdk_pixbuf_new_from_file(g_strconcat(PIXMAPS_DIR,"/beryl-settings-section-",groups[i],".png",NULL),NULL); if (!p) { gint w,h; gtk_icon_size_lookup(GTK_ICON_SIZE_LARGE_TOOLBAR,&w,&h); p = gdk_pixbuf_new_from_file_at_size(g_strconcat(PIXMAPS_DIR,"/beryl-settings-section-",groups[i],".svg",NULL), w,h,NULL); if (!p) p = gdk_pixbuf_new_from_file_at_size(DATADIR "/beryl/icon.png",w,h,NULL); } // p = gtk_widget_render_icon(GTK_WIDGET(SETPluginList),GTK_STOCK_MISSING_IMAGE, // GTK_ICON_SIZE_LARGE_TOOLBAR,"berylplugin"); //look up short & long desc in file //if its 'general', provide defaults shortdesc = g_key_file_get_string(schemaFile,groups[i],"n_p_info",NULL); if (!shortdesc) shortdesc = g_strdup(_("General Options")); longdesc = g_key_file_get_string(schemaFile,groups[i],"l_p_info",NULL); if (!longdesc) longdesc = g_strdup(_("Options for Beryl as a whole")); gtk_list_store_append(pluginList,&t); mark = g_markup_printf_escaped( "<b>%s</b>\n" "<small>[%s] <i>%s</i></small>", _(shortdesc),groups[i],_(longdesc)); gtk_list_store_set(pluginList,&t,PluginName,groups[i],ShortDesc,shortdesc, LongDesc,longdesc,Markup,mark,PluginIcon,p,PluginEnabled,FALSE,PluginCanEnable,TRUE,-1); g_free(mark); g_free(shortdesc); g_free(longdesc); SETOptionPages[page].name=g_strdup(groups[i]); SETOptionPages[page].widget=gtk_notebook_new(); g_object_ref(SETOptionPages[page].widget); do_option_page(groups[i],SETOptionPages[page].widget); page++; } g_strfreev(groups); do_unlisted_plugins(); gtk_box_pack_start(box,GTK_WIDGET(win),FALSE,FALSE,0); gtk_box_pack_start(box,gtk_vseparator_new(),FALSE,FALSE,0); pluginContainer = gtk_alignment_new(0,0,1,1); gtk_container_add(GTK_CONTAINER(pluginContainer),SETOptionPages[0].widget); { GtkWidget * vbox, *hbox; GtkWidget * but; GtkWidget * win; vbox = gtk_vbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(pluginContainer),TRUE,TRUE,0); infoLabel=gtk_label_new(""); hbox = gtk_hbox_new(FALSE,2); infoContainer=hbox; g_object_ref(hbox); gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0); but=gtk_button_new_with_label(_("Hide")); gtk_button_set_image(GTK_BUTTON(but), gtk_image_new_from_stock(GTK_STOCK_CLOSE,GTK_ICON_SIZE_BUTTON)); g_signal_connect(but,"clicked",G_CALLBACK(set_info_pane),""); win = gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(win),infoLabel); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(win), GTK_POLICY_AUTOMATIC,GTK_POLICY_NEVER); gtk_box_pack_start(GTK_BOX(hbox),but,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(hbox),win,TRUE,TRUE,0); gtk_box_pack_start(box,GTK_WIDGET(vbox),TRUE,TRUE,0); gtk_misc_set_alignment(GTK_MISC(infoLabel),0,0); gtk_label_set_line_wrap(GTK_LABEL(_(infoLabel)),TRUE); //gtk_widget_set_size_request(GTK_LABEL(infoLabel),200,-1); //gtk_label_set_max_width_chars(GTK_LABEL(infoLabel),50); } do_active_plugins(); g_signal_connect(rend,"toggled",G_CALLBACK(cb_toggled),NULL); g_signal_connect(gtk_tree_view_get_selection(SETPluginList),"changed", G_CALLBACK(cb_showpage),pluginContainer); gtk_box_pack_start(ebox,gtk_hseparator_new(),FALSE,FALSE,0); bbox=GTK_BOX(gtk_hbox_new(FALSE,0)); gtk_box_pack_start(ebox,GTK_WIDGET(bbox),FALSE,FALSE,0); { GtkWidget * quitbutton; quitbutton=gtk_button_new_from_stock(GTK_STOCK_QUIT); gtk_box_pack_end(bbox,quitbutton,FALSE,FALSE,0); g_signal_connect(quitbutton,"clicked",G_CALLBACK(cb_main_destroy),NULL); }}void setup_main_window(){ mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(mainWindow),N_("Beryl Settings Manager ") VERSION); gtk_window_set_resizable(GTK_WINDOW(mainWindow),TRUE); //gtk_window_set_position(GTK_WINDOW(mainWindow),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(mainWindow),780,500); gtk_window_set_default_icon_from_file(PIXMAPS_DIR "/beryl-settings.svg",NULL); gtk_container_set_border_width(GTK_CONTAINER(mainWindow),5); layout_main_window(); g_signal_connect(G_OBJECT (mainWindow), "destroy", G_CALLBACK(cb_main_destroy), NULL); gtk_widget_show_all(mainWindow); gtk_widget_hide(infoContainer); g_timeout_add(1000,dequeue_sig,NULL);}int main(int argc, char ** argv){ gtk_init(&argc,&argv); gchar * smmser; //set the locale stuff setlocale(LC_ALL,""); bindtextdomain("beryl-settings","/usr/share/locale"); textdomain("beryl-settings"); //end locale smmser=g_strconcat(g_get_home_dir(),"/.beryl",NULL); g_mkdir_with_parents(smmser,00755); g_chmod(smmser,00755); g_free(smmser); if (!g_thread_supported()) g_thread_init(NULL); dbus_g_thread_init(); dbcon = dbus_bus_get (DBUS_BUS_SESSION,NULL); if (!dbcon) g_error("couldn't get dbus."); dbus_connection_setup_with_g_main(dbcon,NULL); // send_option_changed_signal("_","active_plugins"); load_schema_files(); setup_main_window(); gtk_main(); return 0;}CVS AdminPowered by ViewCVS 1.0-dev (Powered by ViewCVS)ViewCVS and CVS Help