diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:23:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:23:22 +0000 |
commit | e42129241681dde7adae7d20697e7b421682fbb4 (patch) | |
tree | af1fe815a5e639e68e59fabd8395ec69458b3e5e /plug-ins/imagemap | |
parent | Initial commit. (diff) | |
download | gimp-e42129241681dde7adae7d20697e7b421682fbb4.tar.xz gimp-e42129241681dde7adae7d20697e7b421682fbb4.zip |
Adding upstream version 2.10.22.upstream/2.10.22upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
112 files changed, 29303 insertions, 0 deletions
diff --git a/plug-ins/imagemap/Makefile.am b/plug-ins/imagemap/Makefile.am new file mode 100644 index 0000000..f24ddb1 --- /dev/null +++ b/plug-ins/imagemap/Makefile.am @@ -0,0 +1,216 @@ +## Process this file with automake to produce Makefile.in + +if OS_WIN32 +mwindows = -mwindows +else +libm = -lm +endif + +libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la +libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la +libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la +libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la +libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la +libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la +libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la + +if HAVE_WINDRES +include $(top_srcdir)/build/windows/gimprc-plug-ins.rule +imagemap_RC = imagemap.rc.o +endif + +AM_LDFLAGS = $(mwindows) + +SUBDIRS = images + +libexecdir = $(gimpplugindir)/plug-ins/imagemap + +libexec_PROGRAMS = imagemap + +EXTRA_DIST = \ + imap_cern.l \ + imap_csim.l \ + imap_ncsa.l \ + imap_cern.y \ + imap_csim.y \ + imap_ncsa.y + +imagemap_SOURCES = \ + imap_about.c \ + imap_about.h \ + imap_browse.c \ + imap_browse.h \ + imap_cern_lex.c \ + imap_cern_parse.c \ + imap_cern_parse.h \ + imap_circle.c \ + imap_circle.h \ + imap_cmd_clear.c \ + imap_cmd_copy.c \ + imap_cmd_copy_object.c \ + imap_cmd_create.c \ + imap_cmd_cut.c \ + imap_cmd_cut_object.c \ + imap_cmd_delete.c \ + imap_cmd_delete_point.c \ + imap_cmd_edit_object.c \ + imap_cmd_gimp_guides.c \ + imap_cmd_guides.c \ + imap_cmd_insert_point.c \ + imap_cmd_move.c \ + imap_cmd_move_down.c \ + imap_cmd_move_sash.c \ + imap_cmd_move_selected.c \ + imap_cmd_move_to_front.c \ + imap_cmd_move_up.c \ + imap_cmd_object_down.c \ + imap_cmd_object_move.c \ + imap_cmd_object_up.c \ + imap_cmd_paste.c \ + imap_cmd_select.c \ + imap_cmd_select_all.c \ + imap_cmd_select_next.c \ + imap_cmd_select_prev.c \ + imap_cmd_select_region.c \ + imap_cmd_send_to_back.c \ + imap_cmd_unselect.c \ + imap_cmd_unselect_all.c \ + imap_command.c \ + imap_command.h \ + imap_commands.h \ + imap_csim_lex.c \ + imap_csim_parse.c \ + imap_csim_parse.h \ + imap_default_dialog.c \ + imap_default_dialog.h \ + imap_edit_area_info.c \ + imap_edit_area_info.h \ + imap_file.c \ + imap_file.h \ + imap_grid.c \ + imap_grid.h \ + imap_main.c \ + imap_main.h \ + imap_menu.c \ + imap_menu.h \ + imap_menu_funcs.c \ + imap_menu_funcs.h \ + imap_misc.c \ + imap_misc.h \ + imap_mru.c \ + imap_mru.h \ + imap_ncsa_lex.c \ + imap_ncsa_parse.c \ + imap_ncsa_parse.h \ + imap_object.c \ + imap_object.h \ + imap_object_popup.c \ + imap_object_popup.h \ + imap_polygon.c \ + imap_polygon.h \ + imap_preferences.c \ + imap_preferences.h \ + imap_preview.c \ + imap_preview.h \ + imap_rectangle.c \ + imap_rectangle.h \ + imap_selection.c \ + imap_selection.h \ + imap_settings.c \ + imap_settings.h \ + imap_source.c \ + imap_source.h \ + imap_stock.c \ + imap_stock.h \ + imap_statusbar.c \ + imap_statusbar.h \ + imap_string.c \ + imap_string.h \ + imap_table.c \ + imap_table.h \ + imap_taglist.c \ + imap_taglist.h + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + $(GTK_CFLAGS) \ + $(GEGL_CFLAGS) \ + -I$(includedir) + +LDADD = \ + $(libm) \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpconfig) \ + $(libgimp) \ + $(libgimpcolor) \ + $(libgimpmath) \ + $(libgimpbase) \ + $(GTK_LIBS) \ + $(GEGL_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(imagemap) + +CLEANFILES = y.tab.c y.tab.h + +## The following rules are not necessary for most users. They are +## only used by the maintainers who modify the symbols and grammar +## that are used for parsing the map files. These rules are very +## specific and a test for flex and bison in configure.ac would not be +## appropriate in most cases, so the Makefile rules are included here. +## In addition, the default rules provided by automake would not be +## sufficient because the source and target files have different base +## names and because of the non-standard prefix used in the output +## code (cern_, csim_, ncsa_). + +## Require flex because the standard lex does not support the -P option. +LEX=flex +YACC=bison -y + +REBUILD_FILES = \ + imap_cern_lex.c.rebuild \ + imap_csim_lex.c.rebuild \ + imap_ncsa_lex.c.rebuild \ + imap_cern_parse.c.rebuild \ + imap_csim_parse.c.rebuild \ + imap_ncsa_parse.c.rebuild \ + imap_cern_parse.h.rebuild \ + imap_csim_parse.h.rebuild \ + imap_ncsa_parse.h.rebuild + +rebuild-parsers: $(REBUILD_FILES) + @list='$(REBUILD_FILES)'; for p in $$list; do \ + newfile="`echo $$p | sed -e 's|.rebuild||'`"; \ + cp $$p $(srcdir)/$$newfile; \ + done + +imap_cern_lex.c.rebuild: imap_cern.l + @$(RM) $@ + $(LEX) $(LFLAGS) -Pcern_ -i -t $< > $@ +imap_csim_lex.c.rebuild: imap_csim.l + @$(RM) $@ + $(LEX) $(LFLAGS) -Pcsim_ -i -t $< > $@ +imap_ncsa_lex.c.rebuild: imap_ncsa.l + @$(RM) $@ + $(LEX) $(LFLAGS) -Pncsa_ -i -t $< > $@ + +imap_cern_parse.c.rebuild: imap_cern.y + $(YACC) $(YFLAGS) -d -p cern_ $< + mv -f y.tab.c $@ +imap_csim_parse.c.rebuild: imap_csim.y + $(YACC) $(YFLAGS) -d -p csim_ $< + mv -f y.tab.c $@ +imap_ncsa_parse.c.rebuild: imap_ncsa.y + $(YACC) $(YFLAGS) -d -p ncsa_ $< + mv -f y.tab.c $@ + +imap_cern_parse.h.rebuild: imap_cern.y + $(YACC) $(YFLAGS) -d -p cern_ $< + mv -f y.tab.h $@ +imap_csim_parse.h.rebuild: imap_csim.y + $(YACC) $(YFLAGS) -d -p csim_ $< + mv -f y.tab.h $@ +imap_ncsa_parse.h.rebuild: imap_ncsa.y + $(YACC) $(YFLAGS) -d -p ncsa_ $< + mv -f y.tab.h $@ diff --git a/plug-ins/imagemap/Makefile.in b/plug-ins/imagemap/Makefile.in new file mode 100644 index 0000000..7054b1e --- /dev/null +++ b/plug-ins/imagemap/Makefile.in @@ -0,0 +1,1530 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Version resources for Microsoft Windows + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +libexec_PROGRAMS = imagemap$(EXEEXT) +subdir = plug-ins/imagemap +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4macros/gtk-doc.m4 \ + $(top_srcdir)/m4macros/intltool.m4 \ + $(top_srcdir)/m4macros/libtool.m4 \ + $(top_srcdir)/m4macros/ltoptions.m4 \ + $(top_srcdir)/m4macros/ltsugar.m4 \ + $(top_srcdir)/m4macros/ltversion.m4 \ + $(top_srcdir)/m4macros/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/m4macros/alsa.m4 \ + $(top_srcdir)/m4macros/ax_compare_version.m4 \ + $(top_srcdir)/m4macros/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4macros/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4macros/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4macros/ax_prog_perl_version.m4 \ + $(top_srcdir)/m4macros/detectcflags.m4 \ + $(top_srcdir)/m4macros/pythondev.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(libexecdir)" +PROGRAMS = $(libexec_PROGRAMS) +am_imagemap_OBJECTS = imap_about.$(OBJEXT) imap_browse.$(OBJEXT) \ + imap_cern_lex.$(OBJEXT) imap_cern_parse.$(OBJEXT) \ + imap_circle.$(OBJEXT) imap_cmd_clear.$(OBJEXT) \ + imap_cmd_copy.$(OBJEXT) imap_cmd_copy_object.$(OBJEXT) \ + imap_cmd_create.$(OBJEXT) imap_cmd_cut.$(OBJEXT) \ + imap_cmd_cut_object.$(OBJEXT) imap_cmd_delete.$(OBJEXT) \ + imap_cmd_delete_point.$(OBJEXT) imap_cmd_edit_object.$(OBJEXT) \ + imap_cmd_gimp_guides.$(OBJEXT) imap_cmd_guides.$(OBJEXT) \ + imap_cmd_insert_point.$(OBJEXT) imap_cmd_move.$(OBJEXT) \ + imap_cmd_move_down.$(OBJEXT) imap_cmd_move_sash.$(OBJEXT) \ + imap_cmd_move_selected.$(OBJEXT) \ + imap_cmd_move_to_front.$(OBJEXT) imap_cmd_move_up.$(OBJEXT) \ + imap_cmd_object_down.$(OBJEXT) imap_cmd_object_move.$(OBJEXT) \ + imap_cmd_object_up.$(OBJEXT) imap_cmd_paste.$(OBJEXT) \ + imap_cmd_select.$(OBJEXT) imap_cmd_select_all.$(OBJEXT) \ + imap_cmd_select_next.$(OBJEXT) imap_cmd_select_prev.$(OBJEXT) \ + imap_cmd_select_region.$(OBJEXT) \ + imap_cmd_send_to_back.$(OBJEXT) imap_cmd_unselect.$(OBJEXT) \ + imap_cmd_unselect_all.$(OBJEXT) imap_command.$(OBJEXT) \ + imap_csim_lex.$(OBJEXT) imap_csim_parse.$(OBJEXT) \ + imap_default_dialog.$(OBJEXT) imap_edit_area_info.$(OBJEXT) \ + imap_file.$(OBJEXT) imap_grid.$(OBJEXT) imap_main.$(OBJEXT) \ + imap_menu.$(OBJEXT) imap_menu_funcs.$(OBJEXT) \ + imap_misc.$(OBJEXT) imap_mru.$(OBJEXT) imap_ncsa_lex.$(OBJEXT) \ + imap_ncsa_parse.$(OBJEXT) imap_object.$(OBJEXT) \ + imap_object_popup.$(OBJEXT) imap_polygon.$(OBJEXT) \ + imap_preferences.$(OBJEXT) imap_preview.$(OBJEXT) \ + imap_rectangle.$(OBJEXT) imap_selection.$(OBJEXT) \ + imap_settings.$(OBJEXT) imap_source.$(OBJEXT) \ + imap_stock.$(OBJEXT) imap_statusbar.$(OBJEXT) \ + imap_string.$(OBJEXT) imap_table.$(OBJEXT) \ + imap_taglist.$(OBJEXT) +imagemap_OBJECTS = $(am_imagemap_OBJECTS) +imagemap_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +imagemap_DEPENDENCIES = $(am__DEPENDENCIES_1) $(libgimpui) \ + $(libgimpwidgets) $(libgimpconfig) $(libgimp) $(libgimpcolor) \ + $(libgimpmath) $(libgimpbase) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imap_about.Po \ + ./$(DEPDIR)/imap_browse.Po ./$(DEPDIR)/imap_cern_lex.Po \ + ./$(DEPDIR)/imap_cern_parse.Po ./$(DEPDIR)/imap_circle.Po \ + ./$(DEPDIR)/imap_cmd_clear.Po ./$(DEPDIR)/imap_cmd_copy.Po \ + ./$(DEPDIR)/imap_cmd_copy_object.Po \ + ./$(DEPDIR)/imap_cmd_create.Po ./$(DEPDIR)/imap_cmd_cut.Po \ + ./$(DEPDIR)/imap_cmd_cut_object.Po \ + ./$(DEPDIR)/imap_cmd_delete.Po \ + ./$(DEPDIR)/imap_cmd_delete_point.Po \ + ./$(DEPDIR)/imap_cmd_edit_object.Po \ + ./$(DEPDIR)/imap_cmd_gimp_guides.Po \ + ./$(DEPDIR)/imap_cmd_guides.Po \ + ./$(DEPDIR)/imap_cmd_insert_point.Po \ + ./$(DEPDIR)/imap_cmd_move.Po ./$(DEPDIR)/imap_cmd_move_down.Po \ + ./$(DEPDIR)/imap_cmd_move_sash.Po \ + ./$(DEPDIR)/imap_cmd_move_selected.Po \ + ./$(DEPDIR)/imap_cmd_move_to_front.Po \ + ./$(DEPDIR)/imap_cmd_move_up.Po \ + ./$(DEPDIR)/imap_cmd_object_down.Po \ + ./$(DEPDIR)/imap_cmd_object_move.Po \ + ./$(DEPDIR)/imap_cmd_object_up.Po \ + ./$(DEPDIR)/imap_cmd_paste.Po ./$(DEPDIR)/imap_cmd_select.Po \ + ./$(DEPDIR)/imap_cmd_select_all.Po \ + ./$(DEPDIR)/imap_cmd_select_next.Po \ + ./$(DEPDIR)/imap_cmd_select_prev.Po \ + ./$(DEPDIR)/imap_cmd_select_region.Po \ + ./$(DEPDIR)/imap_cmd_send_to_back.Po \ + ./$(DEPDIR)/imap_cmd_unselect.Po \ + ./$(DEPDIR)/imap_cmd_unselect_all.Po \ + ./$(DEPDIR)/imap_command.Po ./$(DEPDIR)/imap_csim_lex.Po \ + ./$(DEPDIR)/imap_csim_parse.Po \ + ./$(DEPDIR)/imap_default_dialog.Po \ + ./$(DEPDIR)/imap_edit_area_info.Po ./$(DEPDIR)/imap_file.Po \ + ./$(DEPDIR)/imap_grid.Po ./$(DEPDIR)/imap_main.Po \ + ./$(DEPDIR)/imap_menu.Po ./$(DEPDIR)/imap_menu_funcs.Po \ + ./$(DEPDIR)/imap_misc.Po ./$(DEPDIR)/imap_mru.Po \ + ./$(DEPDIR)/imap_ncsa_lex.Po ./$(DEPDIR)/imap_ncsa_parse.Po \ + ./$(DEPDIR)/imap_object.Po ./$(DEPDIR)/imap_object_popup.Po \ + ./$(DEPDIR)/imap_polygon.Po ./$(DEPDIR)/imap_preferences.Po \ + ./$(DEPDIR)/imap_preview.Po ./$(DEPDIR)/imap_rectangle.Po \ + ./$(DEPDIR)/imap_selection.Po ./$(DEPDIR)/imap_settings.Po \ + ./$(DEPDIR)/imap_source.Po ./$(DEPDIR)/imap_statusbar.Po \ + ./$(DEPDIR)/imap_stock.Po ./$(DEPDIR)/imap_string.Po \ + ./$(DEPDIR)/imap_table.Po ./$(DEPDIR)/imap_taglist.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imagemap_SOURCES) +DIST_SOURCES = $(imagemap_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build/windows/gimprc-plug-ins.rule \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +AA_LIBS = @AA_LIBS@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALL_LINGUAS = @ALL_LINGUAS@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +ALTIVEC_EXTRA_CFLAGS = @ALTIVEC_EXTRA_CFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPSTREAM_UTIL = @APPSTREAM_UTIL@ +AR = @AR@ +AS = @AS@ +ATK_CFLAGS = @ATK_CFLAGS@ +ATK_LIBS = @ATK_LIBS@ +ATK_REQUIRED_VERSION = @ATK_REQUIRED_VERSION@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BABL_CFLAGS = @BABL_CFLAGS@ +BABL_LIBS = @BABL_LIBS@ +BABL_REQUIRED_VERSION = @BABL_REQUIRED_VERSION@ +BUG_REPORT_URL = @BUG_REPORT_URL@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +BZIP2_LIBS = @BZIP2_LIBS@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CAIRO_PDF_CFLAGS = @CAIRO_PDF_CFLAGS@ +CAIRO_PDF_LIBS = @CAIRO_PDF_LIBS@ +CAIRO_PDF_REQUIRED_VERSION = @CAIRO_PDF_REQUIRED_VERSION@ +CAIRO_REQUIRED_VERSION = @CAIRO_REQUIRED_VERSION@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CC_VERSION = @CC_VERSION@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DESKTOP_DATADIR = @DESKTOP_DATADIR@ +DESKTOP_FILE_VALIDATE = @DESKTOP_FILE_VALIDATE@ +DLLTOOL = @DLLTOOL@ +DOC_SHOOTER = @DOC_SHOOTER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILE_AA = @FILE_AA@ +FILE_EXR = @FILE_EXR@ +FILE_HEIF = @FILE_HEIF@ +FILE_JP2_LOAD = @FILE_JP2_LOAD@ +FILE_MNG = @FILE_MNG@ +FILE_PDF_SAVE = @FILE_PDF_SAVE@ +FILE_PS = @FILE_PS@ +FILE_WMF = @FILE_WMF@ +FILE_XMC = @FILE_XMC@ +FILE_XPM = @FILE_XPM@ +FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ +FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ +FONTCONFIG_REQUIRED_VERSION = @FONTCONFIG_REQUIRED_VERSION@ +FREETYPE2_REQUIRED_VERSION = @FREETYPE2_REQUIRED_VERSION@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GDBUS_CODEGEN = @GDBUS_CODEGEN@ +GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@ +GDK_PIXBUF_CSOURCE = @GDK_PIXBUF_CSOURCE@ +GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@ +GDK_PIXBUF_REQUIRED_VERSION = @GDK_PIXBUF_REQUIRED_VERSION@ +GEGL = @GEGL@ +GEGL_CFLAGS = @GEGL_CFLAGS@ +GEGL_LIBS = @GEGL_LIBS@ +GEGL_MAJOR_MINOR_VERSION = @GEGL_MAJOR_MINOR_VERSION@ +GEGL_REQUIRED_VERSION = @GEGL_REQUIRED_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GEXIV2_CFLAGS = @GEXIV2_CFLAGS@ +GEXIV2_LIBS = @GEXIV2_LIBS@ +GEXIV2_REQUIRED_VERSION = @GEXIV2_REQUIRED_VERSION@ +GIMP_API_VERSION = @GIMP_API_VERSION@ +GIMP_APP_VERSION = @GIMP_APP_VERSION@ +GIMP_BINARY_AGE = @GIMP_BINARY_AGE@ +GIMP_COMMAND = @GIMP_COMMAND@ +GIMP_DATA_VERSION = @GIMP_DATA_VERSION@ +GIMP_FULL_NAME = @GIMP_FULL_NAME@ +GIMP_INTERFACE_AGE = @GIMP_INTERFACE_AGE@ +GIMP_MAJOR_VERSION = @GIMP_MAJOR_VERSION@ +GIMP_MICRO_VERSION = @GIMP_MICRO_VERSION@ +GIMP_MINOR_VERSION = @GIMP_MINOR_VERSION@ +GIMP_MKENUMS = @GIMP_MKENUMS@ +GIMP_MODULES = @GIMP_MODULES@ +GIMP_PACKAGE_REVISION = @GIMP_PACKAGE_REVISION@ +GIMP_PKGCONFIG_VERSION = @GIMP_PKGCONFIG_VERSION@ +GIMP_PLUGINS = @GIMP_PLUGINS@ +GIMP_PLUGIN_VERSION = @GIMP_PLUGIN_VERSION@ +GIMP_REAL_VERSION = @GIMP_REAL_VERSION@ +GIMP_SYSCONF_VERSION = @GIMP_SYSCONF_VERSION@ +GIMP_TOOL_VERSION = @GIMP_TOOL_VERSION@ +GIMP_UNSTABLE = @GIMP_UNSTABLE@ +GIMP_USER_VERSION = @GIMP_USER_VERSION@ +GIMP_VERSION = @GIMP_VERSION@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@ +GIO_UNIX_LIBS = @GIO_UNIX_LIBS@ +GIO_WINDOWS_CFLAGS = @GIO_WINDOWS_CFLAGS@ +GIO_WINDOWS_LIBS = @GIO_WINDOWS_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GLIB_REQUIRED_VERSION = @GLIB_REQUIRED_VERSION@ +GMODULE_NO_EXPORT_CFLAGS = @GMODULE_NO_EXPORT_CFLAGS@ +GMODULE_NO_EXPORT_LIBS = @GMODULE_NO_EXPORT_LIBS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +GS_LIBS = @GS_LIBS@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +GTK_MAC_INTEGRATION_CFLAGS = @GTK_MAC_INTEGRATION_CFLAGS@ +GTK_MAC_INTEGRATION_LIBS = @GTK_MAC_INTEGRATION_LIBS@ +GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@ +GTK_UPDATE_ICON_CACHE = @GTK_UPDATE_ICON_CACHE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HARFBUZZ_CFLAGS = @HARFBUZZ_CFLAGS@ +HARFBUZZ_LIBS = @HARFBUZZ_LIBS@ +HARFBUZZ_REQUIRED_VERSION = @HARFBUZZ_REQUIRED_VERSION@ +HAVE_CXX14 = @HAVE_CXX14@ +HAVE_FINITE = @HAVE_FINITE@ +HAVE_ISFINITE = @HAVE_ISFINITE@ +HAVE_VFORK = @HAVE_VFORK@ +HOST_GLIB_COMPILE_RESOURCES = @HOST_GLIB_COMPILE_RESOURCES@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_REQUIRED_VERSION = @INTLTOOL_REQUIRED_VERSION@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +ISO_CODES_LOCALEDIR = @ISO_CODES_LOCALEDIR@ +ISO_CODES_LOCATION = @ISO_CODES_LOCATION@ +JPEG_LIBS = @JPEG_LIBS@ +JSON_GLIB_CFLAGS = @JSON_GLIB_CFLAGS@ +JSON_GLIB_LIBS = @JSON_GLIB_LIBS@ +LCMS_CFLAGS = @LCMS_CFLAGS@ +LCMS_LIBS = @LCMS_LIBS@ +LCMS_REQUIRED_VERSION = @LCMS_REQUIRED_VERSION@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBBACKTRACE_LIBS = @LIBBACKTRACE_LIBS@ +LIBHEIF_CFLAGS = @LIBHEIF_CFLAGS@ +LIBHEIF_LIBS = @LIBHEIF_LIBS@ +LIBHEIF_REQUIRED_VERSION = @LIBHEIF_REQUIRED_VERSION@ +LIBLZMA_REQUIRED_VERSION = @LIBLZMA_REQUIRED_VERSION@ +LIBMYPAINT_CFLAGS = @LIBMYPAINT_CFLAGS@ +LIBMYPAINT_LIBS = @LIBMYPAINT_LIBS@ +LIBMYPAINT_REQUIRED_VERSION = @LIBMYPAINT_REQUIRED_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBPNG_REQUIRED_VERSION = @LIBPNG_REQUIRED_VERSION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIBUNWIND_REQUIRED_VERSION = @LIBUNWIND_REQUIRED_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +LT_VERSION_INFO = @LT_VERSION_INFO@ +LZMA_CFLAGS = @LZMA_CFLAGS@ +LZMA_LIBS = @LZMA_LIBS@ +MAIL = @MAIL@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MIME_INFO_CFLAGS = @MIME_INFO_CFLAGS@ +MIME_INFO_LIBS = @MIME_INFO_LIBS@ +MIME_TYPES = @MIME_TYPES@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MMX_EXTRA_CFLAGS = @MMX_EXTRA_CFLAGS@ +MNG_CFLAGS = @MNG_CFLAGS@ +MNG_LIBS = @MNG_LIBS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +MYPAINT_BRUSHES_CFLAGS = @MYPAINT_BRUSHES_CFLAGS@ +MYPAINT_BRUSHES_LIBS = @MYPAINT_BRUSHES_LIBS@ +NATIVE_GLIB_CFLAGS = @NATIVE_GLIB_CFLAGS@ +NATIVE_GLIB_LIBS = @NATIVE_GLIB_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ +OPENEXR_LIBS = @OPENEXR_LIBS@ +OPENEXR_REQUIRED_VERSION = @OPENEXR_REQUIRED_VERSION@ +OPENJPEG_CFLAGS = @OPENJPEG_CFLAGS@ +OPENJPEG_LIBS = @OPENJPEG_LIBS@ +OPENJPEG_REQUIRED_VERSION = @OPENJPEG_REQUIRED_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOCAIRO_CFLAGS = @PANGOCAIRO_CFLAGS@ +PANGOCAIRO_LIBS = @PANGOCAIRO_LIBS@ +PANGOCAIRO_REQUIRED_VERSION = @PANGOCAIRO_REQUIRED_VERSION@ +PATHSEP = @PATHSEP@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PERL_REQUIRED_VERSION = @PERL_REQUIRED_VERSION@ +PERL_VERSION = @PERL_VERSION@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PNG_CFLAGS = @PNG_CFLAGS@ +PNG_LIBS = @PNG_LIBS@ +POFILES = @POFILES@ +POPPLER_CFLAGS = @POPPLER_CFLAGS@ +POPPLER_DATA_CFLAGS = @POPPLER_DATA_CFLAGS@ +POPPLER_DATA_LIBS = @POPPLER_DATA_LIBS@ +POPPLER_DATA_REQUIRED_VERSION = @POPPLER_DATA_REQUIRED_VERSION@ +POPPLER_LIBS = @POPPLER_LIBS@ +POPPLER_REQUIRED_VERSION = @POPPLER_REQUIRED_VERSION@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PYBIN_PATH = @PYBIN_PATH@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGIMP_EXTRA_CFLAGS = @PYGIMP_EXTRA_CFLAGS@ +PYGTK_CFLAGS = @PYGTK_CFLAGS@ +PYGTK_CODEGEN = @PYGTK_CODEGEN@ +PYGTK_DEFSDIR = @PYGTK_DEFSDIR@ +PYGTK_LIBS = @PYGTK_LIBS@ +PYLINK_LIBS = @PYLINK_LIBS@ +PYTHON = @PYTHON@ +PYTHON2_REQUIRED_VERSION = @PYTHON2_REQUIRED_VERSION@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RSVG_REQUIRED_VERSION = @RSVG_REQUIRED_VERSION@ +RT_LIBS = @RT_LIBS@ +SCREENSHOT_LIBS = @SCREENSHOT_LIBS@ +SED = @SED@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKET_LIBS = @SOCKET_LIBS@ +SSE2_EXTRA_CFLAGS = @SSE2_EXTRA_CFLAGS@ +SSE4_1_EXTRA_CFLAGS = @SSE4_1_EXTRA_CFLAGS@ +SSE_EXTRA_CFLAGS = @SSE_EXTRA_CFLAGS@ +STRIP = @STRIP@ +SVG_CFLAGS = @SVG_CFLAGS@ +SVG_LIBS = @SVG_LIBS@ +SYMPREFIX = @SYMPREFIX@ +TIFF_LIBS = @TIFF_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WEBKIT_CFLAGS = @WEBKIT_CFLAGS@ +WEBKIT_LIBS = @WEBKIT_LIBS@ +WEBKIT_REQUIRED_VERSION = @WEBKIT_REQUIRED_VERSION@ +WEBPDEMUX_CFLAGS = @WEBPDEMUX_CFLAGS@ +WEBPDEMUX_LIBS = @WEBPDEMUX_LIBS@ +WEBPMUX_CFLAGS = @WEBPMUX_CFLAGS@ +WEBPMUX_LIBS = @WEBPMUX_LIBS@ +WEBP_CFLAGS = @WEBP_CFLAGS@ +WEBP_LIBS = @WEBP_LIBS@ +WEBP_REQUIRED_VERSION = @WEBP_REQUIRED_VERSION@ +WEB_PAGE = @WEB_PAGE@ +WIN32_LARGE_ADDRESS_AWARE = @WIN32_LARGE_ADDRESS_AWARE@ +WINDRES = @WINDRES@ +WMF_CFLAGS = @WMF_CFLAGS@ +WMF_CONFIG = @WMF_CONFIG@ +WMF_LIBS = @WMF_LIBS@ +WMF_REQUIRED_VERSION = @WMF_REQUIRED_VERSION@ +XDG_EMAIL = @XDG_EMAIL@ +XFIXES_CFLAGS = @XFIXES_CFLAGS@ +XFIXES_LIBS = @XFIXES_LIBS@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_REQUIRED_VERSION = @XGETTEXT_REQUIRED_VERSION@ +XMC_CFLAGS = @XMC_CFLAGS@ +XMC_LIBS = @XMC_LIBS@ +XMKMF = @XMKMF@ +XMLLINT = @XMLLINT@ +XMU_LIBS = @XMU_LIBS@ +XPM_LIBS = @XPM_LIBS@ +XSLTPROC = @XSLTPROC@ +XVFB_RUN = @XVFB_RUN@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +Z_LIBS = @Z_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gimpdatadir = @gimpdatadir@ +gimpdir = @gimpdir@ +gimplocaledir = @gimplocaledir@ +gimpplugindir = @gimpplugindir@ +gimpsysconfdir = @gimpsysconfdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = $(gimpplugindir)/plug-ins/imagemap +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +manpage_gimpdir = @manpage_gimpdir@ +mkdir_p = @mkdir_p@ +ms_librarian = @ms_librarian@ +mypaint_brushes_dir = @mypaint_brushes_dir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@OS_WIN32_TRUE@mwindows = -mwindows +@OS_WIN32_FALSE@libm = -lm +libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la +libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la +libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la +libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la +libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la +libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la +libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la +@HAVE_WINDRES_TRUE@GIMPPLUGINRC = $(top_builddir)/build/windows/gimp-plug-ins.rc +@HAVE_WINDRES_TRUE@imagemap_RC = imagemap.rc.o +AM_LDFLAGS = $(mwindows) +SUBDIRS = images +EXTRA_DIST = \ + imap_cern.l \ + imap_csim.l \ + imap_ncsa.l \ + imap_cern.y \ + imap_csim.y \ + imap_ncsa.y + +imagemap_SOURCES = \ + imap_about.c \ + imap_about.h \ + imap_browse.c \ + imap_browse.h \ + imap_cern_lex.c \ + imap_cern_parse.c \ + imap_cern_parse.h \ + imap_circle.c \ + imap_circle.h \ + imap_cmd_clear.c \ + imap_cmd_copy.c \ + imap_cmd_copy_object.c \ + imap_cmd_create.c \ + imap_cmd_cut.c \ + imap_cmd_cut_object.c \ + imap_cmd_delete.c \ + imap_cmd_delete_point.c \ + imap_cmd_edit_object.c \ + imap_cmd_gimp_guides.c \ + imap_cmd_guides.c \ + imap_cmd_insert_point.c \ + imap_cmd_move.c \ + imap_cmd_move_down.c \ + imap_cmd_move_sash.c \ + imap_cmd_move_selected.c \ + imap_cmd_move_to_front.c \ + imap_cmd_move_up.c \ + imap_cmd_object_down.c \ + imap_cmd_object_move.c \ + imap_cmd_object_up.c \ + imap_cmd_paste.c \ + imap_cmd_select.c \ + imap_cmd_select_all.c \ + imap_cmd_select_next.c \ + imap_cmd_select_prev.c \ + imap_cmd_select_region.c \ + imap_cmd_send_to_back.c \ + imap_cmd_unselect.c \ + imap_cmd_unselect_all.c \ + imap_command.c \ + imap_command.h \ + imap_commands.h \ + imap_csim_lex.c \ + imap_csim_parse.c \ + imap_csim_parse.h \ + imap_default_dialog.c \ + imap_default_dialog.h \ + imap_edit_area_info.c \ + imap_edit_area_info.h \ + imap_file.c \ + imap_file.h \ + imap_grid.c \ + imap_grid.h \ + imap_main.c \ + imap_main.h \ + imap_menu.c \ + imap_menu.h \ + imap_menu_funcs.c \ + imap_menu_funcs.h \ + imap_misc.c \ + imap_misc.h \ + imap_mru.c \ + imap_mru.h \ + imap_ncsa_lex.c \ + imap_ncsa_parse.c \ + imap_ncsa_parse.h \ + imap_object.c \ + imap_object.h \ + imap_object_popup.c \ + imap_object_popup.h \ + imap_polygon.c \ + imap_polygon.h \ + imap_preferences.c \ + imap_preferences.h \ + imap_preview.c \ + imap_preview.h \ + imap_rectangle.c \ + imap_rectangle.h \ + imap_selection.c \ + imap_selection.h \ + imap_settings.c \ + imap_settings.h \ + imap_source.c \ + imap_source.h \ + imap_stock.c \ + imap_stock.h \ + imap_statusbar.c \ + imap_statusbar.h \ + imap_string.c \ + imap_string.h \ + imap_table.c \ + imap_table.h \ + imap_taglist.c \ + imap_taglist.h + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + $(GTK_CFLAGS) \ + $(GEGL_CFLAGS) \ + -I$(includedir) + +LDADD = \ + $(libm) \ + $(libgimpui) \ + $(libgimpwidgets) \ + $(libgimpconfig) \ + $(libgimp) \ + $(libgimpcolor) \ + $(libgimpmath) \ + $(libgimpbase) \ + $(GTK_LIBS) \ + $(GEGL_LIBS) \ + $(RT_LIBS) \ + $(INTLLIBS) \ + $(imagemap) + +CLEANFILES = y.tab.c y.tab.h +LEX = flex +YACC = bison -y +REBUILD_FILES = \ + imap_cern_lex.c.rebuild \ + imap_csim_lex.c.rebuild \ + imap_ncsa_lex.c.rebuild \ + imap_cern_parse.c.rebuild \ + imap_csim_parse.c.rebuild \ + imap_ncsa_parse.c.rebuild \ + imap_cern_parse.h.rebuild \ + imap_csim_parse.h.rebuild \ + imap_ncsa_parse.h.rebuild + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/windows/gimprc-plug-ins.rule $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plug-ins/imagemap/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plug-ins/imagemap/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/build/windows/gimprc-plug-ins.rule $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +imagemap$(EXEEXT): $(imagemap_OBJECTS) $(imagemap_DEPENDENCIES) $(EXTRA_imagemap_DEPENDENCIES) + @rm -f imagemap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(imagemap_OBJECTS) $(imagemap_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_about.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_browse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cern_lex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cern_parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_circle.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_clear.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_copy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_copy_object.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_create.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_cut.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_cut_object.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_delete.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_delete_point.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_edit_object.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_gimp_guides.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_guides.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_insert_point.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_move.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_move_down.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_move_sash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_move_selected.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_move_to_front.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_move_up.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_object_down.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_object_move.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_object_up.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_paste.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_select.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_select_all.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_select_next.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_select_prev.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_select_region.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_send_to_back.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_unselect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_cmd_unselect_all.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_command.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_csim_lex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_csim_parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_default_dialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_edit_area_info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_grid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_menu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_menu_funcs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_mru.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_ncsa_lex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_ncsa_parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_object.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_object_popup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_polygon.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_preferences.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_preview.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_rectangle.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_selection.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_settings.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_source.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_statusbar.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_stock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_string.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_table.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap_taglist.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(PROGRAMS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libexecdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/imap_about.Po + -rm -f ./$(DEPDIR)/imap_browse.Po + -rm -f ./$(DEPDIR)/imap_cern_lex.Po + -rm -f ./$(DEPDIR)/imap_cern_parse.Po + -rm -f ./$(DEPDIR)/imap_circle.Po + -rm -f ./$(DEPDIR)/imap_cmd_clear.Po + -rm -f ./$(DEPDIR)/imap_cmd_copy.Po + -rm -f ./$(DEPDIR)/imap_cmd_copy_object.Po + -rm -f ./$(DEPDIR)/imap_cmd_create.Po + -rm -f ./$(DEPDIR)/imap_cmd_cut.Po + -rm -f ./$(DEPDIR)/imap_cmd_cut_object.Po + -rm -f ./$(DEPDIR)/imap_cmd_delete.Po + -rm -f ./$(DEPDIR)/imap_cmd_delete_point.Po + -rm -f ./$(DEPDIR)/imap_cmd_edit_object.Po + -rm -f ./$(DEPDIR)/imap_cmd_gimp_guides.Po + -rm -f ./$(DEPDIR)/imap_cmd_guides.Po + -rm -f ./$(DEPDIR)/imap_cmd_insert_point.Po + -rm -f ./$(DEPDIR)/imap_cmd_move.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_down.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_sash.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_selected.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_to_front.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_up.Po + -rm -f ./$(DEPDIR)/imap_cmd_object_down.Po + -rm -f ./$(DEPDIR)/imap_cmd_object_move.Po + -rm -f ./$(DEPDIR)/imap_cmd_object_up.Po + -rm -f ./$(DEPDIR)/imap_cmd_paste.Po + -rm -f ./$(DEPDIR)/imap_cmd_select.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_all.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_next.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_prev.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_region.Po + -rm -f ./$(DEPDIR)/imap_cmd_send_to_back.Po + -rm -f ./$(DEPDIR)/imap_cmd_unselect.Po + -rm -f ./$(DEPDIR)/imap_cmd_unselect_all.Po + -rm -f ./$(DEPDIR)/imap_command.Po + -rm -f ./$(DEPDIR)/imap_csim_lex.Po + -rm -f ./$(DEPDIR)/imap_csim_parse.Po + -rm -f ./$(DEPDIR)/imap_default_dialog.Po + -rm -f ./$(DEPDIR)/imap_edit_area_info.Po + -rm -f ./$(DEPDIR)/imap_file.Po + -rm -f ./$(DEPDIR)/imap_grid.Po + -rm -f ./$(DEPDIR)/imap_main.Po + -rm -f ./$(DEPDIR)/imap_menu.Po + -rm -f ./$(DEPDIR)/imap_menu_funcs.Po + -rm -f ./$(DEPDIR)/imap_misc.Po + -rm -f ./$(DEPDIR)/imap_mru.Po + -rm -f ./$(DEPDIR)/imap_ncsa_lex.Po + -rm -f ./$(DEPDIR)/imap_ncsa_parse.Po + -rm -f ./$(DEPDIR)/imap_object.Po + -rm -f ./$(DEPDIR)/imap_object_popup.Po + -rm -f ./$(DEPDIR)/imap_polygon.Po + -rm -f ./$(DEPDIR)/imap_preferences.Po + -rm -f ./$(DEPDIR)/imap_preview.Po + -rm -f ./$(DEPDIR)/imap_rectangle.Po + -rm -f ./$(DEPDIR)/imap_selection.Po + -rm -f ./$(DEPDIR)/imap_settings.Po + -rm -f ./$(DEPDIR)/imap_source.Po + -rm -f ./$(DEPDIR)/imap_statusbar.Po + -rm -f ./$(DEPDIR)/imap_stock.Po + -rm -f ./$(DEPDIR)/imap_string.Po + -rm -f ./$(DEPDIR)/imap_table.Po + -rm -f ./$(DEPDIR)/imap_taglist.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libexecPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/imap_about.Po + -rm -f ./$(DEPDIR)/imap_browse.Po + -rm -f ./$(DEPDIR)/imap_cern_lex.Po + -rm -f ./$(DEPDIR)/imap_cern_parse.Po + -rm -f ./$(DEPDIR)/imap_circle.Po + -rm -f ./$(DEPDIR)/imap_cmd_clear.Po + -rm -f ./$(DEPDIR)/imap_cmd_copy.Po + -rm -f ./$(DEPDIR)/imap_cmd_copy_object.Po + -rm -f ./$(DEPDIR)/imap_cmd_create.Po + -rm -f ./$(DEPDIR)/imap_cmd_cut.Po + -rm -f ./$(DEPDIR)/imap_cmd_cut_object.Po + -rm -f ./$(DEPDIR)/imap_cmd_delete.Po + -rm -f ./$(DEPDIR)/imap_cmd_delete_point.Po + -rm -f ./$(DEPDIR)/imap_cmd_edit_object.Po + -rm -f ./$(DEPDIR)/imap_cmd_gimp_guides.Po + -rm -f ./$(DEPDIR)/imap_cmd_guides.Po + -rm -f ./$(DEPDIR)/imap_cmd_insert_point.Po + -rm -f ./$(DEPDIR)/imap_cmd_move.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_down.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_sash.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_selected.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_to_front.Po + -rm -f ./$(DEPDIR)/imap_cmd_move_up.Po + -rm -f ./$(DEPDIR)/imap_cmd_object_down.Po + -rm -f ./$(DEPDIR)/imap_cmd_object_move.Po + -rm -f ./$(DEPDIR)/imap_cmd_object_up.Po + -rm -f ./$(DEPDIR)/imap_cmd_paste.Po + -rm -f ./$(DEPDIR)/imap_cmd_select.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_all.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_next.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_prev.Po + -rm -f ./$(DEPDIR)/imap_cmd_select_region.Po + -rm -f ./$(DEPDIR)/imap_cmd_send_to_back.Po + -rm -f ./$(DEPDIR)/imap_cmd_unselect.Po + -rm -f ./$(DEPDIR)/imap_cmd_unselect_all.Po + -rm -f ./$(DEPDIR)/imap_command.Po + -rm -f ./$(DEPDIR)/imap_csim_lex.Po + -rm -f ./$(DEPDIR)/imap_csim_parse.Po + -rm -f ./$(DEPDIR)/imap_default_dialog.Po + -rm -f ./$(DEPDIR)/imap_edit_area_info.Po + -rm -f ./$(DEPDIR)/imap_file.Po + -rm -f ./$(DEPDIR)/imap_grid.Po + -rm -f ./$(DEPDIR)/imap_main.Po + -rm -f ./$(DEPDIR)/imap_menu.Po + -rm -f ./$(DEPDIR)/imap_menu_funcs.Po + -rm -f ./$(DEPDIR)/imap_misc.Po + -rm -f ./$(DEPDIR)/imap_mru.Po + -rm -f ./$(DEPDIR)/imap_ncsa_lex.Po + -rm -f ./$(DEPDIR)/imap_ncsa_parse.Po + -rm -f ./$(DEPDIR)/imap_object.Po + -rm -f ./$(DEPDIR)/imap_object_popup.Po + -rm -f ./$(DEPDIR)/imap_polygon.Po + -rm -f ./$(DEPDIR)/imap_preferences.Po + -rm -f ./$(DEPDIR)/imap_preview.Po + -rm -f ./$(DEPDIR)/imap_rectangle.Po + -rm -f ./$(DEPDIR)/imap_selection.Po + -rm -f ./$(DEPDIR)/imap_settings.Po + -rm -f ./$(DEPDIR)/imap_source.Po + -rm -f ./$(DEPDIR)/imap_statusbar.Po + -rm -f ./$(DEPDIR)/imap_stock.Po + -rm -f ./$(DEPDIR)/imap_string.Po + -rm -f ./$(DEPDIR)/imap_table.Po + -rm -f ./$(DEPDIR)/imap_taglist.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libexecPROGRAMS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libexecPROGRAMS clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libexecPROGRAMS install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libexecPROGRAMS + +.PRECIOUS: Makefile + + +# `windres` seems a very stupid tool and it breaks with double shlashes +# in parameter paths. Strengthen the rule a little. +@HAVE_WINDRES_TRUE@%.rc.o: +@HAVE_WINDRES_TRUE@ $(WINDRES) --define ORIGINALFILENAME_STR="$*$(EXEEXT)" \ +@HAVE_WINDRES_TRUE@ --define INTERNALNAME_STR="$*" \ +@HAVE_WINDRES_TRUE@ --define TOP_SRCDIR="`echo $(top_srcdir) | sed 's*//*/*'`" \ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_srcdir)/app | sed 's%/\+%/%'`" \ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir)/app | sed 's%/\+%/%'`"\ +@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir) | sed 's%/\+%/%'`"\ +@HAVE_WINDRES_TRUE@ $(GIMPPLUGINRC) $@ + +rebuild-parsers: $(REBUILD_FILES) + @list='$(REBUILD_FILES)'; for p in $$list; do \ + newfile="`echo $$p | sed -e 's|.rebuild||'`"; \ + cp $$p $(srcdir)/$$newfile; \ + done + +imap_cern_lex.c.rebuild: imap_cern.l + @$(RM) $@ + $(LEX) $(LFLAGS) -Pcern_ -i -t $< > $@ +imap_csim_lex.c.rebuild: imap_csim.l + @$(RM) $@ + $(LEX) $(LFLAGS) -Pcsim_ -i -t $< > $@ +imap_ncsa_lex.c.rebuild: imap_ncsa.l + @$(RM) $@ + $(LEX) $(LFLAGS) -Pncsa_ -i -t $< > $@ + +imap_cern_parse.c.rebuild: imap_cern.y + $(YACC) $(YFLAGS) -d -p cern_ $< + mv -f y.tab.c $@ +imap_csim_parse.c.rebuild: imap_csim.y + $(YACC) $(YFLAGS) -d -p csim_ $< + mv -f y.tab.c $@ +imap_ncsa_parse.c.rebuild: imap_ncsa.y + $(YACC) $(YFLAGS) -d -p ncsa_ $< + mv -f y.tab.c $@ + +imap_cern_parse.h.rebuild: imap_cern.y + $(YACC) $(YFLAGS) -d -p cern_ $< + mv -f y.tab.h $@ +imap_csim_parse.h.rebuild: imap_csim.y + $(YACC) $(YFLAGS) -d -p csim_ $< + mv -f y.tab.h $@ +imap_ncsa_parse.h.rebuild: imap_ncsa.y + $(YACC) $(YFLAGS) -d -p ncsa_ $< + mv -f y.tab.h $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plug-ins/imagemap/images/Makefile.am b/plug-ins/imagemap/images/Makefile.am new file mode 100644 index 0000000..9cf0b28 --- /dev/null +++ b/plug-ins/imagemap/images/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in + +STOCK_IMAGES = \ + stock-circle.png \ + stock-coord.png \ + stock-dimension.png \ + stock-java.png \ + stock-polygon.png \ + stock-rectangle.png \ + stock-to-back.png \ + stock-to-front.png + +EXTRA_DIST = $(STOCK_IMAGES) + +noinst_DATA = imap-stock-pixbufs.h +CLEANFILES = $(noinst_DATA) stock-icons.list + +stock-icons.list: $(STOCK_IMAGES) Makefile.am + ( rm -f $@; \ + for image in $(STOCK_IMAGES); do \ + echo $$image | \ + sed -e 's|.*/||' -e 's|-|_|g' -e 's|\.png$$||' >> $@; \ + echo " $(srcdir)/$$image" >> $@; \ + done ) + +$(srcdir)/imap-stock-pixbufs.h: stock-icons.list + $(GDK_PIXBUF_CSOURCE) --raw --build-list `cat stock-icons.list` > $(@F) diff --git a/plug-ins/imagemap/images/Makefile.in b/plug-ins/imagemap/images/Makefile.in new file mode 100644 index 0000000..2431dd5 --- /dev/null +++ b/plug-ins/imagemap/images/Makefile.in @@ -0,0 +1,772 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = plug-ins/imagemap/images +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4macros/gtk-doc.m4 \ + $(top_srcdir)/m4macros/intltool.m4 \ + $(top_srcdir)/m4macros/libtool.m4 \ + $(top_srcdir)/m4macros/ltoptions.m4 \ + $(top_srcdir)/m4macros/ltsugar.m4 \ + $(top_srcdir)/m4macros/ltversion.m4 \ + $(top_srcdir)/m4macros/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/m4macros/alsa.m4 \ + $(top_srcdir)/m4macros/ax_compare_version.m4 \ + $(top_srcdir)/m4macros/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4macros/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4macros/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4macros/ax_prog_perl_version.m4 \ + $(top_srcdir)/m4macros/detectcflags.m4 \ + $(top_srcdir)/m4macros/pythondev.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(noinst_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +AA_LIBS = @AA_LIBS@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALL_LINGUAS = @ALL_LINGUAS@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +ALTIVEC_EXTRA_CFLAGS = @ALTIVEC_EXTRA_CFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPSTREAM_UTIL = @APPSTREAM_UTIL@ +AR = @AR@ +AS = @AS@ +ATK_CFLAGS = @ATK_CFLAGS@ +ATK_LIBS = @ATK_LIBS@ +ATK_REQUIRED_VERSION = @ATK_REQUIRED_VERSION@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BABL_CFLAGS = @BABL_CFLAGS@ +BABL_LIBS = @BABL_LIBS@ +BABL_REQUIRED_VERSION = @BABL_REQUIRED_VERSION@ +BUG_REPORT_URL = @BUG_REPORT_URL@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +BZIP2_LIBS = @BZIP2_LIBS@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ +CAIRO_LIBS = @CAIRO_LIBS@ +CAIRO_PDF_CFLAGS = @CAIRO_PDF_CFLAGS@ +CAIRO_PDF_LIBS = @CAIRO_PDF_LIBS@ +CAIRO_PDF_REQUIRED_VERSION = @CAIRO_PDF_REQUIRED_VERSION@ +CAIRO_REQUIRED_VERSION = @CAIRO_REQUIRED_VERSION@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CC_VERSION = @CC_VERSION@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DESKTOP_DATADIR = @DESKTOP_DATADIR@ +DESKTOP_FILE_VALIDATE = @DESKTOP_FILE_VALIDATE@ +DLLTOOL = @DLLTOOL@ +DOC_SHOOTER = @DOC_SHOOTER@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILE_AA = @FILE_AA@ +FILE_EXR = @FILE_EXR@ +FILE_HEIF = @FILE_HEIF@ +FILE_JP2_LOAD = @FILE_JP2_LOAD@ +FILE_MNG = @FILE_MNG@ +FILE_PDF_SAVE = @FILE_PDF_SAVE@ +FILE_PS = @FILE_PS@ +FILE_WMF = @FILE_WMF@ +FILE_XMC = @FILE_XMC@ +FILE_XPM = @FILE_XPM@ +FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ +FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ +FONTCONFIG_REQUIRED_VERSION = @FONTCONFIG_REQUIRED_VERSION@ +FREETYPE2_REQUIRED_VERSION = @FREETYPE2_REQUIRED_VERSION@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GDBUS_CODEGEN = @GDBUS_CODEGEN@ +GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@ +GDK_PIXBUF_CSOURCE = @GDK_PIXBUF_CSOURCE@ +GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@ +GDK_PIXBUF_REQUIRED_VERSION = @GDK_PIXBUF_REQUIRED_VERSION@ +GEGL = @GEGL@ +GEGL_CFLAGS = @GEGL_CFLAGS@ +GEGL_LIBS = @GEGL_LIBS@ +GEGL_MAJOR_MINOR_VERSION = @GEGL_MAJOR_MINOR_VERSION@ +GEGL_REQUIRED_VERSION = @GEGL_REQUIRED_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GEXIV2_CFLAGS = @GEXIV2_CFLAGS@ +GEXIV2_LIBS = @GEXIV2_LIBS@ +GEXIV2_REQUIRED_VERSION = @GEXIV2_REQUIRED_VERSION@ +GIMP_API_VERSION = @GIMP_API_VERSION@ +GIMP_APP_VERSION = @GIMP_APP_VERSION@ +GIMP_BINARY_AGE = @GIMP_BINARY_AGE@ +GIMP_COMMAND = @GIMP_COMMAND@ +GIMP_DATA_VERSION = @GIMP_DATA_VERSION@ +GIMP_FULL_NAME = @GIMP_FULL_NAME@ +GIMP_INTERFACE_AGE = @GIMP_INTERFACE_AGE@ +GIMP_MAJOR_VERSION = @GIMP_MAJOR_VERSION@ +GIMP_MICRO_VERSION = @GIMP_MICRO_VERSION@ +GIMP_MINOR_VERSION = @GIMP_MINOR_VERSION@ +GIMP_MKENUMS = @GIMP_MKENUMS@ +GIMP_MODULES = @GIMP_MODULES@ +GIMP_PACKAGE_REVISION = @GIMP_PACKAGE_REVISION@ +GIMP_PKGCONFIG_VERSION = @GIMP_PKGCONFIG_VERSION@ +GIMP_PLUGINS = @GIMP_PLUGINS@ +GIMP_PLUGIN_VERSION = @GIMP_PLUGIN_VERSION@ +GIMP_REAL_VERSION = @GIMP_REAL_VERSION@ +GIMP_SYSCONF_VERSION = @GIMP_SYSCONF_VERSION@ +GIMP_TOOL_VERSION = @GIMP_TOOL_VERSION@ +GIMP_UNSTABLE = @GIMP_UNSTABLE@ +GIMP_USER_VERSION = @GIMP_USER_VERSION@ +GIMP_VERSION = @GIMP_VERSION@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@ +GIO_UNIX_LIBS = @GIO_UNIX_LIBS@ +GIO_WINDOWS_CFLAGS = @GIO_WINDOWS_CFLAGS@ +GIO_WINDOWS_LIBS = @GIO_WINDOWS_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GLIB_REQUIRED_VERSION = @GLIB_REQUIRED_VERSION@ +GMODULE_NO_EXPORT_CFLAGS = @GMODULE_NO_EXPORT_CFLAGS@ +GMODULE_NO_EXPORT_LIBS = @GMODULE_NO_EXPORT_LIBS@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +GS_LIBS = @GS_LIBS@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +GTK_MAC_INTEGRATION_CFLAGS = @GTK_MAC_INTEGRATION_CFLAGS@ +GTK_MAC_INTEGRATION_LIBS = @GTK_MAC_INTEGRATION_LIBS@ +GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@ +GTK_UPDATE_ICON_CACHE = @GTK_UPDATE_ICON_CACHE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HARFBUZZ_CFLAGS = @HARFBUZZ_CFLAGS@ +HARFBUZZ_LIBS = @HARFBUZZ_LIBS@ +HARFBUZZ_REQUIRED_VERSION = @HARFBUZZ_REQUIRED_VERSION@ +HAVE_CXX14 = @HAVE_CXX14@ +HAVE_FINITE = @HAVE_FINITE@ +HAVE_ISFINITE = @HAVE_ISFINITE@ +HAVE_VFORK = @HAVE_VFORK@ +HOST_GLIB_COMPILE_RESOURCES = @HOST_GLIB_COMPILE_RESOURCES@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_REQUIRED_VERSION = @INTLTOOL_REQUIRED_VERSION@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +ISO_CODES_LOCALEDIR = @ISO_CODES_LOCALEDIR@ +ISO_CODES_LOCATION = @ISO_CODES_LOCATION@ +JPEG_LIBS = @JPEG_LIBS@ +JSON_GLIB_CFLAGS = @JSON_GLIB_CFLAGS@ +JSON_GLIB_LIBS = @JSON_GLIB_LIBS@ +LCMS_CFLAGS = @LCMS_CFLAGS@ +LCMS_LIBS = @LCMS_LIBS@ +LCMS_REQUIRED_VERSION = @LCMS_REQUIRED_VERSION@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBBACKTRACE_LIBS = @LIBBACKTRACE_LIBS@ +LIBHEIF_CFLAGS = @LIBHEIF_CFLAGS@ +LIBHEIF_LIBS = @LIBHEIF_LIBS@ +LIBHEIF_REQUIRED_VERSION = @LIBHEIF_REQUIRED_VERSION@ +LIBLZMA_REQUIRED_VERSION = @LIBLZMA_REQUIRED_VERSION@ +LIBMYPAINT_CFLAGS = @LIBMYPAINT_CFLAGS@ +LIBMYPAINT_LIBS = @LIBMYPAINT_LIBS@ +LIBMYPAINT_REQUIRED_VERSION = @LIBMYPAINT_REQUIRED_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBPNG_REQUIRED_VERSION = @LIBPNG_REQUIRED_VERSION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@ +LIBUNWIND_LIBS = @LIBUNWIND_LIBS@ +LIBUNWIND_REQUIRED_VERSION = @LIBUNWIND_REQUIRED_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +LT_VERSION_INFO = @LT_VERSION_INFO@ +LZMA_CFLAGS = @LZMA_CFLAGS@ +LZMA_LIBS = @LZMA_LIBS@ +MAIL = @MAIL@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MIME_INFO_CFLAGS = @MIME_INFO_CFLAGS@ +MIME_INFO_LIBS = @MIME_INFO_LIBS@ +MIME_TYPES = @MIME_TYPES@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MMX_EXTRA_CFLAGS = @MMX_EXTRA_CFLAGS@ +MNG_CFLAGS = @MNG_CFLAGS@ +MNG_LIBS = @MNG_LIBS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +MYPAINT_BRUSHES_CFLAGS = @MYPAINT_BRUSHES_CFLAGS@ +MYPAINT_BRUSHES_LIBS = @MYPAINT_BRUSHES_LIBS@ +NATIVE_GLIB_CFLAGS = @NATIVE_GLIB_CFLAGS@ +NATIVE_GLIB_LIBS = @NATIVE_GLIB_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ +OPENEXR_LIBS = @OPENEXR_LIBS@ +OPENEXR_REQUIRED_VERSION = @OPENEXR_REQUIRED_VERSION@ +OPENJPEG_CFLAGS = @OPENJPEG_CFLAGS@ +OPENJPEG_LIBS = @OPENJPEG_LIBS@ +OPENJPEG_REQUIRED_VERSION = @OPENJPEG_REQUIRED_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGOCAIRO_CFLAGS = @PANGOCAIRO_CFLAGS@ +PANGOCAIRO_LIBS = @PANGOCAIRO_LIBS@ +PANGOCAIRO_REQUIRED_VERSION = @PANGOCAIRO_REQUIRED_VERSION@ +PATHSEP = @PATHSEP@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PERL_REQUIRED_VERSION = @PERL_REQUIRED_VERSION@ +PERL_VERSION = @PERL_VERSION@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PNG_CFLAGS = @PNG_CFLAGS@ +PNG_LIBS = @PNG_LIBS@ +POFILES = @POFILES@ +POPPLER_CFLAGS = @POPPLER_CFLAGS@ +POPPLER_DATA_CFLAGS = @POPPLER_DATA_CFLAGS@ +POPPLER_DATA_LIBS = @POPPLER_DATA_LIBS@ +POPPLER_DATA_REQUIRED_VERSION = @POPPLER_DATA_REQUIRED_VERSION@ +POPPLER_LIBS = @POPPLER_LIBS@ +POPPLER_REQUIRED_VERSION = @POPPLER_REQUIRED_VERSION@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PYBIN_PATH = @PYBIN_PATH@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGIMP_EXTRA_CFLAGS = @PYGIMP_EXTRA_CFLAGS@ +PYGTK_CFLAGS = @PYGTK_CFLAGS@ +PYGTK_CODEGEN = @PYGTK_CODEGEN@ +PYGTK_DEFSDIR = @PYGTK_DEFSDIR@ +PYGTK_LIBS = @PYGTK_LIBS@ +PYLINK_LIBS = @PYLINK_LIBS@ +PYTHON = @PYTHON@ +PYTHON2_REQUIRED_VERSION = @PYTHON2_REQUIRED_VERSION@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RSVG_REQUIRED_VERSION = @RSVG_REQUIRED_VERSION@ +RT_LIBS = @RT_LIBS@ +SCREENSHOT_LIBS = @SCREENSHOT_LIBS@ +SED = @SED@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKET_LIBS = @SOCKET_LIBS@ +SSE2_EXTRA_CFLAGS = @SSE2_EXTRA_CFLAGS@ +SSE4_1_EXTRA_CFLAGS = @SSE4_1_EXTRA_CFLAGS@ +SSE_EXTRA_CFLAGS = @SSE_EXTRA_CFLAGS@ +STRIP = @STRIP@ +SVG_CFLAGS = @SVG_CFLAGS@ +SVG_LIBS = @SVG_LIBS@ +SYMPREFIX = @SYMPREFIX@ +TIFF_LIBS = @TIFF_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WEBKIT_CFLAGS = @WEBKIT_CFLAGS@ +WEBKIT_LIBS = @WEBKIT_LIBS@ +WEBKIT_REQUIRED_VERSION = @WEBKIT_REQUIRED_VERSION@ +WEBPDEMUX_CFLAGS = @WEBPDEMUX_CFLAGS@ +WEBPDEMUX_LIBS = @WEBPDEMUX_LIBS@ +WEBPMUX_CFLAGS = @WEBPMUX_CFLAGS@ +WEBPMUX_LIBS = @WEBPMUX_LIBS@ +WEBP_CFLAGS = @WEBP_CFLAGS@ +WEBP_LIBS = @WEBP_LIBS@ +WEBP_REQUIRED_VERSION = @WEBP_REQUIRED_VERSION@ +WEB_PAGE = @WEB_PAGE@ +WIN32_LARGE_ADDRESS_AWARE = @WIN32_LARGE_ADDRESS_AWARE@ +WINDRES = @WINDRES@ +WMF_CFLAGS = @WMF_CFLAGS@ +WMF_CONFIG = @WMF_CONFIG@ +WMF_LIBS = @WMF_LIBS@ +WMF_REQUIRED_VERSION = @WMF_REQUIRED_VERSION@ +XDG_EMAIL = @XDG_EMAIL@ +XFIXES_CFLAGS = @XFIXES_CFLAGS@ +XFIXES_LIBS = @XFIXES_LIBS@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_REQUIRED_VERSION = @XGETTEXT_REQUIRED_VERSION@ +XMC_CFLAGS = @XMC_CFLAGS@ +XMC_LIBS = @XMC_LIBS@ +XMKMF = @XMKMF@ +XMLLINT = @XMLLINT@ +XMU_LIBS = @XMU_LIBS@ +XPM_LIBS = @XPM_LIBS@ +XSLTPROC = @XSLTPROC@ +XVFB_RUN = @XVFB_RUN@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +Z_LIBS = @Z_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gimpdatadir = @gimpdatadir@ +gimpdir = @gimpdir@ +gimplocaledir = @gimplocaledir@ +gimpplugindir = @gimpplugindir@ +gimpsysconfdir = @gimpsysconfdir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +manpage_gimpdir = @manpage_gimpdir@ +mkdir_p = @mkdir_p@ +ms_librarian = @ms_librarian@ +mypaint_brushes_dir = @mypaint_brushes_dir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +STOCK_IMAGES = \ + stock-circle.png \ + stock-coord.png \ + stock-dimension.png \ + stock-java.png \ + stock-polygon.png \ + stock-rectangle.png \ + stock-to-back.png \ + stock-to-front.png + +EXTRA_DIST = $(STOCK_IMAGES) +noinst_DATA = imap-stock-pixbufs.h +CLEANFILES = $(noinst_DATA) stock-icons.list +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plug-ins/imagemap/images/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plug-ins/imagemap/images/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +stock-icons.list: $(STOCK_IMAGES) Makefile.am + ( rm -f $@; \ + for image in $(STOCK_IMAGES); do \ + echo $$image | \ + sed -e 's|.*/||' -e 's|-|_|g' -e 's|\.png$$||' >> $@; \ + echo " $(srcdir)/$$image" >> $@; \ + done ) + +$(srcdir)/imap-stock-pixbufs.h: stock-icons.list + $(GDK_PIXBUF_CSOURCE) --raw --build-list `cat stock-icons.list` > $(@F) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plug-ins/imagemap/images/stock-circle.png b/plug-ins/imagemap/images/stock-circle.png Binary files differnew file mode 100644 index 0000000..e81b2ea --- /dev/null +++ b/plug-ins/imagemap/images/stock-circle.png diff --git a/plug-ins/imagemap/images/stock-coord.png b/plug-ins/imagemap/images/stock-coord.png Binary files differnew file mode 100644 index 0000000..6276054 --- /dev/null +++ b/plug-ins/imagemap/images/stock-coord.png diff --git a/plug-ins/imagemap/images/stock-dimension.png b/plug-ins/imagemap/images/stock-dimension.png Binary files differnew file mode 100644 index 0000000..d556717 --- /dev/null +++ b/plug-ins/imagemap/images/stock-dimension.png diff --git a/plug-ins/imagemap/images/stock-java.png b/plug-ins/imagemap/images/stock-java.png Binary files differnew file mode 100644 index 0000000..5c1a8d9 --- /dev/null +++ b/plug-ins/imagemap/images/stock-java.png diff --git a/plug-ins/imagemap/images/stock-polygon.png b/plug-ins/imagemap/images/stock-polygon.png Binary files differnew file mode 100644 index 0000000..4ec7754 --- /dev/null +++ b/plug-ins/imagemap/images/stock-polygon.png diff --git a/plug-ins/imagemap/images/stock-rectangle.png b/plug-ins/imagemap/images/stock-rectangle.png Binary files differnew file mode 100644 index 0000000..901c3e2 --- /dev/null +++ b/plug-ins/imagemap/images/stock-rectangle.png diff --git a/plug-ins/imagemap/images/stock-to-back.png b/plug-ins/imagemap/images/stock-to-back.png Binary files differnew file mode 100644 index 0000000..6438104 --- /dev/null +++ b/plug-ins/imagemap/images/stock-to-back.png diff --git a/plug-ins/imagemap/images/stock-to-front.png b/plug-ins/imagemap/images/stock-to-front.png Binary files differnew file mode 100644 index 0000000..ef0880d --- /dev/null +++ b/plug-ins/imagemap/images/stock-to-front.png diff --git a/plug-ins/imagemap/imap_about.c b/plug-ins/imagemap/imap_about.c new file mode 100644 index 0000000..81b4414 --- /dev/null +++ b/plug-ins/imagemap/imap_about.c @@ -0,0 +1,62 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_about.h" +#include "imap_main.h" + +#include "libgimp/stdplugins-intl.h" + +void +do_about_dialog(void) +{ + static GtkWidget *dialog; + if (!dialog) + { + const gchar* authors[] = {"Maurits Rijk (m.rijk@chello.nl)", NULL}; + + dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG, + "transient-for", get_dialog(), + "program-name", _("Image Map Plug-in"), + "version", "2.3", + "authors", authors, + "copyright", + _("Copyright © 1999-2005 by Maurits Rijk"), + "license", + _("Released under the GNU General Public License"), + NULL); + + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), + dialog); + + g_signal_connect (dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), + &dialog); + + } + + gtk_window_present (GTK_WINDOW (dialog)); +} diff --git a/plug-ins/imagemap/imap_about.h b/plug-ins/imagemap/imap_about.h new file mode 100644 index 0000000..4834a75 --- /dev/null +++ b/plug-ins/imagemap/imap_about.h @@ -0,0 +1,28 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_ABOUT_H +#define _IMAP_ABOUT_H + +void do_about_dialog(void); + +#endif /* _IMAP_ABOUT_H */ diff --git a/plug-ins/imagemap/imap_browse.c b/plug-ins/imagemap/imap_browse.c new file mode 100644 index 0000000..11a8522 --- /dev/null +++ b/plug-ins/imagemap/imap_browse.c @@ -0,0 +1,172 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_browse.h" + +#include "libgimp/stdplugins-intl.h" + + +static const GtkTargetEntry target_table[] = +{ + {"STRING", 0, 1 }, + {"text/plain", 0, 2 } +}; + + +static void +select_cb (GtkWidget *dialog, + gint response_id, + BrowseWidget_t *browse) +{ + if (response_id == GTK_RESPONSE_OK) + { + gchar *p; + gchar *file; + + file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + + p = (browse->filter ? + browse->filter (file, browse->filter_data) : file); + + gtk_entry_set_text (GTK_ENTRY (browse->file), p); + + if (browse->filter) + g_free (p); + + g_free (file); + } + + gtk_widget_hide (dialog); + gtk_widget_grab_focus (browse->file); +} + +static void +browse_cb (GtkWidget *widget, + BrowseWidget_t *browse) +{ + if (!browse->file_chooser) + { + GtkWidget *dialog; + + dialog = browse->file_chooser = + gtk_file_chooser_dialog_new (browse->name, + GTK_WINDOW (gtk_widget_get_toplevel (widget)), + GTK_FILE_CHOOSER_ACTION_OPEN, + + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Open"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect (dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), + &dialog); + g_signal_connect (dialog, "response", + G_CALLBACK (select_cb), + browse); + } + + gtk_window_present (GTK_WINDOW (browse->file_chooser)); +} + +static void +handle_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, + GtkSelectionData *data, guint info, guint time) +{ + gboolean success = FALSE; + + if (gtk_selection_data_get_length (data) >= 0 && + gtk_selection_data_get_format (data) == 8) + { + const gchar *text = (const gchar *) gtk_selection_data_get_data (data); + + if (g_utf8_validate (text, -1, NULL)) + { + gtk_entry_set_text (GTK_ENTRY (widget), text); + success = TRUE; + } + } + + gtk_drag_finish(context, success, FALSE, time); +} + +BrowseWidget_t* +browse_widget_new (const gchar *name) +{ + BrowseWidget_t *browse = g_new(BrowseWidget_t, 1); + GtkWidget *button; + GtkWidget *icon; + + browse->file_chooser = NULL; + browse->name = name; + browse->filter = NULL; + + browse->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); + gtk_widget_show (browse->hbox); + + browse->file = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX(browse->hbox), browse->file, TRUE, TRUE, 0); + gtk_drag_dest_set (browse->file, GTK_DEST_DEFAULT_ALL, target_table, + 2, GDK_ACTION_COPY); + g_signal_connect (browse->file, "drag-data-received", + G_CALLBACK(handle_drop), NULL); + + gtk_widget_show (browse->file); + + browse->button = button = gtk_button_new (); + icon = gtk_image_new_from_icon_name (GIMP_ICON_DOCUMENT_OPEN, + GTK_ICON_SIZE_BUTTON); + gtk_container_add (GTK_CONTAINER (button), icon); + gtk_widget_show (icon); + + gtk_box_pack_end(GTK_BOX (browse->hbox), button, FALSE, FALSE, 0); + g_signal_connect (button, "clicked", + G_CALLBACK(browse_cb), (gpointer) browse); + gtk_widget_show (button); + + return browse; +} + +void +browse_widget_set_filename(BrowseWidget_t *browse, const gchar *filename) +{ + gtk_entry_set_text (GTK_ENTRY (browse->file), filename); +} + +void +browse_widget_set_filter(BrowseWidget_t *browse, BrowseFilter_t filter, + gpointer data) +{ + browse->filter = filter; + browse->filter_data = data; +} diff --git a/plug-ins/imagemap/imap_browse.h b/plug-ins/imagemap/imap_browse.h new file mode 100644 index 0000000..e86c1c8 --- /dev/null +++ b/plug-ins/imagemap/imap_browse.h @@ -0,0 +1,46 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_BROWSE_H +#define _IMAP_BROWSE_H + +typedef gchar* (*BrowseFilter_t) (const gchar *, gpointer data); + +typedef struct +{ + const gchar *name; + BrowseFilter_t filter; + gpointer filter_data; + GtkWidget *hbox; + GtkWidget *file; + GtkWidget *button; + GtkWidget *file_chooser; +} BrowseWidget_t; + +BrowseWidget_t * browse_widget_new (const gchar *name); +void browse_widget_set_filename (BrowseWidget_t *browse, + const gchar *filename); +void browse_widget_set_filter (BrowseWidget_t *browse, + BrowseFilter_t filter, + gpointer data); + +#endif /* _IMAP_BROWSE_H */ diff --git a/plug-ins/imagemap/imap_cern.l b/plug-ins/imagemap/imap_cern.l new file mode 100644 index 0000000..95e7ad0 --- /dev/null +++ b/plug-ins/imagemap/imap_cern.l @@ -0,0 +1,93 @@ +%{ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <glib.h> + +#include "imap_cern_parse.h" + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +#endif /* FLEX_SCANNER */ + +%} + +%option noyywrap +%option noinput +%option nounput + +DIGIT [0-9] +ID [a-zA-Z_][a-zA-Z0-9_\-]* +WS [ \t\n]+ + +%x comment + +%% + +RECT{WS}\(4096,4096\){WS}\(4096,4096\).*#\$AUTHOR: { + BEGIN(comment); + return AUTHOR; + } + +RECT{WS}\(4096,4096\){WS}\(4096,4096\).*#\$DESCRIPTION: { + BEGIN(comment); + return DESCRIPTION; + } + +RECT{WS}\(4096,4096\){WS}\(4096,4096\) { + BEGIN(comment); + return BEGIN_COMMENT; + } + +<comment>.*$ { + BEGIN(INITIAL); + cern_lval.id = g_strndup (yytext, yyleng); + return COMMENT; + } + +RECT return RECTANGLE; + +CIRC return CIRCLE; + +POLY return POLYGON; + +DEFAULT return DEFAULT; + +[^ ,\t\n]+$ { + cern_lval.id = g_strndup (yytext, yyleng); + return LINK; + } + +-?{DIGIT}*"."?{DIGIT}*([Ee][-+]?{DIGIT}*)? { + cern_lval.value = g_ascii_strtod (yytext, NULL); + return FLOAT; + } + +{WS} ; /* Eat white space */ + +. return *yytext; + +%% + + diff --git a/plug-ins/imagemap/imap_cern.y b/plug-ins/imagemap/imap_cern.y new file mode 100644 index 0000000..251eb16 --- /dev/null +++ b/plug-ins/imagemap/imap_cern.y @@ -0,0 +1,184 @@ +%{ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + + +#include <math.h> + +#include <glib/gstdio.h> + +#include <gtk/gtk.h> + +#include "imap_circle.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_polygon.h" +#include "imap_rectangle.h" +#include "imap_string.h" + +extern int cern_lex(void); +extern int cern_restart(FILE *cern_in); +static void cern_error(char* s); + +static Object_t *current_object; + +%} + +%union { + int val; + double value; + char *id; +} + +%token<val> RECTANGLE POLYGON CIRCLE DEFAULT +%token<val> AUTHOR DESCRIPTION BEGIN_COMMENT +%token<value> FLOAT +%token<id> COMMENT LINK + +%% + +cern_file : area_list + ; + +area_list : /* Empty */ + | area_list area + ; + +area : default + | rectangle + | circle + | polygon + | comment_line + ; + +default : DEFAULT LINK + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->default_url, $2); + g_free ($2); + } + ; + + +rectangle : RECTANGLE '(' FLOAT ',' FLOAT ')' '(' FLOAT ',' FLOAT ')' LINK + { + gint x = (gint) $3; + gint y = (gint) $5; + gint width = (gint) fabs($8 - x); + gint height = (gint) fabs($10 - y); + current_object = create_rectangle(x, y, width, height); + object_set_url(current_object, $12); + add_shape(current_object); + g_free ($12); + } + ; + +circle : CIRCLE '(' FLOAT ',' FLOAT ')' FLOAT LINK + { + gint x = (gint) $3; + gint y = (gint) $5; + gint r = (gint) $7; + current_object = create_circle(x, y, r); + object_set_url(current_object, $8); + add_shape(current_object); + g_free ($8); + } + ; + +polygon : POLYGON {current_object = create_polygon(NULL);} coord_list LINK + { + object_set_url(current_object, $4); + add_shape(current_object); + g_free ($4); + } + ; + +coord_list : /* Empty */ + | coord_list coord + { + } + ; + +coord : '(' FLOAT ',' FLOAT ')' + { + Polygon_t *polygon = ObjectToPolygon(current_object); + GdkPoint *point = new_point((gint) $2, (gint) $4); + polygon->points = g_list_append(polygon->points, + (gpointer) point); + } + ; + +comment_line : author_line + | description_line + | real_comment + ; + +real_comment : BEGIN_COMMENT COMMENT + { + g_free ($2); + } + ; + +author_line : AUTHOR COMMENT + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->author, $2); + g_free ($2); + } + ; + +description_line: DESCRIPTION COMMENT + { + MapInfo_t *info = get_map_info(); + gchar *description; + + description = g_strconcat(info->description, $2, "\n", + NULL); + g_strreplace(&info->description, description); + g_free ($2); + } + ; + + +%% + +static void +cern_error(char* s) +{ + extern FILE *cern_in; + cern_restart(cern_in); +} + +gboolean +load_cern(const char* filename) +{ + gboolean status; + extern FILE *cern_in; + cern_in = g_fopen(filename, "r"); + if (cern_in) { + status = !cern_parse(); + fclose(cern_in); + } else { + status = FALSE; + } + return status; +} diff --git a/plug-ins/imagemap/imap_cern_lex.c b/plug-ins/imagemap/imap_cern_lex.c new file mode 100644 index 0000000..eb761d2 --- /dev/null +++ b/plug-ins/imagemap/imap_cern_lex.c @@ -0,0 +1,1939 @@ + +#line 3 "<stdout>" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer cern__create_buffer +#define yy_delete_buffer cern__delete_buffer +#define yy_flex_debug cern__flex_debug +#define yy_init_buffer cern__init_buffer +#define yy_flush_buffer cern__flush_buffer +#define yy_load_buffer_state cern__load_buffer_state +#define yy_switch_to_buffer cern__switch_to_buffer +#define yyin cern_in +#define yyleng cern_leng +#define yylex cern_lex +#define yylineno cern_lineno +#define yyout cern_out +#define yyrestart cern_restart +#define yytext cern_text +#define yywrap cern_wrap +#define yyalloc cern_alloc +#define yyrealloc cern_realloc +#define yyfree cern_free + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 36 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE cern_restart(cern_in ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t cern_leng; + +extern FILE *cern_in, *cern_out; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up cern_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up cern_text again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via cern_restart()), so that the user can continue scanning by + * just pointing cern_in at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when cern_text is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t cern_leng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow cern_wrap()'s to do buffer switches + * instead of setting up a fresh cern_in. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void cern_restart (FILE *input_file ); +void cern__switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE cern__create_buffer (FILE *file,int size ); +void cern__delete_buffer (YY_BUFFER_STATE b ); +void cern__flush_buffer (YY_BUFFER_STATE b ); +void cern_push_buffer_state (YY_BUFFER_STATE new_buffer ); +void cern_pop_buffer_state (void ); + +static void cern_ensure_buffer_stack (void ); +static void cern__load_buffer_state (void ); +static void cern__init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER cern__flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE cern__scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE cern__scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE cern__scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *cern_alloc (yy_size_t ); +void *cern_realloc (void *,yy_size_t ); +void cern_free (void * ); + +#define yy_new_buffer cern__create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + cern_ensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + cern__create_buffer(cern_in,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + cern_ensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + cern__create_buffer(cern_in,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define cern_wrap() 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *cern_in = (FILE *) 0, *cern_out = (FILE *) 0; + +typedef int yy_state_type; + +extern int cern_lineno; + +int cern_lineno = 1; + +extern char *cern_text; +#define yytext_ptr cern_text + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up cern_text. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + cern_leng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 13 +#define YY_END_OF_BUFFER 14 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[94] = + { 0, + 10, 10, 0, 0, 14, 12, 11, 11, 12, 10, + 10, 10, 12, 12, 10, 12, 12, 13, 4, 0, + 9, 11, 10, 10, 10, 10, 0, 0, 10, 10, + 0, 0, 0, 4, 0, 0, 0, 0, 6, 0, + 7, 5, 0, 0, 9, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 2, 0 + + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 4, 5, 1, 1, 1, 6, + 7, 1, 8, 9, 10, 11, 1, 12, 13, 13, + 13, 14, 13, 15, 13, 13, 16, 17, 1, 1, + 1, 1, 1, 1, 18, 1, 19, 20, 21, 22, + 1, 23, 24, 1, 1, 25, 1, 26, 27, 28, + 1, 29, 30, 31, 32, 1, 1, 1, 33, 1, + 1, 1, 1, 1, 1, 1, 34, 1, 35, 36, + + 37, 38, 1, 39, 40, 1, 1, 41, 1, 42, + 43, 44, 1, 45, 46, 47, 48, 1, 1, 1, + 49, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[50] = + { 0, + 1, 2, 3, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[98] = + { 0, + 0, 0, 276, 275, 277, 270, 48, 50, 309, 51, + 86, 121, 52, 53, 156, 54, 56, 269, 309, 268, + 309, 58, 170, 205, 240, 254, 65, 81, 101, 115, + 55, 76, 262, 309, 103, 122, 72, 143, 261, 109, + 260, 67, 136, 80, 141, 145, 248, 258, 235, 230, + 230, 235, 224, 224, 218, 217, 223, 106, 147, 213, + 199, 189, 187, 184, 161, 151, 139, 111, 113, 83, + 81, 147, 161, 156, 141, 163, 150, 183, 194, 185, + 195, 196, 199, 74, 205, 69, 227, 211, 233, 255, + 197, 67, 309, 297, 300, 303, 306 + + } ; + +static yyconst flex_int16_t yy_def[98] = + { 0, + 93, 1, 94, 94, 93, 95, 93, 93, 93, 95, + 95, 95, 95, 95, 95, 95, 95, 96, 93, 95, + 93, 93, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 96, 93, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 93, 93, 95, 93, 95, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 0, 93, 93, 93, 93 + + } ; + +static yyconst flex_int16_t yy_nxt[359] = + { 0, + 6, 7, 8, 6, 6, 6, 6, 6, 9, 10, + 11, 12, 12, 12, 12, 12, 6, 6, 13, 14, + 15, 6, 6, 6, 6, 6, 6, 16, 17, 6, + 6, 6, 6, 6, 13, 14, 15, 6, 6, 6, + 6, 6, 6, 16, 17, 6, 6, 6, 6, 22, + 22, 22, 22, 21, 21, 21, 21, 21, 21, 22, + 22, 23, 24, 24, 24, 24, 24, 21, 44, 45, + 72, 25, 72, 28, 21, 27, 32, 72, 21, 37, + 31, 44, 44, 21, 72, 47, 72, 25, 21, 28, + 86, 27, 32, 35, 38, 37, 31, 26, 26, 26, + + 26, 26, 36, 21, 41, 21, 25, 59, 59, 35, + 38, 21, 30, 30, 30, 30, 30, 21, 36, 70, + 41, 39, 25, 21, 21, 69, 30, 30, 30, 30, + 30, 23, 24, 24, 24, 24, 24, 39, 21, 40, + 43, 25, 44, 44, 72, 21, 47, 21, 59, 59, + 72, 73, 60, 72, 68, 40, 43, 25, 21, 72, + 46, 77, 67, 29, 72, 29, 72, 30, 30, 30, + 30, 30, 21, 42, 66, 48, 46, 77, 74, 79, + 75, 26, 26, 26, 26, 26, 72, 76, 72, 42, + 25, 48, 65, 78, 74, 79, 75, 72, 72, 72, + + 72, 64, 72, 76, 63, 80, 25, 21, 72, 78, + 62, 82, 81, 92, 72, 23, 24, 24, 24, 24, + 24, 80, 85, 83, 84, 25, 61, 82, 81, 58, + 72, 57, 87, 56, 89, 55, 72, 54, 85, 83, + 84, 25, 21, 53, 52, 51, 50, 29, 87, 29, + 89, 30, 30, 30, 30, 30, 21, 88, 72, 90, + 21, 49, 21, 21, 34, 26, 26, 26, 26, 26, + 21, 34, 21, 88, 25, 90, 93, 19, 19, 93, + 91, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 25, 93, 93, 93, 93, 93, 91, 18, 18, 18, + + 20, 93, 20, 33, 33, 33, 71, 71, 5, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93 + } ; + +static yyconst flex_int16_t yy_chk[359] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, + 7, 8, 8, 10, 13, 14, 16, 31, 17, 22, + 22, 10, 10, 10, 10, 10, 10, 27, 42, 42, + 92, 10, 86, 14, 37, 13, 17, 84, 32, 31, + 16, 44, 44, 28, 71, 44, 70, 10, 11, 14, + 84, 13, 17, 27, 32, 31, 16, 11, 11, 11, + + 11, 11, 28, 29, 37, 35, 11, 58, 58, 27, + 32, 40, 29, 29, 29, 29, 29, 30, 28, 69, + 37, 35, 11, 12, 36, 68, 30, 30, 30, 30, + 30, 12, 12, 12, 12, 12, 12, 35, 43, 36, + 40, 12, 45, 45, 75, 38, 45, 46, 59, 59, + 72, 72, 59, 77, 67, 36, 40, 12, 15, 74, + 43, 75, 66, 15, 73, 15, 76, 15, 15, 15, + 15, 15, 23, 38, 65, 46, 43, 75, 73, 77, + 73, 23, 23, 23, 23, 23, 78, 74, 80, 38, + 23, 46, 64, 76, 73, 77, 73, 79, 81, 82, + + 91, 63, 83, 74, 62, 78, 23, 24, 85, 76, + 61, 80, 79, 91, 88, 24, 24, 24, 24, 24, + 24, 78, 83, 81, 82, 24, 60, 80, 79, 57, + 87, 56, 85, 55, 88, 54, 89, 53, 83, 81, + 82, 24, 25, 52, 51, 50, 49, 25, 85, 25, + 88, 25, 25, 25, 25, 25, 26, 87, 90, 89, + 48, 47, 41, 39, 33, 26, 26, 26, 26, 26, + 20, 18, 6, 87, 26, 89, 5, 4, 3, 0, + 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 0, 0, 0, 0, 0, 90, 94, 94, 94, + + 95, 0, 95, 96, 96, 96, 97, 97, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int cern__flex_debug; +int cern__flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *cern_text; +#line 1 "imap_cern.l" +#line 2 "imap_cern.l" +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <glib.h> + +#include "imap_cern_parse.h" + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +#endif /* FLEX_SCANNER */ + +#define YY_NO_INPUT 1 + +#line 617 "<stdout>" + +#define INITIAL 0 +#define comment 1 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int cern_lex_destroy (void ); + +int cern_get_debug (void ); + +void cern_set_debug (int debug_flag ); + +YY_EXTRA_TYPE cern_get_extra (void ); + +void cern_set_extra (YY_EXTRA_TYPE user_defined ); + +FILE *cern_get_in (void ); + +void cern_set_in (FILE * in_str ); + +FILE *cern_get_out (void ); + +void cern_set_out (FILE * out_str ); + +yy_size_t cern_get_leng (void ); + +char *cern_get_text (void ); + +int cern_get_lineno (void ); + +void cern_set_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int cern_wrap (void ); +#else +extern int cern_wrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( cern_text, cern_leng, 1, cern_out )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( cern_in )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( cern_in ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, cern_in))==0 && ferror(cern_in)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(cern_in); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int cern_lex (void); + +#define YY_DECL int cern_lex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after cern_text and cern_leng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 46 "imap_cern.l" + + +#line 801 "<stdout>" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! cern_in ) + cern_in = stdin; + + if ( ! cern_out ) + cern_out = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + cern_ensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + cern__create_buffer(cern_in,YY_BUF_SIZE ); + } + + cern__load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of cern_text. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 94 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 309 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 48 "imap_cern.l" +{ + BEGIN(comment); + return AUTHOR; + } + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 53 "imap_cern.l" +{ + BEGIN(comment); + return DESCRIPTION; + } + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 58 "imap_cern.l" +{ + BEGIN(comment); + return BEGIN_COMMENT; + } + YY_BREAK +case 4: +*yy_cp = (yy_hold_char); /* undo effects of setting up cern_text */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up cern_text again */ +YY_RULE_SETUP +#line 63 "imap_cern.l" +{ + BEGIN(INITIAL); + cern_lval.id = g_strndup (cern_text, cern_leng); + return COMMENT; + } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 69 "imap_cern.l" +return RECTANGLE; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 71 "imap_cern.l" +return CIRCLE; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 73 "imap_cern.l" +return POLYGON; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 75 "imap_cern.l" +return DEFAULT; + YY_BREAK +case 9: +*yy_cp = (yy_hold_char); /* undo effects of setting up cern_text */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up cern_text again */ +YY_RULE_SETUP +#line 77 "imap_cern.l" +{ + cern_lval.id = g_strndup (cern_text, cern_leng); + return LINK; + } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 82 "imap_cern.l" +{ + cern_lval.value = g_ascii_strtod (cern_text, NULL); + return FLOAT; + } + YY_BREAK +case 11: +/* rule 11 can match eol */ +YY_RULE_SETUP +#line 87 "imap_cern.l" +; /* Eat white space */ + YY_BREAK +case 12: +YY_RULE_SETUP +#line 89 "imap_cern.l" +return *cern_text; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 91 "imap_cern.l" +ECHO; + YY_BREAK +#line 978 "<stdout>" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(comment): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed cern_in at a new source and called + * cern_lex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = cern_in; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( cern_wrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * cern_text, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of cern_lex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + cern_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + cern_restart(cern_in ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cern_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 94 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 94 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 93); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + cern_restart(cern_in ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( cern_wrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve cern_text */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void cern_restart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + cern_ensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + cern__create_buffer(cern_in,YY_BUF_SIZE ); + } + + cern__init_buffer(YY_CURRENT_BUFFER,input_file ); + cern__load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void cern__switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * cern_pop_buffer_state(); + * cern_push_buffer_state(new_buffer); + */ + cern_ensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + cern__load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (cern_wrap()) processing, but the only time this flag + * is looked at is after cern_wrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void cern__load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + cern_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE cern__create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) cern_alloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in cern__create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) cern_alloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in cern__create_buffer()" ); + + b->yy_is_our_buffer = 1; + + cern__init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with cern__create_buffer() + * + */ + void cern__delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + cern_free((void *) b->yy_ch_buf ); + + cern_free((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a cern_restart() or at EOF. + */ + static void cern__init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + cern__flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then cern__init_buffer was _probably_ + * called from cern_restart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void cern__flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + cern__load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void cern_push_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + cern_ensure_buffer_stack(); + + /* This block is copied from cern__switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from cern__switch_to_buffer. */ + cern__load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void cern_pop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + cern__delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + cern__load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void cern_ensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)cern_alloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in cern_ensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)cern_realloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in cern_ensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE cern__scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) cern_alloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in cern__scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + cern__switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to cern_lex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * cern__scan_bytes() instead. + */ +YY_BUFFER_STATE cern__scan_string (yyconst char * yystr ) +{ + + return cern__scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to cern_lex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE cern__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) cern_alloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in cern__scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = cern__scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in cern__scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up cern_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + cern_text[cern_leng] = (yy_hold_char); \ + (yy_c_buf_p) = cern_text + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + cern_leng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int cern_get_lineno (void) +{ + + return cern_lineno; +} + +/** Get the input stream. + * + */ +FILE *cern_get_in (void) +{ + return cern_in; +} + +/** Get the output stream. + * + */ +FILE *cern_get_out (void) +{ + return cern_out; +} + +/** Get the length of the current token. + * + */ +yy_size_t cern_get_leng (void) +{ + return cern_leng; +} + +/** Get the current token. + * + */ + +char *cern_get_text (void) +{ + return cern_text; +} + +/** Set the current line number. + * @param line_number + * + */ +void cern_set_lineno (int line_number ) +{ + + cern_lineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see cern__switch_to_buffer + */ +void cern_set_in (FILE * in_str ) +{ + cern_in = in_str ; +} + +void cern_set_out (FILE * out_str ) +{ + cern_out = out_str ; +} + +int cern_get_debug (void) +{ + return cern__flex_debug; +} + +void cern_set_debug (int bdebug ) +{ + cern__flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from cern_lex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + cern_in = stdin; + cern_out = stdout; +#else + cern_in = (FILE *) 0; + cern_out = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * cern_lex_init() + */ + return 0; +} + +/* cern_lex_destroy is for both reentrant and non-reentrant scanners. */ +int cern_lex_destroy (void) +{ + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + cern__delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + cern_pop_buffer_state(); + } + + /* Destroy the stack itself. */ + cern_free((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * cern_lex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *cern_alloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *cern_realloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void cern_free (void * ptr ) +{ + free( (char *) ptr ); /* see cern_realloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 91 "imap_cern.l" + + + + + diff --git a/plug-ins/imagemap/imap_cern_parse.c b/plug-ins/imagemap/imap_cern_parse.c new file mode 100644 index 0000000..56714a2 --- /dev/null +++ b/plug-ins/imagemap/imap_cern_parse.c @@ -0,0 +1,1822 @@ +/* A Bison parser, made by GNU Bison 2.6.1. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse cern_parse +#define yylex cern_lex +#define yyerror cern_error +#define yylval cern_lval +#define yychar cern_char +#define yydebug cern_debug +#define yynerrs cern_nerrs + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 1 "imap_cern.y" + +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + + +#include <math.h> + +#include <glib/gstdio.h> + +#include <gtk/gtk.h> + +#include "imap_circle.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_polygon.h" +#include "imap_rectangle.h" +#include "imap_string.h" + +extern int cern_lex(void); +extern int cern_restart(FILE *cern_in); +static void cern_error(char* s); + +static Object_t *current_object; + + +/* Line 336 of yacc.c */ +#line 120 "y.tab.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef CERN_Y_TAB_H +# define CERN_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int cern_debug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + RECTANGLE = 258, + POLYGON = 259, + CIRCLE = 260, + DEFAULT = 261, + AUTHOR = 262, + DESCRIPTION = 263, + BEGIN_COMMENT = 264, + FLOAT = 265, + COMMENT = 266, + LINK = 267 + }; +#endif +/* Tokens. */ +#define RECTANGLE 258 +#define POLYGON 259 +#define CIRCLE 260 +#define DEFAULT 261 +#define AUTHOR 262 +#define DESCRIPTION 263 +#define BEGIN_COMMENT 264 +#define FLOAT 265 +#define COMMENT 266 +#define LINK 267 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 46 "imap_cern.y" + + int val; + double value; + char *id; + + +/* Line 350 of yacc.c */ +#line 194 "y.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE cern_lval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int cern_parse (void *YYPARSE_PARAM); +#else +int cern_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int cern_parse (void); +#else +int cern_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !CERN_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 222 "y.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 39 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 16 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 15 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 23 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 51 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 267 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 13, 15, 2, 2, 14, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 6, 9, 11, 13, 15, 17, + 19, 22, 35, 44, 45, 50, 51, 54, 60, 62, + 64, 66, 69, 72 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 17, 0, -1, 18, -1, -1, 18, 19, -1, 20, + -1, 21, -1, 22, -1, 23, -1, 27, -1, 6, + 12, -1, 3, 13, 10, 14, 10, 15, 13, 10, + 14, 10, 15, 12, -1, 5, 13, 10, 14, 10, + 15, 10, 12, -1, -1, 4, 24, 25, 12, -1, + -1, 25, 26, -1, 13, 10, 14, 10, 15, -1, + 29, -1, 30, -1, 28, -1, 9, 11, -1, 7, + 11, -1, 8, 11, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 59, 59, 62, 63, 66, 67, 68, 69, 70, + 73, 82, 95, 107, 107, 115, 116, 121, 130, 131, + 132, 135, 141, 149 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "RECTANGLE", "POLYGON", "CIRCLE", + "DEFAULT", "AUTHOR", "DESCRIPTION", "BEGIN_COMMENT", "FLOAT", "COMMENT", + "LINK", "'('", "','", "')'", "$accept", "cern_file", "area_list", "area", + "default", "rectangle", "circle", "polygon", "$@1", "coord_list", + "coord", "comment_line", "real_comment", "author_line", + "description_line", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 40, 44, 41 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 16, 17, 18, 18, 19, 19, 19, 19, 19, + 20, 21, 22, 24, 23, 25, 25, 26, 27, 27, + 27, 28, 29, 30 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 0, 2, 1, 1, 1, 1, 1, + 2, 12, 8, 0, 4, 0, 2, 5, 1, 1, + 1, 2, 2, 2 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 3, 0, 2, 1, 0, 13, 0, 0, 0, 0, + 0, 4, 5, 6, 7, 8, 9, 20, 18, 19, + 0, 15, 0, 10, 22, 23, 21, 0, 0, 0, + 0, 14, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 12, 0, 0, 0, + 11 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 1, 2, 11, 12, 13, 14, 15, 21, 28, + 33, 16, 17, 18, 19 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -6 +static const yytype_int8 yypact[] = +{ + -6, 9, -3, -6, -2, -6, -1, 1, 3, 4, + 5, -6, -6, -6, -6, -6, -6, -6, -6, -6, + 0, -6, 7, -6, -6, -6, -6, 6, -5, 8, + 11, -6, 13, -6, 14, 10, 12, 15, 16, 17, + 18, 21, 19, 20, 22, -6, -6, 23, 24, 25, + -6 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, + -6, -6, -6, -6, -6 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 4, 5, 6, 7, 8, 9, 10, 31, 32, 3, + 27, 20, 22, 23, 24, 25, 26, 29, 0, 0, + 30, 35, 34, 36, 37, 38, 39, 42, 43, 41, + 40, 44, 46, 48, 45, 0, 47, 50, 0, 49 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-6)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 3, 4, 5, 6, 7, 8, 9, 12, 13, 0, + 10, 13, 13, 12, 11, 11, 11, 10, -1, -1, + 14, 10, 14, 10, 10, 15, 14, 10, 10, 13, + 15, 10, 12, 10, 15, -1, 14, 12, -1, 15 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 17, 18, 0, 3, 4, 5, 6, 7, 8, + 9, 19, 20, 21, 22, 23, 27, 28, 29, 30, + 13, 24, 13, 12, 11, 11, 11, 10, 25, 10, + 14, 12, 13, 26, 14, 10, 10, 10, 15, 14, + 15, 13, 10, 10, 10, 15, 12, 14, 10, 15, + 12 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 10: +/* Line 1787 of yacc.c */ +#line 74 "imap_cern.y" + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->default_url, (yyvsp[(2) - (2)].id)); + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 11: +/* Line 1787 of yacc.c */ +#line 83 "imap_cern.y" + { + gint x = (gint) (yyvsp[(3) - (12)].value); + gint y = (gint) (yyvsp[(5) - (12)].value); + gint width = (gint) fabs((yyvsp[(8) - (12)].value) - x); + gint height = (gint) fabs((yyvsp[(10) - (12)].value) - y); + current_object = create_rectangle(x, y, width, height); + object_set_url(current_object, (yyvsp[(12) - (12)].id)); + add_shape(current_object); + g_free ((yyvsp[(12) - (12)].id)); + } + break; + + case 12: +/* Line 1787 of yacc.c */ +#line 96 "imap_cern.y" + { + gint x = (gint) (yyvsp[(3) - (8)].value); + gint y = (gint) (yyvsp[(5) - (8)].value); + gint r = (gint) (yyvsp[(7) - (8)].value); + current_object = create_circle(x, y, r); + object_set_url(current_object, (yyvsp[(8) - (8)].id)); + add_shape(current_object); + g_free ((yyvsp[(8) - (8)].id)); + } + break; + + case 13: +/* Line 1787 of yacc.c */ +#line 107 "imap_cern.y" + {current_object = create_polygon(NULL);} + break; + + case 14: +/* Line 1787 of yacc.c */ +#line 108 "imap_cern.y" + { + object_set_url(current_object, (yyvsp[(4) - (4)].id)); + add_shape(current_object); + g_free ((yyvsp[(4) - (4)].id)); + } + break; + + case 16: +/* Line 1787 of yacc.c */ +#line 117 "imap_cern.y" + { + } + break; + + case 17: +/* Line 1787 of yacc.c */ +#line 122 "imap_cern.y" + { + Polygon_t *polygon = ObjectToPolygon(current_object); + GdkPoint *point = new_point((gint) (yyvsp[(2) - (5)].value), (gint) (yyvsp[(4) - (5)].value)); + polygon->points = g_list_append(polygon->points, + (gpointer) point); + } + break; + + case 21: +/* Line 1787 of yacc.c */ +#line 136 "imap_cern.y" + { + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 22: +/* Line 1787 of yacc.c */ +#line 142 "imap_cern.y" + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->author, (yyvsp[(2) - (2)].id)); + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 23: +/* Line 1787 of yacc.c */ +#line 150 "imap_cern.y" + { + MapInfo_t *info = get_map_info(); + gchar *description; + + description = g_strconcat(info->description, (yyvsp[(2) - (2)].id), "\n", + NULL); + g_strreplace(&info->description, description); + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + +/* Line 1787 of yacc.c */ +#line 1569 "y.tab.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 162 "imap_cern.y" + + +static void +cern_error(char* s) +{ + extern FILE *cern_in; + cern_restart(cern_in); +} + +gboolean +load_cern(const char* filename) +{ + gboolean status; + extern FILE *cern_in; + cern_in = g_fopen(filename, "r"); + if (cern_in) { + status = !cern_parse(); + fclose(cern_in); + } else { + status = FALSE; + } + return status; +} + diff --git a/plug-ins/imagemap/imap_cern_parse.h b/plug-ins/imagemap/imap_cern_parse.h new file mode 100644 index 0000000..f46caff --- /dev/null +++ b/plug-ins/imagemap/imap_cern_parse.h @@ -0,0 +1,110 @@ +/* A Bison parser, made by GNU Bison 2.6.1. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef CERN_Y_TAB_H +# define CERN_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int cern_debug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + RECTANGLE = 258, + POLYGON = 259, + CIRCLE = 260, + DEFAULT = 261, + AUTHOR = 262, + DESCRIPTION = 263, + BEGIN_COMMENT = 264, + FLOAT = 265, + COMMENT = 266, + LINK = 267 + }; +#endif +/* Tokens. */ +#define RECTANGLE 258 +#define POLYGON 259 +#define CIRCLE 260 +#define DEFAULT 261 +#define AUTHOR 262 +#define DESCRIPTION 263 +#define BEGIN_COMMENT 264 +#define FLOAT 265 +#define COMMENT 266 +#define LINK 267 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 46 "imap_cern.y" + + int val; + double value; + char *id; + + +/* Line 2049 of yacc.c */ +#line 88 "y.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE cern_lval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int cern_parse (void *YYPARSE_PARAM); +#else +int cern_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int cern_parse (void); +#else +int cern_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !CERN_Y_TAB_H */ diff --git a/plug-ins/imagemap/imap_circle.c b/plug-ins/imagemap/imap_circle.c new file mode 100644 index 0000000..230b547 --- /dev/null +++ b/plug-ins/imagemap/imap_circle.c @@ -0,0 +1,405 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <math.h> +#include <stdlib.h> + +#include <gtk/gtk.h> + +#include "imap_circle.h" +#include "imap_main.h" +#include "imap_misc.h" +#include "imap_object_popup.h" +#include "imap_stock.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +static gboolean circle_is_valid(Object_t *obj); +static Object_t *circle_clone(Object_t *obj); +static void circle_assign(Object_t *obj, Object_t *des); +static void circle_draw(Object_t* obj, cairo_t *cr); +static void circle_draw_sashes(Object_t* obj, cairo_t *cr); +static MoveSashFunc_t circle_near_sash(Object_t *obj, gint x, gint y); +static gboolean circle_point_is_on(Object_t *obj, gint x, gint y); +static void circle_get_dimensions(Object_t *obj, gint *x, gint *y, + gint *width, gint *height); +static void circle_resize(Object_t *obj, gint percentage_x, gint percentage_y); +static void circle_move(Object_t *obj, gint dx, gint dy); +static gpointer circle_create_info_widget(GtkWidget *frame); +static void circle_fill_info_tab(Object_t *obj, gpointer data); +static void circle_set_initial_focus(Object_t *obj, gpointer data); +static void circle_update(Object_t* obj, gpointer data); +static void circle_write_csim(Object_t* obj, gpointer param, + OutputFunc_t output); +static void circle_write_cern(Object_t* obj, gpointer param, + OutputFunc_t output); +static void circle_write_ncsa(Object_t* obj, gpointer param, + OutputFunc_t output); +static const gchar* circle_get_stock_icon_name(void); + +static ObjectClass_t circle_class = { + N_("C_ircle"), + NULL, /* info_dialog */ + + circle_is_valid, + NULL, /* circle_destruct */ + circle_clone, + circle_assign, + NULL, /* circle_normalize */ + circle_draw, + circle_draw_sashes, + circle_near_sash, + circle_point_is_on, + circle_get_dimensions, + circle_resize, + circle_move, + circle_create_info_widget, + circle_fill_info_tab, /* circle_update_info_widget */ + circle_fill_info_tab, + circle_set_initial_focus, + circle_update, + circle_write_csim, + circle_write_cern, + circle_write_ncsa, + object_do_popup, + circle_get_stock_icon_name +}; + +Object_t* +create_circle(gint x, gint y, gint r) +{ + Circle_t *circle = g_new(Circle_t, 1); + circle->x = x; + circle->y = y; + circle->r = r; + return object_init(&circle->obj, &circle_class); +} + +static gboolean +circle_is_valid(Object_t *obj) +{ + return ObjectToCircle(obj)->r > 0; +} + +static Object_t* +circle_clone(Object_t *obj) +{ + Circle_t *circle = ObjectToCircle(obj); + Circle_t *clone = g_new(Circle_t, 1); + + clone->x = circle->x; + clone->y = circle->y; + clone->r = circle->r; + return &clone->obj; +} + +static void +circle_assign(Object_t *obj, Object_t *des) +{ + Circle_t *src_circle = ObjectToCircle(obj); + Circle_t *des_circle = ObjectToCircle(des); + des_circle->x = src_circle->x; + des_circle->y = src_circle->y; + des_circle->r = src_circle->r; +} + +static void +circle_draw(Object_t *obj, cairo_t *cr) +{ + Circle_t *circle = ObjectToCircle(obj); + draw_circle(cr, circle->x, circle->y, circle->r); +} + +static void +circle_draw_sashes(Object_t *obj, cairo_t *cr) +{ + Circle_t *circle = ObjectToCircle(obj); + draw_sash(cr, circle->x - circle->r, circle->y - circle->r); + draw_sash(cr, circle->x + circle->r, circle->y - circle->r); + draw_sash(cr, circle->x - circle->r, circle->y + circle->r); + draw_sash(cr, circle->x + circle->r, circle->y + circle->r); +} + +static gint sash_x; +static gint sash_y; + +static void +move_sash(Object_t *obj, gint dx, gint dy) +{ + Circle_t *circle = ObjectToCircle(obj); + gint rx, ry; + sash_x += dx; + sash_y += dy; + + rx = abs(circle->x - sash_x); + ry = abs(circle->y - sash_y); + circle->r = (rx > ry) ? rx : ry; +} + +static void +circle_resize(Object_t *obj, gint percentage_x, gint percentage_y) +{ + Circle_t *circle = ObjectToCircle(obj); + circle->x = circle->x * percentage_x / 100; + circle->y = circle->y * percentage_y / 100; + circle->r = circle->r * ((percentage_x < percentage_y) + ? percentage_x : percentage_y) / 100; +} + +static MoveSashFunc_t +circle_near_sash(Object_t *obj, gint x, gint y) +{ + Circle_t *circle = ObjectToCircle(obj); + sash_x = x; + sash_y = y; + if (near_sash(circle->x - circle->r, circle->y - circle->r, x, y) || + near_sash(circle->x + circle->r, circle->y - circle->r, x, y) || + near_sash(circle->x - circle->r, circle->y + circle->r, x, y) || + near_sash(circle->x + circle->r, circle->y + circle->r, x, y)) + return move_sash; + return NULL; +} + +static gboolean +circle_point_is_on(Object_t *obj, gint x, gint y) +{ + Circle_t *circle = ObjectToCircle(obj); + x -= circle->x; + y -= circle->y; + return x * x + y * y <= circle->r * circle->r; +} + +static void +circle_get_dimensions(Object_t *obj, gint *x, gint *y, + gint *width, gint *height) +{ + Circle_t *circle = ObjectToCircle(obj); + *x = circle->x - circle->r; + *y = circle->y - circle->r; + *width = *height = 2 * circle->r; +} + +static void +circle_move(Object_t *obj, gint dx, gint dy) +{ + Circle_t *circle = ObjectToCircle(obj); + circle->x += dx; + circle->y += dy; +} + +typedef struct { + Object_t *obj; + GtkWidget *x; + GtkWidget *y; + GtkWidget *r; +} CircleProperties_t; + +static void +x_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((CircleProperties_t*) data)->obj; + gint x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + ObjectToCircle(obj)->x = x; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static void +y_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((CircleProperties_t*) data)->obj; + gint y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + ObjectToCircle(obj)->y = y; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static void +r_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((CircleProperties_t*) data)->obj; + gint r = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + ObjectToCircle(obj)->r = r; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static gpointer +circle_create_info_widget(GtkWidget *frame) +{ + CircleProperties_t *props = g_new(CircleProperties_t, 1); + GtkWidget *table, *label; + gint max_width = get_image_width(); + gint max_height = get_image_height(); + + table = gtk_table_new(3, 3, FALSE); + gtk_container_add(GTK_CONTAINER(frame), table); + + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 6); + gtk_widget_show(table); + + label = create_label_in_table(table, 0, 0, _("Center _x:")); + props->x = create_spin_button_in_table(table, label, 0, 1, 1, 0, + max_width - 1); + g_signal_connect(props->x, "value-changed", + G_CALLBACK (x_changed_cb), (gpointer) props); + create_label_in_table(table, 0, 2, _("pixels")); + + label = create_label_in_table(table, 1, 0, _("Center _y:")); + props->y = create_spin_button_in_table(table, label, 1, 1, 1, 0, + max_height - 1); + g_signal_connect(props->y, "value-changed", + G_CALLBACK (y_changed_cb), (gpointer) props); + create_label_in_table(table, 1, 2, _("pixels")); + + label = create_label_in_table(table, 2, 0, _("_Radius:")); + props->r = create_spin_button_in_table(table, label, 2, 1, 1, 1, G_MAXINT); + g_signal_connect(props->r, "value-changed", + G_CALLBACK (r_changed_cb), (gpointer) props); + create_label_in_table(table, 2, 2, _("pixels")); + + return props; +} + +static void +circle_fill_info_tab(Object_t *obj, gpointer data) +{ + Circle_t *circle = ObjectToCircle(obj); + CircleProperties_t *props = (CircleProperties_t*) data; + + props->obj = obj; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->x), circle->x); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->y), circle->y); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->r), circle->r); +} + +static void +circle_set_initial_focus(Object_t *obj, gpointer data) +{ + CircleProperties_t *props = (CircleProperties_t*) data; + gtk_widget_grab_focus(props->x); +} + +static void +circle_update(Object_t* obj, gpointer data) +{ + Circle_t *circle = ObjectToCircle(obj); + CircleProperties_t *props = (CircleProperties_t*) data; + + circle->x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(props->x)); + circle->y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(props->y)); + circle->r = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(props->r)); +} + +static void +circle_write_csim(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Circle_t *circle = ObjectToCircle(obj); + output(param, "\"circle\" coords=\"%d,%d,%d\"", circle->x, circle->y, + circle->r); +} + +static void +circle_write_cern(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Circle_t *circle = ObjectToCircle(obj); + output(param, "circ (%d,%d) %d", circle->x, circle->y, circle->r); +} + +static void +circle_write_ncsa(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Circle_t *circle = ObjectToCircle(obj); + output(param, "circle %s %d,%d %d,%d", obj->url, + circle->x, circle->y, circle->x, circle->y + circle->r); +} + +static const gchar* +circle_get_stock_icon_name(void) +{ + return IMAP_STOCK_CIRCLE; +} + +static gint _start_x, _start_y; + +static Object_t* +circle_factory_create_object1(gint x, gint y) +{ + _start_x = x; + _start_y = y; + return create_circle(x, y, 0); +} + +static void +circle_factory_set_xy1(Object_t *obj, guint state, gint x, gint y) +{ + Circle_t *circle = ObjectToCircle(obj); + + circle->x = (_start_x + x) / 2; + circle->y = (_start_y + y) / 2; + x -= _start_x; + y -= _start_y; + circle->r = (gint) sqrt(x * x + y * y) / 2; + + main_set_dimension(circle->r, circle->r); +} + +static ObjectFactory_t circle_factory1 = { + NULL, /* Object pointer */ + NULL, /* Finish func */ + NULL, /* Cancel func */ + circle_factory_create_object1, + circle_factory_set_xy1 +}; + +static Object_t* +circle_factory_create_object2(gint x, gint y) +{ + return create_circle(x, y, 0); +} + +static void +circle_factory_set_xy2(Object_t *obj, guint state, gint x, gint y) +{ + Circle_t *circle = ObjectToCircle(obj); + + x -= circle->x; + y -= circle->y; + circle->r = (gint) sqrt(x * x + y * y); + + main_set_dimension(circle->r, circle->r); +} + +static ObjectFactory_t circle_factory2 = { + NULL, /* Object pointer */ + NULL, /* Finish func */ + NULL, /* Cancel func */ + circle_factory_create_object2, + circle_factory_set_xy2 +}; + +ObjectFactory_t* +get_circle_factory(guint state) +{ + return (state & GDK_SHIFT_MASK) ? &circle_factory1 : &circle_factory2; +} diff --git a/plug-ins/imagemap/imap_circle.h b/plug-ins/imagemap/imap_circle.h new file mode 100644 index 0000000..f56263a --- /dev/null +++ b/plug-ins/imagemap/imap_circle.h @@ -0,0 +1,40 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_CIRCLE_H +#define _IMAP_CIRCLE_H + +#include "imap_object.h" + +typedef struct { + Object_t obj; + gint x; + gint y; + gint r; +} Circle_t; + +#define ObjectToCircle(obj) ((Circle_t*) (obj)) + +Object_t *create_circle(gint x, gint y, gint r); +ObjectFactory_t *get_circle_factory(guint state); + +#endif /* _IMAP_CIRCLE_H */ diff --git a/plug-ins/imagemap/imap_cmd_clear.c b/plug-ins/imagemap/imap_cmd_clear.c new file mode 100644 index 0000000..676e8b8 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_clear.c @@ -0,0 +1,72 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t clear_command_execute(Command_t *parent); + +static CommandClass_t clear_command_class = { + NULL, /* clear_command_destruct */ + clear_command_execute, + NULL, /* clear_command_undo */ + NULL /* clear_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} ClearCommand_t; + +Command_t* +clear_command_new(ObjectList_t *list) +{ + ClearCommand_t *command = g_new(ClearCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Clear"), &clear_command_class); +} + +static void +remove_one_object(Object_t *obj, gpointer data) +{ + ClearCommand_t *command = (ClearCommand_t*) data; + command_add_subcommand(&command->parent, + delete_command_new(command->list, obj)); +} + +static CmdExecuteValue_t +clear_command_execute(Command_t *parent) +{ + ClearCommand_t *command = (ClearCommand_t*) parent; + gpointer id; + + id = object_list_add_remove_cb(command->list, remove_one_object, command); + object_list_delete_selected(command->list); + object_list_remove_remove_cb(command->list, id); + + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_copy.c b/plug-ins/imagemap/imap_cmd_copy.c new file mode 100644 index 0000000..453a5ee --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_copy.c @@ -0,0 +1,71 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t copy_command_execute(Command_t *parent); +static void copy_command_undo(Command_t *parent); + +static CommandClass_t copy_command_class = { + NULL, /* copy_command_destruct */ + copy_command_execute, + copy_command_undo, + NULL /* copy_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + ObjectList_t *paste_buffer; +} CopyCommand_t; + +Command_t* +copy_command_new(ObjectList_t *list) +{ + CopyCommand_t *command = g_new(CopyCommand_t, 1); + command->list = list; + command->paste_buffer = NULL; + return command_init(&command->parent, _("Copy"), ©_command_class); +} + +static CmdExecuteValue_t +copy_command_execute(Command_t *parent) +{ + CopyCommand_t *command = (CopyCommand_t*) parent; + command->paste_buffer = object_list_copy(command->paste_buffer, + get_paste_buffer()); + object_list_copy_to_paste_buffer(command->list); + return CMD_APPEND; +} + +static void +copy_command_undo(Command_t *parent) +{ + CopyCommand_t *command = (CopyCommand_t*) parent; + object_list_copy(get_paste_buffer(), command->paste_buffer); +} diff --git a/plug-ins/imagemap/imap_cmd_copy_object.c b/plug-ins/imagemap/imap_cmd_copy_object.c new file mode 100644 index 0000000..f59fd81 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_copy_object.c @@ -0,0 +1,84 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void copy_object_command_destruct(Command_t *parent); +static CmdExecuteValue_t copy_object_command_execute(Command_t *parent); +static void copy_object_command_undo(Command_t *parent); + +static CommandClass_t copy_object_command_class = { + copy_object_command_destruct, + copy_object_command_execute, + copy_object_command_undo, + NULL /* copy_object_command_redo */ +}; + +typedef struct { + Command_t parent; + Object_t *obj; + ObjectList_t *paste_buffer; +} CopyObjectCommand_t; + +Command_t* +copy_object_command_new(Object_t *obj) +{ + CopyObjectCommand_t *command = g_new(CopyObjectCommand_t, 1); + command->obj = object_ref(obj); + command->paste_buffer = NULL; + return command_init(&command->parent, _("Copy"), + ©_object_command_class); +} + +static void +copy_object_command_destruct(Command_t *parent) +{ + CopyObjectCommand_t *command = (CopyObjectCommand_t*) parent; + object_unref(command->obj); +} + +static CmdExecuteValue_t +copy_object_command_execute(Command_t *parent) +{ + CopyObjectCommand_t *command = (CopyObjectCommand_t*) parent; + ObjectList_t *paste_buffer = get_paste_buffer(); + + command->paste_buffer = object_list_copy(command->paste_buffer, + paste_buffer); + clear_paste_buffer(); + object_list_append(paste_buffer, object_clone(command->obj)); + + return CMD_APPEND; +} + +static void +copy_object_command_undo(Command_t *parent) +{ + CopyObjectCommand_t *command = (CopyObjectCommand_t*) parent; + object_list_copy(get_paste_buffer(), command->paste_buffer); +} diff --git a/plug-ins/imagemap/imap_cmd_create.c b/plug-ins/imagemap/imap_cmd_create.c new file mode 100644 index 0000000..49719d5 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_create.c @@ -0,0 +1,82 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "imap_main.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t create_command_execute(Command_t *parent); +static void create_command_destruct(Command_t *parent); +static void create_command_undo(Command_t *parent); + +static CommandClass_t create_command_class = { + create_command_destruct, + create_command_execute, + create_command_undo, + NULL /* create_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + Object_t *obj; + gboolean changed; +} CreateCommand_t; + +Command_t* +create_command_new(ObjectList_t *list, Object_t *obj) +{ + CreateCommand_t *command = g_new(CreateCommand_t, 1); + command->list = list; + command->obj = object_ref(obj); + return command_init(&command->parent, _("Create"), &create_command_class); +} + +static void +create_command_destruct(Command_t *parent) +{ + CreateCommand_t *command = (CreateCommand_t*) parent; + object_unref(command->obj); +} + +static CmdExecuteValue_t +create_command_execute(Command_t *parent) +{ + CreateCommand_t *command = (CreateCommand_t*) parent; + command->changed = object_list_get_changed(command->list); + object_list_append(command->list, object_ref(command->obj)); + return CMD_APPEND; +} + +static void +create_command_undo(Command_t *parent) +{ + CreateCommand_t *command = (CreateCommand_t*) parent; + object_list_remove(command->list, command->obj); + object_list_set_changed(command->list, command->changed); +} diff --git a/plug-ins/imagemap/imap_cmd_cut.c b/plug-ins/imagemap/imap_cmd_cut.c new file mode 100644 index 0000000..0bf06c1 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_cut.c @@ -0,0 +1,92 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void cut_command_destruct(Command_t *parent); +static CmdExecuteValue_t cut_command_execute(Command_t *parent); +static void cut_command_undo(Command_t *parent); + +static CommandClass_t cut_command_class = { + cut_command_destruct, + cut_command_execute, + cut_command_undo, + NULL /* cut_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + ObjectList_t *paste_buffer; +} CutCommand_t; + +Command_t* +cut_command_new(ObjectList_t *list) +{ + CutCommand_t *command = g_new(CutCommand_t, 1); + command->list = list; + command->paste_buffer = NULL; + return command_init(&command->parent, _("Cut"), &cut_command_class); +} + +static void +cut_command_destruct(Command_t *parent) +{ + CutCommand_t *command = (CutCommand_t*) parent; + object_list_destruct(command->paste_buffer); +} + +static void +remove_one_object(Object_t *obj, gpointer data) +{ + CutCommand_t *command = (CutCommand_t*) data; + command_add_subcommand(&command->parent, + delete_command_new(command->list, obj)); +} + +static CmdExecuteValue_t +cut_command_execute(Command_t *parent) +{ + CutCommand_t *command = (CutCommand_t*) parent; + gpointer id; + + command->paste_buffer = object_list_copy(command->paste_buffer, + get_paste_buffer()); + id = object_list_add_remove_cb(command->list, remove_one_object, command); + object_list_cut(command->list); + object_list_remove_remove_cb(command->list, id); + + return CMD_APPEND; +} + +static void +cut_command_undo(Command_t *parent) +{ + CutCommand_t *command = (CutCommand_t*) parent; + object_list_copy(get_paste_buffer(), command->paste_buffer); +} diff --git a/plug-ins/imagemap/imap_cmd_cut_object.c b/plug-ins/imagemap/imap_cmd_cut_object.c new file mode 100644 index 0000000..780c4f8 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_cut_object.c @@ -0,0 +1,62 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t cut_object_command_execute(Command_t *parent); + +static CommandClass_t cut_object_command_class = { + NULL, /* cut_object_command_destruct */ + cut_object_command_execute, + NULL, /* cut_object_command_undo */ + NULL /* cut_object_command_redo */ +}; + +typedef struct { + Command_t parent; +} CutObjectCommand_t; + +Command_t* +cut_object_command_new(Object_t *obj) +{ + CutObjectCommand_t *command = g_new(CutObjectCommand_t, 1); + Command_t *parent; + + parent = command_init(&command->parent, _("Cut"), + &cut_object_command_class); + command_add_subcommand(parent, copy_object_command_new(obj)); + command_add_subcommand(parent, delete_command_new(obj->list, obj)); + + return parent; +} + +static CmdExecuteValue_t +cut_object_command_execute(Command_t *parent) +{ + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_delete.c b/plug-ins/imagemap/imap_cmd_delete.c new file mode 100644 index 0000000..6c85984 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_delete.c @@ -0,0 +1,83 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void delete_command_destruct(Command_t *parent); +static CmdExecuteValue_t delete_command_execute(Command_t *parent); +static void delete_command_undo(Command_t *parent); + +static CommandClass_t delete_command_class = { + delete_command_destruct, + delete_command_execute, + delete_command_undo, + NULL /* delete_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + Object_t *obj; + gint position; + gboolean changed; +} DeleteCommand_t; + +Command_t* +delete_command_new(ObjectList_t *list, Object_t *obj) +{ + DeleteCommand_t *command = g_new(DeleteCommand_t, 1); + command->list = list; + command->obj = object_ref(obj); + return command_init(&command->parent, _("Delete"), + &delete_command_class); +} + +static void +delete_command_destruct(Command_t *parent) +{ + DeleteCommand_t *command = (DeleteCommand_t*) parent; + object_unref(command->obj); +} + +static CmdExecuteValue_t +delete_command_execute(Command_t *parent) +{ + DeleteCommand_t *command = (DeleteCommand_t*) parent; + command->changed = object_list_get_changed(command->list); + command->position = object_get_position_in_list(command->obj); + object_list_remove(command->list, command->obj); + return CMD_APPEND; +} + +static void +delete_command_undo(Command_t *parent) +{ + DeleteCommand_t *command = (DeleteCommand_t*) parent; + object_list_insert(command->list, command->position, command->obj); + object_list_set_changed(command->list, command->changed); +} diff --git a/plug-ins/imagemap/imap_cmd_delete_point.c b/plug-ins/imagemap/imap_cmd_delete_point.c new file mode 100644 index 0000000..1dd6092 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_delete_point.c @@ -0,0 +1,86 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" +#include "imap_polygon.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t delete_point_command_execute(Command_t *parent); +static void delete_point_command_undo(Command_t *parent); + +static CommandClass_t delete_point_command_class = { + NULL, /* delete_point_command_destruct */ + delete_point_command_execute, + delete_point_command_undo, + NULL /* delete_point_command_redo */ +}; + +typedef struct { + Command_t parent; + Polygon_t *polygon; + GdkPoint *point; + GdkPoint copy; + gint position; +} DeletePointCommand_t; + +Command_t* +delete_point_command_new(Object_t *obj, GdkPoint *point) +{ + DeletePointCommand_t *command = g_new(DeletePointCommand_t, 1); + + command->polygon = ObjectToPolygon(obj); + command->point = point; + command->copy = *point; + command->position = g_list_index(command->polygon->points, + (gpointer) point); + return command_init(&command->parent, _("Delete Point"), + &delete_point_command_class); +} + +static CmdExecuteValue_t +delete_point_command_execute(Command_t *parent) +{ + DeletePointCommand_t *command = (DeletePointCommand_t*) parent; + Polygon_t *polygon = command->polygon; + GList *p = g_list_find(polygon->points, (gpointer) command->point); + + g_free(p->data); + polygon->points = g_list_remove_link(polygon->points, p); + return CMD_APPEND; +} + +static void +delete_point_command_undo(Command_t *parent) +{ + DeletePointCommand_t *command = (DeletePointCommand_t*) parent; + Polygon_t *polygon = command->polygon; + GdkPoint *point = &command->copy; + + command->point = new_point(point->x, point->y); + polygon->points = g_list_insert(polygon->points, (gpointer) command->point, + command->position); +} diff --git a/plug-ins/imagemap/imap_cmd_edit_object.c b/plug-ins/imagemap/imap_cmd_edit_object.c new file mode 100644 index 0000000..d2f0c39 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_edit_object.c @@ -0,0 +1,73 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void edit_object_command_destruct(Command_t *parent); +static void edit_object_command_undo(Command_t *parent); + +static CommandClass_t edit_object_command_class = { + edit_object_command_destruct, + NULL, /* edit_object_command_execute */ + edit_object_command_undo, + edit_object_command_undo +}; + +typedef struct { + Command_t parent; + Object_t *obj; + Object_t *copy; +} EditObjectCommand_t; + +Command_t* +edit_object_command_new(Object_t *obj) +{ + EditObjectCommand_t *command = g_new(EditObjectCommand_t, 1); + command->obj = object_ref(obj); + command->copy = object_clone(obj); + return command_init(&command->parent, _("Edit Object"), + &edit_object_command_class); +} + +static void +edit_object_command_destruct(Command_t *parent) +{ + EditObjectCommand_t *command = (EditObjectCommand_t*) parent; + object_unref(command->copy); + object_unref(command->obj); +} + +static void +edit_object_command_undo(Command_t *parent) +{ + EditObjectCommand_t *command = (EditObjectCommand_t*) parent; + Object_t *copy = object_clone(command->obj); + + object_assign(command->copy, command->obj); + object_assign(copy, command->copy); +} diff --git a/plug-ins/imagemap/imap_cmd_gimp_guides.c b/plug-ins/imagemap/imap_cmd_gimp_guides.c new file mode 100644 index 0000000..3f8fdd2 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_gimp_guides.c @@ -0,0 +1,260 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdio.h> + +#include <gtk/gtk.h> + +#include "libgimp/gimp.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "imap_commands.h" +#include "imap_default_dialog.h" +#include "imap_main.h" +#include "imap_rectangle.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +typedef struct { + DefaultDialog_t *dialog; + + ObjectList_t *list; + gint32 drawable_id; + + GtkWidget *alternate; + GtkWidget *all; + GtkWidget *left_border; + GtkWidget *right_border; + GtkWidget *upper_border; + GtkWidget *lower_border; + GtkWidget *url; +} GimpGuidesDialog_t; + +static gint +guide_sort_func(gconstpointer a, gconstpointer b) +{ + return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b); +} + +static void +gimp_guides_ok_cb(gpointer data) +{ + GimpGuidesDialog_t *param = (GimpGuidesDialog_t*) data; + gint guide_num; + GSList *hguides, *hg; + GSList *vguides, *vg; + gboolean all; + const gchar *url; + gint32 image_ID = gimp_item_get_image (param->drawable_id); + + /* First get some dialog values */ + + all = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->all)); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->left_border))) + vguides = g_slist_append(NULL, GINT_TO_POINTER(0)); + else + vguides = NULL; + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->right_border))) + vguides = g_slist_append(vguides, + GINT_TO_POINTER(gimp_image_width(image_ID))); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->upper_border))) + hguides = g_slist_append(NULL, GINT_TO_POINTER(0)); + else + hguides = NULL; + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->lower_border))) + hguides = g_slist_append(hguides, + GINT_TO_POINTER(gimp_image_height(image_ID))); + + url = gtk_entry_get_text(GTK_ENTRY(param->url)); + + /* Next get all the GIMP guides */ + + guide_num = gimp_image_find_next_guide(image_ID, 0); + + while (guide_num > 0) { + gint position = gimp_image_get_guide_position(image_ID, guide_num); + + if (gimp_image_get_guide_orientation(image_ID, guide_num) + == GIMP_ORIENTATION_HORIZONTAL) { + hguides = g_slist_insert_sorted(hguides, GINT_TO_POINTER(position), + guide_sort_func); + } else { /* GIMP_ORIENTATION_VERTICAL */ + vguides = g_slist_insert_sorted(vguides, GINT_TO_POINTER(position), + guide_sort_func); + } + guide_num = gimp_image_find_next_guide(image_ID, guide_num); + } + + /* Create the areas */ + + subcommand_start(_("Use Gimp Guides")); + + for (hg = hguides; hg && hg->next; + hg = (all) ? hg->next : hg->next->next) { + gint y = GPOINTER_TO_INT(hg->data); + gint height = GPOINTER_TO_INT(hg->next->data) - y; + for (vg = vguides; vg && vg->next; + vg = (all) ? vg->next : vg->next->next) { + gint x = GPOINTER_TO_INT(vg->data); + gint width = GPOINTER_TO_INT(vg->next->data) - x; + Object_t *obj = create_rectangle(x, y, width, height); + Command_t *command = create_command_new(param->list, obj); + + object_set_url(obj, url); + command_execute(command); + } + } + + subcommand_end(); + preview_redraw(); +} + +static GimpGuidesDialog_t* +make_gimp_guides_dialog(void) +{ + GimpGuidesDialog_t *data = g_new(GimpGuidesDialog_t, 1); + DefaultDialog_t *dialog; + GtkWidget *table, *frame, *hbox, *vbox; + GtkWidget *label; + + dialog = data->dialog = make_default_dialog(_("Use Gimp Guides")); + default_dialog_set_ok_cb(dialog, gimp_guides_ok_cb, data); + table = default_dialog_add_table(dialog, 3, 2); + + frame = gimp_frame_new(_("Create")); + gtk_widget_show(frame); + gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 1, 0, 1); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + + data->alternate = + gtk_radio_button_new_with_mnemonic_from_widget(NULL, _("Al_ternate")); + gtk_box_pack_start(GTK_BOX(hbox), data->alternate, FALSE, FALSE, 0); + gtk_widget_show(data->alternate); + + data->all = gtk_radio_button_new_with_mnemonic_from_widget( + GTK_RADIO_BUTTON(data->alternate), _("A_ll")); + gtk_box_pack_start(GTK_BOX(hbox), data->all, FALSE, FALSE, 0); + gtk_widget_show(data->all); + + frame = gimp_frame_new(_("Add Additional Guides")); + gtk_widget_show(frame); + gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 1, 1, 2); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_container_add(GTK_CONTAINER(frame), vbox); + gtk_widget_show(vbox); + + data->left_border = gtk_check_button_new_with_mnemonic(_("L_eft border")); + gtk_container_add(GTK_CONTAINER(vbox), data->left_border); + gtk_widget_show(data->left_border); + + data->right_border = gtk_check_button_new_with_mnemonic(_("_Right border")); + gtk_container_add(GTK_CONTAINER(vbox), data->right_border); + gtk_widget_show(data->right_border); + + data->upper_border = gtk_check_button_new_with_mnemonic(_("_Upper border")); + gtk_container_add(GTK_CONTAINER(vbox), data->upper_border); + gtk_widget_show(data->upper_border); + + data->lower_border = gtk_check_button_new_with_mnemonic(_("Lo_wer border")); + gtk_container_add(GTK_CONTAINER(vbox), data->lower_border); + gtk_widget_show(data->lower_border); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_table_attach_defaults(GTK_TABLE(table), hbox, 0, 2, 2, 3); + gtk_widget_show(hbox); + + label = gtk_label_new_with_mnemonic(_("_Base URL:")); + gtk_widget_show(label); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + data->url = gtk_entry_new(); + gtk_container_add(GTK_CONTAINER(hbox), data->url); + gtk_widget_show(data->url); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->url); + + return data; +} + +static void +init_gimp_guides_dialog(GimpGuidesDialog_t *dialog, ObjectList_t *list, + gint32 drawable_id) +{ + dialog->list = list; + dialog->drawable_id = drawable_id; +} + +static void +do_create_gimp_guides_dialog(ObjectList_t *list, gint32 drawable_id) +{ + static GimpGuidesDialog_t *dialog; + + if (!dialog) + dialog = make_gimp_guides_dialog(); + + init_gimp_guides_dialog(dialog, list, drawable_id); + default_dialog_show(dialog->dialog); +} + +static CmdExecuteValue_t gimp_guides_command_execute(Command_t *parent); + +static CommandClass_t gimp_guides_command_class = { + NULL, /* guides_command_destruct */ + gimp_guides_command_execute, + NULL, /* guides_command_undo */ + NULL /* guides_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + gint32 drawable_id; +} GimpGuidesCommand_t; + +Command_t* +gimp_guides_command_new(ObjectList_t *list, gint32 drawable_id) +{ + GimpGuidesCommand_t *command = g_new(GimpGuidesCommand_t, 1); + command->list = list; + command->drawable_id = drawable_id; + return command_init(&command->parent, _("Use Gimp Guides"), + &gimp_guides_command_class); +} + +static CmdExecuteValue_t +gimp_guides_command_execute(Command_t *parent) +{ + GimpGuidesCommand_t *command = (GimpGuidesCommand_t*) parent; + do_create_gimp_guides_dialog(command->list, command->drawable_id); + return CMD_DESTRUCT; +} diff --git a/plug-ins/imagemap/imap_cmd_guides.c b/plug-ins/imagemap/imap_cmd_guides.c new file mode 100644 index 0000000..aa9667f --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_guides.c @@ -0,0 +1,279 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_commands.h" +#include "imap_default_dialog.h" +#include "imap_main.h" +#include "imap_rectangle.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +typedef struct { + DefaultDialog_t *dialog; + GtkWidget *image_dimensions; + GtkWidget *guide_bounds; + GtkWidget *width; + GtkWidget *height; + GtkWidget *left; + GtkWidget *top; + GtkWidget *horz_spacing; + GtkWidget *vert_spacing; + GtkWidget *no_across; + GtkWidget *no_down; + GtkWidget *base_url; + + ObjectList_t *list; +} GuidesDialog_t; + +static void +guides_ok_cb(gpointer data) +{ + GuidesDialog_t *param = (GuidesDialog_t*) data; + gint y; + int i, j; + gint width, height, left, top, hspace, vspace, rows, cols; + + width = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->width)); + height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->height)); + left = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->left)); + top = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->top)); + hspace = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->horz_spacing)); + vspace = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->vert_spacing)); + rows = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_down)); + cols = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_across)); + + subcommand_start(_("Create Guides")); + y = top; + for (i = 0; i < rows; i++) { + gint x = left; + for (j = 0; j < cols; j++) { + Object_t *obj = create_rectangle(x, y, width, height); + Command_t *command = create_command_new(param->list, obj); + + object_set_url(obj, gtk_entry_get_text(GTK_ENTRY(param->base_url))); + command_execute(command); + x += width + hspace; + } + y += height + vspace; + } + subcommand_end(); +} + +static void +recalc_bounds(GtkWidget *widget, gpointer data) +{ + GuidesDialog_t *param = (GuidesDialog_t*) data; + gint width, height, left, top, hspace, vspace, rows, cols; + gint bound_w, bound_h; + gchar *bounds; + + width = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->width)); + height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->height)); + left = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->left)); + top = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->top)); + hspace = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->horz_spacing)); + vspace = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->vert_spacing)); + rows = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_down)); + cols = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_across)); + + bound_w = (width + hspace) * cols - hspace; + bound_h = (height + vspace) * rows - vspace; + + bounds = g_strdup_printf (_("Resulting Guide Bounds: %d,%d to %d,%d (%d areas)"), + left, top, left + bound_w, top + bound_h, rows * cols); + if (left + bound_w > get_image_width() || + top + bound_h > get_image_height()) + { + gtk_dialog_set_response_sensitive (GTK_DIALOG (param->dialog->dialog), + GTK_RESPONSE_OK, FALSE); + } + else + { + gtk_dialog_set_response_sensitive (GTK_DIALOG (param->dialog->dialog), + GTK_RESPONSE_OK, TRUE); + } + + gtk_label_set_text(GTK_LABEL(param->guide_bounds), bounds); + g_free (bounds); +} + +static GuidesDialog_t* +make_guides_dialog (void) +{ + GuidesDialog_t *data = g_new(GuidesDialog_t, 1); + DefaultDialog_t *dialog; + GtkWidget *table; + GtkWidget *label; + GtkWidget *hbox; + + dialog = data->dialog = make_default_dialog(_("Create Guides")); + default_dialog_set_ok_cb (dialog, guides_ok_cb, data); + + hbox = gimp_hint_box_new ( + _("Guides are pre-defined rectangles covering the image. You define " + "them by their width, height, and spacing from each other. This " + "allows you to rapidly create the most common image map type - " + "image collection of \"thumbnails\", suitable for navigation bars.")); + gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + data->image_dimensions = gtk_label_new (""); + gtk_label_set_xalign (GTK_LABEL (data->image_dimensions), 0.0); + gtk_box_pack_start (GTK_BOX (dialog->vbox), + data->image_dimensions, FALSE, FALSE, 0); + gtk_widget_show (data->image_dimensions); + + data->guide_bounds = gtk_label_new (""); + gtk_label_set_xalign (GTK_LABEL (data->guide_bounds), 0.0); + gtk_box_pack_start (GTK_BOX (dialog->vbox), + data->guide_bounds, FALSE, FALSE, 0); + gtk_widget_show (data->guide_bounds); + + table = default_dialog_add_table (dialog, 4, 4); + + label = create_label_in_table (table, 0, 0, _("_Width:")); + data->width = create_spin_button_in_table (table, label, 0, 1, 32, 1, 100); + g_signal_connect (data->width, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + label = create_label_in_table(table, 0, 2, _("_Left start at:")); + data->left = create_spin_button_in_table (table, label, 0, 3, 0, 0, 100); + g_signal_connect (data->left, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + label = create_label_in_table(table, 1, 0, _("_Height:")); + data->height = create_spin_button_in_table (table, label, 1, 1, 32, 1, 100); + g_signal_connect (data->height, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + label = create_label_in_table (table, 1, 2, _("_Top start at:")); + data->top = create_spin_button_in_table (table, label, 1, 3, 0, 0, 100); + g_signal_connect (data->top, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + label = create_label_in_table (table, 2, 0, _("_Horz. spacing:")); + data->horz_spacing = create_spin_button_in_table (table, label, 2, 1, 0, 0, + 100); + g_signal_connect (data->horz_spacing, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + label = create_label_in_table(table, 2, 2, _("_No. across:")); + data->no_across = create_spin_button_in_table(table, label, 2, 3, 0, 0, + 100); + g_signal_connect (data->no_across, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + label = create_label_in_table(table, 3, 0, _("_Vert. spacing:")); + data->vert_spacing = create_spin_button_in_table(table, label, 3, 1, 0, 0, + 100); + g_signal_connect (data->vert_spacing, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + label = create_label_in_table(table, 3, 2, _("No. _down:")); + data->no_down = create_spin_button_in_table (table, label, 3, 3, 0, 0, 100); + g_signal_connect (data->no_down, "changed", + G_CALLBACK(recalc_bounds), (gpointer) data); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show(hbox); + + label = gtk_label_new_with_mnemonic(_("Base _URL:")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + data->base_url = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (hbox), data->base_url, TRUE, TRUE, 0); + gtk_widget_show(data->base_url); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->base_url); + + return data; +} + +static void +init_guides_dialog(GuidesDialog_t *dialog, ObjectList_t *list) +{ + gchar *dimension; + + dialog->list = list; + dimension = g_strdup_printf (_("Image dimensions: %d × %d"), + get_image_width(), + get_image_height()); + gtk_label_set_text (GTK_LABEL(dialog->image_dimensions), dimension); + g_free (dimension); + gtk_label_set_text (GTK_LABEL(dialog->guide_bounds), + _("Resulting Guide Bounds: 0,0 to 0,0 (0 areas)")); + gtk_widget_grab_focus (dialog->width); +} + +static void +do_create_guides_dialog_local (ObjectList_t *list) +{ + static GuidesDialog_t *dialog; + + if (!dialog) + dialog = make_guides_dialog(); + + init_guides_dialog(dialog, list); + default_dialog_show(dialog->dialog); +} + +static CmdExecuteValue_t guides_command_execute(Command_t *parent); + +static CommandClass_t guides_command_class = { + NULL, /* guides_command_destruct */ + guides_command_execute, + NULL, /* guides_command_undo */ + NULL /* guides_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} GuidesCommand_t; + +Command_t* +guides_command_new(ObjectList_t *list) +{ + GuidesCommand_t *command = g_new(GuidesCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Guides"), &guides_command_class); +} + +static CmdExecuteValue_t +guides_command_execute(Command_t *parent) +{ + GuidesCommand_t *command = (GuidesCommand_t*) parent; + do_create_guides_dialog_local (command->list); + return CMD_DESTRUCT; +} diff --git a/plug-ins/imagemap/imap_cmd_insert_point.c b/plug-ins/imagemap/imap_cmd_insert_point.c new file mode 100644 index 0000000..ad887d3 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_insert_point.c @@ -0,0 +1,96 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" +#include "imap_main.h" +#include "imap_polygon.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t insert_point_command_execute(Command_t *parent); +static void insert_point_command_undo(Command_t *parent); + +static CommandClass_t insert_point_command_class = { + NULL, /* insert_point_command_destruct */ + insert_point_command_execute, + insert_point_command_undo, + NULL /* insert_point_command_redo */ +}; + +typedef struct { + Command_t parent; + Polygon_t *polygon; + gint x; + gint y; + gint edge; + gint position; +} InsertPointCommand_t; + +Command_t* +insert_point_command_new(Object_t *obj, gint x, gint y, gint edge) +{ + InsertPointCommand_t *command = g_new(InsertPointCommand_t, 1); + + command->polygon = ObjectToPolygon(obj); + command->x = x; + command->y = y; + command->edge = edge; + return command_init(&command->parent, _("Insert Point"), + &insert_point_command_class); +} + +static CmdExecuteValue_t +insert_point_command_execute(Command_t *parent) +{ + InsertPointCommand_t *command = (InsertPointCommand_t*) parent; + Polygon_t *polygon = command->polygon; + + GdkPoint *point = new_point(command->x, command->y); + + if (g_list_length(polygon->points) == command->edge - 1) { + polygon->points = g_list_append(polygon->points, (gpointer) point); + command->position = command->edge - 1; + } else { + polygon->points = g_list_insert(polygon->points, (gpointer) point, + command->edge); + command->position = command->edge; + } + preview_redraw(); + + return CMD_APPEND; +} + +static void +insert_point_command_undo(Command_t *parent) +{ + InsertPointCommand_t *command = (InsertPointCommand_t*) parent; + Polygon_t *polygon = command->polygon; + GList *p = g_list_nth(polygon->points, command->position); + + g_free(p->data); + polygon->points = g_list_remove_link(polygon->points, p); + preview_redraw(); /* Fix me! */ +} diff --git a/plug-ins/imagemap/imap_cmd_move.c b/plug-ins/imagemap/imap_cmd_move.c new file mode 100644 index 0000000..491b12d --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_move.c @@ -0,0 +1,166 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "libgimp/gimp.h" + +#include "imap_commands.h" +#include "imap_main.h" + +#include "libgimp/stdplugins-intl.h" + +static void move_command_destruct(Command_t *parent); +static CmdExecuteValue_t move_command_execute(Command_t *parent); + +static CommandClass_t move_command_class = { + move_command_destruct, + move_command_execute, + NULL, /* move_command_undo */ + NULL /* move_command_redo */ +}; + +typedef struct { + Command_t parent; + PreferencesData_t *preferences; + Preview_t *preview; + Object_t *obj; + gint start_x; + gint start_y; + gint obj_start_x; + gint obj_start_y; + gint obj_x; + gint obj_y; + gint obj_width; + gint obj_height; + + gint image_width; + gint image_height; + + GdkCursorType cursor; /* Remember previous cursor */ + gboolean moved_first_time; +} MoveCommand_t; + +Command_t* +move_command_new(Preview_t *preview, Object_t *obj, gint x, gint y) +{ + MoveCommand_t *command = g_new(MoveCommand_t, 1); + + command->preferences = get_preferences(); + command->preview = preview; + command->obj = object_ref(obj); + command->start_x = x; + command->start_y = y; + object_get_dimensions(obj, &command->obj_x, &command->obj_y, + &command->obj_width, &command->obj_height); + command->obj_start_x = command->obj_x; + command->obj_start_y = command->obj_y; + + command->image_width = get_image_width(); + command->image_height = get_image_height(); + + command->moved_first_time = TRUE; + + return command_init(&command->parent, _("Move"), &move_command_class); +} + +static void +move_command_destruct(Command_t *parent) +{ + MoveCommand_t *command = (MoveCommand_t*) parent; + object_unref(command->obj); +} + +static void +button_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) +{ + MoveCommand_t *command = (MoveCommand_t*) data; + Object_t *obj = command->obj; + gint dx = get_real_coord((gint) event->x) - command->start_x; + gint dy = get_real_coord((gint) event->y) - command->start_y; + + if (command->moved_first_time) { + command->moved_first_time = FALSE; + command->cursor = preview_set_cursor(command->preview, GDK_FLEUR); + hide_url(); + } + + if (command->obj_x + dx < 0) + dx = -command->obj_x; + if (command->obj_x + command->obj_width + dx > command->image_width) + dx = command->image_width - command->obj_width - command->obj_x; + if (command->obj_y + dy < 0) + dy = -command->obj_y; + if (command->obj_y + command->obj_height + dy > command->image_height) + dy = command->image_height - command->obj_height - command->obj_y; + + if (dx || dy) { + + command->start_x = get_real_coord((gint) event->x); + command->start_y = get_real_coord((gint) event->y); + command->obj_x += dx; + command->obj_y += dy; + + object_move(obj, dx, dy); + + preview_redraw (); + } +} + +static void +button_release(GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + MoveCommand_t *command = (MoveCommand_t*) data; + + g_signal_handlers_disconnect_by_func (widget, + button_motion, data); + g_signal_handlers_disconnect_by_func (widget, + button_release, data); + + if (!command->moved_first_time) { + preview_set_cursor(command->preview, command->cursor); + show_url(); + } + command->obj_x -= command->obj_start_x; + command->obj_y -= command->obj_start_y; + if (command->obj_x || command->obj_y) + command_list_add(object_move_command_new(command->obj, command->obj_x, + command->obj_y)); + + /* preview_thaw(); */ +} + +static CmdExecuteValue_t +move_command_execute(Command_t *parent) +{ + MoveCommand_t *command = (MoveCommand_t*) parent; + GtkWidget *widget = command->preview->preview; + + /* preview_freeze(); */ + g_signal_connect(widget, "button-release-event", + G_CALLBACK (button_release), command); + g_signal_connect(widget, "motion-notify-event", + G_CALLBACK (button_motion), command); + return CMD_DESTRUCT; +} diff --git a/plug-ins/imagemap/imap_cmd_move_down.c b/plug-ins/imagemap/imap_cmd_move_down.c new file mode 100644 index 0000000..401e597 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_move_down.c @@ -0,0 +1,82 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t move_down_command_execute(Command_t *parent); + +static CommandClass_t move_down_command_class = { + NULL, /* move_down_command_destruct */ + move_down_command_execute, + NULL, /* move_down_command_undo */ + NULL /* move_down_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + gboolean add; +} MoveDownCommand_t; + +Command_t* +move_down_command_new(ObjectList_t *list) +{ + MoveDownCommand_t *command = g_new(MoveDownCommand_t, 1); + command->list = list; + command->add = FALSE; + return command_init(&command->parent, _("Move Down"), + &move_down_command_class); +} + +static void +move_down_one_object(Object_t *obj, gpointer data) +{ + MoveDownCommand_t *command = (MoveDownCommand_t*) data; + + if (command->add) { + command_add_subcommand(&command->parent, + object_down_command_new(command->list, obj)); + command->add = FALSE; + } + else { + command->add = TRUE; + } +} + +static CmdExecuteValue_t +move_down_command_execute(Command_t *parent) +{ + MoveDownCommand_t *command = (MoveDownCommand_t*) parent; + gpointer id; + + id = object_list_add_move_cb(command->list, move_down_one_object, command); + object_list_move_selected_down(command->list); + object_list_remove_move_cb(command->list, id); + + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_move_sash.c b/plug-ins/imagemap/imap_cmd_move_sash.c new file mode 100644 index 0000000..85c1db8 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_move_sash.c @@ -0,0 +1,150 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" +#include "imap_main.h" + +#include "libgimp/stdplugins-intl.h" + +static void move_sash_command_destruct(Command_t *command); +static CmdExecuteValue_t move_sash_command_execute(Command_t *command); +static void move_sash_command_redo(Command_t *command); + +static CommandClass_t move_sash_command_class = { + move_sash_command_destruct, + move_sash_command_execute, + NULL /*undo*/, + move_sash_command_redo +}; + +typedef struct { + Command_t parent; + GtkWidget *widget; + Object_t *obj; + gint x; + gint y; + gint image_width; + gint image_height; + MoveSashFunc_t sash_func; +} MoveSashCommand_t; + +Command_t* +move_sash_command_new(GtkWidget *widget, Object_t *obj, + gint x, gint y, MoveSashFunc_t sash_func) +{ + MoveSashCommand_t *command = g_new(MoveSashCommand_t, 1); + Command_t *parent; + + command->widget = widget; + command->obj = object_ref(obj); + command->x = x; + command->y = y; + command->image_width = get_image_width(); + command->image_height = get_image_height(); + command->sash_func = sash_func; + + parent = command_init(&command->parent, _("Move Sash"), + &move_sash_command_class); + command_add_subcommand(parent, edit_object_command_new(obj)); + + return parent; +} + +static void +move_sash_command_destruct(Command_t *parent) +{ + MoveSashCommand_t *command = (MoveSashCommand_t*) parent; + object_unref(command->obj); +} + +static void +sash_move(GtkWidget *widget, GdkEventMotion *event, gpointer data) +{ + MoveSashCommand_t *command = (MoveSashCommand_t*) data; + Object_t *obj = command->obj; + gint x, y, dx, dy; + + x = get_real_coord((gint) event->x); + y = get_real_coord((gint) event->y); + + if (x < 0) + x = 0; + if (x > command->image_width) + x = command->image_width; + + if (y < 0) + y = 0; + if (y > command->image_height) + y = command->image_height; + + dx = x - command->x; + dy = y - command->y; + + command->x = x; + command->y = y; + + command->sash_func(obj, dx, dy); + object_emit_geometry_signal(obj); + + preview_redraw (); +} + +static void +sash_end(GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + MoveSashCommand_t *command = (MoveSashCommand_t*) data; + Object_t *obj = command->obj; + + g_signal_handlers_disconnect_by_func(widget, + sash_move, data); + g_signal_handlers_disconnect_by_func(widget, + sash_end, data); + if (obj->class->normalize) + object_normalize(obj); + preview_unset_tmp_obj(command->obj); + preview_redraw(); + show_url(); +} + +static CmdExecuteValue_t +move_sash_command_execute(Command_t *parent) +{ + MoveSashCommand_t *command = (MoveSashCommand_t*) parent; + + hide_url(); + g_signal_connect(command->widget, "button-release-event", + G_CALLBACK (sash_end), command); + g_signal_connect(command->widget, "motion-notify-event", + G_CALLBACK (sash_move), command); + preview_set_tmp_obj(command->obj); + + return CMD_APPEND; +} + +static void move_sash_command_redo(Command_t *command) +{ + /* do nothing, but avoid running execute again which will break event handling */ +} diff --git a/plug-ins/imagemap/imap_cmd_move_selected.c b/plug-ins/imagemap/imap_cmd_move_selected.c new file mode 100644 index 0000000..690a86a --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_move_selected.c @@ -0,0 +1,72 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t move_selected_command_execute(Command_t *parent); +static void move_selected_command_undo(Command_t *parent); + +static CommandClass_t move_selected_command_class = { + NULL, /* move_selected_command_destruct */ + move_selected_command_execute, + move_selected_command_undo, + NULL /* move_selected_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + gint dx; + gint dy; +} MoveSelectedCommand_t; + +Command_t* +move_selected_command_new(ObjectList_t *list, gint dx, gint dy) +{ + MoveSelectedCommand_t *command = g_new(MoveSelectedCommand_t, 1); + command->list = list; + command->dx = dx; + command->dy = dy; + return command_init(&command->parent, _("Move Selected Objects"), + &move_selected_command_class); +} + +static CmdExecuteValue_t +move_selected_command_execute(Command_t *parent) +{ + MoveSelectedCommand_t *command = (MoveSelectedCommand_t*) parent; + object_list_move_selected(command->list, command->dx, command->dy); + return CMD_APPEND; +} + +static void +move_selected_command_undo(Command_t *parent) +{ + MoveSelectedCommand_t *command = (MoveSelectedCommand_t*) parent; + object_list_move_selected(command->list, -command->dx, -command->dy); +} diff --git a/plug-ins/imagemap/imap_cmd_move_to_front.c b/plug-ins/imagemap/imap_cmd_move_to_front.c new file mode 100644 index 0000000..c8f81e1 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_move_to_front.c @@ -0,0 +1,83 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t move_to_front_command_execute(Command_t *parent); + +static CommandClass_t move_to_front_command_class = { + NULL, /* move_to_front_command_destruct, */ + move_to_front_command_execute, + NULL, /* move_to_front_command_undo */ + NULL /* move_to_front_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} MoveToFrontCommand_t; + +Command_t* +move_to_front_command_new(ObjectList_t *list) +{ + MoveToFrontCommand_t *command = g_new(MoveToFrontCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Move To Front"), + &move_to_front_command_class); +} + +static void +remove_one_object(Object_t *obj, gpointer data) +{ + MoveToFrontCommand_t *command = (MoveToFrontCommand_t*) data; + command_add_subcommand(&command->parent, + delete_command_new(command->list, obj)); +} + +static void +add_one_object(Object_t *obj, gpointer data) +{ + MoveToFrontCommand_t *command = (MoveToFrontCommand_t*) data; + command_add_subcommand(&command->parent, + create_command_new(command->list, obj)); +} + +static CmdExecuteValue_t +move_to_front_command_execute(Command_t *parent) +{ + MoveToFrontCommand_t *command = (MoveToFrontCommand_t*) parent; + gpointer id1, id2; + + id1 = object_list_add_remove_cb(command->list, remove_one_object, command); + id2 = object_list_add_add_cb(command->list, add_one_object, command); + + object_list_move_to_front(command->list); + object_list_remove_remove_cb(command->list, id1); + object_list_remove_add_cb(command->list, id2); + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_move_up.c b/plug-ins/imagemap/imap_cmd_move_up.c new file mode 100644 index 0000000..ed253a2 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_move_up.c @@ -0,0 +1,81 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t move_up_command_execute(Command_t *parent); + +static CommandClass_t move_up_command_class = { + NULL, /* move_up_command_destruct */ + move_up_command_execute, + NULL, /* move_up_command_undo */ + NULL /* move_up_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + gboolean add; +} MoveUpCommand_t; + +Command_t* +move_up_command_new(ObjectList_t *list) +{ + MoveUpCommand_t *command = g_new(MoveUpCommand_t, 1); + command->list = list; + command->add = FALSE; + return command_init(&command->parent, _("Move Up"), &move_up_command_class); +} + +static void +move_up_one_object(Object_t *obj, gpointer data) +{ + MoveUpCommand_t *command = (MoveUpCommand_t*) data; + + if (command->add) { + command_add_subcommand(&command->parent, + object_up_command_new(command->list, obj)); + command->add = FALSE; + } + else { + command->add = TRUE; + } +} + +static CmdExecuteValue_t +move_up_command_execute(Command_t *parent) +{ + MoveUpCommand_t *command = (MoveUpCommand_t*) parent; + gpointer id; + + id = object_list_add_move_cb(command->list, move_up_one_object, command); + object_list_move_selected_up(command->list); + object_list_remove_move_cb(command->list, id); + + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_object_down.c b/plug-ins/imagemap/imap_cmd_object_down.c new file mode 100644 index 0000000..2849b71 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_object_down.c @@ -0,0 +1,78 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void object_down_command_destruct(Command_t *parent); +static CmdExecuteValue_t object_down_command_execute(Command_t *parent); +static void object_down_command_undo(Command_t *parent); + +static CommandClass_t object_down_command_class = { + object_down_command_destruct, + object_down_command_execute, + object_down_command_undo, + NULL /* object_down_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + Object_t *obj; +} ObjectDownCommand_t; + +Command_t* +object_down_command_new(ObjectList_t *list, Object_t *obj) +{ + ObjectDownCommand_t *command = g_new(ObjectDownCommand_t, 1); + command->list = list; + command->obj = object_ref(obj); + return command_init(&command->parent, _("Move Down"), + &object_down_command_class); +} + +static void +object_down_command_destruct(Command_t *parent) +{ + ObjectDownCommand_t *command = (ObjectDownCommand_t*) parent; + object_unref(command->obj); +} + +static CmdExecuteValue_t +object_down_command_execute(Command_t *parent) +{ + ObjectDownCommand_t *command = (ObjectDownCommand_t*) parent; + object_list_move_down(command->list, command->obj); + return CMD_APPEND; +} + +static void +object_down_command_undo(Command_t *parent) +{ + ObjectDownCommand_t *command = (ObjectDownCommand_t*) parent; + object_list_move_up(command->list, command->obj); +} diff --git a/plug-ins/imagemap/imap_cmd_object_move.c b/plug-ins/imagemap/imap_cmd_object_move.c new file mode 100644 index 0000000..39c575c --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_object_move.c @@ -0,0 +1,80 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void object_move_command_destruct(Command_t *parent); +static CmdExecuteValue_t object_move_command_execute(Command_t *parent); +static void object_move_command_undo(Command_t *parent); + +static CommandClass_t object_move_command_class = { + object_move_command_destruct, + object_move_command_execute, + object_move_command_undo, + NULL /* object_move_command_redo */ +}; + +typedef struct { + Command_t parent; + Object_t *obj; + gint dx; + gint dy; +} ObjectMoveCommand_t; + +Command_t* +object_move_command_new(Object_t *obj, gint dx, gint dy) +{ + ObjectMoveCommand_t *command = g_new(ObjectMoveCommand_t, 1); + command->obj = object_ref(obj); + command->dx = dx; + command->dy = dy; + return command_init(&command->parent, _("Move"), + &object_move_command_class); +} + +static void +object_move_command_destruct(Command_t *parent) +{ + ObjectMoveCommand_t *command = (ObjectMoveCommand_t*) parent; + object_unref(command->obj); +} + +static CmdExecuteValue_t +object_move_command_execute(Command_t *parent) +{ + ObjectMoveCommand_t *command = (ObjectMoveCommand_t*) parent; + object_move(command->obj, command->dx, command->dy); + return CMD_APPEND; +} + +static void +object_move_command_undo(Command_t *parent) +{ + ObjectMoveCommand_t *command = (ObjectMoveCommand_t*) parent; + object_move(command->obj, -command->dx, -command->dy); +} diff --git a/plug-ins/imagemap/imap_cmd_object_up.c b/plug-ins/imagemap/imap_cmd_object_up.c new file mode 100644 index 0000000..edc8f40 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_object_up.c @@ -0,0 +1,78 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void object_up_command_destruct(Command_t *parent); +static CmdExecuteValue_t object_up_command_execute(Command_t *parent); +static void object_up_command_undo(Command_t *parent); + +static CommandClass_t object_up_command_class = { + object_up_command_destruct, + object_up_command_execute, + object_up_command_undo, + NULL /* object_up_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + Object_t *obj; +} ObjectUpCommand_t; + +Command_t* +object_up_command_new(ObjectList_t *list, Object_t *obj) +{ + ObjectUpCommand_t *command = g_new(ObjectUpCommand_t, 1); + command->list = list; + command->obj = object_ref(obj); + return command_init(&command->parent, _("Move Up"), + &object_up_command_class); +} + +static void +object_up_command_destruct(Command_t *parent) +{ + ObjectUpCommand_t *command = (ObjectUpCommand_t*) parent; + object_unref(command->obj); +} + +static CmdExecuteValue_t +object_up_command_execute(Command_t *parent) +{ + ObjectUpCommand_t *command = (ObjectUpCommand_t*) parent; + object_list_move_up(command->list, command->obj); + return CMD_APPEND; +} + +static void +object_up_command_undo(Command_t *parent) +{ + ObjectUpCommand_t *command = (ObjectUpCommand_t*) parent; + object_list_move_down(command->list, command->obj); +} diff --git a/plug-ins/imagemap/imap_cmd_paste.c b/plug-ins/imagemap/imap_cmd_paste.c new file mode 100644 index 0000000..5855548 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_paste.c @@ -0,0 +1,71 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t paste_command_execute(Command_t *parent); + +static CommandClass_t paste_command_class = { + NULL, /* paste_command_destruct, */ + paste_command_execute, + NULL, /* paste_command_undo */ + NULL /* paste_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} PasteCommand_t; + +Command_t* +paste_command_new(ObjectList_t *list) +{ + PasteCommand_t *command = g_new(PasteCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Paste"), &paste_command_class); +} + +static void +paste_one_object(Object_t *obj, gpointer data) +{ + PasteCommand_t *command = (PasteCommand_t*) data; + command_add_subcommand(&command->parent, + create_command_new(command->list, obj)); +} + +static CmdExecuteValue_t +paste_command_execute(Command_t *parent) +{ + PasteCommand_t *command = (PasteCommand_t*) parent; + gpointer id; + + id = object_list_add_add_cb(command->list, paste_one_object, command); + object_list_paste(command->list); + object_list_remove_add_cb(command->list, id); + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_select.c b/plug-ins/imagemap/imap_cmd_select.c new file mode 100644 index 0000000..cbfa38d --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_select.c @@ -0,0 +1,75 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void select_command_destruct(Command_t *parent); +static CmdExecuteValue_t select_command_execute(Command_t *parent); +static void select_command_undo(Command_t *parent); + +static CommandClass_t select_command_class = { + select_command_destruct, + select_command_execute, + select_command_undo, + NULL /* select_command_redo */ +}; + +typedef struct { + Command_t parent; + Object_t *obj; +} SelectCommand_t; + +Command_t* +select_command_new(Object_t *obj) +{ + SelectCommand_t *command = g_new(SelectCommand_t, 1); + command->obj = object_ref(obj); + return command_init(&command->parent, _("Select"), &select_command_class); +} + +static void +select_command_destruct(Command_t *parent) +{ + SelectCommand_t *command = (SelectCommand_t*) parent; + object_unref(command->obj); +} + +static CmdExecuteValue_t +select_command_execute(Command_t *parent) +{ + SelectCommand_t *command = (SelectCommand_t*) parent; + object_select(command->obj); + return CMD_APPEND; +} + +static void +select_command_undo(Command_t *parent) +{ + SelectCommand_t *command = (SelectCommand_t*) parent; + object_unselect(command->obj); +} diff --git a/plug-ins/imagemap/imap_cmd_select_all.c b/plug-ins/imagemap/imap_cmd_select_all.c new file mode 100644 index 0000000..286db3e --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_select_all.c @@ -0,0 +1,74 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t select_all_command_execute(Command_t *parent); + +static CommandClass_t select_all_command_class = { + NULL, /* select_all_command_destruct, */ + select_all_command_execute, + NULL, /* select_all_command_undo */ + NULL /* select_all_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} SelectAllCommand_t; + +Command_t* +select_all_command_new(ObjectList_t *list) +{ + SelectAllCommand_t *command = g_new(SelectAllCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Select All"), + &select_all_command_class); +} + +static void +select_one_object(Object_t *obj, gpointer data) +{ + SelectAllCommand_t *command = (SelectAllCommand_t*) data; + command_add_subcommand(&command->parent, select_command_new(obj)); +} + +static CmdExecuteValue_t +select_all_command_execute(Command_t *parent) +{ + SelectAllCommand_t *command = (SelectAllCommand_t*) parent; + gpointer id; + CmdExecuteValue_t rvalue; + + id = object_list_add_select_cb(command->list, select_one_object, command); + rvalue = (object_list_select_all(command->list)) + ? CMD_APPEND : CMD_DESTRUCT; + object_list_remove_select_cb(command->list, id); + + return rvalue; +} diff --git a/plug-ins/imagemap/imap_cmd_select_next.c b/plug-ins/imagemap/imap_cmd_select_next.c new file mode 100644 index 0000000..325cacb --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_select_next.c @@ -0,0 +1,76 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t select_next_command_execute(Command_t *parent); + +static CommandClass_t select_next_command_class = { + NULL, /* select_next_command_destruct */ + select_next_command_execute, + NULL, /* select_next_command_undo */ + NULL /* select_next_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} SelectNextCommand_t; + +Command_t* +select_next_command_new(ObjectList_t *list) +{ + SelectNextCommand_t *command = g_new(SelectNextCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Select Next"), + &select_next_command_class); +} + +static void +select_one_object(Object_t *obj, gpointer data) +{ + SelectNextCommand_t *command = (SelectNextCommand_t*) data; + Command_t *sub_command; + + sub_command = (obj->selected) + ? select_command_new(obj) : unselect_command_new(obj); + command_add_subcommand(&command->parent, sub_command); +} + +static CmdExecuteValue_t +select_next_command_execute(Command_t *parent) +{ + SelectNextCommand_t *command = (SelectNextCommand_t*) parent; + ObjectList_t *list = command->list; + gpointer id; + + id = object_list_add_select_cb(list, select_one_object, command); + object_list_select_next(list); + object_list_remove_select_cb(list, id); + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_select_prev.c b/plug-ins/imagemap/imap_cmd_select_prev.c new file mode 100644 index 0000000..9f5b8eb --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_select_prev.c @@ -0,0 +1,76 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t select_prev_command_execute(Command_t *parent); + +static CommandClass_t select_prev_command_class = { + NULL, /* select_prev_command_destruct */ + select_prev_command_execute, + NULL, /* select_prev_command_undo */ + NULL /* select_prev_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} SelectPrevCommand_t; + +Command_t* +select_prev_command_new(ObjectList_t *list) +{ + SelectPrevCommand_t *command = g_new(SelectPrevCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Select Previous"), + &select_prev_command_class); +} + +static void +select_one_object(Object_t *obj, gpointer data) +{ + SelectPrevCommand_t *command = (SelectPrevCommand_t*) data; + Command_t *sub_command; + + sub_command = (obj->selected) + ? select_command_new(obj) : unselect_command_new(obj); + command_add_subcommand(&command->parent, sub_command); +} + +static CmdExecuteValue_t +select_prev_command_execute(Command_t *parent) +{ + SelectPrevCommand_t *command = (SelectPrevCommand_t*) parent; + ObjectList_t *list = command->list; + gpointer id; + + id = object_list_add_select_cb(list, select_one_object, command); + object_list_select_prev(list); + object_list_remove_select_cb(list, id); + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_select_region.c b/plug-ins/imagemap/imap_cmd_select_region.c new file mode 100644 index 0000000..6e0029b --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_select_region.c @@ -0,0 +1,142 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" +#include "imap_rectangle.h" +#include "imap_main.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t select_region_command_execute(Command_t *parent); + +static CommandClass_t select_region_command_class = { + NULL, /* select_region_command_destruct, */ + select_region_command_execute, + NULL, /* select_region_command_undo */ + NULL /* select_region_command_redo */ +}; + +typedef struct { + Command_t parent; + GtkWidget *widget; + ObjectList_t *list; + gint x; + gint y; + Object_t *obj; + Command_t *unselect_command; +} SelectRegionCommand_t; + +Command_t* +select_region_command_new(GtkWidget *widget, ObjectList_t *list, gint x, + gint y) +{ + SelectRegionCommand_t *command = g_new(SelectRegionCommand_t, 1); + Command_t *sub_command; + + command->widget = widget; + command->list = list; + command->x = x; + command->y = y; + (void) command_init(&command->parent, _("Select Region"), + &select_region_command_class); + + sub_command = unselect_all_command_new(list, NULL); + command_add_subcommand(&command->parent, sub_command); + command->unselect_command = sub_command; + + return &command->parent; +} + +static void +select_one_object(Object_t *obj, gpointer data) +{ + SelectRegionCommand_t *command = (SelectRegionCommand_t*) data; + command_add_subcommand(&command->parent, select_command_new(obj)); +} + +static void +select_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) +{ + SelectRegionCommand_t *command = (SelectRegionCommand_t*) data; + Object_t *obj = command->obj; + Rectangle_t *rectangle = ObjectToRectangle(obj); + + gint x = get_real_coord((gint) event->x); + gint y = get_real_coord((gint) event->y); + + rectangle->width = x - rectangle->x; + rectangle->height = y - rectangle->y; + + preview_redraw (); +} + +static void +select_release(GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + SelectRegionCommand_t *command = (SelectRegionCommand_t*) data; + Object_t *obj = command->obj; + Rectangle_t *rectangle = ObjectToRectangle(obj); + gpointer id; + gint count; + + g_signal_handlers_disconnect_by_func(widget, + select_motion, data); + g_signal_handlers_disconnect_by_func(widget, + select_release, data); + + object_normalize(obj); + + id = object_list_add_select_cb(command->list, select_one_object, command); + count = object_list_select_region(command->list, rectangle->x, rectangle->y, + rectangle->width, rectangle->height); + object_list_remove_select_cb(command->list, id); + + if (count) { + command_list_add(&command->parent); + } else { /* Nothing selected */ + if (command->unselect_command->sub_commands) + command_list_add(&command->parent); + } + preview_unset_tmp_obj (command->obj); + + preview_redraw (); +} + +static CmdExecuteValue_t +select_region_command_execute(Command_t *parent) +{ + SelectRegionCommand_t *command = (SelectRegionCommand_t*) parent; + + command->obj = create_rectangle(command->x, command->y, 0, 0); + preview_set_tmp_obj (command->obj); + + g_signal_connect(command->widget, "button-release-event", + G_CALLBACK (select_release), command); + g_signal_connect(command->widget, "motion-notify-event", + G_CALLBACK (select_motion), command); + + return CMD_IGNORE; +} diff --git a/plug-ins/imagemap/imap_cmd_send_to_back.c b/plug-ins/imagemap/imap_cmd_send_to_back.c new file mode 100644 index 0000000..99e2e1e --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_send_to_back.c @@ -0,0 +1,83 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static CmdExecuteValue_t send_to_back_command_execute(Command_t *parent); + +static CommandClass_t send_to_back_command_class = { + NULL, /* send_to_back_command_destruct, */ + send_to_back_command_execute, + NULL, /* send_to_back_command_undo */ + NULL /* send_to_back_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; +} SendToBackCommand_t; + +Command_t* +send_to_back_command_new(ObjectList_t *list) +{ + SendToBackCommand_t *command = g_new(SendToBackCommand_t, 1); + command->list = list; + return command_init(&command->parent, _("Send To Back"), + &send_to_back_command_class); +} + +static void +remove_one_object(Object_t *obj, gpointer data) +{ + SendToBackCommand_t *command = (SendToBackCommand_t*) data; + command_add_subcommand(&command->parent, + delete_command_new(command->list, obj)); +} + +static void +add_one_object(Object_t *obj, gpointer data) +{ + SendToBackCommand_t *command = (SendToBackCommand_t*) data; + command_add_subcommand(&command->parent, + create_command_new(command->list, obj)); +} + +static CmdExecuteValue_t +send_to_back_command_execute(Command_t *parent) +{ + SendToBackCommand_t *command = (SendToBackCommand_t*) parent; + gpointer id1, id2; + + id1 = object_list_add_remove_cb(command->list, remove_one_object, command); + id2 = object_list_add_add_cb(command->list, add_one_object, command); + + object_list_send_to_back(command->list); + object_list_remove_remove_cb(command->list, id1); + object_list_remove_add_cb(command->list, id2); + return CMD_APPEND; +} diff --git a/plug-ins/imagemap/imap_cmd_unselect.c b/plug-ins/imagemap/imap_cmd_unselect.c new file mode 100644 index 0000000..23bac7c --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_unselect.c @@ -0,0 +1,76 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void unselect_command_destruct(Command_t *parent); +static CmdExecuteValue_t unselect_command_execute(Command_t *parent); +static void unselect_command_undo(Command_t *parent); + +static CommandClass_t unselect_command_class = { + unselect_command_destruct, + unselect_command_execute, + unselect_command_undo, + NULL /* unselect_command_redo */ +}; + +typedef struct { + Command_t parent; + Object_t *obj; +} UnselectCommand_t; + +Command_t* +unselect_command_new(Object_t *obj) +{ + UnselectCommand_t *command = g_new(UnselectCommand_t, 1); + command->obj = object_ref(obj); + return command_init(&command->parent, _("Unselect"), + &unselect_command_class); +} + +static void +unselect_command_destruct(Command_t *command) +{ + UnselectCommand_t *unselect_command = (UnselectCommand_t*) command; + object_unref(unselect_command->obj); +} + +static CmdExecuteValue_t +unselect_command_execute(Command_t *command) +{ + UnselectCommand_t *unselect_command = (UnselectCommand_t*) command; + object_unselect(unselect_command->obj); + return CMD_APPEND; +} + +static void +unselect_command_undo(Command_t *command) +{ + UnselectCommand_t *unselect_command = (UnselectCommand_t*) command; + object_select(unselect_command->obj); +} diff --git a/plug-ins/imagemap/imap_cmd_unselect_all.c b/plug-ins/imagemap/imap_cmd_unselect_all.c new file mode 100644 index 0000000..f1e45e4 --- /dev/null +++ b/plug-ins/imagemap/imap_cmd_unselect_all.c @@ -0,0 +1,90 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" + +#include "libgimp/stdplugins-intl.h" + +static void unselect_all_command_destruct(Command_t *command); +static CmdExecuteValue_t unselect_all_command_execute(Command_t *command); + +/* COMMAND_PROTO(unselect_all_command); */ + +static CommandClass_t unselect_all_command_class = { + unselect_all_command_destruct, + unselect_all_command_execute, + NULL, /* unselect_all_command_undo */ + NULL /* unselect_all_command_redo */ +}; + +typedef struct { + Command_t parent; + ObjectList_t *list; + Object_t *exception; +} UnselectAllCommand_t; + +Command_t* +unselect_all_command_new(ObjectList_t *list, Object_t *exception) +{ + UnselectAllCommand_t *command = g_new(UnselectAllCommand_t, 1); + command->list = list; + command->exception = (exception) ? object_ref(exception) : exception; + return command_init(&command->parent, _("Unselect All"), + &unselect_all_command_class); +} + +static void +unselect_all_command_destruct(Command_t *parent) +{ + UnselectAllCommand_t *command = (UnselectAllCommand_t*) parent; + if (command->exception) + object_unref(command->exception); +} + +static void +select_one_object(Object_t *obj, gpointer data) +{ + UnselectAllCommand_t *command = (UnselectAllCommand_t*) data; + command_add_subcommand(&command->parent, unselect_command_new(obj)); +} + +static CmdExecuteValue_t +unselect_all_command_execute(Command_t *parent) +{ + UnselectAllCommand_t *command = (UnselectAllCommand_t*) parent; + gpointer id; + CmdExecuteValue_t rvalue; + + id = object_list_add_select_cb(command->list, select_one_object, + command); + if (object_list_deselect_all(command->list, command->exception)) { + rvalue = CMD_APPEND; + } else { + rvalue = CMD_DESTRUCT; + } + object_list_remove_select_cb(command->list, id); + return rvalue; +} diff --git a/plug-ins/imagemap/imap_command.c b/plug-ins/imagemap/imap_command.c new file mode 100644 index 0000000..ae81c1f --- /dev/null +++ b/plug-ins/imagemap/imap_command.c @@ -0,0 +1,384 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdio.h> + +#include <gtk/gtk.h> + +#include "imap_command.h" + +#define INFINITE_UNDO_LEVELS -1 + +static void command_destruct(Command_t *command); + +static CommandList_t _command_list = {NULL, DEFAULT_UNDO_LEVELS}; +static CommandList_t *_current_command_list = &_command_list; + +static void +command_list_callback_add(CommandListCallback_t *list, + CommandListCallbackFunc_t func, gpointer data) +{ + CommandListCB_t *cb = g_new(CommandListCB_t, 1); + cb->func = func; + cb->data = data; + list->list = g_list_append(list->list, cb); +} + +static void +command_list_callback_call(CommandListCallback_t *list, Command_t *command) +{ + GList *p; + for (p = list->list; p; p = p->next) { + CommandListCB_t *cb = (CommandListCB_t*) p->data; + cb->func(command, cb->data); + } +} + +CommandList_t* +command_list_new(gint undo_levels) +{ + CommandList_t *list = g_new(CommandList_t, 1); + list->parent = NULL; + list->undo_levels = undo_levels; + list->list = NULL; + list->undo = NULL; + list->redo = NULL; + list->update_cb.list = NULL; + return list; +} + +static void +command_list_clear(CommandList_t *list) +{ + GList *p; + for (p = list->list; p; p = p->next) + command_destruct((Command_t*) p->data); + g_list_free(list->list); + list->list = NULL; + list->undo = NULL; + list->redo = NULL; + command_list_callback_call(&list->update_cb, NULL); +} + +void +command_list_destruct(CommandList_t *list) +{ + command_list_clear(list); + g_free(list); +} + +void +command_list_remove_all(void) +{ + command_list_clear(&_command_list); +} + +static void +_command_list_add(CommandList_t *list, Command_t *command) +{ + GList *p, *q; + + /* Remove rest */ + for (p = list->redo; p; p = q) { + Command_t *curr = (Command_t*) p->data; + q = p->next; + command_destruct(curr); + list->list = g_list_remove_link(list->list, p); + } + if (g_list_length(list->list) == list->undo_levels) { + GList *first = g_list_first(list->list); + Command_t *curr = (Command_t*) first->data; + command_destruct(curr); + list->list = g_list_remove_link(list->list, first); + } + list->list = g_list_append(list->list, (gpointer) command); + list->undo = g_list_last(list->list); + list->redo = NULL; + + command_list_callback_call(&list->update_cb, command); +} + +void +command_list_add(Command_t *command) +{ + _command_list_add(_current_command_list, command); +} + +/* Fix me! */ +void +subcommand_list_add(CommandList_t *list, Command_t *command) +{ + _command_list_add(list, command); +} + +static CommandClass_t parent_command_class = { + NULL, /* parent_command_destruct */ + NULL, /* parent_command_execute */ + NULL, /* parent_command_undo */ + NULL /* parent_command_redo */ +}; + +static Command_t* +command_list_start(CommandList_t *list, const gchar *name) +{ + Command_t *command = g_new(Command_t, 1); + command_init(command, name, &parent_command_class); + command->sub_commands = command_list_new(INFINITE_UNDO_LEVELS); + + command_list_add(command); + command->sub_commands->parent = _current_command_list; + _current_command_list = command->sub_commands; + + return command; +} + +static void +command_list_end(CommandList_t *list) +{ + _current_command_list = list->parent; +} + +Command_t* +subcommand_start(const gchar *name) +{ + return command_list_start(_current_command_list, name); +} + +void +subcommand_end(void) +{ + command_list_end(_current_command_list); +} + +static void +_command_list_set_undo_level(CommandList_t *list, gint level) +{ + gint diff = g_list_length(list->list) - level; + if (diff > 0) { + GList *p, *q; + /* first remove data at the front */ + for (p = list->list; diff && p != list->undo; p = q, diff--) { + Command_t *curr = (Command_t*) p->data; + q = p->next; + command_destruct(curr); + list->list = g_list_remove_link(list->list, p); + } + + /* If still to long start removing redo levels at the end */ + for (p = g_list_last(list->list); diff && p != list->undo; p = q, + diff--) { + Command_t *curr = (Command_t*) p->data; + q = p->prev; + command_destruct(curr); + list->list = g_list_remove_link(list->list, p); + } + command_list_callback_call(&list->update_cb, + (Command_t*) list->undo->data); + } + list->undo_levels = level; +} + +void +command_list_set_undo_level(gint level) +{ + _command_list_set_undo_level(&_command_list, level); +} + +Command_t* +command_list_get_redo_command(void) +{ + return (_command_list.redo) ? (Command_t*) _command_list.redo->data : NULL; +} + +void +command_list_add_update_cb(CommandListCallbackFunc_t func, gpointer data) +{ + command_list_callback_add(&_command_list.update_cb, func, data); +} + +static void +command_destruct(Command_t *command) +{ + if (command->sub_commands) + command_list_destruct(command->sub_commands); + if (command->class->destruct) + command->class->destruct(command); +} + +static void +command_list_execute(CommandList_t *list) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Command_t *command = (Command_t*) p->data; + if (command->sub_commands) + command_list_execute(command->sub_commands); + if (command->class->execute) + (void) command->class->execute(command); + } +} + +void +command_execute(Command_t *command) +{ + if (command->locked) { + command->locked = FALSE; + } else { + if (command->sub_commands) + command_list_execute(command->sub_commands); + if (command->class->execute) { + CmdExecuteValue_t value = command->class->execute(command); + if (value == CMD_APPEND) + command_list_add(command); + else if (value == CMD_DESTRUCT) + command_destruct(command); + } + } +} + +void +command_redo(Command_t *command) +{ + if (command->sub_commands) + command_list_redo_all(command->sub_commands); + if (command->class->redo) + command->class->redo(command); + else if (command->class->execute) + (void) command->class->execute(command); +} + +void +command_undo(Command_t *command) +{ + if (command->sub_commands) + command_list_undo_all(command->sub_commands); + if (command->class->undo) + command->class->undo(command); +} + +void +command_set_name(Command_t *command, const gchar *name) +{ + command->name = name; + command_list_callback_call(&_command_list.update_cb, command); +} + +void +command_list_undo(CommandList_t *list) +{ + Command_t *command = (Command_t*) list->undo->data; + command_undo(command); + + list->redo = list->undo; + list->undo = list->undo->prev; + if (list->undo) + command = (Command_t*) list->undo->data; + else + command = NULL; + command_list_callback_call(&list->update_cb, command); +} + +void +command_list_undo_all(CommandList_t *list) +{ + while (list->undo) + command_list_undo(list); +} + +void +last_command_undo(void) +{ + command_list_undo(&_command_list); +} + +void +command_list_redo(CommandList_t *list) +{ + Command_t *command = (Command_t*) list->redo->data; + command_redo(command); + + list->undo = list->redo; + list->redo = list->redo->next; + command_list_callback_call(&list->update_cb, command); +} + +void +command_list_redo_all(CommandList_t *list) +{ + while (list->redo) + command_list_redo(list); +} + +void +last_command_redo(void) +{ + command_list_redo(&_command_list); +} + +Command_t* +command_init(Command_t *command, const gchar *name, CommandClass_t *class) +{ + command->sub_commands = NULL; + command->name = name; + command->class = class; + command->locked = FALSE; + return command; +} + +void +command_add_subcommand(Command_t *command, Command_t *sub_command) +{ + if (!command->sub_commands) + command->sub_commands = command_list_new(INFINITE_UNDO_LEVELS); + subcommand_list_add(command->sub_commands, sub_command); +} + +static CmdExecuteValue_t basic_command_execute(Command_t *command); + +static CommandClass_t basic_command_class = { + NULL, /* basic_command_destruct */ + basic_command_execute, + NULL, + NULL /* basic_command_redo */ +}; + +typedef struct { + Command_t parent; + void (*func)(void); +} BasicCommand_t; + +Command_t* +command_new(void (*func)(void)) +{ + BasicCommand_t *command = g_new(BasicCommand_t, 1); + command->func = func; + return command_init(&command->parent, "Unknown", &basic_command_class); +} + +static CmdExecuteValue_t +basic_command_execute(Command_t *command) +{ + ((BasicCommand_t*) command)->func(); + return CMD_DESTRUCT; +} diff --git a/plug-ins/imagemap/imap_command.h b/plug-ins/imagemap/imap_command.h new file mode 100644 index 0000000..1676d2d --- /dev/null +++ b/plug-ins/imagemap/imap_command.h @@ -0,0 +1,103 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_COMMAND_H +#define _IMAP_COMMAND_H + +#include "imap_object.h" + +#define DEFAULT_UNDO_LEVELS 10 + +typedef struct CommandClass_t CommandClass_t; +typedef struct Command_t Command_t; +typedef struct CommandList_t CommandList_t; + +typedef enum {CMD_APPEND, CMD_DESTRUCT, CMD_IGNORE} CmdExecuteValue_t; + +struct CommandClass_t { + void (*destruct)(Command_t*); + CmdExecuteValue_t (*execute)(Command_t*); + void (*undo)(Command_t*); + void (*redo)(Command_t*); +}; + +struct Command_t { + CommandClass_t *class; + CommandList_t *sub_commands; + const gchar *name; + gboolean locked; +}; + + +typedef Command_t* (*CommandFactory_t)(void); + +typedef void (*CommandListCallbackFunc_t)(Command_t*, gpointer); + +typedef struct { + CommandListCallbackFunc_t func; + gpointer data; +} CommandListCB_t; + +typedef struct { + GList *list; +} CommandListCallback_t; + +struct CommandList_t { + CommandList_t *parent; + gint undo_levels; + GList *list; + GList *undo; /* Pointer to current undo command */ + GList *redo; /* Pointer to current redo command */ + CommandListCallback_t update_cb; +}; + +CommandList_t *command_list_new(gint undo_levels); +void command_list_destruct(CommandList_t *list); +void command_list_set_undo_level(gint level); +void command_list_add(Command_t *command); +void command_list_remove_all(void); +void command_list_undo(CommandList_t *list); +void command_list_undo_all(CommandList_t *list); +void command_list_redo(CommandList_t *list); +void command_list_redo_all(CommandList_t *list); +void command_list_add_update_cb(CommandListCallbackFunc_t func, gpointer data); +Command_t *command_list_get_redo_command(void); + +Command_t *command_new(void (*func)(void)); +Command_t *command_init(Command_t *command, const gchar *name, + CommandClass_t *class); +void command_execute(Command_t *command); +void command_undo(Command_t *command); +void command_redo(Command_t *command); +void command_set_name(Command_t *command, const gchar *name); +void command_add_subcommand(Command_t *command, Command_t *sub_command); + +void last_command_undo(void); +void last_command_redo(void); + +void subcommand_list_add(CommandList_t *list, Command_t *command); +Command_t *subcommand_start(const gchar *name); +void subcommand_end(void); + +#define command_lock(command) ((command)->locked = TRUE) + +#endif /* _IMAP_COMMAND_H */ diff --git a/plug-ins/imagemap/imap_commands.h b/plug-ins/imagemap/imap_commands.h new file mode 100644 index 0000000..af8637b --- /dev/null +++ b/plug-ins/imagemap/imap_commands.h @@ -0,0 +1,64 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details.i + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_COMMANDS_H +#define _IMAP_COMMANDS_H + +#include "imap_command.h" +#include "imap_object.h" +#include "imap_preview.h" + +Command_t *clear_command_new(ObjectList_t *list); +Command_t *copy_command_new(ObjectList_t *list); +Command_t *copy_object_command_new(Object_t *obj); +Command_t *create_command_new(ObjectList_t *list, Object_t *obj); +Command_t *cut_command_new(ObjectList_t *list); +Command_t *cut_object_command_new(Object_t *obj); +Command_t *delete_command_new(ObjectList_t *list, Object_t *obj); +Command_t *delete_point_command_new(Object_t *obj, GdkPoint *point); +Command_t *edit_object_command_new(Object_t *obj); +Command_t *gimp_guides_command_new(ObjectList_t *list, + gint32 _drawable_id); +Command_t *guides_command_new(ObjectList_t *list); +Command_t *insert_point_command_new(Object_t *obj, gint x, gint y, gint edge); +Command_t *move_down_command_new(ObjectList_t *list); +Command_t *move_command_new(Preview_t *preview, Object_t *obj, gint x, gint y); +Command_t *move_sash_command_new(GtkWidget *widget, Object_t *obj, + gint x, gint y, MoveSashFunc_t sash_func); +Command_t *move_selected_command_new(ObjectList_t *list, gint dx, gint dy); +Command_t *move_to_front_command_new(ObjectList_t *list); +Command_t *move_up_command_new(ObjectList_t *list); +Command_t *object_down_command_new(ObjectList_t *list, Object_t *obj); +Command_t *object_move_command_new(Object_t *obj, gint x, gint y); +Command_t *object_up_command_new(ObjectList_t *list, Object_t *obj); +Command_t *paste_command_new(ObjectList_t *list); +Command_t *select_all_command_new(ObjectList_t *list); +Command_t *select_command_new(Object_t *obj); +Command_t *select_next_command_new(ObjectList_t *list); +Command_t *select_prev_command_new(ObjectList_t *list); +Command_t *select_region_command_new(GtkWidget *widget, ObjectList_t *list, + gint x, gint y); +Command_t *send_to_back_command_new(ObjectList_t *list); +Command_t *unselect_all_command_new(ObjectList_t *list, Object_t *exception); +Command_t *unselect_command_new(Object_t *obj); + +#endif /* _IMAP_COMMANDS_H */ diff --git a/plug-ins/imagemap/imap_csim.l b/plug-ins/imagemap/imap_csim.l new file mode 100644 index 0000000..32b9803 --- /dev/null +++ b/plug-ins/imagemap/imap_csim.l @@ -0,0 +1,137 @@ +%{ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2000 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <glib.h> + +#include "imap_csim_parse.h" + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +#endif /* FLEX_SCANNER */ + +%} + +%option noyywrap +%option noinput +%option nounput + +DIGIT [0-9] +ID [a-zA-Z_][a-zA-Z0-9_\-]* +WS [ \t\n]+ + +%x quoted_string +%x comment + +%% + +\<!--\ #$AUTHOR: { + BEGIN(comment); + return AUTHOR; + } + +\<!--\ #$DESCRIPTION: { + BEGIN(comment); + return DESCRIPTION; + } + +\<!-- { + BEGIN(comment); + return BEGIN_COMMENT; + } + +<comment>--\> { + BEGIN(INITIAL); + return END_COMMENT; + } + +<comment>.*/--\> { + csim_lval.id = g_strndup (yytext, yyleng); + return STRING; + } + +IMG return IMG; + +SRC return SRC; + +WIDTH return WIDTH; + +HEIGHT return HEIGHT; + +BORDER return BORDER; + +USEMAP return USEMAP; + +MAP return START_MAP; + +\/MAP return END_MAP; + +NAME return NAME; + +AREA return AREA; + +SHAPE return SHAPE; + +COORDS return COORDS; + +TARGET return TARGET; + +ONMOUSEOVER return ONMOUSEOVER; + +ONMOUSEOUT return ONMOUSEOUT; + +ONFOCUS return ONFOCUS; + +ONBLUR return ONBLUR; + +ALT return ALT; + +HREF return HREF; + +NOHREF return NOHREF; + +\" { + BEGIN(quoted_string); + } + +<quoted_string>\" { + BEGIN(INITIAL); + return STRING; + } + +<quoted_string>[^\"]* { + csim_lval.id = g_strndup (yytext, yyleng); + } + +-?{DIGIT}*"."?{DIGIT}*([Ee][-+]?{DIGIT}*)? { + csim_lval.value = g_ascii_strtod (yytext, NULL); + return FLOAT; + } + +{WS} ; /* Eat white space */ + +. return *yytext; + +%% + diff --git a/plug-ins/imagemap/imap_csim.y b/plug-ins/imagemap/imap_csim.y new file mode 100644 index 0000000..abc2dff --- /dev/null +++ b/plug-ins/imagemap/imap_csim.y @@ -0,0 +1,396 @@ +%{ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include <glib/gstdio.h> + +#include <gtk/gtk.h> + +#include "imap_circle.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_polygon.h" +#include "imap_rectangle.h" +#include "imap_string.h" + +extern int csim_lex(void); +extern int csim_restart(FILE *csim_in); +static void csim_error(char* s); +static gchar * unescape_text(gchar *input); + +static enum {UNDEFINED, RECTANGLE, CIRCLE, POLYGON} current_type; +static Object_t *current_object; +static MapInfo_t *_map_info; + +%} + +%union { + int val; + double value; + char *id; +} + +%token<val> IMG SRC WIDTH HEIGHT BORDER USEMAP +%token<val> START_MAP END_MAP NAME AREA SHAPE COORDS ALT HREF NOHREF +%token<val> TARGET ONMOUSEOVER ONMOUSEOUT ONFOCUS ONBLUR +%token<val> AUTHOR DESCRIPTION BEGIN_COMMENT END_COMMENT +%token<value> FLOAT +%token<id> STRING + +%type<val> integer_value + +%% + +csim_file : image start_map comment_lines area_list end_map + ; + +image : '<' IMG SRC '=' STRING image_tags xhtml_close + { + g_strreplace(&_map_info->image_name, $5); + g_free ($5); + } + ; + +image_tags : /* Empty */ + | image_tags image_tag + ; + +image_tag : image_width + | image_height + | BORDER '=' integer_value {} + | USEMAP '=' STRING { g_free ($3); } + | ALT '=' STRING { g_free ($3); } + ; + +image_width : WIDTH '=' integer_value + { + _map_info->old_image_width = $3; + } + ; + +image_height : HEIGHT '=' integer_value + { + _map_info->old_image_height = $3; + } + ; + +integer_value : FLOAT + { + $$ = (gint) $1; + } + | STRING + { + $$ = (gint) g_ascii_strtod ($1, NULL); + g_free ($1); + } + ; + +start_map : '<' START_MAP NAME '=' STRING '>' + { + g_strreplace(&_map_info->title, $5); + g_free ($5); + } + ; + +comment_lines : /* empty */ + | comment_lines comment_line + ; + +comment_line : author_line + | description_line + | real_comment + ; + +real_comment : BEGIN_COMMENT STRING END_COMMENT + { + g_free ($2); + } + ; + +author_line : AUTHOR STRING END_COMMENT + { + g_strreplace(&_map_info->author, $2); + g_free ($2); + } + ; + +description_line: DESCRIPTION STRING END_COMMENT + { + gchar *description; + + description = g_strconcat(_map_info->description, $2, "\n", + NULL); + g_strreplace(&_map_info->description, description); + g_free ($2); + } + ; + +area_list : /* empty */ + | area_list area + ; + +area : '<' AREA tag_list xhtml_close + { + if (current_type != UNDEFINED) + add_shape(current_object); + } + ; + +xhtml_close : '>' + | '/' '>' + ; + +tag_list : /* Empty */ + | tag_list tag + ; + +tag : shape_tag + | coords_tag + | href_tag + | nohref_tag + | alt_tag + | target_tag + | onmouseover_tag + | onmouseout_tag + | onfocus_tag + | onblur_tag + ; + +shape_tag : SHAPE '=' STRING + { + if (!g_ascii_strcasecmp($3, "RECT")) { + current_object = create_rectangle(0, 0, 0, 0); + current_type = RECTANGLE; + } else if (!g_ascii_strcasecmp($3, "CIRCLE")) { + current_object = create_circle(0, 0, 0); + current_type = CIRCLE; + } else if (!g_ascii_strcasecmp($3, "POLY")) { + current_object = create_polygon(NULL); + current_type = POLYGON; + } else if (!g_ascii_strcasecmp($3, "DEFAULT")) { + current_type = UNDEFINED; + } + g_free ($3); + } + ; + +coords_tag : COORDS '=' STRING + { + char *p; + if (current_type == RECTANGLE) { + Rectangle_t *rectangle; + + rectangle = ObjectToRectangle(current_object); + p = strtok($3, ","); + rectangle->x = atoi(p); + p = strtok(NULL, ","); + rectangle->y = atoi(p); + p = strtok(NULL, ","); + rectangle->width = atoi(p) - rectangle->x; + p = strtok(NULL, ","); + rectangle->height = atoi(p) - rectangle->y; + } else if (current_type == CIRCLE) { + Circle_t *circle; + + circle = ObjectToCircle(current_object); + p = strtok($3, ","); + circle->x = atoi(p); + p = strtok(NULL, ","); + circle->y = atoi(p); + p = strtok(NULL, ","); + circle->r = atoi(p); + } else if (current_type == POLYGON) { + Polygon_t *polygon = ObjectToPolygon(current_object); + GList *points; + GdkPoint *point, *first; + gint x, y; + + p = strtok($3, ","); + x = atoi(p); + p = strtok(NULL, ","); + y = atoi(p); + point = new_point(x, y); + points = g_list_append(NULL, (gpointer) point); + + while(1) { + p = strtok(NULL, ","); + if (!p) + break; + x = atoi(p); + p = strtok(NULL, ","); + y = atoi(p); + point = new_point(x, y); + points = g_list_append(points, (gpointer) point); + } + /* Remove last point if duplicate */ + first = (GdkPoint*) points->data; + polygon->points = points; + if (first->x == point->x && first->y == point->y) + polygon_remove_last_point(polygon); + polygon->points = points; + } + + g_free ($3); + } + ; + +href_tag : HREF '=' STRING + { + if (current_type == UNDEFINED) { + g_strreplace(&_map_info->default_url, $3); + } else { + object_set_url(current_object, unescape_text($3)); + } + g_free ($3); + } + ; + +nohref_tag : NOHREF optional_value + { + } + ; + +optional_value : /* Empty */ + | '=' STRING + { + g_free ($2); + } + ; + +alt_tag : ALT '=' STRING + { + object_set_comment(current_object, unescape_text($3)); + g_free ($3); + } + ; + +target_tag : TARGET '=' STRING + { + object_set_target(current_object, unescape_text($3)); + g_free ($3); + } + ; + +onmouseover_tag : ONMOUSEOVER '=' STRING + { + object_set_mouse_over(current_object, unescape_text($3)); + g_free ($3); + } + ; + +onmouseout_tag : ONMOUSEOUT '=' STRING + { + object_set_mouse_out(current_object, unescape_text($3)); + g_free ($3); + } + ; + +onfocus_tag : ONFOCUS '=' STRING + { + object_set_focus(current_object, unescape_text($3)); + g_free ($3); + } + ; + +onblur_tag : ONBLUR '=' STRING + { + object_set_blur(current_object, unescape_text($3)); + g_free ($3); + } + ; + +end_map : '<' END_MAP '>' + ; + +%% + +static void +csim_error(char* s) +{ + extern FILE *csim_in; + csim_restart(csim_in); +} + +gboolean +load_csim (const char* filename) +{ + gboolean status; + extern FILE *csim_in; + csim_in = g_fopen(filename, "r"); + if (csim_in) { + _map_info = get_map_info(); + status = !csim_parse(); + fclose(csim_in); + } else { + status = FALSE; + } + return status; +} + +static gchar* +unescape_text (gchar *input) +{ + /* + * We "unescape" simple things "in place", knowing that unescaped + * strings always are shorter than the original input. + * + * It is a shame there is no g_markup_unescape_text() function, but + * instead you have to create a full GMarkupParser/Context. + */ + struct token { + const char *escaped; + const char unescaped; + }; + const struct token tab[] = { + { """, '"' }, + { "'", '\'' }, + { "&", '&' }, + { "<", '<' }, + { ">", '>' } + }; + + size_t i; + for (i = 0; i < (sizeof tab / sizeof tab[0]); i++) + { + const size_t escaped_len = strlen (tab[i].escaped); + char *p; + + /* FIXME: The following code does not perform a UTF-8 substring + search. */ + for (p = strstr (input, tab[i].escaped); + p != NULL; + p = strstr (p, tab[i].escaped)) + { + size_t copy_len; + *p++ = tab[i].unescaped; + copy_len = strlen (p) - escaped_len + 2; + memmove (p, p + escaped_len - 1, copy_len); + if (*p == 0) + break; + } + } + + return input; +} diff --git a/plug-ins/imagemap/imap_csim_lex.c b/plug-ins/imagemap/imap_csim_lex.c new file mode 100644 index 0000000..88c8b86 --- /dev/null +++ b/plug-ins/imagemap/imap_csim_lex.c @@ -0,0 +1,2054 @@ + +#line 3 "<stdout>" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer csim__create_buffer +#define yy_delete_buffer csim__delete_buffer +#define yy_flex_debug csim__flex_debug +#define yy_init_buffer csim__init_buffer +#define yy_flush_buffer csim__flush_buffer +#define yy_load_buffer_state csim__load_buffer_state +#define yy_switch_to_buffer csim__switch_to_buffer +#define yyin csim_in +#define yyleng csim_leng +#define yylex csim_lex +#define yylineno csim_lineno +#define yyout csim_out +#define yyrestart csim_restart +#define yytext csim_text +#define yywrap csim_wrap +#define yyalloc csim_alloc +#define yyrealloc csim_realloc +#define yyfree csim_free + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 36 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE csim_restart(csim_in ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t csim_leng; + +extern FILE *csim_in, *csim_out; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up csim_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up csim_text again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via csim_restart()), so that the user can continue scanning by + * just pointing csim_in at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when csim_text is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t csim_leng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow csim_wrap()'s to do buffer switches + * instead of setting up a fresh csim_in. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void csim_restart (FILE *input_file ); +void csim__switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE csim__create_buffer (FILE *file,int size ); +void csim__delete_buffer (YY_BUFFER_STATE b ); +void csim__flush_buffer (YY_BUFFER_STATE b ); +void csim_push_buffer_state (YY_BUFFER_STATE new_buffer ); +void csim_pop_buffer_state (void ); + +static void csim_ensure_buffer_stack (void ); +static void csim__load_buffer_state (void ); +static void csim__init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER csim__flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE csim__scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE csim__scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE csim__scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *csim_alloc (yy_size_t ); +void *csim_realloc (void *,yy_size_t ); +void csim_free (void * ); + +#define yy_new_buffer csim__create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + csim_ensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + csim__create_buffer(csim_in,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + csim_ensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + csim__create_buffer(csim_in,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define csim_wrap() 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *csim_in = (FILE *) 0, *csim_out = (FILE *) 0; + +typedef int yy_state_type; + +extern int csim_lineno; + +int csim_lineno = 1; + +extern char *csim_text; +#define yytext_ptr csim_text + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up csim_text. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + csim_leng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 32 +#define YY_END_OF_BUFFER 33 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[154] = + { 0, + 29, 29, 28, 28, 0, 0, 33, 31, 30, 30, + 26, 29, 29, 31, 29, 31, 31, 31, 31, 29, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, + 27, 32, 32, 32, 30, 29, 29, 29, 29, 0, + 0, 0, 0, 0, 0, 29, 29, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, + 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, + 0, 6, 12, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 4, 13, 3, 15, 0, 0, + 0, 24, 14, 0, 0, 0, 0, 0, 0, 0, + + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 8, 0, 10, 17, 9, 25, 22, + 0, 0, 18, 11, 0, 21, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, + 19, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 2, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 5, 6, 7, 8, 1, 1, 1, 1, + 1, 1, 9, 1, 10, 11, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 14, 1, 15, + 1, 16, 1, 1, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 1, 1, 26, 27, 28, 29, 30, + 1, 31, 32, 33, 34, 35, 36, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 37, 38, 39, 40, + + 41, 42, 43, 44, 45, 1, 1, 46, 47, 48, + 49, 50, 1, 51, 52, 53, 54, 55, 56, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[57] = + { 0, + 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[158] = + { 0, + 0, 0, 315, 314, 54, 55, 318, 322, 57, 64, + 322, 58, 49, 36, 61, 301, 47, 46, 47, 71, + 56, 58, 69, 71, 61, 70, 74, 60, 78, 0, + 322, 295, 322, 294, 113, 97, 111, 116, 106, 96, + 293, 95, 109, 100, 105, 289, 288, 110, 115, 114, + 109, 113, 117, 131, 125, 124, 113, 124, 126, 0, + 290, 289, 158, 137, 287, 322, 153, 151, 141, 152, + 154, 322, 322, 156, 148, 154, 152, 153, 153, 322, + 161, 158, 153, 178, 286, 322, 291, 322, 168, 173, + 174, 322, 322, 186, 174, 191, 177, 191, 193, 198, + + 192, 284, 285, 186, 187, 187, 199, 191, 189, 192, + 322, 192, 196, 322, 283, 322, 322, 322, 322, 322, + 197, 212, 322, 322, 230, 322, 209, 214, 230, 220, + 219, 224, 224, 238, 236, 242, 322, 231, 234, 233, + 322, 234, 241, 276, 239, 322, 240, 253, 258, 260, + 90, 322, 322, 308, 311, 314, 316 + } ; + +static yyconst flex_int16_t yy_def[158] = + { 0, + 153, 1, 154, 154, 155, 155, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 156, + 153, 157, 153, 157, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 156, + 157, 157, 157, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 157, 157, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + + 153, 157, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 0, 153, 153, 153, 153 + } ; + +static yyconst flex_int16_t yy_nxt[379] = + { 0, + 8, 9, 10, 9, 8, 11, 8, 8, 8, 12, + 13, 14, 15, 8, 16, 8, 17, 18, 19, 8, + 20, 8, 8, 21, 22, 8, 23, 24, 25, 8, + 8, 26, 27, 28, 8, 29, 17, 18, 19, 8, + 20, 8, 8, 21, 22, 8, 23, 24, 25, 8, + 8, 26, 27, 28, 8, 29, 33, 33, 35, 35, + 35, 39, 40, 34, 34, 35, 35, 35, 36, 38, + 37, 36, 42, 37, 44, 45, 48, 43, 38, 46, + 46, 38, 40, 47, 50, 51, 49, 52, 54, 38, + 57, 58, 42, 55, 44, 45, 48, 43, 38, 53, + + 56, 38, 59, 152, 50, 51, 49, 52, 54, 39, + 57, 58, 64, 55, 35, 35, 35, 38, 39, 53, + 56, 36, 59, 37, 46, 46, 38, 66, 47, 67, + 68, 38, 64, 69, 70, 71, 72, 38, 73, 74, + 75, 79, 80, 81, 82, 83, 38, 66, 76, 67, + 68, 38, 77, 69, 70, 71, 72, 78, 73, 74, + 75, 79, 80, 81, 82, 83, 86, 84, 76, 88, + 89, 90, 77, 85, 91, 92, 93, 78, 94, 95, + 96, 97, 98, 99, 100, 101, 86, 84, 104, 88, + 89, 90, 105, 102, 91, 92, 93, 106, 94, 95, + + 96, 97, 98, 99, 100, 101, 107, 108, 104, 109, + 110, 111, 105, 112, 113, 114, 116, 106, 117, 118, + 119, 120, 121, 122, 123, 124, 107, 108, 126, 109, + 110, 111, 127, 112, 113, 114, 116, 130, 117, 118, + 119, 120, 121, 122, 123, 124, 128, 131, 126, 129, + 132, 135, 127, 133, 134, 136, 137, 130, 138, 139, + 140, 141, 142, 143, 144, 145, 128, 131, 147, 129, + 132, 135, 148, 133, 134, 136, 137, 149, 138, 139, + 140, 141, 142, 143, 144, 145, 150, 151, 147, 146, + 125, 115, 148, 62, 103, 62, 87, 149, 84, 62, + + 47, 47, 65, 63, 62, 41, 150, 151, 30, 30, + 30, 32, 32, 32, 60, 60, 61, 153, 61, 31, + 31, 7, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153 + } ; + +static yyconst flex_int16_t yy_chk[379] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 5, 6, 9, 9, + 9, 13, 14, 5, 6, 10, 10, 10, 12, 13, + 12, 15, 17, 15, 18, 19, 21, 17, 12, 20, + 20, 15, 14, 20, 22, 23, 21, 24, 25, 13, + 27, 28, 17, 26, 18, 19, 21, 17, 12, 24, + + 26, 15, 29, 151, 22, 23, 21, 24, 25, 36, + 27, 28, 40, 26, 35, 35, 35, 36, 39, 24, + 26, 37, 29, 37, 38, 38, 39, 42, 38, 43, + 44, 37, 40, 45, 48, 49, 50, 36, 51, 52, + 53, 55, 56, 57, 58, 59, 39, 42, 54, 43, + 44, 37, 54, 45, 48, 49, 50, 54, 51, 52, + 53, 55, 56, 57, 58, 59, 64, 63, 54, 67, + 68, 69, 54, 63, 70, 71, 74, 54, 75, 76, + 77, 78, 79, 81, 82, 83, 64, 84, 89, 67, + 68, 69, 90, 84, 70, 71, 74, 91, 75, 76, + + 77, 78, 79, 81, 82, 83, 94, 95, 89, 96, + 97, 98, 90, 99, 100, 101, 104, 91, 105, 106, + 107, 108, 109, 110, 112, 113, 94, 95, 121, 96, + 97, 98, 122, 99, 100, 101, 104, 127, 105, 106, + 107, 108, 109, 110, 112, 113, 125, 128, 121, 125, + 129, 131, 122, 130, 130, 132, 133, 127, 134, 135, + 136, 138, 139, 140, 142, 143, 125, 128, 145, 125, + 129, 131, 147, 130, 130, 132, 133, 148, 134, 135, + 136, 138, 139, 140, 142, 143, 149, 150, 145, 144, + 115, 103, 147, 102, 87, 85, 65, 148, 62, 61, + + 47, 46, 41, 34, 32, 16, 149, 150, 154, 154, + 154, 155, 155, 155, 156, 156, 157, 7, 157, 4, + 3, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int csim__flex_debug; +int csim__flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *csim_text; +#line 1 "imap_csim.l" +#line 2 "imap_csim.l" +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2000 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <glib.h> + +#include "imap_csim_parse.h" + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +#endif /* FLEX_SCANNER */ + +#define YY_NO_INPUT 1 + + +#line 641 "<stdout>" + +#define INITIAL 0 +#define quoted_string 1 +#define comment 2 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int csim_lex_destroy (void ); + +int csim_get_debug (void ); + +void csim_set_debug (int debug_flag ); + +YY_EXTRA_TYPE csim_get_extra (void ); + +void csim_set_extra (YY_EXTRA_TYPE user_defined ); + +FILE *csim_get_in (void ); + +void csim_set_in (FILE * in_str ); + +FILE *csim_get_out (void ); + +void csim_set_out (FILE * out_str ); + +yy_size_t csim_get_leng (void ); + +char *csim_get_text (void ); + +int csim_get_lineno (void ); + +void csim_set_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int csim_wrap (void ); +#else +extern int csim_wrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( csim_text, csim_leng, 1, csim_out )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( csim_in )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( csim_in ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, csim_in))==0 && ferror(csim_in)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(csim_in); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int csim_lex (void); + +#define YY_DECL int csim_lex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after csim_text and csim_leng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 47 "imap_csim.l" + + +#line 826 "<stdout>" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! csim_in ) + csim_in = stdin; + + if ( ! csim_out ) + csim_out = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + csim_ensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + csim__create_buffer(csim_in,YY_BUF_SIZE ); + } + + csim__load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of csim_text. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 154 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 322 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 49 "imap_csim.l" +{ + BEGIN(comment); + return AUTHOR; + } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 54 "imap_csim.l" +{ + BEGIN(comment); + return DESCRIPTION; + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 59 "imap_csim.l" +{ + BEGIN(comment); + return BEGIN_COMMENT; + } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 64 "imap_csim.l" +{ + BEGIN(INITIAL); + return END_COMMENT; + } + YY_BREAK +case 5: +*yy_cp = (yy_hold_char); /* undo effects of setting up csim_text */ +(yy_c_buf_p) = yy_cp -= 3; +YY_DO_BEFORE_ACTION; /* set up csim_text again */ +YY_RULE_SETUP +#line 69 "imap_csim.l" +{ + csim_lval.id = g_strndup (csim_text, csim_leng); + return STRING; + } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 74 "imap_csim.l" +return IMG; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 76 "imap_csim.l" +return SRC; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 78 "imap_csim.l" +return WIDTH; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 80 "imap_csim.l" +return HEIGHT; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 82 "imap_csim.l" +return BORDER; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 84 "imap_csim.l" +return USEMAP; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 86 "imap_csim.l" +return START_MAP; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 88 "imap_csim.l" +return END_MAP; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 90 "imap_csim.l" +return NAME; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 92 "imap_csim.l" +return AREA; + YY_BREAK +case 16: +YY_RULE_SETUP +#line 94 "imap_csim.l" +return SHAPE; + YY_BREAK +case 17: +YY_RULE_SETUP +#line 96 "imap_csim.l" +return COORDS; + YY_BREAK +case 18: +YY_RULE_SETUP +#line 98 "imap_csim.l" +return TARGET; + YY_BREAK +case 19: +YY_RULE_SETUP +#line 100 "imap_csim.l" +return ONMOUSEOVER; + YY_BREAK +case 20: +YY_RULE_SETUP +#line 102 "imap_csim.l" +return ONMOUSEOUT; + YY_BREAK +case 21: +YY_RULE_SETUP +#line 104 "imap_csim.l" +return ONFOCUS; + YY_BREAK +case 22: +YY_RULE_SETUP +#line 106 "imap_csim.l" +return ONBLUR; + YY_BREAK +case 23: +YY_RULE_SETUP +#line 108 "imap_csim.l" +return ALT; + YY_BREAK +case 24: +YY_RULE_SETUP +#line 110 "imap_csim.l" +return HREF; + YY_BREAK +case 25: +YY_RULE_SETUP +#line 112 "imap_csim.l" +return NOHREF; + YY_BREAK +case 26: +YY_RULE_SETUP +#line 114 "imap_csim.l" +{ + BEGIN(quoted_string); + } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 118 "imap_csim.l" +{ + BEGIN(INITIAL); + return STRING; + } + YY_BREAK +case 28: +/* rule 28 can match eol */ +YY_RULE_SETUP +#line 123 "imap_csim.l" +{ + csim_lval.id = g_strndup (csim_text, csim_leng); + } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 127 "imap_csim.l" +{ + csim_lval.value = g_ascii_strtod (csim_text, NULL); + return FLOAT; + } + YY_BREAK +case 30: +/* rule 30 can match eol */ +YY_RULE_SETUP +#line 132 "imap_csim.l" +; /* Eat white space */ + YY_BREAK +case 31: +YY_RULE_SETUP +#line 134 "imap_csim.l" +return *csim_text; + YY_BREAK +case 32: +YY_RULE_SETUP +#line 136 "imap_csim.l" +ECHO; + YY_BREAK +#line 1099 "<stdout>" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(quoted_string): +case YY_STATE_EOF(comment): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed csim_in at a new source and called + * csim_lex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = csim_in; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( csim_wrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * csim_text, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of csim_lex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + csim_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + csim_restart(csim_in ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) csim_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 154 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 154 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 153); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + csim_restart(csim_in ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( csim_wrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve csim_text */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void csim_restart (FILE * input_file ) +{ + if ( ! YY_CURRENT_BUFFER ){ + csim_ensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + csim__create_buffer(csim_in,YY_BUF_SIZE ); + } + + csim__init_buffer(YY_CURRENT_BUFFER,input_file ); + csim__load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void csim__switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + /* TODO. We should be able to replace this entire function body + * with + * csim_pop_buffer_state(); + * csim_push_buffer_state(new_buffer); + */ + csim_ensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + csim__load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (csim_wrap()) processing, but the only time this flag + * is looked at is after csim_wrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void csim__load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + csim_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE csim__create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) csim_alloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in csim__create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) csim_alloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in csim__create_buffer()" ); + + b->yy_is_our_buffer = 1; + + csim__init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with csim__create_buffer() + * + */ + void csim__delete_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + csim_free((void *) b->yy_ch_buf ); + + csim_free((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a csim_restart() or at EOF. + */ + static void csim__init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + csim__flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then csim__init_buffer was _probably_ + * called from csim_restart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void csim__flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + csim__load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void csim_push_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + csim_ensure_buffer_stack(); + + /* This block is copied from csim__switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from csim__switch_to_buffer. */ + csim__load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void csim_pop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + csim__delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + csim__load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void csim_ensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)csim_alloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in csim_ensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)csim_realloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in csim_ensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE csim__scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) csim_alloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in csim__scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + csim__switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to csim_lex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * csim__scan_bytes() instead. + */ +YY_BUFFER_STATE csim__scan_string (yyconst char * yystr ) +{ + return csim__scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to csim_lex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE csim__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) csim_alloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in csim__scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = csim__scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in csim__scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up csim_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + csim_text[csim_leng] = (yy_hold_char); \ + (yy_c_buf_p) = csim_text + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + csim_leng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int csim_get_lineno (void) +{ + return csim_lineno; +} + +/** Get the input stream. + * + */ +FILE *csim_get_in (void) +{ + return csim_in; +} + +/** Get the output stream. + * + */ +FILE *csim_get_out (void) +{ + return csim_out; +} + +/** Get the length of the current token. + * + */ +yy_size_t csim_get_leng (void) +{ + return csim_leng; +} + +/** Get the current token. + * + */ + +char *csim_get_text (void) +{ + return csim_text; +} + +/** Set the current line number. + * @param line_number + * + */ +void csim_set_lineno (int line_number ) +{ + csim_lineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see csim__switch_to_buffer + */ +void csim_set_in (FILE * in_str ) +{ + csim_in = in_str ; +} + +void csim_set_out (FILE * out_str ) +{ + csim_out = out_str ; +} + +int csim_get_debug (void) +{ + return csim__flex_debug; +} + +void csim_set_debug (int bdebug ) +{ + csim__flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from csim_lex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + csim_in = stdin; + csim_out = stdout; +#else + csim_in = (FILE *) 0; + csim_out = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * csim_lex_init() + */ + return 0; +} + +/* csim_lex_destroy is for both reentrant and non-reentrant scanners. */ +int csim_lex_destroy (void) +{ + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + csim__delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + csim_pop_buffer_state(); + } + + /* Destroy the stack itself. */ + csim_free((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * csim_lex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *csim_alloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *csim_realloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void csim_free (void * ptr ) +{ + free( (char *) ptr ); /* see csim_realloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 136 "imap_csim.l" + + + + diff --git a/plug-ins/imagemap/imap_csim_parse.c b/plug-ins/imagemap/imap_csim_parse.c new file mode 100644 index 0000000..b6411ac --- /dev/null +++ b/plug-ins/imagemap/imap_csim_parse.c @@ -0,0 +1,2131 @@ +/* A Bison parser, made by GNU Bison 2.6.1. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse csim_parse +#define yylex csim_lex +#define yyerror csim_error +#define yylval csim_lval +#define yychar csim_char +#define yydebug csim_debug +#define yynerrs csim_nerrs + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 1 "imap_csim.y" + +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include <glib/gstdio.h> + +#include <gtk/gtk.h> + +#include "imap_circle.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_polygon.h" +#include "imap_rectangle.h" +#include "imap_string.h" + +extern int csim_lex(void); +extern int csim_restart(FILE *csim_in); +static void csim_error(char* s); +static gchar * unescape_text(gchar *input); + +static enum {UNDEFINED, RECTANGLE, CIRCLE, POLYGON} current_type; +static Object_t *current_object; +static MapInfo_t *_map_info; + + +/* Line 336 of yacc.c */ +#line 123 "y.tab.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef CSIM_Y_TAB_H +# define CSIM_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int csim_debug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + IMG = 258, + SRC = 259, + WIDTH = 260, + HEIGHT = 261, + BORDER = 262, + USEMAP = 263, + START_MAP = 264, + END_MAP = 265, + NAME = 266, + AREA = 267, + SHAPE = 268, + COORDS = 269, + ALT = 270, + HREF = 271, + NOHREF = 272, + TARGET = 273, + ONMOUSEOVER = 274, + ONMOUSEOUT = 275, + ONFOCUS = 276, + ONBLUR = 277, + AUTHOR = 278, + DESCRIPTION = 279, + BEGIN_COMMENT = 280, + END_COMMENT = 281, + FLOAT = 282, + STRING = 283 + }; +#endif +/* Tokens. */ +#define IMG 258 +#define SRC 259 +#define WIDTH 260 +#define HEIGHT 261 +#define BORDER 262 +#define USEMAP 263 +#define START_MAP 264 +#define END_MAP 265 +#define NAME 266 +#define AREA 267 +#define SHAPE 268 +#define COORDS 269 +#define ALT 270 +#define HREF 271 +#define NOHREF 272 +#define TARGET 273 +#define ONMOUSEOVER 274 +#define ONMOUSEOUT 275 +#define ONFOCUS 276 +#define ONBLUR 277 +#define AUTHOR 278 +#define DESCRIPTION 279 +#define BEGIN_COMMENT 280 +#define END_COMMENT 281 +#define FLOAT 282 +#define STRING 283 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 49 "imap_csim.y" + + int val; + double value; + char *id; + + +/* Line 350 of yacc.c */ +#line 229 "y.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE csim_lval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int csim_parse (void *YYPARSE_PARAM); +#else +int csim_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int csim_parse (void); +#else +int csim_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !CSIM_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 257 "y.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 5 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 84 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 33 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 31 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 53 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 106 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 283 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 32, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 29, 30, 31, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 9, 17, 18, 21, 23, 25, 29, + 33, 37, 41, 45, 47, 49, 56, 57, 60, 62, + 64, 66, 70, 74, 78, 79, 82, 87, 89, 92, + 93, 96, 98, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 120, 124, 128, 131, 132, 135, 139, 143, + 147, 151, 155, 159 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 34, 0, -1, 35, 41, 42, 47, 63, -1, 29, + 3, 4, 30, 28, 36, 49, -1, -1, 36, 37, + -1, 38, -1, 39, -1, 7, 30, 40, -1, 8, + 30, 28, -1, 15, 30, 28, -1, 5, 30, 40, + -1, 6, 30, 40, -1, 27, -1, 28, -1, 29, + 9, 11, 30, 28, 31, -1, -1, 42, 43, -1, + 45, -1, 46, -1, 44, -1, 25, 28, 26, -1, + 23, 28, 26, -1, 24, 28, 26, -1, -1, 47, + 48, -1, 29, 12, 50, 49, -1, 31, -1, 32, + 31, -1, -1, 50, 51, -1, 52, -1, 53, -1, + 54, -1, 55, -1, 57, -1, 58, -1, 59, -1, + 60, -1, 61, -1, 62, -1, 13, 30, 28, -1, + 14, 30, 28, -1, 16, 30, 28, -1, 17, 56, + -1, -1, 30, 28, -1, 15, 30, 28, -1, 18, + 30, 28, -1, 19, 30, 28, -1, 20, 30, 28, + -1, 21, 30, 28, -1, 22, 30, 28, -1, 29, + 10, 31, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 66, 66, 69, 76, 77, 80, 81, 82, 83, + 84, 87, 93, 99, 103, 110, 117, 118, 121, 122, + 123, 126, 132, 139, 150, 151, 154, 161, 162, 165, + 166, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 181, 199, 259, 270, 275, 276, 282, 289, 296, + 303, 310, 317, 324 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "IMG", "SRC", "WIDTH", "HEIGHT", + "BORDER", "USEMAP", "START_MAP", "END_MAP", "NAME", "AREA", "SHAPE", + "COORDS", "ALT", "HREF", "NOHREF", "TARGET", "ONMOUSEOVER", "ONMOUSEOUT", + "ONFOCUS", "ONBLUR", "AUTHOR", "DESCRIPTION", "BEGIN_COMMENT", + "END_COMMENT", "FLOAT", "STRING", "'<'", "'='", "'>'", "'/'", "$accept", + "csim_file", "image", "image_tags", "image_tag", "image_width", + "image_height", "integer_value", "start_map", "comment_lines", + "comment_line", "real_comment", "author_line", "description_line", + "area_list", "area", "xhtml_close", "tag_list", "tag", "shape_tag", + "coords_tag", "href_tag", "nohref_tag", "optional_value", "alt_tag", + "target_tag", "onmouseover_tag", "onmouseout_tag", "onfocus_tag", + "onblur_tag", "end_map", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 60, + 61, 62, 47 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 33, 34, 35, 36, 36, 37, 37, 37, 37, + 37, 38, 39, 40, 40, 41, 42, 42, 43, 43, + 43, 44, 45, 46, 47, 47, 48, 49, 49, 50, + 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, + 60, 61, 62, 63 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 5, 7, 0, 2, 1, 1, 3, 3, + 3, 3, 3, 1, 1, 6, 0, 2, 1, 1, + 1, 3, 3, 3, 0, 2, 4, 1, 2, 0, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 2, 0, 2, 3, 3, 3, + 3, 3, 3, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 0, 1, 0, 16, 0, 0, + 24, 0, 0, 0, 0, 0, 17, 20, 18, 19, + 0, 4, 0, 0, 0, 0, 0, 25, 2, 0, + 0, 22, 23, 21, 0, 29, 0, 0, 0, 0, + 0, 27, 0, 5, 6, 7, 3, 15, 53, 0, + 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, + 45, 0, 0, 0, 0, 0, 26, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 13, 14, + 11, 12, 8, 9, 10, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 0, 0, 41, 42, 47, 43, + 46, 48, 49, 50, 51, 52 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 3, 29, 43, 44, 45, 80, 7, 10, + 16, 17, 18, 19, 20, 27, 46, 49, 67, 68, + 69, 70, 71, 90, 72, 73, 74, 75, 76, 77, + 28 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -29 +static const yytype_int8 yypact[] = +{ + -21, 22, 28, 2, 29, -29, 23, -29, 4, 24, + -19, 8, 7, 10, 11, 12, -29, -29, -29, -29, + 13, -29, 15, 18, 19, 20, -3, -29, -29, -5, + 16, -29, -29, -29, 17, -29, 21, 25, 26, 27, + 30, -29, 31, -29, -29, -29, -29, -29, -29, -2, + -6, -6, -6, 33, 35, -29, 34, 36, 37, 38, + 39, 40, 41, 42, 43, 44, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, 47, 48, 49, 50, 51, + -29, 52, 53, 54, 55, 56, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -29, -29, -29, -29, -29, -29, -29, -28, -29, -29, + -29, -29, -29, -29, -29, -29, -8, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 36, 37, 38, 39, 13, 14, 15, 34, 1, 35, + 40, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 78, 79, 81, 82, 4, 41, 42, 5, 41, + 42, 6, 9, 8, 11, 12, 21, 22, 23, 24, + 25, 66, 26, 30, 31, 32, 33, 47, 48, 0, + 0, 50, 0, 0, 0, 51, 52, 53, 0, 0, + 54, 83, 55, 84, 85, 0, 86, 87, 88, 89, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-29)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 5, 6, 7, 8, 23, 24, 25, 10, 29, 12, + 15, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 27, 28, 51, 52, 3, 31, 32, 0, 31, + 32, 29, 9, 4, 30, 11, 28, 30, 28, 28, + 28, 49, 29, 28, 26, 26, 26, 31, 31, -1, + -1, 30, -1, -1, -1, 30, 30, 30, -1, -1, + 30, 28, 31, 28, 30, -1, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 29, 34, 35, 3, 0, 29, 41, 4, 9, + 42, 30, 11, 23, 24, 25, 43, 44, 45, 46, + 47, 28, 30, 28, 28, 28, 29, 48, 63, 36, + 28, 26, 26, 26, 10, 12, 5, 6, 7, 8, + 15, 31, 32, 37, 38, 39, 49, 31, 31, 50, + 30, 30, 30, 30, 30, 31, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 49, 51, 52, 53, + 54, 55, 57, 58, 59, 60, 61, 62, 27, 28, + 40, 40, 40, 28, 28, 30, 30, 30, 30, 30, + 56, 30, 30, 30, 30, 30, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: +/* Line 1787 of yacc.c */ +#line 70 "imap_csim.y" + { + g_strreplace(&_map_info->image_name, (yyvsp[(5) - (7)].id)); + g_free ((yyvsp[(5) - (7)].id)); + } + break; + + case 8: +/* Line 1787 of yacc.c */ +#line 82 "imap_csim.y" + {} + break; + + case 9: +/* Line 1787 of yacc.c */ +#line 83 "imap_csim.y" + { g_free ((yyvsp[(3) - (3)].id)); } + break; + + case 10: +/* Line 1787 of yacc.c */ +#line 84 "imap_csim.y" + { g_free ((yyvsp[(3) - (3)].id)); } + break; + + case 11: +/* Line 1787 of yacc.c */ +#line 88 "imap_csim.y" + { + _map_info->old_image_width = (yyvsp[(3) - (3)].val); + } + break; + + case 12: +/* Line 1787 of yacc.c */ +#line 94 "imap_csim.y" + { + _map_info->old_image_height = (yyvsp[(3) - (3)].val); + } + break; + + case 13: +/* Line 1787 of yacc.c */ +#line 100 "imap_csim.y" + { + (yyval.val) = (gint) (yyvsp[(1) - (1)].value); + } + break; + + case 14: +/* Line 1787 of yacc.c */ +#line 104 "imap_csim.y" + { + (yyval.val) = (gint) g_ascii_strtod ((yyvsp[(1) - (1)].id), NULL); + g_free ((yyvsp[(1) - (1)].id)); + } + break; + + case 15: +/* Line 1787 of yacc.c */ +#line 111 "imap_csim.y" + { + g_strreplace(&_map_info->title, (yyvsp[(5) - (6)].id)); + g_free ((yyvsp[(5) - (6)].id)); + } + break; + + case 21: +/* Line 1787 of yacc.c */ +#line 127 "imap_csim.y" + { + g_free ((yyvsp[(2) - (3)].id)); + } + break; + + case 22: +/* Line 1787 of yacc.c */ +#line 133 "imap_csim.y" + { + g_strreplace(&_map_info->author, (yyvsp[(2) - (3)].id)); + g_free ((yyvsp[(2) - (3)].id)); + } + break; + + case 23: +/* Line 1787 of yacc.c */ +#line 140 "imap_csim.y" + { + gchar *description; + + description = g_strconcat(_map_info->description, (yyvsp[(2) - (3)].id), "\n", + NULL); + g_strreplace(&_map_info->description, description); + g_free ((yyvsp[(2) - (3)].id)); + } + break; + + case 26: +/* Line 1787 of yacc.c */ +#line 155 "imap_csim.y" + { + if (current_type != UNDEFINED) + add_shape(current_object); + } + break; + + case 41: +/* Line 1787 of yacc.c */ +#line 182 "imap_csim.y" + { + if (!g_ascii_strcasecmp((yyvsp[(3) - (3)].id), "RECT")) { + current_object = create_rectangle(0, 0, 0, 0); + current_type = RECTANGLE; + } else if (!g_ascii_strcasecmp((yyvsp[(3) - (3)].id), "CIRCLE")) { + current_object = create_circle(0, 0, 0); + current_type = CIRCLE; + } else if (!g_ascii_strcasecmp((yyvsp[(3) - (3)].id), "POLY")) { + current_object = create_polygon(NULL); + current_type = POLYGON; + } else if (!g_ascii_strcasecmp((yyvsp[(3) - (3)].id), "DEFAULT")) { + current_type = UNDEFINED; + } + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 42: +/* Line 1787 of yacc.c */ +#line 200 "imap_csim.y" + { + char *p; + if (current_type == RECTANGLE) { + Rectangle_t *rectangle; + + rectangle = ObjectToRectangle(current_object); + p = strtok((yyvsp[(3) - (3)].id), ","); + rectangle->x = atoi(p); + p = strtok(NULL, ","); + rectangle->y = atoi(p); + p = strtok(NULL, ","); + rectangle->width = atoi(p) - rectangle->x; + p = strtok(NULL, ","); + rectangle->height = atoi(p) - rectangle->y; + } else if (current_type == CIRCLE) { + Circle_t *circle; + + circle = ObjectToCircle(current_object); + p = strtok((yyvsp[(3) - (3)].id), ","); + circle->x = atoi(p); + p = strtok(NULL, ","); + circle->y = atoi(p); + p = strtok(NULL, ","); + circle->r = atoi(p); + } else if (current_type == POLYGON) { + Polygon_t *polygon = ObjectToPolygon(current_object); + GList *points; + GdkPoint *point, *first; + gint x, y; + + p = strtok((yyvsp[(3) - (3)].id), ","); + x = atoi(p); + p = strtok(NULL, ","); + y = atoi(p); + point = new_point(x, y); + points = g_list_append(NULL, (gpointer) point); + + while(1) { + p = strtok(NULL, ","); + if (!p) + break; + x = atoi(p); + p = strtok(NULL, ","); + y = atoi(p); + point = new_point(x, y); + points = g_list_append(points, (gpointer) point); + } + /* Remove last point if duplicate */ + first = (GdkPoint*) points->data; + polygon->points = points; + if (first->x == point->x && first->y == point->y) + polygon_remove_last_point(polygon); + polygon->points = points; + } + + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 43: +/* Line 1787 of yacc.c */ +#line 260 "imap_csim.y" + { + if (current_type == UNDEFINED) { + g_strreplace(&_map_info->default_url, (yyvsp[(3) - (3)].id)); + } else { + object_set_url(current_object, unescape_text((yyvsp[(3) - (3)].id))); + } + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 44: +/* Line 1787 of yacc.c */ +#line 271 "imap_csim.y" + { + } + break; + + case 46: +/* Line 1787 of yacc.c */ +#line 277 "imap_csim.y" + { + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 47: +/* Line 1787 of yacc.c */ +#line 283 "imap_csim.y" + { + object_set_comment(current_object, unescape_text((yyvsp[(3) - (3)].id))); + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 48: +/* Line 1787 of yacc.c */ +#line 290 "imap_csim.y" + { + object_set_target(current_object, unescape_text((yyvsp[(3) - (3)].id))); + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 49: +/* Line 1787 of yacc.c */ +#line 297 "imap_csim.y" + { + object_set_mouse_over(current_object, unescape_text((yyvsp[(3) - (3)].id))); + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 50: +/* Line 1787 of yacc.c */ +#line 304 "imap_csim.y" + { + object_set_mouse_out(current_object, unescape_text((yyvsp[(3) - (3)].id))); + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 51: +/* Line 1787 of yacc.c */ +#line 311 "imap_csim.y" + { + object_set_focus(current_object, unescape_text((yyvsp[(3) - (3)].id))); + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + case 52: +/* Line 1787 of yacc.c */ +#line 318 "imap_csim.y" + { + object_set_blur(current_object, unescape_text((yyvsp[(3) - (3)].id))); + g_free ((yyvsp[(3) - (3)].id)); + } + break; + + +/* Line 1787 of yacc.c */ +#line 1831 "y.tab.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 327 "imap_csim.y" + + +static void +csim_error(char* s) +{ + extern FILE *csim_in; + csim_restart(csim_in); +} + +gboolean +load_csim (const char* filename) +{ + gboolean status; + extern FILE *csim_in; + csim_in = g_fopen(filename, "r"); + if (csim_in) { + _map_info = get_map_info(); + status = !csim_parse(); + fclose(csim_in); + } else { + status = FALSE; + } + return status; +} + +static gchar* +unescape_text (gchar *input) +{ + /* + * We "unescape" simple things "in place", knowing that unescaped + * strings always are shorter than the original input. + * + * It is a shame there is no g_markup_unescape_text() function, but + * instead you have to create a full GMarkupParser/Context. + */ + struct token { + const char *escaped; + const char unescaped; + }; + const struct token tab[] = { + { """, '"' }, + { "'", '\'' }, + { "&", '&' }, + { "<", '<' }, + { ">", '>' } + }; + + size_t i; + for (i = 0; i < (sizeof tab / sizeof tab[0]); i++) + { + const size_t escaped_len = strlen (tab[i].escaped); + char *p; + + /* FIXME: The following code does not perform a UTF-8 substring + search. */ + for (p = strstr (input, tab[i].escaped); + p != NULL; + p = strstr (p, tab[i].escaped)) + { + size_t copy_len; + *p++ = tab[i].unescaped; + copy_len = strlen (p) - escaped_len + 2; + memmove (p, p + escaped_len - 1, copy_len); + if (*p == 0) + break; + } + } + + return input; +} + diff --git a/plug-ins/imagemap/imap_csim_parse.h b/plug-ins/imagemap/imap_csim_parse.h new file mode 100644 index 0000000..f83d108 --- /dev/null +++ b/plug-ins/imagemap/imap_csim_parse.h @@ -0,0 +1,142 @@ +/* A Bison parser, made by GNU Bison 2.6.1. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef CSIM_Y_TAB_H +# define CSIM_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int csim_debug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + IMG = 258, + SRC = 259, + WIDTH = 260, + HEIGHT = 261, + BORDER = 262, + USEMAP = 263, + START_MAP = 264, + END_MAP = 265, + NAME = 266, + AREA = 267, + SHAPE = 268, + COORDS = 269, + ALT = 270, + HREF = 271, + NOHREF = 272, + TARGET = 273, + ONMOUSEOVER = 274, + ONMOUSEOUT = 275, + ONFOCUS = 276, + ONBLUR = 277, + AUTHOR = 278, + DESCRIPTION = 279, + BEGIN_COMMENT = 280, + END_COMMENT = 281, + FLOAT = 282, + STRING = 283 + }; +#endif +/* Tokens. */ +#define IMG 258 +#define SRC 259 +#define WIDTH 260 +#define HEIGHT 261 +#define BORDER 262 +#define USEMAP 263 +#define START_MAP 264 +#define END_MAP 265 +#define NAME 266 +#define AREA 267 +#define SHAPE 268 +#define COORDS 269 +#define ALT 270 +#define HREF 271 +#define NOHREF 272 +#define TARGET 273 +#define ONMOUSEOVER 274 +#define ONMOUSEOUT 275 +#define ONFOCUS 276 +#define ONBLUR 277 +#define AUTHOR 278 +#define DESCRIPTION 279 +#define BEGIN_COMMENT 280 +#define END_COMMENT 281 +#define FLOAT 282 +#define STRING 283 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 49 "imap_csim.y" + + int val; + double value; + char *id; + + +/* Line 2049 of yacc.c */ +#line 120 "y.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE csim_lval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int csim_parse (void *YYPARSE_PARAM); +#else +int csim_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int csim_parse (void); +#else +int csim_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !CSIM_Y_TAB_H */ diff --git a/plug-ins/imagemap/imap_default_dialog.c b/plug-ins/imagemap/imap_default_dialog.c new file mode 100644 index 0000000..5fff183 --- /dev/null +++ b/plug-ins/imagemap/imap_default_dialog.c @@ -0,0 +1,184 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "imap_default_dialog.h" +#include "imap_main.h" + +#include "libgimp/stdplugins-intl.h" + + +static void +dialog_response (GtkWidget *widget, + gint response_id, + DefaultDialog_t *dialog) +{ + switch (response_id) + { + case GTK_RESPONSE_APPLY: + if (dialog->apply_cb) + dialog->apply_cb (dialog->apply_cb_data); + else if (dialog->ok_cb) + dialog->ok_cb (dialog->ok_cb_data); + break; + + case GTK_RESPONSE_OK: + gtk_widget_hide (dialog->dialog); + if (dialog->ok_cb) + dialog->ok_cb (dialog->ok_cb_data); + break; + + default: + gtk_widget_hide (dialog->dialog); + if (dialog->cancel_cb) + dialog->cancel_cb (dialog->cancel_cb_data); + break; + } +} + +void +default_dialog_set_ok_cb(DefaultDialog_t *dialog, void (*ok_cb)(gpointer), + gpointer ok_cb_data) +{ + dialog->ok_cb = ok_cb; + dialog->ok_cb_data = ok_cb_data; +} + +void +default_dialog_set_apply_cb(DefaultDialog_t *dialog, + void (*apply_cb)(gpointer), + gpointer apply_cb_data) +{ + dialog->apply_cb = apply_cb; + dialog->apply_cb_data = apply_cb_data; +} + +void +default_dialog_set_cancel_cb(DefaultDialog_t *dialog, + void (*cancel_cb)(gpointer), + gpointer cancel_cb_data) +{ + dialog->cancel_cb = cancel_cb; + dialog->cancel_cb_data = cancel_cb_data; +} + +DefaultDialog_t * +make_default_dialog (const gchar *title) +{ + DefaultDialog_t *data = g_new0 (DefaultDialog_t, 1); + + data->ok_cb = NULL; + data->apply_cb = NULL; + data->cancel_cb = NULL; + + data->dialog = gimp_dialog_new (title, PLUG_IN_ROLE, + get_dialog(), 0, + gimp_standard_help_func, PLUG_IN_PROC, + NULL); + + data->apply = gtk_dialog_add_button (GTK_DIALOG (data->dialog), + _("_Apply"), GTK_RESPONSE_APPLY); + + data->cancel = gtk_dialog_add_button (GTK_DIALOG (data->dialog), + _("_Cancel"), GTK_RESPONSE_CANCEL); + + data->ok = gtk_dialog_add_button (GTK_DIALOG (data->dialog), + _("_OK"), GTK_RESPONSE_OK); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (data->dialog), + GTK_RESPONSE_OK, + GTK_RESPONSE_APPLY, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect (data->dialog, "response", + G_CALLBACK (dialog_response), + data); + g_signal_connect (data->dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), + &data->dialog); + + data->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width (GTK_CONTAINER (data->vbox), 12); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (data->dialog))), + data->vbox, TRUE, TRUE, 0); + gtk_widget_show (data->vbox); + + return data; +} + +void +default_dialog_show(DefaultDialog_t *dialog) +{ + gtk_widget_show(dialog->dialog); +} + +void +default_dialog_hide_cancel_button(DefaultDialog_t *dialog) +{ + gtk_widget_hide(dialog->cancel); +} + +void +default_dialog_hide_apply_button(DefaultDialog_t *dialog) +{ + gtk_widget_hide(dialog->apply); +} + +void +default_dialog_hide_help_button(DefaultDialog_t *dialog) +{ + /* gtk_widget_hide(dialog->help); */ +} + +void +default_dialog_set_title(DefaultDialog_t *dialog, const gchar *title) +{ + gtk_window_set_title(GTK_WINDOW(dialog->dialog), title); +} + +void +default_dialog_set_label(DefaultDialog_t *dialog, const gchar *text) +{ + GtkWidget *label = gtk_label_new(text); + + gtk_box_pack_start (GTK_BOX (dialog->vbox), label, TRUE, TRUE, 0); + gtk_widget_show(label); +} + +GtkWidget* +default_dialog_add_table(DefaultDialog_t *dialog, gint rows, gint cols) +{ + GtkWidget *table = gtk_table_new (rows, cols, FALSE); + + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + + gtk_box_pack_start (GTK_BOX (dialog->vbox), table, TRUE, TRUE, 0); + gtk_widget_show (table); + + return table; +} diff --git a/plug-ins/imagemap/imap_default_dialog.h b/plug-ins/imagemap/imap_default_dialog.h new file mode 100644 index 0000000..a1b4ac5 --- /dev/null +++ b/plug-ins/imagemap/imap_default_dialog.h @@ -0,0 +1,59 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_DEFAULT_DIALOG_H +#define _IMAP_DEFAULT_DIALOG_H + +typedef struct +{ + GtkWidget *dialog; + GtkWidget *vbox; + GtkWidget *ok; + GtkWidget *apply; + GtkWidget *cancel; + void (*ok_cb)(gpointer); + gpointer ok_cb_data; + void (*apply_cb)(gpointer); + gpointer apply_cb_data; + void (*cancel_cb)(gpointer); + gpointer cancel_cb_data; +} DefaultDialog_t; + +DefaultDialog_t *make_default_dialog(const gchar *title); +void default_dialog_set_ok_cb(DefaultDialog_t *dialog, void (*ok_cb)(gpointer), + gpointer ok_cb_data); +void default_dialog_set_apply_cb(DefaultDialog_t *dialog, + void (*apply_cb)(gpointer), + gpointer apply_cb_data); +void default_dialog_set_cancel_cb(DefaultDialog_t *dialog, + void (*ok_cb)(gpointer), + gpointer ok_cb_data); +void default_dialog_show(DefaultDialog_t *dialog); +void default_dialog_hide_cancel_button(DefaultDialog_t *dialog); +void default_dialog_hide_apply_button(DefaultDialog_t *dialog); +void default_dialog_hide_help_button(DefaultDialog_t *dialog); +void default_dialog_set_title(DefaultDialog_t *dialog, const gchar *title); +void default_dialog_set_label(DefaultDialog_t *dialog, const gchar *text); +GtkWidget *default_dialog_add_table(DefaultDialog_t *dialog, gint rows, + gint cols); + +#endif /* _IMAP_DEFAULT_DIALOG_H */ diff --git a/plug-ins/imagemap/imap_edit_area_info.c b/plug-ins/imagemap/imap_edit_area_info.c new file mode 100644 index 0000000..698dae6 --- /dev/null +++ b/plug-ins/imagemap/imap_edit_area_info.c @@ -0,0 +1,515 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdio.h> +#include <string.h> + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_browse.h" +#include "imap_commands.h" +#include "imap_default_dialog.h" +#include "imap_edit_area_info.h" +#include "imap_main.h" +#include "imap_stock.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +static gboolean callback_lock; + + +static gchar* +relative_filter(const char *name, gpointer data) +{ + AreaInfoDialog_t *param = (AreaInfoDialog_t*) data; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->relative_link))) + return g_path_get_basename(name); + return g_strdup (name); +} + +static void +url_changed(GtkWidget *widget, gpointer data) +{ + AreaInfoDialog_t *param = (AreaInfoDialog_t*) data; + const gchar *url = gtk_entry_get_text(GTK_ENTRY(param->url)); + GtkWidget *button; + + if (!g_ascii_strncasecmp(url, "http://", sizeof("http://") - 1)) + button = param->web_site; + else if (!g_ascii_strncasecmp(url, "ftp://", sizeof("ftp://") - 1)) + button = param->ftp_site; + else if (!g_ascii_strncasecmp(url, "gopher://", sizeof("gopher://") - 1)) + button = param->gopher; + else if (!g_ascii_strncasecmp(url, "file:/", sizeof("file:/") - 1)) + button = param->file; + else if (!g_ascii_strncasecmp(url, "wais://", sizeof("wais://") - 1)) + button = param->wais; + else if (!g_ascii_strncasecmp(url, "telnet://", sizeof("telnet://") - 1)) + button = param->telnet; + else if (!g_ascii_strncasecmp(url, "mailto:", sizeof("mailto:") - 1)) + button = param->email; + else + button = param->other; + + callback_lock = TRUE; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); +} + +static void +set_url(GtkWidget *widget, AreaInfoDialog_t *param, const gchar *prefix) +{ + if (callback_lock) + { + callback_lock = FALSE; + } + else + { + if (gtk_widget_get_state (widget) & GTK_STATE_SELECTED) + { + char *p; + gchar *url = g_strdup(gtk_entry_get_text(GTK_ENTRY(param->url))); + + p = strstr(url, "//"); /* 'http://' */ + if (p) + { + p += 2; + } + else + { + p = strchr(url, ':'); /* 'mailto:' */ + if (p) + { + p++; + if (*p == '/') /* 'file:/' */ + p++; + } + else + { + p = url; + } + } + p = g_strconcat(prefix, p, NULL); + gtk_entry_set_text(GTK_ENTRY(param->url), p); + g_free(p); + g_free(url); + } + } + gtk_widget_grab_focus(param->url); +} + +static void +select_web_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, "http://"); +} + +static void +select_ftp_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, "ftp://"); +} + +static void +select_gopher_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, "gopher://"); +} + +static void +select_other_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, ""); +} + +static void +select_file_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, "file:/"); +} + +static void +select_wais_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, "wais://"); +} + +static void +select_telnet_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, "telnet://"); +} + +static void +select_email_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + set_url(widget, param, "mailto:"); +} + +static void +append_page (GtkWidget *notebook, GtkWidget *page, const gchar *icon_name, + const gchar *label_name) +{ + GtkWidget *hbox, *icon, *label; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); + gtk_widget_show(hbox); + + icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0); + gtk_widget_show (icon); + + label = gtk_label_new_with_mnemonic (label_name); + gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); + gtk_widget_show (label); + + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, hbox); +} + +static void +create_link_tab(AreaInfoDialog_t *dialog, GtkWidget *notebook) +{ + BrowseWidget_t *browse; + GtkWidget *table, *label; + GtkWidget *subtable, *frame; + GSList *group; + + table = gtk_table_new(11, 1, FALSE); + gtk_container_set_border_width(GTK_CONTAINER(table), 12); + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_widget_show(table); + + frame = gimp_frame_new(_("Link Type")); + gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 2, 0, 1); + gtk_widget_show(frame); + + subtable = gtk_table_new(2, 4, FALSE); + gtk_container_add (GTK_CONTAINER(frame), subtable); + gtk_widget_show(subtable); + + dialog->web_site = create_radio_button_in_table(subtable, NULL, 0, 0, + _("_Web Site")); + g_signal_connect(dialog->web_site, "toggled", + G_CALLBACK (select_web_cb), (gpointer) dialog); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->web_site)); + + dialog->ftp_site = create_radio_button_in_table(subtable, group, 0, 1, + _("_Ftp Site")); + g_signal_connect(dialog->ftp_site, "toggled", + G_CALLBACK (select_ftp_cb), (gpointer) dialog); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->ftp_site)); + + dialog->gopher = create_radio_button_in_table(subtable, group, 0, 2, + _("_Gopher")); + g_signal_connect(dialog->gopher, "toggled", + G_CALLBACK (select_gopher_cb), (gpointer) dialog); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->gopher)); + + dialog->other = create_radio_button_in_table(subtable, group, 0, 3, + _("Ot_her")); + g_signal_connect(dialog->other, "toggled", + G_CALLBACK (select_other_cb), (gpointer) dialog); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->other)); + + dialog->file = create_radio_button_in_table(subtable, group, 1, 0, + _("F_ile")); + g_signal_connect(dialog->file, "toggled", + G_CALLBACK (select_file_cb), (gpointer) dialog); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->file)); + + dialog->wais = create_radio_button_in_table(subtable, group, 1, 1, + _("WAI_S")); + g_signal_connect(dialog->wais, "toggled", + G_CALLBACK (select_wais_cb), (gpointer) dialog); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->wais)); + + dialog->telnet = create_radio_button_in_table(subtable, group, 1, 2, + _("Tel_net")); + g_signal_connect(dialog->telnet, "toggled", + G_CALLBACK (select_telnet_cb), (gpointer) dialog); + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(dialog->telnet)); + + dialog->email = create_radio_button_in_table(subtable, group, 1, 3, + _("e-_mail")); + g_signal_connect(dialog->email, "toggled", + G_CALLBACK (select_email_cb), (gpointer) dialog); + + label = create_label_in_table( + table, 2, 0, + _("_URL to activate when this area is clicked: (required)")); + + browse = browse_widget_new( _("Select HTML file")); + browse_widget_set_filter(browse, relative_filter, (gpointer) dialog); + gtk_table_attach_defaults(GTK_TABLE(table), browse->hbox, 0, 1, 3, 4); + dialog->url = browse->file; + g_signal_connect(dialog->url, "changed", G_CALLBACK(url_changed), + dialog); + gtk_label_set_mnemonic_widget(GTK_LABEL(label), dialog->url); + + dialog->relative_link = create_check_button_in_table(table, 4, 0, + _("Relati_ve link")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->relative_link), + TRUE); + + label = create_label_in_table( + table, 6, 0, + _("_Target frame name/ID: (optional - used for FRAMES only)")); + dialog->target = create_entry_in_table(table, label, 7, 0); + + label = create_label_in_table(table, 9, 0, _("ALT te_xt: (optional)")); + dialog->comment = create_entry_in_table(table, label, 10, 0); + + append_page (notebook, table, GIMP_ICON_WEB, _("_Link")); +} + +static void +geometry_changed(Object_t *obj, gpointer data) +{ + AreaInfoDialog_t *dialog = (AreaInfoDialog_t*) data; + if (dialog->geometry_lock) { + dialog->geometry_lock = FALSE; + } else { + if (dialog->obj == obj) { + object_update_info_widget(obj, dialog->infotab); + obj->class->assign(obj, dialog->clone); + } + } +} + +static void +toggle_preview_cb(GtkWidget *widget, AreaInfoDialog_t *param) +{ + param->preview = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + edit_area_info_dialog_emit_geometry_signal(param); +} + +static void +create_info_tab(AreaInfoDialog_t *dialog, GtkWidget *notebook) +{ + GtkWidget *vbox, *frame, *preview; + Object_t *obj = dialog->obj; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 12); + gtk_widget_show(vbox); + + frame = gimp_frame_new(_("Dimensions")); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + gtk_widget_show(frame); + + preview = gtk_check_button_new_with_mnemonic(_("Pre_view")); + g_signal_connect(preview, "toggled", + G_CALLBACK (toggle_preview_cb), (gpointer) dialog); + gtk_box_pack_start(GTK_BOX(vbox), preview, FALSE, FALSE, 0); + gtk_widget_show(preview); + + dialog->infotab = obj->class->create_info_widget(frame); + + append_page (notebook, vbox, obj->class->get_stock_icon_name (), + gettext (obj->class->name)); +} + +static void +create_java_script_tab(AreaInfoDialog_t *dialog, GtkWidget *notebook) +{ + GtkWidget *vbox, *table, *label; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1); + gtk_widget_show(vbox); + + table = gtk_table_new(11, 1, FALSE); + gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(table), 12); + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_widget_show(table); + + label = create_label_in_table(table, 0, 0, "o_nMouseover:"); + dialog->mouse_over = create_entry_in_table(table, label, 1, 0); + + label = create_label_in_table(table, 3, 0, "on_Mouseout:"); + dialog->mouse_out = create_entry_in_table(table, label, 4, 0); + + label = create_label_in_table(table, 6, 0, "on_Focus (HTML 4.0):"); + dialog->focus = create_entry_in_table(table, label, 7, 0); + + label = create_label_in_table(table, 9, 0, "on_Blur (HTML 4.0):"); + dialog->blur = create_entry_in_table(table, label, 10, 0); + + append_page (notebook, vbox, IMAP_STOCK_JAVA, _("_JavaScript")); +} + +static gboolean +object_was_changed(AreaInfoDialog_t *dialog) +{ + Object_t *clone = dialog->clone; + Object_t *obj = dialog->obj; + gint old_x, old_y, old_width, old_height; + gint new_x, new_y, new_width, new_height; + + object_get_dimensions(clone, &old_x, &old_y, &old_width, &old_height); + object_get_dimensions(obj, &new_x, &new_y, &new_width, &new_height); + + return new_x != old_x || new_y != old_y || new_width != old_width || + new_height != old_height || clone->selected != obj->selected; +} + +static void +edit_area_apply_cb(gpointer data) +{ + AreaInfoDialog_t *param = (AreaInfoDialog_t*) data; + Object_t *obj = param->obj; + + object_set_url(obj, gtk_entry_get_text(GTK_ENTRY(param->url))); + object_set_target(obj, gtk_entry_get_text(GTK_ENTRY(param->target))); + object_set_comment(obj, gtk_entry_get_text(GTK_ENTRY(param->comment))); + object_set_mouse_over(obj, + gtk_entry_get_text(GTK_ENTRY(param->mouse_over))); + object_set_mouse_out(obj, gtk_entry_get_text(GTK_ENTRY(param->mouse_out))); + object_set_focus(obj, gtk_entry_get_text(GTK_ENTRY(param->focus))); + object_set_blur(obj, gtk_entry_get_text(GTK_ENTRY(param->blur))); + object_update(obj, param->infotab); + update_shape(obj); + + if (object_was_changed(param)) + preview_redraw(); +} + +static void +edit_area_ok_cb(gpointer data) +{ + AreaInfoDialog_t *param = (AreaInfoDialog_t*) data; + Object_t *obj = param->obj; + + object_list_remove_geometry_cb(obj->list, param->geometry_cb_id); + + /* Fix me: nasty hack */ + if (param->add) + command_list_add(edit_object_command_new(obj)); + + edit_area_apply_cb(data); + object_unlock(obj); + object_unref(param->clone); +} + +static void +edit_area_cancel_cb(gpointer data) +{ + AreaInfoDialog_t *dialog = (AreaInfoDialog_t*) data; + Object_t *obj = dialog->obj; + gboolean changed = object_was_changed(dialog); + gboolean selected = obj->selected; + + object_list_remove_geometry_cb(obj->list, dialog->geometry_cb_id); + object_unlock(obj); + object_assign(dialog->clone, obj); + obj->selected = selected; + object_unref(dialog->clone); + + if (changed) + preview_redraw(); +} + +static void +switch_page(GtkWidget *widget, gpointer page, gint page_num, + gpointer data) +{ + AreaInfoDialog_t *param = (AreaInfoDialog_t*) data; + if (page_num == 0) { + gtk_widget_grab_focus(param->url); + } else if (page_num == 1) { + Object_t *obj = param->obj; + obj->class->set_initial_focus(obj, param->infotab); + } else { + gtk_widget_grab_focus(param->mouse_over); + } +} + +AreaInfoDialog_t* +create_edit_area_info_dialog(Object_t *obj) +{ + AreaInfoDialog_t *data = g_new(AreaInfoDialog_t, 1); + GtkWidget *notebook; + + data->geometry_lock = FALSE; + data->preview = FALSE; + data->obj = obj; + data->browse = NULL; + data->dialog = make_default_dialog(_("Area Settings")); + default_dialog_set_ok_cb(data->dialog, edit_area_ok_cb, data); + default_dialog_set_apply_cb(data->dialog, edit_area_apply_cb, data); + default_dialog_set_cancel_cb(data->dialog, edit_area_cancel_cb, data); + + data->notebook = notebook = gtk_notebook_new(); + g_signal_connect_after(notebook, "switch-page", + G_CALLBACK(switch_page), (gpointer) data); + + gtk_box_pack_start(GTK_BOX(data->dialog->vbox), notebook, TRUE, TRUE, 0); + create_link_tab(data, notebook); + create_info_tab(data, notebook); + create_java_script_tab(data, notebook); + gtk_widget_show(notebook); + + return data; +} + +void +edit_area_info_dialog_show(AreaInfoDialog_t *dialog, Object_t *obj, + gboolean add) +{ + gchar *title; + + object_unlock(dialog->obj); + object_lock(obj); + dialog->obj = obj; + dialog->clone = object_clone(obj); + dialog->add = add; + object_fill_info_tab(obj, dialog->infotab); + gtk_entry_set_text(GTK_ENTRY(dialog->url), obj->url); + gtk_entry_set_text(GTK_ENTRY(dialog->target), obj->target); + gtk_entry_set_text(GTK_ENTRY(dialog->comment), obj->comment); + gtk_entry_set_text(GTK_ENTRY(dialog->mouse_over), obj->mouse_over); + gtk_entry_set_text(GTK_ENTRY(dialog->mouse_out), obj->mouse_out); + gtk_entry_set_text(GTK_ENTRY(dialog->focus), obj->focus); + gtk_entry_set_text(GTK_ENTRY(dialog->blur), obj->blur); + gtk_widget_grab_focus(dialog->url); + + dialog->geometry_cb_id = + object_list_add_geometry_cb(obj->list, geometry_changed, dialog); + + title = g_strdup_printf (_("Area #%d Settings"), + object_get_position_in_list(obj) + 1); + default_dialog_set_title(dialog->dialog, title); + g_free (title); + default_dialog_show(dialog->dialog); +} + +void +edit_area_info_dialog_emit_geometry_signal(AreaInfoDialog_t *dialog) +{ + if (dialog->preview) { + dialog->geometry_lock = TRUE; + object_emit_geometry_signal(dialog->obj); + } +} diff --git a/plug-ins/imagemap/imap_edit_area_info.h b/plug-ins/imagemap/imap_edit_area_info.h new file mode 100644 index 0000000..fbf45fb --- /dev/null +++ b/plug-ins/imagemap/imap_edit_area_info.h @@ -0,0 +1,66 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_EDIT_AREA_INFO_H +#define _IMAP_EDIT_AREA_INFO_H + +typedef struct AreaInfoDialog_t AreaInfoDialog_t; + +#include "imap_default_dialog.h" +#include "imap_object.h" + +struct AreaInfoDialog_t { + DefaultDialog_t *dialog; + Object_t *obj; + Object_t *clone; + gboolean add; + gboolean geometry_lock; + gboolean preview; + + GtkWidget *notebook; + GtkWidget *web_site; + GtkWidget *ftp_site; + GtkWidget *gopher; + GtkWidget *other; + GtkWidget *file; + GtkWidget *wais; + GtkWidget *telnet; + GtkWidget *email; + GtkWidget *url; + GtkWidget *relative_link; + GtkWidget *target; + GtkWidget *comment; + GtkWidget *mouse_over; + GtkWidget *mouse_out; + GtkWidget *focus; + GtkWidget *blur; + GtkWidget *browse; + gpointer infotab; + gpointer geometry_cb_id; +}; + +AreaInfoDialog_t *create_edit_area_info_dialog(Object_t *obj); +void edit_area_info_dialog_show(AreaInfoDialog_t *dialog, Object_t *obj, + gboolean add); +void edit_area_info_dialog_emit_geometry_signal(AreaInfoDialog_t *dialog); + +#endif /* _IMAP_EDIT_AREA_INFO_H */ diff --git a/plug-ins/imagemap/imap_file.c b/plug-ins/imagemap/imap_file.c new file mode 100644 index 0000000..35ff832 --- /dev/null +++ b/plug-ins/imagemap/imap_file.c @@ -0,0 +1,180 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "imap_file.h" +#include "imap_main.h" + +#include "libgimp/stdplugins-intl.h" + + +static void +open_cb (GtkWidget *dialog, + gint response_id, + gpointer data) +{ + if (response_id == GTK_RESPONSE_OK) + { + gchar *filename; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + + if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + { + do_file_error_dialog (_("Error opening file"), filename); + g_free (filename); + return; + } + + load (filename); + g_free (filename); + } + + gtk_widget_hide (dialog); +} + +void +do_file_open_dialog (void) +{ + static GtkWidget *dialog; + + if (! dialog) + { + dialog = + gtk_file_chooser_dialog_new (_("Load Image Map"), + NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Open"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect (dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), + &dialog); + g_signal_connect (dialog, "response", + G_CALLBACK (open_cb), + dialog); + } + + gtk_window_present (GTK_WINDOW (dialog)); +} + +static void +save_cb (GtkWidget *dialog, + gint response_id, + gpointer data) +{ + if (response_id == GTK_RESPONSE_OK) + { + gchar *filename; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + + save_as (filename); + g_free (filename); + } + + gtk_widget_hide (dialog); +} + +void +do_file_save_as_dialog (void) +{ + static GtkWidget *dialog; + + if (! dialog) + { + gchar *filename; + + dialog = gtk_file_chooser_dialog_new (_("Save Image Map"), + NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, + + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Save"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), + TRUE); + + g_signal_connect (dialog, "destroy", + G_CALLBACK (gtk_widget_destroyed), + &dialog); + g_signal_connect (dialog, "response", + G_CALLBACK (save_cb), + dialog); + + /* Suggest a filename based on the image name. + * The image name is in UTF-8 encoding. + */ + filename = g_strconcat (get_image_name(), ".map", NULL); + + if (filename) + { + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), + filename); + g_free (filename); + } + } + + gtk_window_present (GTK_WINDOW (dialog)); +} + +void +do_file_error_dialog (const char *error, + const char *filename) +{ + GtkWidget *dialog; + + dialog = gtk_message_dialog_new_with_markup + (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s", + error, + gimp_filename_to_utf8 (filename)); + + g_signal_connect_swapped (dialog, "response", + G_CALLBACK (gtk_widget_destroy), + dialog); + gtk_dialog_run (GTK_DIALOG (dialog)); +} diff --git a/plug-ins/imagemap/imap_file.h b/plug-ins/imagemap/imap_file.h new file mode 100644 index 0000000..c661eaa --- /dev/null +++ b/plug-ins/imagemap/imap_file.h @@ -0,0 +1,34 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_FILE_H +#define _IMAP_FILE_H + +void do_file_open_dialog(void); +void do_file_save_as_dialog(void); +void do_file_error_dialog(const char *error, const char *filename); + +gboolean load_csim (const char* filename); +gboolean load_cern (const char* filename); +gboolean load_ncsa (const char* filename); + +#endif /* _IMAP_FILE_H */ diff --git a/plug-ins/imagemap/imap_grid.c b/plug-ins/imagemap/imap_grid.c new file mode 100644 index 0000000..48c6a54 --- /dev/null +++ b/plug-ins/imagemap/imap_grid.c @@ -0,0 +1,414 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdlib.h> + +#include <gtk/gtk.h> + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "imap_grid.h" +#include "imap_main.h" +#include "imap_menu.h" +#include "imap_preview.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +typedef enum {GRID_HIDDEN, GRID_LINES, GRID_CROSSES} GridType_t; + +typedef struct { + DefaultDialog_t *dialog; + GtkWidget *type_frame; + GtkWidget *granularity_frame; + GtkWidget *offset_frame; + GtkWidget *snap; + GtkWidget *width; + GtkWidget *height; + GtkWidget *chain_width_height; + GtkWidget *left; + GtkWidget *top; + GtkWidget *chain_left_top; + GtkWidget *hidden; + GtkWidget *lines; + GtkWidget *crosses; + GtkWidget *preview; + + gboolean enable_preview; +} GridDialog_t; + + +static gboolean grid_snap = FALSE; +static gint grid_width = 15; +static gint grid_height = 15; +static gint grid_left = 0; +static gint grid_top = 0; +static GridType_t grid_type = GRID_LINES; + +static void +grid_settings_ok_cb(gpointer data) +{ + GridDialog_t *param = (GridDialog_t*) data; + gboolean new_snap; + + new_snap = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->snap)); + grid_width = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->width)); + grid_height = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->height)); + grid_left = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->left)); + grid_top = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(param->top)); + + if (grid_snap != new_snap) { + grid_snap = new_snap; + menu_check_grid(grid_snap); + } + preview_redraw(); +} + +static void +snap_toggled_cb(GtkWidget *widget, gpointer data) +{ + GridDialog_t *param = (GridDialog_t*) data; + gint sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + + gtk_widget_set_sensitive(param->type_frame, sensitive); + gtk_widget_set_sensitive(param->granularity_frame, sensitive); + gtk_widget_set_sensitive(param->offset_frame, sensitive); + gtk_widget_set_sensitive(param->preview, sensitive); +} + +static void +type_toggled_cb(GtkWidget *widget, gpointer data) +{ + if (gtk_widget_get_state (widget) & GTK_STATE_SELECTED) + { + grid_type = GPOINTER_TO_INT (data); + preview_redraw(); + } +} + +static void +toggle_preview_cb(GtkWidget *widget, GridDialog_t *param) +{ + param->enable_preview = + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + preview_redraw(); +} + +static void +grid_assign_value(GtkWidget *widget, gpointer data, gint *value) +{ + GridDialog_t *dialog = (GridDialog_t*) data; + if (dialog->enable_preview) { + *value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + preview_redraw(); /* Fix me! */ + } +} + +static void +width_changed_cb(GtkWidget *widget, gpointer data) +{ + GridDialog_t *dialog = (GridDialog_t*) data; + + grid_assign_value(widget, data, &grid_width); + if (gimp_chain_button_get_active( + GIMP_CHAIN_BUTTON(dialog->chain_width_height))) { + gint value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->height), value); + } +} + +static void +height_changed_cb(GtkWidget *widget, gpointer data) +{ + GridDialog_t *dialog = (GridDialog_t*) data; + + grid_assign_value(widget, data, &grid_height); + if (gimp_chain_button_get_active( + GIMP_CHAIN_BUTTON(dialog->chain_width_height))) { + gint value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->width), value); + } +} + +static void +left_changed_cb(GtkWidget *widget, gpointer data) +{ + GridDialog_t *dialog = (GridDialog_t*) data; + + grid_assign_value(widget, data, &grid_left); + if (gimp_chain_button_get_active( + GIMP_CHAIN_BUTTON(dialog->chain_left_top))) { + gint value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->top), value); + } +} + +static void +top_changed_cb(GtkWidget *widget, gpointer data) +{ + GridDialog_t *dialog = (GridDialog_t*) data; + + grid_assign_value(widget, data, &grid_top); + if (gimp_chain_button_get_active( + GIMP_CHAIN_BUTTON(dialog->chain_left_top))) { + gint value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->left), value); + } +} + +static GridDialog_t* +create_grid_settings_dialog(void) +{ + GridDialog_t *data = g_new(GridDialog_t, 1); + DefaultDialog_t *dialog; + GtkWidget *main_table, *table, *label; + GtkWidget *frame; + GtkWidget *hbox; + GtkWidget *button; + GtkWidget *chain_button; + + data->dialog = dialog = make_default_dialog(_("Grid Settings")); + default_dialog_set_ok_cb(dialog, grid_settings_ok_cb, (gpointer) data); + main_table = default_dialog_add_table(dialog, 4, 2); + + data->snap = gtk_check_button_new_with_mnemonic(_("_Snap-to grid enabled")); + g_signal_connect(data->snap, "toggled", + G_CALLBACK (snap_toggled_cb), data); + gtk_table_attach_defaults(GTK_TABLE(main_table), data->snap, 0, 1, 0, 1); + gtk_widget_show(data->snap); + + data->type_frame = frame = gimp_frame_new(_("Grid Visibility and Type")); + gtk_widget_show(frame); + gtk_table_attach_defaults(GTK_TABLE(main_table), frame, 0, 2, 1, 2); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + + button = gtk_radio_button_new_with_mnemonic_from_widget(NULL, _("_Hidden")); + data->hidden = button; + g_signal_connect(button, "toggled", + G_CALLBACK (type_toggled_cb), (gpointer) GRID_HIDDEN); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + button = gtk_radio_button_new_with_mnemonic_from_widget( + GTK_RADIO_BUTTON(button), _("_Lines")); + data->lines = button; + g_signal_connect(button, "toggled", + G_CALLBACK (type_toggled_cb), (gpointer) GRID_LINES); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + button = gtk_radio_button_new_with_mnemonic_from_widget( + GTK_RADIO_BUTTON(button), _("C_rosses")); + data->crosses = button; + g_signal_connect(button, "toggled", + G_CALLBACK (type_toggled_cb), + (gpointer) GRID_CROSSES); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + gtk_widget_show(button); + + data->granularity_frame = frame = gimp_frame_new(_("Grid Granularity")); + gtk_table_attach_defaults(GTK_TABLE(main_table), frame, 0, 1, 2, 3); + table = gtk_table_new(2, 4, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + label = create_label_in_table(table, 0, 0, _("_Width")); + data->width = create_spin_button_in_table(table, label, 0, 1, 15, 1, 100); + g_signal_connect(data->width, "value-changed", + G_CALLBACK (width_changed_cb), (gpointer) data); + create_label_in_table(table, 0, 3, _("pixels")); + + label = create_label_in_table(table, 1, 0, _("_Height")); + data->height = create_spin_button_in_table(table, label, 1, 1, 15, 1, 100); + g_signal_connect(data->height, "value-changed", + G_CALLBACK (height_changed_cb), (gpointer) data); + create_label_in_table(table, 1, 3, _("pixels")); + + chain_button = gimp_chain_button_new(GIMP_CHAIN_RIGHT); + data->chain_width_height = chain_button; + gtk_table_attach_defaults(GTK_TABLE(table), chain_button, 2, 3, 0, 2); + gtk_widget_show(chain_button); + + gtk_widget_show(table); + gtk_widget_show(frame); + + data->offset_frame = frame = gimp_frame_new(_("Grid Offset")); + gtk_table_attach_defaults(GTK_TABLE(main_table), frame, 1, 2, 2, 3); + table = gtk_table_new(2, 3, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + label = create_label_in_table(table, 0, 2, _("pixels from l_eft")); + data->left = create_spin_button_in_table(table, label, 0, 0, 0, 0, 100); + g_signal_connect(data->left, "value-changed", + G_CALLBACK (left_changed_cb), (gpointer) data); + + label = create_label_in_table(table, 1, 2, _("pixels from _top")); + data->top = create_spin_button_in_table(table, label, 1, 0, 0, 0, 100); + g_signal_connect(data->top, "value-changed", + G_CALLBACK (top_changed_cb), (gpointer) data); + + chain_button = gimp_chain_button_new(GIMP_CHAIN_RIGHT); + data->chain_left_top = chain_button; + gtk_table_attach_defaults(GTK_TABLE(table), chain_button, 1, 2, 0, 2); + gtk_widget_show(chain_button); + + data->preview = create_check_button_in_table(main_table, 3, 0, + _("_Preview")); + g_signal_connect(data->preview, "toggled", + G_CALLBACK (toggle_preview_cb), (gpointer) data); + gtk_widget_show(data->preview); + + snap_toggled_cb(data->snap, data); + + gtk_widget_show(table); + gtk_widget_show(frame); + + return data; +} + +void +do_grid_settings_dialog(void) +{ + static GridDialog_t* dialog; + GtkWidget *type; + + if (!dialog) + dialog = create_grid_settings_dialog(); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->snap), grid_snap); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->width), grid_width); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->height), grid_height); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->left), grid_left); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->top), grid_top); + + if (grid_type == GRID_HIDDEN) + type = dialog->hidden; + else if (grid_type == GRID_LINES) + type = dialog->lines; + else + type = dialog->crosses; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(type), TRUE); + + default_dialog_show(dialog->dialog); +} + +static void +draw_lines(cairo_t *cr, gint width, gint height) +{ + gint x, y; + gdouble dash = 4.; + + cairo_set_dash (cr, &dash, 1, 0.); + for (x = grid_left % grid_width; x < width; x += grid_width) + draw_line(cr, x, 1, x, height); + for (y = grid_top % grid_height; y < height; y += grid_height) + draw_line(cr, 1, y, width, y); +} + +static void +draw_crosses(cairo_t *cr, gint width, gint height) +{ + gint x, y; + gdouble dash[4] = { 7., grid_height - 7., 7., grid_width - 7. }; + + cairo_set_dash (cr, dash, 2, 4.5 - grid_top); + for (x = grid_left % grid_width; x < width; x += grid_width) + draw_line(cr, x, 1, x, height); + cairo_set_dash (cr, dash+2, 2, 4.5 - grid_left); + for (y = grid_top % grid_height; y < height; y += grid_height) + draw_line(cr, 1, y, width, y); +} + +void +draw_grid(cairo_t *cr, gint width, gint height) +{ + if (grid_snap && grid_type != GRID_HIDDEN) + { + cairo_save (cr); + if (grid_type == GRID_LINES) + { + draw_lines(cr, width, height); + } + else + { + draw_crosses(cr, width, height); + } + cairo_restore (cr); + } +} + +void +toggle_grid(void) +{ + grid_snap = !grid_snap; + preview_redraw(); +} + +static gint +grid_nearest_x(gint x) +{ + return grid_left + (x - grid_left + grid_width / 2) / grid_width + * grid_width; +} + +static gint +grid_nearest_y(gint y) +{ + return grid_top + (y - grid_top + grid_height / 2) / grid_height + * grid_height; +} + +void +round_to_grid(gint *x, gint *y) +{ + if (grid_snap) { + *x = grid_nearest_x(*x); + *y = grid_nearest_y(*y); + } +} + +gboolean +grid_near_x(gint x) +{ + return grid_snap && grid_type != GRID_HIDDEN + && abs(grid_nearest_x(x) - x) <= 1; +} + +gboolean +grid_near_y(gint y) +{ + return grid_snap && grid_type != GRID_HIDDEN + && abs(grid_nearest_x(y) - y) <= 1; +} diff --git a/plug-ins/imagemap/imap_grid.h b/plug-ins/imagemap/imap_grid.h new file mode 100644 index 0000000..84deb95 --- /dev/null +++ b/plug-ins/imagemap/imap_grid.h @@ -0,0 +1,34 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_GRID_H +#define _IMAP_GRID_H + +void do_grid_settings_dialog (void); +void draw_grid (cairo_t *cr, gint width, gint height); +void toggle_grid (void); +void round_to_grid (gint *x, gint *y); + +gboolean grid_near_x (gint x); +gboolean grid_near_y (gint y); + +#endif /* _IMAP_GRID_H */ diff --git a/plug-ins/imagemap/imap_main.c b/plug-ins/imagemap/imap_main.c new file mode 100644 index 0000000..8254a87 --- /dev/null +++ b/plug-ins/imagemap/imap_main.c @@ -0,0 +1,1306 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2006 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#include <glib/gstdio.h> + +#include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> /* for keyboard values */ + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "imap_about.h" +#include "imap_circle.h" +#include "imap_commands.h" +#include "imap_default_dialog.h" +#include "imap_edit_area_info.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_menu.h" +#include "imap_misc.h" +#include "imap_object.h" +#include "imap_polygon.h" +#include "imap_preview.h" +#include "imap_rectangle.h" +#include "imap_selection.h" +#include "imap_settings.h" +#include "imap_source.h" +#include "imap_statusbar.h" +#include "imap_stock.h" +#include "imap_string.h" + +#include "libgimp/stdplugins-intl.h" + + +#define MAX_ZOOM_FACTOR 8 +#define ZOOMED(x) (_zoom_factor * (x)) +#define GET_REAL_COORD(x) ((x) / _zoom_factor) + +static gint zoom_in (void); +static gint zoom_out (void); + + +/* Global variables */ +static MapInfo_t _map_info; +static PreferencesData_t _preferences = {CSIM, TRUE, FALSE, TRUE, TRUE, FALSE, +FALSE, TRUE, DEFAULT_UNDO_LEVELS, DEFAULT_MRU_SIZE}; +static MRU_t *_mru; + +static gint32 _drawable_id; +static GdkCursorType _cursor = GDK_TOP_LEFT_ARROW; +static gboolean _show_url = TRUE; +static gchar *_filename = NULL; +static gchar *_image_name; +static gint _image_width; +static gint _image_height; +static GtkWidget *_dlg; +static Preview_t *_preview; +static Selection_t *_selection; +static StatusBar_t *_statusbar; +static ObjectList_t *_shapes; +static gint _zoom_factor = 1; +static gboolean (*_button_press_func)(GtkWidget*, GdkEventButton*, gpointer); +static gpointer _button_press_param; + +/* Declare local functions. */ +static void query (void); +static void run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); +static gint dialog (gint32 drawable_id); + +const GimpPlugInInfo PLUG_IN_INFO = { + NULL, /* init_proc */ + NULL, /* quit_proc */ + query, /* query_proc */ + run, /* run_proc */ +}; + +static int run_flag = 0; + + +MAIN () + +static void query(void) +{ + static const GimpParamDef args[] = { + {GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0) }"}, + {GIMP_PDB_IMAGE, "image", "Input image (unused)"}, + {GIMP_PDB_DRAWABLE, "drawable", "Input drawable"}, + }; + static const GimpParamDef *return_vals = NULL; + static int nreturn_vals = 0; + + gimp_install_procedure(PLUG_IN_PROC, + N_("Create a clickable imagemap"), + "", + "Maurits Rijk", + "Maurits Rijk", + "1998-2005", + N_("_Image Map..."), + "RGB*, GRAY*, INDEXED*", + GIMP_PLUGIN, + G_N_ELEMENTS (args), nreturn_vals, + args, return_vals); + + gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Web"); +} + +static void +run (const gchar *name, + gint n_params, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals) +{ + static GimpParam values[1]; + GimpRunMode run_mode; + gint32 drawable_id; + GimpPDBStatusType status = GIMP_PDB_SUCCESS; + + INIT_I18N (); + gegl_init (NULL, NULL); + + *nreturn_vals = 1; + *return_vals = values; + + run_mode = param[0].data.d_int32; + drawable_id = param[2].data.d_drawable; + + _drawable_id = drawable_id; + _image_name = gimp_image_get_name(param[1].data.d_image); + _image_width = gimp_image_width(param[1].data.d_image); + _image_height = gimp_image_height(param[1].data.d_image); + + _map_info.color = gimp_drawable_is_rgb(drawable_id); + + if (run_mode == GIMP_RUN_INTERACTIVE) { + if (!dialog(drawable_id)) { + /* The dialog was closed, or something similarly evil happened. */ + status = GIMP_PDB_EXECUTION_ERROR; + } + } + + values[0].type = GIMP_PDB_STATUS; + values[0].data.d_status = status; +} + +GtkWidget* +get_dialog(void) +{ + return _dlg; +} + +MRU_t* +get_mru(void) +{ + if (!_mru) + _mru = mru_create(); + return _mru; +} + +MapInfo_t* +get_map_info(void) +{ + return &_map_info; +} + +PreferencesData_t* +get_preferences(void) +{ + return &_preferences; +} + +static void +init_preferences(void) +{ + ColorSelData_t *colors = &_preferences.colors; + + colors->normal_fg.red = 0; + colors->normal_fg.green = 0xFFFF; + colors->normal_fg.blue = 0; + + colors->normal_bg.red = 0; + colors->normal_bg.green = 0; + colors->normal_bg.blue = 0xFFFF; + + colors->selected_fg.red = 0xFFFF; + colors->selected_fg.green = 0; + colors->selected_fg.blue = 0; + + colors->selected_bg.red = 0; + colors->selected_bg.green = 0; + colors->selected_bg.blue = 0xFFFF; + + colors->interactive_fg.red = 0xFFFF; + colors->interactive_fg.green = 0; + colors->interactive_fg.blue = 0xFFFF; + + colors->interactive_bg.red = 0xFFFF; + colors->interactive_bg.green = 0xFFFF; + colors->interactive_bg.blue = 0; + + preferences_load(&_preferences); + + mru_set_size(_mru, _preferences.mru_size); + command_list_set_undo_level(_preferences.undo_levels); +} + +gint +get_image_width(void) +{ + return _image_width; +} + +gint +get_image_height(void) +{ + return _image_height; +} + +void +set_busy_cursor(void) +{ + preview_set_cursor(_preview, GDK_WATCH); +} + +void +remove_busy_cursor(void) +{ + gdk_window_set_cursor(gtk_widget_get_window (_dlg), NULL); +} + +static gint +zoom_in(void) +{ + if (_zoom_factor < MAX_ZOOM_FACTOR) { + set_zoom(_zoom_factor + 1); + menu_set_zoom(_zoom_factor); + } + return _zoom_factor; +} + +static gint +zoom_out(void) +{ + if (_zoom_factor > 1) { + set_zoom(_zoom_factor - 1); + menu_set_zoom(_zoom_factor); + } + return _zoom_factor; +} + +void +set_zoom(gint zoom_factor) +{ + set_busy_cursor(); + _zoom_factor = zoom_factor; + preview_zoom(_preview, zoom_factor); + statusbar_set_zoom(_statusbar, zoom_factor); + remove_busy_cursor(); +} + +gint +get_real_coord(gint coord) +{ + return GET_REAL_COORD(coord); +} + +void +draw_line(cairo_t *cr, gint x1, gint y1, gint x2, gint y2) +{ + cairo_move_to (cr, ZOOMED (x1) + .5, ZOOMED (y1) + .5); + cairo_line_to (cr, ZOOMED (x2) + .5, ZOOMED (y2) + .5); + cairo_stroke (cr); +} + +void +draw_rectangle(cairo_t *cr, gboolean filled, gint x, gint y, + gint width, gint height) +{ + cairo_rectangle (cr, ZOOMED (x) + (filled ? 0. : .5), + ZOOMED (y) + (filled ? 0. : .5), + ZOOMED (width), ZOOMED (height)); + if (filled) + cairo_fill (cr); + else + cairo_stroke (cr); +} + +void +draw_circle(cairo_t *cr, gint x, gint y, gint r) +{ + cairo_arc (cr, ZOOMED (x), ZOOMED (y), ZOOMED (r), 0., 2 * G_PI); + cairo_stroke (cr); +} + +void +draw_polygon(cairo_t *cr, GList *list) +{ + GList *p; + + for (p = list; p; p = p->next) { + GdkPoint *src = (GdkPoint*) p->data; + cairo_line_to (cr, ZOOMED (src->x) + .5, ZOOMED (src->y) + .5); + } + cairo_close_path (cr); + cairo_stroke (cr); +} + +void +set_preview_color (GtkRadioAction *action, GtkRadioAction *current, + gpointer user_data) +{ + _map_info.show_gray = (gtk_radio_action_get_current_value (current) == 1); + set_zoom(_zoom_factor); +} + +void +preview_redraw(void) +{ + gtk_widget_queue_draw(_preview->preview); +} + +void +set_zoom_factor (GtkRadioAction *action, GtkRadioAction *current, + gpointer user_data) +{ + gint factor = gtk_radio_action_get_current_value (current); + set_zoom (factor + 1); +} + +const gchar * +get_image_name(void) +{ + return _image_name; +} + +const char* +get_filename(void) +{ + return _filename; +} + +static gboolean +arrow_on_button_press (GtkWidget *widget, + GdkEventButton *event, + gpointer data) +{ + if (gdk_event_triggers_context_menu ((GdkEvent *) event)) + { + do_popup_menu (event); + } + else if (event->button == 1) + { + if (event->type == GDK_2BUTTON_PRESS) + edit_shape((gint) event->x, (gint) event->y); + else + select_shape(widget, event); + } + + return FALSE; +} + +static void +set_arrow_func(void) +{ + _button_press_func = arrow_on_button_press; + _cursor = GDK_TOP_LEFT_ARROW; +} + +static void +set_object_func(gboolean (*func)(GtkWidget*, GdkEventButton*, + gpointer), gpointer param) +{ + _button_press_func = func; + _button_press_param = param; + _cursor = GDK_CROSSHAIR; +} + +void +set_func(GtkRadioAction *action, GtkRadioAction *current, + gpointer user_data) +{ + gint value = gtk_radio_action_get_current_value (current); + switch (value) + { + case 0: + set_arrow_func(); + break; + case 1: + set_object_func(object_on_button_press, get_rectangle_factory); + break; + case 2: + set_object_func(object_on_button_press, get_circle_factory); + break; + case 3: + set_object_func(object_on_button_press, get_polygon_factory); + break; + default: + break; + } +} + +void +add_shape(Object_t *obj) +{ + object_list_append(_shapes, obj); +} + +ObjectList_t* +get_shapes(void) +{ + return _shapes; +} + +void +update_shape(Object_t *obj) +{ + object_list_update(_shapes, obj); +} + +void +do_edit_selected_shape(void) +{ + object_list_edit_selected(_shapes); +} + +void +do_popup_menu(GdkEventButton *event) +{ + gint x = GET_REAL_COORD((gint) event->x); + gint y = GET_REAL_COORD((gint) event->y); + Object_t *obj = object_list_find(_shapes, x, y); + if (obj) { + obj->class->do_popup(obj, event); + } else { + do_main_popup_menu(event); + } +} + +static void +set_all_sensitivities(void) +{ + gint count = object_list_nr_selected(_shapes); + menu_shapes_selected(count); +} + +static void +main_set_title(const char *filename) +{ + char *title, *p; + + g_strreplace(&_filename, filename); + p = filename ? g_filename_display_basename (filename) : (gchar *) _("<Untitled>"); + title = g_strdup_printf("%s - Image Map", p); + if (filename) + g_free (p); + gtk_window_set_title(GTK_WINDOW(_dlg), title); + g_free(title); +} + +void +main_set_dimension(gint width, gint height) +{ + statusbar_set_dimension(_statusbar, + width / _zoom_factor, height / _zoom_factor); +} + +void +main_clear_dimension(void) +{ + statusbar_clear_dimension(_statusbar); +} + +void +show_url(void) +{ + _show_url = TRUE; +} + +void +hide_url(void) +{ + _show_url = FALSE; + statusbar_clear_status(_statusbar); +} + +void +select_shape(GtkWidget *widget, GdkEventButton *event) +{ + Object_t *obj; + gint x = GET_REAL_COORD((gint) event->x); + gint y = GET_REAL_COORD((gint) event->y); + MoveSashFunc_t sash_func; + + obj = object_list_near_sash(_shapes, x, y, &sash_func); + if (obj) { /* Start resizing */ + Command_t *command = move_sash_command_new(widget, obj, x, y, sash_func); + command_execute(command); + } else { + Command_t *command; + + obj = object_list_find(_shapes, x, y); + if (obj) { + if (event->state & GDK_SHIFT_MASK) { + if (obj->selected) + command = unselect_command_new(obj); + else + command = select_command_new(obj); + } else { /* No Shift key pressed */ + if (obj->selected) { + command = unselect_all_command_new(_shapes, obj); + } else { + Command_t *sub_command; + + command = subcommand_start(NULL); + sub_command = unselect_all_command_new(_shapes, NULL); + command_add_subcommand(command, sub_command); + sub_command = select_command_new(obj); + command_add_subcommand(command, sub_command); + command_set_name(command, sub_command->name); + subcommand_end(); + } + } + command_execute(command); + + command = move_command_new(_preview, obj, x, y); + command_execute(command); + } else { /* Start selection rectangle */ + command = select_region_command_new(widget, _shapes, x, y); + command_execute(command); + } + } +} + +void +edit_shape(gint x, gint y) +{ + Object_t *obj; + + x = GET_REAL_COORD(x); + y = GET_REAL_COORD(y); + + obj = object_list_find(_shapes, x, y); + if (obj) { + object_select(obj); + object_edit(obj, TRUE); + } +} + +void +do_zoom_in(void) +{ + gint factor = zoom_in(); + menu_set_zoom_sensitivity(factor); +} + +void +do_zoom_out(void) +{ + gint factor = zoom_out(); + menu_set_zoom_sensitivity(factor); +} + +void +draw_shapes(cairo_t *cr) +{ + object_list_draw(_shapes, cr); +} + +static void +clear_map_info(void) +{ + const gchar *author = g_get_real_name(); + + if (!*author) + author = g_get_user_name(); + g_strreplace(&_map_info.image_name, _image_name); + g_strreplace(&_map_info.title, "map"); + g_strreplace(&_map_info.author, author); + g_strreplace(&_map_info.default_url, ""); + g_strreplace(&_map_info.description, ""); + + _map_info.map_format = _preferences.default_map_type; + _map_info.show_gray = FALSE; +} + +static void +do_data_changed_dialog(void (*continue_cb)(gpointer), gpointer param) +{ + GtkWidget *dialog = gtk_message_dialog_new + (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("Some data has been changed!")); + gtk_message_dialog_format_secondary_text + (GTK_MESSAGE_DIALOG (dialog), + _("Do you really want to discard your changes?")); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) + continue_cb (param); + + gtk_widget_destroy (dialog); +} + +static void +check_if_changed(void (*func)(gpointer), gpointer param) +{ + if (object_list_get_changed (_shapes)) + do_data_changed_dialog (func, param); + else + func (param); +} + +static void +close_current(void) +{ + selection_freeze(_selection); + object_list_remove_all(_shapes); + selection_thaw(_selection); + clear_map_info(); + main_set_title(NULL); + set_all_sensitivities(); + preview_redraw(); + object_list_clear_changed(_shapes); + command_list_remove_all(); +} + +static void +really_close(gpointer data) +{ + close_current(); +} + +void +do_close(void) +{ + check_if_changed(really_close, NULL); +} + +static void +really_quit(gpointer data) +{ + preferences_save(&_preferences); + run_flag = 1; + gtk_widget_destroy(_dlg); +} + +void +do_quit(void) +{ + check_if_changed(really_quit, NULL); +} + +void +do_undo(void) +{ + selection_freeze(_selection); + last_command_undo(); + selection_thaw(_selection); + preview_redraw(); +} + +void +do_redo(void) +{ + selection_freeze(_selection); + last_command_redo(); + selection_thaw(_selection); + preview_redraw(); +} + +void +save(void) +{ + if (_filename) + save_as(_filename); + else + do_file_save_as_dialog(); +} + +static void +write_cern_comment(gpointer param, OutputFunc_t output) +{ + output(param, "rect (4096,4096) (4096,4096) imap:#$"); +} + +static void +save_as_cern(gpointer param, OutputFunc_t output) +{ + char *p; + gchar *description; + gchar *next_token; + + write_cern_comment(param, output); + output(param, "-:Image map file created by GIMP Image Map plug-in\n"); + write_cern_comment(param, output); + output(param, "-:GIMP Image Map plug-in by Maurits Rijk\n"); + write_cern_comment(param, output); + output(param, "-:Please do not edit lines starting with \"#$\"\n"); + write_cern_comment(param, output); + output(param, "VERSION:2.3\n"); + write_cern_comment(param, output); + output(param, "TITLE:%s\n", _map_info.title); + write_cern_comment(param, output); + output(param, "AUTHOR:%s\n", _map_info.author); + write_cern_comment(param, output); + output(param, "FORMAT:cern\n"); + + description = g_strdup(_map_info.description); + next_token = description; + for (p = strtok (next_token, "\n"); p; p = strtok(NULL, "\n")) { + write_cern_comment(param, output); + output(param, "DESCRIPTION:%s\n", p); + } + g_free(description); + + if (*_map_info.default_url) + output(param, "default %s\n", _map_info.default_url); + object_list_write_cern(_shapes, param, output); +} + +static void +save_as_csim(gpointer param, OutputFunc_t output) +{ + char *p; + gchar *description; + + output(param, "<img src=\"%s\" width=\"%d\" height=\"%d\" border=\"0\" " + "usemap=\"#%s\" />\n\n", _map_info.image_name, + _image_width, _image_height, _map_info.title); + output(param, "<map name=\"%s\">\n", _map_info.title); + output(param, + "<!-- #$-:Image map file created by GIMP Image Map plug-in -->\n"); + output(param, "<!-- #$-:GIMP Image Map plug-in by Maurits Rijk -->\n"); + output(param, + "<!-- #$-:Please do not edit lines starting with \"#$\" -->\n"); + output(param, "<!-- #$VERSION:2.3 -->\n"); + output(param, "<!-- #$AUTHOR:%s -->\n", _map_info.author); + + description = g_strdup(_map_info.description); + for (p = strtok(description, "\n"); p; p = strtok(NULL, "\n")) + output(param, "<!-- #$DESCRIPTION:%s -->\n", p); + g_free(description); + + object_list_write_csim(_shapes, param, output); + if (*_map_info.default_url) + output(param, "<area shape=\"default\" href=\"%s\" />\n", + _map_info.default_url); + output(param, "</map>\n"); +} + +static void +save_as_ncsa(gpointer param, OutputFunc_t output) +{ + char *p; + gchar *description; + + output(param, "#$-:Image map file created by GIMP Image Map plug-in\n"); + output(param, "#$-:GIMP Image Map plug-in by Maurits Rijk\n"); + output(param, "#$-:Please do not edit lines starting with \"#$\"\n"); + output(param, "#$VERSION:2.3\n"); + output(param, "#$TITLE:%s\n", _map_info.title); + output(param, "#$AUTHOR:%s\n", _map_info.author); + output(param, "#$FORMAT:ncsa\n"); + + description = g_strdup(_map_info.description); + for (p = strtok(description, "\n"); p; p = strtok(NULL, "\n")) + output(param, "#$DESCRIPTION:%s\n", p); + g_free(description); + + if (*_map_info.default_url) + output(param, "default %s\n", _map_info.default_url); + object_list_write_ncsa(_shapes, param, output); +} + +static void save_to_file (gpointer param, + const char *format, + ...) G_GNUC_PRINTF(2,3); + +static void +save_to_file(gpointer param, const char* format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf((FILE*)param, format, ap); + va_end(ap); +} + +void +dump_output(gpointer param, OutputFunc_t output) +{ + if (_map_info.map_format == NCSA) + save_as_ncsa(param, output); + else if (_map_info.map_format == CERN) + save_as_cern(param, output); + else if (_map_info.map_format == CSIM) + save_as_csim(param, output); +} + +void +save_as(const gchar *filename) +{ + FILE *out = g_fopen(filename, "w"); + if (out) { + dump_output(out, save_to_file); + fclose(out); + + statusbar_set_status(_statusbar, _("File \"%s\" saved."), filename); + main_set_title(filename); + object_list_clear_changed(_shapes); + } else { + do_file_error_dialog( _("Couldn't save file:"), filename); + } +} + +static void +do_image_size_changed_dialog(void) +{ + GtkWidget *dialog = gtk_message_dialog_new_with_markup + (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s", + _("Image size has changed."), + _("Resize area's?")); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) + { + gint per_x = _image_width * 100 / _map_info.old_image_width; + gint per_y = _image_height * 100 / _map_info.old_image_height; + object_list_resize(_shapes, per_x, per_y); + } + + preview_redraw(); + gtk_widget_destroy (dialog); +} + +static void +really_load(gpointer data) +{ + gchar *filename = (gchar*) data; + close_current(); + + selection_freeze(_selection); + _map_info.old_image_width = _image_width; + _map_info.old_image_height = _image_height; + if (load_csim(filename)) { + _map_info.map_format = CSIM; + if (_image_width != _map_info.old_image_width || + _image_height != _map_info.old_image_height) { + do_image_size_changed_dialog(); + } + } else if (load_ncsa(filename)) { + _map_info.map_format = NCSA; + } else if (load_cern(filename)) { + _map_info.map_format = CERN; + } else { + do_file_error_dialog( _("Couldn't read file:"), filename); + selection_thaw(_selection); + close_current(); + return; + } + mru_set_first(_mru, filename); + menu_build_mru_items(_mru); + + selection_thaw(_selection); + main_set_title(filename); + object_list_clear_changed(_shapes); + preview_redraw(); +} + +void +load(const gchar *filename) +{ + static gchar *tmp_filename; + g_strreplace(&tmp_filename, filename); + check_if_changed(really_load, (gpointer) tmp_filename); +} + +void +toggle_area_list(void) +{ + selection_toggle_visibility(_selection); +} + +static gboolean +close_callback(GtkWidget *widget, gpointer data) +{ + do_quit(); + return TRUE; +} + +static gboolean +preview_move(GtkWidget *widget, GdkEventMotion *event) +{ + gint x = GET_REAL_COORD((gint) event->x); + gint y = GET_REAL_COORD((gint) event->y); + static Object_t *prev_obj = NULL; + Object_t *obj = object_list_find(_shapes, x, y); + + statusbar_set_xy(_statusbar, x, y); + if (obj != prev_obj) { + prev_obj = obj; + if (obj && _show_url) { + statusbar_set_status(_statusbar, _("URL: %s"), obj->url); + } else { + statusbar_clear_status(_statusbar); + } + } +#ifdef _NOT_READY_YET_ + if (!obj) { + if (grid_near_x(x)) { + preview_set_cursor(_preview, GDK_SB_H_DOUBLE_ARROW); + } else if (grid_near_y(y)) { + preview_set_cursor(_preview, GDK_SB_V_DOUBLE_ARROW); + } else { + preview_set_cursor(_preview, _cursor); + } + } +#endif + return FALSE; +} + +static void +preview_enter(GtkWidget *widget, GdkEventCrossing *event) +{ + preview_set_cursor(_preview, _cursor); +} + +static void +preview_leave(GtkWidget *widget, GdkEventCrossing *event) +{ + gdk_window_set_cursor(gtk_widget_get_window (_dlg), NULL); + statusbar_clear_xy(_statusbar); +} + +static gboolean +button_press(GtkWidget* widget, GdkEventButton* event, gpointer data) +{ + if (_button_press_func) + return _button_press_func(widget, event, _button_press_param); + + return FALSE; +} + +/* A few global vars for key movement */ + +static guint _timeout; +static guint _keyval; +static gint _dx, _dy; + +static void +move_sash_selected_objects(gint dx, gint dy, gboolean fast) +{ + if (fast) { + dx *= 5; + dy *= 5; + } + + object_list_move_sash_selected(_shapes, dx, dy); + + preview_redraw (); +} + +static void +move_selected_objects(gint dx, gint dy, gboolean fast) +{ + if (fast) { + dx *= 5; + dy *= 5; + } + _dx += dx; + _dy += dy; + + object_list_move_selected(_shapes, dx, dy); + + preview_redraw (); +} + +static gboolean +key_timeout_cb(gpointer data) +{ + switch (_keyval) { + case GDK_KEY_Left: + case GDK_KEY_Right: + case GDK_KEY_Up: + case GDK_KEY_Down: + command_list_add(move_selected_command_new(_shapes, _dx, _dy)); + _dx = _dy = 0; + break; + } + preview_redraw(); + + _timeout = 0; + return FALSE; +} + +static gboolean +key_press_cb(GtkWidget *widget, GdkEventKey *event) +{ + gboolean handled = FALSE; + gboolean shift = event->state & GDK_SHIFT_MASK; + gboolean ctrl = event->state & GDK_CONTROL_MASK; + Command_t *command; + + if (_timeout) + g_source_remove(_timeout); + _timeout = 0; + + switch (event->keyval) { + case GDK_KEY_Left: + if (ctrl) + move_sash_selected_objects(-1, 0, shift); + else + move_selected_objects(-1, 0, shift); + handled = TRUE; + break; + case GDK_KEY_Right: + if (ctrl) + move_sash_selected_objects(1, 0, shift); + else + move_selected_objects(1, 0, shift); + handled = TRUE; + break; + case GDK_KEY_Up: + if (ctrl) + move_sash_selected_objects(0, -1, shift); + else + move_selected_objects(0, -1, shift); + handled = TRUE; + break; + case GDK_KEY_Down: + if (ctrl) + move_sash_selected_objects(0, 1, shift); + else + move_selected_objects(0, 1, shift); + handled = TRUE; + break; + case GDK_KEY_Tab: + if (shift) + command = select_prev_command_new(_shapes); + else + command = select_next_command_new(_shapes); + command_execute(command); + handled = TRUE; + break; + } + if (handled) + g_signal_stop_emission_by_name(widget, "key-press-event"); + + return handled; +} + +static gboolean +key_release_cb(GtkWidget *widget, GdkEventKey *event) +{ + _keyval = event->keyval; + _timeout = g_timeout_add(250, key_timeout_cb, NULL); + return FALSE; +} + +static void +geometry_changed(Object_t *obj, gpointer data) +{ + preview_redraw(); +} + +static void +data_changed(Object_t *obj, gpointer data) +{ + preview_redraw(); + set_all_sensitivities(); +} + +static void +data_selected(Object_t *obj, gpointer data) +{ + set_all_sensitivities(); +} + +void +imap_help (void) +{ + gimp_standard_help_func ("plug-in-imagemap", NULL); +} + +void +do_cut (void) +{ + command_execute (cut_command_new (_shapes)); +} + +void +do_copy (void) +{ + command_execute (copy_command_new (_shapes)); +} + +void +do_paste (void) +{ + command_execute (paste_command_new (_shapes)); +} + +void +do_select_all(void) +{ + command_execute (select_all_command_new (_shapes)); +} + +void +do_deselect_all(void) +{ + command_execute (unselect_all_command_new (_shapes, NULL)); +} + +void +do_clear(void) +{ + command_execute (clear_command_new(_shapes)); +} + +void +do_move_up(void) +{ + /* Fix me! + Command_t *command = object_up_command_new(_current_obj->list, + _current_obj); + command_execute(command); + */ +} + +void +do_move_down(void) +{ + /* Fix me! + Command_t *command = object_down_command_new(_current_obj->list, + _current_obj); + command_execute(command); + */ +} + +void +do_move_to_front(void) +{ + command_execute(move_to_front_command_new(_shapes)); +} + +void +do_send_to_back(void) +{ + command_execute(send_to_back_command_new(_shapes)); +} + +void +do_use_gimp_guides_dialog(void) +{ + command_execute (gimp_guides_command_new (_shapes, _drawable_id)); +} + +void +do_create_guides_dialog(void) +{ + command_execute (guides_command_new (_shapes)); +} + +static Command_t* +factory_move_up(void) +{ + return move_up_command_new(_shapes); +} + +static Command_t* +factory_move_down(void) +{ + return move_down_command_new(_shapes); +} + +static gint +dialog(gint32 drawable_id) +{ + GtkWidget *dlg; + GtkWidget *hbox; + GtkWidget *main_vbox; + GtkWidget *tools; + + gimp_ui_init (PLUG_IN_BINARY, TRUE); + + set_arrow_func (); + + _shapes = make_object_list(); + + _dlg = dlg = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE); + + main_set_title(NULL); + gimp_help_connect (dlg, gimp_standard_help_func, PLUG_IN_PROC, NULL); + + gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE); + + gimp_window_set_transient (GTK_WINDOW (dlg)); + + g_signal_connect (dlg, "delete-event", + G_CALLBACK (close_callback), NULL); + g_signal_connect (dlg, "key-press-event", + G_CALLBACK (key_press_cb), NULL); + g_signal_connect (dlg, "key-release-event", + G_CALLBACK (key_release_cb), NULL); + + g_signal_connect (dlg, "destroy", + G_CALLBACK (gtk_main_quit), + NULL); + + main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add (GTK_CONTAINER (dlg), main_vbox); + gtk_widget_show (main_vbox); + + init_stock_icons(); + + /* Create menu */ + make_menu(main_vbox, dlg); + + /* Create toolbar */ + make_toolbar(main_vbox, dlg); + + /* Dialog area */ + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); + gtk_box_pack_start (GTK_BOX (main_vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show(hbox); + + tools = make_tools(dlg); + /* selection_set_edit_command(tools, factory_edit); */ + gtk_box_pack_start(GTK_BOX(hbox), tools, FALSE, FALSE, 0); + + _preview = make_preview(drawable_id); + + g_signal_connect(_preview->preview, "motion-notify-event", + G_CALLBACK(preview_move), NULL); + g_signal_connect(_preview->preview, "enter-notify-event", + G_CALLBACK(preview_enter), NULL); + g_signal_connect(_preview->preview, "leave-notify-event", + G_CALLBACK(preview_leave), NULL); + g_signal_connect(_preview->preview, "button-press-event", + G_CALLBACK(button_press), NULL); + gtk_box_pack_start (GTK_BOX (hbox), _preview->window, TRUE, TRUE, 0); + + object_list_add_geometry_cb(_shapes, geometry_changed, NULL); + object_list_add_update_cb(_shapes, data_changed, NULL); + object_list_add_add_cb(_shapes, data_changed, NULL); + object_list_add_remove_cb(_shapes, data_changed, NULL); + object_list_add_move_cb(_shapes, data_changed, NULL); + object_list_add_select_cb(_shapes, data_selected, NULL); + + /* Selection */ + _selection = make_selection(_shapes); + selection_set_move_up_command(_selection, factory_move_up); + selection_set_move_down_command(_selection, factory_move_down); + gtk_box_pack_start(GTK_BOX(hbox), _selection->container, FALSE, FALSE, 0); + + _statusbar = make_statusbar(main_vbox, dlg); + statusbar_set_zoom(_statusbar, 1); + + gtk_widget_show(dlg); + + _mru = mru_create(); + init_preferences(); + + clear_map_info(); + + if (!mru_empty(_mru)) + menu_build_mru_items(_mru); + + gtk_main(); + + return run_flag; +} diff --git a/plug-ins/imagemap/imap_main.h b/plug-ins/imagemap/imap_main.h new file mode 100644 index 0000000..b22327d --- /dev/null +++ b/plug-ins/imagemap/imap_main.h @@ -0,0 +1,125 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_MAIN_H +#define _IMAP_MAIN_H + +#include "imap_mru.h" +#include "imap_object.h" +#include "imap_preferences.h" +#include "imap_preview.h" + +#define PLUG_IN_PROC "plug-in-imagemap" +#define PLUG_IN_BINARY "imagemap" +#define PLUG_IN_ROLE "gimp-imagemap" + +typedef enum {NCSA, CERN, CSIM} MapFormat_t; + +typedef struct { + MapFormat_t map_format; + gchar *image_name; + gchar *title; + gchar *author; + gchar *default_url; + gchar *description; + gint old_image_width; + gint old_image_height; + gboolean color; /* Color (TRUE) or Gray (FALSE) */ + gboolean show_gray; +} MapInfo_t; + +void main_set_dimension(gint width, gint height); +void main_clear_dimension(void); +void load(const gchar *filename); +void save_as(const gchar *filename); +void dump_output(gpointer param, OutputFunc_t output); +GtkWidget *get_dialog(void); +MRU_t *get_mru(void); +MapInfo_t *get_map_info(void); +PreferencesData_t *get_preferences(void); + +gint get_image_width(void); +gint get_image_height(void); + +void set_busy_cursor(void); +void remove_busy_cursor(void); + +void main_toolbar_set_grid(gboolean active); + +void set_zoom(gint zoom_factor); +gint get_real_coord(gint coord); +void draw_line(cairo_t *cr, gint x1, gint y1, gint x2, + gint y2); +void draw_rectangle(cairo_t *cr, gboolean filled, gint x, gint y, + gint width, gint height); +void draw_circle(cairo_t *cr, gint x, gint y, + gint r); +void draw_polygon(cairo_t *cr, GList *list); + +const char *get_filename(void); + +ObjectList_t *get_shapes(void); +void add_shape(Object_t *obj); +void update_shape(Object_t *obj); +void select_shape(GtkWidget *widget, GdkEventButton *event); +void edit_shape(gint x, gint y); + +void do_popup_menu(GdkEventButton *event); +void draw_shapes(cairo_t *cr); + +void show_url(void); +void hide_url(void); + +void set_preview_color (GtkRadioAction *action, + GtkRadioAction *current, + gpointer user_data); +void set_zoom_factor (GtkRadioAction *action, + GtkRadioAction *current, + gpointer user_data); +void set_func (GtkRadioAction *action, + GtkRadioAction *current, + gpointer user_data); +void do_edit_selected_shape (void); +void do_zoom_in (void); +void do_zoom_out (void); +void do_close (void); +void do_quit (void); +void do_undo (void); +void do_redo (void); +void do_cut (void); +void do_copy (void); +void do_paste (void); +void do_select_all (void); +void do_deselect_all (void); +void do_clear (void); +void do_move_up (void); +void do_move_down (void); +void do_move_to_front (void); +void do_send_to_back (void); +void do_use_gimp_guides_dialog (void); +void do_create_guides_dialog (void); +void save (void); +void imap_help (void); +void toggle_area_list (void); +const gchar * get_image_name (void); + +#endif /* _IMAP_MAIN_H */ diff --git a/plug-ins/imagemap/imap_menu.c b/plug-ins/imagemap/imap_menu.c new file mode 100644 index 0000000..8e1d0d1 --- /dev/null +++ b/plug-ins/imagemap/imap_menu.c @@ -0,0 +1,551 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2006 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_about.h" +#include "imap_circle.h" +#include "imap_file.h" +#include "imap_grid.h" +#include "imap_main.h" +#include "imap_menu.h" +#include "imap_menu_funcs.h" +#include "imap_polygon.h" +#include "imap_preferences.h" +#include "imap_rectangle.h" +#include "imap_settings.h" +#include "imap_stock.h" +#include "imap_source.h" + +#include "libgimp/stdplugins-intl.h" + +static Menu_t _menu; +static GtkUIManager *ui_manager; + +GtkWidget* +menu_get_widget(const gchar *path) +{ + return gtk_ui_manager_get_widget (ui_manager, path); +} + +static void +set_sensitive (const gchar *path, gboolean sensitive) +{ + GtkAction *action = gtk_ui_manager_get_action (ui_manager, path); + g_object_set (action, "sensitive", sensitive, NULL); +} + +static void +menu_mru(GtkWidget *widget, gpointer data) +{ + MRU_t *mru = get_mru(); + char *filename = (char*) data; + + if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { + load(filename); + } else { + do_file_error_dialog(_("Error opening file"), filename); + mru_remove(mru, filename); + menu_build_mru_items(mru); + } +} + +void +menu_set_zoom_sensitivity(gint factor) +{ + set_sensitive ("/MainMenu/ViewMenu/ZoomIn", factor < 8); + set_sensitive ("/MainMenu/ViewMenu/ZoomOut", factor > 1); +} + +void +menu_set_zoom(gint factor) +{ + menu_set_zoom_sensitivity (factor); +} + +void +menu_shapes_selected(gint count) +{ + gboolean sensitive = (count > 0); + + set_sensitive ("/MainMenu/EditMenu/Cut", sensitive); + set_sensitive ("/MainMenu/EditMenu/Copy", sensitive); + set_sensitive ("/MainMenu/EditMenu/Clear", sensitive); + set_sensitive ("/MainMenu/EditMenu/EditAreaInfo", sensitive); + set_sensitive ("/MainMenu/EditMenu/DeselectAll", sensitive); +} + +static void +command_list_changed(Command_t *command, gpointer data) +{ + GtkAction *action; + gchar *label; + + action = gtk_ui_manager_get_action (ui_manager, "/MainMenu/EditMenu/Undo"); + + label = g_strdup_printf (_("_Undo %s"), + command && command->name ? command->name : ""); + + g_object_set (action, + "label", label, + "sensitive", command != NULL, + NULL); + g_free (label); + + command = command_list_get_redo_command(); + + action = gtk_ui_manager_get_action (ui_manager, "/MainMenu/EditMenu/Redo"); + + label = g_strdup_printf (_("_Redo %s"), + command && command->name ? command->name : ""); + g_object_set (action, + "label", label, + "sensitive", command != NULL, + NULL); + g_free (label); +} + +static void +paste_buffer_added(Object_t *obj, gpointer data) +{ + set_sensitive("/MainMenu/EditMenu/Paste", TRUE); +} + +static void +paste_buffer_removed(Object_t *obj, gpointer data) +{ + set_sensitive("/MainMenu/EditMenu/Paste", FALSE); +} + +/* Normal items */ +static const GtkActionEntry entries[] = +{ + { "FileMenu", NULL, + N_("_File") }, + { "Open", GIMP_ICON_DOCUMENT_OPEN, + N_("_Open..."), NULL, N_("Open"), + do_file_open_dialog}, + { "Save", GIMP_ICON_DOCUMENT_SAVE, + N_("_Save..."), NULL, N_("Save"), + save}, + { "SaveAs", GIMP_ICON_DOCUMENT_SAVE_AS, + N_("Save _As..."), "<shift><control>S", NULL, + do_file_save_as_dialog}, + { "Close", GIMP_ICON_CLOSE, N_("_Close"), "<primary>w", NULL, do_close}, + { "Quit", GIMP_ICON_APPLICATION_EXIT, + N_("_Quit"), "<primary>q", NULL, do_quit}, + + { "EditMenu", NULL, N_("_Edit") }, + { "Undo", GIMP_ICON_EDIT_UNDO, + N_("_Undo"), NULL, N_("Undo"), do_undo}, + { "Redo", GIMP_ICON_EDIT_REDO, + N_("_Redo"), NULL, N_("Redo"), do_redo}, + { "Cut", GIMP_ICON_EDIT_CUT, + N_("Cu_t"), "<primary>x", N_("Cut"), do_cut}, + { "Copy", GIMP_ICON_EDIT_COPY, + N_("_Copy"), "<primary>c", N_("Copy"), do_copy}, + { "Paste", GIMP_ICON_EDIT_PASTE, + N_("_Paste"), "<primary>v", N_("Paste"), do_paste}, + { "Clear", GIMP_ICON_EDIT_DELETE, + N_("_Delete"), NULL, N_("Delete"), do_clear}, + { "SelectAll", NULL, + N_("Select _All"), "<primary>A", NULL, do_select_all}, + { "DeselectAll", NULL, + N_("D_eselect All"), "<shift><primary>A", NULL, + do_deselect_all}, + { "EditAreaInfo", GIMP_ICON_EDIT + , N_("Edit Area _Info..."), NULL, + N_("Edit selected area info"), do_edit_selected_shape}, + { "Preferences", GIMP_ICON_PREFERENCES_SYSTEM, + N_("_Preferences"), NULL, N_("Preferences"), + do_preferences_dialog}, + { "MoveToFront", IMAP_STOCK_TO_FRONT, "", NULL, N_("Move Area to Front"), + do_move_to_front}, + { "SendToBack", IMAP_STOCK_TO_BACK, "", NULL, N_("Move Area to Bottom"), + do_send_to_back}, + { "DeleteArea", NULL, N_("Delete Area"), NULL, NULL, NULL}, + { "MoveUp", GIMP_ICON_GO_UP, N_("Move Up"), NULL, NULL, NULL}, + { "MoveDown", GIMP_ICON_GO_DOWN, N_("Move Down"), NULL, NULL, NULL}, + + { "InsertPoint", NULL, N_("Insert Point"), NULL, NULL, polygon_insert_point}, + { "DeletePoint", NULL, N_("Delete Point"), NULL, NULL, polygon_delete_point}, + + { "ViewMenu", NULL, N_("_View") }, + { "Source", NULL, N_("Source..."), NULL, NULL, do_source_dialog}, + { "ZoomIn", GIMP_ICON_ZOOM_IN, N_("Zoom _In"), "plus", N_("Zoom in"), do_zoom_in}, + { "ZoomOut", GIMP_ICON_ZOOM_OUT, N_("Zoom _Out"), "minus", N_("Zoom out"), do_zoom_out}, + { "ZoomToMenu", NULL, N_("_Zoom To") }, + + { "MappingMenu", NULL, N_("_Mapping") }, + { "EditMapInfo", GIMP_ICON_DIALOG_INFORMATION, N_("Edit Map Info..."), NULL, + N_("Edit Map Info"), do_settings_dialog}, + + { "ToolsMenu", NULL, N_("_Tools") }, + { "GridSettings", NULL, N_("Grid Settings..."), NULL, NULL, + do_grid_settings_dialog}, + { "UseGimpGuides", NULL, N_("Use GIMP Guides..."), NULL, NULL, + do_use_gimp_guides_dialog}, + { "CreateGuides", NULL, N_("Create Guides..."), NULL, NULL, + do_create_guides_dialog}, + + { "HelpMenu", NULL, N_("_Help") }, + { "Contents", GIMP_ICON_HELP, N_("_Contents"), NULL, NULL, imap_help}, + { "About", GIMP_ICON_HELP_ABOUT, N_("_About"), NULL, NULL, do_about_dialog}, + + { "ZoomMenu", NULL, N_("_Zoom") }, +}; + +/* Toggle items */ +static const GtkToggleActionEntry toggle_entries[] = { + { "AreaList", NULL, N_("Area List"), NULL, NULL, NULL, TRUE }, + { "Grid", GIMP_ICON_GRID, N_("_Grid"), NULL, N_("Grid"), toggle_grid, FALSE } +}; + +static const GtkRadioActionEntry color_entries[] = { + { "Color", NULL, N_("Color"), NULL, NULL, 0}, + { "Gray", NULL, N_("Gray"), NULL, NULL, 1}, +}; + +static const GtkRadioActionEntry mapping_entries[] = { + { "Arrow", GIMP_ICON_CURSOR, N_("Arrow"), NULL, + N_("Select existing area"), 0}, + { "Rectangle", IMAP_STOCK_RECTANGLE, N_("Rectangle"), NULL, + N_("Define Rectangle area"), 1}, + { "Circle", IMAP_STOCK_CIRCLE, N_("Circle"), NULL, + N_("Define Circle/Oval area"), 2}, + { "Polygon", IMAP_STOCK_POLYGON, N_("Polygon"), NULL, + N_("Define Polygon area"), 3}, +}; + +static const GtkRadioActionEntry zoom_entries[] = { + { "Zoom1:1", NULL, "1:1", NULL, NULL, 0}, + { "Zoom1:2", NULL, "1:2", NULL, NULL, 1}, + { "Zoom1:3", NULL, "1:3", NULL, NULL, 2}, + { "Zoom1:4", NULL, "1:4", NULL, NULL, 3}, + { "Zoom1:5", NULL, "1:5", NULL, NULL, 4}, + { "Zoom1:6", NULL, "1:6", NULL, NULL, 5}, + { "Zoom1:7", NULL, "1:7", NULL, NULL, 6}, + { "Zoom1:8", NULL, "1:8", NULL, NULL, 7}, +}; + +static const gchar ui_description[] = +"<ui>" +" <menubar name='MainMenu'>" +" <menu action='FileMenu'>" +" <menuitem action='Open'/>" +" <menuitem action='Save'/>" +" <menuitem action='SaveAs'/>" +" <separator/>" +" <menuitem action='Close'/>" +" <menuitem action='Quit'/>" +" </menu>" +" <menu action='EditMenu'>" +" <menuitem action='Undo'/>" +" <menuitem action='Redo'/>" +" <menuitem action='Cut'/>" +" <menuitem action='Copy'/>" +" <menuitem action='Paste'/>" +" <menuitem action='Clear'/>" +" <separator/>" +" <menuitem action='SelectAll'/>" +" <menuitem action='DeselectAll'/>" +" <separator/>" +" <menuitem action='EditAreaInfo'/>" +" <separator/>" +" <menuitem action='Preferences'/>" +" </menu>" +" <menu action='ViewMenu'>" +" <menuitem action='AreaList'/>" +" <menuitem action='Source'/>" +" <separator/>" +" <menuitem action='Color'/>" +" <menuitem action='Gray'/>" +" <separator/>" +" <menuitem action='ZoomIn'/>" +" <menuitem action='ZoomOut'/>" +" <menu action='ZoomToMenu'>" +" <menuitem action='Zoom1:1'/>" +" <menuitem action='Zoom1:2'/>" +" <menuitem action='Zoom1:3'/>" +" <menuitem action='Zoom1:4'/>" +" <menuitem action='Zoom1:5'/>" +" <menuitem action='Zoom1:6'/>" +" <menuitem action='Zoom1:7'/>" +" <menuitem action='Zoom1:8'/>" +" </menu>" +" </menu>" +" <menu action='MappingMenu'>" +" <menuitem action='Arrow'/>" +" <menuitem action='Rectangle'/>" +" <menuitem action='Circle'/>" +" <menuitem action='Polygon'/>" +" <separator/>" +" <menuitem action='EditMapInfo'/>" +" </menu>" +" <menu action='ToolsMenu'>" +" <menuitem action='Grid'/>" +" <menuitem action='GridSettings'/>" +" <separator/>" +" <menuitem action='UseGimpGuides'/>" +" <menuitem action='CreateGuides'/>" +" </menu>" +" <menu action='HelpMenu'>" +" <menuitem action='Contents'/>" +" <menuitem action='About'/>" +" </menu>" +" </menubar>" +"" +" <popup name='PopupMenu'>" +" <menuitem action='EditMapInfo'/>" +" <menu action='ToolsMenu'>" +" <menuitem action='Arrow'/>" +" <menuitem action='Rectangle'/>" +" <menuitem action='Circle'/>" +" <menuitem action='Polygon'/>" +" </menu>" +" <menu action='ZoomMenu'>" +" <menuitem action='ZoomIn'/>" +" <menuitem action='ZoomOut'/>" +" </menu>" +" <menuitem action='Grid'/>" +" <menuitem action='GridSettings'/>" +" <menuitem action='CreateGuides'/>" +" <menuitem action='Paste'/>" +" </popup>" +"" +" <popup name='ObjectPopupMenu'>" +" <menuitem action='EditAreaInfo'/>" +" <menuitem action='DeleteArea'/>" +" <menuitem action='MoveUp'/>" +" <menuitem action='MoveDown'/>" +" <menuitem action='Cut'/>" +" <menuitem action='Copy'/>" +" </popup>" +"" +" <popup name='PolygonPopupMenu'>" +" <menuitem action='InsertPoint'/>" +" <menuitem action='DeletePoint'/>" +" <menuitem action='EditAreaInfo'/>" +" <menuitem action='DeleteArea'/>" +" <menuitem action='MoveUp'/>" +" <menuitem action='MoveDown'/>" +" <menuitem action='Cut'/>" +" <menuitem action='Copy'/>" +" </popup>" +"" +" <toolbar name='Toolbar'>" +" <toolitem action='Open'/>" +" <toolitem action='Save'/>" +" <separator/>" +" <toolitem action='Preferences'/>" +" <separator/>" +" <toolitem action='Undo'/>" +" <toolitem action='Redo'/>" +" <separator/>" +" <toolitem action='Cut'/>" +" <toolitem action='Copy'/>" +" <toolitem action='Paste'/>" +" <separator/>" +" <toolitem action='ZoomIn'/>" +" <toolitem action='ZoomOut'/>" +" <separator/>" +" <toolitem action='EditMapInfo'/>" +" <separator/>" +" <toolitem action='MoveToFront'/>" +" <toolitem action='SendToBack'/>" +" <separator/>" +" <toolitem action='Grid'/>" +" </toolbar>" +"" +" <toolbar name='Tools'>" +" <toolitem action='Arrow'/>" +" <toolitem action='Rectangle'/>" +" <toolitem action='Circle'/>" +" <toolitem action='Polygon'/>" +" <separator/>" +" <toolitem action='EditAreaInfo'/>" +" </toolbar>" +"" +" <toolbar name='Selection'>" +" <toolitem action='MoveUp'/>" +" <toolitem action='MoveDown'/>" +" <toolitem action='EditAreaInfo'/>" +" <toolitem action='Clear'/>" +" </toolbar>" +"</ui>"; + +Menu_t* +make_menu(GtkWidget *main_vbox, GtkWidget *window) +{ + GtkWidget *menubar; + GtkActionGroup *action_group; + GtkAccelGroup *accel_group; + GError *error; + + action_group = gtk_action_group_new ("MenuActions"); + gtk_action_group_set_translation_domain (action_group, NULL); + + gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries), + window); + gtk_action_group_add_toggle_actions (action_group, toggle_entries, + G_N_ELEMENTS (toggle_entries), window); + + gtk_action_group_add_radio_actions (action_group, color_entries, + G_N_ELEMENTS (color_entries), 0, + G_CALLBACK (set_preview_color), NULL); + gtk_action_group_add_radio_actions (action_group, zoom_entries, + G_N_ELEMENTS (zoom_entries), 0, + G_CALLBACK (set_zoom_factor), NULL); + gtk_action_group_add_radio_actions (action_group, mapping_entries, + G_N_ELEMENTS (mapping_entries), 0, + G_CALLBACK (set_func), window); + + ui_manager = gtk_ui_manager_new (); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + + accel_group = gtk_ui_manager_get_accel_group (ui_manager); + gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); + + error = NULL; + if (!gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, + &error)) + { + g_warning ("building menus failed: %s", error->message); + g_error_free (error); + /* exit (EXIT_FAILURE); */ + } + + menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu"); + gtk_widget_show (menubar); + gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0); + + paste_buffer_add_add_cb(paste_buffer_added, NULL); + paste_buffer_add_remove_cb(paste_buffer_removed, NULL); + + set_sensitive ("/MainMenu/EditMenu/Paste", FALSE); + menu_shapes_selected (0); + + menu_set_zoom_sensitivity (1); + + command_list_add_update_cb (command_list_changed, NULL); + + command_list_changed (NULL, NULL); + + return &_menu; +} + +void +menu_build_mru_items(MRU_t *mru) +{ + GList *p; + gint position = 0; + int i; + + return; + + if (_menu.nr_off_mru_items) { + GList *children; + + children = gtk_container_get_children(GTK_CONTAINER(_menu.open_recent)); + p = g_list_nth(children, position); + for (i = 0; i < _menu.nr_off_mru_items; i++, p = p->next) { + gtk_widget_destroy((GtkWidget*) p->data); + } + g_list_free(children); + } + + i = 0; + for (p = mru->list; p; p = p->next, i++) { + GtkWidget *item = insert_item_with_label(_menu.open_recent, position++, + (gchar*) p->data, + menu_mru, p->data); + if (i < 9) { + guchar accelerator_key = '1' + i; + add_accelerator(item, accelerator_key, GDK_CONTROL_MASK); + } + } + _menu.nr_off_mru_items = i; +} + +void +do_main_popup_menu(GdkEventButton *event) +{ + GtkWidget *popup = gtk_ui_manager_get_widget (ui_manager, "/PopupMenu"); + gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, + event->button, event->time); +} + +void +menu_check_grid(gboolean check) +{ + GtkAction *action = gtk_ui_manager_get_action (ui_manager, + "/MainMenu/ToolsMenu/Grid"); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), check); +} + +GtkWidget* +make_toolbar(GtkWidget *main_vbox, GtkWidget *window) +{ + GtkWidget *toolbar; + + toolbar = gtk_ui_manager_get_widget (ui_manager, "/Toolbar"); + gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); + gtk_container_set_border_width (GTK_CONTAINER (toolbar), 0); + gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0); + gtk_widget_show (toolbar); + + return toolbar; +} + +GtkWidget* +make_tools(GtkWidget *window) +{ + GtkWidget *toolbar; + + toolbar = gtk_ui_manager_get_widget (ui_manager, "/Tools"); + gtk_orientable_set_orientation (GTK_ORIENTABLE (toolbar), + GTK_ORIENTATION_VERTICAL); + gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); + gtk_container_set_border_width (GTK_CONTAINER (toolbar), 0); + gtk_widget_show (toolbar); + + return toolbar; +} + +GtkWidget* +make_selection_toolbar(void) +{ + GtkWidget *toolbar; + + toolbar = gtk_ui_manager_get_widget (ui_manager, "/Selection"); + + gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); + gtk_orientable_set_orientation (GTK_ORIENTABLE (toolbar), + GTK_ORIENTATION_VERTICAL); + gtk_container_set_border_width (GTK_CONTAINER (toolbar), 0); + + gtk_widget_show (toolbar); + return toolbar; +} diff --git a/plug-ins/imagemap/imap_menu.h b/plug-ins/imagemap/imap_menu.h new file mode 100644 index 0000000..e34743f --- /dev/null +++ b/plug-ins/imagemap/imap_menu.h @@ -0,0 +1,65 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_MENU_H +#define _IMAP_MENU_H + +#include "imap_command.h" +#include "imap_mru.h" + +typedef struct { + GtkWidget *file_menu; + GtkWidget *edit_menu; + GtkWidget *open_recent; + GtkWidget *undo; + GtkWidget *redo; + GtkWidget *arrow; + GtkWidget *fuzzy_select; + GtkWidget *rectangle; + GtkWidget *circle; + GtkWidget *polygon; + GtkWidget *grid; + GtkWidget *gray; + GtkWidget *color; + GtkWidget *zoom[8]; + GtkWidget *zoom_in; + GtkWidget *zoom_out; + + gint nr_off_mru_items; +} Menu_t; + +GtkWidget *menu_get_widget(const gchar *path); +Menu_t *make_menu(GtkWidget *main_vbox, GtkWidget *window); +void menu_build_mru_items(MRU_t *mru); +void menu_set_zoom_sensitivity(gint factor); + +void menu_set_zoom(gint factor); +void menu_check_grid(gboolean check); +void menu_shapes_selected(gint count); + +void do_main_popup_menu(GdkEventButton *event); + +GtkWidget *make_toolbar(GtkWidget *main_vbox, GtkWidget *window); +GtkWidget *make_tools(GtkWidget *window); +GtkWidget *make_selection_toolbar(void); + +#endif /* _IMAP_MENU_H */ diff --git a/plug-ins/imagemap/imap_menu_funcs.c b/plug-ins/imagemap/imap_menu_funcs.c new file mode 100644 index 0000000..264a6cb --- /dev/null +++ b/plug-ins/imagemap/imap_menu_funcs.c @@ -0,0 +1,58 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_command.h" +#include "imap_menu_funcs.h" + +static GtkAccelGroup *accelerator_group; + +void +init_accel_group(GtkWidget *window) +{ + accelerator_group = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(window), accelerator_group); +} + +void +add_accelerator(GtkWidget *widget, guint accelerator_key, + guint8 accelerator_mods) +{ + gtk_widget_add_accelerator(widget, "activate", accelerator_group, + accelerator_key, accelerator_mods, + GTK_ACCEL_VISIBLE); +} + +GtkWidget* +insert_item_with_label(GtkWidget *parent, gint position, gchar *label, + MenuCallback activate, gpointer data) +{ + GtkWidget *item = gtk_image_menu_item_new_with_mnemonic(label); + gtk_menu_shell_insert(GTK_MENU_SHELL(parent), item, position); + g_signal_connect(item, "activate", G_CALLBACK(activate), data); + gtk_widget_show(item); + + return item; +} diff --git a/plug-ins/imagemap/imap_menu_funcs.h b/plug-ins/imagemap/imap_menu_funcs.h new file mode 100644 index 0000000..8c2b86f --- /dev/null +++ b/plug-ins/imagemap/imap_menu_funcs.h @@ -0,0 +1,39 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_MENU_FUNCS_H +#define _IMAP_MENU_FUNCS_H + +typedef void (*MenuCallback)(GtkWidget *widget, gpointer data); + +void init_accel_group(GtkWidget *window); +GtkWidget *insert_item_with_label(GtkWidget *parent, gint position, + gchar *label, MenuCallback activate, + gpointer data); + +void menu_command(GtkWidget *widget, gpointer data); + +void add_accelerator(GtkWidget *widget, guint accelerator_key, + guint8 accelerator_mods); + + +#endif /* _IMAP_MENU_FUNCS_H */ diff --git a/plug-ins/imagemap/imap_misc.c b/plug-ins/imagemap/imap_misc.c new file mode 100644 index 0000000..4a6b760 --- /dev/null +++ b/plug-ins/imagemap/imap_misc.c @@ -0,0 +1,52 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_main.h" +#include "imap_misc.h" + +#define SASH_SIZE 8 + +static gint _sash_size = SASH_SIZE; + +void +set_sash_size(gboolean double_size) +{ + _sash_size = (double_size) ? 2 * SASH_SIZE : SASH_SIZE; +} + +void +draw_sash(cairo_t *cr, gint x, gint y) +{ + draw_rectangle(cr, TRUE, x - _sash_size / 2, y - _sash_size / 2, + _sash_size, _sash_size); +} + +gboolean +near_sash(gint sash_x, gint sash_y, gint x, gint y) +{ + return x >= sash_x - _sash_size / 2 && x <= sash_x + _sash_size / 2 && + y >= sash_y - _sash_size / 2 && y <= sash_y + _sash_size / 2; +} diff --git a/plug-ins/imagemap/imap_misc.h b/plug-ins/imagemap/imap_misc.h new file mode 100644 index 0000000..f8a047d --- /dev/null +++ b/plug-ins/imagemap/imap_misc.h @@ -0,0 +1,31 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_MISC_H +#define _IMAP_MISC_H + +void set_sash_size(gboolean double_size); +void draw_sash(cairo_t *cr, gint x, gint y); +gboolean near_sash(gint sash_x, gint sash_y, gint x, gint y); + +#endif /* _IMAP_MISC_H */ + diff --git a/plug-ins/imagemap/imap_mru.c b/plug-ins/imagemap/imap_mru.c new file mode 100644 index 0000000..1afb0a5 --- /dev/null +++ b/plug-ins/imagemap/imap_mru.c @@ -0,0 +1,105 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <string.h> + +#include <gtk/gtk.h> + +#include "imap_mru.h" + +MRU_t* +mru_create(void) +{ + MRU_t *mru = g_new(MRU_t, 1); + mru->list = NULL; + mru->max_size = DEFAULT_MRU_SIZE; + return mru; +} + +void +mru_destruct (MRU_t *mru) +{ + g_list_free_full (mru->list, (GDestroyNotify) g_free); + g_free (mru); +} + +static void +mru_remove_link(MRU_t *mru, GList *link) +{ + if (link) + { + g_free(link->data); + mru->list = g_list_remove_link(mru->list, link); + } +} + +static GList* +mru_find_link(MRU_t *mru, const gchar *filename) +{ + return g_list_find_custom(mru->list, (gpointer) filename, + (GCompareFunc) strcmp); +} + +void +mru_add(MRU_t *mru, const gchar *filename) +{ + if (g_list_length(mru->list) == mru->max_size) + mru_remove_link(mru, g_list_last(mru->list)); + mru->list = g_list_prepend(mru->list, g_strdup(filename)); +} + +void +mru_remove(MRU_t *mru, const gchar *filename) +{ + mru_remove_link(mru, mru_find_link(mru, filename)); +} + +void +mru_set_first(MRU_t *mru, const gchar *filename) +{ + GList *link = mru_find_link(mru, filename); + if (link) + mru->list = g_list_prepend(g_list_remove_link(mru->list, link), + link->data); + else + mru_add(mru, filename); +} + +void +mru_set_size(MRU_t *mru, gint size) +{ + gint diff; + + for (diff = g_list_length(mru->list) - size; diff > 0; diff--) + mru_remove_link(mru, g_list_last(mru->list)); + mru->max_size = size; +} + +void +mru_write(MRU_t *mru, FILE *out) +{ + GList *p; + for (p = mru->list; p; p = p->next) + fprintf(out, "(mru-entry %s)\n", (gchar*) p->data); +} diff --git a/plug-ins/imagemap/imap_mru.h b/plug-ins/imagemap/imap_mru.h new file mode 100644 index 0000000..6d2d954 --- /dev/null +++ b/plug-ins/imagemap/imap_mru.h @@ -0,0 +1,45 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_MRU_H +#define _IMAP_MRU_H + +#include <stdio.h> + +#define DEFAULT_MRU_SIZE 4 + +typedef struct { + GList *list; + gint max_size; +} MRU_t; + +MRU_t* mru_create(void); +void mru_destruct(MRU_t *mru); +void mru_add(MRU_t *mru, const gchar *filename); +void mru_remove(MRU_t *mru, const gchar *filename); +void mru_set_first(MRU_t *mru, const gchar *filename); +void mru_set_size(MRU_t *mru, gint size); +void mru_write(MRU_t *mru, FILE *out); + +#define mru_empty(mru) ((mru)->list == NULL) + +#endif /* _IMAP_MRU_H */ diff --git a/plug-ins/imagemap/imap_ncsa.l b/plug-ins/imagemap/imap_ncsa.l new file mode 100644 index 0000000..73b59f2 --- /dev/null +++ b/plug-ins/imagemap/imap_ncsa.l @@ -0,0 +1,112 @@ +%{ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <glib.h> + +#include "imap_ncsa_parse.h" + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +#endif /* FLEX_SCANNER */ + +%} + +%option noyywrap +%option noinput +%option nounput + +DIGIT [0-9] +ID [a-zA-Z_][a-zA-Z0-9_\-]* +WS [ \t\n]+ + +%x imap_link +%x comment + +%% + +#\$AUTHOR: { + BEGIN(comment); + return AUTHOR; + } + +#\$TITLE: { + BEGIN(comment); + return TITLE; + } + +#\$DESCRIPTION: { + BEGIN(comment); + return DESCRIPTION; + } + +# { + BEGIN(comment); + return BEGIN_COMMENT; + } + +<comment>.* { + BEGIN(INITIAL); + ncsa_lval.id = g_strndup (yytext, yyleng); + return COMMENT; + } + +RECT { + BEGIN(imap_link); + return RECTANGLE; + } + +CIRCLE { + BEGIN(imap_link); + return CIRCLE; + } + +POLY { + BEGIN(imap_link); + return POLYGON; + } + +DEFAULT { + BEGIN(imap_link); + return DEFAULT; + } + +<imap_link>[^ ,\t\n]+ { + BEGIN(INITIAL); + ncsa_lval.id = g_strndup (yytext, yyleng); + return LINK; + } + +-?{DIGIT}*"."?{DIGIT}*([Ee][-+]?{DIGIT}*)? { + ncsa_lval.value = g_ascii_strtod (yytext, NULL); + return FLOAT; + } + +{WS} ; /* Eat white space */ + +. return *yytext; + +%% + + diff --git a/plug-ins/imagemap/imap_ncsa.y b/plug-ins/imagemap/imap_ncsa.y new file mode 100644 index 0000000..c93f62d --- /dev/null +++ b/plug-ins/imagemap/imap_ncsa.y @@ -0,0 +1,195 @@ +%{ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <math.h> + +#include <glib/gstdio.h> + +#include <gtk/gtk.h> + +#include "imap_circle.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_polygon.h" +#include "imap_rectangle.h" +#include "imap_string.h" + +extern int ncsa_lex(void); +extern int ncsa_restart(FILE *ncsa_in); +static void ncsa_error(char* s); + +static Object_t *current_object; + +%} + +%union { + int val; + double value; + char *id; +} + +%token<val> RECTANGLE POLYGON CIRCLE DEFAULT +%token<val> AUTHOR TITLE DESCRIPTION BEGIN_COMMENT +%token<value> FLOAT +%token<id> LINK COMMENT + +%% + +ncsa_file : comment_lines area_list + ; + +comment_lines : /* empty */ + | comment_lines comment_line + ; + +comment_line : author_line + | title_line + | description_line + | real_comment + ; + +real_comment : BEGIN_COMMENT COMMENT + { + g_free ($2); + } + ; + +author_line : AUTHOR COMMENT + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->author, $2); + g_free ($2); + } + ; + +title_line : TITLE COMMENT + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->title, $2); + g_free ($2); + } + ; + +description_line: DESCRIPTION COMMENT + { + MapInfo_t *info = get_map_info(); + gchar *description; + + description = g_strconcat(info->description, $2, "\n", + NULL); + g_strreplace(&info->description, description); + g_free ($2); + } + ; + +area_list : /* Empty */ + | area_list area + ; + +area : default + | rectangle + | circle + | polygon + | real_comment + ; + +default : DEFAULT LINK + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->default_url, $2); + g_free ($2); + } + ; + + +rectangle : RECTANGLE LINK FLOAT ',' FLOAT FLOAT ',' FLOAT + { + gint x = (gint) $3; + gint y = (gint) $5; + gint width = (gint) fabs($6 - x); + gint height = (gint) fabs($8 - y); + current_object = create_rectangle(x, y, width, height); + object_set_url(current_object, $2); + add_shape(current_object); + g_free ($2); + } + ; + +circle : CIRCLE LINK FLOAT ',' FLOAT FLOAT ',' FLOAT + { + gint x = (gint) $3; + gint y = (gint) $5; + gint r = (gint) fabs($8 - $5); + current_object = create_circle(x, y, r); + object_set_url(current_object, $2); + add_shape(current_object); + g_free ($2); + } + ; + +polygon : POLYGON LINK {current_object = create_polygon(NULL);} coord_list + { + object_set_url(current_object, $2); + add_shape(current_object); + g_free ($2); + } + ; + +coord_list : /* Empty */ + | coord_list coord + { + } + ; + +coord : FLOAT ',' FLOAT + { + Polygon_t *polygon = ObjectToPolygon(current_object); + GdkPoint *point = new_point((gint) $1, (gint) $3); + polygon->points = g_list_append(polygon->points, + (gpointer) point); + } + ; + +%% + +static void +ncsa_error(char* s) +{ + extern FILE *ncsa_in; + ncsa_restart(ncsa_in); +} + +gboolean +load_ncsa(const char* filename) +{ + gboolean status; + extern FILE *ncsa_in; + ncsa_in = g_fopen(filename, "r"); + if (ncsa_in) { + status = !ncsa_parse(); + fclose(ncsa_in); + } else { + status = FALSE; + } + return status; +} diff --git a/plug-ins/imagemap/imap_ncsa_lex.c b/plug-ins/imagemap/imap_ncsa_lex.c new file mode 100644 index 0000000..56f2fe1 --- /dev/null +++ b/plug-ins/imagemap/imap_ncsa_lex.c @@ -0,0 +1,1917 @@ + +#line 3 "<stdout>" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer ncsa__create_buffer +#define yy_delete_buffer ncsa__delete_buffer +#define yy_flex_debug ncsa__flex_debug +#define yy_init_buffer ncsa__init_buffer +#define yy_flush_buffer ncsa__flush_buffer +#define yy_load_buffer_state ncsa__load_buffer_state +#define yy_switch_to_buffer ncsa__switch_to_buffer +#define yyin ncsa_in +#define yyleng ncsa_leng +#define yylex ncsa_lex +#define yylineno ncsa_lineno +#define yyout ncsa_out +#define yyrestart ncsa_restart +#define yytext ncsa_text +#define yywrap ncsa_wrap +#define yyalloc ncsa_alloc +#define yyrealloc ncsa_realloc +#define yyfree ncsa_free + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 36 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE ncsa_restart(ncsa_in ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t ncsa_leng; + +extern FILE *ncsa_in, *ncsa_out; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up ncsa_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up ncsa_text again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via ncsa_restart()), so that the user can continue scanning by + * just pointing ncsa_in at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when ncsa_text is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t ncsa_leng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow ncsa_wrap()'s to do buffer switches + * instead of setting up a fresh ncsa_in. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void ncsa_restart (FILE *input_file ); +void ncsa__switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE ncsa__create_buffer (FILE *file,int size ); +void ncsa__delete_buffer (YY_BUFFER_STATE b ); +void ncsa__flush_buffer (YY_BUFFER_STATE b ); +void ncsa_push_buffer_state (YY_BUFFER_STATE new_buffer ); +void ncsa_pop_buffer_state (void ); + +static void ncsa_ensure_buffer_stack (void ); +static void ncsa__load_buffer_state (void ); +static void ncsa__init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER ncsa__flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE ncsa__scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE ncsa__scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE ncsa__scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *ncsa_alloc (yy_size_t ); +void *ncsa_realloc (void *,yy_size_t ); +void ncsa_free (void * ); + +#define yy_new_buffer ncsa__create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + ncsa_ensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + ncsa__create_buffer(ncsa_in,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + ncsa_ensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + ncsa__create_buffer(ncsa_in,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define ncsa_wrap() 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *ncsa_in = (FILE *) 0, *ncsa_out = (FILE *) 0; + +typedef int yy_state_type; + +extern int ncsa_lineno; + +int ncsa_lineno = 1; + +extern char *ncsa_text; +#define yytext_ptr ncsa_text + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up ncsa_text. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + ncsa_leng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 14 +#define YY_END_OF_BUFFER 15 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[76] = + { 0, + 11, 11, 0, 0, 5, 5, 15, 13, 12, 12, + 4, 11, 11, 11, 13, 13, 11, 13, 13, 10, + 14, 5, 12, 0, 11, 11, 11, 11, 0, 0, + 11, 11, 0, 0, 10, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 0, 9, 0, 0, 2, 1, 0, 0, + 0, 0, 0, 3, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 4, 5, 1, 1, 1, 1, + 1, 1, 6, 7, 8, 9, 1, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 1, 1, + 1, 1, 1, 1, 12, 1, 13, 14, 15, 16, + 1, 17, 18, 1, 1, 19, 1, 20, 21, 22, + 1, 23, 24, 25, 26, 1, 1, 1, 27, 1, + 1, 1, 1, 1, 1, 1, 28, 1, 29, 30, + + 31, 32, 1, 33, 34, 1, 1, 35, 1, 36, + 37, 38, 1, 39, 40, 41, 42, 1, 1, 1, + 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[44] = + { 0, + 1, 2, 3, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[81] = + { 0, + 0, 38, 4, 14, 62, 61, 58, 178, 16, 22, + 49, 18, 35, 47, 2, 28, 64, 34, 48, 0, + 178, 0, 32, 61, 70, 72, 82, 83, 60, 68, + 34, 27, 75, 82, 0, 0, 70, 82, 86, 92, + 94, 80, 83, 84, 91, 91, 98, 92, 178, 178, + 102, 113, 108, 113, 110, 109, 113, 122, 178, 113, + 116, 122, 21, 178, 15, 119, 178, 178, 122, 130, + 128, 130, 1, 178, 178, 166, 169, 172, 0, 175 + } ; + +static yyconst flex_int16_t yy_def[81] = + { 0, + 76, 76, 77, 77, 78, 78, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 79, + 75, 80, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 79, 80, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 0, 75, 75, 75, 75, 75 + } ; + +static yyconst flex_int16_t yy_nxt[222] = + { 0, + 35, 9, 10, 11, 75, 21, 21, 12, 13, 14, + 21, 74, 15, 16, 17, 21, 21, 23, 23, 29, + 21, 18, 19, 23, 23, 68, 25, 26, 15, 16, + 17, 67, 27, 23, 23, 29, 32, 18, 19, 9, + 10, 11, 30, 32, 28, 12, 13, 14, 27, 27, + 15, 16, 17, 24, 33, 25, 26, 75, 30, 18, + 19, 27, 34, 21, 21, 27, 15, 16, 17, 31, + 33, 31, 37, 32, 38, 18, 19, 27, 34, 28, + 25, 26, 40, 41, 27, 39, 27, 31, 37, 31, + 38, 32, 28, 42, 43, 44, 45, 27, 40, 41, + + 27, 39, 27, 46, 47, 48, 49, 50, 51, 42, + 43, 44, 45, 27, 52, 53, 54, 55, 56, 46, + 47, 48, 49, 50, 51, 57, 58, 59, 60, 61, + 52, 53, 54, 55, 56, 62, 63, 64, 65, 66, + 69, 57, 58, 59, 60, 61, 70, 71, 72, 73, + 75, 62, 63, 64, 65, 66, 69, 75, 75, 75, + 75, 75, 70, 71, 72, 73, 8, 8, 8, 20, + 20, 20, 22, 22, 22, 36, 36, 7, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75 + } ; + +static yyconst flex_int16_t yy_chk[222] = + { 0, + 79, 1, 1, 1, 0, 3, 3, 1, 1, 1, + 3, 73, 1, 1, 1, 4, 4, 9, 9, 15, + 4, 1, 1, 10, 10, 65, 12, 12, 1, 1, + 1, 63, 12, 23, 23, 15, 32, 1, 1, 2, + 2, 2, 16, 31, 13, 2, 2, 2, 12, 13, + 2, 2, 2, 11, 18, 14, 14, 7, 16, 2, + 2, 14, 19, 6, 5, 13, 2, 2, 2, 17, + 18, 17, 24, 17, 24, 2, 2, 14, 19, 25, + 26, 26, 29, 30, 25, 24, 26, 27, 24, 27, + 24, 27, 28, 33, 34, 37, 38, 28, 29, 30, + + 25, 24, 26, 39, 40, 41, 42, 43, 44, 33, + 34, 37, 38, 28, 45, 46, 47, 48, 51, 39, + 40, 41, 42, 43, 44, 52, 53, 54, 55, 56, + 45, 46, 47, 48, 51, 57, 58, 60, 61, 62, + 66, 52, 53, 54, 55, 56, 69, 70, 71, 72, + 0, 57, 58, 60, 61, 62, 66, 0, 0, 0, + 0, 0, 69, 70, 71, 72, 76, 76, 76, 77, + 77, 77, 78, 78, 78, 80, 80, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int ncsa__flex_debug; +int ncsa__flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *ncsa_text; +#line 1 "imap_ncsa.l" +#line 2 "imap_ncsa.l" +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <glib.h> + +#include "imap_ncsa_parse.h" + +#ifdef FLEX_SCANNER +#define YY_NO_UNPUT +#endif /* FLEX_SCANNER */ + +#define YY_NO_INPUT 1 + + +#line 581 "<stdout>" + +#define INITIAL 0 +#define imap_link 1 +#define comment 2 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int ncsa_lex_destroy (void ); + +int ncsa_get_debug (void ); + +void ncsa_set_debug (int debug_flag ); + +YY_EXTRA_TYPE ncsa_get_extra (void ); + +void ncsa_set_extra (YY_EXTRA_TYPE user_defined ); + +FILE *ncsa_get_in (void ); + +void ncsa_set_in (FILE * in_str ); + +FILE *ncsa_get_out (void ); + +void ncsa_set_out (FILE * out_str ); + +yy_size_t ncsa_get_leng (void ); + +char *ncsa_get_text (void ); + +int ncsa_get_lineno (void ); + +void ncsa_set_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int ncsa_wrap (void ); +#else +extern int ncsa_wrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( ncsa_text, ncsa_leng, 1, ncsa_out )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( ncsa_in )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( ncsa_in ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, ncsa_in))==0 && ferror(ncsa_in)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(ncsa_in); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int ncsa_lex (void); + +#define YY_DECL int ncsa_lex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after ncsa_text and ncsa_leng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 47 "imap_ncsa.l" + + +#line 766 "<stdout>" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! ncsa_in ) + ncsa_in = stdin; + + if ( ! ncsa_out ) + ncsa_out = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + ncsa_ensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + ncsa__create_buffer(ncsa_in,YY_BUF_SIZE ); + } + + ncsa__load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of ncsa_text. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 178 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 49 "imap_ncsa.l" +{ + BEGIN(comment); + return AUTHOR; + } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 54 "imap_ncsa.l" +{ + BEGIN(comment); + return TITLE; + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 59 "imap_ncsa.l" +{ + BEGIN(comment); + return DESCRIPTION; + } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 64 "imap_ncsa.l" +{ + BEGIN(comment); + return BEGIN_COMMENT; + } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 69 "imap_ncsa.l" +{ + BEGIN(INITIAL); + ncsa_lval.id = g_strndup (ncsa_text, ncsa_leng); + return COMMENT; + } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 75 "imap_ncsa.l" +{ + BEGIN(imap_link); + return RECTANGLE; + } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 80 "imap_ncsa.l" +{ + BEGIN(imap_link); + return CIRCLE; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 85 "imap_ncsa.l" +{ + BEGIN(imap_link); + return POLYGON; + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 90 "imap_ncsa.l" +{ + BEGIN(imap_link); + return DEFAULT; + } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 95 "imap_ncsa.l" +{ + BEGIN(INITIAL); + ncsa_lval.id = g_strndup (ncsa_text, ncsa_leng); + return LINK; + } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 101 "imap_ncsa.l" +{ + ncsa_lval.value = g_ascii_strtod (ncsa_text, NULL); + return FLOAT; + } + YY_BREAK +case 12: +/* rule 12 can match eol */ +YY_RULE_SETUP +#line 106 "imap_ncsa.l" +; /* Eat white space */ + YY_BREAK +case 13: +YY_RULE_SETUP +#line 108 "imap_ncsa.l" +return *ncsa_text; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 110 "imap_ncsa.l" +ECHO; + YY_BREAK +#line 955 "<stdout>" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(imap_link): +case YY_STATE_EOF(comment): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed ncsa_in at a new source and called + * ncsa_lex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = ncsa_in; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( ncsa_wrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * ncsa_text, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of ncsa_lex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + ncsa_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + ncsa_restart(ncsa_in ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ncsa_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 75); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + ncsa_restart(ncsa_in ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( ncsa_wrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve ncsa_text */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void ncsa_restart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + ncsa_ensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + ncsa__create_buffer(ncsa_in,YY_BUF_SIZE ); + } + + ncsa__init_buffer(YY_CURRENT_BUFFER,input_file ); + ncsa__load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void ncsa__switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * ncsa_pop_buffer_state(); + * ncsa_push_buffer_state(new_buffer); + */ + ncsa_ensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + ncsa__load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (ncsa_wrap()) processing, but the only time this flag + * is looked at is after ncsa_wrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void ncsa__load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + ncsa_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE ncsa__create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) ncsa_alloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in ncsa__create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) ncsa_alloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in ncsa__create_buffer()" ); + + b->yy_is_our_buffer = 1; + + ncsa__init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with ncsa__create_buffer() + * + */ + void ncsa__delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + ncsa_free((void *) b->yy_ch_buf ); + + ncsa_free((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a ncsa_restart() or at EOF. + */ + static void ncsa__init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + ncsa__flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then ncsa__init_buffer was _probably_ + * called from ncsa_restart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void ncsa__flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + ncsa__load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void ncsa_push_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + ncsa_ensure_buffer_stack(); + + /* This block is copied from ncsa__switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from ncsa__switch_to_buffer. */ + ncsa__load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void ncsa_pop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + ncsa__delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + ncsa__load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void ncsa_ensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)ncsa_alloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in ncsa_ensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)ncsa_realloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in ncsa_ensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE ncsa__scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) ncsa_alloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in ncsa__scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + ncsa__switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to ncsa_lex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * ncsa__scan_bytes() instead. + */ +YY_BUFFER_STATE ncsa__scan_string (yyconst char * yystr ) +{ + + return ncsa__scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to ncsa_lex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE ncsa__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) ncsa_alloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in ncsa__scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = ncsa__scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in ncsa__scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up ncsa_text. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + ncsa_text[ncsa_leng] = (yy_hold_char); \ + (yy_c_buf_p) = ncsa_text + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + ncsa_leng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int ncsa_get_lineno (void) +{ + + return ncsa_lineno; +} + +/** Get the input stream. + * + */ +FILE *ncsa_get_in (void) +{ + return ncsa_in; +} + +/** Get the output stream. + * + */ +FILE *ncsa_get_out (void) +{ + return ncsa_out; +} + +/** Get the length of the current token. + * + */ +yy_size_t ncsa_get_leng (void) +{ + return ncsa_leng; +} + +/** Get the current token. + * + */ + +char *ncsa_get_text (void) +{ + return ncsa_text; +} + +/** Set the current line number. + * @param line_number + * + */ +void ncsa_set_lineno (int line_number ) +{ + + ncsa_lineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see ncsa__switch_to_buffer + */ +void ncsa_set_in (FILE * in_str ) +{ + ncsa_in = in_str ; +} + +void ncsa_set_out (FILE * out_str ) +{ + ncsa_out = out_str ; +} + +int ncsa_get_debug (void) +{ + return ncsa__flex_debug; +} + +void ncsa_set_debug (int bdebug ) +{ + ncsa__flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from ncsa_lex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + ncsa_in = stdin; + ncsa_out = stdout; +#else + ncsa_in = (FILE *) 0; + ncsa_out = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * ncsa_lex_init() + */ + return 0; +} + +/* ncsa_lex_destroy is for both reentrant and non-reentrant scanners. */ +int ncsa_lex_destroy (void) +{ + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + ncsa__delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + ncsa_pop_buffer_state(); + } + + /* Destroy the stack itself. */ + ncsa_free((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * ncsa_lex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *ncsa_alloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *ncsa_realloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void ncsa_free (void * ptr ) +{ + free( (char *) ptr ); /* see ncsa_realloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 110 "imap_ncsa.l" + + + + + diff --git a/plug-ins/imagemap/imap_ncsa_parse.c b/plug-ins/imagemap/imap_ncsa_parse.c new file mode 100644 index 0000000..d2bdf47 --- /dev/null +++ b/plug-ins/imagemap/imap_ncsa_parse.c @@ -0,0 +1,1830 @@ +/* A Bison parser, made by GNU Bison 2.6.1. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.6.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse ncsa_parse +#define yylex ncsa_lex +#define yyerror ncsa_error +#define yylval ncsa_lval +#define yychar ncsa_char +#define yydebug ncsa_debug +#define yynerrs ncsa_nerrs + +/* Copy the first part of user declarations. */ +/* Line 336 of yacc.c */ +#line 1 "imap_ncsa.y" + +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include <math.h> + +#include <glib/gstdio.h> + +#include <gtk/gtk.h> + +#include "imap_circle.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_polygon.h" +#include "imap_rectangle.h" +#include "imap_string.h" + +extern int ncsa_lex(void); +extern int ncsa_restart(FILE *ncsa_in); +static void ncsa_error(char* s); + +static Object_t *current_object; + + +/* Line 336 of yacc.c */ +#line 119 "y.tab.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef NCSA_Y_TAB_H +# define NCSA_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int ncsa_debug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + RECTANGLE = 258, + POLYGON = 259, + CIRCLE = 260, + DEFAULT = 261, + AUTHOR = 262, + TITLE = 263, + DESCRIPTION = 264, + BEGIN_COMMENT = 265, + FLOAT = 266, + LINK = 267, + COMMENT = 268 + }; +#endif +/* Tokens. */ +#define RECTANGLE 258 +#define POLYGON 259 +#define CIRCLE 260 +#define DEFAULT 261 +#define AUTHOR 262 +#define TITLE 263 +#define DESCRIPTION 264 +#define BEGIN_COMMENT 265 +#define FLOAT 266 +#define LINK 267 +#define COMMENT 268 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 350 of yacc.c */ +#line 45 "imap_ncsa.y" + + int val; + double value; + char *id; + + +/* Line 350 of yacc.c */ +#line 195 "y.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE ncsa_lval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int ncsa_parse (void *YYPARSE_PARAM); +#else +int ncsa_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int ncsa_parse (void); +#else +int ncsa_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !NCSA_Y_TAB_H */ + +/* Copy the second part of user declarations. */ + +/* Line 353 of yacc.c */ +#line 223 "y.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 35 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 15 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 17 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 27 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 50 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 268 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 14, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 6, 7, 10, 12, 14, 16, 18, + 21, 24, 27, 30, 31, 34, 36, 38, 40, 42, + 44, 47, 56, 65, 66, 71, 72, 75 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 16, 0, -1, 17, 23, -1, -1, 17, 18, -1, + 20, -1, 21, -1, 22, -1, 19, -1, 10, 13, + -1, 7, 13, -1, 8, 13, -1, 9, 13, -1, + -1, 23, 24, -1, 25, -1, 26, -1, 27, -1, + 28, -1, 19, -1, 6, 12, -1, 3, 12, 11, + 14, 11, 11, 14, 11, -1, 5, 12, 11, 14, + 11, 11, 14, 11, -1, -1, 4, 12, 29, 30, + -1, -1, 30, 31, -1, 11, 14, 11, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 58, 58, 61, 62, 65, 66, 67, 68, 71, + 77, 85, 93, 105, 106, 109, 110, 111, 112, 113, + 116, 125, 138, 150, 150, 158, 159, 164 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "RECTANGLE", "POLYGON", "CIRCLE", + "DEFAULT", "AUTHOR", "TITLE", "DESCRIPTION", "BEGIN_COMMENT", "FLOAT", + "LINK", "COMMENT", "','", "$accept", "ncsa_file", "comment_lines", + "comment_line", "real_comment", "author_line", "title_line", + "description_line", "area_list", "area", "default", "rectangle", + "circle", "polygon", "$@1", "coord_list", "coord", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 44 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 15, 16, 17, 17, 18, 18, 18, 18, 19, + 20, 21, 22, 23, 23, 24, 24, 24, 24, 24, + 25, 26, 27, 29, 28, 30, 30, 31 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 0, 2, 1, 1, 1, 1, 2, + 2, 2, 2, 0, 2, 1, 1, 1, 1, 1, + 2, 8, 8, 0, 4, 0, 2, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 3, 0, 13, 1, 0, 0, 0, 0, 4, 8, + 5, 6, 7, 2, 10, 11, 12, 9, 0, 0, + 0, 0, 19, 14, 15, 16, 17, 18, 0, 23, + 0, 20, 0, 25, 0, 0, 24, 0, 0, 0, + 26, 0, 0, 0, 0, 0, 27, 0, 21, 22 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 1, 2, 8, 9, 10, 11, 12, 13, 23, + 24, 25, 26, 27, 33, 36, 40 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -9 +static const yytype_int8 yypact[] = +{ + -9, 4, 1, -9, -8, -7, -1, 0, -9, -9, + -9, -9, -9, -3, -9, -9, -9, -9, 2, 3, + 5, 6, -9, -9, -9, -9, -9, -9, 8, -9, + 9, -9, 7, -9, 10, 11, 12, 14, 15, 13, + -9, 17, 16, 18, 19, 20, -9, 21, -9, -9 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -9, -9, -9, -9, 22, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 18, 19, 20, 21, 3, 14, 15, 7, 4, 5, + 6, 7, 16, 17, 28, 29, 0, 30, 31, 32, + 34, 35, 38, 39, 37, 41, 42, 43, 44, 46, + 45, 48, 49, 47, 0, 22 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-9)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 3, 4, 5, 6, 0, 13, 13, 10, 7, 8, + 9, 10, 13, 13, 12, 12, -1, 12, 12, 11, + 11, 14, 11, 11, 14, 11, 11, 14, 11, 11, + 14, 11, 11, 14, -1, 13 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 16, 17, 0, 7, 8, 9, 10, 18, 19, + 20, 21, 22, 23, 13, 13, 13, 13, 3, 4, + 5, 6, 19, 24, 25, 26, 27, 28, 12, 12, + 12, 12, 11, 29, 11, 14, 30, 14, 11, 11, + 31, 11, 11, 14, 11, 14, 11, 14, 11, 11 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 9: +/* Line 1787 of yacc.c */ +#line 72 "imap_ncsa.y" + { + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 10: +/* Line 1787 of yacc.c */ +#line 78 "imap_ncsa.y" + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->author, (yyvsp[(2) - (2)].id)); + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 11: +/* Line 1787 of yacc.c */ +#line 86 "imap_ncsa.y" + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->title, (yyvsp[(2) - (2)].id)); + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 12: +/* Line 1787 of yacc.c */ +#line 94 "imap_ncsa.y" + { + MapInfo_t *info = get_map_info(); + gchar *description; + + description = g_strconcat(info->description, (yyvsp[(2) - (2)].id), "\n", + NULL); + g_strreplace(&info->description, description); + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 20: +/* Line 1787 of yacc.c */ +#line 117 "imap_ncsa.y" + { + MapInfo_t *info = get_map_info(); + g_strreplace(&info->default_url, (yyvsp[(2) - (2)].id)); + g_free ((yyvsp[(2) - (2)].id)); + } + break; + + case 21: +/* Line 1787 of yacc.c */ +#line 126 "imap_ncsa.y" + { + gint x = (gint) (yyvsp[(3) - (8)].value); + gint y = (gint) (yyvsp[(5) - (8)].value); + gint width = (gint) fabs((yyvsp[(6) - (8)].value) - x); + gint height = (gint) fabs((yyvsp[(8) - (8)].value) - y); + current_object = create_rectangle(x, y, width, height); + object_set_url(current_object, (yyvsp[(2) - (8)].id)); + add_shape(current_object); + g_free ((yyvsp[(2) - (8)].id)); + } + break; + + case 22: +/* Line 1787 of yacc.c */ +#line 139 "imap_ncsa.y" + { + gint x = (gint) (yyvsp[(3) - (8)].value); + gint y = (gint) (yyvsp[(5) - (8)].value); + gint r = (gint) fabs((yyvsp[(8) - (8)].value) - (yyvsp[(5) - (8)].value)); + current_object = create_circle(x, y, r); + object_set_url(current_object, (yyvsp[(2) - (8)].id)); + add_shape(current_object); + g_free ((yyvsp[(2) - (8)].id)); + } + break; + + case 23: +/* Line 1787 of yacc.c */ +#line 150 "imap_ncsa.y" + {current_object = create_polygon(NULL);} + break; + + case 24: +/* Line 1787 of yacc.c */ +#line 151 "imap_ncsa.y" + { + object_set_url(current_object, (yyvsp[(2) - (4)].id)); + add_shape(current_object); + g_free ((yyvsp[(2) - (4)].id)); + } + break; + + case 26: +/* Line 1787 of yacc.c */ +#line 160 "imap_ncsa.y" + { + } + break; + + case 27: +/* Line 1787 of yacc.c */ +#line 165 "imap_ncsa.y" + { + Polygon_t *polygon = ObjectToPolygon(current_object); + GdkPoint *point = new_point((gint) (yyvsp[(1) - (3)].value), (gint) (yyvsp[(3) - (3)].value)); + polygon->points = g_list_append(polygon->points, + (gpointer) point); + } + break; + + +/* Line 1787 of yacc.c */ +#line 1577 "y.tab.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2048 of yacc.c */ +#line 173 "imap_ncsa.y" + + +static void +ncsa_error(char* s) +{ + extern FILE *ncsa_in; + ncsa_restart(ncsa_in); +} + +gboolean +load_ncsa(const char* filename) +{ + gboolean status; + extern FILE *ncsa_in; + ncsa_in = g_fopen(filename, "r"); + if (ncsa_in) { + status = !ncsa_parse(); + fclose(ncsa_in); + } else { + status = FALSE; + } + return status; +} + diff --git a/plug-ins/imagemap/imap_ncsa_parse.h b/plug-ins/imagemap/imap_ncsa_parse.h new file mode 100644 index 0000000..68791a2 --- /dev/null +++ b/plug-ins/imagemap/imap_ncsa_parse.h @@ -0,0 +1,112 @@ +/* A Bison parser, made by GNU Bison 2.6.1. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef NCSA_Y_TAB_H +# define NCSA_Y_TAB_H +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int ncsa_debug; +#endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + RECTANGLE = 258, + POLYGON = 259, + CIRCLE = 260, + DEFAULT = 261, + AUTHOR = 262, + TITLE = 263, + DESCRIPTION = 264, + BEGIN_COMMENT = 265, + FLOAT = 266, + LINK = 267, + COMMENT = 268 + }; +#endif +/* Tokens. */ +#define RECTANGLE 258 +#define POLYGON 259 +#define CIRCLE 260 +#define DEFAULT 261 +#define AUTHOR 262 +#define TITLE 263 +#define DESCRIPTION 264 +#define BEGIN_COMMENT 265 +#define FLOAT 266 +#define LINK 267 +#define COMMENT 268 + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2049 of yacc.c */ +#line 45 "imap_ncsa.y" + + int val; + double value; + char *id; + + +/* Line 2049 of yacc.c */ +#line 90 "y.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE ncsa_lval; + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int ncsa_parse (void *YYPARSE_PARAM); +#else +int ncsa_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int ncsa_parse (void); +#else +int ncsa_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !NCSA_Y_TAB_H */ diff --git a/plug-ins/imagemap/imap_object.c b/plug-ins/imagemap/imap_object.c new file mode 100644 index 0000000..2f06e92 --- /dev/null +++ b/plug-ins/imagemap/imap_object.c @@ -0,0 +1,1040 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" +#include "imap_default_dialog.h" +#include "imap_grid.h" +#include "imap_main.h" +#include "imap_object.h" +#include "imap_string.h" + +typedef struct { + ObjectListCallbackFunc_t func; + gpointer data; +} ObjectListCB_t; + +static ObjectList_t *_paste_buffer; + +static gpointer +object_list_callback_add(ObjectListCallback_t *list, + ObjectListCallbackFunc_t func, gpointer data) +{ + ObjectListCB_t *cb = g_new(ObjectListCB_t, 1); + cb->func = func; + cb->data = data; + list->list = g_list_append(list->list, cb); + return cb; +} + +static void +object_list_callback_remove(ObjectListCallback_t *list, gpointer id) +{ + list->list = g_list_remove(list->list, id); +} + +static void +object_list_callback_call(ObjectListCallback_t *list, Object_t *obj) +{ + GList *p; + for (p = list->list; p; p = p->next) { + ObjectListCB_t *cb = (ObjectListCB_t*) p->data; + cb->func(obj, cb->data); + } +} + +gpointer +object_list_add_changed_cb(ObjectList_t *list, ObjectListCallbackFunc_t func, + gpointer data) +{ + return object_list_callback_add(&list->changed_cb, func, data); +} + +gpointer +object_list_add_update_cb(ObjectList_t *list, ObjectListCallbackFunc_t func, + gpointer data) +{ + return object_list_callback_add(&list->update_cb, func, data); +} + +gpointer +object_list_add_add_cb(ObjectList_t *list, ObjectListCallbackFunc_t func, + gpointer data) +{ + return object_list_callback_add(&list->add_cb, func, data); +} + +gpointer +object_list_add_remove_cb(ObjectList_t *list, ObjectListCallbackFunc_t func, + gpointer data) +{ + return object_list_callback_add(&list->remove_cb, func, data); +} + +gpointer +object_list_add_select_cb(ObjectList_t *list, ObjectListCallbackFunc_t func, + gpointer data) +{ + return object_list_callback_add(&list->select_cb, func, data); +} + +gpointer +object_list_add_move_cb(ObjectList_t *list, ObjectListCallbackFunc_t func, + gpointer data) +{ + return object_list_callback_add(&list->move_cb, func, data); +} + +gpointer +object_list_add_geometry_cb(ObjectList_t *list, ObjectListCallbackFunc_t func, + gpointer data) +{ + return object_list_callback_add(&list->geometry_cb, func, data); +} + +gpointer +paste_buffer_add_add_cb(ObjectListCallbackFunc_t func, gpointer data) +{ + if (!_paste_buffer) + _paste_buffer = make_object_list(); + return object_list_callback_add(&_paste_buffer->add_cb, func, data); +} + +gpointer +paste_buffer_add_remove_cb(ObjectListCallbackFunc_t func, gpointer data) +{ + if (!_paste_buffer) + _paste_buffer = make_object_list(); + return object_list_callback_add(&_paste_buffer->remove_cb, func, data); +} + +void +object_list_remove_add_cb(ObjectList_t *list, gpointer id) +{ + object_list_callback_remove(&list->add_cb, id); +} + +void +object_list_remove_select_cb(ObjectList_t *list, gpointer id) +{ + object_list_callback_remove(&list->select_cb, id); +} + +void +object_list_remove_remove_cb(ObjectList_t *list, gpointer id) +{ + object_list_callback_remove(&list->remove_cb, id); +} + +void +object_list_remove_move_cb(ObjectList_t *list, gpointer id) +{ + object_list_callback_remove(&list->move_cb, id); +} + +void +object_list_remove_geometry_cb(ObjectList_t *list, gpointer id) +{ + object_list_callback_remove(&list->geometry_cb, id); +} + +Object_t* +object_init(Object_t *obj, ObjectClass_t *class) +{ + obj->class = class; + obj->refcount = 1; + obj->selected = FALSE; + obj->locked = FALSE; + obj->url = g_strdup(""); + obj->target = g_strdup(""); + obj->comment = g_strdup(""); + obj->mouse_over = g_strdup(""); + obj->mouse_out = g_strdup(""); + obj->focus = g_strdup(""); + obj->blur = g_strdup(""); + return obj; +} + +static void +object_destruct(Object_t *obj) +{ + if (obj->class->destruct) + obj->class->destruct(obj); + g_free(obj->url); + g_free(obj->target); + g_free(obj->comment); + g_free(obj->mouse_over); + g_free(obj->mouse_out); + g_free(obj->focus); + g_free(obj->blur); + g_free(obj); +} + +Object_t* +object_ref(Object_t *obj) +{ + obj->refcount++; + return obj; +} + +void +object_unref(Object_t *obj) +{ + if (!--obj->refcount) + object_destruct(obj); +} + +Object_t* +object_clone(Object_t *obj) +{ + Object_t *clone = obj->class->clone(obj); + clone->class = obj->class; + clone->refcount = 1; + clone->selected = obj->selected; + clone->locked = FALSE; + clone->url = g_strdup(obj->url); + clone->target = g_strdup(obj->target); + clone->comment = g_strdup(obj->comment); + clone->mouse_over = g_strdup(obj->mouse_over); + clone->mouse_out = g_strdup(obj->mouse_out); + clone->focus = g_strdup(obj->focus); + clone->blur = g_strdup(obj->blur); + return clone; +} + +static Object_t* +object_copy(Object_t *src, Object_t *des) +{ + des->class = src->class; + des->selected = src->selected; + des->locked = FALSE; + g_strreplace(&des->url, src->url); + g_strreplace(&des->target, src->target); + g_strreplace(&des->comment, src->comment); + g_strreplace(&des->mouse_over, src->mouse_over); + g_strreplace(&des->mouse_out, src->mouse_out); + g_strreplace(&des->focus, src->focus); + g_strreplace(&des->blur, src->blur); + return des; +} + +Object_t* +object_assign(Object_t *obj, Object_t *des) +{ + obj->class->assign(obj, des); + return object_copy(obj, des); +} + +void +object_draw(Object_t *obj, cairo_t *cr) +{ + PreferencesData_t *preferences = get_preferences(); + ColorSelData_t *colors = &preferences->colors; + GdkColor *fg, *bg; + gdouble dash = 4.; + + if (obj->selected & 4) { + fg = &colors->interactive_fg; + bg = &colors->interactive_bg; + obj->selected &= ~4; + } else if (obj->selected) { + fg = &colors->selected_fg; + bg = &colors->selected_bg; + } else { + fg = &colors->normal_fg; + bg = &colors->normal_bg; + } + + cairo_save (cr); + gdk_cairo_set_source_color (cr, bg); + obj->class->draw(obj, cr); + gdk_cairo_set_source_color (cr, fg); + cairo_set_dash (cr, &dash, 1, 0.); + obj->class->draw(obj, cr); + + if (obj->selected && preferences->show_area_handle) + obj->class->draw_sashes(obj, cr); + cairo_restore (cr); +} + +void +object_edit(Object_t *obj, gboolean add) +{ + if (!obj->class->info_dialog) + obj->class->info_dialog = create_edit_area_info_dialog(obj); + edit_area_info_dialog_show(obj->class->info_dialog, obj, add); +} + +void +object_select(Object_t *obj) +{ + obj->selected = TRUE; + object_list_callback_call(&obj->list->select_cb, obj); + object_emit_geometry_signal(obj); +} + +void +object_unselect(Object_t *obj) +{ + obj->selected = FALSE; + object_list_callback_call(&obj->list->select_cb, obj); + object_emit_geometry_signal(obj); +} + +void +object_move(Object_t *obj, gint dx, gint dy) +{ + obj->class->move(obj, dx, dy); + object_emit_geometry_signal(obj); +} + +void +object_move_sash(Object_t *obj, gint dx, gint dy) +{ + gint x, y, width, height; + MoveSashFunc_t sash_func; + + obj->class->get_dimensions(obj, &x, &y, &width, &height); + if (dx == 0) + x += (width / 2); + else + x += width; + + if (dy == 0) + y += (height / 2); + else + y += height; + + sash_func = obj->class->near_sash(obj, x, y); + + if (sash_func) { + sash_func(obj, dx, dy); + object_emit_geometry_signal(obj); + } +} + +void +object_remove(Object_t *obj) +{ + object_list_remove(obj->list, obj); + object_emit_geometry_signal(obj); +} + +void +object_lock(Object_t *obj) +{ + obj->locked = TRUE; +} + +void +object_unlock(Object_t *obj) +{ + obj->locked = FALSE; +} + +void +object_set_url(Object_t *obj, const gchar *url) +{ + g_strreplace(&obj->url, url); +} + +void +object_set_target(Object_t *obj, const gchar *target) +{ + g_strreplace(&obj->target, target); +} + +void +object_set_comment(Object_t *obj, const gchar *comment) +{ + g_strreplace(&obj->comment, comment); +} + +void +object_set_mouse_over(Object_t *obj, const gchar *mouse_over) +{ + g_strreplace(&obj->mouse_over, mouse_over); +} + +void +object_set_mouse_out(Object_t *obj, const gchar *mouse_out) +{ + g_strreplace(&obj->mouse_out, mouse_out); +} + +void +object_set_focus(Object_t *obj, const gchar *focus) +{ + g_strreplace(&obj->focus, focus); +} + +void +object_set_blur(Object_t *obj, const gchar *blur) +{ + g_strreplace(&obj->blur, blur); +} + +gint +object_get_position_in_list(Object_t *obj) +{ + return g_list_index(obj->list->list, (gpointer) obj); +} + +void +object_emit_changed_signal(Object_t *obj) +{ + object_list_callback_call(&obj->list->changed_cb, obj); +} + +void +object_emit_geometry_signal(Object_t *obj) +{ + object_list_callback_call(&obj->list->geometry_cb, obj); +} + +void +object_emit_update_signal(Object_t *obj) +{ + object_list_callback_call(&obj->list->update_cb, obj); +} + +void +do_object_locked_dialog(void) +{ + static DefaultDialog_t *dialog; + if (!dialog) { + dialog = make_default_dialog("Object locked"); + default_dialog_hide_cancel_button(dialog); + default_dialog_hide_apply_button(dialog); + default_dialog_set_label( + dialog, + "\n You cannot delete the selected object \n" + "since it is currently being edited.\n"); + } + default_dialog_show(dialog); +} + +static Object_t* +object_factory_create_object(ObjectFactory_t *factory, gint x, gint y) +{ + return factory->obj = factory->create_object(x, y); +} + +static gboolean +button_motion(GtkWidget *widget, GdkEventMotion *event, + ObjectFactory_t *factory) +{ + gint x = get_real_coord((gint) event->x); + gint y = get_real_coord((gint) event->y); + + round_to_grid(&x, &y); + + factory->set_xy(factory->obj, event->state, x, y); + + preview_redraw (); + + return FALSE; +} + +gboolean +object_on_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + static ObjectFactory_t *factory; + PreferencesData_t *preferences = get_preferences(); + gint x = get_real_coord((gint) event->x); + gint y = get_real_coord((gint) event->y); + static Object_t *obj; + + if (event->type == GDK_2BUTTON_PRESS) + return FALSE; + round_to_grid(&x, &y); + + if (obj) { + if (event->button == 1) { + if (!factory->finish || factory->finish(obj, x, y)) { + g_signal_handlers_disconnect_by_func(widget, + button_motion, + factory); + if (object_is_valid(obj)) { + Command_t *command = create_command_new(get_shapes(), obj); + command_execute(command); + if (preferences->prompt_for_area_info) + object_edit(obj, FALSE); + } else { + object_unref(obj); + } + preview_unset_tmp_obj (obj); + preview_redraw (); + obj = NULL; + main_clear_dimension(); + } + } else if (event->button == 3) { + if (!factory->cancel || factory->cancel(event, obj)) { + g_signal_handlers_disconnect_by_func(widget, + button_motion, + factory); + object_unref(obj); + preview_unset_tmp_obj (obj); + preview_redraw (); + obj = NULL; + main_clear_dimension(); + } + return TRUE; + } + } else { + if (event->button == 1) { + factory = ((ObjectFactory_t*(*)(guint)) data)(event->state); + obj = object_factory_create_object(factory, x, y); + preview_set_tmp_obj (obj); + + g_signal_connect(widget, "motion-notify-event", + G_CALLBACK(button_motion), factory); + } + } + return FALSE; +} + +ObjectList_t* +make_object_list(void) +{ + return g_new0 (ObjectList_t, 1); +} + +void +object_list_destruct(ObjectList_t *list) +{ + object_list_remove_all(list); + g_free(list->list); +} + +ObjectList_t* +object_list_append_list(ObjectList_t *des, ObjectList_t *src) +{ + GList *p; + if (!src) + return des; + for (p = src->list; p; p = p->next) + object_list_append(des, object_clone((Object_t*) p->data)); + object_list_set_changed(des, TRUE); + return des; +} + +ObjectList_t* +object_list_copy(ObjectList_t *des, ObjectList_t *src) +{ + if (des) + object_list_remove_all(des); + else + des = make_object_list(); + + return object_list_append_list(des, src); +} + +void +object_list_append(ObjectList_t *list, Object_t *object) +{ + object->list = list; + list->list = g_list_append(list->list, (gpointer) object); + object_list_set_changed(list, TRUE); + object_list_callback_call(&list->add_cb, object); +} + +void +object_list_prepend(ObjectList_t *list, Object_t *object) +{ + object->list = list; + list->list = g_list_prepend(list->list, (gpointer) object); + object_list_set_changed(list, TRUE); + object_list_callback_call(&list->add_cb, object); +} + +void +object_list_insert(ObjectList_t *list, gint position, Object_t *object) +{ + object->list = list; + list->list = g_list_insert(list->list, (gpointer) object, position); + object_list_set_changed(list, TRUE); + object_list_callback_call(&list->add_cb, object); +} + +void +object_list_remove(ObjectList_t *list, Object_t *object) +{ + list->list = g_list_remove(list->list, (gpointer) object); + object_list_set_changed(list, TRUE); + object_list_callback_call(&list->remove_cb, object); + object_unref(object); +} + +void +object_list_remove_link(ObjectList_t *list, GList *link) +{ + list->list = g_list_remove_link(list->list, link); + object_list_set_changed(list, TRUE); + object_list_callback_call(&list->remove_cb, (Object_t*) link->data); +} + +void +object_list_update(ObjectList_t *list, Object_t *object) +{ + object_list_callback_call(&list->update_cb, object); +} + +void +object_list_draw(ObjectList_t *list, cairo_t *cr) +{ + GList *p; + for (p = list->list; p; p = p->next) + object_draw((Object_t*) p->data, cr); +} + +void +object_list_draw_selected(ObjectList_t *list, cairo_t *cr) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) + object_draw(obj, cr); + } +} + +Object_t* +object_list_find(ObjectList_t *list, gint x, gint y) +{ + Object_t *found = NULL; + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->class->point_is_on(obj, x, y)) + found = obj; + } + return found; +} + +Object_t* +object_list_near_sash(ObjectList_t *list, gint x, gint y, + MoveSashFunc_t *sash_func) +{ + Object_t *found = NULL; + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) { + MoveSashFunc_t func = obj->class->near_sash(obj, x, y); + if (func) { + found = obj; + *sash_func = func; + } + } + } + return found; +} + +void +object_list_remove_all(ObjectList_t *list) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + object_list_callback_call(&list->remove_cb, obj); + object_unref(obj); + } + g_list_free(list->list); + list->list = NULL; + object_list_set_changed(list, TRUE); +} + +void +clear_paste_buffer(void) +{ + if (_paste_buffer) + object_list_remove_all(_paste_buffer); + else + _paste_buffer = make_object_list(); +} + +ObjectList_t* +get_paste_buffer(void) +{ + return _paste_buffer; +} + +gint +object_list_cut(ObjectList_t *list) +{ + GList *p, *q; + gint count = 0; + + clear_paste_buffer(); + for (p = list->list; p; p = q) { + Object_t *obj = (Object_t*) p->data; + q = p->next; + if (obj->selected) { + if (obj->locked) { + do_object_locked_dialog(); + } else { + object_list_append(_paste_buffer, obj); + object_list_remove_link(list, p); + count++; + } + } + } + object_list_set_changed(list, (count) ? TRUE : FALSE); + return count; +} + +void +object_list_copy_to_paste_buffer(ObjectList_t *list) +{ + GList *p; + + clear_paste_buffer(); + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) + object_list_append(_paste_buffer, object_clone(obj)); + } +} + +void +object_list_paste(ObjectList_t *list) +{ + object_list_append_list(list, _paste_buffer); +} + +void +object_list_delete_selected(ObjectList_t *list) +{ + GList *p, *q; + for (p = list->list; p; p = q) { + Object_t *obj = (Object_t*) p->data; + q = p->next; + if (obj->selected) { + if (obj->locked) { + do_object_locked_dialog(); + } else { + object_list_remove_link(list, p); + object_unref(obj); + } + } + } +} + +void +object_list_edit_selected(ObjectList_t *list) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) { + object_edit(obj, TRUE); + break; + } + } +} + +gint +object_list_select_all(ObjectList_t *list) +{ + GList *p; + gint count = 0; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (!obj->selected) { + object_select(obj); + count++; + } + } + return count; +} + +void +object_list_select_next(ObjectList_t *list) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) { + object_unselect(obj); + p = (p->next) ? p->next : list->list; + object_select((Object_t*) p->data); + for (p = p->next; p; p = p->next) { + obj = (Object_t*) p->data; + if (obj->selected) + object_unselect(obj); + } + break; + } + } +} + +void object_list_select_prev(ObjectList_t *list) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) { + GList *q = (p->prev) ? p->prev : g_list_last(list->list); + for (; p; p = p->next) { + obj = (Object_t*) p->data; + if (obj->selected) + object_unselect(obj); + } + object_select((Object_t*) q->data); + break; + } + } +} + +gint +object_list_select_region(ObjectList_t *list, gint x, gint y, gint width, + gint height) +{ + GList *p; + gint count = 0; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + gint obj_x, obj_y, obj_width, obj_height; + + object_get_dimensions(obj, &obj_x, &obj_y, &obj_width, &obj_height); + if (obj_x >= x && obj_x + obj_width <= x + width && + obj_y >= y && obj_y + obj_height <= y + height) { + object_select(obj); + count++; + } + } + return count; +} + +gint +object_list_deselect_all(ObjectList_t *list, Object_t *exception) +{ + GList *p; + gint count = 0; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected && obj != exception) { + object_unselect(obj); + count++; + } + } + return count; +} + +gint +object_list_nr_selected(ObjectList_t *list) +{ + GList *p; + gint count = 0; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) + count++; + } + return count; +} + +void +object_list_resize(ObjectList_t *list, gint percentage_x, gint percentage_y) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + object_resize(obj, percentage_x, percentage_y); + } +} + +static void +object_list_swap_prev(ObjectList_t *list, GList *p) +{ + gpointer swap = p->data; + p->data = p->prev->data; + p->prev->data = swap; + object_list_callback_call(&list->move_cb, (Object_t*) p->data); + object_list_callback_call(&list->move_cb, (Object_t*) p->prev->data); +} + +static void +object_list_swap_next(ObjectList_t *list, GList *p) +{ + gpointer swap = p->data; + p->data = p->next->data; + p->next->data = swap; + object_list_callback_call(&list->move_cb, (Object_t*) p->data); + object_list_callback_call(&list->move_cb, (Object_t*) p->next->data); +} + +void +object_list_move_selected(ObjectList_t *list, gint dx, gint dy) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) + object_move(obj, dx, dy); + } +} + +void +object_list_move_up(ObjectList_t *list, Object_t *obj) +{ + GList *p = g_list_find(list->list, (gpointer) obj); + object_list_swap_prev(list, p); +} + +void +object_list_move_down(ObjectList_t *list, Object_t *obj) +{ + GList *p = g_list_find(list->list, (gpointer) obj); + object_list_swap_next(list, p); +} + +void +object_list_move_selected_up(ObjectList_t *list) +{ + GList *p; + + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected && p->prev) + object_list_swap_prev(list, p); + } +} + +void +object_list_move_selected_down(ObjectList_t *list) +{ + GList *p; + + for (p = g_list_last(list->list); p; p = p->prev) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected && p->next) + object_list_swap_next(list, p); + } +} + +void +object_list_move_to_front(ObjectList_t *list) +{ + GList *p, *q; + guint length = g_list_length(list->list); + + for (p = list->list; length; p = q, length--) { + Object_t *obj = (Object_t*) p->data; + q = p->next; + if (obj->selected) { + object_list_remove_link(list, p); + object_list_append(list, obj); + } + } +} + +void +object_list_send_to_back(ObjectList_t *list) +{ + GList *p, *q; + guint length = g_list_length(list->list); + + for (p = list->list; length; p = q, length--) { + Object_t *obj = (Object_t*) p->data; + q = p->next; + if (obj->selected) { + object_list_remove_link(list, p); + object_list_prepend(list, obj); + } + } +} + +void +object_list_move_sash_selected(ObjectList_t *list, gint dx, gint dy) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + if (obj->selected) + object_move_sash(obj, dx, dy); + } +} + +static void +write_xml_attrib(const gchar *attrib, const gchar *value, + const gchar *default_text, gpointer param, + OutputFunc_t output) +{ + if (*value) { + gchar *escaped_value = g_markup_escape_text(value, -1); + output(param, " %s=\"%s\"", attrib, escaped_value); + g_free(escaped_value); + } else if (*default_text) { + output(param, " %s", default_text); + } +} + +void +object_list_write_csim(ObjectList_t *list, gpointer param, OutputFunc_t output) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + + output(param, "<area shape="); + obj->class->write_csim(obj, param, output); + + write_xml_attrib("alt", obj->comment, "", param, output); + write_xml_attrib("target", obj->target, "", param, output); + write_xml_attrib("onmouseover", obj->mouse_over, "", param, output); + write_xml_attrib("onmouseout", obj->mouse_out, "", param, output); + write_xml_attrib("onfocus", obj->focus, "", param, output); + write_xml_attrib("onblur", obj->blur, "", param, output); + write_xml_attrib("href", obj->url, " nohref=\"nohref\"", param, output); + output(param," />\n"); + } +} + +void +object_list_write_cern(ObjectList_t *list, gpointer param, OutputFunc_t output) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + obj->class->write_cern(obj, param, output); + output(param, " %s\n", obj->url); + } +} + +void +object_list_write_ncsa(ObjectList_t *list, gpointer param, OutputFunc_t output) +{ + GList *p; + for (p = list->list; p; p = p->next) { + Object_t *obj = (Object_t*) p->data; + + if (*obj->comment) + output(param, "# %s\n", obj->comment); + obj->class->write_ncsa(obj, param, output); + output(param, "\n"); + } +} diff --git a/plug-ins/imagemap/imap_object.h b/plug-ins/imagemap/imap_object.h new file mode 100644 index 0000000..0aaf078 --- /dev/null +++ b/plug-ins/imagemap/imap_object.h @@ -0,0 +1,253 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_OBJECT_H +#define _IMAP_OBJECT_H + +typedef struct Object_t Object_t; +typedef struct ObjectClass_t ObjectClass_t; +typedef struct ObjectList_t ObjectList_t; + +#include "imap_edit_area_info.h" +#include "imap_menu_funcs.h" + +struct Object_t { + ObjectClass_t *class; + ObjectList_t *list; + gint refcount; + gboolean selected; + gboolean locked; + gchar *url; + gchar *target; + gchar *comment; + gchar *mouse_over; + gchar *mouse_out; + gchar *focus; + gchar *blur; +}; + +typedef void (*MoveSashFunc_t)(Object_t*, gint, gint); +typedef void (*OutputFunc_t)(gpointer, const char*, ...) G_GNUC_PRINTF(2,3); + +struct AreaInfoDialog_t; + +struct ObjectClass_t { + const gchar *name; + AreaInfoDialog_t *info_dialog; + + gboolean (*is_valid)(Object_t *obj); + void (*destruct)(Object_t *obj); + Object_t* (*clone)(Object_t *obj); + void (*assign)(Object_t *obj, Object_t *des); + void (*normalize)(Object_t *obj); + void (*draw)(Object_t *obj, cairo_t *cr); + void (*draw_sashes)(Object_t *obj, cairo_t *cr); + MoveSashFunc_t (*near_sash)(Object_t *obj, gint x, gint y); + gboolean (*point_is_on)(Object_t *obj, gint x, gint y); + void (*get_dimensions)(Object_t *obj, gint *x, gint *y, gint *width, + gint *height); + void (*resize)(Object_t *obj, gint percentage_x, gint percentage_y); + void (*move)(Object_t *obj, gint dx, gint dy); + gpointer (*create_info_widget)(GtkWidget *frame); + void (*update_info_widget)(Object_t *obj, gpointer data); + void (*fill_info_tab)(Object_t *obj, gpointer data); + void (*set_initial_focus)(Object_t *obj, gpointer data); + void (*update)(Object_t *obj, gpointer data); + void (*write_csim)(Object_t *obj, gpointer param, OutputFunc_t output); + void (*write_cern)(Object_t *obj, gpointer param, OutputFunc_t output); + void (*write_ncsa)(Object_t *obj, gpointer param, OutputFunc_t output); + void (*do_popup)(Object_t *obj, GdkEventButton *event); + + const gchar* (*get_stock_icon_name)(void); +}; + +Object_t *object_ref(Object_t *obj); +void object_unref(Object_t *obj); +Object_t* object_init(Object_t *obj, ObjectClass_t *class); +Object_t* object_clone(Object_t *obj); +Object_t* object_assign(Object_t *src, Object_t *des); +void object_draw(Object_t *obj, cairo_t *cr); +void object_edit(Object_t *obj, gboolean add); +void object_select(Object_t *obj); +void object_unselect(Object_t *obj); +void object_move(Object_t *obj, gint dx, gint dy); +void object_move_sash(Object_t *obj, gint dx, gint dy); +void object_remove(Object_t *obj); +void object_lock(Object_t *obj); +void object_unlock(Object_t *obj); +void object_set_url(Object_t *obj, const gchar *url); +void object_set_target(Object_t *obj, const gchar *target); +void object_set_comment(Object_t *obj, const gchar *comment); +void object_set_mouse_over(Object_t *obj, const gchar *mouse_over); +void object_set_mouse_out(Object_t *obj, const gchar *mouse_out); +void object_set_focus(Object_t *obj, const gchar *focus); +void object_set_blur(Object_t *obj, const gchar *blur); +gint object_get_position_in_list(Object_t *obj); + +void object_emit_changed_signal(Object_t *obj); +void object_emit_geometry_signal(Object_t *obj); +void object_emit_update_signal(Object_t *obj); + +#define object_is_valid(obj) \ + ((obj)->class->is_valid(obj)) + +#define object_get_dimensions(obj, x, y, width, height) \ + ((obj)->class->get_dimensions((obj), (x), (y), (width), (height))) + +#define object_normalize(obj) \ + ((obj)->class->normalize(obj)) + +#define object_resize(obj, per_x, per_y) \ + ((obj)->class->resize((obj), (per_x), (per_y))) + +#define object_update(obj, data) \ + ((obj)->class->update((obj), (data))) + +#define object_update_info_widget(obj, data) \ + ((obj)->class->update_info_widget((obj), (data))) + +#define object_fill_info_tab(obj, data) \ + ((obj)->class->fill_info_tab((obj), (data))) + +#define object_get_stock_icon_name(obj) \ + ((obj)->class->get_stock_icon_name()) + +typedef struct { + Object_t *obj; + gboolean (*finish)(Object_t *obj, gint x, gint y); + gboolean (*cancel)(GdkEventButton *event, Object_t *obj); + Object_t* (*create_object)(gint x, gint y); + void (*set_xy)(Object_t *obj, guint state, gint x, gint y); +} ObjectFactory_t; + +gboolean object_on_button_press(GtkWidget *widget, GdkEventButton *event, + gpointer data); + +typedef struct { + GList *list; +} ObjectListCallback_t; + +struct ObjectList_t { + GList *list; + gboolean changed; + ObjectListCallback_t changed_cb; + ObjectListCallback_t update_cb; + ObjectListCallback_t add_cb; + ObjectListCallback_t remove_cb; + ObjectListCallback_t select_cb; + ObjectListCallback_t move_cb; + ObjectListCallback_t geometry_cb; +}; + +ObjectList_t *make_object_list (void); +void object_list_destruct(ObjectList_t *list); +ObjectList_t *object_list_copy(ObjectList_t *des, ObjectList_t *src); +ObjectList_t *object_list_append_list(ObjectList_t *des, ObjectList_t *src); + +void object_list_append(ObjectList_t *list, Object_t *object); +void object_list_prepend(ObjectList_t *list, Object_t *object); +void object_list_insert(ObjectList_t *list, gint position, Object_t *object); +void object_list_remove(ObjectList_t *list, Object_t *object); +void object_list_remove_link(ObjectList_t *list, GList *link); +void object_list_update(ObjectList_t *list, Object_t *object); +void object_list_draw(ObjectList_t *list, cairo_t *cr); +void object_list_draw_selected(ObjectList_t *list, cairo_t *cr); +Object_t *object_list_find(ObjectList_t *list, gint x, gint y); +Object_t *object_list_near_sash(ObjectList_t *list, gint x, gint y, + MoveSashFunc_t *sash_func); + +gint object_list_cut(ObjectList_t *list); +void object_list_copy_to_paste_buffer(ObjectList_t *list); +void object_list_paste(ObjectList_t *list); + +void object_list_remove_all(ObjectList_t *list); +void object_list_delete_selected(ObjectList_t *list); +void object_list_edit_selected(ObjectList_t *list); +gint object_list_select_all(ObjectList_t *list); +void object_list_select_next(ObjectList_t *list); +void object_list_select_prev(ObjectList_t *list); +gint object_list_select_region(ObjectList_t *list, gint x, gint y, gint width, + gint height); +gint object_list_deselect_all(ObjectList_t *list, Object_t *exception); +gint object_list_nr_selected(ObjectList_t *list); +void object_list_resize(ObjectList_t *list, gint percentage_x, + gint percentage_y); +void object_list_move_selected(ObjectList_t *list, gint dx, gint dy); +void object_list_move_up(ObjectList_t *list, Object_t *obj); +void object_list_move_down(ObjectList_t *list, Object_t *obj); +void object_list_move_selected_up(ObjectList_t *list); +void object_list_move_selected_down(ObjectList_t *list); +void object_list_move_to_front(ObjectList_t *list); +void object_list_send_to_back(ObjectList_t *list); +void object_list_move_sash_selected(ObjectList_t *list, gint dx, gint dy); + +void object_list_write_csim(ObjectList_t *list, gpointer param, + OutputFunc_t output); +void object_list_write_cern(ObjectList_t *list, gpointer param, + OutputFunc_t output); +void object_list_write_ncsa(ObjectList_t *list, gpointer param, + OutputFunc_t output); + +typedef void (*ObjectListCallbackFunc_t)(Object_t*, gpointer); + +gpointer object_list_add_changed_cb(ObjectList_t *list, + ObjectListCallbackFunc_t func, + gpointer data); +gpointer object_list_add_update_cb(ObjectList_t *list, + ObjectListCallbackFunc_t func, + gpointer data); +gpointer object_list_add_add_cb(ObjectList_t *list, + ObjectListCallbackFunc_t func, gpointer data); +gpointer object_list_add_remove_cb(ObjectList_t *list, + ObjectListCallbackFunc_t func, + gpointer data); +gpointer object_list_add_select_cb(ObjectList_t *list, + ObjectListCallbackFunc_t func, + gpointer data); +gpointer object_list_add_move_cb(ObjectList_t *list, + ObjectListCallbackFunc_t func, gpointer data); +gpointer object_list_add_geometry_cb(ObjectList_t *list, + ObjectListCallbackFunc_t func, + gpointer data); + +void object_list_remove_add_cb(ObjectList_t *list, gpointer id); +void object_list_remove_select_cb(ObjectList_t *list, gpointer id); +void object_list_remove_remove_cb(ObjectList_t *list, gpointer id); +void object_list_remove_move_cb(ObjectList_t *list, gpointer id); +void object_list_remove_geometry_cb(ObjectList_t *list, gpointer id); + +#define object_list_clear_changed(list) ((list)->changed = FALSE) +#define object_list_set_changed(list, ischanged) \ + ((list)->changed = (ischanged)) +#define object_list_get_changed(list) ((list)->changed) + +void clear_paste_buffer(void); +gpointer paste_buffer_add_add_cb(ObjectListCallbackFunc_t func, gpointer data); +gpointer paste_buffer_add_remove_cb(ObjectListCallbackFunc_t func, + gpointer data); +ObjectList_t *get_paste_buffer(void); + +void do_object_locked_dialog(void); + +#endif /* _IMAP_OBJECT_H */ + + diff --git a/plug-ins/imagemap/imap_object_popup.c b/plug-ins/imagemap/imap_object_popup.c new file mode 100644 index 0000000..63b195f --- /dev/null +++ b/plug-ins/imagemap/imap_object_popup.c @@ -0,0 +1,60 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_commands.h" +#include "imap_main.h" +#include "imap_menu.h" +#include "imap_object_popup.h" + +#include "libgimp/stdplugins-intl.h" + +void +object_handle_popup(ObjectPopup_t *popup, Object_t *obj, GdkEventButton *event) +{ + /* int position = object_get_position_in_list(obj) + 1; */ + +#ifdef _TEMP_ + gtk_widget_set_sensitive(popup->up, (position > 1) ? TRUE : FALSE); + gtk_widget_set_sensitive(popup->down, + (position < g_list_length(obj->list->list)) + ? TRUE : FALSE); +#endif + gtk_menu_popup(GTK_MENU(popup->menu), NULL, NULL, NULL, NULL, + event->button, event->time); +} + +void +object_do_popup(Object_t *obj, GdkEventButton *event) +{ + static ObjectPopup_t *popup; + + if (!popup) + { + popup = g_new (ObjectPopup_t, 1); + popup->menu = menu_get_widget ("/ObjectPopupMenu"); + } + object_handle_popup (popup, obj, event); +} diff --git a/plug-ins/imagemap/imap_object_popup.h b/plug-ins/imagemap/imap_object_popup.h new file mode 100644 index 0000000..bc7afee --- /dev/null +++ b/plug-ins/imagemap/imap_object_popup.h @@ -0,0 +1,39 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_OBJECT_POPUP_H +#define _IMAP_OBJECT_POPUP_H + +#include "imap_object.h" + +typedef struct { + GtkWidget *menu; + GtkWidget *up; + GtkWidget *down; + Object_t *obj; +} ObjectPopup_t; + +void object_handle_popup(ObjectPopup_t *popup, Object_t *obj, + GdkEventButton *event); +void object_do_popup(Object_t *obj, GdkEventButton *event); + +#endif /* _IMAP_OBJECT_POPUP_H */ diff --git a/plug-ins/imagemap/imap_polygon.c b/plug-ins/imagemap/imap_polygon.c new file mode 100644 index 0000000..6428cd3 --- /dev/null +++ b/plug-ins/imagemap/imap_polygon.c @@ -0,0 +1,854 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_commands.h" +#include "imap_main.h" +#include "imap_misc.h" +#include "imap_menu.h" +#include "imap_object_popup.h" +#include "imap_polygon.h" +#include "imap_stock.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +#define MAX_POLYGON_POINTS 99 + +static gboolean polygon_is_valid(Object_t *obj); +static void polygon_destruct(Object_t *obj); +static Object_t *polygon_clone(Object_t *obj); +static void polygon_assign(Object_t *obj, Object_t *des); +static void polygon_draw(Object_t* obj, cairo_t *cr); +static void polygon_draw_sashes(Object_t* obj, cairo_t *cr); +static MoveSashFunc_t polygon_near_sash(Object_t *obj, gint x, gint y); +static gboolean polygon_point_is_on(Object_t *obj, gint x, gint y); +static void polygon_get_dimensions(Object_t *obj, gint *x, gint *y, + gint *width, gint *height); +static void polygon_resize(Object_t *obj, gint percentage_x, + gint percentage_y); +static void polygon_move(Object_t *obj, gint dx, gint dy); +static gpointer polygon_create_info_widget(GtkWidget *frame); +static void polygon_update_info_widget(Object_t *obj, gpointer data); +static void polygon_fill_info_tab(Object_t *obj, gpointer data); +static void polygon_set_initial_focus(Object_t *obj, gpointer data); +static void polygon_update(Object_t* obj, gpointer data); +static void polygon_write_csim(Object_t* obj, gpointer param, + OutputFunc_t output); +static void polygon_write_cern(Object_t* obj, gpointer param, + OutputFunc_t output); +static void polygon_write_ncsa(Object_t* obj, gpointer param, + OutputFunc_t output); +static void polygon_do_popup(Object_t *obj, GdkEventButton *event); +static const gchar* polygon_get_stock_icon_name(void); + +static ObjectClass_t polygon_class = { + N_("_Polygon"), + NULL, /* info_dialog */ + + polygon_is_valid, + polygon_destruct, + polygon_clone, + polygon_assign, + NULL, /* polygon_normalize */ + polygon_draw, + polygon_draw_sashes, + polygon_near_sash, + polygon_point_is_on, + polygon_get_dimensions, + polygon_resize, + polygon_move, + polygon_create_info_widget, + polygon_update_info_widget, + polygon_fill_info_tab, + polygon_set_initial_focus, + polygon_update, + polygon_write_csim, + polygon_write_cern, + polygon_write_ncsa, + polygon_do_popup, + polygon_get_stock_icon_name +}; + +Object_t* +create_polygon(GList *points) +{ + Polygon_t *polygon = g_new(Polygon_t, 1); + polygon->points = points; + return object_init(&polygon->obj, &polygon_class); +} + +static void +polygon_free_list (Polygon_t *polygon) +{ + g_list_free_full (polygon->points, (GDestroyNotify) g_free); + polygon->points = NULL; +} + +static void +polygon_destruct(Object_t *obj) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + polygon_free_list(polygon); +} + +static gboolean +polygon_is_valid(Object_t *obj) +{ + return g_list_length(ObjectToPolygon(obj)->points) > 2; +} + +static Object_t* +polygon_clone(Object_t *obj) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + Polygon_t *clone = g_new(Polygon_t, 1); + GList *p; + + clone->points = NULL; + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + polygon_append_point(clone, point->x, point->y); + } + return &clone->obj; +} + +static void +polygon_assign(Object_t *obj, Object_t *des) +{ + Polygon_t *src_polygon = ObjectToPolygon(obj); + Polygon_t *des_polygon = ObjectToPolygon(des); + GList *p; + + polygon_free_list(des_polygon); + for (p = src_polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + polygon_append_point(des_polygon, point->x, point->y); + } +} + +static void +polygon_draw(Object_t *obj, cairo_t *cr) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + draw_polygon(cr, polygon->points); +} + +static void +polygon_draw_sashes(Object_t *obj, cairo_t *cr) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + draw_sash(cr, point->x, point->y); + } +} + +static GdkPoint *_sash_point; +static gint _sash_index; + +static void +move_sash(Object_t *obj, gint dx, gint dy) +{ + _sash_point->x += dx; + _sash_point->y += dy; +} + +static MoveSashFunc_t +polygon_near_sash(Object_t *obj, gint x, gint y) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + + _sash_index = 0; + for (p = polygon->points; p; p = p->next, _sash_index++) { + GdkPoint *point = (GdkPoint*) p->data; + if (near_sash(point->x, point->y, x, y)) { + _sash_point = point; + return move_sash; + } + } + return NULL; +} + +static gboolean +right_intersect(GdkPoint *p1, GdkPoint *p2, gint x, gint y) +{ + gint dx = p2->x - p1->x; + gint dy = p2->y - p1->y; + + if ((dy > 0 && y > p1->y && y < p2->y) || + (dy < 0 && y > p2->y && y < p1->y)) { + gint sx = p1->x + (y - p1->y) * dx / dy; + return sx > x; + } + return FALSE; +} + +static gboolean +polygon_point_is_on(Object_t *obj, gint x, gint y) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + int count = 0; + GdkPoint *first, *prev; + + p = polygon->points; + first = prev = (GdkPoint*) p->data; + p = p->next; + + for (; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + if (right_intersect(prev, point, x, y)) + count++; + prev = point; + } + if (right_intersect(prev, first, x, y)) + count++; + + return count % 2; +} + +static void +polygon_get_dimensions(Object_t *obj, gint *x, gint *y, + gint *width, gint *height) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + gint min_x = G_MAXINT, min_y = G_MAXINT; + gint max_x = G_MININT, max_y = G_MININT; + GList *p; + + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + if (point->x < min_x) + min_x = point->x; + if (point->x > max_x) + max_x = point->x; + if (point->y < min_y) + min_y = point->y; + if (point->y > max_y) + max_y = point->y; + } + *x = min_x; + *y = min_y; + *width = max_x - min_x; + *height = max_y - min_y; +} + +static void +polygon_resize(Object_t *obj, gint percentage_x, gint percentage_y) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + point->x = point->x * percentage_x / 100; + point->y = point->y * percentage_y / 100; + } +} + +static void +polygon_move(Object_t *obj, gint dx, gint dy) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + point->x += dx; + point->y += dy; + } +} + +typedef struct { + Object_t *obj; + GtkListStore *store; + GtkTreeSelection *selection; + GtkWidget *x; + GtkWidget *y; + GtkWidget *update; + GtkWidget *insert; + GtkWidget *append; + GtkWidget *remove; + gint selected_row; + guint timeout; +} PolygonProperties_t; + +static void +select_row_cb(GtkTreeSelection *selection, PolygonProperties_t *data) +{ + GtkTreeIter iter; + GtkTreeModel *model; + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + GdkPoint *point; + + gtk_tree_model_get (model, &iter, 0, &point, -1); + + _sash_point = point; + + gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->x), point->x); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->y), point->y); + } +} + +static void +update_button_clicked(GtkWidget *widget, PolygonProperties_t *data) +{ + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL(data->store); + + if (gtk_tree_selection_get_selected (data->selection, &model, &iter)) { + GdkPoint *point; + gint x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->x)); + gint y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->y)); + + gtk_tree_model_get (model, &iter, 0, &point, -1); + point->x = x; + point->y = y; + gtk_list_store_set (data->store, &iter, 0, point, -1); + } +} + +static void +set_buttons_sensitivity(PolygonProperties_t *data) +{ + gint rows = gtk_tree_model_iter_n_children (GTK_TREE_MODEL(data->store), + NULL); + gtk_widget_set_sensitive(data->insert, rows != MAX_POLYGON_POINTS); + gtk_widget_set_sensitive(data->append, rows != MAX_POLYGON_POINTS); + gtk_widget_set_sensitive(data->remove, rows > 2); +} + +static void +insert_button_clicked(GtkWidget *widget, PolygonProperties_t *data) +{ + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL(data->store); + + if (gtk_tree_selection_get_selected (data->selection, &model, &iter)) { + Polygon_t *polygon = ObjectToPolygon(data->obj); + GdkPoint *point; + GList *here; + gint x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->x)); + gint y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->y)); + + gtk_tree_model_get (model, &iter, 0, &point, -1); + here = g_list_find(polygon->points, point); + polygon->points = g_list_insert_before(polygon->points, here, + new_point(x, y)); + polygon_fill_info_tab(data->obj, data); + } +} + +static void +append_button_clicked(GtkWidget *widget, PolygonProperties_t *data) +{ + gint x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->x)); + gint y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->y)); + + polygon_append_point(ObjectToPolygon(data->obj), x, y); + polygon_fill_info_tab(data->obj, data); +} + +static void +remove_button_clicked(GtkWidget *widget, PolygonProperties_t *data) +{ + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL(data->store); + + if (gtk_tree_selection_get_selected (data->selection, &model, &iter)) { + Polygon_t *polygon = ObjectToPolygon(data->obj); + GdkPoint *point; + + gtk_tree_model_get (model, &iter, 0, &point, -1); + polygon->points = g_list_remove(polygon->points, point); + g_free(point); + + polygon_fill_info_tab(data->obj, data); + } +} + +static void +x_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((PolygonProperties_t*) data)->obj; + gint x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + _sash_point->x = x; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static void +y_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((PolygonProperties_t*) data)->obj; + gint y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + _sash_point->y = y; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static void +render_x(GtkTreeViewColumn *column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +{ + GdkPoint *point; + gchar scratch[16]; + + gtk_tree_model_get(tree_model, iter, 0, &point, -1); + sprintf(scratch, "%d", point->x); + g_object_set(cell, "text", scratch, "xalign", 1.0, NULL); +} + +static void +render_y(GtkTreeViewColumn *column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +{ + GdkPoint *point; + gchar scratch[16]; + + gtk_tree_model_get(tree_model, iter, 0, &point, -1); + sprintf(scratch, "%d", point->y); + g_object_set(cell, "text", scratch, "xalign", 1.0, NULL); +} + +static gpointer +polygon_create_info_widget(GtkWidget *frame) +{ + PolygonProperties_t *props = g_new(PolygonProperties_t, 1); + GtkWidget *hbox, *swin, *table, *label; + GtkWidget *view; + gint max_width = get_image_width(); + gint max_height = get_image_height(); + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + + swin = gtk_scrolled_window_new(NULL, NULL); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(swin), + GTK_SHADOW_IN); + gtk_box_pack_start(GTK_BOX(hbox), swin, FALSE, FALSE, FALSE); + gtk_widget_show(swin); + + props->store = gtk_list_store_new (1, G_TYPE_POINTER); + view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (props->store)); + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view), TRUE); + g_object_unref (props->store); + gtk_widget_show (view); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("x (pixels)"), + renderer, + NULL); + gtk_tree_view_column_set_cell_data_func(column, renderer, + render_x, props, NULL); + gtk_tree_view_column_set_alignment(column, 0.5); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("y (pixels)"), + renderer, + NULL); + gtk_tree_view_column_set_cell_data_func(column, renderer, + render_y, props, NULL); + gtk_tree_view_column_set_alignment(column, 0.5); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + + gtk_container_add (GTK_CONTAINER (swin), view); + + table = gtk_table_new(6, 3, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 6); + gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, FALSE, FALSE); + gtk_widget_show(table); + + label = create_label_in_table(table, 0, 0, "_x:"); + props->x = create_spin_button_in_table(table, label, 0, 1, 1, 0, + max_width - 1); + g_signal_connect(props->x, "changed", + G_CALLBACK(x_changed_cb), (gpointer) props); + gtk_widget_set_size_request(props->x, 64, -1); + create_label_in_table(table, 0, 2, _("pixels")); + + label = create_label_in_table(table, 1, 0, "_y:"); + props->y = create_spin_button_in_table(table, label, 1, 1, 1, 0, + max_height - 1); + g_signal_connect(props->y, "changed", + G_CALLBACK(y_changed_cb), (gpointer) props); + gtk_widget_set_size_request(props->y, 64, -1); + create_label_in_table(table, 1, 2, _("pixels")); + + props->update = gtk_button_new_with_mnemonic(_("_Update")); + g_signal_connect(props->update, "clicked", + G_CALLBACK(update_button_clicked), props); + gtk_table_attach_defaults(GTK_TABLE(table), props->update, 1, 2, 2, 3); + gtk_widget_show(props->update); + + props->insert = gtk_button_new_with_mnemonic(_("_Insert")); + g_signal_connect(props->insert, "clicked", + G_CALLBACK(insert_button_clicked), props); + gtk_table_attach_defaults(GTK_TABLE(table), props->insert, 1, 2, 3, 4); + gtk_widget_show(props->insert); + + props->append = gtk_button_new_with_mnemonic(_("A_ppend")); + g_signal_connect(props->append, "clicked", + G_CALLBACK(append_button_clicked), props); + gtk_table_attach_defaults(GTK_TABLE(table), props->append, 1, 2, 4, 5); + gtk_widget_show(props->append); + + props->remove = gtk_button_new_with_mnemonic(_("_Remove")); + g_signal_connect(props->remove, "clicked", + G_CALLBACK(remove_button_clicked), props); + gtk_table_attach_defaults(GTK_TABLE(table), props->remove, 1, 2, 5, 6); + gtk_widget_show(props->remove); + + props->timeout = 0; + + props->selection = gtk_tree_view_get_selection(GTK_TREE_VIEW (view)); + gtk_tree_selection_set_mode(props->selection, GTK_SELECTION_SINGLE); + g_signal_connect (props->selection, "changed", + G_CALLBACK (select_row_cb), props); + + return props; +} + +static gboolean +update_timeout(gpointer data) +{ + PolygonProperties_t *props = (PolygonProperties_t*) data; + polygon_fill_info_tab(props->obj, data); + return FALSE; +} + +static void +polygon_update_info_widget(Object_t *obj, gpointer data) +{ + PolygonProperties_t *props = (PolygonProperties_t*) data; + GtkTreeIter iter; + + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->x), _sash_point->x); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->y), _sash_point->y); + + if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(props->store), &iter, + NULL, _sash_index)) { + gtk_tree_selection_select_iter(props->selection, &iter); + } + + if (props->timeout) + g_source_remove(props->timeout); + props->timeout = g_timeout_add(1000, update_timeout, data); +} + +static void +polygon_fill_info_tab(Object_t *obj, gpointer data) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + PolygonProperties_t *props = (PolygonProperties_t*) data; + GtkTreeIter iter; + GList *p; + + props->obj = obj; + + gtk_list_store_clear(props->store); + + for (p = polygon->points; p; p = p->next) { + gtk_list_store_append(props->store, &iter); + gtk_list_store_set(props->store, &iter, 0, p->data, -1); + } + + if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(props->store), &iter, + NULL, _sash_index)) { + gtk_tree_selection_select_iter(props->selection, &iter); + } + set_buttons_sensitivity(props); +} + +static void +polygon_set_initial_focus(Object_t *obj, gpointer data) +{ + PolygonProperties_t *props = (PolygonProperties_t*) data; + gtk_widget_grab_focus(props->x); +} + +static void +polygon_update(Object_t* obj, gpointer data) +{ + /* Nothing to be done! */ +} + +static void +polygon_write_csim(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + + output(param, "\"poly\" coords=\""); + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + output(param, "%d,%d", point->x, point->y); + output(param, "%c", (p->next) ? ',' : '"'); + } +} + +static void +polygon_write_cern(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + GdkPoint *first = (GdkPoint*) polygon->points->data; + + output(param, "poly "); + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + output(param, "(%d,%d) ", point->x, point->y); + } + output(param, "(%d,%d)", first->x, first->y); +} + +static void +polygon_write_ncsa(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p; + GdkPoint *first = (GdkPoint*) polygon->points->data; + + output(param, "poly %s", obj->url); + for (p = polygon->points; p; p = p->next) { + GdkPoint *point = (GdkPoint*) p->data; + output(param, " %d,%d", point->x, point->y); + } + output(param, " %d,%d", first->x, first->y); +} + +static Object_t *_current_obj; +static gboolean _insert_edge; +static gint _insert_x; +static gint _insert_y; + +void +polygon_insert_point(void) +{ + Command_t *command = insert_point_command_new (_current_obj, _insert_x, + _insert_y, _insert_edge); + command_execute (command); +} + +void +polygon_delete_point(void) +{ + Command_t *command = delete_point_command_new(_current_obj, _sash_point); + command_execute (command); +} + +static gboolean +point_near_edge(GdkPoint *first, GdkPoint *second, gint x, gint y) +{ + gint den, nom; + gdouble u; + + den = (first->x - x) * (first->x - second->x) + + (first->y - y) * (first->y - second->y); + nom = (second->x - first->x) * (second->x - first->x) + + (second->y - first->y) * (second->y - first->y); + u = (gdouble) den / nom; + if (u >= 0.0 && u <= 1.0) { + gint sx = first->x + (gint) (u * (second->x - first->x)) - x; + gint sy = first->y + (gint) (u * (second->y - first->y)) - y; + return sx * sx + sy * sy <= 25; /* Fix me! */ + } + return FALSE; +} + +static gint +polygon_near_edge(Object_t *obj, gint x, gint y) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *p = polygon->points; + GdkPoint *first = (GdkPoint*) p->data; + GdkPoint *prev = first; + gint n = 1; + + for (p = p->next; p; p = p->next, n++) { + GdkPoint *next = (GdkPoint*) p->data; + if (point_near_edge(prev, next, x, y)) + return n; + prev = next; + } + return (point_near_edge(prev, first, x, y)) ? n + 1 : 0; +} + +static void +polygon_handle_popup (GdkEventButton *event, gboolean near_sash, + gboolean near_edge) +{ + GtkWidget *popup = menu_get_widget ("/PolygonPopupMenu"); + GtkWidget *delete = menu_get_widget ("/PolygonPopupMenu/DeletePoint"); + GtkWidget *insert = menu_get_widget ("/PolygonPopupMenu/InsertPoint"); + + gtk_widget_set_sensitive (delete, near_sash); + gtk_widget_set_sensitive (insert, near_edge); + + gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL, + event->button, event->time); +} + +static void +polygon_do_popup(Object_t *obj, GdkEventButton *event) +{ + gint x = get_real_coord ((gint) event->x); + gint y = get_real_coord ((gint) event->y); + + _current_obj = obj; + + if (polygon_near_sash (obj, x, y)) + { + polygon_handle_popup (event, TRUE, FALSE); + } + else + { + _insert_edge = polygon_near_edge (obj, x, y); + if (_insert_edge) + { + _insert_x = x; + _insert_y = y; + + polygon_handle_popup (event, FALSE, TRUE); + } + else { + object_do_popup (obj, event); + } + } +} + +static const gchar* +polygon_get_stock_icon_name(void) +{ + return IMAP_STOCK_POLYGON; +} + +static GList *_prev_link; + +static gboolean +polygon_factory_finish(Object_t *obj, gint x, gint y) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GdkPoint *prev_point = (GdkPoint*) _prev_link->data; + + if (x == prev_point->x && y == prev_point->y) { + polygon_remove_last_point(polygon); + return TRUE; + } else { + polygon_append_point(polygon, x, y); + _prev_link = _prev_link->next; + } + return FALSE; +} + +static gboolean +polygon_factory_cancel(GdkEventButton *event, Object_t *obj) +{ + if (event->state & GDK_SHIFT_MASK) { + return TRUE; + } else { + Polygon_t *polygon = ObjectToPolygon(obj); + GList *link = _prev_link; + + _prev_link = _prev_link->prev; + g_free((GdkPoint*) link->data); + polygon->points = g_list_remove_link(polygon->points, link); + } + return _prev_link == NULL; +} + +static Object_t* +polygon_factory_create_object(gint x, gint y) +{ + GList *points; + + points = _prev_link = g_list_append(NULL, new_point(x, y)); + points = g_list_append(points, new_point(x, y)); + + return create_polygon(points); +} + +static void +polygon_factory_set_xy(Object_t *obj, guint state, gint x, gint y) +{ + Polygon_t *polygon = ObjectToPolygon(obj); + GList *last = g_list_last(polygon->points); + GdkPoint *point = (GdkPoint*) last->data; + GdkPoint *prev = (GdkPoint*) last->prev->data; + + point->x = x; + point->y = y; + + main_set_dimension(x - prev->x, y - prev->y); +} + +static ObjectFactory_t polygon_factory = { + NULL, /* Object pointer */ + polygon_factory_finish, + polygon_factory_cancel, + polygon_factory_create_object, + polygon_factory_set_xy +}; + +ObjectFactory_t* +get_polygon_factory(guint state) +{ + return &polygon_factory; +} + +void +polygon_remove_last_point(Polygon_t *polygon) +{ + GList *last = g_list_last(polygon->points); + g_free((GdkPoint*) last->data); + polygon->points = g_list_remove_link(polygon->points, last); +} + +GdkPoint* +new_point(gint x, gint y) +{ + GdkPoint *point = g_new(GdkPoint, 1); + point->x = x; + point->y = y; + return point; +} + +void +polygon_append_point(Polygon_t *polygon, gint x, gint y) +{ + polygon->points = g_list_append(polygon->points, new_point(x, y)); +} diff --git a/plug-ins/imagemap/imap_polygon.h b/plug-ins/imagemap/imap_polygon.h new file mode 100644 index 0000000..13ce29e --- /dev/null +++ b/plug-ins/imagemap/imap_polygon.h @@ -0,0 +1,45 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_POLYGON_H +#define _IMAP_POLYGON_H + +#include "imap_object.h" + +typedef struct { + Object_t obj; + GList *points; +} Polygon_t; + +#define ObjectToPolygon(obj) ((Polygon_t*) (obj)) + +Object_t *create_polygon (GList *points); +ObjectFactory_t *get_polygon_factory (guint state); + +void polygon_insert_point (void); +void polygon_delete_point (void); + +void polygon_remove_last_point (Polygon_t *polygon); +void polygon_append_point (Polygon_t *polygon, gint x, gint y); +GdkPoint *new_point (gint x, gint y); + +#endif /* _IMAP_POLYGON_H */ diff --git a/plug-ins/imagemap/imap_preferences.c b/plug-ins/imagemap/imap_preferences.c new file mode 100644 index 0000000..218aa46 --- /dev/null +++ b/plug-ins/imagemap/imap_preferences.c @@ -0,0 +1,527 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include <glib/gstdio.h> + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_command.h" +#include "imap_file.h" +#include "imap_main.h" +#include "imap_menu.h" +#include "imap_misc.h" +#include "imap_mru.h" +#include "imap_preferences.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +typedef struct { + DefaultDialog_t *dialog; + GtkWidget *notebook; + GtkWidget *ncsa; + GtkWidget *cern; + GtkWidget *csim; + GtkWidget *prompt_for_area_info; + GtkWidget *require_default_url; + GtkWidget *show_area_handle; + GtkWidget *keep_circles_round; + GtkWidget *show_url_tip; + GtkWidget *use_doublesized; + + GtkWidget *undo_levels; + GtkWidget *mru_size; + + GtkWidget *normal_fg; + GtkWidget *normal_bg; + GtkWidget *selected_fg; + GtkWidget *selected_bg; + GtkWidget *interactive_fg; + GtkWidget *interactive_bg; + + GtkWidget *threshold; + GtkWidget *auto_convert; + + PreferencesData_t *old_data; +} PreferencesDialog_t; + +static void get_button_colors (PreferencesDialog_t *dialog, + ColorSelData_t *colors); + +static gint +parse_map_type(void) +{ + char *token = strtok(NULL, " )"); + if (!strcmp(token, "ncsa")) + return NCSA; + else if (!strcmp(token, "cern")) + return CERN; + return CSIM; +} + +static gint +parse_yes_no(void) +{ + char *token = strtok(NULL, " )"); + return (gint) strcmp(token, "no"); +} + +static gint +parse_int(void) +{ + char *token = strtok(NULL, " )"); + return (gint) atoi(token); +} + +static void +parse_color(GdkColor *gdk_color) +{ + gdk_color->red = (guint16) parse_int(); + gdk_color->green = (guint16) parse_int(); + gdk_color->blue = (guint16) parse_int(); +} + +static void +parse_mru_entry(void) +{ + char *filename = strtok(NULL, " )"); + mru_add(get_mru(), filename); +} + +static void +parse_line(PreferencesData_t *data, char *line) +{ + char *token; + ColorSelData_t *colors = &data->colors; + + line++; /* Skip '(' */ + token = strtok(line, " "); + + if (!strcmp(token, "default-map-type")) { + data->default_map_type = parse_map_type(); + }else if (!strcmp(token, "prompt-for-area-info")) { + data->prompt_for_area_info = parse_yes_no(); + } else if (!strcmp(token, "require-default-url")) { + data->require_default_url = parse_yes_no(); + } else if (!strcmp(token, "show-area-handle")) { + data->show_area_handle = parse_yes_no(); + } else if (!strcmp(token, "keep-circles-round")) { + data->keep_circles_round = parse_yes_no(); + } else if (!strcmp(token, "show-url-tip")) { + data->show_url_tip = parse_yes_no(); + } else if (!strcmp(token, "use-doublesized")) { + data->use_doublesized = parse_yes_no(); + } else if (!strcmp(token, "mru-size")) { + data->mru_size = parse_int(); + if (data->mru_size < 1) + data->mru_size = 1; + } else if (!strcmp(token, "undo-levels")) { + data->undo_levels = parse_int(); + if (data->undo_levels < 1) + data->undo_levels = 1; + } else if (!strcmp(token, "normal-fg-color")) { + parse_color(&colors->normal_fg); + } else if (!strcmp(token, "normal-bg-color")) { + parse_color(&colors->normal_bg); + } else if (!strcmp(token, "selected-fg-color")) { + parse_color(&colors->selected_fg); + } else if (!strcmp(token, "selected-bg-color")) { + parse_color(&colors->selected_bg); + } else if (!strcmp(token, "interactive-fg-color")) { + parse_color(&colors->interactive_fg); + } else if (!strcmp(token, "interactive-bg-color")) { + parse_color(&colors->interactive_bg); + } else if (!strcmp(token, "mru-entry")) { + parse_mru_entry(); + } else { + /* Unrecognized, just ignore rest of line */ + } +} + +gboolean +preferences_load(PreferencesData_t *data) +{ + FILE *in; + char buf[256]; + gchar *filename; + + filename = gimp_personal_rc_file ("imagemaprc"); + + in = g_fopen(filename, "rb"); + g_free(filename); + if (in) { + while (fgets(buf, sizeof(buf), in)) { + if (*buf != '\n' && *buf != '#') { + parse_line(data, buf); + } + } + fclose(in); + return TRUE; + } + return FALSE; +} + +void +preferences_save(PreferencesData_t *data) +{ + FILE *out; + gchar *filename; + ColorSelData_t *colors = &data->colors; + + filename = gimp_personal_rc_file ("imagemaprc"); + + out = g_fopen(filename, "wb"); + if (out) { + fprintf(out, "# Image map plug-in resource file\n\n"); + if (data->default_map_type == NCSA) + fprintf(out, "(default-map-type ncsa)\n"); + else if (data->default_map_type == CERN) + fprintf(out, "(default-map-type cern)\n"); + else + fprintf(out, "(default-map-type csim)\n"); + + fprintf(out, "(prompt-for-area-info %s)\n", + (data->prompt_for_area_info) ? "yes" : "no"); + fprintf(out, "(require-default-url %s)\n", + (data->require_default_url) ? "yes" : "no"); + fprintf(out, "(show-area-handle %s)\n", + (data->show_area_handle) ? "yes" : "no"); + fprintf(out, "(keep-circles-round %s)\n", + (data->keep_circles_round) ? "yes" : "no"); + fprintf(out, "(show-url-tip %s)\n", + (data->show_url_tip) ? "yes" : "no"); + fprintf(out, "(use-doublesized %s)\n", + (data->use_doublesized) ? "yes" : "no"); + + fprintf(out, "(undo-levels %d)\n", data->undo_levels); + fprintf(out, "(mru-size %d)\n", data->mru_size); + + fprintf(out, "(normal-fg-color %d %d %d)\n", + colors->normal_fg.red, colors->normal_fg.green, + colors->normal_fg.blue); + fprintf(out, "(normal-bg-color %d %d %d)\n", + colors->normal_bg.red, colors->normal_bg.green, + colors->normal_bg.blue); + fprintf(out, "(selected-fg-color %d %d %d)\n", + colors->selected_fg.red, colors->selected_fg.green, + colors->selected_fg.blue); + fprintf(out, "(selected-bg-color %d %d %d)\n", + colors->selected_bg.red, colors->selected_bg.green, + colors->selected_bg.blue); + fprintf(out, "(interactive-fg-color %d %d %d)\n", + colors->interactive_fg.red, colors->interactive_fg.green, + colors->interactive_fg.blue); + fprintf(out, "(interactive-bg-color %d %d %d)\n", + colors->interactive_bg.red, colors->interactive_bg.green, + colors->interactive_bg.blue); + + mru_write(get_mru(), out); + + fclose(out); + } else { + do_file_error_dialog( _("Couldn't save resource file:"), filename); + } + g_free(filename); +} + +static void +preferences_ok_cb(gpointer data) +{ + PreferencesDialog_t *param = (PreferencesDialog_t*) data; + PreferencesData_t *old_data = param->old_data; + ColorSelData_t *colors = &old_data->colors; + MRU_t *mru = get_mru(); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->cern))) + old_data->default_map_type = CERN; + else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(param->ncsa))) + old_data->default_map_type = NCSA; + else + old_data->default_map_type = CSIM; + + old_data->prompt_for_area_info = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(param->prompt_for_area_info)); + old_data->require_default_url = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(param->require_default_url)); + old_data->show_area_handle = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(param->show_area_handle)); + old_data->keep_circles_round = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(param->keep_circles_round)); + old_data->show_url_tip = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(param->show_url_tip)); + old_data->use_doublesized = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(param->use_doublesized)); + + old_data->mru_size = + gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->mru_size)); + old_data->undo_levels = + gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->undo_levels)); + mru_set_size(mru, old_data->mru_size); + menu_build_mru_items(mru); + command_list_set_undo_level(old_data->undo_levels); + + get_button_colors (param, colors); + + set_sash_size(old_data->use_doublesized); + preview_redraw(); +} + +static void +get_button_color (GtkWidget *button, GdkColor *color) +{ + GimpRGB rgb; + gimp_color_button_get_color (GIMP_COLOR_BUTTON (button), &rgb); + color->red = rgb.r * 0xffff; + color->green = rgb.g * 0xffff; + color->blue = rgb.b * 0xffff; +} + +static void +get_button_colors(PreferencesDialog_t *dialog, ColorSelData_t *colors) +{ + get_button_color (dialog->normal_fg, &colors->normal_fg); + get_button_color (dialog->normal_bg, &colors->normal_bg); + get_button_color (dialog->selected_fg, &colors->selected_fg); + get_button_color (dialog->selected_bg, &colors->selected_bg); + get_button_color (dialog->interactive_fg, &colors->interactive_fg); + get_button_color (dialog->interactive_bg, &colors->interactive_bg); +} + +static void +set_button_color (GtkWidget *button, GdkColor *color) +{ + GimpRGB rgb; + gimp_rgb_set (&rgb, color->red, color->green, color->blue); + gimp_rgb_multiply (&rgb, 1.0 / 0xffff); + gimp_color_button_set_color (GIMP_COLOR_BUTTON (button), &rgb); +} + +static void +set_button_colors(PreferencesDialog_t *dialog, ColorSelData_t *colors) +{ + set_button_color (dialog->normal_fg, &colors->normal_fg); + set_button_color (dialog->normal_bg, &colors->normal_bg); + set_button_color (dialog->selected_fg, &colors->selected_fg); + set_button_color (dialog->selected_bg, &colors->selected_bg); + set_button_color (dialog->interactive_fg, &colors->interactive_fg); + set_button_color (dialog->interactive_bg, &colors->interactive_bg); +} + +static GtkWidget* +create_tab(GtkWidget *notebook, const gchar *label, gint rows, gint cols) +{ + GtkWidget *table; + GtkWidget *vbox; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1); + gtk_widget_show(vbox); + + table = gtk_table_new(rows, cols, FALSE); + gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(table), 12); + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 6); + gtk_widget_show(table); + + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, + gtk_label_new_with_mnemonic(label)); + + return table; +} + +static void +create_general_tab(PreferencesDialog_t *data, GtkWidget *notebook) +{ + GtkWidget *table = create_tab(notebook, _("General"), 7, 2); + GtkWidget *frame; + GtkWidget *hbox; + + frame = gimp_frame_new( _("Default Map Type")); + gtk_widget_show(frame); + gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 2, 0, 1); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + data->ncsa = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "_NCSA"); + gtk_box_pack_start(GTK_BOX(hbox), data->ncsa, TRUE, TRUE, 10); + gtk_widget_show(data->ncsa); + data->cern = gtk_radio_button_new_with_mnemonic_from_widget( + GTK_RADIO_BUTTON(data->ncsa), "C_ERN"); + gtk_box_pack_start(GTK_BOX(hbox), data->cern, TRUE, TRUE, 10); + gtk_widget_show(data->cern); + data->csim = gtk_radio_button_new_with_mnemonic_from_widget( + GTK_RADIO_BUTTON(data->cern), "C_SIM"); + gtk_box_pack_start(GTK_BOX(hbox), data->csim, TRUE, TRUE, 10); + gtk_widget_show(data->csim); + + data->prompt_for_area_info = + create_check_button_in_table(table, 1, 0, _("_Prompt for area info")); + data->require_default_url = + create_check_button_in_table(table, 2, 0, _("_Require default URL")); + data->show_area_handle = + create_check_button_in_table(table, 3, 0, _("Show area _handles")); + data->keep_circles_round = + create_check_button_in_table(table, 4, 0, _("_Keep NCSA circles true")); + data->show_url_tip = + create_check_button_in_table(table, 5, 0, _("Show area URL _tip")); + data->use_doublesized = + create_check_button_in_table(table, 6, 0, + _("_Use double-sized grab handles")); + gtk_widget_show(frame); +} + +static void +create_menu_tab(PreferencesDialog_t *data, GtkWidget *notebook) +{ + GtkWidget *table = create_tab(notebook, _("Menu"), 2, 2); + GtkWidget *label; + + label = create_label_in_table(table, 0, 0, + _("Number of _undo levels (1 - 99):")); + data->undo_levels = create_spin_button_in_table(table, label, 0, 1, 1, 1, + 99); + + label = create_label_in_table(table, 1, 0, + _("Number of M_RU entries (1 - 16):")); + data->mru_size = create_spin_button_in_table(table, label, 1, 1, 1, 1, 16); +} + +static GtkWidget* +create_color_field(PreferencesDialog_t *data, GtkWidget *table, gint row, + gint col) +{ + GimpRGB color = {0.0, 0.0, 0.0, 1.0}; + GtkWidget *area = gimp_color_button_new (_("Select Color"), 16, 8, &color, + GIMP_COLOR_AREA_FLAT); + gimp_color_button_set_update (GIMP_COLOR_BUTTON (area), TRUE); + gtk_table_attach_defaults (GTK_TABLE (table), area, col, col + 1, row, + row + 1); + gtk_widget_show (area); + + return area; +} + +static void +create_colors_tab(PreferencesDialog_t *data, GtkWidget *notebook) +{ + GtkWidget *table = create_tab(notebook, _("Colors"), 3, 3); + + create_label_in_table(table, 0, 0, _("Normal:")); + data->normal_fg = create_color_field(data, table, 0, 1); + data->normal_bg = create_color_field(data, table, 0, 2); + + create_label_in_table(table, 1, 0, _("Selected:")); + data->selected_fg = create_color_field(data, table, 1, 1); + data->selected_bg = create_color_field(data, table, 1, 2); + + create_label_in_table(table, 2, 0, _("Interaction:")); + data->interactive_fg = create_color_field(data, table, 2, 1); + data->interactive_bg = create_color_field(data, table, 2, 2); +} + +#ifdef _NOT_READY_YET_ +static void +create_contiguous_regions_tab(PreferencesDialog_t *data, GtkWidget *notebook) +{ + GtkWidget *table = create_tab(notebook, _("Co_ntiguous Region"), 2, 2); + GtkWidget *label; + + label = create_label_in_table(table, 0, 0, + _("_Threshold:")); + data->auto_convert = + create_check_button_in_table(table, 1, 0, _("_Automatically convert")); +} +#endif + +static PreferencesDialog_t* +create_preferences_dialog(void) +{ + PreferencesDialog_t *data = g_new(PreferencesDialog_t, 1); + DefaultDialog_t *dialog; + GtkWidget *notebook; + + data->dialog = dialog = make_default_dialog( _("General Preferences")); + default_dialog_set_ok_cb(dialog, preferences_ok_cb, (gpointer) data); + + data->notebook = notebook = gtk_notebook_new(); + gtk_box_pack_start (GTK_BOX (data->dialog->vbox), notebook, TRUE, TRUE, 0); + create_general_tab(data, notebook); + create_menu_tab(data, notebook); + create_colors_tab(data, notebook); +#ifdef _NOT_READY_YET_ + create_contiguous_regions_tab(data, notebook); +#endif + gtk_widget_show(notebook); + + return data; +} + +void +do_preferences_dialog(void) +{ + static PreferencesDialog_t *dialog; + PreferencesData_t *old_data; + GtkWidget *map_type; + + if (!dialog) { + dialog = create_preferences_dialog(); + } + gtk_notebook_set_current_page(GTK_NOTEBOOK(dialog->notebook), 0); + dialog->old_data = old_data = get_preferences(); + + if (old_data->default_map_type == CERN) + map_type = dialog->cern; + else if (old_data->default_map_type == NCSA) + map_type = dialog->ncsa; + else + map_type = dialog->csim; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(map_type), TRUE); + + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(dialog->prompt_for_area_info), + old_data->prompt_for_area_info); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->require_default_url), + old_data->require_default_url); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->show_area_handle), + old_data->show_area_handle); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->keep_circles_round), + old_data->keep_circles_round); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->show_url_tip), + old_data->show_url_tip); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->use_doublesized), + old_data->use_doublesized); + + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->undo_levels), + old_data->undo_levels); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->mru_size), + old_data->mru_size); + + set_button_colors(dialog, &old_data->colors); + + default_dialog_show(dialog->dialog); +} diff --git a/plug-ins/imagemap/imap_preferences.h b/plug-ins/imagemap/imap_preferences.h new file mode 100644 index 0000000..7376026 --- /dev/null +++ b/plug-ins/imagemap/imap_preferences.h @@ -0,0 +1,56 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_PREFERENCES_H +#define _IMAP_PREFERENCES_H + +#include "imap_default_dialog.h" + +typedef struct { + GdkColor normal_fg; + GdkColor normal_bg; + GdkColor selected_fg; + GdkColor selected_bg; + GdkColor interactive_bg; + GdkColor interactive_fg; +} ColorSelData_t; + +typedef struct { + gint default_map_type; + gboolean prompt_for_area_info; + gboolean require_default_url; + gboolean show_area_handle; + gboolean keep_circles_round; + gboolean show_url_tip; + gboolean use_doublesized; + gboolean auto_convert; + gdouble threshold; + gint undo_levels; + gint mru_size; + ColorSelData_t colors; +} PreferencesData_t; + +void do_preferences_dialog(void); +gboolean preferences_load(PreferencesData_t *data); +void preferences_save(PreferencesData_t *data); + +#endif /* _IMAP_PREFERENCES_H */ diff --git a/plug-ins/imagemap/imap_preview.c b/plug-ins/imagemap/imap_preview.c new file mode 100644 index 0000000..160a88d --- /dev/null +++ b/plug-ins/imagemap/imap_preview.c @@ -0,0 +1,402 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "imap_commands.h" +#include "imap_grid.h" +#include "imap_main.h" +#include "imap_menu.h" +#include "imap_preview.h" + +#define PREVIEW_MASK (GDK_EXPOSURE_MASK | \ + GDK_POINTER_MOTION_MASK | \ + GDK_BUTTON_PRESS_MASK | \ + GDK_BUTTON_RELEASE_MASK | \ + GDK_BUTTON_MOTION_MASK | \ + GDK_KEY_PRESS_MASK | \ + GDK_KEY_RELEASE_MASK | \ + GDK_ENTER_NOTIFY_MASK | \ + GDK_LEAVE_NOTIFY_MASK) + +#define PREVIEW_SIZE 400 + +/*====================================================================== + Preview Rendering Util routine +=======================================================================*/ + +#define CHECKWIDTH 4 +#define LIGHTCHECK 192 +#define DARKCHECK 128 +#ifndef OPAQUE +#define OPAQUE 255 +#endif + +static Object_t *_tmp_obj; + +static Preview_t* +preview_user_data(GtkWidget *preview) +{ + return (Preview_t*) g_object_get_data (G_OBJECT (preview), "preview"); +} + +gint +preview_get_width(GtkWidget *preview) +{ + return preview_user_data(preview)->width; +} + +gint +preview_get_height(GtkWidget *preview) +{ + return preview_user_data(preview)->height; +} + +static void +render_background(Preview_t *preview_base) +{ + GtkWidget *preview = preview_base->preview; + GtkStyle *style; + const GdkColor *bg_color; + + gtk_widget_ensure_style (preview); + + style = gtk_widget_get_style (preview); + bg_color = &style->bg[GTK_STATE_NORMAL]; + + gimp_preview_area_fill (GIMP_PREVIEW_AREA (preview), + 0, 0, G_MAXINT, G_MAXINT, + bg_color->red >> 8, + bg_color->green >> 8, + bg_color->blue >> 8); +} + +static void +render_rgb_image (Preview_t *preview_base, + gint32 drawable_id) +{ + GeglBuffer *buffer; + guchar *dest_buffer; + gint dwidth, dheight, pwidth, pheight; + GtkWidget *preview = preview_base->preview; + + dwidth = gimp_drawable_width (drawable_id); + dheight = gimp_drawable_height (drawable_id); + pwidth = preview_base->widget_width; + pheight = preview_base->widget_height; + + dest_buffer = g_new (guchar, pwidth * pheight * 4); + + buffer = gimp_drawable_get_buffer (drawable_id); + + gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, pwidth, pheight), + MIN ((gdouble) pwidth / (gdouble) dwidth, + (gdouble) pheight / (gdouble) dheight), + babl_format ("R'G'B'A u8"), dest_buffer, + GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); + + g_object_unref (buffer); + + gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview), + 0, 0, pwidth, pheight, + GIMP_RGBA_IMAGE, + dest_buffer, + pwidth * 4); + + g_free (dest_buffer); +} + +static void +render_preview (Preview_t *preview_base, + gint32 drawable_id) +{ + render_background (preview_base); + render_rgb_image (preview_base, drawable_id); +} + +static gboolean +arrow_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) +{ + if (event->button == 1) + do_main_popup_menu(event); + return TRUE; +} + +static gboolean +preview_expose(GtkWidget *widget, GdkEventExpose *event) +{ + cairo_t *cr; + gint width = preview_get_width (widget); + gint height = preview_get_height (widget); + + cr = gdk_cairo_create (event->window); + gdk_cairo_region (cr, event->region); + cairo_clip (cr); + cairo_set_line_width (cr, 1.); + draw_grid (cr, width, height); + + draw_shapes (cr); + + if (_tmp_obj) + { + /* this is a bit of a hack */ + gdouble dash = 4.; + _tmp_obj->selected |= 4; + cairo_set_source_rgb (cr, 1., 0., 1.); + cairo_set_dash (cr, &dash, 1, dash); + object_draw (_tmp_obj, cr); + } + + cairo_destroy (cr); + return FALSE; +} + +void +preview_set_tmp_obj (Object_t *obj) +{ + _tmp_obj = obj; +} + +void +preview_unset_tmp_obj (Object_t *obj) +{ + if (_tmp_obj == obj) _tmp_obj = NULL; +} + +void +preview_zoom(Preview_t *preview, gint zoom_factor) +{ + preview->widget_width = preview->width * zoom_factor; + preview->widget_height = preview->height * zoom_factor; + gtk_widget_set_size_request (preview->preview, preview->widget_width, + preview->widget_height); + gtk_widget_queue_resize(preview->window); + render_preview(preview, preview->drawable_id); + preview_redraw(); +} + +GdkCursorType +preview_set_cursor(Preview_t *preview, GdkCursorType cursor_type) +{ + GdkCursorType prev_cursor = preview->cursor; + GdkDisplay *display = gtk_widget_get_display (preview->window); + GdkCursor *cursor = gdk_cursor_new_for_display (display, + cursor_type); + + gdk_window_set_cursor(gtk_widget_get_window (preview->window), cursor); + gdk_cursor_unref(cursor); + + preview->cursor = cursor_type; + + return prev_cursor; +} + +static const GtkTargetEntry target_table[] = +{ + {"STRING", 0, 1 }, + {"text/plain", 0, 2 } +}; + +static void +handle_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, + GtkSelectionData *data, guint info, guint time) +{ + gboolean success = FALSE; + + if (gtk_selection_data_get_length (data) >= 0 && + gtk_selection_data_get_format (data) == 8) + { + ObjectList_t *list = get_shapes(); + Object_t *obj; + + x = get_real_coord(x); + y = get_real_coord(y); + obj = object_list_find(list, x, y); + if (obj && !obj->locked) + { + command_list_add(edit_object_command_new(obj)); + object_set_url(obj, (const gchar *) gtk_selection_data_get_data (data)); + object_emit_update_signal(obj); + success = TRUE; + } + } + gtk_drag_finish(context, success, FALSE, time); +} + +static void +preview_size_allocate (GtkWidget *widget, + GtkAllocation *allocation, + gpointer preview_void) +{ + Preview_t *preview = preview_void; + + render_preview (preview, preview->drawable_id); +} + +static void +scroll_adj_changed (GtkAdjustment *adj, + GimpRuler *ruler) +{ + gimp_ruler_set_range (ruler, + gtk_adjustment_get_value (adj), + gtk_adjustment_get_value (adj) + + gtk_adjustment_get_page_size (adj), + gtk_adjustment_get_upper (adj)); +} + +Preview_t * +make_preview (gint32 drawable_id) +{ + Preview_t *data = g_new(Preview_t, 1); + GtkAdjustment *hadj; + GtkAdjustment *vadj; + GtkWidget *preview; + GtkWidget *window; + GtkWidget *viewport; + GtkWidget *button, *arrow; + GtkWidget *ruler; + GtkWidget *table; + GtkWidget *scrollbar; + gint width, height; + + data->drawable_id = drawable_id; + data->preview = preview = gimp_preview_area_new (); + + g_object_set_data (G_OBJECT (preview), "preview", data); + gtk_widget_set_events (GTK_WIDGET (preview), PREVIEW_MASK); + + g_signal_connect_after (preview, "expose-event", + G_CALLBACK (preview_expose), + data); + g_signal_connect (preview, "size-allocate", + G_CALLBACK (preview_size_allocate), + data); + + /* Handle drop of links in preview widget */ + gtk_drag_dest_set (preview, GTK_DEST_DEFAULT_ALL, target_table, + 2, GDK_ACTION_COPY); + + g_signal_connect (preview, "drag-data-received", + G_CALLBACK (handle_drop), + NULL); + + data->widget_width = data->width = gimp_drawable_width (drawable_id); + data->widget_height = data->height = gimp_drawable_height (drawable_id); + gtk_widget_set_size_request (preview, data->widget_width, + data->widget_height); + + /* The main table */ + data->window = table = gtk_table_new (3, 3, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 1); + gtk_table_set_row_spacings (GTK_TABLE (table), 1); + + /* Create button with arrow */ + button = gtk_button_new (); + gtk_widget_set_can_focus (button, FALSE); + gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1, + GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_set_events (button, + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + gtk_widget_show (button); + + g_signal_connect (button, "button-press-event", + G_CALLBACK (arrow_cb), + NULL); + + arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT); + gtk_container_add (GTK_CONTAINER (button), arrow); + gtk_widget_show (arrow); + + /* Create horizontal ruler */ + data->hruler = ruler = gimp_ruler_new (GTK_ORIENTATION_HORIZONTAL); + g_signal_connect_swapped (preview, "motion-notify-event", + G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event), + ruler); + + gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1, + GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (ruler); + + /* Create vertical ruler */ + data->vruler = ruler = gimp_ruler_new (GTK_ORIENTATION_VERTICAL); + g_signal_connect_swapped (preview, "motion-notify-event", + G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event), + ruler); + gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2, + GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); + gtk_widget_show (ruler); + + window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window), + GTK_POLICY_NEVER, GTK_POLICY_NEVER); + width = (data->width > 600) ? 600 : data->width; + height = (data->height > 400) ? 400 : data->height; + gtk_widget_set_size_request (window, width, height); + gtk_table_attach (GTK_TABLE (table), window, 1, 2, 1, 2, + GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (window); + + viewport = gtk_viewport_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (window), viewport); + gtk_widget_show (viewport); + + hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (window)); + + g_signal_connect (hadj, "changed", + G_CALLBACK (scroll_adj_changed), + data->hruler); + g_signal_connect (hadj, "value-changed", + G_CALLBACK (scroll_adj_changed), + data->hruler); + + vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (window)); + + g_signal_connect (vadj, "changed", + G_CALLBACK (scroll_adj_changed), + data->vruler); + g_signal_connect (vadj, "value-changed", + G_CALLBACK (scroll_adj_changed), + data->vruler); + + gtk_container_add (GTK_CONTAINER (viewport), preview); + + scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, hadj); + gtk_table_attach(GTK_TABLE(table), scrollbar, 1, 2, 2, 3, + GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); + gtk_widget_show (scrollbar); + + scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, vadj); + gtk_table_attach (GTK_TABLE (table), scrollbar, 2, 3, 1, 2, + GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); + gtk_widget_show (scrollbar); + + gtk_widget_show (preview); + + render_preview (data, drawable_id); + + gtk_widget_show (table); + + return data; +} diff --git a/plug-ins/imagemap/imap_preview.h b/plug-ins/imagemap/imap_preview.h new file mode 100644 index 0000000..3fe01c4 --- /dev/null +++ b/plug-ins/imagemap/imap_preview.h @@ -0,0 +1,55 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_PREVIEW_H +#define _IMAP_PREVIEW_H + +#include <libgimp/gimp.h> + +typedef struct { + gint32 drawable_id; + GtkWidget *window; + GtkWidget *preview; + GtkWidget *hruler; + GtkWidget *vruler; + gint width; + gint height; + gint widget_width; + gint widget_height; + + GdkCursorType cursor; +} Preview_t; + +Preview_t *make_preview(gint32 drawable_id); +void preview_redraw(void); + +void preview_unset_tmp_obj (Object_t *obj); +void preview_set_tmp_obj (Object_t *obj); + +gint preview_get_width(GtkWidget *preview); +gint preview_get_height(GtkWidget *preview); + +void preview_zoom(Preview_t *preview, gint zoom_factor); +GdkCursorType preview_set_cursor(Preview_t *preview, + GdkCursorType cursor_type); + +#endif /* _IMAP_PREVIEW_H */ diff --git a/plug-ins/imagemap/imap_rectangle.c b/plug-ins/imagemap/imap_rectangle.c new file mode 100644 index 0000000..fa4c3a9 --- /dev/null +++ b/plug-ins/imagemap/imap_rectangle.c @@ -0,0 +1,538 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdlib.h> /* abs */ + +#include <gtk/gtk.h> + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "imap_main.h" +#include "imap_misc.h" +#include "imap_object_popup.h" +#include "imap_rectangle.h" +#include "imap_stock.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + + +static gboolean rectangle_is_valid(Object_t *obj); +static Object_t *rectangle_clone(Object_t *obj); +static void rectangle_assign(Object_t *obj, Object_t *des); +static void rectangle_normalize(Object_t *obj); +static void rectangle_draw(Object_t *obj, cairo_t *cr); +static void rectangle_draw_sashes(Object_t *obj, cairo_t *cr); +static MoveSashFunc_t rectangle_near_sash(Object_t *obj, gint x, gint y); +static gboolean rectangle_point_is_on(Object_t *obj, gint x, gint y); +static void rectangle_get_dimensions(Object_t *obj, gint *x, gint *y, + gint *width, gint *height); +static void rectangle_resize(Object_t *obj, gint percentage_x, + gint percentage_y); +static void rectangle_move(Object_t *obj, gint dx, gint dy); +static gpointer rectangle_create_info_widget(GtkWidget *frame); +static void rectangle_fill_info_tab(Object_t *obj, gpointer data); +static void rectangle_set_initial_focus(Object_t *obj, gpointer data); +static void rectangle_update(Object_t *obj, gpointer data); +static void rectangle_write_csim(Object_t *obj, gpointer param, + OutputFunc_t output); +static void rectangle_write_cern(Object_t *obj, gpointer param, + OutputFunc_t output); +static void rectangle_write_ncsa(Object_t *obj, gpointer param, + OutputFunc_t output); +static const gchar* rectangle_get_stock_icon_name(void); + +static ObjectClass_t rectangle_class = { + N_("_Rectangle"), + NULL, /* info_dialog */ + + rectangle_is_valid, + NULL, /* rectangle_destruct */ + rectangle_clone, + rectangle_assign, + rectangle_normalize, + rectangle_draw, + rectangle_draw_sashes, + rectangle_near_sash, + rectangle_point_is_on, + rectangle_get_dimensions, + rectangle_resize, + rectangle_move, + rectangle_create_info_widget, + rectangle_fill_info_tab, /* rectangle_update_info_widget */ + rectangle_fill_info_tab, + rectangle_set_initial_focus, + rectangle_update, + rectangle_write_csim, + rectangle_write_cern, + rectangle_write_ncsa, + object_do_popup, + rectangle_get_stock_icon_name +}; + +Object_t* +create_rectangle(gint x, gint y, gint width, gint height) +{ + Rectangle_t *rectangle = g_new(Rectangle_t, 1); + rectangle->x = x; + rectangle->y = y; + rectangle->width = width; + rectangle->height = height; + return object_init(&rectangle->obj, &rectangle_class); +} + +static void +draw_any_rectangle(cairo_t *cr, gint x, gint y, gint w, gint h) +{ + if (w < 0) { + x += w; + w = -w; + } + if (h < 0) { + y += h; + h = -h; + } + draw_rectangle(cr, FALSE, x, y, w, h); +} + +static gboolean +rectangle_is_valid(Object_t *obj) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + return rectangle->width && rectangle->height; +} + +static Object_t* +rectangle_clone(Object_t *obj) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + Rectangle_t *clone = g_new(Rectangle_t, 1); + + clone->x = rectangle->x; + clone->y = rectangle->y; + clone->width = rectangle->width; + clone->height = rectangle->height; + return &clone->obj; +} + +static void +rectangle_assign(Object_t *obj, Object_t *des) +{ + Rectangle_t *src_rectangle = ObjectToRectangle(obj); + Rectangle_t *des_rectangle = ObjectToRectangle(des); + des_rectangle->x = src_rectangle->x; + des_rectangle->y = src_rectangle->y; + des_rectangle->width = src_rectangle->width; + des_rectangle->height = src_rectangle->height; +} + +static void +rectangle_normalize(Object_t *obj) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + if (rectangle->width < 0) { + rectangle->x += rectangle->width; + rectangle->width = -rectangle->width; + } + if (rectangle->height < 0) { + rectangle->y += rectangle->height; + rectangle->height = -rectangle->height; + } +} + +static void +rectangle_draw(Object_t *obj, cairo_t *cr) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + draw_any_rectangle(cr, rectangle->x, rectangle->y, + rectangle->width, rectangle->height); +} + +static void +rectangle_draw_sashes(Object_t *obj, cairo_t *cr) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + draw_sash(cr, rectangle->x, rectangle->y); + draw_sash(cr, rectangle->x + rectangle->width / 2, rectangle->y); + draw_sash(cr, rectangle->x + rectangle->width, rectangle->y); + draw_sash(cr, rectangle->x, rectangle->y + rectangle->height / 2); + draw_sash(cr, rectangle->x + rectangle->width, + rectangle->y + rectangle->height / 2); + draw_sash(cr, rectangle->x, rectangle->y + rectangle->height); + draw_sash(cr, rectangle->x + rectangle->width / 2, + rectangle->y + rectangle->height); + draw_sash(cr, rectangle->x + rectangle->width, + rectangle->y + rectangle->height); +} + +static void +MoveUpperSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->y += dy; + rectangle->height -= dy; +} + +static void +MoveLeftSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->x += dx; + rectangle->width -= dx; +} + +static void +MoveRightSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->width += dx; +} + +static void +MoveLowerSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->height += dy; +} + +static void +MoveUpperLeftSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->x += dx; + rectangle->y += dy; + rectangle->width -= dx; + rectangle->height -= dy; +} + +static void +MoveUpperRightSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->y += dy; + rectangle->width += dx; + rectangle->height -= dy; +} + +static void +MoveLowerLeftSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->x += dx; + rectangle->width -= dx; + rectangle->height += dy; +} + +static void +MoveLowerRightSash(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->width += dx; + rectangle->height += dy; +} + +static MoveSashFunc_t +rectangle_near_sash(Object_t *obj, gint x, gint y) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + if (near_sash(rectangle->x, rectangle->y, x, y)) + return MoveUpperLeftSash; + else if (near_sash(rectangle->x + rectangle->width / 2, rectangle->y, x, y)) + return MoveUpperSash; + else if (near_sash(rectangle->x + rectangle->width, rectangle->y, x, y)) + return MoveUpperRightSash; + else if (near_sash(rectangle->x, rectangle->y + rectangle->height / 2, + x, y)) + return MoveLeftSash; + else if (near_sash(rectangle->x + rectangle->width, + rectangle->y + rectangle->height / 2, x, y)) + return MoveRightSash; + else if (near_sash(rectangle->x, rectangle->y + rectangle->height, x, y)) + return MoveLowerLeftSash; + else if (near_sash(rectangle->x + rectangle->width / 2, + rectangle->y + rectangle->height, x, y)) + return MoveLowerSash; + else if (near_sash(rectangle->x + rectangle->width, + rectangle->y + rectangle->height, x, y)) + return MoveLowerRightSash; + return NULL; +} + +static gboolean +rectangle_point_is_on(Object_t *obj, gint x, gint y) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + return x >= rectangle->x && x <= rectangle->x + rectangle->width && + y >= rectangle->y && y <= rectangle->y + rectangle->height; +} + +static void +rectangle_get_dimensions(Object_t *obj, gint *x, gint *y, + gint *width, gint *height) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + *x = rectangle->x; + *y = rectangle->y; + *width = rectangle->width; + *height = rectangle->height; +} + +static void +rectangle_resize(Object_t *obj, gint percentage_x, gint percentage_y) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->x = rectangle->x * percentage_x / 100; + rectangle->y = rectangle->y * percentage_y / 100; + rectangle->width = rectangle->width * percentage_x / 100; + rectangle->height = rectangle->height * percentage_y / 100; +} + +static void +rectangle_move(Object_t *obj, gint dx, gint dy) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + rectangle->x += dx; + rectangle->y += dy; +} + +typedef struct { + Object_t *obj; + GtkWidget *x; + GtkWidget *y; + GtkWidget *width; + GtkWidget *height; + GtkWidget *chain_button; +} RectangleProperties_t; + +static void +x_changed_cb(GtkWidget *widget, gpointer data) +{ + RectangleProperties_t *props = (RectangleProperties_t*) data; + Object_t *obj = props->obj; + gint x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + + if (gimp_chain_button_get_active(GIMP_CHAIN_BUTTON(props->chain_button))) + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->y), x); + + ObjectToRectangle(obj)->x = x; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static void +y_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((RectangleProperties_t*) data)->obj; + gint y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + ObjectToRectangle(obj)->y = y; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static void +width_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((RectangleProperties_t*) data)->obj; + gint width = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + ObjectToRectangle(obj)->width = width; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static void +height_changed_cb(GtkWidget *widget, gpointer data) +{ + Object_t *obj = ((RectangleProperties_t*) data)->obj; + gint height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + ObjectToRectangle(obj)->height = height; + edit_area_info_dialog_emit_geometry_signal(obj->class->info_dialog); +} + +static gpointer +rectangle_create_info_widget(GtkWidget *frame) +{ + RectangleProperties_t *props = g_new(RectangleProperties_t, 1); + GtkWidget *table, *label, *chain_button; + gint max_width = get_image_width(); + gint max_height = get_image_height(); + + table = gtk_table_new(4, 4, FALSE); + gtk_container_add(GTK_CONTAINER(frame), table); + + gtk_table_set_row_spacings(GTK_TABLE(table), 6); + gtk_table_set_col_spacings(GTK_TABLE(table), 6); + gtk_widget_show(table); + + label = create_label_in_table(table, 0, 0, _("Upper left _x:")); + props->x = create_spin_button_in_table(table, label, 0, 1, 1, 0, + max_width - 1); + g_signal_connect(props->x, "value-changed", + G_CALLBACK(x_changed_cb), (gpointer) props); + create_label_in_table(table, 0, 3, _("pixels")); + + label = create_label_in_table(table, 1, 0, _("Upper left _y:")); + props->y = create_spin_button_in_table(table, label, 1, 1, 1, 0, + max_height - 1); + g_signal_connect(props->y, "value-changed", + G_CALLBACK(y_changed_cb), (gpointer) props); + create_label_in_table(table, 1, 3, _("pixels")); + + label = create_label_in_table(table, 2, 0, _("_Width:")); + props->width = create_spin_button_in_table(table, label, 2, 1, 1, 1, + max_width); + g_signal_connect(props->width, "value-changed", + G_CALLBACK(width_changed_cb), (gpointer) props); + create_label_in_table(table, 2, 3, _("pixels")); + + label = create_label_in_table(table, 3, 0, _("_Height:")); + props->height = create_spin_button_in_table(table, label, 3, 1, 1, 1, + max_height); + g_signal_connect(props->height, "value-changed", + G_CALLBACK(height_changed_cb), (gpointer) props); + create_label_in_table(table, 3, 3, _("pixels")); + + chain_button = gimp_chain_button_new(GIMP_CHAIN_RIGHT); + props->chain_button = chain_button; + gtk_table_attach_defaults(GTK_TABLE(table), chain_button, 2, 3, 2, 4); + gtk_widget_show(chain_button); + + return props; +} + +static void +rectangle_fill_info_tab(Object_t *obj, gpointer data) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + RectangleProperties_t *props = (RectangleProperties_t*) data; + + props->obj = obj; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->x), rectangle->x); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->y), rectangle->y); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->width), rectangle->width); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(props->height), + rectangle->height); +} + +static void +rectangle_set_initial_focus(Object_t *obj, gpointer data) +{ + RectangleProperties_t *props = (RectangleProperties_t*) data; + gtk_widget_grab_focus(props->x); +} + +static void +rectangle_update(Object_t* obj, gpointer data) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + RectangleProperties_t *props = (RectangleProperties_t*) data; + + rectangle->x = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(props->x)); + rectangle->y = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(props->y)); + rectangle->width = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(props->width)); + rectangle->height = gtk_spin_button_get_value_as_int( + GTK_SPIN_BUTTON(props->height)); +} + +static void +rectangle_write_csim(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + output(param, "\"rect\" coords=\"%d,%d,%d,%d\"", rectangle->x, rectangle->y, + rectangle->x + rectangle->width, rectangle->y + rectangle->height); +} + +static void +rectangle_write_cern(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + output(param, "rect (%d,%d) (%d,%d)", rectangle->x, rectangle->y, + rectangle->x + rectangle->width, rectangle->y + rectangle->height); +} + +static void +rectangle_write_ncsa(Object_t *obj, gpointer param, OutputFunc_t output) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + output(param, "rect %s %d,%d %d,%d", obj->url, + rectangle->x, rectangle->y, + rectangle->x + rectangle->width, rectangle->y + rectangle->height); +} + +static const gchar* +rectangle_get_stock_icon_name(void) +{ + return IMAP_STOCK_RECTANGLE; +} + +static gboolean +rectangle_factory_finish(Object_t *obj, gint x, gint y) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + + rectangle->width = x - rectangle->x; + rectangle->height = y - rectangle->y; + + rectangle_normalize(obj); + + return TRUE; +} + +static Object_t* +rectangle_factory_create_object(gint x, gint y) +{ + return create_rectangle(x, y, 0, 0); +} + +static void +rectangle_factory_set_xy(Object_t *obj, guint state, gint x, gint y) +{ + Rectangle_t *rectangle = ObjectToRectangle(obj); + + rectangle->width = x - rectangle->x; + rectangle->height = y - rectangle->y; + + if (state & GDK_SHIFT_MASK){ + gint width = abs(rectangle->width); + gint height = abs(rectangle->height); + if (width < height) + rectangle->height = (rectangle->height < 0) ? -width : width; + else + rectangle->width = (rectangle->width < 0) ? -height : height; + } + + main_set_dimension(rectangle->width, rectangle->height); +} + +static ObjectFactory_t rectangle_factory = { + NULL, /* Object pointer */ + rectangle_factory_finish, + NULL, /* Cancel func */ + rectangle_factory_create_object, + rectangle_factory_set_xy +}; + +ObjectFactory_t* +get_rectangle_factory(guint state) +{ + return &rectangle_factory; +} diff --git a/plug-ins/imagemap/imap_rectangle.h b/plug-ins/imagemap/imap_rectangle.h new file mode 100644 index 0000000..fe33e31 --- /dev/null +++ b/plug-ins/imagemap/imap_rectangle.h @@ -0,0 +1,41 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_RECTANGLE_H +#define _IMAP_RECTANGLE_H + +#include "imap_object.h" + +typedef struct { + Object_t obj; + gint x; + gint y; + gint width; + gint height; +} Rectangle_t; + +#define ObjectToRectangle(obj) ((Rectangle_t*) (obj)) + +Object_t* create_rectangle(gint x, gint y, gint width, gint height); +ObjectFactory_t *get_rectangle_factory(guint state); + +#endif /* _IMAP_RECTANGLE_H */ diff --git a/plug-ins/imagemap/imap_selection.c b/plug-ins/imagemap/imap_selection.c new file mode 100644 index 0000000..4713d17 --- /dev/null +++ b/plug-ins/imagemap/imap_selection.c @@ -0,0 +1,452 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdio.h> + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_commands.h" +#include "imap_main.h" +#include "imap_menu.h" +#include "imap_selection.h" + +#include "libgimp/stdplugins-intl.h" + + +static void +changed_cb(GtkTreeSelection *selection, gpointer param) +{ + Selection_t *data = (Selection_t*) param; + + if (data->select_lock) + { + data->select_lock = FALSE; + } else + { + Command_t *command, *sub_command; + GtkTreeModel *model; + GList *list, *selected_rows; + + selected_rows = gtk_tree_selection_get_selected_rows (selection, + &model); + + command = subcommand_start (NULL); + sub_command = unselect_all_command_new (data->object_list, NULL); + command_add_subcommand (command, sub_command); + + for (list = selected_rows; list; list = list->next) + { + Object_t *obj; + GtkTreeIter iter; + GtkTreePath *path = (GtkTreePath*) list->data; + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, 0, &obj, -1); + + sub_command = select_command_new (obj); + command_add_subcommand (command, sub_command); + } + + command_set_name (command, sub_command->name); + subcommand_end (); + + command_execute (command); + + g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free); + } +} + +static gboolean +button_press_cb(GtkWidget *widget, GdkEventButton *event, Selection_t *data) +{ + if (event->button == 1) { + if (data->doubleclick) { + GtkTreePath *path; + + data->doubleclick = FALSE; + + if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), + (gint) event->x, (gint) event->y, + &path, NULL, NULL, NULL)) { + GtkTreeIter iter; + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (data->store), &iter, + path)) { + Object_t *obj; + gtk_tree_model_get (GTK_TREE_MODEL(data->store), &iter, 0, &obj, -1); + object_edit (obj, TRUE); + } + gtk_tree_path_free (path); + } + } else { + data->doubleclick = TRUE; + } + } + return FALSE; +} + +static gboolean +button_release_cb(GtkWidget *widget, GdkEventButton *event, Selection_t *data) +{ + if (event->button == 1) + data->doubleclick = FALSE; + return FALSE; +} + +static void +selection_set_selected(Selection_t *selection, gint row) +{ + GtkTreeIter iter; + + if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (selection->store), &iter, + NULL, row)) { + Object_t *obj; + + gtk_tree_model_get (GTK_TREE_MODEL(selection->store), &iter, 0, &obj, -1); + + selection->select_lock = TRUE; + + if (obj->selected) { + gtk_tree_selection_select_iter (selection->selection, &iter); + } else { + gtk_tree_selection_unselect_iter (selection->selection, &iter); + } + } +} + +static void +object_added_cb(Object_t *obj, gpointer data) +{ + Selection_t *selection = (Selection_t*) data; + GtkTreeIter iter; + gint position = object_get_position_in_list (obj); + + selection->nr_rows++; + if (position < selection->nr_rows - 1) { + gtk_list_store_insert (selection->store, &iter, position); + } else { + gtk_list_store_append (selection->store, &iter); + } + gtk_list_store_set (selection->store, &iter, 0, obj, -1); +} + +static gboolean +selection_find_object(Selection_t *selection, Object_t *lookup, + GtkTreeIter *iter) +{ + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (selection->store), + iter)) { + do { + Object_t *obj; + + gtk_tree_model_get (GTK_TREE_MODEL(selection->store), iter, 0, + &obj, -1); + if (obj == lookup) + return TRUE; + + } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (selection->store), + iter)); + } + return FALSE; +} + +static void +object_updated_cb(Object_t *obj, gpointer data) +{ + Selection_t *selection = (Selection_t*) data; + GtkTreeIter iter; + + if (selection_find_object (selection, obj, &iter)) { + GtkTreePath *path; + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (selection->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (selection->store), path, + &iter); + } +} + +static void +object_removed_cb(Object_t *obj, gpointer data) +{ + Selection_t *selection = (Selection_t*) data; + GtkTreeIter iter; + + if (selection_find_object (selection, obj, &iter)) { + gtk_list_store_remove (GTK_LIST_STORE (selection->store), &iter); + } +} + +static void +object_selected_cb(Object_t *obj, gpointer data) +{ + Selection_t *selection = (Selection_t*) data; + gint position = object_get_position_in_list (obj); + selection_set_selected (selection, position); +} + +static void +object_moved_cb(Object_t *obj, gpointer data) +{ + Selection_t *selection = (Selection_t*) data; + selection->select_lock = TRUE; +} + +static const GtkTargetEntry target_table[] = +{ + {"STRING", 0, 1 }, + {"text/plain", 0, 2 } +}; + +static Object_t* +selection_get_object (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + Object_t *obj; + gtk_tree_model_get (tree_model, iter, 0, &obj, -1); + return obj; +} + +static void +handle_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, + GtkSelectionData *data, guint info, guint time) +{ + gboolean success = FALSE; + + if (gtk_selection_data_get_length (data) >= 0 && + gtk_selection_data_get_format (data) == 8) + { + GtkTreePath *path; + + if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, + &path, NULL, NULL, NULL)) + { + GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); + GtkTreeIter iter; + + if (gtk_tree_model_get_iter (model, &iter, path)) + { + Object_t *obj = selection_get_object (model, &iter); + + if (!obj->locked) + { + command_list_add(edit_object_command_new (obj)); + object_set_url (obj, (const gchar *) gtk_selection_data_get_data (data)); + object_emit_update_signal (obj); + success = TRUE; + } + } + gtk_tree_path_free (path); + } + } + gtk_drag_finish(context, success, FALSE, time); +} + +static void +render_image (GtkTreeViewColumn *column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +{ + Object_t *obj = selection_get_object (tree_model, iter); + g_object_set(cell, "stock-id", object_get_stock_icon_name(obj), NULL); +} + +static void +render_nr (GtkTreeViewColumn *column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +{ + Object_t *obj = selection_get_object (tree_model, iter); + gchar *scratch; + + scratch = g_strdup_printf ("%d", object_get_position_in_list (obj) + 1); + g_object_set (cell, "text", scratch, NULL); + g_free (scratch); +} + +static void +render_url (GtkTreeViewColumn *column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +{ + Object_t *obj = selection_get_object (tree_model, iter); + g_object_set (cell, "text", obj->url, NULL); +} + +static void +render_target (GtkTreeViewColumn *column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +{ + Object_t *obj = selection_get_object (tree_model, iter); + g_object_set (cell, "text", obj->target, NULL); +} + +static void +render_comment (GtkTreeViewColumn *column, GtkCellRenderer *cell, + GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +{ + Object_t *obj = selection_get_object (tree_model, iter); + g_object_set (cell, "text", obj->comment, NULL); +} + +Selection_t* +make_selection(ObjectList_t *object_list) +{ + Selection_t *data = g_new(Selection_t, 1); + GtkWidget *swin, *frame, *hbox; + GtkWidget *toolbar; + GtkWidget *list; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + data->object_list = object_list; + data->selected_child = NULL; + data->is_visible = TRUE; + data->nr_rows = 0; + data->select_lock = FALSE; + data->doubleclick = FALSE; + + data->container = frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); + gtk_widget_show(frame); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + + toolbar = make_selection_toolbar (); + gtk_box_pack_start (GTK_BOX (hbox), toolbar, TRUE, TRUE, 0); + + /* Create selection */ + frame = gimp_frame_new (_("Selection")); + gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); + gtk_widget_show (frame); + + data->store = gtk_list_store_new (1, G_TYPE_POINTER); + data->list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (data->store)); + list = data->list; + g_object_unref (data->store); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (N_("#"), + renderer, + NULL); + gtk_tree_view_column_set_cell_data_func (column, renderer, + render_nr, data, NULL); + gtk_tree_view_column_set_min_width (column, 16); + gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_column_set_alignment (column, 0.5); + gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("URL")); + + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start(column, renderer, FALSE); + gtk_tree_view_column_set_cell_data_func (column, renderer, + render_image, data, NULL); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_cell_data_func (column, renderer, render_url, data, + NULL); + gtk_tree_view_column_set_min_width (column, 80); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_column_set_alignment (column, 0.5); + + gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("ALT Text"), renderer, + NULL); + gtk_tree_view_column_set_cell_data_func (column, renderer, render_comment, + data, NULL); + gtk_tree_view_column_set_min_width (column, 64); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_column_set_alignment (column, 0.5); + gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Target"), renderer, + NULL); + gtk_tree_view_column_set_cell_data_func (column, renderer, + render_target, data, NULL); + gtk_tree_view_column_set_min_width (column, 64); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_column_set_alignment (column, 0.5); + gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); + + + /* Create scrollable window */ + swin = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_size_request (swin, 16 + 80 + 2 * 64 + 16, -1); + gtk_container_add (GTK_CONTAINER(frame), swin); + gtk_widget_show (swin); + + gtk_container_add (GTK_CONTAINER (swin), list); + gtk_widget_show (list); + + /* Drop support */ + gtk_drag_dest_set (list, GTK_DEST_DEFAULT_ALL, target_table, 2, + GDK_ACTION_COPY); + g_signal_connect (list, "drag-data-received", G_CALLBACK(handle_drop), NULL); + + /* For handling doubleclick */ + + g_signal_connect (list, "button-press-event", + G_CALLBACK(button_press_cb), data); + g_signal_connect (list, "button-release-event", + G_CALLBACK(button_release_cb), data); + + /* Callbacks we are interested in */ + data->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list)); + gtk_tree_selection_set_mode (data->selection, GTK_SELECTION_MULTIPLE); + g_signal_connect (data->selection, "changed", G_CALLBACK(changed_cb), data); + + /* Set object list callbacks we're interested in */ + object_list_add_add_cb (object_list, object_added_cb, data); + object_list_add_update_cb (object_list, object_updated_cb, data); + object_list_add_remove_cb (object_list, object_removed_cb, data); + object_list_add_select_cb (object_list, object_selected_cb, data); + object_list_add_move_cb (object_list, object_moved_cb, data); + + return data; +} + +void +selection_toggle_visibility(Selection_t *selection) +{ + /* Toggle */ + selection->is_visible = ! selection->is_visible; + + /* Adapt to new state */ + gtk_widget_set_visible (selection->container, + selection->is_visible); +} + +void +selection_freeze(Selection_t *selection) +{ +} + +void +selection_thaw(Selection_t *selection) +{ +} diff --git a/plug-ins/imagemap/imap_selection.h b/plug-ins/imagemap/imap_selection.h new file mode 100644 index 0000000..cb13afb --- /dev/null +++ b/plug-ins/imagemap/imap_selection.h @@ -0,0 +1,64 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_SELECTION_H +#define _IMAP_SELECTION_H + +#include "imap_command.h" +#include "imap_object.h" + +typedef struct { + GtkListStore *store; + GtkTreeSelection *selection; + + GtkWidget *container; + GtkWidget *list; + GtkWidget *selected_child; + ObjectList_t *object_list; + gint selected_row; + gint nr_rows; + gboolean is_visible; + gboolean select_lock; + gboolean doubleclick; + + CommandFactory_t cmd_move_up; + CommandFactory_t cmd_move_down; + CommandFactory_t cmd_delete; + CommandFactory_t cmd_edit; +} Selection_t; + +Selection_t *make_selection(ObjectList_t *list); +void selection_toggle_visibility(Selection_t *selection); +void selection_freeze(Selection_t *selection); +void selection_thaw(Selection_t *selection); + +#define selection_set_move_up_command(selection, command) \ + ((selection)->cmd_move_up = (command)) +#define selection_set_move_down_command(selection, command) \ + ((selection)->cmd_move_down = (command)) +#define selection_set_delete_command(selection, command) \ + ((selection)->cmd_delete = (command)) +#define selection_set_edit_command(selection, command) \ + ((selection)->cmd_edit = (command)) + +#endif /* _IMAP_SELECTION_H */ + diff --git a/plug-ins/imagemap/imap_settings.c b/plug-ins/imagemap/imap_settings.c new file mode 100644 index 0000000..10a4a33 --- /dev/null +++ b/plug-ins/imagemap/imap_settings.c @@ -0,0 +1,188 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_browse.h" +#include "imap_main.h" +#include "imap_settings.h" +#include "imap_string.h" +#include "imap_table.h" + +#include "libgimp/stdplugins-intl.h" + +typedef struct { + DefaultDialog_t *dialog; + BrowseWidget_t *imagename; + GtkWidget *filename; + GtkWidget *title; + GtkWidget *author; + GtkWidget *default_url; + GtkWidget *ncsa; + GtkWidget *cern; + GtkWidget *csim; + GtkTextBuffer *description; +} SettingsDialog_t; + +static MapFormat_t _map_format = CSIM; + +static void +settings_ok_cb(gpointer data) +{ + SettingsDialog_t *param = (SettingsDialog_t*) data; + MapInfo_t *info = get_map_info(); + gchar *description; + GtkTextIter start, end; + + g_strreplace(&info->image_name, gtk_entry_get_text( + GTK_ENTRY(param->imagename->file))); + g_strreplace(&info->title, gtk_entry_get_text(GTK_ENTRY(param->title))); + g_strreplace(&info->author, gtk_entry_get_text(GTK_ENTRY(param->author))); + g_strreplace(&info->default_url, + gtk_entry_get_text(GTK_ENTRY(param->default_url))); + gtk_text_buffer_get_bounds(param->description, &start, &end); + description = gtk_text_buffer_get_text(param->description, &start, &end, + FALSE); + g_strreplace(&info->description, description); + g_free(description); + + info->map_format = _map_format; +} + +static void +type_toggled_cb(GtkWidget *widget, gpointer data) +{ + if (gtk_widget_get_state (widget) & GTK_STATE_SELECTED) + _map_format = (MapFormat_t) data; +} + +static SettingsDialog_t* +create_settings_dialog(void) +{ + SettingsDialog_t *data = g_new(SettingsDialog_t, 1); + GtkWidget *table, *view, *frame, *hbox, *label, *swin; + DefaultDialog_t *dialog; + + dialog = data->dialog = make_default_dialog(_("Settings for this Mapfile")); + default_dialog_set_ok_cb(dialog, settings_ok_cb, (gpointer) data); + table = default_dialog_add_table(dialog, 9, 2); + + create_label_in_table(table, 0, 0, _("Filename:")); + data->filename = create_label_in_table(table, 0, 1, ""); + + create_label_in_table(table, 1, 0, _("Image name:")); + data->imagename = browse_widget_new(_("Select Image File")); + gtk_table_attach_defaults(GTK_TABLE(table), data->imagename->hbox, 1, 2, + 1, 2); + + label = create_label_in_table(table, 2, 0, _("_Title:")); + data->title = create_entry_in_table(table, label, 2, 1); + label = create_label_in_table(table, 3, 0, _("Aut_hor:")); + data->author = create_entry_in_table(table, label, 3, 1); + label = create_label_in_table(table, 4, 0, _("Default _URL:")); + data->default_url = create_entry_in_table(table, label, 4, 1); + label = create_label_in_table(table, 5, 0, _("_Description:")); + + data->description = gtk_text_buffer_new(NULL); + + view = gtk_text_view_new_with_buffer(data->description); + gtk_widget_set_size_request(view, -1, 128); + gtk_widget_show(view); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), view); + + swin = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), + GTK_SHADOW_IN); + gtk_table_attach(GTK_TABLE(table), swin, 1, 2, 5, 8, + GTK_EXPAND | GTK_SHRINK | GTK_FILL, + GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + gtk_widget_show(swin); + gtk_container_add(GTK_CONTAINER(swin), view); + + frame = gimp_frame_new(_("Map File Format")); + gtk_widget_show(frame); + gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 2, 9, 10); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + + data->ncsa = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "_NCSA"); + g_signal_connect(data->ncsa, "toggled", + G_CALLBACK(type_toggled_cb), (gpointer) NCSA); + gtk_box_pack_start(GTK_BOX(hbox), data->ncsa, FALSE, FALSE, 0); + gtk_widget_show(data->ncsa); + + data->cern = gtk_radio_button_new_with_mnemonic_from_widget( + GTK_RADIO_BUTTON(data->ncsa), "C_ERN"); + g_signal_connect(data->cern, "toggled", + G_CALLBACK(type_toggled_cb), (gpointer) CERN); + gtk_box_pack_start(GTK_BOX(hbox), data->cern, FALSE, FALSE, 0); + gtk_widget_show(data->cern); + + data->csim = gtk_radio_button_new_with_mnemonic_from_widget( + GTK_RADIO_BUTTON(data->cern), "C_SIM"); + g_signal_connect(data->csim, "toggled", + G_CALLBACK(type_toggled_cb), (gpointer) CSIM); + gtk_box_pack_start(GTK_BOX(hbox), data->csim, FALSE, FALSE, 0); + gtk_widget_show(data->csim); + + return data; +} + +void +do_settings_dialog(void) +{ + static SettingsDialog_t *dialog; + const char *filename = get_filename(); + MapInfo_t *info = get_map_info(); + + if (!dialog) + dialog = create_settings_dialog(); + + if (!filename) + filename = _("<Untitled>"); + + gtk_label_set_text(GTK_LABEL(dialog->filename), filename); + browse_widget_set_filename(dialog->imagename, info->image_name); + gtk_entry_set_text(GTK_ENTRY(dialog->title), info->title); + gtk_entry_set_text(GTK_ENTRY(dialog->author), info->author); + gtk_entry_set_text(GTK_ENTRY(dialog->default_url), info->default_url); + + if (info->map_format == NCSA) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->ncsa), TRUE); + else if (info->map_format == CERN) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->cern), TRUE); + else + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->csim), TRUE); + + gtk_widget_grab_focus(dialog->imagename->file); + default_dialog_show(dialog->dialog); + + gtk_text_buffer_set_text (dialog->description, info->description, -1); +} diff --git a/plug-ins/imagemap/imap_settings.h b/plug-ins/imagemap/imap_settings.h new file mode 100644 index 0000000..4b375d6 --- /dev/null +++ b/plug-ins/imagemap/imap_settings.h @@ -0,0 +1,28 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_SETTINGS_H +#define _IMAP_SETTINGS_H + +void do_settings_dialog(void); + +#endif /* _IMAP_SETTINGS_H */ diff --git a/plug-ins/imagemap/imap_source.c b/plug-ins/imagemap/imap_source.c new file mode 100644 index 0000000..40ba1b7 --- /dev/null +++ b/plug-ins/imagemap/imap_source.c @@ -0,0 +1,91 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdarg.h> +#include <stdio.h> + +#include <gtk/gtk.h> + +#include "imap_default_dialog.h" +#include "imap_main.h" +#include "imap_source.h" + +#include "libgimp/stdplugins-intl.h" + +static void save_to_view (GtkTextBuffer *buffer, + const char *format, + ...) G_GNUC_PRINTF(2,3); + +static void +save_to_view(GtkTextBuffer *buffer, const char* format, ...) +{ + va_list ap; + char scratch[1024]; + GtkTextIter iter; + + va_start(ap, format); + vsprintf(scratch, format, ap); + va_end(ap); + + gtk_text_buffer_get_end_iter(buffer, &iter); + gtk_text_buffer_insert(buffer, &iter, scratch, -1); +} + +void +do_source_dialog(void) +{ + static DefaultDialog_t *dialog; + static GtkWidget *text; + static GtkTextBuffer *buffer; + + if (!dialog) + { + GtkWidget *swin; + + dialog = make_default_dialog(_("View Source")); + default_dialog_hide_cancel_button(dialog); + default_dialog_hide_apply_button(dialog); + + buffer = gtk_text_buffer_new(NULL); + + text = gtk_text_view_new_with_buffer(buffer); + gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); + gtk_widget_show(text); + + swin = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), + GTK_SHADOW_IN); + gtk_widget_set_size_request(swin, 400, 300); + gtk_box_pack_start(GTK_BOX(dialog->vbox), swin, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_widget_show(swin); + gtk_container_add(GTK_CONTAINER(swin), text); + } + gtk_text_buffer_set_text(buffer, "", -1); + dump_output(buffer, (OutputFunc_t) save_to_view); + + default_dialog_show(dialog); +} diff --git a/plug-ins/imagemap/imap_source.h b/plug-ins/imagemap/imap_source.h new file mode 100644 index 0000000..a090515 --- /dev/null +++ b/plug-ins/imagemap/imap_source.h @@ -0,0 +1,28 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_SOURCE_H +#define _IMAP_SOURCE_H + +void do_source_dialog(void); + +#endif /* _IMAP_SOURCE_H */ diff --git a/plug-ins/imagemap/imap_statusbar.c b/plug-ins/imagemap/imap_statusbar.c new file mode 100644 index 0000000..ca4bad8 --- /dev/null +++ b/plug-ins/imagemap/imap_statusbar.c @@ -0,0 +1,153 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdarg.h> +#include <stdio.h> + +#include "libgimp/gimp.h" +#include "libgimp/gimpui.h" + +#include "imap_statusbar.h" +#include "imap_stock.h" + +StatusBar_t* +make_statusbar(GtkWidget *main_vbox, GtkWidget *window) +{ + StatusBar_t *statusbar = g_new(StatusBar_t, 1); + GtkWidget *hbox, *iconw; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); + gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0); + + /* Status info */ + statusbar->status = gtk_statusbar_new(); + statusbar->status_id = gtk_statusbar_get_context_id( + GTK_STATUSBAR(statusbar->status), "general_status"); + gtk_box_pack_start(GTK_BOX(hbox), statusbar->status, TRUE, TRUE, 0); + gtk_widget_show(statusbar->status); + + /* (x, y) coordinate */ + iconw = gtk_image_new_from_stock(IMAP_STOCK_COORD, + GTK_ICON_SIZE_SMALL_TOOLBAR); + + gtk_box_pack_start(GTK_BOX(hbox), iconw, FALSE, FALSE, 10); + gtk_widget_show(iconw); + + statusbar->xy = gtk_entry_new(); + gtk_widget_set_size_request(statusbar->xy, 96, -1); + gtk_editable_set_editable(GTK_EDITABLE(statusbar->xy), FALSE); + gtk_widget_set_can_focus (statusbar->xy, FALSE); + gtk_box_pack_start(GTK_BOX(hbox), statusbar->xy, FALSE, FALSE, 0); + gtk_widget_show(statusbar->xy); + + /* Dimension info */ + iconw = gtk_image_new_from_stock(IMAP_STOCK_DIMENSION, + GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_box_pack_start(GTK_BOX(hbox), iconw, FALSE, FALSE, 10); + gtk_widget_show(iconw); + + statusbar->dimension = gtk_entry_new(); + gtk_widget_set_size_request(statusbar->dimension, 96, -1); + gtk_editable_set_editable(GTK_EDITABLE(statusbar->dimension), FALSE); + gtk_widget_set_can_focus (statusbar->dimension, FALSE); + gtk_box_pack_start(GTK_BOX(hbox), statusbar->dimension, FALSE, FALSE, 0); + gtk_widget_show(statusbar->dimension); + + /* Zoom info */ + statusbar->zoom = gtk_statusbar_new(); + gtk_widget_set_size_request(statusbar->zoom, 48, -1); + statusbar->zoom_id = gtk_statusbar_get_context_id( + GTK_STATUSBAR(statusbar->zoom), "zoom_status"); + gtk_box_pack_start(GTK_BOX(hbox), statusbar->zoom, FALSE, FALSE, 5); + gtk_widget_show(statusbar->zoom); + + gtk_widget_show(hbox); + + return statusbar; +} + +void +statusbar_set_status(StatusBar_t *statusbar, const gchar *format, ...) +{ + va_list ap; + char *str; + + va_start(ap, format); + str = g_strdup_vprintf (format, ap); + va_end(ap); + + statusbar_clear_status(statusbar); + statusbar->message_id = + gtk_statusbar_push(GTK_STATUSBAR(statusbar->status), + statusbar->status_id, str); + g_free (str); +} + +void +statusbar_clear_status(StatusBar_t *statusbar) +{ + if (statusbar->message_id) + gtk_statusbar_remove(GTK_STATUSBAR(statusbar->status), + statusbar->status_id, + statusbar->message_id); +} + +void +statusbar_set_xy(StatusBar_t *statusbar, gint x, gint y) +{ + char scratch[16]; + + sprintf(scratch, "%d, %d", (int) x, (int) y); + gtk_entry_set_text(GTK_ENTRY(statusbar->xy), scratch); +} + +void statusbar_clear_xy(StatusBar_t *statusbar) +{ + gtk_entry_set_text(GTK_ENTRY(statusbar->xy), ""); +} + +void +statusbar_set_dimension(StatusBar_t *statusbar, gint w, gint h) +{ + gchar scratch[16]; + + g_snprintf (scratch, sizeof (scratch), "%d × %d", (gint) w, (gint) h); + gtk_entry_set_text(GTK_ENTRY(statusbar->dimension), scratch); +} + +void +statusbar_clear_dimension(StatusBar_t *statusbar) +{ + gtk_entry_set_text(GTK_ENTRY(statusbar->dimension), ""); +} + +void +statusbar_set_zoom(StatusBar_t *statusbar, gint factor) +{ + char scratch[16]; + + sprintf(scratch, "1:%d", factor); + gtk_statusbar_push(GTK_STATUSBAR(statusbar->zoom), statusbar->zoom_id, + scratch); +} diff --git a/plug-ins/imagemap/imap_statusbar.h b/plug-ins/imagemap/imap_statusbar.h new file mode 100644 index 0000000..6b1a87b --- /dev/null +++ b/plug-ins/imagemap/imap_statusbar.h @@ -0,0 +1,47 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2003 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_STATUSBAR_H +#define _IMAP_STATUSBAR_H + +typedef struct { + GtkWidget *status; + GtkWidget *xy; + GtkWidget *dimension; + GtkWidget *zoom; + + gint status_id; + gint message_id; + + gint zoom_id; +} StatusBar_t; + +StatusBar_t *make_statusbar(GtkWidget *main_vbox, GtkWidget *window); +void statusbar_set_status(StatusBar_t *statusbar, const gchar *format, ...) G_GNUC_PRINTF(2,3); +void statusbar_clear_status(StatusBar_t *statusbar); +void statusbar_set_xy(StatusBar_t *statusbar, gint x, gint y); +void statusbar_clear_xy(StatusBar_t *statusbar); +void statusbar_set_dimension(StatusBar_t *statusbar, gint w, gint h); +void statusbar_clear_dimension(StatusBar_t *statusbar); +void statusbar_set_zoom(StatusBar_t *statusbar, gint factor); + +#endif /* _IMAP_STATUSBAR_H */ diff --git a/plug-ins/imagemap/imap_stock.c b/plug-ins/imagemap/imap_stock.c new file mode 100644 index 0000000..4c3fedd --- /dev/null +++ b/plug-ins/imagemap/imap_stock.c @@ -0,0 +1,89 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2005 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gtk/gtk.h> + +#include "imap_stock.h" + +#include "images/imap-stock-pixbufs.h" + +static GtkIconFactory *imap_icon_factory = NULL; + +static GtkStockItem imap_stock_items[] = +{ + { IMAP_STOCK_CIRCLE, NULL, 0, 0, NULL }, + { IMAP_STOCK_COORD, NULL, 0, 0, NULL }, + { IMAP_STOCK_DIMENSION, NULL, 0, 0, NULL }, + { IMAP_STOCK_JAVA, NULL, 0, 0, NULL }, + { IMAP_STOCK_POLYGON, NULL, 0, 0, NULL }, + { IMAP_STOCK_RECTANGLE, NULL, 0, 0, NULL }, + { IMAP_STOCK_TO_BACK, NULL, 0, 0, NULL }, + { IMAP_STOCK_TO_FRONT, NULL, 0, 0, NULL } + }; + +static void +add_stock_icon (const gchar *stock_id, + const guint8 *inline_data) +{ + GtkIconSource *source; + GtkIconSet *set; + GdkPixbuf *pixbuf; + + source = gtk_icon_source_new (); + + gtk_icon_source_set_size (source, GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_icon_source_set_size_wildcarded (source, TRUE); + + pixbuf = gdk_pixbuf_new_from_inline (-1, inline_data, FALSE, NULL); + gtk_icon_source_set_pixbuf (source, pixbuf); + g_object_unref (pixbuf); + + set = gtk_icon_set_new (); + + gtk_icon_set_add_source (set, source); + gtk_icon_source_free (source); + + gtk_icon_factory_add (imap_icon_factory, stock_id, set); + + gtk_icon_set_unref (set); +} + +void +init_stock_icons (void) +{ + imap_icon_factory = gtk_icon_factory_new (); + + add_stock_icon (IMAP_STOCK_CIRCLE, stock_circle); + add_stock_icon (IMAP_STOCK_COORD, stock_coord); + add_stock_icon (IMAP_STOCK_DIMENSION, stock_dimension); + add_stock_icon (IMAP_STOCK_JAVA, stock_java); + add_stock_icon (IMAP_STOCK_POLYGON, stock_polygon); + add_stock_icon (IMAP_STOCK_RECTANGLE, stock_rectangle); + add_stock_icon (IMAP_STOCK_TO_BACK, stock_to_back); + add_stock_icon (IMAP_STOCK_TO_FRONT, stock_to_front); + + gtk_icon_factory_add_default (imap_icon_factory); + + gtk_stock_add_static (imap_stock_items, G_N_ELEMENTS (imap_stock_items)); +} diff --git a/plug-ins/imagemap/imap_stock.h b/plug-ins/imagemap/imap_stock.h new file mode 100644 index 0000000..5587b91 --- /dev/null +++ b/plug-ins/imagemap/imap_stock.h @@ -0,0 +1,39 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2004 Maurits Rijk m.rijk@chello.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_STOCK_H +#define _IMAP_STOCK_H + +#define IMAP_STOCK_ARROW "imap-arrow" +#define IMAP_STOCK_CIRCLE "imap-circle" +#define IMAP_STOCK_COORD "imap-coord" +#define IMAP_STOCK_DIMENSION "imap-dimension" +#define IMAP_STOCK_JAVA "imap-java" +#define IMAP_STOCK_LINK "imap-link" +#define IMAP_STOCK_POLYGON "imap-polygon" +#define IMAP_STOCK_RECTANGLE "imap-rectangle" +#define IMAP_STOCK_TO_BACK "imap-to-back" +#define IMAP_STOCK_TO_FRONT "imap-to-front" + +void init_stock_icons(void); + +#endif /* _IMAP_STOCK_H */ diff --git a/plug-ins/imagemap/imap_string.c b/plug-ins/imagemap/imap_string.c new file mode 100644 index 0000000..5f3b31c --- /dev/null +++ b/plug-ins/imagemap/imap_string.c @@ -0,0 +1,37 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <glib.h> + +#include "imap_string.h" + +gchar* +g_strreplace(gchar **old_str, const gchar *new_str) +{ + if (*old_str != new_str) { + g_free(*old_str); + *old_str = g_strdup(new_str); + } + return *old_str; +} diff --git a/plug-ins/imagemap/imap_string.h b/plug-ins/imagemap/imap_string.h new file mode 100644 index 0000000..c878131 --- /dev/null +++ b/plug-ins/imagemap/imap_string.h @@ -0,0 +1,28 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_STRING_H +#define _IMAP_STRING_H + +gchar *g_strreplace(gchar **old_str, const gchar *new_str); + +#endif /* _IMAP_STRING_H */ diff --git a/plug-ins/imagemap/imap_table.c b/plug-ins/imagemap/imap_table.c new file mode 100644 index 0000000..d72a478 --- /dev/null +++ b/plug-ins/imagemap/imap_table.c @@ -0,0 +1,81 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <libgimp/gimp.h> +#include <libgimp/gimpui.h> + +#include "imap_table.h" + +static GtkWidget* +add_widget_to_table(GtkWidget *table, int row, int col, GtkWidget *w) +{ + gtk_table_attach_defaults(GTK_TABLE(table), w, col, col + 1, row, row + 1); + gtk_widget_show(w); + return w; +} + +GtkWidget* +create_spin_button_in_table(GtkWidget *table, GtkWidget *label, + int row, int col, int value, int min, int max) +{ + GtkObject *adj = gtk_adjustment_new(value, min, max, 1, 10, 0); + GtkWidget *button = gimp_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0); + gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(button), TRUE); + if (label) + gtk_label_set_mnemonic_widget(GTK_LABEL(label), button); + return add_widget_to_table(table, row, col, button); +} + +GtkWidget* +create_check_button_in_table(GtkWidget *table, int row, int col, + const char *text) +{ + GtkWidget *button = gtk_check_button_new_with_mnemonic(text); + return add_widget_to_table(table, row, col, button); +} + +GtkWidget* +create_radio_button_in_table(GtkWidget *table, GSList *group, + int row, int col, const char *text) +{ + GtkWidget *button = gtk_radio_button_new_with_mnemonic(group, text); + return add_widget_to_table(table, row, col, button); +} + +GtkWidget* +create_label_in_table(GtkWidget *table, int row, int col, const char *text) +{ + GtkWidget *label = gtk_label_new_with_mnemonic(text); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + return add_widget_to_table(table, row, col, label); +} + +GtkWidget* +create_entry_in_table(GtkWidget *table, GtkWidget *label, int row, int col) +{ + GtkWidget *entry = gtk_entry_new(); + if (label) + gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); + return add_widget_to_table(table, row, col, entry); +} diff --git a/plug-ins/imagemap/imap_table.h b/plug-ins/imagemap/imap_table.h new file mode 100644 index 0000000..5b6a855 --- /dev/null +++ b/plug-ins/imagemap/imap_table.h @@ -0,0 +1,39 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-2002 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_TABLE_H +#define _IMAP_TABLE_H + +GtkWidget *create_spin_button_in_table(GtkWidget *table, GtkWidget *label, + int row, int col, + int value, int min, int max); +GtkWidget *create_check_button_in_table(GtkWidget *table, int row, int col, + const char *text); +GtkWidget *create_radio_button_in_table(GtkWidget *table, GSList *group, + int row, int col, const char *text); +GtkWidget *create_label_in_table(GtkWidget *table, int row, int col, + const char *text); +GtkWidget *create_entry_in_table(GtkWidget *table, GtkWidget *label, int row, + int col); + +#endif /* _IMAP_TABLE_H */ + diff --git a/plug-ins/imagemap/imap_taglist.c b/plug-ins/imagemap/imap_taglist.c new file mode 100644 index 0000000..9b03c9d --- /dev/null +++ b/plug-ins/imagemap/imap_taglist.c @@ -0,0 +1,126 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <stdio.h> + +#include <glib.h> + +#include "imap_string.h" +#include "imap_taglist.h" + +static Tag_t* +tag_create(const gchar *name, const gchar *value) +{ + Tag_t *tag = g_new(Tag_t, 1); + tag->name = g_strdup(name); + tag->value = g_strdup(value); + return tag; +} + +static Tag_t* +tag_clone(Tag_t *src) +{ + return tag_create(src->name, src->value); +} + +static void +tag_destruct(Tag_t *tag) +{ + g_free(tag->name); + g_free(tag->value); + g_free(tag); +} + +static void +tag_write(Tag_t *tag) +{ + printf("\"%s\"=\"%s\"\n", tag->name, tag->value); +} + +TagList_t* +taglist_create(void) +{ + TagList_t *tlist = g_new(TagList_t, 1); + tlist->list = NULL; + return tlist; +} + +TagList_t* +taglist_clone(TagList_t *src) +{ + return taglist_copy(src, taglist_create()); +} + +static void +taglist_remove_all(TagList_t *tlist) +{ + GList *p; + for (p = tlist->list; p; p = p->next) + tag_destruct((Tag_t*) p->data); + g_list_free(tlist->list); + tlist->list = NULL; +} + +TagList_t* +taglist_copy(TagList_t *src, TagList_t *des) +{ + GList *p; + + taglist_remove_all(des); + for (p = src->list; p; p = p->next) + des->list = g_list_append(des->list, tag_clone((Tag_t*) p->data)); + return des; +} + +void +taglist_destruct(TagList_t *tlist) +{ + taglist_remove_all(tlist); + g_free(tlist); +} + +void +taglist_set(TagList_t *tlist, const gchar *name, const gchar *value) +{ + GList *p; + Tag_t *tag; + + for (p = tlist->list; p; p = p->next) { + tag = (Tag_t*) p->data; + if (!g_ascii_strcasecmp(tag->name, name)) { + g_strreplace(&tag->value, value); + return; + } + } + /* Tag not found, add a new tag */ + tlist->list = g_list_append(tlist->list, tag_create(name, value)); +} + +void +taglist_write(TagList_t *tlist) +{ + GList *p; + for (p = tlist->list; p; p = p->next) + tag_write((Tag_t*) p->data); +} diff --git a/plug-ins/imagemap/imap_taglist.h b/plug-ins/imagemap/imap_taglist.h new file mode 100644 index 0000000..c68ef51 --- /dev/null +++ b/plug-ins/imagemap/imap_taglist.h @@ -0,0 +1,44 @@ +/* + * This is a plug-in for GIMP. + * + * Generates clickable image maps. + * + * Copyright (C) 1998-1999 Maurits Rijk lpeek.mrijk@consunet.nl + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +#ifndef _IMAP_TAGLIST_H +#define _IMAP_TAGLIST_H + +#include <glib.h> + +typedef struct { + gchar *name; + gchar *value; +} Tag_t; + +typedef struct { + GList *list; +} TagList_t; + +TagList_t *taglist_create(void); +TagList_t *taglist_clone(TagList_t *src); +TagList_t *taglist_copy(TagList_t *src, TagList_t *des); +void taglist_destruct(TagList_t *tlist); +void taglist_set(TagList_t *tlist, const gchar *id, const gchar *value); +void taglist_write(TagList_t *tlist); + +#endif /* _IMAP_TAGLIST_H */ |