diff options
Diffstat (limited to 'util/fluxbox-update_configs.cc')
-rw-r--r-- | util/fluxbox-update_configs.cc | 185 |
1 files changed, 142 insertions, 43 deletions
diff --git a/util/fluxbox-update_configs.cc b/util/fluxbox-update_configs.cc index de1fbb9..5aa0d6c 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,29 @@ 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 | if (old_version < 1) { // add mouse events to keys file |
72 | FbTk::Resource<string> rc_keyfile(rm, DEFAULTKEYSFILE, | 71 | FbTk::Resource<string> rc_keyfile(rm, "~/.fluxbox/keys", |
73 | "session.keyFile", "Session.KeyFile"); | 72 | "session.keyFile", "Session.KeyFile"); |
74 | string keyfilename = FbTk::StringUtil::expandFilename(*rc_keyfile); | 73 | string keyfilename = FbTk::StringUtil::expandFilename(*rc_keyfile); |
75 | 74 | ||
76 | // ok, I don't know anything about file handling in c++ | 75 | string whole_keyfile = read_file(keyfilename); |
77 | // what's it to you?!?! | 76 | string new_keyfile = ""; |
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 | |||
81 | ifstream in_keyfile(keyfilename.c_str()); | ||
82 | string whole_keyfile = ""; | ||
83 | |||
84 | while (!in_keyfile.eof()) { | ||
85 | string linebuffer; | ||
86 | |||
87 | getline(in_keyfile, linebuffer); | ||
88 | whole_keyfile += linebuffer + "\n"; | ||
89 | } | ||
90 | in_keyfile.close(); | ||
91 | |||
92 | ofstream out_keyfile(keyfilename.c_str()); | ||
93 | // let's put our new keybindings first, so they're easy to find | 77 | // let's put our new keybindings first, so they're easy to find |
94 | out_keyfile << "!mouse actions added by fluxbox-update_configs" << endl | 78 | new_keyfile += "!mouse actions added by fluxbox-update_configs\n"; |
95 | << "OnDesktop Mouse1 :hideMenus" << endl | 79 | new_keyfile += "OnDesktop Mouse1 :hideMenus\n"; |
96 | << "OnDesktop Mouse2 :workspaceMenu" << endl | 80 | new_keyfile += "OnDesktop Mouse2 :workspaceMenu\n"; |
97 | << "OnDesktop Mouse3 :rootMenu" << endl; | 81 | new_keyfile += "OnDesktop Mouse3 :rootMenu\n"; |
98 | 82 | ||
99 | // scrolling on desktop needs to match user's desktop wheeling settings | 83 | // 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 | 84 | // hmmm, what are the odds that somebody wants this to be different on |
@@ -108,25 +92,66 @@ int run_updates(int old_version, FbTk::ResourceManager rm) { | |||
108 | "Session.Screen0.ReverseWheeling"); | 92 | "Session.Screen0.ReverseWheeling"); |
109 | if (*rc_wheeling) { | 93 | if (*rc_wheeling) { |
110 | if (*rc_reverse) { // if you ask me, this should have been default | 94 | if (*rc_reverse) { // if you ask me, this should have been default |
111 | out_keyfile << "OnDesktop Mouse4 :prevWorkspace" << endl | 95 | new_keyfile += "OnDesktop Mouse4 :prevWorkspace\n"; |
112 | << "OnDesktop Mouse5 :nextWorkspace" << endl; | 96 | new_keyfile += "OnDesktop Mouse5 :nextWorkspace\n"; |
113 | } else { | 97 | } else { |
114 | out_keyfile << "OnDesktop Mouse4 :nextWorkspace" << endl | 98 | new_keyfile += "OnDesktop Mouse4 :nextWorkspace\n"; |
115 | << "OnDesktop Mouse5 :prevWorkspace" << endl; | 99 | new_keyfile += "OnDesktop Mouse5 :prevWorkspace\n"; |
116 | } | 100 | } |
117 | } | 101 | } |
118 | out_keyfile << endl; // just for good looks | 102 | new_keyfile += "\n"; // just for good looks |
103 | new_keyfile += whole_keyfile; // don't forget user's old keybindings | ||
119 | 104 | ||
120 | // now, restore user's old keybindings | 105 | write_file(keyfilename, new_keyfile); |
121 | out_keyfile << whole_keyfile; | ||
122 | new_version = 1; | 106 | new_version = 1; |
123 | } | 107 | } |
124 | 108 | ||
109 | if (old_version < 2) { // move groups entries to apps file | ||
110 | FbTk::Resource<string> rc_groupfile(rm, "~/.fluxbox/groups", | ||
111 | "session.groupFile", "Session.GroupFile"); | ||
112 | string groupfilename = FbTk::StringUtil::expandFilename(*rc_groupfile); | ||
113 | string whole_groupfile = read_file(groupfilename); | ||
114 | |||
115 | FbTk::Resource<string> rc_appsfile(rm, "~/.fluxbox/apps", | ||
116 | "session.appsFile", "Session.AppsFile"); | ||
117 | string appsfilename = FbTk::StringUtil::expandFilename(*rc_appsfile); | ||
118 | string whole_appsfile = read_file(appsfilename); | ||
119 | |||
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)\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 | |||
125 | return new_version; | 149 | return new_version; |
126 | } | 150 | } |
127 | 151 | ||
128 | int main(int argc, char **argv) { | 152 | int main(int argc, char **argv) { |
129 | string rc_filename; | 153 | string rc_filename; |
154 | set<string> style_filenames; | ||
130 | int i = 1; | 155 | int i = 1; |
131 | pid_t fb_pid = 0; | 156 | pid_t fb_pid = 0; |
132 | 157 | ||
@@ -165,11 +190,11 @@ int main(int argc, char **argv) { | |||
165 | // couldn't load rc file | 190 | // couldn't load rc file |
166 | if (!rc_filename.empty()) { | 191 | if (!rc_filename.empty()) { |
167 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "Failed trying to read rc file")<<":"<<rc_filename<<endl; | 192 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "Failed trying to read rc file")<<":"<<rc_filename<<endl; |
168 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFileTrying, "Retrying with", "Retrying rc file loading with (the following file)")<<": "<<DEFAULT_INITFILE<<endl; | 193 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFileTrying, "Retrying with", "Retrying rc file loading with (the following file)")<<": ~/.fluxbox/init"<<endl; |
169 | } | 194 | } |
170 | // couldn't load default rc file, either | 195 | // couldn't load default rc file, either |
171 | if (!resource_manager.load(DEFAULT_INITFILE)) { | 196 | if (!resource_manager.load("~/.fluxbox/init")) { |
172 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "")<<": "<<DEFAULT_INITFILE<<endl; | 197 | cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "")<<": ~/.fluxbox/init"<<endl; |
173 | exit(1); // this is a fatal error for us | 198 | exit(1); // this is a fatal error for us |
174 | } | 199 | } |
175 | } | 200 | } |
@@ -182,8 +207,10 @@ int main(int argc, char **argv) { | |||
182 | int old_version = *config_version; | 207 | int old_version = *config_version; |
183 | int new_version = run_updates(old_version, resource_manager); | 208 | int new_version = run_updates(old_version, resource_manager); |
184 | if (new_version > old_version) { | 209 | if (new_version > old_version) { |
210 | // configs were updated -- let's save our changes | ||
185 | config_version = new_version; | 211 | config_version = new_version; |
186 | resource_manager.save(rc_filename.c_str(), rc_filename.c_str()); | 212 | resource_manager.save(rc_filename.c_str(), rc_filename.c_str()); |
213 | save_all_files(); | ||
187 | 214 | ||
188 | #ifdef HAVE_SIGNAL_H | 215 | #ifdef HAVE_SIGNAL_H |
189 | // if we were given a fluxbox pid, send it a reconfigure signal | 216 | // if we were given a fluxbox pid, send it a reconfigure signal |
@@ -195,3 +222,75 @@ int main(int argc, char **argv) { | |||
195 | 222 | ||
196 | return 0; | 223 | return 0; |
197 | } | 224 | } |
225 | |||
226 | static set<string> modified_files; | ||
227 | // we may want to put a size limit on this cache, so it doesn't grow too big | ||
228 | static map<string,string> file_cache; | ||
229 | |||
230 | // returns the contents of the file given, either from the cache or by reading | ||
231 | // the file from disk | ||
232 | string read_file(string filename) { | ||
233 | // check if we already have the file in memory | ||
234 | map<string,string>::iterator it = file_cache.find(filename); | ||
235 | if (it != file_cache.end()) | ||
236 | return it->second; | ||
237 | |||
238 | // nope, we'll have to read the file | ||
239 | ifstream infile(filename.c_str()); | ||
240 | string whole_file = ""; | ||
241 | |||
242 | if (!infile) // failed to open file | ||
243 | return whole_file; | ||
244 | |||
245 | while (!infile.eof()) { | ||
246 | string linebuffer; | ||
247 | |||
248 | getline(infile, linebuffer); | ||
249 | whole_file += linebuffer + "\n"; | ||
250 | } | ||
251 | infile.close(); | ||
252 | |||
253 | file_cache[filename] = whole_file; | ||
254 | return whole_file; | ||
255 | } | ||
256 | |||
257 | #ifdef NOT_USED | ||
258 | // remove the file from the cache, writing to disk if it's been changed | ||
259 | void forget_file(string filename) { | ||
260 | map<string,string>::iterator cache_it = file_cache.find(filename); | ||
261 | // check if we knew about the file to begin with | ||
262 | if (cache_it == file_cache.end()) | ||
263 | return; | ||
264 | |||
265 | // check if we've actually modified it | ||
266 | set<string>::iterator mod_it = modified_files.find(filename); | ||
267 | if (mod_it == modified_files.end()) { | ||
268 | file_cache.erase(cache_it); | ||
269 | return; | ||
270 | } | ||
271 | |||
272 | // flush our changes to disk and remove all traces | ||
273 | ofstream outfile(filename.c_str()); | ||
274 | outfile << cache_it->second; | ||
275 | file_cache.erase(cache_it); | ||
276 | modified_files.erase(mod_it); | ||
277 | } | ||
278 | #endif // NOT_USED | ||
279 | |||
280 | // updates the file contents in the cache and marks the file as modified so it | ||
281 | // gets saved later | ||
282 | void write_file(string filename, string &contents) { | ||
283 | modified_files.insert(filename); | ||
284 | file_cache[filename] = contents; | ||
285 | } | ||
286 | |||
287 | // actually save all the files we've modified | ||
288 | void save_all_files() { | ||
289 | set<string>::iterator it = modified_files.begin(); | ||
290 | set<string>::iterator it_end = modified_files.end(); | ||
291 | for (; it != it_end; ++it) { | ||
292 | ofstream outfile(it->c_str()); | ||
293 | outfile << file_cache[it->c_str()]; | ||
294 | } | ||
295 | modified_files.clear(); | ||
296 | } | ||