Use statically-allocated thread private data
[projects/chimara/chimara.git] / libchimara / hyperlink.c
index a2795bdc83fb0861e598a3adaa626d1fcb04c884..4545f9993a02b45a5e928aa1bd007129577893b6 100644 (file)
@@ -1,8 +1,10 @@
+#include <config.h>
+#include <glib/gi18n-lib.h>
 #include "hyperlink.h"
 #include "chimara-glk-private.h"
 #include "magic.h"
 
-extern GPrivate *glk_data_key;
+extern GPrivate glk_data_key;
 
 /**
  * glk_set_hyperlink:
@@ -14,7 +16,7 @@ extern GPrivate *glk_data_key;
 void 
 glk_set_hyperlink(glui32 linkval)
 {
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
        g_return_if_fail(glk_data->current_stream != NULL);
        glk_set_hyperlink_stream(glk_data->current_stream, linkval);
 }
@@ -56,7 +58,7 @@ glk_set_hyperlink_stream(strid_t str, glui32 linkval)
        g_return_if_fail(str != NULL);
        g_return_if_fail(str->type == STREAM_TYPE_WINDOW);
        g_return_if_fail(str->window != NULL);
-       g_return_if_fail(str->window->type == wintype_TextBuffer);
+       g_return_if_fail(str->window->type == wintype_TextBuffer || str->window->type == wintype_TextGrid);
 
        flush_window_buffer(str->window);
 
@@ -75,7 +77,8 @@ glk_set_hyperlink_stream(strid_t str, glui32 linkval)
                new_hyperlink->value = linkval;
                new_hyperlink->tag = gtk_text_tag_new(NULL);
                new_hyperlink->event_handler = g_signal_connect( new_hyperlink->tag, "event", G_CALLBACK(on_hyperlink_clicked), new_hyperlink );
-               g_signal_handler_block(new_hyperlink->tag, new_hyperlink->event_handler);
+               if(!str->window->hyperlink_event_requested)
+                       g_signal_handler_block(new_hyperlink->tag, new_hyperlink->event_handler);
                new_hyperlink->window = str->window;
 
                /* Add the new tag to the tag table of the textbuffer */
@@ -83,8 +86,6 @@ glk_set_hyperlink_stream(strid_t str, glui32 linkval)
                GtkTextTagTable *tags = gtk_text_buffer_get_tag_table(textbuffer);
                gtk_text_tag_table_add(tags, new_hyperlink->tag);
 
-               printf("inserting link %d\n", linkval);
-
                gint *linkval_pointer = g_new0(gint, 1);
                *linkval_pointer = linkval;
                g_hash_table_insert(str->window->hyperlinks, linkval_pointer, new_hyperlink);
@@ -100,7 +101,6 @@ hyperlink_unblock_event_handler(gpointer key, gpointer value, gpointer user_data
 {
        hyperlink_t *link = (hyperlink_t *) value;
        g_signal_handler_unblock(link->tag, link->event_handler);
-       printf("unblocking link %d\n", link->value);
 }
 
 /* Internal function used to iterate over all the hyperlinks, blocking the event handler */
@@ -138,8 +138,14 @@ glk_request_hyperlink_event(winid_t win)
 {
        VALID_WINDOW(win, return);
        g_return_if_fail(win != NULL);
-       g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid);
+       g_return_if_fail(win->type == wintype_TextBuffer || win->type == wintype_TextGrid);
+
+       if(win->hyperlink_event_requested) {
+               WARNING(_("Tried to request a hyperlink event on a window that already had a hyperlink request"));
+               return;
+       }
 
+       win->hyperlink_event_requested = TRUE;
        g_hash_table_foreach(win->hyperlinks, hyperlink_unblock_event_handler, NULL);
 
 }
@@ -156,8 +162,14 @@ glk_cancel_hyperlink_event(winid_t win)
 {
        VALID_WINDOW(win, return);
        g_return_if_fail(win != NULL);
-       g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid);
+       g_return_if_fail(win->type == wintype_TextBuffer || win->type == wintype_TextGrid);
+
+       if(!win->hyperlink_event_requested) {
+               WARNING(_("Tried to cancel a nonexistent hyperlink request"));
+               return;
+       }
 
+       win->hyperlink_event_requested = FALSE;
        g_hash_table_foreach(win->hyperlinks, hyperlink_block_event_handler, NULL);
 }
 
@@ -168,6 +180,8 @@ on_hyperlink_clicked(GtkTextTag *tag, GObject *object, GdkEvent *event, GtkTextI
        g_assert(glk);
 
        if(event->type == GDK_BUTTON_PRESS) {
+               link->window->hyperlink_event_requested = FALSE;
+               g_hash_table_foreach(link->window->hyperlinks, hyperlink_block_event_handler, NULL);
                event_throw(glk, evtype_Hyperlink, link->window, link->value, 0);
        }