1 /*
2
3 This file is from Nitrogen, an X11 background setter.
4 Copyright (C) 2006 Dave Foster & Javeed Shaikh
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 */
21
22 #include "main.h"
23 #include "NWindow.h"
24 #include "Config.h"
25 #include "SetBG.h"
26 #include "ArgParser.h"
27 #include "Util.h"
28 //#include "gettext.h"
29 //#include <inti/i18n.h>
30 #include "gcs-i18n.h"
31
restore_bgs(SetBG * bg_setter)32 void restore_bgs(SetBG* bg_setter)
33 {
34 Util::program_log("entering restore_bgs()");
35 bg_setter->restore_bgs();
36 while( Gtk::Main::events_pending() )
37 Gtk::Main::iteration();
38 Util::program_log("leaving restore_bgs()");
39 }
40
set_bg_once(Config * cfg,SetBG * bg_setter,Glib::ustring path,int head,SetBG::SetMode mode,bool save,Gdk::Color col,bool random)41 int set_bg_once(Config *cfg, SetBG* bg_setter, Glib::ustring path, int head, SetBG::SetMode mode, bool save, Gdk::Color col, bool random)
42 {
43 Util::program_log("entering set_bg_once()");
44 Glib::ustring disp;
45 Glib::ustring file;
46
47 if (random) {
48 if (path.length() > 0) {
49 if (Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) {
50 path = Util::pick_random_file(path, cfg->get_recurse());
51 }
52 } else {
53 path = Util::pick_random_file(cfg->get_dirs(), cfg->get_recurse());
54 }
55
56 if (path.length() == 0) {
57 std::cerr << "Could not find an image to set!\n";
58 return 1;
59 }
60 }
61
62 // path must be resolved to a file at this point, make sure it exists
63 if (Glib::file_test(path, Glib::FILE_TEST_IS_REGULAR|Glib::FILE_TEST_IS_SYMLINK)) {
64 file = path;
65 } else {
66 std::cerr << "Set must be called with a file!\n";
67 return 1;
68 }
69
70 // @TODO: test file for an image format supported
71
72 // saving of pixmaps is for interactive only
73 bg_setter->disable_pixmap_save();
74
75 disp = bg_setter->make_display_key(head);
76 bool shouldSave = bg_setter->set_bg(disp, file, mode, col);
77
78 if (save && shouldSave)
79 Config::get_instance()->set_bg(disp, file, mode, col);
80
81 while (Gtk::Main::events_pending())
82 Gtk::Main::iteration();
83
84 Util::program_log("leaving set_bg_once()");
85 return 0;
86 }
87
on_window_close_save_pos(GdkEventAny * event,Gtk::Window * window)88 bool on_window_close_save_pos(GdkEventAny* event, Gtk::Window *window)
89 {
90 Config *cfg = Config::get_instance();
91 int x, y;
92 window->get_position(x, y);
93 cfg->set_pos(x, y);
94
95 int w, h;
96 window->get_size(w, h);
97 cfg->set_size(w, h);
98
99 return false;
100 }
101
102 #ifdef USE_INOTIFY
poll_inotify(void)103 bool poll_inotify(void) {
104 Inotify::Watch::poll(0);
105 return true;
106 }
107 #endif
108
main(int argc,char ** argv)109 int main (int argc, char ** argv) {
110 int xin_head = -1;
111 bool random = false;
112 bool set_once = false;
113 SetBG::SetMode mode;
114
115
116 // set up i18n
117 bindtextdomain(PACKAGE, LOCALEDIR);
118 bind_textdomain_codeset(PACKAGE, "UTF-8");
119 textdomain(PACKAGE);
120
121 /* i18n::set_text_domain_dir(PACKAGE, LOCALEDIR);
122 i18n::set_text_domain(PACKAGE);*/
123
124 Gtk::Main kit(argc, argv);
125 Gtk::IconTheme::get_default()->append_search_path(NITROGEN_DATA_DIR
126 G_DIR_SEPARATOR_S "icons");
127 if (!Glib::thread_supported()) Glib::thread_init();
128 Config *cfg = Config::get_instance();
129 ArgParser *parser = Util::create_arg_parser();
130
131 // parse command line
132 if ( ! parser->parse(argc, argv) ) {
133 std::cerr << _("Error parsing command line") << ": " << parser->get_error() << "\n";
134 return -1;
135 }
136
137 // if we got a help, display it and exit
138 if ( parser->has_argument("help") ) {
139 std::cout << parser->help_text() << "\n";
140 return 0;
141 }
142
143 // factory to make the correct setter, if no force specified on command line
144 SetBG* setter;
145 if (parser->has_argument("force-setter")) {
146 Glib::ustring setter_str = parser->get_value("force-setter");
147
148 if (setter_str == "xwindows")
149 setter = new SetBGXWindows();
150 #ifdef USE_XINERAMA
151 else if (setter_str == "xinerama") {
152 setter = new SetBGXinerama();
153
154 XineramaScreenInfo *xinerama_info;
155 gint xinerama_num_screens;
156
157 Glib::RefPtr<Gdk::Display> dpy = Gdk::DisplayManager::get()->get_default_display();
158 xinerama_info = XineramaQueryScreens(GDK_DISPLAY_XDISPLAY(dpy->gobj()), &xinerama_num_screens);
159 ((SetBGXinerama*)setter)->set_xinerama_info(xinerama_info, xinerama_num_screens);
160 }
161 #endif /* USE_XINERAMA */
162 else if (setter_str == "gnome")
163 setter = new SetBGGnome();
164 else if (setter_str == "pcmanfm")
165 setter = new SetBGPcmanfm();
166 else
167 setter = SetBG::get_bg_setter();
168
169 } else {
170 setter = SetBG::get_bg_setter();
171 }
172
173 // if we got restore, set it and exit
174 if ( parser->has_argument("restore") ) {
175 restore_bgs(setter);
176 return 0;
177 }
178
179 // get the starting dir
180 std::string startdir = parser->get_extra_args();
181 bool bcmdlinedir = startdir.length() > 0;
182 if (bcmdlinedir) {
183 startdir = Util::fix_start_dir(std::string(startdir));
184
185 if (!Glib::file_test(startdir, Glib::FILE_TEST_EXISTS)) {
186 std::cerr << "Given path \"" << startdir << "\" does not exist!\n";
187 return 1;
188 }
189 }
190
191 // load configuration if there is one
192 cfg->load_cfg();
193
194 // should we set on the command line?
195 Gdk::Color color("#000000");
196 if ( parser->has_argument("set-color") ) {
197 Glib::ustring bgcolor_str = parser->get_value ("set-color");
198 color.parse(bgcolor_str);
199 }
200
201 if ( parser->has_argument("head") )
202 xin_head = parser->get_intvalue("head");
203
204 if (parser->has_argument("random"))
205 random = true;
206
207 if ( parser->has_argument("set-tiled") ) {
208 set_once = true;
209 mode = SetBG::SET_TILE;
210 }
211
212 if ( parser->has_argument("set-scaled") ) {
213 set_once = true;
214 mode = SetBG::SET_SCALE;
215 }
216
217 if ( parser->has_argument("set-auto") ) {
218 set_once = true;
219 mode = SetBG::SET_AUTO;
220 }
221
222 if ( parser->has_argument("set-zoom") ) {
223 set_once = true;
224 mode = SetBG::SET_ZOOM;
225 }
226
227 if ( parser->has_argument("set-zoom-fill") ) {
228 set_once = true;
229 mode = SetBG::SET_ZOOM_FILL;
230 }
231
232 if ( parser->has_argument("set-centered") ) {
233 set_once = true;
234 mode = SetBG::SET_CENTER;
235 }
236
237 if (set_once) {
238 set_once = true;
239 return set_bg_once(cfg, setter, startdir, xin_head, mode, parser->has_argument("save"), color, random);
240 }
241
242 if ( parser->has_argument("no-recurse") )
243 cfg->set_recurse(false);
244 else
245 cfg->set_recurse(cfg->get_recurse());
246
247 guint w, h;
248 cfg->get_size(w, h);
249
250 gint x, y;
251 cfg->get_pos(x, y);
252
253 // create main window
254 NWindow* main_window = new NWindow(setter);
255 main_window->set_default_size(w, h);
256 main_window->move(x, y); // most likely will be ignored by the wm
257
258 // main_window->view.set_dir(startdir);
259 if (bcmdlinedir)
260 main_window->view.load_dir(startdir);
261 else
262 main_window->view.load_dir(cfg->get_dirs());
263
264 main_window->view.set_current_display_mode(cfg->get_display_mode());
265 main_window->set_default_selections();
266 main_window->view.set_icon_captions(cfg->get_icon_captions());
267 main_window->signal_delete_event().connect(sigc::bind(sigc::ptr_fun(&on_window_close_save_pos), main_window));
268 main_window->show();
269
270 main_window->set_default_display(xin_head);
271
272 if ( parser->has_argument("sort") ) {
273 Glib::ustring sort_mode = parser->get_value ("sort");
274 Thumbview::SortMode mode;
275
276 if (sort_mode == "alpha") {
277 mode = Thumbview::SORT_ALPHA;
278 } else if (sort_mode == "ralpha") {
279 mode = Thumbview::SORT_RALPHA;
280 } else if (sort_mode == "time") {
281 mode = Thumbview::SORT_TIME;
282 } else {
283 mode = Thumbview::SORT_RTIME;
284 }
285
286 main_window->view.set_sort_mode (mode);
287 }
288 else
289 main_window->view.set_sort_mode(cfg->get_sort_mode());
290
291 // remove parser
292 delete parser;
293
294 // rig up idle/thread routines
295 Glib::Thread::create(sigc::mem_fun(main_window->view, &Thumbview::load_cache_images), true);
296 Glib::Thread::create(sigc::mem_fun(main_window->view, &Thumbview::create_cache_images), true);
297
298 #ifdef USE_INOTIFY
299 Glib::signal_timeout().connect(sigc::ptr_fun(&poll_inotify), (unsigned)1e3);
300 #endif
301
302 Gtk::Main::run (*main_window);
303
304 cfg->save_cfg();
305
306 return 0;
307 }
308