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