summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog713
-rw-r--r--src/Makefile.in17
-rw-r--r--src/abbrev.c74
-rw-r--r--src/alloc.c20
-rw-r--r--src/buffer.c2
-rw-r--r--src/callint.c13
-rw-r--r--src/casetab.c2
-rw-r--r--src/coding.c6
-rw-r--r--src/config.in9
-rw-r--r--src/data.c17
-rw-r--r--src/dispextern.h4
-rw-r--r--src/doc.c2
-rw-r--r--src/editfns.c36
-rw-r--r--src/emacs.c17
-rw-r--r--src/eval.c150
-rw-r--r--src/fileio.c7
-rw-r--r--src/fns.c49
-rw-r--r--src/fontset.c2
-rw-r--r--src/frame.c18
-rw-r--r--src/frame.h4
-rw-r--r--src/gmalloc.c2
-rw-r--r--src/image.c105
-rw-r--r--src/keyboard.c117
-rw-r--r--src/keymap.c507
-rw-r--r--src/keymap.h4
-rw-r--r--src/lisp.h30
-rw-r--r--src/lread.c7
-rw-r--r--src/m/alpha.h4
-rw-r--r--src/mac.c4
-rw-r--r--src/macfns.c46
-rw-r--r--src/macgui.h13
-rw-r--r--src/macmenu.c273
-rw-r--r--src/macselect.c11
-rw-r--r--src/macterm.c2853
-rw-r--r--src/macterm.h53
-rw-r--r--src/minibuf.c26
-rw-r--r--src/process.c364
-rw-r--r--src/process.h76
-rw-r--r--src/regex.c76
-rw-r--r--src/regex.h2
-rw-r--r--src/search.c181
-rw-r--r--src/sunfns.c2
-rw-r--r--src/sysdep.c8
-rw-r--r--src/term.c770
-rw-r--r--src/termhooks.h15
-rw-r--r--src/w32.c54
-rw-r--r--src/w32term.c9
-rw-r--r--src/window.c107
-rw-r--r--src/xdisp.c36
-rw-r--r--src/xfaces.c2
-rw-r--r--src/xfns.c10
-rw-r--r--src/xmenu.c8
-rw-r--r--src/xselect.c2
-rw-r--r--src/xterm.c56
-rw-r--r--src/xterm.h1
55 files changed, 4956 insertions, 2040 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 419f39e034f..3779a9fe8f3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -4,6 +4,16 @@
* COPYING: Switch to GPLv3.
+2007-07-25 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * eval.c (Fcommandp): Pay attention to the `interactive-form' property.
+
+ * data.c (Finteractive_form): Check for the presence of an
+ `interactive-form' symbol property more thoroughly.
+
+ * data.c (Finteractive_form): Use an `interactive-form' property if
+ present, analogous to the function-documentation property.
+
2007-07-24 Jason Rumney <jasonr@gnu.org>
* w32fns.c (x_real_positions): Get real position from OS instead of
@@ -13,9 +23,14 @@
* filelock.c (current_lock_owner): Allow for @ sign in username.
-2007-07-20 Eli Zaretskii <eliz@gnu.org>
+2007-07-22 Nick Roberts <nickrob@snap.net.nz>
- * makefile.w32-in (clean): Don't delete *~.
+ * xdisp.c (decode_mode_spec): Add case 'R' for to test for
+ remote default-directory.
+
+ * buffer.c (mode-line-format): Describe above case in doc string.
+
+2007-07-20 Eli Zaretskii <eliz@gnu.org>
* w32proc.c (IMAGE_NT_OPTIONAL_HDR32_MAGIC, IMAGE_OPTIONAL_HEADER32):
Define if not defined.
@@ -24,20 +39,107 @@
* w32proc.c (w32_executable_type): Handle 64 bit executables.
-2007-07-16 Juanma Barranquero <lekktu@gmail.com>
+2007-07-18 Richard Stallman <rms@gnu.org>
+
+ * data.c (Fsetq_default): Doc fix.
+
+ * eval.c (Fsetq): Doc fix.
+
+2007-07-18 Juanma Barranquero <lekktu@gmail.com>
* coding.c (Ffind_operation_coding_system):
- * eval.c (For, Fand, Fprogn):
+ * eval.c (For, Fand): Doc fixes.
+ Reported by Johan Bockg,Ae(Brd.
+
+2007-07-18 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * xfns.c (Fx_focus_frame): Call x_ewmh_activate_frame.
+
+ * xterm.h: Declare x_ewmh_activate_frame.
+
+ * xterm.c (x_ewmh_activate_frame): New function.
+ (XTframe_raise_lower): Move code to x_ewmh_activate_frame.
+
+2007-07-17 Martin Rudalics <rudalics@gmx.at>
+
+ * window.c (Fdisplay_buffer): If largest or LRU window is the
+ only window, split it even if it is not eligible for splitting.
+ This restores the original behavior broken by the 2007-07-15
+ change.
+
+2007-07-17 Glenn Morris <rgm@gnu.org>
+
+ * abbrev.c (abbrev_check_chars): New function.
+ (Fdefine_global_abbrev, Fdefine_mode_abbrev): Call
+ abbrev_check_chars to check abbrev characters are word
+ constituents. Doc fix.
+
+2007-07-17 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * process.c (Fstart_process, Fmake_network_process)
+ (read_process_output): Fix up last changes.
+
+2007-07-16 Eli Zaretskii <eliz@gnu.org>
+
+ * makefile.w32-in (clean): Don't delete *~.
+
+2007-07-16 Andreas Schwab <schwab@suse.de>
+
+ * window.c (Fdisplay_buffer): Use NILP.
+ (Fset_window_scroll_bars): Likewise.
+
+2007-07-15 Martin Rudalics <rudalics@gmx.at>
+
+ * window.c (window_min_size_2): New function.
+ (window_min_size_1, size_window, Fdisplay_buffer)
+ (Fsplit_window, adjust_window_trailing_edge): Use it to avoid
+ windows without mode- or header-lines when window-min-height is
+ too small.
+ (size_window): Reset nodelete_p after testing it, following an
+ earlier note by Kim F. Storm.
+ (display_buffer): Do not set split_height_threshold to twice the
+ value of window_min_height to avoid changing the value of a
+ customizable variable. Rather explicitly check whether the
+ height of the window that shall be splitted is at least as large
+ as split_height_threshold.
+
+2007-07-14 Jason Rumney <jasonr@gnu.org>
+
+ * process.c [WINDOWSNT]: Don't undefine AF_INET6.
+
+2007-07-14 Richard Stallman <rms@gnu.org>
+
+ * eval.c (maybe_call_debugger): New function.
+ (find_handler_clause): Use maybe_call_debugger.
+ Call it when the handler says `debug'.
+ Eliminate DEBUGGER_VALUE_PTR.
+ (Fsignal): Eliminate debugger_value.
+ (Qdebug): New variable.
+ (syms_of_eval): Initialize it.
+
+2007-07-14 Juanma Barranquero <lekktu@gmail.com>
+
+ * eval.c (Fprogn):
* keyboard.c (Ftrack_mouse):
* print.c (Fwith_output_to_temp_buffer):
- * window.c (Fsave_window_excursion): Doc fixes (some reported
- by Johan Bockg,Ae(Brd).
+ * window.c (Fsave_window_excursion): Doc fix.
-2007-07-15 Richard Stallman <rms@gnu.org>
+2007-07-13 Stefan Monnier <monnier@iro.umontreal.ca>
- * data.c (Fsetq_default): Doc fix.
+ * eval.c (init_eval_once): Bump max_lisp_eval_depth to 400.
- * eval.c (Fsetq): Doc fix.
+2007-07-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * process.h (struct Lisp_Process): Turn slots infd, outfd,
+ kill_without_query, pty_flag, tick, update_tick, decoding_carryover,
+ inherit_coding_system_flag, filter_multibyte, adaptive_read_buffering,
+ read_output_delay, and read_output_skip from Lisp_Objects to ints.
+ Remove unused encoding_carryover.
+ * process.c: Adjust all functions accordingly.
+
+2007-07-12 Richard Stallman <rms@gnu.org>
+
+ * term.c: Include unistd.h only if HAVE_UNISTD_H.
2007-07-11 Jason Rumney <jasonr@gnu.org>
@@ -46,10 +148,74 @@
* w32fns.c (w32_msg_pump) <WM_EMACS_CREATEWINDOW>: Initialize COM.
(w32_msg_pump) <WM_DESTROY>: Uninitialize COM.
+2007-07-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp.h (struct Lisp_Hash_Table): Turn next_weak into a bare pointer.
+ * fns.c (weak_hash_tables): Rename from Vweak_hash_tables and turned
+ from a Lisp_Object into a bare pointer.
+ (make_hash_table, copy_hash_table, sweep_weak_hash_tables, init_fns):
+ Adjust the code correspondingly.
+
+ * alloc.c (emacs_blocked_free): Remove unused var `bytes_used_now'.
+
+ * term.c: Include unistd.h for ttyname, used in handle_one_term_event.
+ (term_show_mouse_face): Remove unused var `j'.
+ (handle_one_term_event): Remove unused vars `i' and `j'.
+ Don't cast return value of ttyname since it's not necessary.
+
+2007-07-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * alloc.c (mark_maybe_pointer): Enforce mult-of-8 alignment when using
+ USE_LSB_TAG. Suggested by Dmitry Antipov <dmantipov@yandex.ru>.
+
+ * fns.c (map_char_table): Use an array of int for `indices' rather than
+ an array of Lisp_Objects (which are only ever integers anyway).
+ (Fmap_char_table): Update caller.
+ * lisp.h: Update prototype.
+ * keymap.c (Fset_keymap_parent, map_keymap, Fcopy_keymap):
+ * fontset.c (Ffontset_info):
+ * casetab.c (set_case_table): Update callers.
+
+ * editfns.c (Ftranspose_regions): Use EMACS_INT for positions.
+
+ * keymap.c (struct accessible_keymaps_data)
+ (struct where_is_internal_data): New structures.
+ (accessible_keymaps_1, where_is_internal_1): Use them to change
+ interface to adhere to the one used by map_keymap.
+ (Faccessible_keymaps, where_is_internal): Use map_keymap.
+ (accessible_keymaps_char_table, where_is_internal_2): Remove.
+
+ * keymap.h (map_keymap_function_t): More informative prototype.
+
+2007-07-10 Guanpeng Xu <herberteuler@hotmail.com>
+
+ * search.c (Vinhibit_changing_match_data, search_regs_1): New vars.
+ (looking_at_1): Don't change search_regs and last_thing_searched
+ if `inhibit-changing-match-data' is non-nil.
+ (string_match_1, search_buffer, set_search_regs): Likewise.
+ (syms_of_search): Add Lisp level definition for
+ `inhibit-changing-match-data' and set it to nil.
+ (boyer_moore): If `inhibit-changing-match-data' is non-nil, compute
+ start and end of the match, instead of using values in search_regs.
+
+2007-07-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * minibuf.c (Fcompleting_read): New value `confirm-only'
+ for `require-match'.
+
+2007-06-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * fileio.c (Fdo_auto_save): Revert last patch installed unwillingly as
+ part of the 2007-06-27 change to syms_of_fileio.
+
2007-06-28 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* macterm.c [USE_MAC_TSM] (mac_handle_text_input_event):
- Check WINDOWP before using XWINDOW.
+ Check WINDOWP before using XWINDOW. Consolidate return statements.
+
+2007-06-27 Richard Stallman <rms@gnu.org>
+
+ * fileio.c (syms_of_fileio) <after-insert-file-functions>: Doc fix.
2007-06-27 Juanma Barranquero <lekktu@gmail.com>
@@ -73,6 +239,49 @@
Copy hook value to automatic variable before its use.
(memalign): Copy hook value to automatic variable before its use.
+2007-06-26 Kenichi Handa <handa@m17n.org>
+
+ * coding.c (Ffind_operation_coding_system): Docstring improved.
+ (syms_of_coding): Docstring of `file-coding-system-alist' improved.
+
+2007-06-25 David Kastrup <dak@gnu.org>
+
+ * keymap.c (Fcurrent_active_maps): Add `position' argument.
+ (Fwhere_is_internal): Adjust call to `current-active-maps' to
+ cater for additional parameter.
+
+ * keymap.h: Adjust number of parameters to `current-active-maps'.
+
+ * doc.c (Fsubstitute_command_keys): Adjust call of
+ `current-active-maps'.
+
+2007-06-25 David Kastrup <dak@gnu.org>
+
+ * callint.c (Fcall_interactively): Make the parsing of interactive
+ specs somewhat more readable.
+
+2007-06-23 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (x_draw_fringe_bitmap) [MAC_OSX]: Extend fringe background
+ to scroll bar gap also when bitmap fills fringe. Draw only foreground
+ if extended background has already been filled.
+
+2007-06-22 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macgui.h (USE_CG_DRAWING): Don't require USE_ATSUI.
+ (USE_MAC_TOOLBAR): Require USE_CG_DRAWING.
+
+ * macmenu.c (mac_dialog_modal_filter, Fx_popup_dialog) [MAC_OSX]:
+ Put special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p
+ in #if 0 as it is not compatible with y-or-n-p-with-timeout.
+ (timer_check) [TARGET_API_MAC_CARBON]: Add extern.
+ [TARGET_API_MAC_CARBON] (mac_handle_dialog_event): Use QuitEventLoop
+ instead of QuitAppModalLoopForWindow. Consolidate QuitEventLoop calls.
+ (pop_down_dialog) [TARGET_API_MAC_CARBON]: New function.
+ [TARGET_API_MAC_CARBON] (create_and_show_dialog): Use it for unwind.
+ Run timers during dialog popup.
+ (Fmenu_or_popup_active_p) [TARGET_API_MAC_CARBON]: Use popup_activated.
+
2007-06-21 Jason Rumney <jasonr@gnu.org>
* image.c (convert_mono_to_color_image): Swap fore and background.
@@ -82,18 +291,30 @@
* w32bdf.c (w32_BDF_to_x_font): Unmap memory when finished.
(w32_free_bdf_font): Unmap memory not handle.
+2007-06-20 Sam Steingold <sds@gnu.org>
+
+ * gmalloc.c (__morecore): Fix the declaration to comply with the
+ definition.
+
2007-06-20 Juanma Barranquero <lekktu@gmail.com>
+ * w32term.c (w32_delete_display): Remove leftover declaration.
+ (w32_define_cursor, w32_initialize): Make static.
+
* w32.c (_wsa_errlist): Fix typo in error message.
(init_environment): Ignore any environment variable from the
registry having a null value.
+2007-06-20 Glenn Morris <rgm@gnu.org>
+
+ * Makefile.in (LIBGIF): Default to -lgif.
+
2007-06-17 Jason Rumney <jasonr@gnu.org>
* w32menu.c (add_menu_item): Don't use multibyte string functions on
unicode strings.
-2007-06-17 Juanma Barranquero <lekktu@gmail.com>
+2007-06-16 Juanma Barranquero <lekktu@gmail.com>
* xdisp.c (syms_of_xdisp) <auto-resize-tool-bars>:
Fix typo in docstring.
@@ -103,41 +324,272 @@
* w32menu.c (add_menu_item): Escape `&' characters in menu items
and their keybindings.
+2007-06-15 Chong Yidong <cyd@stupidchicken.com>
+
+ * composite.c (update_compositions): Fix last fix.
+
+2007-06-14 Jason Rumney <jasonr@gnu.org>
+
+ * w32.c (get_process_times_fn): New function pointer.
+ (globals_of_w32): Intialize it if present in kernel32.dll.
+ (w32_get_internal_run_time): New function.
+
+ * editfns.c (Fget_internal_run_time) [WINDOWSNT]: Use it.
+
+2007-06-14 Kenichi Handa <handa@etlken.m17n.org>
+
+ * composite.c (update_compositions): Check the validness of
+ compositions.
+
+2007-06-14 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * frame.h (struct frame) [MAC_OS]: New member external_tool_bar.
+ (FRAME_EXTERNAL_TOOL_BAR) [MAC_OS]: Use it.
+
+ * macfns.c (mac_window) [USE_MAC_TOOLBAR]: Set toolbar_win_gravity.
+ (x_set_tool_bar_lines) [USE_MAC_TOOLBAR]: Set FRAME_EXTERNAL_TOOL_BAR.
+
+ * macgui.h (USE_MAC_TOOLBAR): New define.
+
+ * macmenu.c [TARGET_API_MAC_CARBON] (menu_target_item_handler):
+ Return immediately unless popup is activated.
+
+ * macterm.c (x_draw_fringe_bitmap) [MAC_OSX]: Extend fringe
+ background to scroll bar gap.
+ (x_scroll_bar_create) [MAC_OSX]: Set bar->fringe_extended_p.
+ (XTset_vertical_scroll_bar) [MAC_OSX]: Put leftmost/rightmost
+ scroll bars on frame edge. Check fringe background extension.
+ Don't clear extended fringe background area.
+ (TOOLBAR_IDENTIFIER, TOOLBAR_ICON_ITEM_IDENTIFIER)
+ (TOOLBAR_ITEM_COMMAND_ID_OFFSET, TOOLBAR_ITEM_COMMAND_ID_P)
+ (TOOLBAR_ITEM_COMMAND_ID_VALUE, TOOLBAR_ITEM_MAKE_COMMAND_ID):
+ [USE_MAC_TOOLBAR]: New macros.
+ (mac_move_window_with_gravity, mac_get_window_origin_with_gravity)
+ (mac_handle_toolbar_event, mac_image_spec_to_cg_image)
+ (mac_create_frame_tool_bar, update_frame_tool_bar, free_frame_tool_bar)
+ (mac_tool_bar_note_mouse_movement, mac_handle_toolbar_command_event)
+ [USE_MAC_TOOLBAR]: New functions.
+ (mac_handle_window_event) [USE_MAC_TOOLBAR]: Reposition window
+ manually if previous repositioning has failed.
+ (mac_handle_keyboard_event): Use precomputed event kind.
+ (XTread_socket) [USE_MAC_TOOLBAR]: Handle click in structure region
+ as tool bar item click. Handle mouse movement over tool bar items.
+
+ * macterm.h (struct mac_output) [USE_MAC_TOOLBAR]: New member
+ toolbar_win_gravity.
+ (struct scroll_bar) [MAC_OSX]: New member fringe_extended_p.
+ (update_frame_tool_bar, free_frame_tool_bar) [USE_MAC_TOOLBAR]:
+ Add externs.
+
+ * xdisp.c (update_tool_bar, redisplay_tool_bar, redisplay_window)
+ [USE_MAC_TOOLBAR]: Sync with GTK+ tool bar display.
+
2007-06-14 Chong Yidong <cyd@stupidchicken.com>
- * composite.c (update_compositions): Check validity of compositions.
+ * image.c (search_image_cache): Remove unused variable.
+
+2007-06-13 Chong Yidong <cyd@stupidchicken.com>
+
+ * xfns.c, xmenu.c: Link to xaw3d if available.
+
+2007-06-13 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * dispextern.h (struct image) [HAVE_WINDOW_SYSTEM]: New members
+ frame_foreground and frame_background.
+
+ * image.c (lookup_image): Save frame foreground and background colors.
+ (search_image_cache): Check if saved and current frame colors match.
+
+2007-06-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * regex.c (regex_compile): Remove the `regnum' counter.
+ Use bufp->re_nsub instead. Add support for \(?N:RE\).
+
+2007-06-11 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * term.c: Include intervals.h to declare Fget_text_property.
2007-06-10 Jason Rumney <jasonr@gnu.org>
* w32fns.c (Fx_file_dialog): Take size from struct not pointer.
-2007-06-06 Jason Rumney <jasonr@gnu.org>
+2007-06-08 Juanma Barranquero <lekktu@gmail.com>
+
+ * callint.c (Fcall_interactively):
+ * editfns.c (Fdelete_and_extract_region):
+ * fileio.c (Fread_file_name):
+ * fns.c (Fmapconcat):
+ * keyboard.c (cmd_error_internal):
+ * keymap.c (Fkey_description):
+ * lread.c (openp):
+ * minibuf.c (read_minibuf):
+ * search.c (wordify):
+ * sunfns.c (sel_read):
+ * xdisp.c (Fformat_mode_line, syms_of_xdisp):
+ * xfns.c (x_default_scroll_bar_color_parameter):
+ * xmenu.c (menu_help_callback):
+ * xselect.c (Fx_get_atom_name):
+ * xterm.c (x_term_init): Use empty_unibyte_string.
+
+2007-06-08 Dmitry Antipov <dmantipov@yandex.ru> (tiny change)
+
+ * alloc.c (init_strings): Initialize canonical empty strings.
+ (make_uninit_string, make_uninit_multibyte_string): Return appropriate
+ canonical empty string when the requested size is 0.
+
+ * emacs.c (empty_unibyte_string): Rename from empty_string.
+ (empty_multibyte_string): New canonical empty string.
+ (syms_of_emacs): Don't initialize empty_string.
+
+ * lisp.h (STRING_SET_UNIBYTE): Return the canonical empty unibyte
+ string, if appropriate.
+ (empty_unibyte_string, empty_multibyte_string): New externs.
+ (empty_string): Remove extern.
+
+ * lread.c (syms_of_lread): Use empty_unibyte_string.
+
+2007-06-07 Jason Rumney <jasonr@gnu.org>
* s/ms-w32.h: Don't define HAVE_TZNAME.
+ * editfns.c (Fcurrent_time_zone): Remove hack for Japanese Windows.
+
+2007-06-07 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * mac.c (xrm_get_preference_database): Remove BLOCK_INPUT.
+
+ * macfns.c (mac_get_window_bounds): Move extern to macterm.h.
+ (compute_tip_xy) [TARGET_API_MAC_CARBON]: Use GetGlobalMouse.
+
+ * macmenu.c [TARGET_API_MAC_CARBON] (menu_target_item_handler):
+ Don't call next handler.
+ [TARGET_API_MAC_CARBON] (install_menu_target_item_handler):
+ Remove argument. Install handler to application.
+ (set_frame_menubar): Don't change deep_p.
+ (mac_menu_show): Use FRAME_OUTER_TO_INNER_DIFF_X and
+ FRAME_OUTER_TO_INNER_DIFF_Y.
+ (DIALOG_BUTTON_COMMAND_ID_OFFSET, DIALOG_BUTTON_COMMAND_ID_P)
+ (DIALOG_BUTTON_COMMAND_ID_VALUE, DIALOG_BUTTON_MAKE_COMMAND_ID)
+ [HAVE_DIALOGS]: New macros.
+ [HAVE_DIALOGS] (mac_handle_dialog_event, create_and_show_dialog):
+ Use them.
+ (fill_menubar) [TARGET_API_MAC_CARBON]: Use CFString.
+
+ * macselect.c [MAC_OSX] (install_service_handler): Rename from
+ init_service_handler. All callers changed. Return OSStatus value.
+
+ * macterm.c (mac_begin_cg_clip): New arg F. Call SetPortWindowPort.
+ All callers changed so as not to call SetPortWindowPort.
+ (mac_begin_cg_clip) [USE_CG_DRAWING]: Call mac_prepare_for_quickdraw.
+ (mac_draw_image_string_atsui) [USE_ATSUI]: New function created from
+ mac_draw_string_common.
+ (mac_draw_image_string_qd): Likewise.
+ (mac_draw_string_common): Use them. Add INLINE.
+ (XTmouse_position, x_scroll_bar_report_motion) [TARGET_API_MAC_CARBON]:
+ Use FRAME_OUTER_TO_INNER_DIFF_X, FRAME_OUTER_TO_INNER_DIFF_Y, and
+ GetGlobalMouse.
+ (x_set_mouse_pixel_position) [MAC_OSX]: Use FRAME_OUTER_TO_INNER_DIFF_X
+ and FRAME_OUTER_TO_INNER_DIFF_Y.
+ [TARGET_API_MAC_CARBON] (mac_handle_mouse_event): Likewise.
+ [USE_MAC_TSM] (mac_handle_text_input_event): Likewise.
+ (x_make_frame_visible) [TARGET_API_MAC_CARBON]: Move code for
+ repositioning window to mac_handle_window_event.
+ (x_make_frame_invisible) [TARGET_API_MAC_CARBON]: Move code for
+ saving window location to mac_handle_window_event
+ [USE_MAC_FONT_PANEL] (mac_show_hide_font_panel): Install handler here.
+ (install_menu_target_item_handler): Remove argument in extern.
+ [TARGET_API_MAC_CARBON] (mac_event_to_emacs_modifiers):
+ Also accept command events.
+ (do_keystroke): New function created from XTread_socket.
+ (init_command_handler): Remove functions.
+ [TARGET_API_MAC_CARBON] (mac_handle_window_event): Reposition window
+ and save window location by kEventWindowShowing and kEventWindowHiding
+ handlers here. Don't call next handler for window state change and
+ focus events.
+ (mac_handle_application_event, mac_handle_keyboard_event)
+ [TARGET_API_MAC_CARBON]: New functions.
+ (install_window_handler) [TARGET_API_MAC_CARBON]: Register handlers for
+ kEventWindowShowing and kEventWindowHiding events. Move installation
+ of mouse, font, text input and menu target item handlers to
+ install_application_handler.
+ (install_application_handler) [TARGET_API_MAC_CARBON]: New function.
+ (mac_handle_cg_display_reconfig) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+ New function.
+ (init_dm_notification_handler) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+ Register it.
+ (XTread_socket) [TARGET_API_MAC_CARBON]:
+ Consolidate SendEventToEventTarget calls.
+ Use FRAME_OUTER_TO_INNER_DIFF_X and FRAME_OUTER_TO_INNER_DIFF_Y.
+ Move application activation handler to mac_handle_application_event.
+ Move keyboard handler to mac_handle_keyboard_event.
+ (XTread_socket) [!TARGET_API_MAC_CARBON]: Use do_keystroke.
+ (mac_initialize) [TARGET_API_MAC_CARBON]: Don't call
+ init_command_handler. Call install_application_handler.
+
+ * macterm.h (mac_get_window_bounds): Move extern from macfns.c.
+ (FRAME_OUTER_TO_INNER_DIFF_X, FRAME_OUTER_TO_INNER_DIFF_Y): New macros.
+
+2007-06-07 Glenn Morris <rgm@gnu.org>
+
+ * emacs.c (main): Use `emacs-copyright' in --version output.
+
2007-06-06 Chong Yidong <cyd@stupidchicken.com>
- * image.c (xpm_load): Remove spurious call to
- xpm_init_color_cache.
+ * image.c (xpm_load): Remove spurious call to xpm_init_color_cache.
-2007-06-06 Martin Rudalics <rudalics@gmx.at>
+2007-06-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
- * syntax.c (scan_words): Fix arg to UPDATE_SYNTAX_TABLE_BACKWARD.
+ * macfns.c (mac_window): Replace WindowPtr with WindowRef.
-2007-06-05 Dan Nicolaescu <dann@ics.uci.edu>
+ * macgui.h: Replace WindowPtr with WindowRef.
- * xfaces.c (syms_of_xfaces): Delete stray semicolon.
- * xdisp.c (next_element_from_buffer):
- * window.c (delete_window):
- * term.c (term_mouse_highlight):
- * msdos.c (getdefdir):
- * macterm.c (mac_create_bitmap_from_bitmap_data)
- (init_font_name_table):
- * fns.c (Fsxhash):
- * data.c (Fmake_local_variable):
- * ccl.c (ccl_driver): Likewise.
+ * macmenu.c: Replace MenuHandle and GetMenuHandle with MenuRef and
+ GetMenuRef, respectively. Replace WindowPtr with WindowRef.
+ Replace ControlHandle with ControlRef.
+ (install_menu_quit_handler): Rename arg MENU_HANDLE to ROOT_MENU.
+
+ * macterm.c: Replace MenuHandle and GetMenuHandle with MenuRef and
+ GetMenuRef, respectively. Replace WindowPtr with WindowRef.
+ Replace ControlHandle with ControlRef.
+ (USE_CARBON_EVENTS): Remove. Use TARGET_API_MAC_CARBON instead.
+ [MAC_OS8] (do_get_menus): Rename variable `menu_handle' to `menu'.
+
+ * macterm.h (struct scroll_bar): Rename member control_handle_low
+ and control_handle_high to control_ref_low and control_ref_high.
+ All uses changed.
+ (SCROLL_BAR_CONTROL_REF, SET_SCROLL_BAR_CONTROL_REF): Rename from
+ SCROLL_BAR_CONTROL_HANDLE and SET_SCROLL_BAR_CONTROL_HANDLE,
+ respectively. All uses changed.
+ (XCreatePixmap, XCreatePixmapFromBitmapData, XSetWindowBackground)
+ (install_window_handler, remove_window_handler): Replace WindowPtr
+ with WindowRef in externs.
+
+2007-06-05 Juanma Barranquero <lekktu@gmail.com>
-2007-06-04 Juanma Barranquero <lekktu@gmail.com>
+ * xfaces.c (Finternal_lisp_face_p): Signal error for face alias loops.
+
+2007-06-03 Nick Roberts <nickrob@snap.net.nz>
+
+ * keyboard.c (discard_mouse_events): Add GPM_CLICK_EVENT case.
+
+ * frame.c (Fmouse_position, Fmouse_pixel_position):
+ Condition on HAVE_GPM too.
+
+ * term.c (term_mouse_highlight): Remove unused variables.
+ (Fterm_open_connection): Set gpm_zerobased to 1.
+ (term_mouse_movement, term_mouse_click, handle_one_term_event):
+ Use zero based co-ordinates.
+ (handle_one_term_event): Report a drag as mouse movement too.
+
+ * Makefile.in (MOUSE_SUPPORT): Define for HAVE_GPM.
+
+2007-06-03 Chong Yidong <cyd@stupidchicken.com>
+
+ * image.c (search_image_cache): New function. Require background
+ color match if background color is unspecified in the image spec.
+ (uncache_image, lookup_image): Use it.
+
+2007-06-01 Juanma Barranquero <lekktu@gmail.com>
* window.c (Fshrink_window): Reflow docstring.
@@ -145,12 +597,9 @@
* Version 22.1 released.
- * xfns.c (x_set_name_internal): Undo last change.
-
2007-06-01 Richard Stallman <rms@gnu.org>
* xfns.c (x_encode_text): Add GCPRO.
- (x_set_name_internal): Separate USE_GTK and non-USE_GTK cases.
2007-06-01 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
@@ -161,26 +610,83 @@
* buffer.c (syms_of_buffer): Doc fix.
+2007-05-30 Nick Roberts <nickrob@snap.net.nz>
+
+ * sysdep.c (init_sys_modes): Add rather than replace with
+ O_NONBLOCK.
+
+ * frame.c [HAVE_GPM] (Fset_mouse_pixel_position): Add call to
+ term_mouse_moveto.
+
+ * termhooks.h (term_mouse_moveto): New extern.
+
+ * term.c (mouse_face_window): Rename...
+ (Qmouse_face_window): ...to this.
+ (term_show_mouse_face, term_clear_mouse_face)
+ (term_mouse_highlight): Use Qmouse_face_window.
+ (term_mouse_moveto): New function.
+ (term_mouse_position): Make it work.
+ (syms_of_term): Uncomment assignment to mouse_position_hook.
+ Staticpro Qmouse_face_window.
+
2007-05-28 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* xdisp.c (redisplay_internal): Bind inhibit-point-motion-hooks to t
around current_column call.
-2007-05-24 Chong Yidong <cyd@stupidchicken.com>
+2007-05-26 Dan Nicolaescu <dann@ics.uci.edu>
- * xdisp.c (redisplay_window): If first window line is a
- continuation line, recompute the new window start instead of
- recentering.
+ * xfaces.c (syms_of_xfaces): Delete stray semicolon.
+ * xdisp.c (next_element_from_buffer):
+ * window.c (delete_window):
+ * term.c (term_mouse_highlight):
+ * msdos.c (getdefdir):
+ * macterm.c (mac_create_bitmap_from_bitmap_data)
+ (init_font_name_table):
+ * fns.c (Fsxhash):
+ * data.c (Fmake_local_variable):
+ * ccl.c (ccl_driver): Likewise.
2007-05-24 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* macterm.c [USE_CARBON_EVENTS] (mac_handle_window_event):
Call mac_wakeup_from_rne on window size change.
+2007-05-25 Chong Yidong <cyd@stupidchicken.com>
+
+ * image.c (uncache_image): Fix typo.
+
+2007-05-23 Johannes Weiner <hannes@saeurebad.de> (tiny change)
+
+ * keyboard.c (make_lispy_movement): Condition on HAVE_GPM too.
+
2007-05-22 Richard Stallman <rms@gnu.org>
* xterm.c (x_connection_closed): Remove NO_RETURN.
+2007-05-22 Martin Rudalics <rudalics@gmx.at>
+
+ * syntax.c (scan_words): Fix arg to UPDATE_SYNTAX_TABLE_BACKWARD.
+
+2007-05-21 Chong Yidong <cyd@stupidchicken.com>
+
+ * image.c (uncache_image): New function.
+ (Fimage_refresh): New function.
+
+2007-05-20 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * Makefile.in: Move GPM check outside HAVE_X_WINDOWS.
+
+2007-05-20 Nick Roberts <nickrob@snap.net.nz>
+
+ * config.in, keyboard.c, Makefile.in, sysdep.c, term.c,
+ * termhooks.h: Use HAVE_GPM instead of HAVE_GPM_H.
+
+2007-05-20 Nick Roberts <nickrob@snap.net.nz>
+
+ * keyboard.c (make_lispy_event): Make case GPM_CLICK_EVENT
+ conditional on [HAVE_GPM_H].
+
2007-05-19 Stefan Monnier <monnier@iro.umontreal.ca>
* syntax.c (skip_chars): Update syntax-table only after we checked that
@@ -191,6 +697,59 @@
* macterm.c (x_calc_absolute_position): Add BLOCK_INPUT around
mac_get_window_bounds.
+2007-05-20 Nick Roberts <nickrob@snap.net.nz>
+
+ * Makefile.in (LIBGPM): Allow it to be set from configure.
+ If set then link Emacs with it.
+
+ * config.in: Regenerate.
+
+ * lisp.h (add_gpm_wait_descriptor, delete_gpm_wait_descriptor):
+ New externs.
+
+ * termhooks.h [HAVE_GPM_H] (enum event_kind): Add GPM_CLICK_EVENT.
+ Include gpm.h.
+ (handle_one_term_event, term_gpm): New externs.
+
+ * sysdep.c [HAVE_GPM_H] (init_sys_modes): Make gpm_fd nonblocking
+ and allow it to be interrupted by SIGIO.
+
+ * process.c (gpm_wait_mask, max_gpm_desc): New variables.
+ (wait_reading_process_output): Wait on gpm_fd too.
+ (add_gpm_wait_descriptor, delete_gpm_wait_descriptor)): New functions.
+ (add_gpm_wait_descriptor_called_flag): New variable.
+ (delete_keyboard_wait_descriptor): Check gpm_wait_mask.
+
+ * keyboard.c [HAVE_GPM_H] (Qmouse_fixup_help_message)
+ (make_lispy_movement, tracking_off, Ftrack_mouse, some_mouse_moved)
+ (show_help_echo, readable_events, kbd_buffer_get_event, init_keyboard):
+ Extend HAVE_MOUSE ifdefs to HAVE_GPM_H.
+ (make_lispy_event): Add case GPM_CLICK_EVENT.
+ (read_avail_input): Handle mouse input.
+
+ * term.c (write_glyphs_with_face): New function.
+ [HAVE_GPM_H]: Include buffer.h, sys/fcntl.h.
+ (mouse_face_beg_row, mouse_face_beg_col, mouse_face_end_row)
+ (mouse_face_end_col, mouse_face_past_end, mouse_face_window)
+ (mouse_face_face_id, term_gpm, pos_x, pos_y)
+ (last_mouse_x, last_mouse_y): New variables.
+ (term_show_mouse_face, term_clear_mouse_face, fast_find_position)
+ (term_mouse_highlight, term_mouse_movement, term_mouse_position)
+ (term_mouse_click, handle_one_term_event, Fterm_open_connection)
+ (Fterm_close_connection): New functions.
+ (term_init): Initialise mouse_face_window.
+
+2007-05-19 Chong Yidong <cyd@stupidchicken.com>
+
+ * xdisp.c (redisplay_window): If first window line is a
+ continuation line, recompute the new window start instead of
+ recentering.
+
+2007-05-18 Glenn Morris <rgm@gnu.org>
+
+ * m/alpha.h (ORDINARY_LINK): No longer define on OpenBSD.
+ Suggested by Alfred M. Szmidt <ams@gnu.org>.
+
2007-05-17 Glenn Morris <rgm@gnu.org>
* m/macppc.h (ORDINARY_LINK): No longer define on OpenBSD.
@@ -200,6 +759,10 @@
* macterm.c [USE_CARBON_EVENTS] (mac_convert_event_ref): Also convert
dead key repeat and up events.
+2007-05-14 Chong Yidong <cyd@stupidchicken.com>
+
+ * image.c (pbm_load): Check image size for monochrome pbm.
+
2007-05-13 Chong Yidong <cyd@stupidchicken.com>
* xterm.c (XTread_socket): Revert last change.
@@ -212,18 +775,17 @@
2007-05-07 Stefan Monnier <monnier@iro.umontreal.ca>
- * editfns.c (Ftranspose_regions): Yet another int/Lisp_Object mixup (YAILOM)
+ * editfns.c (Ftranspose_regions): Yet another int/Lisp_Object
+ mixup (YAILOM).
-2007-05-06 Richard Stallman <rms@gnu.org>
+2007-05-07 Andreas Schwab <schwab@suse.de>
- * process.c: Undo May 3 change.
+ * keymap.c (Flookup_key): Fix typo in last change.
-2007-05-03 Per Cederqvist <ceder@lysator.liu.se> (tiny change)
+2007-05-07 Stefan Monnier <monnier@iro.umontreal.ca>
- * process.c (Faccept_process_output): Revert 2006-03-22 change so
- that the third argument once again is in microseconds (not
- milliseconds). This makes it compatible with Emacs 21 and
- earlier. Problem found by Henrik Rindl,Av(Bw.
+ * keymap.c (Fdefine_key, Flookup_key): Only do the 0x80->meta_modifier
+ mapping for unibyte strings.
2007-05-01 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
@@ -234,11 +796,19 @@
* insdel.c (replace_range): For undo, record insertion first.
+2007-04-29 Andreas Schwab <schwab@suse.de>
+
+ * lisp.h (VECSIZE): Use OFFSETOF.
+
2007-04-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* xdisp.c (try_window_reusing_current_matrix): Fix number of
disabled lines.
+2007-04-28 Richard Stallman <rms@gnu.org>
+
+ * lread.c (read_escape): In a string, \s is always space.
+
2007-04-27 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* xmenu.c (xdialog_show): Call Fredisplay before showing the dialog.
@@ -248,6 +818,10 @@
2007-04-24 Chong Yidong <cyd@stupidchicken.com>
+ * Branch for 22.1.
+
+2007-04-24 Chong Yidong <cyd@stupidchicken.com>
+
* xdisp.c (redisplay_window): Use BEG_UNCHANGED and END_UNCHANGED
values of the actual window.
@@ -2661,7 +3235,7 @@
for writing files. Call gtk_file_chooser_set_current_name to keep
default filename.
- * minibuf.c (Finternal_complete_buffer): Move after DEFUN:s it calls
+ * minibuf.c (Finternal_complete_buffer): Move after DEFUN:s it calls.
2006-09-02 Jindrich Makovicka <makovick@gmail.com> (tiny change)
@@ -2918,7 +3492,7 @@
* xterm.h (struct x_display_info): Add x_dnd_atoms* to keep track
of drag and drop Atoms.
- * xterm.c (x_term_init): Initialize dpyinfo->x_dnd_atoms*
+ * xterm.c (x_term_init): Initialize dpyinfo->x_dnd_atoms*.
2006-08-10 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
@@ -4084,7 +4658,7 @@
2006-05-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
- * xterm.c: Remove declarations already in xterm.h
+ * xterm.c: Remove declarations already in xterm.h.
* xterm.h: Add extern declarations for x_clear_errors,
x_fully_uncatch_errors, x_catching_errors and
@@ -4825,7 +5399,8 @@
* puresize.h (pure_write_error): Mark as NO_RETURN.
- * lisp.h (args_out_of_range, args_out_of_range_3)
+ * lisp.h (args_out_of_range, args_out_of_range_3, Fkill_emacs):
+ Likewise.
2006-04-08 Eli Zaretskii <eliz@gnu.org>
@@ -6442,7 +7017,7 @@
* macterm.c (Qmac_ready_for_drag_n_drop, Qapplication, Qabout)
(Qpreferences): Remove variables.
- (syms_of_macterm) : Don't initialize them.
+ (syms_of_macterm): Don't initialize them.
(Qhicommand) [USE_CARBON_EVENTS]: New variable.
(syms_of_macterm) [USE_CARBON_EVENTS]: Initialize it.
(init_required_apple_events, do_ae_open_application)
@@ -7124,7 +7699,7 @@
* mac.c [TARGET_API_MAC_CARBON] (get_cfstring_encoding_from_lisp):
Allow nil as argument.
- [TARGET_API_MAC_CARBON] (Fmac_code_convert_string): Regard nil
+ [TARGET_API_MAC_CARBON] (Fmac_code_convert_string): Regard nil
for encoding arguments as UTF-16 in native byte order, no BOM.
* macfns.c (Fx_create_frame): Add debugging code.
@@ -10060,7 +10635,7 @@
(cfobject_desc_to_lisp, cfproperty_list_to_lisp): Likewise.
* process.c (init_process): Change `#ifdef DARWIN' to `#if
- defined (DARWIN) || defined (MAC_OSX)'
+ defined (DARWIN) || defined (MAC_OSX)'.
* s/darwin.h (DARWIN): Don't define.
@@ -10597,7 +11172,7 @@
2005-02-03 Kim F. Storm <storm@cua.dk>
* dispnew.c (build_frame_matrix_from_leaf_window)
- [!GLYPH_DEBUG]: Fix xassert.
+ [!GLYPH_DEBUG]: Fix xassert.
* xfaces.c (x_free_gc) [!GLYPH_DEBUG]: Fix xassert.
@@ -11487,7 +12062,7 @@
2004-12-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
- * macterm.c (mac_do_list_fonts): Fix memory leak
+ * macterm.c (mac_do_list_fonts): Fix memory leak.
2004-12-20 Richard M. Stallman <rms@gnu.org>
@@ -12267,7 +12842,7 @@
* Makefile.in (SOME_MACHINE_OBJECTS): Add fringe.o, image.o
and w32*.o.
(temacs${EXEEXT}): Generate buildobj.lst when temacs is linked.
- (mostlyclean): Rm buildobj.lst
+ (mostlyclean): Rm buildobj.lst.
* makefile.w32-in ($(TEMACS)): Generate buildobj.lst when temacs
is linked.
@@ -12605,7 +13180,7 @@
(SAFE_ALLOCA, SAFE_ALLOCA_LISP): Increment it when malloc is used.
(SAFE_FREE): Test it to determine if we need to unwind to free.
Remove size arg. All users changed.
- (SAFE_FREE_LISP) Remove. All users changed to use SAFE_FREE.
+ (SAFE_FREE_LISP): Remove. All users changed to use SAFE_FREE.
2004-10-26 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
@@ -13267,7 +13842,7 @@
(single_submenu): Use ENCODE_MENU_STRING
(mac_menu_show): Use ENCODE_MENU_STRING. Reset grabbed because
button release isn't passed to event loop
- (add_menu_item): Use SetMenuItemWithCFString
+ (add_menu_item): Use SetMenuItemWithCFString.
2004-08-26 Steven Tamm <steventamm@mac.com>
@@ -13536,7 +14111,7 @@
blocking on event queue only by calling ReceiveNextEvent
instead of select (since GUI events aren't on an fd).
(sys_read): Remove function
- * sysdep.c: Remove redefine of read to sys_read if HAVE_CARBON
+ * sysdep.c: Remove redefine of read to sys_read if HAVE_CARBON.
2004-07-18 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
@@ -13546,12 +14121,12 @@
* macterm.c (x_make_frame_visible): Comment in polling on
frame creation.
- * keyboard.c: Undef SIGIO on Carbon
+ * keyboard.c: Undef SIGIO on Carbon.
* atimer.c (alarm_signal_handler): Call alarm handlers after
scheduling.
- * eval.c (Feval): Remove quit_char test
+ * eval.c (Feval): Remove quit_char test.
* process.c (wait_reading_process_input): Remove clearing
stdin for select call on process input.
@@ -14503,7 +15078,7 @@
2004-05-11 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* macterm.c (x_flush, XTframe_up_to_date): Use FRAME_MAC_P
- instead of FRAME_X_P
+ instead of FRAME_X_P.
2004-05-11 Kim F. Storm <storm@cua.dk>
@@ -14673,7 +15248,7 @@
2004-05-01 Jason Rumney <jasonr@gnu.org>
- * w32term.c (x_draw_hollow_cursor): Sync with xterm.c
+ * w32term.c (x_draw_hollow_cursor): Sync with xterm.c.
2004-04-30 Kim F. Storm <storm@cua.dk>
@@ -15899,7 +16474,7 @@
* cmds.c (Fend_of_line): Doc fix.
-2004-02-16 Dmitry Antipov <dmitry.antipov@mail.ru> (tiny change)
+2004-02-16 Dmitry Antipov <dmantipov@yandex.ru> (tiny change)
* keyboard.c (prev_read): New static variable.
(read_avail_input): Use it to zero out only those slots in buf[]
@@ -17466,7 +18041,7 @@
* makefile.w32-in (alloca.o): Remove.
(coding.o): Depend on intervals.h
- (emacs.o, bytecode.o): Depend on window.h
+ (emacs.o, bytecode.o): Depend on window.h.
2003-09-01 Dave Love <fx@gnu.org>
@@ -18247,7 +18822,7 @@
* gtkutil.c: Include keyboard.h, charset.h, coding.h.
(xg_create_frame_widgets): Use ENCODE_UTF_8.
- * xterm.c (Qutf_8): Move to coding.c
+ * xterm.c (Qutf_8): Move to coding.c.
* xmenu.c (ENCODE_MENU_STRING): New.
(list_of_panes, list_of_items, digest_single_submenu, xmenu_show):
@@ -20976,7 +21551,7 @@
(redisplay_internal): Add check for USE_GTK and popup_activated.
(redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_MENU_BAR.
(redisplay_window): Add check for USE_GTK and FRAME_EXTERNAL_TOOL_BAR.
- (display_menu_bar): Add check for USE_GTK
+ (display_menu_bar): Add check for USE_GTK.
* lisp.h (Vx_resource_name): Declare extern.
@@ -21715,7 +22290,7 @@
(best_matching_font, choose_face_font): Add `needs_overstrike'
argument, and use it to return whether overstriking is desirable
for this face/font combo.
- (set_font_frame_param: Pass new argument to choose_face_font.
+ (set_font_frame_param): Pass new argument to choose_face_font.
2002-11-17 Ben Key <BKey1@tampabay.rr.com>
@@ -22094,7 +22669,7 @@
* buffer.c (assoc_ignore_text_properties, Fother_buffer, Fkill_buffer)
(call_overlay_mod_hooks): Use CONSP and XCAR/XCDR.
- (Fget_buffer_create, advance_to_char_boundary): Use BEG and BEG_BYTE;
+ (Fget_buffer_create, advance_to_char_boundary): Use BEG and BEG_BYTE.
2002-10-21 Stefan Monnier <monnier@cs.yale.edu>
@@ -23793,8 +24368,8 @@
* fns.c (Fstring_make_unibyte): Doc fix.
* xselect.c (lisp_data_to_selection_data): If the requested type
- is STRING, call string_make_unibyte to encode the selected text
- as a string.
+ is STRING, call string_make_unibyte to encode the selected text
+ as a string.
* window.c (Fset_window_hscroll): Doc fix.
diff --git a/src/Makefile.in b/src/Makefile.in
index 3bc01234347..2740cb96827 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -440,7 +440,7 @@ XFT_LIBS=@XFT_LIBS@
#if HAVE_GIF
#ifndef LIBGIF
-#define LIBGIF -lungif
+#define LIBGIF -lgif
#endif /* not defined LIBGIF */
#else /* not HAVE_GIF */
#define LIBGIF
@@ -457,6 +457,15 @@ LIBX= $(LIBXMENU) LD_SWITCH_X_SITE -lX10 LIBX10_MACHINE LIBX10_SYSTEM
#else /* not HAVE_X_WINDOWS */
#endif /* not HAVE_X_WINDOWS */
+#if HAVE_GPM
+#ifndef LIBGPM
+#define LIBGPM -lgpm
+#endif /* not defined LIBGPM */
+#else /* not HAVE_GPM */
+#define LIBGPM
+#endif /* not HAVE_GPM */
+
+
LIBSOUND= @LIBSOUND@
CFLAGS_SOUND= @CFLAGS_SOUND@
@@ -664,8 +673,12 @@ otherobj= $(termcapobj) lastfile.o $(mallocobj) $(allocaobj) $(widgetobj) $(LIBO
#define MOUSE_SUPPORT ${lispsource}mouse.elc \
${lispsource}select.elc ${lispsource}scroll-bar.elc
#else
+#ifdef HAVE_GPM
+#define MOUSE_SUPPORT ${lispsource}mouse.elc
+#else
#define MOUSE_SUPPORT
#endif
+#endif
#ifdef VMS
#define VMS_SUPPORT ${lispsource}vmsproc.elc ${lispsource}vms-patch.elc
@@ -933,7 +946,7 @@ SOME_MACHINE_LISP = ${dotdot}/lisp/mouse.elc \
Note that SunOS needs -lm to come before -lc; otherwise, you get
duplicated symbols. If the standard libraries were compiled
with GCC, we might need gnulib again after them. */
-LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) \
+LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) LIBGPM \
LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
LIBS_DEBUG $(GETLOADAVG_LIBS) $(GNULIB_VAR) LIB_MATH LIB_STANDARD \
$(GNULIB_VAR)
diff --git a/src/abbrev.c b/src/abbrev.c
index bdb8dc66ba7..da1724e2998 100644
--- a/src/abbrev.c
+++ b/src/abbrev.c
@@ -172,12 +172,79 @@ overwrite a non-system abbreviation of the same name. */)
return name;
}
+/* Check if the characters in ABBREV have word syntax in either the
+ * current (if global == 0) or standard syntax table. */
+static void
+abbrev_check_chars (abbrev, global)
+ Lisp_Object abbrev;
+ int global;
+{
+ int i, i_byte, len, nbad = 0;
+ int j, found, nuniq = 0;
+ char *badchars, *baduniq;
+
+ CHECK_STRING (abbrev);
+ len = SCHARS (abbrev);
+
+ badchars = (char *) alloca (len + 1);
+
+ for (i = 0, i_byte = 0; i < len; )
+ {
+ int c;
+
+ FETCH_STRING_CHAR_ADVANCE (c, abbrev, i, i_byte);
+
+ if (global)
+ {
+ /* Copied from SYNTAX in syntax.h, except using FOLLOW_PARENT. */
+ Lisp_Object syntax_temp
+ = SYNTAX_ENTRY_FOLLOW_PARENT (Vstandard_syntax_table, c);
+ if ( (CONSP (syntax_temp)
+ ? (enum syntaxcode) (XINT (XCAR (syntax_temp)) & 0xff)
+ : Swhitespace) != Sword ) badchars[nbad++] = c;
+ }
+ else if (SYNTAX (c) != Sword)
+ badchars[nbad++] = c;
+ }
+
+ if (nbad == 0) return;
+
+ baduniq = (char *) alloca (nbad + 1);
+
+ for (i = 0; i < nbad; i++)
+ {
+ found = 0;
+
+ for (j = 0; j < nuniq; j++)
+ {
+ if (badchars[i] == baduniq[j])
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) continue ;
+
+ baduniq[nuniq++] = badchars[i];
+ }
+
+ baduniq[nuniq] = '\0';
+
+ error ("Some abbrev characters (%s) are not word constituents %s",
+ baduniq, global ? "in the standard syntax" : "in this mode" );
+}
+
DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2, 2,
"sDefine global abbrev: \nsExpansion for %s: ",
- doc: /* Define ABBREV as a global abbreviation for EXPANSION. */)
+ doc: /* Define ABBREV as a global abbreviation for EXPANSION.
+The characters in ABBREV must all be word constituents in the standard
+syntax table. */)
(abbrev, expansion)
Lisp_Object abbrev, expansion;
{
+ abbrev_check_chars (abbrev, 1);
+
Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
expansion, Qnil, make_number (0), Qnil);
return abbrev;
@@ -185,13 +252,16 @@ DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2,
DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
"sDefine mode abbrev: \nsExpansion for %s: ",
- doc: /* Define ABBREV as a mode-specific abbreviation for EXPANSION. */)
+ doc: /* Define ABBREV as a mode-specific abbreviation for EXPANSION.
+The characters in ABBREV must all be word-constituents in the current mode. */)
(abbrev, expansion)
Lisp_Object abbrev, expansion;
{
if (NILP (current_buffer->abbrev_table))
error ("Major mode has no abbrev table");
+ abbrev_check_chars (abbrev, 0);
+
Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
expansion, Qnil, make_number (0), Qnil);
return abbrev;
diff --git a/src/alloc.c b/src/alloc.c
index 948b87851a7..a69f5045713 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1179,8 +1179,6 @@ emacs_blocked_free (ptr, ptr2)
void *ptr;
const void *ptr2;
{
- EMACS_INT bytes_used_now;
-
BLOCK_INPUT_ALLOC;
#ifdef GC_MALLOC_CHECK
@@ -1756,6 +1754,8 @@ init_strings ()
string_blocks = NULL;
n_string_blocks = 0;
string_free_list = NULL;
+ empty_unibyte_string = make_pure_string ("", 0, 0, 0);
+ empty_multibyte_string = make_pure_string ("", 0, 0, 1);
}
@@ -2479,6 +2479,9 @@ make_uninit_string (length)
int length;
{
Lisp_Object val;
+
+ if (!length)
+ return empty_unibyte_string;
val = make_uninit_multibyte_string (length, length);
STRING_SET_UNIBYTE (val);
return val;
@@ -2497,6 +2500,8 @@ make_uninit_multibyte_string (nchars, nbytes)
if (nchars < 0)
abort ();
+ if (!nbytes)
+ return empty_multibyte_string;
s = allocate_string ();
allocate_string_data (s, nchars, nbytes);
@@ -4256,9 +4261,14 @@ mark_maybe_pointer (p)
{
struct mem_node *m;
- /* Quickly rule out some values which can't point to Lisp data. We
- assume that Lisp data is aligned on even addresses. */
- if ((EMACS_INT) p & 1)
+ /* Quickly rule out some values which can't point to Lisp data. */
+ if ((EMACS_INT) p %
+#ifdef USE_LSB_TAG
+ 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */
+#else
+ 2 /* We assume that Lisp data is aligned on even addresses. */
+#endif
+ )
return;
m = mem_find (p);
diff --git a/src/buffer.c b/src/buffer.c
index 554ca145b79..2ded9857455 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5501,6 +5501,8 @@ A string is printed verbatim in the mode line except for %-constructs:
%P -- print percent of buffer above bottom of window, perhaps plus Top,
or print Bottom or All.
%n -- print Narrow if appropriate.
+ %R -- print R or hyphen. R means that default-directory is on a
+ remote machine.
%t -- visited file is text or binary (if OS supports this distinction).
%z -- print mnemonics of keyboard, terminal, and buffer coding systems.
%Z -- like %z, but including the end-of-line format.
diff --git a/src/callint.c b/src/callint.c
index 9dcc077fd65..9b3535474c0 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -473,16 +473,19 @@ invoke it. If KEYS is omitted or nil, the return value of
/* Count the number of arguments the interactive spec would have
us give to the function. */
tem = string;
- for (j = 0; *tem; j++)
+ for (j = 0; *tem;)
{
/* 'r' specifications ("point and mark as 2 numeric args")
produce *two* arguments. */
- if (*tem == 'r') j++;
+ if (*tem == 'r')
+ j += 2;
+ else
+ j++;
tem = (unsigned char *) index (tem, '\n');
if (tem)
- tem++;
+ ++tem;
else
- tem = (unsigned char *) "";
+ break;
}
count = j;
@@ -585,7 +588,7 @@ invoke it. If KEYS is omitted or nil, the return value of
case 'G': /* Possibly nonexistent file name,
default to directory alone. */
args[i] = Fread_file_name (callint_message,
- Qnil, Qnil, Qnil, build_string (""), Qnil);
+ Qnil, Qnil, Qnil, empty_unibyte_string, Qnil);
break;
case 'i': /* Ignore an argument -- Does not do I/O */
diff --git a/src/casetab.c b/src/casetab.c
index 1d364a6df7e..bf0e022f139 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -126,7 +126,7 @@ set_case_table (table, standard)
int standard;
{
Lisp_Object up, canon, eqv;
- Lisp_Object indices[3];
+ int indices[3];
check_case_table (table);
diff --git a/src/coding.c b/src/coding.c
index 907521edd5c..7359f0214ba 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -7464,6 +7464,8 @@ They may specify a coding system, a cons of coding systems,
or a function symbol to call.
In the last case, we call the function with one argument,
which is a list of all the arguments given to this function.
+If the function can't decide a coding system, it can return
+`undecided' so that the normal code-detection is performed.
If OPERATION is `insert-file-contents', the argument corresponding to
TARGET may be a cons (FILENAME . BUFFER). In that case, FILENAME is a
@@ -7967,7 +7969,9 @@ and the cdr part is used for encoding.
If VAL is a function symbol, the function must return a coding system
or a cons of coding systems which are used as above. The function is
called with an argument that is a list of the arguments with which
-`find-operation-coding-system' was called.
+`find-operation-coding-system' was called. If the function can't decide
+a coding system, it can return `undecided' so that the normal
+code-detection is performed.
See also the function `find-operation-coding-system'
and the variable `auto-coding-alist'. */);
diff --git a/src/config.in b/src/config.in
index 158ae109aae..70a5b7bee32 100644
--- a/src/config.in
+++ b/src/config.in
@@ -228,9 +228,13 @@ Boston, MA 02110-1301, USA. */
/* Define to 1 if you have the `get_current_dir_name' function. */
#undef HAVE_GET_CURRENT_DIR_NAME
-/* Define to 1 if you have the ungif library (-lungif). */
+/* Define to 1 if you have a gif library (default -lgif; otherwise specify
+ with LIBGIF). */
#undef HAVE_GIF
+/* Define to 1 if you have the gpm library (-lgpm). */
+#undef HAVE_GPM
+
/* Define to 1 if you have the `grantpt' function. */
#undef HAVE_GRANTPT
@@ -765,6 +769,9 @@ Boston, MA 02110-1301, USA. */
Solaris, for example). */
#undef LD_SWITCH_X_SITE_AUX
+/* Compiler option to link with the gif library (if not -lgif). */
+#undef LIBGIF
+
/* Define to 1 if localtime caches TZ. */
#undef LOCALTIME_CACHE
diff --git a/src/data.c b/src/data.c
index 5e7453e9d42..3f27e387350 100644
--- a/src/data.c
+++ b/src/data.c
@@ -750,7 +750,22 @@ Value, if non-nil, is a list \(interactive SPEC). */)
(cmd)
Lisp_Object cmd;
{
- Lisp_Object fun = indirect_function (cmd);
+ Lisp_Object fun = indirect_function (cmd); /* Check cycles. */
+
+ if (NILP (fun) || EQ (fun, Qunbound))
+ return Qnil;
+
+ /* Use an `interactive-form' property if present, analogous to the
+ function-documentation property. */
+ fun = cmd;
+ while (SYMBOLP (fun))
+ {
+ Lisp_Object tmp = Fget (fun, intern ("interactive-form"));
+ if (!NILP (tmp))
+ return tmp;
+ else
+ fun = Fsymbol_function (fun);
+ }
if (SUBRP (fun))
{
diff --git a/src/dispextern.h b/src/dispextern.h
index 4a7a790ad7e..4cd9c42cc0f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2431,6 +2431,10 @@ struct image
if necessary. */
unsigned long background;
+ /* Foreground and background colors of the frame on which the image
+ is created. */
+ unsigned long frame_foreground, frame_background;
+
/* True if this image has a `transparent' background -- that is, is
uses an image mask. The accessor macro for this is
`IMAGE_BACKGROUND_TRANSPARENT'. */
diff --git a/src/doc.c b/src/doc.c
index 65c0f21ce39..25f6625d404 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -883,7 +883,7 @@ a new string, without any text properties, is returned. */)
struct buffer *oldbuf;
int start_idx;
/* This is for computing the SHADOWS arg for describe_map_tree. */
- Lisp_Object active_maps = Fcurrent_active_maps (Qnil);
+ Lisp_Object active_maps = Fcurrent_active_maps (Qnil, Qnil);
Lisp_Object earlier_maps;
changed = 1;
diff --git a/src/editfns.c b/src/editfns.c
index 5ab8e5eddc8..7bb74958c2c 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -84,6 +84,11 @@ extern char **environ;
extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
const struct tm *, int));
+
+#ifdef WINDOWSNT
+extern Lisp_Object w32_get_internal_run_time ();
+#endif
+
static int tm_diff P_ ((struct tm *, struct tm *));
static void find_field P_ ((Lisp_Object, Lisp_Object, Lisp_Object, int *, Lisp_Object, int *));
static void update_buffer_properties P_ ((int, int));
@@ -1483,9 +1488,13 @@ on systems that do not provide resolution finer than a second. */)
return list3 (make_number ((secs >> 16) & 0xffff),
make_number ((secs >> 0) & 0xffff),
make_number (usecs));
-#else
+#else /* ! HAVE_GETRUSAGE */
+#if WINDOWSNT
+ return w32_get_internal_run_time ();
+#else /* ! WINDOWSNT */
return Fcurrent_time ();
-#endif
+#endif /* WINDOWSNT */
+#endif /* HAVE_GETRUSAGE */
}
@@ -1974,6 +1983,7 @@ the data it can't find. */)
int offset = tm_diff (t, &gmt);
char *s = 0;
char buf[6];
+
#ifdef HAVE_TM_ZONE
if (t->tm_zone)
s = (char *)t->tm_zone;
@@ -1984,19 +1994,6 @@ the data it can't find. */)
#endif
#endif /* not HAVE_TM_ZONE */
-#if defined HAVE_TM_ZONE || defined HAVE_TZNAME
- if (s)
- {
- /* On Japanese w32, we can get a Japanese string as time
- zone name. Don't accept that. */
- char *p;
- for (p = s; *p && (isalnum ((unsigned char)*p) || *p == ' '); ++p)
- ;
- if (p == s || *p)
- s = NULL;
- }
-#endif
-
if (!s)
{
/* No local time zone name is available; use "+-NNNN" instead. */
@@ -2004,6 +2001,7 @@ the data it can't find. */)
sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
s = buf;
}
+
return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
}
else
@@ -3042,7 +3040,7 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
{
validate_region (&start, &end);
if (XINT (start) == XINT (end))
- return build_string ("");
+ return empty_unibyte_string;
return del_range_1 (XINT (start), XINT (end), 1, 1);
}
@@ -4114,9 +4112,9 @@ Transposing beyond buffer boundaries is an error. */)
(startr1, endr1, startr2, endr2, leave_markers)
Lisp_Object startr1, endr1, startr2, endr2, leave_markers;
{
- register int start1, end1, start2, end2;
- int start1_byte, start2_byte, len1_byte, len2_byte;
- int gap, len1, len_mid, len2;
+ register EMACS_INT start1, end1, start2, end2;
+ EMACS_INT start1_byte, start2_byte, len1_byte, len2_byte;
+ EMACS_INT gap, len1, len_mid, len2;
unsigned char *start1_addr, *start2_addr, *temp;
INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2, tmp_interval3;
diff --git a/src/emacs.c b/src/emacs.c
index f70588634d9..6c7773770d7 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -133,8 +133,8 @@ Lisp_Object Vinstallation_directory;
/* Hook run by `kill-emacs' before it does really anything. */
Lisp_Object Vkill_emacs_hook;
-/* An empty lisp string. To avoid having to build any other. */
-Lisp_Object empty_string;
+/* Empty lisp strings. To avoid having to build any others. */
+Lisp_Object empty_unibyte_string, empty_multibyte_string;
/* Search path separator. */
Lisp_Object Vpath_separator;
@@ -856,17 +856,23 @@ main (argc, argv
So ignore --version otherwise. */
&& initialized)
{
- Lisp_Object tem;
+ Lisp_Object tem, tem2;
tem = Fsymbol_value (intern ("emacs-version"));
+ tem2 = Fsymbol_value (intern ("emacs-copyright"));
if (!STRINGP (tem))
{
fprintf (stderr, "Invalid value of `emacs-version'\n");
exit (1);
}
+ if (!STRINGP (tem2))
+ {
+ fprintf (stderr, "Invalid value of `emacs-copyright'\n");
+ exit (1);
+ }
else
{
printf ("GNU Emacs %s\n", SDATA (tem));
- printf ("Copyright (C) 2007 Free Software Foundation, Inc.\n");
+ printf ("%s\n", SDATA(tem2));
printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
printf ("You may redistribute copies of Emacs\n");
printf ("under the terms of the GNU General Public License.\n");
@@ -2468,9 +2474,6 @@ see `kill-emacs-query-functions' instead.
The hook is not run in batch mode, i.e., if `noninteractive' is non-nil. */);
Vkill_emacs_hook = Qnil;
- empty_string = build_string ("");
- staticpro (&empty_string);
-
DEFVAR_INT ("emacs-priority", &emacs_priority,
doc: /* Priority for Emacs to run at.
This value is effective only if set before Emacs is dumped,
diff --git a/src/eval.c b/src/eval.c
index 0993767b9e3..78316eb1a3c 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -221,7 +221,7 @@ init_eval_once ()
specpdl_ptr = specpdl;
/* Don't forget to update docs (lispref node "Local Variables"). */
max_specpdl_size = 1000;
- max_lisp_eval_depth = 300;
+ max_lisp_eval_depth = 400;
Vrun_hooks = Qnil;
}
@@ -1586,8 +1586,7 @@ internal_condition_case_2 (bfun, nargs, args, handlers, hfun)
static Lisp_Object find_handler_clause P_ ((Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object,
- Lisp_Object *));
+ Lisp_Object, Lisp_Object));
DEFUN ("signal", Fsignal, Ssignal, 2, 2, 0,
doc: /* Signal an error. Args are ERROR-SYMBOL and associated DATA.
@@ -1613,7 +1612,6 @@ See also the function `condition-case'. */)
Lisp_Object conditions;
extern int gc_in_progress;
extern int waiting_for_input;
- Lisp_Object debugger_value;
Lisp_Object string;
Lisp_Object real_error_symbol;
struct backtrace *bp;
@@ -1671,7 +1669,7 @@ See also the function `condition-case'. */)
register Lisp_Object clause;
clause = find_handler_clause (handlerlist->handler, conditions,
- error_symbol, data, &debugger_value);
+ error_symbol, data);
if (EQ (clause, Qlambda))
{
@@ -1702,7 +1700,7 @@ See also the function `condition-case'. */)
handlerlist = allhandlers;
/* If no handler is present now, try to run the debugger,
and if that fails, throw to top level. */
- find_handler_clause (Qerror, conditions, error_symbol, data, &debugger_value);
+ find_handler_clause (Qerror, conditions, error_symbol, data);
if (catchlist != 0)
Fthrow (Qtop_level, Qt);
@@ -1854,75 +1852,54 @@ skip_debugger (conditions, data)
= SIG is nil, and DATA is (SYMBOL . REST-OF-DATA).
This is for memory-full errors only.
- Store value returned from debugger into *DEBUGGER_VALUE_PTR.
-
We need to increase max_specpdl_size temporarily around
anything we do that can push on the specpdl, so as not to get
a second error here in case we're handling specpdl overflow. */
static Lisp_Object
-find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
+find_handler_clause (handlers, conditions, sig, data)
Lisp_Object handlers, conditions, sig, data;
- Lisp_Object *debugger_value_ptr;
{
register Lisp_Object h;
register Lisp_Object tem;
+ int debugger_called = 0;
+ int debugger_considered = 0;
- if (EQ (handlers, Qt)) /* t is used by handlers for all conditions, set up by C code. */
+ /* t is used by handlers for all conditions, set up by C code. */
+ if (EQ (handlers, Qt))
return Qt;
+
+ /* Don't run the debugger for a memory-full error.
+ (There is no room in memory to do that!) */
+ if (NILP (sig))
+ debugger_considered = 1;
+
/* error is used similarly, but means print an error message
and run the debugger if that is enabled. */
if (EQ (handlers, Qerror)
|| !NILP (Vdebug_on_signal)) /* This says call debugger even if
there is a handler. */
{
- int debugger_called = 0;
- Lisp_Object sig_symbol, combined_data;
- /* This is set to 1 if we are handling a memory-full error,
- because these must not run the debugger.
- (There is no room in memory to do that!) */
- int no_debugger = 0;
-
- if (NILP (sig))
- {
- combined_data = data;
- sig_symbol = Fcar (data);
- no_debugger = 1;
- }
- else
- {
- combined_data = Fcons (sig, data);
- sig_symbol = sig;
- }
-
- if (wants_debugger (Vstack_trace_on_error, conditions))
+ if (!NILP (sig) && wants_debugger (Vstack_trace_on_error, conditions))
{
max_specpdl_size++;
-#ifdef PROTOTYPES
+ #ifdef PROTOTYPES
internal_with_output_to_temp_buffer ("*Backtrace*",
(Lisp_Object (*) (Lisp_Object)) Fbacktrace,
Qnil);
-#else
+ #else
internal_with_output_to_temp_buffer ("*Backtrace*",
Fbacktrace, Qnil);
-#endif
+ #endif
max_specpdl_size--;
}
- if (! no_debugger
- /* Don't try to run the debugger with interrupts blocked.
- The editing loop would return anyway. */
- && ! INPUT_BLOCKED_P
- && (EQ (sig_symbol, Qquit)
- ? debug_on_quit
- : wants_debugger (Vdebug_on_error, conditions))
- && ! skip_debugger (conditions, combined_data)
- && when_entered_debugger < num_nonmacro_input_events)
+
+ if (!debugger_considered)
{
- *debugger_value_ptr
- = call_debugger (Fcons (Qerror,
- Fcons (combined_data, Qnil)));
- debugger_called = 1;
+ debugger_considered = 1;
+ debugger_called = maybe_call_debugger (conditions, sig, data);
}
+
/* If there is no handler, return saying whether we ran the debugger. */
if (EQ (handlers, Qerror))
{
@@ -1931,6 +1908,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
return Qt;
}
}
+
for (h = handlers; CONSP (h); h = Fcdr (h))
{
Lisp_Object handler, condit;
@@ -1949,18 +1927,55 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
/* Handle a list of condition names in handler HANDLER. */
else if (CONSP (condit))
{
- while (CONSP (condit))
+ Lisp_Object tail;
+ for (tail = condit; CONSP (tail); tail = XCDR (tail))
{
- tem = Fmemq (Fcar (condit), conditions);
+ tem = Fmemq (Fcar (tail), conditions);
if (!NILP (tem))
- return handler;
- condit = XCDR (condit);
+ {
+ /* This handler is going to apply.
+ Does it allow the debugger to run first? */
+ if (! debugger_considered && !NILP (Fmemq (Qdebug, condit)))
+ maybe_call_debugger (conditions, sig, data);
+ return handler;
+ }
}
}
}
+
return Qnil;
}
+/* Call the debugger if calling it is currently enabled for CONDITIONS.
+ SIG and DATA describe the signal, as in find_handler_clause. */
+
+int
+maybe_call_debugger (conditions, sig, data)
+ Lisp_Object conditions, sig, data;
+{
+ Lisp_Object combined_data;
+
+ combined_data = Fcons (sig, data);
+
+ if (
+ /* Don't try to run the debugger with interrupts blocked.
+ The editing loop would return anyway. */
+ ! INPUT_BLOCKED_P
+ /* Does user wants to enter debugger for this kind of error? */
+ && (EQ (sig, Qquit)
+ ? debug_on_quit
+ : wants_debugger (Vdebug_on_error, conditions))
+ && ! skip_debugger (conditions, combined_data)
+ /* rms: what's this for? */
+ && when_entered_debugger < num_nonmacro_input_events)
+ {
+ call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil)));
+ return 1;
+ }
+
+ return 0;
+}
+
/* dump an error message; called like printf */
/* VARARGS 1 */
@@ -2025,42 +2040,49 @@ then strings and vectors are not accepted. */)
{
register Lisp_Object fun;
register Lisp_Object funcar;
+ Lisp_Object if_prop = Qnil;
fun = function;
- fun = indirect_function (fun);
- if (EQ (fun, Qunbound))
+ fun = indirect_function (fun); /* Check cycles. */
+ if (NILP (fun) || EQ (fun, Qunbound))
return Qnil;
+ /* Check an `interactive-form' property if present, analogous to the
+ function-documentation property. */
+ fun = function;
+ while (SYMBOLP (fun))
+ {
+ Lisp_Object tmp = Fget (fun, intern ("interactive-form"));
+ if (!NILP (tmp))
+ if_prop = Qt;
+ fun = Fsymbol_function (fun);
+ }
+
/* Emacs primitives are interactive if their DEFUN specifies an
interactive spec. */
if (SUBRP (fun))
- {
- if (XSUBR (fun)->prompt)
- return Qt;
- else
- return Qnil;
- }
+ return XSUBR (fun)->prompt ? Qt : if_prop;
/* Bytecode objects are interactive if they are long enough to
have an element whose index is COMPILED_INTERACTIVE, which is
where the interactive spec is stored. */
else if (COMPILEDP (fun))
return ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE
- ? Qt : Qnil);
+ ? Qt : if_prop);
/* Strings and vectors are keyboard macros. */
- if (NILP (for_call_interactively) && (STRINGP (fun) || VECTORP (fun)))
- return Qt;
+ if (STRINGP (fun) || VECTORP (fun))
+ return NILP (for_call_interactively) ? Qt : Qnil;
/* Lists may represent commands. */
if (!CONSP (fun))
return Qnil;
funcar = XCAR (fun);
if (EQ (funcar, Qlambda))
- return Fassq (Qinteractive, Fcdr (XCDR (fun)));
+ return !NILP (Fassq (Qinteractive, Fcdr (XCDR (fun)))) ? Qt : if_prop;
if (EQ (funcar, Qautoload))
- return Fcar (Fcdr (Fcdr (XCDR (fun))));
+ return !NILP (Fcar (Fcdr (Fcdr (XCDR (fun))))) ? Qt : if_prop;
else
return Qnil;
}
diff --git a/src/fileio.c b/src/fileio.c
index 3859f9e35aa..f70109dc2ad 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6430,7 +6430,7 @@ and `read-file-name-function'. */)
if (! replace_in_history)
add_to_history = 1;
- val = empty_string;
+ val = empty_unibyte_string;
}
unbind_to (count, Qnil);
@@ -6683,8 +6683,9 @@ or local variable spec of the tailing lines with `coding:' tag. */);
DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
doc: /* A list of functions to be called at the end of `insert-file-contents'.
-Each is passed one argument, the number of characters inserted.
-It should return the new character count, and leave point the same.
+Each is passed one argument, the number of characters inserted,
+with point at the start of the inserted text. Each function
+should leave point the same, and return the new character count.
If `insert-file-contents' is intercepted by a handler from
`file-name-handler-alist', that handler is responsible for calling the
functions in `after-insert-file-functions' if appropriate. */);
diff --git a/src/fns.c b/src/fns.c
index 59cb2e3c9f6..eef67551b48 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2825,8 +2825,8 @@ DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
void
map_char_table (c_function, function, table, subtable, arg, depth, indices)
void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
- Lisp_Object function, table, subtable, arg, *indices;
- int depth;
+ Lisp_Object function, table, subtable, arg;
+ int depth, *indices;
{
int i, to;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
@@ -2860,7 +2860,7 @@ map_char_table (c_function, function, table, subtable, arg, depth, indices)
}
else
{
- int charset = XFASTINT (indices[0]) - 128;
+ int charset = indices[0] - 128;
i = 32;
to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
@@ -2874,8 +2874,8 @@ map_char_table (c_function, function, table, subtable, arg, depth, indices)
int charset;
elt = XCHAR_TABLE (subtable)->contents[i];
- XSETFASTINT (indices[depth], i);
- charset = XFASTINT (indices[0]) - 128;
+ indices[depth] = i;
+ charset = indices[0] - 128;
if (depth == 0
&& (!CHARSET_DEFINED_P (charset)
|| charset == CHARSET_8_BIT_CONTROL
@@ -2892,8 +2892,8 @@ map_char_table (c_function, function, table, subtable, arg, depth, indices)
{
int c1, c2, c;
- c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
- c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
+ c1 = depth >= 1 ? indices[1] : 0;
+ c2 = depth >= 2 ? indices[2] : 0;
c = MAKE_CHAR (charset, c1, c2);
if (NILP (elt))
@@ -2927,14 +2927,14 @@ The key is always a possible IDX argument to `aref'. */)
Lisp_Object function, char_table;
{
/* The depth of char table is at most 3. */
- Lisp_Object indices[3];
+ int indices[3];
CHECK_CHAR_TABLE (char_table);
/* When Lisp_Object is represented as a union, `call2' cannot directly
be passed to map_char_table because it returns a Lisp_Object rather
than returning nothing.
- Casting leads to crashes on some architectures. -stef */
+ Casting leads to crashes on some architectures. --Stef */
map_char_table (void_call2, Qnil, char_table, char_table, function, 0, indices);
return Qnil;
}
@@ -3134,7 +3134,7 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
len = Flength (sequence);
leni = XINT (len);
nargs = leni + leni - 1;
- if (nargs < 0) return build_string ("");
+ if (nargs < 0) return empty_unibyte_string;
SAFE_ALLOCA_LISP (args, nargs);
@@ -4268,7 +4268,7 @@ base64_decode_1 (from, to, length, multibyte, nchars_return)
/* The list of all weak hash tables. Don't staticpro this one. */
-Lisp_Object Vweak_hash_tables;
+struct Lisp_Hash_Table *weak_hash_tables;
/* Various symbols. */
@@ -4614,11 +4614,11 @@ make_hash_table (test, size, rehash_size, rehash_threshold, weak,
/* Maybe add this hash table to the list of all weak hash tables. */
if (NILP (h->weak))
- h->next_weak = Qnil;
+ h->next_weak = NULL;
else
{
- h->next_weak = Vweak_hash_tables;
- Vweak_hash_tables = table;
+ h->next_weak = weak_hash_tables;
+ weak_hash_tables = h;
}
return table;
@@ -4649,8 +4649,8 @@ copy_hash_table (h1)
/* Maybe add this hash table to the list of all weak hash tables. */
if (!NILP (h2->weak))
{
- h2->next_weak = Vweak_hash_tables;
- Vweak_hash_tables = table;
+ h2->next_weak = weak_hash_tables;
+ weak_hash_tables = h2;
}
return table;
@@ -4969,13 +4969,12 @@ sweep_weak_table (h, remove_entries_p)
/* Remove elements from weak hash tables that don't survive the
current garbage collection. Remove weak tables that don't survive
- from Vweak_hash_tables. Called from gc_sweep. */
+ from weak_hash_tables. Called from gc_sweep. */
void
sweep_weak_hash_tables ()
{
- Lisp_Object table, used, next;
- struct Lisp_Hash_Table *h;
+ struct Lisp_Hash_Table *h, *used, *next;
int marked;
/* Mark all keys and values that are in use. Keep on marking until
@@ -4987,9 +4986,8 @@ sweep_weak_hash_tables ()
do
{
marked = 0;
- for (table = Vweak_hash_tables; !GC_NILP (table); table = h->next_weak)
+ for (h = weak_hash_tables; h; h = h->next_weak)
{
- h = XHASH_TABLE (table);
if (h->size & ARRAY_MARK_FLAG)
marked |= sweep_weak_table (h, 0);
}
@@ -4997,9 +4995,8 @@ sweep_weak_hash_tables ()
while (marked);
/* Remove tables and entries that aren't used. */
- for (table = Vweak_hash_tables, used = Qnil; !GC_NILP (table); table = next)
+ for (h = weak_hash_tables, used = NULL; h; h = next)
{
- h = XHASH_TABLE (table);
next = h->next_weak;
if (h->size & ARRAY_MARK_FLAG)
@@ -5010,11 +5007,11 @@ sweep_weak_hash_tables ()
/* Add table to the list of used weak hash tables. */
h->next_weak = used;
- used = table;
+ used = h;
}
}
- Vweak_hash_tables = used;
+ weak_hash_tables = used;
}
@@ -5915,7 +5912,7 @@ used if both `use-dialog-box' and this variable are non-nil. */);
void
init_fns ()
{
- Vweak_hash_tables = Qnil;
+ weak_hash_tables = NULL;
}
/* arch-tag: 787f8219-5b74-46bd-8469-7e1cc475fa31
diff --git a/src/fontset.c b/src/fontset.c
index bf6f7121b23..97f86faaff9 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -1437,7 +1437,7 @@ If FRAME is omitted, it defaults to the currently selected frame. */)
{
Lisp_Object fontset;
FRAME_PTR f;
- Lisp_Object indices[3];
+ int indices[3];
Lisp_Object val, tail, elt;
Lisp_Object *realized;
struct font_info *fontp = NULL;
diff --git a/src/frame.c b/src/frame.c
index 1fa48182e5e..b29e20ab0ca 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1450,7 +1450,7 @@ and returns whatever that function returns. */)
f = SELECTED_FRAME ();
x = y = Qnil;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* It's okay for the hook to refrain from storing anything. */
if (mouse_position_hook)
(*mouse_position_hook) (&f, -1,
@@ -1494,7 +1494,7 @@ and nil for X and Y. */)
f = SELECTED_FRAME ();
x = y = Qnil;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* It's okay for the hook to refrain from storing anything. */
if (mouse_position_hook)
(*mouse_position_hook) (&f, -1,
@@ -1539,6 +1539,13 @@ before calling this function on it, like this.
Fselect_frame (frame);
mouse_moveto (XINT (x), XINT (y));
}
+#else
+#ifdef HAVE_GPM
+ {
+ Fselect_frame (frame);
+ term_mouse_moveto (XINT (x), XINT (y));
+ }
+#endif
#endif
#endif
@@ -1574,6 +1581,13 @@ before calling this function on it, like this.
Fselect_frame (frame);
mouse_moveto (XINT (x), XINT (y));
}
+#else
+#ifdef HAVE_GPM
+ {
+ Fselect_frame (frame);
+ term_mouse_moveto (XINT (x), XINT (y));
+ }
+#endif
#endif
#endif
diff --git a/src/frame.h b/src/frame.h
index 1a827e786ea..d5e9f21ed10 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -214,7 +214,7 @@ struct frame
be used for output. */
unsigned glyphs_initialized_p : 1;
-#if defined (USE_GTK)
+#if defined (USE_GTK) || defined (MAC_OS)
/* Nonzero means using a tool bar that comes from the toolkit. */
int external_tool_bar;
#endif
@@ -549,7 +549,7 @@ typedef struct frame *FRAME_PTR;
/* Nonzero if this frame should display a tool bar
in a way that does not use any text lines. */
-#if defined (USE_GTK)
+#if defined (USE_GTK) || defined (MAC_OS)
#define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
#else
#define FRAME_EXTERNAL_TOOL_BAR(f) 0
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 1e8b12c5c7f..fcd9f655321 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -381,7 +381,7 @@ Fifth Floor, Boston, MA 02110-1301, USA.
extern __ptr_t bss_sbrk PP ((ptrdiff_t __size));
extern int bss_sbrk_did_unexec;
#endif
-__ptr_t (*__morecore) PP ((ptrdiff_t __size)) = __default_morecore;
+__ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore;
/* Debugging hook for `malloc'. */
__ptr_t (*__malloc_hook) PP ((__malloc_size_t __size));
diff --git a/src/image.c b/src/image.c
index 69e1a7d33bd..74bb1d75451 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1609,6 +1609,7 @@ x_alloc_image_color (f, img, color_name, dflt)
Image Cache
***********************************************************************/
+static struct image *search_image_cache P_ ((struct frame *, Lisp_Object, unsigned));
static void cache_image P_ ((struct frame *f, struct image *img));
static void postprocess_image P_ ((struct frame *, struct image *));
@@ -1631,6 +1632,56 @@ make_image_cache ()
}
+/* Find an image matching SPEC in the cache, and return it. If no
+ image is found, return NULL. */
+static struct image *
+search_image_cache (f, spec, hash)
+ struct frame *f;
+ Lisp_Object spec;
+ unsigned hash;
+{
+ struct image *img;
+ struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+ int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
+
+ /* If the image spec does not specify a background color, the cached
+ image must have the same background color as the current frame.
+ The foreground color must also match, for the sake of monochrome
+ images.
+
+ In fact, we could ignore the foreground color matching condition
+ for color images, or if the image spec specifies :foreground;
+ similarly we could ignore the background color matching condition
+ for formats that don't use transparency (such as jpeg), or if the
+ image spec specifies :background. However, the extra memory
+ usage is probably negligible in practice, so we don't bother. */
+ if (!c) return NULL;
+
+ for (img = c->buckets[i]; img; img = img->next)
+ if (img->hash == hash
+ && !NILP (Fequal (img->spec, spec))
+ /* If the image spec specifies a background, it doesn't matter
+ what the frame background is. */
+ && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f)
+ && img->frame_background == FRAME_BACKGROUND_PIXEL (f))
+ break;
+ return img;
+}
+
+
+/* Search frame F for an image with spec SPEC, and free it. */
+
+static void
+uncache_image (f, spec)
+ struct frame *f;
+ Lisp_Object spec;
+{
+ struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
+ if (img)
+ free_image (f, img);
+}
+
+
/* Free image cache of frame F. Be aware that X frames share images
caches. */
@@ -1741,6 +1792,36 @@ FRAME t means clear the image caches of all frames. */)
}
+DEFUN ("image-refresh", Fimage_refresh, Simage_refresh,
+ 1, 2, 0,
+ doc: /* Refresh the image with specification SPEC on frame FRAME.
+If SPEC specifies an image file, the displayed image is updated with
+the current contents of that file.
+FRAME nil or omitted means use the selected frame.
+FRAME t means refresh the image on all frames. */)
+ (spec, frame)
+ Lisp_Object spec, frame;
+{
+ if (!valid_image_p (spec))
+ error ("Invalid image specification");
+
+ if (EQ (frame, Qt))
+ {
+ Lisp_Object tail;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_WINDOW_P (f))
+ uncache_image (f, spec);
+ }
+ }
+ else
+ uncache_image (check_x_frame (frame), spec);
+
+ return Qnil;
+}
+
+
/* Compute masks and transform image IMG on frame F, as specified
by the image's specification, */
@@ -1824,9 +1905,7 @@ lookup_image (f, spec)
struct frame *f;
Lisp_Object spec;
{
- struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
struct image *img;
- int i;
unsigned hash;
struct gcpro gcpro1;
EMACS_TIME now;
@@ -1840,12 +1919,7 @@ lookup_image (f, spec)
/* Look up SPEC in the hash table of the image cache. */
hash = sxhash (spec, 0);
- i = hash % IMAGE_CACHE_BUCKETS_SIZE;
-
- for (img = c->buckets[i]; img; img = img->next)
- if (img->hash == hash && !NILP (Fequal (img->spec, spec)))
- break;
-
+ img = search_image_cache (f, spec, hash);
if (img && img->load_failed_p)
{
free_image (f, img);
@@ -1861,6 +1935,8 @@ lookup_image (f, spec)
img = make_image (spec, hash);
cache_image (f, img);
img->load_failed_p = img->type->load (f, img) == 0;
+ img->frame_foreground = FRAME_FOREGROUND_PIXEL (f);
+ img->frame_background = FRAME_BACKGROUND_PIXEL (f);
/* If we can't load the image, and we don't have a width and
height, use some arbitrary width and height so that we can
@@ -5727,7 +5803,17 @@ pbm_load (f, img)
if (raw_p)
{
if ((x & 7) == 0)
- c = *p++;
+ {
+ if (p >= end)
+ {
+ x_destroy_x_image (ximg);
+ x_clear_image (f, img);
+ image_error ("Invalid image size in image `%s'",
+ img->spec, Qnil);
+ goto error;
+ }
+ c = *p++;
+ }
g = c & 0x80;
c <<= 1;
}
@@ -8647,6 +8733,7 @@ non-numeric, there is no explicit limit on the size of images. */);
defsubr (&Sinit_image_library);
defsubr (&Sclear_image_cache);
+ defsubr (&Simage_refresh);
defsubr (&Simage_size);
defsubr (&Simage_mask_p);
defsubr (&Simage_extension_data);
diff --git a/src/keyboard.c b/src/keyboard.c
index 5cedd0572b2..b096424a615 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -521,7 +521,7 @@ Lisp_Object Qmake_frame_visible;
Lisp_Object Qselect_window;
Lisp_Object Qhelp_echo;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
Lisp_Object Qmouse_fixup_help_message;
#endif
@@ -677,7 +677,7 @@ static Lisp_Object read_char_x_menu_prompt ();
static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int,
Lisp_Object *));
static Lisp_Object make_lispy_event P_ ((struct input_event *));
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object,
enum scroll_bar_part,
Lisp_Object, Lisp_Object,
@@ -1249,7 +1249,7 @@ cmd_error_internal (data, context)
/* Use user's specified output function if any. */
if (!NILP (Vcommand_error_function))
call3 (Vcommand_error_function, data,
- build_string (context ? context : ""),
+ context ? build_string (context) : empty_unibyte_string,
Vsignaling_function);
/* If the window system or terminal frame hasn't been initialized
yet, or we're not interactive, write the message to stderr and exit. */
@@ -1390,7 +1390,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
return Qnil;
}
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
of this function. */
@@ -1466,7 +1466,7 @@ some_mouse_moved ()
return 0;
}
-#endif /* HAVE_MOUSE */
+#endif /* HAVE_MOUSE || HAVE_GPM */
/* This is the actual command reading loop,
sans error-handling encapsulation. */
@@ -2388,7 +2388,7 @@ show_help_echo (help, window, object, pos, ok_to_overwrite_keystroke_echo)
return;
}
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!noninteractive && STRINGP (help))
{
/* The mouse-fixup-help-message Lisp function can call
@@ -3640,7 +3640,7 @@ readable_events (flags)
return 1;
}
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
&& !NILP (do_mouse_tracking) && some_mouse_moved ())
return 1;
@@ -3918,6 +3918,9 @@ discard_mouse_events ()
#ifdef WINDOWSNT
|| sp->kind == W32_SCROLL_BAR_CLICK_EVENT
#endif
+#ifdef HAVE_GPM
+ || sp->kind == GPM_CLICK_EVENT
+#endif
|| sp->kind == SCROLL_BAR_CLICK_EVENT)
{
sp->kind = NO_EVENT;
@@ -3992,7 +3995,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
{
if (kbd_fetch_ptr != kbd_store_ptr)
break;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!NILP (do_mouse_tracking) && some_mouse_moved ())
break;
#endif
@@ -4014,7 +4017,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
#endif /* SIGIO */
if (kbd_fetch_ptr != kbd_store_ptr)
break;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
if (!NILP (do_mouse_tracking) && some_mouse_moved ())
break;
#endif
@@ -4250,7 +4253,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
}
}
}
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
/* Try generating a mouse motion event. */
else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
{
@@ -4291,7 +4294,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
if (!NILP (x) && NILP (obj))
obj = make_lispy_movement (f, bar_window, part, x, y, time);
}
-#endif /* HAVE_MOUSE */
+#endif /* HAVE_MOUSE || HAVE GPM */
else
/* We were promised by the above while loop that there was
something for us to read! */
@@ -6008,13 +6011,73 @@ make_lispy_event (event)
}
#endif
+#ifdef HAVE_GPM
+ case GPM_CLICK_EVENT:
+ {
+ FRAME_PTR f = XFRAME (event->frame_or_window);
+ Lisp_Object head, position;
+ Lisp_Object *start_pos_ptr;
+ Lisp_Object start_pos;
+ int button = event->code;
+
+ if (button >= ASIZE (button_down_location))
+ {
+ button_down_location = larger_vector (button_down_location,
+ button + 1, Qnil);
+ mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
+ }
+
+ start_pos_ptr = &AREF (button_down_location, button);
+ start_pos = *start_pos_ptr;
+
+ position = make_lispy_position (f, &event->x, &event->y,
+ event->timestamp);
+
+ if (event->modifiers & down_modifier)
+ *start_pos_ptr = Fcopy_alist (position);
+ else if (event->modifiers & (up_modifier | drag_modifier))
+ {
+ if (!CONSP (start_pos))
+ return Qnil;
+ event->modifiers &= ~up_modifier;
+ }
+
+ head = modify_event_symbol (button,
+ event->modifiers,
+ Qmouse_click, Vlispy_mouse_stem,
+ NULL,
+ &mouse_syms,
+ XVECTOR (mouse_syms)->size);
+
+ if (event->modifiers & drag_modifier)
+ return Fcons (head,
+ Fcons (start_pos,
+ Fcons (position,
+ Qnil)));
+ else if (event->modifiers & double_modifier)
+ return Fcons (head,
+ Fcons (position,
+ Fcons (make_number (2),
+ Qnil)));
+ else if (event->modifiers & triple_modifier)
+ return Fcons (head,
+ Fcons (position,
+ Fcons (make_number (3),
+ Qnil)));
+ else
+ return Fcons (head,
+ Fcons (position,
+ Qnil));
+ }
+#endif /* HAVE_GPM */
+
/* The 'kind' field of the event is something we don't recognize. */
default:
abort ();
}
}
-#ifdef HAVE_MOUSE
+#if defined(HAVE_MOUSE) || defined(HAVE_GPM)
static Lisp_Object
make_lispy_movement (frame, bar_window, part, x, y, time)
@@ -6053,7 +6116,7 @@ make_lispy_movement (frame, bar_window, part, x, y, time)
}
}
-#endif /* HAVE_MOUSE */
+#endif /* HAVE_MOUSE || HAVE GPM */
/* Construct a switch frame event. */
static Lisp_Object
@@ -6865,8 +6928,28 @@ read_avail_input (expected)
if (n_to_read == 0)
return 0;
#else /* not MSDOS */
+#ifdef HAVE_GPM
+ if (term_gpm)
+ {
+ Gpm_Event event;
+ struct input_event hold_quit;
+ int gpm;
+
+ EVENT_INIT (hold_quit);
+ hold_quit.kind = NO_EVENT;
+
+ while (gpm = Gpm_GetEvent (&event), gpm == 1) {
+ nread += handle_one_term_event (&event, &hold_quit);
+ }
+ if (hold_quit.kind != NO_EVENT)
+ kbd_buffer_store_event (&hold_quit);
+ if (nread)
+ return nread;
+ }
+#endif /* HAVE_GPM */
#ifdef FIONREAD
- /* Find out how much input is available. */
+
+ /* Find out how much input is available. */
if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
/* Formerly simply reported no input, but that sometimes led to
a failure of Emacs to terminate.
@@ -11045,7 +11128,7 @@ init_keyboard ()
recent_keys_index = 0;
kbd_fetch_ptr = kbd_buffer;
kbd_store_ptr = kbd_buffer;
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
do_mouse_tracking = Qnil;
#endif
input_pending = 0;
@@ -11235,7 +11318,7 @@ syms_of_keyboard ()
Qmenu_bar = intern ("menu-bar");
staticpro (&Qmenu_bar);
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
Qmouse_fixup_help_message = intern ("mouse-fixup-help-message");
staticpro (&Qmouse_fixup_help_message);
#endif
@@ -11367,7 +11450,7 @@ syms_of_keyboard ()
defsubr (&Sread_key_sequence);
defsubr (&Sread_key_sequence_vector);
defsubr (&Srecursive_edit);
-#ifdef HAVE_MOUSE
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
defsubr (&Strack_mouse);
#endif
defsubr (&Sinput_pending_p);
diff --git a/src/keymap.c b/src/keymap.c
index a39c0d43984..c9817199a4f 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -429,7 +429,7 @@ Return PARENT. PARENT should be nil or another keymap. */)
if (CHAR_TABLE_P (XCAR (list)))
{
- Lisp_Object indices[3];
+ int indices[3];
map_char_table (fix_submap_inheritance, Qnil,
XCAR (list), XCAR (list),
@@ -728,7 +728,7 @@ map_keymap (map, fun, args, data, autoload)
}
else if (CHAR_TABLE_P (binding))
{
- Lisp_Object indices[3];
+ int indices[3];
map_char_table (map_keymap_char_table_item, Qnil, binding, binding,
Fcons (make_save_value (fun, 0),
Fcons (make_save_value (data, 0),
@@ -1079,7 +1079,7 @@ is not copied. */)
Lisp_Object elt = XCAR (keymap);
if (CHAR_TABLE_P (elt))
{
- Lisp_Object indices[3];
+ int indices[3];
elt = Fcopy_sequence (elt);
map_char_table (copy_keymap_1, Qnil, elt, elt, elt, 0, indices);
}
@@ -1156,7 +1156,8 @@ binding KEY to DEF is added at the front of KEYMAP. */)
if (SYMBOLP (def) && !EQ (Vdefine_key_rebound_commands, Qt))
Vdefine_key_rebound_commands = Fcons (def, Vdefine_key_rebound_commands);
- meta_bit = VECTORP (key) ? meta_modifier : 0x80;
+ meta_bit = (VECTORP (key) || (STRINGP (key) && STRING_MULTIBYTE (key))
+ ? meta_modifier : 0x80);
if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
{ /* DEF is apparently an XEmacs-style keyboard macro. */
@@ -1312,7 +1313,7 @@ recognize the default bindings, just as `read-key-sequence' does. */)
c = Fevent_convert_list (c);
/* Turn the 8th bit of string chars into a meta modifier. */
- if (INTEGERP (c) && XINT (c) & 0x80 && STRINGP (key))
+ if (STRINGP (key) && XINT (c) & 0x80 && !STRING_MULTIBYTE (key))
XSETINT (c, (XINT (c) | meta_modifier) & ~0x80);
/* Allow string since binding for `menu-bar-select-buffer'
@@ -1540,14 +1541,47 @@ current_minor_maps (modeptr, mapptr)
}
DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
- 0, 1, 0,
+ 0, 2, 0,
doc: /* Return a list of the currently active keymaps.
OLP if non-nil indicates that we should obey `overriding-local-map' and
-`overriding-terminal-local-map'. */)
- (olp)
- Lisp_Object olp;
+`overriding-terminal-local-map'. POSITION can specify a click position
+like in the respective argument of `key-binding'. */)
+ (olp, position)
+ Lisp_Object olp, position;
{
- Lisp_Object keymaps = Fcons (current_global_map, Qnil);
+ int count = SPECPDL_INDEX ();
+
+ Lisp_Object keymaps;
+
+ /* If a mouse click position is given, our variables are based on
+ the buffer clicked on, not the current buffer. So we may have to
+ switch the buffer here. */
+
+ if (CONSP (position))
+ {
+ Lisp_Object window;
+
+ window = POSN_WINDOW (position);
+
+ if (WINDOWP (window)
+ && BUFFERP (XWINDOW (window)->buffer)
+ && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+ {
+ /* Arrange to go back to the original buffer once we're done
+ processing the key sequence. We don't use
+ save_excursion_{save,restore} here, in analogy to
+ `read-key-sequence' to avoid saving point. Maybe this
+ would not be a problem here, but it is easier to keep
+ things the same.
+ */
+
+ record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+
+ set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
+ }
+ }
+
+ keymaps = Fcons (current_global_map, Qnil);
if (!NILP (olp))
{
@@ -1561,15 +1595,76 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
}
if (NILP (XCDR (keymaps)))
{
- Lisp_Object local;
Lisp_Object *maps;
int nmaps, i;
- /* This usually returns the buffer's local map,
- but that can be overridden by a `local-map' property. */
- local = get_local_map (PT, current_buffer, Qlocal_map);
- if (!NILP (local))
- keymaps = Fcons (local, keymaps);
+ Lisp_Object keymap, local_map;
+ EMACS_INT pt;
+
+ pt = INTEGERP (position) ? XINT (position)
+ : MARKERP (position) ? marker_position (position)
+ : PT;
+
+ /* Get the buffer local maps, possibly overriden by text or
+ overlay properties */
+
+ local_map = get_local_map (pt, current_buffer, Qlocal_map);
+ keymap = get_local_map (pt, current_buffer, Qkeymap);
+
+ if (CONSP (position))
+ {
+ Lisp_Object string;
+
+ /* For a mouse click, get the local text-property keymap
+ of the place clicked on, rather than point. */
+
+ if (POSN_INBUFFER_P (position))
+ {
+ Lisp_Object pos;
+
+ pos = POSN_BUFFER_POSN (position);
+ if (INTEGERP (pos)
+ && XINT (pos) >= BEG && XINT (pos) <= Z)
+ {
+ local_map = get_local_map (XINT (pos),
+ current_buffer, Qlocal_map);
+
+ keymap = get_local_map (XINT (pos),
+ current_buffer, Qkeymap);
+ }
+ }
+
+ /* If on a mode line string with a local keymap,
+ or for a click on a string, i.e. overlay string or a
+ string displayed via the `display' property,
+ consider `local-map' and `keymap' properties of
+ that string. */
+
+ if (string = POSN_STRING (position),
+ (CONSP (string) && STRINGP (XCAR (string))))
+ {
+ Lisp_Object pos, map;
+
+ pos = XCDR (string);
+ string = XCAR (string);
+ if (INTEGERP (pos)
+ && XINT (pos) >= 0
+ && XINT (pos) < SCHARS (string))
+ {
+ map = Fget_text_property (pos, Qlocal_map, string);
+ if (!NILP (map))
+ local_map = map;
+
+ map = Fget_text_property (pos, Qkeymap, string);
+ if (!NILP (map))
+ keymap = map;
+ }
+ }
+
+ }
+
+ if (!NILP (local_map))
+ keymaps = Fcons (local_map, keymaps);
/* Now put all the minor mode keymaps on the list. */
nmaps = current_minor_maps (0, &maps);
@@ -1578,12 +1673,12 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
if (!NILP (maps[i]))
keymaps = Fcons (maps[i], keymaps);
- /* This returns nil unless there is a `keymap' property. */
- local = get_local_map (PT, current_buffer, Qkeymap);
- if (!NILP (local))
- keymaps = Fcons (local, keymaps);
+ if (!NILP (keymap))
+ keymaps = Fcons (keymap, keymaps);
}
+ unbind_to (count, Qnil);
+
return keymaps;
}
@@ -1951,12 +2046,23 @@ DEFUN ("current-minor-mode-maps", Fcurrent_minor_mode_maps, Scurrent_minor_mode_
/* Help functions for describing and documenting keymaps. */
+struct accessible_keymaps_data {
+ Lisp_Object maps, tail, thisseq;
+ /* Does the current sequence end in the meta-prefix-char? */
+ int is_metized;
+};
static void
-accessible_keymaps_1 (key, cmd, maps, tail, thisseq, is_metized)
- Lisp_Object maps, tail, thisseq, key, cmd;
- int is_metized; /* If 1, `key' is assumed to be INTEGERP. */
+accessible_keymaps_1 (key, cmd, args, data)
+ Lisp_Object key, cmd, args;
+ /* Use void* to be compatible with map_keymap_function_t. */
+ void *data;
{
+ struct accessible_keymaps_data *d = data; /* Cast! */
+ Lisp_Object maps = d->maps;
+ Lisp_Object tail = d->tail;
+ Lisp_Object thisseq = d->thisseq;
+ int is_metized = d->is_metized && INTEGERP (key);
Lisp_Object tem;
cmd = get_keymap (get_keyelt (cmd, 0), 0, 0);
@@ -2010,17 +2116,6 @@ accessible_keymaps_1 (key, cmd, maps, tail, thisseq, is_metized)
}
}
-static void
-accessible_keymaps_char_table (args, index, cmd)
- Lisp_Object args, index, cmd;
-{
- accessible_keymaps_1 (index, cmd,
- XCAR (XCAR (args)),
- XCAR (XCDR (args)),
- XCDR (XCDR (args)),
- XINT (XCDR (XCAR (args))));
-}
-
/* This function cannot GC. */
DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps,
@@ -2035,14 +2130,11 @@ then the value includes only maps for prefixes that start with PREFIX. */)
Lisp_Object keymap, prefix;
{
Lisp_Object maps, tail;
- int prefixlen = 0;
+ int prefixlen = XINT (Flength (prefix));
/* no need for gcpro because we don't autoload any keymaps. */
if (!NILP (prefix))
- prefixlen = XINT (Flength (prefix));
-
- if (!NILP (prefix))
{
/* If a prefix was specified, start with the keymap (if any) for
that prefix, so we don't waste time considering other prefixes. */
@@ -2052,7 +2144,9 @@ then the value includes only maps for prefixes that start with PREFIX. */)
if the prefix is not defined in this particular map.
It might even give us a list that isn't a keymap. */
tem = get_keymap (tem, 0, 0);
- if (CONSP (tem))
+ /* If the keymap is autoloaded `tem' is not a cons-cell, but we still
+ want to return it. */
+ if (!NILP (tem))
{
/* Convert PREFIX to a vector now, so that later on
we don't have to deal with the possibility of a string. */
@@ -2092,57 +2186,26 @@ then the value includes only maps for prefixes that start with PREFIX. */)
for (tail = maps; CONSP (tail); tail = XCDR (tail))
{
- register Lisp_Object thisseq, thismap;
+ struct accessible_keymaps_data data;
+ register Lisp_Object thismap = Fcdr (XCAR (tail));
Lisp_Object last;
- /* Does the current sequence end in the meta-prefix-char? */
- int is_metized;
- thisseq = Fcar (Fcar (tail));
- thismap = Fcdr (Fcar (tail));
- last = make_number (XINT (Flength (thisseq)) - 1);
- is_metized = (XINT (last) >= 0
+ data.thisseq = Fcar (XCAR (tail));
+ data.maps = maps;
+ data.tail = tail;
+ last = make_number (XINT (Flength (data.thisseq)) - 1);
+ /* Does the current sequence end in the meta-prefix-char? */
+ data.is_metized = (XINT (last) >= 0
/* Don't metize the last char of PREFIX. */
&& XINT (last) >= prefixlen
- && EQ (Faref (thisseq, last), meta_prefix_char));
-
- for (; CONSP (thismap); thismap = XCDR (thismap))
- {
- Lisp_Object elt;
-
- elt = XCAR (thismap);
-
- QUIT;
-
- if (CHAR_TABLE_P (elt))
- {
- Lisp_Object indices[3];
-
- map_char_table (accessible_keymaps_char_table, Qnil, elt,
- elt, Fcons (Fcons (maps, make_number (is_metized)),
- Fcons (tail, thisseq)),
- 0, indices);
- }
- else if (VECTORP (elt))
- {
- register int i;
-
- /* Vector keymap. Scan all the elements. */
- for (i = 0; i < ASIZE (elt); i++)
- accessible_keymaps_1 (make_number (i), AREF (elt, i),
- maps, tail, thisseq, is_metized);
+ && EQ (Faref (data.thisseq, last), meta_prefix_char));
- }
- else if (CONSP (elt))
- accessible_keymaps_1 (XCAR (elt), XCDR (elt),
- maps, tail, thisseq,
- is_metized && INTEGERP (XCAR (elt)));
-
- }
+ /* Since we can't run lisp code, we can't scan autoloaded maps. */
+ if (CONSP (thismap))
+ map_keymap (thismap, accessible_keymaps_1, Qnil, &data, 0);
}
-
return maps;
}
-
Lisp_Object Qsingle_key_description, Qkey_description;
/* This function cannot GC. */
@@ -2187,7 +2250,7 @@ spaces are put between sequence elements, etc. */)
len += 2;
}
else if (len == 0)
- return empty_string;
+ return empty_unibyte_string;
return Fconcat (len - 1, args);
}
@@ -2413,7 +2476,7 @@ around function keys and event symbols. */)
{
char buf[256];
- sprintf (buf, "Invalid char code %d", XINT (key));
+ sprintf (buf, "Invalid char code %ld", XINT (key));
return build_string (buf);
}
else if (charset
@@ -2556,8 +2619,8 @@ ascii_sequence_p (seq)
/* where-is - finding a command in a set of keymaps. */
static Lisp_Object where_is_internal ();
-static Lisp_Object where_is_internal_1 ();
-static void where_is_internal_2 ();
+static void where_is_internal_1 P_ ((Lisp_Object key, Lisp_Object binding,
+ Lisp_Object args, void *data));
/* Like Flookup_key, but uses a list of keymaps SHADOW instead of a single map.
Returns the first non-nil binding found in any of those maps. */
@@ -2586,6 +2649,12 @@ shadow_lookup (shadow, key, flag)
static Lisp_Object Vmouse_events;
+struct where_is_internal_data {
+ Lisp_Object definition, noindirect, this, last;
+ int last_is_meta;
+ Lisp_Object sequences;
+};
+
/* This function can GC if Flookup_key autoloads any keymaps. */
static Lisp_Object
@@ -2623,6 +2692,7 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
{
/* Key sequence to reach map, and the map that it reaches */
register Lisp_Object this, map, tem;
+ struct where_is_internal_data data;
/* In order to fold [META-PREFIX-CHAR CHAR] sequences into
[M-CHAR] sequences, check if last character of the sequence
@@ -2647,148 +2717,94 @@ where_is_internal (definition, keymaps, firstonly, noindirect, no_remap)
QUIT;
- while (CONSP (map))
- {
- /* Because the code we want to run on each binding is rather
- large, we don't want to have two separate loop bodies for
- sparse keymap bindings and tables; we want to iterate one
- loop body over both keymap and vector bindings.
+ data.definition = definition;
+ data.noindirect = noindirect;
+ data.this = this;
+ data.last = last;
+ data.last_is_meta = last_is_meta;
+ data.sequences = Qnil;
- For this reason, if Fcar (map) is a vector, we don't
- advance map to the next element until i indicates that we
- have finished off the vector. */
- Lisp_Object elt, key, binding;
- elt = XCAR (map);
- map = XCDR (map);
+ if (CONSP (map))
+ map_keymap (map, where_is_internal_1, Qnil, &data, 0);
- sequences = Qnil;
+ sequences = data.sequences;
- QUIT;
-
- /* Set key and binding to the current key and binding, and
- advance map and i to the next binding. */
- if (VECTORP (elt))
+ while (CONSP (sequences))
+ {
+ Lisp_Object sequence, remapped, function;
+
+ sequence = XCAR (sequences);
+ sequences = XCDR (sequences);
+
+ /* If the current sequence is a command remapping with
+ format [remap COMMAND], find the key sequences
+ which run COMMAND, and use those sequences instead. */
+ remapped = Qnil;
+ if (NILP (no_remap)
+ && VECTORP (sequence) && XVECTOR (sequence)->size == 2
+ && EQ (AREF (sequence, 0), Qremap)
+ && (function = AREF (sequence, 1), SYMBOLP (function)))
{
- Lisp_Object sequence;
- int i;
- /* In a vector, look at each element. */
- for (i = 0; i < XVECTOR (elt)->size; i++)
+ Lisp_Object remapped1;
+
+ remapped1 = where_is_internal (function, keymaps, firstonly, noindirect, Qt);
+ if (CONSP (remapped1))
{
- binding = AREF (elt, i);
- XSETFASTINT (key, i);
- sequence = where_is_internal_1 (binding, key, definition,
- noindirect, this,
- last, nomenus, last_is_meta);
- if (!NILP (sequence))
- sequences = Fcons (sequence, sequences);
+ /* Verify that this key binding actually maps to the
+ remapped command (see below). */
+ if (!EQ (shadow_lookup (keymaps, XCAR (remapped1), Qnil), function))
+ continue;
+ sequence = XCAR (remapped1);
+ remapped = XCDR (remapped1);
+ goto record_sequence;
}
}
- else if (CHAR_TABLE_P (elt))
- {
- Lisp_Object indices[3];
- Lisp_Object args;
-
- args = Fcons (Fcons (Fcons (definition, noindirect),
- Qnil), /* Result accumulator. */
- Fcons (Fcons (this, last),
- Fcons (make_number (nomenus),
- make_number (last_is_meta))));
- map_char_table (where_is_internal_2, Qnil, elt, elt, args,
- 0, indices);
- sequences = XCDR (XCAR (args));
- }
- else if (CONSP (elt))
- {
- Lisp_Object sequence;
- key = XCAR (elt);
- binding = XCDR (elt);
+ /* Verify that this key binding is not shadowed by another
+ binding for the same key, before we say it exists.
- sequence = where_is_internal_1 (binding, key, definition,
- noindirect, this,
- last, nomenus, last_is_meta);
- if (!NILP (sequence))
- sequences = Fcons (sequence, sequences);
- }
+ Mechanism: look for local definition of this key and if
+ it is defined and does not match what we found then
+ ignore this key.
+ Either nil or number as value from Flookup_key
+ means undefined. */
+ if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
+ continue;
- while (!NILP (sequences))
+ record_sequence:
+ /* Don't annoy user with strings from a menu such as
+ Select Paste. Change them all to "(any string)",
+ so that there seems to be only one menu item
+ to report. */
+ if (! NILP (sequence))
{
- Lisp_Object sequence, remapped, function;
-
- sequence = XCAR (sequences);
- sequences = XCDR (sequences);
-
- /* If the current sequence is a command remapping with
- format [remap COMMAND], find the key sequences
- which run COMMAND, and use those sequences instead. */
- remapped = Qnil;
- if (NILP (no_remap)
- && VECTORP (sequence) && XVECTOR (sequence)->size == 2
- && EQ (AREF (sequence, 0), Qremap)
- && (function = AREF (sequence, 1), SYMBOLP (function)))
- {
- Lisp_Object remapped1;
-
- remapped1 = where_is_internal (function, keymaps, firstonly, noindirect, Qt);
- if (CONSP (remapped1))
- {
- /* Verify that this key binding actually maps to the
- remapped command (see below). */
- if (!EQ (shadow_lookup (keymaps, XCAR (remapped1), Qnil), function))
- continue;
- sequence = XCAR (remapped1);
- remapped = XCDR (remapped1);
- goto record_sequence;
- }
- }
-
- /* Verify that this key binding is not shadowed by another
- binding for the same key, before we say it exists.
-
- Mechanism: look for local definition of this key and if
- it is defined and does not match what we found then
- ignore this key.
-
- Either nil or number as value from Flookup_key
- means undefined. */
- if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
- continue;
-
- record_sequence:
- /* Don't annoy user with strings from a menu such as
- Select Paste. Change them all to "(any string)",
- so that there seems to be only one menu item
- to report. */
- if (! NILP (sequence))
- {
- Lisp_Object tem;
- tem = Faref (sequence, make_number (XVECTOR (sequence)->size - 1));
- if (STRINGP (tem))
- Faset (sequence, make_number (XVECTOR (sequence)->size - 1),
- build_string ("(any string)"));
- }
+ Lisp_Object tem;
+ tem = Faref (sequence, make_number (XVECTOR (sequence)->size - 1));
+ if (STRINGP (tem))
+ Faset (sequence, make_number (XVECTOR (sequence)->size - 1),
+ build_string ("(any string)"));
+ }
- /* It is a true unshadowed match. Record it, unless it's already
- been seen (as could happen when inheriting keymaps). */
- if (NILP (Fmember (sequence, found)))
- found = Fcons (sequence, found);
-
- /* If firstonly is Qnon_ascii, then we can return the first
- binding we find. If firstonly is not Qnon_ascii but not
- nil, then we should return the first ascii-only binding
- we find. */
- if (EQ (firstonly, Qnon_ascii))
- RETURN_UNGCPRO (sequence);
- else if (!NILP (firstonly) && ascii_sequence_p (sequence))
- RETURN_UNGCPRO (sequence);
-
- if (CONSP (remapped))
- {
- sequence = XCAR (remapped);
- remapped = XCDR (remapped);
- goto record_sequence;
- }
+ /* It is a true unshadowed match. Record it, unless it's already
+ been seen (as could happen when inheriting keymaps). */
+ if (NILP (Fmember (sequence, found)))
+ found = Fcons (sequence, found);
+
+ /* If firstonly is Qnon_ascii, then we can return the first
+ binding we find. If firstonly is not Qnon_ascii but not
+ nil, then we should return the first ascii-only binding
+ we find. */
+ if (EQ (firstonly, Qnon_ascii))
+ RETURN_UNGCPRO (sequence);
+ else if (!NILP (firstonly) && ascii_sequence_p (sequence))
+ RETURN_UNGCPRO (sequence);
+
+ if (CONSP (remapped))
+ {
+ sequence = XCAR (remapped);
+ remapped = XCDR (remapped);
+ goto record_sequence;
}
}
}
@@ -2841,7 +2857,7 @@ remapped command in the returned list. */)
else if (!NILP (keymap))
keymaps = Fcons (keymap, Fcons (current_global_map, Qnil));
else
- keymaps = Fcurrent_active_maps (Qnil);
+ keymaps = Fcurrent_active_maps (Qnil, Qnil);
/* Only use caching for the menubar (i.e. called with (def nil t nil).
We don't really need to check `keymap'. */
@@ -2907,53 +2923,19 @@ remapped command in the returned list. */)
return result;
}
-/* This is the function that Fwhere_is_internal calls using map_char_table.
- ARGS has the form
- (((DEFINITION . NOINDIRECT) . (KEYMAP . RESULT))
- .
- ((THIS . LAST) . (NOMENUS . LAST_IS_META)))
- Since map_char_table doesn't really use the return value from this function,
- we the result append to RESULT, the slot in ARGS.
-
- This function can GC because it calls where_is_internal_1 which can
- GC. */
-
-static void
-where_is_internal_2 (args, key, binding)
- Lisp_Object args, key, binding;
-{
- Lisp_Object definition, noindirect, this, last;
- Lisp_Object result, sequence;
- int nomenus, last_is_meta;
- struct gcpro gcpro1, gcpro2, gcpro3;
-
- GCPRO3 (args, key, binding);
- result = XCDR (XCAR (args));
- definition = XCAR (XCAR (XCAR (args)));
- noindirect = XCDR (XCAR (XCAR (args)));
- this = XCAR (XCAR (XCDR (args)));
- last = XCDR (XCAR (XCDR (args)));
- nomenus = XFASTINT (XCAR (XCDR (XCDR (args))));
- last_is_meta = XFASTINT (XCDR (XCDR (XCDR (args))));
-
- sequence = where_is_internal_1 (binding, key, definition, noindirect,
- this, last, nomenus, last_is_meta);
-
- if (!NILP (sequence))
- XSETCDR (XCAR (args), Fcons (sequence, result));
-
- UNGCPRO;
-}
-
-
/* This function can GC because get_keyelt can. */
-static Lisp_Object
-where_is_internal_1 (binding, key, definition, noindirect, this, last,
- nomenus, last_is_meta)
- Lisp_Object binding, key, definition, noindirect, this, last;
- int nomenus, last_is_meta;
+static void
+where_is_internal_1 (key, binding, args, data)
+ Lisp_Object key, binding, args;
+ void *data;
{
+ struct where_is_internal_data *d = data; /* Cast! */
+ Lisp_Object definition = d->definition;
+ Lisp_Object noindirect = d->noindirect;
+ Lisp_Object this = d->this;
+ Lisp_Object last = d->last;
+ int last_is_meta = d->last_is_meta;
Lisp_Object sequence;
/* Search through indirections unless that's not wanted. */
@@ -2967,7 +2949,7 @@ where_is_internal_1 (binding, key, definition, noindirect, this, last,
|| EQ (binding, definition)
|| (CONSP (definition) && !NILP (Fequal (binding, definition)))))
/* Doesn't match. */
- return Qnil;
+ return;
/* We have found a match. Construct the key sequence where we found it. */
if (INTEGERP (key) && last_is_meta)
@@ -2982,10 +2964,9 @@ where_is_internal_1 (binding, key, definition, noindirect, this, last,
{
Lisp_Object sequences = Fgethash (binding, where_is_cache, Qnil);
Fputhash (binding, Fcons (sequence, sequences), where_is_cache);
- return Qnil;
}
else
- return sequence;
+ d->sequences = Fcons (sequence, d->sequences);
}
/* describe-bindings - summarizing all the bindings in a set of keymaps. */
diff --git a/src/keymap.h b/src/keymap.h
index 8b921850765..1a51de705be 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -34,7 +34,7 @@ EXFUN (Fkey_binding, 4);
EXFUN (Fkey_description, 2);
EXFUN (Fsingle_key_description, 2);
EXFUN (Fwhere_is_internal, 5);
-EXFUN (Fcurrent_active_maps, 1);
+EXFUN (Fcurrent_active_maps, 2);
extern Lisp_Object access_keymap P_ ((Lisp_Object, Lisp_Object, int, int, int));
extern Lisp_Object get_keyelt P_ ((Lisp_Object, int));
extern Lisp_Object get_keymap P_ ((Lisp_Object, int, int));
@@ -47,7 +47,7 @@ extern void syms_of_keymap P_ ((void));
extern void keys_of_keymap P_ ((void));
typedef void (*map_keymap_function_t)
- P_ ((Lisp_Object, Lisp_Object, Lisp_Object, void*));
+ P_ ((Lisp_Object key, Lisp_Object val, Lisp_Object args, void* data));
extern void map_keymap P_ ((Lisp_Object map, map_keymap_function_t fun, Lisp_Object largs, void* cargs, int autoload));
#endif
diff --git a/src/lisp.h b/src/lisp.h
index 9a13a95b3b0..d86fdc0e915 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -56,7 +56,7 @@ Boston, MA 02110-1301, USA. */
#ifdef GC_CHECK_CONS_LIST
#define CHECK_CONS_LIST() check_cons_list()
#else
-#define CHECK_CONS_LIST() 0
+#define CHECK_CONS_LIST() ((void)0)
#endif
/* These are default choices for the types to use. */
@@ -701,7 +701,10 @@ extern int string_bytes P_ ((struct Lisp_String *));
#endif /* not GC_CHECK_STRING_BYTES */
/* Mark STR as a unibyte string. */
-#define STRING_SET_UNIBYTE(STR) (XSTRING (STR)->size_byte = -1)
+#define STRING_SET_UNIBYTE(STR) \
+ do { if (EQ (STR, empty_multibyte_string)) \
+ (STR) = empty_unibyte_string; \
+ else XSTRING (STR)->size_byte = -1; } while (0)
/* Get text properties. */
#define STRING_INTERVALS(STR) (XSTRING (STR)->intervals + 0)
@@ -735,9 +738,9 @@ struct Lisp_Vector
/* If a struct is made to look like a vector, this macro returns the length
of the shortest vector that would hold that struct. */
-#define VECSIZE(type) ((sizeof (type) - (sizeof (struct Lisp_Vector) \
- - sizeof (Lisp_Object)) \
- + sizeof(Lisp_Object) - 1) /* round up */ \
+#define VECSIZE(type) ((sizeof (type) \
+ - OFFSETOF (struct Lisp_Vector, contents[0]) \
+ + sizeof(Lisp_Object) - 1) /* round up */ \
/ sizeof (Lisp_Object))
/* Like VECSIZE, but used when the pseudo-vector has non-Lisp_Object fields
@@ -1038,16 +1041,16 @@ struct Lisp_Hash_Table
hash table size to reduce collisions. */
Lisp_Object index;
- /* Next weak hash table if this is a weak hash table. The head
- of the list is in Vweak_hash_tables. */
- Lisp_Object next_weak;
-
/* User-supplied hash function, or nil. */
Lisp_Object user_hash_function;
/* User-supplied key comparison function, or nil. */
Lisp_Object user_cmp_function;
+ /* Next weak hash table if this is a weak hash table. The head
+ of the list is in weak_hash_tables. */
+ struct Lisp_Hash_Table *next_weak;
+
/* C function to compare two keys. */
int (* cmpfn) P_ ((struct Lisp_Hash_Table *, Lisp_Object,
unsigned, Lisp_Object, unsigned));
@@ -2425,7 +2428,7 @@ EXFUN (Fstring_lessp, 2);
extern int char_table_translate P_ ((Lisp_Object, int));
extern void map_char_table P_ ((void (*) (Lisp_Object, Lisp_Object, Lisp_Object),
Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, int,
- Lisp_Object *));
+ int *));
extern Lisp_Object char_table_ref_and_index P_ ((Lisp_Object, int, int *));
extern void syms_of_fns P_ ((void));
@@ -3060,7 +3063,8 @@ extern void syms_of_frame P_ ((void));
/* defined in emacs.c */
extern Lisp_Object decode_env_path P_ ((char *, char *));
extern Lisp_Object Vinvocation_name, Vinvocation_directory;
-extern Lisp_Object Vinstallation_directory, empty_string;
+extern Lisp_Object Vinstallation_directory;
+extern Lisp_Object empty_unibyte_string, empty_multibyte_string;
EXFUN (Fkill_emacs, 1);
#if HAVE_SETLOCALE
void fixup_locale P_ ((void));
@@ -3096,6 +3100,8 @@ extern int wait_reading_process_output P_ ((int, int, int, int,
int));
extern void add_keyboard_wait_descriptor P_ ((int));
extern void delete_keyboard_wait_descriptor P_ ((int));
+extern void add_gpm_wait_descriptor P_ ((int));
+extern void delete_gpm_wait_descriptor P_ ((int));
extern void close_process_descs P_ ((void));
extern void init_process P_ ((void));
extern void syms_of_process P_ ((void));
@@ -3238,6 +3244,7 @@ EXFUN (Fx_file_dialog, 5);
#endif
/* Defined in xfaces.c */
+EXFUN (Fclear_face_cache, 1);
extern void syms_of_xfaces P_ ((void));
#ifndef HAVE_GETLOADAVG
@@ -3253,6 +3260,7 @@ extern void syms_of_xfns P_ ((void));
extern void syms_of_xsmfns P_ ((void));
/* Defined in xselect.c */
+EXFUN (Fx_send_client_event, 6);
extern void syms_of_xselect P_ ((void));
/* Defined in xterm.c */
diff --git a/src/lread.c b/src/lread.c
index 5ecb521ff8a..ef999fac74c 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1199,7 +1199,7 @@ openp (path, str, suffixes, storeptr, predicate)
fn = (char *) alloca (fn_size = 100 + want_size);
/* Loop over suffixes. */
- for (tail = NILP (suffixes) ? Fcons (build_string (""), Qnil) : suffixes;
+ for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : suffixes;
CONSP (tail); tail = XCDR (tail))
{
int lsuffix = SBYTES (XCAR (tail));
@@ -1894,7 +1894,7 @@ read_escape (readcharfun, stringp, byterep)
case 's':
c = READCHAR;
- if (c != '-')
+ if (stringp || c != '-')
{
UNREAD (c);
return ' ';
@@ -4070,8 +4070,7 @@ and, if so, which suffixes they should try to append to the file name
in order to do so. However, if you want to customize which suffixes
the loading functions recognize as compression suffixes, you should
customize `jka-compr-load-suffixes' rather than the present variable. */);
- /* We don't use empty_string because it's not initialized yet. */
- Vload_file_rep_suffixes = Fcons (build_string (""), Qnil);
+ Vload_file_rep_suffixes = Fcons (empty_unibyte_string, Qnil);
DEFVAR_BOOL ("load-in-progress", &load_in_progress,
doc: /* Non-nil iff inside of `load'. */);
diff --git a/src/m/alpha.h b/src/m/alpha.h
index d9fd342ef19..84e74d581d1 100644
--- a/src/m/alpha.h
+++ b/src/m/alpha.h
@@ -99,10 +99,6 @@ NOTE-END
# endif
#endif
-#if defined(__OpenBSD__)
-#define ORDINARY_LINK
-#endif
-
#ifdef __ELF__
#undef UNEXEC
#define UNEXEC unexelf.o
diff --git a/src/mac.c b/src/mac.c
index 0321e8f2ae1..a64c3d208e3 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -1826,8 +1826,6 @@ xrm_get_preference_database (application)
GCPRO3 (database, quarks, value);
- BLOCK_INPUT;
-
app_id = kCFPreferencesCurrentApplication;
if (application)
{
@@ -1879,8 +1877,6 @@ xrm_get_preference_database (application)
CFRelease (key_set);
CFRelease (app_id);
- UNBLOCK_INPUT;
-
UNGCPRO;
return database;
diff --git a/src/macfns.c b/src/macfns.c
index 8dff77cd5fd..34f80943497 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -218,9 +218,6 @@ void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-
-extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
-
/* Store the screen positions of frame F into XPTR and YPTR.
@@ -1685,6 +1682,25 @@ x_set_tool_bar_lines (f, value, oldval)
/* Make sure we redisplay all windows in this frame. */
++windows_or_buffers_changed;
+#if USE_MAC_TOOLBAR
+ FRAME_TOOL_BAR_LINES (f) = 0;
+ if (nlines)
+ {
+ FRAME_EXTERNAL_TOOL_BAR (f) = 1;
+ if (FRAME_MAC_P (f) && !IsWindowToolbarVisible (FRAME_MAC_WINDOW (f)))
+ /* Make sure next redisplay shows the tool bar. */
+ XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
+ }
+ else
+ {
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ free_frame_tool_bar (f);
+ FRAME_EXTERNAL_TOOL_BAR (f) = 0;
+ }
+
+ return;
+#endif
+
delta = nlines - FRAME_TOOL_BAR_LINES (f);
/* Don't resize the tool-bar to more than we have room for. */
@@ -2263,11 +2279,11 @@ mac_window (f)
FRAME_MAC_WINDOW (f) = NULL;
}
}
-#else
+#else /* !TARGET_API_MAC_CARBON */
FRAME_MAC_WINDOW (f)
= NewCWindow (NULL, &r, "\p", false, zoomDocProc,
- (WindowPtr) -1, 1, (long) f->output_data.mac);
-#endif
+ (WindowRef) -1, 1, (long) f->output_data.mac);
+#endif /* !TARGET_API_MAC_CARBON */
/* so that update events can find this mac_output struct */
f->output_data.mac->mFP = f; /* point back to emacs frame */
@@ -2287,6 +2303,16 @@ mac_window (f)
XSetWindowBackground (FRAME_MAC_DISPLAY(f), FRAME_MAC_WINDOW (f),
FRAME_BACKGROUND_PIXEL (f));
+#if USE_MAC_TOOLBAR
+ /* At the moment, the size of the tool bar is not yet known. We
+ record the gravity value of the newly created window and use it
+ to adjust the position of the window (especially for a negative
+ specification of its vertical position) when the tool bar is
+ first redisplayed. */
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ f->output_data.mac->toolbar_win_gravity = f->win_gravity;
+#endif
+
validate_x_resource_name ();
/* x_set_name normally ignores requests to set the name if the
@@ -3120,7 +3146,7 @@ If omitted or nil, that stands for the selected frame's display. */)
UNBLOCK_INPUT;
}
#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else
+ else /* CGDisplayScreenSize == NULL */
#endif
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
@@ -3157,7 +3183,7 @@ If omitted or nil, that stands for the selected frame's display. */)
UNBLOCK_INPUT;
}
#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else
+ else /* CGDisplayScreenSize == NULL */
#endif
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
@@ -4076,8 +4102,12 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
Point mouse_pos;
BLOCK_INPUT;
+#if TARGET_API_MAC_CARBON
+ GetGlobalMouse (&mouse_pos);
+#else
GetMouse (&mouse_pos);
LocalToGlobal (&mouse_pos);
+#endif
*root_x = mouse_pos.h;
*root_y = mouse_pos.v;
UNBLOCK_INPUT;
diff --git a/src/macgui.h b/src/macgui.h
index 04f48b087a6..7a65e583b1b 100644
--- a/src/macgui.h
+++ b/src/macgui.h
@@ -71,7 +71,7 @@ typedef unsigned long Time;
#undef Z
#define Z (current_buffer->text->z)
#else /* not HAVE_CARBON */
-#include <QuickDraw.h> /* for WindowPtr */
+#include <QuickDraw.h> /* for WindowRef */
#include <QDOffscreen.h> /* for GWorldPtr */
#include <Appearance.h> /* for ThemeCursor */
#include <Windows.h>
@@ -98,7 +98,7 @@ typedef unsigned long Time;
/* Whether to use Quartz 2D routines for drawing operations other than
texts. */
#ifndef USE_CG_DRAWING
-#if USE_ATSUI && MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
#define USE_CG_DRAWING 1
#endif
#endif
@@ -117,7 +117,14 @@ typedef unsigned long Time;
#endif
#endif
-typedef WindowPtr Window;
+/* Whether to use HIToolbar. */
+#ifndef USE_MAC_TOOLBAR
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 && MAC_OS_X_VERSION_MIN_REQUIRED != 1020
+#define USE_MAC_TOOLBAR 1
+#endif
+#endif
+
+typedef WindowRef Window;
typedef GWorldPtr Pixmap;
#define Cursor ThemeCursor
diff --git a/src/macmenu.c b/src/macmenu.c
index b8cfd6a4d2f..e2d4ba8be38 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -200,7 +200,7 @@ static void list_of_items P_ ((Lisp_Object));
static void find_and_call_menu_selection P_ ((FRAME_PTR, int, Lisp_Object,
void *));
-static int fill_menu P_ ((MenuHandle, widget_value *, enum mac_menu_kind, int));
+static int fill_menu P_ ((MenuRef, widget_value *, enum mac_menu_kind, int));
static void fill_menubar P_ ((widget_value *, int));
static void dispose_menus P_ ((enum mac_menu_kind, int));
@@ -882,7 +882,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
/* Regard ESC and C-g as Cancel even without the Cancel button. */
-#ifdef MAC_OSX
+#if 0 /* defined (MAC_OSX) */
static Boolean
mac_dialog_modal_filter (dialog, event, item_hit)
DialogRef dialog;
@@ -991,7 +991,7 @@ for instance using the window manager, then this produces a quit and
but I don't want to make one now. */
CHECK_WINDOW (window);
-#ifdef MAC_OSX
+#if 0 /* defined (MAC_OSX) */
/* Special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p. */
if (EQ (position, Qt)
&& STRINGP (Fcar (contents))
@@ -1162,7 +1162,7 @@ x_activate_menubar (f)
#endif
if (menu_id)
{
- MenuHandle menu = GetMenuHandle (menu_id);
+ MenuRef menu = GetMenuRef (menu_id);
if (menu)
{
@@ -1595,14 +1595,16 @@ menu_target_item_handler (next_handler, event, data)
EventRef event;
void *data;
{
- OSStatus err, result;
+ OSStatus err;
MenuRef menu;
MenuItemIndex menu_item;
Lisp_Object help;
GrafPtr port;
int specpdl_count = SPECPDL_INDEX ();
- result = CallNextEventHandler (next_handler, event);
+ /* Don't be bothered with the overflowed toolbar items menu. */
+ if (!popup_activated ())
+ return eventNotHandledErr;
err = GetEventParameter (event, kEventParamDirectObject, typeMenuRef,
NULL, sizeof (MenuRef), NULL, &menu);
@@ -1626,30 +1628,21 @@ menu_target_item_handler (next_handler, event, data)
SetPort (port);
unbind_to (specpdl_count, Qnil);
- return err == noErr ? noErr : result;
+ return err == noErr ? noErr : eventNotHandledErr;
}
-#endif
OSStatus
-install_menu_target_item_handler (window)
- WindowPtr window;
+install_menu_target_item_handler ()
{
- OSStatus err = noErr;
-#if TARGET_API_MAC_CARBON
static const EventTypeSpec specs[] =
{{kEventClassMenu, kEventMenuTargetItem}};
- static EventHandlerUPP menu_target_item_handlerUPP = NULL;
-
- if (menu_target_item_handlerUPP == NULL)
- menu_target_item_handlerUPP =
- NewEventHandlerUPP (menu_target_item_handler);
- err = InstallWindowEventHandler (window, menu_target_item_handlerUPP,
- GetEventTypeCount (specs), specs,
- NULL, NULL);
-#endif
- return err;
+ return InstallApplicationEventHandler (NewEventHandlerUPP
+ (menu_target_item_handler),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
}
+#endif /* TARGET_API_MAC_CARBON */
/* Event handler function that pops down a menu on C-g. We can only pop
down menus if CancelMenuTracking is present (OSX 10.3 or later). */
@@ -1687,15 +1680,15 @@ menu_quit_handler (nextHandler, theEvent, userData)
}
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
-/* Add event handler to all menus that belong to KIND so we can detect C-g.
- MENU_HANDLE is the root menu of the tracking session to dismiss
- when C-g is detected. NULL means the menu bar.
- If CancelMenuTracking isn't available, do nothing. */
+/* Add event handler to all menus that belong to KIND so we can detect
+ C-g. ROOT_MENU is the root menu of the tracking session to dismiss
+ when C-g is detected. NULL means the menu bar. If
+ CancelMenuTracking isn't available, do nothing. */
static void
-install_menu_quit_handler (kind, menu_handle)
+install_menu_quit_handler (kind, root_menu)
enum mac_menu_kind kind;
- MenuHandle menu_handle;
+ MenuRef root_menu;
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
static const EventTypeSpec typesList[] =
@@ -1708,13 +1701,13 @@ install_menu_quit_handler (kind, menu_handle)
#endif
for (id = min_menu_id[kind]; id < min_menu_id[kind + 1]; id++)
{
- MenuHandle menu = GetMenuHandle (id);
+ MenuRef menu = GetMenuRef (id);
if (menu == NULL)
break;
InstallMenuEventHandler (menu, menu_quit_handler,
GetEventTypeCount (typesList),
- typesList, menu_handle, NULL);
+ typesList, root_menu, NULL);
}
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
}
@@ -1738,10 +1731,13 @@ set_frame_menubar (f, first_time, deep_p)
XSETFRAME (Vmenu_updating_frame, f);
+ /* This seems to be unnecessary for Carbon. */
+#if 0
if (! menubar_widget)
deep_p = 1;
else if (pending_menu_activation && !deep_p)
deep_p = 1;
+#endif
if (deep_p)
{
@@ -1978,7 +1974,7 @@ pop_down_menu (arg)
{
struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
FRAME_PTR f = p->pointer;
- MenuHandle menu = GetMenuHandle (min_menu_id[MAC_MENU_POPUP]);
+ MenuRef menu = GetMenuRef (min_menu_id[MAC_MENU_POPUP]);
BLOCK_INPUT;
@@ -2024,8 +2020,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
int i;
int menu_item_choice;
UInt32 menu_item_selection;
- MenuHandle menu;
- Point pos;
+ MenuRef menu;
widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
widget_value **submenu_stack
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -2231,11 +2226,8 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
free_menubar_widget_value_tree (first_wv);
/* Adjust coordinates to be root-window-relative. */
- pos.h = x;
- pos.v = y;
-
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
- LocalToGlobal (&pos);
+ x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
/* No selection has been chosen yet. */
menu_item_selection = 0;
@@ -2248,13 +2240,13 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
/* Display the menu. */
popup_activated_flag = 1;
- menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0);
+ menu_item_choice = PopUpMenuSelect (menu, y, x, 0);
popup_activated_flag = 0;
/* Get the refcon to find the correct item */
if (menu_item_choice)
{
- MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice));
+ MenuRef sel_menu = GetMenuRef (HiWord (menu_item_choice));
if (sel_menu)
GetMenuItemRefCon (sel_menu, LoWord (menu_item_choice),
@@ -2330,14 +2322,25 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
#if TARGET_API_MAC_CARBON
+#define DIALOG_BUTTON_COMMAND_ID_OFFSET 'Bt\0\0'
+#define DIALOG_BUTTON_COMMAND_ID_P(id) \
+ (((id) & ~0xffff) == DIALOG_BUTTON_COMMAND_ID_OFFSET)
+#define DIALOG_BUTTON_COMMAND_ID_VALUE(id) \
+ ((id) - DIALOG_BUTTON_COMMAND_ID_OFFSET)
+#define DIALOG_BUTTON_MAKE_COMMAND_ID(value) \
+ ((value) + DIALOG_BUTTON_COMMAND_ID_OFFSET)
+
+extern EMACS_TIME timer_check P_ ((int));
+
static pascal OSStatus
mac_handle_dialog_event (next_handler, event, data)
EventHandlerCallRef next_handler;
EventRef event;
void *data;
{
- OSStatus err;
+ OSStatus err, result = eventNotHandledErr;
WindowRef window = (WindowRef) data;
+ int quit_event_loop_p = 0;
switch (GetEventClass (event))
{
@@ -2349,15 +2352,14 @@ mac_handle_dialog_event (next_handler, event, data)
typeHICommand, NULL, sizeof (HICommand),
NULL, &command);
if (err == noErr)
- if ((command.commandID & ~0xffff) == 'Bt\0\0')
+ if (DIALOG_BUTTON_COMMAND_ID_P (command.commandID))
{
SetWRefCon (window, command.commandID);
- err = QuitAppModalLoopForWindow (window);
-
- return err == noErr ? noErr : eventNotHandledErr;
+ quit_event_loop_p = 1;
+ break;
}
- return CallNextEventHandler (next_handler, event);
+ result = CallNextEventHandler (next_handler, event);
}
break;
@@ -2367,8 +2369,8 @@ mac_handle_dialog_event (next_handler, event, data)
char char_code;
result = CallNextEventHandler (next_handler, event);
- if (result == noErr)
- return noErr;
+ if (result != eventNotHandledErr)
+ break;
err = GetEventParameter (event, kEventParamKeyMacCharCodes,
typeChar, NULL, sizeof (char),
@@ -2377,7 +2379,7 @@ mac_handle_dialog_event (next_handler, event, data)
switch (char_code)
{
case kEscapeCharCode:
- err = QuitAppModalLoopForWindow (window);
+ quit_event_loop_p = 1;
break;
default:
@@ -2392,23 +2394,26 @@ mac_handle_dialog_event (next_handler, event, data)
typeUInt32, NULL, sizeof (UInt32),
NULL, &key_code);
if (err == noErr)
- {
- if (mac_quit_char_key_p (modifiers, key_code))
- err = QuitAppModalLoopForWindow (window);
- else
- err = eventNotHandledErr;
- }
+ if (mac_quit_char_key_p (modifiers, key_code))
+ quit_event_loop_p = 1;
}
break;
}
-
- return err == noErr ? noErr : result;
}
break;
default:
abort ();
}
+
+ if (quit_event_loop_p)
+ {
+ err = QuitEventLoop (GetCurrentEventLoop ());
+ if (err == noErr)
+ result = noErr;
+ }
+
+ return result;
}
static OSStatus
@@ -2443,6 +2448,25 @@ install_dialog_event_handler (window)
#define DIALOG_ICON_LEFT_MARGIN (24)
#define DIALOG_ICON_TOP_MARGIN (15)
+static Lisp_Object
+pop_down_dialog (arg)
+ Lisp_Object arg;
+{
+ struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+ WindowRef window = p->pointer;
+
+ BLOCK_INPUT;
+
+ if (popup_activated_flag)
+ EndAppModalStateForWindow (window);
+ DisposeWindow (window);
+ popup_activated_flag = 0;
+
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
+
static int
create_and_show_dialog (f, first_wv)
FRAME_PTR f;
@@ -2456,6 +2480,7 @@ create_and_show_dialog (f, first_wv)
Rect empty_rect, *rects;
WindowRef window = NULL;
ControlRef *buttons, default_button = NULL, text;
+ int specpdl_count = SPECPDL_INDEX ();
dialog_name = first_wv->name;
nb_buttons = dialog_name[1] - '0';
@@ -2472,8 +2497,11 @@ create_and_show_dialog (f, first_wv)
kWindowStandardHandlerAttribute,
&empty_rect, &window);
if (err == noErr)
- err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
- true);
+ {
+ record_unwind_protect (pop_down_dialog, make_save_value (window, 0));
+ err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
+ true);
+ }
if (err == noErr)
err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q'
? CFSTR ("Question")
@@ -2518,14 +2546,16 @@ create_and_show_dialog (f, first_wv)
}
if (err == noErr)
{
+ UInt32 command_id;
+
OffsetRect (&rects[i], -rects[i].left, -rects[i].top);
if (rects[i].right < DIALOG_BUTTON_MIN_WIDTH)
rects[i].right = DIALOG_BUTTON_MIN_WIDTH;
else if (rects[i].right > DIALOG_MAX_INNER_WIDTH)
rects[i].right = DIALOG_MAX_INNER_WIDTH;
- err = SetControlCommandID (buttons[i],
- 'Bt\0\0' + (int) wv->call_data);
+ command_id = DIALOG_BUTTON_MAKE_COMMAND_ID ((int) wv->call_data);
+ err = SetControlCommandID (buttons[i], command_id);
}
if (err != noErr)
break;
@@ -2696,18 +2726,55 @@ create_and_show_dialog (f, first_wv)
SetWRefCon (window, 0);
ShowWindow (window);
BringToFront (window);
- err = RunAppModalLoopForWindow (window);
+ popup_activated_flag = 1;
+ err = BeginAppModalStateForWindow (window);
+ }
+ if (err == noErr)
+ {
+ EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget ();
+
+ while (1)
+ {
+ EMACS_TIME next_time = timer_check (1);
+ long secs = EMACS_SECS (next_time);
+ long usecs = EMACS_USECS (next_time);
+ EventTimeout timeout;
+ EventRef event;
+
+ if (secs < 0 || (secs == 0 && usecs == 0))
+ {
+ /* Sometimes timer_check returns -1 (no timers) even if
+ there are timers. So do a timeout anyway. */
+ secs = 1;
+ usecs = 0;
+ }
+
+ timeout = (secs * kEventDurationSecond
+ + usecs * kEventDurationMicrosecond);
+ err = ReceiveNextEvent (0, NULL, timeout, kEventRemoveFromQueue,
+ &event);
+ if (err == noErr)
+ {
+ SendEventToEventTarget (event, toolbox_dispatcher);
+ ReleaseEvent (event);
+ }
+ else if (err != eventLoopTimedOutErr)
+ {
+ if (err == eventLoopQuitErr)
+ err = noErr;
+ break;
+ }
+ }
}
if (err == noErr)
{
UInt32 command_id = GetWRefCon (window);
- if ((command_id & ~0xffff) == 'Bt\0\0')
- result = command_id - 'Bt\0\0';
+ if (DIALOG_BUTTON_COMMAND_ID_P (command_id))
+ result = DIALOG_BUTTON_COMMAND_ID_VALUE (command_id);
}
- if (window)
- DisposeWindow (window);
+ unbind_to (specpdl_count, Qnil);
return result;
}
@@ -2724,8 +2791,8 @@ mac_dialog (widget_value *wv)
int i;
int dialog_width;
Rect rect;
- WindowPtr window_ptr;
- ControlHandle ch;
+ WindowRef window_ptr;
+ ControlRef ch;
int left;
EventRecord event_record;
SInt16 part_code;
@@ -2754,7 +2821,7 @@ mac_dialog (widget_value *wv)
wv = wv->next;
}
- window_ptr = GetNewCWindow (DIALOG_WINDOW_RESOURCE, NULL, (WindowPtr) -1);
+ window_ptr = GetNewCWindow (DIALOG_WINDOW_RESOURCE, NULL, (WindowRef) -1);
SetPortWindowPort (window_ptr);
@@ -3031,7 +3098,7 @@ name_is_separator (name)
static void
add_menu_item (menu, pos, wv)
- MenuHandle menu;
+ MenuRef menu;
int pos;
widget_value *wv;
{
@@ -3108,7 +3175,7 @@ add_menu_item (menu, pos, wv)
static int
fill_menu (menu, wv, kind, submenu_id)
- MenuHandle menu;
+ MenuRef menu;
widget_value *wv;
enum mac_menu_kind kind;
int submenu_id;
@@ -3120,7 +3187,7 @@ fill_menu (menu, wv, kind, submenu_id)
add_menu_item (menu, pos, wv);
if (wv->contents && submenu_id < min_menu_id[kind + 1])
{
- MenuHandle submenu = NewMenu (submenu_id, "\pX");
+ MenuRef submenu = NewMenu (submenu_id, "\pX");
InsertMenu (submenu, -1);
SetMenuItemHierarchicalID (menu, pos, submenu_id);
@@ -3139,8 +3206,6 @@ fill_menubar (wv, deep_p)
int deep_p;
{
int id, submenu_id;
- MenuHandle menu;
- Str255 title;
#if !TARGET_API_MAC_CARBON
int title_changed_p = 0;
#endif
@@ -3162,45 +3227,75 @@ fill_menubar (wv, deep_p)
wv != NULL && id < min_menu_id[MAC_MENU_MENU_BAR + 1];
wv = wv->next, id++)
{
+ OSStatus err = noErr;
+ MenuRef menu;
+#if TARGET_API_MAC_CARBON
+ CFStringRef title;
+
+ title = CFStringCreateWithCString (NULL, wv->name,
+ kCFStringEncodingMacRoman);
+#else
+ Str255 title;
+
strncpy (title, wv->name, 255);
title[255] = '\0';
c2pstr (title);
+#endif
- menu = GetMenuHandle (id);
+ menu = GetMenuRef (id);
if (menu)
{
#if TARGET_API_MAC_CARBON
- Str255 old_title;
+ CFStringRef old_title;
- GetMenuTitle (menu, old_title);
- if (!EqualString (title, old_title, false, false))
- SetMenuTitle (menu, title);
+ err = CopyMenuTitleAsCFString (menu, &old_title);
+ if (err == noErr)
+ {
+ if (CFStringCompare (title, old_title, 0) != kCFCompareEqualTo)
+ err = SetMenuTitleWithCFString (menu, title);
+ CFRelease (old_title);
+ }
+ else
+ err = SetMenuTitleWithCFString (menu, title);
#else /* !TARGET_API_MAC_CARBON */
if (!EqualString (title, (*menu)->menuData, false, false))
{
DeleteMenu (id);
DisposeMenu (menu);
menu = NewMenu (id, title);
- InsertMenu (menu, GetMenuHandle (id + 1) ? id + 1 : 0);
+ InsertMenu (menu, GetMenuRef (id + 1) ? id + 1 : 0);
title_changed_p = 1;
}
#endif /* !TARGET_API_MAC_CARBON */
}
else
{
+#if TARGET_API_MAC_CARBON
+ err = CreateNewMenu (id, 0, &menu);
+ if (err == noErr)
+ err = SetMenuTitleWithCFString (menu, title);
+#else
menu = NewMenu (id, title);
- InsertMenu (menu, 0);
+#endif
+ if (err == noErr)
+ {
+ InsertMenu (menu, 0);
#if !TARGET_API_MAC_CARBON
- title_changed_p = 1;
+ title_changed_p = 1;
#endif
+ }
}
+#if TARGET_API_MAC_CARBON
+ CFRelease (title);
+#endif
- if (wv->contents)
- submenu_id = fill_menu (menu, wv->contents, MAC_MENU_MENU_BAR_SUB,
- submenu_id);
+ if (err == noErr)
+ if (wv->contents)
+ submenu_id = fill_menu (menu, wv->contents, MAC_MENU_MENU_BAR_SUB,
+ submenu_id);
}
- if (id < min_menu_id[MAC_MENU_MENU_BAR + 1] && GetMenuHandle (id))
+ if (id < min_menu_id[MAC_MENU_MENU_BAR + 1] && GetMenuRef (id))
{
dispose_menus (MAC_MENU_MENU_BAR, id);
#if !TARGET_API_MAC_CARBON
@@ -3224,7 +3319,7 @@ dispose_menus (kind, id)
{
for (id = max (id, min_menu_id[kind]); id < min_menu_id[kind + 1]; id++)
{
- MenuHandle menu = GetMenuHandle (id);
+ MenuRef menu = GetMenuRef (id);
if (menu == NULL)
break;
@@ -3249,9 +3344,13 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
doc: /* Return t if a menu or popup dialog is active. */)
()
{
+#if TARGET_API_MAC_CARBON
+ return (popup_activated ()) ? Qt : Qnil;
+#else
/* Always return Qnil since menu selection functions do not return
until a selection has been made or cancelled. */
return Qnil;
+#endif
}
void
diff --git a/src/macselect.c b/src/macselect.c
index 5bd91a68582..04034c499b7 100644
--- a/src/macselect.c
+++ b/src/macselect.c
@@ -1623,16 +1623,19 @@ remove_drag_handler (window)
Services menu support
***********************************************************************/
#ifdef MAC_OSX
-void
-init_service_handler ()
+OSStatus
+install_service_handler ()
{
static const EventTypeSpec specs[] =
{{kEventClassService, kEventServiceGetTypes},
{kEventClassService, kEventServiceCopy},
{kEventClassService, kEventServicePaste},
{kEventClassService, kEventServicePerform}};
- InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event),
- GetEventTypeCount (specs), specs, NULL, NULL);
+
+ return InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_service_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
}
extern OSStatus mac_store_service_event P_ ((EventRef));
diff --git a/src/macterm.c b/src/macterm.c
index 87a9861934c..1fd4ee308b1 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -35,12 +35,7 @@ Boston, MA 02110-1301, USA. */
#include <alloca.h>
#endif
-#if TARGET_API_MAC_CARBON
-/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
- obtain events from the event queue. If set to 0, WaitNextEvent is
- used instead. */
-#define USE_CARBON_EVENTS 1
-#else /* not TARGET_API_MAC_CARBON */
+#if !TARGET_API_MAC_CARBON
#include <Quickdraw.h>
#include <ToolUtils.h>
#include <Sound.h>
@@ -263,7 +258,7 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
Lisp_Object *, Lisp_Object *,
unsigned long *));
-static int is_emacs_window P_ ((WindowPtr));
+static int is_emacs_window P_ ((WindowRef));
static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
static void XSetFont P_ ((Display *, GC, XFontStruct *));
@@ -416,7 +411,8 @@ mac_prepare_for_quickdraw (f)
static RgnHandle saved_port_clip_region = NULL;
static void
-mac_begin_clip (gc)
+mac_begin_clip (f, gc)
+ struct frame *f;
GC gc;
{
static RgnHandle new_region = NULL;
@@ -426,6 +422,11 @@ mac_begin_clip (gc)
if (new_region == NULL)
new_region = NewRgn ();
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ SetPortWindowPort (FRAME_MAC_WINDOW (f));
+
if (gc->n_clip_rects)
{
GetClip (saved_port_clip_region);
@@ -445,15 +446,6 @@ mac_end_clip (gc)
/* X display function emulation */
-void
-XFreePixmap (display, pixmap)
- Display *display; /* not used */
- Pixmap pixmap;
-{
- DisposeGWorld (pixmap);
-}
-
-
/* Mac version of XDrawLine. */
static void
@@ -495,11 +487,8 @@ mac_draw_line (f, gc, x1, y1, x2, y2)
x2--;
}
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
-
- mac_begin_clip (gc);
MoveTo (x1, y1);
LineTo (x2, y2);
mac_end_clip (gc);
@@ -555,25 +544,25 @@ mac_erase_rectangle (f, gc, x, y, width, height)
unsigned int width, height;
{
#if USE_CG_DRAWING
- CGContextRef context;
+ {
+ CGContextRef context;
- context = mac_begin_cg_clip (f, gc);
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect (context, CGRectMake (x, y, width, height));
- mac_end_cg_clip (f);
+ context = mac_begin_cg_clip (f, gc);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+ CGContextFillRect (context, CGRectMake (x, y, width, height));
+ mac_end_cg_clip (f);
+ }
#else
- Rect r;
-
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- RGBBackColor (GC_BACK_COLOR (gc));
- SetRect (&r, x, y, x + width, y + height);
-
- mac_begin_clip (gc);
- EraseRect (&r);
- mac_end_clip (gc);
+ {
+ Rect r;
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ mac_begin_clip (f, gc);
+ RGBBackColor (GC_BACK_COLOR (gc));
+ SetRect (&r, x, y, x + width, y + height);
+ EraseRect (&r);
+ RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ mac_end_clip (gc);
+ }
#endif
}
@@ -596,15 +585,17 @@ mac_clear_window (f)
struct frame *f;
{
#if USE_CG_DRAWING
- CGContextRef context;
- GC gc = FRAME_NORMAL_GC (f);
-
- context = mac_begin_cg_clip (f, NULL);
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
- FRAME_PIXEL_HEIGHT (f)));
- mac_end_cg_clip (f);
-#else
+ {
+ CGContextRef context;
+ GC gc = FRAME_NORMAL_GC (f);
+
+ context = mac_begin_cg_clip (f, NULL);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+ CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
+ FRAME_PIXEL_HEIGHT (f)));
+ mac_end_cg_clip (f);
+ }
+#else /* !USE_CG_DRAWING */
SetPortWindowPort (FRAME_MAC_WINDOW (f));
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
@@ -678,13 +669,10 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p)
bitmap.baseAddr = (char *)bits;
SetRect (&(bitmap.bounds), 0, 0, width, height);
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
RGBBackColor (GC_BACK_COLOR (gc));
SetRect (&r, x, y, x + width, y + height);
-
- mac_begin_clip (gc);
#if TARGET_API_MAC_CARBON
{
CGrafPtr port;
@@ -699,9 +687,8 @@ mac_draw_bitmap (f, gc, x, y, width, height, bits, overlay_p)
CopyBits (&bitmap, &(FRAME_MAC_WINDOW (f)->portBits), &(bitmap.bounds), &r,
overlay_p ? srcOr : srcCopy, 0);
#endif /* not TARGET_API_MAC_CARBON */
- mac_end_clip (gc);
-
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ mac_end_clip (gc);
}
#endif /* !USE_CG_DRAWING */
@@ -752,8 +739,8 @@ mac_free_bitmap (bitmap)
Pixmap
XCreatePixmap (display, w, width, height, depth)
- Display *display; /* not used */
- WindowPtr w;
+ Display *display;
+ WindowRef w;
unsigned int width, height;
unsigned int depth;
{
@@ -781,8 +768,8 @@ XCreatePixmap (display, w, width, height, depth)
Pixmap
XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
- Display *display; /* not used */
- WindowPtr w;
+ Display *display;
+ WindowRef w;
char *data;
unsigned int width, height;
unsigned long fg, bg;
@@ -792,7 +779,7 @@ XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
BitMap bitmap;
CGrafPtr old_port;
GDHandle old_gdh;
- static GC gc = NULL; /* not reentrant */
+ static GC gc = NULL;
if (gc == NULL)
gc = XCreateGC (display, w, 0, NULL);
@@ -824,6 +811,15 @@ XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
}
+void
+XFreePixmap (display, pixmap)
+ Display *display;
+ Pixmap pixmap;
+{
+ DisposeGWorld (pixmap);
+}
+
+
/* Mac replacement for XFillRectangle. */
static void
@@ -843,12 +839,9 @@ mac_fill_rectangle (f, gc, x, y, width, height)
#else
Rect r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
SetRect (&r, x, y, x + width, y + height);
-
- mac_begin_clip (gc);
PaintRect (&r); /* using foreground color of gc */
mac_end_clip (gc);
#endif
@@ -875,18 +868,34 @@ mac_draw_rectangle (f, gc, x, y, width, height)
#else
Rect r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+ mac_begin_clip (f, gc);
RGBForeColor (GC_FORE_COLOR (gc));
SetRect (&r, x, y, x + width + 1, y + height + 1);
-
- mac_begin_clip (gc);
FrameRect (&r); /* using foreground color of gc */
mac_end_clip (gc);
#endif
}
+static void
+mac_invert_rectangle (f, x, y, width, height)
+ struct frame *f;
+ int x, y;
+ unsigned int width, height;
+{
+ Rect r;
+
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ SetPortWindowPort (FRAME_MAC_WINDOW (f));
+
+ SetRect (&r, x, y, x + width, y + height);
+
+ InvertRect (&r);
+}
+
+
#if USE_ATSUI
static OSStatus
atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
@@ -896,7 +905,7 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
ATSUTextLayout *text_layout;
{
OSStatus err;
- static ATSUTextLayout saved_text_layout = NULL; /* not reentrant */
+ static ATSUTextLayout saved_text_layout = NULL;
if (saved_text_layout == NULL)
{
@@ -923,7 +932,6 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
err = ATSUSetLayoutControls (saved_text_layout,
sizeof (tags) / sizeof (tags[0]),
tags, sizes, values);
- /* XXX: Should we do this? */
if (err == noErr)
err = ATSUSetTransientFontMatching (saved_text_layout, true);
}
@@ -942,224 +950,224 @@ atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
*text_layout = saved_text_layout;
return err;
}
-#endif
static void
-mac_invert_rectangle (f, x, y, width, height)
- struct frame *f;
- int x, y;
- unsigned int width, height;
-{
- Rect r;
-
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
-#endif
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- SetRect (&r, x, y, x + width, y + height);
-
- InvertRect (&r);
-}
-
-
-static void
-mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
- overstrike_p, bytes_per_char)
+mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char)
struct frame *f;
GC gc;
int x, y;
char *buf;
int nchars, bg_width, overstrike_p, bytes_per_char;
{
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-#if USE_ATSUI
- if (GC_FONT (gc)->mac_style)
- {
- OSStatus err;
- ATSUTextLayout text_layout;
+ OSStatus err;
+ ATSUTextLayout text_layout;
- xassert (bytes_per_char == 2);
+ xassert (bytes_per_char == 2);
#ifndef WORDS_BIG_ENDIAN
- {
- int i;
- UniChar *text = (UniChar *)buf;
+ {
+ int i;
+ UniChar *text = (UniChar *)buf;
- for (i = 0; i < nchars; i++)
- text[i] = EndianU16_BtoN (text[i]);
- }
+ for (i = 0; i < nchars; i++)
+ text[i] = EndianU16_BtoN (text[i]);
+ }
#endif
- err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
- nchars,
- GC_FONT (gc)->mac_style,
- &text_layout);
- if (err != noErr)
- return;
+ err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
+ nchars,
+ GC_FONT (gc)->mac_style,
+ &text_layout);
+ if (err != noErr)
+ return;
#ifdef MAC_OSX
- if (!mac_use_core_graphics)
- {
-#endif
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
+ if (!mac_use_core_graphics)
+ {
#endif
- mac_begin_clip (gc);
- RGBForeColor (GC_FORE_COLOR (gc));
- if (bg_width)
- {
- Rect r;
+ mac_begin_clip (f, gc);
+ RGBForeColor (GC_FORE_COLOR (gc));
+ if (bg_width)
+ {
+ Rect r;
- SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
- x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
- RGBBackColor (GC_BACK_COLOR (gc));
- EraseRect (&r);
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- }
- MoveTo (x, y);
+ SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+ x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+ RGBBackColor (GC_BACK_COLOR (gc));
+ EraseRect (&r);
+ RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ }
+ MoveTo (x, y);
+ ATSUDrawText (text_layout,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+ if (overstrike_p)
+ {
+ MoveTo (x + 1, y);
ATSUDrawText (text_layout,
kATSUFromTextBeginning, kATSUToTextEnd,
kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
- if (overstrike_p)
- {
- MoveTo (x + 1, y);
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
- }
- mac_end_clip (gc);
-#ifdef MAC_OSX
}
- else
- {
- CGrafPtr port;
- static CGContextRef context;
- float port_height = FRAME_PIXEL_HEIGHT (f);
- static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
- static const ByteCount sizes[] = {sizeof (CGContextRef)};
- static const ATSUAttributeValuePtr values[] = {&context};
+ mac_end_clip (gc);
+#ifdef MAC_OSX
+ }
+ else
+ {
+ static CGContextRef context;
+ float port_height = FRAME_PIXEL_HEIGHT (f);
+ static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
+ static const ByteCount sizes[] = {sizeof (CGContextRef)};
+ static const ATSUAttributeValuePtr values[] = {&context};
#if USE_CG_DRAWING
- context = mac_begin_cg_clip (f, gc);
+ context = mac_begin_cg_clip (f, gc);
#else
- GetPort (&port);
- QDBeginCGContext (port, &context);
- if (gc->n_clip_rects || bg_width)
- {
- CGContextTranslateCTM (context, 0, port_height);
- CGContextScaleCTM (context, 1, -1);
- if (gc->n_clip_rects)
- CGContextClipToRects (context, gc->clip_rects,
- gc->n_clip_rects);
-#endif
- if (bg_width)
- {
- CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
- CGContextFillRect
- (context,
- CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
- bg_width, FONT_HEIGHT (GC_FONT (gc))));
- }
- CGContextScaleCTM (context, 1, -1);
- CGContextTranslateCTM (context, 0, -port_height);
-#if !USE_CG_DRAWING
- }
+ CGrafPtr port;
+
+ GetPort (&port);
+ QDBeginCGContext (port, &context);
+ if (gc->n_clip_rects || bg_width)
+ {
+ CGContextTranslateCTM (context, 0, port_height);
+ CGContextScaleCTM (context, 1, -1);
+ if (gc->n_clip_rects)
+ CGContextClipToRects (context, gc->clip_rects,
+ gc->n_clip_rects);
#endif
- CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
- err = ATSUSetLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
- if (err == noErr)
+ if (bg_width)
{
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- Long2Fix (x), Long2Fix (port_height - y));
- if (overstrike_p)
- ATSUDrawText (text_layout,
- kATSUFromTextBeginning, kATSUToTextEnd,
- Long2Fix (x + 1), Long2Fix (port_height - y));
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+ CGContextFillRect (context,
+ CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
+ bg_width,
+ FONT_HEIGHT (GC_FONT (gc))));
}
+ CGContextScaleCTM (context, 1, -1);
+ CGContextTranslateCTM (context, 0, -port_height);
+#if !USE_CG_DRAWING
+ }
+#endif
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
+ err = ATSUSetLayoutControls (text_layout,
+ sizeof (tags) / sizeof (tags[0]),
+ tags, sizes, values);
+ if (err == noErr)
+ {
+ ATSUDrawText (text_layout,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ Long2Fix (x), Long2Fix (port_height - y));
+ if (overstrike_p)
+ ATSUDrawText (text_layout,
+ kATSUFromTextBeginning, kATSUToTextEnd,
+ Long2Fix (x + 1), Long2Fix (port_height - y));
+ }
#if USE_CG_DRAWING
- mac_end_cg_clip (f);
- context = NULL;
+ mac_end_cg_clip (f);
+ context = NULL;
#else
- CGContextSynchronize (context);
- QDEndCGContext (port, &context);
+ CGContextSynchronize (context);
+ QDEndCGContext (port, &context);
#endif
#if 0
- /* This doesn't work on Mac OS X 10.1. */
- ATSUClearLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]), tags);
+ /* This doesn't work on Mac OS X 10.1. */
+ ATSUClearLayoutControls (text_layout,
+ sizeof (tags) / sizeof (tags[0]), tags);
#else
- ATSUSetLayoutControls (text_layout,
- sizeof (tags) / sizeof (tags[0]),
- tags, sizes, values);
+ ATSUSetLayoutControls (text_layout,
+ sizeof (tags) / sizeof (tags[0]),
+ tags, sizes, values);
#endif
- }
-#endif /* MAC_OSX */
}
- else
+#endif /* MAC_OSX */
+}
#endif /* USE_ATSUI */
- {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- UInt32 savedFlags;
- if (mac_use_core_graphics)
- savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
+
+static void
+mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char)
+ struct frame *f;
+ GC gc;
+ int x, y;
+ char *buf;
+ int nchars, bg_width, overstrike_p, bytes_per_char;
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ UInt32 savedFlags;
#endif
-#if USE_CG_DRAWING
- mac_prepare_for_quickdraw (f);
+
+ mac_begin_clip (f, gc);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ if (mac_use_core_graphics)
+ savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
#endif
- mac_begin_clip (gc);
- RGBForeColor (GC_FORE_COLOR (gc));
+ RGBForeColor (GC_FORE_COLOR (gc));
#ifdef MAC_OS8
- if (bg_width)
- {
- RGBBackColor (GC_BACK_COLOR (gc));
- TextMode (srcCopy);
- }
- else
- TextMode (srcOr);
+ if (bg_width)
+ {
+ RGBBackColor (GC_BACK_COLOR (gc));
+ TextMode (srcCopy);
+ }
+ else
+ TextMode (srcOr);
#else
- /* We prefer not to use srcCopy text transfer mode on Mac OS X
- because:
- - Screen is double-buffered. (In srcCopy mode, a text is
- drawn into an offscreen graphics world first. So
- performance gain cannot be expected.)
- - It lowers rendering quality.
- - Some fonts leave garbage on cursor movement. */
- if (bg_width)
- {
- Rect r;
+ /* We prefer not to use srcCopy text transfer mode on Mac OS X
+ because:
+ - Screen is double-buffered. (In srcCopy mode, a text is drawn
+ into an offscreen graphics world first. So performance gain
+ cannot be expected.)
+ - It lowers rendering quality.
+ - Some fonts leave garbage on cursor movement. */
+ if (bg_width)
+ {
+ Rect r;
- RGBBackColor (GC_BACK_COLOR (gc));
- SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
- x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
- EraseRect (&r);
- }
- TextMode (srcOr);
+ RGBBackColor (GC_BACK_COLOR (gc));
+ SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+ x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+ EraseRect (&r);
+ }
+ TextMode (srcOr);
#endif
- TextFont (GC_FONT (gc)->mac_fontnum);
- TextSize (GC_FONT (gc)->mac_fontsize);
- TextFace (GC_FONT (gc)->mac_fontface);
- MoveTo (x, y);
+ TextFont (GC_FONT (gc)->mac_fontnum);
+ TextSize (GC_FONT (gc)->mac_fontsize);
+ TextFace (GC_FONT (gc)->mac_fontface);
+ MoveTo (x, y);
+ DrawText (buf, 0, nchars * bytes_per_char);
+ if (overstrike_p)
+ {
+ TextMode (srcOr);
+ MoveTo (x + 1, y);
DrawText (buf, 0, nchars * bytes_per_char);
- if (overstrike_p)
- {
- TextMode (srcOr);
- MoveTo (x + 1, y);
- DrawText (buf, 0, nchars * bytes_per_char);
- }
- if (bg_width)
- RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
- mac_end_clip (gc);
+ }
+ if (bg_width)
+ RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+ mac_end_clip (gc);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- if (mac_use_core_graphics)
- SwapQDTextFlags(savedFlags);
+ if (mac_use_core_graphics)
+ SwapQDTextFlags(savedFlags);
#endif
- }
+}
+
+
+static INLINE void
+mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char)
+ struct frame *f;
+ GC gc;
+ int x, y;
+ char *buf;
+ int nchars, bg_width, overstrike_p, bytes_per_char;
+{
+#if USE_ATSUI
+ if (GC_FONT (gc)->mac_style)
+ mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char);
+ else
+#endif /* USE_ATSUI */
+ mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+ overstrike_p, bytes_per_char);
}
@@ -1376,7 +1384,6 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
XChar2b *buf;
int nchars, bg_width, overstrike_p;
{
- CGrafPtr port;
float port_height, gx, gy;
int i;
CGContextRef context;
@@ -1386,7 +1393,6 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
if (!mac_use_core_graphics || GC_FONT (gc)->cg_font == NULL)
return 0;
- port = GetWindowPort (FRAME_MAC_WINDOW (f));
port_height = FRAME_PIXEL_HEIGHT (f);
gx = x;
gy = port_height - y;
@@ -1407,7 +1413,7 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
#if USE_CG_DRAWING
context = mac_begin_cg_clip (f, gc);
#else
- QDBeginCGContext (port, &context);
+ QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
if (gc->n_clip_rects || bg_width)
{
CGContextTranslateCTM (context, 0, port_height);
@@ -1447,7 +1453,7 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
}
}
#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
- else
+ else /* CGContextShowGlyphsWithAdvances == NULL */
#endif
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
@@ -1465,7 +1471,7 @@ mac_draw_image_string_cg (f, gc, x, y, buf, nchars, bg_width, overstrike_p)
mac_end_cg_clip (f);
#else
CGContextSynchronize (context);
- QDEndCGContext (port, &context);
+ QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
#endif
return 1;
@@ -1487,7 +1493,7 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
{
Rect src_r, dest_r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ mac_begin_clip (f, gc);
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -1495,7 +1501,6 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
ForeColor (blackColor);
BackColor (whiteColor);
- mac_begin_clip (gc);
LockPixels (GetGWorldPixMap (src));
#if TARGET_API_MAC_CARBON
{
@@ -1513,9 +1518,10 @@ mac_copy_area (src, f, gc, src_x, src_y, width, height, dest_x, dest_y)
&src_r, &dest_r, srcCopy, 0);
#endif /* not TARGET_API_MAC_CARBON */
UnlockPixels (GetGWorldPixMap (src));
- mac_end_clip (gc);
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+ mac_end_clip (gc);
}
@@ -1531,7 +1537,7 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
{
Rect src_r, dest_r;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ mac_begin_clip (f, gc);
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -1539,7 +1545,6 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
ForeColor (blackColor);
BackColor (whiteColor);
- mac_begin_clip (gc);
LockPixels (GetGWorldPixMap (src));
LockPixels (GetGWorldPixMap (mask));
#if TARGET_API_MAC_CARBON
@@ -1559,9 +1564,10 @@ mac_copy_area_with_mask (src, mask, f, gc, src_x, src_y,
#endif /* not TARGET_API_MAC_CARBON */
UnlockPixels (GetGWorldPixMap (mask));
UnlockPixels (GetGWorldPixMap (src));
- mac_end_clip (gc);
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+ mac_end_clip (gc);
}
#endif /* !USE_CG_DRAWING */
@@ -1590,9 +1596,9 @@ mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
DisposeRgn (dummy);
#else /* not TARGET_API_MAC_CARBON */
Rect src_r, dest_r;
- WindowPtr w = FRAME_MAC_WINDOW (f);
+ WindowRef w = FRAME_MAC_WINDOW (f);
- SetPort (w);
+ mac_begin_clip (f, gc);
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -1601,11 +1607,11 @@ mac_scroll_area (f, gc, src_x, src_y, width, height, dest_x, dest_y)
color mapping in CopyBits. Otherwise, it will be slow. */
ForeColor (blackColor);
BackColor (whiteColor);
- mac_begin_clip (gc);
CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
- mac_end_clip (gc);
RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+ mac_end_clip (gc);
#endif /* not TARGET_API_MAC_CARBON */
}
@@ -1850,7 +1856,7 @@ mac_reset_clip_rectangles (display, gc)
void
XSetWindowBackground (display, w, color)
Display *display;
- WindowPtr w;
+ WindowRef w;
unsigned long color;
{
#if !TARGET_API_MAC_CARBON
@@ -2188,6 +2194,81 @@ x_draw_fringe_bitmap (w, row, p)
Display *display = FRAME_MAC_DISPLAY (f);
struct face *face = p->face;
int rowY;
+ int overlay_p = p->overlay_p;
+
+#ifdef MAC_OSX
+ if (!overlay_p)
+ {
+ int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
+
+#if 0 /* MAC_TODO: stipple */
+ /* In case the same realized face is used for fringes and
+ for something displayed in the text (e.g. face `region' on
+ mono-displays, the fill style may have been changed to
+ FillSolid in x_draw_glyph_string_background. */
+ if (face->stipple)
+ XSetFillStyle (FRAME_X_DISPLAY (f), face->gc, FillOpaqueStippled);
+ else
+ XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->background);
+#endif
+
+ /* If the fringe is adjacent to the left (right) scroll bar of a
+ leftmost (rightmost, respectively) window, then extend its
+ background to the gap between the fringe and the bar. */
+ if ((WINDOW_LEFTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ || (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
+ {
+ int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+
+ if (sb_width > 0)
+ {
+ int left = WINDOW_SCROLL_BAR_AREA_X (w);
+ int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
+ * FRAME_COLUMN_WIDTH (f));
+
+ if (bx < 0
+ && (left + width == p->x
+ || p->x + p->wd == left))
+ {
+ /* Bitmap fills the fringe and we need background
+ extension. */
+ int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+
+ bx = p->x;
+ nx = p->wd;
+ by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+ row->y));
+ ny = row->visible_height;
+ }
+
+ if (bx >= 0)
+ {
+ if (left + width == bx)
+ {
+ bx = left + sb_width;
+ nx += width - sb_width;
+ }
+ else if (bx + nx == left)
+ nx += width - sb_width;
+ }
+ }
+ }
+
+ if (bx >= 0)
+ {
+ mac_erase_rectangle (f, face->gc, bx, by, nx, ny);
+ /* The fringe background has already been filled. */
+ overlay_p = 1;
+ }
+
+#if 0 /* MAC_TODO: stipple */
+ if (!face->stipple)
+ XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
+#endif
+ }
+#endif /* MAC_OSX */
/* Must clip because of partially visible lines. */
rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
@@ -2206,6 +2287,7 @@ x_draw_fringe_bitmap (w, row, p)
else
x_clip_to_row (w, row, -1, face->gc);
+#ifndef MAC_OSX
if (p->bx >= 0 && !p->overlay_p)
{
#if 0 /* MAC_TODO: stipple */
@@ -2226,6 +2308,7 @@ x_draw_fringe_bitmap (w, row, p)
XSetForeground (FRAME_X_DISPLAY (f), face->gc, face->foreground);
#endif
}
+#endif /* !MAC_OSX */
if (p->which
#if USE_CG_DRAWING
@@ -2243,10 +2326,10 @@ x_draw_fringe_bitmap (w, row, p)
: face->foreground));
#if USE_CG_DRAWING
mac_draw_cg_image (fringe_bmp[p->which], f, face->gc, 0, p->dh,
- p->wd, p->h, p->x, p->y, p->overlay_p);
+ p->wd, p->h, p->x, p->y, overlay_p);
#else
mac_draw_bitmap (f, face->gc, p->x, p->y,
- p->wd, p->h, p->bits + p->dh, p->overlay_p);
+ p->wd, p->h, p->bits + p->dh, overlay_p);
#endif
XSetForeground (display, face->gc, gcv.foreground);
}
@@ -4373,7 +4456,7 @@ x_detect_focus_change (dpyinfo, event, bufp)
{
struct frame *frame;
- frame = mac_window_to_frame ((WindowPtr) event->message);
+ frame = mac_window_to_frame ((WindowRef) event->message);
if (! frame)
return;
@@ -4613,8 +4696,14 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
the frame are divided into. */
Point mouse_pos;
+#if TARGET_API_MAC_CARBON
+ GetGlobalMouse (&mouse_pos);
+ mouse_pos.h -= f1->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f1);
+ mouse_pos.v -= f1->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f1);
+#else
SetPortWindowPort (FRAME_MAC_WINDOW (f1));
GetMouse (&mouse_pos);
+#endif
remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v,
&last_mouse_glyph);
last_mouse_glyph_frame = f1;
@@ -4644,14 +4733,14 @@ static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval));
static int control_part_code_to_scroll_bar_part P_ ((ControlPartCode));
static void construct_scroll_bar_click P_ ((struct scroll_bar *, int,
struct input_event *));
-static OSStatus get_control_part_bounds P_ ((ControlHandle, ControlPartCode,
+static OSStatus get_control_part_bounds P_ ((ControlRef, ControlPartCode,
Rect *));
static void x_scroll_bar_handle_press P_ ((struct scroll_bar *,
ControlPartCode, Point,
struct input_event *));
static void x_scroll_bar_handle_release P_ ((struct scroll_bar *,
struct input_event *));
-static void x_scroll_bar_handle_drag P_ ((WindowPtr, struct scroll_bar *,
+static void x_scroll_bar_handle_drag P_ ((WindowRef, struct scroll_bar *,
Point, struct input_event *));
static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
int, int, int));
@@ -4744,7 +4833,7 @@ construct_scroll_bar_click (bar, part, bufp)
static OSStatus
get_control_part_bounds (ch, part_code, rect)
- ControlHandle ch;
+ ControlRef ch;
ControlPartCode part_code;
Rect *rect;
{
@@ -4774,7 +4863,7 @@ x_scroll_bar_handle_press (bar, part_code, mouse_pos, bufp)
if (part != scroll_bar_handle)
{
construct_scroll_bar_click (bar, part, bufp);
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code);
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY);
bar->dragging = Qnil;
}
@@ -4782,7 +4871,7 @@ x_scroll_bar_handle_press (bar, part_code, mouse_pos, bufp)
{
Rect r;
- get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar),
+ get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
kControlIndicatorPart, &r);
XSETINT (bar->dragging, - (mouse_pos.v - r.top) - 1);
}
@@ -4800,7 +4889,7 @@ x_scroll_bar_handle_release (bar, bufp)
|| (INTEGERP (bar->dragging) && XINT (bar->dragging) >= 0))
construct_scroll_bar_click (bar, scroll_bar_end_scroll, bufp);
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0);
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
set_scroll_bar_timer (kEventDurationForever);
last_scroll_bar_part = -1;
@@ -4810,19 +4899,19 @@ x_scroll_bar_handle_release (bar, bufp)
static void
x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
- WindowPtr win;
+ WindowRef win;
struct scroll_bar *bar;
Point mouse_pos;
struct input_event *bufp;
{
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
if (last_scroll_bar_part == scroll_bar_handle)
{
int top, top_range;
Rect r;
- get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar),
+ get_control_part_bounds (SCROLL_BAR_CONTROL_REF (bar),
kControlIndicatorPart, &r);
if (INTEGERP (bar->dragging) && XINT (bar->dragging) < 0)
@@ -4870,13 +4959,13 @@ x_scroll_bar_handle_drag (win, bar, mouse_pos, bufp)
}
if (unhilite_p)
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0);
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), 0);
else if (part != last_scroll_bar_part
|| scroll_bar_timer_event_posted_p)
{
construct_scroll_bar_click (bar, part, bufp);
last_scroll_bar_part = part;
- HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code);
+ HiliteControl (SCROLL_BAR_CONTROL_REF (bar), part_code);
set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY);
}
}
@@ -4890,7 +4979,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
struct scroll_bar *bar;
int portion, position, whole;
{
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
int value, viewsize, maximum;
if (XINT (bar->track_height) == 0)
@@ -4949,7 +5038,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
struct scroll_bar *bar
= XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
Rect r;
- ControlHandle ch;
+ ControlRef ch;
BLOCK_INPUT;
@@ -4973,7 +5062,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", width < disp_height,
0, 0, 0, scrollBarProc, (long) bar);
#endif
- SET_SCROLL_BAR_CONTROL_HANDLE (bar, ch);
+ SET_SCROLL_BAR_CONTROL_REF (bar, ch);
XSETWINDOW (bar->window, w);
XSETINT (bar->top, top);
@@ -4983,6 +5072,9 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height)
XSETINT (bar->start, 0);
XSETINT (bar->end, 0);
bar->dragging = Qnil;
+#ifdef MAC_OSX
+ bar->fringe_extended_p = Qnil;
+#endif
#ifdef USE_TOOLKIT_SCROLL_BARS
bar->track_top = Qnil;
bar->track_height = Qnil;
@@ -5023,7 +5115,7 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
int rebuild;
{
int dragging = ! NILP (bar->dragging);
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
int length = end - start;
@@ -5092,7 +5184,7 @@ x_scroll_bar_remove (bar)
mac_prepare_for_quickdraw (f);
#endif
/* Destroy the Mac scroll bar control */
- DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar));
+ DisposeControl (SCROLL_BAR_CONTROL_REF (bar));
/* Disassociate this scroll bar from its window. */
XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
@@ -5115,6 +5207,9 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
struct scroll_bar *bar;
int top, height, left, sb_left, width, sb_width, disp_top, disp_height;
int window_y, window_height;
+#ifdef MAC_OSX
+ int fringe_extended_p;
+#endif
/* Get window dimensions. */
window_box (w, -1, 0, &window_y, 0, &window_height);
@@ -5134,9 +5229,9 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
/* Compute the left edge of the scroll bar. */
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
- sb_left = left;
+ sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
else
- sb_left = left + width - sb_width;
+ sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
/* Adjustments according to Inside Macintosh to make it look nice */
disp_top = top;
@@ -5157,11 +5252,29 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
sb_left++;
#endif
+#ifdef MAC_OSX
+ if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ fringe_extended_p = (WINDOW_LEFTMOST_P (w)
+ && WINDOW_LEFT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_LEFT_MARGIN_COLS (w) == 0));
+ else
+ fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_RIGHT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+#endif
+
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
{
BLOCK_INPUT;
- mac_clear_area (f, left, top, width, height);
+#ifdef MAC_OSX
+ if (fringe_extended_p)
+ mac_clear_area (f, sb_left, top, sb_width, height);
+ else
+#endif
+ mac_clear_area (f, left, top, width, height);
UNBLOCK_INPUT;
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height, disp_top,
disp_height);
@@ -5170,10 +5283,10 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
else
{
/* It may just need to be moved and resized. */
- ControlHandle ch;
+ ControlRef ch;
bar = XSCROLL_BAR (w->vertical_scroll_bar);
- ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+ ch = SCROLL_BAR_CONTROL_REF (bar);
BLOCK_INPUT;
@@ -5181,11 +5294,20 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
if (!(XINT (bar->left) == sb_left
&& XINT (bar->top) == top
&& XINT (bar->width) == sb_width
- && XINT (bar->height) == height))
+ && XINT (bar->height) == height
+#ifdef MAC_OSX
+ && !NILP (bar->fringe_extended_p) == fringe_extended_p
+#endif
+ ))
{
/* Since toolkit scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
- mac_clear_area (f, left, top, width, height);
+#ifdef MAC_OSX
+ if (fringe_extended_p)
+ mac_clear_area (f, sb_left, top, sb_width, height);
+ else
+#endif
+ mac_clear_area (f, left, top, width, height);
#if USE_CG_DRAWING
mac_prepare_for_quickdraw (f);
@@ -5214,6 +5336,10 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
UNBLOCK_INPUT;
}
+#ifdef MAC_OSX
+ bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+#endif
+
#ifdef USE_TOOLKIT_SCROLL_BARS
if (NILP (bar->track_top))
{
@@ -5229,7 +5355,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
}
else
{
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
Rect r0, r1;
BLOCK_INPUT;
@@ -5506,19 +5632,24 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
unsigned long *time;
{
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
- ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+ ControlRef ch = SCROLL_BAR_CONTROL_REF (bar);
#if TARGET_API_MAC_CARBON
- WindowPtr wp = GetControlOwner (ch);
+ WindowRef wp = GetControlOwner (ch);
#else
- WindowPtr wp = (*ch)->contrlOwner;
+ WindowRef wp = (*ch)->contrlOwner;
#endif
Point mouse_pos;
struct frame *f = mac_window_to_frame (wp);
int win_y, top_range;
+#if TARGET_API_MAC_CARBON
+ GetGlobalMouse (&mouse_pos);
+ mouse_pos.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ mouse_pos.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+#else
SetPortWindowPort (wp);
-
GetMouse (&mouse_pos);
+#endif
win_y = mouse_pos.v - XINT (bar->top);
top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
@@ -5572,6 +5703,539 @@ x_scroll_bar_clear (f)
/***********************************************************************
+ Tool-bars
+ ***********************************************************************/
+#if USE_MAC_TOOLBAR
+
+/* In identifiers such as function/variable names, Emacs tool bar is
+ referred to as `tool_bar', and Carbon HIToolbar as `toolbar'. */
+
+#define TOOLBAR_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar"))
+#define TOOLBAR_ICON_ITEM_IDENTIFIER (CFSTR ("org.gnu.Emacs.toolbar.icon"))
+
+#define TOOLBAR_ITEM_COMMAND_ID_OFFSET 'Tb\0\0'
+#define TOOLBAR_ITEM_COMMAND_ID_P(id) \
+ (((id) & ~0xffff) == TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+#define TOOLBAR_ITEM_COMMAND_ID_VALUE(id) \
+ ((id) - TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+#define TOOLBAR_ITEM_MAKE_COMMAND_ID(value) \
+ ((value) + TOOLBAR_ITEM_COMMAND_ID_OFFSET)
+
+static int mac_event_to_emacs_modifiers P_ ((EventRef));
+static void mac_handle_origin_change P_ ((struct frame *));
+static OSStatus mac_handle_toolbar_command_event P_ ((EventHandlerCallRef,
+ EventRef, void *));
+
+static void
+mac_move_window_with_gravity (f, win_gravity, left, top)
+ struct frame *f;
+ int win_gravity;
+ short left, top;
+{
+ Rect inner, outer;
+
+ mac_get_window_bounds (f, &inner, &outer);
+
+ switch (win_gravity)
+ {
+ case NorthWestGravity:
+ case WestGravity:
+ case SouthWestGravity:
+ left += inner.left - outer.left;
+ break;
+
+ case NorthGravity:
+ case CenterGravity:
+ case SouthGravity:
+ left += ((inner.left - outer.left) + (inner.right - outer.right)) / 2;
+ break;
+
+ case NorthEastGravity:
+ case EastGravity:
+ case SouthEastGravity:
+ left += inner.right - outer.right;
+ break;
+ }
+
+ switch (win_gravity)
+ {
+ case NorthWestGravity:
+ case NorthGravity:
+ case NorthEastGravity:
+ top += inner.top - outer.top;
+ break;
+
+ case WestGravity:
+ case CenterGravity:
+ case EastGravity:
+ top += ((inner.top - outer.top) + (inner.bottom - outer.bottom)) / 2;
+ break;
+
+ case SouthWestGravity:
+ case SouthGravity:
+ case SouthEastGravity:
+ top += inner.bottom - outer.bottom;
+ break;
+ }
+
+ MoveWindow (FRAME_MAC_WINDOW (f), left, top, false);
+}
+
+static void
+mac_get_window_origin_with_gravity (f, win_gravity, left, top)
+ struct frame *f;
+ int win_gravity;
+ short *left, *top;
+{
+ Rect inner, outer;
+
+ mac_get_window_bounds (f, &inner, &outer);
+
+ switch (win_gravity)
+ {
+ case NorthWestGravity:
+ case WestGravity:
+ case SouthWestGravity:
+ *left = outer.left;
+ break;
+
+ case NorthGravity:
+ case CenterGravity:
+ case SouthGravity:
+ *left = outer.left + ((outer.right - outer.left)
+ - (inner.right - inner.left)) / 2;
+ break;
+
+ case NorthEastGravity:
+ case EastGravity:
+ case SouthEastGravity:
+ *left = outer.right - (inner.right - inner.left);
+ break;
+ }
+
+ switch (win_gravity)
+ {
+ case NorthWestGravity:
+ case NorthGravity:
+ case NorthEastGravity:
+ *top = outer.top;
+ break;
+
+ case WestGravity:
+ case CenterGravity:
+ case EastGravity:
+ *top = outer.top + ((outer.bottom - outer.top)
+ - (inner.bottom - inner.top)) / 2;
+ break;
+
+ case SouthWestGravity:
+ case SouthGravity:
+ case SouthEastGravity:
+ *top = outer.bottom - (inner.bottom - inner.top);
+ break;
+ }
+}
+
+static OSStatus
+mac_handle_toolbar_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+
+ switch (GetEventKind (event))
+ {
+ case kEventToolbarGetDefaultIdentifiers:
+ result = noErr;
+ break;
+
+ case kEventToolbarGetAllowedIdentifiers:
+ {
+ CFMutableArrayRef array;
+
+ GetEventParameter (event, kEventParamMutableArray,
+ typeCFMutableArrayRef, NULL,
+ sizeof (CFMutableArrayRef), NULL, &array);
+ CFArrayAppendValue (array, TOOLBAR_ICON_ITEM_IDENTIFIER);
+ result = noErr;
+ }
+ break;
+
+ case kEventToolbarCreateItemWithIdentifier:
+ {
+ CFStringRef identifier;
+ HIToolbarItemRef item = NULL;
+
+ GetEventParameter (event, kEventParamToolbarItemIdentifier,
+ typeCFStringRef, NULL,
+ sizeof (CFStringRef), NULL, &identifier);
+
+ if (CFStringCompare (identifier, TOOLBAR_ICON_ITEM_IDENTIFIER, 0)
+ == kCFCompareEqualTo)
+ HIToolbarItemCreate (identifier,
+ kHIToolbarItemAllowDuplicates
+ | kHIToolbarItemCantBeRemoved, &item);
+
+ if (item)
+ {
+ SetEventParameter (event, kEventParamToolbarItem,
+ typeHIToolbarItemRef,
+ sizeof (HIToolbarItemRef), &item);
+ result = noErr;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+
+static CGImageRef
+mac_image_spec_to_cg_image (f, image)
+ struct frame *f;
+ Lisp_Object image;
+{
+ if (!valid_image_p (image))
+ return NULL;
+ else
+ {
+ int img_id = lookup_image (f, image);
+ struct image *img = IMAGE_FROM_ID (f, img_id);
+
+ prepare_image_for_display (f, img);
+
+ return img->data.ptr_val;
+ }
+}
+
+/* Create a tool bar for frame F. */
+
+static OSStatus
+mac_create_frame_tool_bar (f)
+ FRAME_PTR f;
+{
+ OSStatus err;
+ HIToolbarRef toolbar;
+
+ err = HIToolbarCreate (TOOLBAR_IDENTIFIER, kHIToolbarNoAttributes,
+ &toolbar);
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassToolbar, kEventToolbarGetDefaultIdentifiers},
+ {kEventClassToolbar, kEventToolbarGetAllowedIdentifiers},
+ {kEventClassToolbar, kEventToolbarCreateItemWithIdentifier}};
+
+ err = InstallEventHandler (HIObjectGetEventTarget (toolbar),
+ mac_handle_toolbar_event,
+ GetEventTypeCount (specs), specs,
+ f, NULL);
+ }
+
+ if (err == noErr)
+ err = HIToolbarSetDisplayMode (toolbar, kHIToolbarDisplayModeIconOnly);
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassCommand, kEventCommandProcess}};
+
+ err = InstallWindowEventHandler (FRAME_MAC_WINDOW (f),
+ mac_handle_toolbar_command_event,
+ GetEventTypeCount (specs),
+ specs, f, NULL);
+ }
+ if (err == noErr)
+ err = SetWindowToolbar (FRAME_MAC_WINDOW (f), toolbar);
+
+ if (toolbar)
+ CFRelease (toolbar);
+
+ return err;
+}
+
+/* Update the tool bar for frame F. Add new buttons and remove old. */
+
+void
+update_frame_tool_bar (f)
+ FRAME_PTR f;
+{
+ HIToolbarRef toolbar = NULL;
+ short left, top;
+ CFArrayRef old_items = NULL;
+ CFIndex old_count;
+ int i, pos, win_gravity = f->output_data.mac->toolbar_win_gravity;
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+ BLOCK_INPUT;
+
+ GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
+ if (toolbar == NULL)
+ {
+ mac_create_frame_tool_bar (f);
+ GetWindowToolbar (FRAME_MAC_WINDOW (f), &toolbar);
+ if (toolbar == NULL)
+ goto out;
+ if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
+ mac_get_window_origin_with_gravity (f, win_gravity, &left, &top);
+ }
+
+ HIToolbarCopyItems (toolbar, &old_items);
+ if (old_items == NULL)
+ goto out;
+
+ old_count = CFArrayGetCount (old_items);
+ pos = 0;
+ for (i = 0; i < f->n_tool_bar_items; ++i)
+ {
+#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
+
+ int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
+ int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
+ int idx;
+ Lisp_Object image;
+ CGImageRef cg_image;
+ CFStringRef label;
+ HIToolbarItemRef item;
+
+ /* If image is a vector, choose the image according to the
+ button state. */
+ image = PROP (TOOL_BAR_ITEM_IMAGES);
+ if (VECTORP (image))
+ {
+ if (enabled_p)
+ idx = (selected_p
+ ? TOOL_BAR_IMAGE_ENABLED_SELECTED
+ : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
+ else
+ idx = (selected_p
+ ? TOOL_BAR_IMAGE_DISABLED_SELECTED
+ : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
+
+ xassert (ASIZE (image) >= idx);
+ image = AREF (image, idx);
+ }
+ else
+ idx = -1;
+
+ cg_image = mac_image_spec_to_cg_image (f, image);
+ /* Ignore invalid image specifications. */
+ if (cg_image == NULL)
+ continue;
+
+ label = cfstring_create_with_string (PROP (TOOL_BAR_ITEM_CAPTION));
+ if (label == NULL)
+ label = CFSTR ("");
+
+ if (pos < old_count)
+ {
+ CGImageRef old_cg_image = NULL;
+ CFStringRef old_label = NULL;
+ Boolean old_enabled_p;
+
+ item = (HIToolbarItemRef) CFArrayGetValueAtIndex (old_items, pos);
+
+ HIToolbarItemCopyImage (item, &old_cg_image);
+ if (cg_image != old_cg_image)
+ HIToolbarItemSetImage (item, cg_image);
+ CGImageRelease (old_cg_image);
+
+ HIToolbarItemCopyLabel (item, &old_label);
+ if (CFStringCompare (label, old_label, 0) != kCFCompareEqualTo)
+ HIToolbarItemSetLabel (item, label);
+ CFRelease (old_label);
+
+ old_enabled_p = HIToolbarItemIsEnabled (item);
+ if ((enabled_p || idx >= 0) != old_enabled_p)
+ HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
+ }
+ else
+ {
+ item = NULL;
+ HIToolbarCreateItemWithIdentifier (toolbar,
+ TOOLBAR_ICON_ITEM_IDENTIFIER,
+ NULL, &item);
+ if (item)
+ {
+ HIToolbarItemSetImage (item, cg_image);
+ HIToolbarItemSetLabel (item, label);
+ HIToolbarItemSetEnabled (item, (enabled_p || idx >= 0));
+ HIToolbarAppendItem (toolbar, item);
+ CFRelease (item);
+ }
+ }
+
+ CFRelease (label);
+ if (item)
+ {
+ HIToolbarItemSetCommandID (item, TOOLBAR_ITEM_MAKE_COMMAND_ID (i));
+ pos++;
+ }
+ }
+
+ CFRelease (old_items);
+
+ while (pos < old_count)
+ HIToolbarRemoveItemAtIndex (toolbar, --old_count);
+
+ ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), true,
+ !win_gravity && f == mac_focus_frame (dpyinfo));
+ /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events on
+ toolbar visibility change. */
+ mac_handle_origin_change (f);
+ if (win_gravity >= NorthWestGravity && win_gravity <= SouthEastGravity)
+ {
+ mac_move_window_with_gravity (f, win_gravity, left, top);
+ /* If the title bar is completely outside the screen, adjust the
+ position. */
+ ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
+ kWindowConstrainMoveRegardlessOfFit
+ | kWindowConstrainAllowPartial, NULL, NULL);
+ f->output_data.mac->toolbar_win_gravity = 0;
+ }
+
+ out:
+ UNBLOCK_INPUT;
+}
+
+/* Hide the tool bar on frame F. Unlike the counterpart on GTK+, it
+ doesn't deallocate the resources. */
+
+void
+free_frame_tool_bar (f)
+ FRAME_PTR f;
+{
+ if (IsWindowToolbarVisible (FRAME_MAC_WINDOW (f)))
+ {
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+ BLOCK_INPUT;
+ ShowHideWindowToolbar (FRAME_MAC_WINDOW (f), false,
+ f == mac_focus_frame (dpyinfo));
+ /* Mac OS X 10.3 does not issue kEventWindowBoundsChanged events
+ on toolbar visibility change. */
+ mac_handle_origin_change (f);
+ UNBLOCK_INPUT;
+ }
+}
+
+static void
+mac_tool_bar_note_mouse_movement (f, event)
+ struct frame *f;
+ EventRef event;
+{
+ OSStatus err;
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+ int mouse_down_p;
+ HIViewRef item_view;
+ UInt32 command_id;
+
+ mouse_down_p = (dpyinfo->grabbed
+ && f == last_mouse_frame
+ && FRAME_LIVE_P (f));
+ if (mouse_down_p)
+ return;
+
+ err = HIViewGetViewForMouseEvent (HIViewGetRoot (FRAME_MAC_WINDOW (f)),
+ event, &item_view);
+ /* This doesn't work on Mac OS X 10.2. On Mac OS X 10.3 and 10.4, a
+ toolbar item view seems to have the same command ID with that of
+ the toolbar item. */
+ if (err == noErr)
+ err = GetControlCommandID (item_view, &command_id);
+ if (err == noErr && TOOLBAR_ITEM_COMMAND_ID_P (command_id))
+ {
+ int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command_id);
+
+ if (i < f->n_tool_bar_items)
+ {
+ HIRect bounds;
+ HIViewRef content_view;
+
+ err = HIViewGetBounds (item_view, &bounds);
+ if (err == noErr)
+ err = HIViewFindByID (HIViewGetRoot (FRAME_MAC_WINDOW (f)),
+ kHIViewWindowContentID, &content_view);
+ if (err == noErr)
+ err = HIViewConvertRect (&bounds, item_view, content_view);
+ if (err == noErr)
+ SetRect (&last_mouse_glyph,
+ CGRectGetMinX (bounds), CGRectGetMinY (bounds),
+ CGRectGetMaxX (bounds), CGRectGetMaxY (bounds));
+
+ help_echo_object = help_echo_window = Qnil;
+ help_echo_pos = -1;
+ help_echo_string = PROP (TOOL_BAR_ITEM_HELP);
+ if (NILP (help_echo_string))
+ help_echo_string = PROP (TOOL_BAR_ITEM_CAPTION);
+ }
+ }
+}
+
+static OSStatus
+mac_handle_toolbar_command_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+ struct frame *f = (struct frame *) data;
+ HICommand command;
+
+ err = GetEventParameter (event, kEventParamDirectObject,
+ typeHICommand, NULL,
+ sizeof (HICommand), NULL, &command);
+ if (err != noErr)
+ return result;
+
+ switch (GetEventKind (event))
+ {
+ case kEventCommandProcess:
+ if (!TOOLBAR_ITEM_COMMAND_ID_P (command.commandID))
+ result = CallNextEventHandler (next_handler, event);
+ else
+ {
+ int i = TOOLBAR_ITEM_COMMAND_ID_VALUE (command.commandID);
+
+ if (i < f->n_tool_bar_items
+ && !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)))
+ {
+ Lisp_Object frame;
+ struct input_event buf;
+
+ EVENT_INIT (buf);
+
+ XSETFRAME (frame, f);
+ buf.kind = TOOL_BAR_EVENT;
+ buf.frame_or_window = frame;
+ buf.arg = frame;
+ kbd_buffer_store_event (&buf);
+
+ buf.kind = TOOL_BAR_EVENT;
+ buf.frame_or_window = frame;
+ buf.arg = PROP (TOOL_BAR_ITEM_KEY);
+ buf.modifiers = mac_event_to_emacs_modifiers (event);
+ kbd_buffer_store_event (&buf);
+
+ result = noErr;
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+#undef PROP
+
+ return result;
+}
+#endif /* USE_MAC_TOOLBAR */
+
+
+/***********************************************************************
Text Cursor
***********************************************************************/
@@ -6146,9 +6810,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
kWindowConstrainMoveRegardlessOfFit
| kWindowConstrainAllowPartial, NULL, NULL);
-#if USE_CARBON_EVENTS
if (!NILP (tip_frame) && XFRAME (tip_frame) == f)
-#endif
mac_handle_origin_change (f);
#else
{
@@ -6224,7 +6886,7 @@ x_set_window_size (f, change_gravity, cols, rows)
SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
if (!NILP (tip_frame) && f == XFRAME (tip_frame))
#endif
mac_handle_size_change (f, pixelwidth, pixelheight);
@@ -6271,17 +6933,11 @@ x_set_mouse_pixel_position (f, pix_x, pix_y)
int pix_x, pix_y;
{
#ifdef MAC_OSX
- Point p;
- CGPoint point;
+ pix_x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ pix_y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
BLOCK_INPUT;
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
- p.h = pix_x;
- p.v = pix_y;
- LocalToGlobal (&p);
- point.x = p.h;
- point.y = p.v;
- CGWarpMouseCursorPosition (point);
+ CGWarpMouseCursorPosition (CGPointMake (pix_x, pix_y));
UNBLOCK_INPUT;
#else
#if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
@@ -6363,7 +7019,7 @@ static void
mac_handle_visibility_change (f)
struct frame *f;
{
- WindowPtr wp = FRAME_MAC_WINDOW (f);
+ WindowRef wp = FRAME_MAC_WINDOW (f);
int visible = 0, iconified = 0;
struct input_event buf;
@@ -6431,32 +7087,7 @@ x_make_frame_visible (f)
before the window gets really visible. */
if (! FRAME_ICONIFIED_P (f)
&& ! f->output_data.mac->asked_for_visible)
- {
-#if TARGET_API_MAC_CARBON
- if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition)))
- {
- struct frame *sf = SELECTED_FRAME ();
- if (!FRAME_MAC_P (sf))
- RepositionWindow (FRAME_MAC_WINDOW (f), NULL,
- kWindowCenterOnMainScreen);
- else
- RepositionWindow (FRAME_MAC_WINDOW (f),
- FRAME_MAC_WINDOW (sf),
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- kWindowCascadeStartAtParentWindowScreen
-#else
- kWindowCascadeOnParentWindowScreen
-#endif
- );
-#if USE_CARBON_EVENTS
- if (!NILP (tip_frame) && f == XFRAME (tip_frame))
-#endif
- mac_handle_origin_change (f);
- }
- else
-#endif
- x_set_offset (f, f->left_pos, f->top_pos, 0);
- }
+ x_set_offset (f, f->left_pos, f->top_pos, 0);
f->output_data.mac->asked_for_visible = 1;
@@ -6530,18 +7161,20 @@ x_make_frame_invisible (f)
BLOCK_INPUT;
+#if !TARGET_API_MAC_CARBON
/* Before unmapping the window, update the WM_SIZE_HINTS property to claim
that the current position of the window is user-specified, rather than
program-specified, so that when the window is mapped again, it will be
placed at the same location, without forcing the user to position it
by hand again (they have already done that once for this window.) */
x_wm_set_size_hint (f, (long) 0, 1);
+#endif
HideWindow (FRAME_MAC_WINDOW (f));
UNBLOCK_INPUT;
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
mac_handle_visibility_change (f);
#endif
}
@@ -6580,7 +7213,7 @@ x_iconify_frame (f)
if (err != noErr)
error ("Can't notify window manager of iconification");
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
mac_handle_visibility_change (f);
#endif
}
@@ -6593,7 +7226,7 @@ x_free_frame_resources (f)
struct frame *f;
{
struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- WindowPtr wp = FRAME_MAC_WINDOW (f);
+ WindowRef wp = FRAME_MAC_WINDOW (f);
BLOCK_INPUT;
@@ -8728,16 +9361,93 @@ x_find_ccl_program (fontp)
possible. */
static int font_panel_shown_p = 0;
+extern Lisp_Object Qfont;
+static Lisp_Object Qpanel_closed, Qselection;
+
+static OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID,
+ Lisp_Object,
+ Lisp_Object,
+ EventRef, UInt32,
+ const EventParamName *,
+ const EventParamType *));
+
int
mac_font_panel_visible_p ()
{
return font_panel_shown_p && FPIsFontPanelVisible ();
}
+static pascal OSStatus
+mac_handle_font_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus result, err;
+ Lisp_Object id_key;
+ int num_params;
+ const EventParamName *names;
+ const EventParamType *types;
+ static const EventParamName names_sel[] = {kEventParamATSUFontID,
+ kEventParamATSUFontSize,
+ kEventParamFMFontFamily,
+ kEventParamFMFontSize,
+ kEventParamFontColor};
+ static const EventParamType types_sel[] = {typeATSUFontID,
+ typeATSUSize,
+ typeFMFontFamily,
+ typeFMFontSize,
+ typeFontColor};
+
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ return result;
+
+ switch (GetEventKind (event))
+ {
+ case kEventFontPanelClosed:
+ id_key = Qpanel_closed;
+ num_params = 0;
+ names = NULL;
+ types = NULL;
+ break;
+
+ case kEventFontSelection:
+ id_key = Qselection;
+ num_params = sizeof (names_sel) / sizeof (names_sel[0]);
+ names = names_sel;
+ types = types_sel;
+ break;
+ }
+
+ err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
+ event, num_params,
+ names, types);
+ if (err == noErr)
+ result = noErr;
+
+ return result;
+}
+
OSStatus
mac_show_hide_font_panel ()
{
- font_panel_shown_p = 1;
+ if (!font_panel_shown_p)
+ {
+ OSStatus err;
+
+ static const EventTypeSpec specs[] =
+ {{kEventClassFont, kEventFontPanelClosed},
+ {kEventClassFont, kEventFontSelection}};
+
+ err = InstallApplicationEventHandler (mac_handle_font_event,
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ if (err != noErr)
+ return err;
+
+ font_panel_shown_p = 1;
+ }
return FPShowHideFontPanel ();
}
@@ -8853,7 +9563,7 @@ Lisp_Object Vmac_function_modifier;
a three button mouse */
Lisp_Object Vmac_emulate_three_button_mouse;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
/* Non-zero if the mouse wheel button (i.e. button 4) should map to
mouse-2, instead of mouse-3. */
int mac_wheel_button_is_mouse_2;
@@ -8878,16 +9588,12 @@ static int mac_screen_config_changed = 0;
Point saved_menu_event_location;
/* Apple Events */
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
static Lisp_Object Qhi_command;
#ifdef MAC_OSX
extern Lisp_Object Qwindow;
static Lisp_Object Qtoolbar_switch_mode;
#endif
-#if USE_MAC_FONT_PANEL
-extern Lisp_Object Qfont;
-static Lisp_Object Qpanel_closed, Qselection;
-#endif
#if USE_MAC_TSM
static TSMDocumentID tsm_document_id;
static Lisp_Object Qtext_input;
@@ -8899,7 +9605,7 @@ static Lisp_Object saved_ts_script_language_on_focus;
static ScriptLanguageRecord saved_ts_language;
static Component saved_ts_component;
#endif
-#endif
+#endif /* TARGET_API_MAC_CARBON */
extern int mac_ready_for_apple_events;
extern Lisp_Object Qundefined;
extern void init_apple_event_handler P_ ((void));
@@ -8912,20 +9618,15 @@ extern OSErr init_coercion_handler P_ ((void));
extern OSErr install_drag_handler P_ ((WindowRef));
extern void remove_drag_handler P_ ((WindowRef));
+#if TARGET_API_MAC_CARBON
/* Showing help echo string during menu tracking */
-extern OSStatus install_menu_target_item_handler P_ ((WindowPtr));
+extern OSStatus install_menu_target_item_handler P_ ((void));
-#if USE_CARBON_EVENTS
#ifdef MAC_OSX
-extern void init_service_handler ();
+extern OSStatus install_service_handler ();
static Lisp_Object Qservice, Qpaste, Qperform;
#endif
-
-/* Window Event Handler */
-static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
- EventRef, void *);
#endif
-OSStatus install_window_handler (WindowPtr);
extern void init_emacs_passwd_dir ();
extern int emacs_main (int, char **, char **);
@@ -9009,7 +9710,7 @@ static const unsigned char fn_keycode_to_keycode_table[] = {
#endif /* MAC_OSX */
static int
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
mac_to_emacs_modifiers (UInt32 mods)
#else
mac_to_emacs_modifiers (EventModifiers mods)
@@ -9118,17 +9819,19 @@ mac_quit_char_key_p (modifiers, key_code)
}
#endif
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
/* Obtains the event modifiers from the event ref and then calls
mac_to_emacs_modifiers. */
static int
mac_event_to_emacs_modifiers (EventRef eventRef)
{
- UInt32 mods = 0;
+ UInt32 mods = 0, class;
+
GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
sizeof (UInt32), NULL, &mods);
+ class = GetEventClass (eventRef);
if (!NILP (Vmac_emulate_three_button_mouse) &&
- GetEventClass(eventRef) == kEventClassMouse)
+ (class == kEventClassMouse || class == kEventClassCommand))
{
mods &= ~(optionKey | cmdKey);
}
@@ -9267,7 +9970,7 @@ static void
do_get_menus (void)
{
Handle menubar_handle;
- MenuHandle menu_handle;
+ MenuRef menu;
menubar_handle = GetNewMBar (128);
if(menubar_handle == NULL)
@@ -9276,9 +9979,9 @@ do_get_menus (void)
DrawMenuBar ();
#if !TARGET_API_MAC_CARBON
- menu_handle = GetMenuHandle (M_APPLE);
- if(menu_handle != NULL)
- AppendResMenu (menu_handle,'DRVR');
+ menu = GetMenuRef (M_APPLE);
+ if (menu != NULL)
+ AppendResMenu (menu, 'DRVR');
else
abort ();
#endif
@@ -9327,7 +10030,7 @@ do_check_ram_size (void)
#endif /* MAC_OS8 */
static void
-do_window_update (WindowPtr win)
+do_window_update (WindowRef win)
{
struct frame *f = mac_window_to_frame (win);
@@ -9372,7 +10075,7 @@ do_window_update (WindowPtr win)
}
static int
-is_emacs_window (WindowPtr win)
+is_emacs_window (WindowRef win)
{
Lisp_Object tail, frame;
@@ -9485,7 +10188,7 @@ do_apple_menu (SInt16 menu_item)
NoteAlert (ABOUT_ALERT_ID, NULL);
else
{
- GetMenuItemText (GetMenuHandle (M_APPLE), menu_item, item_name);
+ GetMenuItemText (GetMenuRef (M_APPLE), menu_item, item_name);
da_driver_refnum = OpenDeskAcc (item_name);
}
}
@@ -9496,7 +10199,7 @@ do_apple_menu (SInt16 menu_item)
static void
do_grow_window (w, e)
- WindowPtr w;
+ WindowRef w;
const EventRecord *e;
{
Rect limit_rect;
@@ -9548,7 +10251,7 @@ mac_get_ideal_size (f)
struct frame *f;
{
struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- WindowPtr w = FRAME_MAC_WINDOW (f);
+ WindowRef w = FRAME_MAC_WINDOW (f);
Point ideal_size;
Rect standard_rect;
int height, width, columns, rows;
@@ -9574,7 +10277,7 @@ mac_get_ideal_size (f)
wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
static void
-do_zoom_window (WindowPtr w, int zoom_in_or_out)
+do_zoom_window (WindowRef w, int zoom_in_or_out)
{
Rect zoom_rect, port_rect;
int width, height;
@@ -9637,13 +10340,9 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
SetPort (save_port);
#endif /* not TARGET_API_MAC_CARBON */
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
/* retrieve window size and update application values */
-#if TARGET_API_MAC_CARBON
- GetWindowPortBounds (w, &port_rect);
-#else
port_rect = w->portRect;
-#endif
height = port_rect.bottom - port_rect.top;
width = port_rect.right - port_rect.left;
@@ -9652,6 +10351,210 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out)
#endif
}
+static void
+mac_set_unicode_keystroke_event (code, buf)
+ UniChar code;
+ struct input_event *buf;
+{
+ int charset_id, c1, c2;
+
+ if (code < 0x80)
+ {
+ buf->kind = ASCII_KEYSTROKE_EVENT;
+ buf->code = code;
+ }
+ else if (code < 0x100)
+ {
+ if (code < 0xA0)
+ charset_id = CHARSET_8_BIT_CONTROL;
+ else
+ charset_id = charset_latin_iso8859_1;
+ buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ buf->code = MAKE_CHAR (charset_id, code, 0);
+ }
+ else
+ {
+ if (code < 0x2500)
+ charset_id = charset_mule_unicode_0100_24ff,
+ code -= 0x100;
+ else if (code < 0x33FF)
+ charset_id = charset_mule_unicode_2500_33ff,
+ code -= 0x2500;
+ else if (code >= 0xE000)
+ charset_id = charset_mule_unicode_e000_ffff,
+ code -= 0xE000;
+ c1 = (code / 96) + 32, c2 = (code % 96) + 32;
+ buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ buf->code = MAKE_CHAR (charset_id, c1, c2);
+ }
+}
+
+static void
+do_keystroke (action, char_code, key_code, modifiers, timestamp, buf)
+ EventKind action;
+ unsigned char char_code;
+ UInt32 key_code, modifiers;
+ unsigned long timestamp;
+ struct input_event *buf;
+{
+ static SInt16 last_key_script = -1;
+ SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
+ UInt32 mapped_modifiers = mac_mapped_modifiers (modifiers);
+
+#ifdef MAC_OSX
+ if (mapped_modifiers & kEventKeyModifierFnMask
+ && key_code <= 0x7f
+ && fn_keycode_to_keycode_table[key_code])
+ key_code = fn_keycode_to_keycode_table[key_code];
+#endif
+
+ if (key_code <= 0x7f && keycode_to_xkeysym_table[key_code])
+ {
+ buf->kind = NON_ASCII_KEYSTROKE_EVENT;
+ buf->code = 0xff00 | keycode_to_xkeysym_table[key_code];
+#ifdef MAC_OSX
+ if (modifiers & kEventKeyModifierFnMask
+ && key_code <= 0x7f
+ && fn_keycode_to_keycode_table[key_code] == key_code)
+ modifiers &= ~kEventKeyModifierFnMask;
+#endif
+ }
+ else if (mapped_modifiers)
+ {
+ /* translate the keycode back to determine the original key */
+#ifdef MAC_OSX
+ UCKeyboardLayout *uchr_ptr = NULL;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ OSStatus err;
+ KeyboardLayoutRef layout;
+
+ err = KLGetCurrentKeyboardLayout (&layout);
+ if (err == noErr)
+ err = KLGetKeyboardLayoutProperty (layout, kKLuchrData,
+ (const void **) &uchr_ptr);
+#else
+ static SInt16 last_key_layout_id = 0;
+ static Handle uchr_handle = (Handle)-1;
+ SInt16 current_key_layout_id =
+ GetScriptVariable (current_key_script, smScriptKeys);
+
+ if (uchr_handle == (Handle)-1
+ || last_key_layout_id != current_key_layout_id)
+ {
+ uchr_handle = GetResource ('uchr', current_key_layout_id);
+ last_key_layout_id = current_key_layout_id;
+ }
+ if (uchr_handle)
+ uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
+#endif
+
+ if (uchr_ptr)
+ {
+ OSStatus status;
+ UInt16 key_action = action - keyDown;
+ UInt32 modifier_key_state = (modifiers & ~mapped_modifiers) >> 8;
+ UInt32 keyboard_type = LMGetKbdType ();
+ SInt32 dead_key_state = 0;
+ UniChar code;
+ UniCharCount actual_length;
+
+ status = UCKeyTranslate (uchr_ptr, key_code, key_action,
+ modifier_key_state, keyboard_type,
+ kUCKeyTranslateNoDeadKeysMask,
+ &dead_key_state,
+ 1, &actual_length, &code);
+ if (status == noErr && actual_length == 1)
+ mac_set_unicode_keystroke_event (code, buf);
+ }
+#endif /* MAC_OSX */
+
+ if (buf->kind == NO_EVENT)
+ {
+ /* This code comes from Keyboard Resource, Appendix C of IM
+ - Text. This is necessary since shift is ignored in KCHR
+ table translation when option or command is pressed. It
+ also does not translate correctly control-shift chars
+ like C-% so mask off shift here also. */
+ /* Mask off modifier keys that are mapped to some Emacs
+ modifiers. */
+ int new_modifiers = modifiers & ~mapped_modifiers;
+ /* set high byte of keycode to modifier high byte*/
+ int new_key_code = key_code | new_modifiers;
+ Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+ unsigned long some_state = 0;
+ UInt32 new_char_code;
+
+ new_char_code = KeyTranslate (kchr_ptr, new_key_code, &some_state);
+ if (new_char_code == 0)
+ /* Seems like a dead key. Append up-stroke. */
+ new_char_code = KeyTranslate (kchr_ptr, new_key_code | 0x80,
+ &some_state);
+ if (new_char_code)
+ {
+ buf->kind = ASCII_KEYSTROKE_EVENT;
+ buf->code = new_char_code & 0xff;
+ }
+ }
+ }
+
+ if (buf->kind == NO_EVENT)
+ {
+ buf->kind = ASCII_KEYSTROKE_EVENT;
+ buf->code = char_code;
+ }
+
+ buf->modifiers = mac_to_emacs_modifiers (modifiers);
+ buf->modifiers |= (extra_keyboard_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
+
+#if TARGET_API_MAC_CARBON
+ if (buf->kind == ASCII_KEYSTROKE_EVENT
+ && buf->code >= 0x80 && buf->modifiers)
+ {
+ OSStatus err;
+ TextEncoding encoding = kTextEncodingMacRoman;
+ TextToUnicodeInfo ttu_info;
+
+ UpgradeScriptInfoToTextEncoding (current_key_script,
+ kTextLanguageDontCare,
+ kTextRegionDontCare,
+ NULL, &encoding);
+ err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
+ if (err == noErr)
+ {
+ UniChar code;
+ Str255 pstr;
+ ByteCount unicode_len;
+
+ pstr[0] = 1;
+ pstr[1] = buf->code;
+ err = ConvertFromPStringToUnicode (ttu_info, pstr,
+ sizeof (UniChar),
+ &unicode_len, &code);
+ if (err == noErr && unicode_len == sizeof (UniChar))
+ mac_set_unicode_keystroke_event (code, buf);
+ DisposeTextToUnicodeInfo (&ttu_info);
+ }
+ }
+#endif
+
+ if (buf->kind == ASCII_KEYSTROKE_EVENT
+ && buf->code >= 0x80
+ && last_key_script != current_key_script)
+ {
+ struct input_event event;
+
+ EVENT_INIT (event);
+ event.kind = LANGUAGE_CHANGE_EVENT;
+ event.arg = Qnil;
+ event.code = current_key_script;
+ event.timestamp = timestamp;
+ kbd_buffer_store_event (&event);
+ last_key_script = current_key_script;
+ }
+}
+
void
mac_store_apple_event (class, id, desc)
Lisp_Object class, id;
@@ -9730,54 +10633,49 @@ mac_store_drag_event (window, mouse_pos, modifiers, desc)
buf.arg = mac_aedesc_to_lisp (desc);
kbd_buffer_store_event (&buf);
}
-#endif
-#if USE_CARBON_EVENTS
-static pascal OSStatus
-mac_handle_command_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
+#ifdef MAC_OSX
+OSStatus
+mac_store_service_event (event)
EventRef event;
- void *data;
{
- OSStatus result, err;
- HICommand command;
- static const EventParamName names[] =
- {kEventParamDirectObject, kEventParamKeyModifiers};
- static const EventParamType types[] =
- {typeHICommand, typeUInt32};
- int num_params = sizeof (names) / sizeof (names[0]);
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
+ OSStatus err;
+ Lisp_Object id_key;
+ int num_params;
+ const EventParamName *names;
+ const EventParamType *types;
+ static const EventParamName names_pfm[] =
+ {kEventParamServiceMessageName, kEventParamServiceUserData};
+ static const EventParamType types_pfm[] =
+ {typeCFStringRef, typeCFStringRef};
- err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
- NULL, sizeof (HICommand), NULL, &command);
+ switch (GetEventKind (event))
+ {
+ case kEventServicePaste:
+ id_key = Qpaste;
+ num_params = 0;
+ names = NULL;
+ types = NULL;
+ break;
- if (err != noErr || command.commandID == 0)
- return eventNotHandledErr;
+ case kEventServicePerform:
+ id_key = Qperform;
+ num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
+ names = names_pfm;
+ types = types_pfm;
+ break;
- /* A HI command event is mapped to an Apple event whose event class
- symbol is `hi-command' and event ID is its command ID. */
- err = mac_store_event_ref_as_apple_event (0, command.commandID,
- Qhi_command, Qnil,
- event, num_params, names, types);
- return err == noErr ? noErr : eventNotHandledErr;
-}
+ default:
+ abort ();
+ }
-static OSStatus
-init_command_handler ()
-{
- static const EventTypeSpec specs[] =
- {{kEventClassCommand, kEventCommandProcess}};
- static EventHandlerUPP handle_command_eventUPP = NULL;
+ err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
+ event, num_params,
+ names, types);
- if (handle_command_eventUPP == NULL)
- handle_command_eventUPP = NewEventHandlerUPP (mac_handle_command_event);
- return InstallApplicationEventHandler (handle_command_eventUPP,
- GetEventTypeCount (specs), specs,
- NULL, NULL);
+ return err;
}
+#endif /* MAC_OSX */
static pascal OSStatus
mac_handle_window_event (next_handler, event, data)
@@ -9785,47 +10683,85 @@ mac_handle_window_event (next_handler, event, data)
EventRef event;
void *data;
{
- WindowPtr wp;
- OSStatus result, err;
+ WindowRef wp;
+ OSStatus err, result = eventNotHandledErr;
struct frame *f;
UInt32 attributes;
XSizeHints *size_hints;
err = GetEventParameter (event, kEventParamDirectObject, typeWindowRef,
- NULL, sizeof (WindowPtr), NULL, &wp);
+ NULL, sizeof (WindowRef), NULL, &wp);
if (err != noErr)
return eventNotHandledErr;
f = mac_window_to_frame (wp);
switch (GetEventKind (event))
{
+ /* -- window refresh events -- */
+
case kEventWindowUpdate:
result = CallNextEventHandler (next_handler, event);
if (result != eventNotHandledErr)
- return result;
+ break;
do_window_update (wp);
- return noErr;
+ result = noErr;
+ break;
- case kEventWindowGetIdealSize:
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
+ /* -- window state change events -- */
- {
- Point ideal_size = mac_get_ideal_size (f);
+ case kEventWindowShowing:
+ size_hints = FRAME_SIZE_HINTS (f);
+ if (!(size_hints->flags & (USPosition | PPosition)))
+ {
+ struct frame *sf = SELECTED_FRAME ();
- err = SetEventParameter (event, kEventParamDimensions,
- typeQDPoint, sizeof (Point), &ideal_size);
- if (err == noErr)
- return noErr;
- }
+ if (!(FRAME_MAC_P (sf)))
+ RepositionWindow (wp, NULL, kWindowCenterOnMainScreen);
+ else
+ {
+ RepositionWindow (wp, FRAME_MAC_WINDOW (sf),
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ kWindowCascadeStartAtParentWindowScreen
+#else
+ kWindowCascadeOnParentWindowScreen
+#endif
+ );
+#if USE_MAC_TOOLBAR
+ /* This is a workaround. RepositionWindow fails to put
+ a window at the cascading position when its parent
+ window has a Carbon HIToolbar. */
+ if (f->top_pos == sf->top_pos && f->left_pos == sf->left_pos)
+ MoveWindowStructure (wp, f->left_pos + 10, f->top_pos + 32);
+#endif
+ }
+ result = noErr;
+ }
+ break;
+
+ case kEventWindowHiding:
+ /* Before unmapping the window, update the WM_SIZE_HINTS
+ property to claim that the current position of the window is
+ user-specified, rather than program-specified, so that when
+ the window is mapped again, it will be placed at the same
+ location, without forcing the user to position it by hand
+ again (they have already done that once for this window.) */
+ x_wm_set_size_hint (f, (long) 0, 1);
+ result = noErr;
+ break;
+
+ case kEventWindowShown:
+ case kEventWindowHidden:
+ case kEventWindowCollapsed:
+ case kEventWindowExpanded:
+ mac_handle_visibility_change (f);
+ result = noErr;
break;
case kEventWindowBoundsChanging:
result = CallNextEventHandler (next_handler, event);
if (result != eventNotHandledErr)
- return result;
+ break;
err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
NULL, sizeof (UInt32), NULL, &attributes);
@@ -9869,7 +10805,7 @@ mac_handle_window_event (next_handler, event, data)
bounds.bottom = bounds.top + height;
SetEventParameter (event, kEventParamCurrentBounds,
typeQDRectangle, sizeof (Rect), &bounds);
- return noErr;
+ result = noErr;
}
break;
@@ -9900,21 +10836,12 @@ mac_handle_window_event (next_handler, event, data)
if (attributes & kWindowBoundsChangeOriginChanged)
mac_handle_origin_change (f);
- return noErr;
-
- case kEventWindowShown:
- case kEventWindowHidden:
- case kEventWindowExpanded:
- case kEventWindowCollapsed:
- result = CallNextEventHandler (next_handler, event);
-
- mac_handle_visibility_change (f);
- return noErr;
-
+ result = noErr;
break;
+ /* -- window action events -- */
+
case kEventWindowClose:
- result = CallNextEventHandler (next_handler, event);
{
struct input_event buf;
@@ -9924,11 +10851,26 @@ mac_handle_window_event (next_handler, event, data)
buf.arg = Qnil;
kbd_buffer_store_event (&buf);
}
- return noErr;
+ result = noErr;
+ break;
+
+ case kEventWindowGetIdealSize:
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ {
+ Point ideal_size = mac_get_ideal_size (f);
+
+ err = SetEventParameter (event, kEventParamDimensions,
+ typeQDPoint, sizeof (Point), &ideal_size);
+ if (err == noErr)
+ result = noErr;
+ }
+ break;
#ifdef MAC_OSX
case kEventWindowToolbarSwitchMode:
- result = CallNextEventHandler (next_handler, event);
{
static const EventParamName names[] = {kEventParamDirectObject,
kEventParamWindowMouseLocation,
@@ -9950,23 +10892,194 @@ mac_handle_window_event (next_handler, event, data)
event, num_params,
names, types);
}
- return err == noErr ? noErr : result;
+ if (err == noErr)
+ result = noErr;
+ break;
#endif
#if USE_MAC_TSM
+ /* -- window focus events -- */
+
case kEventWindowFocusAcquired:
- result = CallNextEventHandler (next_handler, event);
err = mac_tsm_resume ();
- return err == noErr ? noErr : result;
+ if (err == noErr)
+ result = noErr;
+ break;
case kEventWindowFocusRelinquish:
- result = CallNextEventHandler (next_handler, event);
err = mac_tsm_suspend ();
- return err == noErr ? noErr : result;
+ if (err == noErr)
+ result = noErr;
+ break;
#endif
+
+ default:
+ abort ();
}
- return eventNotHandledErr;
+ return result;
+}
+
+static pascal OSStatus
+mac_handle_application_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+
+ switch (GetEventKind (event))
+ {
+#if USE_MAC_TSM
+ case kEventAppActivated:
+ err = mac_tsm_resume ();
+ break;
+
+ case kEventAppDeactivated:
+ err = mac_tsm_suspend ();
+ break;
+#endif
+
+ default:
+ abort ();
+ }
+
+ if (err == noErr)
+ result = noErr;
+
+ return result;
+}
+
+static pascal OSStatus
+mac_handle_keyboard_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+ UInt32 event_kind, key_code, modifiers, mapped_modifiers;
+ unsigned char char_code;
+
+ event_kind = GetEventKind (event);
+ switch (event_kind)
+ {
+ case kEventRawKeyDown:
+ case kEventRawKeyRepeat:
+ case kEventRawKeyUp:
+ if (read_socket_inev == NULL)
+ {
+ result = CallNextEventHandler (next_handler, event);
+ break;
+ }
+
+ err = GetEventParameter (event, kEventParamKeyModifiers,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &modifiers);
+ if (err != noErr)
+ break;
+
+ mapped_modifiers = mac_mapped_modifiers (modifiers);
+
+ /* When using Carbon Events, we need to pass raw keyboard events
+ to the TSM ourselves. If TSM handles it, it will pass back
+ noErr, otherwise it will pass back "eventNotHandledErr" and
+ we can process it normally. */
+ if (!(mapped_modifiers
+ & ~(mac_pass_command_to_system ? cmdKey : 0)
+ & ~(mac_pass_control_to_system ? controlKey : 0)))
+ {
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+ }
+
+#if USE_MAC_TSM
+ if (read_socket_inev->kind != NO_EVENT)
+ {
+ result = noErr;
+ break;
+ }
+#endif
+
+ if (event_kind == kEventRawKeyUp)
+ break;
+
+ err = GetEventParameter (event, kEventParamKeyMacCharCodes,
+ typeChar, NULL,
+ sizeof (char), NULL, &char_code);
+ if (err != noErr)
+ break;
+
+ err = GetEventParameter (event, kEventParamKeyCode,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &key_code);
+ if (err != noErr)
+ break;
+
+ do_keystroke ((event_kind == kEventRawKeyDown ? keyDown : autoKey),
+ char_code, key_code, modifiers,
+ ((unsigned long)
+ (GetEventTime (event) / kEventDurationMillisecond)),
+ read_socket_inev);
+ result = noErr;
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
+}
+
+static pascal OSStatus
+mac_handle_command_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus err, result = eventNotHandledErr;
+ HICommand command;
+ static const EventParamName names[] =
+ {kEventParamDirectObject, kEventParamKeyModifiers};
+ static const EventParamType types[] =
+ {typeHICommand, typeUInt32};
+ int num_params = sizeof (names) / sizeof (names[0]);
+
+ err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
+ NULL, sizeof (HICommand), NULL, &command);
+ if (err != noErr)
+ return eventNotHandledErr;
+
+ switch (GetEventKind (event))
+ {
+ case kEventCommandProcess:
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ break;
+
+ err = GetEventParameter (event, kEventParamDirectObject,
+ typeHICommand, NULL,
+ sizeof (HICommand), NULL, &command);
+
+ if (err != noErr || command.commandID == 0)
+ break;
+
+ /* A HI command event is mapped to an Apple event whose event
+ class symbol is `hi-command' and event ID is its command
+ ID. */
+ err = mac_store_event_ref_as_apple_event (0, command.commandID,
+ Qhi_command, Qnil,
+ event, num_params,
+ names, types);
+ if (err == noErr)
+ result = noErr;
+ break;
+
+ default:
+ abort ();
+ }
+
+ return result;
}
static pascal OSStatus
@@ -9975,13 +11088,13 @@ mac_handle_mouse_event (next_handler, event, data)
EventRef event;
void *data;
{
- OSStatus result, err;
+ OSStatus err, result = eventNotHandledErr;
switch (GetEventKind (event))
{
case kEventMouseWheelMoved:
{
- WindowPtr wp;
+ WindowRef wp;
struct frame *f;
EventMouseWheelAxis axis;
SInt32 delta;
@@ -9989,15 +11102,14 @@ mac_handle_mouse_event (next_handler, event, data)
result = CallNextEventHandler (next_handler, event);
if (result != eventNotHandledErr || read_socket_inev == NULL)
- return result;
+ break;
+
+ f = mac_focus_frame (&one_mac_display_info);
err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
NULL, sizeof (WindowRef), NULL, &wp);
- if (err != noErr)
- break;
-
- f = mac_window_to_frame (wp);
- if (f != mac_focus_frame (&one_mac_display_info))
+ if (err != noErr
+ || wp != FRAME_MAC_WINDOW (f))
break;
err = GetEventParameter (event, kEventParamMouseWheelAxis,
@@ -10012,8 +11124,8 @@ mac_handle_mouse_event (next_handler, event, data)
if (err != noErr)
break;
- SetPortWindowPort (wp);
- GlobalToLocal (&point);
+ point.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+ point.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
if (point.h < 0 || point.v < 0
|| EQ (window_from_coordinates (f, point.h, point.v, 0, 0, 0, 1),
f->tool_bar_window))
@@ -10034,68 +11146,16 @@ mac_handle_mouse_event (next_handler, event, data)
XSETINT (read_socket_inev->y, point.v);
XSETFRAME (read_socket_inev->frame_or_window, f);
- return noErr;
+ result = noErr;
}
break;
default:
- break;
- }
-
- return eventNotHandledErr;
-}
-
-#if USE_MAC_FONT_PANEL
-static pascal OSStatus
-mac_handle_font_event (next_handler, event, data)
- EventHandlerCallRef next_handler;
- EventRef event;
- void *data;
-{
- OSStatus result, err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_sel[] = {kEventParamATSUFontID,
- kEventParamATSUFontSize,
- kEventParamFMFontFamily,
- kEventParamFMFontSize,
- kEventParamFontColor};
- static const EventParamType types_sel[] = {typeATSUFontID,
- typeATSUSize,
- typeFMFontFamily,
- typeFMFontSize,
- typeFontColor};
-
- result = CallNextEventHandler (next_handler, event);
- if (result != eventNotHandledErr)
- return result;
-
- switch (GetEventKind (event))
- {
- case kEventFontPanelClosed:
- id_key = Qpanel_closed;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
-
- case kEventFontSelection:
- id_key = Qselection;
- num_params = sizeof (names_sel) / sizeof (names_sel[0]);
- names = names_sel;
- types = types_sel;
- break;
+ abort ();
}
- err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
- event, num_params,
- names, types);
-
- return err == noErr ? noErr : eventNotHandledErr;
+ return result;
}
-#endif
#if USE_MAC_TSM
static pascal OSStatus
@@ -10104,7 +11164,7 @@ mac_handle_text_input_event (next_handler, event, data)
EventRef event;
void *data;
{
- OSStatus result, err = noErr;
+ OSStatus err, result;
Lisp_Object id_key = Qnil;
int num_params;
const EventParamName *names;
@@ -10152,6 +11212,8 @@ mac_handle_text_input_event (next_handler, event, data)
typeUnicodeText};
result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ return result;
switch (GetEventKind (event))
{
@@ -10163,6 +11225,7 @@ mac_handle_text_input_event (next_handler, event, data)
SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
typeUInt32, sizeof (UInt32), &seqno_uaia);
seqno_uaia++;
+ result = noErr;
break;
case kEventTextInputUnicodeForKeyEvent:
@@ -10179,8 +11242,8 @@ mac_handle_text_input_event (next_handler, event, data)
sizeof (UInt32), NULL, &modifiers);
if (err == noErr && mac_mapped_modifiers (modifiers))
/* There're mapped modifier keys. Process it in
- XTread_socket. */
- return eventNotHandledErr;
+ do_keystroke. */
+ break;
if (err == noErr)
err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
typeUnicodeText, NULL, 0, &actual_size,
@@ -10194,7 +11257,7 @@ mac_handle_text_input_event (next_handler, event, data)
sizeof (UniChar), NULL, &code);
if (err == noErr && code < 0x80)
{
- /* ASCII character. Process it in XTread_socket. */
+ /* ASCII character. Process it in do_keystroke. */
if (read_socket_inev && code >= 0x20 && code <= 0x7e)
{
UInt32 key_code;
@@ -10219,16 +11282,20 @@ mac_handle_text_input_event (next_handler, event, data)
XSETFRAME (read_socket_inev->frame_or_window, f);
}
}
- return eventNotHandledErr;
+ break;
}
}
+ if (err == noErr)
+ {
+ /* Non-ASCII keystrokes without mapped modifiers are
+ processed at the Lisp level. */
+ id_key = Qunicode_for_key_event;
+ num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
+ names = names_ufke;
+ types = types_ufke;
+ result = noErr;
+ }
}
- /* Non-ASCII keystrokes without mapped modifiers are processed
- at the Lisp level. */
- id_key = Qunicode_for_key_event;
- num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
- names = names_ufke;
- types = types_ufke;
break;
case kEventTextInputOffsetToPos:
@@ -10238,34 +11305,35 @@ mac_handle_text_input_event (next_handler, event, data)
Point p;
if (!OVERLAYP (Vmac_ts_active_input_overlay))
- return eventNotHandledErr;
+ break;
/* Strictly speaking, this is not always correct because
previous events may change some states about display. */
- if (NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+ if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+ {
+ /* Active input area is displayed around the current point. */
+ f = SELECTED_FRAME ();
+ w = XWINDOW (f->selected_window);
+ }
+ else if (WINDOWP (echo_area_window))
{
- if (!WINDOWP (echo_area_window))
- return eventNotHandledErr;
-
/* Active input area is displayed in the echo area. */
w = XWINDOW (echo_area_window);
f = WINDOW_XFRAME (w);
}
else
- {
- /* Active input area is displayed around the current point. */
- f = SELECTED_FRAME ();
- w = XWINDOW (f->selected_window);
- }
+ break;
p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
- + WINDOW_LEFT_FRINGE_WIDTH (w));
+ + WINDOW_LEFT_FRINGE_WIDTH (w)
+ + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
- + FONT_BASE (FRAME_FONT (f)));
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
- LocalToGlobal (&p);
+ + FONT_BASE (FRAME_FONT (f))
+ + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
err = SetEventParameter (event, kEventParamTextInputReplyPoint,
typeQDPoint, sizeof (typeQDPoint), &p);
+ if (err == noErr)
+ result = noErr;
}
break;
@@ -10277,146 +11345,152 @@ mac_handle_text_input_event (next_handler, event, data)
err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
event, num_params,
names, types);
-
- return err == noErr ? noErr : result;
+ return result;
}
#endif
+#endif /* TARGET_API_MAC_CARBON */
+
-#ifdef MAC_OSX
OSStatus
-mac_store_service_event (event)
- EventRef event;
+install_window_handler (window)
+ WindowRef window;
{
- OSStatus err;
- Lisp_Object id_key;
- int num_params;
- const EventParamName *names;
- const EventParamType *types;
- static const EventParamName names_pfm[] =
- {kEventParamServiceMessageName, kEventParamServiceUserData};
- static const EventParamType types_pfm[] =
- {typeCFStringRef, typeCFStringRef};
+ OSStatus err = noErr;
- switch (GetEventKind (event))
+#if TARGET_API_MAC_CARBON
+ if (err == noErr)
{
- case kEventServicePaste:
- id_key = Qpaste;
- num_params = 0;
- names = NULL;
- types = NULL;
- break;
+ static const EventTypeSpec specs[] =
+ {
+ /* -- window refresh events -- */
+ {kEventClassWindow, kEventWindowUpdate},
+ /* -- window state change events -- */
+ {kEventClassWindow, kEventWindowShowing},
+ {kEventClassWindow, kEventWindowHiding},
+ {kEventClassWindow, kEventWindowShown},
+ {kEventClassWindow, kEventWindowHidden},
+ {kEventClassWindow, kEventWindowCollapsed},
+ {kEventClassWindow, kEventWindowExpanded},
+ {kEventClassWindow, kEventWindowBoundsChanging},
+ {kEventClassWindow, kEventWindowBoundsChanged},
+ /* -- window action events -- */
+ {kEventClassWindow, kEventWindowClose},
+ {kEventClassWindow, kEventWindowGetIdealSize},
+#ifdef MAC_OSX
+ {kEventClassWindow, kEventWindowToolbarSwitchMode},
+#endif
+#if USE_MAC_TSM
+ /* -- window focus events -- */
+ {kEventClassWindow, kEventWindowFocusAcquired},
+ {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
+ };
+ static EventHandlerUPP handle_window_eventUPP = NULL;
- case kEventServicePerform:
- id_key = Qperform;
- num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
- names = names_pfm;
- types = types_pfm;
- break;
+ if (handle_window_eventUPP == NULL)
+ handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
- default:
- abort ();
+ err = InstallWindowEventHandler (window, handle_window_eventUPP,
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
}
+#endif
- err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
- event, num_params,
- names, types);
+ if (err == noErr)
+ err = install_drag_handler (window);
return err;
}
-#endif /* MAC_OSX */
-#endif /* USE_CARBON_EVENTS */
+void
+remove_window_handler (window)
+ WindowRef window;
+{
+ remove_drag_handler (window);
+}
-OSStatus
-install_window_handler (window)
- WindowPtr window;
+#if TARGET_API_MAC_CARBON
+static OSStatus
+install_application_handler ()
{
OSStatus err = noErr;
-#if USE_CARBON_EVENTS
- static const EventTypeSpec specs_window[] =
- {{kEventClassWindow, kEventWindowUpdate},
- {kEventClassWindow, kEventWindowGetIdealSize},
- {kEventClassWindow, kEventWindowBoundsChanging},
- {kEventClassWindow, kEventWindowBoundsChanged},
- {kEventClassWindow, kEventWindowShown},
- {kEventClassWindow, kEventWindowHidden},
- {kEventClassWindow, kEventWindowExpanded},
- {kEventClassWindow, kEventWindowCollapsed},
- {kEventClassWindow, kEventWindowClose},
-#ifdef MAC_OSX
- {kEventClassWindow, kEventWindowToolbarSwitchMode},
-#endif
-#if USE_MAC_TSM
- {kEventClassWindow, kEventWindowFocusAcquired},
- {kEventClassWindow, kEventWindowFocusRelinquish},
-#endif
- };
- static const EventTypeSpec specs_mouse[] =
- {{kEventClassMouse, kEventMouseWheelMoved}};
- static EventHandlerUPP handle_window_eventUPP = NULL;
- static EventHandlerUPP handle_mouse_eventUPP = NULL;
-#if USE_MAC_FONT_PANEL
- static const EventTypeSpec specs_font[] =
- {{kEventClassFont, kEventFontPanelClosed},
- {kEventClassFont, kEventFontSelection}};
- static EventHandlerUPP handle_font_eventUPP = NULL;
-#endif
-#if USE_MAC_TSM
- static const EventTypeSpec specs_text_input[] =
- {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
- {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
- {kEventClassTextInput, kEventTextInputOffsetToPos}};
- static EventHandlerUPP handle_text_input_eventUPP = NULL;
-#endif
- if (handle_window_eventUPP == NULL)
- handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
- if (handle_mouse_eventUPP == NULL)
- handle_mouse_eventUPP = NewEventHandlerUPP (mac_handle_mouse_event);
-#if USE_MAC_FONT_PANEL
- if (handle_font_eventUPP == NULL)
- handle_font_eventUPP = NewEventHandlerUPP (mac_handle_font_event);
-#endif
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] = {
#if USE_MAC_TSM
- if (handle_text_input_eventUPP == NULL)
- handle_text_input_eventUPP =
- NewEventHandlerUPP (mac_handle_text_input_event);
+ {kEventClassApplication, kEventAppActivated},
+ {kEventClassApplication, kEventAppDeactivated},
#endif
- err = InstallWindowEventHandler (window, handle_window_eventUPP,
- GetEventTypeCount (specs_window),
- specs_window, NULL, NULL);
+ };
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_application_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
if (err == noErr)
- err = InstallWindowEventHandler (window, handle_mouse_eventUPP,
- GetEventTypeCount (specs_mouse),
- specs_mouse, NULL, NULL);
-#if USE_MAC_FONT_PANEL
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassKeyboard, kEventRawKeyDown},
+ {kEventClassKeyboard, kEventRawKeyRepeat},
+ {kEventClassKeyboard, kEventRawKeyUp}};
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_keyboard_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
if (err == noErr)
- err = InstallWindowEventHandler (window, handle_font_eventUPP,
- GetEventTypeCount (specs_font),
- specs_font, NULL, NULL);
-#endif
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassCommand, kEventCommandProcess}};
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_command_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
+ if (err == noErr)
+ {
+ static const EventTypeSpec specs[] =
+ {{kEventClassMouse, kEventMouseWheelMoved}};
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_mouse_event),
+ GetEventTypeCount (specs),
+ specs, NULL, NULL);
+ }
+
#if USE_MAC_TSM
if (err == noErr)
- err = InstallWindowEventHandler (window, handle_text_input_eventUPP,
- GetEventTypeCount (specs_text_input),
- specs_text_input, window, NULL);
-#endif
+ {
+ static const EventTypeSpec spec[] =
+ {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
+ {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
+ {kEventClassTextInput, kEventTextInputOffsetToPos}};
+
+ err = InstallApplicationEventHandler (NewEventHandlerUPP
+ (mac_handle_text_input_event),
+ GetEventTypeCount (spec),
+ spec, NULL, NULL);
+ }
#endif
+
if (err == noErr)
- err = install_drag_handler (window);
+ err = install_menu_target_item_handler ();
+
+#ifdef MAC_OSX
if (err == noErr)
- err = install_menu_target_item_handler (window);
+ err = install_service_handler ();
+#endif
return err;
}
-
-void
-remove_window_handler (window)
- WindowPtr window;
-{
- remove_drag_handler (window);
-}
-
+#endif
static pascal void
mac_handle_dm_notification (event)
@@ -10425,20 +11499,48 @@ mac_handle_dm_notification (event)
mac_screen_config_changed = 1;
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static void
+mac_handle_cg_display_reconfig (display, flags, user_info)
+ CGDirectDisplayID display;
+ CGDisplayChangeSummaryFlags flags;
+ void *user_info;
+{
+ mac_screen_config_changed = 1;
+}
+#endif
+
static OSErr
init_dm_notification_handler ()
{
- OSErr err;
- static DMNotificationUPP handle_dm_notificationUPP = NULL;
- ProcessSerialNumber psn;
+ OSErr err = noErr;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGDisplayRegisterReconfigurationCallback != NULL)
+#endif
+ {
+ CGDisplayRegisterReconfigurationCallback (mac_handle_cg_display_reconfig,
+ NULL);
+ }
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ else /* CGDisplayRegisterReconfigurationCallback == NULL */
+#endif
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ {
+ static DMNotificationUPP handle_dm_notificationUPP = NULL;
+ ProcessSerialNumber psn;
- if (handle_dm_notificationUPP == NULL)
- handle_dm_notificationUPP =
- NewDMNotificationUPP (mac_handle_dm_notification);
+ if (handle_dm_notificationUPP == NULL)
+ handle_dm_notificationUPP =
+ NewDMNotificationUPP (mac_handle_dm_notification);
- err = GetCurrentProcess (&psn);
- if (err == noErr)
- err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
+ err = GetCurrentProcess (&psn);
+ if (err == noErr)
+ err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
+ }
+#endif
return err;
}
@@ -10583,7 +11685,7 @@ main (void)
}
#endif
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
static RgnHandle mouse_region = NULL;
Boolean
@@ -10620,7 +11722,7 @@ mac_wait_next_event (er, sleep_time, dequeue)
er_buf.what = nullEvent;
return true;
}
-#endif /* not USE_CARBON_EVENTS */
+#endif /* not TARGET_API_MAC_CARBON */
#if TARGET_API_MAC_CARBON
OSStatus
@@ -10654,44 +11756,6 @@ mac_post_mouse_moved_event ()
return err;
}
-
-static void
-mac_set_unicode_keystroke_event (code, buf)
- UniChar code;
- struct input_event *buf;
-{
- int charset_id, c1, c2;
-
- if (code < 0x80)
- {
- buf->kind = ASCII_KEYSTROKE_EVENT;
- buf->code = code;
- }
- else if (code < 0x100)
- {
- if (code < 0xA0)
- charset_id = CHARSET_8_BIT_CONTROL;
- else
- charset_id = charset_latin_iso8859_1;
- buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- buf->code = MAKE_CHAR (charset_id, code, 0);
- }
- else
- {
- if (code < 0x2500)
- charset_id = charset_mule_unicode_0100_24ff,
- code -= 0x100;
- else if (code < 0x33FF)
- charset_id = charset_mule_unicode_2500_33ff,
- code -= 0x2500;
- else if (code >= 0xE000)
- charset_id = charset_mule_unicode_e000_ffff,
- code -= 0xE000;
- c1 = (code / 96) + 32, c2 = (code % 96) + 32;
- buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- buf->code = MAKE_CHAR (charset_id, c1, c2);
- }
-}
#endif
/* Emacs calls this whenever it wants to read an input event from the
@@ -10703,7 +11767,7 @@ XTread_socket (sd, expected, hold_quit)
{
struct input_event inev;
int count = 0;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
EventRef eventRef;
EventTargetRef toolbox_dispatcher;
#endif
@@ -10724,7 +11788,7 @@ XTread_socket (sd, expected, hold_quit)
++handling_signal;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
toolbox_dispatcher = GetEventDispatcherTarget ();
while (
@@ -10733,9 +11797,9 @@ XTread_socket (sd, expected, hold_quit)
#endif
!ReceiveNextEvent (0, NULL, kEventDurationNoWait,
kEventRemoveFromQueue, &eventRef))
-#else /* !USE_CARBON_EVENTS */
+#else /* !TARGET_API_MAC_CARBON */
while (mac_wait_next_event (&er, 0, true))
-#endif /* !USE_CARBON_EVENTS */
+#endif /* !TARGET_API_MAC_CARBON */
{
int do_help = 0;
struct frame *f;
@@ -10745,44 +11809,33 @@ XTread_socket (sd, expected, hold_quit)
inev.kind = NO_EVENT;
inev.arg = Qnil;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
timestamp = GetEventTime (eventRef) / kEventDurationMillisecond;
-#else
- timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-#endif
-#if USE_CARBON_EVENTS
- /* Handle new events */
if (!mac_convert_event_ref (eventRef, &er))
- {
- /* There used to be a handler for the kEventMouseWheelMoved
- event here. But as of Mac OS X 10.4, this kind of event
- is not directly posted to the main event queue by
- two-finger scrolling on the trackpad. Instead, some
- private event is posted and it is converted to a wheel
- event by the default handler for the application target.
- The converted one can be received by a Carbon event
- handler installed on a window target. */
- read_socket_inev = &inev;
- SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- }
- else
-#endif /* USE_CARBON_EVENTS */
+ goto OTHER;
+#else /* !TARGET_API_MAC_CARBON */
+ timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
+#endif /* !TARGET_API_MAC_CARBON */
+
switch (er.what)
{
case mouseDown:
case mouseUp:
{
- WindowPtr window_ptr;
+ WindowRef window_ptr;
ControlPartCode part_code;
int tool_bar_p = 0;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
+ OSStatus err;
+
/* This is needed to send mouse events like aqua window
buttons to the correct handler. */
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
+ read_socket_inev = &inev;
+ err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+ read_socket_inev = NULL;
+ if (err != eventNotHandledErr)
break;
#endif
last_mouse_glyph_frame = 0;
@@ -10830,17 +11883,20 @@ XTread_socket (sd, expected, hold_quit)
else
{
ControlPartCode control_part_code;
- ControlHandle ch;
- Point mouse_loc = er.where;
+ ControlRef ch;
+ Point mouse_loc;
#ifdef MAC_OSX
ControlKind control_kind;
#endif
f = mac_window_to_frame (window_ptr);
/* convert to local coordinates of new window */
- SetPortWindowPort (window_ptr);
-
- GlobalToLocal (&mouse_loc);
+ mouse_loc.h = (er.where.h
+ - (f->left_pos
+ + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+ mouse_loc.v = (er.where.v
+ - (f->top_pos
+ + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
#if TARGET_API_MAC_CARBON
ch = FindControlUnderMouse (mouse_loc, window_ptr,
&control_part_code);
@@ -10853,7 +11909,7 @@ XTread_socket (sd, expected, hold_quit)
&ch);
#endif
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
inev.code = mac_get_mouse_btn (eventRef);
inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
@@ -10989,16 +12045,14 @@ XTread_socket (sd, expected, hold_quit)
DragWindow (window_ptr, er.where, NULL);
#else /* not TARGET_API_MAC_CARBON */
DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
-#endif /* not TARGET_API_MAC_CARBON */
/* Update the frame parameters. */
-#if !USE_CARBON_EVENTS
{
struct frame *f = mac_window_to_frame (window_ptr);
if (f && !f->async_iconified)
mac_handle_origin_change (f);
}
-#endif
+#endif /* not TARGET_API_MAC_CARBON */
break;
case inGoAway:
@@ -11022,41 +12076,38 @@ XTread_socket (sd, expected, hold_quit)
do_zoom_window (window_ptr, part_code);
break;
+#if USE_MAC_TOOLBAR
+ case inStructure:
+ {
+ OSStatus err;
+ HIViewRef ch;
+
+ err = HIViewGetViewForMouseEvent (HIViewGetRoot (window_ptr),
+ eventRef, &ch);
+ /* This doesn't work on Mac OS X 10.2. */
+ if (err == noErr)
+ HIViewClick (ch, eventRef);
+ }
+ break;
+#endif /* USE_MAC_TOOLBAR */
+
default:
break;
}
}
break;
+#if !TARGET_API_MAC_CARBON
case updateEvt:
-#if USE_CARBON_EVENTS
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#else
- do_window_update ((WindowPtr) er.message);
-#endif
+ do_window_update ((WindowRef) er.message);
break;
+#endif
case osEvt:
-#if USE_CARBON_EVENTS
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
switch ((er.message >> 24) & 0x000000FF)
{
- case suspendResumeMessage:
-#if USE_MAC_TSM
- if (er.message & resumeFlag)
- mac_tsm_resume ();
- else
- mac_tsm_suspend ();
-#endif
- break;
-
case mouseMovedMessage:
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
SetRectRgn (mouse_region, er.where.h, er.where.v,
er.where.h + 1, er.where.v + 1);
#endif
@@ -11077,13 +12128,15 @@ XTread_socket (sd, expected, hold_quit)
if (f)
{
- WindowPtr wp = FRAME_MAC_WINDOW (f);
- Point mouse_pos = er.where;
-
- SetPortWindowPort (wp);
-
- GlobalToLocal (&mouse_pos);
-
+ WindowRef wp = FRAME_MAC_WINDOW (f);
+ Point mouse_pos;
+
+ mouse_pos.h = (er.where.h
+ - (f->left_pos
+ + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+ mouse_pos.v = (er.where.v
+ - (f->top_pos
+ + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
if (dpyinfo->grabbed && tracked_scroll_bar)
#ifdef USE_TOOLKIT_SCROLL_BARS
x_scroll_bar_handle_drag (wp, tracked_scroll_bar,
@@ -11122,6 +12175,10 @@ XTread_socket (sd, expected, hold_quit)
}
if (!note_mouse_movement (f, &mouse_pos))
help_echo_string = previous_help_echo_string;
+#if USE_MAC_TOOLBAR
+ else
+ mac_tool_bar_note_mouse_movement (f, eventRef);
+#endif
}
}
@@ -11131,18 +12188,16 @@ XTread_socket (sd, expected, hold_quit)
if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
do_help = 1;
break;
+
+ default:
+ goto OTHER;
}
break;
case activateEvt:
{
- WindowPtr window_ptr = (WindowPtr) er.message;
+ WindowRef window_ptr = (WindowRef) er.message;
-#if USE_CARBON_EVENTS
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
if (window_ptr == tip_window)
{
HideWindow (tip_window);
@@ -11150,21 +12205,26 @@ XTread_socket (sd, expected, hold_quit)
}
if (!is_emacs_window (window_ptr))
- break;
+ goto OTHER;
+
+ f = mac_window_to_frame (window_ptr);
if ((er.modifiers & activeFlag) != 0)
{
/* A window has been activated */
- Point mouse_loc = er.where;
+ Point mouse_loc;
x_detect_focus_change (dpyinfo, &er, &inev);
- SetPortWindowPort (window_ptr);
- GlobalToLocal (&mouse_loc);
+ mouse_loc.h = (er.where.h
+ - (f->left_pos
+ + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+ mouse_loc.v = (er.where.v
+ - (f->top_pos
+ + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
/* Window-activated event counts as mouse movement,
so update things that depend on mouse position. */
- note_mouse_movement (mac_window_to_frame (window_ptr),
- &mouse_loc);
+ note_mouse_movement (f, &mouse_loc);
}
else
{
@@ -11189,7 +12249,6 @@ XTread_socket (sd, expected, hold_quit)
x_detect_focus_change (dpyinfo, &er, &inev);
- f = mac_window_to_frame (window_ptr);
if (f == dpyinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
@@ -11212,218 +12271,26 @@ XTread_socket (sd, expected, hold_quit)
case keyDown:
case keyUp:
case autoKey:
- {
- int keycode = (er.message & keyCodeMask) >> 8;
- static SInt16 last_key_script = -1;
- SInt16 current_key_script;
- UInt32 modifiers = er.modifiers, mapped_modifiers;
-
-#if USE_CARBON_EVENTS && defined (MAC_OSX)
- GetEventParameter (eventRef, kEventParamKeyModifiers,
- typeUInt32, NULL,
- sizeof (UInt32), NULL, &modifiers);
-#endif
- mapped_modifiers = mac_mapped_modifiers (modifiers);
-
-#if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
- /* When using Carbon Events, we need to pass raw keyboard
- events to the TSM ourselves. If TSM handles it, it
- will pass back noErr, otherwise it will pass back
- "eventNotHandledErr" and we can process it
- normally. */
- if (!(mapped_modifiers
- & ~(mac_pass_command_to_system ? cmdKey : 0)
- & ~(mac_pass_control_to_system ? controlKey : 0)))
- {
- OSStatus err;
-
- read_socket_inev = &inev;
- err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
- read_socket_inev = NULL;
- if (err != eventNotHandledErr)
- break;
- }
-#endif
- if (er.what == keyUp)
- break;
-
- ObscureCursor ();
-
- f = mac_focus_frame (dpyinfo);
-
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
- && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
- {
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_hidden = 1;
- }
-
- current_key_script = GetScriptManagerVariable (smKeyScript);
- if (last_key_script != current_key_script)
- {
- struct input_event event;
-
- EVENT_INIT (event);
- event.kind = LANGUAGE_CHANGE_EVENT;
- event.arg = Qnil;
- event.code = current_key_script;
- event.timestamp = timestamp;
- kbd_buffer_store_event (&event);
- count++;
- last_key_script = current_key_script;
- }
-
-#if USE_MAC_TSM
- if (inev.kind != NO_EVENT)
- break;
-#endif
-
-#ifdef MAC_OSX
- if (mapped_modifiers & kEventKeyModifierFnMask
- && keycode <= 0x7f
- && fn_keycode_to_keycode_table[keycode])
- keycode = fn_keycode_to_keycode_table[keycode];
-#endif
- if (keycode <= 0x7f && keycode_to_xkeysym_table [keycode])
- {
- inev.kind = NON_ASCII_KEYSTROKE_EVENT;
- inev.code = 0xff00 | keycode_to_xkeysym_table [keycode];
-#ifdef MAC_OSX
- if (modifiers & kEventKeyModifierFnMask
- && keycode <= 0x7f
- && fn_keycode_to_keycode_table[keycode] == keycode)
- modifiers &= ~kEventKeyModifierFnMask;
-#endif
- }
- else if (mapped_modifiers)
- {
- /* translate the keycode back to determine the
- original key */
-#ifdef MAC_OSX
- UCKeyboardLayout *uchr_ptr = NULL;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
- OSStatus err;
- KeyboardLayoutRef layout;
-
- err = KLGetCurrentKeyboardLayout (&layout);
- if (err == noErr)
- KLGetKeyboardLayoutProperty (layout, kKLuchrData,
- (const void **) &uchr_ptr);
-#else
- static SInt16 last_key_layout_id = 0;
- static Handle uchr_handle = (Handle)-1;
- SInt16 current_key_layout_id =
- GetScriptVariable (current_key_script, smScriptKeys);
-
- if (uchr_handle == (Handle)-1
- || last_key_layout_id != current_key_layout_id)
- {
- uchr_handle = GetResource ('uchr', current_key_layout_id);
- last_key_layout_id = current_key_layout_id;
- }
- if (uchr_handle)
- uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
-#endif
-
- if (uchr_ptr)
- {
- OSStatus status;
- UInt16 key_action = er.what - keyDown;
- UInt32 modifier_key_state =
- (modifiers & ~mapped_modifiers) >> 8;
- UInt32 keyboard_type = LMGetKbdType ();
- SInt32 dead_key_state = 0;
- UniChar code;
- UniCharCount actual_length;
-
- status = UCKeyTranslate (uchr_ptr,
- keycode, key_action,
- modifier_key_state,
- keyboard_type,
- kUCKeyTranslateNoDeadKeysMask,
- &dead_key_state,
- 1, &actual_length, &code);
- if (status == noErr && actual_length == 1)
- mac_set_unicode_keystroke_event (code, &inev);
- }
-#endif /* MAC_OSX */
-
- if (inev.kind == NO_EVENT)
- {
- /* This code comes from Keyboard Resource,
- Appendix C of IM - Text. This is necessary
- since shift is ignored in KCHR table
- translation when option or command is pressed.
- It also does not translate correctly
- control-shift chars like C-% so mask off shift
- here also. */
- /* Mask off modifier keys that are mapped to some
- Emacs modifiers. */
- int new_modifiers = er.modifiers & ~mapped_modifiers;
- /* set high byte of keycode to modifier high byte*/
- int new_keycode = keycode | new_modifiers;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- unsigned long some_state = 0;
- UInt32 new_char_code;
-
- new_char_code = KeyTranslate (kchr_ptr, new_keycode,
- &some_state);
- if (new_char_code == 0)
- /* Seems like a dead key. Append up-stroke. */
- new_char_code = KeyTranslate (kchr_ptr,
- new_keycode | 0x80,
- &some_state);
- if (new_char_code)
- {
- inev.kind = ASCII_KEYSTROKE_EVENT;
- inev.code = new_char_code & 0xff;
- }
- }
- }
-
- if (inev.kind == NO_EVENT)
- {
- inev.kind = ASCII_KEYSTROKE_EVENT;
- inev.code = er.message & charCodeMask;
- }
+ ObscureCursor ();
- inev.modifiers = mac_to_emacs_modifiers (modifiers);
- inev.modifiers |= (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- XSETFRAME (inev.frame_or_window, f);
+ f = mac_focus_frame (dpyinfo);
+ XSETFRAME (inev.frame_or_window, f);
+ /* If mouse-highlight is an integer, input clears out mouse
+ highlighting. */
+ if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+ && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+ {
+ clear_mouse_face (dpyinfo);
+ dpyinfo->mouse_face_hidden = 1;
+ }
#if TARGET_API_MAC_CARBON
- if (inev.kind == ASCII_KEYSTROKE_EVENT
- && inev.code >= 0x80 && inev.modifiers)
- {
- OSStatus err;
- TextEncoding encoding = kTextEncodingMacRoman;
- TextToUnicodeInfo ttu_info;
-
- UpgradeScriptInfoToTextEncoding (current_key_script,
- kTextLanguageDontCare,
- kTextRegionDontCare,
- NULL, &encoding);
- err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
- if (err == noErr)
- {
- UniChar code;
- Str255 pstr;
- ByteCount unicode_len;
-
- pstr[0] = 1;
- pstr[1] = inev.code;
- err = ConvertFromPStringToUnicode (ttu_info, pstr,
- sizeof (UniChar),
- &unicode_len, &code);
- if (err == noErr && unicode_len == sizeof (UniChar))
- mac_set_unicode_keystroke_event (code, &inev);
- DisposeTextToUnicodeInfo (&ttu_info);
- }
- }
+ goto OTHER;
+#else
+ do_keystroke (er.what, er.message & charCodeMask,
+ (er.message & keyCodeMask) >> 8,
+ er.modifiers, timestamp, &inev);
#endif
- }
break;
case kHighLevelEvent:
@@ -11431,9 +12298,19 @@ XTread_socket (sd, expected, hold_quit)
break;
default:
+ OTHER:
+#if TARGET_API_MAC_CARBON
+ {
+ OSStatus err;
+
+ read_socket_inev = &inev;
+ err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+ read_socket_inev = NULL;
+ }
+#endif
break;
}
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
ReleaseEvent (eventRef);
#endif
@@ -11485,7 +12362,7 @@ XTread_socket (sd, expected, hold_quit)
mac_screen_config_changed = 0;
}
-#if !USE_CARBON_EVENTS
+#if !TARGET_API_MAC_CARBON
/* Check which frames are still visible. We do this here because
there doesn't seem to be any direct notification from the Window
Manager that the visibility of a window has changed (at least,
@@ -11590,7 +12467,7 @@ make_mac_terminal_frame (struct frame *f)
if (!(FRAME_MAC_WINDOW (f) =
NewCWindow (NULL, &r, "\p", true, dBoxProc,
- (WindowPtr) -1, 1, (long) f->output_data.mac)))
+ (WindowRef) -1, 1, (long) f->output_data.mac)))
abort ();
/* so that update events can find this mac_output struct */
f->output_data.mac->mFP = f; /* point back to emacs frame */
@@ -11780,7 +12657,6 @@ init_menu_bar ()
&menu, &menu_index);
if (err == noErr)
SetMenuItemCommandKey (menu, menu_index, false, 0);
-#if USE_CARBON_EVENTS
EnableMenuCommand (NULL, kHICommandPreferences);
err = GetIndMenuItemWithCommandID (NULL, kHICommandPreferences, 1,
&menu, &menu_index);
@@ -11792,10 +12668,9 @@ init_menu_bar ()
InsertMenuItemTextWithCFString (menu, CFSTR ("About Emacs"),
0, 0, kHICommandAbout);
}
-#endif /* USE_CARBON_EVENTS */
#else /* !MAC_OSX */
-#if USE_CARBON_EVENTS
- SetMenuItemCommandID (GetMenuHandle (M_APPLE), I_ABOUT, kHICommandAbout);
+#if TARGET_API_MAC_CARBON
+ SetMenuItemCommandID (GetMenuRef (M_APPLE), I_ABOUT, kHICommandAbout);
#endif
#endif
}
@@ -11902,19 +12777,13 @@ mac_initialize ()
#if TARGET_API_MAC_CARBON
-#if USE_CARBON_EVENTS
-#ifdef MAC_OSX
- init_service_handler ();
-#endif /* MAC_OSX */
-
- init_command_handler ();
+ install_application_handler ();
init_menu_bar ();
#if USE_MAC_TSM
init_tsm ();
#endif
-#endif /* USE_CARBON_EVENTS */
#ifdef MAC_OSX
init_coercion_handler ();
@@ -11964,7 +12833,7 @@ syms_of_macterm ()
Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
Qhi_command = intern ("hi-command"); staticpro (&Qhi_command);
#ifdef MAC_OSX
Qtoolbar_switch_mode = intern ("toolbar-switch-mode");
@@ -12089,7 +12958,7 @@ The symbol `reverse' means that the option-key will register for
mouse-3 and the command-key will register for mouse-2. */);
Vmac_emulate_three_button_mouse = Qnil;
-#if USE_CARBON_EVENTS
+#if TARGET_API_MAC_CARBON
DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2,
doc: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
Otherwise, the right click will be treated as mouse-2 and the wheel
diff --git a/src/macterm.h b/src/macterm.h
index f9ce0ef051d..2dc13665f67 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -333,6 +333,16 @@ struct mac_output
/* Hints for the size and the position of a window. */
XSizeHints *size_hints;
+#if USE_MAC_TOOLBAR
+ /* This variable records the gravity value of the window position if
+ the window has an external tool bar when it is created. The
+ position of the window is adjusted using this information when
+ the tool bar is first redisplayed. Once the tool bar is
+ redisplayed, it is set to 0 in order to avoid further
+ adjustment. */
+ int toolbar_win_gravity;
+#endif
+
#if USE_CG_DRAWING
/* Quartz 2D graphics context. */
CGContextRef cg_context;
@@ -369,6 +379,12 @@ typedef struct mac_output mac_output;
/* This is the 'font_info *' which frame F has. */
#define FRAME_MAC_FONT_TABLE(f) (FRAME_MAC_DISPLAY_INFO (f)->font_table)
+/* The difference in pixels between the top left corner of the
+ Emacs window (including possible window manager decorations)
+ and FRAME_MAC_WINDOW (f). */
+#define FRAME_OUTER_TO_INNER_DIFF_X(f) ((f)->x_pixels_diff)
+#define FRAME_OUTER_TO_INNER_DIFF_Y(f) ((f)->y_pixels_diff)
+
/* Value is the smallest width of any character in any font on frame F. */
#define FRAME_SMALLEST_CHAR_WIDTH(F) \
@@ -406,9 +422,9 @@ struct scroll_bar {
/* The next and previous in the chain of scroll bars in this frame. */
Lisp_Object next, prev;
- /* The Mac control handle of this scroll bar. Since this is a
+ /* The Mac control reference of this scroll bar. Since this is a
pointer value, we store it split into two Lisp integers. */
- Lisp_Object control_handle_low, control_handle_high;
+ Lisp_Object control_ref_low, control_ref_high;
/* The position and size of the scroll bar in pixels, relative to the
frame. */
@@ -435,6 +451,12 @@ struct scroll_bar {
being dragged, this is Qnil. */
Lisp_Object dragging;
+#ifdef MAC_OSX
+ /* t if the background of the fringe that is adjacent to a scroll
+ bar is extended to the gap between the fringe and the bar. */
+ Lisp_Object fringe_extended_p;
+#endif
+
#ifdef USE_TOOLKIT_SCROLL_BARS
/* The position and size of the scroll bar handle track area in
pixels, relative to the frame. */
@@ -466,14 +488,14 @@ struct scroll_bar {
/* Extract the Mac control handle of the scroll bar from a struct
scroll_bar. */
-#define SCROLL_BAR_CONTROL_HANDLE(ptr) \
- ((ControlHandle) SCROLL_BAR_PACK ((ptr)->control_handle_low, \
- (ptr)->control_handle_high))
+#define SCROLL_BAR_CONTROL_REF(ptr) \
+ ((ControlRef) SCROLL_BAR_PACK ((ptr)->control_ref_low, \
+ (ptr)->control_ref_high))
/* Store a Mac control handle in a struct scroll_bar. */
-#define SET_SCROLL_BAR_CONTROL_HANDLE(ptr, handle) \
- (SCROLL_BAR_UNPACK ((ptr)->control_handle_low, \
- (ptr)->control_handle_high, (unsigned long) (handle)))
+#define SET_SCROLL_BAR_CONTROL_REF(ptr, ref) \
+ (SCROLL_BAR_UNPACK ((ptr)->control_ref_low, \
+ (ptr)->control_ref_high, (unsigned long) (ref)))
/* Return the inside width of a vertical scroll bar, given the outside
width. */
@@ -615,9 +637,9 @@ extern void x_destroy_window P_ ((struct frame *));
extern void x_wm_set_size_hint P_ ((struct frame *, long, int));
extern void x_delete_display P_ ((struct x_display_info *));
extern void mac_initialize P_ ((void));
-extern Pixmap XCreatePixmap P_ ((Display *, WindowPtr, unsigned int,
+extern Pixmap XCreatePixmap P_ ((Display *, WindowRef, unsigned int,
unsigned int, unsigned int));
-extern Pixmap XCreatePixmapFromBitmapData P_ ((Display *, WindowPtr, char *,
+extern Pixmap XCreatePixmapFromBitmapData P_ ((Display *, WindowRef, char *,
unsigned int, unsigned int,
unsigned long, unsigned long,
unsigned int));
@@ -626,7 +648,7 @@ extern GC XCreateGC P_ ((Display *, void *, unsigned long, XGCValues *));
extern void XFreeGC P_ ((Display *, GC));
extern void XSetForeground P_ ((Display *, GC, unsigned long));
extern void XSetBackground P_ ((Display *, GC, unsigned long));
-extern void XSetWindowBackground P_ ((Display *, WindowPtr, unsigned long));
+extern void XSetWindowBackground P_ ((Display *, WindowRef, unsigned long));
extern void XDrawLine P_ ((Display *, Pixmap, GC, int, int, int, int));
extern void mac_clear_area P_ ((struct frame *, int, int,
unsigned int, unsigned int));
@@ -634,8 +656,8 @@ extern void mac_unload_font P_ ((struct mac_display_info *, XFontStruct *));
extern int mac_font_panel_visible_p P_ ((void));
extern OSStatus mac_show_hide_font_panel P_ ((void));
extern OSStatus mac_set_font_info_for_selection P_ ((struct frame *, int, int));
-extern OSStatus install_window_handler P_ ((WindowPtr));
-extern void remove_window_handler P_ ((WindowPtr));
+extern OSStatus install_window_handler P_ ((WindowRef));
+extern void remove_window_handler P_ ((WindowRef));
extern OSStatus mac_post_mouse_moved_event P_ ((void));
#if !TARGET_API_MAC_CARBON
extern void do_apple_menu P_ ((SInt16));
@@ -643,7 +665,12 @@ extern void do_apple_menu P_ ((SInt16));
#if USE_CG_DRAWING
extern void mac_prepare_for_quickdraw P_ ((struct frame *));
#endif
+extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
extern int mac_quit_char_key_p P_ ((UInt32, UInt32));
+#if USE_MAC_TOOLBAR
+extern void update_frame_tool_bar P_ ((FRAME_PTR f));
+extern void free_frame_tool_bar P_ ((FRAME_PTR f));
+#endif
#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
diff --git a/src/minibuf.c b/src/minibuf.c
index 0a1d737a793..9c21be3f068 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -529,7 +529,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
GCPRO5 (map, initial, val, ambient_dir, input_method);
if (!STRINGP (prompt))
- prompt = empty_string;
+ prompt = empty_unibyte_string;
if (!enable_recursive_minibuffers
&& minibuf_level > 0)
@@ -1717,9 +1717,15 @@ PREDICATE limits completion to a subset of COLLECTION.
See `try-completion' and `all-completions' for more details
on completion, COLLECTION, and PREDICATE.
-If REQUIRE-MATCH is non-nil, the user is not allowed to exit unless
- the input is (or completes to) an element of COLLECTION or is null.
- If it is also not t, typing RET does not exit if it does non-null completion.
+REQUIRE-MATCH can take the following values:
+- t means that the user is not allowed to exit unless
+ the input is (or completes to) an element of COLLECTION or is null.
+- nil means that the user can exit with any input.
+- `confirm-only' means that the user can exit with any input, but she will
+ need to confirm her choice if the input is not an element of COLLECTION.
+- anything else behaves like t except that typing RET does not exit if it
+ does non-null completion.
+
If the input is null, `completing-read' returns DEF, or an empty string
if DEF is nil, regardless of the value of REQUIRE-MATCH.
@@ -2230,6 +2236,18 @@ a repetition of this command will exit. */)
goto exit;
}
+ if (EQ (Vminibuffer_completion_confirm, intern ("confirm-only")))
+ { /* The user is permitted to exit with an input that's rejected
+ by test-completion, but at the condition to confirm her choice. */
+ if (EQ (current_kboard->Vlast_command, Vthis_command))
+ goto exit;
+ else
+ {
+ temp_echo_area_glyphs (build_string (" [Confirm]"));
+ return Qnil;
+ }
+ }
+
/* Call do_completion, but ignore errors. */
SET_PT (ZV);
val = internal_condition_case (complete_and_exit_1, Qerror,
diff --git a/src/process.c b/src/process.c
index 99c5e07f0d4..08358539a6c 100644
--- a/src/process.c
+++ b/src/process.c
@@ -121,14 +121,6 @@ Boston, MA 02110-1301, USA. */
#include <sys/wait.h>
#endif
-/* Disable IPv6 support for w32 until someone figures out how to do it
- properly. */
-#ifdef WINDOWSNT
-# ifdef AF_INET6
-# undef AF_INET6
-# endif
-#endif
-
#include "lisp.h"
#include "systime.h"
#include "systty.h"
@@ -328,14 +320,18 @@ extern int timers_run;
static SELECT_TYPE input_wait_mask;
-/* Mask that excludes keyboard input descriptor (s). */
+/* Mask that excludes keyboard input descriptor(s). */
static SELECT_TYPE non_keyboard_wait_mask;
-/* Mask that excludes process input descriptor (s). */
+/* Mask that excludes process input descriptor(s). */
static SELECT_TYPE non_process_wait_mask;
+/* Mask for the gpm mouse input descriptor. */
+
+static SELECT_TYPE gpm_wait_mask;
+
#ifdef NON_BLOCKING_CONNECT
/* Mask of bits indicating the descriptors that we wait for connect to
complete on. Once they complete, they are removed from this mask
@@ -357,6 +353,9 @@ static int max_process_desc;
/* The largest descriptor currently in use for keyboard input. */
static int max_keyboard_desc;
+/* The largest descriptor currently in use for gpm mouse input. */
+static int max_gpm_desc;
+
/* Nonzero means delete a process right away if it exits. */
static int delete_exited_processes;
@@ -386,7 +385,7 @@ struct sockaddr_and_len {
int len;
} datagram_address[MAXDESC];
#define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0)
-#define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XINT (XPROCESS (proc)->infd)].sa != 0)
+#define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XPROCESS (proc)->infd].sa != 0)
#else
#define DATAGRAM_CHAN_P(chan) (0)
#define DATAGRAM_CONN_P(proc) (0)
@@ -621,19 +620,19 @@ make_process (name)
p = allocate_process ();
- XSETINT (p->infd, -1);
- XSETINT (p->outfd, -1);
- XSETFASTINT (p->tick, 0);
- XSETFASTINT (p->update_tick, 0);
+ p->infd = -1;
+ p->outfd = -1;
+ p->tick = 0;
+ p->update_tick = 0;
p->pid = 0;
p->raw_status_new = 0;
p->status = Qrun;
p->mark = Fmake_marker ();
#ifdef ADAPTIVE_READ_BUFFERING
- p->adaptive_read_buffering = Qnil;
- XSETFASTINT (p->read_output_delay, 0);
- p->read_output_skip = Qnil;
+ p->adaptive_read_buffering = 0;
+ p->read_output_delay = 0;
+ p->read_output_skip = 0;
#endif
/* If name is already in use, modify it until it is unused. */
@@ -672,8 +671,8 @@ setup_process_coding_systems (process)
Lisp_Object process;
{
struct Lisp_Process *p = XPROCESS (process);
- int inch = XINT (p->infd);
- int outch = XINT (p->outfd);
+ int inch = p->infd;
+ int outch = p->outfd;
if (inch < 0 || outch < 0)
return;
@@ -685,7 +684,7 @@ setup_process_coding_systems (process)
proc_decode_coding_system[inch]);
if (! NILP (p->filter))
{
- if (NILP (p->filter_multibyte))
+ if (!p->filter_multibyte)
setup_raw_text_coding_system (proc_decode_coding_system[inch]);
}
else if (BUFFERP (p->buffer))
@@ -808,10 +807,10 @@ nil, indicating the current buffer's process. */)
if (NETCONN1_P (p))
{
p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
status_notify (p);
}
- else if (XINT (p->infd) >= 0)
+ else if (p->infd >= 0)
{
#ifdef SIGCHLD
Lisp_Object symbol;
@@ -839,7 +838,7 @@ nil, indicating the current buffer's process. */)
/* Do this now, since remove_process will make sigchld_handler do nothing. */
p->status
= Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
status_notify (p);
}
}
@@ -1031,18 +1030,18 @@ The string argument is normally a multibyte string, except:
(debug)
(set-process-filter process ...) */
- if (XINT (p->infd) >= 0)
+ if (p->infd >= 0)
{
if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
{
- FD_CLR (XINT (p->infd), &input_wait_mask);
- FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_CLR (p->infd, &input_wait_mask);
+ FD_CLR (p->infd, &non_keyboard_wait_mask);
}
else if (EQ (p->filter, Qt)
&& !EQ (p->command, Qt)) /* Network process not stopped. */
{
- FD_SET (XINT (p->infd), &input_wait_mask);
- FD_SET (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_SET (p->infd, &input_wait_mask);
+ FD_SET (p->infd, &non_keyboard_wait_mask);
}
}
@@ -1104,8 +1103,8 @@ DEFUN ("set-process-window-size", Fset_process_window_size,
CHECK_NATNUM (height);
CHECK_NATNUM (width);
- if (XINT (XPROCESS (process)->infd) < 0
- || set_window_size (XINT (XPROCESS (process)->infd),
+ if (XPROCESS (process)->infd < 0
+ || set_window_size (XPROCESS (process)->infd,
XINT (height), XINT (width)) <= 0)
return Qnil;
else
@@ -1133,7 +1132,7 @@ for the process which will run. */)
register Lisp_Object process, flag;
{
CHECK_PROCESS (process);
- XPROCESS (process)->inherit_coding_system_flag = flag;
+ XPROCESS (process)->inherit_coding_system_flag = !NILP (flag);
return flag;
}
@@ -1148,7 +1147,7 @@ the process output. */)
register Lisp_Object process;
{
CHECK_PROCESS (process);
- return XPROCESS (process)->inherit_coding_system_flag;
+ return XPROCESS (process)->inherit_coding_system_flag ? Qt : Qnil;
}
DEFUN ("set-process-query-on-exit-flag",
@@ -1161,7 +1160,7 @@ exiting if PROCESS is running. */)
register Lisp_Object process, flag;
{
CHECK_PROCESS (process);
- XPROCESS (process)->kill_without_query = Fnull (flag);
+ XPROCESS (process)->kill_without_query = NILP (flag);
return flag;
}
@@ -1173,7 +1172,7 @@ DEFUN ("process-query-on-exit-flag",
register Lisp_Object process;
{
CHECK_PROCESS (process);
- return Fnull (XPROCESS (process)->kill_without_query);
+ return (XPROCESS (process)->kill_without_query ? Qnil : Qt);
}
#ifdef DATAGRAM_SOCKETS
@@ -1348,7 +1347,7 @@ list_processes_1 (query_only)
p = XPROCESS (proc);
if (NILP (p->childp))
continue;
- if (!NILP (query_only) && !NILP (p->kill_without_query))
+ if (!NILP (query_only) && p->kill_without_query)
continue;
if (STRINGP (p->name)
&& ( i = SCHARS (p->name), (i > w_proc)))
@@ -1411,7 +1410,7 @@ list_processes_1 (query_only)
p = XPROCESS (proc);
if (NILP (p->childp))
continue;
- if (!NILP (query_only) && !NILP (p->kill_without_query))
+ if (!NILP (query_only) && p->kill_without_query)
continue;
Finsert (1, &p->name);
@@ -1487,7 +1486,7 @@ list_processes_1 (query_only)
if (NILP (port))
port = Fformat_network_address (Fplist_get (p->childp, QClocal), Qnil);
sprintf (tembuf, "(network %s server on %s)\n",
- (DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"),
+ (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
(STRINGP (port) ? (char *)SDATA (port) : "?"));
insert_string (tembuf);
}
@@ -1505,7 +1504,7 @@ list_processes_1 (query_only)
if (NILP (host))
host = Fformat_network_address (Fplist_get (p->childp, QCremote), Qnil);
sprintf (tembuf, "(network %s connection to %s)\n",
- (DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"),
+ (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
(STRINGP (host) ? (char *)SDATA (host) : "?"));
insert_string (tembuf);
}
@@ -1636,11 +1635,13 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
XPROCESS (proc)->sentinel = Qnil;
XPROCESS (proc)->filter = Qnil;
XPROCESS (proc)->filter_multibyte
- = buffer_defaults.enable_multibyte_characters;
+ = !NILP (buffer_defaults.enable_multibyte_characters);
XPROCESS (proc)->command = Flist (nargs - 2, args + 2);
#ifdef ADAPTIVE_READ_BUFFERING
- XPROCESS (proc)->adaptive_read_buffering = Vprocess_adaptive_read_buffering;
+ XPROCESS (proc)->adaptive_read_buffering
+ = (NILP (Vprocess_adaptive_read_buffering) ? 0
+ : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2);
#endif
/* Make the process marker point into the process buffer (if any). */
@@ -1771,13 +1772,11 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
#endif /* not VMS */
XPROCESS (proc)->decoding_buf = make_uninit_string (0);
- XPROCESS (proc)->decoding_carryover = make_number (0);
+ XPROCESS (proc)->decoding_carryover = 0;
XPROCESS (proc)->encoding_buf = make_uninit_string (0);
- XPROCESS (proc)->encoding_carryover = make_number (0);
XPROCESS (proc)->inherit_coding_system_flag
- = (NILP (buffer) || !inherit_process_coding_system
- ? Qnil : Qt);
+ = !(NILP (buffer) || !inherit_process_coding_system);
create_process (proc, (char **) new_argv, current_dir);
@@ -1949,15 +1948,15 @@ create_process (process, new_argv, current_dir)
/* Record this as an active process, with its channels.
As a result, child_setup will close Emacs's side of the pipes. */
chan_process[inchannel] = process;
- XSETINT (XPROCESS (process)->infd, inchannel);
- XSETINT (XPROCESS (process)->outfd, outchannel);
+ XPROCESS (process)->infd = inchannel;
+ XPROCESS (process)->outfd = outchannel;
/* Previously we recorded the tty descriptor used in the subprocess.
It was only used for getting the foreground tty process, so now
we just reopen the device (see emacs_get_tty_pgrp) as this is
more portable (see USG_SUBTTY_WORKS above). */
- XPROCESS (process)->pty_flag = (pty_flag ? Qt : Qnil);
+ XPROCESS (process)->pty_flag = pty_flag;
XPROCESS (process)->status = Qrun;
setup_process_coding_systems (process);
@@ -2474,7 +2473,7 @@ DEFUN ("process-datagram-address", Fprocess_datagram_address, Sprocess_datagram_
if (!DATAGRAM_CONN_P (process))
return Qnil;
- channel = XINT (XPROCESS (process)->infd);
+ channel = XPROCESS (process)->infd;
return conv_sockaddr_to_lisp (datagram_address[channel].sa,
datagram_address[channel].len);
}
@@ -2494,7 +2493,7 @@ Returns nil upon error setting address, ADDRESS otherwise. */)
if (!DATAGRAM_CONN_P (process))
return Qnil;
- channel = XINT (XPROCESS (process)->infd);
+ channel = XPROCESS (process)->infd;
len = get_lisp_to_sockaddr_size (address, &family);
if (datagram_address[channel].len != len)
@@ -2659,7 +2658,7 @@ OPTION is not a supported option, return nil instead; otherwise return t. */)
if (!NETCONN1_P (p))
error ("Process is not a network process");
- s = XINT (p->infd);
+ s = p->infd;
if (s < 0)
error ("Process is not running");
@@ -3413,18 +3412,18 @@ usage: (make-network-process &rest ARGS) */)
p->buffer = buffer;
p->sentinel = sentinel;
p->filter = filter;
- p->filter_multibyte = buffer_defaults.enable_multibyte_characters;
+ p->filter_multibyte = !NILP (buffer_defaults.enable_multibyte_characters);
/* Override the above only if :filter-multibyte is specified. */
if (! NILP (Fplist_member (contact, QCfilter_multibyte)))
- p->filter_multibyte = Fplist_get (contact, QCfilter_multibyte);
+ p->filter_multibyte = !NILP (Fplist_get (contact, QCfilter_multibyte));
p->log = Fplist_get (contact, QClog);
if (tem = Fplist_get (contact, QCnoquery), !NILP (tem))
- p->kill_without_query = Qt;
+ p->kill_without_query = 1;
if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
p->command = Qt;
p->pid = 0;
- XSETINT (p->infd, inch);
- XSETINT (p->outfd, outch);
+ p->infd = inch;
+ p->outfd = outch;
if (is_server && socktype == SOCK_STREAM)
p->status = Qlisten;
@@ -3545,13 +3544,11 @@ usage: (make-network-process &rest ARGS) */)
setup_process_coding_systems (proc);
p->decoding_buf = make_uninit_string (0);
- p->decoding_carryover = make_number (0);
+ p->decoding_carryover = 0;
p->encoding_buf = make_uninit_string (0);
- p->encoding_carryover = make_number (0);
p->inherit_coding_system_flag
- = (!NILP (tem) || NILP (buffer) || !inherit_process_coding_system
- ? Qnil : Qt);
+ = !(!NILP (tem) || NILP (buffer) || !inherit_process_coding_system);
UNGCPRO;
return proc;
@@ -3814,16 +3811,16 @@ deactivate_process (proc)
register int inchannel, outchannel;
register struct Lisp_Process *p = XPROCESS (proc);
- inchannel = XINT (p->infd);
- outchannel = XINT (p->outfd);
+ inchannel = p->infd;
+ outchannel = p->outfd;
#ifdef ADAPTIVE_READ_BUFFERING
- if (XINT (p->read_output_delay) > 0)
+ if (p->read_output_delay > 0)
{
if (--process_output_delay_count < 0)
process_output_delay_count = 0;
- XSETINT (p->read_output_delay, 0);
- p->read_output_skip = Qnil;
+ p->read_output_delay = 0;
+ p->read_output_skip = 0;
}
#endif
@@ -3845,8 +3842,8 @@ deactivate_process (proc)
emacs_close (outchannel);
#endif
- XSETINT (p->infd, -1);
- XSETINT (p->outfd, -1);
+ p->infd = -1;
+ p->outfd = -1;
#ifdef DATAGRAM_SOCKETS
if (DATAGRAM_CHAN_P (inchannel))
{
@@ -3894,8 +3891,8 @@ close_process_descs ()
process = chan_process[i];
if (!NILP (process))
{
- int in = XINT (XPROCESS (process)->infd);
- int out = XINT (XPROCESS (process)->outfd);
+ int in = XPROCESS (process)->infd;
+ int out = XPROCESS (process)->outfd;
if (in >= 0)
emacs_close (in);
if (out >= 0 && in != out)
@@ -4139,8 +4136,8 @@ server_accept_connection (server, channel)
p->filter = ps->filter;
p->command = Qnil;
p->pid = 0;
- XSETINT (p->infd, s);
- XSETINT (p->outfd, s);
+ p->infd = s;
+ p->outfd = s;
p->status = Qrun;
/* Client processes for accepted connections are not stopped initially. */
@@ -4163,12 +4160,11 @@ server_accept_connection (server, channel)
setup_process_coding_systems (proc);
p->decoding_buf = make_uninit_string (0);
- p->decoding_carryover = make_number (0);
+ p->decoding_carryover = 0;
p->encoding_buf = make_uninit_string (0);
- p->encoding_carryover = make_number (0);
p->inherit_coding_system_flag
- = (NILP (buffer) ? Qnil : ps->inherit_coding_system_flag);
+ = (NILP (buffer) ? 0 : ps->inherit_coding_system_flag);
if (!NILP (ps->log))
call3 (ps->log, server, proc,
@@ -4293,7 +4289,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
/* If wait_proc is a process to watch, set wait_channel accordingly. */
if (wait_proc != NULL)
- wait_channel = XINT (wait_proc->infd);
+ wait_channel = wait_proc->infd;
record_unwind_protect (wait_reading_process_output_unwind,
make_number (waiting_for_user_input_p));
@@ -4446,7 +4442,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
EMACS_SET_SECS_USECS (timeout, 0, 0);
- if ((select (max (max_process_desc, max_keyboard_desc) + 1,
+ if ((select (max (max (max_process_desc, max_keyboard_desc),
+ max_gpm_desc) + 1,
&Atemp,
#ifdef NON_BLOCKING_CONNECT
(num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
@@ -4477,9 +4474,9 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
XSETPROCESS (proc, wait_proc);
/* Read data from the process, until we exhaust it. */
- while (XINT (wait_proc->infd) >= 0)
+ while (wait_proc->infd >= 0)
{
- nread = read_process_output (proc, XINT (wait_proc->infd));
+ nread = read_process_output (proc, wait_proc->infd);
if (nread == 0)
break;
@@ -4509,9 +4506,9 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
if (wait_proc && just_wait_proc)
{
- if (XINT (wait_proc->infd) < 0) /* Terminated */
+ if (wait_proc->infd < 0) /* Terminated */
break;
- FD_SET (XINT (wait_proc->infd), &Available);
+ FD_SET (wait_proc->infd, &Available);
check_delay = 0;
IF_NON_BLOCKING_CONNECT (check_connect = 0);
}
@@ -4559,7 +4556,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
#ifdef ADAPTIVE_READ_BUFFERING
/* Set the timeout for adaptive read buffering if any
- process has non-nil read_output_skip and non-zero
+ process has non-zero read_output_skip and non-zero
read_output_delay, and we are not reading output for a
specific wait_channel. It is not executed if
Vprocess_adaptive_read_buffering is nil. */
@@ -4574,16 +4571,16 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
if (NILP (proc))
continue;
/* Find minimum non-zero read_output_delay among the
- processes with non-nil read_output_skip. */
- if (XINT (XPROCESS (proc)->read_output_delay) > 0)
+ processes with non-zero read_output_skip. */
+ if (XPROCESS (proc)->read_output_delay > 0)
{
check_delay--;
- if (NILP (XPROCESS (proc)->read_output_skip))
+ if (!XPROCESS (proc)->read_output_skip)
continue;
FD_CLR (channel, &Available);
- XPROCESS (proc)->read_output_skip = Qnil;
- if (XINT (XPROCESS (proc)->read_output_delay) < usecs)
- usecs = XINT (XPROCESS (proc)->read_output_delay);
+ XPROCESS (proc)->read_output_skip = 0;
+ if (XPROCESS (proc)->read_output_delay < usecs)
+ usecs = XPROCESS (proc)->read_output_delay;
}
}
EMACS_SET_SECS_USECS (timeout, 0, usecs);
@@ -4591,7 +4588,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
}
#endif
- nfds = select (max (max_process_desc, max_keyboard_desc) + 1,
+ nfds = select (max (max (max_process_desc, max_keyboard_desc),
+ max_gpm_desc) + 1,
&Available,
#ifdef NON_BLOCKING_CONNECT
(check_connect ? &Connecting : (SELECT_TYPE *)0),
@@ -4855,7 +4853,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
else
{
/* Preserve status of processes already terminated. */
- XSETINT (XPROCESS (proc)->tick, ++process_tick);
+ XPROCESS (proc)->tick = ++process_tick;
deactivate_process (proc);
if (XPROCESS (proc)->raw_status_new)
update_status (XPROCESS (proc));
@@ -4907,7 +4905,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
#endif
if (xerrno)
{
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
p->status = Fcons (Qfailed, Fcons (make_number (xerrno), Qnil));
deactivate_process (proc);
}
@@ -4920,8 +4918,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
exec_sentinel (proc, build_string ("open\n"));
if (!EQ (p->filter, Qt) && !EQ (p->command, Qt))
{
- FD_SET (XINT (p->infd), &input_wait_mask);
- FD_SET (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_SET (p->infd, &input_wait_mask);
+ FD_SET (p->infd, &non_keyboard_wait_mask);
}
}
}
@@ -4995,7 +4993,7 @@ read_process_output (proc, channel)
register struct Lisp_Process *p = XPROCESS (proc);
register int opoint;
struct coding_system *coding = proc_decode_coding_system[channel];
- int carryover = XINT (p->decoding_carryover);
+ int carryover = p->decoding_carryover;
int readmax = 4096;
#ifdef VMS
@@ -5048,9 +5046,9 @@ read_process_output (proc, channel)
{
nbytes = emacs_read (channel, chars + carryover, readmax);
#ifdef ADAPTIVE_READ_BUFFERING
- if (nbytes > 0 && !NILP (p->adaptive_read_buffering))
+ if (nbytes > 0 && p->adaptive_read_buffering)
{
- int delay = XINT (p->read_output_delay);
+ int delay = p->read_output_delay;
if (nbytes < 256)
{
if (delay < READ_OUTPUT_DELAY_MAX_MAX)
@@ -5066,10 +5064,10 @@ read_process_output (proc, channel)
if (delay == 0)
process_output_delay_count--;
}
- XSETINT (p->read_output_delay, delay);
+ p->read_output_delay = delay;
if (delay)
{
- p->read_output_skip = Qt;
+ p->read_output_skip = 1;
process_output_skip = 1;
}
}
@@ -5087,7 +5085,7 @@ read_process_output (proc, channel)
}
#endif /* not VMS */
- XSETINT (p->decoding_carryover, 0);
+ p->decoding_carryover = 0;
/* At this point, NBYTES holds number of bytes just received
(including the one in proc_buffered_char[channel]). */
@@ -5161,14 +5159,14 @@ read_process_output (proc, channel)
valid memory because p->outfd will be changed once EOF is
sent to the process. */
if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[XINT (p->outfd)])
+ && proc_encode_coding_system[p->outfd])
{
p->encode_coding_system = coding->symbol;
setup_coding_system (coding->symbol,
- proc_encode_coding_system[XINT (p->outfd)]);
- if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]);
+ if (proc_encode_coding_system[p->outfd]->eol_type
== CODING_EOL_UNDECIDED)
- proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]->eol_type
= system_eol_type;
}
}
@@ -5181,9 +5179,9 @@ read_process_output (proc, channel)
p->decoding_buf = make_uninit_string (carryover);
bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
carryover);
- XSETINT (p->decoding_carryover, carryover);
+ p->decoding_carryover = carryover;
/* Adjust the multibyteness of TEXT to that of the filter. */
- if (NILP (p->filter_multibyte) != ! STRING_MULTIBYTE (text))
+ if (!p->filter_multibyte != !STRING_MULTIBYTE (text))
text = (STRING_MULTIBYTE (text)
? Fstring_as_unibyte (text)
: Fstring_to_multibyte (text));
@@ -5275,14 +5273,14 @@ read_process_output (proc, channel)
{
p->decode_coding_system = coding->symbol;
if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[XINT (p->outfd)])
+ && proc_encode_coding_system[p->outfd])
{
p->encode_coding_system = coding->symbol;
setup_coding_system (coding->symbol,
- proc_encode_coding_system[XINT (p->outfd)]);
- if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]);
+ if (proc_encode_coding_system[p->outfd]->eol_type
== CODING_EOL_UNDECIDED)
- proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]->eol_type
= system_eol_type;
}
}
@@ -5294,7 +5292,7 @@ read_process_output (proc, channel)
p->decoding_buf = make_uninit_string (carryover);
bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
carryover);
- XSETINT (p->decoding_carryover, carryover);
+ p->decoding_carryover = carryover;
/* Adjust the multibyteness of TEXT to that of the buffer. */
if (NILP (current_buffer->enable_multibyte_characters)
@@ -5413,10 +5411,10 @@ send_process (proc, buf, len, object)
update_status (p);
if (! EQ (p->status, Qrun))
error ("Process %s not running", SDATA (p->name));
- if (XINT (p->outfd) < 0)
+ if (p->outfd < 0)
error ("Output file descriptor of %s is closed", SDATA (p->name));
- coding = proc_encode_coding_system[XINT (p->outfd)];
+ coding = proc_encode_coding_system[p->outfd];
Vlast_coding_system_used = coding->symbol;
if ((STRINGP (object) && STRING_MULTIBYTE (object))
@@ -5509,7 +5507,7 @@ send_process (proc, buf, len, object)
if (pty_max_bytes == 0)
{
#if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON)
- pty_max_bytes = fpathconf (XFASTINT (p->outfd), _PC_MAX_CANON);
+ pty_max_bytes = fpathconf (p->outfd, _PC_MAX_CANON);
if (pty_max_bytes < 0)
pty_max_bytes = 250;
#else
@@ -5531,7 +5529,7 @@ send_process (proc, buf, len, object)
/* Decide how much data we can send in one batch.
Long lines need to be split into multiple batches. */
- if (!NILP (p->pty_flag))
+ if (p->pty_flag)
{
/* Starting this at zero is always correct when not the first
iteration because the previous iteration ended by sending C-d.
@@ -5560,7 +5558,7 @@ send_process (proc, buf, len, object)
/* Send this batch, using one or more write calls. */
while (this > 0)
{
- int outfd = XINT (p->outfd);
+ int outfd = p->outfd;
old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap);
#ifdef DATAGRAM_SOCKETS
if (DATAGRAM_CHAN_P (outfd))
@@ -5580,12 +5578,12 @@ send_process (proc, buf, len, object)
{
rv = emacs_write (outfd, (char *) buf, this);
#ifdef ADAPTIVE_READ_BUFFERING
- if (XINT (p->read_output_delay) > 0
- && EQ (p->adaptive_read_buffering, Qt))
+ if (p->read_output_delay > 0
+ && p->adaptive_read_buffering == 1)
{
- XSETFASTINT (p->read_output_delay, 0);
+ p->read_output_delay = 0;
process_output_delay_count--;
- p->read_output_skip = Qnil;
+ p->read_output_skip = 0;
}
#endif
}
@@ -5628,7 +5626,7 @@ send_process (proc, buf, len, object)
if (errno == EAGAIN)
{
int flags = FWRITE;
- ioctl (XINT (p->outfd), TIOCFLUSH, &flags);
+ ioctl (p->outfd, TIOCFLUSH, &flags);
}
#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
@@ -5677,7 +5675,7 @@ send_process (proc, buf, len, object)
#endif
p->raw_status_new = 0;
p->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
deactivate_process (proc);
#ifdef VMS
error ("Error writing to process %s; closed it", SDATA (p->name));
@@ -5729,10 +5727,10 @@ send_process_object (proc, start, end)
update_status (p);
if (! EQ (p->status, Qrun))
error ("Process %s not running", SDATA (p->name));
- if (XINT (p->outfd) < 0)
+ if (p->outfd < 0)
error ("Output file descriptor of %s is closed", SDATA (p->name));
- coding = proc_encode_coding_system[XINT (p->outfd)];
+ coding = proc_encode_coding_system[p->outfd];
if (! EQ (coding->symbol, p->encode_coding_system))
/* The coding system for encoding was changed to raw-text
because we sent a unibyte text previously. Now we are
@@ -5821,7 +5819,7 @@ emacs_get_tty_pgrp (p)
int gid = -1;
#ifdef TIOCGPGRP
- if (ioctl (XINT (p->infd), TIOCGPGRP, &gid) == -1 && ! NILP (p->tty_name))
+ if (ioctl (p->infd, TIOCGPGRP, &gid) == -1 && ! NILP (p->tty_name))
{
int fd;
/* Some OS:es (Solaris 8/9) does not allow TIOCGPGRP from the
@@ -5859,7 +5857,7 @@ return t unconditionally. */)
if (!EQ (p->childp, Qt))
error ("Process %s is not a subprocess",
SDATA (p->name));
- if (XINT (p->infd) < 0)
+ if (p->infd < 0)
error ("Process %s is not active",
SDATA (p->name));
@@ -5902,11 +5900,11 @@ process_send_signal (process, signo, current_group, nomsg)
if (!EQ (p->childp, Qt))
error ("Process %s is not a subprocess",
SDATA (p->name));
- if (XINT (p->infd) < 0)
+ if (p->infd < 0)
error ("Process %s is not active",
SDATA (p->name));
- if (NILP (p->pty_flag))
+ if (!p->pty_flag)
current_group = Qnil;
/* If we are using pgrps, get a pgrp number and make it negative. */
@@ -5925,7 +5923,7 @@ process_send_signal (process, signo, current_group, nomsg)
struct termios t;
cc_t *sig_char = NULL;
- tcgetattr (XINT (p->infd), &t);
+ tcgetattr (p->infd, &t);
switch (signo)
{
@@ -5965,16 +5963,16 @@ process_send_signal (process, signo, current_group, nomsg)
switch (signo)
{
case SIGINT:
- ioctl (XINT (p->infd), TIOCGETC, &c);
+ ioctl (p->infd, TIOCGETC, &c);
send_process (proc, &c.t_intrc, 1, Qnil);
return;
case SIGQUIT:
- ioctl (XINT (p->infd), TIOCGETC, &c);
+ ioctl (p->infd, TIOCGETC, &c);
send_process (proc, &c.t_quitc, 1, Qnil);
return;
#ifdef SIGTSTP
case SIGTSTP:
- ioctl (XINT (p->infd), TIOCGLTC, &lc);
+ ioctl (p->infd, TIOCGLTC, &lc);
send_process (proc, &lc.t_suspc, 1, Qnil);
return;
#endif /* ! defined (SIGTSTP) */
@@ -5989,16 +5987,16 @@ process_send_signal (process, signo, current_group, nomsg)
switch (signo)
{
case SIGINT:
- ioctl (XINT (p->infd), TCGETA, &t);
+ ioctl (p->infd, TCGETA, &t);
send_process (proc, &t.c_cc[VINTR], 1, Qnil);
return;
case SIGQUIT:
- ioctl (XINT (p->infd), TCGETA, &t);
+ ioctl (p->infd, TCGETA, &t);
send_process (proc, &t.c_cc[VQUIT], 1, Qnil);
return;
#ifdef SIGTSTP
case SIGTSTP:
- ioctl (XINT (p->infd), TCGETA, &t);
+ ioctl (p->infd, TCGETA, &t);
send_process (proc, &t.c_cc[VSWTCH], 1, Qnil);
return;
#endif /* ! defined (SIGTSTP) */
@@ -6056,7 +6054,7 @@ process_send_signal (process, signo, current_group, nomsg)
case SIGCONT:
p->raw_status_new = 0;
p->status = Qrun;
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
if (!nomsg)
status_notify (NULL);
break;
@@ -6076,7 +6074,7 @@ process_send_signal (process, signo, current_group, nomsg)
sys$forcex (&(p->pid), 0, 1);
whoosh:
#endif
- flush_pending_output (XINT (p->infd));
+ flush_pending_output (p->infd);
break;
}
@@ -6093,7 +6091,7 @@ process_send_signal (process, signo, current_group, nomsg)
#ifdef TIOCSIGSEND
if (!NILP (current_group))
{
- if (ioctl (XINT (p->infd), TIOCSIGSEND, signo) == -1)
+ if (ioctl (p->infd, TIOCSIGSEND, signo) == -1)
EMACS_KILLPG (gid, signo);
}
else
@@ -6159,10 +6157,10 @@ If PROCESS is a network process, inhibit handling of incoming traffic. */)
p = XPROCESS (process);
if (NILP (p->command)
- && XINT (p->infd) >= 0)
+ && p->infd >= 0)
{
- FD_CLR (XINT (p->infd), &input_wait_mask);
- FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_CLR (p->infd, &input_wait_mask);
+ FD_CLR (p->infd, &non_keyboard_wait_mask);
}
p->command = Qt;
return process;
@@ -6190,11 +6188,11 @@ If PROCESS is a network process, resume handling of incoming traffic. */)
p = XPROCESS (process);
if (EQ (p->command, Qt)
- && XINT (p->infd) >= 0
+ && p->infd >= 0
&& (!EQ (p->filter, Qt) || EQ (p->status, Qlisten)))
{
- FD_SET (XINT (p->infd), &input_wait_mask);
- FD_SET (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_SET (p->infd, &input_wait_mask);
+ FD_SET (p->infd, &non_keyboard_wait_mask);
}
p->command = Qnil;
return process;
@@ -6391,7 +6389,7 @@ text to PROCESS after you call this function. */)
return process;
proc = get_process (process);
- coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
+ coding = proc_encode_coding_system[XPROCESS (proc)->outfd];
/* Make sure the process is really alive. */
if (XPROCESS (proc)->raw_status_new)
@@ -6408,7 +6406,7 @@ text to PROCESS after you call this function. */)
#ifdef VMS
send_process (proc, "\032", 1, Qnil); /* ^z */
#else
- if (!NILP (XPROCESS (proc)->pty_flag))
+ if (XPROCESS (proc)->pty_flag)
send_process (proc, "\004", 1, Qnil);
else
{
@@ -6420,18 +6418,18 @@ text to PROCESS after you call this function. */)
(In some old system, shutdown to socketpair doesn't work.
Then we just can't win.) */
if (XPROCESS (proc)->pid == 0
- || XINT (XPROCESS (proc)->outfd) == XINT (XPROCESS (proc)->infd))
- shutdown (XINT (XPROCESS (proc)->outfd), 1);
+ || XPROCESS (proc)->outfd == XPROCESS (proc)->infd)
+ shutdown (XPROCESS (proc)->outfd, 1);
/* In case of socketpair, outfd == infd, so don't close it. */
- if (XINT (XPROCESS (proc)->outfd) != XINT (XPROCESS (proc)->infd))
- emacs_close (XINT (XPROCESS (proc)->outfd));
+ if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd)
+ emacs_close (XPROCESS (proc)->outfd);
#else /* not HAVE_SHUTDOWN */
- emacs_close (XINT (XPROCESS (proc)->outfd));
+ emacs_close (XPROCESS (proc)->outfd);
#endif /* not HAVE_SHUTDOWN */
new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0);
if (new_outfd < 0)
abort ();
- old_outfd = XINT (XPROCESS (proc)->outfd);
+ old_outfd = XPROCESS (proc)->outfd;
if (!proc_encode_coding_system[new_outfd])
proc_encode_coding_system[new_outfd]
@@ -6442,7 +6440,7 @@ text to PROCESS after you call this function. */)
bzero (proc_encode_coding_system[old_outfd],
sizeof (struct coding_system));
- XSETINT (XPROCESS (proc)->outfd, new_outfd);
+ XPROCESS (proc)->outfd = new_outfd;
}
#endif /* VMS */
return process;
@@ -6465,7 +6463,7 @@ kill_buffer_processes (buffer)
{
if (NETCONN_P (proc))
Fdelete_process (proc);
- else if (XINT (XPROCESS (proc)->infd) >= 0)
+ else if (XPROCESS (proc)->infd >= 0)
process_send_signal (proc, SIGHUP, Qnil, 1);
}
}
@@ -6595,21 +6593,21 @@ sigchld_handler (signo)
union { int i; WAITTYPE wt; } u;
int clear_desc_flag = 0;
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
u.wt = w;
p->raw_status = u.i;
p->raw_status_new = 1;
/* If process has terminated, stop waiting for its output. */
if ((WIFSIGNALED (w) || WIFEXITED (w))
- && XINT (p->infd) >= 0)
+ && p->infd >= 0)
clear_desc_flag = 1;
/* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */
if (clear_desc_flag)
{
- FD_CLR (XINT (p->infd), &input_wait_mask);
- FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_CLR (p->infd, &input_wait_mask);
+ FD_CLR (p->infd, &non_keyboard_wait_mask);
}
/* Tell wait_reading_process_output that it needs to wake up and
@@ -6786,18 +6784,18 @@ status_notify (deleting_process)
proc = Fcdr (Fcar (tail));
p = XPROCESS (proc);
- if (XINT (p->tick) != XINT (p->update_tick))
+ if (p->tick != p->update_tick)
{
- XSETINT (p->update_tick, XINT (p->tick));
+ p->update_tick = p->tick;
/* If process is still active, read any output that remains. */
while (! EQ (p->filter, Qt)
&& ! EQ (p->status, Qconnect)
&& ! EQ (p->status, Qlisten)
&& ! EQ (p->command, Qt) /* Network process not stopped. */
- && XINT (p->infd) >= 0
+ && p->infd >= 0
&& p != deleting_process
- && read_process_output (proc, XINT (p->infd)) > 0);
+ && read_process_output (proc, p->infd) > 0);
buffer = p->buffer;
@@ -6824,7 +6822,7 @@ status_notify (deleting_process)
So set p->update_tick again
so that an error in the sentinel will not cause
this code to be run again. */
- XSETINT (p->update_tick, XINT (p->tick));
+ p->update_tick = p->tick;
/* Now output the message suitably. */
if (!NILP (p->sentinel))
exec_sentinel (proc, msg);
@@ -6897,9 +6895,9 @@ encode subprocess input. */)
CHECK_PROCESS (process);
p = XPROCESS (process);
- if (XINT (p->infd) < 0)
+ if (p->infd < 0)
error ("Input file descriptor of %s closed", SDATA (p->name));
- if (XINT (p->outfd) < 0)
+ if (p->outfd < 0)
error ("Output file descriptor of %s closed", SDATA (p->name));
Fcheck_coding_system (decoding);
Fcheck_coding_system (encoding);
@@ -6936,7 +6934,7 @@ suppressed. */)
CHECK_PROCESS (process);
p = XPROCESS (process);
- p->filter_multibyte = flag;
+ p->filter_multibyte = !NILP (flag);
setup_process_coding_systems (process);
return Qnil;
@@ -6953,7 +6951,7 @@ DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p,
CHECK_PROCESS (process);
p = XPROCESS (process);
- return (NILP (p->filter_multibyte) ? Qnil : Qt);
+ return (p->filter_multibyte ? Qt : Qnil);
}
@@ -6978,6 +6976,21 @@ add_keyboard_wait_descriptor (desc)
max_keyboard_desc = desc;
}
+static int add_gpm_wait_descriptor_called_flag;
+
+void
+add_gpm_wait_descriptor (desc)
+ int desc;
+{
+ if (! add_gpm_wait_descriptor_called_flag)
+ FD_CLR (0, &input_wait_mask);
+ add_gpm_wait_descriptor_called_flag = 1;
+ FD_SET (desc, &input_wait_mask);
+ FD_SET (desc, &gpm_wait_mask);
+ if (desc > max_gpm_desc)
+ max_gpm_desc = desc;
+}
+
/* From now on, do not expect DESC to give keyboard input. */
void
@@ -6993,10 +7006,29 @@ delete_keyboard_wait_descriptor (desc)
if (desc == max_keyboard_desc)
for (fd = 0; fd < lim; fd++)
if (FD_ISSET (fd, &input_wait_mask)
- && !FD_ISSET (fd, &non_keyboard_wait_mask))
+ && !FD_ISSET (fd, &non_keyboard_wait_mask)
+ && !FD_ISSET (fd, &gpm_wait_mask))
max_keyboard_desc = fd;
}
+void
+delete_gpm_wait_descriptor (desc)
+ int desc;
+{
+ int fd;
+ int lim = max_gpm_desc;
+
+ FD_CLR (desc, &input_wait_mask);
+ FD_CLR (desc, &non_process_wait_mask);
+
+ if (desc == max_gpm_desc)
+ for (fd = 0; fd < lim; fd++)
+ if (FD_ISSET (fd, &input_wait_mask)
+ && !FD_ISSET (fd, &non_keyboard_wait_mask)
+ && !FD_ISSET (fd, &non_process_wait_mask))
+ max_gpm_desc = fd;
+}
+
/* Return nonzero if *MASK has a bit set
that corresponds to one of the keyboard input descriptors. */
diff --git a/src/process.h b/src/process.h
index 6fb783e72b0..79875564766 100644
--- a/src/process.h
+++ b/src/process.h
@@ -36,10 +36,6 @@ struct Lisp_Process
{
EMACS_INT size;
struct Lisp_Vector *v_next;
- /* Descriptor by which we read from this process */
- Lisp_Object infd;
- /* Descriptor by which we write to this process */
- Lisp_Object outfd;
/* Name of subprocess terminal. */
Lisp_Object tty_name;
/* Name of this process */
@@ -64,61 +60,65 @@ struct Lisp_Process
Lisp_Object plist;
/* Marker set to end of last buffer-inserted output from this process */
Lisp_Object mark;
- /* Non-nil means kill silently if Emacs is exited.
- This is the inverse of the `query-on-exit' flag. */
- Lisp_Object kill_without_query;
/* Symbol indicating status of process.
This may be a symbol: run, open, or closed.
Or it may be a list, whose car is stop, exit or signal
and whose cdr is a pair (EXIT_CODE . COREDUMP_FLAG)
or (SIGNAL_NUMBER . COREDUMP_FLAG). */
Lisp_Object status;
- /* Non-nil if communicating through a pty. */
- Lisp_Object pty_flag;
- /* Event-count of last event in which this process changed status. */
- Lisp_Object tick;
- /* Event-count of last such event reported. */
- Lisp_Object update_tick;
/* Coding-system for decoding the input from this process. */
Lisp_Object decode_coding_system;
/* Working buffer for decoding. */
Lisp_Object decoding_buf;
- /* Size of carryover in decoding. */
- Lisp_Object decoding_carryover;
/* Coding-system for encoding the output to this process. */
Lisp_Object encode_coding_system;
/* Working buffer for encoding. */
Lisp_Object encoding_buf;
- /* Size of carryover in encoding. */
- Lisp_Object encoding_carryover;
- /* Flag to set coding-system of the process buffer from the
- coding_system used to decode process output. */
- Lisp_Object inherit_coding_system_flag;
- /* Flat to decide the multibyteness of a string given to the
- filter (if any). It is initialized to the value of
- `default-enable-multibyte-characters' when the process is
- generated, and can be changed by the function
- `set-process-fileter-multibyte'. */
- Lisp_Object filter_multibyte;
- /* Should we delay reading output from this process.
- Initialized from `Vprocess_adaptive_read_buffering'. */
- Lisp_Object adaptive_read_buffering;
- /* Hysteresis to try to read process output in larger blocks.
- On some systems, e.g. GNU/Linux, Emacs is seen as
- an interactive app also when reading process output, meaning
- that process output can be read in as little as 1 byte at a
- time. Value is micro-seconds to delay reading output from
- this process. Range is 0 .. 50000. */
- Lisp_Object read_output_delay;
- /* Skip reading this process on next read. */
- Lisp_Object read_output_skip;
/* After this point, there are no Lisp_Objects any more. */
+ /* alloc.c assumes that `pid' is the first such non-Lisp slot. */
/* Number of this process.
allocate_process assumes this is the first non-Lisp_Object field.
A value 0 is used for pseudo-processes such as network connections. */
pid_t pid;
+ /* Descriptor by which we read from this process */
+ int infd;
+ /* Descriptor by which we write to this process */
+ int outfd;
+ /* Event-count of last event in which this process changed status. */
+ int tick;
+ /* Event-count of last such event reported. */
+ int update_tick;
+ /* Size of carryover in decoding. */
+ int decoding_carryover;
+ /* Hysteresis to try to read process output in larger blocks.
+ On some systems, e.g. GNU/Linux, Emacs is seen as
+ an interactive app also when reading process output, meaning
+ that process output can be read in as little as 1 byte at a
+ time. Value is micro-seconds to delay reading output from
+ this process. Range is 0 .. 50000. */
+ int read_output_delay;
+ /* Should we delay reading output from this process.
+ Initialized from `Vprocess_adaptive_read_buffering'.
+ 0 = nil, 1 = t, 2 = other. */
+ int adaptive_read_buffering : 2;
+ /* Skip reading this process on next read. */
+ int read_output_skip : 1;
+ /* Non-nil means kill silently if Emacs is exited.
+ This is the inverse of the `query-on-exit' flag. */
+ int kill_without_query : 1;
+ /* Non-nil if communicating through a pty. */
+ int pty_flag : 1;
+ /* Flag to set coding-system of the process buffer from the
+ coding_system used to decode process output. */
+ int inherit_coding_system_flag : 1;
+ /* Flag to decide the multibyteness of a string given to the
+ filter (if any). It is initialized to the value of
+ `default-enable-multibyte-characters' when the process is
+ generated, and can be changed by the function
+ `set-process-filter-multibyte'. */
+ int filter_multibyte : 1;
/* Record the process status in the raw form in which it comes from `wait'.
This is to avoid consing in a signal handler. The `raw_status_new'
flag indicates that `raw_status' contains a new status that still
diff --git a/src/regex.c b/src/regex.c
index 095afa1c465..1e80b9bbeef 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -3,12 +3,11 @@
internationalization features.)
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007 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, or (at your option)
+ the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
@@ -2483,11 +2482,6 @@ regex_compile (pattern, size, syntax, bufp)
last -- ends with a forward jump of this sort. */
unsigned char *fixup_alt_jump = 0;
- /* Counts open-groups as they are encountered. Remembered for the
- matching close-group on the compile stack, so the same register
- number is put in the stop_memory as the start_memory. */
- regnum_t regnum = 0;
-
/* Work area for range table of charset. */
struct range_table_work_area range_table_work;
@@ -3124,28 +3118,54 @@ regex_compile (pattern, size, syntax, bufp)
handle_open:
{
int shy = 0;
+ regnum_t regnum = 0;
if (p+1 < pend)
{
/* Look for a special (?...) construct */
if ((syntax & RE_SHY_GROUPS) && *p == '?')
{
PATFETCH (c); /* Gobble up the '?'. */
- PATFETCH (c);
- switch (c)
+ while (!shy)
{
- case ':': shy = 1; break;
- default:
- /* Only (?:...) is supported right now. */
- FREE_STACK_RETURN (REG_BADPAT);
+ PATFETCH (c);
+ switch (c)
+ {
+ case ':': shy = 1; break;
+ case '0':
+ /* An explicitly specified regnum must start
+ with non-0. */
+ if (regnum == 0)
+ FREE_STACK_RETURN (REG_BADPAT);
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ regnum = 10*regnum + (c - '0'); break;
+ default:
+ /* Only (?:...) is supported right now. */
+ FREE_STACK_RETURN (REG_BADPAT);
+ }
}
}
}
if (!shy)
- {
- bufp->re_nsub++;
- regnum++;
+ regnum = ++bufp->re_nsub;
+ else if (regnum)
+ { /* It's actually not shy, but explicitly numbered. */
+ shy = 0;
+ if (regnum > bufp->re_nsub)
+ bufp->re_nsub = regnum;
+ else if (regnum > bufp->re_nsub
+ /* Ideally, we'd want to check that the specified
+ group can't have matched (i.e. all subgroups
+ using the same regnum are in other branches of
+ OR patterns), but we don't currently keep track
+ of enough info to do that easily. */
+ || group_in_compile_stack (compile_stack, regnum))
+ FREE_STACK_RETURN (REG_BADPAT);
}
+ else
+ /* It's really shy. */
+ regnum = - bufp->re_nsub;
if (COMPILE_STACK_FULL)
{
@@ -3164,12 +3184,11 @@ regex_compile (pattern, size, syntax, bufp)
COMPILE_STACK_TOP.fixup_alt_jump
= fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
- COMPILE_STACK_TOP.regnum = shy ? -regnum : regnum;
+ COMPILE_STACK_TOP.regnum = regnum;
- /* Do not push a
- start_memory for groups beyond the last one we can
- represent in the compiled pattern. */
- if (regnum <= MAX_REGNUM && !shy)
+ /* Do not push a start_memory for groups beyond the last one
+ we can represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM && regnum > 0)
BUF_PUSH_2 (start_memory, regnum);
compile_stack.avail++;
@@ -3214,7 +3233,7 @@ regex_compile (pattern, size, syntax, bufp)
/* We don't just want to restore into `regnum', because
later groups should continue to be numbered higher,
as in `(ab)c(de)' -- the second group is #2. */
- regnum_t this_group_regnum;
+ regnum_t regnum;
compile_stack.avail--;
begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
@@ -3223,7 +3242,7 @@ regex_compile (pattern, size, syntax, bufp)
? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
: 0;
laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
- this_group_regnum = COMPILE_STACK_TOP.regnum;
+ regnum = COMPILE_STACK_TOP.regnum;
/* If we've reached MAX_REGNUM groups, then this open
won't actually generate any code, so we'll have to
clear pending_exact explicitly. */
@@ -3231,8 +3250,8 @@ regex_compile (pattern, size, syntax, bufp)
/* We're at the end of the group, so now we know how many
groups were inside this one. */
- if (this_group_regnum <= MAX_REGNUM && this_group_regnum > 0)
- BUF_PUSH_2 (stop_memory, this_group_regnum);
+ if (regnum <= MAX_REGNUM && regnum > 0)
+ BUF_PUSH_2 (stop_memory, regnum);
}
break;
@@ -3558,8 +3577,9 @@ regex_compile (pattern, size, syntax, bufp)
reg = c - '0';
- /* Can't back reference to a subexpression before its end. */
- if (reg > regnum || group_in_compile_stack (compile_stack, reg))
+ if (reg > bufp->re_nsub || reg < 1
+ /* Can't back reference to a subexp before its end. */
+ || group_in_compile_stack (compile_stack, reg))
FREE_STACK_RETURN (REG_ESUBREG);
laststart = b;
diff --git a/src/regex.h b/src/regex.h
index 580b1369489..dd57ba36f57 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -7,7 +7,7 @@
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, or (at your option)
+ the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
diff --git a/src/search.c b/src/search.c
index c74b1071237..4ae3a68b304 100644
--- a/src/search.c
+++ b/src/search.c
@@ -92,6 +92,11 @@ Lisp_Object Qsearch_failed;
Lisp_Object Vsearch_spaces_regexp;
+/* If non-nil, the match data will not be changed during call to
+ searching or matching functions. This variable is for internal use
+ only. */
+Lisp_Object Vinhibit_changing_match_data;
+
static void set_search_regs ();
static void save_search_regs ();
static int simple_search ();
@@ -321,7 +326,9 @@ looking_at_1 (string, posix)
= current_buffer->case_eqv_table;
CHECK_STRING (string);
- bufp = compile_pattern (string, &search_regs,
+ bufp = compile_pattern (string,
+ (NILP (Vinhibit_changing_match_data)
+ ? &search_regs : NULL),
(!NILP (current_buffer->case_fold_search)
? current_buffer->case_canon_table : Qnil),
posix,
@@ -352,7 +359,9 @@ looking_at_1 (string, posix)
re_match_object = Qnil;
i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2,
- PT_BYTE - BEGV_BYTE, &search_regs,
+ PT_BYTE - BEGV_BYTE,
+ (NILP (Vinhibit_changing_match_data)
+ ? &search_regs : NULL),
ZV_BYTE - BEGV_BYTE);
immediate_quit = 0;
@@ -360,7 +369,7 @@ looking_at_1 (string, posix)
matcher_overflow ();
val = (0 <= i ? Qt : Qnil);
- if (i >= 0)
+ if (NILP (Vinhibit_changing_match_data) && i >= 0)
for (i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
{
@@ -369,7 +378,11 @@ looking_at_1 (string, posix)
search_regs.end[i]
= BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
}
- XSETBUFFER (last_thing_searched, current_buffer);
+
+ /* Set last_thing_searched only when match data is changed. */
+ if (NILP (Vinhibit_changing_match_data))
+ XSETBUFFER (last_thing_searched, current_buffer);
+
return val;
}
@@ -431,7 +444,9 @@ string_match_1 (regexp, string, start, posix)
XCHAR_TABLE (current_buffer->case_canon_table)->extras[2]
= current_buffer->case_eqv_table;
- bufp = compile_pattern (regexp, &search_regs,
+ bufp = compile_pattern (regexp,
+ (NILP (Vinhibit_changing_match_data)
+ ? &search_regs : NULL),
(!NILP (current_buffer->case_fold_search)
? current_buffer->case_canon_table : Qnil),
posix,
@@ -442,21 +457,27 @@ string_match_1 (regexp, string, start, posix)
val = re_search (bufp, (char *) SDATA (string),
SBYTES (string), pos_byte,
SBYTES (string) - pos_byte,
- &search_regs);
+ (NILP (Vinhibit_changing_match_data)
+ ? &search_regs : NULL));
immediate_quit = 0;
- last_thing_searched = Qt;
+
+ /* Set last_thing_searched only when match data is changed. */
+ if (NILP (Vinhibit_changing_match_data))
+ last_thing_searched = Qt;
+
if (val == -2)
matcher_overflow ();
if (val < 0) return Qnil;
- for (i = 0; i < search_regs.num_regs; i++)
- if (search_regs.start[i] >= 0)
- {
- search_regs.start[i]
- = string_byte_to_char (string, search_regs.start[i]);
- search_regs.end[i]
- = string_byte_to_char (string, search_regs.end[i]);
- }
+ if (NILP (Vinhibit_changing_match_data))
+ for (i = 0; i < search_regs.num_regs; i++)
+ if (search_regs.start[i] >= 0)
+ {
+ search_regs.start[i]
+ = string_byte_to_char (string, search_regs.start[i]);
+ search_regs.end[i]
+ = string_byte_to_char (string, search_regs.end[i]);
+ }
return make_number (string_byte_to_char (string, val));
}
@@ -1074,6 +1095,11 @@ do \
} \
while (0)
+/* Only used in search_buffer, to record the end position of the match
+ when searching regexps and SEARCH_REGS should not be changed
+ (i.e. Vinhibit_changing_match_data is non-nil). */
+static struct re_registers search_regs_1;
+
static int
search_buffer (string, pos, pos_byte, lim, lim_byte, n,
RE, trt, inverse_trt, posix)
@@ -1109,7 +1135,10 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
int s1, s2;
struct re_pattern_buffer *bufp;
- bufp = compile_pattern (string, &search_regs, trt, posix,
+ bufp = compile_pattern (string,
+ (NILP (Vinhibit_changing_match_data)
+ ? &search_regs : &search_regs_1),
+ trt, posix,
!NILP (current_buffer->enable_multibyte_characters));
immediate_quit = 1; /* Quit immediately if user types ^G,
@@ -1142,7 +1171,8 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
int val;
val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
pos_byte - BEGV_BYTE, lim_byte - pos_byte,
- &search_regs,
+ (NILP (Vinhibit_changing_match_data)
+ ? &search_regs : &search_regs_1),
/* Don't allow match past current point */
pos_byte - BEGV_BYTE);
if (val == -2)
@@ -1151,18 +1181,27 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
}
if (val >= 0)
{
- pos_byte = search_regs.start[0] + BEGV_BYTE;
- for (i = 0; i < search_regs.num_regs; i++)
- if (search_regs.start[i] >= 0)
- {
- search_regs.start[i]
- = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
- search_regs.end[i]
- = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
- }
- XSETBUFFER (last_thing_searched, current_buffer);
- /* Set pos to the new position. */
- pos = search_regs.start[0];
+ if (NILP (Vinhibit_changing_match_data))
+ {
+ pos_byte = search_regs.start[0] + BEGV_BYTE;
+ for (i = 0; i < search_regs.num_regs; i++)
+ if (search_regs.start[i] >= 0)
+ {
+ search_regs.start[i]
+ = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
+ search_regs.end[i]
+ = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
+ }
+ XSETBUFFER (last_thing_searched, current_buffer);
+ /* Set pos to the new position. */
+ pos = search_regs.start[0];
+ }
+ else
+ {
+ pos_byte = search_regs_1.start[0] + BEGV_BYTE;
+ /* Set pos to the new position. */
+ pos = BYTE_TO_CHAR (search_regs_1.start[0] + BEGV_BYTE);
+ }
}
else
{
@@ -1176,7 +1215,8 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
int val;
val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
pos_byte - BEGV_BYTE, lim_byte - pos_byte,
- &search_regs,
+ (NILP (Vinhibit_changing_match_data)
+ ? &search_regs : &search_regs_1),
lim_byte - BEGV_BYTE);
if (val == -2)
{
@@ -1184,17 +1224,25 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
}
if (val >= 0)
{
- pos_byte = search_regs.end[0] + BEGV_BYTE;
- for (i = 0; i < search_regs.num_regs; i++)
- if (search_regs.start[i] >= 0)
- {
- search_regs.start[i]
- = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
- search_regs.end[i]
- = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
- }
- XSETBUFFER (last_thing_searched, current_buffer);
- pos = search_regs.end[0];
+ if (NILP (Vinhibit_changing_match_data))
+ {
+ pos_byte = search_regs.end[0] + BEGV_BYTE;
+ for (i = 0; i < search_regs.num_regs; i++)
+ if (search_regs.start[i] >= 0)
+ {
+ search_regs.start[i]
+ = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
+ search_regs.end[i]
+ = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
+ }
+ XSETBUFFER (last_thing_searched, current_buffer);
+ pos = search_regs.end[0];
+ }
+ else
+ {
+ pos_byte = search_regs_1.end[0] + BEGV_BYTE;
+ pos = BYTE_TO_CHAR (search_regs_1.end[0] + BEGV_BYTE);
+ }
}
else
{
@@ -1926,7 +1974,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
cursor += dirlen - i - direction; /* fix cursor */
if (i + direction == 0)
{
- int position;
+ int position, start, end;
cursor -= direction;
@@ -1934,11 +1982,24 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
? 1 - len_byte : 0);
set_search_regs (position, len_byte);
+ if (NILP (Vinhibit_changing_match_data))
+ {
+ start = search_regs.start[0];
+ end = search_regs.end[0];
+ }
+ else
+ /* If Vinhibit_changing_match_data is non-nil,
+ search_regs will not be changed. So let's
+ compute start and end here. */
+ {
+ start = BYTE_TO_CHAR (position);
+ end = BYTE_TO_CHAR (position + len_byte);
+ }
+
if ((n -= direction) != 0)
cursor += dirlen; /* to resume search */
else
- return ((direction > 0)
- ? search_regs.end[0] : search_regs.start[0]);
+ return direction > 0 ? end : start;
}
else
cursor += stride_for_teases; /* <sigh> we lose - */
@@ -2003,18 +2064,30 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
pos_byte += dirlen - i- direction;
if (i + direction == 0)
{
- int position;
+ int position, start, end;
pos_byte -= direction;
position = pos_byte + ((direction > 0) ? 1 - len_byte : 0);
-
set_search_regs (position, len_byte);
+ if (NILP (Vinhibit_changing_match_data))
+ {
+ start = search_regs.start[0];
+ end = search_regs.end[0];
+ }
+ else
+ /* If Vinhibit_changing_match_data is non-nil,
+ search_regs will not be changed. So let's
+ compute start and end here. */
+ {
+ start = BYTE_TO_CHAR (position);
+ end = BYTE_TO_CHAR (position + len_byte);
+ }
+
if ((n -= direction) != 0)
pos_byte += dirlen; /* to resume search */
else
- return ((direction > 0)
- ? search_regs.end[0] : search_regs.start[0]);
+ return direction > 0 ? end : start;
}
else
pos_byte += stride_for_teases;
@@ -2037,6 +2110,9 @@ set_search_regs (beg_byte, nbytes)
{
int i;
+ if (!NILP (Vinhibit_changing_match_data))
+ return;
+
/* Make sure we have registers in which to store
the match position. */
if (search_regs.num_regs == 0)
@@ -2095,7 +2171,7 @@ wordify (string)
if (SYNTAX (prev_c) == Sword)
word_count++;
if (!word_count)
- return empty_string;
+ return empty_unibyte_string;
adjust = - punct_count + 5 * (word_count - 1) + 4;
if (STRING_MULTIBYTE (string))
@@ -3167,6 +3243,13 @@ or other such regexp constructs are not replaced with this.
A value of nil (which is the normal value) means treat spaces literally. */);
Vsearch_spaces_regexp = Qnil;
+ DEFVAR_LISP ("inhibit-changing-match-data", &Vinhibit_changing_match_data,
+ doc: /* Internal use only.
+If non-nil, the match data will not be changed during call to searching or
+matching functions, such as `looking-at', `string-match', `re-search-forward'
+etc. */);
+ Vinhibit_changing_match_data = Qnil;
+
defsubr (&Slooking_at);
defsubr (&Sposix_looking_at);
defsubr (&Sstring_match);
diff --git a/src/sunfns.c b/src/sunfns.c
index 8aedfa07010..86e64cbcdcc 100644
--- a/src/sunfns.c
+++ b/src/sunfns.c
@@ -287,7 +287,7 @@ sel_read (sel, file)
register int i, n;
register char *cp;
- Current_Selection = make_string ("", 0);
+ Current_Selection = empty_unibyte_string;
if (sel->sel_items <= 0)
return (0);
cp = (char *) malloc(sel->sel_items);
diff --git a/src/sysdep.c b/src/sysdep.c
index 408ccf2131a..f2170dabed7 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1675,6 +1675,14 @@ init_sys_modes ()
old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
fcntl (input_fd, F_SETOWN, getpid ());
init_sigio (input_fd);
+#ifdef HAVE_GPM
+ if (term_gpm)
+ {
+ fcntl (gpm_fd, F_SETOWN, getpid ());
+ fcntl (gpm_fd, F_SETFL, fcntl (gpm_fd, F_GETFL, 0) | O_NONBLOCK);
+ init_sigio (gpm_fd);
+ }
+#endif /* HAVE_GPM */
}
#endif /* F_GETOWN */
#endif /* F_SETOWN_BUG */
diff --git a/src/term.c b/src/term.c
index 0648b960a6d..798fc37ca46 100644
--- a/src/term.c
+++ b/src/term.c
@@ -25,6 +25,9 @@ Boston, MA 02110-1301, USA. */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#include "termchar.h"
#include "termopts.h"
@@ -39,6 +42,7 @@ Boston, MA 02110-1301, USA. */
#include "window.h"
#include "keymap.h"
#include "blockinput.h"
+#include "intervals.h"
/* For now, don't try to include termcap.h. On some systems,
configure finds a non-standard termcap.h that the main build
@@ -144,25 +148,6 @@ int (*read_socket_hook) P_ ((int, int, struct input_event *));
void (*frame_up_to_date_hook) P_ ((struct frame *));
-/* Return the current position of the mouse.
-
- Set *f to the frame the mouse is in, or zero if the mouse is in no
- Emacs frame. If it is set to zero, all the other arguments are
- garbage.
-
- If the motion started in a scroll bar, set *bar_window to the
- scroll bar's window, *part to the part the mouse is currently over,
- *x to the position of the mouse along the scroll bar, and *y to the
- overall length of the scroll bar.
-
- Otherwise, set *bar_window to Qnil, and *x and *y to the column and
- row of the character cell the mouse is over.
-
- Set *time to the time the mouse was at the returned position.
-
- This should clear mouse_moved until the next motion
- event arrives. */
-
void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
Lisp_Object *bar_window,
enum scroll_bar_part *part,
@@ -413,6 +398,9 @@ static int tty_cursor_hidden;
char *tparam ();
extern char *tgetstr ();
+
+static void term_clear_mouse_face ();
+static void term_mouse_highlight (struct frame *f, int x, int y);
#ifdef WINDOWSNT
@@ -426,6 +414,28 @@ extern char *tgetstr ();
#define FRAME_TERMCAP_P(_f_) 0
#endif /* WINDOWSNT */
+#ifdef HAVE_GPM
+#include <sys/fcntl.h>
+#include "buffer.h"
+
+/* Nonzero means mouse is enabled on Linux console. */
+int term_gpm = 0;
+
+/* These variables describe the range of text currently shown in its
+ mouse-face, together with the window they apply to. As long as
+ the mouse stays within this range, we need not redraw anything on
+ its account. Rows and columns are glyph matrix positions in
+ MOUSE_FACE_WINDOW. */
+static int mouse_face_beg_row, mouse_face_beg_col;
+static int mouse_face_end_row, mouse_face_end_col;
+static int mouse_face_past_end;
+static Lisp_Object Qmouse_face_window;
+static int mouse_face_face_id;
+
+static int pos_x, pos_y;
+static int last_mouse_x, last_mouse_y;
+#endif /* HAVE_GPM */
+
void
ring_bell ()
{
@@ -1010,6 +1020,65 @@ write_glyphs (string, len)
cmcheckmagic ();
}
+void
+write_glyphs_with_face (string, len, face_id)
+ register struct glyph *string;
+ register int len, face_id;
+{
+ struct frame *sf = XFRAME (selected_frame);
+ struct frame *f = updating_frame ? updating_frame : sf;
+ unsigned char *conversion_buffer;
+ struct coding_system *coding;
+
+ turn_off_insert ();
+ tty_hide_cursor ();
+
+ /* Don't dare write in last column of bottom line, if Auto-Wrap,
+ since that would scroll the whole frame on some terminals. */
+
+ if (AutoWrap
+ && curY + 1 == FRAME_LINES (sf)
+ && (curX + len) == FRAME_COLS (sf))
+ len --;
+ if (len <= 0)
+ return;
+
+ cmplus (len);
+
+ /* If terminal_coding does any conversion, use it, otherwise use
+ safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
+ because it always return 1 if the member src_multibyte is 1. */
+ coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? &terminal_coding : &safe_terminal_coding);
+ /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
+ the tail. */
+ coding->mode &= ~CODING_MODE_LAST_BLOCK;
+
+
+ /* Turn appearance modes of the face. */
+ highlight_if_desired ();
+ turn_on_face (f, face_id);
+
+ coding->mode |= CODING_MODE_LAST_BLOCK;
+ conversion_buffer = encode_terminal_code (string, len, coding);
+ if (coding->produced > 0)
+ {
+ BLOCK_INPUT;
+ fwrite (conversion_buffer, 1, coding->produced, stdout);
+ if (ferror (stdout))
+ clearerr (stdout);
+ if (termscript)
+ fwrite (conversion_buffer, 1, coding->produced, termscript);
+ UNBLOCK_INPUT;
+ }
+
+ /* Turn appearance modes off. */
+ turn_off_face (f, face_id);
+ turn_off_highlight ();
+
+ cmcheckmagic ();
+}
+
/* If start is zero, insert blanks instead of a string at start */
void
@@ -2308,6 +2377,658 @@ set_tty_color_mode (f, val)
/***********************************************************************
+ Mouse
+ ***********************************************************************/
+
+#ifdef HAVE_GPM
+void
+term_mouse_moveto (int x, int y)
+{
+ /* TODO: how to set mouse position?
+ const char *name;
+ int fd;
+ name = (const char *) ttyname (0);
+ fd = open (name, O_WRONLY);
+ SOME_FUNCTION (x, y, fd);
+ close (fd);
+ last_mouse_x = x;
+ last_mouse_y = y; */
+}
+
+static void
+term_show_mouse_face (enum draw_glyphs_face draw)
+{
+ struct window *w = XWINDOW (Qmouse_face_window);
+ int save_x, save_y;
+ int i;
+
+ if (/* If window is in the process of being destroyed, don't bother
+ to do anything. */
+ w->current_matrix != NULL
+ /* Recognize when we are called to operate on rows that don't exist
+ anymore. This can happen when a window is split. */
+ && mouse_face_end_row < w->current_matrix->nrows)
+ {
+ /* write_glyphs writes at cursor position, so we need to
+ temporarily move cursor coordinates to the beginning of
+ the highlight region. */
+
+ /* Save current cursor co-ordinates */
+ save_y = curY;
+ save_x = curX;
+
+ /* Note that mouse_face_beg_row etc. are window relative. */
+ for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++)
+ {
+ int start_hpos, end_hpos, nglyphs;
+ struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
+
+ /* Don't do anything if row doesn't have valid contents. */
+ if (!row->enabled_p)
+ continue;
+
+ /* For all but the first row, the highlight starts at column 0. */
+ if (i == mouse_face_beg_row)
+ start_hpos = mouse_face_beg_col;
+ else
+ start_hpos = 0;
+
+ if (i == mouse_face_end_row)
+ end_hpos = mouse_face_end_col;
+ else
+ {
+ end_hpos = row->used[TEXT_AREA];
+ if (draw == DRAW_NORMAL_TEXT)
+ row->fill_line_p = 1; /* Clear to end of line */
+ }
+
+ if (end_hpos <= start_hpos)
+ continue;
+ /* Record that some glyphs of this row are displayed in
+ mouse-face. */
+ row->mouse_face_p = draw > 0;
+
+ nglyphs = end_hpos - start_hpos;
+
+ if (end_hpos >= row->used[TEXT_AREA])
+ nglyphs = row->used[TEXT_AREA] - start_hpos;
+
+ pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
+ pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
+ + WINDOW_LEFT_EDGE_X (w);
+
+ cursor_to (pos_y, pos_x);
+
+ if (draw == DRAW_MOUSE_FACE)
+ {
+ write_glyphs_with_face (row->glyphs[TEXT_AREA] + start_hpos,
+ nglyphs, mouse_face_face_id);
+ }
+ else /* draw == DRAW_NORMAL_TEXT */
+ write_glyphs (row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
+ }
+ cursor_to (save_y, save_x);
+ }
+}
+
+static void
+term_clear_mouse_face ()
+{
+ if (!NILP (Qmouse_face_window))
+ term_show_mouse_face (DRAW_NORMAL_TEXT);
+
+ mouse_face_beg_row = mouse_face_beg_col = -1;
+ mouse_face_end_row = mouse_face_end_col = -1;
+ Qmouse_face_window = Qnil;
+}
+
+/* Find the glyph matrix position of buffer position POS in window W.
+ *HPOS and *VPOS are set to the positions found. W's current glyphs
+ must be up to date. If POS is above window start return (0, 0).
+ If POS is after end of W, return end of last line in W.
+ - taken from msdos.c */
+static int
+fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
+{
+ int i, lastcol, line_start_position, maybe_next_line_p = 0;
+ int yb = window_text_bottom_y (w);
+ struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
+
+ while (row->y < yb)
+ {
+ if (row->used[TEXT_AREA])
+ line_start_position = row->glyphs[TEXT_AREA]->charpos;
+ else
+ line_start_position = 0;
+
+ if (line_start_position > pos)
+ break;
+ /* If the position sought is the end of the buffer,
+ don't include the blank lines at the bottom of the window. */
+ else if (line_start_position == pos
+ && pos == BUF_ZV (XBUFFER (w->buffer)))
+ {
+ maybe_next_line_p = 1;
+ break;
+ }
+ else if (line_start_position > 0)
+ best_row = row;
+
+ /* Don't overstep the last matrix row, lest we get into the
+ never-never land... */
+ if (row->y + 1 >= yb)
+ break;
+
+ ++row;
+ }
+
+ /* Find the right column within BEST_ROW. */
+ lastcol = 0;
+ row = best_row;
+ for (i = 0; i < row->used[TEXT_AREA]; i++)
+ {
+ struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
+ int charpos;
+
+ charpos = glyph->charpos;
+ if (charpos == pos)
+ {
+ *hpos = i;
+ *vpos = row->y;
+ return 1;
+ }
+ else if (charpos > pos)
+ break;
+ else if (charpos > 0)
+ lastcol = i;
+ }
+
+ /* If we're looking for the end of the buffer,
+ and we didn't find it in the line we scanned,
+ use the start of the following line. */
+ if (maybe_next_line_p)
+ {
+ ++row;
+ lastcol = 0;
+ }
+
+ *vpos = row->y;
+ *hpos = lastcol + 1;
+ return 0;
+}
+
+static void
+term_mouse_highlight (struct frame *f, int x, int y)
+{
+ enum window_part part;
+ Lisp_Object window;
+ struct window *w;
+ struct buffer *b;
+
+ if (NILP (Vmouse_highlight)
+ || !f->glyphs_initialized_p)
+ return;
+
+ /* Which window is that in? */
+ window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
+
+ /* Not on a window -> return. */
+ if (!WINDOWP (window))
+ return;
+
+ if (!EQ (window, Qmouse_face_window))
+ term_clear_mouse_face ();
+
+ w = XWINDOW (window);
+
+ /* Are we in a window whose display is up to date?
+ And verify the buffer's text has not changed. */
+ b = XBUFFER (w->buffer);
+ if (part == ON_TEXT
+ && EQ (w->window_end_valid, w->buffer)
+ && XFASTINT (w->last_modified) == BUF_MODIFF (b)
+ && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
+ {
+ int pos, i, nrows = w->current_matrix->nrows;
+ struct glyph_row *row;
+ struct glyph *glyph;
+
+ /* Find the glyph under X/Y. */
+ glyph = NULL;
+ if (y >= 0 && y < nrows)
+ {
+ row = MATRIX_ROW (w->current_matrix, y);
+ /* Give up if some row before the one we are looking for is
+ not enabled. */
+ for (i = 0; i <= y; i++)
+ if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
+ break;
+ if (i > y /* all rows upto and including the one at Y are enabled */
+ && row->displays_text_p
+ && x < window_box_width (w, TEXT_AREA))
+ {
+ glyph = row->glyphs[TEXT_AREA];
+ if (x >= row->used[TEXT_AREA])
+ glyph = NULL;
+ else
+ {
+ glyph += x;
+ if (!BUFFERP (glyph->object))
+ glyph = NULL;
+ }
+ }
+ }
+
+ /* Clear mouse face if X/Y not over text. */
+ if (glyph == NULL)
+ {
+ term_clear_mouse_face ();
+ return;
+ }
+
+ if (!BUFFERP (glyph->object))
+ abort ();
+ pos = glyph->charpos;
+
+ /* Check for mouse-face. */
+ {
+ extern Lisp_Object Qmouse_face;
+ Lisp_Object mouse_face, overlay, position, *overlay_vec;
+ int noverlays, obegv, ozv;
+ struct buffer *obuf;
+
+ /* If we get an out-of-range value, return now; avoid an error. */
+ if (pos > BUF_Z (b))
+ return;
+
+ /* Make the window's buffer temporarily current for
+ overlays_at and compute_char_face. */
+ obuf = current_buffer;
+ current_buffer = b;
+ obegv = BEGV;
+ ozv = ZV;
+ BEGV = BEG;
+ ZV = Z;
+
+ /* Is this char mouse-active? */
+ XSETINT (position, pos);
+
+ /* Put all the overlays we want in a vector in overlay_vec. */
+ GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
+ /* Sort overlays into increasing priority order. */
+ noverlays = sort_overlays (overlay_vec, noverlays, w);
+
+ /* Check mouse-face highlighting. */
+ if (!(EQ (window, Qmouse_face_window)
+ && y >= mouse_face_beg_row
+ && y <= mouse_face_end_row
+ && (y > mouse_face_beg_row
+ || x >= mouse_face_beg_col)
+ && (y < mouse_face_end_row
+ || x < mouse_face_end_col
+ || mouse_face_past_end)))
+ {
+ /* Clear the display of the old active region, if any. */
+ term_clear_mouse_face ();
+
+ /* Find the highest priority overlay that has a mouse-face
+ property. */
+ overlay = Qnil;
+ for (i = noverlays - 1; i >= 0; --i)
+ {
+ mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
+ if (!NILP (mouse_face))
+ {
+ overlay = overlay_vec[i];
+ break;
+ }
+ }
+
+ /* If no overlay applies, get a text property. */
+ if (NILP (overlay))
+ mouse_face = Fget_text_property (position, Qmouse_face,
+ w->buffer);
+
+ /* Handle the overlay case. */
+ if (!NILP (overlay))
+ {
+ /* Find the range of text around this char that
+ should be active. */
+ Lisp_Object before, after;
+ int ignore;
+
+
+ before = Foverlay_start (overlay);
+ after = Foverlay_end (overlay);
+ /* Record this as the current active region. */
+ fast_find_position (w, XFASTINT (before),
+ &mouse_face_beg_col,
+ &mouse_face_beg_row);
+
+ mouse_face_past_end
+ = !fast_find_position (w, XFASTINT (after),
+ &mouse_face_end_col,
+ &mouse_face_end_row);
+ Qmouse_face_window = window;
+
+ mouse_face_face_id
+ = face_at_buffer_position (w, pos, 0, 0,
+ &ignore, pos + 1, 1);
+
+ /* Display it as active. */
+ term_show_mouse_face (DRAW_MOUSE_FACE);
+ }
+ /* Handle the text property case. */
+ else if (!NILP (mouse_face))
+ {
+ /* Find the range of text around this char that
+ should be active. */
+ Lisp_Object before, after, beginning, end;
+ int ignore;
+
+ beginning = Fmarker_position (w->start);
+ XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos)));
+ before
+ = Fprevious_single_property_change (make_number (pos + 1),
+ Qmouse_face,
+ w->buffer, beginning);
+ after
+ = Fnext_single_property_change (position, Qmouse_face,
+ w->buffer, end);
+
+ /* Record this as the current active region. */
+ fast_find_position (w, XFASTINT (before),
+ &mouse_face_beg_col,
+ &mouse_face_beg_row);
+ mouse_face_past_end
+ = !fast_find_position (w, XFASTINT (after),
+ &mouse_face_end_col,
+ &mouse_face_end_row);
+ Qmouse_face_window = window;
+
+ mouse_face_face_id
+ = face_at_buffer_position (w, pos, 0, 0,
+ &ignore, pos + 1, 1);
+
+ /* Display it as active. */
+ term_show_mouse_face (DRAW_MOUSE_FACE);
+ }
+ }
+
+ /* Look for a `help-echo' property. */
+ {
+ Lisp_Object help;
+ extern Lisp_Object Qhelp_echo;
+
+ /* Check overlays first. */
+ help = Qnil;
+ for (i = noverlays - 1; i >= 0 && NILP (help); --i)
+ {
+ overlay = overlay_vec[i];
+ help = Foverlay_get (overlay, Qhelp_echo);
+ }
+
+ if (!NILP (help))
+ {
+ help_echo_string = help;
+ help_echo_window = window;
+ help_echo_object = overlay;
+ help_echo_pos = pos;
+ }
+ /* Try text properties. */
+ else if (NILP (help)
+ && ((STRINGP (glyph->object)
+ && glyph->charpos >= 0
+ && glyph->charpos < SCHARS (glyph->object))
+ || (BUFFERP (glyph->object)
+ && glyph->charpos >= BEGV
+ && glyph->charpos < ZV)))
+ {
+ help = Fget_text_property (make_number (glyph->charpos),
+ Qhelp_echo, glyph->object);
+ if (!NILP (help))
+ {
+ help_echo_string = help;
+ help_echo_window = window;
+ help_echo_object = glyph->object;
+ help_echo_pos = glyph->charpos;
+ }
+ }
+ }
+
+ BEGV = obegv;
+ ZV = ozv;
+ current_buffer = obuf;
+ }
+ }
+}
+
+static int
+term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
+{
+ /* Has the mouse moved off the glyph it was on at the last sighting? */
+ if (event->x != last_mouse_x || event->y != last_mouse_y)
+ {
+ frame->mouse_moved = 1;
+ term_mouse_highlight (frame, event->x, event->y);
+ /* Remember which glyph we're now on. */
+ last_mouse_x = event->x;
+ last_mouse_y = event->y;
+ return 1;
+ }
+ return 0;
+}
+
+/* Return the current position of the mouse.
+
+ Set *f to the frame the mouse is in, or zero if the mouse is in no
+ Emacs frame. If it is set to zero, all the other arguments are
+ garbage.
+
+ Set *bar_window to Qnil, and *x and *y to the column and
+ row of the character cell the mouse is over.
+
+ Set *time to the time the mouse was at the returned position.
+
+ This clears mouse_moved until the next motion
+ event arrives. */
+static void
+term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+ enum scroll_bar_part *part, Lisp_Object *x,
+ Lisp_Object *y, unsigned long *time)
+{
+ struct timeval now;
+
+ *fp = SELECTED_FRAME ();
+ (*fp)->mouse_moved = 0;
+
+ *bar_window = Qnil;
+ *part = 0;
+
+ XSETINT (*x, last_mouse_x);
+ XSETINT (*y, last_mouse_y);
+ gettimeofday(&now, 0);
+ *time = (now.tv_sec * 1000) + (now.tv_usec / 1000);
+}
+
+/* Prepare a mouse-event in *RESULT for placement in the input queue.
+
+ If the event is a button press, then note that we have grabbed
+ the mouse. */
+
+static Lisp_Object
+term_mouse_click (struct input_event *result, Gpm_Event *event,
+ struct frame *f)
+{
+ struct timeval now;
+ int i, j;
+
+ result->kind = GPM_CLICK_EVENT;
+ for (i = 0, j = GPM_B_LEFT; i < 3; i++, j >>= 1 )
+ {
+ if (event->buttons & j) {
+ result->code = i; /* button number */
+ break;
+ }
+ }
+ gettimeofday(&now, 0);
+ result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000);
+
+ if (event->type & GPM_UP)
+ result->modifiers = up_modifier;
+ else if (event->type & GPM_DOWN)
+ result->modifiers = down_modifier;
+ else
+ result->modifiers = 0;
+
+ if (event->type & GPM_SINGLE)
+ result->modifiers |= click_modifier;
+
+ if (event->type & GPM_DOUBLE)
+ result->modifiers |= double_modifier;
+
+ if (event->type & GPM_TRIPLE)
+ result->modifiers |= triple_modifier;
+
+ if (event->type & GPM_DRAG)
+ result->modifiers |= drag_modifier;
+
+ if (!(event->type & (GPM_MOVE | GPM_DRAG))) {
+
+ /* 1 << KG_SHIFT */
+ if (event->modifiers & (1 << 0))
+ result->modifiers |= shift_modifier;
+
+ /* 1 << KG_CTRL */
+ if (event->modifiers & (1 << 2))
+ result->modifiers |= ctrl_modifier;
+
+ /* 1 << KG_ALT || KG_ALTGR */
+ if (event->modifiers & (1 << 3)
+ || event->modifiers & (1 << 1))
+ result->modifiers |= meta_modifier;
+ }
+
+ XSETINT (result->x, event->x);
+ XSETINT (result->y, event->y);
+ XSETFRAME (result->frame_or_window, f);
+ result->arg = Qnil;
+ return Qnil;
+}
+
+int
+handle_one_term_event (Gpm_Event *event, struct input_event* hold_quit)
+{
+ struct frame *f = SELECTED_FRAME ();
+ int fd;
+ struct input_event ie;
+ int do_help = 0;
+ int count = 0;
+
+ EVENT_INIT (ie);
+ ie.kind = NO_EVENT;
+ ie.arg = Qnil;
+
+ if (event->type & (GPM_MOVE | GPM_DRAG)) {
+ unsigned char buf[6 * sizeof (short)];
+ unsigned short *arg = (unsigned short *) buf + 1;
+ const char *name;
+
+ previous_help_echo_string = help_echo_string;
+ help_echo_string = Qnil;
+
+ /* Display mouse pointer */
+ buf[sizeof(short) - 1] = 2; /* set selection */
+
+ arg[0] = arg[2] = (unsigned short) event->x + gpm_zerobased;
+ arg[1] = arg[3] = (unsigned short) event->y + gpm_zerobased;
+ arg[4] = (unsigned short) 3;
+
+ name = ttyname (0);
+ fd = open (name, O_WRONLY);
+ ioctl (fd, TIOCLINUX, buf + sizeof (short) - 1);
+ close (fd);
+
+ if (!term_mouse_movement (f, event))
+ help_echo_string = previous_help_echo_string;
+
+ /* If the contents of the global variable help_echo_string
+ has changed, generate a HELP_EVENT. */
+ if (!NILP (help_echo_string)
+ || !NILP (previous_help_echo_string))
+ do_help = 1;
+
+ goto done;
+ }
+ else {
+ f->mouse_moved = 0;
+ term_mouse_click (&ie, event, f);
+ }
+
+ done:
+ if (ie.kind != NO_EVENT)
+ {
+ kbd_buffer_store_event_hold (&ie, hold_quit);
+ count++;
+ }
+
+ if (do_help
+ && !(hold_quit && hold_quit->kind != NO_EVENT))
+ {
+ Lisp_Object frame;
+
+ if (f)
+ XSETFRAME (frame, f);
+ else
+ frame = Qnil;
+
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ count++;
+ }
+
+ return count;
+}
+
+DEFUN ("term-open-connection", Fterm_open_connection, Sterm_open_connection,
+ 0, 0, 0,
+ doc: /* Open a connection to Gpm. */)
+ ()
+{
+ Gpm_Connect connection;
+
+ connection.eventMask = ~0;
+ connection.defaultMask = ~GPM_HARD;
+ connection.maxMod = ~0;
+ connection.minMod = 0;
+ gpm_zerobased = 1;
+
+ if (Gpm_Open (&connection, 0) < 0)
+ return Qnil;
+ else
+ {
+ term_gpm = 1;
+ reset_sys_modes ();
+ init_sys_modes ();
+ add_gpm_wait_descriptor (gpm_fd);
+ return Qt;
+ }
+}
+
+DEFUN ("term-close-connection", Fterm_close_connection, Sterm_close_connection,
+ 0, 0, 0,
+ doc: /* Close a connection to Gpm. */)
+ ()
+{
+ delete_gpm_wait_descriptor (gpm_fd);
+ while (Gpm_Close()); /* close all the stack */
+ term_gpm = 0;
+ return Qnil;
+}
+#endif /* HAVE_GPM */
+
+
+/***********************************************************************
Initialization
***********************************************************************/
@@ -2325,6 +3046,11 @@ term_init (terminal_type)
encode_terminal_bufsize = 0;
+#ifdef HAVE_GPM
+ mouse_position_hook = term_mouse_position;
+ Qmouse_face_window = Qnil;
+#endif
+
#ifdef WINDOWSNT
initialize_w32_display ();
@@ -2772,6 +3498,12 @@ bigger, or it may make it blink, or it may do nothing at all. */);
defsubr (&Stty_display_color_p);
defsubr (&Stty_display_color_cells);
defsubr (&Stty_no_underline);
+#ifdef HAVE_GPM
+ defsubr (&Sterm_open_connection);
+ defsubr (&Sterm_close_connection);
+
+ staticpro (&Qmouse_face_window);
+#endif /* HAVE_GPM */
fullscreen_hook = NULL;
}
diff --git a/src/termhooks.h b/src/termhooks.h
index 5d317f2da3d..889c3ab1ab7 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -340,7 +340,11 @@ enum event_kind
symbols, respectively. Member `arg' is a Lisp object converted
from the received Apple event. Parameters for non-Apple events
are converted to those in Apple events. */
- MAC_APPLE_EVENT
+ MAC_APPLE_EVENT,
+#endif
+
+#ifdef HAVE_GPM
+ GPM_CLICK_EVENT
#endif
};
@@ -446,6 +450,15 @@ enum {
meta_modifier = CHAR_META /* Under X, the XK_Meta_[LR] keysyms. */
};
+#ifdef HAVE_GPM
+#include <gpm.h>
+extern int handle_one_term_event (Gpm_Event *, struct input_event *);
+extern void term_mouse_moveto (int, int);
+
+/* Nonzero means mouse is enabled on Linux console */
+extern int term_gpm;
+#endif
+
#endif
/* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d
diff --git a/src/w32.c b/src/w32.c
index eaad69010f8..d7e95aac7d1 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -137,6 +137,15 @@ typedef BOOL (WINAPI * GetTokenInformation_Proc) (
LPVOID TokenInformation,
DWORD TokenInformationLength,
PDWORD ReturnLength);
+typedef BOOL (WINAPI * GetProcessTimes_Proc) (
+ HANDLE process_handle,
+ LPFILETIME creation_time,
+ LPFILETIME exit_time,
+ LPFILETIME kernel_time,
+ LPFILETIME user_time);
+
+GetProcessTimes_Proc get_process_times_fn = NULL;
+
#ifdef _UNICODE
const char * const LookupAccountSid_Name = "LookupAccountSidW";
#else
@@ -172,6 +181,46 @@ is_windows_9x ()
return s_b_ret;
}
+/* Get total user and system times for get-internal-run-time.
+ Returns a list of three integers if the times are provided by the OS
+ (NT derivatives), otherwise it returns the result of current-time. */
+Lisp_Object
+w32_get_internal_run_time ()
+{
+ if (get_process_times_fn)
+ {
+ FILETIME create, exit, kernel, user;
+ HANDLE proc = GetCurrentProcess();
+ if ((*get_process_times_fn) (proc, &create, &exit, &kernel, &user))
+ {
+ LARGE_INTEGER user_int, kernel_int, total;
+ int microseconds;
+ user_int.LowPart = user.dwLowDateTime;
+ user_int.HighPart = user.dwHighDateTime;
+ kernel_int.LowPart = kernel.dwLowDateTime;
+ kernel_int.HighPart = kernel.dwHighDateTime;
+ total.QuadPart = user_int.QuadPart + kernel_int.QuadPart;
+ /* FILETIME is 100 nanosecond increments, Emacs only wants
+ microsecond resolution. */
+ total.QuadPart /= 10;
+ microseconds = total.QuadPart % 1000000;
+ total.QuadPart /= 1000000;
+
+ /* Sanity check to make sure we can represent the result. */
+ if (total.HighPart == 0)
+ {
+ int secs = total.LowPart;
+
+ return list3 (make_number ((secs >> 16) & 0xffff),
+ make_number (secs & 0xffff),
+ make_number (microseconds));
+ }
+ }
+ }
+
+ return Fcurrent_time ();
+}
+
/* ** The wrapper functions ** */
BOOL WINAPI open_process_token (
@@ -4146,6 +4195,11 @@ BOOL WINAPI shutdown_handler(DWORD type)
void
globals_of_w32 ()
{
+ HMODULE kernel32 = GetModuleHandle ("kernel32.dll");
+
+ get_process_times_fn = (GetProcessTimes_Proc)
+ GetProcAddress (kernel32, "GetProcessTimes");
+
g_b_init_is_windows_9x = 0;
g_b_init_open_process_token = 0;
g_b_init_get_token_information = 0;
diff --git a/src/w32term.c b/src/w32term.c
index b3bf9a0f704..129f52dcfe0 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -218,10 +218,9 @@ extern int errno;
extern EMACS_INT extra_keyboard_modifiers;
static void x_update_window_end P_ ((struct window *, int, int));
-void w32_delete_display P_ ((struct w32_display_info *));
static void w32_handle_tool_bar_click P_ ((struct frame *,
struct input_event *));
-void w32_define_cursor P_ ((Window, Cursor));
+static void w32_define_cursor P_ ((Window, Cursor));
void x_lower_frame P_ ((struct frame *));
void x_scroll_bar_clear P_ ((struct frame *));
@@ -230,7 +229,7 @@ void x_raise_frame P_ ((struct frame *));
void x_set_window_size P_ ((struct frame *, int, int, int));
void x_wm_set_window_state P_ ((struct frame *, int));
void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-void w32_initialize P_ ((void));
+static void w32_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
@@ -3278,7 +3277,7 @@ redo_mouse_highlight ()
HIWORD (last_mouse_motion_event.lParam));
}
-void
+static void
w32_define_cursor (window, cursor)
Window window;
Cursor cursor;
@@ -6345,7 +6344,7 @@ static struct redisplay_interface w32_redisplay_interface =
w32_shift_glyphs_for_insert
};
-void
+static void
w32_initialize ()
{
rif = &w32_redisplay_interface;
diff --git a/src/window.c b/src/window.c
index e6fe32ea506..f1c3a6e49f2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -62,6 +62,7 @@ static void window_scroll P_ ((Lisp_Object, int, int, int));
static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
static int window_min_size_1 P_ ((struct window *, int));
+static int window_min_size_2 P_ ((struct window *, int));
static int window_min_size P_ ((struct window *, int, int, int *));
static void size_window P_ ((Lisp_Object, int, int, int, int, int));
static int freeze_window_start P_ ((struct window *, void *));
@@ -2553,7 +2554,6 @@ check_frame_size (frame, rows, cols)
*cols = MIN_SAFE_WINDOW_WIDTH;
}
-
/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
check if W's width can be changed, otherwise check W's height.
CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
@@ -2655,6 +2655,33 @@ window_fixed_size_p (w, width_p, check_siblings_p)
return fixed_p;
}
+/* Return the minimum size for leaf window W. WIDTH_P non-zero means
+ take into account fringes and the scrollbar of W. WIDTH_P zero
+ means take into account mode-line and header-line of W. Return 1
+ for the minibuffer. */
+
+static int
+window_min_size_2 (w, width_p)
+ struct window *w;
+ int width_p;
+{
+ int size;
+
+ if (width_p)
+ size = max (window_min_width,
+ (MIN_SAFE_WINDOW_WIDTH
+ + WINDOW_FRINGE_COLS (w)
+ + WINDOW_SCROLL_BAR_COLS (w)));
+ else if (MINI_WINDOW_P (w))
+ size = 1;
+ else
+ size = max (window_min_height,
+ (MIN_SAFE_WINDOW_HEIGHT
+ + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)
+ + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 )));
+
+ return size;
+}
/* Return the minimum size of window W, not taking fixed-width windows
into account. WIDTH_P non-zero means return the minimum width,
@@ -2724,22 +2751,7 @@ window_min_size_1 (w, width_p)
}
}
else
- {
- if (width_p)
- size = max (window_min_width,
- (MIN_SAFE_WINDOW_WIDTH
- + WINDOW_FRINGE_COLS (w)
- + WINDOW_SCROLL_BAR_COLS (w)));
- else
- {
- if (MINI_WINDOW_P (w)
- || (!WINDOW_WANTS_MODELINE_P (w)
- && !WINDOW_WANTS_HEADER_LINE_P (w)))
- size = 1;
- else
- size = window_min_height;
- }
- }
+ size = window_min_size_2 (w, width_p);
return size;
}
@@ -2981,11 +2993,6 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
Lisp_Object child, *forward, *sideward;
int old_size, min_size, safe_min_size;
- /* We test nodelete_p != 2 and nodelete_p != 1 below, so it
- seems like it's too soon to do this here. ++KFS. */
- if (nodelete_p == 2)
- nodelete_p = 0;
-
check_min_window_sizes ();
size = max (0, size);
@@ -2996,22 +3003,23 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
{
old_size = WINDOW_TOTAL_COLS (w);
min_size = window_min_width;
- /* Ensure that there is room for the scroll bar and fringes!
- We may reduce display margins though. */
- safe_min_size = (MIN_SAFE_WINDOW_WIDTH
- + WINDOW_FRINGE_COLS (w)
- + WINDOW_SCROLL_BAR_COLS (w));
+ safe_min_size = window_min_size_2 (w, 1);
}
else
{
old_size = XINT (w->total_lines);
min_size = window_min_height;
- safe_min_size = MIN_SAFE_WINDOW_HEIGHT;
+ safe_min_size = window_min_size_2 (w, 0);
}
if (old_size < min_size && nodelete_p != 2)
w->too_small_ok = Qt;
+ /* Move the following test here since otherwise the
+ preceding test doesn't make sense. martin. */
+ if (nodelete_p == 2)
+ nodelete_p = 0;
+
/* Maybe delete WINDOW if it's too small. */
if (nodelete_p != 1 && !NILP (w->parent))
{
@@ -3708,9 +3716,6 @@ displayed. */)
frames = Qnil;
if (FRAME_MINIBUF_ONLY_P (f))
XSETFRAME (frames, last_nonminibuf_frame);
- /* Don't try to create a window if we would get an error. */
- if (split_height_threshold < window_min_height << 1)
- split_height_threshold = window_min_height << 1;
/* Note that both Fget_largest_window and Fget_lru_window
ignore minibuffers and dedicated windows.
@@ -3733,25 +3738,30 @@ displayed. */)
else
window = Fget_largest_window (frames, Qt);
- /* If we got a tall enough full-width window that can be split,
- split it. */
+ /* If the largest window is tall enough, full-width, and either eligible
+ for splitting or the only window, split it. */
if (!NILP (window)
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
- && window_height (window) >= split_height_threshold
- && WINDOW_FULL_WIDTH_P (XWINDOW (window)))
+ && WINDOW_FULL_WIDTH_P (XWINDOW (window))
+ && (window_height (window) >= split_height_threshold
+ || (NILP (XWINDOW (window)->parent)))
+ && (window_height (window)
+ >= (2 * window_min_size_2 (XWINDOW (window), 0))))
window = Fsplit_window (window, Qnil, Qnil);
else
{
Lisp_Object upper, lower, other;
window = Fget_lru_window (frames, Qt);
- /* If the LRU window is selected, and big enough,
- and can be split, split it. */
+ /* If the LRU window is tall enough, and either eligible for splitting
+ and selected or the only window, split it. */
if (!NILP (window)
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
- && (EQ (window, selected_window)
- || EQ (XWINDOW (window)->parent, Qnil))
- && window_height (window) >= window_min_height << 1)
+ && ((EQ (window, selected_window)
+ && window_height (window) >= split_height_threshold)
+ || (NILP (XWINDOW (window)->parent)))
+ && (window_height (window)
+ >= (2 * window_min_size_2 (XWINDOW (window), 0))))
window = Fsplit_window (window, Qnil, Qnil);
else
window = Fget_lru_window (frames, Qnil);
@@ -4000,9 +4010,11 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/)
if (NILP (horflag))
{
- if (size_int < window_min_height)
+ int window_safe_height = window_min_size_2 (o, 0);
+
+ if (size_int < window_safe_height)
error ("Window height %d too small (after splitting)", size_int);
- if (size_int + window_min_height > XFASTINT (o->total_lines))
+ if (size_int + window_safe_height > XFASTINT (o->total_lines))
error ("Window height %d too small (after splitting)",
XFASTINT (o->total_lines) - size_int);
if (NILP (o->parent)
@@ -4015,10 +4027,11 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/)
}
else
{
- if (size_int < window_min_width)
+ int window_safe_width = window_min_size_2 (o, 1);
+
+ if (size_int < window_safe_width)
error ("Window width %d too small (after splitting)", size_int);
-
- if (size_int + window_min_width > XFASTINT (o->total_cols))
+ if (size_int + window_safe_width > XFASTINT (o->total_cols))
error ("Window width %d too small (after splitting)",
XFASTINT (o->total_cols) - size_int);
if (NILP (o->parent)
@@ -4499,7 +4512,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
/* Don't make this window too small. */
if (XINT (CURSIZE (window)) + delta
- < (horiz_flag ? window_min_width : window_min_height))
+ < window_min_size_2 (XWINDOW (window), horiz_flag))
{
Fset_window_configuration (old_config);
error ("Cannot adjust window size as specified");
@@ -6897,7 +6910,7 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */)
vertical_type = Qnil;
}
- if (!(EQ (vertical_type, Qnil)
+ if (!(NILP (vertical_type)
|| EQ (vertical_type, Qleft)
|| EQ (vertical_type, Qright)
|| EQ (vertical_type, Qt)))
diff --git a/src/xdisp.c b/src/xdisp.c
index 46247beb10f..41105456d95 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9365,7 +9365,7 @@ update_tool_bar (f, save_match_data)
struct frame *f;
int save_match_data;
{
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
int do_update = WINDOWP (f->tool_bar_window)
@@ -9831,7 +9831,7 @@ redisplay_tool_bar (f)
struct it it;
struct glyph_row *row;
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
return 0;
@@ -12783,7 +12783,7 @@ redisplay_window (window, just_this_one_p)
int rc;
int centering_position = -1;
int last_line_misfit = 0;
- int save_beg_unchanged, save_end_unchanged;
+ int beg_unchanged, end_unchanged;
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
@@ -12848,8 +12848,8 @@ redisplay_window (window, just_this_one_p)
set_buffer_internal_1 (XBUFFER (w->buffer));
SET_TEXT_POS (opoint, PT, PT_BYTE);
- save_beg_unchanged = BEG_UNCHANGED;
- save_end_unchanged = END_UNCHANGED;
+ beg_unchanged = BEG_UNCHANGED;
+ end_unchanged = END_UNCHANGED;
current_matrix_up_to_date_p
= (!NILP (w->window_end_valid)
@@ -13155,16 +13155,16 @@ redisplay_window (window, just_this_one_p)
than a simple mouse-click. */
if (NILP (w->start_at_line_beg)
&& NILP (do_mouse_tracking)
- && CHARPOS (startp) > BEGV
- && CHARPOS (startp) > BEG + save_beg_unchanged
- && CHARPOS (startp) <= Z - save_end_unchanged)
+ && CHARPOS (startp) > BEGV
+ && CHARPOS (startp) > BEG + beg_unchanged
+ && CHARPOS (startp) <= Z - end_unchanged)
{
w->force_start = Qt;
if (XMARKER (w->start)->buffer == current_buffer)
compute_window_start_on_continuation_line (w);
SET_TEXT_POS_FROM_MARKER (startp, w->start);
goto force_start;
- }
+ }
#if GLYPH_DEBUG
debug_method_add (w, "same window start");
@@ -13467,7 +13467,7 @@ redisplay_window (window, just_this_one_p)
display_menu_bar (w);
#ifdef HAVE_WINDOW_SYSTEM
-#ifdef USE_GTK
+#if defined (USE_GTK) || USE_MAC_TOOLBAR
redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
#else
redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
@@ -17342,7 +17342,7 @@ are the selected window and the window's buffer). */)
CHECK_BUFFER (buffer);
if (NILP (format))
- return build_string ("");
+ return empty_unibyte_string;
if (no_props)
face = Qnil;
@@ -17400,7 +17400,7 @@ are the selected window and the window's buffer). */)
{
mode_line_string_list = Fnreverse (mode_line_string_list);
str = Fmapconcat (intern ("identity"), mode_line_string_list,
- make_string ("", 0));
+ empty_unibyte_string);
}
unbind_to (count, Qnil);
@@ -17994,6 +17994,16 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
#endif
break;
+ case 'R':
+ {
+ Lisp_Object val;
+ val = call1 (intern ("file-remote-p"), current_buffer->directory);
+ if (NILP (val))
+ return "-";
+ else
+ return "@";
+ }
+
case 't': /* indicate TEXT or BINARY */
#ifdef MODE_LINE_BINARY_TEXT
return MODE_LINE_BINARY_TEXT (b);
@@ -24081,7 +24091,7 @@ and is used only on frames for which no explicit name has been set
= Vframe_title_format
= Fcons (intern ("multiple-frames"),
Fcons (build_string ("%b"),
- Fcons (Fcons (empty_string,
+ Fcons (Fcons (empty_unibyte_string,
Fcons (intern ("invocation-name"),
Fcons (build_string ("@"),
Fcons (intern ("system-name"),
diff --git a/src/xfaces.c b/src/xfaces.c
index 31e033736f6..ffaf2afda21 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3935,6 +3935,8 @@ Otherwise check for the existence of a global face. */)
{
Lisp_Object lface;
+ face = resolve_face_name (face, 1);
+
if (!NILP (frame))
{
CHECK_LIVE_FRAME (frame);
diff --git a/src/xfns.c b/src/xfns.c
index 80f21411890..0c06abb44d4 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -72,8 +72,13 @@ Boston, MA 02110-1301, USA. */
#include <X11/Shell.h>
#ifndef USE_MOTIF
+#ifdef HAVE_XAW3D
+#include <X11/Xaw3d/Paned.h>
+#include <X11/Xaw3d/Label.h>
+#else /* !HAVE_XAW3D */
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Label.h>
+#endif /* HAVE_XAW3D */
#endif /* USE_MOTIF */
#ifdef USG
@@ -1847,9 +1852,9 @@ x_default_scroll_bar_color_parameter (f, alist, prop, xprop, xclass,
build_string (foreground_p
? "foreground"
: "background"),
- empty_string,
+ empty_unibyte_string,
build_string ("verticalScrollBar"),
- empty_string);
+ empty_unibyte_string);
if (!STRINGP (tem))
{
/* If nothing has been specified, scroll bars will use a
@@ -3505,6 +3510,7 @@ FRAME nil means use the selected frame. */)
x_catch_errors (dpy);
XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
RevertToParent, CurrentTime);
+ x_ewmh_activate_frame (f);
x_uncatch_errors ();
UNBLOCK_INPUT;
diff --git a/src/xmenu.c b/src/xmenu.c
index 723de57fc5d..f68f3a41e3f 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -82,7 +82,11 @@ Boston, MA 02110-1301, USA. */
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#ifdef USE_LUCID
+#ifdef HAVE_XAW3D
+#include <X11/Xaw3d/Paned.h>
+#else /* !HAVE_XAW3D */
#include <X11/Xaw/Paned.h>
+#endif /* HAVE_XAW3D */
#endif /* USE_LUCID */
#include "../lwlib/lwlib.h"
#else /* not USE_X_TOOLKIT */
@@ -325,7 +329,7 @@ restore_menu_items (saved)
menu_items_used = XINT (XCAR (saved));
saved = XCDR (saved);
menu_items_n_panes = XINT (XCAR (saved));
- saved = XCDR (saved);
+ saved = XCDR (saved);
menu_items_submenu_depth = XINT (XCAR (saved));
return Qnil;
}
@@ -3428,7 +3432,7 @@ menu_help_callback (help_string, pane, item)
pane_name = first_item[MENU_ITEMS_PANE_NAME];
else if (EQ (first_item[0], Qquote))
/* This shouldn't happen, see xmenu_show. */
- pane_name = empty_string;
+ pane_name = empty_unibyte_string;
else
pane_name = first_item[MENU_ITEMS_ITEM_NAME];
diff --git a/src/xselect.c b/src/xselect.c
index 0204abb2d96..729c05f190a 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2678,7 +2678,7 @@ If the value is 0 or the atom is not known, return the empty string. */)
ret = make_string (name, strlen (name));
if (atom && name) XFree (name);
- if (NILP (ret)) ret = make_string ("", 0);
+ if (NILP (ret)) ret = empty_unibyte_string;
UNBLOCK_INPUT;
diff --git a/src/xterm.c b/src/xterm.c
index 3deb518bad5..bc70bb05ac4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8357,7 +8357,7 @@ wm_supports (f, atomname)
prop_atom, 0, max_len, False, target_type,
&actual_type, &actual_format, &actual_size,
&bytes_remaining, &tmp_data);
-
+
if (rc != Success || actual_type != XA_WINDOW || x_had_errors_p (dpy))
{
if (tmp_data) XFree (tmp_data);
@@ -8412,7 +8412,7 @@ wm_supports (f, atomname)
rc = 0;
want_atom = XInternAtom (dpy, atomname, False);
- for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i)
+ for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i)
rc = dpyinfo->net_supported_atoms[i] == want_atom;
x_uncatch_errors ();
@@ -8853,38 +8853,36 @@ x_lower_frame (f)
}
}
+/* Activate frame with Extended Window Manager Hints */
+
+void
+x_ewmh_activate_frame (f)
+ FRAME_PTR f;
+{
+ /* See Window Manager Specification/Extended Window Manager Hints at
+ http://freedesktop.org/wiki/Standards_2fwm_2dspec */
+
+ const char *atom = "_NET_ACTIVE_WINDOW";
+ if (f->async_visible && wm_supports (f, atom))
+ {
+ Lisp_Object frame;
+ XSETFRAME (frame, f);
+ Fx_send_client_event (frame, make_number (0), frame,
+ make_unibyte_string (atom, strlen (atom)),
+ make_number (32),
+ Fcons (make_number (1),
+ Fcons (make_number (last_user_time),
+ Qnil)));
+ }
+}
+
static void
XTframe_raise_lower (f, raise_flag)
FRAME_PTR f;
int raise_flag;
{
if (raise_flag)
- {
- /* The following code is needed for `raise-frame' to work on
- some versions of metacity; see Window Manager
- Specification/Extended Window Manager Hints at
- http://freedesktop.org/wiki/Standards_2fwm_2dspec */
-
-#if 0
- /* However, on other versions (metacity 2.17.2-1.fc7), it
- reportedly causes hangs when resizing frames. */
-
- const char *atom = "_NET_ACTIVE_WINDOW";
- if (f->async_visible && wm_supports (f, atom))
- {
- Lisp_Object frame;
- XSETFRAME (frame, f);
- Fx_send_client_event (frame, make_number (0), frame,
- make_unibyte_string (atom, strlen (atom)),
- make_number (32),
- Fcons (make_number (1),
- Fcons (make_number (last_user_time),
- Qnil)));
- }
- else
-#endif
- x_raise_frame (f);
- }
+ x_raise_frame (f);
else
x_lower_frame (f);
}
@@ -10649,7 +10647,7 @@ x_term_init (display_name, xrm_option, resource_name)
UNBLOCK_INPUT;
dpyinfo->kboard->Vsystem_key_alist
= call1 (Qvendor_specific_keysyms,
- build_string (vendor ? vendor : ""));
+ vendor ? build_string (vendor) : empty_unibyte_string);
BLOCK_INPUT;
}
diff --git a/src/xterm.h b/src/xterm.h
index 84f12d94abd..70e0522e9cc 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -988,6 +988,7 @@ extern void x_fully_uncatch_errors P_ ((void));
extern void x_set_window_size P_ ((struct frame *, int, int, int));
extern void x_set_mouse_position P_ ((struct frame *, int, int));
extern void x_set_mouse_pixel_position P_ ((struct frame *, int, int));
+extern void x_ewmh_activate_frame P_ ((struct frame *));
extern void x_raise_frame P_ ((struct frame *));
extern void x_lower_frame P_ ((struct frame *));
extern void x_make_frame_visible P_ ((struct frame *));