1 #ifndef slic3r_InstanceCheck_hpp_
2 #define slic3r_InstanceCheck_hpp_
3 
4 #include "Event.hpp"
5 
6 #if _WIN32
7 #include <windows.h>
8 #endif //_WIN32
9 
10 #include <string>
11 
12 #include <boost/filesystem.hpp>
13 
14 #if __linux__
15 #include <boost/thread.hpp>
16 #include <mutex>
17 #include <condition_variable>
18 #endif // __linux__
19 
20 
21 namespace Slic3r {
22 // checks for other running instances and sends them argv,
23 // if there is --single-instance argument or AppConfig is set to single_instance=1
24 // returns true if this instance should terminate
25 bool    instance_check(int argc, char** argv, bool app_config_single_instance);
26 
27 #if __APPLE__
28 // apple implementation of inner functions of instance_check
29 // in InstanceCheckMac.mm
30 void    send_message_mac(const std::string& msg, const std::string& version);
31 
32 bool unlock_lockfile(const std::string& name, const std::string& path);
33 #endif //__APPLE__
34 
35 namespace GUI {
36 
37 class MainFrame;
38 
39 #if __linux__
40     #define BACKGROUND_MESSAGE_LISTENER
41 #endif // __linux__
42 
43 using LoadFromOtherInstanceEvent = Event<std::vector<boost::filesystem::path>>;
44 wxDECLARE_EVENT(EVT_LOAD_MODEL_OTHER_INSTANCE, LoadFromOtherInstanceEvent);
45 
46 using InstanceGoToFrontEvent = SimpleEvent;
47 wxDECLARE_EVENT(EVT_INSTANCE_GO_TO_FRONT, InstanceGoToFrontEvent);
48 
49 class OtherInstanceMessageHandler
50 {
51 public:
52 	OtherInstanceMessageHandler() = default;
53 	OtherInstanceMessageHandler(OtherInstanceMessageHandler const&) = delete;
54 	void operator=(OtherInstanceMessageHandler const&) = delete;
~OtherInstanceMessageHandler()55 	~OtherInstanceMessageHandler() { assert(!m_initialized); }
56 
57 	// inits listening, on each platform different. On linux starts background thread
58 	void    init(wxEvtHandler* callback_evt_handler);
59 	// stops listening, on linux stops the background thread
60 	void    shutdown(MainFrame* main_frame);
61 
62 	//finds paths to models in message(= command line arguments, first should be prusaSlicer executable)
63 	//and sends them to plater via LoadFromOtherInstanceEvent
64 	//security of messages: from message all existing paths are proccesed to load model
65 	//						win32 - anybody who has hwnd can send message.
66 	//						mac - anybody who posts notification with name:@"OtherPrusaSlicerTerminating"
67 	//						linux - instrospectable on dbus
68 	void           handle_message(const std::string& message);
69 #ifdef _WIN32
70 	static void    init_windows_properties(MainFrame* main_frame, size_t instance_hash);
71 #endif //WIN32
72 private:
73 	bool                    m_initialized { false };
74 	wxEvtHandler*           m_callback_evt_handler { nullptr };
75 
76 #ifdef BACKGROUND_MESSAGE_LISTENER
77 	//worker thread to listen incoming dbus communication
78 	boost::thread 			m_thread;
79 	std::condition_variable m_thread_stop_condition;
80 	mutable std::mutex 		m_thread_stop_mutex;
81 	bool 					m_stop{ false };
82 	bool					m_start{ true };
83 
84 	// background thread method
85 	void    listen();
86 #endif //BACKGROUND_MESSAGE_LISTENER
87 
88 #if __APPLE__
89 	//implemented at InstanceCheckMac.mm
90 	void    register_for_messages(const std::string &version_hash);
91 	void    unregister_for_messages();
92 	// Opaque pointer to RemovableDriveManagerMM
93 	void* m_impl_osx;
94 public:
95 	void    bring_instance_forward();
96 #endif //__APPLE__
97 
98 };
99 } // namespace GUI
100 } // namespace Slic3r
101 #endif // slic3r_InstanceCheck_hpp_
102