Mercurial > hg > xemacs-beta
annotate src/menubar-x.c @ 4952:19a72041c5ed
Mule-izing, various fixes related to char * arguments
-------------------- ChangeLog entries follow: --------------------
modules/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
* postgresql/postgresql.c (CHECK_LIVE_CONNECTION):
* postgresql/postgresql.c (print_pgresult):
* postgresql/postgresql.c (Fpq_conn_defaults):
* postgresql/postgresql.c (Fpq_connectdb):
* postgresql/postgresql.c (Fpq_connect_start):
* postgresql/postgresql.c (Fpq_result_status):
* postgresql/postgresql.c (Fpq_res_status):
Mule-ize large parts of it.
2010-01-26 Ben Wing <ben@xemacs.org>
* ldap/eldap.c (print_ldap):
* ldap/eldap.c (allocate_ldap):
Use write_ascstring().
src/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (build_ascstring):
* alloc.c (build_msg_cistring):
* alloc.c (staticpro_1):
* alloc.c (staticpro_name):
* alloc.c (staticpro_nodump_1):
* alloc.c (staticpro_nodump_name):
* alloc.c (unstaticpro_nodump_1):
* alloc.c (mcpro_1):
* alloc.c (mcpro_name):
* alloc.c (object_memory_usage_stats):
* alloc.c (common_init_alloc_early):
* alloc.c (init_alloc_once_early):
* buffer.c (print_buffer):
* buffer.c (vars_of_buffer):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.c (init_initial_directory):
* bytecode.c (invalid_byte_code):
* bytecode.c (print_compiled_function):
* bytecode.c (mark_compiled_function):
* chartab.c (print_table_entry):
* chartab.c (print_char_table):
* config.h.in:
* console-gtk.c:
* console-gtk.c (gtk_device_to_console_connection):
* console-gtk.c (gtk_semi_canonicalize_console_connection):
* console-gtk.c (gtk_canonicalize_console_connection):
* console-gtk.c (gtk_semi_canonicalize_device_connection):
* console-gtk.c (gtk_canonicalize_device_connection):
* console-stream.c (stream_init_frame_1):
* console-stream.c (vars_of_console_stream):
* console-stream.c (init_console_stream):
* console-x.c (x_semi_canonicalize_console_connection):
* console-x.c (x_semi_canonicalize_device_connection):
* console-x.c (x_canonicalize_device_connection):
* console-x.h:
* data.c (eq_with_ebola_notice):
* data.c (Fsubr_interactive):
* data.c (Fnumber_to_string):
* data.c (digit_to_number):
* device-gtk.c (gtk_init_device):
* device-msw.c (print_devmode):
* device-x.c (x_event_name):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-msw.c (handle_file_dialog_box):
* dialog-msw.c (vars_of_dialog_mswindows):
* doc.c (weird_doc):
* doc.c (Fsnarf_documentation):
* doc.c (vars_of_doc):
* dumper.c (pdump):
* dynarr.c:
* dynarr.c (Dynarr_realloc):
* editfns.c (Fuser_real_login_name):
* editfns.c (get_home_directory):
* elhash.c (print_hash_table_data):
* elhash.c (print_hash_table):
* emacs.c (main_1):
* emacs.c (vars_of_emacs):
* emodules.c:
* emodules.c (_emodules_list):
* emodules.c (Fload_module):
* emodules.c (Funload_module):
* emodules.c (Flist_modules):
* emodules.c (find_make_module):
* emodules.c (attempt_module_delete):
* emodules.c (emodules_load):
* emodules.c (emodules_doc_subr):
* emodules.c (emodules_doc_sym):
* emodules.c (syms_of_module):
* emodules.c (vars_of_module):
* emodules.h:
* eval.c (print_subr):
* eval.c (signal_call_debugger):
* eval.c (build_error_data):
* eval.c (signal_error):
* eval.c (maybe_signal_error):
* eval.c (signal_continuable_error):
* eval.c (maybe_signal_continuable_error):
* eval.c (signal_error_2):
* eval.c (maybe_signal_error_2):
* eval.c (signal_continuable_error_2):
* eval.c (maybe_signal_continuable_error_2):
* eval.c (signal_ferror):
* eval.c (maybe_signal_ferror):
* eval.c (signal_continuable_ferror):
* eval.c (maybe_signal_continuable_ferror):
* eval.c (signal_ferror_with_frob):
* eval.c (maybe_signal_ferror_with_frob):
* eval.c (signal_continuable_ferror_with_frob):
* eval.c (maybe_signal_continuable_ferror_with_frob):
* eval.c (syntax_error):
* eval.c (syntax_error_2):
* eval.c (maybe_syntax_error):
* eval.c (sferror):
* eval.c (sferror_2):
* eval.c (maybe_sferror):
* eval.c (invalid_argument):
* eval.c (invalid_argument_2):
* eval.c (maybe_invalid_argument):
* eval.c (invalid_constant):
* eval.c (invalid_constant_2):
* eval.c (maybe_invalid_constant):
* eval.c (invalid_operation):
* eval.c (invalid_operation_2):
* eval.c (maybe_invalid_operation):
* eval.c (invalid_change):
* eval.c (invalid_change_2):
* eval.c (maybe_invalid_change):
* eval.c (invalid_state):
* eval.c (invalid_state_2):
* eval.c (maybe_invalid_state):
* eval.c (wtaerror):
* eval.c (stack_overflow):
* eval.c (out_of_memory):
* eval.c (print_multiple_value):
* eval.c (issue_call_trapping_problems_warning):
* eval.c (backtrace_specials):
* eval.c (backtrace_unevalled_args):
* eval.c (Fbacktrace):
* eval.c (warn_when_safe):
* event-Xt.c (modwarn):
* event-Xt.c (modbarf):
* event-Xt.c (check_modifier):
* event-Xt.c (store_modifier):
* event-Xt.c (emacs_Xt_format_magic_event):
* event-Xt.c (describe_event):
* event-gtk.c (dragndrop_data_received):
* event-gtk.c (store_modifier):
* event-gtk.c (gtk_reset_modifier_mapping):
* event-msw.c (dde_eval_string):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (FROB):
* event-msw.c (emacs_mswindows_format_magic_event):
* event-stream.c (external_debugging_print_event):
* event-stream.c (execute_help_form):
* event-stream.c (vars_of_event_stream):
* events.c (print_event_1):
* events.c (print_event):
* events.c (event_equal):
* extents.c (print_extent_1):
* extents.c (print_extent):
* extents.c (vars_of_extents):
* faces.c (print_face):
* faces.c (complex_vars_of_faces):
* file-coding.c:
* file-coding.c (print_coding_system):
* file-coding.c (print_coding_system_in_print_method):
* file-coding.c (default_query_method):
* file-coding.c (find_coding_system):
* file-coding.c (make_coding_system_1):
* file-coding.c (chain_print):
* file-coding.c (undecided_print):
* file-coding.c (gzip_print):
* file-coding.c (vars_of_file_coding):
* file-coding.c (complex_vars_of_file_coding):
* fileio.c:
* fileio.c (report_file_type_error):
* fileio.c (report_error_with_errno):
* fileio.c (report_file_error):
* fileio.c (barf_or_query_if_file_exists):
* fileio.c (vars_of_fileio):
* floatfns.c (matherr):
* fns.c (print_bit_vector):
* fns.c (Fmapconcat):
* fns.c (add_suffix_to_symbol):
* fns.c (add_prefix_to_symbol):
* frame-gtk.c:
* frame-gtk.c (Fgtk_window_id):
* frame-x.c (def):
* frame-x.c (x_cde_transfer_callback):
* frame.c:
* frame.c (Fmake_frame):
* gc.c (show_gc_cursor_and_message):
* gc.c (vars_of_gc):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate):
* glyphs-gtk.c (gtk_print_image_instance):
* glyphs-msw.c (mswindows_print_image_instance):
* glyphs-x.c (x_print_image_instance):
* glyphs-x.c (update_widget_face):
* glyphs.c (make_string_from_file):
* glyphs.c (print_image_instance):
* glyphs.c (signal_image_error):
* glyphs.c (signal_image_error_2):
* glyphs.c (signal_double_image_error):
* glyphs.c (signal_double_image_error_2):
* glyphs.c (xbm_mask_file_munging):
* glyphs.c (pixmap_to_lisp_data):
* glyphs.h:
* gui.c (gui_item_display_flush_left):
* hpplay.c (player_error_internal):
* hpplay.c (myHandler):
* intl-win32.c:
* intl-win32.c (langcode_to_lang):
* intl-win32.c (sublangcode_to_lang):
* intl-win32.c (Fmswindows_get_locale_info):
* intl-win32.c (lcid_to_locale_mule_or_no):
* intl-win32.c (mswindows_multibyte_to_unicode_print):
* intl-win32.c (complex_vars_of_intl_win32):
* keymap.c:
* keymap.c (print_keymap):
* keymap.c (ensure_meta_prefix_char_keymapp):
* keymap.c (Fkey_description):
* keymap.c (Ftext_char_description):
* lisp.h:
* lisp.h (struct):
* lisp.h (DECLARE_INLINE_HEADER):
* lread.c (Fload_internal):
* lread.c (locate_file):
* lread.c (read_escape):
* lread.c (read_raw_string):
* lread.c (read1):
* lread.c (read_list):
* lread.c (read_compiled_function):
* lread.c (init_lread):
* lrecord.h:
* marker.c (print_marker):
* marker.c (marker_equal):
* menubar-msw.c (displayable_menu_item):
* menubar-x.c (command_builder_operate_menu_accelerator):
* menubar.c (vars_of_menubar):
* minibuf.c (reinit_complex_vars_of_minibuf):
* minibuf.c (complex_vars_of_minibuf):
* mule-charset.c (Fmake_charset):
* mule-charset.c (complex_vars_of_mule_charset):
* mule-coding.c (iso2022_print):
* mule-coding.c (fixed_width_query):
* number.c (bignum_print):
* number.c (ratio_print):
* number.c (bigfloat_print):
* number.c (bigfloat_finalize):
* objects-msw.c:
* objects-msw.c (mswindows_color_to_string):
* objects-msw.c (mswindows_color_list):
* objects-tty.c:
* objects-tty.c (tty_font_list):
* objects-tty.c (tty_find_charset_font):
* objects-xlike-inc.c (xft_find_charset_font):
* objects-xlike-inc.c (endif):
* print.c:
* print.c (write_istring):
* print.c (write_ascstring):
* print.c (Fterpri):
* print.c (Fprint):
* print.c (print_error_message):
* print.c (print_vector_internal):
* print.c (print_cons):
* print.c (print_string):
* print.c (printing_unreadable_object):
* print.c (print_internal):
* print.c (print_float):
* print.c (print_symbol):
* process-nt.c (mswindows_report_winsock_error):
* process-nt.c (nt_canonicalize_host_name):
* process-unix.c (unix_canonicalize_host_name):
* process.c (print_process):
* process.c (report_process_error):
* process.c (report_network_error):
* process.c (make_process_internal):
* process.c (Fstart_process_internal):
* process.c (status_message):
* process.c (putenv_internal):
* process.c (vars_of_process):
* process.h:
* profile.c (vars_of_profile):
* rangetab.c (print_range_table):
* realpath.c (vars_of_realpath):
* redisplay.c (vars_of_redisplay):
* search.c (wordify):
* search.c (Freplace_match):
* sheap.c (sheap_adjust_h):
* sound.c (report_sound_error):
* sound.c (Fplay_sound_file):
* specifier.c (print_specifier):
* symbols.c (Fsubr_name):
* symbols.c (do_symval_forwarding):
* symbols.c (set_default_buffer_slot_variable):
* symbols.c (set_default_console_slot_variable):
* symbols.c (store_symval_forwarding):
* symbols.c (default_value):
* symbols.c (defsymbol_massage_name_1):
* symbols.c (defsymbol_massage_name_nodump):
* symbols.c (defsymbol_massage_name):
* symbols.c (defsymbol_massage_multiword_predicate_nodump):
* symbols.c (defsymbol_massage_multiword_predicate):
* symbols.c (defsymbol_nodump):
* symbols.c (defsymbol):
* symbols.c (defkeyword):
* symbols.c (defkeyword_massage_name):
* symbols.c (check_module_subr):
* symbols.c (deferror_1):
* symbols.c (deferror):
* symbols.c (deferror_massage_name):
* symbols.c (deferror_massage_name_and_message):
* symbols.c (defvar_magic):
* symeval.h:
* symeval.h (DEFVAR_SYMVAL_FWD):
* sysdep.c:
* sysdep.c (init_system_name):
* sysdll.c:
* sysdll.c (MAYBE_PREPEND_UNDERSCORE):
* sysdll.c (dll_function):
* sysdll.c (dll_variable):
* sysdll.c (dll_error):
* sysdll.c (dll_open):
* sysdll.c (dll_close):
* sysdll.c (image_for_address):
* sysdll.c (my_find_image):
* sysdll.c (search_linked_libs):
* sysdll.h:
* sysfile.h:
* sysfile.h (DEFAULT_DIRECTORY_FALLBACK):
* syswindows.h:
* tests.c (DFC_CHECK_LENGTH):
* tests.c (DFC_CHECK_CONTENT):
* tests.c (Ftest_hash_tables):
* text.c (vars_of_text):
* text.h:
* tooltalk.c (tt_opnum_string):
* tooltalk.c (tt_message_arg_ival_string):
* tooltalk.c (Ftooltalk_default_procid):
* tooltalk.c (Ftooltalk_default_session):
* tooltalk.c (init_tooltalk):
* tooltalk.c (vars_of_tooltalk):
* ui-gtk.c (Fdll_load):
* ui-gtk.c (type_to_marshaller_type):
* ui-gtk.c (Fgtk_import_function_internal):
* ui-gtk.c (emacs_gtk_object_printer):
* ui-gtk.c (emacs_gtk_boxed_printer):
* unicode.c (unicode_to_ichar):
* unicode.c (unicode_print):
* unicode.c (unicode_query):
* unicode.c (vars_of_unicode):
* unicode.c (complex_vars_of_unicode):
* win32.c:
* win32.c (mswindows_report_process_error):
* window.c (print_window):
* xemacs.def.in.in:
BASIC IDEA: Further fixing up uses of char * and CIbyte *
to reflect their actual semantics; Mule-izing some code;
redoing of the not-yet-working code to handle message translation.
Clean up code to handle message-translation (not yet working).
Create separate versions of build_msg_string() for working with
Ibyte *, CIbyte *, and Ascbyte * arguments. Assert that Ascbyte *
arguments are pure-ASCII. Make build_msg_string() be the same
as build_msg_ascstring(). Create same three versions of GETTEXT()
and DEFER_GETTEXT(). Also create build_defer_string() and
variants for the equivalent of DEFER_GETTEXT() when building a
string. Remove old CGETTEXT(). Clean up code where GETTEXT(),
DEFER_GETTEXT(), build_msg_string(), etc. was being called and
introduce some new calls to build_msg_string(), etc. Remove
GETTEXT() from calls to weird_doc() -- we assume that the
message snarfer knows about weird_doc(). Remove uses of
DEFER_GETTEXT() from error messages in sysdep.c and instead use
special comments /* @@@begin-snarf@@@ */ and /* @@@end-snarf@@@ */
that the message snarfer presumably knows about.
Create build_ascstring() and use it in many instances in place
of build_string(). The purpose of having Ascbyte * variants is
to make the code more self-documenting in terms of what sort of
semantics is expected for char * strings. In fact in the process
of looking for uses of build_string(), much improperly Mule-ized
was discovered.
Mule-ize a lot of code as described in previous paragraph,
e.g. in sysdep.c.
Make the error functions take Ascbyte * strings and fix up a
couple of places where non-pure-ASCII strings were being passed in
(file-coding.c, mule-coding.c, unicode.c). (It's debatable whether
we really need to make the error functions work this way. It
helps catch places where code is written in a way that message
translation won't work, but we may well never implement message
translation.)
Make staticpro() and friends take Ascbyte * strings instead of
raw char * strings. Create a const_Ascbyte_ptr dynarr type
to describe what's held by staticpro_names[] and friends,
create pdump descriptions for const_Ascbyte_ptr dynarrs, and
use them in place of specially-crafted staticpro descriptions.
Mule-ize certain other functions (e.g. x_event_name) by correcting
raw use of char * to Ascbyte *, Rawbyte * or another such type,
and raw use of char[] buffers to another type (usually Ascbyte[]).
Change many uses of write_c_string() to write_msg_string(),
write_ascstring(), etc.
Mule-ize emodules.c, emodules.h, sysdll.h.
Fix some un-Mule-ized code in intl-win32.c.
A comment in event-Xt.c and the limitations of the message
snarfer (make-msgfile or whatever) is presumably incorrect --
it should be smart enough to handle function calls spread over
more than one line. Clean up code in event-Xt.c that was
written awkwardly for this reason.
In config.h.in, instead of NEED_ERROR_CHECK_TYPES_INLINES,
create a more general XEMACS_DEFS_NEEDS_INLINE_DECLS to
indicate when inlined functions need to be declared in
xemacs.defs.in.in, and make use of it in xemacs.defs.in.in.
We need to do this because postgresql.c now calls qxestrdup(),
which is an inline function.
Make nconc2() and other such functions MODULE_API and put
them in xemacs.defs.in.in since postgresql.c now uses them.
Clean up indentation in lread.c and a few other places.
In text.h, document ASSERT_ASCTEXT_ASCII() and
ASSERT_ASCTEXT_ASCII_LEN(), group together the stand-in
encodings and add some more for DLL symbols, function and
variable names, etc.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Tue, 26 Jan 2010 23:22:30 -0600 |
parents | 726060ee587c |
children | 4aebb0131297 |
rev | line source |
---|---|
428 | 1 /* Implements an elisp-programmable menubar -- X interface. |
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp. | |
1261 | 4 Copyright (C) 2000, 2001, 2002, 2003 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Not in FSF. */ | |
24 | |
442 | 25 /* This file Mule-ized by Ben Wing, 7-8-00. */ |
26 | |
27 /* Authorship: | |
28 | |
29 Created 16-dec-91 by Jamie Zawinski. | |
30 Menu filters and many other keywords added by Stig for 19.12. | |
31 Original device-abstraction work and GC cleanup work by Ben Wing for 19.13. | |
32 Menu accelerators c. 1997? by ??. Moved here from event-stream.c. | |
33 Other work post-1996 by ??. | |
34 */ | |
428 | 35 |
36 #include <config.h> | |
37 #include "lisp.h" | |
38 | |
39 #include "buffer.h" | |
40 #include "commands.h" /* zmacs_regions */ | |
872 | 41 #include "device-impl.h" |
428 | 42 #include "events.h" |
872 | 43 #include "frame-impl.h" |
442 | 44 #include "gui.h" |
45 #include "keymap.h" | |
46 #include "menubar.h" | |
428 | 47 #include "opaque.h" |
872 | 48 #include "window-impl.h" |
428 | 49 |
872 | 50 #include "console-x-impl.h" |
800 | 51 |
52 #include "EmacsFrame.h" | |
53 #include "../lwlib/lwlib.h" | |
54 | |
428 | 55 static int set_frame_menubar (struct frame *f, |
56 int deep_p, | |
57 int first_time_p); | |
58 | |
59 #define MENUBAR_TYPE 0 | |
60 #define SUBMENU_TYPE 1 | |
61 #define POPUP_TYPE 2 | |
62 | |
63 | |
64 /* Converting Lisp menu tree descriptions to lwlib's `widget_value' form. | |
65 | |
66 menu_item_descriptor_to_widget_value() converts a lisp description of a | |
67 menubar into a tree of widget_value structures. It allocates widget_values | |
68 with malloc_widget_value() and allocates other storage only for the `key' | |
69 slot. All other slots are filled with pointers to Lisp_String data. We | |
70 allocate a widget_value description of the menu or menubar, and hand it to | |
71 lwlib, which then makes a copy of it, which it manages internally. We then | |
72 immediately free our widget_value tree; it will not be referenced again. | |
73 | |
74 Incremental menu construction callbacks operate just a bit differently. | |
75 They allocate widget_values and call replace_widget_value_tree() to tell | |
76 lwlib to destructively modify the incremental stub (subtree) of its | |
77 separate widget_value tree. | |
78 | |
79 This function is highly recursive (it follows the menu trees) and may call | |
80 eval. The reason we keep pointers to lisp string data instead of copying | |
81 it and freeing it later is to avoid the speed penalty that would entail | |
82 (since this needs to be fast, in the simple cases at least). (The reason | |
83 we malloc/free the keys slot is because there's not a lisp string around | |
84 for us to use in that case.) | |
85 | |
86 Since we keep pointers to lisp strings, and we call eval, we could lose if | |
87 GC relocates (or frees) those strings. It's not easy to gc protect the | |
88 strings because of the recursive nature of this function, and the fact that | |
89 it returns a data structure that gets freed later. So... we do the | |
90 sleaziest thing possible and inhibit GC for the duration. This is probably | |
91 not a big deal... | |
92 | |
93 We do not have to worry about the pointers to Lisp_String data after | |
94 this function successfully finishes. lwlib copies all such data with | |
95 strdup(). */ | |
96 | |
97 static widget_value * | |
98 menu_item_descriptor_to_widget_value_1 (Lisp_Object desc, | |
99 int menu_type, int deep_p, | |
100 int filter_p, | |
101 int depth) | |
102 { | |
103 /* This function cannot GC. | |
104 It is only called from menu_item_descriptor_to_widget_value, which | |
105 prohibits GC. */ | |
106 int menubar_root_p = (menu_type == MENUBAR_TYPE && depth == 0); | |
107 int count = specpdl_depth (); | |
108 int partition_seen = 0; | |
438 | 109 widget_value *wv = xmalloc_widget_value (); |
110 Lisp_Object wv_closure = make_opaque_ptr (wv); | |
428 | 111 |
112 record_unwind_protect (widget_value_unwind, wv_closure); | |
113 | |
114 if (STRINGP (desc)) | |
115 { | |
867 | 116 Ibyte *string_chars = XSTRING_DATA (desc); |
428 | 117 wv->type = (separator_string_p (string_chars) ? SEPARATOR_TYPE : |
118 TEXT_TYPE); | |
119 if (wv->type == SEPARATOR_TYPE) | |
120 { | |
442 | 121 wv->value = menu_separator_style_and_to_external (string_chars); |
428 | 122 } |
123 else | |
124 { | |
442 | 125 LISP_STRING_TO_EXTERNAL_MALLOC (desc, wv->name, Qlwlib_encoding); |
428 | 126 wv->enabled = 1; |
127 /* dverna Dec. 98: command_builder_operate_menu_accelerator will | |
128 manipulate the accel as a Lisp_Object if the widget has a name. | |
129 Since simple labels have a name, but no accel, we *must* set it | |
130 to nil */ | |
131 wv->accel = LISP_TO_VOID (Qnil); | |
132 } | |
133 } | |
134 else if (VECTORP (desc)) | |
135 { | |
136 Lisp_Object gui_item = gui_parse_item_keywords (desc); | |
442 | 137 if (!button_item_to_widget_value (Qmenubar, |
138 gui_item, wv, 1, | |
428 | 139 (menu_type == MENUBAR_TYPE |
442 | 140 && depth <= 1), 1, 1)) |
428 | 141 { |
142 /* :included form was nil */ | |
143 wv = NULL; | |
144 goto menu_item_done; | |
145 } | |
146 } | |
147 else if (CONSP (desc)) | |
148 { | |
149 Lisp_Object incremental_data = desc; | |
150 widget_value *prev = 0; | |
151 | |
152 if (STRINGP (XCAR (desc))) | |
153 { | |
154 Lisp_Object key, val; | |
155 Lisp_Object include_p = Qnil, hook_fn = Qnil, config_tag = Qnil; | |
156 Lisp_Object active_p = Qt; | |
157 Lisp_Object accel; | |
158 int included_spec = 0; | |
159 int active_spec = 0; | |
160 wv->type = CASCADE_TYPE; | |
161 wv->enabled = 1; | |
442 | 162 wv->name = add_accel_and_to_external (XCAR (desc)); |
428 | 163 |
442 | 164 accel = gui_name_accelerator (XCAR (desc)); |
428 | 165 wv->accel = LISP_TO_VOID (accel); |
166 | |
167 desc = Fcdr (desc); | |
168 | |
169 while (key = Fcar (desc), KEYWORDP (key)) | |
170 { | |
171 Lisp_Object cascade = desc; | |
172 desc = Fcdr (desc); | |
173 if (NILP (desc)) | |
563 | 174 sferror ("Keyword in menu lacks a value", cascade); |
428 | 175 val = Fcar (desc); |
176 desc = Fcdr (desc); | |
177 if (EQ (key, Q_included)) | |
178 include_p = val, included_spec = 1; | |
179 else if (EQ (key, Q_config)) | |
180 config_tag = val; | |
181 else if (EQ (key, Q_filter)) | |
182 hook_fn = val; | |
183 else if (EQ (key, Q_active)) | |
184 active_p = val, active_spec = 1; | |
185 else if (EQ (key, Q_accelerator)) | |
186 { | |
187 if ( SYMBOLP (val) | |
188 || CHARP (val)) | |
189 wv->accel = LISP_TO_VOID (val); | |
190 else | |
563 | 191 invalid_argument ("bad keyboard accelerator", val); |
428 | 192 } |
193 else if (EQ (key, Q_label)) | |
194 { | |
195 /* implement in 21.2 */ | |
196 } | |
197 else | |
563 | 198 invalid_argument ("Unknown menu cascade keyword", cascade); |
428 | 199 } |
200 | |
201 if ((!NILP (config_tag) | |
202 && NILP (Fmemq (config_tag, Vmenubar_configuration))) | |
203 || (included_spec && NILP (Feval (include_p)))) | |
204 { | |
205 wv = NULL; | |
206 goto menu_item_done; | |
207 } | |
208 | |
209 if (active_spec) | |
210 active_p = Feval (active_p); | |
211 | |
212 if (!NILP (hook_fn) && !NILP (active_p)) | |
213 { | |
214 #if defined LWLIB_MENUBARS_LUCID || defined LWLIB_MENUBARS_MOTIF | |
215 if (filter_p || depth == 0) | |
216 { | |
217 #endif | |
853 | 218 desc = call1 (hook_fn, desc); |
428 | 219 if (UNBOUNDP (desc)) |
220 desc = Qnil; | |
221 #if defined LWLIB_MENUBARS_LUCID || defined LWLIB_MENUBARS_MOTIF | |
222 } | |
223 else | |
224 { | |
225 widget_value *incr_wv = xmalloc_widget_value (); | |
226 wv->contents = incr_wv; | |
227 incr_wv->type = INCREMENTAL_TYPE; | |
228 incr_wv->enabled = 1; | |
229 incr_wv->name = wv->name; | |
436 | 230 incr_wv->name = xstrdup (wv->name); |
428 | 231 /* This is automatically GC protected through |
232 the call to lw_map_widget_values(); no need | |
233 to worry. */ | |
234 incr_wv->call_data = LISP_TO_VOID (incremental_data); | |
235 goto menu_item_done; | |
236 } | |
237 #endif /* LWLIB_MENUBARS_LUCID || LWLIB_MENUBARS_MOTIF */ | |
238 } | |
239 if (menu_type == POPUP_TYPE && popup_menu_titles && depth == 0) | |
240 { | |
241 /* Simply prepend three more widget values to the contents of | |
242 the menu: a label, and two separators (to get a double | |
243 line). */ | |
244 widget_value *title_wv = xmalloc_widget_value (); | |
245 widget_value *sep_wv = xmalloc_widget_value (); | |
246 title_wv->type = TEXT_TYPE; | |
436 | 247 title_wv->name = xstrdup (wv->name); |
428 | 248 title_wv->enabled = 1; |
249 title_wv->next = sep_wv; | |
250 sep_wv->type = SEPARATOR_TYPE; | |
867 | 251 sep_wv->value = menu_separator_style_and_to_external ((Ibyte *) "=="); |
428 | 252 sep_wv->next = 0; |
253 | |
254 wv->contents = title_wv; | |
255 prev = sep_wv; | |
256 } | |
257 wv->enabled = ! NILP (active_p); | |
258 if (deep_p && !wv->enabled && !NILP (desc)) | |
259 { | |
260 widget_value *dummy; | |
261 /* Add a fake entry so the menus show up */ | |
262 wv->contents = dummy = xmalloc_widget_value (); | |
436 | 263 dummy->name = xstrdup ("(inactive)"); |
428 | 264 dummy->accel = LISP_TO_VOID (Qnil); |
265 dummy->enabled = 0; | |
266 dummy->selected = 0; | |
267 dummy->value = NULL; | |
268 dummy->type = BUTTON_TYPE; | |
269 dummy->call_data = NULL; | |
270 dummy->next = NULL; | |
271 | |
272 goto menu_item_done; | |
442 | 273 } |
428 | 274 |
275 } | |
276 else if (menubar_root_p) | |
277 { | |
436 | 278 wv->name = xstrdup ("menubar"); |
428 | 279 wv->type = CASCADE_TYPE; /* Well, nothing else seems to fit and |
280 this is ignored anyway... */ | |
281 } | |
282 else | |
283 { | |
563 | 284 sferror ("Menu name (first element) must be a string", desc); |
428 | 285 } |
286 | |
287 if (deep_p || menubar_root_p) | |
288 { | |
289 widget_value *next; | |
290 for (; !NILP (desc); desc = Fcdr (desc)) | |
291 { | |
292 Lisp_Object child = Fcar (desc); | |
293 if (menubar_root_p && NILP (child)) /* the partition */ | |
294 { | |
295 if (partition_seen) | |
563 | 296 sferror |
442 | 297 ("More than one partition (nil) in menubar description", |
298 desc); | |
428 | 299 partition_seen = 1; |
300 next = xmalloc_widget_value (); | |
301 next->type = PUSHRIGHT_TYPE; | |
302 } | |
303 else | |
304 { | |
305 next = menu_item_descriptor_to_widget_value_1 | |
306 (child, menu_type, deep_p, filter_p, depth + 1); | |
307 } | |
308 if (! next) | |
309 continue; | |
310 else if (prev) | |
311 prev->next = next; | |
312 else | |
313 wv->contents = next; | |
314 prev = next; | |
315 } | |
316 } | |
317 if (deep_p && !wv->contents) | |
318 wv = NULL; | |
319 } | |
320 else if (NILP (desc)) | |
563 | 321 sferror ("nil may not appear in menu descriptions", desc); |
428 | 322 else |
563 | 323 sferror ("Unrecognized menu descriptor", desc); |
428 | 324 |
442 | 325 menu_item_done: |
428 | 326 |
327 if (wv) | |
328 { | |
329 /* Completed normally. Clear out the object that widget_value_unwind() | |
330 will be called with to tell it not to free the wv (as we are | |
331 returning it.) */ | |
332 set_opaque_ptr (wv_closure, 0); | |
333 } | |
334 | |
771 | 335 unbind_to (count); |
428 | 336 return wv; |
337 } | |
338 | |
853 | 339 struct menu_item_descriptor_to_widget_value |
340 { | |
341 Lisp_Object desc; | |
342 int menu_type, deep_p, filter_p; | |
343 widget_value *wv; | |
344 }; | |
428 | 345 |
346 static Lisp_Object | |
853 | 347 protected_menu_item_descriptor_to_widget_value_1 (void *gack) |
428 | 348 { |
853 | 349 struct menu_item_descriptor_to_widget_value *midtwv = |
350 (struct menu_item_descriptor_to_widget_value *) gack; | |
1918 | 351 int count = begin_gc_forbidden (); |
352 /* Can't GC! */ | |
353 midtwv->wv = menu_item_descriptor_to_widget_value_1 (midtwv->desc, | |
354 midtwv->menu_type, | |
355 midtwv->deep_p, | |
356 midtwv->filter_p, | |
357 0); | |
358 unbind_to (count); | |
442 | 359 return Qnil; |
428 | 360 } |
853 | 361 |
362 /* Inside of the pre_activate_callback, we absolutely need to protect | |
363 against errors, esp. but not exclusively in the filter code. (We do | |
364 other evalling, too.) We also need to reenable quit checking, which | |
365 was disabled by next_event_internal() so as to read C-g as an | |
366 event. */ | |
428 | 367 |
853 | 368 static widget_value * |
369 protected_menu_item_descriptor_to_widget_value (Lisp_Object desc, | |
370 int menu_type, int deep_p, | |
371 int filter_p) | |
428 | 372 { |
853 | 373 struct menu_item_descriptor_to_widget_value midtwv; |
1279 | 374 int depth = internal_bind_int (&in_menu_callback, 1); |
375 Lisp_Object retval; | |
428 | 376 |
853 | 377 midtwv.desc = desc; |
378 midtwv.menu_type = menu_type; | |
379 midtwv.deep_p = deep_p; | |
380 midtwv.filter_p = filter_p; | |
428 | 381 |
1279 | 382 retval = event_stream_protect_modal_loop |
383 ("Error during menu callback", | |
384 protected_menu_item_descriptor_to_widget_value_1, &midtwv, | |
385 UNINHIBIT_QUIT); | |
386 unbind_to (depth); | |
387 | |
388 if (UNBOUNDP (retval)) | |
853 | 389 return 0; |
390 | |
391 return midtwv.wv; | |
428 | 392 } |
853 | 393 |
1918 | 394 /* The two callers of menu_item_descriptor_to_widget_value may both run while |
395 in redisplay. Some descriptor to widget value conversions call Feval, and | |
396 at least one calls QUIT. Hence, we have to establish protection here.. */ | |
397 | |
398 static widget_value * | |
399 menu_item_descriptor_to_widget_value (Lisp_Object desc, | |
400 int menu_type, /* if this is a menubar, | |
401 popup or sub menu */ | |
402 int deep_p, /* */ | |
403 int filter_p) /* if :filter forms | |
404 should run now */ | |
405 { | |
406 struct menu_item_descriptor_to_widget_value midtwv; | |
407 Lisp_Object retval; | |
408 | |
409 midtwv.desc = desc; | |
410 midtwv.menu_type = menu_type; | |
411 midtwv.deep_p = deep_p; | |
412 midtwv.filter_p = filter_p; | |
413 | |
414 retval = call_trapping_problems | |
415 (Qevent, "Error during menu construction", 0, NULL, | |
416 protected_menu_item_descriptor_to_widget_value_1, &midtwv); | |
417 | |
418 if (UNBOUNDP (retval)) | |
419 return NULL; | |
420 | |
421 return midtwv.wv; | |
422 } | |
423 | |
428 | 424 /* The order in which callbacks are run is funny to say the least. |
425 It's sometimes tricky to avoid running a callback twice, and to | |
426 avoid returning prematurely. So, this function returns true | |
427 if the menu's callbacks are no longer gc protected. So long | |
428 as we unprotect them before allowing other callbacks to run, | |
429 everything should be ok. | |
430 | |
431 The pre_activate_callback() *IS* intentionally called multiple times. | |
432 If client_data == NULL, then it's being called before the menu is posted. | |
433 If client_data != NULL, then client_data is a (widget_value *) and | |
434 client_data->data is a Lisp_Object pointing to a lisp submenu description | |
435 that must be converted into widget_values. *client_data is destructively | |
436 modified. | |
437 | |
438 #### Stig thinks that there may be a GC problem here due to the | |
439 fact that pre_activate_callback() is called multiple times, but I | |
440 think he's wrong. | |
441 | |
442 */ | |
443 | |
444 static void | |
2286 | 445 pre_activate_callback (Widget widget, LWLIB_ID UNUSED (id), |
446 XtPointer client_data) | |
428 | 447 { |
448 /* This function can GC */ | |
449 struct device *d = get_device_from_display (XtDisplay (widget)); | |
450 struct frame *f = x_any_window_to_frame (d, XtWindow (widget)); | |
451 Lisp_Object frame; | |
452 | |
453 /* set in lwlib to the time stamp associated with the most recent menu | |
454 operation */ | |
455 extern Time x_focus_timestamp_really_sucks_fix_me_better; | |
456 | |
457 if (!f) | |
458 f = x_any_window_to_frame (d, XtWindow (XtParent (widget))); | |
459 if (!f) | |
460 return; | |
461 | |
462 /* make sure f is the selected frame */ | |
793 | 463 frame = wrap_frame (f); |
428 | 464 Fselect_frame (frame); |
465 | |
466 if (client_data) | |
467 { | |
468 /* this is an incremental menu construction callback */ | |
469 widget_value *hack_wv = (widget_value *) client_data; | |
470 Lisp_Object submenu_desc; | |
471 widget_value *wv; | |
472 | |
473 assert (hack_wv->type == INCREMENTAL_TYPE); | |
826 | 474 submenu_desc = VOID_TO_LISP (hack_wv->call_data); |
428 | 475 |
853 | 476 wv = (protected_menu_item_descriptor_to_widget_value |
477 (submenu_desc, SUBMENU_TYPE, 1, 0)); | |
428 | 478 |
479 if (!wv) | |
480 { | |
481 wv = xmalloc_widget_value (); | |
482 wv->type = CASCADE_TYPE; | |
483 wv->next = NULL; | |
484 wv->accel = LISP_TO_VOID (Qnil); | |
485 wv->contents = xmalloc_widget_value (); | |
486 wv->contents->type = TEXT_TYPE; | |
436 | 487 wv->contents->name = xstrdup ("No menu"); |
428 | 488 wv->contents->next = NULL; |
489 wv->contents->accel = LISP_TO_VOID (Qnil); | |
490 } | |
491 assert (wv && wv->type == CASCADE_TYPE && wv->contents); | |
492 replace_widget_value_tree (hack_wv, wv->contents); | |
493 free_popup_widget_value_tree (wv); | |
1261 | 494 /* Now that we've destructively modified part of the widget value |
495 hierarchy, our list of protected callbacks will no longer be | |
496 valid, so we need to recompute it. */ | |
1346 | 497 gcpro_popup_callbacks (FRAME_X_MENUBAR_ID (f)); |
428 | 498 } |
1346 | 499 else if (!FRAME_X_MENUBAR_ID (f)) |
428 | 500 return; |
501 else | |
502 { | |
503 /* #### - It is necessary to *ALWAYS* call set_frame_menubar() now that | |
504 incremental menus are implemented. If a subtree of a menu has been | |
505 updated incrementally (a destructive operation), then that subtree | |
506 must somehow be wiped. | |
507 | |
508 It is difficult to undo the destructive operation in lwlib because | |
509 a pointer back to lisp data needs to be hidden away somewhere. So | |
510 that an INCREMENTAL_TYPE widget_value can be recreated... Hmmmmm. */ | |
853 | 511 run_hook_trapping_problems |
1333 | 512 (Qmenubar, Qactivate_menubar_hook, |
853 | 513 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION); |
428 | 514 set_frame_menubar (f, 1, 0); |
515 DEVICE_X_MOUSE_TIMESTAMP (XDEVICE (FRAME_DEVICE (f))) = | |
516 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (XDEVICE (FRAME_DEVICE (f))) = | |
517 x_focus_timestamp_really_sucks_fix_me_better; | |
518 } | |
519 } | |
520 | |
521 static widget_value * | |
522 compute_menubar_data (struct frame *f, Lisp_Object menubar, int deep_p) | |
523 { | |
524 if (NILP (menubar)) | |
438 | 525 return 0; |
428 | 526 else |
527 { | |
438 | 528 widget_value *data; |
428 | 529 int count = specpdl_depth (); |
530 | |
438 | 531 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); |
532 Fset_buffer (XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer); | |
428 | 533 data = menu_item_descriptor_to_widget_value (menubar, MENUBAR_TYPE, |
534 deep_p, 0); | |
771 | 535 unbind_to (count); |
438 | 536 |
537 return data; | |
428 | 538 } |
539 } | |
540 | |
541 static int | |
542 set_frame_menubar (struct frame *f, int deep_p, int first_time_p) | |
543 { | |
544 widget_value *data; | |
545 Lisp_Object menubar; | |
546 int menubar_visible; | |
547 long id; | |
438 | 548 /* As with the toolbar, the minibuffer does not have its own menubar. */ |
428 | 549 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); |
550 | |
551 if (! FRAME_X_P (f)) | |
552 return 0; | |
553 | |
554 /***** first compute the contents of the menubar *****/ | |
555 | |
556 if (! first_time_p) | |
557 { | |
558 /* evaluate `current-menubar' in the buffer of the selected window | |
559 of the frame in question. */ | |
560 menubar = symbol_value_in_buffer (Qcurrent_menubar, w->buffer); | |
561 } | |
562 else | |
563 { | |
564 /* That's a little tricky the first time since the frame isn't | |
565 fully initialized yet. */ | |
566 menubar = Fsymbol_value (Qcurrent_menubar); | |
567 } | |
568 | |
569 if (NILP (menubar)) | |
570 { | |
571 menubar = Vblank_menubar; | |
572 menubar_visible = 0; | |
573 } | |
574 else | |
575 menubar_visible = !NILP (w->menubar_visible_p); | |
576 | |
577 data = compute_menubar_data (f, menubar, deep_p); | |
578 if (!data || (!data->next && !data->contents)) | |
2500 | 579 ABORT (); |
428 | 580 |
1346 | 581 if (!FRAME_X_MENUBAR_ID (f)) |
582 FRAME_X_MENUBAR_ID (f) = new_lwlib_id (); | |
428 | 583 |
584 /***** now store into the menubar widget, creating it if necessary *****/ | |
585 | |
1346 | 586 id = FRAME_X_MENUBAR_ID (f); |
428 | 587 if (!FRAME_X_MENUBAR_WIDGET (f)) |
588 { | |
589 Widget parent = FRAME_X_CONTAINER_WIDGET (f); | |
590 | |
591 assert (first_time_p); | |
592 | |
593 /* It's the first time we've mapped the menubar so compute its | |
594 contents completely once. This makes sure that the menubar | |
595 components are created with the right type. */ | |
596 if (!deep_p) | |
597 { | |
598 free_popup_widget_value_tree (data); | |
599 data = compute_menubar_data (f, menubar, 1); | |
600 } | |
601 | |
602 | |
603 FRAME_X_MENUBAR_WIDGET (f) = | |
604 lw_create_widget ("menubar", "menubar", id, data, parent, | |
605 0, pre_activate_callback, | |
606 popup_selection_callback, 0); | |
607 | |
608 } | |
609 else | |
610 { | |
611 lw_modify_all_widgets (id, data, deep_p ? True : False); | |
612 } | |
613 free_popup_widget_value_tree (data); | |
614 | |
1261 | 615 /* Buried inside of the lwlib data are pointers to Lisp objects that may |
616 have been freshly created. They need to be GC-protected, so snarf them | |
617 now and record them into the popup-data object associated with the | |
618 frame. */ | |
1346 | 619 gcpro_popup_callbacks (id); |
1261 | 620 |
1346 | 621 FRAME_X_MENUBAR_CONTENTS_UP_TO_DATE (f) = deep_p; |
622 FRAME_X_LAST_MENUBAR_BUFFER (f) = | |
428 | 623 XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f))->buffer; |
624 return menubar_visible; | |
625 } | |
626 | |
627 | |
628 /* Called from x_create_widgets() to create the initial menubar of a frame | |
629 before it is mapped, so that the window is mapped with the menubar already | |
630 there instead of us tacking it on later and thrashing the window after it | |
631 is visible. */ | |
632 int | |
633 x_initialize_frame_menubar (struct frame *f) | |
634 { | |
635 return set_frame_menubar (f, 1, 1); | |
636 } | |
637 | |
638 | |
639 static LWLIB_ID last_popup_menu_selection_callback_id; | |
640 | |
641 static void | |
642 popup_menu_selection_callback (Widget widget, LWLIB_ID id, | |
643 XtPointer client_data) | |
644 { | |
645 last_popup_menu_selection_callback_id = id; | |
646 popup_selection_callback (widget, id, client_data); | |
647 /* lw_destroy_all_widgets() will be called from popup_down_callback() */ | |
648 } | |
649 | |
650 static void | |
2286 | 651 popup_menu_down_callback (Widget widget, LWLIB_ID id, |
652 XtPointer UNUSED (client_data)) | |
428 | 653 { |
654 if (popup_handled_p (id)) | |
655 return; | |
656 assert (popup_up_p != 0); | |
657 ungcpro_popup_callbacks (id); | |
658 popup_up_p--; | |
659 /* if this isn't called immediately after the selection callback, then | |
660 there wasn't a menu selection. */ | |
661 if (id != last_popup_menu_selection_callback_id) | |
662 popup_selection_callback (widget, id, (XtPointer) -1); | |
663 lw_destroy_all_widgets (id); | |
664 } | |
665 | |
666 | |
667 static void | |
440 | 668 make_dummy_xbutton_event (XEvent *dummy, Widget daddy, Lisp_Event *eev) |
428 | 669 /* NULL for eev means query pointer */ |
670 { | |
671 XButtonPressedEvent *btn = (XButtonPressedEvent *) dummy; | |
672 | |
673 btn->type = ButtonPress; | |
674 btn->serial = 0; | |
675 btn->send_event = 0; | |
676 btn->display = XtDisplay (daddy); | |
677 btn->window = XtWindow (daddy); | |
678 if (eev) | |
679 { | |
680 Position shellx, shelly, framex, framey; | |
681 Arg al [2]; | |
934 | 682 btn->time = EVENT_TIMESTAMP (eev); |
1204 | 683 btn->button = EVENT_BUTTON_BUTTON (eev); |
934 | 684 btn->root = RootWindowOfScreen (XtScreen (daddy)); |
685 btn->subwindow = (Window) NULL; | |
1204 | 686 btn->x = EVENT_BUTTON_X (eev); |
687 btn->y = EVENT_BUTTON_Y (eev); | |
428 | 688 shellx = shelly = 0; |
689 #ifndef HAVE_WMCOMMAND | |
690 { | |
691 Widget shell = XtParent (daddy); | |
692 | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
693 Xt_SET_ARG (al [0], XtNx, &shellx); |
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
694 Xt_SET_ARG (al [1], XtNy, &shelly); |
428 | 695 XtGetValues (shell, al, 2); |
696 } | |
438 | 697 #endif |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
698 Xt_SET_ARG (al [0], XtNx, &framex); |
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
699 Xt_SET_ARG (al [1], XtNy, &framey); |
428 | 700 XtGetValues (daddy, al, 2); |
701 btn->x_root = shellx + framex + btn->x; | |
702 btn->y_root = shelly + framey + btn->y; | |
703 btn->state = ButtonPressMask; /* all buttons pressed */ | |
704 } | |
705 else | |
706 { | |
707 /* CurrentTime is just ZERO, so it's worthless for | |
708 determining relative click times. */ | |
709 struct device *d = get_device_from_display (XtDisplay (daddy)); | |
710 btn->time = DEVICE_X_MOUSE_TIMESTAMP (d); /* event-Xt maintains this */ | |
711 btn->button = 0; | |
712 XQueryPointer (btn->display, btn->window, &btn->root, | |
713 &btn->subwindow, &btn->x_root, &btn->y_root, | |
714 &btn->x, &btn->y, &btn->state); | |
715 } | |
716 } | |
717 | |
718 | |
719 | |
720 static void | |
721 x_update_frame_menubar_internal (struct frame *f) | |
722 { | |
723 /* We assume the menubar contents has changed if the global flag is set, | |
724 or if the current buffer has changed, or if the menubar has never | |
725 been updated before. | |
726 */ | |
727 int menubar_contents_changed = | |
728 (f->menubar_changed | |
1346 | 729 || !FRAME_X_MENUBAR_ID (f) |
730 || (!EQ (FRAME_X_LAST_MENUBAR_BUFFER (f), | |
428 | 731 XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f))->buffer))); |
732 | |
733 Boolean menubar_was_visible = XtIsManaged (FRAME_X_MENUBAR_WIDGET (f)); | |
734 Boolean menubar_will_be_visible = menubar_was_visible; | |
735 Boolean menubar_visibility_changed; | |
736 | |
737 if (menubar_contents_changed) | |
738 menubar_will_be_visible = set_frame_menubar (f, 0, 0); | |
739 | |
740 menubar_visibility_changed = menubar_was_visible != menubar_will_be_visible; | |
741 | |
742 if (!menubar_visibility_changed) | |
743 return; | |
744 | |
745 /* Set menubar visibility */ | |
746 (menubar_will_be_visible ? XtManageChild : XtUnmanageChild) | |
747 (FRAME_X_MENUBAR_WIDGET (f)); | |
748 | |
749 MARK_FRAME_SIZE_SLIPPED (f); | |
750 } | |
751 | |
752 static void | |
753 x_update_frame_menubars (struct frame *f) | |
754 { | |
755 assert (FRAME_X_P (f)); | |
756 | |
757 x_update_frame_menubar_internal (f); | |
758 | |
759 /* #### This isn't going to work right now that this function works on | |
760 a per-frame, not per-device basis. Guess what? I don't care. */ | |
761 } | |
762 | |
763 static void | |
764 x_free_frame_menubars (struct frame *f) | |
765 { | |
766 Widget menubar_widget; | |
767 | |
768 assert (FRAME_X_P (f)); | |
769 | |
770 menubar_widget = FRAME_X_MENUBAR_WIDGET (f); | |
771 if (menubar_widget) | |
772 { | |
1346 | 773 LWLIB_ID id = FRAME_X_MENUBAR_ID (f); |
428 | 774 lw_destroy_all_widgets (id); |
1346 | 775 ungcpro_popup_callbacks (id); |
776 FRAME_X_MENUBAR_ID (f) = 0; | |
428 | 777 } |
778 } | |
779 | |
780 static void | |
781 x_popup_menu (Lisp_Object menu_desc, Lisp_Object event) | |
782 { | |
783 int menu_id; | |
784 struct frame *f = selected_frame (); | |
785 widget_value *data; | |
786 Widget parent; | |
787 Widget menu; | |
440 | 788 Lisp_Event *eev = NULL; |
428 | 789 XEvent xev; |
793 | 790 Lisp_Object frame = wrap_frame (f); |
428 | 791 |
792 CHECK_X_FRAME (frame); | |
793 parent = FRAME_X_SHELL_WIDGET (f); | |
794 | |
795 if (!NILP (event)) | |
796 { | |
797 CHECK_LIVE_EVENT (event); | |
798 eev= XEVENT (event); | |
799 if (eev->event_type != button_press_event | |
800 && eev->event_type != button_release_event) | |
801 wrong_type_argument (Qmouse_event_p, event); | |
802 } | |
803 else if (!NILP (Vthis_command_keys)) | |
804 { | |
805 /* if an event wasn't passed, use the last event of the event sequence | |
806 currently being executed, if that event is a mouse event */ | |
807 eev = XEVENT (Vthis_command_keys); /* last event first */ | |
808 if (eev->event_type != button_press_event | |
809 && eev->event_type != button_release_event) | |
810 eev = NULL; | |
811 } | |
812 make_dummy_xbutton_event (&xev, parent, eev); | |
813 | |
814 if (SYMBOLP (menu_desc)) | |
815 menu_desc = Fsymbol_value (menu_desc); | |
816 CHECK_CONS (menu_desc); | |
817 CHECK_STRING (XCAR (menu_desc)); | |
818 data = menu_item_descriptor_to_widget_value (menu_desc, POPUP_TYPE, 1, 1); | |
819 | |
563 | 820 if (! data) signal_error (Qgui_error, "no menu", Qunbound); |
428 | 821 |
822 menu_id = new_lwlib_id (); | |
823 menu = lw_create_widget ("popup", "popup" /* data->name */, menu_id, data, | |
824 parent, 1, 0, | |
825 popup_menu_selection_callback, | |
826 popup_menu_down_callback); | |
827 free_popup_widget_value_tree (data); | |
828 | |
829 gcpro_popup_callbacks (menu_id); | |
830 | |
831 /* Setting zmacs-region-stays is necessary here because executing a command | |
832 from a menu is really a two-command process: the first command (bound to | |
833 the button-click) simply pops up the menu, and returns. This causes a | |
834 sequence of magic-events (destined for the popup-menu widget) to begin. | |
835 Eventually, a menu item is selected, and a menu-event blip is pushed onto | |
836 the end of the input stream, which is then executed by the event loop. | |
837 | |
838 So there are two command-events, with a bunch of magic-events between | |
839 them. We don't want the *first* command event to alter the state of the | |
840 region, so that the region can be available as an argument for the second | |
841 command. | |
442 | 842 */ |
428 | 843 if (zmacs_regions) |
844 zmacs_region_stays = 1; | |
845 | |
846 popup_up_p++; | |
847 lw_popup_menu (menu, &xev); | |
848 /* this speeds up display of pop-up menus */ | |
849 XFlush (XtDisplay (parent)); | |
850 } | |
851 | |
852 | |
442 | 853 |
854 #if defined(LWLIB_MENUBARS_LUCID) | |
855 static void | |
856 menu_move_up (void) | |
857 { | |
858 widget_value *current = lw_get_entries (False); | |
859 widget_value *entries = lw_get_entries (True); | |
860 widget_value *prev = NULL; | |
861 | |
862 while (entries != current) | |
863 { | |
864 if (entries->name /*&& entries->enabled*/) prev = entries; | |
865 entries = entries->next; | |
866 assert (entries); | |
867 } | |
868 | |
869 if (!prev) | |
870 /* move to last item */ | |
871 { | |
872 while (entries->next) | |
873 { | |
874 if (entries->name /*&& entries->enabled*/) prev = entries; | |
875 entries = entries->next; | |
876 } | |
877 if (prev) | |
878 { | |
879 if (entries->name /*&& entries->enabled*/) | |
880 prev = entries; | |
881 } | |
882 else | |
883 { | |
884 /* no selectable items in this menu, pop up to previous level */ | |
885 lw_pop_menu (); | |
886 return; | |
887 } | |
888 } | |
889 lw_set_item (prev); | |
890 } | |
891 | |
892 static void | |
893 menu_move_down (void) | |
894 { | |
895 widget_value *current = lw_get_entries (False); | |
3025 | 896 widget_value *new_ = current; |
442 | 897 |
3025 | 898 while (new_->next) |
442 | 899 { |
3025 | 900 new_ = new_->next; |
901 if (new_->name /*&& new_->enabled*/) break; | |
442 | 902 } |
903 | |
3025 | 904 if (new_==current||!(new_->name/*||new_->enabled*/)) |
442 | 905 { |
3025 | 906 new_ = lw_get_entries (True); |
907 while (new_!=current) | |
442 | 908 { |
3025 | 909 if (new_->name /*&& new_->enabled*/) break; |
910 new_ = new_->next; | |
442 | 911 } |
3025 | 912 if (new_==current&&!(new_->name /*|| new_->enabled*/)) |
442 | 913 { |
914 lw_pop_menu (); | |
915 return; | |
916 } | |
917 } | |
918 | |
3025 | 919 lw_set_item (new_); |
442 | 920 } |
921 | |
922 static void | |
923 menu_move_left (void) | |
924 { | |
925 int level = lw_menu_level (); | |
926 int l = level; | |
927 widget_value *current; | |
928 | |
929 while (level-- >= 3) | |
930 lw_pop_menu (); | |
931 | |
932 menu_move_up (); | |
933 current = lw_get_entries (False); | |
934 if (l > 2 && current->contents) | |
935 lw_push_menu (current->contents); | |
936 } | |
937 | |
938 static void | |
939 menu_move_right (void) | |
940 { | |
941 int level = lw_menu_level (); | |
942 int l = level; | |
943 widget_value *current; | |
944 | |
945 while (level-- >= 3) | |
946 lw_pop_menu (); | |
947 | |
948 menu_move_down (); | |
949 current = lw_get_entries (False); | |
950 if (l > 2 && current->contents) | |
951 lw_push_menu (current->contents); | |
952 } | |
953 | |
954 static void | |
955 menu_select_item (widget_value *val) | |
956 { | |
957 if (val == NULL) | |
958 val = lw_get_entries (False); | |
959 | |
960 /* is match a submenu? */ | |
961 | |
962 if (val->contents) | |
963 { | |
964 /* enter the submenu */ | |
965 | |
966 lw_set_item (val); | |
967 lw_push_menu (val->contents); | |
968 } | |
969 else | |
970 { | |
971 /* Execute the menu entry by calling the menu's `select' | |
972 callback function | |
973 */ | |
974 lw_kill_menus (val); | |
975 } | |
976 } | |
977 | |
978 Lisp_Object | |
979 command_builder_operate_menu_accelerator (struct command_builder *builder) | |
980 { | |
981 /* this function can GC */ | |
982 | |
983 struct console *con = XCONSOLE (Vselected_console); | |
984 Lisp_Object evee = builder->most_current_event; | |
985 Lisp_Object binding; | |
986 widget_value *entries; | |
987 | |
988 extern int lw_menu_accelerate; /* lwlib.c */ | |
989 | |
990 #if 0 | |
991 { | |
992 int i; | |
993 Lisp_Object t; | |
994 | |
995 t = builder->current_events; | |
996 i = 0; | |
997 while (!NILP (t)) | |
998 { | |
999 i++; | |
800 | 1000 write_fmt_string (Qexternal_debugging_output, "OPERATE (%d): ",i); |
442 | 1001 print_internal (t, Qexternal_debugging_output, 1); |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4528
diff
changeset
|
1002 write_ascstring (Qexternal_debugging_output, "\n"); |
442 | 1003 t = XEVENT_NEXT (t); |
1004 } | |
1005 } | |
1006 #endif /* 0 */ | |
1007 | |
1008 /* menu accelerator keys don't go into keyboard macros */ | |
1009 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro)) | |
1010 con->kbd_macro_ptr = con->kbd_macro_end; | |
1011 | |
1012 /* don't echo menu accelerator keys */ | |
1013 /*reset_key_echo (builder, 1);*/ | |
1014 | |
1015 if (!lw_menu_accelerate) | |
1016 { | |
1017 /* `convert' mouse display to keyboard display | |
1018 by entering the open submenu | |
1019 */ | |
1020 entries = lw_get_entries (False); | |
1021 if (entries->contents) | |
1022 { | |
1023 lw_push_menu (entries->contents); | |
1024 lw_display_menu (CurrentTime); | |
1025 } | |
1026 } | |
1027 | |
1028 /* compare event to the current menu accelerators */ | |
1029 | |
1030 entries=lw_get_entries (True); | |
1031 | |
1032 while (entries) | |
1033 { | |
1034 Lisp_Object accel; | |
826 | 1035 accel = VOID_TO_LISP (entries->accel); |
442 | 1036 if (entries->name && !NILP (accel)) |
1037 { | |
1204 | 1038 if (event_matches_key_specifier_p (evee, accel)) |
442 | 1039 { |
1040 /* a match! */ | |
1041 | |
1042 menu_select_item (entries); | |
1043 | |
1044 if (lw_menu_active) lw_display_menu (CurrentTime); | |
1045 | |
1046 reset_this_command_keys (Vselected_console, 1); | |
1047 /*reset_command_builder_event_chain (builder);*/ | |
1048 return Vmenu_accelerator_map; | |
1049 } | |
1050 } | |
1051 entries = entries->next; | |
1052 } | |
1053 | |
1054 /* try to look up event in menu-accelerator-map */ | |
1055 | |
1056 binding = event_binding_in (evee, Vmenu_accelerator_map, 1); | |
1057 | |
1058 if (NILP (binding)) | |
1059 { | |
1060 /* beep at user for undefined key */ | |
1061 return Qnil; | |
1062 } | |
1063 else | |
1064 { | |
1065 if (EQ (binding, Qmenu_quit)) | |
1066 { | |
1067 /* turn off menus and set quit flag */ | |
1068 lw_kill_menus (NULL); | |
1069 Vquit_flag = Qt; | |
1070 } | |
1071 else if (EQ (binding, Qmenu_up)) | |
1072 { | |
1073 int level = lw_menu_level (); | |
1074 if (level > 2) | |
1075 menu_move_up (); | |
1076 } | |
1077 else if (EQ (binding, Qmenu_down)) | |
1078 { | |
1079 int level = lw_menu_level (); | |
1080 if (level > 2) | |
1081 menu_move_down (); | |
1082 else | |
1083 menu_select_item (NULL); | |
1084 } | |
1085 else if (EQ (binding, Qmenu_left)) | |
1086 { | |
1087 int level = lw_menu_level (); | |
1088 if (level > 3) | |
1089 { | |
1090 lw_pop_menu (); | |
1091 lw_display_menu (CurrentTime); | |
1092 } | |
1093 else | |
1094 menu_move_left (); | |
1095 } | |
1096 else if (EQ (binding, Qmenu_right)) | |
1097 { | |
1098 int level = lw_menu_level (); | |
1099 if (level > 2 && | |
1100 lw_get_entries (False)->contents) | |
1101 { | |
1102 widget_value *current = lw_get_entries (False); | |
1103 if (current->contents) | |
1104 menu_select_item (NULL); | |
1105 } | |
1106 else | |
1107 menu_move_right (); | |
1108 } | |
1109 else if (EQ (binding, Qmenu_select)) | |
1110 menu_select_item (NULL); | |
1111 else if (EQ (binding, Qmenu_escape)) | |
1112 { | |
1113 int level = lw_menu_level (); | |
1114 | |
1115 if (level > 2) | |
1116 { | |
1117 lw_pop_menu (); | |
1118 lw_display_menu (CurrentTime); | |
1119 } | |
1120 else | |
1121 { | |
1122 /* turn off menus quietly */ | |
1123 lw_kill_menus (NULL); | |
1124 } | |
1125 } | |
1126 else if (KEYMAPP (binding)) | |
1127 { | |
1128 /* prefix key */ | |
1129 reset_this_command_keys (Vselected_console, 1); | |
1130 /*reset_command_builder_event_chain (builder);*/ | |
1131 return binding; | |
1132 } | |
1133 else | |
1134 { | |
1135 /* turn off menus and execute binding */ | |
1136 lw_kill_menus (NULL); | |
1137 reset_this_command_keys (Vselected_console, 1); | |
1138 /*reset_command_builder_event_chain (builder);*/ | |
1139 return binding; | |
1140 } | |
1141 } | |
1142 | |
1143 if (lw_menu_active) lw_display_menu (CurrentTime); | |
1144 | |
1145 reset_this_command_keys (Vselected_console, 1); | |
1146 /*reset_command_builder_event_chain (builder);*/ | |
1147 | |
1148 return Vmenu_accelerator_map; | |
1149 } | |
1150 | |
1151 static Lisp_Object | |
2286 | 1152 menu_accelerator_junk_on_error (Lisp_Object errordata, |
1153 Lisp_Object UNUSED (ignored)) | |
442 | 1154 { |
1155 Vmenu_accelerator_prefix = Qnil; | |
1156 Vmenu_accelerator_modifiers = Qnil; | |
1157 Vmenu_accelerator_enabled = Qnil; | |
1158 if (!NILP (errordata)) | |
1159 { | |
1160 /* #### This should call | |
1161 (with-output-to-string (display-error errordata)) | |
1162 but that stuff is all in Lisp currently. */ | |
1163 warn_when_safe_lispobj | |
1164 (Qerror, Qwarning, | |
771 | 1165 emacs_sprintf_string_lisp |
1166 ("%s: %s", Qnil, 2, | |
1167 build_msg_string ("Error in menu accelerators (setting to nil)"), | |
1168 errordata)); | |
442 | 1169 } |
1170 | |
1171 return Qnil; | |
1172 } | |
1173 | |
1174 static Lisp_Object | |
1175 menu_accelerator_safe_compare (Lisp_Object event0) | |
1176 { | |
1177 if (CONSP (Vmenu_accelerator_prefix)) | |
1178 { | |
1179 Lisp_Object t; | |
1180 t=Vmenu_accelerator_prefix; | |
1181 while (!NILP (t) | |
1182 && !NILP (event0) | |
1204 | 1183 && event_matches_key_specifier_p (event0, Fcar (t))) |
442 | 1184 { |
1185 t = Fcdr (t); | |
1186 event0 = XEVENT_NEXT (event0); | |
1187 } | |
1188 if (!NILP (t)) | |
1189 return Qnil; | |
1190 } | |
1191 else if (NILP (event0)) | |
1192 return Qnil; | |
1204 | 1193 else if (event_matches_key_specifier_p (event0, Vmenu_accelerator_prefix)) |
442 | 1194 event0 = XEVENT_NEXT (event0); |
1195 else | |
1196 return Qnil; | |
1197 return event0; | |
1198 } | |
1199 | |
1200 static Lisp_Object | |
1201 menu_accelerator_safe_mod_compare (Lisp_Object cons) | |
1202 { | |
1204 | 1203 return (event_matches_key_specifier_p (XCAR (cons), XCDR (cons)) ? Qt |
442 | 1204 : Qnil); |
1205 } | |
1206 | |
1207 Lisp_Object | |
1208 command_builder_find_menu_accelerator (struct command_builder *builder) | |
1209 { | |
1210 /* this function can GC */ | |
1211 Lisp_Object event0 = builder->current_events; | |
1212 struct console *con = XCONSOLE (Vselected_console); | |
1213 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con)); | |
1214 Widget menubar_widget; | |
1215 | |
1216 /* compare entries in event0 against the menu prefix */ | |
1217 | |
1218 if ((!CONSOLE_X_P (XCONSOLE (builder->console))) || NILP (event0) || | |
1219 XEVENT (event0)->event_type != key_press_event) | |
1220 return Qnil; | |
1221 | |
1222 if (!NILP (Vmenu_accelerator_prefix)) | |
1223 { | |
1224 event0 = condition_case_1 (Qerror, | |
1225 menu_accelerator_safe_compare, | |
1226 event0, | |
1227 menu_accelerator_junk_on_error, | |
1228 Qnil); | |
1229 } | |
1230 | |
1231 if (NILP (event0)) | |
1232 return Qnil; | |
1233 | |
1234 menubar_widget = FRAME_X_MENUBAR_WIDGET (f); | |
1235 if (menubar_widget | |
1236 && CONSP (Vmenu_accelerator_modifiers)) | |
1237 { | |
446 | 1238 Lisp_Object fake = Qnil; |
442 | 1239 Lisp_Object last = Qnil; |
1240 struct gcpro gcpro1; | |
1241 Lisp_Object matchp; | |
1242 | |
1243 widget_value *val; | |
1346 | 1244 LWLIB_ID id = FRAME_X_MENUBAR_ID (f); |
442 | 1245 |
1246 val = lw_get_all_values (id); | |
1247 if (val) | |
1248 { | |
1249 val = val->contents; | |
1250 | |
1251 fake = Fcopy_sequence (Vmenu_accelerator_modifiers); | |
1252 last = fake; | |
1253 | |
1254 while (!NILP (Fcdr (last))) | |
1255 last = Fcdr (last); | |
1256 | |
1257 Fsetcdr (last, Fcons (Qnil, Qnil)); | |
1258 last = Fcdr (last); | |
1259 } | |
1260 | |
1261 fake = Fcons (Qnil, fake); | |
1262 | |
1263 GCPRO1 (fake); | |
1264 | |
1265 while (val) | |
1266 { | |
1267 Lisp_Object accel; | |
826 | 1268 accel = VOID_TO_LISP (val->accel); |
442 | 1269 if (val->name && !NILP (accel)) |
1270 { | |
1271 Fsetcar (last, accel); | |
1272 Fsetcar (fake, event0); | |
1273 matchp = condition_case_1 (Qerror, | |
1274 menu_accelerator_safe_mod_compare, | |
1275 fake, | |
1276 menu_accelerator_junk_on_error, | |
1277 Qnil); | |
1278 if (!NILP (matchp)) | |
1279 { | |
1280 /* we found one! */ | |
1281 | |
1282 lw_set_menu (menubar_widget, val); | |
1283 /* yah - yet another hack. | |
1284 pretend emacs timestamp is the same as an X timestamp, | |
1285 which for the moment it is. (read events.h) | |
1286 */ | |
1287 lw_map_menu (XEVENT (event0)->timestamp); | |
1288 | |
1289 if (val->contents) | |
1290 lw_push_menu (val->contents); | |
1291 | |
1292 lw_display_menu (CurrentTime); | |
1293 | |
1294 /* menu accelerator keys don't go into keyboard macros */ | |
1295 if (!NILP (con->defining_kbd_macro) | |
1296 && NILP (Vexecuting_macro)) | |
1297 con->kbd_macro_ptr = con->kbd_macro_end; | |
1298 | |
1299 /* don't echo menu accelerator keys */ | |
1300 /*reset_key_echo (builder, 1);*/ | |
1301 reset_this_command_keys (Vselected_console, 1); | |
1302 UNGCPRO; | |
1303 | |
1304 return Vmenu_accelerator_map; | |
1305 } | |
1306 } | |
1307 | |
1308 val = val->next; | |
1309 } | |
1310 | |
1311 UNGCPRO; | |
1312 } | |
1313 return Qnil; | |
1314 } | |
1315 | |
1316 int | |
1317 x_kludge_lw_menu_active (void) | |
1318 { | |
1319 return lw_menu_active; | |
1320 } | |
1321 | |
1322 DEFUN ("accelerate-menu", Faccelerate_menu, 0, 0, "_", /* | |
1323 Make the menubar active. Menu items can be selected using menu accelerators | |
1324 or by actions defined in menu-accelerator-map. | |
1325 */ | |
1326 ()) | |
1327 { | |
1328 struct console *con = XCONSOLE (Vselected_console); | |
1329 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con)); | |
1330 LWLIB_ID id; | |
1331 widget_value *val; | |
1332 | |
1346 | 1333 if (!FRAME_X_MENUBAR_ID (f)) |
563 | 1334 invalid_argument ("Frame has no menubar", Qunbound); |
442 | 1335 |
1346 | 1336 id = FRAME_X_MENUBAR_ID (f); |
442 | 1337 val = lw_get_all_values (id); |
1338 val = val->contents; | |
1339 lw_set_menu (FRAME_X_MENUBAR_WIDGET (f), val); | |
1340 lw_map_menu (CurrentTime); | |
1341 | |
1342 lw_display_menu (CurrentTime); | |
1343 | |
1344 /* menu accelerator keys don't go into keyboard macros */ | |
1345 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro)) | |
1346 con->kbd_macro_ptr = con->kbd_macro_end; | |
1347 | |
1348 return Qnil; | |
1349 } | |
1350 #endif /* LWLIB_MENUBARS_LUCID */ | |
1351 | |
1352 | |
428 | 1353 void |
1354 syms_of_menubar_x (void) | |
1355 { | |
442 | 1356 #if defined(LWLIB_MENUBARS_LUCID) |
1357 DEFSUBR (Faccelerate_menu); | |
1358 #endif | |
428 | 1359 } |
1360 | |
1361 void | |
1362 console_type_create_menubar_x (void) | |
1363 { | |
1364 CONSOLE_HAS_METHOD (x, update_frame_menubars); | |
1365 CONSOLE_HAS_METHOD (x, free_frame_menubars); | |
1366 CONSOLE_HAS_METHOD (x, popup_menu); | |
1367 } | |
1368 | |
1369 void | |
1370 reinit_vars_of_menubar_x (void) | |
1371 { | |
1372 last_popup_menu_selection_callback_id = (LWLIB_ID) -1; | |
1373 } | |
1374 | |
1375 void | |
1376 vars_of_menubar_x (void) | |
1377 { | |
1378 #if defined (LWLIB_MENUBARS_LUCID) | |
1379 Fprovide (intern ("lucid-menubars")); | |
1380 #elif defined (LWLIB_MENUBARS_MOTIF) | |
1381 Fprovide (intern ("motif-menubars")); | |
1382 #elif defined (LWLIB_MENUBARS_ATHENA) | |
1383 Fprovide (intern ("athena-menubars")); | |
1384 #endif | |
1385 } |