Ejemplo de «Plugs» y «Sockets».

El siguiente es un ejemplo simple del uso de «sockets» y «plugs». El método de comunicación entre los procesos se mantiene simple deliberadamente: el Plug escribe su ID en un archivo de texto llamado plug.id y el proceso con el «socket» lee el ID de este archivo. En un programa real, probablemente quiera usar un método más sofisticado de comunicación entre procesos.

Código fuente

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)
      {
        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));
        ::Window plug_id = 0;
        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)
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
  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)
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
  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;
}

Este ejemplo crea dos programas ejecutables: socket y plug. La idea es que socket tenga una ventana de aplicación en la que se empotre un widget del programa plug. Dada la manera en la que este ejemplo está diseñado, plug debe estar en ejecución antes de iniciar socket. Para ver el ejemplo en acción, ejecute los siguientes comandos en orden desde la carpeta de ejemplos:

Ejecute el programa plug y envíelo a segundo plano (o simplemente use otra terminal).

$ ./plug &

Después de esto debería ver algo así:

The window ID is: 69206019

Entonces, ejecute el programa socket:

$ ./socket

Después de haber ejecutado socket, debería ver la siguiente salida en la terminal:

I've been embedded.
A plug was added

La primera línea de la salida es de plug, después de que se le ha notificado que se empotró en un Socket. La segunda línea la emite socket en respuesta a su señal plug_added. Si todo se realizó como se describió anteriormente, la ventana socket debería verse más o menos así:

Si, por alguna razón, el Socket no pudiera adjuntar el Plug, la ventana se vería más o menos así: