summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>2006-06-07 18:05:10 +0000
committerMiles Bader <miles@gnu.org>2006-06-07 18:05:10 +0000
commitb883cdb2fefa8ea9c3b0d82eba7a9ee792f871bb (patch)
treede3804210a8cd955e0d3b9abc15679480930bc82 /src
parent885b7d0991bd4b4b8f4bd1d3cd21c18a697bbce2 (diff)
parent26c9afc3239e18b03537faaea33e3e82e28099e6 (diff)
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 285-296) - Update from CVS - Merge from gnus--rel--5.10 - Update from CVS: admin/FOR-RELEASE: Update refcard section. * gnus--rel--5.10 (patch 102-104) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-64
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog455
-rw-r--r--src/Makefile.in3
-rw-r--r--src/buffer.c21
-rw-r--r--src/callint.c2
-rw-r--r--src/coding.c11
-rw-r--r--src/config.in6
-rw-r--r--src/dispextern.h8
-rw-r--r--src/dispnew.c10
-rw-r--r--src/emacs.c19
-rw-r--r--src/fileio.c38
-rw-r--r--src/fns.c2
-rw-r--r--src/frame.c2
-rw-r--r--src/gtkutil.c34
-rw-r--r--src/image.c13
-rw-r--r--src/intervals.c4
-rw-r--r--src/lisp.h6
-rw-r--r--src/lread.c71
-rw-r--r--src/mac.c180
-rw-r--r--src/macfns.c46
-rw-r--r--src/macgui.h7
-rw-r--r--src/macselect.c369
-rw-r--r--src/macterm.c735
-rw-r--r--src/macterm.h53
-rw-r--r--src/minibuf.c46
-rw-r--r--src/process.c84
-rw-r--r--src/puresize.h2
-rw-r--r--src/search.c1
-rw-r--r--src/sound.c413
-rw-r--r--src/sysdep.c2
-rw-r--r--src/w32.c38
-rw-r--r--src/w32fns.c2
-rw-r--r--src/w32heap.c4
-rw-r--r--src/w32term.c222
-rw-r--r--src/window.c15
-rw-r--r--src/xdisp.c100
-rw-r--r--src/xfaces.c75
-rw-r--r--src/xfns.c4
-rw-r--r--src/xmenu.c117
-rw-r--r--src/xterm.c51
-rw-r--r--src/xterm.h10
40 files changed, 2634 insertions, 647 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 61fca56c357..d0ad63de10d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,441 @@
+2006-06-06 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c [USE_MAC_TSM] (mac_handle_text_input_event): Exclude
+ 0x7f from ASCII range.
+
+2006-06-05 Jason Rumney <jasonr@gnu.org>
+
+ * w32term.c (w32_set_scroll_bar_thumb, x_scroll_bar_create)
+ (w32_set_vertical_scroll_bar, w32_scroll_bar_handle_click)
+ (x_scroll_bar_report_motion): Remove workarounds for
+ versions of Windows NT < 3.51.
+ [!SIF_ALL]: Remove.
+ (pfnSetScrollInfo, pfnGetScrollInfo): Remove.
+ (w32_initialize): Don't dynamically load Get/SetScrollInfo.
+
+2006-06-04 David Kastrup <dak@gnu.org>
+
+ * dispnew.c: Mention `redisplay-dont-pause' in doc string of
+ `sit-for'.
+
+2006-06-03 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macfns.c (x_set_icon_name): Apply 2006-06-02 change for xfns.c.
+
+ * macgui.h (USE_MAC_TSM): Set default to 1 on Mac OS X.
+
+ * macterm.c (tsm_document_id) [USE_MAC_TSM]: New variable.
+ (Qtext_input, Qupdate_active_input_area, Qunicode_for_key_event)
+ [USE_MAC_TSM]: Likewise.
+ (syms_of_macterm) [USE_MAC_TSM]: Intern and staticpro them.
+ (Qbefore_string) [USE_MAC_TSM]: Add extern.
+ (do_app_resume, do_app_suspend) [USE_MAC_TSM]: Call
+ ActivateTSMDocument/DeactivateTSMDocument.
+ (mac_store_event_ref_as_apple_event): Call mac_post_mouse_moved_event.
+ (mac_handle_window_event) [USE_MAC_TSM]: Handle
+ kEventWindowFocusAcquired/kEventWindowFocusRelinquish.
+ (mac_handle_text_input_event) [USE_MAC_TSM]: New function.
+ (install_window_handler) [USE_MAC_TSM]: Install it. Register
+ kEventWindowFocusAcquired/kEventWindowFocusRelinquish.
+ (keycode_to_xkeysym_table): Add entry for f16.
+ (XTread_socket) [USE_MAC_TSM]: Set/reset read_socket_inev
+ before/after passing keystroke event to toolbox dispatcher.
+ (init_tsm) [USE_MAC_TSM]: New function.
+ (mac_initialize) [USE_MAC_TSM]: Call it.
+ (Vmac_ts_active_input_overlay) [USE_MAC_TSM]: New defvar.
+
+ * macterm.h (EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER): New enumerator.
+
+2006-06-02 John Paul Wallington <jpw@gnu.org>
+
+ * xfns.c (x_set_name_internal): Set icon to `text', derived from
+ name, when frame's icon_name isn't a string rather than only when
+ it is nil.
+
+2006-06-03 Eli Zaretskii <eliz@gnu.org>
+
+ * w32fns.c (x_set_icon_name): Don't use arg if it's not a string
+ and not nil.
+
+2006-06-02 Chong Yidong <cyd@stupidchicken.com>
+
+ * xfns.c (x_set_icon_name): No-op if arg is non-nil and not a
+ string.
+
+2006-06-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * xdisp.c (next_element_from_composition): Set it->object to
+ it->string if composition is coming from string.
+ (set_cursor_from_row): Don't return 0 unless row displays a
+ continued line.
+ (dump_glyph): Dump composite glyph.
+
+2006-06-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * gtkutil.c (menu_nav_ended): Check that menubar_widget is not NULL.
+
+2006-06-01 Richard Stallman <rms@gnu.org>
+
+ * window.c (Fsplit_window): Doc fix.
+
+2006-06-01 Micha,Ak(Bl Cadilhac <michael.cadilhac@lrde.org>
+
+ * process.c (deleted_pid_list): New variable to store the pids
+ of deleted processes. Declare it only if SIGCHLD is defined.
+ (init_process): Initialize it.
+ (syms_of_process): Staticpro it.
+ (Fdelete_process): Add pid of the deleted process to it. Check after
+ the addition and before the kill if the process is already stopped,
+ in which case it is deleted from the list and not killed.
+ (sigchld_handler): Define it only if SIGCHLD is. Search the process
+ that signaled Emacs in `deleted_pid_list' before `Vprocess_alist'.
+ Original idea by Stefan Monnier.
+
+2006-06-01 Kim F. Storm <storm@cua.dk>
+
+ * dispnew.c (sit_for): Perform redisplay even if input is pending
+ when redisplay-dont-pause is non-nil.
+
+2006-06-01 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (mac_handle_visibility_change): Set buf.arg to Qnil.
+ (XTread_socket): Remove obsolete comment.
+
+2006-06-01 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * xmenu.c (syms_of_xmenu): Make accelerate-menu an alias for
+ menu-bar-open.
+
+2006-06-01 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * xmenu.c (Fmenu_bar_open, syms_of_xmenu): Change menu-bar-start to
+ menu-bar-open.
+
+ * gtkutil.c (menu_nav_ended): Change x-menu-bar-start to menu-bar-open.
+
+2006-05-31 Juri Linkov <juri@jurta.org>
+
+ * minibuf.c (Vhistory_add_new_input): New variable.
+ (read_minibuf): Use it.
+ (syms_of_minibuf) <history-add-new-input>: New Lisp variable.
+ (syms_of_minibuf) <history-delete-duplicates>: Doc fix.
+
+2006-05-31 Kim F. Storm <storm@cua.dk>
+
+ * process.c (select_wrapper): Add wrapper around select to work around
+ "incomplete backtrace" bug in gdb 5.3, when emacs is stopped inside
+ select called from wait_reading_process_output.
+
+2006-05-30 Andreas Schwab <schwab@suse.de>
+
+ * xmenu.c (Fmenu_bar_start): Return a value.
+
+2006-05-30 Richard Stallman <rms@gnu.org>
+
+ * coding.c (Ffind_operation_coding_system): Doc fix.
+
+2006-05-30 Eli Zaretskii <eliz@gnu.org>
+
+ * w32term.c (x_draw_hollow_cursor): Fix last change.
+
+2006-05-29 Kim F. Storm <storm@cua.dk>
+
+ * w32term.c (x_draw_stretch_glyph_string): Fix last change.
+
+2006-05-29 Eli Zaretskii <eliz@gnu.org>
+
+ * coding.c (Ffind_operation_coding_system): Doc fix.
+
+2006-05-29 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macfns.c [USE_MAC_FONT_PANEL] (Fmac_set_font_panel_visibility):
+ Call mac_set_font_info_for_selection if font panel is made visible.
+
+ * macterm.c (font_panel_shown_p) [USE_MAC_FONT_PANEL]: New variable.
+ (mac_font_panel_visible_p, mac_show_hide_font_panel)
+ [USE_MAC_FONT_PANEL]: New functions.
+ [USE_MAC_FONT_PANEL] (mac_set_font_info_for_selection): Return
+ immediately if font panel is not visible.
+
+ * macterm.h (mac_font_panel_visible_p, mac_show_hide_font_panel):
+ Add externs.
+
+2006-05-29 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * search.c (matcher_overflow): Mark as NO_RETURN.
+
+ * xterm.c (x_connection_closed): Likewise.
+
+ * sysdep.c (croak): Likewise.
+
+ * sound.c (sound_perror, alsa_sound_perror): Likewise.
+
+ * lisp.h (die, nsberror): Likewise.
+
+2006-05-29 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * sound.c (alsa_open, alsa_configure, alsa_write): Move
+ assignment to err out of if-statement.
+
+ * gtkutil.c (menu_nav_ended): New function.
+ (create_menus): Connect menu_nav_ended to "selection-done" to fix
+ grabs.
+
+ * xmenu.c (Fmenu_bar_start): New function for USE_GTK and USE_X_TOOLKIT.
+
+2006-05-28 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * charset.h (invalid_character): Mark as NO_RETURN.
+
+2006-05-29 Kenichi Handa <handa@m17n.org>
+
+ * coding.c (Ffind_operation_coding_system): Call a function by
+ safe_call1 instead of call1.
+
+2006-05-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * window.c (struct saved_window): Add `dedicated'.
+ (Fset_window_configuration, save_window_save): Save/restore the
+ `dedicated' flag.
+
+2006-05-28 Kim F. Storm <storm@cua.dk>
+
+ * xdisp.c (set_cursor_from_row): If cursor cannot be set in row,
+ don't update w->cursor and return 0. Return 1 on success.
+ (try_cursor_movement): Repeat set_cursor_from_row on successive rows
+ until it succeeds.
+
+ * dispextern.h (set_cursor_from_row): Update prototype.
+
+2006-05-28 Kim F. Storm <storm@cua.dk>
+
+ * xdisp.c (get_phys_cursor_geometry): Return computed x and y through
+ parameters. Adjust x and width in case cursor in on a partially
+ visible stretch glyph on the left edge.
+ (erase_phys_cursor): Don't erase into left fringe/margin in case
+ previous cursor glyph is a partially visible stretch glyph on left.
+
+ * dispextern.h (get_phys_cursor_geometry): Update prototype.
+
+ * xterm.c (x_draw_stretch_glyph_string): Fix problems with invisible
+ cursor and erasing cursor on partially visible stretch glyph on left.
+ (x_draw_hollow_cursor): Compute x via get_phys_cursor_geometry.
+
+ * macterm.c: Likewise.
+
+ * w32term.c: Likewise.
+
+2006-05-27 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macselect.c (mac_handle_apple_event):
+ Return errAEEventNotHandled if key binding is not found.
+
+2006-05-26 Eli Zaretskii <eliz@gnu.org>
+
+ * emacs.c (main) [PROFILING]: Enable also for __MINGW32__.
+ [__MINGW32__]: MinGW-specific declaration of `etext'.
+
+ * w32heap.c (etext, edata): Remove unused definitions.
+
+2006-05-26 Chong Yidong <cyd@stupidchicken.com>
+
+ * fileio.c (Fcopy_file): Delete argument MUSTBENEW.
+ Incorporate the exclusive file-opening functionality into the behavior
+ when OK-IF-ALREADY-EXISTS is nil.
+ (Frename_file): Call Fcopy_file without MUSTBENEW argument.
+
+2006-05-26 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * sound.c (alsa_configure): Move get period/buffer_size after
+ setting hwparams.
+
+2006-05-26 Kenichi Handa <handa@m17n.org>
+
+ * coding.c (Ffind_operation_coding_system): Allow (FILENAME
+ . BUFFER) in TARGET.
+
+2006-05-25 Chong Yidong <cyd@stupidchicken.com>
+
+ * image.c (png_load): Don't call fclose on NULL.
+
+2006-05-25 Luc Teirlinck <teirllm@auburn.edu>
+
+ * fns.c (Fyes_or_no_p):
+ * callint.c (Fcall_interactively): Fread_from_minibuffer now takes
+ only seven args.
+
+2006-05-25 Juri Linkov <juri@jurta.org>
+
+ * lisp.h (Fread_from_minibuffer): Decrement number of args.
+
+ * minibuf.c (read_minibuf): Remove arg KEEP_ALL. Callers changed.
+ (Fread_from_minibuffer): Remove arg KEEP_ALL. Callers changed.
+
+ * buffer.c (mode-line-format): Fix docstring.
+
+2006-05-25 Richard Stallman <rms@gnu.org>
+
+ * emacs.c (main, Fdump_emacs): Don't test __linux or __linux__.
+
+2006-05-24 Luc Teirlinck <teirllm@auburn.edu>
+
+ * puresize.h (BASE_PURESIZE): Increase to 1210000.
+
+2006-05-24 Alan Mackenzie <acm@muc.de>
+
+ * lread.c (Vload_history): Enhance doc-string to say that the file
+ is the absolute truename of the loaded file.
+
+ * lread.c (Vafter_load_alist): doc-string: state that an element
+ now has a regexp to match file names, not a file name as such.
+
+ * lread.c (readevalloop): Call file-truename on the name for
+ load-history, except at preloading time.
+
+ * lread.c (Fload): At preloading time, preserve the extension of
+ the filename which goes into load-history. New var hist_file_name.
+
+ * lread.c (Fload): Do eval-after-load stuff by calling the lisp
+ function do-after-load-evaluation.
+
+2006-05-24 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * mac.c (ae_attr_table): New variable.
+ (syms_of_mac): Intern and staticpro its elements.
+ (mac_aelist_to_lisp): Also convert Apple event attributes.
+ (mac_ae_put_lisp): New function.
+ (create_apple_event_from_event_ref) [MAC_OSX]: Use typeUTF8Text.
+
+ * macfns.c (Fx_server_version): Use gestaltSystemVersionMajor etc.
+
+ * macselect.c (Qemacs_suspension_id): New variable.
+ (syms_of_macselect): Intern and staticpro it.
+ (struct suspended_ae_info): New struct.
+ (deferred_apple_events, defer_apple_events)
+ (Fmac_process_deferred_apple_events): Use it.
+ (suspended_apple_events): New variable.
+ (mac_handle_apple_event_1): New function.
+ (mac_handle_apple_event): Use it. Don't process previously
+ suspended events.
+ (cleanup_suspended_apple_events, get_suspension_id)
+ (cleanup_all_suspended_apple_events): New functions.
+ (init_apple_event_handler): Call cleanup_all_suspended_apple_events
+ at exit.
+ (Fmac_cleanup_expired_apple_events, Fmac_ae_set_reply_parameter)
+ (Fmac_resume_apple_event): New defuns.
+ (syms_of_macselect): Defsubr them.
+
+ * macterm.c (fn_keycode_to_keycode_table, XTread_socket) [MAC_OSX]:
+ Fix last change. Don't map `fn' modifier if pressed with F1 ... F12.
+
+ * macterm.h (TYPE_FILE_NAME): Change from macro to enumerator.
+ (KEY_EMACS_SUSPENSION_ID_ATTR): New enumerator.
+ (keyReplyRequestedAttr) [MAC_OS_X_VERSION_MAX_ALLOWED < 1030]: Likewise.
+ (gestaltSystemVersionMajor, gestaltSystemVersionMinor)
+ (gestaltSystemVersionBugFix) [MAC_OS_X_VERSION_MAX_ALLOWED < 1040]:
+ Likewise.
+ (typeUTF8Text, kEventParamWindowMouseLocation)
+ [MAC_OSX && MAC_OS_X_VERSION_MAX_ALLOWED < 1020]: Likewise.
+ (x_get_focus_frame, mac_ae_put_lisp): Add externs.
+
+2006-05-23 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (fn_keycode_to_xkeysym_table, convert_fn_keycode): Remove.
+ (fn_keycode_to_keycode_table) [MAC_OSX]: New variable.
+ (mac_set_unicode_keystroke_event) [TARGET_API_MAC_CARBON]: New function.
+ (XTread_socket) [TARGET_API_MAC_CARBON]: Use it.
+ (XTread_socket) [MAC_OSX]: Try 'uchr' Unicode keyboard-layout
+ resource to backtranslate key with modifiers.
+ (XTread_socket): Don't set read_socket_inev around AEProcessAppleEvent.
+
+2006-05-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * 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
+ x_alloc_lighter_color_for_widget. Remove duplicated declarations.
+
+2006-05-21 Richard Stallman <rms@gnu.org>
+
+ * xfaces.c (best_matching_font): Abort for best == NULL
+ before we start to use it.
+
+ * buffer.c (syms_of_buffer, Fmake_overlay): Doc fixes.
+
+2006-05-20 Kim F. Storm <storm@cua.dk>
+
+ * xfaces.c (best_matching_font): Fix crash in 2006-05-17 change.
+
+2006-05-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macterm.c (convert_fn_keycode): Fix last change.
+
+2006-05-19 Eli Zaretskii <eliz@gnu.org>
+
+ * w32.c (init_environment): Perform the processing of environment
+ variables on a copy of default variables and their values, not on
+ the original. Simplify code that calls ExpandEnvironmentStrings
+ and make buf1[] and buf2[] more visible for easier debugging.
+
+2006-05-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * frame.c (x_set_border_width): Remove #ifndef MAC_OS.
+
+ * image.c [MAC_OS] (gif_load): Allocate Lisp string first.
+
+ * macfns.c (Fx_focus_frame): Don't check dpyinfo->x_focus_frame.
+
+ * macterm.c (XTread_socket) [TARGET_API_MAC_CARBON && MAC_OSX]:
+ Forward keyUp events to toolbox_dispatcher.
+
+ * window.c (foreach_window): Check WINDOWP (FRAME_ROOT_WINDOW (f)).
+
+2006-05-18 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
+
+ * config.in: Regenerated (HAVE_ALSA).
+
+ * sound.c (alsa_sound_perror, alsa_open, alsa_period_size)
+ (alsa_configure, alsa_close, alsa_choose_format, alsa_write)
+ (snd_error_quiet, alsa_init): New functions.
+ (vox_init): Return 0 if unable to open device.
+ (Fplay_sound_internal): Test for alsa first and use vox (oss) as
+ a fallback.
+ (struct sound_device): Add period_size.
+ (wav_play, au_play): Use period_size if set.
+
+ * Makefile.in (CFLAGS_SOUND): New flags for ALSA
+ (ALL_CFLAGS): Add CFLAGS_SOUND
+
+2006-05-18 Kenichi Handa <handa@m17n.org>
+
+ * callproc.c (Fcall_process): Reject encoding arguments by
+ ascii-incompatible coding systems (e.g. utf-16).
+
+ * coding.c (Qascii_incompatible): New variable.
+ (syms_of_coding): Setup Qascii_incompatible.
+ (setup_coding_system): Be sure to initialize coding->common_flags.
+ Check `ascii-incompatible' property of the coding system.
+
+ * coding.h (CODING_ASCII_INCOMPATIBLE_MASK): New macro.
+
+2006-05-18 Kim F. Storm <storm@cua.dk>
+
+ * xdisp.c (display_tool_bar_line): Restore entire tool-bar geometry when
+ backtracking in case last image doesn't fit on line.
+
+2006-05-18 MIYOSHI Masanori <miyoshi@meadowy.org> (tiny change)
+
+ * xdisp.c (display_tool_bar_line): Don't adjust tool-bar height by more than
+ height of one frame default line.
+
+2006-05-17 Richard Stallman <rms@gnu.org>
+
+ * xfaces.c (better_font_p): Any font beats no font.
+ (best_matching_font): Simplify based on above change.
+
+ * buffer.c (Fprevious_overlay_change, Fnext_overlay_change): Doc fixes.
+
2006-05-16 Kim F. Storm <storm@cua.dk>
* xterm.c (handle_one_xevent): Check that f is not NULL before
@@ -62,7 +500,7 @@
[MAC_OS] (gif_load): Emulate Graphic Control Extension block.
* macfns.c (x_to_mac_color): Fix shift amount change.
- [USE_MAC_FONT_PANEL] (mac_set_font): Use x_get_focus_frame.
+ (mac_set_font) [USE_MAC_FONT_PANEL]: Use x_get_focus_frame.
[USE_MAC_FONT_PANEL] (Fmac_set_font_panel_visibility): Doc fix.
* macselect.c (Vmac_service_selection) [MAC_OSX]: Rename from
@@ -490,7 +928,7 @@
* puresize.h (BASE_PURESIZE): Increment to 1210000.
-2006-04-13 Micha,Ak(Bl Cadilhac <michael.cadilhac@lrde.org> (tiny change)
+2006-04-13 Micha,Ak(Bl Cadilhac <michael.cadilhac@lrde.org>
* print.c (Fprin1_to_string): Mention in the `doc' that the
behavior is modified by `print-level' and `print-length'.
@@ -611,7 +1049,7 @@
* xfaces.c (Finternal_merge_in_global_face, try_font_list):
Add explicit braces to avoid ambiguous `else'.
-2006-04-11 Micha,Ak(Bl Cadilhac <michael.cadilhac@lrde.org> (tiny change)
+2006-04-11 Micha,Ak(Bl Cadilhac <michael.cadilhac@lrde.org>
* dispnew.c (init_display): Don't init X display if the user asked
for a non-X display.
@@ -8477,7 +8915,7 @@
* xfns.c (xic_create_xfontset): Initialize missing_list to NULL.
-2004-10-21 K,Ba(Broly L,Bu(Brentey <lorentey@elte.hu>
+2004-10-21 K,Aa(Broly L$,1 q(Brentey <lorentey@elte.hu>
* xterm.h (x_output): New member `xic_base_fontname'.
(FRAME_XIC_BASE_FONTNAME): New macro.
@@ -9421,7 +9859,7 @@
* fileio.c (Fvisited_file_modtime): Return a list of two integers,
instead of a cons.
-2004-07-14 K,Ba(Broly L,Bu(Brentey <lorentey@elte.hu>
+2004-07-14 K,Aa(Broly L$,1 q(Brentey <lorentey@elte.hu>
* keyboard.c (echo_dash): Do nothing if there already is a dash
at the end of the echo string.
@@ -9758,7 +10196,7 @@
* keyboard.c (cmd_error): Don't call any_kboard_state
if inside a recursive edit level.
-2004-06-13 K,Ba(Broly L,Bu(Brentey <lorentey@elte.hu>
+2004-06-13 K,Aa(Broly L$,1 q(Brentey <lorentey@elte.hu>
* keyboard.c (command_loop): Call any_kboard_state before
command_loop_2 when at top level.
@@ -10071,7 +10509,7 @@
before actually accepting connection in case it has already been
accepted due to recursion.
-2004-05-23 K,Ba(Broly L,Bu(Brentey <lorentey@elte.hu>
+2004-05-23 K,Aa(Broly L$,1 q(Brentey <lorentey@elte.hu>
* coding.c (Fset_safe_terminal_coding_system_internal):
Set suppress_error in safe_terminal_coding, not terminal_coding.
@@ -17007,8 +17445,7 @@
(Fapropos_internal): Initialize them and clear them out.
Don't GCPRO them.
- * buffer.c (syms_of_buffer) <scroll-up-aggressively, scroll-down-aggressively>:
- Doc fixes.
+ * buffer.c (syms_of_buffer) <scroll-up|down-aggressively>: Doc fixes.
* lisp.h: New misc type Lisp_Save_Value.
(enum Lisp_Misc_Type): Add Lisp_Misc_Save_Value.
diff --git a/src/Makefile.in b/src/Makefile.in
index 049a4c5bc17..342540df7be 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -281,7 +281,7 @@ TOOLKIT_DEFINES =
/* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM
since it may have -I options that should override those two. */
-ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@
+ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@
.c.o:
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
@@ -459,6 +459,7 @@ LIBX= $(LIBXMENU) LD_SWITCH_X_SITE -lX10 LIBX10_MACHINE LIBX10_SYSTEM
#endif /* not HAVE_X_WINDOWS */
LIBSOUND= @LIBSOUND@
+CFLAGS_SOUND= @CFLAGS_SOUND@
#ifndef ORDINARY_LINK
/* Fix linking if compiled with GCC. */
diff --git a/src/buffer.c b/src/buffer.c
index e4d846c8093..5bdfe737767 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2481,10 +2481,10 @@ swap_out_buffer_local_variables (b)
Return the number found, and store them in a vector in *VEC_PTR.
Store in *LEN_PTR the size allocated for the vector.
Store in *NEXT_PTR the next position after POS where an overlay starts,
- or ZV if there are no more overlays.
+ or ZV if there are no more overlays between POS and ZV.
Store in *PREV_PTR the previous position before POS where an overlay ends,
or where an overlay starts which ends at or after POS;
- or BEGV if there are no such overlays.
+ or BEGV if there are no such overlays from BEGV to POS.
NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
*VEC_PTR and *LEN_PTR should contain a valid vector and size
@@ -3570,10 +3570,10 @@ If omitted, BUFFER defaults to the current buffer.
BEG and END may be integers or markers.
The fourth arg FRONT-ADVANCE, if non-nil, makes the marker
for the front of the overlay advance when text is inserted there
-(which means the text *is not* included in the overlay).
+\(which means the text *is not* included in the overlay).
The fifth arg REAR-ADVANCE, if non-nil, makes the marker
for the rear of the overlay advance when text is inserted there
-(which means the text *is* included in the overlay). */)
+\(which means the text *is* included in the overlay). */)
(beg, end, buffer, front_advance, rear_advance)
Lisp_Object beg, end, buffer;
Lisp_Object front_advance, rear_advance;
@@ -3955,7 +3955,8 @@ or between BEG and END. */)
DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
1, 1, 0,
doc: /* Return the next position after POS where an overlay starts or ends.
-If there are no more overlay boundaries after POS, return (point-max). */)
+If there are no overlay boundaries from POS to (point-max),
+the value is (point-max). */)
(pos)
Lisp_Object pos;
{
@@ -3996,7 +3997,8 @@ If there are no more overlay boundaries after POS, return (point-max). */)
DEFUN ("previous-overlay-change", Fprevious_overlay_change,
Sprevious_overlay_change, 1, 1, 0,
doc: /* Return the previous position before POS where an overlay starts or ends.
-If there are no more overlay boundaries before POS, return (point-min). */)
+If there are no overlay boundaries from (point-min) to POS,
+the value is (point-min). */)
(pos)
Lisp_Object pos;
{
@@ -5454,10 +5456,11 @@ A string is printed verbatim in the mode line except for %-constructs:
%p -- print percent of buffer above top of window, or Top, Bot or All.
%P -- print percent of buffer above bottom of window, perhaps plus Top,
or print Bottom or All.
- %m -- print the mode name.
%n -- print Narrow if appropriate.
+ %t -- visited file is text or binary (if OS supports this distinction).
%z -- print mnemonics of buffer, terminal, and keyboard coding systems.
%Z -- like %z, but including the end-of-line format.
+ %e -- print error message about full memory.
%[ -- print one [ for each recursive editing level. %] similar.
%% -- print %. %- -- print infinitely many dashes.
Decimal digits after the % specify field width to which to pad. */);
@@ -5753,7 +5756,7 @@ the actual bitmap shown in the left or right fringe for the logical
indicator. LEFT and RIGHT are the bitmaps shown in the left and/or
right fringe for the specific indicator. The LEFT1 or RIGHT1 bitmaps
are used only for the `bottom' and `one-line' indicators when the last
-(only) line in has no final newline. BITMAPS may also be a single
+\(only) line in has no final newline. BITMAPS may also be a single
symbol which is used in both left and right fringes. */);
DEFVAR_PER_BUFFER ("fringe-cursor-alist",
@@ -6000,7 +6003,7 @@ this variable has no effect; the cursor appears as a hollow box. */);
doc: /* Additional space to put between lines when displaying a buffer.
The space is measured in pixels, and put below lines on window systems.
If value is a floating point number, it specifies the spacing relative
-to the default frame line height. */);
+to the default frame line height. nil means add no extra space. */);
DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
&current_buffer->cursor_in_non_selected_windows, Qnil,
diff --git a/src/callint.c b/src/callint.c
index 4789fb5582d..ae10e64e1de 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -730,7 +730,7 @@ If KEYS is omitted or nil, the return value of `this-command-keys' is used. */)
tem = Fread_from_minibuffer (build_string (callint_message),
Qnil, Qnil, Qnil, Qnil, Qnil,
- Qnil, Qnil);
+ Qnil);
if (! STRINGP (tem) || SCHARS (tem) == 0)
args[i] = Qnil;
else
diff --git a/src/coding.c b/src/coding.c
index debb2f27ffc..9f95c2c6777 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -8315,7 +8315,7 @@ is selected as the TARGET. For example, if OPERATION does file I/O,
whichever argument specifies the file name is TARGET.
TARGET has a meaning which depends on OPERATION:
- For file I/O, TARGET is a file name.
+ For file I/O, TARGET is a file name (except for the special case below).
For process I/O, TARGET is a process name.
For network I/O, TARGET is a service name or a port number
@@ -8327,6 +8327,13 @@ 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 OPERATION is `insert-file-contents', the argument corresponding to
+TARGET may be a cons (FILENAME . BUFFER). In that case, FILENAME is a
+file name to look up, and BUFFER is a buffer that contains the file's
+contents (not yet decoded). If `file-coding-system-alist' specifies a
+function to call for FILENAME, that function should examine the
+contents of BUFFER instead of reading the file.
+
usage: (find-operation-coding-system OPERATION ARGUMENTS ...) */)
(nargs, args)
int nargs;
@@ -8380,7 +8387,7 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS ...) */)
return Fcons (val, val);
if (! NILP (Ffboundp (val)))
{
- val = call1 (val, Flist (nargs, args));
+ val = safe_call1 (val, Flist (nargs, args));
if (CONSP (val))
return val;
if (SYMBOLP (val) && ! NILP (Fcoding_system_p (val)))
diff --git a/src/config.in b/src/config.in
index 9c1abadd283..106aeea920c 100644
--- a/src/config.in
+++ b/src/config.in
@@ -87,6 +87,9 @@ Boston, MA 02110-1301, USA. */
*/
#undef HAVE_ALLOCA_H
+/* Define to 1 if ALSA is available. */
+#undef HAVE_ALSA
+
/* Define to 1 if you have the `bcmp' function. */
#undef HAVE_BCMP
@@ -955,6 +958,9 @@ Boston, MA 02110-1301, USA. */
#ifdef HAVE_SOUNDCARD_H
#define HAVE_SOUND 1
#endif
+#ifdef HAVE_ALSA
+#define HAVE_SOUND 1
+#endif
#endif /* __FreeBSD__ || __NetBSD__ || __linux__ */
/* If using GNU, then support inline function declarations. */
diff --git a/src/dispextern.h b/src/dispextern.h
index 0aac78f9557..92005e6b149 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2642,8 +2642,8 @@ void remember_mouse_glyph P_ ((struct frame *, int, int, NativeRectangle *));
void mark_window_display_accurate P_ ((Lisp_Object, int));
void redisplay_preserve_echo_area P_ ((int));
-void set_cursor_from_row P_ ((struct window *, struct glyph_row *,
- struct glyph_matrix *, int, int, int, int));
+int set_cursor_from_row P_ ((struct window *, struct glyph_row *,
+ struct glyph_matrix *, int, int, int, int));
void init_iterator P_ ((struct it *, struct window *, int,
int, struct glyph_row *, enum face_id));
void init_iterator_to_row_start P_ ((struct it *, struct window *,
@@ -2703,8 +2703,8 @@ extern void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
extern void draw_phys_cursor_glyph P_ ((struct window *,
struct glyph_row *,
enum draw_glyphs_face));
-extern int get_phys_cursor_geometry P_ ((struct window *, struct glyph_row *,
- struct glyph *, int *));
+extern void get_phys_cursor_geometry P_ ((struct window *, struct glyph_row *,
+ struct glyph *, int *, int *, int *));
extern void erase_phys_cursor P_ ((struct window *));
extern void display_and_set_cursor P_ ((struct window *,
int, int, int, int, int));
diff --git a/src/dispnew.c b/src/dispnew.c
index e8833376701..f239d6969f4 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -355,8 +355,7 @@ static unsigned history_tick;
static void add_frame_display_history P_ ((struct frame *, int));
static void add_window_display_history P_ ((struct window *, char *, int));
-
-
+
/* Add to the redisplay history how window W has been displayed.
MSG is a trace containing the information how W's glyph matrix
has been constructed. PAUSED_P non-zero means that the update
@@ -6391,7 +6390,9 @@ sit_for (sec, usec, reading, display, initial_display)
{
swallow_events (display);
- if (detect_input_pending_run_timers (display) || !NILP (Vexecuting_kbd_macro))
+ if ((detect_input_pending_run_timers (display)
+ && !redisplay_dont_pause)
+ || !NILP (Vexecuting_kbd_macro))
return Qnil;
if (initial_display)
@@ -6421,6 +6422,9 @@ Redisplay is preempted as always if input arrives, and does not happen
if input is available before it starts.
Value is t if waited the full time with no input arriving.
+Redisplay will occur even when input is available if you bind
+`redisplay-dont-pause' to a non-nil value.
+
An obsolete but still supported form is
\(sit-for SECONDS &optional MILLISECONDS NODISP)
Where the optional arg MILLISECONDS specifies an additional wait period,
diff --git a/src/emacs.c b/src/emacs.c
index 27e349c637f..4bbbf84ebab 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1770,16 +1770,21 @@ main (argc, argv
#endif
}
- /* Set up for profiling. This is known to work on FreeBSD and
- GNU/Linux. It might work on some other systems too. Give it a
- try and tell us if it works on your system. To compile for
- profiling use something like `make CFLAGS="-pg -g -O -DPROFILING=1'. */
-#if defined (__FreeBSD__) || defined (__linux)
+ /* Set up for profiling. This is known to work on FreeBSD,
+ GNU/Linux and MinGW. It might work on some other systems too.
+ Give it a try and tell us if it works on your system. To compile
+ for profiling use something like:
+ `make CFLAGS="-pg -g -O -DPROFILING=1'. */
+#if defined (__FreeBSD__) || defined (GNU_LINUX) || defined(__MINGW32__)
#ifdef PROFILING
if (initialized)
{
extern void _mcleanup ();
+#ifdef __MINGW32__
+ extern unsigned char etext asm ("etext");
+#else
extern char etext;
+#endif
extern void safe_bcopy ();
extern void dump_opcode_frequencies ();
@@ -2253,7 +2258,7 @@ You must run Emacs in batch mode in order to dump it. */)
if (! noninteractive)
error ("Dumping Emacs works only in batch mode");
-#ifdef __linux__
+#ifdef GNU_LINUX
if (heap_bss_diff > MAX_HEAP_BSS_DIFF)
{
fprintf (stderr, "**************************************************\n");
@@ -2265,7 +2270,7 @@ You must run Emacs in batch mode in order to dump it. */)
fprintf (stderr, "exec-shield in etc/PROBLEMS for more information.\n");
fprintf (stderr, "**************************************************\n");
}
-#endif /* __linux__ */
+#endif /* GNU_LINUX */
/* Bind `command-line-processed' to nil before dumping,
so that the dumped Emacs will process its command line
diff --git a/src/fileio.c b/src/fileio.c
index 84b32f8dda9..8ce89ba23f3 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2409,32 +2409,31 @@ barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
return;
}
-DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6,
+DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5,
"fCopy file: \nGCopy %s to file: \np\nP",
doc: /* Copy FILE to NEWNAME. Both args must be strings.
If NEWNAME names a directory, copy FILE there.
-Signals a `file-already-exists' error if file NEWNAME already exists,
-unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
-A number as third arg means request confirmation if NEWNAME already exists.
-This is what happens in interactive use with M-x.
-Always sets the file modes of the output file to match the input file.
+
+This function always sets the file modes of the output file to match
+the input file.
+
+The optional third argument OK-IF-ALREADY-EXISTS specifies what to do
+if file NEWNAME already exists. If OK-IF-ALREADY-EXISTS is nil, we
+signal a `file-already-exists' error without overwriting. If
+OK-IF-ALREADY-EXISTS is a number, we request confirmation from the user
+about overwriting; this is what happens in interactive use with M-x.
+Any other value for OK-IF-ALREADY-EXISTS means to overwrite the
+existing file.
Fourth arg KEEP-TIME non-nil means give the output file the same
last-modified time as the old one. (This works on only some systems.)
A prefix arg makes KEEP-TIME non-nil.
-The optional fifth arg MUSTBENEW, if non-nil, insists on a check
-for an existing file with the same name. If MUSTBENEW is `excl',
-that means to get an error if the file already exists; never overwrite.
-If MUSTBENEW is neither nil nor `excl', that means ask for
-confirmation before overwriting, but do go ahead and overwrite the file
-if the user confirms.
-
If PRESERVE-UID-GID is non-nil, we try to transfer the
uid and gid of FILE to NEWNAME. */)
- (file, newname, ok_if_already_exists, keep_time, mustbenew, preserve_uid_gid)
- Lisp_Object file, newname, ok_if_already_exists, keep_time, mustbenew;
+ (file, newname, ok_if_already_exists, keep_time, preserve_uid_gid)
+ Lisp_Object file, newname, ok_if_already_exists, keep_time;
Lisp_Object preserve_uid_gid;
{
int ifd, ofd, n;
@@ -2451,9 +2450,6 @@ uid and gid of FILE to NEWNAME. */)
CHECK_STRING (file);
CHECK_STRING (newname);
- if (!NILP (mustbenew) && !EQ (mustbenew, Qexcl))
- barf_or_query_if_file_exists (newname, "overwrite", 1, 0, 1);
-
if (!NILP (Ffile_directory_p (newname)))
newname = Fexpand_file_name (Ffile_name_nondirectory (file), newname);
else
@@ -2556,12 +2552,12 @@ uid and gid of FILE to NEWNAME. */)
/* System's default file type was set to binary by _fmode in emacs.c. */
ofd = emacs_open (SDATA (encoded_newname),
O_WRONLY | O_TRUNC | O_CREAT
- | (EQ (mustbenew, Qexcl) ? O_EXCL : 0),
+ | (NILP (ok_if_already_exists) ? O_EXCL : 0),
S_IREAD | S_IWRITE);
#else /* not MSDOS */
ofd = emacs_open (SDATA (encoded_newname),
O_WRONLY | O_TRUNC | O_CREAT
- | (EQ (mustbenew, Qexcl) ? O_EXCL : 0),
+ | (NILP (ok_if_already_exists) ? O_EXCL : 0),
0666);
#endif /* not MSDOS */
#endif /* VMS */
@@ -2806,7 +2802,7 @@ This is what happens in interactive use with M-x. */)
/* We have already prompted if it was an integer,
so don't have copy-file prompt again. */
NILP (ok_if_already_exists) ? Qnil : Qt,
- Qt, Qnil, Qt);
+ Qt, Qt);
Fdelete_file (file);
}
diff --git a/src/fns.c b/src/fns.c
index 545b4d7b0ea..3b4b3e5149b 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2798,7 +2798,7 @@ is nil, and `use-dialog-box' is non-nil. */)
{
ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
Qyes_or_no_p_history, Qnil,
- Qnil, Qnil));
+ Qnil));
if (SCHARS (ans) == 3 && !strcmp (SDATA (ans), "yes"))
{
UNGCPRO;
diff --git a/src/frame.c b/src/frame.c
index 1606f195f90..cafa9b655d4 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3156,10 +3156,8 @@ x_set_border_width (f, arg, oldval)
if (XINT (arg) == f->border_width)
return;
-#ifndef MAC_OS
if (FRAME_X_WINDOW (f) != 0)
error ("Cannot change the border width of a frame");
-#endif /* MAC_TODO */
f->border_width = XINT (arg);
}
diff --git a/src/gtkutil.c b/src/gtkutil.c
index b8d37df2214..2a6ed9d1524 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1970,6 +1970,34 @@ xg_create_one_menuitem (item, f, select_cb, highlight_cb, cl_data, group)
return w;
}
+/* Callback called when keyboard traversal (started by menu-bar-open) ends.
+ WMENU is the menu for which traversal has been done. DATA points to the
+ frame for WMENU. We must release grabs, some bad interaction between GTK
+ and Emacs makes the menus keep the grabs. */
+
+static void
+menu_nav_ended (wmenu, data)
+ GtkMenuShell *wmenu;
+ gpointer data;
+{
+ FRAME_PTR f = (FRAME_PTR) data;
+
+ if (FRAME_X_OUTPUT (f)->menubar_widget)
+ {
+ GtkMenuShell *w = GTK_MENU_SHELL (FRAME_X_OUTPUT (f)->menubar_widget);
+ Display *dpy = FRAME_X_DISPLAY (f);
+
+ BLOCK_INPUT;
+ gtk_menu_shell_deactivate (w);
+ gtk_menu_shell_deselect (w);
+
+ XUngrabKeyboard (dpy, CurrentTime);
+ XUngrabPointer (dpy, CurrentTime);
+ UNBLOCK_INPUT;
+ }
+}
+
+
static GtkWidget *create_menus P_ ((widget_value *, FRAME_PTR, GCallback,
GCallback, GCallback, int, int, int,
GtkWidget *, xg_menu_cb_data *, char *));
@@ -2024,6 +2052,12 @@ create_menus (data, f, select_cb, deactivate_cb, highlight_cb,
}
else wmenu = gtk_menu_bar_new ();
+ /* Fix up grabs after keyboard traversal ends. */
+ g_signal_connect (G_OBJECT (wmenu),
+ "selection-done",
+ G_CALLBACK (menu_nav_ended),
+ f);
+
/* Put cl_data on the top menu for easier access. */
cl_data = make_cl_data (cl_data, f, highlight_cb);
g_object_set_data (G_OBJECT (wmenu), XG_FRAME_DATA, (gpointer)cl_data);
diff --git a/src/image.c b/src/image.c
index f309a401139..70ffabc1937 100644
--- a/src/image.c
+++ b/src/image.c
@@ -6104,7 +6104,6 @@ png_load (f, img)
{
image_error ("Cannot open image file `%s'", file, Qnil);
UNGCPRO;
- fclose (fp);
return 0;
}
@@ -8067,18 +8066,18 @@ gif_load (f, img)
/* Save GIF image extension data for `image-extension-data'.
Format is (count IMAGES 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK). */
{
- unsigned char gce[4];
+ Lisp_Object gce = make_uninit_string (4);
int centisec = ((float)duration / time_scale) * 100.0f + 0.5f;
/* Fill the delay time field. */
- gce[1] = centisec & 0xff;
- gce[2] = (centisec >> 8) & 0xff;
+ SSET (gce, 1, centisec & 0xff);
+ SSET (gce, 2, (centisec >> 8) & 0xff);
/* We don't know about other fields. */
- gce[0] = gce[3] = 0;
+ SSET (gce, 0, 0);
+ SSET (gce, 3, 0);
img->data.lisp_val = list4 (Qcount, make_number (nsamples),
- make_number (0xf9),
- make_unibyte_string (gce, 4));
+ make_number (0xf9), gce);
}
/* Maybe fill in the background field while we have ximg handy. */
diff --git a/src/intervals.c b/src/intervals.c
index 21e60c96d3f..fecd1d181dc 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -2016,6 +2016,10 @@ set_point_both (buffer, charpos, bytepos)
register INTERVAL to, from, toprev, fromprev;
int buffer_point;
int old_position = BUF_PT (buffer);
+ /* This ensures that we move forward past intangible text when the
+ initial position is the same as the destination, in the rare
+ instances where this is important, e.g. in line-move-finish
+ (simple.el). */
int backwards = (charpos < old_position ? 1 : 0);
int have_overlays;
int original_position;
diff --git a/src/lisp.h b/src/lisp.h
index bf2426e25a7..af7fae52eaf 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -80,7 +80,7 @@ Boston, MA 02110-1301, USA. */
/* Extra internal type checking? */
extern int suppress_checking;
-extern void die P_((const char *, const char *, int));
+extern void die P_((const char *, const char *, int)) NO_RETURN;
#ifdef ENABLE_CHECKING
@@ -2816,7 +2816,7 @@ extern void set_time_zone_rule P_ ((char *));
/* defined in buffer.c */
extern int mouse_face_overlay_overlaps P_ ((Lisp_Object));
-extern void nsberror P_ ((Lisp_Object));
+extern void nsberror P_ ((Lisp_Object)) NO_RETURN;
extern char *no_switch_window P_ ((Lisp_Object window));
EXFUN (Fset_buffer_multibyte, 1);
EXFUN (Foverlay_start, 1);
@@ -2936,7 +2936,7 @@ extern void syms_of_search P_ ((void));
extern Lisp_Object last_minibuf_string;
extern void choose_minibuf_frame P_ ((void));
EXFUN (Fcompleting_read, 8);
-EXFUN (Fread_from_minibuffer, 8);
+EXFUN (Fread_from_minibuffer, 7);
EXFUN (Fread_variable, 2);
EXFUN (Fread_buffer, 3);
EXFUN (Fread_minibuffer, 2);
diff --git a/src/lread.c b/src/lread.c
index b6161ebedaa..d8abde1c458 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -89,6 +89,7 @@ Lisp_Object Qascii_character, Qload, Qload_file_name;
Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
Lisp_Object Qinhibit_file_name_operation;
Lisp_Object Qeval_buffer_list, Veval_buffer_list;
+Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */
/* Used instead of Qget_file_char while loading *.elc files compiled
by Emacs 21 or older. */
@@ -897,8 +898,8 @@ Return t if the file exists and loads successfully. */)
register int fd = -1;
int count = SPECPDL_INDEX ();
Lisp_Object temp;
- struct gcpro gcpro1, gcpro2;
- Lisp_Object found, efound;
+ struct gcpro gcpro1, gcpro2, gcpro3;
+ Lisp_Object found, efound, hist_file_name;
/* 1 means we printed the ".el is newer" message. */
int newer = 0;
/* 1 means we are loading a compiled file. */
@@ -906,6 +907,7 @@ Return t if the file exists and loads successfully. */)
Lisp_Object handler;
int safe_p = 1;
char *fmode = "r";
+ Lisp_Object tmp[2];
int version;
#ifdef DOS_NT
@@ -924,7 +926,7 @@ Return t if the file exists and loads successfully. */)
the need to gcpro noerror, nomessage and nosuffix.
(Below here, we care only whether they are nil or not.)
The presence of this call is the result of a historical accident:
- it used to be in every file-operations and when it got removed
+ it used to be in every file-operation and when it got removed
everywhere, it accidentally stayed here. Since then, enough people
supposedly have things like (load "$PROJECT/foo.el") in their .emacs
that it seemed risky to remove. */
@@ -944,7 +946,6 @@ Return t if the file exists and loads successfully. */)
if (SCHARS (file) > 0)
{
int size = SBYTES (file);
- Lisp_Object tmp[2];
found = Qnil;
GCPRO2 (file, found);
@@ -1028,6 +1029,13 @@ Return t if the file exists and loads successfully. */)
Vloads_in_progress = Fcons (found, Vloads_in_progress);
}
+ /* Get the name for load-history. */
+ hist_file_name = (! NILP (Vpurify_flag)
+ ? Fconcat (2, (tmp[0] = Ffile_name_directory (file),
+ tmp[1] = Ffile_name_nondirectory (found),
+ tmp))
+ : found) ;
+
version = -1;
if (!bcmp (SDATA (found) + SBYTES (found) - 4,
".elc", 4)
@@ -1040,7 +1048,7 @@ Return t if the file exists and loads successfully. */)
struct stat s1, s2;
int result;
- GCPRO2 (file, found);
+ GCPRO3 (file, found, hist_file_name);
if (version < 0
&& ! (version = safe_to_load_p (fd)))
@@ -1095,14 +1103,14 @@ Return t if the file exists and loads successfully. */)
if (fd >= 0)
emacs_close (fd);
- val = call4 (Vload_source_file_function, found, file,
+ val = call4 (Vload_source_file_function, found, hist_file_name,
NILP (noerror) ? Qnil : Qt,
NILP (nomessage) ? Qnil : Qt);
return unbind_to (count, val);
}
}
- GCPRO2 (file, found);
+ GCPRO3 (file, found, hist_file_name);
#ifdef WINDOWSNT
emacs_close (fd);
@@ -1142,23 +1150,23 @@ Return t if the file exists and loads successfully. */)
= Fcons (make_number (fileno (stream)), load_descriptor_list);
load_in_progress++;
if (! version || version >= 22)
- readevalloop (Qget_file_char, stream,
- (! NILP (Vpurify_flag) ? file : found),
+ readevalloop (Qget_file_char, stream, hist_file_name,
Feval, 0, Qnil, Qnil, Qnil, Qnil);
else
{
/* We can't handle a file which was compiled with
byte-compile-dynamic by older version of Emacs. */
specbind (Qload_force_doc_strings, Qt);
- readevalloop (Qget_emacs_mule_file_char, stream, file, Feval,
+ readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name, Feval,
0, Qnil, Qnil, Qnil, Qnil);
}
unbind_to (count, Qnil);
- /* Run any load-hooks for this file. */
- temp = Fassoc (file, Vafter_load_alist);
- if (!NILP (temp))
- Fprogn (Fcdr (temp));
+ /* Run any eval-after-load forms for this file */
+ if (NILP (Vpurify_flag)
+ && (!NILP (Ffboundp (Qdo_after_load_evaluation))))
+ call1 (Qdo_after_load_evaluation, hist_file_name) ;
+
UNGCPRO;
if (saved_doc_string)
@@ -1583,6 +1591,12 @@ readevalloop (readcharfun, stream, sourcename, evalfun,
GCPRO4 (sourcename, readfun, start, end);
+ /* Try to ensure sourcename is a truename, except whilst preloading. */
+ if (NILP (Vpurify_flag)
+ && !NILP (sourcename) && Ffile_name_absolute_p (sourcename)
+ && (!NILP (Ffboundp (Qfile_truename))))
+ sourcename = call1 (Qfile_truename, sourcename) ;
+
LOADHIST_ATTACH (sourcename);
continue_reading_p = 1;
@@ -4110,16 +4124,17 @@ customize `jka-compr-load-suffixes' rather than the present variable. */);
DEFVAR_LISP ("after-load-alist", &Vafter_load_alist,
doc: /* An alist of expressions to be evalled when particular files are loaded.
-Each element looks like (FILENAME FORMS...).
-When `load' is run and the file-name argument is FILENAME,
-the FORMS in the corresponding element are executed at the end of loading.
+Each element looks like (REGEXP-OR-FEATURE FORMS...).
-FILENAME must match exactly! Normally FILENAME is the name of a library,
-with no directory specified, since that is how `load' is normally called.
-An error in FORMS does not undo the load,
-but does prevent execution of the rest of the FORMS.
-FILENAME can also be a symbol (a feature) and FORMS are then executed
-when the corresponding call to `provide' is made. */);
+REGEXP-OR-FEATURE is either a regular expression to match file names, or
+a symbol \(a feature name).
+
+When `load' is run and the file-name argument matches an element's
+REGEXP-OR-FEATURE, or when `provide' is run and provides the symbol
+REGEXP-OR-FEATURE, the FORMS in the element are executed.
+
+An error in FORMS does not undo the load, but does prevent execution of
+the rest of the FORMS. */);
Vafter_load_alist = Qnil;
DEFVAR_LISP ("load-history", &Vload_history,
@@ -4127,6 +4142,10 @@ when the corresponding call to `provide' is made. */);
Each alist element is a list that starts with a file name,
except for one element (optional) that starts with nil and describes
definitions evaluated from buffers not visiting files.
+
+The file name is absolute and is the true file name (i.e. it doesn't
+contain symbolic links) of the loaded file.
+
The remaining elements of each list are symbols defined as variables
and cons cells of the form `(provide . FEATURE)', `(require . FEATURE)',
`(defun . FUNCTION)', `(autoload . SYMBOL)', and `(t . SYMBOL)'.
@@ -4263,6 +4282,12 @@ to load. See also `load-dangerous-libraries'. */);
Qeval_buffer_list = intern ("eval-buffer-list");
staticpro (&Qeval_buffer_list);
+ Qfile_truename = intern ("file-truename");
+ staticpro (&Qfile_truename) ;
+
+ Qdo_after_load_evaluation = intern ("do-after-load-evaluation");
+ staticpro (&Qdo_after_load_evaluation) ;
+
staticpro (&dump_path);
staticpro (&read_objects);
diff --git a/src/mac.c b/src/mac.c
index f7fcbe9ac88..5fc9ea4ee28 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -270,6 +270,26 @@ posix_to_mac_pathname (const char *ufn, char *mfn, int mfnbuflen)
static Lisp_Object Qundecoded_file_name;
+static struct {
+ AEKeyword keyword;
+ char *name;
+ Lisp_Object symbol;
+} ae_attr_table [] =
+ {{keyTransactionIDAttr, "transaction-id"},
+ {keyReturnIDAttr, "return-id"},
+ {keyEventClassAttr, "event-class"},
+ {keyEventIDAttr, "event-id"},
+ {keyAddressAttr, "address"},
+ {keyOptionalKeywordAttr, "optional-keyword"},
+ {keyTimeoutAttr, "timeout"},
+ {keyInteractLevelAttr, "interact-level"},
+ {keyEventSourceAttr, "event-source"},
+ /* {keyMissedKeywordAttr, "missed-keyword"}, */
+ {keyOriginalAddressAttr, "original-address"},
+ {keyReplyRequestedAttr, "reply-requested"},
+ {KEY_EMACS_SUSPENSION_ID_ATTR, "emacs-suspension-id"}
+ };
+
static Lisp_Object
mac_aelist_to_lisp (desc_list)
const AEDescList *desc_list;
@@ -281,22 +301,36 @@ mac_aelist_to_lisp (desc_list)
Size size;
AEKeyword keyword;
AEDesc desc;
+ int attribute_p = 0;
err = AECountItems (desc_list, &count);
if (err != noErr)
return Qnil;
result = Qnil;
+
+ again:
while (count > 0)
{
- err = AESizeOfNthItem (desc_list, count, &desc_type, &size);
+ if (attribute_p)
+ {
+ keyword = ae_attr_table[count - 1].keyword;
+ err = AESizeOfAttribute (desc_list, keyword, &desc_type, &size);
+ }
+ else
+ err = AESizeOfNthItem (desc_list, count, &desc_type, &size);
+
if (err == noErr)
switch (desc_type)
{
case typeAEList:
case typeAERecord:
case typeAppleEvent:
- err = AEGetNthDesc (desc_list, count, typeWildCard,
- &keyword, &desc);
+ if (attribute_p)
+ err = AEGetAttributeDesc (desc_list, keyword, typeWildCard,
+ &desc);
+ else
+ err = AEGetNthDesc (desc_list, count, typeWildCard,
+ &keyword, &desc);
if (err != noErr)
break;
elem = mac_aelist_to_lisp (&desc);
@@ -309,8 +343,13 @@ mac_aelist_to_lisp (desc_list)
else
{
elem = make_uninit_string (size);
- err = AEGetNthPtr (desc_list, count, typeWildCard, &keyword,
- &desc_type, SDATA (elem), size, &size);
+ if (attribute_p)
+ err = AEGetAttributePtr (desc_list, keyword, typeWildCard,
+ &desc_type, SDATA (elem),
+ size, &size);
+ else
+ err = AEGetNthPtr (desc_list, count, typeWildCard, &keyword,
+ &desc_type, SDATA (elem), size, &size);
}
if (err != noErr)
break;
@@ -319,18 +358,35 @@ mac_aelist_to_lisp (desc_list)
break;
}
- if (err != noErr)
- elem = Qnil;
- else if (desc_list->descriptorType != typeAEList)
+ if (err == noErr || desc_list->descriptorType == typeAEList)
{
- keyword = EndianU32_NtoB (keyword);
- elem = Fcons (make_unibyte_string ((char *) &keyword, 4), elem);
+ if (err != noErr)
+ elem = Qnil; /* Don't skip elements in AEList. */
+ else if (desc_list->descriptorType != typeAEList)
+ {
+ if (attribute_p)
+ elem = Fcons (ae_attr_table[count-1].symbol, elem);
+ else
+ {
+ keyword = EndianU32_NtoB (keyword);
+ elem = Fcons (make_unibyte_string ((char *) &keyword, 4),
+ elem);
+ }
+ }
+
+ result = Fcons (elem, result);
}
- result = Fcons (elem, result);
count--;
}
+ if (desc_list->descriptorType == typeAppleEvent && !attribute_p)
+ {
+ attribute_p = 1;
+ count = sizeof (ae_attr_table) / sizeof (ae_attr_table[0]);
+ goto again;
+ }
+
desc_type = EndianU32_NtoB (desc_list->descriptorType);
return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
}
@@ -403,6 +459,93 @@ mac_aedesc_to_lisp (desc)
return Fcons (make_unibyte_string ((char *) &desc_type, 4), result);
}
+OSErr
+mac_ae_put_lisp (desc, keyword_or_index, obj)
+ AEDescList *desc;
+ UInt32 keyword_or_index;
+ Lisp_Object obj;
+{
+ OSErr err;
+
+ if (!(desc->descriptorType == typeAppleEvent
+ || desc->descriptorType == typeAERecord
+ || desc->descriptorType == typeAEList))
+ return errAEWrongDataType;
+
+ if (CONSP (obj) && STRINGP (XCAR (obj)) && SBYTES (XCAR (obj)) == 4)
+ {
+ DescType desc_type1 = EndianU32_BtoN (*((UInt32 *) SDATA (XCAR (obj))));
+ Lisp_Object data = XCDR (obj), rest;
+ AEDesc desc1;
+
+ switch (desc_type1)
+ {
+ case typeNull:
+ case typeAppleEvent:
+ break;
+
+ case typeAEList:
+ case typeAERecord:
+ err = AECreateList (NULL, 0, desc_type1 == typeAERecord, &desc1);
+ if (err == noErr)
+ {
+ for (rest = data; CONSP (rest); rest = XCDR (rest))
+ {
+ UInt32 keyword_or_index1 = 0;
+ Lisp_Object elem = XCAR (rest);
+
+ if (desc_type1 == typeAERecord)
+ {
+ if (CONSP (elem) && STRINGP (XCAR (elem))
+ && SBYTES (XCAR (elem)) == 4)
+ {
+ keyword_or_index1 =
+ EndianU32_BtoN (*((UInt32 *)
+ SDATA (XCAR (elem))));
+ elem = XCDR (elem);
+ }
+ else
+ continue;
+ }
+
+ err = mac_ae_put_lisp (&desc1, keyword_or_index1, elem);
+ if (err != noErr)
+ break;
+ }
+
+ if (err == noErr)
+ {
+ if (desc->descriptorType == typeAEList)
+ err = AEPutDesc (desc, keyword_or_index, &desc1);
+ else
+ err = AEPutParamDesc (desc, keyword_or_index, &desc1);
+ }
+
+ AEDisposeDesc (&desc1);
+ }
+ return err;
+
+ default:
+ if (!STRINGP (data))
+ break;
+ if (desc->descriptorType == typeAEList)
+ err = AEPutPtr (desc, keyword_or_index, desc_type1,
+ SDATA (data), SBYTES (data));
+ else
+ err = AEPutParamPtr (desc, keyword_or_index, desc_type1,
+ SDATA (data), SBYTES (data));
+ return err;
+ }
+ }
+
+ if (desc->descriptorType == typeAEList)
+ err = AEPutPtr (desc, keyword_or_index, typeNull, NULL, 0);
+ else
+ err = AEPutParamPtr (desc, keyword_or_index, typeNull, NULL, 0);
+
+ return err;
+}
+
static pascal OSErr
mac_coerce_file_name_ptr (type_code, data_ptr, data_size,
to_type, handler_refcon, result)
@@ -722,8 +865,7 @@ create_apple_event_from_event_ref (event, num_params, names, types, result)
'?');
if (data == NULL)
break;
- /* typeUTF8Text is not available on Mac OS X 10.1. */
- AEPutParamPtr (result, names[i], 'utf8',
+ AEPutParamPtr (result, names[i], typeUTF8Text,
CFDataGetBytePtr (data), CFDataGetLength (data));
CFRelease (data);
break;
@@ -4661,7 +4803,7 @@ cfstring_create_normalized (str, symbol)
}
if (in_text)
- err = CreateUnicodeToTextInfo(&map, &uni);
+ err = CreateUnicodeToTextInfo (&map, &uni);
while (err == noErr)
{
out_buf = xmalloc (out_size);
@@ -5234,6 +5376,16 @@ syms_of_mac ()
QHFS_plus_C = intern ("HFS+C"); staticpro (&QHFS_plus_C);
#endif
+ {
+ int i;
+
+ for (i = 0; i < sizeof (ae_attr_table) / sizeof (ae_attr_table[0]); i++)
+ {
+ ae_attr_table[i].symbol = intern (ae_attr_table[i].name);
+ staticpro (&ae_attr_table[i].symbol);
+ }
+ }
+
defsubr (&Smac_coerce_ae_data);
#if TARGET_API_MAC_CARBON
defsubr (&Smac_get_preference);
diff --git a/src/macfns.c b/src/macfns.c
index 8e0d5153034..1c774f8ade2 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -1592,7 +1592,7 @@ x_set_icon_name (f, arg, oldval)
if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
return;
}
- else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
+ else if (!NILP (arg) || NILP (oldval))
return;
f->icon_name = arg;
@@ -2829,26 +2829,22 @@ FRAME nil means use the selected frame. */)
Lisp_Object frame;
{
struct frame *f = check_x_frame (frame);
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- if (dpyinfo->x_focus_frame != f)
- {
- BLOCK_INPUT;
+ BLOCK_INPUT;
#ifdef MAC_OSX
- ActivateWindow (ActiveNonFloatingWindow (), false);
- ActivateWindow (FRAME_MAC_WINDOW (f), true);
+ ActivateWindow (ActiveNonFloatingWindow (), false);
+ ActivateWindow (FRAME_MAC_WINDOW (f), true);
#else
#if !TARGET_API_MAC_CARBON
- /* SelectWindow (Non-Carbon) does not issue deactivate events if
- the possibly inactive window that is to be selected is
- already the frontmost one. */
- SendBehind (FRAME_MAC_WINDOW (f), NULL);
+ /* SelectWindow (Non-Carbon) does not issue deactivate events if the
+ possibly inactive window that is to be selected is already the
+ frontmost one. */
+ SendBehind (FRAME_MAC_WINDOW (f), NULL);
#endif
- /* This brings the window to the front. */
- SelectWindow (FRAME_MAC_WINDOW (f));
+ /* This brings the window to the front. */
+ SelectWindow (FRAME_MAC_WINDOW (f));
#endif
- UNBLOCK_INPUT;
- }
+ UNBLOCK_INPUT;
return Qnil;
}
@@ -3028,11 +3024,11 @@ If omitted or nil, that stands for the selected frame's display. */)
{
if (response >= 0x00001040)
{
- err = Gestalt ('sys1', &major); /* gestaltSystemVersionMajor */
+ err = Gestalt (gestaltSystemVersionMajor, &major);
if (err == noErr)
- err = Gestalt ('sys2', &minor); /* gestaltSystemVersionMinor */
+ err = Gestalt (gestaltSystemVersionMinor, &minor);
if (err == noErr)
- err = Gestalt ('sys3', &bugfix); /* gestaltSystemVersionBugFix */
+ err = Gestalt (gestaltSystemVersionBugFix, &bugfix);
}
else
{
@@ -4518,8 +4514,18 @@ This is for internal use only. Use `mac-font-panel-mode' instead. */)
check_mac ();
BLOCK_INPUT;
- if (NILP (visible) == (FPIsFontPanelVisible () == true))
- err = FPShowHideFontPanel ();
+ if (NILP (visible) != !mac_font_panel_visible_p ())
+ {
+ err = mac_show_hide_font_panel ();
+ if (err == noErr && !NILP (visible))
+ {
+ Lisp_Object focus_frame = x_get_focus_frame (SELECTED_FRAME ());
+ struct frame *f = (NILP (focus_frame) ? SELECTED_FRAME ()
+ : XFRAME (focus_frame));
+
+ mac_set_font_info_for_selection (f, DEFAULT_FACE_ID, 0);
+ }
+ }
UNBLOCK_INPUT;
if (err != noErr)
diff --git a/src/macgui.h b/src/macgui.h
index 690840c6c33..90688e5703e 100644
--- a/src/macgui.h
+++ b/src/macgui.h
@@ -112,6 +112,13 @@ typedef unsigned long Time;
#endif
#endif
+/* Whether to use Text Services Manager. */
+#ifndef USE_MAC_TSM
+#ifdef MAC_OSX
+#define USE_MAC_TSM 1
+#endif
+#endif
+
typedef WindowPtr Window;
typedef GWorldPtr Pixmap;
diff --git a/src/macselect.c b/src/macselect.c
index 1b6a1a46cc3..3afea1e9813 100644
--- a/src/macselect.c
+++ b/src/macselect.c
@@ -909,14 +909,13 @@ and t is the same as `SECONDARY'. */)
}
+/***********************************************************************
+ Apple event support
+***********************************************************************/
int mac_ready_for_apple_events = 0;
static Lisp_Object Vmac_apple_event_map;
static Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id;
-static struct
-{
- AppleEvent *buf;
- int size, count;
-} deferred_apple_events;
+static Lisp_Object Qemacs_suspension_id;
extern Lisp_Object Qundefined;
extern void mac_store_apple_event P_ ((Lisp_Object, Lisp_Object,
const AEDesc *));
@@ -927,6 +926,19 @@ struct apple_event_binding
Lisp_Object key, binding;
};
+struct suspended_ae_info
+{
+ UInt32 expiration_tick, suspension_id;
+ AppleEvent apple_event, reply;
+ struct suspended_ae_info *next;
+};
+
+/* List of deferred apple events at the startup time. */
+static struct suspended_ae_info *deferred_apple_events = NULL;
+
+/* List of suspended apple events, in order of expiration_tick. */
+static struct suspended_ae_info *suspended_apple_events = NULL;
+
static void
find_event_binding_fun (key, binding, args, data)
Lisp_Object key, binding, args;
@@ -1003,6 +1015,12 @@ defer_apple_events (apple_event, reply)
const AppleEvent *apple_event, *reply;
{
OSErr err;
+ struct suspended_ae_info *new;
+
+ new = xmalloc (sizeof (struct suspended_ae_info));
+ bzero (new, sizeof (struct suspended_ae_info));
+ new->apple_event.descriptorType = typeNull;
+ new->reply.descriptorType = typeNull;
err = AESuspendTheCurrentEvent (apple_event);
@@ -1011,30 +1029,88 @@ defer_apple_events (apple_event, reply)
manual says it doesn't. Anyway we create copies of them and save
them in `deferred_apple_events'. */
if (err == noErr)
+ err = AEDuplicateDesc (apple_event, &new->apple_event);
+ if (err == noErr)
+ err = AEDuplicateDesc (reply, &new->reply);
+ if (err == noErr)
{
- if (deferred_apple_events.buf == NULL)
- {
- deferred_apple_events.size = 16;
- deferred_apple_events.count = 0;
- deferred_apple_events.buf =
- xmalloc (sizeof (AppleEvent) * deferred_apple_events.size);
- }
- else if (deferred_apple_events.count == deferred_apple_events.size)
+ new->next = deferred_apple_events;
+ deferred_apple_events = new;
+ }
+ else
+ {
+ AEDisposeDesc (&new->apple_event);
+ AEDisposeDesc (&new->reply);
+ xfree (new);
+ }
+
+ return err;
+}
+
+static OSErr
+mac_handle_apple_event_1 (class, id, apple_event, reply)
+ Lisp_Object class, id;
+ const AppleEvent *apple_event;
+ AppleEvent *reply;
+{
+ OSErr err;
+ static UInt32 suspension_id = 0;
+ struct suspended_ae_info *new;
+
+ new = xmalloc (sizeof (struct suspended_ae_info));
+ bzero (new, sizeof (struct suspended_ae_info));
+ new->apple_event.descriptorType = typeNull;
+ new->reply.descriptorType = typeNull;
+
+ err = AESuspendTheCurrentEvent (apple_event);
+ if (err == noErr)
+ err = AEDuplicateDesc (apple_event, &new->apple_event);
+ if (err == noErr)
+ err = AEDuplicateDesc (reply, &new->reply);
+ if (err == noErr)
+ err = AEPutAttributePtr (&new->apple_event, KEY_EMACS_SUSPENSION_ID_ATTR,
+ typeUInt32, &suspension_id, sizeof (UInt32));
+ if (err == noErr)
+ {
+ OSErr err1;
+ SInt32 reply_requested;
+
+ err1 = AEGetAttributePtr (&new->apple_event, keyReplyRequestedAttr,
+ typeSInt32, NULL, &reply_requested,
+ sizeof (SInt32), NULL);
+ if (err1 != noErr)
{
- deferred_apple_events.size *= 2;
- deferred_apple_events.buf
- = xrealloc (deferred_apple_events.buf,
- sizeof (AppleEvent) * deferred_apple_events.size);
+ /* Emulate keyReplyRequestedAttr in older versions. */
+ reply_requested = reply->descriptorType != typeNull;
+ err = AEPutAttributePtr (&new->apple_event, keyReplyRequestedAttr,
+ typeSInt32, &reply_requested,
+ sizeof (SInt32));
}
}
-
if (err == noErr)
{
- int count = deferred_apple_events.count;
+ SInt32 timeout = 0;
+ struct suspended_ae_info **p;
+
+ new->suspension_id = suspension_id;
+ suspension_id++;
+ err = AEGetAttributePtr (apple_event, keyTimeoutAttr, typeSInt32,
+ NULL, &timeout, sizeof (SInt32), NULL);
+ new->expiration_tick = TickCount () + timeout;
+
+ for (p = &suspended_apple_events; *p; p = &(*p)->next)
+ if ((*p)->expiration_tick >= new->expiration_tick)
+ break;
+ new->next = *p;
+ *p = new;
- AEDuplicateDesc (apple_event, deferred_apple_events.buf + count);
- AEDuplicateDesc (reply, deferred_apple_events.buf + count + 1);
- deferred_apple_events.count += 2;
+ mac_store_apple_event (class, id, &new->apple_event);
+ }
+ else
+ {
+ AEDisposeDesc (&new->reply);
+ AEDisposeDesc (&new->apple_event);
+ xfree (new);
}
return err;
@@ -1047,17 +1123,11 @@ mac_handle_apple_event (apple_event, reply, refcon)
SInt32 refcon;
{
OSErr err;
+ UInt32 suspension_id;
AEEventClass event_class;
AEEventID event_id;
Lisp_Object class_key, id_key, binding;
- /* We can't handle an Apple event that requests a reply, but this
- seems to be too restrictive. */
-#if 0
- if (reply->descriptorType != typeNull)
- return errAEEventNotHandled;
-#endif
-
if (!mac_ready_for_apple_events)
{
err = defer_apple_events (apple_event, reply);
@@ -1066,6 +1136,13 @@ mac_handle_apple_event (apple_event, reply, refcon)
return noErr;
}
+ err = AEGetAttributePtr (apple_event, KEY_EMACS_SUSPENSION_ID_ATTR,
+ typeUInt32, NULL,
+ &suspension_id, sizeof (UInt32), NULL);
+ if (err == noErr)
+ /* Previously suspended event. Pass it to the next handler. */
+ return errAEEventNotHandled;
+
err = AEGetAttributePtr (apple_event, keyEventClassAttr, typeType, NULL,
&event_class, sizeof (AEEventClass), NULL);
if (err == noErr)
@@ -1079,11 +1156,49 @@ mac_handle_apple_event (apple_event, reply, refcon)
{
if (INTEGERP (binding))
return XINT (binding);
- mac_store_apple_event (class_key, id_key, apple_event);
- return noErr;
+ err = mac_handle_apple_event_1 (class_key, id_key,
+ apple_event, reply);
}
+ else
+ err = errAEEventNotHandled;
}
- return errAEEventNotHandled;
+ if (err == noErr)
+ return noErr;
+ else
+ return errAEEventNotHandled;
+}
+
+static int
+cleanup_suspended_apple_events (head, all_p)
+ struct suspended_ae_info **head;
+ int all_p;
+{
+ UInt32 current_tick = TickCount (), nresumed = 0;
+ struct suspended_ae_info *p, *next;
+
+ for (p = *head; p; p = next)
+ {
+ if (!all_p && p->expiration_tick > current_tick)
+ break;
+ AESetTheCurrentEvent (&p->apple_event);
+ AEResumeTheCurrentEvent (&p->apple_event, &p->reply,
+ (AEEventHandlerUPP) kAENoDispatch, 0);
+ AEDisposeDesc (&p->reply);
+ AEDisposeDesc (&p->apple_event);
+ nresumed++;
+ next = p->next;
+ xfree (p);
+ }
+ *head = p;
+
+ return nresumed;
+}
+
+static void
+cleanup_all_suspended_apple_events ()
+{
+ cleanup_suspended_apple_events (&deferred_apple_events, 1);
+ cleanup_suspended_apple_events (&suspended_apple_events, 1);
}
void
@@ -1109,34 +1224,190 @@ init_apple_event_handler ()
0L, false);
if (err != noErr)
abort ();
+
+ atexit (cleanup_all_suspended_apple_events);
+}
+
+static UInt32
+get_suspension_id (apple_event)
+ Lisp_Object apple_event;
+{
+ Lisp_Object tem;
+
+ CHECK_CONS (apple_event);
+ CHECK_STRING_CAR (apple_event);
+ if (SBYTES (XCAR (apple_event)) != 4
+ || strcmp (SDATA (XCAR (apple_event)), "aevt") != 0)
+ error ("Not an apple event");
+
+ tem = assq_no_quit (Qemacs_suspension_id, XCDR (apple_event));
+ if (NILP (tem))
+ error ("Suspension ID not available");
+
+ tem = XCDR (tem);
+ if (!(CONSP (tem)
+ && STRINGP (XCAR (tem)) && SBYTES (XCAR (tem)) == 4
+ && strcmp (SDATA (XCAR (tem)), "magn") == 0
+ && STRINGP (XCDR (tem)) && SBYTES (XCDR (tem)) == 4))
+ error ("Bad suspension ID format");
+
+ return *((UInt32 *) SDATA (XCDR (tem)));
}
+
DEFUN ("mac-process-deferred-apple-events", Fmac_process_deferred_apple_events, Smac_process_deferred_apple_events, 0, 0, 0,
doc: /* Process Apple events that are deferred at the startup time. */)
()
{
- Lisp_Object result = Qnil;
- long i;
-
if (mac_ready_for_apple_events)
return Qnil;
BLOCK_INPUT;
mac_ready_for_apple_events = 1;
- if (deferred_apple_events.buf)
+ if (deferred_apple_events)
{
- for (i = 0; i < deferred_apple_events.count; i += 2)
+ struct suspended_ae_info *prev, *tail, *next;
+
+ /* `nreverse' deferred_apple_events. */
+ prev = NULL;
+ for (tail = deferred_apple_events; tail; tail = next)
+ {
+ next = tail->next;
+ tail->next = prev;
+ prev = tail;
+ }
+
+ /* Now `prev' points to the first cell. */
+ for (tail = prev; tail; tail = next)
{
- AEResumeTheCurrentEvent (deferred_apple_events.buf + i,
- deferred_apple_events.buf + i + 1,
+ next = tail->next;
+ AEResumeTheCurrentEvent (&tail->apple_event, &tail->reply,
((AEEventHandlerUPP)
kAEUseStandardDispatch), 0);
- AEDisposeDesc (deferred_apple_events.buf + i);
- AEDisposeDesc (deferred_apple_events.buf + i + 1);
+ AEDisposeDesc (&tail->reply);
+ AEDisposeDesc (&tail->apple_event);
+ xfree (tail);
}
- xfree (deferred_apple_events.buf);
- bzero (&deferred_apple_events, sizeof (deferred_apple_events));
+ deferred_apple_events = NULL;
+ }
+ UNBLOCK_INPUT;
+
+ return Qt;
+}
+
+DEFUN ("mac-cleanup-expired-apple-events", Fmac_cleanup_expired_apple_events, Smac_cleanup_expired_apple_events, 0, 0, 0,
+ doc: /* Clean up expired Apple events.
+Return the number of expired events. */)
+ ()
+{
+ int nexpired;
+
+ BLOCK_INPUT;
+ nexpired = cleanup_suspended_apple_events (&suspended_apple_events, 0);
+ UNBLOCK_INPUT;
+
+ return make_number (nexpired);
+}
+
+DEFUN ("mac-ae-set-reply-parameter", Fmac_ae_set_reply_parameter, Smac_ae_set_reply_parameter, 3, 3, 0,
+ doc: /* Set parameter KEYWORD to DESCRIPTOR on reply of APPLE-EVENT.
+KEYWORD is a 4-byte string. DESCRIPTOR is a Lisp representation of an
+Apple event descriptor. It has the form of (TYPE . DATA), where TYPE
+is a 4-byte string. Valid format of DATA is as follows:
+
+ * If TYPE is "null", then DATA is nil.
+ * If TYPE is "list", then DATA is a list (DESCRIPTOR1 ... DESCRIPTORn).
+ * If TYPE is "reco", then DATA is a list ((KEYWORD1 . DESCRIPTOR1)
+ ... (KEYWORDn . DESCRIPTORn)).
+ * If TYPE is "aevt", then DATA is ignored and the descriptor is
+ treated as null.
+ * Otherwise, DATA is a string.
+
+If a (sub-)descriptor is in an invalid format, it is silently treated
+as null.
+
+Return t if the parameter is successfully set. Otherwise return nil. */)
+ (apple_event, keyword, descriptor)
+ Lisp_Object apple_event, keyword, descriptor;
+{
+ Lisp_Object result = Qnil;
+ UInt32 suspension_id;
+ struct suspended_ae_info *p;
+
+ suspension_id = get_suspension_id (apple_event);
+
+ CHECK_STRING (keyword);
+ if (SBYTES (keyword) != 4)
+ error ("Apple event keyword must be a 4-byte string: %s",
+ SDATA (keyword));
+
+ BLOCK_INPUT;
+ for (p = suspended_apple_events; p; p = p->next)
+ if (p->suspension_id == suspension_id)
+ break;
+ if (p && p->reply.descriptorType != typeNull)
+ {
+ OSErr err;
+
+ err = mac_ae_put_lisp (&p->reply,
+ EndianU32_BtoN (*((UInt32 *) SDATA (keyword))),
+ descriptor);
+ if (err == noErr)
+ result = Qt;
+ }
+ UNBLOCK_INPUT;
+
+ return result;
+}
+
+DEFUN ("mac-resume-apple-event", Fmac_resume_apple_event, Smac_resume_apple_event, 1, 2, 0,
+ doc: /* Resume handling of APPLE-EVENT.
+Every Apple event handled by the Lisp interpreter is suspended first.
+This function resumes such a suspended event either to complete Apple
+event handling to give a reply, or to redispatch it to other handlers.
+
+If optional ERROR-CODE is an integer, it specifies the error number
+that is set in the reply. If ERROR-CODE is t, the resumed event is
+handled with the standard dispatching mechanism, but it is not handled
+by Emacs again, thus it is redispatched to other handlers.
+
+Return t if APPLE-EVENT is successfully resumed. Otherwise return
+nil, which means the event is already resumed or expired. */)
+ (apple_event, error_code)
+ Lisp_Object apple_event, error_code;
+{
+ Lisp_Object result = Qnil;
+ UInt32 suspension_id;
+ struct suspended_ae_info **p, *ae;
+
+ suspension_id = get_suspension_id (apple_event);
+
+ BLOCK_INPUT;
+ for (p = &suspended_apple_events; *p; p = &(*p)->next)
+ if ((*p)->suspension_id == suspension_id)
+ break;
+ if (*p)
+ {
+ ae = *p;
+ *p = (*p)->next;
+ if (INTEGERP (error_code)
+ && ae->apple_event.descriptorType != typeNull)
+ {
+ SInt32 errn = XINT (error_code);
+
+ AEPutParamPtr (&ae->reply, keyErrorNumber, typeSInt32,
+ &errn, sizeof (SInt32));
+ }
+ AESetTheCurrentEvent (&ae->apple_event);
+ AEResumeTheCurrentEvent (&ae->apple_event, &ae->reply,
+ ((AEEventHandlerUPP)
+ (EQ (error_code, Qt) ?
+ kAEUseStandardDispatch : kAENoDispatch)),
+ 0);
+ AEDisposeDesc (&ae->reply);
+ AEDisposeDesc (&ae->apple_event);
+ xfree (ae);
result = Qt;
}
UNBLOCK_INPUT;
@@ -1145,6 +1416,9 @@ DEFUN ("mac-process-deferred-apple-events", Fmac_process_deferred_apple_events,
}
+/***********************************************************************
+ Drag and drop support
+***********************************************************************/
#if TARGET_API_MAC_CARBON
static Lisp_Object Vmac_dnd_known_types;
static pascal OSErr mac_do_track_drag P_ ((DragTrackingMessage, WindowRef,
@@ -1337,6 +1611,9 @@ remove_drag_handler (window)
}
+/***********************************************************************
+ Services menu support
+***********************************************************************/
#ifdef MAC_OSX
void
init_service_handler ()
@@ -1554,6 +1831,9 @@ syms_of_macselect ()
defsubr (&Sx_selection_owner_p);
defsubr (&Sx_selection_exists_p);
defsubr (&Smac_process_deferred_apple_events);
+ defsubr (&Smac_cleanup_expired_apple_events);
+ defsubr (&Smac_resume_apple_event);
+ defsubr (&Smac_ae_set_reply_parameter);
Vselection_alist = Qnil;
staticpro (&Vselection_alist);
@@ -1635,6 +1915,9 @@ The types are chosen in the order they appear in the list. */);
Qmac_apple_event_id = intern ("mac-apple-event-id");
staticpro (&Qmac_apple_event_id);
+
+ Qemacs_suspension_id = intern ("emacs-suspension-id");
+ staticpro (&Qemacs_suspension_id);
}
/* arch-tag: f3c91ad8-99e0-4bd6-9eef-251b2f848732
diff --git a/src/macterm.c b/src/macterm.c
index e3b8b3b5881..549e1e7977b 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -3531,19 +3531,28 @@ x_draw_stretch_glyph_string (s)
{
/* If `x-stretch-block-cursor' is nil, don't draw a block cursor
as wide as the stretch glyph. */
- int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
+ int width, background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
/* Draw cursor. */
- x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
+ x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
/* Clear rest using the GC of the original non-cursor face. */
- if (width < s->background_width)
+ if (width < background_width)
{
- int x = s->x + width, y = s->y;
- int w = s->background_width - width, h = s->height;
+ int y = s->y;
+ int w = background_width - width, h = s->height;
Rect r;
GC gc;
+ x += width;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
@@ -3570,8 +3579,18 @@ x_draw_stretch_glyph_string (s)
}
}
else if (!s->background_filled_p)
- x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
- s->height);
+ {
+ int background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (background_width > 0)
+ x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+ }
s->background_filled_p = 1;
}
@@ -5398,8 +5417,7 @@ x_draw_hollow_cursor (w, row)
return;
/* Compute frame-relative coordinates for phys cursor. */
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
wd = w->phys_cursor_width;
/* The foreground of cursor_gc is typically the same as the normal
@@ -6135,6 +6153,7 @@ mac_handle_visibility_change (f)
EVENT_INIT (buf);
buf.kind = DEICONIFY_EVENT;
XSETFRAME (buf.frame_or_window, f);
+ buf.arg = Qnil;
kbd_buffer_store_event (&buf);
}
else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list)))
@@ -6148,6 +6167,7 @@ mac_handle_visibility_change (f)
EVENT_INIT (buf);
buf.kind = ICONIFY_EVENT;
XSETFRAME (buf.frame_or_window, f);
+ buf.arg = Qnil;
kbd_buffer_store_event (&buf);
}
@@ -8341,6 +8361,26 @@ x_find_ccl_program (fontp)
}
#if USE_MAC_FONT_PANEL
+/* Whether Font Panel has been shown before. The first call to font
+ panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
+ slow. This variable is used for deferring such a call as much as
+ possible. */
+static int font_panel_shown_p = 0;
+
+int
+mac_font_panel_visible_p ()
+{
+ return font_panel_shown_p && FPIsFontPanelVisible ();
+}
+
+OSStatus
+mac_show_hide_font_panel ()
+{
+ font_panel_shown_p = 1;
+
+ return FPShowHideFontPanel ();
+}
+
OSStatus
mac_set_font_info_for_selection (f, face_id, c)
struct frame *f;
@@ -8350,6 +8390,9 @@ mac_set_font_info_for_selection (f, face_id, c)
EventTargetRef target = NULL;
XFontStruct *font = NULL;
+ if (!mac_font_panel_visible_p ())
+ return noErr;
+
if (f)
{
target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
@@ -8484,6 +8527,13 @@ static Lisp_Object Qtoolbar_switch_mode;
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;
+static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
+static Lisp_Object Vmac_ts_active_input_overlay;
+extern Lisp_Object Qbefore_string;
+#endif
#endif
extern int mac_ready_for_apple_events;
extern Lisp_Object Qundefined;
@@ -8835,13 +8885,17 @@ is_emacs_window (WindowPtr win)
static void
do_app_resume ()
{
- /* Window-activate events will do the job. */
+#if USE_MAC_TSM
+ ActivateTSMDocument (tsm_document_id);
+#endif
}
static void
do_app_suspend ()
{
- /* Window-deactivate events will do the job. */
+#if USE_MAC_TSM
+ DeactivateTSMDocument (tsm_document_id);
+#endif
}
@@ -9101,6 +9155,9 @@ mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
{
mac_store_apple_event (class_key, id_key, &apple_event);
AEDisposeDesc (&apple_event);
+ /* Post a harmless event so as to wake up from
+ ReceiveNextEvent. */
+ mac_post_mouse_moved_event ();
}
}
}
@@ -9290,6 +9347,18 @@ mac_handle_window_event (next_handler, event, data)
}
return err == noErr ? noErr : result;
#endif
+
+#if USE_MAC_TSM
+ case kEventWindowFocusAcquired:
+ result = CallNextEventHandler (next_handler, event);
+ err = ActivateTSMDocument (tsm_document_id);
+ return err == noErr ? noErr : result;
+
+ case kEventWindowFocusRelinquish:
+ result = CallNextEventHandler (next_handler, event);
+ err = DeactivateTSMDocument (tsm_document_id);
+ return err == noErr ? noErr : result;
+#endif
}
return eventNotHandledErr;
@@ -9416,6 +9485,183 @@ mac_handle_font_event (next_handler, event, data)
}
#endif
+#if USE_MAC_TSM
+static pascal OSStatus
+mac_handle_text_input_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus result, err = noErr;
+ Lisp_Object id_key = Qnil;
+ int num_params;
+ EventParamName *names;
+ EventParamType *types;
+ static UInt32 seqno_uaia = 0;
+ static EventParamName names_uaia[] =
+ {kEventParamTextInputSendComponentInstance,
+ kEventParamTextInputSendRefCon,
+ kEventParamTextInputSendSLRec,
+ kEventParamTextInputSendFixLen,
+ kEventParamTextInputSendText,
+ kEventParamTextInputSendUpdateRng,
+ kEventParamTextInputSendHiliteRng,
+ kEventParamTextInputSendClauseRng,
+ kEventParamTextInputSendPinRng,
+ kEventParamTextInputSendTextServiceEncoding,
+ kEventParamTextInputSendTextServiceMacEncoding,
+ EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
+ static EventParamType types_uaia[] =
+ {typeComponentInstance,
+ typeLongInteger,
+ typeIntlWritingCode,
+ typeLongInteger,
+ typeUnicodeText,
+ typeTextRangeArray,
+ typeTextRangeArray,
+ typeOffsetArray,
+ typeTextRange,
+ typeUInt32,
+ typeUInt32,
+ typeUInt32};
+ static EventParamName names_ufke[] =
+ {kEventParamTextInputSendComponentInstance,
+ kEventParamTextInputSendRefCon,
+ kEventParamTextInputSendSLRec,
+ kEventParamTextInputSendText};
+ static EventParamType types_ufke[] =
+ {typeComponentInstance,
+ typeLongInteger,
+ typeIntlWritingCode,
+ typeUnicodeText};
+
+ result = CallNextEventHandler (next_handler, event);
+
+ switch (GetEventKind (event))
+ {
+ case kEventTextInputUpdateActiveInputArea:
+ id_key = Qupdate_active_input_area;
+ num_params = sizeof (names_uaia) / sizeof (names_uaia[0]);
+ names = names_uaia;
+ types = types_uaia;
+ SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
+ typeUInt32, sizeof (UInt32), &seqno_uaia);
+ seqno_uaia++;
+ break;
+
+ case kEventTextInputUnicodeForKeyEvent:
+ {
+ EventRef kbd_event;
+ UInt32 actual_size, modifiers, mapped_modifiers;
+ UniChar code;
+
+ err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
+ typeEventRef, NULL, sizeof (EventRef), NULL,
+ &kbd_event);
+ if (err == noErr)
+ err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &modifiers);
+ if (err == noErr)
+ {
+ mapped_modifiers =
+ (NILP (Vmac_control_modifier) ? 0 : controlKey)
+ | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+ | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+#ifdef MAC_OSX
+ mapped_modifiers |=
+ (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+#endif
+ if (modifiers & mapped_modifiers)
+ /* There're mapped modifier keys. Process it in
+ XTread_socket. */
+ return eventNotHandledErr;
+ }
+ if (err == noErr)
+ err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+ typeUnicodeText, NULL, 0, &actual_size,
+ NULL);
+ if (err == noErr)
+ {
+ if (actual_size == sizeof (UniChar))
+ err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+ typeUnicodeText, NULL,
+ sizeof (UniChar), NULL, &code);
+ if (err == noErr && code < 0x80)
+ {
+ /* ASCII character. Process it in XTread_socket. */
+ if (read_socket_inev && code >= 0x20 && code <= 0x7e)
+ {
+ struct frame *f = mac_focus_frame (&one_mac_display_info);
+
+ read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
+ read_socket_inev->code = code;
+ read_socket_inev->modifiers =
+ (extra_keyboard_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
+ XSETFRAME (read_socket_inev->frame_or_window, f);
+ }
+ return eventNotHandledErr;
+ }
+ }
+ }
+ /* 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:
+ {
+ struct frame *f;
+ struct window *w;
+ Point p;
+
+ if (!OVERLAYP (Vmac_ts_active_input_overlay))
+ return eventNotHandledErr;
+
+ /* 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)))
+ {
+ /* 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);
+ }
+
+ p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
+ + WINDOW_LEFT_FRINGE_WIDTH (w));
+ p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
+ + FONT_BASE (FRAME_FONT (f)));
+ SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ LocalToGlobal (&p);
+ err = SetEventParameter (event, kEventParamTextInputReplyPoint,
+ typeQDPoint, sizeof (typeQDPoint), &p);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (!NILP (id_key))
+ err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
+ event, num_params,
+ names, types);
+
+ return err == noErr ? noErr : result;
+}
+#endif
+
#ifdef MAC_OSX
OSStatus
mac_store_service_event (event)
@@ -9477,6 +9723,10 @@ install_window_handler (window)
#ifdef MAC_OSX
{kEventClassWindow, kEventWindowToolbarSwitchMode},
#endif
+#if USE_MAC_TSM
+ {kEventClassWindow, kEventWindowFocusAcquired},
+ {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
};
EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}};
static EventHandlerUPP handle_window_eventUPP = NULL;
@@ -9486,6 +9736,13 @@ install_window_handler (window)
{kEventClassFont, kEventFontSelection}};
static EventHandlerUPP handle_font_eventUPP = NULL;
#endif
+#if USE_MAC_TSM
+ 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);
@@ -9495,6 +9752,11 @@ install_window_handler (window)
if (handle_font_eventUPP == NULL)
handle_font_eventUPP = NewEventHandlerUPP (mac_handle_font_event);
#endif
+#if USE_MAC_TSM
+ if (handle_text_input_eventUPP == NULL)
+ handle_text_input_eventUPP =
+ NewEventHandlerUPP (mac_handle_text_input_event);
+#endif
err = InstallWindowEventHandler (window, handle_window_eventUPP,
GetEventTypeCount (specs_window),
specs_window, NULL, NULL);
@@ -9508,6 +9770,12 @@ install_window_handler (window)
GetEventTypeCount (specs_font),
specs_font, NULL, NULL);
#endif
+#if USE_MAC_TSM
+ if (err == noErr)
+ err = InstallWindowEventHandler (window, handle_text_input_eventUPP,
+ GetEventTypeCount (specs_text_input),
+ specs_text_input, window, NULL);
+#endif
#endif
if (err == noErr)
err = install_drag_handler (window);
@@ -9633,7 +9901,7 @@ static unsigned char keycode_to_xkeysym_table[] = {
/*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
/*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
- /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
+ /*0x68*/ 0, 0xca /*f13*/, 0xcd /*f16*/, 0xcb /*f14*/,
/*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
/*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
@@ -9650,7 +9918,13 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
return *xKeySym != 0;
}
-static unsigned char fn_keycode_to_xkeysym_table[] = {
+#ifdef MAC_OSX
+/* Table for translating Mac keycode with the laptop `fn' key to that
+ without it. Destination symbols in comments are keys on US
+ keyboard, and they may not be the same on other types of keyboards.
+ If the destination is identical to the source (f1 ... f12), it
+ doesn't map `fn' key to a modifier. */
+static unsigned char fn_keycode_to_keycode_table[] = {
/*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -9660,113 +9934,27 @@ static unsigned char fn_keycode_to_xkeysym_table[] = {
/*0x38*/ 0, 0, 0, 0,
/*0x3C*/ 0, 0, 0, 0,
- /*0x40*/ 0, 0x2e /*kp-. = .*/, 0, 0x50 /*kp-* = 'p'*/,
- /*0x44*/ 0, '/' /*kp-+*/, 0, 0,
- /*0x48*/ 0, 0, 0, 0x30 /*kp-/ = '0'*/,
- /*0x4C*/ 0, 0, 0x3b /*kp-- = ';'*/, 0,
+ /*0x40*/ 0, 0x2f /*kp-. -> '.'*/, 0, 0x23 /*kp-* -> 'p'*/,
+ /*0x44*/ 0, 0x2c /*kp-+ -> '/'*/, 0, 0x16 /*clear -> '6'*/,
+ /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
+ /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-- -> ';'*/, 0,
- /*0x50*/ 0, 0x2d /*kp-= = '-'*/, 0x6d /*kp-0 = 'm'*/, 0x6a /*kp-1 = 'j'*/,
- /*0x54*/ 0x6b /*kp-2 = 'k'*/, 0x6c /*kp-3 = 'l'*/, 'u' /*kp-4*/, 'i' /*kp-5*/,
- /*0x58*/ 'o' /*kp-6*/, '7' /*kp-7*/, 0, '8' /*kp-8*/,
- /*0x5C*/ '9' /*kp-9*/, 0, 0, 0,
+ /*0x50*/ 0, 0x1b /*kp-= -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
+ /*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
+ /*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
+ /*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
- /*0x60*/ 0, 0, 0, 0,
- /*0x64*/ 0, 0, 0, 0,
+ /*0x60*/ 0x60 /*f5 = f5*/, 0x61 /*f6 = f6*/, 0x62 /*f7 = f7*/, 0x63 /*f3 = f3*/,
+ /*0x64*/ 0x64 /*f8 = f8*/, 0x65 /*f9 = f9*/, 0, 0x67 /*f11 = f11*/,
/*0x68*/ 0, 0, 0, 0,
- /*0x6C*/ 0, 0, 0, 0,
+ /*0x6C*/ 0, 0x6d /*f10 = f10*/, 0, 0x6f /*f12 = f12*/,
- /*0x70*/ 0, 0, 0, 0,
- /*0x74*/ 0, 0, 0, 0,
- /*0x78*/ 0, 0, 0, 0,
+ /*0x70*/ 0, 0, 0, 0x7b /*home -> left*/,
+ /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0x76 /*f4 = f4*/, 0x7c /*end -> right*/,
+ /*0x78*/ 0x78 /*f2 = f2*/, 0x7d /*pgdown -> down*/, 0x7a /*f1 = f1*/, 0,
/*0x7C*/ 0, 0, 0, 0
};
-static int
-convert_fn_keycode (EventRef eventRef, int keyCode, int *newCode)
-{
-#ifdef MAC_OSX
- /* Use the special map to translate keys when function modifier is
- to be caught. KeyTranslate can't be used in that case.
- We can't detect the function key using the input_event.modifiers,
- because this uses the high word of an UInt32. Therefore,
- we'll just read it out of the original eventRef.
- */
-
-
- /* TODO / known issues
-
- - Fn-Shift-j is regonized as Fn-j and not Fn-J.
- The above table always translates to lower characters. We need to use
- the KCHR keyboard resource (KeyTranslate() ) to map k->K and 8->*.
-
- - The table is meant for English language keyboards, and it will work
- for many others with the exception of key combinations like Fn-ö on
- a German keyboard, which is currently mapped to Fn-;.
- How to solve this without keeping separate tables for all keyboards
- around? KeyTranslate isn't of much help here, as it only takes a 16-bit
- value for keycode with the modifiers in he high byte, i.e. no room for the
- Fn modifier. That's why we need the table.
-
- */
- OSStatus err;
- UInt32 mods = 0;
- if (!NILP(Vmac_function_modifier))
- {
- err = GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
- NULL, sizeof (UInt32), NULL, &mods);
- if (err != noErr && mods & kEventKeyModifierFnMask)
- { *newCode = fn_keycode_to_xkeysym_table [keyCode & 0x7f];
-
- return (*newCode != 0);
- }
- }
-#endif
- return false;
-}
-
-static int
-backtranslate_modified_keycode(int mods, int keycode, int def)
-{
- EventModifiers mapped_modifiers =
- (NILP (Vmac_control_modifier) ? 0 : controlKey)
- | (NILP (Vmac_option_modifier) ? 0 : optionKey)
- | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
-
- if (mods & mapped_modifiers)
- {
- /* 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.
-
- Not done for combinations with the option key (alt)
- unless it is to be caught by Emacs: this is
- to preserve key combinations translated by the OS
- such as Alt-3.
- */
- /* Mask off modifier keys that are mapped to some Emacs
- modifiers. */
- int new_modifiers = mods & ~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;
- return (int) KeyTranslate (kchr_ptr, new_keycode,
- &some_state) & 0xff;
- /* TO DO: Recognize two separate resulting characters, "for
- example, when the user presses Option-E followed by N, you
- can map this through the KeyTranslate function using the
- U.S. 'KCHR' resource to produce ´n, which KeyTranslate
- returns as two characters in the bytes labeled Character code
- 1 and Character code 2." (from Carbon API doc) */
-
- }
- else
- return def;
-}
-
+#endif /* MAC_OSX */
#if !USE_CARBON_EVENTS
static RgnHandle mouse_region = NULL;
@@ -9840,6 +10028,44 @@ 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
@@ -9889,10 +10115,6 @@ XTread_socket (sd, expected, hold_quit)
struct frame *f;
unsigned long timestamp;
- /* It is necessary to set this (additional) argument slot of an
- event to nil because keyboard.c protects incompletely
- processed event from being garbage collected by placing them
- in the kbd_buffer_gcpro vector. */
EVENT_INIT (inev);
inev.kind = NO_EVENT;
inev.arg = Qnil;
@@ -10354,10 +10576,29 @@ XTread_socket (sd, expected, hold_quit)
break;
case keyDown:
+ case keyUp:
case autoKey:
{
int keycode = (er.message & keyCodeMask) >> 8;
int xkeysym;
+ static SInt16 last_key_script = -1;
+ SInt16 current_key_script;
+ UInt32 modifiers = er.modifiers, mapped_modifiers;
+
+ mapped_modifiers =
+ (NILP (Vmac_control_modifier) ? 0 : controlKey)
+ | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+ | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+
+#if USE_CARBON_EVENTS && defined (MAC_OSX)
+ mapped_modifiers |=
+ (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+
+ GetEventParameter (eventRef, kEventParamKeyModifiers,
+ typeUInt32, NULL,
+ sizeof (UInt32), NULL, &modifiers);
+#endif
+ mapped_modifiers &= modifiers;
#if USE_CARBON_EVENTS && defined (MAC_OSX)
/* When using Carbon Events, we need to pass raw keyboard
@@ -10365,45 +10606,21 @@ XTread_socket (sd, expected, hold_quit)
will pass back noErr, otherwise it will pass back
"eventNotHandledErr" and we can process it
normally. */
- if ((mac_pass_command_to_system
- || !(er.modifiers & cmdKey))
- && (mac_pass_control_to_system
- || !(er.modifiers & controlKey))
- && (NILP (Vmac_option_modifier)
- || !(er.modifiers & optionKey)))
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
-
-#if 0
- if (dpyinfo->x_focus_frame == NULL)
+ if (!(mapped_modifiers
+ & ~(mac_pass_command_to_system ? cmdKey : 0)
+ & ~(mac_pass_control_to_system ? controlKey : 0)))
{
- /* Beep if keyboard input occurs when all the frames
- are invisible. */
- SysBeep (1);
- break;
+ OSStatus err;
+
+ read_socket_inev = &inev;
+ err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+ read_socket_inev = NULL;
+ if (err != eventNotHandledErr)
+ break;
}
#endif
-
- {
- static SInt16 last_key_script = -1;
- SInt16 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 (er.what == keyUp)
+ break;
ObscureCursor ();
@@ -10416,51 +10633,163 @@ XTread_socket (sd, expected, hold_quit)
dpyinfo->mouse_face_hidden = 1;
}
- /* translate the keycode back to determine the original key */
- /* Convert key code if function key is pressed.
- Otherwise, if non-ASCII-event, take care of that
- without re-translating the key code. */
-#if USE_CARBON_EVENTS
- if (convert_fn_keycode (eventRef, keycode, &xkeysym))
+ current_key_script = GetScriptManagerVariable (smKeyScript);
+ if (last_key_script != current_key_script)
{
- inev.code = xkeysym;
- /* this doesn't work - tried to add shift modifiers */
- inev.code =
- backtranslate_modified_keycode(er.modifiers & (~0x2200),
- xkeysym | 0x80, xkeysym);
- inev.kind = ASCII_KEYSTROKE_EVENT;
+ 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;
}
- else
+
+#if USE_MAC_TSM
+ if (inev.kind != NO_EVENT)
+ break;
#endif
- if (keycode_to_xkeysym (keycode, &xkeysym))
- {
- inev.code = 0xff00 | xkeysym;
- inev.kind = NON_ASCII_KEYSTROKE_EVENT;
- }
- else
- {
- inev.code =
- backtranslate_modified_keycode(er.modifiers, keycode,
- er.message & charCodeMask);
- inev.kind = ASCII_KEYSTROKE_EVENT;
- }
- }
-#if USE_CARBON_EVENTS
- inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
- inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
+#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_to_xkeysym (keycode, &xkeysym))
+ {
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.code = 0xff00 | xkeysym;
+#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
+ 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)
+ {
+ 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 ((UCKeyboardLayout *)*uchr_handle,
+ 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;
+ }
+
+ 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);
+
+#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);
+ }
+ }
#endif
- inev.modifiers |= (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- XSETFRAME (inev.frame_or_window, f);
+ }
break;
case kHighLevelEvent:
- read_socket_inev = &inev;
AEProcessAppleEvent (&er);
- read_socket_inev = NULL;
break;
default:
@@ -10932,6 +11261,16 @@ init_menu_bar ()
#endif
}
+#if USE_MAC_TSM
+static void
+init_tsm ()
+{
+ static InterfaceTypeList types = {kUnicodeDocument};
+
+ NewTSMDocument (sizeof (types) / sizeof (types[0]), types,
+ &tsm_document_id, 0);
+}
+#endif
/* Set up use of X before we make the first connection. */
@@ -11026,6 +11365,10 @@ mac_initialize ()
init_command_handler ();
init_menu_bar ();
+
+#if USE_MAC_TSM
+ init_tsm ();
+#endif
#endif /* USE_CARBON_EVENTS */
#ifdef MAC_OSX
@@ -11082,6 +11425,13 @@ syms_of_macterm ()
Qpaste = intern ("paste"); staticpro (&Qpaste);
Qperform = intern ("perform"); staticpro (&Qperform);
#endif
+#if USE_MAC_TSM
+ Qtext_input = intern ("text-input"); staticpro (&Qtext_input);
+ Qupdate_active_input_area = intern ("update-active-input-area");
+ staticpro (&Qupdate_active_input_area);
+ Qunicode_for_key_event = intern ("unicode-for-key-event");
+ staticpro (&Qunicode_for_key_event);
+#endif
#endif
#ifdef MAC_OSX
@@ -11224,6 +11574,11 @@ order. */);
make_float (DEFAULT_REHASH_THRESHOLD),
Qnil, Qnil, Qnil);
#endif
+#if USE_MAC_TSM
+ DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
+ doc: /* Overlay used to display Mac TSM active input area. */);
+ Vmac_ts_active_input_overlay = Qnil;
+#endif
}
/* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
diff --git a/src/macterm.h b/src/macterm.h
index 8b45777e546..55bf583c214 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -539,6 +539,53 @@ struct scroll_bar {
#define HOURGLASS_WIDTH 16
#define HOURGLASS_HEIGHT 16
+/* Some constants that are used locally. */
+/* Apple event descriptor types */
+enum {
+ TYPE_FILE_NAME = 'fNam'
+};
+
+/* Keywords for Apple event attributes */
+enum {
+ KEY_EMACS_SUSPENSION_ID_ATTR = 'esId' /* typeUInt32 */
+};
+
+/* Carbon event parameter names. */
+enum {
+ EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER = 'tsSn' /* typeUInt32 */
+};
+
+/* Some constants that are not defined in older versions. */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
+/* Keywords for Apple event attributes */
+enum {
+ keyReplyRequestedAttr = 'repq'
+};
+#endif
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1040
+/* Gestalt selectors */
+enum {
+ gestaltSystemVersionMajor = 'sys1',
+ gestaltSystemVersionMinor = 'sys2',
+ gestaltSystemVersionBugFix = 'sys3'
+};
+#endif
+
+#ifdef MAC_OSX
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1020
+/* Apple event descriptor types */
+enum {
+ typeUTF8Text = 'utf8'
+};
+
+/* Carbon event parameter names */
+enum {
+ kEventParamWindowMouseLocation = 'wmou'
+};
+#endif
+#endif
+
struct frame;
struct face;
struct image;
@@ -584,6 +631,8 @@ extern void mac_draw_line_to_pixmap P_ ((Display *, Pixmap, GC, int, int,
extern void mac_clear_area P_ ((struct frame *, int, int,
unsigned int, unsigned int));
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 OSErr install_window_handler P_ ((WindowPtr));
extern void remove_window_handler P_ ((WindowPtr));
@@ -596,8 +645,6 @@ extern void mac_prepare_for_quickdraw P_ ((struct frame *));
#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
-#define TYPE_FILE_NAME 'fNam'
-
/* Defined in macselect.c */
extern void x_clear_frame_selections P_ ((struct frame *));
@@ -615,6 +662,7 @@ extern int x_char_height P_ ((struct frame *));
extern void x_sync P_ ((struct frame *));
extern void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
extern void mac_update_title_bar P_ ((struct frame *, int));
+extern Lisp_Object x_get_focus_frame P_ ((struct frame *));
/* Defined in macmenu.c */
@@ -625,6 +673,7 @@ extern void free_frame_menubar P_ ((struct frame *));
extern void mac_clear_font_name_table P_ ((void));
extern Lisp_Object mac_aedesc_to_lisp P_ ((const AEDesc *));
+extern OSErr mac_ae_put_lisp P_ ((AEDescList *, UInt32, Lisp_Object));
#if TARGET_API_MAC_CARBON
extern OSErr create_apple_event_from_event_ref P_ ((EventRef, UInt32,
EventParamName *,
diff --git a/src/minibuf.c b/src/minibuf.c
index d37f82c9dcd..c5910b1771f 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -66,6 +66,10 @@ Lisp_Object Qhistory_length, Vhistory_length;
int history_delete_duplicates;
+/* Non-nil means add new input to history. */
+
+Lisp_Object Vhistory_add_new_input;
+
/* Fread_minibuffer leaves the input here as a string. */
Lisp_Object last_minibuf_string;
@@ -219,7 +223,7 @@ static Lisp_Object read_minibuf P_ ((Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object,
int, Lisp_Object,
Lisp_Object, Lisp_Object,
- int, int, int));
+ int, int));
static Lisp_Object read_minibuf_noninteractive P_ ((Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object,
int, Lisp_Object,
@@ -440,8 +444,7 @@ The current buffer must be a minibuffer. */)
static Lisp_Object
read_minibuf (map, initial, prompt, backup_n, expflag,
- histvar, histpos, defalt, allow_props, inherit_input_method,
- keep_all)
+ histvar, histpos, defalt, allow_props, inherit_input_method)
Lisp_Object map;
Lisp_Object initial;
Lisp_Object prompt;
@@ -452,7 +455,6 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
Lisp_Object defalt;
int allow_props;
int inherit_input_method;
- int keep_all;
{
Lisp_Object val;
int count = SPECPDL_INDEX ();
@@ -747,7 +749,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
last_minibuf_string = val;
/* Choose the string to add to the history. */
- if (SCHARS (val) != 0 || keep_all)
+ if (SCHARS (val) != 0)
histstring = val;
else if (STRINGP (defalt))
histstring = defalt;
@@ -755,7 +757,8 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
histstring = Qnil;
/* Add the value to the appropriate history list, if any. */
- if (SYMBOLP (Vminibuffer_history_variable)
+ if (!NILP (Vhistory_add_new_input)
+ && SYMBOLP (Vminibuffer_history_variable)
&& !NILP (histstring))
{
/* If the caller wanted to save the value read on a history list,
@@ -774,8 +777,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag,
if (NILP (histval)
|| (CONSP (histval)
/* Don't duplicate the most recent entry in the history. */
- && (keep_all
- || NILP (Fequal (histstring, Fcar (histval))))))
+ && (NILP (Fequal (histstring, Fcar (histval))))))
{
Lisp_Object length;
@@ -937,7 +939,7 @@ read_minibuf_unwind (data)
}
-DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 8, 0,
+DEFUN ("read-from-minibuffer", Fread_from_minibuffer, Sread_from_minibuffer, 1, 7, 0,
doc: /* Read a string from the minibuffer, prompting with string PROMPT.
The optional second arg INITIAL-CONTENTS is an obsolete alternative to
DEFAULT-VALUE. It normally should be nil in new code, except when
@@ -961,8 +963,6 @@ Sixth arg DEFAULT-VALUE is the default value. If non-nil, it is available
the empty string.
Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
the current input method and the setting of `enable-multibyte-characters'.
-Eight arg KEEP-ALL, if non-nil, says to put all inputs in the history list,
- even empty or duplicate inputs.
If the variable `minibuffer-allow-text-properties' is non-nil,
then the string which is returned includes whatever text properties
were present in the minibuffer. Otherwise the value has no text properties.
@@ -978,9 +978,9 @@ POSITION in the minibuffer. Any integer value less than or equal to
one puts point at the beginning of the string. *Note* that this
behavior differs from the way such arguments are used in `completing-read'
and some related functions, which use zero-indexing for POSITION. */)
- (prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method, keep_all)
+(prompt, initial_contents, keymap, read, hist, default_value, inherit_input_method)
Lisp_Object prompt, initial_contents, keymap, read, hist, default_value;
- Lisp_Object inherit_input_method, keep_all;
+ Lisp_Object inherit_input_method;
{
Lisp_Object histvar, histpos, val;
struct gcpro gcpro1;
@@ -1011,8 +1011,7 @@ and some related functions, which use zero-indexing for POSITION. */)
Qnil, !NILP (read),
histvar, histpos, default_value,
minibuffer_allow_text_properties,
- !NILP (inherit_input_method),
- !NILP (keep_all));
+ !NILP (inherit_input_method));
UNGCPRO;
return val;
}
@@ -1029,7 +1028,7 @@ arguments are used as in `read-from-minibuffer') */)
CHECK_STRING (prompt);
return read_minibuf (Vminibuffer_local_map, initial_contents,
prompt, Qnil, 1, Qminibuffer_history,
- make_number (0), Qnil, 0, 0, 0);
+ make_number (0), Qnil, 0, 0);
}
DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
@@ -1067,7 +1066,7 @@ Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
Lisp_Object val;
val = Fread_from_minibuffer (prompt, initial_input, Qnil,
Qnil, history, default_value,
- inherit_input_method, Qnil);
+ inherit_input_method);
if (STRINGP (val) && SCHARS (val) == 0 && ! NILP (default_value))
val = default_value;
return val;
@@ -1089,7 +1088,7 @@ the current input method and the setting of`enable-multibyte-characters'. */)
CHECK_STRING (prompt);
return read_minibuf (Vminibuffer_local_ns_map, initial, prompt, Qnil,
0, Qminibuffer_history, make_number (0), Qnil, 0,
- !NILP (inherit_input_method), 0);
+ !NILP (inherit_input_method));
}
DEFUN ("read-command", Fread_command, Sread_command, 1, 2, 0,
@@ -1778,7 +1777,7 @@ Completion ignores case if the ambient value of
: Vminibuffer_local_must_match_filename_map),
init, prompt, make_number (pos), 0,
histvar, histpos, def, 0,
- !NILP (inherit_input_method), 0);
+ !NILP (inherit_input_method));
if (STRINGP (val) && SCHARS (val) == 0 && ! NILP (def))
val = def;
@@ -2797,9 +2796,16 @@ property of a history variable overrides this default. */);
DEFVAR_BOOL ("history-delete-duplicates", &history_delete_duplicates,
doc: /* *Non-nil means to delete duplicates in history.
If set to t when adding a new history element, all previous identical
-elements are deleted. */);
+elements are deleted from the history list. */);
history_delete_duplicates = 0;
+ DEFVAR_LISP ("history-add-new-input", &Vhistory_add_new_input,
+ doc: /* *Non-nil means to add new elements in history.
+If set to nil, minibuffer reading functions don't add new elements to the
+history list, so it is possible to do this afterwards by calling
+`add-to-history' explicitly. */);
+ Vhistory_add_new_input = Qt;
+
DEFVAR_LISP ("completion-auto-help", &Vcompletion_auto_help,
doc: /* *Non-nil means automatically provide help for invalid completion input.
Under Partial Completion mode, a non-nil, non-t value has a special meaning;
diff --git a/src/process.c b/src/process.c
index 1960e6a914c..2281f1ce3f6 100644
--- a/src/process.c
+++ b/src/process.c
@@ -777,6 +777,16 @@ get_process (name)
return proc;
}
+
+#ifdef SIGCHLD
+/* Fdelete_process promises to immediately forget about the process, but in
+ reality, Emacs needs to remember those processes until they have been
+ treated by sigchld_handler; otherwise this handler would consider the
+ process as being synchronous and say that the synchronous process is
+ dead. */
+static Lisp_Object deleted_pid_list;
+#endif
+
DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
doc: /* Delete PROCESS: kill it and forget about it immediately.
PROCESS may be a process, a buffer, the name of a process or buffer, or
@@ -798,12 +808,31 @@ nil, indicating the current buffer's process. */)
}
else if (XINT (p->infd) >= 0)
{
- Fkill_process (process, Qnil);
- /* 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);
- status_notify (p);
+#ifdef SIGCHLD
+ Lisp_Object symbol;
+
+ /* No problem storing the pid here, as it is still in Vprocess_alist. */
+ deleted_pid_list = Fcons (make_fixnum_or_float (p->pid),
+ /* GC treated elements set to nil. */
+ Fdelq (Qnil, deleted_pid_list));
+ /* If the process has already signaled, remove it from the list. */
+ if (p->raw_status_new)
+ update_status (p);
+ symbol = p->status;
+ if (CONSP (p->status))
+ symbol = XCAR (p->status);
+ if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
+ Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list);
+ else
+#endif
+ {
+ Fkill_process (process, Qnil);
+ /* 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);
+ status_notify (p);
+ }
}
remove_process (process);
return Qnil;
@@ -4134,6 +4163,25 @@ wait_reading_process_output_1 ()
{
}
+/* Use a wrapper around select to work around a bug in gdb 5.3.
+ Normally, the wrapper is optimzed away by inlining.
+
+ If emacs is stopped inside select, the gdb backtrace doesn't
+ show the function which called select, so it is practically
+ impossible to step through wait_reading_process_output. */
+
+#ifndef select
+static INLINE int
+select_wrapper (n, rfd, wfd, xfd, tmo)
+ int n;
+ SELECT_TYPE *rfd, *wfd, *xfd;
+ EMACS_TIME *tmo;
+{
+ return select (n, rfd, wfd, xfd, tmo);
+}
+#define select select_wrapper
+#endif
+
/* Read and dispose of subprocess output while waiting for timeout to
elapse and/or keyboard input to be available.
@@ -6304,6 +6352,7 @@ kill_buffer_processes (buffer)
** Malloc WARNING: This should never call malloc either directly or
indirectly; if it does, that is a bug */
+#ifdef SIGCHLD
SIGTYPE
sigchld_handler (signo)
int signo;
@@ -6361,6 +6410,15 @@ sigchld_handler (signo)
/* Find the process that signaled us, and record its status. */
+ /* The process can have been deleted by Fdelete_process. */
+ tail = Fmember (make_fixnum_or_float (pid), deleted_pid_list);
+ if (!NILP (tail))
+ {
+ Fsetcar (tail, Qnil);
+ goto sigchld_end_of_loop;
+ }
+
+ /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
p = 0;
for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
{
@@ -6412,8 +6470,8 @@ sigchld_handler (signo)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
}
- /* There was no asynchronous process found for that id. Check
- if we have a synchronous process. */
+ /* There was no asynchronous process found for that pid: we have
+ a synchronous process. */
else
{
synch_process_alive = 0;
@@ -6430,6 +6488,9 @@ sigchld_handler (signo)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
}
+ sigchld_end_of_loop:
+ ;
+
/* On some systems, we must return right away.
If any more processes want to signal us, we will
get another signal.
@@ -6446,6 +6507,7 @@ sigchld_handler (signo)
#endif /* USG, but not HPUX with WNOHANG */
}
}
+#endif /* SIGCHLD */
static Lisp_Object
@@ -6831,6 +6893,9 @@ init_process ()
FD_SET (0, &input_wait_mask);
Vprocess_alist = Qnil;
+#ifdef SIGCHLD
+ deleted_pid_list = Qnil;
+#endif
for (i = 0; i < MAXDESC; i++)
{
chan_process[i] = Qnil;
@@ -6969,6 +7034,9 @@ syms_of_process ()
staticpro (&Qlast_nonmenu_event);
staticpro (&Vprocess_alist);
+#ifdef SIGCHLD
+ staticpro (&deleted_pid_list);
+#endif
DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
doc: /* *Non-nil means delete processes immediately when they exit.
diff --git a/src/puresize.h b/src/puresize.h
index 1288feff151..67e758ae799 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -43,7 +43,7 @@ Boston, MA 02110-1301, USA. */
#endif
#ifndef BASE_PURESIZE
-#define BASE_PURESIZE (1205000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
+#define BASE_PURESIZE (1210000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
#endif
/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */
diff --git a/src/search.c b/src/search.c
index f613630eaf9..15cc51cb511 100644
--- a/src/search.c
+++ b/src/search.c
@@ -90,6 +90,7 @@ static void save_search_regs ();
static int simple_search ();
static int boyer_moore ();
static int search_buffer ();
+static void matcher_overflow () NO_RETURN;
static void
matcher_overflow ()
diff --git a/src/sound.c b/src/sound.c
index 0fbeceb4b9e..af2369040cc 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -73,6 +73,10 @@ Boston, MA 02110-1301, USA. */
#ifdef HAVE_SOUNDCARD_H
#include <soundcard.h>
#endif
+#ifdef HAVE_ALSA
+#include <asoundlib.h>
+#endif
+
/* END: Non Windows Includes */
#else /* WINDOWSNT */
@@ -109,7 +113,8 @@ enum sound_attr
SOUND_ATTR_SENTINEL
};
-static void sound_perror P_ ((char *));
+static void alsa_sound_perror P_ ((char *, int)) NO_RETURN;
+static void sound_perror P_ ((char *)) NO_RETURN;
static void sound_warning P_ ((char *));
static int parse_sound P_ ((Lisp_Object, Lisp_Object *));
@@ -121,6 +126,9 @@ static int parse_sound P_ ((Lisp_Object, Lisp_Object *));
#ifndef DEFAULT_SOUND_DEVICE
#define DEFAULT_SOUND_DEVICE "/dev/dsp"
#endif
+#ifndef DEFAULT_ALSA_SOUND_DEVICE
+#define DEFAULT_ALSA_SOUND_DEVICE "default"
+#endif
/* Structure forward declarations. */
@@ -227,6 +235,10 @@ struct sound_device
void (* choose_format) P_ ((struct sound_device *sd,
struct sound *s));
+ /* Return a preferred data size in bytes to be sent to write (below)
+ each time. 2048 is used if this is NULL. */
+ int (* period_size) P_ ((struct sound_device *sd));
+
/* Write NYBTES bytes from BUFFER to device SD. */
void (* write) P_ ((struct sound_device *sd, const char *buffer,
int nbytes));
@@ -280,7 +292,7 @@ static void vox_open P_ ((struct sound_device *));
static void vox_configure P_ ((struct sound_device *));
static void vox_close P_ ((struct sound_device *sd));
static void vox_choose_format P_ ((struct sound_device *, struct sound *));
-static void vox_init P_ ((struct sound_device *));
+static int vox_init P_ ((struct sound_device *));
static void vox_write P_ ((struct sound_device *, const char *, int));
static void find_sound_type P_ ((struct sound *));
static u_int32_t le2hl P_ ((u_int32_t));
@@ -604,7 +616,7 @@ wav_play (s, sd)
{
char *buffer;
int nbytes;
- int blksize = 2048;
+ int blksize = sd->period_size ? sd->period_size (sd) : 2048;
buffer = (char *) alloca (blksize);
lseek (s->fd, sizeof *header, SEEK_SET);
@@ -633,7 +645,8 @@ enum au_encoding
AU_ENCODING_32,
AU_ENCODING_IEEE32,
AU_ENCODING_IEEE64,
- AU_COMPRESSED = 23
+ AU_COMPRESSED = 23,
+ AU_ENCODING_ALAW_8 = 27
};
@@ -689,7 +702,7 @@ au_play (s, sd)
SBYTES (s->data) - header->data_offset);
else
{
- int blksize = 2048;
+ int blksize = sd->period_size ? sd->period_size (sd) : 2048;
char *buffer;
int nbytes;
@@ -868,16 +881,33 @@ vox_choose_format (sd, s)
/* Initialize device SD. Set up the interface functions in the device
structure. */
-static void
+static int
vox_init (sd)
struct sound_device *sd;
{
+ char *file;
+ int fd;
+
+ /* Open the sound device. Default is /dev/dsp. */
+ if (sd->file)
+ file = sd->file;
+ else
+ file = DEFAULT_SOUND_DEVICE;
+ fd = emacs_open (file, O_WRONLY, 0);
+ if (fd >= 0)
+ emacs_close (fd);
+ else
+ return 0;
+
sd->fd = -1;
sd->open = vox_open;
sd->close = vox_close;
sd->configure = vox_configure;
sd->choose_format = vox_choose_format;
sd->write = vox_write;
+ sd->period_size = NULL;
+
+ return 1;
}
/* Write NBYTES bytes from BUFFER to device SD. */
@@ -893,6 +923,368 @@ vox_write (sd, buffer, nbytes)
sound_perror ("Error writing to sound device");
}
+#ifdef HAVE_ALSA
+/***********************************************************************
+ ALSA Driver Interface
+ ***********************************************************************/
+
+/* This driver is available on GNU/Linux. */
+
+static void
+alsa_sound_perror (msg, err)
+ char *msg;
+ int err;
+{
+ error ("%s: %s", msg, snd_strerror (err));
+}
+
+struct alsa_params
+{
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+ snd_pcm_uframes_t period_size;
+};
+
+/* Open device SD. If SD->file is non-null, open that device,
+ otherwise use a default device name. */
+
+static void
+alsa_open (sd)
+ struct sound_device *sd;
+{
+ char *file;
+ struct alsa_params *p;
+ int err;
+
+ /* Open the sound device. Default is "default". */
+ if (sd->file)
+ file = sd->file;
+ else
+ file = DEFAULT_ALSA_SOUND_DEVICE;
+
+ p = xmalloc (sizeof (*p));
+ p->handle = NULL;
+ p->hwparams = NULL;
+ p->swparams = NULL;
+
+ sd->fd = -1;
+ sd->data = p;
+
+
+ err = snd_pcm_open (&p->handle, file, SND_PCM_STREAM_PLAYBACK, 0);
+ if (err < 0)
+ alsa_sound_perror (file, err);
+}
+
+static int
+alsa_period_size (sd)
+ struct sound_device *sd;
+{
+ struct alsa_params *p = (struct alsa_params *) sd->data;
+ return p->period_size;
+}
+
+static void
+alsa_configure (sd)
+ struct sound_device *sd;
+{
+ int val, err, dir;
+ struct alsa_params *p = (struct alsa_params *) sd->data;
+ snd_pcm_uframes_t buffer_size;
+
+ xassert (p->handle != 0);
+
+ err = snd_pcm_hw_params_malloc (&p->hwparams);
+ if (err < 0)
+ alsa_sound_perror ("Could not allocate hardware parameter structure", err);
+
+ err = snd_pcm_sw_params_malloc (&p->swparams);
+ if (err < 0)
+ alsa_sound_perror ("Could not allocate software parameter structure", err);
+
+ err = snd_pcm_hw_params_any (p->handle, p->hwparams);
+ if (err < 0)
+ alsa_sound_perror ("Could not initialize hardware parameter structure", err);
+
+ err = snd_pcm_hw_params_set_access (p->handle, p->hwparams,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+ if (err < 0)
+ alsa_sound_perror ("Could not set access type", err);
+
+ val = sd->format;
+ err = snd_pcm_hw_params_set_format (p->handle, p->hwparams, val);
+ if (err < 0)
+ alsa_sound_perror ("Could not set sound format", err);
+
+ val = sd->sample_rate;
+ err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &val, 0);
+ if (err < 0)
+ alsa_sound_perror ("Could not set sample rate", err);
+
+ val = sd->channels;
+ err = snd_pcm_hw_params_set_channels (p->handle, p->hwparams, val);
+ if (err < 0)
+ alsa_sound_perror ("Could not set channel count", err);
+
+ err = snd_pcm_hw_params (p->handle, p->hwparams);
+ if (err < 0)
+ alsa_sound_perror ("Could not set parameters", err);
+
+
+ err = snd_pcm_hw_params_get_period_size (p->hwparams, &p->period_size, &dir);
+ if (err < 0)
+ alsa_sound_perror ("Unable to get period size for playback", err);
+
+ err = snd_pcm_hw_params_get_buffer_size (p->hwparams, &buffer_size);
+ if (err < 0)
+ alsa_sound_perror("Unable to get buffer size for playback", err);
+
+ err = snd_pcm_sw_params_current (p->handle, p->swparams);
+ if (err < 0)
+ alsa_sound_perror ("Unable to determine current swparams for playback",
+ err);
+
+ /* Start the transfer when the buffer is almost full */
+ err = snd_pcm_sw_params_set_start_threshold (p->handle, p->swparams,
+ (buffer_size / p->period_size)
+ * p->period_size);
+ if (err < 0)
+ alsa_sound_perror ("Unable to set start threshold mode for playback", err);
+
+ /* Allow the transfer when at least period_size samples can be processed */
+ err = snd_pcm_sw_params_set_avail_min (p->handle, p->swparams, p->period_size);
+ if (err < 0)
+ alsa_sound_perror ("Unable to set avail min for playback", err);
+
+ /* Align all transfers to 1 period */
+ err = snd_pcm_sw_params_set_xfer_align (p->handle, p->swparams,
+ p->period_size);
+ if (err < 0)
+ alsa_sound_perror ("Unable to set transfer align for playback", err);
+
+ err = snd_pcm_sw_params (p->handle, p->swparams);
+ if (err < 0)
+ alsa_sound_perror ("Unable to set sw params for playback\n", err);
+
+ snd_pcm_hw_params_free (p->hwparams);
+ p->hwparams = NULL;
+ snd_pcm_sw_params_free (p->swparams);
+ p->swparams = NULL;
+
+ err = snd_pcm_prepare (p->handle);
+ if (err < 0)
+ alsa_sound_perror ("Could not prepare audio interface for use", err);
+
+ if (sd->volume > 0)
+ {
+ int chn;
+ snd_mixer_t *handle;
+ snd_mixer_elem_t *e;
+ char *file = sd->file ? sd->file : DEFAULT_ALSA_SOUND_DEVICE;
+
+ if (snd_mixer_open (&handle, 0) >= 0)
+ {
+ if (snd_mixer_attach (handle, file) >= 0
+ && snd_mixer_load (handle) >= 0
+ && snd_mixer_selem_register (handle, NULL, NULL) >= 0)
+ for (e = snd_mixer_first_elem (handle);
+ e;
+ e = snd_mixer_elem_next (e))
+ {
+ if (snd_mixer_selem_has_playback_volume (e))
+ {
+ long pmin, pmax;
+ snd_mixer_selem_get_playback_volume_range (e, &pmin, &pmax);
+ long vol = pmin + (sd->volume * (pmax - pmin)) / 100;
+
+ for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++)
+ snd_mixer_selem_set_playback_volume (e, chn, vol);
+ }
+ }
+ snd_mixer_close(handle);
+ }
+ }
+}
+
+
+/* Close device SD if it is open. */
+
+static void
+alsa_close (sd)
+ struct sound_device *sd;
+{
+ struct alsa_params *p = (struct alsa_params *) sd->data;
+ if (p)
+ {
+ if (p->hwparams)
+ snd_pcm_hw_params_free (p->hwparams);
+ if (p->swparams)
+ snd_pcm_sw_params_free (p->swparams);
+ if (p->handle)
+ {
+ snd_pcm_drain(p->handle);
+ snd_pcm_close (p->handle);
+ }
+ free (p);
+ }
+}
+
+/* Choose device-dependent format for device SD from sound file S. */
+
+static void
+alsa_choose_format (sd, s)
+ struct sound_device *sd;
+ struct sound *s;
+{
+ struct alsa_params *p = (struct alsa_params *) sd->data;
+ if (s->type == RIFF)
+ {
+ struct wav_header *h = (struct wav_header *) s->header;
+ if (h->precision == 8)
+ sd->format = SND_PCM_FORMAT_U8;
+ else if (h->precision == 16)
+ sd->format = SND_PCM_FORMAT_S16_LE;
+ else
+ error ("Unsupported WAV file format");
+ }
+ else if (s->type == SUN_AUDIO)
+ {
+ struct au_header *header = (struct au_header *) s->header;
+ switch (header->encoding)
+ {
+ case AU_ENCODING_ULAW_8:
+ sd->format = SND_PCM_FORMAT_MU_LAW;
+ break;
+ case AU_ENCODING_ALAW_8:
+ sd->format = SND_PCM_FORMAT_A_LAW;
+ break;
+ case AU_ENCODING_IEEE32:
+ sd->format = SND_PCM_FORMAT_FLOAT_BE;
+ break;
+ case AU_ENCODING_IEEE64:
+ sd->format = SND_PCM_FORMAT_FLOAT64_BE;
+ break;
+ case AU_ENCODING_8:
+ sd->format = SND_PCM_FORMAT_S8;
+ break;
+ case AU_ENCODING_16:
+ sd->format = SND_PCM_FORMAT_S16_BE;
+ break;
+ case AU_ENCODING_24:
+ sd->format = SND_PCM_FORMAT_S24_BE;
+ break;
+ case AU_ENCODING_32:
+ sd->format = SND_PCM_FORMAT_S32_BE;
+ break;
+
+ default:
+ error ("Unsupported AU file format");
+ }
+ }
+ else
+ abort ();
+}
+
+
+/* Write NBYTES bytes from BUFFER to device SD. */
+
+static void
+alsa_write (sd, buffer, nbytes)
+ struct sound_device *sd;
+ const char *buffer;
+ int nbytes;
+{
+ struct alsa_params *p = (struct alsa_params *) sd->data;
+
+ /* The the third parameter to snd_pcm_writei is frames, not bytes. */
+ int fact = snd_pcm_format_size (sd->format, 1) * sd->channels;
+ int nwritten = 0;
+ int err;
+
+ while (nwritten < nbytes)
+ {
+ err = snd_pcm_writei (p->handle,
+ buffer + nwritten,
+ (nbytes - nwritten)/fact);
+ if (err < 0)
+ {
+ if (err == -EPIPE)
+ { /* under-run */
+ err = snd_pcm_prepare (p->handle);
+ if (err < 0)
+ alsa_sound_perror ("Can't recover from underrun, prepare failed",
+ err);
+ }
+ else if (err == -ESTRPIPE)
+ {
+ while ((err = snd_pcm_resume (p->handle)) == -EAGAIN)
+ sleep(1); /* wait until the suspend flag is released */
+ if (err < 0)
+ {
+ err = snd_pcm_prepare (p->handle);
+ if (err < 0)
+ alsa_sound_perror ("Can't recover from suspend, "
+ "prepare failed",
+ err);
+ }
+ }
+ else
+ alsa_sound_perror ("Error writing to sound device", err);
+
+ }
+ else
+ nwritten += err * fact;
+ }
+}
+
+static void
+snd_error_quiet (file, line, function, err, fmt)
+ const char *file;
+ int line;
+ const char *function;
+ int err;
+ const char *fmt;
+{
+}
+
+/* Initialize device SD. Set up the interface functions in the device
+ structure. */
+
+static int
+alsa_init (sd)
+ struct sound_device *sd;
+{
+ char *file;
+ snd_pcm_t *handle;
+ int err;
+
+ /* Open the sound device. Default is "default". */
+ if (sd->file)
+ file = sd->file;
+ else
+ file = DEFAULT_ALSA_SOUND_DEVICE;
+
+ snd_lib_error_set_handler ((snd_lib_error_handler_t) snd_error_quiet);
+ err = snd_pcm_open (&handle, file, SND_PCM_STREAM_PLAYBACK, 0);
+ snd_lib_error_set_handler (NULL);
+ if (err < 0)
+ return 0;
+
+ sd->fd = -1;
+ sd->open = alsa_open;
+ sd->close = alsa_close;
+ sd->configure = alsa_configure;
+ sd->choose_format = alsa_choose_format;
+ sd->write = alsa_write;
+ sd->period_size = alsa_period_size;
+
+ return 1;
+}
+
+#endif /* HAVE_ALSA */
+
+
/* END: Non Windows functions */
#else /* WINDOWSNT */
@@ -1056,10 +1448,11 @@ Internal use only, use `play-sound' instead.\n */)
args[1] = sound;
Frun_hook_with_args (2, args);
- /* There is only one type of device we currently support, the VOX
- sound driver. Set up the device interface functions for that
- device. */
- vox_init (current_sound_device);
+#ifdef HAVE_ALSA
+ if (!alsa_init (current_sound_device))
+#endif
+ if (!vox_init (current_sound_device))
+ error ("No usable sound device driver found");
/* Open the device. */
current_sound_device->open (current_sound_device);
diff --git a/src/sysdep.c b/src/sysdep.c
index 3e06170e721..307f69290d6 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -244,7 +244,7 @@ int emacs_ospeed;
under VMS, we place the input channel number here. */
int input_fd;
-void croak P_ ((char *));
+void croak P_ ((char *)) NO_RETURN;
#ifdef AIXHFT
void hft_init ();
diff --git a/src/w32.c b/src/w32.c
index 71799befdbb..f11ffb7a785 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -950,11 +950,11 @@ init_environment (char ** argv)
struct stat ignored;
char default_home[MAX_PATH];
- static struct env_entry
+ static const struct env_entry
{
char * name;
char * def_value;
- } env_vars[] =
+ } dflt_envvars[] =
{
{"HOME", "C:/"},
{"PRELOAD_WINSOCK", NULL},
@@ -971,6 +971,17 @@ init_environment (char ** argv)
{"LANG", NULL},
};
+#define N_ENV_VARS sizeof(dflt_envvars)/sizeof(dflt_envvars[0])
+
+ /* We need to copy dflt_envvars[] and work on the copy because we
+ don't want the dumped Emacs to inherit the values of
+ environment variables we saw during dumping (which could be on
+ a different system). The defaults above must be left intact. */
+ struct env_entry env_vars[N_ENV_VARS];
+
+ for (i = 0; i < N_ENV_VARS; i++)
+ env_vars[i] = dflt_envvars[i];
+
/* For backwards compatibility, check if a .emacs file exists in C:/
If not, then we can try to default to the appdata directory under the
user's profile, which is more likely to be writable. */
@@ -1005,7 +1016,7 @@ init_environment (char ** argv)
LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
locale_name, sizeof (locale_name)))
{
- for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
+ for (i = 0; i < N_ENV_VARS; i++)
{
if (strcmp (env_vars[i].name, "LANG") == 0)
{
@@ -1069,7 +1080,7 @@ init_environment (char ** argv)
}
}
- for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
+ for (i = 0; i < N_ENV_VARS; i++)
{
if (!getenv (env_vars[i].name))
{
@@ -1084,20 +1095,17 @@ init_environment (char ** argv)
if (lpval)
{
- if (dwType == REG_EXPAND_SZ)
- {
- char buf1[SET_ENV_BUF_SIZE], buf2[SET_ENV_BUF_SIZE];
+ char buf1[SET_ENV_BUF_SIZE], buf2[SET_ENV_BUF_SIZE];
- ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof(buf1));
- _snprintf (buf2, sizeof(buf2)-1, "%s=%s", env_vars[i].name, buf1);
- _putenv (strdup (buf2));
- }
+ if (dwType == REG_EXPAND_SZ)
+ ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof(buf1));
else if (dwType == REG_SZ)
+ strcpy (buf1, lpval);
+ if (dwType == REG_EXPAND_SZ || dwType == REG_SZ)
{
- char buf[SET_ENV_BUF_SIZE];
-
- _snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval);
- _putenv (strdup (buf));
+ _snprintf (buf2, sizeof(buf2)-1, "%s=%s", env_vars[i].name,
+ buf1);
+ _putenv (strdup (buf2));
}
if (!dont_free)
diff --git a/src/w32fns.c b/src/w32fns.c
index 4da5271c870..aa83e006194 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1684,7 +1684,7 @@ x_set_icon_name (f, arg, oldval)
if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
return;
}
- else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
+ else if (!NILP (arg) || NILP (oldval))
return;
f->icon_name = arg;
diff --git a/src/w32heap.c b/src/w32heap.c
index f1fa196abe7..e1bdd867721 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -42,10 +42,6 @@ OSVERSIONINFO osinfo_cache;
unsigned long syspage_mask = 0;
-/* These are defined to get Emacs to compile, but are not used. */
-int edata;
-int etext;
-
/* The major and minor versions of NT. */
int w32_major_version;
int w32_minor_version;
diff --git a/src/w32term.c b/src/w32term.c
index 305527946fb..0a7007cc8f4 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -173,32 +173,6 @@ HANDLE hWindowsThread = NULL;
DWORD dwMainThreadId = 0;
HANDLE hMainThread = NULL;
-#ifndef SIF_ALL
-/* These definitions are new with Windows 95. */
-#define SIF_RANGE 0x0001
-#define SIF_PAGE 0x0002
-#define SIF_POS 0x0004
-#define SIF_DISABLENOSCROLL 0x0008
-#define SIF_TRACKPOS 0x0010
-#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
-
-typedef struct tagSCROLLINFO
-{
- UINT cbSize;
- UINT fMask;
- int nMin;
- int nMax;
- UINT nPage;
- int nPos;
- int nTrackPos;
-} SCROLLINFO, FAR *LPSCROLLINFO;
-typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
-#endif /* SIF_ALL */
-
-/* Dynamic linking to new proportional scroll bar functions. */
-int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
-BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
-
int vertical_scroll_bar_min_handle;
int vertical_scroll_bar_top_border;
int vertical_scroll_bar_bottom_border;
@@ -2540,20 +2514,29 @@ x_draw_stretch_glyph_string (s)
{
/* If `x-stretch-block-cursor' is nil, don't draw a block cursor
as wide as the stretch glyph. */
- int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
+ int width, background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
/* Draw cursor. */
- x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
+ x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
/* Clear rest using the GC of the original non-cursor face. */
- if (width < s->background_width)
+ if (width < background_width)
{
XGCValues *gc = s->face->gc;
- int x = s->x + width, y = s->y;
- int w = s->background_width - width, h = s->height;
+ int y = s->y;
+ int w = background_width - width, h = s->height;
RECT r;
HDC hdc = s->hdc;
+ x += width;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
@@ -2582,8 +2565,18 @@ x_draw_stretch_glyph_string (s)
}
}
else if (!s->background_filled_p)
- x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
- s->height);
+ {
+ int background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (background_width > 0)
+ x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+ }
s->background_filled_p = 1;
}
@@ -3619,6 +3612,7 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
int sb_page, sb_pos;
BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
+ SCROLLINFO si;
if (whole)
{
@@ -3643,24 +3637,17 @@ w32_set_scroll_bar_thumb (bar, portion, position, whole)
BLOCK_INPUT;
- if (pfnSetScrollInfo)
- {
- SCROLLINFO si;
-
- si.cbSize = sizeof (si);
- /* Only update page size if currently dragging, to reduce
- flicker effects. */
- if (draggingp)
- si.fMask = SIF_PAGE;
- else
- si.fMask = SIF_PAGE | SIF_POS;
- si.nPage = sb_page;
- si.nPos = sb_pos;
-
- pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
- }
+ si.cbSize = sizeof (si);
+ /* Only update page size if currently dragging, to reduce
+ flicker effects. */
+ if (draggingp)
+ si.fMask = SIF_PAGE;
else
- SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
+ si.fMask = SIF_PAGE | SIF_POS;
+ si.nPage = sb_page;
+ si.nPos = sb_pos;
+
+ SetScrollInfo (w, SB_CTL, &si, !draggingp);
UNBLOCK_INPUT;
}
@@ -3749,6 +3736,7 @@ x_scroll_bar_create (w, top, left, width, height)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
HWND hwnd;
+ SCROLLINFO si;
struct scroll_bar *bar
= XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
@@ -3767,26 +3755,15 @@ x_scroll_bar_create (w, top, left, width, height)
hwnd = my_create_scrollbar (f, bar);
- if (pfnSetScrollInfo)
- {
- SCROLLINFO si;
-
- si.cbSize = sizeof (si);
- si.fMask = SIF_ALL;
- si.nMin = 0;
- si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
- + VERTICAL_SCROLL_BAR_MIN_HANDLE;
- si.nPage = si.nMax;
- si.nPos = 0;
+ si.cbSize = sizeof (si);
+ si.fMask = SIF_ALL;
+ si.nMin = 0;
+ si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
+ + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+ si.nPage = si.nMax;
+ si.nPos = 0;
- pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
- }
- else
- {
- SetScrollRange (hwnd, SB_CTL, 0,
- VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
- SetScrollPos (hwnd, SB_CTL, 0, FALSE);
- }
+ SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
@@ -3895,6 +3872,8 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
else
{
HDC hdc;
+ SCROLLINFO si;
+
BLOCK_INPUT;
if (width && height)
{
@@ -3914,21 +3893,15 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1), TRUE);
- if (pfnSetScrollInfo)
- {
- SCROLLINFO si;
- si.cbSize = sizeof (si);
- si.fMask = SIF_RANGE;
- si.nMin = 0;
- si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
- + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+ si.cbSize = sizeof (si);
+ si.fMask = SIF_RANGE;
+ si.nMin = 0;
+ si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
+ + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+
+ SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
- pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
- }
- else
- SetScrollRange (hwnd, SB_CTL, 0,
- VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
my_show_window (f, hwnd, SW_NORMAL);
/* InvalidateRect (w, NULL, FALSE); */
@@ -4080,19 +4053,13 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
int y;
int dragging = !NILP (bar->dragging);
+ SCROLLINFO si;
- if (pfnGetScrollInfo)
- {
- SCROLLINFO si;
-
- si.cbSize = sizeof (si);
- si.fMask = SIF_POS;
+ si.cbSize = sizeof (si);
+ si.fMask = SIF_POS;
- pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
- y = si.nPos;
- }
- else
- y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
+ GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
+ y = si.nPos;
bar->dragging = Qnil;
@@ -4129,21 +4096,18 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
emacs_event->part = scroll_bar_handle;
/* "Silently" update current position. */
- if (pfnSetScrollInfo)
- {
- SCROLLINFO si;
+ {
+ SCROLLINFO si;
- si.cbSize = sizeof (si);
- si.fMask = SIF_POS;
- si.nPos = y;
- /* Remember apparent position (we actually lag behind the real
- position, so don't set that directly. */
- last_scroll_bar_drag_pos = y;
+ si.cbSize = sizeof (si);
+ si.fMask = SIF_POS;
+ si.nPos = y;
+ /* Remember apparent position (we actually lag behind the real
+ position, so don't set that directly. */
+ last_scroll_bar_drag_pos = y;
- pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
- }
- else
- SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
+ SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
+ }
break;
case SB_ENDSCROLL:
/* If this is the end of a drag sequence, then reset the scroll
@@ -4151,20 +4115,15 @@ w32_scroll_bar_handle_click (bar, msg, emacs_event)
nothing. */
if (dragging)
{
- if (pfnSetScrollInfo)
- {
- SCROLLINFO si;
- int start = XINT (bar->start);
- int end = XINT (bar->end);
+ SCROLLINFO si;
+ int start = XINT (bar->start);
+ int end = XINT (bar->end);
- si.cbSize = sizeof (si);
- si.fMask = SIF_PAGE | SIF_POS;
- si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
- si.nPos = last_scroll_bar_drag_pos;
- pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
- }
- else
- SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
+ si.cbSize = sizeof (si);
+ si.fMask = SIF_PAGE | SIF_POS;
+ si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
+ si.nPos = last_scroll_bar_drag_pos;
+ SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
}
/* fall through */
default:
@@ -4195,25 +4154,19 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int pos;
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
+ SCROLLINFO si;
BLOCK_INPUT;
*fp = f;
*bar_window = bar->window;
- if (pfnGetScrollInfo)
- {
- SCROLLINFO si;
-
- si.cbSize = sizeof (si);
- si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
+ si.cbSize = sizeof (si);
+ si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
- pfnGetScrollInfo (w, SB_CTL, &si);
- pos = si.nPos;
- top_range = si.nMax - si.nPage + 1;
- }
- else
- pos = GetScrollPos (w, SB_CTL);
+ GetScrollInfo (w, SB_CTL, &si);
+ pos = si.nPos;
+ top_range = si.nMax - si.nPage + 1;
switch (LOWORD (last_mouse_scroll_bar_pos))
{
@@ -5082,7 +5035,7 @@ x_draw_hollow_cursor (w, row)
struct frame *f = XFRAME (WINDOW_FRAME (w));
HDC hdc;
RECT rect;
- int h;
+ int left, top, h;
struct glyph *cursor_glyph;
HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
@@ -5093,8 +5046,9 @@ x_draw_hollow_cursor (w, row)
return;
/* Compute frame-relative coordinates for phys cursor. */
- rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- rect.top = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
+ rect.left = left;
+ rect.top = top;
rect.bottom = rect.top + h;
rect.right = rect.left + w->phys_cursor_width;
diff --git a/src/window.c b/src/window.c
index 1abeec92367..59c223b4a8f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3778,7 +3778,9 @@ SIZE includes that window's scroll bar, or the divider column to its right.
Interactively, all arguments are nil.
Returns the newly created window (which is the lower or rightmost one).
-The upper or leftmost window is the original one and remains selected.
+The upper or leftmost window is the original one, and remains selected
+if it was selected before.
+
See Info node `(elisp)Splitting Windows' for more details and examples.*/)
(window, size, horflag)
Lisp_Object window, size, horflag;
@@ -5794,6 +5796,7 @@ struct saved_window
Lisp_Object left_margin_cols, right_margin_cols;
Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
+ Lisp_Object dedicated;
};
#define SAVED_WINDOW_N(swv,n) \
@@ -5804,9 +5807,7 @@ DEFUN ("window-configuration-p", Fwindow_configuration_p, Swindow_configuration_
(object)
Lisp_Object object;
{
- if (WINDOW_CONFIGURATIONP (object))
- return Qt;
- return Qnil;
+ return WINDOW_CONFIGURATIONP (object) ? Qt : Qnil;
}
DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_configuration_frame, 1, 1, 0,
@@ -6028,6 +6029,7 @@ the return value is nil. Otherwise the value is t. */)
w->fringes_outside_margins = p->fringes_outside_margins;
w->scroll_bar_width = p->scroll_bar_width;
w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
+ w->dedicated = p->dedicated;
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
@@ -6297,6 +6299,7 @@ save_window_save (window, vector, i)
p->fringes_outside_margins = w->fringes_outside_margins;
p->scroll_bar_width = w->scroll_bar_width;
p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
+ p->dedicated = w->dedicated;
if (!NILP (w->buffer))
{
/* Save w's value of point in the window configuration.
@@ -6796,7 +6799,9 @@ foreach_window (f, fn, user_data)
int (* fn) P_ ((struct window *, void *));
void *user_data;
{
- foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data);
+ /* Fdelete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
+ if (WINDOWP (FRAME_ROOT_WINDOW (f)))
+ foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data);
}
diff --git a/src/xdisp.c b/src/xdisp.c
index 9b5b913938b..0cb34a2fef8 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1995,15 +1995,15 @@ get_glyph_string_clip_rect (s, nr)
Set w->phys_cursor_width to width of phys cursor.
*/
-int
-get_phys_cursor_geometry (w, row, glyph, heightp)
+void
+get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
struct window *w;
struct glyph_row *row;
struct glyph *glyph;
- int *heightp;
+ int *xp, *yp, *heightp;
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- int y, wd, h, h0, y0;
+ int x, y, wd, h, h0, y0;
/* Compute the width of the rectangle to draw. If on a stretch
glyph, and `x-stretch-block-cursor' is nil, don't draw a
@@ -2013,6 +2013,14 @@ get_phys_cursor_geometry (w, row, glyph, heightp)
#ifdef HAVE_NTGUI
wd++; /* Why? */
#endif
+
+ x = w->phys_cursor.x;
+ if (x < 0)
+ {
+ wd += x;
+ x = 0;
+ }
+
if (glyph->type == STRETCH_GLYPH
&& !x_stretch_cursor_p)
wd = min (FRAME_COLUMN_WIDTH (f), wd);
@@ -2042,8 +2050,9 @@ get_phys_cursor_geometry (w, row, glyph, heightp)
}
}
+ *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
+ *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
*heightp = h;
- return WINDOW_TO_FRAME_PIXEL_Y (w, y);
}
/*
@@ -6334,6 +6343,8 @@ next_element_from_composition (it)
it->position = (STRINGP (it->string)
? it->current.string_pos
: it->current.pos);
+ if (STRINGP (it->string))
+ it->object = it->string;
return 1;
}
@@ -9608,7 +9619,8 @@ display_tool_bar_line (it, height)
while (it->current_x < max_x)
{
- int x_before, x, n_glyphs_before, i, nglyphs;
+ int x, n_glyphs_before, i, nglyphs;
+ struct it it_before;
/* Get the next display element. */
if (!get_next_display_element (it))
@@ -9620,22 +9632,23 @@ display_tool_bar_line (it, height)
}
/* Produce glyphs. */
- x_before = it->current_x;
- n_glyphs_before = it->glyph_row->used[TEXT_AREA];
+ n_glyphs_before = row->used[TEXT_AREA];
+ it_before = *it;
+
PRODUCE_GLYPHS (it);
- nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
+ nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
i = 0;
- x = x_before;
+ x = it_before.current_x;
while (i < nglyphs)
{
struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
if (x + glyph->pixel_width > max_x)
{
- /* Glyph doesn't fit on line. */
- it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
- it->current_x = x;
+ /* Glyph doesn't fit on line. Backtrack. */
+ row->used[TEXT_AREA] = n_glyphs_before;
+ *it = it_before;
goto out;
}
@@ -9666,6 +9679,8 @@ display_tool_bar_line (it, height)
/* Make line the desired height and center it vertically. */
if ((height -= it->max_ascent + it->max_descent) > 0)
{
+ /* Don't add more than one line height. */
+ height %= FRAME_LINE_HEIGHT (it->f);
it->max_ascent += height / 2;
it->max_descent += (height + 1) / 2;
}
@@ -11713,9 +11728,11 @@ redisplay_window_1 (window)
/* Set cursor position of W. PT is assumed to be displayed in ROW.
DELTA is the number of bytes by which positions recorded in ROW
- differ from current buffer positions. */
+ differ from current buffer positions.
-void
+ Return 0 if cursor is not on this row. 1 otherwise. */
+
+int
set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
struct window *w;
struct glyph_row *row;
@@ -11865,6 +11882,11 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
}
}
+
+ /* If we reached the end of the line, and end was from a string,
+ cursor is not on this line. */
+ if (glyph == end && row->continued_p)
+ return 0;
}
w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
@@ -11898,6 +11920,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
else
CHARPOS (this_line_start_pos) = 0;
}
+
+ return 1;
}
@@ -12581,8 +12605,18 @@ try_cursor_movement (window, startp, scroll_step)
rc = CURSOR_MOVEMENT_MUST_SCROLL;
else
{
- set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
- rc = CURSOR_MOVEMENT_SUCCESS;
+ do
+ {
+ if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
+ {
+ rc = CURSOR_MOVEMENT_SUCCESS;
+ break;
+ }
+ ++row;
+ }
+ while (MATRIX_ROW_BOTTOM_Y (row) < last_y
+ && MATRIX_ROW_START_CHARPOS (row) == PT
+ && cursor_row_p (w, row));
}
}
}
@@ -15035,6 +15069,25 @@ dump_glyph (row, glyph, area)
glyph->left_box_line_p,
glyph->right_box_line_p);
}
+ else if (glyph->type == COMPOSITE_GLYPH)
+ {
+ fprintf (stderr,
+ " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+ glyph - row->glyphs[TEXT_AREA],
+ '+',
+ glyph->charpos,
+ (BUFFERP (glyph->object)
+ ? 'B'
+ : (STRINGP (glyph->object)
+ ? 'S'
+ : '-')),
+ glyph->pixel_width,
+ glyph->u.cmp_id,
+ '.',
+ glyph->face_id,
+ glyph->left_box_line_p,
+ glyph->right_box_line_p);
+ }
}
@@ -21603,7 +21656,7 @@ erase_phys_cursor (w)
/* Maybe clear the display under the cursor. */
if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
{
- int x, y;
+ int x, y, left_x;
int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
int width;
@@ -21611,11 +21664,16 @@ erase_phys_cursor (w)
if (cursor_glyph == NULL)
goto mark_cursor_off;
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+ width = cursor_glyph->pixel_width;
+ left_x = window_box_left_offset (w, TEXT_AREA);
+ x = w->phys_cursor.x;
+ if (x < left_x)
+ width -= left_x - x;
+ width = min (width, window_box_width (w, TEXT_AREA) - x);
y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
- width = min (cursor_glyph->pixel_width,
- window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
+ x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
+ if (width > 0)
rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
}
diff --git a/src/xfaces.c b/src/xfaces.c
index 2b2f1620133..9adc9218f6d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6762,6 +6762,12 @@ better_font_p (values, font1, font2, compare_pt_p, avgwidth)
{
int i;
+ /* Any font is better than no font. */
+ if (! font1)
+ return 0;
+ if (! font2)
+ return 1;
+
for (i = 0; i < DIM (font_sort_order); ++i)
{
int xlfd_idx = font_sort_order[i];
@@ -7012,29 +7018,19 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
if (needs_overstrike)
*needs_overstrike = 0;
- /* Start with the first non-scalable font in the list. */
- for (i = 0; i < nfonts; ++i)
- if (!font_scalable_p (fonts + i))
- break;
+ best = NULL;
/* Find the best match among the non-scalable fonts. */
- if (i < nfonts)
- {
- best = fonts + i;
-
- for (i = 1; i < nfonts; ++i)
- if (!font_scalable_p (fonts + i)
- && better_font_p (specified, fonts + i, best, 1, avgwidth))
- {
- best = fonts + i;
+ for (i = 0; i < nfonts; ++i)
+ if (!font_scalable_p (fonts + i)
+ && better_font_p (specified, fonts + i, best, 1, avgwidth))
+ {
+ best = fonts + i;
- exact_p = exact_face_match_p (specified, best, avgwidth);
- if (exact_p)
- break;
- }
- }
- else
- best = NULL;
+ exact_p = exact_face_match_p (specified, best, avgwidth);
+ if (exact_p)
+ break;
+ }
/* Unless we found an exact match among non-scalable fonts, see if
we can find a better match among scalable fonts. */
@@ -7058,8 +7054,7 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
for (i = 0; i < nfonts; ++i)
if (font_scalable_p (fonts + i))
{
- if (best == NULL
- || better_font_p (specified, fonts + i, best, 0, 0)
+ if (better_font_p (specified, fonts + i, best, 0, 0)
|| (!non_scalable_has_exact_height_p
&& !better_font_p (specified, best, fonts + i, 0, 0)))
{
@@ -7067,23 +7062,27 @@ best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
best = fonts + i;
}
}
+ }
- if (needs_overstrike)
- {
- enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
- enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
+ /* We should have found SOME font. */
+ if (best == NULL)
+ abort ();
- if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
- {
- /* We want a bold font, but didn't get one; try to use
- overstriking instead to simulate bold-face. However,
- don't overstrike an already-bold fontn unless the
- desired weight grossly exceeds the available weight. */
- if (got_weight > XLFD_WEIGHT_MEDIUM)
- *needs_overstrike = (got_weight - want_weight) > 2;
- else
- *needs_overstrike = 1;
- }
+ if (! exact_p && needs_overstrike)
+ {
+ enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
+ enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
+
+ if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
+ {
+ /* We want a bold font, but didn't get one; try to use
+ overstriking instead to simulate bold-face. However,
+ don't overstrike an already-bold fontn unless the
+ desired weight grossly exceeds the available weight. */
+ if (got_weight > XLFD_WEIGHT_MEDIUM)
+ *needs_overstrike = (got_weight - want_weight) > 2;
+ else
+ *needs_overstrike = 1;
}
}
@@ -7488,7 +7487,7 @@ realize_default_face (f)
face = realize_face (c, attrs, DEFAULT_FACE_ID);
#ifdef HAVE_WINDOW_SYSTEM
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_X_WINDOWS
if (face->font != FRAME_FONT (f))
/* As the font specified for the frame was not acceptable as a
font for the default face (perhaps because auto-scaled fonts
diff --git a/src/xfns.c b/src/xfns.c
index ed6d00d0325..b4d16615fb0 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1256,7 +1256,7 @@ x_set_icon_name (f, arg, oldval)
if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
return;
}
- else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
+ else if (!NILP (arg) || NILP (oldval))
return;
f->icon_name = arg;
@@ -1612,7 +1612,7 @@ x_set_name_internal (f, name)
text.format = 8;
text.nitems = bytes;
- if (NILP (f->icon_name))
+ if (!STRINGP (f->icon_name))
{
icon = text;
}
diff --git a/src/xmenu.c b/src/xmenu.c
index 2abf0a48319..8e994ac5efb 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1301,9 +1301,119 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers)
}
}
+DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+ doc: /* Start key navigation of the menu bar in FRAME.
+This initially opens the first menu bar item and you can then navigate with the
+arrow keys, select a menu entry with the return key or cancel with the
+escape key. If FRAME has no menu bar this function does nothing.
+
+If FRAME is nil or not given, use the selected frame. */)
+ (frame)
+ Lisp_Object frame;
+{
+ XEvent ev;
+ FRAME_PTR f = check_x_frame (frame);
+ Widget menubar;
+ BLOCK_INPUT;
+
+ if (FRAME_EXTERNAL_MENU_BAR (f))
+ set_frame_menubar (f, 0, 1);
+
+ menubar = FRAME_X_OUTPUT (f)->menubar_widget;
+ if (menubar)
+ {
+ Window child;
+ int error_p = 0;
+
+ x_catch_errors (FRAME_X_DISPLAY (f));
+ memset (&ev, 0, sizeof ev);
+ ev.xbutton.display = FRAME_X_DISPLAY (f);
+ ev.xbutton.window = XtWindow (menubar);
+ ev.xbutton.root = FRAME_X_DISPLAY_INFO (f)->root_window;
+ ev.xbutton.time = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
+ ev.xbutton.button = Button1;
+ ev.xbutton.x = ev.xbutton.y = FRAME_MENUBAR_HEIGHT (f) / 2;
+ ev.xbutton.same_screen = True;
+
+#ifdef USE_MOTIF
+ {
+ Arg al[2];
+ WidgetList list;
+ Cardinal nr;
+ XtSetArg (al[0], XtNchildren, &list);
+ XtSetArg (al[1], XtNnumChildren, &nr);
+ XtGetValues (menubar, al, 2);
+ ev.xbutton.window = XtWindow (list[0]);
+ }
+#endif
+
+ XTranslateCoordinates (FRAME_X_DISPLAY (f),
+ /* From-window, to-window. */
+ ev.xbutton.window, ev.xbutton.root,
+
+ /* From-position, to-position. */
+ ev.xbutton.x, ev.xbutton.y,
+ &ev.xbutton.x_root, &ev.xbutton.y_root,
+
+ /* Child of win. */
+ &child);
+ error_p = x_had_errors_p (FRAME_X_DISPLAY (f));
+ x_uncatch_errors ();
+
+ if (! error_p)
+ {
+ ev.type = ButtonPress;
+ ev.xbutton.state = 0;
+
+ XtDispatchEvent (&ev);
+ ev.xbutton.type = ButtonRelease;
+ ev.xbutton.state = Button1Mask;
+ XtDispatchEvent (&ev);
+ }
+ }
+
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
#endif /* USE_X_TOOLKIT */
+
#ifdef USE_GTK
+DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+ doc: /* Start key navigation of the menu bar in FRAME.
+This initially opens the first menu bar item and you can then navigate with the
+arrow keys, select a menu entry with the return key or cancel with the
+escape key. If FRAME has no menu bar this function does nothing.
+
+If FRAME is nil or not given, use the selected frame. */)
+ (frame)
+ Lisp_Object frame;
+{
+ GtkWidget *menubar;
+ BLOCK_INPUT;
+ FRAME_PTR f = check_x_frame (frame);
+
+ if (FRAME_EXTERNAL_MENU_BAR (f))
+ set_frame_menubar (f, 0, 1);
+
+ menubar = FRAME_X_OUTPUT (f)->menubar_widget;
+ if (menubar)
+ {
+ /* Activate the first menu. */
+ GList *children = gtk_container_get_children (GTK_CONTAINER (menubar));
+
+ gtk_menu_shell_select_item (GTK_MENU_SHELL (menubar),
+ GTK_WIDGET (children->data));
+
+ popup_activated_flag = 1;
+ g_list_free (children);
+ }
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
+
/* Loop util popup_activated_flag is set to zero in a callback.
Used for popup menus and dialogs. */
@@ -3659,6 +3769,13 @@ The enable predicate for a menu command should check this variable. */);
#endif
defsubr (&Sx_popup_menu);
+
+#if defined (USE_GTK) || defined (USE_X_TOOLKIT)
+ defsubr (&Smenu_bar_open);
+ Fdefalias (intern ("accelerate-menu"), intern (Smenu_bar_open.symbol_name),
+ Qnil);
+#endif
+
#ifdef HAVE_MENUS
defsubr (&Sx_popup_dialog);
#endif
diff --git a/src/xterm.c b/src/xterm.c
index c25f23cc573..7407585ebf0 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -326,20 +326,8 @@ static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
static const XColor *x_color_cells P_ ((Display *, int *));
static void x_update_window_end P_ ((struct window *, int, int));
-void x_delete_display P_ ((struct x_display_info *));
static int x_io_error_quitter P_ ((Display *));
-void x_catch_errors P_ ((Display *));
-void x_uncatch_errors P_ ((void));
-void x_lower_frame P_ ((struct frame *));
-void x_scroll_bar_clear P_ ((struct frame *));
-int x_had_errors_p P_ ((Display *));
-void x_wm_set_size_hint P_ ((struct frame *, long, int));
-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 x_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
@@ -374,6 +362,7 @@ static void x_check_fullscreen P_ ((struct frame *));
static void x_check_expected_move P_ ((struct frame *));
static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
int *, struct input_event *));
+static SIGTYPE x_connection_closed P_ ((Display *, char *));
/* Flush display of frame F, or of all frames if F is null. */
@@ -2694,19 +2683,28 @@ x_draw_stretch_glyph_string (s)
{
/* If `x-stretch-block-cursor' is nil, don't draw a block cursor
as wide as the stretch glyph. */
- int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
+ int width, background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
/* Draw cursor. */
- x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
+ x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
/* Clear rest using the GC of the original non-cursor face. */
- if (width < s->background_width)
+ if (width < background_width)
{
- int x = s->x + width, y = s->y;
- int w = s->background_width - width, h = s->height;
+ int y = s->y;
+ int w = background_width - width, h = s->height;
XRectangle r;
GC gc;
+ x += width;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
@@ -2737,8 +2735,18 @@ x_draw_stretch_glyph_string (s)
}
}
else if (!s->background_filled_p)
- x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
- s->height);
+ {
+ int background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (background_width > 0)
+ x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+ }
s->background_filled_p = 1;
}
@@ -6320,6 +6328,8 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
f = x_any_window_to_frame (dpyinfo, event.xkey.window);
+ /* If mouse-highlight is an integer, input clears out
+ mouse highlighting. */
if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
&& (f == 0
|| !EQ (f->tool_bar_window, dpyinfo->mouse_face_window)))
@@ -7375,8 +7385,7 @@ x_draw_hollow_cursor (w, row)
return;
/* Compute frame-relative coordinates for phys cursor. */
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
wd = w->phys_cursor_width;
/* The foreground of cursor_gc is typically the same as the normal
diff --git a/src/xterm.h b/src/xterm.h
index 8e1e06097a8..1d1319fca31 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -962,10 +962,6 @@ void x_delete_display P_ ((struct x_display_info *));
void x_make_frame_visible P_ ((struct frame *));
void x_iconify_frame P_ ((struct frame *));
void x_wm_set_size_hint P_ ((struct frame *, long, int));
-void x_catch_errors P_ ((Display *));
-int x_had_errors_p P_ ((Display *));
-void x_uncatch_errors P_ ((void));
-void x_check_errors P_ ((Display *, char *));
int x_text_icon P_ ((struct frame *, char *));
int x_bitmap_icon P_ ((struct frame *, Lisp_Object));
void x_set_window_size P_ ((struct frame *, int, int, int));
@@ -981,7 +977,10 @@ extern int x_bitmap_icon P_ ((struct frame *, Lisp_Object));
extern void x_catch_errors P_ ((Display *));
extern void x_check_errors P_ ((Display *, char *));
extern int x_had_errors_p P_ ((Display *));
+extern int x_catching_errors P_ ((void));
extern void x_uncatch_errors P_ ((void));
+extern void x_clear_errors P_ ((Display *));
+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));
@@ -1000,6 +999,9 @@ extern void x_initialize P_ ((void));
extern unsigned long x_copy_color P_ ((struct frame *, unsigned long));
#ifdef USE_X_TOOLKIT
extern XtAppContext Xt_app_con;
+extern int x_alloc_lighter_color_for_widget __P ((Widget, Display*, Colormap,
+ unsigned long *,
+ double, int));
#endif
extern void x_query_colors P_ ((struct frame *f, XColor *, int));
extern void x_query_color P_ ((struct frame *f, XColor *));