2 #include "chimara-glk-private.h"
5 extern GPrivate *glk_data_key;
9 * @linkval: Set to nonzero to initiate hyperlink mode. Set to zero to disengage.
11 * Use this function to create hyperlinks in a textbuffer. It sets the current stream
12 * to hyperlink mode, after which text will become a hyperlink until hyperlink mode
13 * is turned off. If the current stream does not write to a textbuffer window, this function
16 * You can request hyperlink events with glk_request_hyperlink_event() to react
17 * to clicks on the link.
20 glk_set_hyperlink(glui32 linkval)
22 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
23 g_return_if_fail(glk_data->current_stream != NULL);
24 glk_set_hyperlink_stream(glk_data->current_stream, linkval);
28 * glk_set_hyperlink_stream:
29 * @str: The stream to set the hyperlink mode on.
30 * @linkval: Set to nonzero to initiate hyperlink mode. Set to zero to disengage.
32 * Use this function to create hyperlinks in a textbuffer. It sets a stream to a textbuffer
33 * window to hyperlink mode, after which text will become a hyperlink until hyperlink mode
34 * is turned off. Calling this function on a stream that does not write to a textbuffer does
37 * You can request hyperlink events with glk_request_hyperlink_event() to react
38 * to clicks on the link.
41 glk_set_hyperlink_stream(strid_t str, glui32 linkval)
43 g_return_if_fail(str != NULL);
44 g_return_if_fail(str->window != NULL);
45 g_return_if_fail(str->window->type == wintype_TextBuffer);
47 flush_window_buffer(str->window);
50 /* Turn off hyperlink mode */
51 str->hyperlink_mode = FALSE;
52 str->window->current_hyperlink = NULL;
56 /* Check whether a tag with the needed value already exists */
57 hyperlink_t *new_hyperlink = g_hash_table_lookup(str->window->hyperlinks, &linkval);
58 if(new_hyperlink == NULL) {
59 /* Create a new hyperlink with the requested value */
60 new_hyperlink = g_new0(struct hyperlink, 1);
61 new_hyperlink->value = linkval;
62 new_hyperlink->tag = gtk_text_tag_new(NULL);
63 new_hyperlink->event_handler = g_signal_connect( new_hyperlink->tag, "event", G_CALLBACK(on_hyperlink_clicked), new_hyperlink );
64 g_signal_handler_block(new_hyperlink->tag, new_hyperlink->event_handler);
65 new_hyperlink->window = str->window;
67 /* Add the new tag to the tag table of the textbuffer */
68 GtkTextBuffer *textbuffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(str->window->widget) );
69 GtkTextTagTable *tags = gtk_text_buffer_get_tag_table(textbuffer);
70 gtk_text_tag_table_add(tags, new_hyperlink->tag);
72 printf("inserting link %d\n", linkval);
74 gint *linkval_pointer = g_new0(gint, 1);
75 *linkval_pointer = linkval;
76 g_hash_table_insert(str->window->hyperlinks, linkval_pointer, new_hyperlink);
79 str->hyperlink_mode = TRUE;
80 str->window->current_hyperlink = new_hyperlink;
83 /* Internal function used to iterate over all the hyperlinks, unblocking the event handler */
85 hyperlink_unblock_event_handler(gpointer key, gpointer value, gpointer user_data)
87 hyperlink_t *link = (hyperlink_t *) value;
88 g_signal_handler_unblock(link->tag, link->event_handler);
89 printf("unblocking link %d\n", link->value);
92 /* Internal function used to iterate over all the hyperlinks, blocking the event handler */
94 hyperlink_block_event_handler(gpointer key, gpointer value, gpointer user_data)
96 hyperlink_t *link = (hyperlink_t *) value;
97 g_signal_handler_block(link->tag, link->event_handler);
101 glk_request_hyperlink_event(winid_t win)
103 VALID_WINDOW(win, return);
104 g_return_if_fail(win != NULL);
105 g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid);
107 g_hash_table_foreach(win->hyperlinks, hyperlink_unblock_event_handler, NULL);
112 glk_cancel_hyperlink_event(winid_t win)
114 VALID_WINDOW(win, return);
115 g_return_if_fail(win != NULL);
116 g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid);
118 g_hash_table_foreach(win->hyperlinks, hyperlink_block_event_handler, NULL);
122 on_hyperlink_clicked(GtkTextTag *tag, GObject *object, GdkEvent *event, GtkTextIter *iter, hyperlink_t *link)
124 ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(link->window->widget, CHIMARA_TYPE_GLK));
127 if(event->type == GDK_BUTTON_PRESS) {
128 event_throw(glk, evtype_Hyperlink, link->window, link->value, 0);