Plugs and Sockets Example
| Chapter 20. Plugs and Sockets |

## Plugs and Sockets Example

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 files. In a real program, you may want to use a more sophisticated method of inter-process communication.

Source Code

File: `plug.cc`

    #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();
            }

        private:
            Gtk::Label m_label;
    };

    int main(int argc, char** argv)
    {
        Gtk::Main app(argc, argv);
        MyPlug plug;

        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;
    }

File: `socket.cc`

    #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)
                {
                    Gtk::Socket* socket = Gtk::manage(new Gtk::Socket());
                    add(*socket);
                    socket->signal_plug_added().connect(sigc::ptr_fun(plug_added));
                    socket->signal_plug_removed().connect(sigc::ptr_fun(plug_removed));
                    Gdk::NativeWindow plug_id;
                    infile >> plug_id;
                    infile.close();
                    socket->add_id(plug_id);
                }
                else
                {
                    Gtk::Label* label = Gtk::manage(
                            new 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)
    {
        Gtk::Main app(argc, argv);
        MySocketWindow win;
        app.run(win);
        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:

Chapter 20. Plugs and Sockets |  | Chapter 21. Timeouts, I/O and Idle Functions