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