山崎です。

説明が不足していました。すみません。

> viewerの EXTのところ、見せてもらえませんか?
> clickedの signal handler だけでも良いです。

コードが長いので、関係ありそうなところを説明を加えて送ります。

C/gtk viewer ウイジェットでは、"click_text" というシグナルを用意して、
文書中の先頭からの位置(整数)、user data(gpointer) をシグナルコールバック
に渡すことにしていました。

    static void
    gtk_text_browse_class_init (GtkTextBrowseClass *klass)
    { ...
       widget_class->button_press_event = gtk_text_browse_button_press;
       ...
       tb_signals[CLICK_TEXT] = 
         gtk_signal_new( "click_text", GTK_RUN_FIRST, object_class->type,
                        GTK_SIGNAL_OFFSET( GtkTextBrowseClass, click_text ),
                        gtk_marshal_NONE__INT_POINTER,
                        GTK_TYPE_NONE, 2, GTK_TYPE_INT,GTK_TYPE_POINTER); 
       ... }

    static gint
    gtk_text_browse_button_press(GtkWidget * widget, GdkEventButton * event)
    {
       gint pos;
       pos = gtk_text_browse_xy2pos(widget, (gint)event->x, (gint)event->y );
       if ( pos >= 0 ){ // ウイジェット中で文字がある位置をクリックした時
            gtk_signal_emit( GTK_OBJECT(widget), tb_signals[CLICK_TEXT],
	    pos, gtk_text_browse_get_data( widget, pos ) );
       } 
       return TRUE;
    }

user data は、ウイジェットに文字列を設定して行くときに、指定する仕様です。
C/gtk viewer 自体は、user data を保持するだけです。

   gint gtk_text_browse_append( GtkWidget * widget, char * str, 
                                GdkColor * fg, GdkColor * bg, gpointer data )

C/gtk viewer を、C によるテストプログラムでテストし、コールバックに
user data が渡るのは確認しました。(下の例では文字列のポインタ)

   static void clicked(GtkWidget *w, gint i,gpointer s)
   {
      printf("callback %d %s\n",i, s);
   }

   int main(int argc, char ** argv)
   { 
         ...
      gtk_text_browse_append( tb, "abcdefg", &Black, &White, "data-1" );
         ...                                    # user data ^^^^^^^^
      gtk_signal_connect(tb,"click_text",clicked,NULL);
   }

ruby/gtk viewer 拡張では、 user data として ruby のオブジェクトを設定する
仕様です。それで、C/gtk viewer の gtk_text_browse_append に対して、
append メソッドが user data の VALUE を gpointer としてそのまま渡していま
す。(省略したときは NULL を渡していて、ruby からは false となって見えます。
Qnil にすべきと思いますが)

   static VALUE
   tb_append(int argc, VALUE * argv, VALUE self)
   {
      ....      
      if ( argc >= 4 ){
         d = argv[3];     add_relative(self,d);
      } else {
         d = NULL;  // Qnil にするべきだと思う
      }
      gtk_text_browse_append(GTK_WIDGET(tb), str, fg, bg, d);
      ...
   }

また、C/gtkで 文書中の位置からuser data を返す gtk_text_browse_get_data
に対して、get_data(pos) メソッドがあり、gtk_text_browse_get_data で返る
gpointer を、そのまま VALUE として返します。スクリプトでこのメソッドを
呼ぶ分には、設定したオブジェクトが返ってきます。

テストスクリプトのシグナルハンドラは以下の通りです。

   t.signal_connect("click_text") { |*a| p a }

クリックしたときの結果は下の通りです。
 (1) user data を省略した場所をクリック(user data が NULL)
     Gtk-CRITICAL **: file gtkobject.c: line 1144 (gtk_object_get_user_data):
                            assertion `object != NULL' failed.
     [#<Gtk::TextBrowse: id=0x8160798>, 221, false]
                 (self、 位置、user data です。)
		 
 (2) user data (nil や文字列を指定) のある場所をクリック
      Segmentation fault

(1)の結果と、rbgtk.c から、「arg_to_value 中で GTK_TYPE_POINTER 型は 
gtk のオブジェクトであるとされているよう」と思ったのですが ...
(2)は、仕様変更後出なくなったので調べていません。(多分(1)と同じ理由だと
思っていたので)

--------------------------------------------------------------------
山崎