tagging release
[dasher.git] / trunk / Src / Gtk2 / gpesettings_store.cc
blobcc60d2d5f3bd608ae6c436a80c9a3e4bf2449901
1 #include "../Common/Common.h"
3 #include "gpesettings_store.h"
5 XSettingsClient *client;
7 static GdkFilterReturn xsettings_event_filter(GdkXEvent *xevp, GdkEvent *ev, gpointer p) {
8 if(xsettings_client_process_event(client, (XEvent *) xevp))
9 return GDK_FILTER_REMOVE;
11 return GDK_FILTER_CONTINUE;
14 static void notify_func(const char *name, XSettingsAction action, XSettingsSetting *setting, void *cb_data) {
15 size_t length;
16 char *settingname;
17 if(strncmp(name, "dasher/", 7) == 0) {
18 length = strlen(name);
19 settingname = (char *)malloc(length * sizeof(char));
20 for(size_t i = 0; i < length; i++) {
21 settingname[i] = name[i + 7];
23 free(settingname);
27 static void watch_func(Window window, Bool is_start, long mask, void *cb_data) {
28 GdkWindow *gdkwin;
30 gdkwin = gdk_window_lookup(window);
32 if(is_start) {
33 if(!gdkwin)
34 gdkwin = gdk_window_foreign_new(window);
35 else
36 g_object_ref(gdkwin);
38 gdk_window_add_filter(gdkwin, xsettings_event_filter, NULL);
40 else {
41 g_object_unref(gdkwin);
42 gdk_window_remove_filter(gdkwin, xsettings_event_filter, NULL);
46 void init_xsettings() {
47 client = xsettings_client_new(GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), notify_func, watch_func, NULL);
50 bool get_long_option_callback(const std::string &Key, long *value) {
51 char keypath[1024];
53 snprintf(keypath, 1024, "dasher/%s", Key.c_str());
55 XSettingsSetting *setting;
57 if(xsettings_client_get_setting(client, keypath, &setting) != XSETTINGS_SUCCESS) {
58 return false;
61 if(setting->type == XSETTINGS_TYPE_INT) {
62 *value = setting->data.v_int;
65 return (true);
68 bool get_bool_option_callback(const std::string &Key, bool *value) {
69 long tmp;
70 if(get_long_option_callback(Key, &tmp) == false) {
71 return false;
73 if(tmp) {
74 *value = true;
76 else {
77 *value = false;
79 return true;
82 bool get_string_option_callback(const std::string &Key, std::string *value) {
83 char keypath[1024];
85 snprintf(keypath, 1024, "dasher/%s", Key.c_str());
87 XSettingsSetting *setting;
89 if(xsettings_client_get_setting(client, keypath, &setting) != XSETTINGS_SUCCESS) {
90 return false;
93 if(setting->type == XSETTINGS_TYPE_STRING) {
94 *value = setting->data.v_string;
97 return (true);
100 void set_long_option_callback(const std::string &Key, long Value) {
101 int realvalue = Value;
102 long currentvalue;
103 Atom gpe_settings_update_atom = XInternAtom(GDK_DISPLAY(), "_GPE_SETTINGS_UPDATE", 0);
104 Window manager = XGetSelectionOwner(GDK_DISPLAY(), gpe_settings_update_atom);
105 XSettingsType type;
106 size_t length, name_len;
107 gchar *buffer;
108 XClientMessageEvent ev;
109 gboolean done = FALSE;
110 Window win;
111 char keypath[1024];
113 get_long_option_callback(Key, &currentvalue);
115 if(currentvalue == Value)
116 return;
118 snprintf(keypath, 1024, "dasher/%s", Key.c_str());
120 if(manager == None) {
121 fprintf(stderr, "gpe-confd not running.\n");
124 win = XCreateSimpleWindow(GDK_DISPLAY(), DefaultRootWindow(GDK_DISPLAY()), 1, 1, 1, 1, 0, 0, 0);
126 type = XSETTINGS_TYPE_INT;
127 length = 4;
129 name_len = strlen(keypath);
130 // This crack rounds up to the nearest 4
131 name_len = (name_len + 3) & ~3;
132 buffer = (gchar *) g_malloc(length + 4 + name_len);
133 *buffer = type;
134 buffer[1] = 0;
135 buffer[2] = name_len & 0xff;
136 buffer[3] = (name_len >> 8) & 0xff;
137 memcpy(buffer + 4, keypath, name_len);
138 *((unsigned long *)(buffer + 4 + name_len)) = realvalue;
140 XChangeProperty(GDK_DISPLAY(), win, gpe_settings_update_atom, gpe_settings_update_atom, 8, PropModeReplace, (const unsigned char *)buffer, length + 4 + name_len);
141 g_free(buffer);
142 XSelectInput(GDK_DISPLAY(), win, PropertyChangeMask);
143 ev.type = ClientMessage;
144 ev.window = win;
145 ev.message_type = gpe_settings_update_atom;
146 ev.format = 32;
147 ev.data.l[0] = gpe_settings_update_atom;
148 XSendEvent(GDK_DISPLAY(), manager, FALSE, 0, (XEvent *) & ev);
150 while(!done) {
151 XEvent ev;
152 XNextEvent(GDK_DISPLAY(), &ev);
153 switch (ev.xany.type) {
154 case PropertyNotify:
155 if(ev.xproperty.window == win && ev.xproperty.atom == gpe_settings_update_atom)
156 done = TRUE;
157 break;
162 void set_bool_option_callback(const std::string &Key, bool Value) {
163 set_long_option_callback(Key, long (Value));
166 void set_string_option_callback(const std::string &Key, const std::string &Value) {
167 Atom gpe_settings_update_atom = XInternAtom(GDK_DISPLAY(), "_GPE_SETTINGS_UPDATE", 0);
168 Window manager = XGetSelectionOwner(GDK_DISPLAY(), gpe_settings_update_atom);
169 XSettingsType type;
170 std::string currentvalue;
171 size_t length, name_len;
172 gchar *buffer;
173 XClientMessageEvent ev;
174 gboolean done = FALSE;
175 Window win;
176 char keypath[1024];
178 get_string_option_callback(Key, &currentvalue);
179 if(currentvalue == Value)
180 return;
182 snprintf(keypath, 1024, "dasher/%s", Key.c_str());
184 if(manager == None) {
185 fprintf(stderr, "gpe-confd not running.\n");
188 win = XCreateSimpleWindow(GDK_DISPLAY(), DefaultRootWindow(GDK_DISPLAY()), 1, 1, 1, 1, 0, 0, 0);
190 type = XSETTINGS_TYPE_STRING;
191 length = 4 + (strlen(Value.c_str()) + 3) & ~3;
193 name_len = strlen(keypath);
194 // As does this crack
195 name_len = (name_len + 3) & ~3;
196 buffer = (gchar *) g_malloc(length + 4 + name_len);
197 *buffer = type;
198 buffer[1] = 0;
199 buffer[2] = name_len & 0xff;
200 buffer[3] = (name_len >> 8) & 0xff;
201 memcpy(buffer + 4, keypath, name_len);
202 *((unsigned long *)(buffer + 4 + name_len)) = strlen(Value.c_str());
203 memcpy(buffer + 8 + name_len, Value.c_str(), strlen(Value.c_str()));
204 XChangeProperty(GDK_DISPLAY(), win, gpe_settings_update_atom, gpe_settings_update_atom, 8, PropModeReplace, (const unsigned char *)buffer, length + 4 + name_len);
205 g_free(buffer);
206 XSelectInput(GDK_DISPLAY(), win, PropertyChangeMask);
207 ev.type = ClientMessage;
208 ev.window = win;
209 ev.message_type = gpe_settings_update_atom;
210 ev.format = 32;
211 ev.data.l[0] = gpe_settings_update_atom;
212 XSendEvent(GDK_DISPLAY(), manager, FALSE, 0, (XEvent *) & ev);
213 while(!done) {
214 XEvent ev;
215 XNextEvent(GDK_DISPLAY(), &ev);
217 switch (ev.xany.type) {
218 case PropertyNotify:
219 if(ev.xproperty.window == win && ev.xproperty.atom == gpe_settings_update_atom)
220 done = TRUE;
221 break;