The following is a simple example of using sockets and plugs. The method
of communication between processes is deliberately kept very simple: The
Plug
writes its ID out to a text file named
plug.id
and the process with the socket reads the ID
from this file. In a real program, you may want to use a more
sophisticated method of inter-process communication.
File: socket.cc
(For use with gtkmm 3, not gtkmm 2)
#include <iostream> #include <fstream> #include <gtkmm.h> #include <gtkmm/socket.h> using namespace std; const char* id_filename = "plug.id"; void plug_added() { cout << "A plug was added" << endl; } bool plug_removed() { cout << "A Plug was removed" << endl; return true; } class MySocketWindow : public Gtk::Window { public: MySocketWindow() { ifstream infile(id_filename); if (infile) { auto socket = Gtk::make_managed<Gtk::Socket>(); add(*socket); socket->signal_plug_added().connect(sigc::ptr_fun(plug_added)); socket->signal_plug_removed().connect(sigc::ptr_fun(plug_removed)); ::Window plug_id = 0; infile >> plug_id; infile.close(); socket->add_id(plug_id); } else { auto label = Gtk::make_managed<Gtk::Label>( "Plug id file not found.\n Make sure plug is running."); add(*label); set_size_request(150, 50); } show_all(); } }; int main(int argc, char** argv) { // The plug and the socket have different application ids, so they can run // simultaneously. auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example.socket"); MySocketWindow win; app->run(win); return 0; }
File: plug.cc
(For use with gtkmm 3, not gtkmm 2)
#include <iostream> #include <fstream> #include <gtkmm.h> #include <gtkmm/plug.h> #include <glib/gstdio.h> using namespace std; const char* id_filename = "plug.id"; void on_embed() { cout << "I've been embedded." << endl; } class MyPlug : public Gtk::Plug { public: MyPlug() : m_label("I am the plug") { set_size_request(150, 100); add(m_label); signal_embedded().connect(sigc::ptr_fun(on_embed)); show_all_children(); } private: Gtk::Label m_label; }; int main(int argc, char** argv) { // The plug and the socket have different application ids, so they can run // simultaneously. auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example.plug"); MyPlug plug; plug.show(); ofstream out(id_filename); out << plug.get_id(); out.close(); cout << "The window ID is: " << plug.get_id() << endl; app->run(plug); // remove the ID file when the program exits g_remove(id_filename); return 0; }
This example creates two executable programs: socket
and plug
. The idea is that
socket
has an application window that will embed a
widget from the plug
program. The way this example
is designed, plug
must be running first before
starting socket
. To see the example in action,
execute the following commands in order from within the example directory:
Start the plug
program and send it to the background
(or just use a different terminal).
$ ./plug &
After which you should see something like the following:
The window ID is: 69206019
Then start the socket
program:
$ ./socket
After starting socket
, you should see the following
output in the terminal:
I've been embedded. A plug was added
The first line of output is from plug
, after it has
been notified that it has been embedded inside of a
Socket
. The second line was emitted by
socket
in response to its
plug_added
signal. If everything was done as
described above, the socket
window should look
roughly like the following:
If for some reason the Socket
couldn't attach the
Plug
, the window would look something like this: