+static gboolean call_close_block(GtkWidget *object, gpointer data)
+{
+ jub_close_block_t block = data;
+ block();
+
+ return FALSE;
+}
+
+struct init_params {
+ OFString *title;
+ JubGtkChatUI *object;
+ volatile BOOL *initialized;
+};
+
+static gboolean init(gpointer data)
+{
+ struct init_params *params = data;
+
+ GtkTextView *chat_view;
+ GtkEntry *chat_entry;
+
+ GtkBuilder *builder = gtk_builder_new();
+ gtk_builder_add_from_file(builder, "data/gtk/chat.ui", NULL);
+
+ params->object.chat_window = GTK_WIDGET(
+ gtk_builder_get_object(builder, "ChatWindow"));
+ g_signal_connect(params->object.chat_window, "destroy",
+ G_CALLBACK(call_close_block), params->object.closeBlock);
+
+
+ chat_view = GTK_TEXT_VIEW(
+ gtk_builder_get_object(builder, "ChatTextView"));
+ params->object.chat_buffer = gtk_text_view_get_buffer(chat_view);
+ gtk_text_buffer_create_tag(params->object.chat_buffer, "bold",
+ "weight", PANGO_WEIGHT_BOLD, NULL);
+
+ chat_entry = GTK_ENTRY(
+ gtk_builder_get_object(builder, "ChatEntry"));
+ struct call_send_block_params *send_params =
+ [params->object allocMemoryWithSize: sizeof(*send_params)];
+ send_params->block = params->object.sendBlock;
+ send_params->chat = params->object;
+ g_signal_connect(chat_entry, "key_release_event",
+ G_CALLBACK(call_send_block), send_params);
+
+ gtk_window_set_title(GTK_WINDOW(params->object.chat_window),
+ [params->title UTF8String]);
+ gtk_widget_show(params->object.chat_window);
+
+ *params->initialized = YES;
+
+ g_object_unref(builder);
+ [params->title release];
+ free(params);