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
) {
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];
27 static void watch_func(Window window
, Bool is_start
, long mask
, void *cb_data
) {
30 gdkwin
= gdk_window_lookup(window
);
34 gdkwin
= gdk_window_foreign_new(window
);
38 gdk_window_add_filter(gdkwin
, xsettings_event_filter
, NULL
);
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
) {
53 snprintf(keypath
, 1024, "dasher/%s", Key
.c_str());
55 XSettingsSetting
*setting
;
57 if(xsettings_client_get_setting(client
, keypath
, &setting
) != XSETTINGS_SUCCESS
) {
61 if(setting
->type
== XSETTINGS_TYPE_INT
) {
62 *value
= setting
->data
.v_int
;
68 bool get_bool_option_callback(const std::string
&Key
, bool *value
) {
70 if(get_long_option_callback(Key
, &tmp
) == false) {
82 bool get_string_option_callback(const std::string
&Key
, std::string
*value
) {
85 snprintf(keypath
, 1024, "dasher/%s", Key
.c_str());
87 XSettingsSetting
*setting
;
89 if(xsettings_client_get_setting(client
, keypath
, &setting
) != XSETTINGS_SUCCESS
) {
93 if(setting
->type
== XSETTINGS_TYPE_STRING
) {
94 *value
= setting
->data
.v_string
;
100 void set_long_option_callback(const std::string
&Key
, long Value
) {
101 int realvalue
= Value
;
103 Atom gpe_settings_update_atom
= XInternAtom(GDK_DISPLAY(), "_GPE_SETTINGS_UPDATE", 0);
104 Window manager
= XGetSelectionOwner(GDK_DISPLAY(), gpe_settings_update_atom
);
106 size_t length
, name_len
;
108 XClientMessageEvent ev
;
109 gboolean done
= FALSE
;
113 get_long_option_callback(Key
, ¤tvalue
);
115 if(currentvalue
== Value
)
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
;
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
);
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
);
142 XSelectInput(GDK_DISPLAY(), win
, PropertyChangeMask
);
143 ev
.type
= ClientMessage
;
145 ev
.message_type
= gpe_settings_update_atom
;
147 ev
.data
.l
[0] = gpe_settings_update_atom
;
148 XSendEvent(GDK_DISPLAY(), manager
, FALSE
, 0, (XEvent
*) & ev
);
152 XNextEvent(GDK_DISPLAY(), &ev
);
153 switch (ev
.xany
.type
) {
155 if(ev
.xproperty
.window
== win
&& ev
.xproperty
.atom
== gpe_settings_update_atom
)
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
);
170 std::string currentvalue
;
171 size_t length
, name_len
;
173 XClientMessageEvent ev
;
174 gboolean done
= FALSE
;
178 get_string_option_callback(Key
, ¤tvalue
);
179 if(currentvalue
== Value
)
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
);
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
);
206 XSelectInput(GDK_DISPLAY(), win
, PropertyChangeMask
);
207 ev
.type
= ClientMessage
;
209 ev
.message_type
= gpe_settings_update_atom
;
211 ev
.data
.l
[0] = gpe_settings_update_atom
;
212 XSendEvent(GDK_DISPLAY(), manager
, FALSE
, 0, (XEvent
*) & ev
);
215 XNextEvent(GDK_DISPLAY(), &ev
);
217 switch (ev
.xany
.type
) {
219 if(ev
.xproperty
.window
== win
&& ev
.xproperty
.atom
== gpe_settings_update_atom
)