Exemple #1
0
void
debug_show_value(GValue *gval)
{
	GType tp;

	tp = G_VALUE_TYPE(gval);
	if (tp == G_TYPE_STRING)
	{
		g_message("Type %s value %s", "string", g_value_get_string(gval));
	}
	else if (tp == G_TYPE_INT)
	{
		g_message("Type %s value %d", "int", g_value_get_int(gval));
	}
	else if (tp == G_TYPE_INT64)
	{
		g_message("Type %s value %" PRId64, "int64", g_value_get_int64(gval));
	}
	else if (tp == G_TYPE_DOUBLE)
	{
		g_message("Type %s value %f", "double", g_value_get_double(gval));
	}
	else if (tp == G_TYPE_BOOLEAN)
	{
		g_message("Type %s value %d", "boolean", g_value_get_boolean(gval));
	}
	else if (tp == ghb_array_get_type())
	{
		g_message("Type %s", "boolean");
	}
	else if (tp == ghb_dict_get_type())
	{
		g_message("Type %s", "dict");
	}
}
Exemple #2
0
void
debug_show_type(GType tp)
{
	const gchar *str = "unknown";
	if (tp == G_TYPE_STRING)
	{
		str ="string";
	}
	else if (tp == G_TYPE_INT)
	{
		str ="int";
	}
	else if (tp == G_TYPE_INT64)
	{
		str ="int64";
	}
	else if (tp == G_TYPE_DOUBLE)
	{
		str ="double";
	}
	else if (tp == G_TYPE_BOOLEAN)
	{
		str ="bool";
	}
	else if (tp == ghb_array_get_type())
	{
		str ="array";
	}
	else if (tp == ghb_dict_get_type())
	{
		str ="dict";
	}
	g_debug("Type %s", str);
}
Exemple #3
0
GValue*
ghb_dict_value_new()
{
	GHashTable *dict;
	GValue *gval = ghb_value_new(ghb_dict_get_type());
	dict = g_hash_table_new_full(g_str_hash, g_str_equal,
								dict_delete_key, dict_delete_value);
	g_value_take_boxed(gval, dict);
	return gval;
}
static void
end_element(
	GMarkupParseContext *ctx, 
	const gchar *name, 
	gpointer ud,
	GError **error)
{
	parse_data_t *pd = (parse_data_t*)ud;
	gint id;
	union 
	{
		gint id;
		gpointer pid;
	} start_id;
	gint ii;

	// Check to see if the first element found has been closed
	// If so, ignore any junk following it.
	if (pd->closed_top)
		return;

	for (ii = 0; ii < TAG_MAP_SZ; ii++)
	{
		if (strcmp(name, tag_map[ii].tag) == 0)
		{
			id = tag_map[ii].id;
			break;
		}
	}
	if (ii == TAG_MAP_SZ)
	{
		g_warning("Unrecognized start tag (%s)", name);
		return;
	}
	start_id.pid = g_queue_pop_head(pd->tag_stack);
	if (start_id.id != id)
		g_warning("start tag != end tag: (%s %d) %d", name, id, id);

	GValue *gval = NULL;
	GValue *current = g_queue_peek_head(pd->stack);
	GType gtype = 0;
	switch (id)
	{
		case R_SECTION:
		{
			g_queue_pop_head(pd->stack);
		} break;
	}
	if (gval)
	{
		// Get the top of the data structure stack and if it's an array
		// or dict, add the current element
		if (current == NULL)
		{
			pd->plist = gval;
			pd->closed_top = TRUE;
			return;
		}
		gtype = G_VALUE_TYPE(current);
		if (gtype == ghb_array_get_type())
		{
			ghb_array_append(current, gval);
		}
		else if (gtype == ghb_dict_get_type())
		{
			if (pd->key == NULL)
			{
				g_warning("No key for dictionary item");
				ghb_value_free(gval);
			}
			else
			{
				ghb_dict_insert(current, g_strdup(pd->key), gval);
			}
		}
		else
		{
			g_error("Invalid container type. This shouldn't happen");
		}
	}
	if (g_queue_is_empty(pd->tag_stack))
		pd->closed_top = TRUE;
}
static void
start_element(
	GMarkupParseContext *ctx, 
	const gchar *tag, 
	const gchar **attr_names,
	const gchar **attr_values,
	gpointer ud,
	GError **error)
{
	parse_data_t *pd = (parse_data_t*)ud;
	union 
	{
		gint id;
		gpointer pid;
	} id;
	gint ii;

	// Check to see if the first element found has been closed
	// If so, ignore any junk following it.
	if (pd->closed_top)
		return;

	for (ii = 0; ii < TAG_MAP_SZ; ii++)
	{
		if (strcmp(tag, tag_map[ii].tag) == 0)
		{
			id.id = tag_map[ii].id;
			break;
		}
	}
	if (ii == TAG_MAP_SZ)
	{
		g_warning("Unrecognized start tag (%s)", tag);
		return;
	}
	g_queue_push_head(pd->tag_stack, id.pid);
	GType gtype = 0;
	GValue *gval = NULL;
	GValue *current = g_queue_peek_head(pd->stack);
	switch (id.id)
	{
		case R_SECTION:
		{
			const gchar *name;

			name = lookup_attr_value("name", attr_names, attr_values);
			if (name && strcmp(name, "icons") == 0)
			{
				gval = ghb_dict_value_new();
				if (pd->key) g_free(pd->key);
				pd->key = g_strdup(name);
				g_queue_push_head(pd->stack, gval);
			}
		} break;
		case R_ICON:
		{
			gchar *filename;
			const gchar *name;

			name = lookup_attr_value("file", attr_names, attr_values);
			filename = find_file(inc_list, name);
			name = lookup_attr_value("name", attr_names, attr_values);
			if (filename && name)
			{
				ghb_rawdata_t *rd;
				GdkPixbuf *pb;
				GError *err = NULL;

				pb = gdk_pixbuf_new_from_file(filename, &err);
				if (pb == NULL)
				{
					g_warning("Failed to open icon file %s: %s", filename, err->message);
					break;
				}
				gval = ghb_dict_value_new();
				int colorspace = gdk_pixbuf_get_colorspace(pb);
				gboolean alpha = gdk_pixbuf_get_has_alpha(pb);
				int width = gdk_pixbuf_get_width(pb);
				int height = gdk_pixbuf_get_height(pb);
				int bps = gdk_pixbuf_get_bits_per_sample(pb);
				int rowstride = gdk_pixbuf_get_rowstride(pb);

				ghb_dict_insert(gval, g_strdup("colorspace"), 
								ghb_int_value_new(colorspace));
				ghb_dict_insert(gval, g_strdup("alpha"), 
								ghb_boolean_value_new(alpha));
				ghb_dict_insert(gval, g_strdup("width"), 
								ghb_int_value_new(width));
				ghb_dict_insert(gval, g_strdup("height"), 
								ghb_int_value_new(height));
				ghb_dict_insert(gval, g_strdup("bps"), 
								ghb_int_value_new(bps));
				ghb_dict_insert(gval, g_strdup("rowstride"), 
								ghb_int_value_new(rowstride));

				rd = g_malloc(sizeof(ghb_rawdata_t));
				rd->data = gdk_pixbuf_get_pixels(pb);
				rd->size = height * rowstride * bps / 8;
				GValue *data = ghb_rawdata_value_new(rd);
				ghb_dict_insert(gval, g_strdup("data"), data);

				if (pd->key) g_free(pd->key);
				pd->key = g_strdup(name);
				g_free(filename);
			}
			else
			{
				g_warning("%s:missing a requried attribute", name);
    			exit(EXIT_FAILURE);
			}
		} break;
		case R_PLIST:
		{
			gchar *filename;
			const gchar *name;

			name = lookup_attr_value("file", attr_names, attr_values);
			filename = find_file(inc_list, name);
			name = lookup_attr_value("name", attr_names, attr_values);
			if (filename && name)
			{
				gval = ghb_plist_parse_file(filename);
				if (pd->key) g_free(pd->key);
				pd->key = g_strdup(name);
				g_free(filename);
			}
			else
			{
				g_warning("%s:missing a requried attribute", name);
    			exit(EXIT_FAILURE);
			}
		} break;
		case R_STRING:
		{
			gchar *filename;
			const gchar *name;

			name = lookup_attr_value("file", attr_names, attr_values);
			filename = find_file(inc_list, name);
			name = lookup_attr_value("name", attr_names, attr_values);
			if (filename && name)
			{
				gval = read_string_from_file(filename);
				if (pd->key) g_free(pd->key);
				pd->key = g_strdup(name);
				g_free(filename);
			}
			else
			{
				g_warning("%s:missing a requried attribute", name);
    			exit(EXIT_FAILURE);
			}
		} break;
	}
	// Add the element to the current container
	if (gval)
	{ // There's an element to add
		if (current == NULL)
		{
			pd->plist = gval;
			return;
		}
		gtype = G_VALUE_TYPE(current);
		if (gtype == ghb_array_get_type())
		{
			ghb_array_append(current, gval);
		}
		else if (gtype == ghb_dict_get_type())
		{
			if (pd->key == NULL)
			{
				g_warning("No key for dictionary item");
				ghb_value_free(gval);
			}
			else
			{
				ghb_dict_insert(current, g_strdup(pd->key), gval);
			}
		}
		else
		{
			g_error("Invalid container type. This shouldn't happen");
		}
	}
}
Exemple #6
0
static void
start_element(
	GMarkupParseContext *ctx, 
	const gchar *name, 
	const gchar **attr_names,
	const gchar **attr_values,
	gpointer ud,
	GError **error)
{
	parse_data_t *pd = (parse_data_t*)ud;
	union 
	{
		gint id;
		gpointer pid;
	} id;
	gint ii;

	// Check to see if the first element found has been closed
	// If so, ignore any junk following it.
	if (pd->closed_top)
		return;

	for (ii = 0; ii < TAG_MAP_SZ; ii++)
	{
		if (strcmp(name, tag_map[ii].tag) == 0)
		{
			id.id = tag_map[ii].id;
			break;
		}
	}
	if (ii == TAG_MAP_SZ)
	{
		g_warning("Unrecognized start tag (%s)", name);
		return;
	}
	g_queue_push_head(pd->tag_stack, id.pid);
	GType gtype = 0;
	GValue *gval = NULL;
	GValue *current = g_queue_peek_head(pd->stack);
	switch (id.id)
	{
		case P_PLIST:
		{ // Ignore
		} break;
		case P_KEY:
		{
			if (pd->key) g_free(pd->key);
			pd->key = NULL;
		} break;
		case P_DICT:
		{
			gval = ghb_dict_value_new();
			g_queue_push_head(pd->stack, gval);
		} break;
		case P_ARRAY:
		{
			gval = ghb_array_value_new(128);
			g_queue_push_head(pd->stack, gval);
		} break;
		case P_INTEGER:
		{
		} break;
		case P_REAL:
		{
		} break;
		case P_STRING:
		{
		} break;
		case P_DATE:
		{
		} break;
		case P_TRUE:
		{
		} break;
		case P_FALSE:
		{
		} break;
		case P_DATA:
		{
		} break;
	}
	// Add the element to the current container
	if (gval)
	{ // There's an element to add
		if (current == NULL)
		{
			pd->plist = gval;
			return;
		}
		gtype = G_VALUE_TYPE(current);
		if (gtype == ghb_array_get_type())
		{
			ghb_array_append(current, gval);
		}
		else if (gtype == ghb_dict_get_type())
		{
			if (pd->key == NULL)
			{
				g_warning("No key for dictionary item");
				ghb_value_free(gval);
			}
			else
			{
				ghb_dict_insert(current, g_strdup(pd->key), gval);
			}
		}
		else
		{
			g_error("Invalid container type. This shouldn't happen");
		}
	}
}
Exemple #7
0
static void
gval_write(FILE *file, GValue *gval)
{
	static gint indent = 0;
	gint ii;
	GType gtype;

	if (gval == NULL) return;
	gtype = G_VALUE_TYPE(gval);
	if (gtype == ghb_array_get_type())
	{
		GValue *val;
		gint count;

		indent_fprintf(file, indent, "<array>\n");
		indent++;
		count = ghb_array_len(gval);
		for (ii = 0; ii < count; ii++)
		{
			val = ghb_array_get_nth(gval, ii);
			gval_write(file, val);
		}
		indent--;
		indent_fprintf(file, indent, "</array>\n");
	}
	else if (gtype == ghb_dict_get_type())
	{
		GValue *val;
		GHashTable *dict = g_value_get_boxed(gval);
		GList *link, *keys;
		keys = g_hash_table_get_keys(dict);
		// Sort the dictionary.  Not really necessray, but it makes
		// finding things easier
		keys = g_list_sort(keys, key_cmp);
		link = keys;
		indent_fprintf(file, indent, "<dict>\n");
		indent++;
		while (link)
		{
			gchar *key = (gchar*)link->data;
			val = g_hash_table_lookup(dict, key);
			indent_fprintf(file, indent, "<key>%s</key>\n", key);
			gval_write(file, val);
			link = link->next;
		}
		indent--;
		indent_fprintf(file, indent, "</dict>\n");
		g_list_free(keys);
	}
	else if (gtype == G_TYPE_BOOLEAN)
	{
		gchar *tag;
		if (g_value_get_boolean(gval))
		{
			tag = "true";
		}
		else
		{
			tag = "false";
		}
		indent_fprintf(file, indent, "<%s />\n", tag);
	}
	else if (gtype == g_date_get_type())
	{
		GDate *date;
		date = g_value_get_boxed(gval);
		indent_fprintf(file, indent, "<date>%d-%d-%d</date>\n", 
			g_date_get_year(date),
			g_date_get_month(date),
			g_date_get_day(date)
		);
	}
	else if (gtype == ghb_rawdata_get_type())
	{
		ghb_rawdata_t *data;
		gchar *base64;
		data = g_value_get_boxed(gval);
		base64 = g_base64_encode(data->data, data->size);
		indent_fprintf(file, indent, "<data>\n");
		indent_fprintf(file, 0, "%s\n", base64);
		indent_fprintf(file, indent, "</data>\n");
		g_free(base64);
	}
	else if (gtype == G_TYPE_DOUBLE)
	{
		gdouble val = g_value_get_double(gval);
		indent_fprintf(file, indent, "<real>%.17g</real>\n", val);
	}
	else if (gtype == G_TYPE_INT64)
	{
		gint val = g_value_get_int64(gval);
		indent_fprintf(file, indent, "<integer>%d</integer>\n", val);
	}
	else if (gtype == G_TYPE_INT)
	{
		gint val = g_value_get_int(gval);
		indent_fprintf(file, indent, "<integer>%d</integer>\n", val);
	}
	else if (gtype == G_TYPE_STRING)
	{
		const gchar *str = g_value_get_string(gval);
		gchar *esc = g_markup_escape_text(str, -1);
		indent_fprintf(file, indent, "<string>%s</string>\n", esc);
		g_free(esc);
	}
	else
	{
		// Try to make anything thats unrecognized into a string
		const gchar *str;
		GValue val = {0,};
		g_value_init(&val, G_TYPE_STRING);
		if (g_value_transform(gval, &val))
		{
			str = g_value_get_string(&val);
			gchar *esc = g_markup_escape_text(str, -1);
			indent_fprintf(file, indent, "<string>%s</string>\n", esc);
			g_free(esc);
		}
		else
		{
			g_message("failed to transform");
		}
		g_value_unset(&val);
	}
}
Exemple #8
0
static void
end_element(
	GMarkupParseContext *ctx, 
	const gchar *name, 
	gpointer ud,
	GError **error)
{
	parse_data_t *pd = (parse_data_t*)ud;
	gint id;
	union 
	{
		gint id;
		gpointer pid;
	} start_id;
	gint ii;

	// Check to see if the first element found has been closed
	// If so, ignore any junk following it.
	if (pd->closed_top)
		return;

	for (ii = 0; ii < TAG_MAP_SZ; ii++)
	{
		if (strcmp(name, tag_map[ii].tag) == 0)
		{
			id = tag_map[ii].id;
			break;
		}
	}
	if (ii == TAG_MAP_SZ)
	{
		g_warning("Unrecognized start tag (%s)", name);
		return;
	}
	start_id.pid = g_queue_pop_head(pd->tag_stack);
	if (start_id.id != id)
		g_warning("start tag != end tag: (%s %d) %d", name, id, id);

	GValue *gval = NULL;
	GValue *current = g_queue_peek_head(pd->stack);
	GType gtype = 0;
	switch (id)
	{
		case P_PLIST:
		{ // Ignore
		} break;
		case P_KEY:
		{
			if (pd->key) g_free(pd->key);
			pd->key = g_strdup(pd->value);
			return;
		} break;
		case P_DICT:
		{
			g_queue_pop_head(pd->stack);
		} break;
		case P_ARRAY:
		{
			g_queue_pop_head(pd->stack);
		} break;
		case P_INTEGER:
		{
			gint64 val = g_strtod(pd->value, NULL);
			gval = ghb_int64_value_new(val);
		} break;
		case P_REAL:
		{
			gdouble val = g_strtod(pd->value, NULL);
			gval = ghb_double_value_new(val);
		} break;
		case P_STRING:
		{
			gval = ghb_string_value_new(pd->value);
		} break;
		case P_DATE:
		{
			GDate date;
			GTimeVal time;
			g_time_val_from_iso8601(pd->value, &time);
			g_date_set_time_val(&date, &time);
			gval = ghb_date_value_new(&date);
		} break;
		case P_TRUE:
		{
			gval = ghb_boolean_value_new(TRUE);
		} break;
		case P_FALSE:
		{
			gval = ghb_boolean_value_new(FALSE);
		} break;
		case P_DATA:
		{
			ghb_rawdata_t *data;
			data = g_malloc(sizeof(ghb_rawdata_t));
			data->data = g_base64_decode(pd->value, &(data->size));
			gval = ghb_rawdata_value_new(data);
		} break;
	}
	if (gval)
	{
		// Get the top of the data structure stack and if it's an array
		// or dict, add the current element
		if (current == NULL)
		{
			pd->plist = gval;
			pd->closed_top = TRUE;
			return;
		}
		gtype = G_VALUE_TYPE(current);
		if (gtype == ghb_array_get_type())
		{
			ghb_array_append(current, gval);
		}
		else if (gtype == ghb_dict_get_type())
		{
			if (pd->key == NULL)
			{
				g_warning("No key for dictionary item");
				ghb_value_free(gval);
			}
			else
			{
				ghb_dict_insert(current, g_strdup(pd->key), gval);
			}
		}
		else
		{
			g_error("Invalid container type. This shouldn't happen");
		}
	}
	if (g_queue_is_empty(pd->stack))
		pd->closed_top = TRUE;
}
Exemple #9
0
void
ghb_update_widget(GtkWidget *widget, const GValue *value)
{
    GType type;
    gchar *str;
    gint ival;
    gdouble dval;

    g_debug("ghb_update_widget");
    type = G_VALUE_TYPE(value);
    if (type == ghb_array_get_type() || type == ghb_dict_get_type())
        return;
    if (value == NULL) return;
    str = ghb_value_string(value);
    ival = ghb_value_int(value);
    dval = ghb_value_double(value);
    type = G_OBJECT_TYPE(widget);

    if (type == GTK_TYPE_ENTRY)
    {
        g_debug("entry");
        gtk_entry_set_text((GtkEntry*)widget, str);
    }
    else if (type == GTK_TYPE_RADIO_BUTTON)
    {
        g_debug("radio button");
        if (ival)
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), !!ival);
    }
    else if (type == GTK_TYPE_CHECK_BUTTON)
    {
        g_debug("check button");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
    }
    else if (type == GTK_TYPE_TOGGLE_TOOL_BUTTON)
    {
        g_debug("toggle button");
        gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), ival);
    }
    else if (type == GTK_TYPE_TOGGLE_BUTTON)
    {
        g_debug("toggle button");
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
    }
    else if (type == GTK_TYPE_CHECK_MENU_ITEM)
    {
        g_debug("check menu item");
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ival);
    }
    else if (type == GTK_TYPE_COMBO_BOX)
    {
        GtkTreeModel *store;
        GtkTreeIter iter;
        gchar *shortOpt;
        gdouble ivalue;
        gboolean foundit = FALSE;

        g_debug("combo (%s)", str);
        store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
        if (gtk_tree_model_get_iter_first (store, &iter))
        {
            do
            {
                gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
                if (strcasecmp(shortOpt, str) == 0)
                {
                    gtk_combo_box_set_active_iter (
                        GTK_COMBO_BOX(widget), &iter);
                    g_free(shortOpt);
                    foundit = TRUE;
                    break;
                }
                g_free(shortOpt);
            } while (gtk_tree_model_iter_next (store, &iter));
        }
        if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
        {
            do
            {
                gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
                if ((gint)ivalue == ival || ivalue == dval)
                {
                    gtk_combo_box_set_active_iter (
                        GTK_COMBO_BOX(widget), &iter);
                    foundit = TRUE;
                    break;
                }
            } while (gtk_tree_model_iter_next (store, &iter));
        }
        if (!foundit)
        {
            if (gtk_combo_box_get_has_entry(GTK_COMBO_BOX(widget)))
            {
                GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)));
                if (entry)
                {
                    gtk_entry_set_text (entry, str);
                }
                else
                {
                    gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0);
                }
            }
            else
            {
                gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0);
            }
        }
    }
    else if (type == GTK_TYPE_SPIN_BUTTON)
    {
        g_debug("spin (%s)", str);
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), dval);
    }
    else if (type == GTK_TYPE_SCALE)
    {
        g_debug("hscale");
        gtk_range_set_value(GTK_RANGE(widget), dval);
    }
    else if (type == GTK_TYPE_SCALE_BUTTON)
    {
        g_debug("scale_button");
        gtk_scale_button_set_value(GTK_SCALE_BUTTON(widget), dval);
    }
    else if (type == GTK_TYPE_TEXT_VIEW)
    {
        g_debug("textview (%s)", str);
        GtkTextBuffer *buffer = gtk_text_view_get_buffer(
                                                GTK_TEXT_VIEW(widget));
        gtk_text_buffer_set_text (buffer, str, -1);
    }
    else if (type == GTK_TYPE_LABEL)
    {
        gtk_label_set_markup (GTK_LABEL(widget), str);
    }
    else if (type == GTK_TYPE_FILE_CHOOSER_BUTTON)
    {
        GtkFileChooserAction act;
        act = gtk_file_chooser_get_action(GTK_FILE_CHOOSER(widget));

        if (str[0] == 0)
        {
            // Do nothing
            ;
        }
        else if (act == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
                 act == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
        {
            gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), str);
        }
        else if (act == GTK_FILE_CHOOSER_ACTION_SAVE)
        {
            gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), str);
        }
        else
        {
            if (g_file_test(str, G_FILE_TEST_IS_DIR))
            {
                gtk_file_chooser_set_current_folder(
                    GTK_FILE_CHOOSER(widget), str);
            }
            else if (g_file_test(str, G_FILE_TEST_EXISTS))
            {
                gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), str);
            }
            else
            {
                gchar *dirname;

                dirname = g_path_get_dirname(str);
                gtk_file_chooser_set_current_folder(
                    GTK_FILE_CHOOSER(widget), dirname);
                g_free(dirname);
            }
        }
    }
    else
    {
        g_debug("Attempt to set unknown widget type");
    }
    g_free(str);
}
Exemple #10
0
gint
ghb_value_cmp(const GValue *vala, const GValue *valb)
{
	GType typa;
	GType typb;

	if ((vala == NULL && valb != NULL) || (vala != NULL && valb == NULL))
	{
		return 1;
	}
	typa = G_VALUE_TYPE(vala);
	typb = G_VALUE_TYPE(valb);
	if (typa != typb)
	{
		return 1;
	}
	
	if (typa == G_TYPE_STRING)
	{
		char *stra, *strb;
		gint res;
		stra = ghb_value_string(vala);
		strb = ghb_value_string(valb);
		if (stra == NULL && strb == NULL)
			return 0;
		if (stra == NULL)
		{
			g_free(strb);
			return -1;
		}
		if (strb == NULL)
		{
			g_free(stra);
			return 1;
		}
		res =  strcmp(stra, strb);
		g_free(stra);
		g_free(strb);
		return res;
	}
	else if (typa == G_TYPE_INT64 || typa == G_TYPE_INT || 
			typa == G_TYPE_BOOLEAN)
	{
		return ghb_value_int64(vala) - ghb_value_int64(valb);
	}
	else if (typa == G_TYPE_DOUBLE || typa == G_TYPE_FLOAT)
	{
		return ghb_value_double(vala) - ghb_value_double(valb);
	}
	else if (typa == ghb_array_get_type())
	{
		// Cheating here.  Just assume they are different.
		// Maybe later I'll recurse through these
		return 1;
	}
	else if (typa == ghb_dict_get_type())
	{
		// Cheating here.  Just assume they are different.
		// Maybe later I'll recurse through these
		return 1;
	}
	else
	{
		g_warning("ghb_value_cmp: unrecognized type");
		return 1;
	}
	return 0;
}