summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog371
-rw-r--r--src/buffer.c3
-rw-r--r--src/callint.c2
-rw-r--r--src/charset.h2
-rw-r--r--src/coding.c15
-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/gtkutil.c34
-rw-r--r--src/image.c1
-rw-r--r--src/lisp.h6
-rw-r--r--src/lread.c119
-rw-r--r--src/mac.c180
-rw-r--r--src/macfns.c22
-rw-r--r--src/macgui.h7
-rw-r--r--src/macselect.c369
-rw-r--r--src/macterm.c374
-rw-r--r--src/macterm.h53
-rw-r--r--src/minibuf.c46
-rw-r--r--src/process.c84
-rw-r--r--src/search.c1
-rw-r--r--src/sound.c48
-rw-r--r--src/sysdep.c2
-rw-r--r--src/w32fns.c2
-rw-r--r--src/w32heap.c4
-rw-r--r--src/w32term.c240
-rw-r--r--src/window.c13
-rw-r--r--src/xdisp.c82
-rw-r--r--src/xfns.c4
-rw-r--r--src/xmenu.c117
-rw-r--r--src/xterm.c37
33 files changed, 1910 insertions, 405 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c2fdb389729..5154dc5012e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,355 @@
+2006-06-03 Aidan Kehoe <kehoea@parhasard.net>
+
+ * lread.c (read_escape): Provide a Unicode character escape
+ syntax; \u followed by exactly four or \U followed by exactly
+ eight hex digits in a comment or string is read as a Unicode
+ character with that code point.
+
+2006-06-09 Eli Zaretskii <eliz@gnu.org>
+
+ * window.c (window_scroll_pixel_based): Signal "Beginning of
+ buffer" when scroll-down at the beginning of an empty buffer.
+
+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.
@@ -13,11 +365,14 @@
* 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_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>
@@ -90,7 +445,7 @@
* 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>
@@ -585,7 +940,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'.
@@ -706,7 +1061,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.
@@ -8577,7 +8932,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.
@@ -9521,7 +9876,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.
@@ -9858,7 +10213,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.
@@ -10171,7 +10526,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.
diff --git a/src/buffer.c b/src/buffer.c
index 3dff44a6b86..73db9d21419 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5470,10 +5470,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. */);
diff --git a/src/callint.c b/src/callint.c
index c54b03394c0..2411617917f 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/charset.h b/src/charset.h
index 0d61aa054c0..b7ab4cb8b53 100644
--- a/src/charset.h
+++ b/src/charset.h
@@ -825,7 +825,7 @@ while (0)
/* This is the maximum byte length of multi-byte sequence. */
#define MAX_MULTIBYTE_LENGTH 4
-extern void invalid_character P_ ((int));
+extern void invalid_character P_ ((int)) NO_RETURN;
extern int translate_char P_ ((Lisp_Object, int, int, int, int));
extern int split_string P_ ((const unsigned char *, int, int *,
diff --git a/src/coding.c b/src/coding.c
index 659b52b93fb..e35cb5ddc09 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -7465,7 +7465,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
@@ -7477,6 +7477,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;
@@ -7503,8 +7510,12 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS ...) */)
target_idx = make_number (4);
target = args[XINT (target_idx) + 1];
if (!(STRINGP (target)
+ || (EQ (operation, Qinsert_file_contents) && CONSP (target)
+ && STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))
|| (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
error ("Invalid argument %d", XINT (target_idx) + 1);
+ if (CONSP (target))
+ target = XCAR (target);
chain = ((EQ (operation, Qinsert_file_contents)
|| EQ (operation, Qwrite_region))
@@ -7537,7 +7548,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/dispextern.h b/src/dispextern.h
index c836bc751d0..ed91d2df76e 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2623,8 +2623,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 *,
@@ -2682,8 +2682,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 a3ac89e05d5..c346e94a103 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -342,8 +342,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
@@ -6437,7 +6436,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)
@@ -6467,6 +6468,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 ac6bf57c2cd..530f008270c 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1753,16 +1753,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 ();
@@ -2235,7 +2240,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");
@@ -2247,7 +2252,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 842ca8f6b61..b2940d46e9e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2406,32 +2406,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;
@@ -2448,9 +2447,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
@@ -2553,12 +2549,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 */
@@ -2803,7 +2799,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 f06f39fae04..2fea9af40cd 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3433,7 +3433,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/gtkutil.c b/src/gtkutil.c
index ec886b52faf..f4a2b4d3f52 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 b8a640a9391..490ede60e35 100644
--- a/src/image.c
+++ b/src/image.c
@@ -6106,7 +6106,6 @@ png_load (f, img)
{
image_error ("Cannot open image file `%s'", file, Qnil);
UNGCPRO;
- fclose (fp);
return 0;
}
diff --git a/src/lisp.h b/src/lisp.h
index 0df41a0d1f4..1a9e11b54dd 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
@@ -2780,7 +2780,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);
@@ -2899,7 +2899,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 8d0d6b098c0..797ae1078fb 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 */
extern Lisp_Object Qevent_symbol_element_mask;
extern Lisp_Object Qfile_exists_p;
@@ -720,8 +721,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. */
@@ -729,6 +730,7 @@ Return t if the file exists and loads successfully. */)
Lisp_Object handler;
int safe_p = 1;
char *fmode = "r";
+ Lisp_Object tmp[2];
#ifdef DOS_NT
fmode = "rt";
#endif /* DOS_NT */
@@ -745,7 +747,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. */
@@ -765,7 +767,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);
@@ -849,6 +850,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) ;
+
if (!bcmp (SDATA (found) + SBYTES (found) - 4,
".elc", 4))
/* Load .elc files directly, but not when they are
@@ -859,7 +867,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 (!safe_to_load_p (fd))
{
@@ -913,14 +921,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);
@@ -959,14 +967,15 @@ Return t if the file exists and loads successfully. */)
load_descriptor_list
= Fcons (make_number (fileno (stream)), load_descriptor_list);
load_in_progress++;
- readevalloop (Qget_file_char, stream, (! NILP (Vpurify_flag) ? file : found),
+ readevalloop (Qget_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)
@@ -1393,6 +1402,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;
@@ -1751,6 +1766,9 @@ read_escape (readcharfun, stringp, byterep)
int *byterep;
{
register int c = READCHAR;
+ /* \u allows up to four hex digits, \U up to eight. Default to the
+ behaviour for \u, and change this value in the case that \U is seen. */
+ int unicode_hex_count = 4;
*byterep = 0;
@@ -1915,6 +1933,52 @@ read_escape (readcharfun, stringp, byterep)
return i;
}
+ case 'U':
+ /* Post-Unicode-2.0: Up to eight hex chars. */
+ unicode_hex_count = 8;
+ case 'u':
+
+ /* A Unicode escape. We only permit them in strings and characters,
+ not arbitrarily in the source code, as in some other languages. */
+ {
+ int i = 0;
+ int count = 0;
+ Lisp_Object lisp_char;
+ struct gcpro gcpro1;
+
+ while (++count <= unicode_hex_count)
+ {
+ c = READCHAR;
+ /* isdigit(), isalpha() may be locale-specific, which we don't
+ want. */
+ if (c >= '0' && c <= '9') i = (i << 4) + (c - '0');
+ else if (c >= 'a' && c <= 'f') i = (i << 4) + (c - 'a') + 10;
+ else if (c >= 'A' && c <= 'F') i = (i << 4) + (c - 'A') + 10;
+ else
+ {
+ error ("Non-hex digit used for Unicode escape");
+ break;
+ }
+ }
+
+ GCPRO1 (readcharfun);
+ lisp_char = call2(intern("decode-char"), intern("ucs"),
+ make_number(i));
+ UNGCPRO;
+
+ if (EQ(Qnil, lisp_char))
+ {
+ /* This is ugly and horrible and trashes the user's data. */
+ XSETFASTINT (i, MAKE_CHAR (charset_katakana_jisx0201,
+ 34 + 128, 46 + 128));
+ return i;
+ }
+ else
+ {
+ return XFASTINT (lisp_char);
+ }
+ }
+
default:
if (BASE_LEADING_CODE_P (c))
c = read_multibyte (c, readcharfun);
@@ -3973,16 +4037,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.
-
-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. */);
+Each element looks like (REGEXP-OR-FEATURE FORMS...).
+
+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,
@@ -3990,6 +4055,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)'.
@@ -4120,6 +4189,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 577167e6fe3..4345cef2611 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;
@@ -3024,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
{
@@ -4514,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 f7005600d43..a93131e565e 100644
--- a/src/macgui.h
+++ b/src/macgui.h
@@ -110,6 +110,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;
+ }
+ 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);
}
- return errAEEventNotHandled;
+ *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)
{
- AEResumeTheCurrentEvent (deferred_apple_events.buf + i,
- deferred_apple_events.buf + i + 1,
+ next = tail->next;
+ tail->next = prev;
+ prev = tail;
+ }
+
+ /* Now `prev' points to the first cell. */
+ for (tail = prev; tail; tail = next)
+ {
+ 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 e793e5d04f0..b0765069277 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -3529,19 +3529,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))
{
@@ -3568,8 +3577,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;
}
@@ -5396,8 +5415,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
@@ -6116,6 +6134,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)))
@@ -6129,6 +6148,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);
}
@@ -8320,6 +8340,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;
@@ -8329,6 +8369,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));
@@ -8463,6 +8506,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;
@@ -8814,13 +8864,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
}
@@ -9080,6 +9134,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 ();
}
}
}
@@ -9269,6 +9326,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;
@@ -9395,6 +9464,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)
@@ -9456,6 +9702,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;
@@ -9465,6 +9715,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);
@@ -9474,6 +9731,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);
@@ -9487,6 +9749,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);
@@ -9612,7 +9880,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*/,
@@ -9632,8 +9900,9 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
#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. */
+ 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,
@@ -9654,14 +9923,14 @@ static unsigned char fn_keycode_to_keycode_table[] = {
/*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, 0x7b /*home -> left*/,
- /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0, 0x7c /*end -> right*/,
- /*0x78*/ 0, 0x7d /*pgdown -> down*/, 0, 0,
+ /*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
};
#endif /* MAC_OSX */
@@ -9825,10 +10094,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;
@@ -10311,19 +10576,27 @@ XTread_socket (sd, expected, hold_quit)
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
events to the TSM ourselves. If TSM handles it, it
will pass back noErr, otherwise it will pass back
"eventNotHandledErr" and we can process it
normally. */
- if (!(modifiers
- & mapped_modifiers
+ if (!(mapped_modifiers
& ~(mac_pass_command_to_system ? cmdKey : 0)
& ~(mac_pass_control_to_system ? controlKey : 0)))
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
+ {
+ OSStatus err;
+
+ read_socket_inev = &inev;
+ err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+ read_socket_inev = NULL;
+ if (err != eventNotHandledErr)
break;
+ }
#endif
if (er.what == keyUp)
break;
@@ -10354,8 +10627,13 @@ XTread_socket (sd, expected, hold_quit)
last_key_script = current_key_script;
}
+#if USE_MAC_TSM
+ if (inev.kind != NO_EVENT)
+ break;
+#endif
+
#ifdef MAC_OSX
- if (modifiers & kEventKeyModifierFnMask
+ if (mapped_modifiers & kEventKeyModifierFnMask
&& keycode <= 0x7f
&& fn_keycode_to_keycode_table[keycode])
keycode = fn_keycode_to_keycode_table[keycode];
@@ -10364,8 +10642,14 @@ XTread_socket (sd, expected, hold_quit)
{
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 (modifiers & mapped_modifiers)
+ else if (mapped_modifiers)
{
/* translate the keycode back to determine the
original key */
@@ -10444,11 +10728,7 @@ XTread_socket (sd, expected, hold_quit)
inev.code = er.message & charCodeMask;
}
-#if USE_CARBON_EVENTS
- inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
- inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
-#endif
+ inev.modifiers = mac_to_emacs_modifiers (modifiers);
inev.modifiers |= (extra_keyboard_modifiers
& (meta_modifier | alt_modifier
| hyper_modifier | super_modifier));
@@ -10960,6 +11240,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. */
@@ -11055,6 +11345,10 @@ mac_initialize ()
init_command_handler ();
init_menu_bar ();
+
+#if USE_MAC_TSM
+ init_tsm ();
+#endif
#endif /* USE_CARBON_EVENTS */
#ifdef MAC_OSX
@@ -11111,6 +11405,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
@@ -11253,6 +11554,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 abdce7a799e..fd71e36d28d 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -536,6 +536,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;
@@ -581,6 +628,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));
@@ -593,8 +642,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 *));
@@ -612,6 +659,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 */
@@ -622,6 +670,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 dc920287304..9a1a3636e97 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -67,6 +67,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;
@@ -220,7 +224,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,
@@ -441,8 +445,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;
@@ -453,7 +456,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 ();
@@ -753,7 +755,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;
@@ -761,7 +763,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,
@@ -780,8 +783,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;
@@ -943,7 +945,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
@@ -967,8 +969,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.
@@ -984,9 +984,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;
@@ -1017,8 +1017,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;
}
@@ -1035,7 +1034,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,
@@ -1073,7 +1072,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;
@@ -1095,7 +1094,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,
@@ -1784,7 +1783,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;
@@ -2812,9 +2811,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 de4dbd4a3ff..965b33c52c3 100644
--- a/src/process.c
+++ b/src/process.c
@@ -778,6 +778,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
@@ -799,12 +809,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;
@@ -4140,6 +4169,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.
@@ -6321,6 +6369,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;
@@ -6378,6 +6427,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))
{
@@ -6429,8 +6487,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;
@@ -6447,6 +6505,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.
@@ -6463,6 +6524,7 @@ sigchld_handler (signo)
#endif /* USG, but not HPUX with WNOHANG */
}
}
+#endif /* SIGCHLD */
static Lisp_Object
@@ -6845,6 +6907,9 @@ init_process ()
#endif
Vprocess_alist = Qnil;
+#ifdef SIGCHLD
+ deleted_pid_list = Qnil;
+#endif
for (i = 0; i < MAXDESC; i++)
{
chan_process[i] = Qnil;
@@ -6983,6 +7048,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/search.c b/src/search.c
index dfbf66fc7ed..99db7f184fc 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 2ceefd3bce3..af2369040cc 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -113,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 *));
@@ -971,7 +972,8 @@ alsa_open (sd)
sd->data = p;
- if ((err = snd_pcm_open (&p->handle, file, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
+ err = snd_pcm_open (&p->handle, file, SND_PCM_STREAM_PLAYBACK, 0);
+ if (err < 0)
alsa_sound_perror (file, err);
}
@@ -993,32 +995,42 @@ alsa_configure (sd)
xassert (p->handle != 0);
- if ((err = snd_pcm_hw_params_malloc (&p->hwparams)) < 0)
+ err = snd_pcm_hw_params_malloc (&p->hwparams);
+ if (err < 0)
alsa_sound_perror ("Could not allocate hardware parameter structure", err);
- if ((err = snd_pcm_sw_params_malloc (&p->swparams)) < 0)
+ err = snd_pcm_sw_params_malloc (&p->swparams);
+ if (err < 0)
alsa_sound_perror ("Could not allocate software parameter structure", err);
- if ((err = snd_pcm_hw_params_any (p->handle, p->hwparams)) < 0)
+ err = snd_pcm_hw_params_any (p->handle, p->hwparams);
+ if (err < 0)
alsa_sound_perror ("Could not initialize hardware parameter structure", err);
- if ((err = snd_pcm_hw_params_set_access (p->handle, p->hwparams,
- SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
+ 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;
- if ((err = snd_pcm_hw_params_set_format (p->handle, p->hwparams, val)) < 0)
+ 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;
- if ((err = snd_pcm_hw_params_set_rate_near (p->handle, p->hwparams, &val, 0))
- < 0)
+ 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;
- if ((err = snd_pcm_hw_params_set_channels (p->handle, p->hwparams, val)) < 0)
+ 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)
@@ -1028,9 +1040,6 @@ alsa_configure (sd)
if (err < 0)
alsa_sound_perror("Unable to get buffer size for playback", err);
- if ((err = snd_pcm_hw_params (p->handle, p->hwparams)) < 0)
- alsa_sound_perror ("Could not set parameters", err);
-
err = snd_pcm_sw_params_current (p->handle, p->swparams);
if (err < 0)
alsa_sound_perror ("Unable to determine current swparams for playback",
@@ -1063,7 +1072,8 @@ alsa_configure (sd)
snd_pcm_sw_params_free (p->swparams);
p->swparams = NULL;
- if ((err = snd_pcm_prepare (p->handle)) < 0)
+ err = snd_pcm_prepare (p->handle);
+ if (err < 0)
alsa_sound_perror ("Could not prepare audio interface for use", err);
if (sd->volume > 0)
@@ -1194,11 +1204,11 @@ alsa_write (sd, buffer, nbytes)
while (nwritten < nbytes)
{
- if ((err = snd_pcm_writei (p->handle,
- buffer + nwritten,
- (nbytes - nwritten)/fact)) < 0)
+ err = snd_pcm_writei (p->handle,
+ buffer + nwritten,
+ (nbytes - nwritten)/fact);
+ if (err < 0)
{
- fprintf(stderr, "Err %d/%s\n", err, snd_strerror(err));
if (err == -EPIPE)
{ /* under-run */
err = snd_pcm_prepare (p->handle);
diff --git a/src/sysdep.c b/src/sysdep.c
index 6e09748bca9..6d630c4832f 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -242,7 +242,7 @@ static int baud_convert[] =
int emacs_ospeed;
-void croak P_ ((char *));
+void croak P_ ((char *)) NO_RETURN;
#ifdef AIXHFT
void hft_init P_ ((struct tty_display_info *));
diff --git a/src/w32fns.c b/src/w32fns.c
index 609a88debbd..25aa22f0683 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1683,7 +1683,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 05fd303f4d1..f85a5334022 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -146,32 +146,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;
@@ -2389,20 +2363,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))
{
@@ -2431,8 +2414,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;
}
@@ -3468,6 +3461,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)
{
@@ -3492,24 +3486,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;
}
@@ -3598,6 +3585,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));
@@ -3616,26 +3604,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);
@@ -3744,6 +3721,8 @@ w32_set_vertical_scroll_bar (w, portion, whole, position)
else
{
HDC hdc;
+ SCROLLINFO si;
+
BLOCK_INPUT;
if (width && height)
{
@@ -3763,21 +3742,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); */
@@ -3929,19 +3902,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;
@@ -3978,21 +3945,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
@@ -4000,20 +3964,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);
-
- 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);
+ 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;
+ SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
}
/* fall through */
default:
@@ -4044,25 +4003,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))
{
@@ -4931,7 +4884,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);
@@ -4942,8 +4895,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;
@@ -6390,26 +6344,14 @@ w32_initialize ()
AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
#endif
- /* Dynamically link to optional system components. */
+ /* Load system settings. */
{
- HANDLE user_lib = LoadLibrary ("user32.dll");
UINT smoothing_type;
BOOL smoothing_enabled;
-#define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
-
- /* New proportional scroll bar functions. */
- LOAD_PROC (SetScrollInfo);
- LOAD_PROC (GetScrollInfo);
-
-#undef LOAD_PROC
-
- FreeLibrary (user_lib);
-
/* If using proportional scroll bars, ensure handle is at least 5 pixels;
otherwise use the fixed height. */
- vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
- GetSystemMetrics (SM_CYVTHUMB);
+ vertical_scroll_bar_min_handle = 5;
/* For either kind of scroll bar, take account of the arrows; these
effectively form the border of the main scroll bar range. */
diff --git a/src/window.c b/src/window.c
index 5dced198811..e7f2ed93fd3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3780,7 +3780,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;
@@ -4895,6 +4897,8 @@ window_scroll_pixel_based (window, n, whole, noerror)
}
else if (noerror)
return;
+ else if (n < 0) /* could happen with empty buffers */
+ Fsignal (Qbeginning_of_buffer, Qnil);
else
Fsignal (Qend_of_buffer, Qnil);
}
@@ -5796,6 +5800,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) \
@@ -5806,9 +5811,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,
@@ -6030,6 +6033,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);
@@ -6299,6 +6303,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.
diff --git a/src/xdisp.c b/src/xdisp.c
index 32255f92da7..f87f38dc50e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1973,15 +1973,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
@@ -1991,6 +1991,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);
@@ -2020,8 +2028,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);
}
/*
@@ -6215,6 +6224,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;
}
@@ -11617,9 +11628,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;
@@ -11769,6 +11782,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];
@@ -11802,6 +11820,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
else
CHARPOS (this_line_start_pos) = 0;
}
+
+ return 1;
}
@@ -12485,8 +12505,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));
}
}
}
@@ -14944,6 +14974,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);
+ }
}
@@ -21333,7 +21382,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;
@@ -21341,12 +21390,17 @@ 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));
- FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
+ if (width > 0)
+ FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
}
/* Erase the cursor by redrawing the character underneath it. */
diff --git a/src/xfns.c b/src/xfns.c
index acbf22b600c..11552a5a9f7 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1260,7 +1260,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;
@@ -1635,7 +1635,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 794a6f22898..48320479ad8 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1310,9 +1310,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. */
@@ -3704,6 +3814,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 cc06c48df33..2bfb8a15bb8 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -362,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. */
@@ -2543,19 +2544,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))
{
@@ -2586,8 +2596,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;
}
@@ -7172,8 +7192,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