diff --git a/m4/geany-lib.m4 b/m4/geany-lib.m4 index 90323342..3e63b09b 100644 --- a/m4/geany-lib.m4 +++ b/m4/geany-lib.m4 @@ -24,25 +24,14 @@ dnl `__attribute__((visibility(...)))` extension and use it if so. ]) CFLAGS="${libgeany_backup_cflags}" -dnl Try and see if we can use our list of dynamically exported symbols with -dnl the linker and use it if so. - AC_MSG_CHECKING([whether linker supports --dynamic-list]) - libgeany_backup_ldflags=$LDFLAGS - LDFLAGS=-Wl,--dynamic-list="${srcdir}/src/dynamicsymbols.list" - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([], []) - ], [ - LIBGEANY_LIBS="-Wl,--dynamic-list=\"\$(top_srcdir)/src/dynamicsymbols.list\"" - AC_MSG_RESULT([yes]) - ], [ - LIBGEANY_LIBS="" - AC_MSG_RESULT([no]) - ]) - LDFLAGS="${libgeany_backup_ldflags}" - - LIBGEANY_LIBS="${LIBGEANY_LIBS} -version-info ${libgeany_current}:${libgeany_revision}:${libgeany_age}" + LIBGEANY_LIBS="-version-info ${libgeany_current}:${libgeany_revision}:${libgeany_age}" AC_SUBST([LIBGEANY_CFLAGS]) AC_SUBST([LIBGEANY_LIBS]) +dnl Check for utilities needed to do codegen + AC_PATH_PROG([SORT], [sort], [ + AC_MSG_ERROR([The 'sort' utility is required, is it installed?])]) + AC_PATH_PROG([UNIQ], [uniq], [ + AC_MSG_ERROR([The 'uniq' utility is required, is it installed?])]) ]) diff --git a/scripts/dynamicsymbols.py b/scripts/dynamicsymbols.py deleted file mode 100755 index 6a8b4fd9..00000000 --- a/scripts/dynamicsymbols.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -""" -Script to parse GtkBuilder XML file for signal handler references and list -them in a linker file for which symbols to dynamically export. -""" - -import optparse -import os -import re -import sys -from xml.etree import ElementTree as ET - -def find_handlers(xml_filename, excludes=[]): - def is_excluded(name, excludes): - for exclude in excludes: - m = re.match(exclude, name) - if m: - return True - return False - - tree = ET.parse(xml_filename) - root = tree.getroot() - handlers = [] - signals = root.findall(".//signal") - - for signal in signals: - handler = signal.attrib["handler"] - if not is_excluded(handler, excludes): - handlers.append(handler) - - return sorted(handlers) - -def write_dynamic_list(handlers, output_file): - output_file.write("""\ -/* This file was auto-generated by the `%s' script, do not edit. */ -{ -""" % os.path.basename(__file__)) - for handler in handlers: - output_file.write("\t%s;\n" % handler) - output_file.write("};\n") - -def main(args): - p = optparse.OptionParser(usage="%prog [-o FILE] XMLFILE") - p.add_option("-o", "--output", metavar="FILE", dest="output_file", - default="-", help="write the output to this file (default `-' for stdin)") - - opts, args = p.parse_args(args) - - output_file = None - try: - if opts.output_file == "-": - output_file = sys.stdout - else: - output_file = open(opts.output_file, 'w') - - args = args[1:] - if len(args) == 0: - p.error("invalid XMLFILE argument, expecting a filename, got none") - elif len(args) > 1: - p.error("too many XMLFILE arguments, expecting a single filename") - - handlers = find_handlers(args[0], ["gtk_.+"]) - write_dynamic_list(handlers, output_file) - - finally: - if output_file is not None and output_file is not sys.stdout: - output_file.close() - - return 0 - -if __name__ == "__main__": - sys.exit(main(sys.argv)) diff --git a/src/Makefile.am b/src/Makefile.am index 636e636b..78c5436c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,7 @@ EXTRA_DIST = \ pluginprivate.h \ projectprivate.h \ makefile.win32 \ - $(top_srcdir)/src/dynamicsymbols.list + $(srcdir)/signalconn.c.in bin_PROGRAMS = geany lib_LTLIBRARIES = libgeany.la @@ -173,10 +173,20 @@ AM_CFLAGS = -DGEANY_DATADIR=\""$(datadir)"\" \ clean-local: -# Helper rule to rebuild the dynamicsymbols.list file when handlers are -# added to data/geany.glade. Run `make dynamic-symbols' from the src builddir. -$(top_srcdir)/src/dynamicsymbols.list: $(top_srcdir)/data/geany.glade - -python $(top_srcdir)/scripts/dynamicsymbols.py -o $@ $(top_srcdir)/data/geany.glade -dynamic-symbols: $(top_srcdir)/src/dynamicsymbols.list - endif + +callbacks.c: signalconn.c + +glade_file=$(top_srcdir)/data/geany.glade +template_file=$(srcdir)/signalconn.c.in + +signalconn.c: $(glade_file) $(template_file) + $(AM_V_GEN)( \ + echo '/* This file is auto-generated, do not edit. */' && \ + $(SED) -n '/@callback_map@/q;p' "$(template_file)" && \ + $(SED) -n 's/^.*handler="\([^"]\+\)".*$$/\tg_hash_table_insert(hash, "\1", G_CALLBACK(\1));/p' "$(glade_file)" \ + | $(SORT) | $(UNIQ) && \ + $(SED) -n '/@callback_map@/{:l;n;p;b l}' "$(template_file)" \ + ) > $@ || { $(RM) $@ && exit 1; } + +CLEANFILES = signalconn.c diff --git a/src/callbacks.c b/src/callbacks.c index 039f9030..4923050f 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -1988,3 +1988,5 @@ GEANY_EXPORT_SYMBOL void on_detect_width_from_file_activate(GtkMenuItem *menuite ui_document_show_hide(doc); } } + +#include "signalconn.c" diff --git a/src/callbacks.h b/src/callbacks.h index de187958..6017b1ed 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -26,6 +26,9 @@ G_BEGIN_DECLS +/* Defined in auto-generated code in signalconn.c */ +void callbacks_connect(GtkBuilder *builder); + extern gboolean ignore_callback; void on_new1_activate(GtkMenuItem *menuitem, gpointer user_data); diff --git a/src/dynamicsymbols.list b/src/dynamicsymbols.list deleted file mode 100644 index d3117f0f..00000000 --- a/src/dynamicsymbols.list +++ /dev/null @@ -1,161 +0,0 @@ -/* This file was auto-generated by the `dynamicsymbols.py' script, do not edit. */ -{ - on_button_customize_toolbar_clicked; - on_change_font1_activate; - on_clone1_activate; - on_close1_activate; - on_close_all1_activate; - on_close_other_documents1_activate; - on_comments_bsd_activate; - on_comments_changelog_activate; - on_comments_changelog_activate; - on_comments_fileheader_activate; - on_comments_fileheader_activate; - on_comments_function_activate; - on_comments_function_activate; - on_comments_gpl_activate; - on_comments_multiline_activate; - on_context_action1_activate; - on_copy1_activate; - on_copy1_activate; - on_copy_current_lines1_activate; - on_count_words1_activate; - on_cr_activate; - on_crlf_activate; - on_customize_toolbar1_activate; - on_cut1_activate; - on_cut1_activate; - on_cut_current_lines1_activate; - on_debug_messages1_activate; - on_delete1_activate; - on_delete1_activate; - on_delete_current_lines1_activate; - on_detect_type_from_file_activate; - on_detect_width_from_file_activate; - on_duplicate_line_or_selection1_activate; - on_edit1_activate; - on_escape_key_press_event; - on_file1_activate; - on_file_properties_activate; - on_find1_activate; - on_find_document_usage1_activate; - on_find_document_usage1_activate; - on_find_in_files1_activate; - on_find_next1_activate; - on_find_nextsel1_activate; - on_find_previous1_activate; - on_find_prevsel1_activate; - on_find_usage1_activate; - on_find_usage1_activate; - on_fullscreen1_toggled; - on_go_to_line_activate; - on_go_to_next_marker1_activate; - on_go_to_previous_marker1_activate; - on_goto_tag_declaration1; - on_goto_tag_definition1; - on_goto_tag_definition1; - on_help1_activate; - on_help_menu_item_bug_report_activate; - on_help_menu_item_donate_activate; - on_help_menu_item_wiki_activate; - on_help_shortcuts1_activate; - on_hide_toolbar1_activate; - on_indent_width_activate; - on_indent_width_activate; - on_indent_width_activate; - on_indent_width_activate; - on_indent_width_activate; - on_indent_width_activate; - on_indent_width_activate; - on_indent_width_activate; - on_info1_activate; - on_insert_alternative_white_space1_activate; - on_insert_alternative_white_space1_activate; - on_lf_activate; - on_line_breaking1_activate; - on_line_wrapping1_toggled; - on_load_tags1_activate; - on_mark_all1_activate; - on_markers_margin1_toggled; - on_menu_color_schemes_activate; - on_menu_comment_line1_activate; - on_menu_comments_bsd_activate; - on_menu_comments_gpl_activate; - on_menu_comments_multiline_activate; - on_menu_decrease_indent1_activate; - on_menu_fold_all1_activate; - on_menu_increase_indent1_activate; - on_menu_open_selected_file1_activate; - on_menu_open_selected_file1_activate; - on_menu_project1_activate; - on_menu_reload_configuration1_activate; - on_menu_remove_indicators1_activate; - on_menu_select_all1_activate; - on_menu_select_all1_activate; - on_menu_show_indentation_guides1_toggled; - on_menu_show_line_endings1_toggled; - on_menu_show_sidebar1_toggled; - on_menu_show_white_space1_toggled; - on_menu_toggle_all_additional_widgets1_activate; - on_menu_toggle_line_commentation1_activate; - on_menu_uncomment_line1_activate; - on_menu_unfold_all1_activate; - on_menu_write_unicode_bom1_toggled; - on_motion_event; - on_move_lines_down1_activate; - on_move_lines_up1_activate; - on_new1_activate; - on_next_message1_activate; - on_normal_size1_activate; - on_notebook1_switch_page_after; - on_open1_activate; - on_page_setup1_activate; - on_paste1_activate; - on_paste1_activate; - on_plugin_preferences1_activate; - on_preferences1_activate; - on_previous_message1_activate; - on_print1_activate; - on_project_close1_activate; - on_project_new1_activate; - on_project_open1_activate; - on_project_properties1_activate; - on_quit1_activate; - on_redo1_activate; - on_redo1_activate; - on_reflow_lines_block1_activate; - on_remove_markers1_activate; - on_replace1_activate; - on_replace_spaces_activate; - on_replace_tabs_activate; - on_reset_indentation1_activate; - on_save1_activate; - on_save_all1_activate; - on_save_as1_activate; - on_search1_activate; - on_select_current_lines1_activate; - on_select_current_paragraph1_activate; - on_send_selection_to_vte1_activate; - on_set_file_readonly1_toggled; - on_show_color_chooser1_activate; - on_show_line_numbers1_toggled; - on_show_messages_window1_toggled; - on_show_toolbar1_toggled; - on_smart_line_indent1_activate; - on_spaces1_activate; - on_strip_trailing_spaces1_activate; - on_tabs1_activate; - on_tabs_and_spaces1_activate; - on_toggle_case1_activate; - on_toolbutton_reload_clicked; - on_tv_notebook_switch_page; - on_tv_notebook_switch_page_after; - on_undo1_activate; - on_undo1_activate; - on_use_auto_indentation1_toggled; - on_website1_activate; - on_window_delete_event; - on_window_state_event; - on_zoom_in1_activate; - on_zoom_out1_activate; -}; diff --git a/src/signalconn.c.in b/src/signalconn.c.in new file mode 100644 index 00000000..d5983f0a --- /dev/null +++ b/src/signalconn.c.in @@ -0,0 +1,32 @@ + + +static void builder_connect_func(GtkBuilder *builder, GObject *object, + const gchar *signal_name, const gchar *handler_name, GObject *connect_obj, + GConnectFlags flags, gpointer user_data) +{ + GHashTable *hash = user_data; + GCallback callback; + + callback = g_hash_table_lookup(hash, handler_name); + g_return_if_fail(callback); + + if (connect_obj == NULL) + g_signal_connect_data(object, signal_name, callback, NULL, NULL, flags); + else + g_signal_connect_object(object, signal_name, callback, connect_obj, flags); +} + + +void callbacks_connect(GtkBuilder *builder) +{ + GHashTable *hash; + + g_return_if_fail(GTK_IS_BUILDER(builder)); + + hash = g_hash_table_new(g_str_hash, g_str_equal); + +@callback_map@ + + gtk_builder_connect_signals_full(builder, builder_connect_func, hash); + g_hash_table_destroy(hash); +} diff --git a/src/ui_utils.c b/src/ui_utils.c index 4f049451..e9f548a0 100644 --- a/src/ui_utils.c +++ b/src/ui_utils.c @@ -2448,7 +2448,7 @@ void ui_init_builder(void) } g_free(interface_file); - gtk_builder_connect_signals(builder, NULL); + callbacks_connect(builder); edit_menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "edit_menu1")); prefs_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "prefs_dialog"));