1 /* gobby - A GTKmm driven libobby client
2  * Copyright (C) 2005, 2006 0x539 dev group
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 #ifndef _GOBBY_IPC_HPP_
20 #define _GOBBY_IPC_HPP_
21 
22 #ifdef WIN32
23 # include <windows.h>
24 #else
25 # include <set>
26 # include <net6/packet.hpp>
27 # include <net6/connection.hpp>
28 # include "unix.hpp"
29 # include "gselector.hpp"
30 #endif
31 
32 #include <net6/non_copyable.hpp>
33 #include <gtkmm/window.h>
34 
35 namespace Gobby
36 {
37 
38 namespace Ipc
39 {
40 
41 #ifndef WIN32
42 typedef net6::connection<GSelector> Connection;
43 #endif
44 
45 class Error: public Glib::Error
46 {
47 public:
48 	enum Code {
49 		NO_REMOTE_INSTANCE, // No remote instance found
50 		SERVER_ERROR, // Error occured on server socket
51 		WINDOW_CREATION_FAILED, // Failed to create hidden window
52 
53 		FAILED
54 	};
55 
56 	Error(Code error_code, const Glib::ustring& error_message);
57 	Code code() const;
58 };
59 
60 #ifdef WIN32
61 /** Hidden message-only window to send and receive messages from/to other
62  * windows.
63  */
64 class HiddenWindow
65 {
66 public:
67 	typedef sigc::signal<LRESULT, UINT, WPARAM, LPARAM> signal_message_type;
68 
69 	HiddenWindow(const char* title);
70 	~HiddenWindow();
71 
get_hwnd() const72 	HWND get_hwnd() const { return m_hwnd; }
73 
74 	signal_message_type message_event() const;
75 protected:
76 	HWND m_hwnd;
77 
78 	signal_message_type m_signal_message;
79 };
80 #endif
81 
82 /** @brief Represents a remote gobby instance.
83  *
84  * A remote gobby instance actually is a gobby instance on the some machine
85  * but not _this_ instance.
86  */
87 class RemoteInstance
88 {
89 public:
90 	/** @Brief Finds a remote Gobby instance.
91 	 *
92 	 * If no instance has been found, an error with code
93 	 * Error::NO_REMOTE_INSTANCE is thrown.
94 	 */
95 	RemoteInstance();
96 
97 #ifdef WIN32
get_hwnd() const98 	HWND get_hwnd() const { return m_hwnd; }
99 #else
get_addr() const100 	const Unix::Address& get_addr() const { return m_addr; }
101 #endif
102 
103 private:
104 #ifdef WIN32
105 	HWND m_hwnd;
106 #else
107 	Unix::Address m_addr;
108 #endif
109 };
110 
111 /** @brief Connection to a remote Gobby instance.
112  */
113 class RemoteConnection: private net6::non_copyable
114 {
115 public:
116 	typedef sigc::signal<void> signal_done_type;
117 
118 	/** @brief Creates a connection to a remote gobby instance.
119 	 */
120 	RemoteConnection(const RemoteInstance& to);
121 
122 	/** @brief Sends a file to open by the remote instance.
123 	 */
124 	void send_file(const char* file);
125 
126 	/** @brief Signal that is emitted when all files have been
127 	 * transmitted to the other process.
128 	 */
129 	signal_done_type done_event() const;
130 private:
131 #ifdef WIN32
132 	HiddenWindow m_local_hwnd;
133 	HWND m_remote_hwnd;
134 #else
135 	GSelector m_selector;
136 	Connection m_conn;
137 #endif
138 
139 	signal_done_type m_signal_done;
140 };
141 
142 /** @brief Represents the local obby instance.
143  */
144 class LocalInstance: public sigc::trackable, private net6::non_copyable
145 {
146 public:
147 	typedef sigc::signal<void, const std::string&> signal_file_type;
148 
149 	LocalInstance();
150 	~LocalInstance();
151 
152 	/** @brief Signal that is emitted when another instance sent a file
153 	 * we have to open.
154 	 */
155 	signal_file_type file_event() const;
156 private:
157 #ifdef WIN32
158 	HiddenWindow m_hwnd;
159 
160 	LRESULT on_message(UINT msg, WPARAM wparam, LPARAM lparam);
161 #else
162 	GSelector m_selector;
163 
164 	Unix::Address m_addr;
165 	std::auto_ptr<net6::tcp_server_socket> m_serv;
166 	std::set<Connection*> m_clients;
167 
168 	void on_accept(net6::io_condition cond);
169 
170 	void on_read(const net6::packet& pack);
171 	void on_close(Connection& conn);
172 #endif
173 
174 	signal_file_type m_signal_file;
175 };
176 
177 } // namespace Ipc
178 
179 } // namespace Gobby
180 
181 #endif // _GOBBY_IPC_HPP_
182