Reset Glk style hints at beginning of program
[projects/chimara/chimara.git] / libchimara / style.c
index dc0d4bb942acb13d4e73ddbeeca3bac7131e1f4f..b4aa029367a61443955c413b832235a9caea33b3 100644 (file)
@@ -8,7 +8,7 @@
 #include "stream.h"
 #include "strio.h"
 
-extern GPrivate *glk_data_key;
+extern GPrivate glk_data_key;
 
 static gboolean style_accept(GScanner *scanner, GTokenType token);
 static gboolean style_accept_style_selector(GScanner *scanner, ChimaraGlk *glk);
@@ -34,7 +34,7 @@ static void style_cascade_colors(GtkTextTag *tag, GtkTextTag *glk_tag, GtkTextTa
 void
 glk_set_style(glui32 styl)
 {
-       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_style_stream(glk_data->current_stream, styl);
 }
@@ -53,7 +53,6 @@ static const gchar* TAG_NAMES[] = {
        "user1",
        "user2",
        "hyperlink",
-       "pager",
        "default"
 };
 
@@ -123,23 +122,13 @@ glk_set_style_stream(strid_t str, glui32 styl) {
        str->glk_style = (gchar*) get_glk_tag_name(styl);
 }
 
-/* Internal function: call this to initialize the layout of the 'more' prompt. */
-void
-style_init_more_prompt(winid_t win)
-{
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
-
-       win->pager_layout = gtk_widget_create_pango_layout(win->widget, "More");
-       pango_layout_set_attributes(win->pager_layout, glk_data->pager_attr_list);
-}
-
 /* Internal function: call this to initialize the default styles to a textbuffer. */
 void
 style_init_textbuffer(GtkTextBuffer *buffer)
 {
        g_return_if_fail(buffer != NULL);
 
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
 
        /* Place the default text tags in the textbuffer's tag table */
        g_hash_table_foreach(glk_data->styles->text_buffer, style_copy_tag_to_textbuffer, gtk_text_buffer_get_tag_table(buffer));
@@ -157,8 +146,8 @@ void
 style_init_textgrid(GtkTextBuffer *buffer)
 {
        g_return_if_fail(buffer != NULL);
-       
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
 
        /* Place the default text tags in the textbuffer's tag table */
        g_hash_table_foreach(glk_data->styles->text_grid, style_copy_tag_to_textbuffer, gtk_text_buffer_get_tag_table(buffer));
@@ -186,36 +175,43 @@ GtkTextTag *
 gtk_text_tag_copy(GtkTextTag *tag)
 {
        GtkTextTag *copy;
+       char *tag_name;
+       GParamSpec **properties;
+       unsigned nprops, count;
 
        g_return_val_if_fail(tag != NULL, NULL);
 
-       copy = gtk_text_tag_new(tag->name);
-       gtk_text_attributes_copy_values(tag->values, copy->values);
-       
-       #define _COPY_FLAG(flag) copy->flag = tag->flag
-               _COPY_FLAG (bg_color_set);
-               _COPY_FLAG (bg_color_set);
-               _COPY_FLAG (bg_stipple_set);
-               _COPY_FLAG (fg_color_set);
-               _COPY_FLAG (fg_stipple_set);
-               _COPY_FLAG (justification_set);
-               _COPY_FLAG (left_margin_set);
-               _COPY_FLAG (indent_set);
-               _COPY_FLAG (rise_set);
-               _COPY_FLAG (strikethrough_set);
-               _COPY_FLAG (right_margin_set);
-               _COPY_FLAG (pixels_above_lines_set);
-               _COPY_FLAG (pixels_below_lines_set);
-               _COPY_FLAG (pixels_inside_wrap_set);
-               _COPY_FLAG (tabs_set);
-               _COPY_FLAG (underline_set);
-               _COPY_FLAG (wrap_mode_set);
-               _COPY_FLAG (bg_full_height_set);
-               _COPY_FLAG (invisible_set);
-               _COPY_FLAG (editable_set);
-               _COPY_FLAG (language_set);
-               _COPY_FLAG (scale_set);
-       #undef _COPY_FLAG
+       g_object_get(tag, "name", &tag_name, NULL);
+       copy = gtk_text_tag_new(tag_name);
+       g_free(tag_name);
+
+       /* Copy all the original tag's properties to the new tag */
+       properties = g_object_class_list_properties( G_OBJECT_GET_CLASS(tag), &nprops );
+       for(count = 0; count < nprops; count++) {
+
+               /* Only copy properties that are readable, writable, not construct-only,
+               and not deprecated */
+               GParamFlags flags = properties[count]->flags;
+               if(flags & G_PARAM_CONSTRUCT_ONLY
+                       || flags & G_PARAM_DEPRECATED
+                       || !(flags & G_PARAM_READABLE)
+                       || !(flags & G_PARAM_WRITABLE))
+                       continue;
+
+               const char *prop_name = g_param_spec_get_name(properties[count]);
+               GValue prop_value = G_VALUE_INIT;
+
+               g_value_init( &prop_value, G_PARAM_SPEC_VALUE_TYPE(properties[count]) );
+               g_object_get_property( G_OBJECT(tag), prop_name, &prop_value );
+               /* Don't copy the PangoTabArray if it is NULL, that prints a warning */
+               if(strcmp(prop_name, "tabs") == 0 && g_value_get_boxed(&prop_value) == NULL) {
+                       g_value_unset(&prop_value);
+                       continue;
+               }
+               g_object_set_property( G_OBJECT(copy), prop_name, &prop_value );
+               g_value_unset(&prop_value);
+       }
+       g_free(properties);
 
        /* Copy the data that was added manually */
        gpointer reverse_color = g_object_get_data( G_OBJECT(tag), "reverse-color" );
@@ -235,8 +231,6 @@ style_init(ChimaraGlk *glk)
        
        GHashTable *default_text_grid_styles = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
        GHashTable *default_text_buffer_styles = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
-       GHashTable *glk_text_grid_styles = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
-       GHashTable *glk_text_buffer_styles = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
        GtkTextTag *tag;
 
        /* Initialise the default styles for a text grid */
@@ -336,14 +330,23 @@ style_init(ChimaraGlk *glk)
        g_object_set(tag, "foreground", "#0000ff", "foreground-set", TRUE, "underline", PANGO_UNDERLINE_SINGLE, "underline-set", TRUE, NULL);
        g_hash_table_insert(default_text_buffer_styles, "hyperlink", tag);
 
-       GtkTextTag *pager_tag = gtk_text_tag_new("pager");
-       g_object_set(pager_tag, "family", "Monospace", "family-set", TRUE, "foreground", "#ffffff", "foreground-set", TRUE, "background", "#000000", "background-set", TRUE, NULL);
-       g_hash_table_insert(default_text_buffer_styles, "pager", pager_tag);
-       text_tag_to_attr_list(pager_tag, priv->pager_attr_list);
-
        priv->styles->text_grid = default_text_grid_styles;
        priv->styles->text_buffer = default_text_buffer_styles;
 
+       style_reset_glk(glk);
+}
+
+/* Reset the style hints set from the Glk program to be blank. Call this when
+starting a new game so that style hints from the previous game don't carry
+over. */
+void
+style_reset_glk(ChimaraGlk *glk)
+{
+       CHIMARA_GLK_USE_PRIVATE(glk, priv);
+
+       GHashTable *glk_text_grid_styles = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
+       GHashTable *glk_text_buffer_styles = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
+       GtkTextTag *tag;
 
        /* Initialize the GLK styles to empty tags */
        int i;
@@ -389,9 +392,6 @@ scan_css_file(GScanner *scanner, ChimaraGlk *glk)
        }
 
        g_scanner_destroy(scanner);
-
-       /* Update the pager prompt to the new style */
-       style_update(glk);
 }
 
 /* Internal function: parses a token */
@@ -654,7 +654,7 @@ apply_stylehint_to_tag(GtkTextTag *tag, glui32 wintype, glui32 styl, glui32 hint
 {
        g_return_if_fail(tag != NULL);
 
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
        GObject *tag_object = G_OBJECT(tag);
 
        gint reverse_color = GPOINTER_TO_INT( g_object_get_data(tag_object, "reverse-color") );
@@ -814,7 +814,7 @@ query_tag(GtkTextTag *tag, glui32 wintype, glui32 hint)
 
        g_return_val_if_fail(tag != NULL, 0);
 
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
 
        switch(hint) {
        case stylehint_Indentation:
@@ -909,7 +909,7 @@ glk_stylehint_set(glui32 wintype, glui32 styl, glui32 hint, glsi32 val)
        g_printf("glk_stylehint_set(wintype=%d, styl=%d, hint=%d, val=%d)\n", wintype, styl, hint, val);
 #endif
 
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
 
        GtkTextTag *to_change;
        if(wintype == wintype_TextBuffer || wintype == wintype_AllTypes) {
@@ -944,7 +944,7 @@ glk_stylehint_clear(glui32 wintype, glui32 styl, glui32 hint)
        g_printf("glk_stylehint_clear(wintype=%d, styl=%d, hint=%d)\n", wintype, styl, hint);
 #endif
 
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
        GtkTextTag *tag;
 
        switch(wintype) {
@@ -1070,7 +1070,7 @@ glk_style_measure(winid_t win, glui32 styl, glui32 hint, glui32 *result)
        g_printf("glk_style_measure(win->rock=%d, styl=%d, hint=%d, result=...)\n", win->rock, styl, hint);
 #endif
 
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
        GtkTextTag *tag;
 
        switch(win->type) {
@@ -1096,7 +1096,7 @@ glk_style_measure(winid_t win, glui32 styl, glui32 hint, glui32 *result)
 PangoFontDescription *
 get_current_font(guint32 wintype)
 {
-       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
        GHashTable *styles, *glk_styles;
        PangoFontDescription *font;
 
@@ -1199,16 +1199,6 @@ text_tag_to_attr_list(GtkTextTag *tag, PangoAttrList *list)
        }
 }
 
-/* Update pager tag */
-void
-style_update(ChimaraGlk *glk)
-{
-       CHIMARA_GLK_USE_PRIVATE(glk, priv);
-
-       GtkTextTag *pager_tag = GTK_TEXT_TAG( g_hash_table_lookup(priv->styles->text_buffer, "pager") );
-       text_tag_to_attr_list(pager_tag, priv->pager_attr_list);
-}
-
 /* Determine the current colors used to render the text for a given stream. 
  * This can be set in a number of places */
 static void
@@ -1273,7 +1263,8 @@ style_stream_colors(strid_t str, GdkColor **foreground, GdkColor **background)
        }
 }
 
-/* Apply styles to a segment of text in a GtkTextBuffer
+/* Apply styles to a segment of text in a GtkTextBuffer, combining multiple
+ * GtkTextTags.
  */
 void
 style_apply(winid_t win, GtkTextIter *start, GtkTextIter *end)