diff options
Diffstat (limited to 'cursor/cursorthemegen/themefile.c')
-rw-r--r-- | cursor/cursorthemegen/themefile.c | 609 |
1 files changed, 0 insertions, 609 deletions
diff --git a/cursor/cursorthemegen/themefile.c b/cursor/cursorthemegen/themefile.c deleted file mode 100644 index a8a703f..0000000 --- a/cursor/cursorthemegen/themefile.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright © 2003 Red Hat, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Red Hat not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Red Hat makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Owen Taylor, Red Hat, Inc. - */ -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> - -#include "cursortheme.h" - -typedef struct _ParseData ParseData; - -typedef enum { - OUTSIDE, - IN_THEME, - IN_SOURCE, - IN_IMAGE, - IN_ALIAS, - IN_LAYOUT, - IN_ROW, - IN_CURSOR, - IN_FRAME -} ParseState; - -struct _ParseData { - CursorTheme *theme; - ParseState state; - gboolean seen_theme; - gboolean seen_layout; - int row; - int column; - Cursor *current_cursor; -}; - -static gboolean -expect_tag (GMarkupParseContext *context, - const gchar *element_name, - const gchar *expected_name, /* Null for expected empty */ - GError **error) -{ - if (!expected_name || strcmp (element_name, expected_name) != 0) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Unexpected tag '%s'", - element_name); - return FALSE; - } - return TRUE; -} - -static gboolean -extract_attrs (GMarkupParseContext *context, - const gchar **attribute_names, - const gchar **attribute_values, - GError **error, - ...) -{ - va_list vap; - const char *name; - gboolean *attr_map; - gboolean nattrs = 0; - int i; - - for (i = 0; attribute_names[i]; i++) - nattrs++; - - attr_map = g_new0 (gboolean, nattrs); - - va_start (vap, error); - name = va_arg (vap, const char *); - while (name) - { - gboolean mandatory = va_arg (vap, gboolean); - const char **loc = va_arg (vap, const char **); - gboolean found = FALSE; - - for (i = 0; attribute_names[i]; i++) - { - if (!attr_map[i] && strcmp (attribute_names[i], name) == 0) - { - if (found) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Duplicate attribute '%s'", name); - return FALSE; - } - - *loc = attribute_values[i]; - found = TRUE; - attr_map[i] = TRUE; - } - } - - if (!found && mandatory) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Missing attribute '%s'", name); - return FALSE; - } - - name = va_arg (vap, const char *); - } - - for (i = 0; i < nattrs; i++) - if (!attr_map[i]) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, - "Unknown attribute '%s'", attribute_names[i]); - return FALSE; - } - - return TRUE; -} - -static gboolean -get_int (const char *str, - int *result) -{ - long val; - char *p; - - val = strtol (str, &p, 0); - if (*str == '\0' || *p != '\0' || - val < G_MININT || val > G_MAXINT) - return FALSE; - - *result = val; - - return TRUE; -} - -static void -add_source (ParseData *parse_data, - int size, - int gridsize) -{ - CursorSource *source = g_new0 (CursorSource, 1); - source->size = size; - source->gridsize = gridsize; - parse_data->theme->sources = g_slist_prepend (parse_data->theme->sources, source); -} - -static void -add_alias (ParseData *parse_data, - const char *name, - const char *target) -{ - CursorAlias *alias = g_new0 (CursorAlias, 1); - alias->name = g_strdup (name); - alias->target = g_strdup (target); - - g_hash_table_insert (parse_data->theme->aliases, alias->name, alias); -} - -static gboolean -add_image (ParseData *parse_data, - const char *file, - int use, - GError **error) -{ - GdkPixbuf *pixbuf; - CursorSource *source; - CursorImage *image; - - pixbuf = gdk_pixbuf_new_from_file (file, error); - if (!pixbuf) - return FALSE; - - source = parse_data->theme->sources->data; - image = g_new0 (CursorImage, 1); - image->image = pixbuf; - image->use = use; - source->images = g_slist_prepend (source->images, image); - - return TRUE; -} - -static void -add_cursor (ParseData *parse_data, - const char *name) -{ - Cursor *cursor = g_new0 (Cursor, 1); - cursor->name = g_strdup (name); - cursor->row = parse_data->row; - cursor->column = parse_data->column; - parse_data->current_cursor = cursor; - g_hash_table_insert (parse_data->theme->cursors, cursor->name, cursor); -} - -static void -add_frame_config (ParseData *parse_data, - int delay) -{ - Cursor *cursor = parse_data->current_cursor; - CursorFrameConfig *frame_config = g_new0 (CursorFrameConfig, 1); - frame_config->delay = delay; - cursor->frame_configs = g_slist_prepend (cursor->frame_configs, frame_config); -} - -/* Called for open tags <foo bar="baz"> */ -static void -cursor_theme_start_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - ParseData *parse_data = user_data; - - switch (parse_data->state) - { - case OUTSIDE: - { - const char *name; - - if (!expect_tag (context, element_name, "theme", error)) - return; - if (parse_data->seen_theme) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Multiple occurrences of <theme>"); - return; - } - parse_data->seen_theme = TRUE; - parse_data->state = IN_THEME; - - if (!extract_attrs (context, attribute_names, attribute_values, error, - "name", TRUE, &name, - NULL)) - return; - - parse_data->theme->name = g_strdup (name); - } - break; - case IN_THEME: - if (strcmp (element_name, "source") == 0) - { - const char *size_str; - const char *gridsize_str; - int size, gridsize; - - parse_data->state = IN_SOURCE; - - if (!extract_attrs (context, attribute_names, attribute_values, error, - "size", TRUE, &size_str, - "gridsize", FALSE, &gridsize_str, - NULL)) - return; - - if (!get_int (size_str, &size) || size < 0) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Invalid size %s", size_str); - return; - } - - if (gridsize_str) - { - if (!get_int (gridsize_str, &gridsize) || size < 0) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Invalid size %s", size_str); - return; - } - } - else - gridsize = size; - - add_source (parse_data, size, gridsize); - } - else if (strcmp (element_name, "alias") == 0) - { - const char *name; - const char *target; - - parse_data->state = IN_ALIAS; - - if (!extract_attrs (context, attribute_names, attribute_values, error, - "name", TRUE, &name, - "target", FALSE, &target, - NULL)) - return; - - add_alias (parse_data, name, target); - } - else if (strcmp (element_name, "layout") == 0) - { - if (parse_data->seen_layout) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Multiple occurrences of <layout>"); - return; - } - parse_data->seen_layout = TRUE; - parse_data->state = IN_LAYOUT; - - if (!extract_attrs (context, attribute_names, attribute_values, error, - NULL)) - return; - } - else - expect_tag (context, element_name, NULL, error); - break; - case IN_SOURCE: - { - const char *file; - const char *use_str; - int use; - - if (!expect_tag (context, element_name, "image", error)) - return; - parse_data->state = IN_IMAGE; - - if (!extract_attrs (context, attribute_names, attribute_values, error, - "file", TRUE, &file, - "use", TRUE, &use_str, - NULL)) - return; - - if (strcmp (use_str, "hotspot") == 0) - use = -1; - else - { - if (!get_int (use_str, &use) || use < 0) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Invalid use value %s", use_str); - return; - } - } - - add_image (parse_data, file, use, error); - } - - break; - case IN_LAYOUT: - if (!expect_tag (context, element_name, "row", error)) - return; - parse_data->state = IN_ROW; - parse_data->column = 0; - break; - case IN_ROW: - { - const char *name; - - if (!expect_tag (context, element_name, "cursor", error)) - return; - parse_data->state = IN_CURSOR; - - if (!extract_attrs (context, attribute_names, attribute_values, error, - "name", TRUE, &name, - NULL)) - return; - - add_cursor (parse_data, name); - } - break; - case IN_CURSOR: - { - const char *delay_str = NULL; - int delay = -1; - - if (!expect_tag (context, element_name, "frame", error)) - return; - parse_data->state = IN_FRAME; - - if (!extract_attrs (context, attribute_names, attribute_values, error, - "delay", FALSE, &delay_str, - NULL)) - return; - - if (delay_str) - { - if (!get_int (delay_str, &delay) || delay < 0) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Invalid delay value '%s'", delay_str); - return; - } - } - - add_frame_config (parse_data, delay); - } - break; - case IN_ALIAS: - case IN_IMAGE: - case IN_FRAME: - expect_tag (context, element_name, NULL, error); - break; - } -} - -/* Called for close tags </foo> */ -static void -cursor_theme_end_element (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - ParseData *parse_data = user_data; - - switch (parse_data->state) - { - case OUTSIDE: - g_assert_not_reached (); - break; - case IN_THEME: - parse_data->state = OUTSIDE; - parse_data->theme->sources = g_slist_reverse (parse_data->theme->sources); - break; - case IN_SOURCE: - { - CursorSource *source = parse_data->theme->sources->data; - source->images = g_slist_reverse (source->images); - parse_data->state = IN_THEME; - } - break; - case IN_ALIAS: - parse_data->state = IN_THEME; - break; - case IN_IMAGE: - parse_data->state = IN_SOURCE; - break; - case IN_LAYOUT: - parse_data->state = IN_THEME; - break; - case IN_ROW: - parse_data->state = IN_LAYOUT; - parse_data->row++; - break; - case IN_CURSOR: - { - Cursor *cursor = parse_data->current_cursor; - if (!cursor->frame_configs) - add_frame_config (parse_data, -1); - cursor->frame_configs = g_slist_reverse (cursor->frame_configs); - parse_data->state = IN_ROW; - parse_data->column++; - parse_data->current_cursor = NULL; - } - break; - case IN_FRAME: - parse_data->state = IN_CURSOR; - break; - } -} - -/* Called for character data */ -/* text is not nul-terminated */ -static void -cursor_theme_text (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) -{ - int i; - - for (i = 0; i < text_len; i++) - if (!g_ascii_isspace (text[i])) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Unexpected text in theme file"); - return; - } -} - -/* Called for strings that should be re-saved verbatim in this same - * position, but are not otherwise interpretable. At the moment - * this includes comments and processing instructions. - */ -/* text is not nul-terminated. */ -static void -cursor_theme_passthrough (GMarkupParseContext *context, - const gchar *passthrough_text, - gsize text_len, - gpointer user_data, - GError **error) -{ - /* do nothing */ -} - -/* Called on error, including one set by other - * methods in the vtable. The GError should not be freed. - */ -static void -cursor_theme_error (GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ -} - -static GMarkupParser cursor_theme_parse = { - cursor_theme_start_element, - cursor_theme_end_element, - cursor_theme_text, - cursor_theme_passthrough, - cursor_theme_error -}; - -static void -cursor_theme_free (CursorTheme *theme) -{ -} - -CursorTheme * -cursor_theme_read (const char *filename) -{ - ParseData parse_data; - GMarkupParseContext *context; - GError *error = NULL; - char *text; - gboolean have_error = FALSE; - size_t len; - - if (!g_file_get_contents (filename, &text, &len, &error)) - { - g_printerr ("Cannot read theme definition file: %s\n", error->message); - g_error_free (error); - return NULL; - } - - parse_data.theme = g_new0 (CursorTheme, 1); - parse_data.theme->cursors = g_hash_table_new (g_str_hash, g_str_equal); - parse_data.theme->aliases = g_hash_table_new (g_str_hash, g_str_equal); - - parse_data.state = OUTSIDE; - parse_data.seen_theme = FALSE; - parse_data.seen_layout = FALSE; - parse_data.row = 0; - parse_data.column = 0; - - context = g_markup_parse_context_new (&cursor_theme_parse, 0, - &parse_data, NULL); - - if (!g_markup_parse_context_parse (context, text, len, &error) || - !g_markup_parse_context_end_parse (context, &error)) - { - g_printerr ("Error parsing theme definition file: %s\n", error->message); - have_error = TRUE; - g_error_free (error); - } - else if (!parse_data.seen_theme) - { - g_printerr ("Did not find <theme> element in theme file\n"); - have_error = TRUE; - } - else if (!parse_data.seen_layout) - { - g_printerr ("Did not find <layout> element in theme file\n"); - have_error = TRUE; - } - else if (!parse_data.theme->sources) - { - g_printerr ("No <source> element in theme file\n"); - have_error = TRUE; - } - - g_markup_parse_context_free (context); - - if (!have_error) - return parse_data.theme; - else - { - cursor_theme_free (parse_data.theme); - return NULL; - } -} |