プラグとソケットの例

以下のシンプルな例ではソケットとプラグを使っています。ここでのプロセス間通信の方法はわざと非常にシンプルなものに留めています: Plugオブジェクトは自身のIDをplug.idというテキストファイルに出力します。そして、ソケットを持つプロセスがこのファイルからIDを読み込みます。実際のプログラムではもうすこし洗練されたプロセス間通信を行いたいと思われるかもしれません。

Source Code

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

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

この例では二つの実行可能プログラムを作成しています: socketplugです。概観としては、socketはウィンドウをもつアプリケーションであり、ここにplugプログラムのウィジットが埋め込まれます。この例はplugを最初に起動しておき、socketを後で動かすというようにデザインされています。ですから、例を動作させるには以下のコマンドを例のディレクトリ内で順番に実行してください:

plugプログラムを起動し、バックグラウンドに送る(あるいは別の端末を使ってもよい)。

$ ./plug &

こうすると次のようなものが出るはずです:

The window ID is: 69206019

それではsocketプログラムを起動しましょう:

$ ./socket

socketが起動されると、次の出力が端末に出るはずです:

I've been embedded.
A plug was added

出力の最初の行はplugからのメッセージであり、プラグがSocketオブジェクトの中に埋め込まれたときに出力するものです。二番目の行はsocketプログラムがplug_addedシグナルに答えて出力しています。全てがこのようにうまくいけば、socketウィンドウはだいたい次のようになっているはずです:

何らかの理由でSocketPlugに接続することが出来なかった場合、ウィンドウはこのようになります: