diff options
Diffstat (limited to 'util/fluxbox-update_configs.cc')
-rw-r--r-- | util/fluxbox-update_configs.cc | 217 |
1 files changed, 176 insertions, 41 deletions
diff --git a/util/fluxbox-update_configs.cc b/util/fluxbox-update_configs.cc index 8cfe8ef..2dc5eb6 100644 --- a/util/fluxbox-update_configs.cc +++ b/util/fluxbox-update_configs.cc | |||
@@ -38,23 +38,17 @@ | |||
38 | #define _GNU_SOURCE | 38 | #define _GNU_SOURCE |
39 | #endif // _GNU_SOURCE | 39 | #endif // _GNU_SOURCE |
40 | 40 | ||
41 | #ifdef HAVE_CSTDIO | ||
42 | #include <cstdio> | ||
43 | #else | ||
44 | #include <stdio.h> | ||
45 | #endif | ||
46 | #ifdef HAVE_CSTDLIB | ||
47 | #include <cstdlib> | ||
48 | #else | ||
49 | #include <stdlib.h> | ||
50 | #endif | ||
51 | #ifdef HAVE_CSTRING | 41 | #ifdef HAVE_CSTRING |
52 | #include <cstring> | 42 | #include <cstring> |
53 | #else | 43 | #else |
54 | #include <string.h> | 44 | #include <string.h> |
55 | #endif | 45 | #endif |
46 | |||
56 | #include <iostream> | 47 | #include <iostream> |
57 | #include <fstream> | 48 | #include <fstream> |
49 | #include <set> | ||
50 | #include <map> | ||
51 | #include <list> | ||
58 | 52 | ||
59 | using std::cout; | 53 | using std::cout; |
60 | using std::cerr; | 54 | using std::cerr; |
@@ -62,39 +56,34 @@ using std::endl; | |||
62 | using std::string; | 56 | using std::string; |
63 | using std::ifstream; | 57 | using std::ifstream; |
64 | using std::ofstream; | 58 | using std::ofstream; |
59 | using std::set; | ||
60 | using std::map; | ||
61 | using std::list; | ||
65 | 62 | ||
66 | #define VERSION 1 | 63 | string read_file(string filename); |
64 | void write_file(string filename, string &contents); | ||
65 | void save_all_files(); | ||
67 | 66 | ||
68 | int run_updates(int old_version, FbTk::ResourceManager rm) { | 67 | int run_updates(int old_version, FbTk::ResourceManager rm) { |
69 | int new_version = old_version; | 68 | int new_version = old_version; |
70 | 69 | ||
71 | if (old_version < 1) { // add mouse events to keys file | 70 | FbTk::Resource<string> rc_keyfile(rm, "~/.fluxbox/keys", |
72 | FbTk::Resource<string> rc_keyfile(rm, DEFAULTKEYSFILE, | 71 | "session.keyFile", "Session.KeyFile"); |
73 | "session.keyFile", "Session.KeyFile"); | 72 | FbTk::Resource<string> rc_appsfile(rm, "~/.fluxbox/apps", |
74 | string keyfilename = FbTk::StringUtil::expandFilename(*rc_keyfile); | 73 | "session.appsFile", "Session.AppsFile"); |
75 | |||
76 | // ok, I don't know anything about file handling in c++ | ||
77 | // what's it to you?!?! | ||
78 | // I assume there should be some error handling in here, but I sure | ||
79 | // don't know how, and I don't have documentation | ||
80 | 74 | ||
81 | ifstream in_keyfile(keyfilename.c_str()); | 75 | string appsfilename = FbTk::StringUtil::expandFilename(*rc_appsfile); |
82 | string whole_keyfile = ""; | 76 | string keyfilename = FbTk::StringUtil::expandFilename(*rc_keyfile); |
83 | 77 | ||
84 | while (!in_keyfile.eof()) { | 78 | if (old_version < 1) { // add mouse events to keys file |
85 | string linebuffer; | ||
86 | |||
87 | getline(in_keyfile, linebuffer); | ||
88 | whole_keyfile += linebuffer + "\n"; | ||
89 | } | ||
90 | in_keyfile.close(); | ||
91 | 79 | ||
92 | ofstream out_keyfile(keyfilename.c_str()); | 80 | string whole_keyfile = read_file(keyfilename); |
81 | string new_keyfile = ""; | ||
93 | // let's put our new keybindings first, so they're easy to find | 82 | // let's put our new keybindings first, so they're easy to find |
94 | out_keyfile << "!mouse actions added by fluxbox-update_configs" << endl | 83 | new_keyfile += "!mouse actions added by fluxbox-update_configs\n"; |
95 | << "OnDesktop Mouse1 :hideMenus" << endl | 84 | new_keyfile += "OnDesktop Mouse1 :hideMenus\n"; |
96 | << "OnDesktop Mouse2 :workspaceMenu" << endl | 85 | new_keyfile += "OnDesktop Mouse2 :workspaceMenu\n"; |
97 | << "OnDesktop Mouse3 :rootMenu" << endl; | 86 | new_keyfile += "OnDesktop Mouse3 :rootMenu\n"; |
98 | 87 | ||
99 | // scrolling on desktop needs to match user's desktop wheeling settings | 88 | // scrolling on desktop needs to match user's desktop wheeling settings |
100 | // hmmm, what are the odds that somebody wants this to be different on | 89 | // hmmm, what are the odds that somebody wants this to be different on |
@@ -108,25 +97,97 @@ int run_updates(int old_version, FbTk::ResourceManager rm) { | |||
108 | "Session.Screen0.ReverseWheeling"); | 97 | "Session.Screen0.ReverseWheeling"); |
109 | if (*rc_wheeling) { | 98 | if (*rc_wheeling) { |
110 | if (*rc_reverse) { // if you ask me, this should have been default | 99 | if (*rc_reverse) { // if you ask me, this should have been default |
111 | out_keyfile << "OnDesktop Mouse4 :prevWorkspace" << endl | 100 | new_keyfile += "OnDesktop Mouse4 :prevWorkspace\n"; |
112 | << "OnDesktop Mouse5 :nextWorkspace" << endl; | 101 | new_keyfile += "OnDesktop Mouse5 :nextWorkspace\n"; |
113 | } else { | 102 | } else { |
114 | out_keyfile << "OnDesktop Mouse4 :nextWorkspace" << endl | 103 | new_keyfile += "OnDesktop Mouse4 :nextWorkspace\n"; |
115 | << "OnDesktop Mouse5 :prevWorkspace" << endl; | 104 | new_keyfile += "OnDesktop Mouse5 :prevWorkspace\n"; |
116 | } | 105 | } |
117 | } | 106 | } |
118 | out_keyfile << endl; // just for good looks | 107 | new_keyfile += "\n"; // just for good looks |
108 | new_keyfile += whole_keyfile; // don't forget user's old keybindings | ||
119 | 109 | ||
120 | // now, restore user's old keybindings | 110 | write_file(keyfilename, new_keyfile); |
121 | out_keyfile << whole_keyfile; | ||
122 | new_version = 1; | 111 | new_version = 1; |
123 | } | 112 | } |
124 | 113 | ||
114 | if (old_version < 2) { // move groups entries to apps file | ||
115 | FbTk::Resource<string> rc_groupfile(rm, "~/.fluxbox/groups", | ||
116 | "session.groupFile", "Session.GroupFile"); | ||
117 | string groupfilename = FbTk::StringUtil::expandFilename(*rc_groupfile); | ||
118 | string whole_groupfile = read_file(groupfilename); | ||
119 | string whole_appsfile = read_file(appsfilename); | ||
120 | string new_appsfile = ""; | ||
121 | |||
122 | list<string> lines; | ||
123 | FbTk::StringUtil::stringtok(lines, whole_groupfile, "\n"); | ||
124 | |||
125 | list<string>::iterator line_it = lines.begin(); | ||
126 | list<string>::iterator line_it_end = lines.end(); | ||
127 | for (; line_it != line_it_end; ++line_it) { | ||
128 | new_appsfile += "[group] (workspace=[current])\n"; | ||
129 | |||
130 | list<string> apps; | ||
131 | FbTk::StringUtil::stringtok(apps, *line_it); | ||
132 | |||
133 | list<string>::iterator it = apps.begin(); | ||
134 | list<string>::iterator it_end = apps.end(); | ||
135 | for (; it != it_end; ++it) { | ||
136 | new_appsfile += " [app] (name="; | ||
137 | new_appsfile += *it; | ||
138 | new_appsfile += ")\n"; | ||
139 | } | ||
140 | |||
141 | new_appsfile += "[end]\n"; | ||
142 | } | ||
143 | |||
144 | new_appsfile += whole_appsfile; | ||
145 | write_file(appsfilename, new_appsfile); | ||
146 | new_version = 2; | ||
147 | } | ||
148 | |||
149 | if (old_version < 3) { // move toolbar wheeling to keys file | ||
150 | string whole_keyfile = read_file(keyfilename); | ||
151 | string new_keyfile = ""; | ||
152 | // let's put our new keybindings first, so they're easy to find | ||
153 | new_keyfile += "!mouse actions added by fluxbox-update_configs\n"; | ||
154 | bool keep_changes = false; | ||
155 | |||
156 | // scrolling on toolbar needs to match user's toolbar wheeling settings | ||
157 | FbTk::Resource<string> rc_wheeling(rm, "Off", | ||
158 | "session.screen0.iconbar.wheelMode", | ||
159 | "Session.Screen0.Iconbar.WheelMode"); | ||
160 | FbTk::Resource<bool> rc_screen(rm, true, | ||
161 | "session.screen0.desktopwheeling", | ||
162 | "Session.Screen0.DesktopWheeling"); | ||
163 | FbTk::Resource<bool> rc_reverse(rm, false, | ||
164 | "session.screen0.reversewheeling", | ||
165 | "Session.Screen0.ReverseWheeling"); | ||
166 | if (strcasecmp((*rc_wheeling).c_str(), "On") == 0 || | ||
167 | (strcasecmp((*rc_wheeling).c_str(), "Screen") && *rc_screen)) { | ||
168 | keep_changes = true; | ||
169 | if (*rc_reverse) { // if you ask me, this should have been default | ||
170 | new_keyfile += "OnToolbar Mouse4 :prevWorkspace\n"; | ||
171 | new_keyfile += "OnToolbar Mouse5 :nextWorkspace\n"; | ||
172 | } else { | ||
173 | new_keyfile += "OnToolbar Mouse4 :nextWorkspace\n"; | ||
174 | new_keyfile += "OnToolbar Mouse5 :prevWorkspace\n"; | ||
175 | } | ||
176 | } | ||
177 | new_keyfile += "\n"; // just for good looks | ||
178 | new_keyfile += whole_keyfile; // don't forget user's old keybindings | ||
179 | |||
180 | if (keep_changes) | ||
181 | write_file(keyfilename, new_keyfile); | ||
182 | new_version = 3; | ||
183 | } | ||
184 | |||
125 | return new_version; | 185 | return new_version; |
126 | } | 186 | } |
127 | 187 | ||
128 | int main(int argc, char **argv) { | 188 | int main(int argc, char **argv) { |
129 | string rc_filename; | 189 | string rc_filename; |
190 | set<string> style_filenames; | ||
130 | int i = 1; | 191 | int i = 1; |
131 | pid_t fb_pid = 0; | 192 | pid_t fb_pid = 0; |
132 | 193 | ||
@@ -184,8 +245,10 @@ int main(int argc, char **argv) { | |||
184 | int old_version = *config_version; | 245 | int old_version = *config_version; |
185 | int new_version = run_updates(old_version, resource_manager); | 246 | int new_version = run_updates(old_version, resource_manager); |
186 | if (new_version > old_version) { | 247 | if (new_version > old_version) { |
248 | // configs were updated -- let's save our changes | ||
187 | config_version = new_version; | 249 | config_version = new_version; |
188 | resource_manager.save(rc_filename.c_str(), rc_filename.c_str()); | 250 | resource_manager.save(rc_filename.c_str(), rc_filename.c_str()); |
251 | save_all_files(); | ||
189 | 252 | ||
190 | #ifdef HAVE_SIGNAL_H | 253 | #ifdef HAVE_SIGNAL_H |
191 | // if we were given a fluxbox pid, send it a reconfigure signal | 254 | // if we were given a fluxbox pid, send it a reconfigure signal |
@@ -197,3 +260,75 @@ int main(int argc, char **argv) { | |||
197 | 260 | ||
198 | return 0; | 261 | return 0; |
199 | } | 262 | } |
263 | |||
264 | static set<string> modified_files; | ||
265 | // we may want to put a size limit on this cache, so it doesn't grow too big | ||
266 | static map<string,string> file_cache; | ||
267 | |||
268 | // returns the contents of the file given, either from the cache or by reading | ||
269 | // the file from disk | ||
270 | string read_file(string filename) { | ||
271 | // check if we already have the file in memory | ||
272 | map<string,string>::iterator it = file_cache.find(filename); | ||
273 | if (it != file_cache.end()) | ||
274 | return it->second; | ||
275 | |||
276 | // nope, we'll have to read the file | ||
277 | ifstream infile(filename.c_str()); | ||
278 | string whole_file = ""; | ||
279 | |||
280 | if (!infile) // failed to open file | ||
281 | return whole_file; | ||
282 | |||
283 | while (!infile.eof()) { | ||
284 | string linebuffer; | ||
285 | |||
286 | getline(infile, linebuffer); | ||
287 | whole_file += linebuffer + "\n"; | ||
288 | } | ||
289 | infile.close(); | ||
290 | |||
291 | file_cache[filename] = whole_file; | ||
292 | return whole_file; | ||
293 | } | ||
294 | |||
295 | #ifdef NOT_USED | ||
296 | // remove the file from the cache, writing to disk if it's been changed | ||
297 | void forget_file(string filename) { | ||
298 | map<string,string>::iterator cache_it = file_cache.find(filename); | ||
299 | // check if we knew about the file to begin with | ||
300 | if (cache_it == file_cache.end()) | ||
301 | return; | ||
302 | |||
303 | // check if we've actually modified it | ||
304 | set<string>::iterator mod_it = modified_files.find(filename); | ||
305 | if (mod_it == modified_files.end()) { | ||
306 | file_cache.erase(cache_it); | ||
307 | return; | ||
308 | } | ||
309 | |||
310 | // flush our changes to disk and remove all traces | ||
311 | ofstream outfile(filename.c_str()); | ||
312 | outfile << cache_it->second; | ||
313 | file_cache.erase(cache_it); | ||
314 | modified_files.erase(mod_it); | ||
315 | } | ||
316 | #endif // NOT_USED | ||
317 | |||
318 | // updates the file contents in the cache and marks the file as modified so it | ||
319 | // gets saved later | ||
320 | void write_file(string filename, string &contents) { | ||
321 | modified_files.insert(filename); | ||
322 | file_cache[filename] = contents; | ||
323 | } | ||
324 | |||
325 | // actually save all the files we've modified | ||
326 | void save_all_files() { | ||
327 | set<string>::iterator it = modified_files.begin(); | ||
328 | set<string>::iterator it_end = modified_files.end(); | ||
329 | for (; it != it_end; ++it) { | ||
330 | ofstream outfile(it->c_str()); | ||
331 | outfile << file_cache[it->c_str()]; | ||
332 | } | ||
333 | modified_files.clear(); | ||
334 | } | ||