summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2013-06-03 12:25:05 -0600
committerTom Tromey <tromey@redhat.com>2013-06-03 12:25:05 -0600
commit68359abba96d7ec4db8aab3d3dd9cf1105c3bab5 (patch)
tree862703e7e1a1888170136a8296a5750d6b2ae2eb /src
parentcbcba8ce7f980b01c18c0fd561ef6687b1361507 (diff)
parente2d8a6f0a229b4ebe26484b892ec4f14888f58b6 (diff)
downloademacs-68359abba96d7ec4db8aab3d3dd9cf1105c3bab5.tar.gz
merge from trunk; clean up some issues
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit21
-rw-r--r--src/ChangeLog1342
-rw-r--r--src/ChangeLog.102
-rw-r--r--src/ChangeLog.112
-rw-r--r--src/Makefile.in75
-rw-r--r--src/alloc.c129
-rw-r--r--src/blockinput.h2
-rw-r--r--src/buffer.c55
-rw-r--r--src/bytecode.c7
-rw-r--r--src/callint.c38
-rw-r--r--src/callproc.c16
-rw-r--r--src/casetab.c14
-rw-r--r--src/ccl.c2
-rw-r--r--src/cm.c4
-rw-r--r--src/coding.c409
-rw-r--r--src/coding.h2
-rw-r--r--src/data.c62
-rw-r--r--src/dbusbind.c2
-rw-r--r--src/dired.c14
-rw-r--r--src/dispextern.h50
-rw-r--r--src/dispnew.c155
-rw-r--r--src/doc.c26
-rw-r--r--src/editfns.c17
-rw-r--r--src/emacs.c15
-rw-r--r--src/emacsgtkfixed.c2
-rw-r--r--src/eval.c494
-rw-r--r--src/fileio.c117
-rw-r--r--src/filelock.c10
-rw-r--r--src/floatfns.c4
-rw-r--r--src/fns.c7
-rw-r--r--src/font.c44
-rw-r--r--src/fontset.c9
-rw-r--r--src/fontset.h3
-rw-r--r--src/frame.c199
-rw-r--r--src/frame.h92
-rw-r--r--src/fringe.c12
-rw-r--r--src/ftfont.c6
-rw-r--r--src/gfilenotify.c266
-rw-r--r--src/gtkutil.c13
-rw-r--r--src/image.c86
-rw-r--r--src/indent.c35
-rw-r--r--src/insdel.c26
-rw-r--r--src/intervals.c54
-rw-r--r--src/keyboard.c412
-rw-r--r--src/keymap.c9
-rw-r--r--src/lisp.h305
-rw-r--r--src/lread.c42
-rw-r--r--src/makefile.w32-in8
-rw-r--r--src/menu.c5
-rw-r--r--src/minibuf.c46
-rw-r--r--src/msdos.c13
-rw-r--r--src/nsfns.m762
-rw-r--r--src/nsfont.m49
-rw-r--r--src/nsimage.m4
-rw-r--r--src/nsmenu.m133
-rw-r--r--src/nsselect.m18
-rw-r--r--src/nsterm.h46
-rw-r--r--src/nsterm.m346
-rw-r--r--src/print.c94
-rw-r--r--src/process.c502
-rw-r--r--src/process.h1
-rw-r--r--src/profiler.c21
-rw-r--r--src/puresize.h4
-rw-r--r--src/regex.c398
-rw-r--r--src/regex.h2
-rw-r--r--src/search.c22
-rw-r--r--src/sysdep.c6
-rw-r--r--src/systime.h4
-rw-r--r--src/term.c2
-rw-r--r--src/termhooks.h2
-rw-r--r--src/textprop.c3
-rw-r--r--src/thread.c12
-rw-r--r--src/thread.h3
-rw-r--r--src/undo.c6
-rw-r--r--src/unexcw.c17
-rw-r--r--src/unexelf.c204
-rw-r--r--src/unexw32.c8
-rw-r--r--src/w32.c92
-rw-r--r--src/w32fns.c166
-rw-r--r--src/w32font.c4
-rw-r--r--src/w32menu.c6
-rw-r--r--src/w32term.c104
-rw-r--r--src/w32term.h14
-rw-r--r--src/window.c739
-rw-r--r--src/window.h128
-rw-r--r--src/xdisp.c451
-rw-r--r--src/xfaces.c47
-rw-r--r--src/xfns.c653
-rw-r--r--src/xgselect.c3
-rw-r--r--src/xmenu.c15
-rw-r--r--src/xselect.c14
-rw-r--r--src/xsettings.c9
-rw-r--r--src/xterm.c21
-rw-r--r--src/xterm.h27
94 files changed, 6483 insertions, 3459 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index c4604e6e2b0..1bfc293c466 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -1150,17 +1150,18 @@ Print $ assuming it is a list font (font-spec, font-entity, or font-object).
end
define xbacktrace
- set $bt = backtrace_list
- while $bt
- xgettype ($bt->function)
+ set $bt = backtrace_top ()
+ while backtrace_p ($bt)
+ set $fun = backtrace_function ($bt)
+ xgettype $fun
if $type == Lisp_Symbol
- xprintsym ($bt->function)
- printf " (0x%x)\n", $bt->args
+ xprintsym $fun
+ printf " (0x%x)\n", backtrace_args ($bt)
else
- xgetptr $bt->function
+ xgetptr $fun
printf "0x%x ", $ptr
if $type == Lisp_Vectorlike
- xgetptr ($bt->function)
+ xgetptr $fun
set $size = ((struct Lisp_Vector *) $ptr)->header.size
if ($size & PSEUDOVECTOR_FLAG)
output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
@@ -1172,7 +1173,7 @@ define xbacktrace
end
echo \n
end
- set $bt = $bt->next
+ set $bt = backtrace_next ($bt)
end
end
document xbacktrace
@@ -1220,8 +1221,8 @@ end
# Show Lisp backtrace after normal backtrace.
define hookpost-backtrace
- set $bt = backtrace_list
- if $bt
+ set $bt = backtrace_top ()
+ if backtrace_p ($bt)
echo \n
echo Lisp Backtrace:\n
xbacktrace
diff --git a/src/ChangeLog b/src/ChangeLog
index 3a2a36c0cf7..a1aa4efcc86 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,1319 @@
+2013-06-03 Eli Zaretskii <eliz@gnu.org>
+
+ * w32.c (gettimeofday): Make the signature identical to prototype
+ in nt/inc/sys/time.h.
+
+2013-06-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * eval.c (backtrace_p, backtrace_top, backtrace_next): Export them to
+ .gdbinit.
+
+ * keyboard.c (safe_run_hooks_error): Improve error message.
+
+ * data.c (pure_write_error): Add `object' argument.
+ * puresize.h (CHECK_IMPURE): Use it.
+
+2013-06-03 Michael Albinus <michael.albinus@gmx.de>
+
+ * Makefile.in (NOTIFY_OBJ): New variable.
+ (base_obj): Replace inotify.o by $(NOTIFY_OBJ).
+
+ * emacs.c (main): Use HAVE_W32NOTIFY to wrap respective code.
+ Call syms_of_gfilenotify.
+
+ * gfilenotify.c: New file.
+
+ * keyboard.c (Qfile_notify): New variable. Replaces Qfile_inotify
+ and Qfile_w32notify.
+ (top): Wrap respective code by HAVE_GFILENOTIFY, HAVE_INOTIFY,
+ HAVE_W32NOTIFY and USE_FILE_NOTIFY.
+
+ * lisp.h: Declare syms_of_gfilenotify.
+
+ * termhooks.h (e): Wrap enum by USE_FILE_NOTIFY.
+
+2013-06-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ Merge the specpdl and backtrace stacks. Make the structure of the
+ specpdl entries more obvious via a tagged union of structs.
+ * lisp.h (BITS_PER_PTRDIFF_T): New constant.
+ (enum specbind_tag): New enum.
+ (struct specbinding): Make it a tagged union of structs.
+ Add a case for backtrace records.
+ (specpdl_symbol, specpdl_old_value, specpdl_where, specpdl_arg)
+ (specpdl_func, backtrace_function, backtrace_nargs, backtrace_args)
+ (backtrace_debug_on_exit): New accessors.
+ (struct backtrace): Remove.
+ (struct catchtag): Remove backlist field.
+ * data.c (let_shadows_buffer_binding_p, let_shadows_global_binding_p):
+ Move to eval.c.
+ (Flocal_variable_p): Speed up the common case where the binding is
+ already loaded.
+ * eval.c (backtrace_list): Remove.
+ (set_specpdl_symbol, set_specpdl_old_value): Remove.
+ (set_backtrace_args, set_backtrace_nargs)
+ (set_backtrace_debug_on_exit, backtrace_p, backtrace_top)
+ (backtrace_next): New functions.
+ (Fdefvaralias, Fdefvar): Adjust to new specpdl format.
+ (unwind_to_catch, internal_lisp_condition_case)
+ (internal_condition_case, internal_condition_case_1)
+ (internal_condition_case_2, internal_condition_case_n): Don't bother
+ with backtrace_list any more.
+ (Fsignal): Adjust to new backtrace format.
+ (grow_specpdl): Move up.
+ (record_in_backtrace): New function.
+ (eval_sub, Ffuncall): Use it.
+ (apply_lambda): Adjust to new backtrace format.
+ (let_shadows_buffer_binding_p, let_shadows_global_binding_p): Move from
+ data.c.
+ (specbind): Adjust to new specpdl format. Simplify.
+ (record_unwind_protect, unbind_to): Adjust to new specpdl format.
+ (Fbacktrace_debug, Fbacktrace, Fbacktrace_frame): Adjust to new
+ backtrace format.
+ (mark_backtrace): Remove.
+ (mark_specpdl, get_backtrace, backtrace_top_function): New functions.
+ * xdisp.c (redisplay_internal): Use record_in_backtrace.
+ * alloc.c (Fgarbage_collect): Use record_in_backtrace.
+ Use mark_specpdl.
+ * profiler.c (record_backtrace): Use get_backtrace.
+ (handle_profiler_signal): Use backtrace_top_function.
+ * .gdbinit (xbacktrace, hookpost-backtrace): Use new backtrace
+ accessor functions.
+
+2013-06-02 Jan Djärv <jan.h.d@swipnet.se>
+
+ * process.h (catch_child_signal): Declare.
+
+ * process.c (catch_child_signal): New function.
+ (init_process_emacs): Call it.
+
+ * nsterm.m: Include process.h if NS_IMPL_GNUSTEP.
+ (ns_menu_bar_is_hidden, menu_will_open_state): Define only if
+ NS_IMPL_COCOA.
+ (x_set_cursor_type): Remove declaration.
+ (ns_update_begin): Only use r and bp if NS_IMPL_COCOA.
+ (ns_update_end, ns_focus, ns_unfocus): Remove GNUStep specific code.
+ (x_set_window_size): Remove 3 pixels from toolbar if NS_IMPL_GNUSTEP.
+ (ns_get_color): Use F suffix on float.
+ (ns_color_to_lisp, ns_query_color): Use EmacsCGFloat.
+ (ns_get_rgb_color): Remove.
+ (x_set_frame_alpha): Move view inside NS_IMPL_COCOA.
+ (note_mouse_movement): x and y are CGFloat.
+ (ns_draw_fringe_bitmap): Remove unused rowY.
+ Change #if to COCOA && >= 10_6.
+ (ns_draw_window_cursor): Remove unused overspill.
+ (ns_draw_underwave): width and x are EamcsCGFloat.
+ (ns_draw_box): thickness is CGFloat.
+ (ns_dumpglyphs_image): Change #if to COCOA && >= 10_6.
+ (ns_send_appdefined): When NS_IMPL_GNUSTEP, redirect to main thread
+ if not in main thread.
+ (ns_get_pending_menu_title, ns_check_menu_open)
+ (ns_check_pending_open_menu): Put inside #if COCOA && >= 10_5.
+ (ns_term_init): Call catch_child_signal if NS_IMPL_GNUSTEP && SIGCHLD.
+ (sendFromMainThread:): New method.
+ (changeFont:): size is CGFloat.
+ (keyDown:): Check for Delete when NS_IMPL_GNUSTEP.
+ Disable warning about permanent text.
+ (characterIndexForPoint:): Adjust return type depending on GNUStep
+ version.
+ (mouseDown:): delta is CGFloat.
+ (updateFrameSize): Remove unised variable f.
+ (initFrameFromEmacs): Move toggleButton inside NS_IMPL_COCOA.
+ Cast float to EmacsCGFloat.
+ (windowWillUseStandardFrame:defaultFrame:): Set maximized_height
+ also to -1 when restoring.
+ (windowDidExitFullScreen:): Put call to updateCollectionBehaviour
+ inside NS_IMPL_COCOA.
+ (toggleFullScreen:): Put call to toggleFullScreen inside
+ NS_IMPL_COCOA. Cast float to EmacsCGFloat.
+ (setPosition:portion:whole:): por is CGFloat.
+ (getMouseMotionPart:window:x:y:): Add F suffix to float.
+ (mouseDown:): Use CGFloat.
+ (mouseDragged:): Remove unised variable edge.
+ (EmacsDocument): Implement for NS_IMPL_GNUSTEP.
+
+ * nsterm.h (EmacsCGFloat): Typedef for OSX and GNUStep when the size
+ of CGFloat differs.
+ (EmacsApp): New variable nextappdefined. Declare sendFromMainThread
+ when NS_IMPL_GNUSTEP.
+ (EmacsDocument): Declare when NS_IMPL_GNUSTEP.
+ (EmacsView): Remove unlockFocusNeedsFlush, add windowDidMove.
+ (EmacsToolbar): Add clearAll. Add tag argument to
+ addDisplayItemWithImage.
+ (EmacsSavePanel, EmacsOpenPanel): Remove getFilename and getDirectory.
+
+ * nsselect.m (ns_get_local_selection): Remove unused variable type.
+
+ * nsmenu.m (ns_update_menubar): Make static.
+ (x_activate_menubar): Surround with ifdef NS_IMPL_COCOA
+ (fillWithWidgetValue:): Add cast to SEL for setAction.
+ (addSubmenuWithTitle:forFrame:): Add cast to SEL for action.
+ (update_frame_tool_bar): Update code for GNUStep.
+ (clearAll): New method.
+ (addDisplayItemWithImage:idx:tag:helpText:enabled:): Handle new tag
+ argument. Call insertItemWithItemIdentifier when NS_IMPL_GNUSTEP. Move
+ identifierToItem setObject and activeIdentifiers addObject before
+ call to insertItemWithItemIdentifier.
+ (validateVisibleItems): Fix indentation.
+ (toolbarAllowedItemIdentifiers:): Return activeIdentifiers.
+ (initWithContentRect:styleMask:backing:defer:): Add ClosableWindow and
+ UtilityWindow to aStyle, remove call to setStyleMask.
+
+ * nsimage.m (setXBMColor:, getPixelAtX:Y:): Use EmacsCGFloat.
+
+ * nsfont.m (ns_attribute_fvalue, ns_spec_to_descriptor)
+ (ns_charset_covers, ns_get_covering_families, nsfont_open):
+ Use F suffix on floats.
+ (ns_char_width): Returns CGFloat.
+ (ns_ascii_average_width): w is CGFloat instead of float.
+ (nsfont_draw): cbuf and c are unsigned. Cast to char* in call to
+ DPSxshow.
+ (ns_glyph_metrics): CGFloat instead of float.
+
+ * nsfns.m (x_set_foreground_color, x_set_background_color): Use
+ EmacsCGFloat.
+ (ns_implicitly_set_icon_type, Fx_create_frame): Make static, remove
+ unused variables.
+ (Fns_read_file_name): Keep track if panel is for save. Use
+ ns_filename_from_panel/ns_directory_from_panel.
+ (Fns_list_services): delegate only used for COCOA.
+ (Fns_convert_utf8_nfd_to_nfc): Remove warning for GNUStep. Just
+ return the input if GNUStep.
+ (x_screen_planes): Remove.
+ (Fxw_color_values): Use EmacsCGFloat
+ (Fns_display_monitor_attributes_list): Only get screen number for
+ Cocoa.
+ (getDirectory, getFilename): Removed from EmacsOpenPanel and
+ EmacsSavePanel.
+ (EmacsOpenPanel:ok:): Use ns_filename_from_panel and
+ ns_directory_from_panel.
+
+2013-06-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ * process.c (handle_child_signal): Also use WCONTINUED.
+ This is so that list-processes doesn't mistakenly list the process
+ as stopped, when the process has actually been continued and is
+ now running.
+
+2013-05-31 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don't let D-bus autolaunch mess up SIGCHLD handling (Bug#14474).
+ * xterm.c (x_term_init): Inhibit D-Bus autolaunch if D-Bus is
+ not already configured.
+
+ * fileio.c (Finsert_file_contents): Remove unused local (Bug#8447).
+
+2013-05-29 Eli Zaretskii <eliz@gnu.org>
+
+ * Makefile.in (mostlyclean): Remove *.res files.
+
+2013-05-29 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * fileio.c (Finsert_file_contents): Preserve undo info when reverting
+ a buffer (bug#8447).
+
+2013-05-27 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (pos_visible_p): When CHARPOS is displayed frrom a
+ display vector, and we backtrack, handle the case that the
+ previous character position is also displayed from a display
+ vector or covered by a display string or image. (Bug#14476)
+
+2013-05-25 Jan Djärv <jan.h.d@swipnet.se>
+
+ * xfns.c (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Remove.
+ (struct MonitorInfo, free_monitors): Remove.
+ (x_make_monitor_attribute_list): Call make_monitor_attribute_list.
+ (Fx_display_monitor_attributes_list): Call make_monitor_attribute_list.
+ (syms_of_xfns): Remove DEFSYM for Qgeometry, Qworkarea, Qmm_size,
+ Qframes, Qsource.
+
+ * nsfns.m (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Remove.
+ (struct MonitorInfo, free_monitors): Remove.
+ (ns_screen_name): Make static.
+ (ns_make_monitor_attribute_list): Call make_monitor_attribute_list.
+ (syms_of_nsfns): Remove DEFSYM for Qgeometry, Qworkarea, Qmm_size,
+ Qframes, Qsource.
+
+ * frame.h (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare.
+ (struct MonitorInfo): New struct.
+ (free_monitors, make_monitor_attribute_list): Declare.
+
+ * frame.c (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource):
+ New Lisp_Object:s.
+ (free_monitors, make_monitor_attribute_list): New functions.
+ (syms_of_frame): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes,
+ Qsource.
+
+2013-05-25 Xue Fuqiao <xfq.free@gmail.com>
+
+ * callproc.c (call_process): Refine the doc string. (Bug#14045)
+
+2013-05-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * keyboard.c: Apply keyboard decoding only to events that come directly
+ from the tty, not from unread-command-events (bug#14368).
+ (read_event_from_main_queue): New function, extracted from read_char).
+ (read_decoded_char): Remove.
+ (read_decoded_event_from_main_queue): New function to replace it.
+ (read_char): Use it.
+ (read_key_sequence): Use read_char rather than read_decoded_char.
+
+ * keyboard.c (read_decoded_char): Don't decode under w32 (bug#14403).
+
+2013-05-22 Barry OReilly <gundaetiapo@gmail.com> (tiny change)
+
+ * casetab.c (init_casetab_once): Fix last change (bug#14424).
+
+2013-05-22 Kenichi Handa <handa@gnu.org>
+
+ The following changes are to fix the setting of
+ buffer-file-coding-system on, for instance, C-x RET c unix RET
+ _FILE_OF_DOS_EOL_TYPE_ RET.
+
+ * coding.h (struct coding_system): New member detected_utf8_chars.
+
+ * coding.c (detect_coding_utf_8): Count characters and check EOL
+ format. Include CATEGORY_MASK_UTF_8_AUTO in detect_info->found if
+ BOM is there.
+ (setup_coding_system): Do not initialize coding->head_ascii.
+ (check_ascii): Do not set coding->eol_seen but update it. Do not
+ call adjust_coding_eol_type here.
+ (detect_coding): Fix detection of BOM for utf-8 and utf-16.
+ If the eol-type of CODING is already specified, adjust the eol type
+ of the found coding-system.
+ (decode_coding_gap): Cancel previous change. Utilize the
+ character numbers counted by detect_coding_utf_8. Fix detection
+ of BOM for utf-8.
+
+2013-05-21 Barry OReilly <gundaetiapo@gmail.com> (tiny change)
+
+ * search.c (looking_at_1): Only set last_thing_searched if the match
+ changed the match-data (bug#14281).
+
+2013-05-21 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * xdisp.c (reseat_at_previous_visible_line_start):
+ Already declared in dispextern.h, so remove it here.
+ (move_it_vertically_backward): Likewise.
+
+2013-05-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * xfns.c (check_x_display_info): Don't use XINT for terminal object.
+ (Fx_display_pixel_width, Fx_display_pixel_height)
+ (Fx_display_mm_width, Fx_display_mm_height):
+ Mention `display-monitor-attributes-list' in docstrings.
+
+ * nsfns.m (ns_get_screen): Remove function. All uses removed.
+ (check_ns_display_info): Sync with check_x_display_info in xfns.c.
+ (Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
+ (Fx_display_screens, Fx_display_mm_width, Fx_display_mm_height)
+ (Fx_display_backing_store, Fx_display_visual_class)
+ (Fx_display_save_under, Fx_close_connection, Fxw_display_color_p)
+ (Fx_display_grayscale_p, Fx_display_pixel_width)
+ (Fx_display_pixel_height, Fx_display_planes)
+ (Fx_display_color_cells): Sync args and docstrings with xfns.c.
+ (Fx_display_screens): Don't confuse X11 screens with NS screens.
+ (Fx_display_mm_width, Fx_display_mm_height)
+ (Fx_display_pixel_width, Fx_display_pixel_width): Return width or
+ height for all physical monitors as in X11.
+
+ * nsterm.m (x_display_pixel_width, x_display_pixel_height):
+ Return pixel width or height for all physical monitors as in X11.
+
+2013-05-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port --enable-gcc-warnings to clang.
+ * bytecode.c (exec_byte_code):
+ * regex.c:
+ Redo diagnostic pragmas to pacify clang, too.
+ * dbusbind.c (xd_retrieve_arg): Do not use uninitialized variable.
+ * editfns.c (Fencode_time):
+ * fileio.c (file_accessible_directory_p):
+ * font.c (font_unparse_xlfd):
+ Use '&"string"[index]' instead of '"string" + (index)'.
+ * undo.c (user_error): Remove; unused.
+
+2013-05-16 Eli Zaretskii <eliz@gnu.org>
+
+ * insdel.c (insert_1_both): Document the arguments, instead of
+ referring to insert_1, which no longer exists.
+
+ * xdisp.c (message_dolog): If the *Messages* buffer is shown in
+ some window, increment windows_or_buffers_changed, so that
+ *Messages* display in that window is updated. (Bug#14408)
+
+ * w32.c: Include epaths.h.
+ (init_environment): Use cmdproxy.exe without leading directories.
+ Support emacs.exe in src; point SHELL to cmdproxy in ../nt in that
+ case.
+ (gettimeofday): Adjust signature and return value to Posix
+ expectations.
+
+ * unexw32.c (open_output_file): Delete the existing emacs.exe
+ before creating it, to break the hard link to the versioned
+ executable.
+
+ * Makefile.in (EMACS_MANIFEST, CM_OBJ, TEMACS_POST_LINK)
+ (ADDSECTION, EMACS_HEAPSIZE, MINGW_TEMACS_POST_LINK)
+ (FIRSTFILE_OBJ): New variables.
+ (W32_RES): Rename to EMACSRES. All users changed.
+ (base_obj): Use $(CM_OBJ).
+ (ALLOBJS): Use $(FIRSTFILE_OBJ).
+ (emacs$(EXEEXT)): Depend on $(ADDSECTION).
+ (temacs$(EXEEXT)): Use $(TEMACS_POST_LINK), and move
+ $(W32_RES_LINK) before $(LIBES).
+ (emacs.res): Depend on $(EMACS_MANIFEST). Put emacs.rc in nt.
+
+2013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * makefile.w32-in (DOC): Use just "DOC".
+
+ * Makefile.in (bootstrap-clean): DOC-* doesn't exist any more.
+
+ * process.c: Export default filters and sentinels to Elisp.
+ (Qinternal_default_process_sentinel, Qinternal_default_process_filter):
+ New constants.
+ (pset_filter, pset_sentinel, make_process, Fset_process_filter)
+ (Fset_process_sentinel, Fformat_network_address):
+ Default to them instead of nil.
+ (server_accept_connection): Sentinels can't be nil any more.
+ (read_and_dispose_of_process_output): New function, extracted from
+ read_process_output.
+ (read_process_output): Use it; filters can't be nil.
+ (Finternal_default_process_filter): New function, extracted from
+ read_process_output.
+ (exec_sentinel_unwind): Remove function.
+ (exec_sentinel): Don't zilch sentinel while running.
+ (status_notify): Sentinels can't be nil.
+ (Finternal_default_process_sentinel): New function extracted from
+ status_notify.
+ (setup_process_coding_systems): Default filter is not nil any more.
+ (syms_of_process): Export new Elisp functions and initialize
+ new constants.
+ * lisp.h (make_lisp_proc): New function.
+
+2013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * regex.c (regex_compile) [\=, \>, \<]: Don't forget to set laststart.
+
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * w32fns.c (w32_wnd_proc): Don't call WINDOW_HEADER_LINE_HEIGHT
+ unless we know that the window w is a leaf window.
+ Another attempt at solving bug#14062.
+
+2013-05-14 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsfont.m (ns_spec_to_descriptor): Retain and autorelease
+ fdesc (Bug#14375).
+
+2013-05-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ * image.c (gif_load): Check that subimages fit (Bug#14345).
+
+2013-05-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lread.c (skip_dyn_eof): New function.
+ (read1): Use it to skip the end of a file in response to #@00.
+
+ * doc.c (get_doc_string): Slightly relax the sanity checking.
+
+2013-05-09 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsfns.m: Include IOGraphicsLib.h if Cocoa.
+ (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare.
+ (MonitorInfo): New struct.
+ (free_monitors, ns_screen_name, ns_make_monitor_attribute_list)
+ (Fns_display_monitor_attributes_list): New functions.
+ (display-usable-bounds): Remove.
+ (syms_of_nsfns): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes and
+ Qsource.
+
+2013-05-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ * xterm.h (GTK_PREREQ): Remove, replacing with GTK_CHECK_VERSION.
+ (GTK_CHECK_VERSION): New macro, if not already defined.
+ All uses of GTK_PREREQ, GTK_MAJOR_VERSION, etc.
+ replaced by GTK_CHECK_VERSION.
+
+2013-05-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ * xterm.h (GTK_PREREQ): New macro.
+ All simple uses of GTK_MAJOR_VERSION and GTK_MINOR_VERSION changed
+ to use this macro instead, for consistency and clarity.
+
+2013-05-08 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (row_for_charpos_p): New function, with code of
+ cursor_row_p, but accepts an additional argument CHARPOS instead
+ of using a hardcoded PT.
+ (cursor_row_p): Call row_for_charpos_p with 2nd argument PT.
+ (row_containing_pos): Call row_for_charpos_p instead of partially
+ doing the same. Fixes cursor positioning under longlines-mode
+ when longlines-show-effect includes more than one newline, when
+ moving the cursor vertically up.
+
+2013-05-08 Juanma Barranquero <lekktu@gmail.com>
+
+ * makefile.w32-in (ACL_H): New macro.
+ ($(BLD)/fileio.$(O)): Update dependencies.
+
+2013-05-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use Gnulib ACL implementation, for benefit of Solaris etc. (Bug#14295)
+ * Makefile.in (LIB_ACL): New macro.
+ (LIBACL_LIBS): Remove.
+ (LIBES): Use LIB_ACL, not LIBACL_LIBS.
+ * fileio.c: Include <acl.h>.
+ Use HAVE_ACL_SET_FILE rather than HAVE_POSIX_ACL.
+ (ACL_NOT_WELL_SUPPORTED): Remove. All uses replaced by
+ !acl_errno_valid.
+ (Fcopy_file) [!WINDOWSNT]: Use qcopy_acl instead of rolling
+ it ourselves.
+
+ * unexelf.c: Don't assume ElfW (Half) fits in int.
+ (entry_address, find_section, unexec): Use ptrdiff_t, not int,
+ when dealing with ElfW (Half) values, since they can exceed 2**31
+ on 64-bit OpenBSD hosts. Problem reported privately by Han Boetes.
+ (entry_address): Omit unused NUM arg. All uses changed.
+
+2013-05-07 Juri Linkov <juri@jurta.org>
+
+ * callint.c (Fcall_interactively): Set `visargs[i]' for code 'n'
+ to the string converted from number with `Fnumber_to_string'.
+ (Bug#14254)
+
+2013-05-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ * xfns.c (x_get_net_workarea): Define only if !GTK || GTK<3.4.
+ This fixes a problem introduced by my previous change.
+
+2013-05-07 Glenn Morris <rgm@gnu.org>
+
+ * lread.c (readchar): Don't read from a dead buffer. (Bug#14280)
+
+2013-05-07 Jan Djärv <jan.h.d@swipnet.se>
+
+ * xfns.c: Move misplaced ifndef USE_GTK from previous checkin.
+
+2013-05-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Static checking by GCC 4.8.0.
+ * xfns.c (x_get_net_workarea, struct MonitorInfo, free_monitors)
+ (x_get_monitor_for_frame, x_make_monitor_attribute_list)
+ (x_get_monitor_attributes_fallback)
+ (x_get_monitor_attributes_xinerama)
+ (x_get_monitor_attributes_xrandr, x_get_monitor_attributes):
+ Define only if USE_GTK.
+ (free_monitors): Define only if HAVE_XINERAMA || HAVE_XRANDR.
+ (x_get_monitor_attributes_fallback): Omit unused locals.
+ (x_get_monitor_attributes_xinerama, Fx_display_monitor_attributes_list):
+ Use double, not float, to avoid mixed-mode floating point arithmetic.
+
+2013-05-07 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+ Jan Djärv <jan.h.d@swipnet.se>
+
+ * Makefile.in (XRANDR_LIBS, XRANDR_CFLAGS, XINERAMA_LIBS)
+ (XINERAMA_CFLAGS): New macros.
+ (ALL_CFLAGS, LIBES): Use them.
+
+ * xfns.c: Include <X11/extensions/Xrandr.h> if HAVE_XRANDR, and
+ include <X11/extensions/Xinerama.h> if HAVE_XINERAMA.
+ (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): New variables.
+ (syms_of_xfns): DEFSYM them.
+ (struct MonitorInfo): New struct.
+ (x_get_net_workarea, free_monitors, x_get_monitor_for_frame)
+ (x_make_monitor_attribute_list, x_get_monitor_attributes_fallback)
+ (x_get_monitor_attributes_xrandr, x_get_monitor_attributes)
+ (x_get_monitor_attributes_xinerama): New functions.
+ (Fx_display_monitor_attributes_list): New primitive.
+ (syms_of_xfns): Defsubr it.
+
+ * xterm.h (x_display_info): Add Xatom_net_workarea and
+ Xatom_net_current_desktop.
+
+ * xterm.c (x_term_init): Initialize dpyinfo->Xatom_net_workarea
+ and dpyinfo->Xatom_net_current_desktop.
+
+2013-05-06 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (pos_visible_p): Use the special code for finding the
+ beginning of a display property or overlay for any "replacing"
+ display property, not just for display strings. This solves
+ incorrect reporting of position by posn-at-point. (Bug#14241)
+
+2013-05-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ * unexelf.c: Fix some 32-bit integer problems, notably when debugging.
+ Include <limits.h>, <stdbool.h>, <intprops.h>, <verify.h>.
+ Verify that ElfW (Half) fits in int.
+ (fatal): Use same signature as lisp.h.
+ (UNEXELF_DEBUG): New macro, replacing DEBUG, so that people can
+ configure and build with -DUNEXELF_DEBUG without worrying about
+ other modules that use DEBUG.
+ (DEBUG_LOG) [UNEXELF_DEBUG]: New macro. All debug code that prints
+ possibly-wide integers now uses it instead of plain fprintf.
+ (entry_address): New function, which avoids problems with 32-bit
+ overflow on 64-bit hosts.
+ (OLD_SECTION_H, NEW_SECTION_H, NEW_PROGRAM_H): Use it.
+ (round_up): Don't assume the remainder fits in int.
+ (find_section): Use bool for boolean. Simplify debug code.
+ (unexec): Don't assume file sizes fit in int or size_t.
+ Omit unnecessary trailing newline in 'fatal' format.
+ Use strerror rather than outputting decimal error number.
+ Remove unused code when emacs is not defined;
+ this file relies on Emacs now.
+ Don't assume e_phnum and e_shnum are positive.
+
+ * regex.c: Fix problems when DEBUG is defined.
+ (extract_number, extract_number_and_incr): Define regardless of
+ whether DEBUG is defined; that's simpler and makes the code less
+ likely to go stale in the normal case when DEBUG is not defined.
+ Return int rather than taking an int * arg. All callers changed.
+ (DEBUG_PRINT1, DEBUG_PRINT2, DEBUG_PRINT3, DEBUG_PRINT4):
+ Remove, replacing with ...
+ (DEBUG_PRINT): New macro. All callers changed.
+ (DEBUG_COMPILES_ARGUMENTS): New macro.
+ (print_fastmap, print_partial_compiled_pattern) [DEBUG]:
+ (print_compiled_pattern, print_double_string) [DEBUG]:
+ Use prototype rather than old-style definition.
+ (print_partial_compiled_pattern, print_compiled_pattern) [DEBUG]:
+ (ENSURE_FAIL_STACK, PUSH_FAILURE_REG) [DEBUG]:
+ (POP_FAILURE_REG_OR_COUNT, PUSH_FAILURE_POINT) [DEBUG]:
+ (POP_FAILURE_POINT, re_match_2_internal) [DEBUG]:
+ Don't assume ptrdiff_t, size_t, and long are the same width as int.
+ (POINTER_TO_OFFSET): Return ptrdiff_t, not regoff_t.
+ This matters only when DEBUG is defined.
+
+2013-05-05 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (set_iterator_to_next): Set the
+ ignore_overlay_strings_at_pos_p flag only if we are _really_
+ iterating over an overlay string, as indicated by the
+ current.overlay_string_index member. (Bug#14306)
+
+2013-05-05 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsmenu.m (ns_update_menubar): Move initialization of submenuTitle
+ to where it is used, to avoid autorelease issues (Bug#14050).
+
+2013-05-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ `write-region-inhibit-fsync' defaults to noninteractive (Bug#14273).
+ * fileio.c (syms_of_fileio): Implement this.
+ * filelock.c (create_lock_file): If symbolic links don't work, so
+ we use a regular file as a lock file, do not fsync the lock file;
+ it's not needed.
+
+2013-05-04 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * minibuf.c (Fread_minibuffer, Feval_minibuffer): Move to Elisp.
+ (syms_of_minibuf): Adjust accodingly.
+ * lread.c (Fread):
+ * callint.c (Fcall_interactively): Adjust calls accordingly.
+
+2013-05-04 Eli Zaretskii <eliz@gnu.org>
+
+ * dispextern.h (WINDOW_WANTS_HEADER_LINE_P): Verify that
+ w->contents is a buffer before computing everything else.
+ Use parentheses to disambiguate last part of the condition.
+
+ * w32fns.c (w32_wnd_proc): Remove temporary code used to trap
+ assertion violations. (Bug#14062)
+
+2013-05-01 David Reitter <david.reitter@gmail.com>
+
+ * nsfns.m (ns_tooltip): Initialize.
+
+2013-04-28 Eli Zaretskii <eliz@gnu.org>
+
+ * coding.c (decode_coding_gap): Don't remove the character before
+ a newline unless it's a CR character. (Bug#14287)
+
+2013-04-28 Dan Nicolaescu <dann@gnu.org>
+
+ * dispextern.h (struct face): Move enum face_underline_type
+ earlier so that bitfields can be in the same word.
+
+2013-04-28 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsfns.m (handlePanelKeys): New function.
+ (EmacsOpenPanel:performKeyEquivalent:)
+ (EmacsSavePanel:performKeyEquivalent:): Call handlePanelKeys to handle
+ arrows/function/control and copy/paste keys (Bug#14296).
+
+2013-04-27 Juri Linkov <juri@jurta.org>
+
+ * callint.c (Fcall_interactively): Call `Qread_number' for
+ interactive code letter `n' instead of using duplicate code.
+ (Bug#14254)
+
+2013-04-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ * systime.h (make_timeval): Declare as 'const'.
+
+2013-04-27 Kenichi Handa <handa@gnu.org>
+
+ * font.c (font_open_entity): Always open a font of manageable
+ size.
+
+2013-04-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Port better to AIX (Bug#14258).
+ * lisp.h (ENUM_BF) [__IBMC__]: Make it 'unsigned int' here, too,
+ to pacify AIX xlc.
+
+2013-04-24 Kenichi Handa <handa@gnu.org>
+
+ * coding.c (decode_coding_iso_2022): When an invalid escape
+ sequence is encountered, reset the invocation and designation
+ status to the safest one.
+
+2013-04-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ * Makefile.in (bootstrap-clean): Remove stamp-h1 too.
+ Without this fix, "make distclean" leaves stamp-h1 behind.
+
+2013-04-20 Erik Charlebois <erikcharlebois@gmail.com>
+
+ * w32fns.c (w32_fullscreen_rect): New function to compute the
+ window rectangle for the given fullscreen mode.
+ (w32_wnd_proc): When in a fullscreen mode, WM_WINDOWPOSCHANGING no
+ longer tunes the window size. This keeps the window's edges flush
+ with the screen and allows the taskbar to hide itself in fullboth.
+
+ * w32term.c (w32fullscreen_hook): 'fullboth' now shows without
+ window decorations and uses the entire screen.
+
+ * w32term.h (w32_fullscreen_rect) Add prototype.
+ (struct w32_output): Replace normal_width, normal_height,
+ normal_top, and normal_left members with a single normal_placement
+ struct.
+ (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP):
+ Remove macros.
+ (FRAME_NORMAL_PLACEMENT): New macro.
+
+2013-04-16 Juanma Barranquero <lekktu@gmail.com>
+
+ * minibuf.c (Ftest_completion): Silence compiler warning.
+
+2013-04-15 Eli Zaretskii <eliz@gnu.org>
+
+ * w32fns.c (w32_wnd_proc): Add more assertions to investigate
+ bug#14062.
+
+ * frame.h (WINDOW_FRAME): Protect macro and its argument with
+ parentheses.
+
+ * dispextern.h (CURRENT_MODE_LINE_HEIGHT)
+ (CURRENT_HEADER_LINE_HEIGHT, WINDOW_WANTS_MODELINE_P)
+ (WINDOW_WANTS_HEADER_LINE_P): Protect macro arguments with
+ parentheses where appropriate.
+
+2013-04-14 Paul Eggert <eggert@cs.ucla.edu>
+
+ * keyboard.c (timer_start_idle): Remove no-longer-used local.
+
+2013-04-14 Eli Zaretskii <eliz@gnu.org>
+
+ * buffer.c (syms_of_buffer) <left-margin-width, right-margin-width>
+ <left-fringe-width, right-fringe-width, fringes-outside-margins>:
+ Mention in the doc string that setting these variables takes
+ effect only after a call to set-window-buffer. (Bug#14200)
+
+2013-04-13 Eli Zaretskii <eliz@gnu.org>
+
+ * indent.c (Fvertical_motion): Don't consider display strings on
+ overlay strings as display strings on the buffer position we
+ started from. This prevents vertical cursor motion from jumping
+ more than one line when there's an overlay string with a display
+ property at end of line.
+ Reported by Karl Chen <Karl.Chen@quarl.org> in
+ http://lists.gnu.org/archive/html/emacs-devel/2013-04/msg00362.html.
+
+2013-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * window.c (select_window): `record_buffer' even if window is
+ already selected (bug#14191).
+
+2013-04-11 Eli Zaretskii <eliz@gnu.org>
+
+ * window.c (Fwindow_end): Test more flags, including the buffer's
+ last_overlay_modified flag, to determine whether the window's
+ display is really up-to-date. Prevents the function from
+ returning a stale value. (Bug#14170)
+ (Fwindow_line_height): Fix the test for up-to-date-ness of the
+ current matrix.
+
+2013-04-10 Eli Zaretskii <eliz@gnu.org>
+
+ * frame.c (do_switch_frame): Mark the TTY frame we switch to as
+ garbaged only if it is not already the top frame on its TTY.
+ This prevents flickering due to constant redrawing of TTY frames when
+ there are GUI frames open in the same session. (Bug#13864)
+
+2013-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * keyboard.c (timer_start_idle): Call internal-timer-start-idle instead
+ of marking the idle timers directly.
+
+2013-04-09 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * minibuf.c (Ftest_completion): Ignore non-string/symbol keys in hash
+ tables (bug#14054).
+
+2013-04-08 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * window.c (select_window): Don't record_buffer while the invariant is
+ temporarily broken (bug#14161).
+
+ * fns.c (Fdelq): Don't assume !NILP => CONSP.
+
+2013-04-07 Eli Zaretskii <eliz@gnu.org>
+
+ * fileio.c (ACL_NOT_WELL_SUPPORTED): Define macro for WINDOWSNT.
+
+2013-04-07 Romain Francoise <romain@orebokech.com>
+
+ Ignore additional platform-specific ACL errors (Bug#13702).
+ * fileio.c (ACL_NOT_WELL_SUPPORTED): New macro copied from gnulib.
+ (Fcopy_file, Fset_file_acl) [HAVE_POSIX_ACL]: Use it.
+
+2013-03-31 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsterm.m (ns_mouse_position): Use NS_FRAME_P instead of checking
+ f->output_data.ns.
+
+2013-04-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix --enable-profiling bug introduced by 2013-02-25 change (Bug#13783).
+ This bug was introduced by my 2013-02-25 change that simplified
+ data_start configuration. Without this change, on GNU/Linux
+ an Emacs configured with --enable-profiling fails immediately
+ due to a profiler signal.
+ * Makefile.in: Compile with $(PROFILING_CFLAGS), but do not link
+ with these flags. On platforms where special flags are needed
+ when linking temacs, the flags are now in LD_SWITCH_SYSTEM_TEMACS.
+ (ALL_CFLAGS): Remove $(PROFILING_CFLAGS).
+ (.c.o, .m.o): Compile with $(PROFILING_CFLAGS).
+
+2013-04-07 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Get rid of some platform-specific functions examining window
+ system and its capabilities. This is a partial rework of the
+ 2013-04-05 change.
+ * lisp.h (have_menus_p): Remove prototype. This function is
+ replaced with platform-independent window_system_available.
+ (check_window_system): Move to...
+ * frame.h (decode_window_system_frame, window_system_available):
+ ...here, add new prototypes.
+ * frame.c (window_system_available, decode_window_system_frame):
+ New functions.
+ (check_window_system): Platform-independent now.
+ * xterm.h (x_in_use): Remove declaration.
+ (check_x_frame):
+ * w32term.h (check_x_frame):
+ * nsterm.h (check_x_frame): Remove prototypes. This function
+ is replaced with platform-independent decode_window_system_frame.
+ * msdos.c (have_menus_p): Remove.
+ * nsfns.m (check_window_system, have_menus_p, check_ns_frame):
+ Remove platform-specific functions. Use check_window_system,
+ decode_window_system_frame and check_ns_display_info where
+ appropriate. Minor style and comment tweaks.
+ * w32fns.c (w32_in_use, check_window_system, have_menus_p)
+ (check_x_frame): Likewise.
+ * xfns.c (x_in_use, check_window_system, have_menus_p, check_x_frame):
+ Likewise.
+ * fileio.c, fns.c, font.c, fontset.c, image.c, menu.c, nsmenu.m:
+ * nsselect.m, nsterm.m, w32font.c, w32menu.c, xfaces.c, xgselect.c:
+ * xmenu.c, xselect.c: All related users changed.
+
+2013-04-03 Kenichi Handa <handa@gnu.org>
+
+ The following changes is to optimize the code for reading UTF-8
+ files.
+
+ * coding.c (check_ascii): Rename from detect_ascii. Return value
+ changed. Check EOL format. Do not call adjust_coding_eol_type
+ here.
+ (check_utf_8): New function.
+ (adjust_coding_eol_type): Do nothing if already adjusted.
+ (detect_coding): Compare the return value of check_ascii with
+ coding->src_bytes. Call adjust_coding_eol_type if necessary.
+ (decode_coding_gap): Optimize for valid UTF-8.
+
+2013-03-21 Kenichi Handa <handa@gnu.org>
+
+ * coding.c (syms_of_coding): Cancel previous change.
+
+ * insdel.c (insert_from_gap): Fix previous change.
+
+2013-04-05 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Consistently use platform-specific function to detect window system.
+ * lisp.h (check_window_system): New prototype. This function is
+ going to replace check_x, check_w32 and check_ns.
+ (have_menus_p): Mention msdos.c in comment.
+ * fontset.c (check_window_system_func): Remove. Adjust all users.
+ * fontset.h (check_window_system_func): Remove prototype.
+ * nsterm.h (check_ns):
+ * xterm.h (check_x):
+ * w32term.h (check_w32): Likewise.
+ * menu.c (Fx_popup_menu): Use check_window_system.
+ * msdos.c (check_window_system): Define for MS-DOS.
+ * nsfns.m (check_window_system): Define for NS. Adjust all users.
+ * w32fns.c (check_window_system): Likewise for MS-Windows.
+ * xfns.c (check_window_system): Likewise for X.
+ * font.c, frame.c, nsmenu.m, nsselect.m, nsterm.m, w32menu.c:
+ * xfaces.c, xmenu.c: Use check_window_system where appropriate.
+
+2013-04-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ Prefer < to > in range checks such as 0 <= i && i < N.
+ This makes it easier to visualize quantities on a number line.
+ This patch doesn't apply to all such range checks,
+ only to the range checks affected by the 2013-03-24 change.
+ This patch reverts most of the 2013-03-24 change.
+ * alloc.c (xpalloc, Fgarbage_collect):
+ * ccl.c (ccl_driver, resolve_symbol_ccl_program):
+ * character.c (string_escape_byte8):
+ * charset.c (read_hex):
+ * data.c (cons_to_unsigned):
+ * dispnew.c (update_frame_1):
+ * doc.c (Fsubstitute_command_keys):
+ * doprnt.c (doprnt):
+ * editfns.c (hi_time, decode_time_components):
+ * fileio.c (file_offset):
+ * fns.c (larger_vector, make_hash_table, Fmake_hash_table):
+ * font.c (font_intern_prop):
+ * frame.c (x_set_alpha):
+ * gtkutil.c (get_utf8_string):
+ * indent.c (check_display_width):
+ * keymap.c (Fkey_description):
+ * lisp.h (FIXNUM_OVERFLOW_P, vcopy):
+ * lread.c (read1):
+ * minibuf.c (read_minibuf_noninteractive):
+ * process.c (wait_reading_process_output):
+ * search.c (Freplace_match):
+ * window.c (get_phys_cursor_glyph):
+ * xdisp.c (redisplay_internal):
+ * xsmfns.c (smc_save_yourself_CB):
+ Prefer < to > for range checks.
+ * dispnew.c (sit_for): Don't mishandle NaNs.
+ This fixes a bug introduced in the 2013-03-24 change.
+ * editfns.c (decode_time_components): Don't hoist comparison.
+ This fixes another bug introduced in the 2013-03-24 change.
+
+2013-03-31 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * frame.h (struct frame): Drop scroll_bottom_vpos
+ member becaue all real users are dead long ago.
+ (FRAME_SCROLL_BOTTOM_VPOS): Remove.
+ * xdisp.c (redisplay_internal): Adjust user.
+
+2013-03-30 Darren Ho <darren.hoo@gmail.com> (tiny change)
+
+ * nsmenu.m (showAtX:Y:for:): setLevel to
+ NSPopUpMenuWindowLevel (Bug#13998).
+
+2013-03-30 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsterm.h (ns_get_pending_menu_title, ns_check_menu_open)
+ (ns_check_pending_open_menu): Declare.
+
+ * nsmenu.m (ns_update_menubar): Correct NSTRACE.
+ (x_activate_menubar): Update the menu with title that matches
+ ns_get_pending_menu_title, and call
+ ns_check_pending_openmenu (Bug#12698).
+ (menuWillOpen:): New method.
+ (menuNeedsUpdate:): Add check for ! COCOA || OSX < 10.5 (Bug#12698).
+
+ * nsterm.m (menu_will_open_state, menu_mouse_point)
+ (menu_pending_title): New varaibles.
+ (ns_get_pending_menu_title, ns_check_menu_open)
+ (ns_check_pending_open_menu): New functions.
+
+2013-03-29 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * indent.c (current_column_bol_cache): Remove leftover which is not
+ used in Fmove_to_column any more.
+ (current_column, scan_for_column): Adjust users.
+ * keyboard.c (last_point_position_buffer, last_point_position_window):
+ Remove leftovers which are not used for recording undo any more.
+ (command_loop_1, syms_of_keyboard): Adjust users.
+ * xdisp.c (last_max_ascent): Remove leftover which is not used in
+ redisplay_window any more.
+ (move_it_to): Adjust user.
+
+2013-03-29 Juanma Barranquero <lekktu@gmail.com>
+
+ * makefile.w32-in ($(BLD)/filelock.$(O), $(BLD)/filelock.$(O)):
+ Update dependencies.
+
+2013-03-28 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * lisp.h (save_type, XSAVE_POINTER, set_save_pointer, XSAVE_INTEGER)
+ (set_save_integer, XSAVE_OBJECT, XSAVE_VALUE): Move to avoid
+ forward references.
+
+2013-03-28 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * window.h (struct window): Replace hchild, vchild and buffer slots
+ with the only contents slot. This is possible because each valid
+ window may have either the child window (in vertical or horizontal
+ combination) or buffer to display (for the leaf window). Using that,
+ a lof of operations to traverse and/or change window hierarchies may
+ be simplified. New member horizontal is used to distinguish between
+ horizontal and vertical combinations of internal windows.
+ (WINDOW_LEAF_P, WINDOW_HORIZONTAL_COMBINATION_P)
+ (WINDOW_VERTICAL_COMBINATION_P): New macros.
+ (WINDOW_VALID_P, WINDOW_LIVE_P): Adjust to match struct window changes.
+ * window.c (wset_hchild, wset_vchild): Remove. Adjust all users.
+ Use contents slot, not buffer, where appropriate.
+ (wset_combination): New function.
+ (wset_buffer): Add eassert.
+ (Fframe_first_window): Simplify the loop reaching first window.
+ (Fwindow_buffer): Use WINDOW_LEAF_P.
+ (Fwindow_top_child): Use WINDOW_VERTICAL_COMBINATION_P.
+ (Fwindow_left_child): Use WINDOW_HORIZONTAL_COMBINATION_P.
+ (unshow_buffer): Convert initial debugging check to eassert.
+ (replace_window, recombine_windows, Fdelete_other_windows_internal)
+ (make_parent_window, window_resize_check, window_resize_apply)
+ (resize_frame_windows, Fsplit_window_internal, Fdelete_window_internal)
+ (Fset_window_configuration, delete_all_child_windows, save_window_save):
+ Adjust to match struct window changes.
+ (window_loop): Check for broken markers in CHECK_ALL_WINDOWS.
+ (mark_window_cursors_off, count_windows, get_leaf_windows)
+ (foreach_window_1): Simplify the loop.
+ * alloc.c (mark_object): Do not check for the leaf window because
+ internal windows has no glyph matrices anyway.
+ * dispnew.c (clear_window_matrices, showing_window_margins_p)
+ (allocate_matrices_for_window_redisplay, fake_current_matrices)
+ (allocate_matrices_for_frame_redisplay, free_window_matrices)
+ (build_frame_matrix_from_window_tree, mirror_make_current)
+ (frame_row_to_window, mirror_line_dance, check_window_matrix_pointers)
+ (update_window_tree, set_window_update_flags): Simplify the loop.
+ (sync_window_with_frame_matrix_rows): Enforce live window.
+ Use contents slot, not buffer, where appropriate.
+ * frame.c (set_menu_bar_lines_1): Use WINDOW_VERTICAL_COMBINATION_P
+ and WINDOW_HORIZONTAL_COMBINATION_P.
+ (make_frame_visible_1): Simplify the loop.
+ Use contents slot, not buffer, where appropriate.
+ * xdisp.c (hscroll_window_tree, mark_window_display_accurate)
+ (redisplay_windows, redisplay_mode_lines, update_cursor_in_window_tree)
+ (expose_window_tree): Likewise.
+ Use contents slot, not buffer, where appropriate.
+ * textprop.c (get_char_property_and_overlay): Add CHECK_LIVE_WINDOW
+ to avoid deleted windows. Use contents slot instead of buffer.
+ * buffer.c, dispextern.h, editfns.c, fileio.c, font.c, fringe.c:
+ * indent.c, insdel.c, keyboard.c, keymap.c, minibuf.c, msdos.c:
+ * nsfns.m, nsmenu.m, nsterm.m, print.c, w32fns.c, w32menu.c, xfaces.c:
+ * xfns.c, xmenu.c: Use contents slot, not buffer, where appropriate.
+
+2013-03-28 Eli Zaretskii <eliz@gnu.org>
+
+ * w32fns.c (w32_wnd_proc) [ENABLE_CHECKING]: Add code to help
+ identify the reasons for assertion violations in bug#14062 and
+ similar ones.
+ (Fx_show_tip): Fix compilation error under
+ "--enable-check-lisp-object-type". (Bug#14073)
+
+ * image.c (g_error_free) [WINDOWSNT]: Add DEF_IMGLIB_FN.
+ Reported by <rzl24ozi@gmail.com>.
+
+2013-03-28 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * xdisp.c (with_echo_area_buffer_unwind_data): Save window
+ start marker...
+ (unwind_with_echo_area_buffer): ...to restore it here.
+ This is needed to ensure that...
+ (redisplay_window): ...both window markers are valid here,
+ which is verified by eassert.
+ * editfns.c (save_excursion_save): Do not assume that
+ selected_window always displays the buffer.
+ * buffer.c (Fbuffer_swap_text): Adjust window start markers.
+ Fix comment.
+
+2013-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * casetab.c (init_casetab_once): Don't abuse the ascii eqv table for
+ the upcase table.
+
+2013-03-27 rzl24ozi <rzl24ozi@gmail.com> (tiny changes)
+
+ * image.c [WINDOWSNT]: Fix calls to DEF_IMGLIB_FN for SVG function.
+
+2013-03-27 Eli Zaretskii <eliz@gnu.org>
+
+ * w32proc.c (IsValidLocale) [__GNUC__]: Don't declare prototype,
+ since MinGW's w32api headers do. This avoids compiler warnings.
+
+ * w32.c (FSCTL_GET_REPARSE_POINT) [_MSC_VER || _W64]: Don't define
+ if already defined.
+
+2013-03-26 Eli Zaretskii <eliz@gnu.org>
+
+ * w32.c (_REPARSE_DATA_BUFFER): Condition by _MSVC and _W64.
+
+2013-03-26 Jan Djärv <jan.h.d@swipnet.se>
+
+ * gtkutil.c (style_changed_cb): Check if frame is live and an
+ X frame (Bug#14038).
+
+2013-03-26 Eli Zaretskii <eliz@gnu.org>
+
+ * w32.c (_PROCESS_MEMORY_COUNTERS_EX) [_WIN32_WINNT < 0x0500]:
+ Define only for _WIN32_WINNT less than 0x0500.
+ (_ANONYMOUS_UNION, _ANONYMOUS_STRUCT) [!_W64]: Don't define for
+ MinGW64.
+ Move inclusion of time.h before sys/time.h, so that MinGW64 could
+ see its own definitions of 'struct timeval' and 'struct timezone'.
+
+ Fix incompatibilities between MinGW.org and MinGW64 headers.
+ * w32term.c (WCRANGE, GLYPHSET): Don't define if _W64 is defined.
+
+ * w32.c (REPARSE_DATA_BUFFER): Guard with
+ MAXIMUM_REPARSE_DATA_BUFFER_SIZE being defined.
+
+2013-03-25 Jan Djärv <jan.h.d@swipnet.se>
+
+ * xterm.c: Include X11/XKBlib.h
+ (XTring_bell): Use XkbBell if HAVE_XKB (Bug#14041).
+
+2013-03-24 Andreas Schwab <schwab@linux-m68k.org>
+
+ * alloc.c (xpalloc, Fgarbage_collect): Reorder conditions that are
+ written backwards.
+ * blockinput.h (input_blocked_p): Likewise.
+ * bytecode.c (exec_byte_code): Likewise.
+ * callproc.c (call_process_kill, call_process_cleanup)
+ (Fcall_process): Likewise.
+ * ccl.c (ccl_driver, resolve_symbol_ccl_program)
+ (Fccl_execute_on_string): Likewise.
+ * character.c (string_escape_byte8): Likewise.
+ * charset.c (read_hex): Likewise.
+ * cm.c (calccost): Likewise.
+ * data.c (cons_to_unsigned): Likewise.
+ * dired.c (directory_files_internal, file_name_completion):
+ Likewise.
+ * dispnew.c (scrolling_window, update_frame_1, Fsleep_for)
+ (sit_for): Likewise.
+ * doc.c (Fsubstitute_command_keys): Likewise.
+ * doprnt.c (doprnt): Likewise.
+ * editfns.c (hi_time, decode_time_components, Fformat): Likewise.
+ * emacsgtkfixed.c: Likewise.
+ * fileio.c (file_offset, Fwrite_region): Likewise.
+ * floatfns.c (Fexpt, fmod_float): Likewise.
+ * fns.c (larger_vector, make_hash_table, Fmake_hash_table):
+ Likewise.
+ * font.c (font_intern_prop): Likewise.
+ * frame.c (x_set_alpha): Likewise.
+ * gtkutil.c (get_utf8_string): Likewise.
+ * indent.c (check_display_width): Likewise.
+ * intervals.c (create_root_interval, rotate_right, rotate_left)
+ (split_interval_right, split_interval_left)
+ (adjust_intervals_for_insertion, delete_node)
+ (interval_deletion_adjustment, adjust_intervals_for_deletion)
+ (merge_interval_right, merge_interval_left, copy_intervals)
+ (set_intervals_multibyte_1): Likewise.
+ * keyboard.c (gobble_input, append_tool_bar_item): Likewise.
+ * keymap.c (Fkey_description): Likewise.
+ * lisp.h (FIXNUM_OVERFLOW_P, vcopy): Likewise.
+ * lread.c (openp, read_integer, read1, string_to_number):
+ Likewise.
+ * menu.c (ensure_menu_items): Likewise.
+ * minibuf.c (read_minibuf_noninteractive): Likewise.
+ * print.c (printchar, strout): Likewise.
+ * process.c (create_process, Faccept_process_output)
+ (wait_reading_process_output, read_process_output, send_process)
+ (wait_reading_process_output): Likewise.
+ * profiler.c (make_log, handle_profiler_signal): Likewise.
+ * regex.c (re_exec): Likewise.
+ * regex.h: Likewise.
+ * search.c (looking_at_1, Freplace_match): Likewise.
+ * sysdep.c (get_child_status, procfs_ttyname)
+ (procfs_get_total_memory): Likewise.
+ * systime.h (EMACS_TIME_VALID_P): Likewise.
+ * term.c (dissociate_if_controlling_tty): Likewise.
+ * window.c (get_phys_cursor_glyph): Likewise.
+ * xdisp.c (init_iterator, redisplay_internal, redisplay_window)
+ (try_window_reusing_current_matrix, try_window_id, pint2hrstr):
+ Likewise.
+ * xfns.c (Fx_window_property): Likewise.
+ * xmenu.c (set_frame_menubar): Likewise.
+ * xselect.c (x_get_window_property, x_handle_dnd_message):
+ Likewise.
+ * xsmfns.c (smc_save_yourself_CB): Likewise.
+ * xterm.c (x_scroll_bar_set_handle): Likewise.
+
+2013-03-24 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * xfaces.c (Finternal_face_x_get_resource): Allow 3rd (frame) argument
+ to be optional or nil. Adjust comment and convert it to docstring.
+ * xselect.c (Fx_send_client_event): Rename to Fx_send_client_message.
+ * frame.c (display_x_get_resource, Fx_get_resource): Break long line.
+
+2013-03-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ Static checking by GCC 4.8-20130319.
+ * image.c (gif_load): Assume pass < 3 to pacify GCC.
+ * process.c (Fset_process_datagram_address)
+ (Fmake_network_process): Check get_lisp_to_sockaddr_size return value.
+ * xdisp.c (get_char_face_and_encoding):
+ (get_glyph_face_and_encoding): Ensure that *CHAR2B is initialized.
+ (get_glyph_face_and_encoding): Prepare face before possibly using it.
+ (get_per_char_metric): Don't use CHAR2B if it might not be initialized.
+
+2013-03-24 Ken Brown <kbrown@cornell.edu>
+
+ * w32fns.c (emacs_abort) [CYGWIN]: Define `_open' as a macro to
+ fix compilation on 64-bit Cygwin, where underscores are not
+ automatically prepended.
+
+ * w32term.c (w32_initialize): Silence compiler warning.
+
+2013-03-23 Eli Zaretskii <eliz@gnu.org>
+
+ * w32term.c (w32fullscreen_hook): Use FRAME_NORMAL_WIDTH,
+ FRAME_NORMAL_HEIGHT, and FRAME_PREV_FSMODE, instead of static
+ variables, to save and restore frame dimensions.
+ Use FRAME_NORMAL_LEFT and FRAME_NORMAL_TOP to restore frame position
+ after returning from a 'fullscreen' configuration.
+ use SendMessage instead of PostMessage to send the SC_RESTORE message,
+ to avoid races between the main thread and the input thread.
+
+ * w32term.h (struct w32_output): New members normal_width,
+ normal_height, normal_top, normal_left, and prev_fsmode.
+ (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP)
+ (FRAME_NORMAL_LEFT, FRAME_PREV_FSMODE): New macros to access these
+ members of a frame.
+
+ * w32term.c (w32fullscreen_hook): Record last value of the frame's
+ 'fullscreen' parameter. Always record previous width and height
+ of the frame, except when switching out of maximized modes, so
+ that they could be restored correctly, instead of resetting to the
+ default frame dimensions. Send SC_RESTORE command to the frame,
+ unless we are going to send SC_MAXIMIZE, to restore the frame
+ resize hints in the mouse pointer shown by the window manager.
+ (Bug#14032)
+
+ * frame.c (get_frame_param): Now extern for WINDOWSNT as well.
+
+ * lisp.h (get_frame_param): Adjust conditions for prototype
+ declaration.
+
+2013-03-22 Ken Brown <kbrown@cornell.edu>
+
+ * unexcw.c: Drop unneeded inclusion of w32common.h.
+ (report_sheap_usage): Declare.
+ (read_exe_header): Add magic numbers for x86_64.
+ (fixup_executable): Fix printf format specifier for unsigned long
+ argument.
+
+2013-03-22 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * frame.h (struct frame): Put menu_bar_window under #ifdef
+ because this member is not needed when X toolkit is in use.
+ (fset_menu_bar_window):
+ * dispnew.c (clear_current_matrices, clear_desired_matrices)
+ (free_glyphs, update_frame):
+ * xdisp.c (expose_frame): Likewise.
+ (display_menu_bar): Likewise. Remove redundant eassert.
+ * window.h (WINDOW_MENU_BAR_P): Always define to 0 if X
+ toolkit is in use.
+
+2013-03-21 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use functions and constants to manipulate Lisp_Save_Value objects.
+ This replaces code that used macros and strings and token-pasting.
+ The change makes the C source a bit easier to follow,
+ and shrinks the Emacs executable a bit.
+ * alloc.c: Verify some properties of Lisp_Save_Value's representation.
+ (make_save_value): Change 1st arg from string to enum. All callers
+ changed.
+ (INTX): Remove.
+ (mark_object): Use if, not #if, for GC_MARK_STACK.
+ * lisp.h (SAVE_VALUEP, XSAVE_VALUE, XSAVE_POINTER, XSAVE_INTEGER)
+ (XSAVE_OBJECT): Now functions, not macros.
+ (STRING_BYTES_BOUND): Now just a macro, not a constant too;
+ the constant was never used.
+ (SAVE_SLOT_BITS, SAVE_VALUE_SLOTS, SAVE_TYPE_BITS, SAVE_TYPE_INT_INT)
+ (SAVE_TYPE_INT_INT_INT, SAVE_TYPE_OBJ_OBJ, SAVE_TYPE_OBJ_OBJ_OBJ)
+ (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, SAVE_TYPE_PTR_INT, SAVE_TYPE_PTR_OBJ)
+ (SAVE_TYPE_PTR_PTR, SAVE_TYPE_PTR_PTR_OBJ, SAVE_TYPE_MEMORY):
+ New constants.
+ (struct Lisp_Save_Value): Replace members area, type0, type1, type2,
+ type3 with a single member save_type. All uses changed.
+ (save_type, set_save_pointer, set_save_integer): New functions.
+ * print.c (PRINTX): Remove.
+
+ * alloc.c: Remove redundant static declarations.
+
+2013-03-20 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * window.h (struct window): Convert left_col, top_line, total_lines
+ and total_cols from Lisp_Objects to integers. Adjust comments.
+ (wset_left_col, wset_top_line, wset_total_cols, wset_total_lines):
+ Remove.
+ (WINDOW_TOTAL_COLS, WINDOW_TOTAL_LINES, WINDOW_LEFT_EDGE_COL)
+ (WINDOW_TOP_EDGE_LINE): Drop Lisp_Object to integer conversion.
+ * dispnew.c, frame.c, w32fns.c, window.c, xdisp.c, xfns.c:
+ Adjust users where appropriate.
+
+2013-03-20 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * frame.h (struct frame): Drop resx and resy because the same data is
+ available from window system-specific output context. Adjust users.
+ (default_pixels_per_inch_x, default_pixels_per_inch_y):
+ New functions to provide defaults when no window system available.
+ (FRAME_RES_X, FRAME_RES_Y): New macros.
+ (NUMVAL): Move from xdisp.c.
+ * font.c (font_pixel_size, font_find_for_lface, font_open_for_lface)
+ (Ffont_face_attributes, Fopen_font):
+ * image.c (gs_load):
+ * w32font.c (fill_in_logfont):
+ * xdisp.c (calc_pixel_width_or_height):
+ * xfaces.c (Fx_family_fonts, set_lface_from_font): Use them.
+ * xsettings.c (apply_xft_settings): Drop frame loop and adjust comment.
+
+2013-03-20 Kenichi Handa <handa@gnu.org>
+
+ * coding.c (syms_of_coding): Initialize disable_ascii_optimization
+ to 1 (temporary workaround until a bug related to ASCII
+ optimization is fixed).
+
+2013-03-19 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * window.c (Fwindow_combination_limit, Fset_window_combination_limit):
+ Signal error if window is not internal. Adjust docstring.
+ (delete_all_child_windows): Use combination_limit to save the buffer.
+ (Fset_window_configuration): Adjust accordingly.
+ * print.c (syms_of_print): Initialize debugging output not here...
+ (init_print_once): ...but in a new function here.
+ * lisp.h (init_print_once): Add prototype.
+ * emacs.c (main): Add call to init_print_once. Adjust comments.
+
+2013-03-18 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * window.c (window_resize_check, window_resize_apply)
+ (window_from_coordinates, recombine_windows, set_window_buffer)
+ (make_parent_window, Fwindow_resize_apply, resize_frame_windows)
+ (Fsplit_window_internal, Fdelete_window_internal)
+ (freeze_window_starts): Use bool for booleans.
+ * window.h (window_frame_coordinates, resize_frame_windows)
+ (freeze_window_starts, set_window_buffer): Adjust prototypes.
+
+2013-03-17 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * dispnew.c (bitch_at_user): Use `user-error'.
+
+2013-03-17 Ken Brown <kbrown@cornell.edu>
+
+ * dispextern.h (RGB_PIXEL_COLOR): Move here from image.c. Use it
+ as return type of image_background. (Bug#13981)
+ * image.c (RGB_PIXEL_COLOR): Move to dispextern.h.
+
2013-03-16 Jan Djärv <jan.h.d@swipnet.se>
* nsterm.m (updateFrameSize:): Change resize increments if needed.
@@ -6,8 +1322,8 @@
* nsterm.h (EmacsSavePanel, EmacsOpenPanel): Add getFilename
and getDirectory.
- * nsfns.m (ns_filename_from_panel, ns_directory_from_panel): New
- functions.
+ * nsfns.m (ns_filename_from_panel, ns_directory_from_panel):
+ New functions.
(Fns_read_file_name): ret is BOOL. If ! dir_only_p, don't choose
directories. If filename is nil, get directory name (Bug#13932).
Use getFilename and getDirectory.
@@ -19,7 +1335,7 @@
* coding.c (decode_coding_gap): Fix typo caught by static checking.
-2013-03-15 handa <handa@gnu.org>
+2013-03-15 Kenichi Handa <handa@gnu.org>
* insdel.c (insert_from_gap): New arg text_at_gap_tail.
(adjust_after_replace): Make it back to static. Delete the third
@@ -40,10 +1356,6 @@
(syms_of_coding): Declare disable-ascii-optimization as a Lisp
variable.
- * global.h (struct emacs_globals): New member
- f_disable_ascii_optimization.
- (disable_ascii_optimization): New macro.
-
* lisp.h (adjust_after_replace): Cancel externing it.
(insert_from_gap): Adjust prototype.
@@ -645,7 +1957,7 @@
(Fcommand_execute): Remove, replace by an Elisp implementation.
(syms_of_keyboard): Adjust accordingly.
-2013-02-19 Daniel Colascione <dancol@dancol.org>
+2013-02-19 Daniel Colascione <dancol@dancol.org>
* sheap.c (report_sheap_usage): Use message, not message1, so
that we don't try to create a buffer while we're in the middle
@@ -2431,7 +3743,7 @@
Use xputenv instead of setenv or putenv, to detect memory exhaustion.
* editfns.c (initial_tz): Move static var decl up.
(tzvalbuf_in_environ): New static var.
- (init_editfns): Initialize these two static vars.
+ (init_editfns): Initialize these two static vars.
(Fencode_time): Don't assume arbitrary limit on EMACS_INT width.
Save old TZ value on stack, if it's small.
(Fencode_time, set_time_zone_rule): Don't modify 'environ' directly;
@@ -2710,7 +4022,7 @@
Use execve to avoid need to munge environ (Bug#13054).
* callproc.c (Fcall_process):
* process.c (create_process):
- Don't save and restore environ; no longer needed.
+ Don't save and restore environ; no longer needed.
* callproc.c (child_setup):
Use execve, not execvp, to preserve environ.
@@ -5110,8 +6422,8 @@
a public macro and no need to inline by hand.
2012-09-26 Tomohiro Matsuyama <tomo@cx4a.org>
- Stefan Monnier <monnier@iro.umontreal.ca>
- Juanma Barranquero <lekktu@gmail.com>
+ Stefan Monnier <monnier@iro.umontreal.ca>
+ Juanma Barranquero <lekktu@gmail.com>
* profiler.c: New file.
* Makefile.in (base_obj): Add profiler.o.
@@ -11469,9 +12781,9 @@
to denote vector blocks. Adjust users (live_vector_p,
mark_maybe_pointer, valid_lisp_object_p) accordingly.
(COMMON_MULTIPLE): Move outside #if USE_LSB_TAG.
- (VECTOR_BLOCK_SIZE, vroundup, VECTOR_BLOCK_BYTES),
- (VBLOCK_BYTES_MIN, VBLOCK_BYTES_MAX, VECTOR_MAX_FREE_LIST_INDEX),
- (VECTOR_FREE_LIST_FLAG, ADVANCE, VINDEX, SETUP_ON_FREE_LIST),
+ (VECTOR_BLOCK_SIZE, vroundup, VECTOR_BLOCK_BYTES)
+ (VBLOCK_BYTES_MIN, VBLOCK_BYTES_MAX, VECTOR_MAX_FREE_LIST_INDEX)
+ (VECTOR_FREE_LIST_FLAG, ADVANCE, VINDEX, SETUP_ON_FREE_LIST)
(VECTOR_SIZE, VECTOR_IN_BLOCK): New macros.
(roundup_size): New constant.
(struct vector_block): New data type.
diff --git a/src/ChangeLog.10 b/src/ChangeLog.10
index 508a2a9dd4c..57c1cbf1299 100644
--- a/src/ChangeLog.10
+++ b/src/ChangeLog.10
@@ -1865,7 +1865,7 @@
2006-10-07 Ralf Angeli <angeli@caeruleus.net>
- * w32fns.c (w32_createwindow): Honour left and top positions if
+ * w32fns.c (w32_createwindow): Honor left and top positions if
supplied explicitly.
2006-10-06 Kim F. Storm <storm@cua.dk>
diff --git a/src/ChangeLog.11 b/src/ChangeLog.11
index 1195a8f9592..a67dd2cc458 100644
--- a/src/ChangeLog.11
+++ b/src/ChangeLog.11
@@ -14366,7 +14366,7 @@
2009-01-10 Chong Yidong <cyd@stupidchicken.com>
* xdisp.c (pos_visible_p): When iterator stops on the last glyph
- of a display vector, backtrack.
+ of a display vector, backtrack. (Bug#1810)
(try_window_reusing_current_matrix): Check glyph type before
referencing charpos member.
diff --git a/src/Makefile.in b/src/Makefile.in
index eeb2b88bf32..86e5aca36ec 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -137,6 +137,7 @@ LIBOTF_LIBS = @LIBOTF_LIBS@
M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@
M17N_FLT_LIBS = @M17N_FLT_LIBS@
+LIB_ACL=@LIB_ACL@
LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@
LIB_EACCESS=@LIB_EACCESS@
LIB_FDATASYNC=@LIB_FDATASYNC@
@@ -155,6 +156,11 @@ SETTINGS_LIBS = @SETTINGS_LIBS@
## gtkutil.o if USE_GTK, else empty.
GTK_OBJ=@GTK_OBJ@
+## gfilenotify.o if HAVE_GFILENOTIFY.
+## inotify.o if HAVE_INOTIFY.
+## w32notify.o if HAVE_W32NOTIFY.
+NOTIFY_OBJ = @NOTIFY_OBJ@
+
## -ltermcap, or -lncurses, or -lcurses, or "".
LIBS_TERMCAP=@LIBS_TERMCAP@
## terminfo.o if TERMINFO, else tparam.o.
@@ -232,6 +238,12 @@ IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
+XRANDR_LIBS = @XRANDR_LIBS@
+XRANDR_CFLAGS = @XRANDR_CFLAGS@
+
+XINERAMA_LIBS = @XINERAMA_LIBS@
+XINERAMA_CFLAGS = @XINERAMA_CFLAGS@
+
## widget.o if USE_X_TOOLKIT, otherwise empty.
WIDGET_OBJ=@WIDGET_OBJ@
@@ -260,10 +272,13 @@ W32_OBJ=@W32_OBJ@
W32_LIBS=@W32_LIBS@
## emacs.res if HAVE_W32
-W32_RES=@W32_RES@
+EMACSRES = @EMACSRES@
+## emacs-*.manifest if HAVE_W32
+EMACS_MANIFEST = @EMACS_MANIFEST@
## If HAVE_W32, compiler arguments for including
## the resource file in the binary.
-## XXX -Wl,-b -Wl,pe-i386 -Wl,emacs.res
+## Cygwin: -Wl,emacs.res
+## MinGW: emacs.res
W32_RES_LINK=@W32_RES_LINK@
## Empty if !HAVE_X_WINDOWS
@@ -272,6 +287,9 @@ W32_RES_LINK=@W32_RES_LINK@
## else xfont.o
FONT_OBJ=@FONT_OBJ@
+## Empty for MinGW, cm.o for the rest.
+CM_OBJ=@CM_OBJ@
+
LIBGPM = @LIBGPM@
## -lresolv, or empty.
@@ -282,8 +300,6 @@ LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
-LIBACL_LIBS = @LIBACL_LIBS@
-
LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
INTERVALS_H = dispextern.h intervals.h composite.h
@@ -292,6 +308,14 @@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
RUN_TEMACS = `/bin/pwd`/temacs
+## Invoke ../nt/addsection for MinGW, ":" elsewhere.
+TEMACS_POST_LINK = @TEMACS_POST_LINK@
+ADDSECTION = @ADDSECTION@
+EMACS_HEAPSIZE = @EMACS_HEAPSIZE@
+MINGW_TEMACS_POST_LINK = \
+ mv temacs$(EXEEXT) temacs.tmp; \
+ ../nt/addsection temacs.tmp temacs$(EXEEXT) EMHEAP $(EMACS_HEAPSIZE)
+
UNEXEC_OBJ = @UNEXEC_OBJ@
CANNOT_DUMP=@CANNOT_DUMP@
@@ -315,9 +339,9 @@ ALL_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
-I$(lib) -I$(srcdir)/../lib \
$(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
$(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
- $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \
+ $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) \
$(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
- $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \
+ $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
$(LIBGNUTLS_CFLAGS) \
$(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS)
ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
@@ -325,16 +349,16 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
.SUFFIXES: .m
.c.o:
@$(MKDEPDIR)
- $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) $<
.m.o:
@$(MKDEPDIR)
- $(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $(PROFILING_CFLAGS) $<
## lastfile must follow all files whose initialized data areas should
## be dumped as pure by dump-emacs.
base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
- cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
+ $(CM_OBJ) term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
emacs.o keyboard.o macros.o keymap.o sysdep.o \
buffer.o filelock.o insdel.o marker.o \
minibuf.o fileio.o dired.o \
@@ -344,7 +368,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
syntax.o $(UNEXEC_OBJ) bytecode.o \
process.o gnutls.o callproc.o \
region-cache.o sound.o atimer.o \
- doprnt.o intervals.o textprop.o composite.o xml.o inotify.o \
+ doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \
profiler.o \
thread.o systhread.o \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
@@ -373,9 +397,9 @@ VMLIMIT_OBJ=@VMLIMIT_OBJ@
## ralloc.o if !SYSTEM_MALLOC && REL_ALLOC, else empty.
RALLOC_OBJ=@RALLOC_OBJ@
-## Empty on Cygwin, lastfile.o elsewhere.
+## Empty on Cygwin and MinGW, lastfile.o elsewhere.
PRE_ALLOC_OBJ=@PRE_ALLOC_OBJ@
-## lastfile.o on Cygwin, empty elsewhere.
+## lastfile.o on Cygwin and MinGW, empty elsewhere.
POST_ALLOC_OBJ=@POST_ALLOC_OBJ@
## List of object files that make-docfile should not be told about.
@@ -383,7 +407,9 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
$(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS)
## All object files linked into temacs. $(VMLIMIT_OBJ) should be first.
-ALLOBJS = $(VMLIMIT_OBJ) $(obj) $(otherobj)
+## (On MinGW, firstfile.o should be before vm-limit.o.)
+FIRSTFILE_OBJ=@FIRSTFILE_OBJ@
+ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj)
## Configure inserts the file lisp.mk at this point, defining $lisp.
@lisp_frag@
@@ -392,13 +418,13 @@ ALLOBJS = $(VMLIMIT_OBJ) $(obj) $(otherobj)
## Construct full set of libraries to be linked.
LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
$(LIBX_OTHER) $(LIBSOUND) \
- $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \
+ $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(LIB_CLOCK_GETTIME) \
$(LIB_EACCESS) $(LIB_FDATASYNC) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
- $(LIB_EXECINFO) \
+ $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) \
$(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
- $(LIBACL_LIBS) $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \
+ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \
$(LIB_MATH)
all: emacs$(EXEEXT) $(OTHER_FILES)
@@ -412,7 +438,8 @@ $(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
## Strictly speaking, emacs does not depend directly on all of $lisp,
## since not all pieces are used on all platforms. But DOC depends
## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here.
-emacs$(EXEEXT): temacs$(EXEEXT) $(etc)/DOC $(lisp) $(leimdir)/leim-list.el
+emacs$(EXEEXT): temacs$(EXEEXT) $(ADDSECTION) \
+ $(etc)/DOC $(lisp) $(leimdir)/leim-list.el
if test "$(CANNOT_DUMP)" = "yes"; then \
rm -f emacs$(EXEEXT); \
ln temacs$(EXEEXT) emacs$(EXEEXT); \
@@ -464,10 +491,10 @@ $(lib)/libgnu.a: $(config_h)
cd $(lib) && $(MAKE) libgnu.a
temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \
- $(lib)/libgnu.a $(W32_RES)
+ $(lib)/libgnu.a $(EMACSRES)
$(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
- -o temacs $(ALLOBJS) $(lib)/libgnu.a $(LIBES) \
- $(W32_RES_LINK)
+ -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES)
+ $(TEMACS_POST_LINK)
test "$(CANNOT_DUMP)" = "yes" || \
test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT)
@@ -510,8 +537,9 @@ doc.o: buildobj.h
emacs.res: $(ntsource)/emacs.rc \
$(ntsource)/icons/emacs.ico \
- $(ntsource)/emacs-x86.manifest
- $(WINDRES) -O COFF -o $@ $(ntsource)/emacs.rc
+ $(ntsource)/$(EMACS_MANIFEST)
+ $(WINDRES) -O COFF --include-dir=$(srcdir)/../nt \
+ -o $@ $(ntsource)/emacs.rc
ns-app: emacs$(EXEEXT)
cd ../nextstep && $(MAKE) $(MFLAGS) all
@@ -525,6 +553,7 @@ mostlyclean:
rm -f bootstrap-emacs$(EXEEXT) emacs-$(version)$(EXEEXT)
rm -f buildobj.h
rm -f globals.h gl-stamp
+ rm -f *.res
clean: mostlyclean
rm -f emacs-*.*.*$(EXEEXT) emacs$(EXEEXT)
-rm -rf $(DEPDIR)
@@ -533,7 +562,7 @@ clean: mostlyclean
## It should remove all files generated during a compilation/bootstrap,
## but not things like config.status or TAGS.
bootstrap-clean: clean
- rm -f epaths.h config.h config.stamp stamp-oldxmenu ../etc/DOC-*
+ rm -f epaths.h config.h config.stamp stamp-h1 stamp-oldxmenu
if test -f ./.gdbinit; then \
mv ./.gdbinit ./.gdbinit.save; \
if test -f "$(srcdir)/.gdbinit"; then rm -f ./.gdbinit.save; \
diff --git a/src/alloc.c b/src/alloc.c
index 6da0ac428ab..b5885bdb283 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -319,19 +319,7 @@ static void *min_heap_address, *max_heap_address;
static struct mem_node mem_z;
#define MEM_NIL &mem_z
-static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t);
-static void lisp_free (void *);
-static bool live_vector_p (struct mem_node *, void *);
-static bool live_buffer_p (struct mem_node *, void *);
-static bool live_string_p (struct mem_node *, void *);
-static bool live_cons_p (struct mem_node *, void *);
-static bool live_symbol_p (struct mem_node *, void *);
-static bool live_float_p (struct mem_node *, void *);
-static bool live_misc_p (struct mem_node *, void *);
-static void mark_maybe_object (Lisp_Object);
-static void mark_memory (void *, void *);
#if GC_MARK_STACK || defined GC_MALLOC_CHECK
-static void mem_init (void);
static struct mem_node *mem_insert (void *, void *, enum mem_type);
static void mem_insert_fixup (struct mem_node *);
static void mem_rotate_left (struct mem_node *);
@@ -341,11 +329,6 @@ static void mem_delete_fixup (struct mem_node *);
static struct mem_node *mem_find (void *);
#endif
-
-#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
-static void check_gcpros (void);
-#endif
-
#endif /* GC_MARK_STACK || GC_MALLOC_CHECK */
#ifndef DEADP
@@ -1153,7 +1136,7 @@ lisp_align_free (void *block)
#define INTERVAL_BLOCK_SIZE \
((1020 - sizeof (struct interval_block *)) / sizeof (struct interval))
-/* Intervals are allocated in chunks in form of an interval_block
+/* Intervals are allocated in chunks in the form of an interval_block
structure. */
struct interval_block
@@ -3342,56 +3325,50 @@ free_misc (Lisp_Object misc)
total_free_markers++;
}
+/* Verify properties of Lisp_Save_Value's representation
+ that are assumed here and elsewhere. */
+
+verify (SAVE_UNUSED == 0);
+verify ((SAVE_INTEGER | SAVE_POINTER | SAVE_OBJECT) >> SAVE_SLOT_BITS == 0);
+
/* Return a Lisp_Save_Value object with the data saved according to
- FMT. Format specifiers are `i' for an integer, `p' for a pointer
- and `o' for Lisp_Object. Up to 4 objects can be specified. */
+ DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */
Lisp_Object
-make_save_value (const char *fmt, ...)
+make_save_value (enum Lisp_Save_Type save_type, ...)
{
va_list ap;
- int len = strlen (fmt);
+ int i;
Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
struct Lisp_Save_Value *p = XSAVE_VALUE (val);
- eassert (0 < len && len < 5);
- va_start (ap, fmt);
-
-#define INITX(index) \
- do { \
- if (len <= index) \
- p->type ## index = SAVE_UNUSED; \
- else \
- { \
- if (fmt[index] == 'i') \
- { \
- p->type ## index = SAVE_INTEGER; \
- p->data[index].integer = va_arg (ap, ptrdiff_t); \
- } \
- else if (fmt[index] == 'p') \
- { \
- p->type ## index = SAVE_POINTER; \
- p->data[index].pointer = va_arg (ap, void *); \
- } \
- else if (fmt[index] == 'o') \
- { \
- p->type ## index = SAVE_OBJECT; \
- p->data[index].object = va_arg (ap, Lisp_Object); \
- } \
- else \
- emacs_abort (); \
- } \
- } while (0)
+ eassert (0 < save_type
+ && (save_type < 1 << (SAVE_TYPE_BITS - 1)
+ || save_type == SAVE_TYPE_MEMORY));
+ p->save_type = save_type;
+ va_start (ap, save_type);
+ save_type &= ~ (1 << (SAVE_TYPE_BITS - 1));
+
+ for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS)
+ switch (save_type & ((1 << SAVE_SLOT_BITS) - 1))
+ {
+ case SAVE_POINTER:
+ p->data[i].pointer = va_arg (ap, void *);
+ break;
- INITX (0);
- INITX (1);
- INITX (2);
- INITX (3);
+ case SAVE_INTEGER:
+ p->data[i].integer = va_arg (ap, ptrdiff_t);
+ break;
-#undef INITX
+ case SAVE_OBJECT:
+ p->data[i].object = va_arg (ap, Lisp_Object);
+ break;
+
+ default:
+ emacs_abort ();
+ }
va_end (ap);
- p->area = 0;
return val;
}
@@ -3402,11 +3379,8 @@ make_save_pointer (void *pointer)
{
Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
struct Lisp_Save_Value *p = XSAVE_VALUE (val);
-
- p->area = 0;
- p->type0 = SAVE_POINTER;
+ p->save_type = SAVE_POINTER;
p->data[0].pointer = pointer;
- p->type1 = p->type2 = p->type3 = SAVE_UNUSED;
return val;
}
@@ -5197,7 +5171,6 @@ returns nil, because real GC can't be done.
See Info node `(elisp)Garbage Collection'. */)
(void)
{
- struct specbinding *bind;
struct buffer *nextb;
char stack_top_variable;
ptrdiff_t i;
@@ -5206,7 +5179,6 @@ See Info node `(elisp)Garbage Collection'. */)
EMACS_TIME start;
Lisp_Object retval = Qnil;
size_t tot_before = 0;
- struct backtrace backtrace;
if (abort_on_gc)
emacs_abort ();
@@ -5217,12 +5189,7 @@ See Info node `(elisp)Garbage Collection'. */)
return Qnil;
/* Record this function, so it appears on the profiler's backtraces. */
- backtrace.next = backtrace_list;
- backtrace.function = Qautomatic_gc;
- backtrace.args = &Qnil;
- backtrace.nargs = 0;
- backtrace.debug_on_exit = 0;
- backtrace_list = &backtrace;
+ record_in_backtrace (Qautomatic_gc, &Qnil, 0);
check_cons_list ();
@@ -5486,7 +5453,6 @@ See Info node `(elisp)Garbage Collection'. */)
malloc_probe (swept);
}
- backtrace_list = backtrace.next;
return retval;
}
@@ -5810,14 +5776,13 @@ mark_object (Lisp_Object arg)
case PVEC_WINDOW:
{
struct window *w = (struct window *) ptr;
- bool leaf = NILP (w->hchild) && NILP (w->vchild);
mark_vectorlike (ptr);
- /* Mark glyphs for leaf windows. Marking window
+ /* Mark glyph matrices, if any. Marking window
matrices is sufficient because frame matrices
use the same glyph memory. */
- if (leaf && w->current_matrix)
+ if (w->current_matrix)
{
mark_glyph_matrix (w->current_matrix);
mark_glyph_matrix (w->desired_matrix);
@@ -5949,12 +5914,11 @@ mark_object (Lisp_Object arg)
case Lisp_Misc_Save_Value:
XMISCANY (obj)->gcmarkbit = 1;
{
- register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
- /* If `area' is nonzero, `data[0].pointer' is the address
+ struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
+ /* If `save_type' is zero, `data[0].pointer' is the address
of a memory area containing `data[1].integer' potential
Lisp_Objects. */
-#if GC_MARK_STACK
- if (ptr->area)
+ if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY)
{
Lisp_Object *p = ptr->data[0].pointer;
ptrdiff_t nelt;
@@ -5962,17 +5926,12 @@ mark_object (Lisp_Object arg)
mark_maybe_object (*p);
}
else
-#endif /* GC_MARK_STACK */
{
/* Find Lisp_Objects in `data[N]' slots and mark them. */
- if (ptr->type0 == SAVE_OBJECT)
- mark_object (ptr->data[0].object);
- if (ptr->type1 == SAVE_OBJECT)
- mark_object (ptr->data[1].object);
- if (ptr->type2 == SAVE_OBJECT)
- mark_object (ptr->data[2].object);
- if (ptr->type3 == SAVE_OBJECT)
- mark_object (ptr->data[3].object);
+ int i;
+ for (i = 0; i < SAVE_VALUE_SLOTS; i++)
+ if (save_type (ptr, i) == SAVE_OBJECT)
+ mark_object (ptr->data[i].object);
}
}
break;
diff --git a/src/blockinput.h b/src/blockinput.h
index 192c813073d..6dc22c6f5dd 100644
--- a/src/blockinput.h
+++ b/src/blockinput.h
@@ -67,7 +67,7 @@ extern void unblock_input_to (int);
BLOCKINPUT_INLINE bool
input_blocked_p (void)
{
- return 0 < interrupt_input_blocked;
+ return interrupt_input_blocked > 0;
}
INLINE_HEADER_END
diff --git a/src/buffer.c b/src/buffer.c
index b7b471d6d46..e78962e1550 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1770,7 +1770,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
since anything can happen within do_yes_or_no_p. */
/* Don't kill the minibuffer now current. */
- if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
+ if (EQ (buffer, XWINDOW (minibuf_window)->contents))
return Qnil;
/* When we kill an ordinary buffer which shares it's buffer text
@@ -1821,7 +1821,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
/* If the buffer now current is shown in the minibuffer and our buffer
is the sole other buffer give up. */
XSETBUFFER (tem, current_buffer);
- if (EQ (tem, XWINDOW (minibuf_window)->buffer)
+ if (EQ (tem, XWINDOW (minibuf_window)->contents)
&& EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
return Qnil;
@@ -2395,8 +2395,9 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
BUF_MARKERS(buf) should either be for `buf' or dead. */
eassert (!m->buffer);
}
- { /* Some of the C code expects that w->buffer == w->pointm->buffer.
- So since we just swapped the markers between the two buffers, we need
+ { /* Some of the C code expects that both window markers of a
+ live window points to that window's buffer. So since we
+ just swapped the markers between the two buffers, we need
to undo the effect of this swap for window markers. */
Lisp_Object w = Fselected_window (), ws = Qnil;
Lisp_Object buf1, buf2;
@@ -2406,12 +2407,19 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
{
ws = Fcons (w, ws);
if (MARKERP (XWINDOW (w)->pointm)
- && (EQ (XWINDOW (w)->buffer, buf1)
- || EQ (XWINDOW (w)->buffer, buf2)))
+ && (EQ (XWINDOW (w)->contents, buf1)
+ || EQ (XWINDOW (w)->contents, buf2)))
Fset_marker (XWINDOW (w)->pointm,
make_number
- (BUF_BEGV (XBUFFER (XWINDOW (w)->buffer))),
- XWINDOW (w)->buffer);
+ (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
+ XWINDOW (w)->contents);
+ if (MARKERP (XWINDOW (w)->start)
+ && (EQ (XWINDOW (w)->contents, buf1)
+ || EQ (XWINDOW (w)->contents, buf2)))
+ Fset_marker (XWINDOW (w)->start,
+ make_number
+ (XBUFFER (XWINDOW (w)->contents)->last_window_start),
+ XWINDOW (w)->contents);
w = Fnext_window (w, Qt, Qt);
}
}
@@ -3894,7 +3902,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
if (buffer_window_count (buf) > 0)
{
/* ... it's visible in other window than selected, */
- if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
+ if (buf != XBUFFER (XWINDOW (selected_window)->contents))
windows_or_buffers_changed = 1;
/* ... or if we modify an overlay at the end of the buffer
and so we cannot be sure that window end is still valid. */
@@ -5494,6 +5502,8 @@ This is the same as (default-value 'left-margin). */);
DEFVAR_BUFFER_DEFAULTS ("default-tab-width",
tab_width,
doc: /* Default value of `tab-width' for buffers that do not override it.
+NOTE: This controls the display width of a TAB character, and not
+the size of an indentation step.
This is the same as (default-value 'tab-width). */);
DEFVAR_BUFFER_DEFAULTS ("default-case-fold-search",
@@ -5685,6 +5695,8 @@ Linefeed indents to this column in Fundamental mode. */);
DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
Qintegerp,
doc: /* Distance between tab stops (for display of tab characters), in columns.
+NOTE: This controls the display width of a TAB character, and not
+the size of an indentation step.
This should be an integer greater than zero. */);
DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
@@ -5876,29 +5888,44 @@ See also the functions `display-table-slot' and `set-display-table-slot'. */);
DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols),
Qintegerp,
doc: /* Width of left marginal area for display of a buffer.
-A value of nil means no marginal area. */);
+A value of nil means no marginal area.
+
+Setting this variable does not take effect until a new buffer is displayed
+in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols),
Qintegerp,
doc: /* Width of right marginal area for display of a buffer.
-A value of nil means no marginal area. */);
+A value of nil means no marginal area.
+
+Setting this variable does not take effect until a new buffer is displayed
+in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width),
Qintegerp,
doc: /* Width of this buffer's left fringe (in pixels).
A value of 0 means no left fringe is shown in this buffer's window.
-A value of nil means to use the left fringe width from the window's frame. */);
+A value of nil means to use the left fringe width from the window's frame.
+
+Setting this variable does not take effect until a new buffer is displayed
+in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width),
Qintegerp,
doc: /* Width of this buffer's right fringe (in pixels).
A value of 0 means no right fringe is shown in this buffer's window.
-A value of nil means to use the right fringe width from the window's frame. */);
+A value of nil means to use the right fringe width from the window's frame.
+
+Setting this variable does not take effect until a new buffer is displayed
+in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("fringes-outside-margins", &BVAR (current_buffer, fringes_outside_margins),
Qnil,
doc: /* Non-nil means to display fringes outside display margins.
-A value of nil means to display fringes between margins and buffer text. */);
+A value of nil means to display fringes between margins and buffer text.
+
+Setting this variable does not take effect until a new buffer is displayed
+in a window. To make the change take effect, call `set-window-buffer'. */);
DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
Qintegerp,
diff --git a/src/bytecode.c b/src/bytecode.c
index 45fe5d49154..9e5f4d1434f 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -657,9 +657,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
the table clearer. */
#define LABEL(OP) [OP] = &&insn_ ## OP
-#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Woverride-init"
+#elif defined __clang__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Winitializer-overrides"
#endif
/* This is the dispatch table for the threaded interpreter. */
@@ -673,7 +676,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
#undef DEFINE
};
-#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) || defined __clang__
# pragma GCC diagnostic pop
#endif
diff --git a/src/callint.c b/src/callint.c
index 212dd2e3d62..0651b68dc05 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -34,6 +34,7 @@ static Lisp_Object Qcommand_debug_status;
static Lisp_Object Qenable_recursive_minibuffers;
static Lisp_Object Qhandle_shift_selection;
+static Lisp_Object Qread_number;
Lisp_Object Qmouse_leave_buffer_hook;
@@ -250,6 +251,9 @@ invoke it. If KEYS is omitted or nil, the return value of
`this-command-keys-vector' is used. */)
(Lisp_Object function, Lisp_Object record_flag, Lisp_Object keys)
{
+ /* `args' will contain the array of arguments to pass to the function.
+ `visargs' will contain the same list but in a nicer form, so that if we
+ pass it to `Fformat' it will be understandable to a human. */
Lisp_Object *args, *visargs;
Lisp_Object specs;
Lisp_Object filter_specs;
@@ -683,29 +687,10 @@ invoke it. If KEYS is omitted or nil, the return value of
if (!NILP (prefix_arg))
goto have_prefix_arg;
case 'n': /* Read number from minibuffer. */
- {
- bool first = 1;
- do
- {
- Lisp_Object str;
- if (! first)
- {
- message1 ("Please enter a number.");
- sit_for (make_number (1), 0, 0);
- }
- first = 0;
-
- str = Fread_from_minibuffer (callint_message,
- Qnil, Qnil, Qnil, Qnil, Qnil,
- Qnil);
- if (! STRINGP (str) || SCHARS (str) == 0)
- args[i] = Qnil;
- else
- args[i] = Fread (str);
- }
- while (! NUMBERP (args[i]));
- }
- visargs[i] = args[i];
+ args[i] = call1 (Qread_number, callint_message);
+ /* Passing args[i] directly stimulates compiler bug. */
+ teml = args[i];
+ visargs[i] = Fnumber_to_string (teml);
break;
case 'P': /* Prefix arg in raw form. Does no I/O. */
@@ -754,12 +739,12 @@ invoke it. If KEYS is omitted or nil, the return value of
break;
case 'x': /* Lisp expression read but not evaluated. */
- args[i] = Fread_minibuffer (callint_message, Qnil);
+ args[i] = call1 (intern ("read-minibuffer"), callint_message);
visargs[i] = last_minibuf_string;
break;
case 'X': /* Lisp expression read and evaluated. */
- args[i] = Feval_minibuffer (callint_message, Qnil);
+ args[i] = call1 (intern ("eval-minibuffer"), callint_message);
visargs[i] = last_minibuf_string;
break;
@@ -811,6 +796,8 @@ invoke it. If KEYS is omitted or nil, the return value of
if (arg_from_tty || !NILP (record_flag))
{
+ /* We don't need `visargs' any more, so let's recycle it since we need
+ an array of just the same size. */
visargs[0] = function;
for (i = 1; i < nargs; i++)
{
@@ -903,6 +890,7 @@ syms_of_callint (void)
DEFSYM (Qminus, "-");
DEFSYM (Qplus, "+");
DEFSYM (Qhandle_shift_selection, "handle-shift-selection");
+ DEFSYM (Qread_number, "read-number");
DEFSYM (Qcall_interactively, "call-interactively");
DEFSYM (Qcommand_debug_status, "command-debug-status");
DEFSYM (Qenable_recursive_minibuffers, "enable-recursive-minibuffers");
diff --git a/src/callproc.c b/src/callproc.c
index 9132c0dd976..745d58c45f4 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1,5 +1,5 @@
/* Synchronous subprocess invocation for GNU Emacs.
- Copyright (C) 1985-1988, 1993-1995, 1999-2012
+ Copyright (C) 1985-1988, 1993-1995, 1999-2013
Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -125,7 +125,7 @@ record_kill_process (struct Lisp_Process *p)
static Lisp_Object
call_process_kill (Lisp_Object ignored)
{
- if (0 <= synch_process_fd)
+ if (synch_process_fd >= 0)
emacs_close (synch_process_fd);
if (synch_process_pid)
@@ -173,7 +173,7 @@ call_process_cleanup (Lisp_Object arg)
}
#endif
- if (0 <= synch_process_fd)
+ if (synch_process_fd >= 0)
emacs_close (synch_process_fd);
#ifdef MSDOS
@@ -190,11 +190,11 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0,
doc: /* Call PROGRAM synchronously in separate process.
The remaining arguments are optional.
The program's input comes from file INFILE (nil means `/dev/null').
-Insert output in BUFFER before point; t means current buffer; nil for BUFFER
+Insert output in DESTINATION before point; t means current buffer; nil for DESTINATION
means discard it; 0 means discard and don't wait; and `(:file FILE)', where
FILE is a file name string, means that it should be written to that file
\(if the file already exists it is overwritten).
-BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
+DESTINATION can also have the form (REAL-BUFFER STDERR-FILE); in that case,
REAL-BUFFER says what to do with standard output, as above,
while STDERR-FILE says what to do with standard error in the child.
STDERR-FILE may be nil (discard standard error output),
@@ -207,12 +207,12 @@ If executable PROGRAM can't be found as an executable, `call-process'
signals a Lisp error. `call-process' reports errors in execution of
the program only through its return and output.
-If BUFFER is 0, `call-process' returns immediately with value nil.
+If DESTINATION is 0, `call-process' returns immediately with value nil.
Otherwise it waits for PROGRAM to terminate
and returns a numeric exit status or a signal description string.
If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
-usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
+usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
Lisp_Object infile, buffer, current_dir, path;
@@ -682,7 +682,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
child_errno = errno;
- if (0 < pid)
+ if (pid > 0)
{
if (INTEGERP (buffer))
record_deleted_pid (pid);
diff --git a/src/casetab.c b/src/casetab.c
index 76f72b26db3..5f3c8db2869 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -246,7 +246,7 @@ void
init_casetab_once (void)
{
register int i;
- Lisp_Object down, up;
+ Lisp_Object down, up, eqv;
DEFSYM (Qcase_table, "case-table");
/* Intern this now in case it isn't already done.
@@ -275,13 +275,21 @@ init_casetab_once (void)
for (i = 0; i < 128; i++)
{
+ int c = (i >= 'a' && i <= 'z') ? i + ('A' - 'a') : i;
+ CHAR_TABLE_SET (up, i, make_number (c));
+ }
+
+ eqv = Fmake_char_table (Qcase_table, Qnil);
+
+ for (i = 0; i < 128; i++)
+ {
int c = ((i >= 'A' && i <= 'Z') ? i + ('a' - 'A')
: ((i >= 'a' && i <= 'z') ? i + ('A' - 'a')
: i));
- CHAR_TABLE_SET (up, i, make_number (c));
+ CHAR_TABLE_SET (eqv, i, make_number (c));
}
- set_char_table_extras (down, 2, Fcopy_sequence (up));
+ set_char_table_extras (down, 2, eqv);
/* Fill in what isn't filled in. */
set_case_table (down, 1);
diff --git a/src/ccl.c b/src/ccl.c
index 7f77e1d22fa..8fec18296a6 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -2130,7 +2130,7 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
produced_chars += ccl.produced;
offset = outp - outbuf;
shortfall = ccl.produced * max_expansion - (outbufsize - offset);
- if (0 < shortfall)
+ if (shortfall > 0)
{
outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1);
outp = outbuf + offset;
diff --git a/src/cm.c b/src/cm.c
index 3a5f927eda3..481ac15e435 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -214,7 +214,7 @@ calccost (struct tty_display_info *tty,
if (doit)
do
emacs_tputs (tty, p, 1, cmputc);
- while (0 < --deltay);
+ while (--deltay > 0);
x:
if ((deltax = dstx - srcx) == 0)
goto done;
@@ -297,7 +297,7 @@ fail:
if (doit)
do
emacs_tputs (tty, p, 1, cmputc);
- while (0 < --deltax);
+ while (--deltax > 0);
done:
return totalcost;
}
diff --git a/src/coding.c b/src/coding.c
index 6cfcec905a1..42fd81b6322 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -1125,6 +1125,14 @@ alloc_destination (struct coding_system *coding, ptrdiff_t nbytes,
*buf++ = id; \
} while (0)
+
+/* Bitmasks for coding->eol_seen. */
+
+#define EOL_SEEN_NONE 0
+#define EOL_SEEN_LF 1
+#define EOL_SEEN_CR 2
+#define EOL_SEEN_CRLF 4
+
/*** 2. Emacs' internal format (emacs-utf-8) ***/
@@ -1147,6 +1155,9 @@ alloc_destination (struct coding_system *coding, ptrdiff_t nbytes,
#define UTF_8_BOM_2 0xBB
#define UTF_8_BOM_3 0xBF
+/* Unlike the other detect_coding_XXX, this function counts number of
+ characters and check EOL format. */
+
static bool
detect_coding_utf_8 (struct coding_system *coding,
struct coding_detection_info *detect_info)
@@ -1156,11 +1167,23 @@ detect_coding_utf_8 (struct coding_system *coding,
bool multibytep = coding->src_multibyte;
ptrdiff_t consumed_chars = 0;
bool bom_found = 0;
- bool found = 0;
+ int nchars = coding->head_ascii;
+ int eol_seen = coding->eol_seen;
detect_info->checked |= CATEGORY_MASK_UTF_8;
/* A coding system of this category is always ASCII compatible. */
- src += coding->head_ascii;
+ src += nchars;
+
+ if (src == coding->source /* BOM should be at the head. */
+ && src + 3 < src_end /* BOM is 3-byte long. */
+ && src[0] == UTF_8_BOM_1
+ && src[1] == UTF_8_BOM_2
+ && src[2] == UTF_8_BOM_3)
+ {
+ bom_found = 1;
+ src += 3;
+ nchars++;
+ }
while (1)
{
@@ -1169,13 +1192,29 @@ detect_coding_utf_8 (struct coding_system *coding,
src_base = src;
ONE_MORE_BYTE (c);
if (c < 0 || UTF_8_1_OCTET_P (c))
- continue;
+ {
+ nchars++;
+ if (c == '\r')
+ {
+ if (src < src_end && *src == '\n')
+ {
+ eol_seen |= EOL_SEEN_CRLF;
+ src++;
+ nchars++;
+ }
+ else
+ eol_seen |= EOL_SEEN_CR;
+ }
+ else if (c == '\n')
+ eol_seen |= EOL_SEEN_LF;
+ continue;
+ }
ONE_MORE_BYTE (c1);
if (c1 < 0 || ! UTF_8_EXTRA_OCTET_P (c1))
break;
if (UTF_8_2_OCTET_LEADING_P (c))
{
- found = 1;
+ nchars++;
continue;
}
ONE_MORE_BYTE (c2);
@@ -1183,10 +1222,7 @@ detect_coding_utf_8 (struct coding_system *coding,
break;
if (UTF_8_3_OCTET_LEADING_P (c))
{
- found = 1;
- if (src_base == coding->source
- && c == UTF_8_BOM_1 && c1 == UTF_8_BOM_2 && c2 == UTF_8_BOM_3)
- bom_found = 1;
+ nchars++;
continue;
}
ONE_MORE_BYTE (c3);
@@ -1194,7 +1230,7 @@ detect_coding_utf_8 (struct coding_system *coding,
break;
if (UTF_8_4_OCTET_LEADING_P (c))
{
- found = 1;
+ nchars++;
continue;
}
ONE_MORE_BYTE (c4);
@@ -1202,7 +1238,7 @@ detect_coding_utf_8 (struct coding_system *coding,
break;
if (UTF_8_5_OCTET_LEADING_P (c))
{
- found = 1;
+ nchars++;
continue;
}
break;
@@ -1219,14 +1255,17 @@ detect_coding_utf_8 (struct coding_system *coding,
if (bom_found)
{
/* The first character 0xFFFE doesn't necessarily mean a BOM. */
- detect_info->found |= CATEGORY_MASK_UTF_8_SIG | CATEGORY_MASK_UTF_8_NOSIG;
+ detect_info->found |= CATEGORY_MASK_UTF_8_AUTO | CATEGORY_MASK_UTF_8_SIG | CATEGORY_MASK_UTF_8_NOSIG;
}
else
{
detect_info->rejected |= CATEGORY_MASK_UTF_8_SIG;
- if (found)
- detect_info->found |= CATEGORY_MASK_UTF_8_NOSIG;
+ if (nchars < src_end - coding->source)
+ /* The found characters are less than source bytes, which
+ means that we found a valid non-ASCII characters. */
+ detect_info->found |= CATEGORY_MASK_UTF_8_AUTO | CATEGORY_MASK_UTF_8_NOSIG;
}
+ coding->detected_utf8_chars = nchars;
return 1;
}
@@ -3887,6 +3926,14 @@ decode_coding_iso_2022 (struct coding_system *coding)
*charbuf++ = c < 0 ? -c : ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
char_offset++;
coding->errors++;
+ /* Reset the invocation and designation status to the safest
+ one; i.e. designate ASCII to the graphic register 0, and
+ invoke that register to the graphic plane 0. This typically
+ helps the case that an designation sequence for ASCII "ESC (
+ B" is somehow broken (e.g. broken by a newline). */
+ CODING_ISO_INVOCATION (coding, 0) = 0;
+ CODING_ISO_DESIGNATION (coding, 0) = charset_ascii;
+ charset_id_0 = charset_ascii;
continue;
break_loop:
@@ -5614,7 +5661,6 @@ setup_coding_system (Lisp_Object coding_system, struct coding_system *coding)
eol_type = inhibit_eol_conversion ? Qunix : CODING_ID_EOL_TYPE (coding->id);
coding->mode = 0;
- coding->head_ascii = -1;
if (VECTORP (eol_type))
coding->common_flags = (CODING_REQUIRE_DECODING_MASK
| CODING_REQUIRE_DETECTION_MASK);
@@ -6066,51 +6112,40 @@ complement_process_encoding_system (Lisp_Object coding_system)
*/
-#define EOL_SEEN_NONE 0
-#define EOL_SEEN_LF 1
-#define EOL_SEEN_CR 2
-#define EOL_SEEN_CRLF 4
+static Lisp_Object adjust_coding_eol_type (struct coding_system *coding,
+ int eol_seen);
-static Lisp_Object adjust_coding_eol_type (struct coding_system *coding, int eol_seen);
+/* Return the number of ASCII characters at the head of the source.
+ By side effects, set coding->head_ascii and update
+ coding->eol_seen. The value of coding->eol_seen is "logical or" of
+ EOL_SEEN_LF, EOL_SEEN_CR, and EOL_SEEN_CRLF, but the value is
+ reliable only when all the source bytes are ASCII. */
-
-/* Return 1 if all the source bytes are ASCII, and return 0 otherwize.
- By side effects, set coding->head_ascii and coding->eol_seen. The
- value of coding->eol_seen is "logical or" of EOL_SEEN_LF,
- EOL_SEEN_CR, and EOL_SEEN_CRLF, but the value is reliable only when
- all the source bytes are ASCII. */
-
-static bool
-detect_ascii (struct coding_system *coding)
+static int
+check_ascii (struct coding_system *coding)
{
const unsigned char *src, *end;
Lisp_Object eol_type = CODING_ID_EOL_TYPE (coding->id);
- int eol_seen;
+ int eol_seen = coding->eol_seen;
- eol_seen = (VECTORP (eol_type) ? EOL_SEEN_NONE
- : EQ (eol_type, Qunix) ? EOL_SEEN_LF
- : EQ (eol_type, Qdos) ? EOL_SEEN_CRLF
- : EOL_SEEN_CR);
coding_set_source (coding);
src = coding->source;
end = src + coding->src_bytes;
- if (inhibit_eol_conversion)
+ if (inhibit_eol_conversion
+ || SYMBOLP (eol_type))
{
/* We don't have to check EOL format. */
- while (src < end && !( *src & 0x80)) src++;
- eol_seen = EOL_SEEN_LF;
- adjust_coding_eol_type (coding, eol_seen);
- }
- else if (eol_seen != EOL_SEEN_NONE)
- {
- /* We don't have to check EOL format either. */
- while (src < end && !(*src & 0x80)) src++;
+ while (src < end && !( *src & 0x80))
+ {
+ if (*src++ == '\n')
+ eol_seen |= EOL_SEEN_LF;
+ }
}
else
{
- end--; /* We look ahead one byte. */
+ end--; /* We look ahead one byte for "CR LF". */
while (src < end)
{
int c = *src;
@@ -6118,6 +6153,69 @@ detect_ascii (struct coding_system *coding)
if (c & 0x80)
break;
src++;
+ if (c == '\r')
+ {
+ if (*src == '\n')
+ {
+ eol_seen |= EOL_SEEN_CRLF;
+ src++;
+ }
+ else
+ eol_seen |= EOL_SEEN_CR;
+ }
+ else if (c == '\n')
+ eol_seen |= EOL_SEEN_LF;
+ }
+ if (src == end)
+ {
+ int c = *src;
+
+ /* All bytes but the last one C are ASCII. */
+ if (! (c & 0x80))
+ {
+ if (c == '\r')
+ eol_seen |= EOL_SEEN_CR;
+ else if (c == '\n')
+ eol_seen |= EOL_SEEN_LF;
+ src++;
+ }
+ }
+ }
+ coding->head_ascii = src - coding->source;
+ coding->eol_seen = eol_seen;
+ return (coding->head_ascii);
+}
+
+
+/* Return the number of characters at the source if all the bytes are
+ valid UTF-8 (of Unicode range). Otherwise, return -1. By side
+ effects, update coding->eol_seen. The value of coding->eol_seen is
+ "logical or" of EOL_SEEN_LF, EOL_SEEN_CR, and EOL_SEEN_CRLF, but
+ the value is reliable only when all the source bytes are valid
+ UTF-8. */
+
+static int
+check_utf_8 (struct coding_system *coding)
+{
+ const unsigned char *src, *end;
+ int eol_seen;
+ int nchars = coding->head_ascii;
+
+ if (coding->head_ascii < 0)
+ check_ascii (coding);
+ else
+ coding_set_source (coding);
+ src = coding->source + coding->head_ascii;
+ /* We look ahead one byte for CR LF. */
+ end = coding->source + coding->src_bytes - 1;
+ eol_seen = coding->eol_seen;
+ while (src < end)
+ {
+ int c = *src;
+
+ if (UTF_8_1_OCTET_P (*src))
+ {
+ src++;
if (c < 0x20)
{
if (c == '\r')
@@ -6126,6 +6224,7 @@ detect_ascii (struct coding_system *coding)
{
eol_seen |= EOL_SEEN_CRLF;
src++;
+ nchars++;
}
else
eol_seen |= EOL_SEEN_CR;
@@ -6134,27 +6233,58 @@ detect_ascii (struct coding_system *coding)
eol_seen |= EOL_SEEN_LF;
}
}
- if (src > end)
- /* The last two bytes are CR LF, which means that we have
- scanned all bytes. */
- end++;
- else if (src == end)
+ else if (UTF_8_2_OCTET_LEADING_P (c))
{
- end++;
- if (! (*src & 0x80))
- {
- if (*src == '\r')
- eol_seen |= EOL_SEEN_CR;
- else if (*src == '\n')
- eol_seen |= EOL_SEEN_LF;
- src++;
- }
+ if (c < 0xC2 /* overlong sequence */
+ || src + 1 >= end
+ || ! UTF_8_EXTRA_OCTET_P (src[1]))
+ return -1;
+ src += 2;
}
- adjust_coding_eol_type (coding, eol_seen);
+ else if (UTF_8_3_OCTET_LEADING_P (c))
+ {
+ if (src + 2 >= end
+ || ! (UTF_8_EXTRA_OCTET_P (src[1])
+ && UTF_8_EXTRA_OCTET_P (src[2])))
+ return -1;
+ c = (((c & 0xF) << 12)
+ | ((src[1] & 0x3F) << 6) | (src[2] & 0x3F));
+ if (c < 0x800 /* overlong sequence */
+ || (c >= 0xd800 && c < 0xe000)) /* surrogates (invalid) */
+ return -1;
+ src += 3;
+ }
+ else if (UTF_8_4_OCTET_LEADING_P (c))
+ {
+ if (src + 3 >= end
+ || ! (UTF_8_EXTRA_OCTET_P (src[1])
+ && UTF_8_EXTRA_OCTET_P (src[2])
+ && UTF_8_EXTRA_OCTET_P (src[3])))
+ return -1;
+ c = (((c & 0x7) << 18) | ((src[1] & 0x3F) << 12)
+ | ((src[2] & 0x3F) << 6) | (src[3] & 0x3F));
+ if (c < 0x10000 /* overlong sequence */
+ || c >= 0x110000) /* non-Unicode character */
+ return -1;
+ src += 4;
+ }
+ else
+ return -1;
+ nchars++;
+ }
+
+ if (src == end)
+ {
+ if (! UTF_8_1_OCTET_P (*src))
+ return -1;
+ nchars++;
+ if (*src == '\r')
+ eol_seen |= EOL_SEEN_CR;
+ else if (*src == '\n')
+ eol_seen |= EOL_SEEN_LF;
}
- coding->head_ascii = src - coding->source;
coding->eol_seen = eol_seen;
- return (src == end);
+ return nchars;
}
@@ -6269,6 +6399,9 @@ adjust_coding_eol_type (struct coding_system *coding, int eol_seen)
Lisp_Object eol_type;
eol_type = CODING_ID_EOL_TYPE (coding->id);
+ if (! VECTORP (eol_type))
+ /* Already adjusted. */
+ return eol_type;
if (eol_seen & EOL_SEEN_LF)
{
coding->id = CODING_SYSTEM_ID (AREF (eol_type, 0));
@@ -6296,6 +6429,8 @@ detect_coding (struct coding_system *coding)
{
const unsigned char *src, *src_end;
unsigned int saved_mode = coding->mode;
+ Lisp_Object found = Qnil;
+ Lisp_Object eol_type = CODING_ID_EOL_TYPE (coding->id);
coding->consumed = coding->consumed_char = 0;
coding->produced = coding->produced_char = 0;
@@ -6303,6 +6438,7 @@ detect_coding (struct coding_system *coding)
src_end = coding->source + coding->src_bytes;
+ coding->eol_seen = EOL_SEEN_NONE;
/* If we have not yet decided the text encoding type, detect it
now. */
if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qundecided))
@@ -6312,7 +6448,6 @@ detect_coding (struct coding_system *coding)
bool null_byte_found = 0, eight_bit_found = 0;
coding->head_ascii = 0;
- coding->eol_seen = EOL_SEEN_NONE;
detect_info.checked = detect_info.found = detect_info.rejected = 0;
for (src = coding->source; src < src_end; src++)
{
@@ -6360,7 +6495,8 @@ detect_coding (struct coding_system *coding)
{
coding->eol_seen |= EOL_SEEN_CRLF;
src++;
- coding->head_ascii++;
+ if (! eight_bit_found)
+ coding->head_ascii++;
}
else
coding->eol_seen |= EOL_SEEN_CR;
@@ -6422,32 +6558,58 @@ detect_coding (struct coding_system *coding)
}
else if ((*(this->detector)) (coding, &detect_info)
&& detect_info.found & (1 << category))
- {
- if (category == coding_category_utf_16_auto)
- {
- if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
- category = coding_category_utf_16_le;
- else
- category = coding_category_utf_16_be;
- }
- break;
- }
+ break;
}
}
if (i < coding_category_raw_text)
- setup_coding_system (CODING_ID_NAME (this->id), coding);
+ {
+ if (category == coding_category_utf_8_auto)
+ {
+ Lisp_Object coding_systems;
+
+ coding_systems = AREF (CODING_ID_ATTRS (this->id),
+ coding_attr_utf_bom);
+ if (CONSP (coding_systems))
+ {
+ if (detect_info.found & CATEGORY_MASK_UTF_8_SIG)
+ found = XCAR (coding_systems);
+ else
+ found = XCDR (coding_systems);
+ }
+ else
+ found = CODING_ID_NAME (this->id);
+ }
+ else if (category == coding_category_utf_16_auto)
+ {
+ Lisp_Object coding_systems;
+
+ coding_systems = AREF (CODING_ID_ATTRS (this->id),
+ coding_attr_utf_bom);
+ if (CONSP (coding_systems))
+ {
+ if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
+ found = XCAR (coding_systems);
+ else if (detect_info.found & CATEGORY_MASK_UTF_16_BE)
+ found = XCDR (coding_systems);
+ }
+ else
+ found = CODING_ID_NAME (this->id);
+ }
+ else
+ found = CODING_ID_NAME (this->id);
+ }
else if (null_byte_found)
- setup_coding_system (Qno_conversion, coding);
+ found = Qno_conversion;
else if ((detect_info.rejected & CATEGORY_MASK_ANY)
== CATEGORY_MASK_ANY)
- setup_coding_system (Qraw_text, coding);
+ found = Qraw_text;
else if (detect_info.rejected)
for (i = 0; i < coding_category_raw_text; i++)
if (! (detect_info.rejected & (1 << coding_priorities[i])))
{
this = coding_categories + coding_priorities[i];
- setup_coding_system (CODING_ID_NAME (this->id), coding);
+ found = CODING_ID_NAME (this->id);
break;
}
}
@@ -6461,9 +6623,10 @@ detect_coding (struct coding_system *coding)
coding_systems
= AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_bom);
detect_info.found = detect_info.rejected = 0;
- if (detect_ascii (coding))
+ if (check_ascii (coding) == coding->src_bytes)
{
- setup_coding_system (XCDR (coding_systems), coding);
+ if (CONSP (coding_systems))
+ found = XCDR (coding_systems);
}
else
{
@@ -6471,9 +6634,9 @@ detect_coding (struct coding_system *coding)
&& detect_coding_utf_8 (coding, &detect_info))
{
if (detect_info.found & CATEGORY_MASK_UTF_8_SIG)
- setup_coding_system (XCAR (coding_systems), coding);
+ found = XCAR (coding_systems);
else
- setup_coding_system (XCDR (coding_systems), coding);
+ found = XCDR (coding_systems);
}
}
}
@@ -6487,16 +6650,28 @@ detect_coding (struct coding_system *coding)
= AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_bom);
detect_info.found = detect_info.rejected = 0;
coding->head_ascii = 0;
- coding->eol_seen = EOL_SEEN_NONE;
if (CONSP (coding_systems)
&& detect_coding_utf_16 (coding, &detect_info))
{
if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
- setup_coding_system (XCAR (coding_systems), coding);
+ found = XCAR (coding_systems);
else if (detect_info.found & CATEGORY_MASK_UTF_16_BE)
- setup_coding_system (XCDR (coding_systems), coding);
+ found = XCDR (coding_systems);
}
}
+
+ if (! NILP (found))
+ {
+ int specified_eol = (VECTORP (eol_type) ? EOL_SEEN_NONE
+ : EQ (eol_type, Qdos) ? EOL_SEEN_CRLF
+ : EQ (eol_type, Qmac) ? EOL_SEEN_CR
+ : EOL_SEEN_LF);
+
+ setup_coding_system (found, coding);
+ if (specified_eol != EOL_SEEN_NONE)
+ adjust_coding_eol_type (coding, specified_eol);
+ }
+
coding->mode = saved_mode;
}
@@ -7617,19 +7792,55 @@ decode_coding_gap (struct coding_system *coding,
coding->dst_pos_byte = PT_BYTE;
coding->dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
+ coding->head_ascii = -1;
+ coding->detected_utf8_chars = -1;
+ coding->eol_seen = EOL_SEEN_NONE;
if (CODING_REQUIRE_DETECTION (coding))
detect_coding (coding);
attrs = CODING_ID_ATTRS (coding->id);
- if (! disable_ascii_optimization)
- {
- if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs))
- && NILP (CODING_ATTR_POST_READ (attrs))
- && NILP (get_translation_table (attrs, 0, NULL))
- && (coding->head_ascii >= 0 /* We've already called detect_coding */
- ? coding->head_ascii == bytes
- : detect_ascii (coding)))
+ if (! disable_ascii_optimization
+ && ! coding->src_multibyte
+ && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs))
+ && NILP (CODING_ATTR_POST_READ (attrs))
+ && NILP (get_translation_table (attrs, 0, NULL)))
+ {
+ chars = coding->head_ascii;
+ if (chars < 0)
+ chars = check_ascii (coding);
+ if (chars != bytes)
+ {
+ /* There exists a non-ASCII byte. */
+ if (EQ (CODING_ATTR_TYPE (attrs), Qutf_8))
+ {
+ if (coding->detected_utf8_chars >= 0)
+ chars = coding->detected_utf8_chars;
+ else
+ chars = check_utf_8 (coding);
+ if (CODING_UTF_8_BOM (coding) != utf_without_bom
+ && coding->head_ascii == 0
+ && coding->source[0] == UTF_8_BOM_1
+ && coding->source[1] == UTF_8_BOM_2
+ && coding->source[2] == UTF_8_BOM_3)
+ {
+ chars--;
+ bytes -= 3;
+ coding->src_bytes -= 3;
+ }
+ }
+ else
+ chars = -1;
+ }
+ if (chars >= 0)
{
- if (coding->eol_seen == EOL_SEEN_CR)
+ Lisp_Object eol_type;
+
+ eol_type = CODING_ID_EOL_TYPE (coding->id);
+ if (VECTORP (eol_type))
+ {
+ if (coding->eol_seen != EOL_SEEN_NONE)
+ eol_type = adjust_coding_eol_type (coding, coding->eol_seen);
+ }
+ if (EQ (eol_type, Qmac))
{
unsigned char *src_end = GAP_END_ADDR;
unsigned char *src = src_end - coding->src_bytes;
@@ -7640,22 +7851,26 @@ decode_coding_gap (struct coding_system *coding,
src[-1] = '\n';
}
}
- else if (coding->eol_seen == EOL_SEEN_CRLF)
+ else if (EQ (eol_type, Qdos))
{
unsigned char *src = GAP_END_ADDR;
unsigned char *src_beg = src - coding->src_bytes;
unsigned char *dst = src;
+ ptrdiff_t diff;
while (src_beg < src)
{
*--dst = *--src;
- if (*src == '\n')
+ if (*src == '\n' && src > src_beg && src[-1] == '\r')
src--;
}
- bytes -= dst - src;
+ diff = dst - src;
+ bytes -= diff;
+ chars -= diff;
}
- coding->produced_char = coding->produced = bytes;
- insert_from_gap (bytes, bytes, 1);
+ coding->produced = bytes;
+ coding->produced_char = chars;
+ insert_from_gap (chars, bytes, 1);
return;
}
}
diff --git a/src/coding.h b/src/coding.h
index d40209be68f..d13fd42fe4f 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -444,6 +444,8 @@ struct coding_system
the eol format. */
ptrdiff_t head_ascii;
+ ptrdiff_t detected_utf8_chars;
+
/* Used internally in coding.c. See the comment of detect_ascii. */
int eol_seen;
diff --git a/src/data.c b/src/data.c
index 8a66cbe9197..c6cb1b43dd6 100644
--- a/src/data.c
+++ b/src/data.c
@@ -101,9 +101,10 @@ wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
}
void
-pure_write_error (void)
+pure_write_error (Lisp_Object obj)
{
- error ("Attempt to modify read-only object");
+ Fsignal (Qerror, Fcons (build_string ("Attempt to modify read-only object"),
+ Fcons (obj, Qnil)));
}
void
@@ -1106,40 +1107,6 @@ DEFUN ("set", Fset, Sset, 2, 2, 0,
return newval;
}
-/* Return true if SYMBOL currently has a let-binding
- which was made in the buffer that is now current. */
-
-static bool
-let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
-{
- struct specbinding *p;
-
- for (p = specpdl_ptr; p > specpdl; )
- if ((--p)->func == NULL
- && CONSP (p->symbol))
- {
- struct Lisp_Symbol *let_bound_symbol = XSYMBOL (XCAR (p->symbol));
- eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS);
- if (symbol == let_bound_symbol
- && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer)
- return 1;
- }
-
- return 0;
-}
-
-static bool
-let_shadows_global_binding_p (Lisp_Object symbol)
-{
- struct specbinding *p;
-
- for (p = specpdl_ptr; p > specpdl; )
- if ((--p)->func == NULL && EQ (p->symbol, symbol))
- return 1;
-
- return 0;
-}
-
/* Store the value NEWVAL into SYMBOL.
If buffer/frame-locality is an issue, WHERE specifies which context to use.
(nil stands for the current buffer/frame).
@@ -1878,17 +1845,18 @@ BUFFER defaults to the current buffer. */)
XSETBUFFER (tmp, buf);
XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
- for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
- {
- elt = XCAR (tail);
- if (EQ (variable, XCAR (elt)))
- {
- eassert (!blv->frame_local);
- eassert (blv_found (blv) || !EQ (blv->where, tmp));
- return Qt;
- }
- }
- eassert (!blv_found (blv) || !EQ (blv->where, tmp));
+ if (EQ (blv->where, tmp)) /* The binding is already loaded. */
+ return blv_found (blv) ? Qt : Qnil;
+ else
+ for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ if (EQ (variable, XCAR (elt)))
+ {
+ eassert (!blv->frame_local);
+ return Qt;
+ }
+ }
return Qnil;
}
case SYMBOL_FORWARDED:
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 863f7634eb5..3ec3c28431b 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -882,7 +882,7 @@ xd_retrieve_arg (int dtype, DBusMessageIter *iter)
#endif
{
dbus_uint32_t val;
- unsigned int pval = val;
+ unsigned int pval;
dbus_message_iter_get_basic (iter, &val);
pval = val;
XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
diff --git a/src/dired.c b/src/dired.c
index 0e37568f211..7bbfee7e5b0 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -258,7 +258,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
QUIT;
if (NILP (match)
- || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
+ || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0)
wanted = 1;
immediate_quit = 0;
@@ -517,8 +517,9 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
QUIT;
if (len < SCHARS (encoded_file)
- || 0 <= scmp (dp->d_name, SSDATA (encoded_file),
- SCHARS (encoded_file)))
+ || (scmp (dp->d_name, SSDATA (encoded_file),
+ SCHARS (encoded_file))
+ >= 0))
continue;
if (file_name_completion_stat (fd, dp, &st) < 0)
@@ -580,7 +581,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
if (skip < 0)
continue;
- if (0 <= scmp (dp->d_name + skip, p1, elt_len))
+ if (scmp (dp->d_name + skip, p1, elt_len) >= 0)
continue;
break;
}
@@ -602,9 +603,8 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
skip = len - SCHARS (elt);
if (skip < 0) continue;
- if (0 <= scmp (dp->d_name + skip,
- SSDATA (elt),
- SCHARS (elt)))
+ if (scmp (dp->d_name + skip, SSDATA (elt), SCHARS (elt))
+ >= 0)
continue;
break;
}
diff --git a/src/dispextern.h b/src/dispextern.h
index 46878745c07..50a32ffaf8f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -602,8 +602,8 @@ struct glyph_pool
2. Window glyph matrices on frames having frame glyph matrices.
Such matrices are sub-matrices of their corresponding frame matrix,
- i.e. frame glyph matrices and window glyph matrices share the same
- glyph memory which is allocated in form of a glyph_pool structure.
+ i.e., frame glyph matrices and window glyph matrices share the same
+ glyph memory, which is allocated in the form of a glyph_pool structure.
Glyph rows in such a window matrix are slices of frame matrix rows.
2. Free-standing window glyph matrices managing their own glyph
@@ -1384,7 +1384,7 @@ struct glyph_string
? current_mode_line_height \
: (MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \
? MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \
- : estimate_mode_line_height (XFRAME (W->frame), \
+ : estimate_mode_line_height (XFRAME ((W)->frame), \
CURRENT_MODE_LINE_FACE_ID (W))))
/* Return the current height of the header line of window W. If not
@@ -1397,7 +1397,7 @@ struct glyph_string
? current_header_line_height \
: (MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \
? MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \
- : estimate_mode_line_height (XFRAME (W->frame),\
+ : estimate_mode_line_height (XFRAME ((W)->frame), \
HEADER_LINE_FACE_ID)))
/* Return the height of the desired mode line of window W. */
@@ -1412,25 +1412,25 @@ struct glyph_string
/* Value is non-zero if window W wants a mode line. */
-#define WINDOW_WANTS_MODELINE_P(W) \
- (!MINI_WINDOW_P ((W)) \
- && !(W)->pseudo_window_p \
- && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
- && BUFFERP (W->buffer) \
- && !NILP (BVAR (XBUFFER (W->buffer), mode_line_format)) \
- && WINDOW_TOTAL_LINES (W) > 1)
+#define WINDOW_WANTS_MODELINE_P(W) \
+ (!MINI_WINDOW_P ((W)) \
+ && !(W)->pseudo_window_p \
+ && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
+ && BUFFERP ((W)->contents) \
+ && !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
+ && WINDOW_TOTAL_LINES (W) > 1)
/* Value is true if window W wants a header line. */
#define WINDOW_WANTS_HEADER_LINE_P(W) \
- (!MINI_WINDOW_P ((W)) \
+ (BUFFERP ((W)->contents) \
+ ? (!MINI_WINDOW_P ((W)) \
&& !(W)->pseudo_window_p \
&& FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
- && BUFFERP (W->buffer) \
- && !NILP (BVAR (XBUFFER (W->buffer), header_line_format)) \
- && WINDOW_TOTAL_LINES (W) > 1 \
- + !NILP (BVAR (XBUFFER (W->buffer), mode_line_format)))
-
+ && !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \
+ && WINDOW_TOTAL_LINES (W) > \
+ (1 + !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)))) \
+ : 0)
/* Return proper value to be used as baseline offset of font that has
ASCENT and DESCENT to draw characters by the font at the vertical
@@ -1592,13 +1592,13 @@ struct face
shadow colors derived from the background color of the face. */
enum face_box_type box;
+ /* Style of underlining. */
+ enum face_underline_type underline_type;
+
/* If `box' above specifies a 3D type, 1 means use box_color for
drawing shadows. */
unsigned use_box_color_for_shadows_p : 1;
- /* Style of underlining. */
- enum face_underline_type underline_type;
-
/* Non-zero if text in this face should be underlined, overlined,
strike-through or have a box drawn around it. */
unsigned underline_p : 1;
@@ -3186,7 +3186,15 @@ bool valid_image_p (Lisp_Object);
void prepare_image_for_display (struct frame *, struct image *);
ptrdiff_t lookup_image (struct frame *, Lisp_Object);
-unsigned long image_background (struct image *, struct frame *,
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_NS)
+#define RGB_PIXEL_COLOR unsigned long
+#endif
+
+#ifdef HAVE_NTGUI
+#define RGB_PIXEL_COLOR COLORREF
+#endif
+
+RGB_PIXEL_COLOR image_background (struct image *, struct frame *,
XImagePtr_or_DC ximg);
int image_background_transparent (struct image *, struct frame *,
XImagePtr_or_DC mask);
diff --git a/src/dispnew.c b/src/dispnew.c
index 47adab6b8f7..b4ca654a8f7 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -223,9 +223,9 @@ add_window_display_history (struct window *w, const char *msg, bool paused_p)
"%"pMu": window %p (`%s')%s\n%s",
history_tick++,
w,
- ((BUFFERP (w->buffer)
- && STRINGP (BVAR (XBUFFER (w->buffer), name)))
- ? SSDATA (BVAR (XBUFFER (w->buffer), name))
+ ((BUFFERP (w->contents)
+ && STRINGP (BVAR (XBUFFER (w->contents), name)))
+ ? SSDATA (BVAR (XBUFFER (w->contents), name))
: "???"),
paused_p ? " ***paused***" : "",
msg);
@@ -363,7 +363,7 @@ margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin
if (NUMBERP (margin))
{
- int width = XFASTINT (w->total_cols);
+ int width = w->total_cols;
double d = max (0, XFLOATINT (margin));
d = min (width / 2 - 1, d);
n = (int) ((double) total_glyphs / width * d);
@@ -794,11 +794,13 @@ clear_current_matrices (register struct frame *f)
if (f->current_matrix)
clear_glyph_matrix (f->current_matrix);
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Clear the matrix of the menu bar window, if such a window exists.
The menu bar window is currently used to display menus on X when
no toolkit support is compiled in. */
if (WINDOWP (f->menu_bar_window))
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
+#endif
/* Clear the matrix of the tool-bar window, if any. */
if (WINDOWP (f->tool_bar_window))
@@ -818,8 +820,10 @@ clear_desired_matrices (register struct frame *f)
if (f->desired_matrix)
clear_glyph_matrix (f->desired_matrix);
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
if (WINDOWP (f->menu_bar_window))
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
+#endif
if (WINDOWP (f->tool_bar_window))
clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
@@ -838,16 +842,8 @@ clear_window_matrices (struct window *w, bool desired_p)
{
while (w)
{
- if (!NILP (w->hchild))
- {
- eassert (WINDOWP (w->hchild));
- clear_window_matrices (XWINDOW (w->hchild), desired_p);
- }
- else if (!NILP (w->vchild))
- {
- eassert (WINDOWP (w->vchild));
- clear_window_matrices (XWINDOW (w->vchild), desired_p);
- }
+ if (WINDOWP (w->contents))
+ clear_window_matrices (XWINDOW (w->contents), desired_p);
else
{
if (desired_p)
@@ -1468,7 +1464,7 @@ check_matrix_invariants (struct window *w)
struct glyph_row *row = matrix->rows;
struct glyph_row *last_text_row = NULL;
struct buffer *saved = current_buffer;
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
int c;
/* This can sometimes happen for a fresh window. */
@@ -1632,7 +1628,7 @@ allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
vertically below other windows. */
in_horz_combination_p
= (!NILP (XWINDOW (window)->parent)
- && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
+ && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (XWINDOW (window)->parent)));
/* For WINDOW and all windows on the same level. */
do
@@ -1641,12 +1637,8 @@ allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
/* Get the dimension of the window sub-matrix for W, depending
on whether this is a combination or a leaf window. */
- if (!NILP (w->hchild))
- dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y,
- dim_only_p,
- window_change_flags);
- else if (!NILP (w->vchild))
- dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
+ if (WINDOWP (w->contents))
+ dim = allocate_matrices_for_frame_redisplay (w->contents, x, y,
dim_only_p,
window_change_flags);
else
@@ -1776,7 +1768,7 @@ required_matrix_width (struct window *w)
}
#endif /* HAVE_WINDOW_SYSTEM */
- return XINT (w->total_cols);
+ return w->total_cols;
}
@@ -1788,10 +1780,8 @@ allocate_matrices_for_window_redisplay (struct window *w)
{
while (w)
{
- if (!NILP (w->vchild))
- allocate_matrices_for_window_redisplay (XWINDOW (w->vchild));
- else if (!NILP (w->hchild))
- allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
+ if (WINDOWP (w->contents))
+ allocate_matrices_for_window_redisplay (XWINDOW (w->contents));
else
{
/* W is a leaf window. */
@@ -1863,18 +1853,12 @@ showing_window_margins_p (struct window *w)
{
while (w)
{
- if (!NILP (w->hchild))
+ if (WINDOWP (w->contents))
{
- if (showing_window_margins_p (XWINDOW (w->hchild)))
+ if (showing_window_margins_p (XWINDOW (w->contents)))
return 1;
}
- else if (!NILP (w->vchild))
- {
- if (showing_window_margins_p (XWINDOW (w->vchild)))
- return 1;
- }
- else if (!NILP (w->left_margin_cols)
- || !NILP (w->right_margin_cols))
+ else if (!NILP (w->left_margin_cols) || !NILP (w->right_margin_cols))
return 1;
w = NILP (w->next) ? 0 : XWINDOW (w->next);
@@ -1895,10 +1879,8 @@ fake_current_matrices (Lisp_Object window)
{
w = XWINDOW (window);
- if (!NILP (w->hchild))
- fake_current_matrices (w->hchild);
- else if (!NILP (w->vchild))
- fake_current_matrices (w->vchild);
+ if (WINDOWP (w->contents))
+ fake_current_matrices (w->contents);
else
{
int i;
@@ -2114,10 +2096,10 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
/* Set window dimensions to frame dimensions and allocate or
adjust glyph matrices of W. */
- wset_top_line (w, make_number (0));
- wset_left_col (w, make_number (0));
- wset_total_lines (w, make_number (FRAME_MENU_BAR_LINES (f)));
- wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f)));
+ w->top_line = 0;
+ w->left_col = 0;
+ w->total_lines = FRAME_MENU_BAR_LINES (f);
+ w->total_cols = FRAME_TOTAL_COLS (f);
allocate_matrices_for_window_redisplay (w);
}
#endif /* not USE_X_TOOLKIT && not USE_GTK */
@@ -2140,10 +2122,10 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
else
w = XWINDOW (f->tool_bar_window);
- wset_top_line (w, make_number (FRAME_MENU_BAR_LINES (f)));
- wset_left_col (w, make_number (0));
- wset_total_lines (w, make_number (FRAME_TOOL_BAR_LINES (f)));
- wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f)));
+ w->top_line = FRAME_MENU_BAR_LINES (f);
+ w->left_col = 0;
+ w->total_lines = FRAME_TOOL_BAR_LINES (f);
+ w->total_cols = FRAME_TOTAL_COLS (f);
allocate_matrices_for_window_redisplay (w);
}
#endif
@@ -2184,6 +2166,7 @@ free_glyphs (struct frame *f)
if (!NILP (f->root_window))
free_window_matrices (XWINDOW (f->root_window));
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Free the dummy window for menu bars without X toolkit and its
glyph matrices. */
if (!NILP (f->menu_bar_window))
@@ -2194,6 +2177,7 @@ free_glyphs (struct frame *f)
w->desired_matrix = w->current_matrix = NULL;
fset_menu_bar_window (f, Qnil);
}
+#endif
/* Free the tool bar window and its glyph matrices. */
if (!NILP (f->tool_bar_window))
@@ -2236,10 +2220,8 @@ free_window_matrices (struct window *w)
{
while (w)
{
- if (!NILP (w->hchild))
- free_window_matrices (XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- free_window_matrices (XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ free_window_matrices (XWINDOW (w->contents));
else
{
/* This is a leaf window. Free its memory and reset fields
@@ -2372,10 +2354,8 @@ build_frame_matrix_from_window_tree (struct glyph_matrix *matrix, struct window
{
while (w)
{
- if (!NILP (w->hchild))
- build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ build_frame_matrix_from_window_tree (matrix, XWINDOW (w->contents));
else
build_frame_matrix_from_leaf_window (matrix, w);
@@ -2639,10 +2619,8 @@ mirror_make_current (struct window *w, int frame_row)
{
while (w)
{
- if (!NILP (w->hchild))
- mirror_make_current (XWINDOW (w->hchild), frame_row);
- else if (!NILP (w->vchild))
- mirror_make_current (XWINDOW (w->vchild), frame_row);
+ if (WINDOWP (w->contents))
+ mirror_make_current (XWINDOW (w->contents), frame_row);
else
{
/* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
@@ -2738,8 +2716,8 @@ sync_window_with_frame_matrix_rows (struct window *w)
struct glyph_row *window_row, *window_row_end, *frame_row;
int left, right, x, width;
- /* Preconditions: W must be a leaf window on a tty frame. */
- eassert (NILP (w->hchild) && NILP (w->vchild));
+ /* Preconditions: W must be a live window on a tty frame. */
+ eassert (BUFFERP (w->contents));
eassert (!FRAME_WINDOW_P (f));
left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
@@ -2775,10 +2753,8 @@ frame_row_to_window (struct window *w, int row)
while (w && !found)
{
- if (!NILP (w->hchild))
- found = frame_row_to_window (XWINDOW (w->hchild), row);
- else if (!NILP (w->vchild))
- found = frame_row_to_window (XWINDOW (w->vchild), row);
+ if (WINDOWP (w->contents))
+ found = frame_row_to_window (XWINDOW (w->contents), row);
else if (row >= WINDOW_TOP_EDGE_LINE (w)
&& row < WINDOW_BOTTOM_EDGE_LINE (w))
found = w;
@@ -2806,11 +2782,8 @@ mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy
{
while (w)
{
- if (!NILP (w->hchild))
- mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
- nlines, copy_from, retained_p);
- else if (!NILP (w->vchild))
- mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
+ if (WINDOWP (w->contents))
+ mirror_line_dance (XWINDOW (w->contents), unchanged_at_top,
nlines, copy_from, retained_p);
else
{
@@ -2919,10 +2892,8 @@ check_window_matrix_pointers (struct window *w)
{
while (w)
{
- if (!NILP (w->hchild))
- check_window_matrix_pointers (XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- check_window_matrix_pointers (XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ check_window_matrix_pointers (XWINDOW (w->contents));
else
{
struct frame *f = XFRAME (w->frame);
@@ -3092,10 +3063,12 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
when pending input is detected. */
update_begin (f);
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Update the menu bar on X frames that don't have toolkit
support. */
if (WINDOWP (f->menu_bar_window))
update_window (XWINDOW (f->menu_bar_window), 1);
+#endif
/* Update the tool-bar window, if present. */
if (WINDOWP (f->tool_bar_window))
@@ -3186,10 +3159,8 @@ update_window_tree (struct window *w, bool force_p)
while (w && !paused_p)
{
- if (!NILP (w->hchild))
- paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
- else if (!NILP (w->vchild))
- paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
+ if (WINDOWP (w->contents))
+ paused_p |= update_window_tree (XWINDOW (w->contents), force_p);
else if (w->must_be_updated_p)
paused_p |= update_window (w, force_p);
@@ -3967,10 +3938,8 @@ set_window_update_flags (struct window *w, bool on_p)
{
while (w)
{
- if (!NILP (w->hchild))
- set_window_update_flags (XWINDOW (w->hchild), on_p);
- else if (!NILP (w->vchild))
- set_window_update_flags (XWINDOW (w->vchild), on_p);
+ if (WINDOWP (w->contents))
+ set_window_update_flags (XWINDOW (w->contents), on_p);
else
w->must_be_updated_p = on_p;
@@ -4451,7 +4420,7 @@ scrolling_window (struct window *w, bool header_line_p)
row_table[row_entry_pool[i].bucket] = NULL;
/* Value is 1 to indicate that we scrolled the display. */
- return 0 < nruns;
+ return nruns > 0;
}
@@ -5117,7 +5086,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
/* We used to set current_buffer directly here, but that does the
wrong thing with `face-remapping-alist' (bug#2044). */
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
itdata = bidi_shelve_cache ();
SET_TEXT_POS_FROM_MARKER (startp, w->start);
CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
@@ -5163,7 +5132,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
*dx = x0 + it.first_visible_x - it.current_x;
*dy = *y - it.current_y;
- string = w->buffer;
+ string = w->contents;
if (STRINGP (it.string))
string = it.string;
*pos = it.current;
@@ -5181,7 +5150,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
if (STRINGP (it.string))
BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
else
- BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->buffer),
+ BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->contents),
CHARPOS (pos->pos));
}
@@ -5583,7 +5552,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
FrameCols (FRAME_TTY (f)) = newwidth;
if (WINDOWP (f->tool_bar_window))
- wset_total_cols (XWINDOW (f->tool_bar_window), make_number (newwidth));
+ XWINDOW (f->tool_bar_window)->total_cols = newwidth;
}
FRAME_LINES (f) = newheight;
@@ -5725,7 +5694,11 @@ bitch_at_user (void)
if (noninteractive)
putchar (07);
else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
- error ("Keyboard macro terminated by a command ringing the bell");
+ {
+ const char *msg
+ = "Keyboard macro terminated by a command ringing the bell";
+ Fsignal (Quser_error, Fcons (build_string (msg), Qnil));
+ }
else
ring_bell (XFRAME (selected_frame));
}
@@ -5752,7 +5725,7 @@ additional wait period, in milliseconds; this is for backwards compatibility.
duration += XINT (milliseconds) / 1000.0;
}
- if (0 < duration)
+ if (duration > 0)
{
EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX),
@@ -5792,7 +5765,7 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
if (INTEGERP (timeout))
{
sec = XINT (timeout);
- if (! (0 < sec))
+ if (sec <= 0)
return Qt;
nsec = 0;
}
diff --git a/src/doc.c b/src/doc.c
index 7234fb38bf9..e45481944f0 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -58,7 +58,7 @@ read_bytecode_char (bool unreadflag)
}
/* Extract a doc string from a file. FILEPOS says where to get it.
- If it is an integer, use that position in the standard DOC-... file.
+ If it is an integer, use that position in the standard DOC file.
If it is (FILE . INTEGER), use FILE as the file name
and INTEGER as the position in that file.
But if INTEGER is negative, make it positive.
@@ -215,14 +215,20 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
if (CONSP (filepos))
{
int test = 1;
- if (get_doc_string_buffer[offset - test++] != ' ')
- return Qnil;
- while (get_doc_string_buffer[offset - test] >= '0'
- && get_doc_string_buffer[offset - test] <= '9')
- test++;
- if (get_doc_string_buffer[offset - test++] != '@'
- || get_doc_string_buffer[offset - test] != '#')
- return Qnil;
+ /* A dynamic docstring should be either at the very beginning of a "#@
+ comment" or right after a dynamic docstring delimiter (in case we
+ pack several such docstrings within the same comment). */
+ if (get_doc_string_buffer[offset - test] != '\037')
+ {
+ if (get_doc_string_buffer[offset - test++] != ' ')
+ return Qnil;
+ while (get_doc_string_buffer[offset - test] >= '0'
+ && get_doc_string_buffer[offset - test] <= '9')
+ test++;
+ if (get_doc_string_buffer[offset - test++] != '@'
+ || get_doc_string_buffer[offset - test] != '#')
+ return Qnil;
+ }
}
else
{
@@ -602,7 +608,7 @@ the same file name is found in the `doc-directory'. */)
while (*beg && c_isspace (*beg)) ++beg;
for (end = beg; *end && ! c_isspace (*end); ++end)
- if (*end == '/') beg = end+1; /* skip directory part */
+ if (*end == '/') beg = end + 1; /* Skip directory part. */
len = end - beg;
if (len > 4 && end[-4] == '.' && end[-3] == 'o')
diff --git a/src/editfns.c b/src/editfns.c
index f34c574cae3..cc6b4cff895 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -373,7 +373,7 @@ get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object o
if (NILP (object))
XSETBUFFER (object, current_buffer);
else if (WINDOWP (object))
- object = XWINDOW (object)->buffer;
+ object = XWINDOW (object)->contents;
if (!BUFFERP (object))
/* pos-property only makes sense in buffers right now, since strings
@@ -839,14 +839,14 @@ Lisp_Object
save_excursion_save (void)
{
return make_save_value
- ("oooo",
+ (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ,
Fpoint_marker (),
/* Do not copy the mark if it points to nowhere. */
(XMARKER (BVAR (current_buffer, mark))->buffer
? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
: Qnil),
/* Selected window if current buffer is shown in it, nil otherwise. */
- ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
+ (EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ())
? selected_window : Qnil),
BVAR (current_buffer, mark_active));
}
@@ -915,7 +915,7 @@ save_excursion_restore (Lisp_Object info)
tem = XSAVE_OBJECT (info, 2);
if (WINDOWP (tem)
&& !EQ (tem, selected_window)
- && (tem1 = XWINDOW (tem)->buffer,
+ && (tem1 = XWINDOW (tem)->contents,
(/* Window is live... */
BUFFERP (tem1)
/* ...and it shows the current buffer. */
@@ -1946,7 +1946,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
EMACS_INT zone_hr = abszone / (60*60);
int zone_min = (abszone/60) % 60;
int zone_sec = abszone % 60;
- sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0),
+ sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0],
zone_hr, zone_min, zone_sec);
tzstring = tzbuf;
}
@@ -3958,7 +3958,7 @@ usage: (format STRING &rest OBJECTS) */)
trailing "d"). */
pMlen = sizeof pMd - 2
};
- verify (0 < USEFUL_PRECISION_MAX);
+ verify (USEFUL_PRECISION_MAX > 0);
int prec;
ptrdiff_t padding, sprintf_bytes;
@@ -4241,7 +4241,10 @@ usage: (format STRING &rest OBJECTS) */)
memcpy (buf, initial_buffer, used);
}
else
- XSAVE_POINTER (buf_save_value, 0) = buf = xrealloc (buf, bufsize);
+ {
+ buf = xrealloc (buf, bufsize);
+ set_save_pointer (buf_save_value, 0, buf);
+ }
p = buf + used;
}
diff --git a/src/emacs.c b/src/emacs.c
index 148bb836927..b4b726183cf 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1069,7 +1069,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
noninteractive1 = noninteractive;
-/* Perform basic initializations (not merely interning symbols). */
+ /* Perform basic initializations (not merely interning symbols). */
if (!initialized)
{
@@ -1081,8 +1081,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_coding_once ();
init_syntax_once (); /* Create standard syntax table. */
init_category_once (); /* Create standard category table. */
- /* Must be done before init_buffer. */
- init_casetab_once ();
+ init_casetab_once (); /* Must be done before init_buffer_once. */
init_buffer_once (); /* Create buffer table and some buffers. */
init_minibuf_once (); /* Create list of minibuffers. */
/* Must precede init_window_once. */
@@ -1107,6 +1106,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_fileio ();
/* Before syms_of_coding to initialize Vgc_cons_threshold. */
syms_of_alloc ();
+ /* May call Ffuncall and so GC, thus the latter should be initialized. */
+ init_print_once ();
/* Before syms_of_coding because it initializes Qcharsetp. */
syms_of_charset ();
/* Before init_window_once, because it sets up the
@@ -1242,7 +1243,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#ifdef WINDOWSNT
globals_of_w32 ();
+#ifdef HAVE_W32NOTIFY
globals_of_w32notify ();
+#endif
/* Initialize environment from registry settings. */
init_environment (argv);
init_ntproc (dumping); /* must precede init_editfns. */
@@ -1399,6 +1402,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_gnutls ();
#endif
+#ifdef HAVE_GFILENOTIFY
+ syms_of_gfilenotify ();
+#endif /* HAVE_GFILENOTIFY */
+
#ifdef HAVE_INOTIFY
syms_of_inotify ();
#endif /* HAVE_INOTIFY */
@@ -1409,7 +1416,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#ifdef WINDOWSNT
syms_of_ntterm ();
+#ifdef HAVE_W32NOTIFY
syms_of_w32notify ();
+#endif /* HAVE_W32NOTIFY */
#endif /* WINDOWSNT */
syms_of_threads ();
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index 6a8c751e306..970683da9c4 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -28,7 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "xterm.h"
/* Silence a bogus diagnostic; see GNOME bug 683906. */
-#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
diff --git a/src/eval.c b/src/eval.c
index a58a1508aaf..be9de93bf1f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -32,8 +32,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "xterm.h"
#endif
-/* static struct backtrace *backtrace_list; */
-
/* #if !BYTE_MARK_STACK */
/* static */
/* #endif */
@@ -105,7 +103,7 @@ static EMACS_INT when_entered_debugger;
/* The function from which the last `signal' was called. Set in
Fsignal. */
-
+/* FIXME: We should probably get rid of this! */
Lisp_Object Vsignaling_function;
/* If non-nil, Lisp code must not be run since some part of Emacs is
@@ -117,26 +115,39 @@ Lisp_Object inhibit_lisp_code;
static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args);
-/* Functions to set Lisp_Object slots of struct specbinding. */
+/* Functions to modify slots of backtrace records. */
-static void
-set_specpdl_symbol (Lisp_Object symbol)
-{
- specpdl_ptr->symbol = symbol;
-}
+static void set_backtrace_args (struct specbinding *pdl, Lisp_Object *args)
+{ eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.args = args; }
-static void
-set_specpdl_old_value (Lisp_Object oldval)
+static void set_backtrace_nargs (struct specbinding *pdl, ptrdiff_t n)
+{ eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.nargs = n; }
+
+void set_backtrace_debug_on_exit (struct specbinding *pdl, bool doe)
+{ eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.debug_on_exit = doe; }
+
+/* Helper functions to scan the backtrace. */
+
+EXTERN_INLINE bool backtrace_p (struct specbinding *pdl)
+{ return pdl >= specpdl; }
+
+EXTERN_INLINE struct specbinding *backtrace_top (void)
{
- specpdl_ptr->old_value = oldval;
+ struct specbinding *pdl = specpdl_ptr - 1;
+ while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE)
+ pdl--;
+ return pdl;
}
-static inline void
-set_specpdl_saved_value (Lisp_Object savedval)
+EXTERN_INLINE struct specbinding *backtrace_next (struct specbinding *pdl)
{
- specpdl_ptr->saved_value = savedval;
+ pdl--;
+ while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE)
+ pdl--;
+ return pdl;
}
+
void
init_eval_once (void)
{
@@ -157,7 +168,6 @@ init_eval (void)
specpdl_ptr = specpdl;
catchlist = 0;
handlerlist = 0;
- backtrace_list = 0;
Vquit_flag = Qnil;
debug_on_next_call = 0;
lisp_eval_depth = 0;
@@ -253,7 +263,7 @@ static void
do_debug_on_call (Lisp_Object code)
{
debug_on_next_call = 0;
- backtrace_list->debug_on_exit = 1;
+ set_backtrace_debug_on_exit (specpdl_ptr - 1, true);
call_debugger (Fcons (code, Qnil));
}
@@ -549,9 +559,8 @@ The return value is BASE-VARIABLE. */)
struct specbinding *p;
for (p = specpdl_ptr; p > specpdl; )
- if ((--p)->func == NULL
- && (EQ (new_alias,
- CONSP (p->symbol) ? XCAR (p->symbol) : p->symbol)))
+ if ((--p)->kind >= SPECPDL_LET
+ && (EQ (new_alias, specpdl_symbol (p))))
error ("Don't know how to make a let-bound variable an alias");
}
@@ -616,8 +625,9 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
struct specbinding *pdl = specpdl_ptr;
while (pdl > specpdl)
{
- if (EQ ((--pdl)->symbol, sym) && !pdl->func
- && EQ (pdl->old_value, Qunbound))
+ if ((--pdl)->kind >= SPECPDL_LET
+ && EQ (specpdl_symbol (pdl), sym)
+ && EQ (specpdl_old_value (pdl), Qunbound))
{
message_with_string
("Warning: defvar ignored because %s is let-bound",
@@ -956,7 +966,7 @@ usage: (catch TAG BODY...) */)
/* Set up a catch, then call C function FUNC on argument ARG.
FUNC should return a Lisp_Object.
- This is how catches are done from within C code. */
+ This is how catches are done from within C code. */
Lisp_Object
internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg)
@@ -968,7 +978,6 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object
c.next = catchlist;
c.tag = tag;
c.val = Qnil;
- c.backlist = backtrace_list;
c.f_handlerlist = handlerlist;
c.f_lisp_eval_depth = lisp_eval_depth;
c.pdlcount = SPECPDL_INDEX ();
@@ -1033,7 +1042,6 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
#ifdef DEBUG_GCPRO
gcpro_level = gcprolist ? gcprolist->level + 1 : 0;
#endif
- backtrace_list = catch->backlist;
lisp_eval_depth = catch->f_lisp_eval_depth;
sys_longjmp (catch->jmp, 1);
@@ -1134,7 +1142,6 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
c.tag = Qnil;
c.val = Qnil;
- c.backlist = backtrace_list;
c.f_handlerlist = handlerlist;
c.f_lisp_eval_depth = lisp_eval_depth;
c.pdlcount = SPECPDL_INDEX ();
@@ -1150,7 +1157,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
/* Note that this just undoes the binding of h.var; whoever
longjumped to us unwound the stack to c.pdlcount before
- throwing. */
+ throwing. */
unbind_to (c.pdlcount, Qnil);
return val;
}
@@ -1189,7 +1196,6 @@ internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers,
c.tag = Qnil;
c.val = Qnil;
- c.backlist = backtrace_list;
c.f_handlerlist = handlerlist;
c.f_lisp_eval_depth = lisp_eval_depth;
c.pdlcount = SPECPDL_INDEX ();
@@ -1227,7 +1233,6 @@ internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg,
c.tag = Qnil;
c.val = Qnil;
- c.backlist = backtrace_list;
c.f_handlerlist = handlerlist;
c.f_lisp_eval_depth = lisp_eval_depth;
c.pdlcount = SPECPDL_INDEX ();
@@ -1269,7 +1274,6 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object),
c.tag = Qnil;
c.val = Qnil;
- c.backlist = backtrace_list;
c.f_handlerlist = handlerlist;
c.f_lisp_eval_depth = lisp_eval_depth;
c.pdlcount = SPECPDL_INDEX ();
@@ -1313,7 +1317,6 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
c.tag = Qnil;
c.val = Qnil;
- c.backlist = backtrace_list;
c.f_handlerlist = handlerlist;
c.f_lisp_eval_depth = lisp_eval_depth;
c.pdlcount = SPECPDL_INDEX ();
@@ -1381,7 +1384,6 @@ See also the function `condition-case'. */)
= (NILP (error_symbol) ? Fcar (data) : error_symbol);
register Lisp_Object clause = Qnil;
struct handler *h;
- struct backtrace *bp;
immediate_quit = 0;
abort_on_gc = 0;
@@ -1417,13 +1419,13 @@ See also the function `condition-case'. */)
too. Don't do this when ERROR_SYMBOL is nil, because that
is a memory-full error. */
Vsignaling_function = Qnil;
- if (backtrace_list && !NILP (error_symbol))
+ if (!NILP (error_symbol))
{
- bp = backtrace_list->next;
- if (bp && EQ (bp->function, Qerror))
- bp = bp->next;
- if (bp)
- Vsignaling_function = bp->function;
+ struct specbinding *pdl = backtrace_next (backtrace_top ());
+ if (backtrace_p (pdl) && EQ (backtrace_function (pdl), Qerror))
+ pdl = backtrace_next (pdl);
+ if (backtrace_p (pdl))
+ Vsignaling_function = backtrace_function (pdl);
}
for (h = handlerlist; h; h = h->next)
@@ -1920,6 +1922,36 @@ If LEXICAL is t, evaluate using lexical scoping. */)
return unbind_to (count, eval_sub (form));
}
+static void
+grow_specpdl (void)
+{
+ register ptrdiff_t count = SPECPDL_INDEX ();
+ ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX);
+ if (max_size <= specpdl_size)
+ {
+ if (max_specpdl_size < 400)
+ max_size = max_specpdl_size = 400;
+ if (max_size <= specpdl_size)
+ signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil);
+ }
+ specpdl = xpalloc (specpdl, &specpdl_size, 1, max_size, sizeof *specpdl);
+ specpdl_ptr = specpdl + count;
+}
+
+LISP_INLINE void
+record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
+{
+ eassert (nargs >= UNEVALLED);
+ if (specpdl_ptr == specpdl + specpdl_size)
+ grow_specpdl ();
+ specpdl_ptr->kind = SPECPDL_BACKTRACE;
+ specpdl_ptr->v.bt.function = function;
+ specpdl_ptr->v.bt.args = args;
+ specpdl_ptr->v.bt.nargs = nargs;
+ specpdl_ptr->v.bt.debug_on_exit = false;
+ specpdl_ptr++;
+}
+
/* Eval a sub-expression of the current expression (i.e. in the same
lexical scope). */
Lisp_Object
@@ -1927,7 +1959,6 @@ eval_sub (Lisp_Object form)
{
Lisp_Object fun, val, original_fun, original_args;
Lisp_Object funcar;
- struct backtrace backtrace;
struct gcpro gcpro1, gcpro2, gcpro3;
if (SYMBOLP (form))
@@ -1965,12 +1996,8 @@ eval_sub (Lisp_Object form)
original_fun = XCAR (form);
original_args = XCDR (form);
- backtrace.next = backtrace_list;
- backtrace.function = original_fun; /* This also protects them from gc. */
- backtrace.args = &original_args;
- backtrace.nargs = UNEVALLED;
- backtrace.debug_on_exit = 0;
- backtrace_list = &backtrace;
+ /* This also protects them from gc. */
+ record_in_backtrace (original_fun, &original_args, UNEVALLED);
if (debug_on_next_call)
do_debug_on_call (Qt);
@@ -2024,8 +2051,8 @@ eval_sub (Lisp_Object form)
gcpro3.nvars = argnum;
}
- backtrace.args = vals;
- backtrace.nargs = XINT (numargs);
+ set_backtrace_args (specpdl_ptr - 1, vals);
+ set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals);
UNGCPRO;
@@ -2046,8 +2073,8 @@ eval_sub (Lisp_Object form)
UNGCPRO;
- backtrace.args = argvals;
- backtrace.nargs = XINT (numargs);
+ set_backtrace_args (specpdl_ptr - 1, argvals);
+ set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
switch (i)
{
@@ -2137,9 +2164,9 @@ eval_sub (Lisp_Object form)
check_cons_list ();
lisp_eval_depth--;
- if (backtrace.debug_on_exit)
+ if (backtrace_debug_on_exit (specpdl_ptr - 1))
val = call_debugger (Fcons (Qexit, Fcons (val, Qnil)));
- backtrace_list = backtrace.next;
+ specpdl_ptr--;
return val;
}
@@ -2619,7 +2646,6 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
ptrdiff_t numargs = nargs - 1;
Lisp_Object lisp_numargs;
Lisp_Object val;
- struct backtrace backtrace;
register Lisp_Object *internal_args;
ptrdiff_t i;
@@ -2633,12 +2659,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
error ("Lisp nesting exceeds `max-lisp-eval-depth'");
}
- backtrace.next = backtrace_list;
- backtrace.function = args[0];
- backtrace.args = &args[1]; /* This also GCPROs them. */
- backtrace.nargs = nargs - 1;
- backtrace.debug_on_exit = 0;
- backtrace_list = &backtrace;
+ /* This also GCPROs them. */
+ record_in_backtrace (args[0], &args[1], nargs - 1);
/* Call GC after setting up the backtrace, so the latter GCPROs the args. */
maybe_gc ();
@@ -2763,9 +2785,9 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
}
check_cons_list ();
lisp_eval_depth--;
- if (backtrace.debug_on_exit)
+ if (backtrace_debug_on_exit (specpdl_ptr - 1))
val = call_debugger (Fcons (Qexit, Fcons (val, Qnil)));
- backtrace_list = backtrace.next;
+ specpdl_ptr--;
return val;
}
@@ -2797,15 +2819,17 @@ apply_lambda (Lisp_Object fun, Lisp_Object args)
UNGCPRO;
- backtrace_list->args = arg_vector;
- backtrace_list->nargs = i;
+ set_backtrace_args (specpdl_ptr - 1, arg_vector);
+ set_backtrace_nargs (specpdl_ptr - 1, i);
tem = funcall_lambda (fun, numargs, arg_vector);
/* Do the debug-on-exit now, while arg_vector still exists. */
- if (backtrace_list->debug_on_exit)
- tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil)));
- /* Don't do it again when we return to eval. */
- backtrace_list->debug_on_exit = 0;
+ if (backtrace_debug_on_exit (specpdl_ptr - 1))
+ {
+ /* Don't do it again when we return to eval. */
+ set_backtrace_debug_on_exit (specpdl_ptr - 1, false);
+ tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil)));
+ }
SAFE_FREE ();
return tem;
}
@@ -2955,20 +2979,38 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode,
return object;
}
-static void
-grow_specpdl (void)
+/* Return true if SYMBOL currently has a let-binding
+ which was made in the buffer that is now current. */
+
+bool
+let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
{
- register ptrdiff_t count = SPECPDL_INDEX ();
- ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX);
- if (max_size <= specpdl_size)
- {
- if (max_specpdl_size < 400)
- max_size = max_specpdl_size = 400;
- if (max_size <= specpdl_size)
- signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil);
- }
- specpdl = xpalloc (specpdl, &specpdl_size, 1, max_size, sizeof *specpdl);
- specpdl_ptr = specpdl + count;
+ struct specbinding *p;
+ Lisp_Object buf = Fcurrent_buffer ();
+
+ for (p = specpdl_ptr; p > specpdl; )
+ if ((--p)->kind > SPECPDL_LET)
+ {
+ struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p));
+ eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS);
+ if (symbol == let_bound_symbol
+ && EQ (specpdl_where (p), buf))
+ return 1;
+ }
+
+ return 0;
+}
+
+bool
+let_shadows_global_binding_p (Lisp_Object symbol)
+{
+ struct specbinding *p;
+
+ for (p = specpdl_ptr; p > specpdl; )
+ if ((--p)->kind >= SPECPDL_LET && EQ (specpdl_symbol (p), symbol))
+ return 1;
+
+ return 0;
}
static Lisp_Object
@@ -3050,10 +3092,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
case SYMBOL_PLAINVAL:
/* The most common case is that of a non-constant symbol with a
trivial value. Make that as fast as we can. */
- set_specpdl_symbol (symbol);
- set_specpdl_old_value (SYMBOL_VAL (sym));
- specpdl_ptr->func = NULL;
- specpdl_ptr->saved_value = Qnil;
+ specpdl_ptr->kind = SPECPDL_LET;
+ specpdl_ptr->v.let.symbol = symbol;
+ specpdl_ptr->v.let.old_value = SYMBOL_VAL (sym);
+ specpdl_ptr->v.let.saved_value = Qnil;
++specpdl_ptr;
do_specbind (sym, specpdl_ptr - 1, value);
break;
@@ -3063,59 +3105,36 @@ specbind (Lisp_Object symbol, Lisp_Object value)
case SYMBOL_FORWARDED:
{
Lisp_Object ovalue = find_symbol_value (symbol);
- specpdl_ptr->func = 0;
- set_specpdl_old_value (ovalue);
+ specpdl_ptr->kind = SPECPDL_LET_LOCAL;
+ specpdl_ptr->v.let.symbol = symbol;
+ specpdl_ptr->v.let.old_value = ovalue;
+ specpdl_ptr->v.let.where = Fcurrent_buffer ();
eassert (sym->redirect != SYMBOL_LOCALIZED
- || (EQ (SYMBOL_BLV (sym)->where,
- SYMBOL_BLV (sym)->frame_local ?
- Fselected_frame () : Fcurrent_buffer ())));
+ || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ())));
- if (sym->redirect == SYMBOL_LOCALIZED
- || BUFFER_OBJFWDP (SYMBOL_FWD (sym)))
+ if (sym->redirect == SYMBOL_LOCALIZED)
+ {
+ if (!blv_found (SYMBOL_BLV (sym)))
+ specpdl_ptr->kind = SPECPDL_LET_DEFAULT;
+ }
+ else if (BUFFER_OBJFWDP (SYMBOL_FWD (sym)))
{
- Lisp_Object where, cur_buf = Fcurrent_buffer ();
-
- /* For a local variable, record both the symbol and which
- buffer's or frame's value we are saving. */
- if (!NILP (Flocal_variable_p (symbol, Qnil)))
- {
- eassert (sym->redirect != SYMBOL_LOCALIZED
- || (blv_found (SYMBOL_BLV (sym))
- && EQ (cur_buf, SYMBOL_BLV (sym)->where)));
- where = cur_buf;
- }
- else if (sym->redirect == SYMBOL_LOCALIZED
- && blv_found (SYMBOL_BLV (sym)))
- where = SYMBOL_BLV (sym)->where;
- else
- where = Qnil;
-
- /* We're not using the `unused' slot in the specbinding
- structure because this would mean we have to do more
- work for simple variables. */
- /* FIXME: The third value `current_buffer' is only used in
- let_shadows_buffer_binding_p which is itself only used
- in set_internal for local_if_set. */
- eassert (NILP (where) || EQ (where, cur_buf));
- set_specpdl_symbol (Fcons (symbol, Fcons (where, cur_buf)));
-
/* If SYMBOL is a per-buffer variable which doesn't have a
buffer-local value here, make the `let' change the global
value by changing the value of SYMBOL in all buffers not
having their own value. This is consistent with what
happens with other buffer-local variables. */
- if (NILP (where)
- && sym->redirect == SYMBOL_FORWARDED)
+ if (NILP (Flocal_variable_p (symbol, Qnil)))
{
- eassert (BUFFER_OBJFWDP (SYMBOL_FWD (sym)));
+ specpdl_ptr->kind = SPECPDL_LET_DEFAULT;
++specpdl_ptr;
do_specbind (sym, specpdl_ptr - 1, value);
return;
}
}
else
- set_specpdl_symbol (symbol);
+ specpdl_ptr->kind = SPECPDL_LET;
specpdl_ptr++;
do_specbind (sym, specpdl_ptr - 1, value);
@@ -3130,10 +3149,9 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg)
{
if (specpdl_ptr == specpdl + specpdl_size)
grow_specpdl ();
- specpdl_ptr->func = function;
- set_specpdl_symbol (Qnil);
- set_specpdl_old_value (arg);
- set_specpdl_saved_value (Qnil);
+ specpdl_ptr->kind = SPECPDL_UNWIND;
+ specpdl_ptr->v.unwind.func = function;
+ specpdl_ptr->v.unwind.arg = arg;
specpdl_ptr++;
}
@@ -3144,7 +3162,7 @@ rebind_for_thread_switch (void)
for (bind = specpdl; bind != specpdl_ptr; ++bind)
{
- if (bind->func == NULL)
+ if (bind->kind >= SPECPDL_LET)
{
Lisp_Object value = bind->saved_value;
@@ -3157,41 +3175,50 @@ rebind_for_thread_switch (void)
static void
do_one_unbind (const struct specbinding *this_binding, int unwinding)
{
- if (this_binding->func != 0)
- (*this_binding->func) (this_binding->old_value);
- /* If the symbol is a list, it is really (SYMBOL WHERE
- . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
- frame. If WHERE is a buffer or frame, this indicates we
- bound a variable that had a buffer-local or frame-local
- binding. WHERE nil means that the variable had the default
- value when it was bound. CURRENT-BUFFER is the buffer that
- was current when the variable was bound. */
- else if (CONSP (this_binding->symbol))
- {
- Lisp_Object symbol, where;
-
- symbol = XCAR (this_binding->symbol);
- where = XCAR (XCDR (this_binding->symbol));
-
- if (NILP (where))
- Fset_default (symbol, this_binding->old_value);
- /* If `where' is non-nil, reset the value in the appropriate
- local binding, but only if that binding still exists. */
- else if (BUFFERP (where)
- ? !NILP (Flocal_variable_p (symbol, where))
- : !NILP (Fassq (symbol, XFRAME (where)->param_alist)))
- set_internal (symbol, this_binding->old_value, where, 1);
- }
- /* If variable has a trivial value (no forwarding), we can
- just set it. No need to check for constant symbols here,
- since that was already done by specbind. */
- else if (XSYMBOL (this_binding->symbol)->redirect == SYMBOL_PLAINVAL)
- SET_SYMBOL_VAL (XSYMBOL (this_binding->symbol),
- this_binding->old_value);
- else
- /* NOTE: we only ever come here if make_local_foo was used for
- the first time on this var within this let. */
- Fset_default (this_binding->symbol, this_binding->old_value);
+ switch (this_binding->kind)
+ {
+ case SPECPDL_UNWIND:
+ (*specpdl_func (this_binding)) (specpdl_arg (this_binding));
+ break;
+ case SPECPDL_LET:
+ /* If variable has a trivial value (no forwarding), we can
+ just set it. No need to check for constant symbols here,
+ since that was already done by specbind. */
+ if (XSYMBOL (specpdl_symbol (this_binding))->redirect
+ == SYMBOL_PLAINVAL)
+ SET_SYMBOL_VAL (XSYMBOL (specpdl_symbol (this_binding)),
+ specpdl_old_value (this_binding));
+ else
+ /* NOTE: we only ever come here if make_local_foo was used for
+ the first time on this var within this let. */
+ Fset_default (specpdl_symbol (this_binding),
+ specpdl_old_value (this_binding));
+ break;
+ case SPECPDL_BACKTRACE:
+ break;
+ case SPECPDL_LET_LOCAL:
+ case SPECPDL_LET_DEFAULT:
+ { /* If the symbol is a list, it is really (SYMBOL WHERE
+ . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
+ frame. If WHERE is a buffer or frame, this indicates we
+ bound a variable that had a buffer-local or frame-local
+ binding. WHERE nil means that the variable had the default
+ value when it was bound. CURRENT-BUFFER is the buffer that
+ was current when the variable was bound. */
+ Lisp_Object symbol = specpdl_symbol (this_binding);
+ Lisp_Object where = specpdl_where (this_binding);
+ eassert (BUFFERP (where));
+
+ if (this_binding->kind == SPECPDL_LET_DEFAULT)
+ Fset_default (symbol, specpdl_old_value (this_binding));
+ /* If this was a local binding, reset the value in the appropriate
+ buffer, but only if that buffer's binding still exists. */
+ else if (!NILP (Flocal_variable_p (symbol, where)))
+ set_internal (symbol, specpdl_old_value (this_binding),
+ where, 1);
+ }
+ break;
+ }
}
Lisp_Object
@@ -3231,7 +3258,7 @@ unbind_for_thread_switch (void)
for (bind = specpdl_ptr; bind != specpdl; --bind)
{
- if (bind->func == NULL)
+ if (bind->kind >= SPECPDL_LET)
{
bind->saved_value = find_symbol_value (binding_symbol (bind));
do_one_unbind (bind, 0);
@@ -3255,18 +3282,16 @@ DEFUN ("backtrace-debug", Fbacktrace_debug, Sbacktrace_debug, 2, 2, 0,
The debugger is entered when that frame exits, if the flag is non-nil. */)
(Lisp_Object level, Lisp_Object flag)
{
- register struct backtrace *backlist = backtrace_list;
+ struct specbinding *pdl = backtrace_top ();
register EMACS_INT i;
CHECK_NUMBER (level);
- for (i = 0; backlist && i < XINT (level); i++)
- {
- backlist = backlist->next;
- }
+ for (i = 0; backtrace_p (pdl) && i < XINT (level); i++)
+ pdl = backtrace_next (pdl);
- if (backlist)
- backlist->debug_on_exit = !NILP (flag);
+ if (backtrace_p (pdl))
+ set_backtrace_debug_on_exit (pdl, !NILP (flag));
return flag;
}
@@ -3276,58 +3301,41 @@ DEFUN ("backtrace", Fbacktrace, Sbacktrace, 0, 0, "",
Output stream used is value of `standard-output'. */)
(void)
{
- register struct backtrace *backlist = backtrace_list;
- Lisp_Object tail;
+ struct specbinding *pdl = backtrace_top ();
Lisp_Object tem;
- struct gcpro gcpro1;
Lisp_Object old_print_level = Vprint_level;
if (NILP (Vprint_level))
XSETFASTINT (Vprint_level, 8);
- tail = Qnil;
- GCPRO1 (tail);
-
- while (backlist)
+ while (backtrace_p (pdl))
{
- write_string (backlist->debug_on_exit ? "* " : " ", 2);
- if (backlist->nargs == UNEVALLED)
+ write_string (backtrace_debug_on_exit (pdl) ? "* " : " ", 2);
+ if (backtrace_nargs (pdl) == UNEVALLED)
{
- Fprin1 (Fcons (backlist->function, *backlist->args), Qnil);
+ Fprin1 (Fcons (backtrace_function (pdl), *backtrace_args (pdl)),
+ Qnil);
write_string ("\n", -1);
}
else
{
- tem = backlist->function;
+ tem = backtrace_function (pdl);
Fprin1 (tem, Qnil); /* This can QUIT. */
write_string ("(", -1);
- if (backlist->nargs == MANY)
- { /* FIXME: Can this happen? */
- bool later_arg = 0;
- for (tail = *backlist->args; !NILP (tail); tail = Fcdr (tail))
- {
- if (later_arg)
- write_string (" ", -1);
- Fprin1 (Fcar (tail), Qnil);
- later_arg = 1;
- }
- }
- else
- {
- ptrdiff_t i;
- for (i = 0; i < backlist->nargs; i++)
- {
- if (i) write_string (" ", -1);
- Fprin1 (backlist->args[i], Qnil);
- }
- }
+ {
+ ptrdiff_t i;
+ for (i = 0; i < backtrace_nargs (pdl); i++)
+ {
+ if (i) write_string (" ", -1);
+ Fprin1 (backtrace_args (pdl)[i], Qnil);
+ }
+ }
write_string (")\n", -1);
}
- backlist = backlist->next;
+ pdl = backtrace_next (pdl);
}
Vprint_level = old_print_level;
- UNGCPRO;
return Qnil;
}
@@ -3343,53 +3351,85 @@ or a lambda expression for macro calls.
If NFRAMES is more than the number of frames, the value is nil. */)
(Lisp_Object nframes)
{
- register struct backtrace *backlist = backtrace_list;
+ struct specbinding *pdl = backtrace_top ();
register EMACS_INT i;
- Lisp_Object tem;
CHECK_NATNUM (nframes);
/* Find the frame requested. */
- for (i = 0; backlist && i < XFASTINT (nframes); i++)
- backlist = backlist->next;
+ for (i = 0; backtrace_p (pdl) && i < XFASTINT (nframes); i++)
+ pdl = backtrace_next (pdl);
- if (!backlist)
+ if (!backtrace_p (pdl))
return Qnil;
- if (backlist->nargs == UNEVALLED)
- return Fcons (Qnil, Fcons (backlist->function, *backlist->args));
+ if (backtrace_nargs (pdl) == UNEVALLED)
+ return Fcons (Qnil,
+ Fcons (backtrace_function (pdl), *backtrace_args (pdl)));
else
{
- if (backlist->nargs == MANY) /* FIXME: Can this happen? */
- tem = *backlist->args;
- else
- tem = Flist (backlist->nargs, backlist->args);
+ Lisp_Object tem = Flist (backtrace_nargs (pdl), backtrace_args (pdl));
- return Fcons (Qt, Fcons (backlist->function, tem));
+ return Fcons (Qt, Fcons (backtrace_function (pdl), tem));
}
}
-#if BYTE_MARK_STACK
void
-mark_backtrace (void)
+mark_specpdl (struct specbinding *first, struct specbinding *ptr)
{
- register struct backtrace *backlist;
- ptrdiff_t i;
-
- for (backlist = backtrace_list; backlist; backlist = backlist->next)
+ struct specbinding *pdl;
+ for (pdl = first; pdl != ptr; pdl++)
{
- mark_object (backlist->function);
+ switch (pdl->kind)
+ {
+ case SPECPDL_UNWIND:
+ mark_object (specpdl_arg (pdl));
+ break;
+ case SPECPDL_BACKTRACE:
+ {
+ ptrdiff_t nargs = backtrace_nargs (pdl);
+ mark_object (backtrace_function (pdl));
+ if (nargs == UNEVALLED)
+ nargs = 1;
+ while (nargs--)
+ mark_object (backtrace_args (pdl)[nargs]);
+ }
+ break;
+ case SPECPDL_LET_DEFAULT:
+ case SPECPDL_LET_LOCAL:
+ mark_object (specpdl_where (pdl));
+ case SPECPDL_LET:
+ mark_object (specpdl_symbol (pdl));
+ mark_object (specpdl_old_value (pdl));
+ mark_object (specpdl_saved_value (pdl));
+ }
+ }
+}
+
+void
+get_backtrace (Lisp_Object array)
+{
+ struct specbinding *pdl = backtrace_next (backtrace_top ());
+ ptrdiff_t i = 0, asize = ASIZE (array);
- if (backlist->nargs == UNEVALLED
- || backlist->nargs == MANY) /* FIXME: Can this happen? */
- i = 1;
+ /* Copy the backtrace contents into working memory. */
+ for (; i < asize; i++)
+ {
+ if (backtrace_p (pdl))
+ {
+ ASET (array, i, backtrace_function (pdl));
+ pdl = backtrace_next (pdl);
+ }
else
- i = backlist->nargs;
- while (i--)
- mark_object (backlist->args[i]);
+ ASET (array, i, Qnil);
}
}
-#endif
+
+Lisp_Object backtrace_top_function (void)
+{
+ struct specbinding *pdl = backtrace_top ();
+ return (backtrace_p (pdl) ? backtrace_function (pdl) : Qnil);
+}
void
syms_of_eval (void)
diff --git a/src/fileio.c b/src/fileio.c
index 724250c8aaa..75e1f13a09b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -36,7 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <selinux/context.h>
#endif
-#ifdef HAVE_POSIX_ACL
+#ifdef HAVE_ACL_SET_FILE
#include <sys/acl.h>
#endif
@@ -82,6 +82,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#endif
#include "systime.h"
+#include <acl.h>
#include <allocator.h>
#include <careadlinkat.h>
#include <stat-time.h>
@@ -1969,7 +1970,7 @@ entries (depending on how Emacs was built). */)
security_context_t con;
int conlength = 0;
#endif
-#ifdef HAVE_POSIX_ACL
+#ifdef WINDOWSNT
acl_t acl = NULL;
#endif
@@ -2009,11 +2010,9 @@ entries (depending on how Emacs was built). */)
#ifdef WINDOWSNT
if (!NILP (preserve_extended_attributes))
{
-#ifdef HAVE_POSIX_ACL
acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS);
- if (acl == NULL && errno != ENOTSUP)
+ if (acl == NULL && acl_errno_valid (errno))
report_file_error ("Getting ACL", Fcons (file, Qnil));
-#endif
}
if (!CopyFile (SDATA (encoded_file),
SDATA (encoded_newname),
@@ -2050,17 +2049,15 @@ entries (depending on how Emacs was built). */)
/* Restore original attributes. */
SetFileAttributes (filename, attributes);
}
-#ifdef HAVE_POSIX_ACL
if (acl != NULL)
{
bool fail =
acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0;
- if (fail && errno != ENOTSUP)
+ if (fail && acl_errno_valid (errno))
report_file_error ("Setting ACL", Fcons (newname, Qnil));
acl_free (acl);
}
-#endif
#else /* not WINDOWSNT */
immediate_quit = 1;
ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0);
@@ -2084,12 +2081,6 @@ entries (depending on how Emacs was built). */)
report_file_error ("Doing fgetfilecon", Fcons (file, Qnil));
}
#endif
-
-#ifdef HAVE_POSIX_ACL
- acl = acl_get_fd (ifd);
- if (acl == NULL && errno != ENOTSUP)
- report_file_error ("Getting ACL", Fcons (file, Qnil));
-#endif
}
if (out_st.st_mode != 0
@@ -2137,7 +2128,7 @@ entries (depending on how Emacs was built). */)
immediate_quit = 0;
#ifndef MSDOS
- /* Preserve the original file modes, and if requested, also its
+ /* Preserve the original file permissions, and if requested, also its
owner and group. */
{
mode_t mode_mask = 07777;
@@ -2154,8 +2145,16 @@ entries (depending on how Emacs was built). */)
mode_mask |= 02000;
}
}
- if (fchmod (ofd, st.st_mode & mode_mask) != 0)
- report_file_error ("Doing chmod", Fcons (newname, Qnil));
+
+ switch (!NILP (preserve_extended_attributes)
+ ? qcopy_acl (SSDATA (encoded_file), ifd,
+ SSDATA (encoded_newname), ofd,
+ st.st_mode & mode_mask)
+ : fchmod (ofd, st.st_mode & mode_mask))
+ {
+ case -2: report_file_error ("Copying permissions from", list1 (file));
+ case -1: report_file_error ("Copying permissions to", list1 (newname));
+ }
}
#endif /* not MSDOS */
@@ -2172,17 +2171,6 @@ entries (depending on how Emacs was built). */)
}
#endif
-#ifdef HAVE_POSIX_ACL
- if (acl != NULL)
- {
- bool fail = acl_set_fd (ofd, acl) != 0;
- if (fail && errno != ENOTSUP)
- report_file_error ("Setting ACL", Fcons (newname, Qnil));
-
- acl_free (acl);
- }
-#endif
-
if (!NILP (keep_time))
{
EMACS_TIME atime = get_stat_atime (&st);
@@ -2885,7 +2873,7 @@ file_accessible_directory_p (char const *file)
and it's a safe optimization here. */
char *buf = SAFE_ALLOCA (len + 3);
memcpy (buf, file, len);
- strcpy (buf + len, "/." + (file[len - 1] == '/'));
+ strcpy (buf + len, &"/."[file[len - 1] == '/']);
dir = buf;
}
@@ -3092,7 +3080,7 @@ was unable to determine the ACL entries. */)
{
Lisp_Object absname;
Lisp_Object handler;
-#ifdef HAVE_POSIX_ACL
+#ifdef HAVE_ACL_SET_FILE
acl_t acl;
Lisp_Object acl_string;
char *str;
@@ -3107,7 +3095,7 @@ was unable to determine the ACL entries. */)
if (!NILP (handler))
return call2 (handler, Qfile_acl, absname);
-#ifdef HAVE_POSIX_ACL
+#ifdef HAVE_ACL_SET_FILE
absname = ENCODE_FILE (absname);
acl = acl_get_file (SSDATA (absname), ACL_TYPE_ACCESS);
@@ -3145,7 +3133,7 @@ support. */)
{
Lisp_Object absname;
Lisp_Object handler;
-#ifdef HAVE_POSIX_ACL
+#ifdef HAVE_ACL_SET_FILE
Lisp_Object encoded_absname;
acl_t acl;
bool fail;
@@ -3159,7 +3147,7 @@ support. */)
if (!NILP (handler))
return call3 (handler, Qset_file_acl, absname, acl_string);
-#ifdef HAVE_POSIX_ACL
+#ifdef HAVE_ACL_SET_FILE
if (STRINGP (acl_string))
{
acl = acl_from_text (SSDATA (acl_string));
@@ -3174,7 +3162,7 @@ support. */)
fail = (acl_set_file (SSDATA (encoded_absname), ACL_TYPE_ACCESS,
acl)
!= 0);
- if (fail && errno != ENOTSUP)
+ if (fail && acl_errno_valid (errno))
report_file_error ("Setting ACL", Fcons (absname, Qnil));
acl_free (acl);
@@ -3501,7 +3489,6 @@ by calling `format-decode', which see. */)
EMACS_TIME mtime;
int fd;
ptrdiff_t inserted = 0;
- bool nochange = 0;
ptrdiff_t how_much;
off_t beg_offset, end_offset;
int unprocessed;
@@ -3518,6 +3505,11 @@ by calling `format-decode', which see. */)
bool set_coding_system = 0;
Lisp_Object coding_system;
bool read_quit = 0;
+ /* If the undo log only contains the insertion, there's no point
+ keeping it. It's typically when we first fill a file-buffer. */
+ bool empty_undo_list_p
+ = (!NILP (visit) && NILP (BVAR (current_buffer, undo_list))
+ && BEG == Z);
Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
bool we_locked_file = 0;
bool deferred_remove_unwind_protect = 0;
@@ -3958,7 +3950,7 @@ by calling `format-decode', which see. */)
/* If display currently starts at beginning of line,
keep it that way. */
- if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
+ if (XBUFFER (XWINDOW (selected_window)->contents) == current_buffer)
XWINDOW (selected_window)->start_at_line_beg = !NILP (Fbolp ());
replace_handled = 1;
@@ -4067,9 +4059,7 @@ by calling `format-decode', which see. */)
if (bufpos == inserted)
{
/* Truncate the buffer to the size of the file. */
- if (same_at_start == same_at_end)
- nochange = 1;
- else
+ if (same_at_start != same_at_end)
del_range_byte (same_at_start, same_at_end, 0);
inserted = 0;
@@ -4108,7 +4098,7 @@ by calling `format-decode', which see. */)
/* If display currently starts at beginning of line,
keep it that way. */
- if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
+ if (XBUFFER (XWINDOW (selected_window)->contents) == current_buffer)
XWINDOW (selected_window)->start_at_line_beg = !NILP (Fbolp ());
/* Replace the chars that we need to replace,
@@ -4120,6 +4110,7 @@ by calling `format-decode', which see. */)
{
del_range_byte (same_at_start, same_at_end, 0);
temp = GPT;
+ eassert (same_at_start == GPT_BYTE);
same_at_start = GPT_BYTE;
}
else
@@ -4132,6 +4123,7 @@ by calling `format-decode', which see. */)
= buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
same_at_start - BEGV_BYTE
+ BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
+ eassert (same_at_start_charpos == temp - (BEGV - BEG));
inserted_chars
= (buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
same_at_start + inserted - BEGV_BYTE
@@ -4218,7 +4210,8 @@ by calling `format-decode', which see. */)
to be signaled after decoding the text we read. */
nbytes = internal_condition_case_1
(read_non_regular,
- make_save_value ("iii", (ptrdiff_t) fd, inserted, trytry),
+ make_save_value (SAVE_TYPE_INT_INT_INT, (ptrdiff_t) fd,
+ inserted, trytry),
Qerror, read_non_regular_quit);
if (NILP (nbytes))
@@ -4415,7 +4408,7 @@ by calling `format-decode', which see. */)
if (!NILP (visit))
{
- if (!EQ (BVAR (current_buffer, undo_list), Qt) && !nochange)
+ if (empty_undo_list_p)
bset_undo_list (current_buffer, Qnil);
if (NILP (handler))
@@ -4557,7 +4550,7 @@ by calling `format-decode', which see. */)
p = XCDR (p);
}
- if (NILP (visit))
+ if (!empty_undo_list_p)
{
bset_undo_list (current_buffer, old_undo);
if (CONSP (old_undo) && inserted != old_inserted)
@@ -4959,15 +4952,14 @@ This calls `write-region-annotate-functions' at the start, and
immediate_quit = 0;
- /* fsync appears to change the modtime on BSD4.2.
- Disk full in NFS may be reported here. */
- /* mib says that closing the file will try to write as fast as NFS can do
- it, and that means the fsync here is not crucial for autosave files. */
+ /* fsync is not crucial for auto-save files, since they might lose
+ some work anyway. */
if (!auto_saving && !write_region_inhibit_fsync)
{
- /* Transfer data and metadata to disk, retrying if interrupted. Also,
- ignore EINVAL which happens when fsync is not supported on this
- file. */
+ /* Transfer data and metadata to disk, retrying if interrupted.
+ fsync can report a write failure here, e.g., due to disk full
+ under NFS. But ignore EINVAL, which means fsync is not
+ supported on this file. */
while (fsync (desc) != 0)
if (errno != EINTR)
{
@@ -5012,7 +5004,7 @@ This calls `write-region-annotate-functions' at the start, and
&& ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system))
{
int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0);
- if (0 <= desc1)
+ if (desc1 >= 0)
{
struct stat st1;
if (fstat (desc1, &st1) == 0
@@ -5815,7 +5807,7 @@ before any other event (mouse or keypress) is handled. */)
if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
&& use_file_dialog
- && have_menus_p ())
+ && window_system_available (SELECTED_FRAME ()))
return Qt;
#endif
return Qnil;
@@ -6049,11 +6041,28 @@ in the buffer; this is the default behavior, because the auto-save
file is usually more useful if it contains the deleted text. */);
Vauto_save_include_big_deletions = Qnil;
+ /* fsync can be a significant performance hit. Often it doesn't
+ suffice to make the file-save operation survive a crash. For
+ batch scripts, which are typically part of larger shell commands
+ that don't fsync other files, its effect on performance can be
+ significant so its utility is particularly questionable.
+ Hence, for now by default fsync is used only when interactive.
+
+ For more on why fsync often fails to work on today's hardware, see:
+ Zheng M et al. Understanding the robustness of SSDs under power fault.
+ 11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
+ http://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
+
+ For more on why fsync does not suffice even if it works properly, see:
+ Roche X. Necessary step(s) to synchronize filename operations on disk.
+ Austin Group Defect 672, 2013-03-19
+ http://austingroupbugs.net/view.php?id=672 */
DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync,
doc: /* Non-nil means don't call fsync in `write-region'.
This variable affects calls to `write-region' as well as save commands.
-A non-nil value may result in data loss! */);
- write_region_inhibit_fsync = 0;
+Setting this to nil may avoid data loss if the system loses power or
+the operating system crashes. */);
+ write_region_inhibit_fsync = noninteractive;
DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
doc: /* Specifies whether to use the system's trash can.
diff --git a/src/filelock.c b/src/filelock.c
index f17d3182eab..de6aba8385c 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -437,14 +437,8 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len
|| (need_fchmod && fchmod (fd, world_readable) != 0))
err = errno;
- else
- while (fsync (fd) != 0)
- if (errno != EINTR)
- {
- if (errno != EINVAL)
- err = errno;
- break;
- }
+ /* There is no need to call fsync here, as the contents of
+ the lock file need not survive system crashes. */
if (emacs_close (fd) != 0)
err = errno;
if (!err && rename_lock_file (nonce, lfname, force) != 0)
diff --git a/src/floatfns.c b/src/floatfns.c
index 43576a16248..6113758f964 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -193,7 +193,7 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
CHECK_NUMBER_OR_FLOAT (arg2);
if (INTEGERP (arg1) /* common lisp spec */
&& INTEGERP (arg2) /* don't promote, if both are ints, and */
- && 0 <= XINT (arg2)) /* we are sure the result is not fractional */
+ && XINT (arg2) >= 0) /* we are sure the result is not fractional */
{ /* this can be improved by pre-calculating */
EMACS_INT y; /* some binary powers of x then accumulating */
EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */
@@ -475,7 +475,7 @@ fmod_float (Lisp_Object x, Lisp_Object y)
f1 = fmod (f1, f2);
/* If the "remainder" comes out with the wrong sign, fix it. */
- if (f2 < 0 ? 0 < f1 : f1 < 0)
+ if (f2 < 0 ? f1 > 0 : f1 < 0)
f1 += f2;
return make_float (f1);
diff --git a/src/fns.c b/src/fns.c
index b3a1dc2317a..08c6f055f38 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1551,7 +1551,7 @@ the value of a list `foo'. */)
tail = list;
prev = Qnil;
- while (!NILP (tail))
+ while (CONSP (tail))
{
CHECK_LIST_CONS (tail, list);
tem = XCAR (tail);
@@ -2443,10 +2443,9 @@ is nil, and `use-dialog-box' is non-nil. */)
CHECK_STRING (prompt);
#ifdef HAVE_MENUS
- if (FRAME_WINDOW_P (SELECTED_FRAME ())
- && (NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
+ if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
&& use_dialog_box
- && have_menus_p ())
+ && window_system_available (SELECTED_FRAME ()))
{
Lisp_Object pane, menu, obj;
redisplay_preserve_echo_area (4);
diff --git a/src/font.c b/src/font.c
index db7bf352c94..7bd44a5e52f 100644
--- a/src/font.c
+++ b/src/font.c
@@ -287,7 +287,7 @@ font_pixel_size (FRAME_PTR f, Lisp_Object spec)
if (INTEGERP (val))
dpi = XINT (val);
else
- dpi = f->resy;
+ dpi = FRAME_RES_Y (f);
pixel_size = POINT_TO_PIXEL (point_size, dpi);
return pixel_size;
#else
@@ -1219,7 +1219,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
return -1;
f[j] = p = alloca (alloc);
sprintf (p, "%s%s-*", SDATA (val),
- "*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
+ &"*"[SDATA (val)[SBYTES (val) - 1] == '*']);
}
else
f[j] = SSDATA (val);
@@ -1618,7 +1618,7 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
}
if (point_size > 0)
{
- int len = snprintf (p, lim - p, "-%d" + (p == name), point_size);
+ int len = snprintf (p, lim - p, &"-%d"[p == name], point_size);
if (! (0 <= len && len < lim - p))
return -1;
p += len;
@@ -2819,7 +2819,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
struct font_driver_list *driver_list;
Lisp_Object objlist, size, val, font_object;
struct font *font;
- int min_width, height;
+ int min_width, height, psize;
eassert (FONT_ENTITY_P (entity));
size = AREF (entity, FONT_SIZE_INDEX);
@@ -2846,12 +2846,19 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
}
}
- font_object = driver_list->driver->open (f, entity, pixel_size);
- if (!NILP (font_object))
- ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
+ /* We always open a font of manageable size; i.e non-zero average
+ width and height. */
+ for (psize = pixel_size; ; psize++)
+ {
+ font_object = driver_list->driver->open (f, entity, psize);
+ if (NILP (font_object))
+ return Qnil;
+ font = XFONT_OBJECT (font_object);
+ if (font->average_width > 0 && font->height > 0)
+ break;
+ }
+ ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
FONT_ADD_LOG ("open", entity, font_object);
- if (NILP (font_object))
- return Qnil;
ASET (entity, FONT_OBJLIST_INDEX,
Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX)));
@@ -3117,7 +3124,9 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
{
double pt = XINT (attrs[LFACE_HEIGHT_INDEX]);
- pixel_size = POINT_TO_PIXEL (pt / 10, f->resy);
+ pixel_size = POINT_TO_PIXEL (pt / 10, FRAME_RES_Y (f));
+ if (pixel_size < 1)
+ pixel_size = 1;
}
ASET (work, FONT_SIZE_INDEX, Qnil);
foundry[0] = AREF (work, FONT_FOUNDRY_INDEX);
@@ -3247,12 +3256,13 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
}
pt /= 10;
- size = POINT_TO_PIXEL (pt, f->resy);
+ size = POINT_TO_PIXEL (pt, FRAME_RES_Y (f));
#ifdef HAVE_NS
if (size == 0)
{
Lisp_Object ffsize = get_frame_param (f, Qfontsize);
- size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0;
+ size = (NUMBERP (ffsize)
+ ? POINT_TO_PIXEL (XINT (ffsize), FRAME_RES_Y (f)) : 0);
}
#endif
}
@@ -4021,7 +4031,7 @@ are to be displayed on. If omitted, the selected frame is used. */)
if (INTEGERP (val))
{
Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX);
- int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : f->resy;
+ int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : FRAME_RES_Y (f);
plist[n++] = QCheight;
plist[n++] = make_number (PIXEL_TO_POINT (XINT (val) * 10, dpi));
}
@@ -4532,7 +4542,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
{
CHECK_NUMBER_OR_FLOAT (size);
if (FLOATP (size))
- isize = POINT_TO_PIXEL (XFLOAT_DATA (size), f->resy);
+ isize = POINT_TO_PIXEL (XFLOAT_DATA (size), FRAME_RES_Y (f));
else
isize = XINT (size);
if (! (INT_MIN <= isize && isize <= INT_MAX))
@@ -4760,7 +4770,7 @@ character at index specified by POSITION. */)
if (NILP (string))
{
- if (XBUFFER (w->buffer) != current_buffer)
+ if (XBUFFER (w->contents) != current_buffer)
error ("Specified window is not displaying the current buffer.");
CHECK_NUMBER_COERCE_MARKER (position);
if (! (BEGV <= XINT (position) && XINT (position) < ZV))
@@ -4843,11 +4853,9 @@ If the named font is not yet loaded, return nil. */)
Lisp_Object info;
Lisp_Object font_object;
- (*check_window_system_func) ();
-
if (! FONTP (name))
CHECK_STRING (name);
- f = decode_live_frame (frame);
+ f = decode_window_system_frame (frame);
if (STRINGP (name))
{
diff --git a/src/fontset.c b/src/fontset.c
index 3578bc9403d..2f6313c4214 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -179,10 +179,6 @@ static int next_fontset_id;
font for each character. */
static Lisp_Object Vdefault_fontset;
-/* Check if any window system is used now. */
-void (*check_window_system_func) (void);
-
-
/* Prototype declarations for static functions. */
static Lisp_Object make_fontset (Lisp_Object, Lisp_Object, Lisp_Object);
@@ -1213,7 +1209,7 @@ If REGEXPP is non-nil, PATTERN is a regular expression. */)
Lisp_Object fontset;
int id;
- (*check_window_system_func) ();
+ check_window_system (NULL);
CHECK_STRING (pattern);
@@ -1919,8 +1915,7 @@ format is the same as above. */)
Lisp_Object val, elt;
int c, i, j, k;
- (*check_window_system_func) ();
-
+ check_window_system (NULL);
fontset = check_fontset_name (fontset, &frame);
/* Recode fontsets realized on FRAME from the base fontset FONTSET
diff --git a/src/fontset.h b/src/fontset.h
index 07ee5d65c25..926520c8001 100644
--- a/src/fontset.h
+++ b/src/fontset.h
@@ -26,9 +26,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef EMACS_FONTSET_H
#define EMACS_FONTSET_H
-/* Check if any window system is used now. */
-extern void (*check_window_system_func) (void);
-
struct face;
extern void free_face_fontset (FRAME_PTR, struct face *);
diff --git a/src/frame.c b/src/frame.c
index 0fa821682f3..e88432b9802 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -76,7 +76,6 @@ Lisp_Object Qterminal_live_p;
Lisp_Object Qauto_raise, Qauto_lower;
Lisp_Object Qborder_color, Qborder_width;
Lisp_Object Qcursor_color, Qcursor_type;
-static Lisp_Object Qgeometry; /* Not used */
Lisp_Object Qheight, Qwidth;
Lisp_Object Qleft, Qright;
Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
@@ -115,6 +114,8 @@ Lisp_Object Qface_set_after_frame_default;
static Lisp_Object Qdelete_frame_functions;
+Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
+
#ifdef HAVE_WINDOW_SYSTEM
static void x_report_frame_params (struct frame *, Lisp_Object *);
#endif
@@ -149,25 +150,56 @@ decode_any_frame (register Lisp_Object frame)
return XFRAME (frame);
}
+bool
+window_system_available (struct frame *f)
+{
+ if (f)
+ return FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f);
+ else
+#ifdef HAVE_WINDOW_SYSTEM
+ return x_display_list != NULL;
+#else
+ return 0;
+#endif
+}
+
+struct frame *
+decode_window_system_frame (Lisp_Object frame)
+{
+ struct frame *f = decode_live_frame (frame);
+
+ if (!window_system_available (f))
+ error ("Window system frame should be used");
+ return f;
+}
+
+void
+check_window_system (struct frame *f)
+{
+ if (!window_system_available (f))
+ error (f ? "Window system frame should be used"
+ : "Window system is not in use or not initialized");
+}
+
static void
set_menu_bar_lines_1 (Lisp_Object window, int n)
{
struct window *w = XWINDOW (window);
w->last_modified = 0;
- wset_top_line (w, make_number (XFASTINT (w->top_line) + n));
- wset_total_lines (w, make_number (XFASTINT (w->total_lines) - n));
+ w->top_line += n;
+ w->total_lines -= n;
/* Handle just the top child in a vertical split. */
- if (!NILP (w->vchild))
- set_menu_bar_lines_1 (w->vchild, n);
-
- /* Adjust all children in a horizontal split. */
- for (window = w->hchild; !NILP (window); window = w->next)
- {
- w = XWINDOW (window);
- set_menu_bar_lines_1 (window, n);
- }
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
+ set_menu_bar_lines_1 (w->contents, n);
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
+ /* Adjust all children in a horizontal split. */
+ for (window = w->contents; !NILP (window); window = w->next)
+ {
+ w = XWINDOW (window);
+ set_menu_bar_lines_1 (window, n);
+ }
}
void
@@ -332,14 +364,14 @@ make_frame (int mini_p)
SET_FRAME_COLS (f, 10);
FRAME_LINES (f) = 10;
- wset_total_cols (XWINDOW (root_window), make_number (10));
- wset_total_lines (XWINDOW (root_window), make_number (mini_p ? 9 : 10));
+ XWINDOW (root_window)->total_cols = 10;
+ XWINDOW (root_window)->total_lines = mini_p ? 9 : 10;
if (mini_p)
{
- wset_total_cols (XWINDOW (mini_window), make_number (10));
- wset_top_line (XWINDOW (mini_window), make_number (9));
- wset_total_lines (XWINDOW (mini_window), make_number (1));
+ XWINDOW (mini_window)->total_cols = 10;
+ XWINDOW (mini_window)->top_line = 9;
+ XWINDOW (mini_window)->total_lines = 1;
}
/* Choose a buffer for the frame's root window. */
@@ -421,7 +453,7 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis
/* Make the chosen minibuffer window display the proper minibuffer,
unless it is already showing a minibuffer. */
- if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
+ if (NILP (Fmemq (XWINDOW (mini_window)->contents, Vminibuffer_list)))
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
set_window_buffer (mini_window,
@@ -803,10 +835,18 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
{
- if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
- /* Mark previously displayed frame as now obscured. */
- SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (XFRAME (frame))->top_frame), 2);
- SET_FRAME_VISIBLE (XFRAME (frame), 1);
+ Lisp_Object top_frame = FRAME_TTY (XFRAME (frame))->top_frame;
+
+ /* Don't mark the frame garbaged and/or obscured if we are
+ switching to the frame that is already the top frame of that
+ TTY. */
+ if (!EQ (frame, top_frame))
+ {
+ if (FRAMEP (top_frame))
+ /* Mark previously displayed frame as now obscured. */
+ SET_FRAME_VISIBLE (XFRAME (top_frame), 2);
+ SET_FRAME_VISIBLE (XFRAME (frame), 1);
+ }
FRAME_TTY (XFRAME (frame))->top_frame = frame;
}
@@ -889,7 +929,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
same tty (for tty frames) or among frames which uses FRAME's keyboard.
If MINIBUF is nil, do not consider minibuffer-only candidate.
- If MINIBUF is `visible', do not consider an invisible candidate.
+ If MINIBUF is `visible', do not consider an invisible candidate.
If MINIBUF is a window, consider only its own frame and candidate now
using that window as the minibuffer.
If MINIBUF is 0, consider candidate if it is visible or iconified.
@@ -1189,7 +1229,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
set_window_buffer (sf->minibuffer_window,
- XWINDOW (minibuf_window)->buffer, 0, 0);
+ XWINDOW (minibuf_window)->contents, 0, 0);
minibuf_window = sf->minibuffer_window;
/* If the dying minibuffer window was selected,
@@ -1593,17 +1633,13 @@ make_frame_visible_1 (Lisp_Object window)
{
struct window *w;
- for (;!NILP (window); window = w->next)
+ for (; !NILP (window); window = w->next)
{
w = XWINDOW (window);
-
- if (!NILP (w->buffer))
- bset_display_time (XBUFFER (w->buffer), Fcurrent_time ());
-
- if (!NILP (w->vchild))
- make_frame_visible_1 (w->vchild);
- if (!NILP (w->hchild))
- make_frame_visible_1 (w->hchild);
+ if (WINDOWP (w->contents))
+ make_frame_visible_1 (w->contents);
+ else
+ bset_display_time (XBUFFER (w->contents), Fcurrent_time ());
}
}
@@ -1634,7 +1670,7 @@ displayed in the terminal. */)
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
set_window_buffer (sf->minibuffer_window,
- XWINDOW (minibuf_window)->buffer, 0, 0);
+ XWINDOW (minibuf_window)->contents, 0, 0);
minibuf_window = sf->minibuffer_window;
}
@@ -1665,7 +1701,7 @@ If omitted, FRAME defaults to the currently selected frame. */)
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
set_window_buffer (sf->minibuffer_window,
- XWINDOW (minibuf_window)->buffer, 0, 0);
+ XWINDOW (minibuf_window)->contents, 0, 0);
minibuf_window = sf->minibuffer_window;
}
@@ -1819,7 +1855,7 @@ See `redirect-frame-focus'. */)
/* Return the value of frame parameter PROP in frame FRAME. */
#ifdef HAVE_WINDOW_SYSTEM
-#if !HAVE_NS
+#if !HAVE_NS && !defined(WINDOWSNT)
static
#endif
Lisp_Object
@@ -3315,16 +3351,15 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
else if (FLOATP (item))
{
alpha = XFLOAT_DATA (item);
- if (alpha < 0.0 || 1.0 < alpha)
+ if (! (0 <= alpha && alpha <= 1.0))
args_out_of_range (make_float (0.0), make_float (1.0));
}
else if (INTEGERP (item))
{
EMACS_INT ialpha = XINT (item);
- if (ialpha < 0 || 100 < ialpha)
+ if (! (0 <= ialpha && alpha <= 100))
args_out_of_range (make_number (0), make_number (100));
- else
- alpha = ialpha / 100.0;
+ alpha = ialpha / 100.0;
}
else
wrong_type_argument (Qnumberp, item);
@@ -3495,11 +3530,10 @@ The optional arguments COMPONENT and SUBCLASS add to the key and the
class, respectively. You must specify both of them or neither.
If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
and the class is `Emacs.CLASS.SUBCLASS'. */)
- (Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
+ (Lisp_Object attribute, Lisp_Object class, Lisp_Object component,
+ Lisp_Object subclass)
{
-#ifdef HAVE_X_WINDOWS
- check_x ();
-#endif
+ check_window_system (NULL);
return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
attribute, class, component, subclass);
@@ -3508,7 +3542,9 @@ and the class is `Emacs.CLASS.SUBCLASS'. */)
/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
Lisp_Object
-display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
+display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
+ Lisp_Object class, Lisp_Object component,
+ Lisp_Object subclass)
{
return xrdb_get_resource (dpyinfo->xrdb,
attribute, class, component, subclass);
@@ -4094,6 +4130,73 @@ selected frame. This is useful when `make-pointer-invisible' is set. */)
return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
}
+
+
+/***********************************************************************
+ Multimonitor data
+ ***********************************************************************/
+
+#ifdef HAVE_WINDOW_SYSTEM
+
+void
+free_monitors (struct MonitorInfo *monitors, int n_monitors)
+{
+ int i;
+ for (i = 0; i < n_monitors; ++i)
+ xfree (monitors[i].name);
+ xfree (monitors);
+}
+
+Lisp_Object
+make_monitor_attribute_list (struct MonitorInfo *monitors,
+ int n_monitors,
+ int primary_monitor,
+ Lisp_Object monitor_frames,
+ const char *source)
+{
+ Lisp_Object attributes_list = Qnil;
+ Lisp_Object primary_monitor_attributes = Qnil;
+ int i;
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ Lisp_Object geometry, workarea, attributes = Qnil;
+ struct MonitorInfo *mi = &monitors[i];
+
+ if (mi->geom.width == 0) continue;
+
+ workarea = list4i (mi->work.x, mi->work.y,
+ mi->work.width, mi->work.height);
+ geometry = list4i (mi->geom.x, mi->geom.y,
+ mi->geom.width, mi->geom.height);
+ attributes = Fcons (Fcons (Qsource,
+ make_string (source, strlen (source))),
+ attributes);
+ attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
+ attributes);
+ attributes = Fcons (Fcons (Qmm_size,
+ list2i (mi->mm_width, mi->mm_height)),
+ attributes);
+ attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
+ attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
+ if (mi->name)
+ attributes = Fcons (Fcons (Qname, make_string (mi->name,
+ strlen (mi->name))),
+ attributes);
+
+ if (i == primary_monitor)
+ primary_monitor_attributes = attributes;
+ else
+ attributes_list = Fcons (attributes, attributes_list);
+ }
+
+ if (!NILP (primary_monitor_attributes))
+ attributes_list = Fcons (primary_monitor_attributes, attributes_list);
+ return attributes_list;
+}
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
/***********************************************************************
Initialization
@@ -4152,6 +4255,12 @@ syms_of_frame (void)
DEFSYM (Qterminal, "terminal");
DEFSYM (Qterminal_live_p, "terminal-live-p");
+ DEFSYM (Qgeometry, "geometry");
+ DEFSYM (Qworkarea, "workarea");
+ DEFSYM (Qmm_size, "mm-size");
+ DEFSYM (Qframes, "frames");
+ DEFSYM (Qsource, "source");
+
#ifdef HAVE_NS
DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
#endif
diff --git a/src/frame.h b/src/frame.h
index c18b7662079..12aa48b2d92 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -170,9 +170,11 @@ struct frame
most recently buried buffer is first. For last-buffer. */
Lisp_Object buried_buffer_list;
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* A dummy window used to display menu bars under X when no X
toolkit support is available. */
Lisp_Object menu_bar_window;
+#endif
/* A window used to display the tool-bar of a frame. */
Lisp_Object tool_bar_window;
@@ -276,9 +278,6 @@ struct frame
/* Size of the frame window in pixels. */
int pixel_height, pixel_width;
- /* Dots per inch of the screen the frame is on. */
- double resx, resy;
-
/* These many pixels are the difference between the outer window (i.e. the
left and top of the window manager decoration) and FRAME_X_WINDOW. */
int x_pixels_diff, y_pixels_diff;
@@ -428,10 +427,6 @@ struct frame
/* Width of bar cursor (if we are using that) for blink-off state. */
int blink_off_cursor_width;
- /* Nonnegative if current redisplay should not do scroll computation
- for lines beyond a certain vpos. This is the vpos. */
- int scroll_bottom_vpos;
-
/* Configured width of the scroll bar, in pixels and in characters.
config_scroll_bar_cols tracks config_scroll_bar_width if the
latter is positive; a zero value in config_scroll_bar_width means
@@ -518,11 +513,13 @@ fset_menu_bar_vector (struct frame *f, Lisp_Object val)
{
f->menu_bar_vector = val;
}
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
FRAME_INLINE void
fset_menu_bar_window (struct frame *f, Lisp_Object val)
{
f->menu_bar_window = val;
}
+#endif
FRAME_INLINE void
fset_name (struct frame *f, Lisp_Object val)
{
@@ -569,6 +566,26 @@ fset_tool_bar_window (struct frame *f, Lisp_Object val)
f->tool_bar_window = val;
}
+#define NUMVAL(X) ((INTEGERP (X) || FLOATP (X)) ? XFLOATINT (X) : -1)
+
+FRAME_INLINE double
+default_pixels_per_inch_x (void)
+{
+ Lisp_Object v = (CONSP (Vdisplay_pixels_per_inch)
+ ? XCAR (Vdisplay_pixels_per_inch)
+ : Vdisplay_pixels_per_inch);
+ return NUMVAL (v) > 0 ? NUMVAL (v) : 72.0;
+}
+
+FRAME_INLINE double
+default_pixels_per_inch_y (void)
+{
+ Lisp_Object v = (CONSP (Vdisplay_pixels_per_inch)
+ ? XCDR (Vdisplay_pixels_per_inch)
+ : Vdisplay_pixels_per_inch);
+ return NUMVAL (v) > 0 ? NUMVAL (v) : 72.0;
+}
+
#define FRAME_KBOARD(f) ((f)->terminal->kboard)
/* Return a pointer to the image cache of frame F. */
@@ -581,7 +598,7 @@ typedef struct frame *FRAME_PTR;
#define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME))
/* Given a window, return its frame as a Lisp_Object. */
-#define WINDOW_FRAME(w) w->frame
+#define WINDOW_FRAME(w) ((w)->frame)
/* Test a frame for particular kinds of display methods. */
#define FRAME_INITIAL_P(f) ((f)->output_method == output_initial)
@@ -602,6 +619,37 @@ typedef struct frame *FRAME_PTR;
#else
#define FRAME_NS_P(f) ((f)->output_method == output_ns)
#endif
+
+/* Dots per inch of the screen the frame F is on. */
+
+#ifdef HAVE_X_WINDOWS
+#define FRAME_RES_X(f) \
+ (eassert (FRAME_X_P (f)), FRAME_X_DISPLAY_INFO (f)->resx)
+#define FRAME_RES_Y(f) \
+ (eassert (FRAME_X_P (f)), FRAME_X_DISPLAY_INFO (f)->resy)
+#endif
+
+#ifdef HAVE_NTGUI
+#define FRAME_RES_X(f) \
+ (eassert (FRAME_W32_P (f)), FRAME_W32_DISPLAY_INFO (f)->resx)
+#define FRAME_RES_Y(f) \
+ (eassert (FRAME_W32_P (f)), FRAME_W32_DISPLAY_INFO (f)->resy)
+#endif
+
+#ifdef HAVE_NS
+#define FRAME_RES_X(f) \
+ (eassert (FRAME_NS_P (f)), FRAME_NS_DISPLAY_INFO (f)->resx)
+#define FRAME_RES_Y(f) \
+ (eassert (FRAME_NS_P (f)), FRAME_NS_DISPLAY_INFO (f)->resy)
+#endif
+
+/* Defaults when no window system available. */
+
+#ifndef FRAME_RES_X
+#define FRAME_RES_X(f) default_pixels_per_inch_x ()
+#define FRAME_RES_Y(f) default_pixels_per_inch_y ()
+#endif
+
/* FRAME_WINDOW_P tests whether the frame is a window, and is
defined to be the predicate for the window system being used. */
@@ -733,7 +781,6 @@ typedef struct frame *FRAME_PTR;
#define FRAME_DELETE_COST(f) (f)->delete_line_cost
#define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost
#define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost
-#define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos
#define FRAME_FOCUS_FRAME(f) f->focus_frame
/* This frame slot says whether scroll bars are currently enabled for frame F,
@@ -911,6 +958,7 @@ extern Lisp_Object Qnoelisp;
extern struct frame *last_nonminibuf_frame;
extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
+extern struct frame *decode_window_system_frame (Lisp_Object);
extern struct frame *decode_live_frame (Lisp_Object);
extern struct frame *decode_any_frame (Lisp_Object);
extern struct frame *make_initial_frame (void);
@@ -921,6 +969,8 @@ extern struct frame *make_frame_without_minibuffer (Lisp_Object,
struct kboard *,
Lisp_Object);
#endif /* HAVE_WINDOW_SYSTEM */
+extern bool window_system_available (struct frame *);
+extern void check_window_system (struct frame *);
extern void frame_make_pointer_invisible (void);
extern void frame_make_pointer_visible (void);
extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
@@ -1148,6 +1198,8 @@ extern Lisp_Object Qdisplay;
extern Lisp_Object Qrun_hook_with_args;
+extern Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
+
#ifdef HAVE_WINDOW_SYSTEM
/* The class of this X application. */
@@ -1238,6 +1290,28 @@ extern void x_query_colors (struct frame *f, XColor *, int);
extern void x_query_color (struct frame *f, XColor *);
#endif /* HAVE_WINDOW_SYSTEM */
+
+/***********************************************************************
+ Multimonitor data
+ ***********************************************************************/
+
+#ifdef HAVE_WINDOW_SYSTEM
+
+struct MonitorInfo {
+ XRectangle geom, work;
+ int mm_width, mm_height;
+ char *name;
+};
+
+extern void free_monitors (struct MonitorInfo *monitors, int n_monitors);
+extern Lisp_Object make_monitor_attribute_list (struct MonitorInfo *monitors,
+ int n_monitors,
+ int primary_monitor,
+ Lisp_Object monitor_frames,
+ const char *source);
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
INLINE_HEADER_END
diff --git a/src/fringe.c b/src/fringe.c
index fa6f889ba69..f728cd6d5ff 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -699,7 +699,7 @@ get_logical_cursor_bitmap (struct window *w, Lisp_Object cursor)
{
Lisp_Object cmap, bm = Qnil;
- if ((cmap = BVAR (XBUFFER (w->buffer), fringe_cursor_alist)), !NILP (cmap))
+ if ((cmap = BVAR (XBUFFER (w->contents), fringe_cursor_alist)), !NILP (cmap))
{
bm = Fassq (cursor, cmap);
if (CONSP (bm))
@@ -736,7 +736,7 @@ get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, in
If partial, lookup partial bitmap in default value if not found here.
If not partial, or no partial spec is present, use non-partial bitmap. */
- if ((cmap = BVAR (XBUFFER (w->buffer), fringe_indicator_alist)), !NILP (cmap))
+ if ((cmap = BVAR (XBUFFER (w->contents), fringe_indicator_alist)), !NILP (cmap))
{
bm1 = Fassq (bitmap, cmap);
if (CONSP (bm1))
@@ -963,7 +963,7 @@ update_window_fringes (struct window *w, int keep_current_p)
return 0;
if (!MINI_WINDOW_P (w)
- && (ind = BVAR (XBUFFER (w->buffer), indicate_buffer_boundaries), !NILP (ind)))
+ && (ind = BVAR (XBUFFER (w->contents), indicate_buffer_boundaries), !NILP (ind)))
{
if (EQ (ind, Qleft) || EQ (ind, Qright))
boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
@@ -1004,7 +1004,7 @@ update_window_fringes (struct window *w, int keep_current_p)
{
if (top_ind_rn < 0 && row->visible_height > 0)
{
- if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))
+ if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->contents))
&& !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
row->indicate_bob_p = !NILP (boundary_top);
else
@@ -1014,7 +1014,7 @@ update_window_fringes (struct window *w, int keep_current_p)
if (bot_ind_rn < 0)
{
- if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))
+ if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->contents))
&& !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
row->indicate_eob_p = !NILP (boundary_bot), bot_ind_rn = rn;
else if (y + row->height >= yb)
@@ -1024,7 +1024,7 @@ update_window_fringes (struct window *w, int keep_current_p)
}
}
- empty_pos = BVAR (XBUFFER (w->buffer), indicate_empty_lines);
+ empty_pos = BVAR (XBUFFER (w->contents), indicate_empty_lines);
if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
diff --git a/src/ftfont.c b/src/ftfont.c
index 867e25a7a25..0ad173af98a 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -393,7 +393,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
cache_data = xmalloc (sizeof *cache_data);
cache_data->ft_face = NULL;
cache_data->fc_charset = NULL;
- val = make_save_value ("pi", cache_data, 0);
+ val = make_save_value (SAVE_TYPE_PTR_INT, cache_data, 0);
cache = Fcons (Qnil, val);
Fputhash (key, cache, ft_face_cache);
}
@@ -1211,7 +1211,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
return Qnil;
}
}
- XSAVE_INTEGER (val, 1)++;
+ set_save_integer (val, 1, XSAVE_INTEGER (val, 1) + 1);
size = XINT (AREF (entity, FONT_SIZE_INDEX));
if (size == 0)
size = pixel_size;
@@ -1326,7 +1326,7 @@ ftfont_close (FRAME_PTR f, struct font *font)
cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE);
eassert (CONSP (cache));
val = XCDR (cache);
- XSAVE_INTEGER (val, 1)--;
+ set_save_integer (val, 1, XSAVE_INTEGER (val, 1) - 1);
if (XSAVE_INTEGER (val, 1) == 0)
{
struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0);
diff --git a/src/gfilenotify.c b/src/gfilenotify.c
new file mode 100644
index 00000000000..4ccc430d815
--- /dev/null
+++ b/src/gfilenotify.c
@@ -0,0 +1,266 @@
+/* Filesystem notifications support with glib API.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#ifdef HAVE_GFILENOTIFY
+#include <stdio.h>
+#include <gio/gio.h>
+#include "lisp.h"
+#include "coding.h"
+#include "frame.h"
+#include "termhooks.h"
+#include "keyboard.h"
+#include "process.h"
+
+
+/* Subroutines. */
+static Lisp_Object Qgfile_add_watch;
+static Lisp_Object Qgfile_rm_watch;
+
+/* Filter objects. */
+static Lisp_Object Qwatch_mounts; /* G_FILE_MONITOR_WATCH_MOUNTS */
+static Lisp_Object Qsend_moved; /* G_FILE_MONITOR_SEND_MOVED */
+
+/* Event types. */
+static Lisp_Object Qchanged; /* G_FILE_MONITOR_EVENT_CHANGED */
+static Lisp_Object Qchanges_done_hint; /* G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT */
+static Lisp_Object Qdeleted; /* G_FILE_MONITOR_EVENT_DELETED */
+static Lisp_Object Qcreated; /* G_FILE_MONITOR_EVENT_CREATED */
+static Lisp_Object Qattribute_changed; /* G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED */
+static Lisp_Object Qpre_unmount; /* G_FILE_MONITOR_EVENT_PRE_UNMOUNT */
+static Lisp_Object Qunmounted; /* G_FILE_MONITOR_EVENT_UNMOUNTED */
+static Lisp_Object Qmoved; /* G_FILE_MONITOR_EVENT_MOVED */
+
+static Lisp_Object watch_list;
+
+/* This is the callback function for arriving signals from
+ g_file_monitor. It shall create a Lisp event, and put it into
+ Emacs input queue. */
+static gboolean
+dir_monitor_callback (GFileMonitor* monitor,
+ GFile* file,
+ GFile* other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ Lisp_Object symbol, watch_object;
+ char *name = g_file_get_parse_name (file);
+ char *oname = other_file ? g_file_get_parse_name (other_file) : NULL;
+
+ /* Determine event symbol. */
+ switch (event_type)
+ {
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ symbol = Qchanged;
+ break;
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ symbol = Qchanges_done_hint;
+ break;
+ case G_FILE_MONITOR_EVENT_DELETED:
+ symbol = Qdeleted;
+ break;
+ case G_FILE_MONITOR_EVENT_CREATED:
+ symbol = Qcreated;
+ break;
+ case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
+ symbol = Qattribute_changed;
+ break;
+ case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
+ symbol = Qpre_unmount;
+ break;
+ case G_FILE_MONITOR_EVENT_UNMOUNTED:
+ symbol = Qunmounted;
+ break;
+ case G_FILE_MONITOR_EVENT_MOVED:
+ symbol = Qmoved;
+ break;
+ default:
+ goto cleanup;
+ }
+
+ /* Determine callback function. */
+ watch_object = Fassoc (XIL ((EMACS_INT) monitor), watch_list);
+
+ if (FUNCTIONP (CDR_SAFE (watch_object)))
+ {
+ /* Construct an event. */
+ struct input_event event;
+ EVENT_INIT (event);
+ event.kind = FILE_NOTIFY_EVENT;
+ event.frame_or_window = Qnil;
+ event.arg = oname
+ ? list2 (list4 (XIL ((EMACS_INT) monitor), symbol,
+ build_string (name), build_string (oname)),
+ CDR_SAFE (watch_object))
+ : list2 (list3 (XIL ((EMACS_INT) monitor), symbol, build_string (name)),
+ CDR_SAFE (watch_object));
+
+ /* Store it into the input event queue. */
+ kbd_buffer_store_event (&event);
+ }
+
+ /* Cleanup. */
+ cleanup:
+ g_free (name);
+ g_free (oname);
+
+ return TRUE;
+}
+
+DEFUN ("gfile-add-watch", Fgfile_add_watch, Sgfile_add_watch, 3, 3, 0,
+ doc: /* Add a watch for filesystem events pertaining to FILE.
+
+This arranges for filesystem events pertaining to FILE to be reported
+to Emacs. Use `gfile-rm-watch' to cancel the watch.
+
+Value is a descriptor for the added watch. If the file cannot be
+watched for some reason, this function signals a `file-error' error.
+
+FLAGS is a list of conditions to set what will be watched for. It can
+include the following symbols:
+
+ 'watch-mounts' -- watch for mount events
+ 'send-moved' -- pair 'deleted' and 'created' events caused by file
+ renames (moves) and send a single 'event-moved'
+ event instead
+
+When any event happens, Emacs will call the CALLBACK function passing
+it a single argument EVENT, which is of the form
+
+ (DESCRIPTOR ACTION FILE [FILE1])
+
+DESCRIPTOR is the same object as the one returned by this function.
+ACTION is the description of the event. It could be any one of the
+following:
+
+ 'changed' -- FILE has changed
+ 'changes-done-hint' -- a hint that this was probably the last change
+ in a set of changes
+ 'deleted' -- FILE was deleted
+ 'created' -- FILE was created
+ 'attribute-changed' -- a FILE attribute was changed
+ 'pre-unmount' -- the FILE location will soon be unmounted
+ 'unmounted' -- the FILE location was unmounted
+ 'moved' -- FILE was moved to FILE1
+
+FILE is the name of the file whose event is being reported. FILE1
+will be reported only in case of the 'moved' event. */)
+ (Lisp_Object file, Lisp_Object flags, Lisp_Object callback)
+{
+ Lisp_Object watch_descriptor, watch_object;
+ GFile *gfile;
+ GFileMonitor* monitor;
+ GFileMonitorFlags gflags = G_FILE_MONITOR_NONE;
+
+ /* Check parameters. */
+ CHECK_STRING (file);
+ file = Fdirectory_file_name (Fexpand_file_name (file, Qnil));
+ if (NILP (Ffile_exists_p (file)))
+ report_file_error ("File does not exists", Fcons (file, Qnil));
+
+ CHECK_LIST (flags);
+
+ if (!FUNCTIONP (callback))
+ wrong_type_argument (Qinvalid_function, callback);
+
+ /* Create GFile name. */
+ gfile = g_file_new_for_path (SSDATA (ENCODE_FILE (file)));
+
+ /* Assemble flags. */
+ if (!NILP (Fmember (Qwatch_mounts, flags)))
+ gflags |= G_FILE_MONITOR_WATCH_MOUNTS;
+ if (!NILP (Fmember (Qsend_moved, flags)))
+ gflags |= G_FILE_MONITOR_SEND_MOVED;
+
+ /* Enable watch. */
+ monitor = g_file_monitor (gfile, gflags, NULL, NULL);
+ if (monitor != NULL)
+ g_signal_connect (monitor, "changed",
+ (GCallback) dir_monitor_callback, NULL);
+ else
+ report_file_error ("Cannot watch file", Fcons (file, Qnil));
+
+ /* Store watch object in watch list. */
+ watch_descriptor = XIL ((EMACS_INT) monitor);
+ watch_object = Fcons (watch_descriptor, callback);
+ watch_list = Fcons (watch_object, watch_list);
+
+ return watch_descriptor;
+}
+
+DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
+ doc: /* Remove an existing WATCH-DESCRIPTOR.
+
+WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */)
+ (Lisp_Object watch_descriptor)
+{
+ Lisp_Object watch_object;
+ GFileMonitor *monitor = (GFileMonitor *) XLI (watch_descriptor);
+
+ watch_object = Fassoc (watch_descriptor, watch_list);
+ if (NILP (watch_object))
+ report_file_error ("Not a watch descriptor",
+ Fcons (watch_descriptor, Qnil));
+
+ if (!g_file_monitor_cancel (monitor))
+ report_file_error ("Could not rm watch",
+ Fcons (watch_descriptor, Qnil));
+
+ /* Remove watch descriptor from watch list. */
+ watch_list = Fdelete (watch_object, watch_list);
+
+ /* Cleanup. */
+ g_object_unref (monitor);
+
+ return Qt;
+}
+
+
+void
+syms_of_gfilenotify (void)
+{
+
+ g_type_init ();
+
+ DEFSYM (Qgfile_add_watch, "gfile-add-watch");
+ defsubr (&Sgfile_add_watch);
+
+ DEFSYM (Qgfile_rm_watch, "gfile-rm-watch");
+ defsubr (&Sgfile_rm_watch);
+
+ DEFSYM (Qwatch_mounts, "watch-mounts");
+ DEFSYM (Qsend_moved, "send-moved");
+ DEFSYM (Qchanged, "changed");
+ DEFSYM (Qchanges_done_hint, "changes-done-hint");
+ DEFSYM (Qdeleted, "deleted");
+ DEFSYM (Qcreated, "created");
+ DEFSYM (Qattribute_changed, "attribute-changed");
+ DEFSYM (Qpre_unmount, "pre-unmount");
+ DEFSYM (Qunmounted, "unmounted");
+ DEFSYM (Qmoved, "moved");
+
+ /* Initialize internal objects. */
+ watch_list = Qnil;
+ staticpro (&watch_list);
+
+ Fprovide (intern_c_string ("gfilenotify"), Qnil);
+
+}
+
+#endif /* HAVE_GFILENOTIFY */
diff --git a/src/gtkutil.c b/src/gtkutil.c
index d6e4dcebcd3..8ac58f18158 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -70,13 +70,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define gtk_adjustment_get_step_increment(w) ((w)->step_increment)
#define gtk_adjustment_set_step_increment(w, s) ((w)->step_increment = (s))
#endif
-#if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 11
+#if GTK_CHECK_VERSION (2, 12, 0)
#define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL)
#else
#define remove_submenu(w) gtk_menu_item_remove_submenu ((w))
#endif
-#if GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 2)
+#if GTK_CHECK_VERSION (3, 2, 0)
#define USE_NEW_GTK_FONT_CHOOSER 1
#else
#define USE_NEW_GTK_FONT_CHOOSER 0
@@ -202,7 +202,7 @@ xg_display_close (Display *dpy)
gdpy_def = gdpy_new;
}
-#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 10
+#if GTK_CHECK_VERSION (2, 0, 0) && ! GTK_CHECK_VERSION (2, 10, 0)
/* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug
http://bugzilla.gnome.org/show_bug.cgi?id=85715). This way we
can continue running, but there will be memory leaks. */
@@ -1094,7 +1094,9 @@ style_changed_cb (GObject *go,
FOR_EACH_FRAME (rest, frame)
{
FRAME_PTR f = XFRAME (frame);
- if (FRAME_X_DISPLAY (f) == dpy)
+ if (FRAME_LIVE_P (f)
+ && FRAME_X_P (f)
+ && FRAME_X_DISPLAY (f) == dpy)
{
x_set_scroll_bar_default_width (f);
xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
@@ -1153,7 +1155,8 @@ xg_create_frame_widgets (FRAME_PTR f)
has backported it to Gtk+ 2.0 and they add the resize grip for
Gtk+ 2.0 applications also. But it has a bug that makes Emacs loop
forever, so disable the grip. */
-#if GTK_MAJOR_VERSION < 3 && defined (HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP)
+#if (! GTK_CHECK_VERSION (3, 0, 0) \
+ && defined HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP)
gtk_window_set_has_resize_grip (GTK_WINDOW (wtop), FALSE);
#endif
diff --git a/src/image.c b/src/image.c
index 2d4e7e731ad..f9f6ce70040 100644
--- a/src/image.c
+++ b/src/image.c
@@ -68,8 +68,6 @@ typedef struct x_bitmap_record Bitmap_Record;
#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
#define NO_PIXMAP None
-#define RGB_PIXEL_COLOR unsigned long
-
#define PIX_MASK_RETAIN 0
#define PIX_MASK_DRAW 1
#endif /* HAVE_X_WINDOWS */
@@ -88,8 +86,6 @@ typedef struct w32_bitmap_record Bitmap_Record;
#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
#define NO_PIXMAP 0
-#define RGB_PIXEL_COLOR COLORREF
-
#define PIX_MASK_RETAIN 0
#define PIX_MASK_DRAW 1
@@ -110,7 +106,6 @@ typedef struct ns_bitmap_record Bitmap_Record;
#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
#define NO_PIXMAP 0
-#define RGB_PIXEL_COLOR unsigned long
#define ZPixmap 0
#define PIX_MASK_RETAIN 0
@@ -159,15 +154,15 @@ XGetImage (Display *display, Pixmap pixmap, int x, int y,
return pixmap;
}
-/* use with imgs created by ns_image_for_XPM */
+/* Use with images created by ns_image_for_XPM. */
unsigned long
XGetPixel (XImagePtr ximage, int x, int y)
{
return ns_get_pixel (ximage, x, y);
}
-/* use with imgs created by ns_image_for_XPM; alpha set to 1;
- pixel is assumed to be in form RGB */
+/* Use with images created by ns_image_for_XPM; alpha set to 1;
+ pixel is assumed to be in RGB form. */
void
XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
{
@@ -894,7 +889,7 @@ or omitted means use the selected frame. */)
size = Qnil;
if (valid_image_p (spec))
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
ptrdiff_t id = lookup_image (f, spec);
struct image *img = IMAGE_FROM_ID (f, id);
int width = img->width + 2 * img->hmargin;
@@ -924,7 +919,7 @@ or omitted means use the selected frame. */)
mask = Qnil;
if (valid_image_p (spec))
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
ptrdiff_t id = lookup_image (f, spec);
struct image *img = IMAGE_FROM_ID (f, id);
if (img->mask)
@@ -947,7 +942,7 @@ or omitted means use the selected frame. */)
ext = Qnil;
if (valid_image_p (spec))
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
ptrdiff_t id = lookup_image (f, spec);
struct image *img = IMAGE_FROM_ID (f, id);
ext = img->lisp_data;
@@ -1555,7 +1550,7 @@ which is then usually a filename. */)
if (!(EQ (filter, Qnil) || FRAMEP (filter)))
clear_image_caches (filter);
else
- clear_image_cache (check_x_frame (filter), Qt);
+ clear_image_cache (decode_window_system_frame (filter), Qt);
return Qnil;
}
@@ -1586,7 +1581,7 @@ FRAME t means refresh the image on all frames. */)
}
}
else
- uncache_image (check_x_frame (frame), spec);
+ uncache_image (decode_window_system_frame (frame), spec);
return Qnil;
}
@@ -7268,6 +7263,25 @@ gif_load (struct frame *f, struct image *img)
return 0;
}
+ /* Check that the selected subimages fit. It's not clear whether
+ the GIF spec requires this, but Emacs can crash if they don't fit. */
+ for (j = 0; j <= idx; ++j)
+ {
+ struct SavedImage *subimage = gif->SavedImages + j;
+ int subimg_width = subimage->ImageDesc.Width;
+ int subimg_height = subimage->ImageDesc.Height;
+ int subimg_top = subimage->ImageDesc.Top;
+ int subimg_left = subimage->ImageDesc.Left;
+ if (! (0 <= subimg_width && 0 <= subimg_height
+ && 0 <= subimg_top && subimg_top <= height - subimg_height
+ && 0 <= subimg_left && subimg_left <= width - subimg_width))
+ {
+ image_error ("Subimage does not fit in image", Qnil, Qnil);
+ fn_DGifCloseFile (gif);
+ return 0;
+ }
+ }
+
/* Create the X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
{
@@ -7378,11 +7392,10 @@ gif_load (struct frame *f, struct image *img)
y < subimg_height;
y++, row += interlace_increment[pass])
{
- if (row >= subimg_height)
+ while (subimg_height <= row)
{
+ lint_assume (pass < 3);
row = interlace_start[++pass];
- while (row >= subimg_height)
- row = interlace_start[++pass];
}
for (x = 0; x < subimg_width; x++)
@@ -8126,24 +8139,25 @@ svg_image_p (Lisp_Object object)
#ifdef WINDOWSNT
/* SVG library functions. */
-DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new);
-DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions);
-DEF_IMGLIB_FN (gboolean, rsvg_handle_write);
-DEF_IMGLIB_FN (gboolean, rsvg_handle_close);
-DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf);
-
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_width);
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_height);
-DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels);
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride);
-DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace);
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels);
-DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha);
-DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample);
-
-DEF_IMGLIB_FN (void, g_type_init);
-DEF_IMGLIB_FN (void, g_object_unref);
-DEF_IMGLIB_FN (void, g_error_free);
+DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new, (void));
+DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions, (RsvgHandle *, RsvgDimensionData *));
+DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **));
+DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
+DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
+DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback, (RsvgHandle *, RsvgSizeFunc, gpointer, GDestroyNotify));
+
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
+DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride, (const GdkPixbuf *));
+DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace, (const GdkPixbuf *));
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *));
+DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *));
+DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
+
+DEF_IMGLIB_FN (void, g_type_init, (void));
+DEF_IMGLIB_FN (void, g_object_unref, (gpointer));
+DEF_IMGLIB_FN (void, g_error_free, (GError *));
Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
@@ -8559,10 +8573,10 @@ gs_load (struct frame *f, struct image *img)
info. */
pt_width = image_spec_value (img->spec, QCpt_width, NULL);
in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
- in_width *= FRAME_X_DISPLAY_INFO (f)->resx;
+ in_width *= FRAME_RES_X (f);
pt_height = image_spec_value (img->spec, QCpt_height, NULL);
in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
- in_height *= FRAME_X_DISPLAY_INFO (f)->resy;
+ in_height *= FRAME_RES_Y (f);
if (! (in_width <= INT_MAX && in_height <= INT_MAX
&& check_image_size (f, in_width, in_height)))
diff --git a/src/indent.c b/src/indent.c
index d1f95da6bcf..47358e17db8 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -56,11 +56,6 @@ static EMACS_INT last_known_column_modified;
static ptrdiff_t current_column_1 (void);
static ptrdiff_t position_indentation (ptrdiff_t);
-/* Cache of beginning of line found by the last call of
- current_column. */
-
-static ptrdiff_t current_column_bol_cache;
-
/* Get the display table to use for the current buffer. */
struct Lisp_Char_Table *
@@ -254,7 +249,7 @@ skip_invisible (ptrdiff_t pos, ptrdiff_t *next_boundary_p, ptrdiff_t to, Lisp_Ob
the next property change */
prop = Fget_char_property (position, Qinvisible,
(!NILP (window)
- && EQ (XWINDOW (window)->buffer, buffer))
+ && EQ (XWINDOW (window)->contents, buffer))
? window : buffer);
inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
/* When counting columns (window == nil), don't skip over ellipsis text. */
@@ -439,11 +434,6 @@ current_column (void)
col += post_tab;
}
- if (ptr == BEGV_ADDR)
- current_column_bol_cache = BEGV;
- else
- current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
-
last_known_column = col;
last_known_column_point = PT;
last_known_column_modified = MODIFF;
@@ -525,7 +515,6 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol)
{
ptrdiff_t opoint = PT, opoint_byte = PT_BYTE;
scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
- current_column_bol_cache = PT;
scan = PT, scan_byte = PT_BYTE;
SET_PT_BOTH (opoint, opoint_byte);
next_boundary = scan;
@@ -1088,8 +1077,8 @@ static struct position val_compute_motion;
: (window_width + window_left != frame_cols))
where
- window_width is XFASTINT (w->total_cols),
- window_left is XFASTINT (w->left_col),
+ window_width is w->total_cols,
+ window_left is w->left_col,
has_vertical_scroll_bars is
WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
and frame_cols = FRAME_COLS (XFRAME (window->frame))
@@ -1826,7 +1815,7 @@ vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
/* If the window contains this buffer, use it for getting text properties.
Otherwise use the current buffer as arg for doing that. */
- if (EQ (w->buffer, Fcurrent_buffer ()))
+ if (EQ (w->contents, Fcurrent_buffer ()))
text_prop_object = window;
else
text_prop_object = Fcurrent_buffer ();
@@ -1979,14 +1968,14 @@ whether or not it is currently displayed in some window. */)
old_buffer = Qnil;
GCPRO1 (old_buffer);
- if (XBUFFER (w->buffer) != current_buffer)
+ if (XBUFFER (w->contents) != current_buffer)
{
/* Set the window's buffer temporarily to the current buffer. */
- old_buffer = w->buffer;
+ old_buffer = w->contents;
old_charpos = marker_position (w->pointm);
old_bytepos = marker_byte_position (w->pointm);
wset_buffer (w, Fcurrent_buffer ());
- set_marker_both (w->pointm, w->buffer,
+ set_marker_both (w->pointm, w->contents,
BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
}
@@ -2017,11 +2006,15 @@ whether or not it is currently displayed in some window. */)
const char *s = SSDATA (it.string);
const char *e = s + SBYTES (it.string);
+ disp_string_at_start_p =
/* If it.area is anything but TEXT_AREA, we need not bother
about the display string, as it doesn't affect cursor
positioning. */
- disp_string_at_start_p =
- it.string_from_display_prop_p && it.area == TEXT_AREA;
+ it.area == TEXT_AREA
+ && it.string_from_display_prop_p
+ /* A display string on anything but buffer text (e.g., on
+ an overlay string) doesn't affect cursor positioning. */
+ && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER);
while (s < e)
{
if (*s++ == '\n')
@@ -2139,7 +2132,7 @@ whether or not it is currently displayed in some window. */)
if (BUFFERP (old_buffer))
{
wset_buffer (w, old_buffer);
- set_marker_both (w->pointm, w->buffer,
+ set_marker_both (w->pointm, w->contents,
old_charpos, old_bytepos);
}
diff --git a/src/insdel.c b/src/insdel.c
index a60fed0c32e..ed684264249 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -771,8 +771,13 @@ count_combining_after (const unsigned char *string,
/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
- starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
- are the same as in insert_1. */
+ starting at STRING. INHERIT non-zero means inherit the text
+ properties from neighboring characters; zero means inserted text
+ will have no text properties. PREPARE non-zero means call
+ prepare_to_modify_buffer, which checks that the region is not
+ read-only, and calls before-change-function and any modification
+ properties the text may have. BEFORE_MARKERS non-zero means adjust
+ all markers that point at the insertion place to point after it. */
void
insert_1_both (const char *string,
@@ -983,6 +988,9 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
void
insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
{
+ int ins_charpos = GPT;
+ int ins_bytepos = GPT_BYTE;
+
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
nchars = nbytes;
@@ -1003,18 +1011,18 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
eassert (GPT <= GPT_BYTE);
- adjust_overlays_for_insert (GPT - nchars, nchars);
- adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes,
- GPT, GPT_BYTE, 0);
+ adjust_overlays_for_insert (ins_charpos, nchars);
+ adjust_markers_for_insert (ins_charpos, ins_bytepos,
+ ins_charpos + nchars, ins_bytepos + nbytes, 0);
if (buffer_intervals (current_buffer))
{
- offset_intervals (current_buffer, GPT - nchars, nchars);
- graft_intervals_into_buffer (NULL, GPT - nchars, nchars,
+ offset_intervals (current_buffer, ins_charpos, nchars);
+ graft_intervals_into_buffer (NULL, ins_charpos, nchars,
current_buffer, 0);
}
- if (! text_at_gap_tail && GPT - nchars < PT)
+ if (ins_charpos < PT)
adjust_point (nchars, nbytes);
check_markers ();
@@ -1798,7 +1806,7 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
/* If we're modifying the buffer other than shown in a selected window,
let redisplay consider other windows if this buffer is visible. */
- if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer
+ if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer
&& buffer_window_count (current_buffer))
++windows_or_buffers_changed;
diff --git a/src/intervals.c b/src/intervals.c
index db38c86c00b..f65ce0ecc77 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -110,14 +110,14 @@ create_root_interval (Lisp_Object parent)
{
new->total_length = (BUF_Z (XBUFFER (parent))
- BUF_BEG (XBUFFER (parent)));
- eassert (0 <= TOTAL_LENGTH (new));
+ eassert (TOTAL_LENGTH (new) >= 0);
set_buffer_intervals (XBUFFER (parent), new);
new->position = BEG;
}
else if (STRINGP (parent))
{
new->total_length = SCHARS (parent);
- eassert (0 <= TOTAL_LENGTH (new));
+ eassert (TOTAL_LENGTH (new) >= 0);
set_string_intervals (parent, new);
new->position = 0;
}
@@ -371,11 +371,11 @@ rotate_right (INTERVAL interval)
/* A's total length is decreased by the length of B and its left child. */
interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval);
- eassert (0 <= TOTAL_LENGTH (interval));
+ eassert (TOTAL_LENGTH (interval) >= 0);
/* B must have the same total length of A. */
B->total_length = old_total;
- eassert (0 <= TOTAL_LENGTH (B));
+ eassert (TOTAL_LENGTH (B) >= 0);
return B;
}
@@ -418,11 +418,11 @@ rotate_left (INTERVAL interval)
/* A's total length is decreased by the length of B and its right child. */
interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval);
- eassert (0 <= TOTAL_LENGTH (interval));
+ eassert (TOTAL_LENGTH (interval) >= 0);
/* B must have the same total length of A. */
B->total_length = old_total;
- eassert (0 <= TOTAL_LENGTH (B));
+ eassert (TOTAL_LENGTH (B) >= 0);
return B;
}
@@ -556,7 +556,7 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
{
set_interval_right (interval, new);
new->total_length = new_length;
- eassert (0 <= TOTAL_LENGTH (new));
+ eassert (TOTAL_LENGTH (new) >= 0);
}
else
{
@@ -565,7 +565,7 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
set_interval_parent (interval->right, new);
set_interval_right (interval, new);
new->total_length = new_length + new->right->total_length;
- eassert (0 <= TOTAL_LENGTH (new));
+ eassert (TOTAL_LENGTH (new) >= 0);
balance_an_interval (new);
}
@@ -601,7 +601,7 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
{
set_interval_left (interval, new);
new->total_length = new_length;
- eassert (0 <= TOTAL_LENGTH (new));
+ eassert (TOTAL_LENGTH (new) >= 0);
}
else
{
@@ -610,7 +610,7 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
set_interval_parent (new->left, new);
set_interval_left (interval, new);
new->total_length = new_length + new->left->total_length;
- eassert (0 <= TOTAL_LENGTH (new));
+ eassert (TOTAL_LENGTH (new) >= 0);
balance_an_interval (new);
}
@@ -960,7 +960,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
{
temp->total_length += length;
- eassert (0 <= TOTAL_LENGTH (temp));
+ eassert (TOTAL_LENGTH (temp) >= 0);
temp = balance_possible_root_interval (temp);
}
@@ -1016,7 +1016,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
{
temp->total_length += length;
- eassert (0 <= TOTAL_LENGTH (temp));
+ eassert (TOTAL_LENGTH (temp) >= 0);
temp = balance_possible_root_interval (temp);
}
}
@@ -1218,7 +1218,7 @@ delete_node (register INTERVAL i)
this = this->left;
this->total_length += migrate_amt;
}
- eassert (0 <= TOTAL_LENGTH (this));
+ eassert (TOTAL_LENGTH (this) >= 0);
set_interval_left (this, migrate);
set_interval_parent (migrate, this);
@@ -1300,7 +1300,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
relative_position,
amount);
tree->total_length -= subtract;
- eassert (0 <= TOTAL_LENGTH (tree));
+ eassert (TOTAL_LENGTH (tree) >= 0);
return subtract;
}
/* Right branch. */
@@ -1315,7 +1315,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
relative_position,
amount);
tree->total_length -= subtract;
- eassert (0 <= TOTAL_LENGTH (tree));
+ eassert (TOTAL_LENGTH (tree) >= 0);
return subtract;
}
/* Here -- this node. */
@@ -1330,7 +1330,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
amount = my_amount;
tree->total_length -= amount;
- eassert (0 <= TOTAL_LENGTH (tree));
+ eassert (TOTAL_LENGTH (tree) >= 0);
if (LENGTH (tree) == 0)
delete_interval (tree);
@@ -1372,7 +1372,7 @@ adjust_intervals_for_deletion (struct buffer *buffer,
if (ONLY_INTERVAL_P (tree))
{
tree->total_length -= length;
- eassert (0 <= TOTAL_LENGTH (tree));
+ eassert (TOTAL_LENGTH (tree) >= 0);
return;
}
@@ -1435,19 +1435,19 @@ merge_interval_right (register INTERVAL i)
while (! NULL_LEFT_CHILD (successor))
{
successor->total_length += absorb;
- eassert (0 <= TOTAL_LENGTH (successor));
+ eassert (TOTAL_LENGTH (successor) >= 0);
successor = successor->left;
}
successor->total_length += absorb;
- eassert (0 <= TOTAL_LENGTH (successor));
+ eassert (TOTAL_LENGTH (successor) >= 0);
delete_interval (i);
return successor;
}
/* Zero out this interval. */
i->total_length -= absorb;
- eassert (0 <= TOTAL_LENGTH (i));
+ eassert (TOTAL_LENGTH (i) >= 0);
successor = i;
while (! NULL_PARENT (successor)) /* It's above us. Subtract as
@@ -1462,7 +1462,7 @@ merge_interval_right (register INTERVAL i)
successor = INTERVAL_PARENT (successor);
successor->total_length -= absorb;
- eassert (0 <= TOTAL_LENGTH (successor));
+ eassert (TOTAL_LENGTH (successor) >= 0);
}
/* This must be the rightmost or last interval and cannot
@@ -1491,19 +1491,19 @@ merge_interval_left (register INTERVAL i)
while (! NULL_RIGHT_CHILD (predecessor))
{
predecessor->total_length += absorb;
- eassert (0 <= TOTAL_LENGTH (predecessor));
+ eassert (TOTAL_LENGTH (predecessor) >= 0);
predecessor = predecessor->right;
}
predecessor->total_length += absorb;
- eassert (0 <= TOTAL_LENGTH (predecessor));
+ eassert (TOTAL_LENGTH (predecessor) >= 0);
delete_interval (i);
return predecessor;
}
/* Zero out this interval. */
i->total_length -= absorb;
- eassert (0 <= TOTAL_LENGTH (i));
+ eassert (TOTAL_LENGTH (i) >= 0);
predecessor = i;
while (! NULL_PARENT (predecessor)) /* It's above us. Go up,
@@ -1518,7 +1518,7 @@ merge_interval_left (register INTERVAL i)
predecessor = INTERVAL_PARENT (predecessor);
predecessor->total_length -= absorb;
- eassert (0 <= TOTAL_LENGTH (predecessor));
+ eassert (TOTAL_LENGTH (predecessor) >= 0);
}
/* This must be the leftmost or first interval and cannot
@@ -2272,7 +2272,7 @@ copy_intervals (INTERVAL tree, ptrdiff_t start, ptrdiff_t length)
new->position = 0;
got = (LENGTH (i) - (start - i->position));
new->total_length = length;
- eassert (0 <= TOTAL_LENGTH (new));
+ eassert (TOTAL_LENGTH (new) >= 0);
copy_properties (i, new);
t = new;
@@ -2355,7 +2355,7 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
i->total_length = end - start;
else
i->total_length = end_byte - start_byte;
- eassert (0 <= TOTAL_LENGTH (i));
+ eassert (TOTAL_LENGTH (i) >= 0);
if (TOTAL_LENGTH (i) == 0)
{
diff --git a/src/keyboard.c b/src/keyboard.c
index e43b7a73172..8dd109d252d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -72,7 +72,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
-/* Variables for blockinput.h: */
+/* Variables for blockinput.h: */
/* Positive if interrupt input is blocked right now. */
volatile int interrupt_input_blocked;
@@ -210,12 +210,6 @@ static EMACS_INT last_auto_save;
/* The value of point when the last command was started. */
static ptrdiff_t last_point_position;
-/* The buffer that was current when the last command was started. */
-static Lisp_Object last_point_position_buffer;
-
-/* The window that was selected when the last command was started. */
-static Lisp_Object last_point_position_window;
-
/* The frame in which the last input event occurred, or Qmacro if the
last event came from a macro. We use this to determine when to
generate switch-frame events. This may be cleared by functions
@@ -314,18 +308,15 @@ static Lisp_Object Qfunction_key;
Lisp_Object Qmouse_click;
#ifdef HAVE_NTGUI
Lisp_Object Qlanguage_change;
-#ifdef WINDOWSNT
-Lisp_Object Qfile_w32notify;
-#endif
#endif
static Lisp_Object Qdrag_n_drop;
static Lisp_Object Qsave_session;
#ifdef HAVE_DBUS
static Lisp_Object Qdbus_event;
#endif
-#ifdef HAVE_INOTIFY
-static Lisp_Object Qfile_inotify;
-#endif /* HAVE_INOTIFY */
+#ifdef USE_FILE_NOTIFY
+static Lisp_Object Qfile_notify;
+#endif /* USE_FILE_NOTIFY */
static Lisp_Object Qconfig_changed_event;
/* Lisp_Object Qmouse_movement; - also an event header */
@@ -833,7 +824,7 @@ This function is called by the editor initialization to begin editing. */)
update_mode_lines = 1;
if (command_loop_level
- && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
+ && current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
buffer = Fcurrent_buffer ();
else
buffer = Qnil;
@@ -1395,7 +1386,7 @@ command_loop_1 (void)
Fkill_emacs (Qnil);
/* Make sure the current window's buffer is selected. */
- set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
+ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
/* Display any malloc warning that just came out. Use while because
displaying one warning can cause another. */
@@ -1461,7 +1452,7 @@ command_loop_1 (void)
/* A filter may have run while we were reading the input. */
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
Fkill_emacs (Qnil);
- set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
+ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
++num_input_keys;
@@ -1492,7 +1483,7 @@ command_loop_1 (void)
{
struct buffer *b;
XWINDOW (selected_window)->force_start = 0;
- b = XBUFFER (XWINDOW (selected_window)->buffer);
+ b = XBUFFER (XWINDOW (selected_window)->contents);
BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
}
@@ -1512,8 +1503,6 @@ command_loop_1 (void)
prev_buffer = current_buffer;
prev_modiff = MODIFF;
last_point_position = PT;
- last_point_position_window = selected_window;
- XSETBUFFER (last_point_position_buffer, prev_buffer);
/* By default, we adjust point to a boundary of a region that
has such a property that should be treated intangible
@@ -1893,7 +1882,7 @@ safe_run_hooks_error (Lisp_Object error_data)
= CONSP (Vinhibit_quit) ? XCAR (Vinhibit_quit) : Vinhibit_quit;
Lisp_Object fun = CONSP (Vinhibit_quit) ? XCDR (Vinhibit_quit) : Qnil;
Lisp_Object args[4];
- args[0] = build_string ("Error in %s (%s): %S");
+ args[0] = build_string ("Error in %s (%S): %S");
args[1] = hook;
args[2] = fun;
args[3] = error_data;
@@ -2230,6 +2219,160 @@ do { if (! polling_stopped_here) stop_polling (); \
do { if (polling_stopped_here) start_polling (); \
polling_stopped_here = 0; } while (0)
+static Lisp_Object
+read_event_from_main_queue (EMACS_TIME *end_time,
+ sys_jmp_buf local_getcjmp,
+ bool *used_mouse_menu)
+{
+ Lisp_Object c = Qnil;
+ sys_jmp_buf save_jump;
+ KBOARD *kb IF_LINT (= NULL);
+
+ start:
+
+ /* Read from the main queue, and if that gives us something we can't use yet,
+ we put it on the appropriate side queue and try again. */
+
+ if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
+ return c;
+
+ /* Actually read a character, waiting if necessary. */
+ save_getcjmp (save_jump);
+ restore_getcjmp (local_getcjmp);
+ if (!end_time)
+ timer_start_idle ();
+ c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
+ restore_getcjmp (save_jump);
+
+ if (! NILP (c) && (kb != current_kboard))
+ {
+ Lisp_Object last = KVAR (kb, kbd_queue);
+ if (CONSP (last))
+ {
+ while (CONSP (XCDR (last)))
+ last = XCDR (last);
+ if (!NILP (XCDR (last)))
+ emacs_abort ();
+ }
+ if (!CONSP (last))
+ kset_kbd_queue (kb, Fcons (c, Qnil));
+ else
+ XSETCDR (last, Fcons (c, Qnil));
+ kb->kbd_queue_has_data = 1;
+ c = Qnil;
+ if (single_kboard)
+ goto start;
+ current_kboard = kb;
+ /* This is going to exit from read_char
+ so we had better get rid of this frame's stuff. */
+ return make_number (-2);
+ }
+
+ /* Terminate Emacs in batch mode if at eof. */
+ if (noninteractive && INTEGERP (c) && XINT (c) < 0)
+ Fkill_emacs (make_number (1));
+
+ if (INTEGERP (c))
+ {
+ /* Add in any extra modifiers, where appropriate. */
+ if ((extra_keyboard_modifiers & CHAR_CTL)
+ || ((extra_keyboard_modifiers & 0177) < ' '
+ && (extra_keyboard_modifiers & 0177) != 0))
+ XSETINT (c, make_ctrl_char (XINT (c)));
+
+ /* Transfer any other modifier bits directly from
+ extra_keyboard_modifiers to c. Ignore the actual character code
+ in the low 16 bits of extra_keyboard_modifiers. */
+ XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
+ }
+
+ /* FIXME: Decode tty keyboard input here. */
+ return c;
+}
+
+
+
+/* Like `read_event_from_main_queue' but applies keyboard-coding-system
+ to tty input. */
+static Lisp_Object
+read_decoded_event_from_main_queue (EMACS_TIME *end_time,
+ sys_jmp_buf local_getcjmp,
+ Lisp_Object prev_event,
+ bool *used_mouse_menu)
+{
+#define MAX_ENCODED_BYTES 16
+ Lisp_Object events[MAX_ENCODED_BYTES];
+ int n = 0;
+ while (true)
+ {
+ Lisp_Object nextevt
+ = read_event_from_main_queue (end_time, local_getcjmp,
+ used_mouse_menu);
+#ifdef WINDOWSNT
+ /* w32_console already returns decoded events. It either reads
+ Unicode characters from the Windows keyboard input, or
+ converts characters encoded in the current codepage into
+ Unicode. See w32inevt.c:key_event, near its end. */
+ return nextevt;
+#else
+ struct frame *frame = XFRAME (selected_frame);
+ struct terminal *terminal = frame->terminal;
+ if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
+ /* Don't apply decoding if we're just reading a raw event
+ (e.g. reading bytes sent by the xterm to specify the position
+ of a mouse click). */
+ && (!EQ (prev_event, Qt))
+ && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
+ & CODING_REQUIRE_DECODING_MASK)))
+ return nextevt; /* No decoding needed. */
+ else
+ {
+ int meta_key = terminal->display_info.tty->meta_key;
+ eassert (n < MAX_ENCODED_BYTES);
+ events[n++] = nextevt;
+ if (NATNUMP (nextevt)
+ && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
+ { /* An encoded byte sequence, let's try to decode it. */
+ struct coding_system *coding
+ = TERMINAL_KEYBOARD_CODING (terminal);
+ unsigned char *src = alloca (n);
+ int i;
+ for (i = 0; i < n; i++)
+ src[i] = XINT (events[i]);
+ if (meta_key != 2)
+ for (i = 0; i < n; i++)
+ src[i] &= ~0x80;
+ coding->destination = alloca (n * 4);
+ coding->dst_bytes = n * 4;
+ decode_coding_c_string (coding, src, n, Qnil);
+ eassert (coding->produced_char <= n);
+ if (coding->produced_char == 0)
+ { /* The encoded sequence is incomplete. */
+ if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
+ continue; /* Read on! */
+ }
+ else
+ {
+ const unsigned char *p = coding->destination;
+ eassert (coding->carryover_bytes == 0);
+ n = 0;
+ while (n < coding->produced_char)
+ events[n++] = make_number (STRING_CHAR_ADVANCE (p));
+ }
+ }
+ /* Now `events' should hold decoded events.
+ Normally, n should be equal to 1, but better not rely on it.
+ We can only return one event here, so return the first we
+ had and keep the others (if any) for later. */
+ while (n > 1)
+ Vunread_command_events
+ = Fcons (events[--n], Vunread_command_events);
+ return events[0];
+ }
+#endif
+ }
+}
+
/* Read a character from the keyboard; call the redisplay if needed. */
/* commandflag 0 means do not autosave, but do redisplay.
-1 means do not redisplay, but do autosave.
@@ -2747,68 +2890,20 @@ read_char (int commandflag, Lisp_Object map,
STOP_POLLING;
- /* Finally, we read from the main queue,
- and if that gives us something we can't use yet, we put it on the
- appropriate side queue and try again. */
-
if (NILP (c))
{
- KBOARD *kb IF_LINT (= NULL);
-
+ c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
+ prev_event, used_mouse_menu);
if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
- goto exit;
-
- /* Actually read a character, waiting if necessary. */
- save_getcjmp (save_jump);
- restore_getcjmp (local_getcjmp);
- if (!end_time)
- timer_start_idle ();
- c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
- restore_getcjmp (save_jump);
-
- if (! NILP (c) && (kb != current_kboard))
- {
- Lisp_Object last = KVAR (kb, kbd_queue);
- if (CONSP (last))
- {
- while (CONSP (XCDR (last)))
- last = XCDR (last);
- if (!NILP (XCDR (last)))
- emacs_abort ();
- }
- if (!CONSP (last))
- kset_kbd_queue (kb, Fcons (c, Qnil));
- else
- XSETCDR (last, Fcons (c, Qnil));
- kb->kbd_queue_has_data = 1;
- c = Qnil;
- if (single_kboard)
- goto wrong_kboard;
- current_kboard = kb;
+ goto exit;
+ if (EQ (c, make_number (-2)))
+ {
/* This is going to exit from read_char
so we had better get rid of this frame's stuff. */
UNGCPRO;
- return make_number (-2);
- }
- }
-
- /* Terminate Emacs in batch mode if at eof. */
- if (noninteractive && INTEGERP (c) && XINT (c) < 0)
- Fkill_emacs (make_number (1));
-
- if (INTEGERP (c))
- {
- /* Add in any extra modifiers, where appropriate. */
- if ((extra_keyboard_modifiers & CHAR_CTL)
- || ((extra_keyboard_modifiers & 0177) < ' '
- && (extra_keyboard_modifiers & 0177) != 0))
- XSETINT (c, make_ctrl_char (XINT (c)));
-
- /* Transfer any other modifier bits directly from
- extra_keyboard_modifiers to c. Ignore the actual character code
- in the low 16 bits of extra_keyboard_modifiers. */
- XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
- }
+ return c;
+ }
+ }
non_reread:
@@ -3915,18 +4010,22 @@ kbd_buffer_get_event (KBOARD **kbp,
kbd_fetch_ptr = event + 1;
}
#endif
-#ifdef WINDOWSNT
+#ifdef USE_FILE_NOTIFY
else if (event->kind == FILE_NOTIFY_EVENT)
{
+#ifdef HAVE_W32NOTIFY
/* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
- obj = Fcons (Qfile_w32notify,
+ obj = Fcons (Qfile_notify,
list2 (list3 (make_number (event->code),
XCAR (event->arg),
XCDR (event->arg)),
event->frame_or_window));
+#else
+ obj = make_lispy_event (event);
+#endif
kbd_fetch_ptr = event + 1;
}
-#endif
+#endif /* USE_FILE_NOTIFY */
else if (event->kind == SAVE_SESSION_EVENT)
{
obj = Fcons (Qsave_session, Fcons (event->arg, Qnil));
@@ -3984,13 +4083,6 @@ kbd_buffer_get_event (KBOARD **kbp,
kbd_fetch_ptr = event + 1;
}
#endif
-#ifdef HAVE_INOTIFY
- else if (event->kind == FILE_NOTIFY_EVENT)
- {
- obj = make_lispy_event (event);
- kbd_fetch_ptr = event + 1;
- }
-#endif
else if (event->kind == CONFIG_CHANGED_EVENT)
{
obj = make_lispy_event (event);
@@ -4196,8 +4288,6 @@ swallow_events (bool do_display)
static void
timer_start_idle (void)
{
- Lisp_Object timers;
-
/* If we are already in the idle state, do nothing. */
if (EMACS_TIME_VALID_P (timer_idleness_start_time))
return;
@@ -4206,16 +4296,7 @@ timer_start_idle (void)
timer_last_idleness_start_time = timer_idleness_start_time;
/* Mark all idle-time timers as once again candidates for running. */
- for (timers = Vtimer_idle_list; CONSP (timers); timers = XCDR (timers))
- {
- Lisp_Object timer;
-
- timer = XCAR (timers);
-
- if (!VECTORP (timer) || ASIZE (timer) != 9)
- continue;
- ASET (timer, 0, Qnil);
- }
+ call0 (intern ("internal-timer-start-idle"));
}
/* Record that Emacs is no longer idle, so stop running idle-time timers. */
@@ -4345,10 +4426,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
}
idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
- idle_timer_difference =
- (idle_timer_ripe
- ? sub_emacs_time (idleness_now, idle_timer_time)
- : sub_emacs_time (idle_timer_time, idleness_now));
+ idle_timer_difference
+ = (idle_timer_ripe
+ ? sub_emacs_time (idleness_now, idle_timer_time)
+ : sub_emacs_time (idle_timer_time, idleness_now));
}
/* Decide which timer is the next timer,
@@ -5142,7 +5223,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
if (STRINGP (string))
string_info = Fcons (string, make_number (charpos));
textpos = (w == XWINDOW (selected_window)
- && current_buffer == XBUFFER (w->buffer))
+ && current_buffer == XBUFFER (w->contents))
? PT : marker_position (w->pointm);
xret = wx;
@@ -5904,12 +5985,12 @@ make_lispy_event (struct input_event *event)
}
#endif /* HAVE_DBUS */
-#ifdef HAVE_INOTIFY
+#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY
case FILE_NOTIFY_EVENT:
{
- return Fcons (Qfile_inotify, event->arg);
+ return Fcons (Qfile_notify, event->arg);
}
-#endif /* HAVE_INOTIFY */
+#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
case CONFIG_CHANGED_EVENT:
return Fcons (Qconfig_changed_event,
@@ -6766,7 +6847,7 @@ gobble_input (void)
hold_quit.kind = NO_EVENT;
/* No need for FIONREAD or fcntl; just say don't wait. */
- while (0 < (nr = (*t->read_socket_hook) (t, &hold_quit)))
+ while ((nr = (*t->read_socket_hook) (t, &hold_quit)) > 0)
nread += nr;
if (nr == -1) /* Not OK to read input now. */
@@ -6846,6 +6927,8 @@ tty_read_avail_input (struct terminal *terminal,
/* XXX I think the following code should be moved to separate hook
functions in system-dependent files. */
#ifdef WINDOWSNT
+ /* FIXME: AFAIK, tty_read_avail_input is not used under w32 since the non-GUI
+ code sets read_socket_hook to w32_console_read_socket instead! */
return 0;
#else /* not WINDOWSNT */
if (! tty->term_initted) /* In case we get called during bootstrap. */
@@ -8240,9 +8323,8 @@ append_tool_bar_item (void)
- (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
/* Enlarge tool_bar_items_vector if necessary. */
- if (0 < incr)
- tool_bar_items_vector
- = larger_vector (tool_bar_items_vector, incr, -1);
+ if (incr > 0)
+ tool_bar_items_vector = larger_vector (tool_bar_items_vector, incr, -1);
/* Append entries from tool_bar_item_properties to the end of
tool_bar_items_vector. */
@@ -8708,71 +8790,6 @@ test_undefined (Lisp_Object binding)
&& EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
}
-/* Like `read_char' but applies keyboard-coding-system to tty input. */
-static Lisp_Object
-read_decoded_char (int commandflag, Lisp_Object map,
- Lisp_Object prev_event, bool *used_mouse_menu)
-{
-#define MAX_ENCODED_BYTES 16
- Lisp_Object events[MAX_ENCODED_BYTES];
- int n = 0;
- while (true)
- {
- Lisp_Object nextevt
- = read_char (commandflag, map, prev_event, used_mouse_menu, NULL);
- struct frame *frame = XFRAME (selected_frame);
- struct terminal *terminal = frame->terminal;
- if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
- && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
- & CODING_REQUIRE_DECODING_MASK)))
- return nextevt; /* No decoding needed. */
- else
- {
- int meta_key = terminal->display_info.tty->meta_key;
- eassert (n < MAX_ENCODED_BYTES);
- events[n++] = nextevt;
- if (NATNUMP (nextevt)
- && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
- { /* An encoded byte sequence, let's try to decode it. */
- struct coding_system *coding
- = TERMINAL_KEYBOARD_CODING (terminal);
- unsigned char *src = alloca (n);
- int i;
- for (i = 0; i < n; i++)
- src[i] = XINT (events[i]);
- if (meta_key != 2)
- for (i = 0; i < n; i++)
- src[i] &= ~0x80;
- coding->destination = alloca (n * 4);
- coding->dst_bytes = n * 4;
- decode_coding_c_string (coding, src, n, Qnil);
- eassert (coding->produced_char <= n);
- if (coding->produced_char == 0)
- { /* The encoded sequence is incomplete. */
- if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
- continue; /* Read on! */
- }
- else
- {
- const unsigned char *p = coding->destination;
- eassert (coding->carryover_bytes == 0);
- n = 0;
- while (n < coding->produced_char)
- events[n++] = make_number (STRING_CHAR_ADVANCE (p));
- }
- }
- /* Now `events' should hold decoded events.
- Normally, n should be equal to 1, but better not rely on it.
- We can only return one event here, so return the first we
- had and keep the others (if any) for later. */
- while (n > 1)
- Vunread_command_events
- = Fcons (events[--n], Vunread_command_events);
- return events[0];
- }
- }
-}
-
/* Read a sequence of keys that ends with a non prefix character,
storing it in KEYBUF, a buffer of size BUFSIZE.
Prompt with PROMPT.
@@ -9050,9 +9067,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
{
KBOARD *interrupted_kboard = current_kboard;
struct frame *interrupted_frame = SELECTED_FRAME ();
- key = read_decoded_char (NILP (prompt),
- current_binding, last_nonmenu_event,
- &used_mouse_menu);
+ key = read_char (NILP (prompt),
+ current_binding, last_nonmenu_event,
+ &used_mouse_menu, NULL);
if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
/* When switching to a new tty (with a new keyboard),
read_char returns the new buffer, rather than -2
@@ -9146,9 +9163,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
{
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
Fkill_emacs (Qnil);
- if (XBUFFER (XWINDOW (selected_window)->buffer)
+ if (XBUFFER (XWINDOW (selected_window)->contents)
!= current_buffer)
- Fset_buffer (XWINDOW (selected_window)->buffer);
+ Fset_buffer (XWINDOW (selected_window)->contents);
}
goto replay_sequence;
@@ -9196,9 +9213,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
special-event-map, ...) might have switched the current buffer
or the selected window from under us in the mean time. */
if (fix_current_buffer
- && (XBUFFER (XWINDOW (selected_window)->buffer)
+ && (XBUFFER (XWINDOW (selected_window)->contents)
!= current_buffer))
- Fset_buffer (XWINDOW (selected_window)->buffer);
+ Fset_buffer (XWINDOW (selected_window)->contents);
current_binding = active_maps (first_event);
}
@@ -9247,8 +9264,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
not the current buffer. If we're at the
beginning of a key sequence, switch buffers. */
if (WINDOWP (window)
- && BUFFERP (XWINDOW (window)->buffer)
- && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+ && BUFFERP (XWINDOW (window)->contents)
+ && XBUFFER (XWINDOW (window)->contents) != current_buffer)
{
ASET (raw_keybuf, raw_keybuf_count, key);
raw_keybuf_count++;
@@ -9269,7 +9286,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
Fkill_emacs (Qnil);
- set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
+ set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
goto replay_sequence;
}
}
@@ -10983,17 +11000,13 @@ syms_of_keyboard (void)
DEFSYM (Qlanguage_change, "language-change");
#endif
-#ifdef WINDOWSNT
- DEFSYM (Qfile_w32notify, "file-w32notify");
-#endif
-
#ifdef HAVE_DBUS
DEFSYM (Qdbus_event, "dbus-event");
#endif
-#ifdef HAVE_INOTIFY
- DEFSYM (Qfile_inotify, "file-inotify");
-#endif /* HAVE_INOTIFY */
+#ifdef USE_FILE_NOTIFY
+ DEFSYM (Qfile_notify, "file-notify");
+#endif /* USE_FILE_NOTIFY */
DEFSYM (QCenable, ":enable");
DEFSYM (QCvisible, ":visible");
@@ -11048,9 +11061,6 @@ syms_of_keyboard (void)
Fset (Qinput_method_exit_on_first_char, Qnil);
Fset (Qinput_method_use_echo_area, Qnil);
- last_point_position_buffer = Qnil;
- last_point_position_window = Qnil;
-
{
int i;
int len = sizeof (head_table) / sizeof (head_table[0]);
@@ -11742,20 +11752,18 @@ keys_of_keyboard (void)
"dbus-handle-event");
#endif
-#ifdef HAVE_INOTIFY
- /* Define a special event which is raised for inotify callback
+#ifdef USE_FILE_NOTIFY
+ /* Define a special event which is raised for notification callback
functions. */
- initial_define_lispy_key (Vspecial_event_map, "file-inotify",
- "inotify-handle-event");
-#endif /* HAVE_INOTIFY */
+ initial_define_lispy_key (Vspecial_event_map, "file-notify",
+ "file-notify-handle-event");
+#endif /* USE_FILE_NOTIFY */
initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
"ignore");
#if defined (WINDOWSNT)
initial_define_lispy_key (Vspecial_event_map, "language-change",
"ignore");
- initial_define_lispy_key (Vspecial_event_map, "file-w32notify",
- "w32notify-handle-event");
#endif
}
diff --git a/src/keymap.c b/src/keymap.c
index 00eefb375ef..c43d528b25b 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -611,7 +611,8 @@ map_keymap_internal (Lisp_Object map,
}
else if (CHAR_TABLE_P (binding))
map_char_table (map_keymap_char_table_item, Qnil, binding,
- make_save_value ("ppo", fun, data, args));
+ make_save_value (SAVE_TYPE_PTR_PTR_OBJ,
+ fun, data, args));
}
UNGCPRO;
return tail;
@@ -1555,8 +1556,8 @@ like in the respective argument of `key-binding'. */)
window = POSN_WINDOW (position);
if (WINDOWP (window)
- && BUFFERP (XWINDOW (window)->buffer)
- && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
+ && BUFFERP (XWINDOW (window)->contents)
+ && XBUFFER (XWINDOW (window)->contents) != current_buffer)
{
/* Arrange to go back to the original buffer once we're done
processing the key sequence. We don't use
@@ -1566,7 +1567,7 @@ like in the respective argument of `key-binding'. */)
things the same.
*/
record_unwind_current_buffer ();
- set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
+ set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
}
}
diff --git a/src/lisp.h b/src/lisp.h
index 44dde1860cc..c8732d125cc 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -75,6 +75,7 @@ enum
BITS_PER_SHORT = CHAR_BIT * sizeof (short),
BITS_PER_INT = CHAR_BIT * sizeof (int),
BITS_PER_LONG = CHAR_BIT * sizeof (long int),
+ BITS_PER_PTRDIFF_T = CHAR_BIT * sizeof (ptrdiff_t),
BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT)
};
@@ -233,9 +234,9 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
#define case_Lisp_Int case Lisp_Int0: case Lisp_Int1
#define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0)
-/* Stolen from GDB. The only known compiler that doesn't support
- enums in bitfields is MSVC. */
-#ifdef _MSC_VER
+/* Idea stolen from GDB. MSVC doesn't support enums in bitfields,
+ and xlc complains vociferously about them. */
+#if defined _MSC_VER || defined __IBMC__
#define ENUM_BF(TYPE) unsigned int
#else
#define ENUM_BF(TYPE) enum TYPE
@@ -556,6 +557,7 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
return num < lower ? lower : num <= upper ? num : upper;
}
+
/* Extract a value or address from a Lisp_Object. */
#define XCONS(a) (eassert (CONSP (a)), \
@@ -576,7 +578,6 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
#define XMISCTYPE(a) (XMISCANY (a)->type)
#define XMARKER(a) (eassert (MARKERP (a)), &(XMISC (a)->u_marker))
#define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay))
-#define XSAVE_VALUE(a) (eassert (SAVE_VALUEP (a)), &(XMISC (a)->u_save_value))
/* Forwarding object types. */
@@ -590,10 +591,12 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
(eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd))
/* Pseudovector types. */
-
+struct Lisp_Process;
+LISP_INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p)
+{ return make_lisp_ptr (p, Lisp_Vectorlike); }
#define XPROCESS(a) (eassert (PROCESSP (a)), \
(struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike))
-#define XWINDOW(a) (eassert (WINDOWP (a)), \
+#define XWINDOW(a) (eassert (WINDOWP (a)), \
(struct window *) XUNTAG (a, Lisp_Vectorlike))
#define XTERMINAL(a) (eassert (TERMINALP (a)), \
(struct terminal *) XUNTAG (a, Lisp_Vectorlike))
@@ -792,13 +795,10 @@ extern ptrdiff_t string_bytes (struct Lisp_String *);
would expose alloc.c internal details that we'd rather keep
private.
- This is a macro for use in static initializers, and a constant for
- visibility to GDB. The cast to ptrdiff_t ensures that
- the macro is signed. */
-static ptrdiff_t const STRING_BYTES_BOUND =
+ This is a macro for use in static initializers. The cast to
+ ptrdiff_t ensures that the macro is signed. */
#define STRING_BYTES_BOUND \
((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1))
- STRING_BYTES_BOUND;
/* Mark STR as a unibyte string. */
#define STRING_SET_UNIBYTE(STR) \
@@ -1403,6 +1403,35 @@ enum
SAVE_OBJECT
};
+/* Number of bits needed to store one of the above values. */
+enum { SAVE_SLOT_BITS = 2 };
+
+/* Number of slots in a save value where save_type is nonzero. */
+enum { SAVE_VALUE_SLOTS = 4 };
+
+/* Bit-width and values for struct Lisp_Save_Value's save_type member. */
+
+enum { SAVE_TYPE_BITS = SAVE_VALUE_SLOTS * SAVE_SLOT_BITS + 1 };
+
+enum Lisp_Save_Type
+ {
+ SAVE_TYPE_INT_INT = SAVE_INTEGER + (SAVE_INTEGER << SAVE_SLOT_BITS),
+ SAVE_TYPE_INT_INT_INT
+ = (SAVE_INTEGER + (SAVE_TYPE_INT_INT << SAVE_SLOT_BITS)),
+ SAVE_TYPE_OBJ_OBJ = SAVE_OBJECT + (SAVE_OBJECT << SAVE_SLOT_BITS),
+ SAVE_TYPE_OBJ_OBJ_OBJ = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ << SAVE_SLOT_BITS),
+ SAVE_TYPE_OBJ_OBJ_OBJ_OBJ
+ = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ_OBJ << SAVE_SLOT_BITS),
+ SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS),
+ SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS),
+ SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS),
+ SAVE_TYPE_PTR_PTR_OBJ
+ = SAVE_POINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS),
+
+ /* This has an extra bit indicating it's raw memory. */
+ SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1))
+ };
+
/* Special object used to hold a different values for later use.
This is mostly used to package C integers and pointers to call
@@ -1423,74 +1452,50 @@ enum
If yon need to pass more than just one C pointer, you should
use make_save_value. This function allows you to pack up to
- 4 integers, pointers or Lisp_Objects and conveniently get them
- back with XSAVE_POINTER, XSAVE_INTEGER and XSAVE_OBJECT macros:
+ SAVE_VALUE_SLOTS integers, pointers or Lisp_Objects and
+ conveniently get them back with XSAVE_POINTER, XSAVE_INTEGER and
+ XSAVE_OBJECT macros:
...
struct my_data *md = get_my_data ();
- ptrdiff_t my_offset = get_my_offset ();
Lisp_Object my_object = get_my_object ();
record_unwind_protect
- (my_unwind, make_save_value ("pio", md, my_offset, my_object));
+ (my_unwind, make_save_value (SAVE_TYPE_PTR_OBJ, md, my_object));
...
Lisp_Object my_unwind (Lisp_Object arg)
{
struct my_data *md = XSAVE_POINTER (arg, 0);
- ptrdiff_t my_offset = XSAVE_INTEGER (arg, 1);
- Lisp_Object my_object = XSAVE_OBJECT (arg, 2);
+ Lisp_Object my_object = XSAVE_OBJECT (arg, 1);
...
}
If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the
saved objects and raise eassert if type of the saved object doesn't match
the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2)
- or XSAVE_OBJECT (arg, 1) are wrong because integer was saved in slot 1 and
- Lisp_Object was saved in slot 2 of ARG. */
+ or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and
+ Lisp_Object was saved in slot 1 of ARG. */
struct Lisp_Save_Value
{
ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */
unsigned gcmarkbit : 1;
- int spacer : 6;
- /* If `area' is nonzero, `data[0].pointer' is the address of a memory area
- containing `data[1].integer' potential Lisp_Objects. The rest of `data'
- fields are unused. */
- unsigned area : 1;
- /* If `area' is zero, `data[N]' may hold different objects which type is
- encoded in `typeN' fields as described by the anonymous enum above.
- E.g. if `type0' is SAVE_INTEGER, `data[0].integer' is in use. */
- unsigned type0 : 2;
- unsigned type1 : 2;
- unsigned type2 : 2;
- unsigned type3 : 2;
+ int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
+
+ /* DATA[N] may hold up to SAVE_VALUE_SLOTS entries. The type of
+ V's Ith entry is given by save_type (V, I). E.g., if save_type
+ (V, 3) == SAVE_INTEGER, V->data[3].integer is in use.
+
+ If SAVE_TYPE == SAVE_TYPE_MEMORY, DATA[0].pointer is the address of
+ a memory area containing DATA[1].integer potential Lisp_Objects. */
+ ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS;
union {
void *pointer;
ptrdiff_t integer;
Lisp_Object object;
- } data[4];
+ } data[SAVE_VALUE_SLOTS];
};
-/* Macro to set and extract Nth saved pointer. Type
- checking is ugly because it's used as an lvalue. */
-
-#define XSAVE_POINTER(obj, n) \
- XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
- ## n == SAVE_POINTER), n)].pointer
-
-/* Likewise for the saved integer. */
-
-#define XSAVE_INTEGER(obj, n) \
- XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
- ## n == SAVE_INTEGER), n)].integer
-
-/* Macro to extract Nth saved object. This is never used as
- an lvalue, so we can do more convenient type checking. */
-
-#define XSAVE_OBJECT(obj, n) \
- (eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT), \
- XSAVE_VALUE (obj)->data[n].object)
-
/* A miscellaneous object, when it's on the free list. */
struct Lisp_Free
{
@@ -1797,7 +1802,66 @@ typedef struct {
#define VECTORP(x) (VECTORLIKEP (x) && !(ASIZE (x) & PSEUDOVECTOR_FLAG))
#define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay)
#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
-#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
+
+LISP_INLINE bool
+SAVE_VALUEP (Lisp_Object x)
+{
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value;
+}
+
+LISP_INLINE struct Lisp_Save_Value *
+XSAVE_VALUE (Lisp_Object a)
+{
+ eassert (SAVE_VALUEP (a));
+ return & XMISC (a)->u_save_value;
+}
+
+/* Return the type of V's Nth saved value. */
+LISP_INLINE int
+save_type (struct Lisp_Save_Value *v, int n)
+{
+ eassert (0 <= n && n < SAVE_VALUE_SLOTS);
+ return (v->save_type >> (SAVE_SLOT_BITS * n) & ((1 << SAVE_SLOT_BITS) - 1));
+}
+
+/* Get and set the Nth saved pointer. */
+
+LISP_INLINE void *
+XSAVE_POINTER (Lisp_Object obj, int n)
+{
+ eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER);
+ return XSAVE_VALUE (obj)->data[n].pointer;;
+}
+LISP_INLINE void
+set_save_pointer (Lisp_Object obj, int n, void *val)
+{
+ eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER);
+ XSAVE_VALUE (obj)->data[n].pointer = val;
+}
+
+/* Likewise for the saved integer. */
+
+LISP_INLINE ptrdiff_t
+XSAVE_INTEGER (Lisp_Object obj, int n)
+{
+ eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER);
+ return XSAVE_VALUE (obj)->data[n].integer;
+}
+LISP_INLINE void
+set_save_integer (Lisp_Object obj, int n, ptrdiff_t val)
+{
+ eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER);
+ XSAVE_VALUE (obj)->data[n].integer = val;
+}
+
+/* Extract Nth saved object. */
+
+LISP_INLINE Lisp_Object
+XSAVE_OBJECT (Lisp_Object obj, int n)
+{
+ eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_OBJECT);
+ return XSAVE_VALUE (obj)->data[n].object;
+}
#define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x)))
@@ -2136,12 +2200,24 @@ typedef jmp_buf sys_jmp_buf;
#endif
+/* Elisp uses several stacks:
+ - the C stack.
+ - the bytecode stack: used internally by the bytecode interpreter.
+ Allocated from the C stack.
+ - The specpdl stack: keeps track of active unwind-protect and
+ dynamic-let-bindings. Allocated from the `specpdl' array, a manually
+ managed stack.
+ - The catch stack: keeps track of active catch tags.
+ Allocated on the C stack. This is where the setmp data is kept.
+ - The handler stack: keeps track of active condition-case handlers.
+ Allocated on the C stack. Every entry there also uses an entry in
+ the catch stack. */
+
/* Structure for recording Lisp call stack for backtrace purposes. */
/* The special binding stack holds the outer values of variables while
they are bound by a function application or a let form, stores the
- code to be executed for Lisp unwind-protect forms, and stores the C
- functions to be called for record_unwind_protect.
+ code to be executed for unwind-protect forms.
If func is non-zero, undoing this binding applies func to old_value;
This implements record_unwind_protect.
@@ -2154,32 +2230,82 @@ typedef jmp_buf sys_jmp_buf;
which means having bound a local value while CURRENT-BUFFER was active.
If WHERE is nil this means we saw the default value when binding SYMBOL.
WHERE being a buffer or frame means we saw a buffer-local or frame-local
- value. Other values of WHERE mean an internal error. */
+ value. Other values of WHERE mean an internal error.
+
+ NOTE: The specbinding struct is defined here, because SPECPDL_INDEX is
+ used all over the place, needs to be fast, and needs to know the size of
+ struct specbinding. But only eval.c should access it. */
typedef Lisp_Object (*specbinding_func) (Lisp_Object);
+enum specbind_tag {
+ SPECPDL_UNWIND, /* An unwind_protect function. */
+ SPECPDL_BACKTRACE, /* An element of the backtrace. */
+ SPECPDL_LET, /* A plain and simple dynamic let-binding. */
+ /* Tags greater than SPECPDL_LET must be "subkinds" of LET. */
+ SPECPDL_LET_LOCAL, /* A buffer-local let-binding. */
+ SPECPDL_LET_DEFAULT /* A global binding for a localized var. */
+};
+
struct specbinding
{
- Lisp_Object symbol, old_value;
- specbinding_func func;
- /* Normally this is unused; but it is to the symbol's current
- value when a thread is swapped out. */
- Lisp_Object saved_value;
+ enum specbind_tag kind;
+ union {
+ struct {
+ Lisp_Object arg;
+ specbinding_func func;
+ } unwind;
+ struct {
+ /* `where' is not used in the case of SPECPDL_LET. */
+ Lisp_Object symbol, old_value, where;
+ /* Normally this is unused; but it is to the symbol's current
+ value when a thread is swapped out. */
+ Lisp_Object saved_value;
+ } let;
+ struct {
+ Lisp_Object function;
+ Lisp_Object *args;
+ ptrdiff_t nargs : BITS_PER_PTRDIFF_T - 1;
+ bool debug_on_exit : 1;
+ } bt;
+ } v;
};
-#define SPECPDL_INDEX() (specpdl_ptr - specpdl)
+LISP_INLINE Lisp_Object specpdl_symbol (struct specbinding *pdl)
+{ eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.symbol; }
-struct backtrace
-{
- struct backtrace *next;
- Lisp_Object function;
- Lisp_Object *args; /* Points to vector of args. */
- ptrdiff_t nargs; /* Length of vector. */
- /* Nonzero means call value of debugger when done with this operation. */
- unsigned int debug_on_exit : 1;
-};
+LISP_INLINE Lisp_Object specpdl_old_value (struct specbinding *pdl)
+{ eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.old_value; }
+
+LISP_INLINE Lisp_Object specpdl_saved_value (struct specbinding *pdl)
+{ eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.saved_value; }
-extern struct backtrace *backtrace_list;
+LISP_INLINE Lisp_Object specpdl_where (struct specbinding *pdl)
+{ eassert (pdl->kind > SPECPDL_LET); return pdl->v.let.where; }
+
+LISP_INLINE Lisp_Object specpdl_arg (struct specbinding *pdl)
+{ eassert (pdl->kind == SPECPDL_UNWIND); return pdl->v.unwind.arg; }
+
+LISP_INLINE specbinding_func specpdl_func (struct specbinding *pdl)
+{ eassert (pdl->kind == SPECPDL_UNWIND); return pdl->v.unwind.func; }
+
+LISP_INLINE Lisp_Object backtrace_function (struct specbinding *pdl)
+{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.function; }
+
+LISP_INLINE ptrdiff_t backtrace_nargs (struct specbinding *pdl)
+{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.nargs; }
+
+LISP_INLINE Lisp_Object *backtrace_args (struct specbinding *pdl)
+{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.args; }
+
+LISP_INLINE bool backtrace_debug_on_exit (struct specbinding *pdl)
+{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.debug_on_exit; }
+
+/* extern struct specbinding *specpdl; */
+/* extern struct specbinding *specpdl_ptr; */
+/* extern ptrdiff_t specpdl_size; */
+
+#define SPECPDL_INDEX() (specpdl_ptr - specpdl)
/* Everything needed to describe an active condition case.
@@ -2235,9 +2361,10 @@ struct catchtag
Lisp_Object tag;
Lisp_Object volatile val;
struct catchtag *volatile next;
+#if 1 /* GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS, but they're defined later. */
struct gcpro *gcpro;
+#endif
sys_jmp_buf jmp;
- struct backtrace *backlist;
struct handler *f_handlerlist;
EMACS_INT f_lisp_eval_depth;
ptrdiff_t volatile pdlcount;
@@ -3122,7 +3249,7 @@ extern bool abort_on_gc;
extern Lisp_Object make_float (double);
extern void display_malloc_warning (void);
extern ptrdiff_t inhibit_garbage_collection (void);
-extern Lisp_Object make_save_value (const char *, ...);
+extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...);
extern Lisp_Object make_save_pointer (void *);
extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
extern void free_marker (Lisp_Object);
@@ -3180,6 +3307,7 @@ extern Lisp_Object internal_with_output_to_temp_buffer
(const char *, Lisp_Object (*) (Lisp_Object), Lisp_Object);
enum FLOAT_TO_STRING_BUFSIZE { FLOAT_TO_STRING_BUFSIZE = 350 };
extern int float_to_string (char *, double);
+extern void init_print_once (void);
extern void syms_of_print (void);
/* Defined in doprnt.c. */
@@ -3294,6 +3422,14 @@ extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
extern void init_eval (void);
extern void syms_of_eval (void);
+extern void record_in_backtrace (Lisp_Object function,
+ Lisp_Object *args, ptrdiff_t nargs);
+extern void mark_specpdl (struct specbinding *first, struct specbinding *ptr);
+extern void get_backtrace (Lisp_Object array);
+Lisp_Object backtrace_top_function (void);
+extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
+extern bool let_shadows_global_binding_p (Lisp_Object symbol);
+
/* Defined in thread.c. */
extern void mark_threads (void);
@@ -3464,7 +3600,7 @@ extern Lisp_Object Qvisible;
extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object);
extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
-#if HAVE_NS
+#if HAVE_NS || defined(WINDOWSNT)
extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
#endif
extern void frames_discard_buffer (Lisp_Object);
@@ -3678,9 +3814,9 @@ extern void syms_of_fontset (void);
extern Lisp_Object Qfont_param;
#endif
-#ifdef WINDOWSNT
-/* Defined on w32notify.c. */
-extern void syms_of_w32notify (void);
+/* Defined in gfilenotify.c */
+#ifdef HAVE_GFILENOTIFY
+extern void syms_of_gfilenotify (void);
#endif
/* Defined in inotify.c */
@@ -3688,6 +3824,11 @@ extern void syms_of_w32notify (void);
extern void syms_of_inotify (void);
#endif
+#ifdef HAVE_W32NOTIFY
+/* Defined on w32notify.c. */
+extern void syms_of_w32notify (void);
+#endif
+
/* Defined in xfaces.c. */
extern Lisp_Object Qdefault, Qtool_bar, Qfringe;
extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
@@ -3728,11 +3869,6 @@ extern void syms_of_xml (void);
extern void xml_cleanup_parser (void);
#endif
-#ifdef HAVE_MENUS
-/* Defined in (x|w32)fns.c, nsfns.m... */
-extern int have_menus_p (void);
-#endif
-
#ifdef HAVE_DBUS
/* Defined in dbusbind.c. */
void syms_of_dbusbind (void);
@@ -3840,8 +3976,7 @@ extern void *record_xmalloc (size_t);
{ \
Lisp_Object arg_; \
buf = xmalloc ((nelt) * word_size); \
- arg_ = make_save_value ("pi", buf, nelt); \
- XSAVE_VALUE (arg_)->area = 1; \
+ arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \
sa_must_free = 1; \
record_unwind_protect (safe_alloca_unwind, arg_); \
} \
diff --git a/src/lread.c b/src/lread.c
index f8ab03af218..3ca644bb45b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -201,6 +201,9 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
ptrdiff_t pt_byte = BUF_PT_BYTE (inbuffer);
+ if (! BUFFER_LIVE_P (inbuffer))
+ return -1;
+
if (pt_byte >= BUF_ZV_BYTE (inbuffer))
return -1;
@@ -375,6 +378,19 @@ skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n)
}
}
+static void
+skip_dyn_eof (Lisp_Object readcharfun)
+{
+ if (FROM_FILE_P (readcharfun))
+ {
+ block_input (); /* FIXME: Not sure if it's needed. */
+ fseek (instream, 0, SEEK_END);
+ unblock_input ();
+ }
+ else
+ while (READCHAR >= 0);
+}
+
/* Unread the character C in the way appropriate for the stream READCHARFUN.
If the stream is a user function, call it with the char as argument. */
@@ -1571,7 +1587,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
{
struct stat st;
fd = emacs_open (pfn, O_RDONLY, 0);
- if (0 <= fd
+ if (fd >= 0
&& (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode)))
{
emacs_close (fd);
@@ -1976,7 +1992,9 @@ STREAM or the value of `standard-input' may be:
if (EQ (stream, Qt))
stream = Qread_char;
if (EQ (stream, Qread_char))
- return Fread_minibuffer (build_string ("Lisp expression: "), Qnil);
+ /* FIXME: ¿¡ When is this used !? */
+ return call1 (intern ("read-minibuffer"),
+ build_string ("Lisp expression: "));
return read_internal_start (stream, Qnil, Qnil);
}
@@ -2359,7 +2377,7 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
while (c == '0');
}
- while (-1 <= (digit = digit_to_number (c, radix)))
+ while ((digit = digit_to_number (c, radix)) >= -1)
{
if (digit == -1)
valid = 0;
@@ -2617,7 +2635,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
if (c == '@')
{
enum { extra = 100 };
- ptrdiff_t i, nskip = 0;
+ ptrdiff_t i, nskip = 0, digits = 0;
/* Read a decimal integer. */
while ((c = READCHAR) >= 0
@@ -2625,8 +2643,14 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
{
if ((STRING_BYTES_BOUND - extra) / 10 <= nskip)
string_overflow ();
+ digits++;
nskip *= 10;
nskip += c - '0';
+ if (digits == 2 && nskip == 0)
+ { /* We've just seen #@00, which means "skip to end". */
+ skip_dyn_eof (readcharfun);
+ return Qnil;
+ }
}
if (nskip > 0)
/* We can't use UNREAD here, because in the code below we side-step
@@ -2636,7 +2660,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
nskip--;
else
UNREAD (c);
-
+
if (load_force_doc_strings
&& (FROM_FILE_P (readcharfun)))
{
@@ -3298,12 +3322,12 @@ string_to_number (char const *string, int base, bool ignore_trailing)
state = 0;
leading_digit = digit_to_number (*cp, base);
- if (0 <= leading_digit)
+ if (leading_digit >= 0)
{
state |= LEAD_INT;
do
++cp;
- while (0 <= digit_to_number (*cp, base));
+ while (digit_to_number (*cp, base) >= 0);
}
if (*cp == '.')
{
@@ -3380,7 +3404,7 @@ string_to_number (char const *string, int base, bool ignore_trailing)
/* If the number uses integer and not float syntax, and is in C-language
range, use its value, preferably as a fixnum. */
- if (0 <= leading_digit && ! float_syntax)
+ if (leading_digit >= 0 && ! float_syntax)
{
uintmax_t n;
@@ -3533,7 +3557,7 @@ read_list (bool flag, Lisp_Object readcharfun)
{
if (NILP (Vdoc_file_name))
/* We have not yet called Snarf-documentation, so assume
- this file is described in the DOC-MM.NN file
+ this file is described in the DOC file
and Snarf-documentation will fill in the right value later.
For now, replace the whole list with 0. */
doc_reference = 1;
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 93f12900dde..272b053ed12 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -41,7 +41,7 @@ TRES = $(BLD)/emacs.res
TLASTLIB = $(BLD)/lastfile.$(A)
GNULIB = ../lib/$(BLD)/libgnu.$(A)
-DOC = $(OBJDIR)/etc/DOC-X
+DOC = $(OBJDIR)/etc/DOC
FULL_LINK_FLAGS = $(LINK_FLAGS) $(TEMACS_EXTRA_LINK)
@@ -388,6 +388,9 @@ EMACS_ROOT = ..
GNU_LIB = $(EMACS_ROOT)/lib
NT_INC = $(EMACS_ROOT)/nt/inc
+ACL_H = $(GNU_LIB)/acl.h \
+ $(NT_INC)/sys/stat.h \
+ $(NT_INC)/stdbool.h
SYSTIME_H = $(SRC)/systime.h \
$(NT_INC)/sys/time.h \
$(GNU_LIB)/timespec.h
@@ -848,6 +851,7 @@ $(BLD)/fileio.$(O) : \
$(NT_INC)/sys/stat.h \
$(NT_INC)/unistd.h \
$(GNU_LIB)/allocator.h \
+ $(ACL_H) \
$(BUFFER_H) \
$(CAREADLINKAT_H) \
$(CHARACTER_H) \
@@ -873,6 +877,7 @@ $(BLD)/filelock.$(O) : \
$(CHARACTER_H) \
$(CODING_H) \
$(CONFIG_H) \
+ $(C_CTYPE_H) \
$(LISP_H) \
$(SYSTIME_H)
@@ -1398,6 +1403,7 @@ $(BLD)/sysdep.$(O) : \
$(NT_INC)/netdb.h \
$(NT_INC)/pwd.h \
$(NT_INC)/sys/file.h \
+ $(NT_INC)/sys/param.h \
$(NT_INC)/sys/stat.h \
$(NT_INC)/unistd.h \
$(GNU_LIB)/execinfo.h \
diff --git a/src/menu.c b/src/menu.c
index fdef54dd657..58558d5aedd 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -173,7 +173,7 @@ static void
ensure_menu_items (int items)
{
int incr = items - (menu_items_allocated - menu_items_used);
- if (0 < incr)
+ if (incr > 0)
{
menu_items = larger_vector (menu_items, incr, INT_MAX);
menu_items_allocated = ASIZE (menu_items);
@@ -1085,7 +1085,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
#ifdef HAVE_MENUS
{
bool get_current_pos_p = 0;
- /* FIXME!! check_w32 (); or check_x (); or check_ns (); */
+
+ check_window_system (SELECTED_FRAME ());
/* Decode the first argument: find the window and the coordinates. */
if (EQ (position, Qt)
diff --git a/src/minibuf.c b/src/minibuf.c
index 25425cb97dc..b69a16eff42 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -114,7 +114,7 @@ choose_minibuf_frame (void)
/* Under X, we come here with minibuf_window being the
minibuffer window of the unused termcap window created in
init_window_once. That window doesn't have a buffer. */
- buffer = XWINDOW (minibuf_window)->buffer;
+ buffer = XWINDOW (minibuf_window)->contents;
if (BUFFERP (buffer))
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
@@ -844,7 +844,7 @@ read_minibuf_unwind (Lisp_Object data)
window = minibuf_window;
/* To keep things predictable, in case it matters, let's be in the
minibuffer when we reset the relevant variables. */
- Fset_buffer (XWINDOW (window)->buffer);
+ Fset_buffer (XWINDOW (window)->contents);
/* Restore prompt, etc, from outer minibuffer level. */
minibuf_prompt = Fcar (minibuf_save_list);
@@ -986,34 +986,6 @@ and some related functions, which use zero-indexing for POSITION. */)
return val;
}
-DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0,
- doc: /* Return a Lisp object read using the minibuffer, unevaluated.
-Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
-is a string to insert in the minibuffer before reading.
-\(INITIAL-CONTENTS can also be a cons of a string and an integer.
-Such arguments are used as in `read-from-minibuffer'.) */)
- (Lisp_Object prompt, Lisp_Object initial_contents)
-{
- CHECK_STRING (prompt);
- return read_minibuf (Vminibuffer_local_map, initial_contents,
- prompt, 1, Qminibuffer_history,
- make_number (0), Qnil, 0, 0);
-}
-
-DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
- doc: /* Return value of Lisp expression read using the minibuffer.
-Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
-is a string to insert in the minibuffer before reading.
-\(INITIAL-CONTENTS can also be a cons of a string and an integer.
-Such arguments are used as in `read-from-minibuffer'.) */)
- (Lisp_Object prompt, Lisp_Object initial_contents)
-{
- return Feval (read_minibuf (Vread_expression_map, initial_contents,
- prompt, 1, Qread_expression_history,
- make_number (0), Qnil, 0, 0),
- Qnil);
-}
-
/* Functions that use the minibuffer to read various things. */
DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0,
@@ -1799,18 +1771,22 @@ the values STRING, PREDICATE and `lambda'. */)
else if (HASH_TABLE_P (collection))
{
struct Lisp_Hash_Table *h = XHASH_TABLE (collection);
+ Lisp_Object key = Qnil;
i = hash_lookup (h, string, NULL);
if (i >= 0)
tem = HASH_KEY (h, i);
else
for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
if (!NILP (HASH_HASH (h, i))
+ && (key = HASH_KEY (h, i),
+ SYMBOLP (key) ? key = Fsymbol_name (key) : key,
+ STRINGP (key))
&& EQ (Fcompare_strings (string, make_number (0), Qnil,
- HASH_KEY (h, i), make_number (0) , Qnil,
+ key, make_number (0) , Qnil,
completion_ignore_case ? Qt : Qnil),
Qt))
{
- tem = HASH_KEY (h, i);
+ tem = key;
break;
}
if (!STRINGP (tem))
@@ -2133,15 +2109,9 @@ properties. */);
Vminibuffer_prompt_properties
= Fcons (intern_c_string ("read-only"), Fcons (Qt, Qnil));
- DEFVAR_LISP ("read-expression-map", Vread_expression_map,
- doc: /* Minibuffer keymap used for reading Lisp expressions. */);
- Vread_expression_map = Qnil;
-
defsubr (&Sactive_minibuffer_window);
defsubr (&Sset_minibuffer_window);
defsubr (&Sread_from_minibuffer);
- defsubr (&Seval_minibuffer);
- defsubr (&Sread_minibuffer);
defsubr (&Sread_string);
defsubr (&Sread_command);
defsubr (&Sread_variable);
diff --git a/src/msdos.c b/src/msdos.c
index ee47109d5f2..a2bcc06ac17 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -1261,7 +1261,7 @@ IT_update_begin (struct frame *f)
/* If the mouse highlight is in the window that was deleted
(e.g., if it was popped by completion), clear highlight
unconditionally. */
- if (NILP (w->buffer))
+ if (NILP (w->contents))
hlinfo->mouse_face_window = Qnil;
else
{
@@ -1271,7 +1271,7 @@ IT_update_begin (struct frame *f)
break;
}
- if (NILP (w->buffer) || i < w->desired_matrix->nrows)
+ if (NILP (w->contents) || i < w->desired_matrix->nrows)
clear_mouse_face (hlinfo);
}
}
@@ -1321,7 +1321,7 @@ IT_frame_up_to_date (struct frame *f)
new_cursor = frame_desired_cursor;
else
{
- struct buffer *b = XBUFFER (sw->buffer);
+ struct buffer *b = XBUFFER (sw->contents);
if (EQ (BVAR (b,cursor_type), Qt))
new_cursor = frame_desired_cursor;
@@ -1920,7 +1920,7 @@ dos_get_saved_screen (char **screen, int *rows, int *cols)
/* We are not X, but we can emulate it well enough for our needs... */
void
-check_x (void)
+check_window_system (void)
{
if (! FRAME_MSDOS_P (SELECTED_FRAME ()))
error ("Not running under a window system");
@@ -2983,11 +2983,6 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
/* --------------------------- X Menu emulation ---------------------- */
-/* Report availability of menus. */
-
-int
-have_menus_p (void) { return 1; }
-
/* Create a brand new menu structure. */
XMenu *
diff --git a/src/nsfns.m b/src/nsfns.m
index ef18acaa045..94339183159 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -44,6 +44,10 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
#include "fontset.h"
#include "font.h"
+#ifdef NS_IMPL_COCOA
+#include <IOKit/graphics/IOGraphicsLib.h>
+#endif
+
#if 0
int fns_trace_num = 1;
#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
@@ -88,7 +92,7 @@ Lisp_Object Qfontsize;
/* hack for OS X file panels */
char panelOK = 0;
-EmacsTooltip *ns_tooltip;
+EmacsTooltip *ns_tooltip = nil;
/* Need forward declaration here to preserve organizational integrity of file */
Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object);
@@ -101,87 +105,52 @@ static int as_status;
static ptrdiff_t image_cache_refcount;
#endif
+
/* ==========================================================================
Internal utility functions
========================================================================== */
+/* Let the user specify a Nextstep display with a Lisp object.
+ OBJECT may be nil, a frame or a terminal object.
+ nil stands for the selected frame--or, if that is not a Nextstep frame,
+ the first Nextstep display on the list. */
-void
-check_ns (void)
-{
- if (NSApp == nil)
- error ("OpenStep is not in use or not initialized");
-}
-
-
-/* Nonzero if we can use mouse menus. */
-int
-have_menus_p (void)
-{
- return NSApp != nil;
-}
-
-
-/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
- and checking validity for NS. */
-static FRAME_PTR
-check_ns_frame (Lisp_Object frame)
+static struct ns_display_info *
+check_ns_display_info (Lisp_Object object)
{
- FRAME_PTR f;
+ struct ns_display_info *dpyinfo = NULL;
- if (NILP (frame))
- f = SELECTED_FRAME ();
- else
+ if (NILP (object))
{
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
- }
- if (! FRAME_NS_P (f))
- error ("non-Nextstep frame used");
- return f;
-}
-
+ struct frame *sf = XFRAME (selected_frame);
-/* Let the user specify an Nextstep display with a frame.
- nil stands for the selected frame--or, if that is not an Nextstep frame,
- the first Nextstep display on the list. */
-static struct ns_display_info *
-check_ns_display_info (Lisp_Object frame)
-{
- if (NILP (frame))
- {
- struct frame *f = SELECTED_FRAME ();
- if (FRAME_NS_P (f) && FRAME_LIVE_P (f) )
- return FRAME_NS_DISPLAY_INFO (f);
+ if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
+ dpyinfo = FRAME_NS_DISPLAY_INFO (sf);
else if (x_display_list != 0)
- return x_display_list;
+ dpyinfo = x_display_list;
else
error ("Nextstep windows are not in use or not initialized");
}
- else if (INTEGERP (frame))
+ else if (TERMINALP (object))
{
- struct terminal *t = get_terminal (frame, 1);
+ struct terminal *t = get_terminal (object, 1);
if (t->type != output_ns)
- error ("Terminal %"pI"d is not a Nextstep display", XINT (frame));
+ error ("Terminal %d is not a Nextstep display", t->id);
- return t->display_info.ns;
+ dpyinfo = t->display_info.ns;
}
- else if (STRINGP (frame))
- return ns_display_info_for_name (frame);
+ else if (STRINGP (object))
+ dpyinfo = ns_display_info_for_name (object);
else
{
- FRAME_PTR f;
-
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
- if (! FRAME_NS_P (f))
- error ("non-Nextstep frame used");
- return FRAME_NS_DISPLAY_INFO (f);
+ FRAME_PTR f = decode_window_system_frame (object);
+ dpyinfo = FRAME_NS_DISPLAY_INFO (f);
}
- return NULL; /* shut compiler up */
+
+ return dpyinfo;
}
@@ -201,35 +170,6 @@ ns_get_window (Lisp_Object maybeFrame)
}
-static NSScreen *
-ns_get_screen (Lisp_Object screen)
-{
- struct frame *f;
- struct terminal *terminal;
-
- if (EQ (Qt, screen)) /* not documented */
- return [NSScreen mainScreen];
-
- terminal = get_terminal (screen, 1);
- if (terminal->type != output_ns)
- return NULL;
-
- if (NILP (screen))
- f = SELECTED_FRAME ();
- else if (FRAMEP (screen))
- f = XFRAME (screen);
- else
- {
- struct ns_display_info *dpyinfo = terminal->display_info.ns;
- f = dpyinfo->x_focus_frame
- ? dpyinfo->x_focus_frame : dpyinfo->x_highlight_frame;
- }
-
- return ((f && FRAME_NS_P (f)) ? [[FRAME_NS_VIEW (f) window] screen]
- : NULL);
-}
-
-
/* Return the X display structure for the display named NAME.
Open a new connection if necessary. */
struct ns_display_info *
@@ -347,7 +287,7 @@ static void
x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
NSColor *col;
- CGFloat r, g, b, alpha;
+ EmacsCGFloat r, g, b, alpha;
if (ns_lisp_to_color (arg, &col))
{
@@ -379,7 +319,7 @@ x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
struct face *face;
NSColor *col;
NSView *view = FRAME_NS_VIEW (f);
- CGFloat r, g, b, alpha;
+ EmacsCGFloat r, g, b, alpha;
if (ns_lisp_to_color (arg, &col))
{
@@ -404,7 +344,7 @@ x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
[[view window] setBackgroundColor: col];
- if (alpha != 1.0)
+ if (alpha != (EmacsCGFloat) 1.0)
[[view window] setOpaque: NO];
else
[[view window] setOpaque: YES];
@@ -619,7 +559,7 @@ ns_set_name_as_filename (struct frame *f)
{
NSView *view;
Lisp_Object name, filename;
- Lisp_Object buf = XWINDOW (f->selected_window)->buffer;
+ Lisp_Object buf = XWINDOW (f->selected_window)->contents;
const char *title;
NSAutoreleasePool *pool;
struct gcpro gcpro1;
@@ -774,7 +714,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
}
-void
+static void
ns_implicitly_set_icon_type (struct frame *f)
{
Lisp_Object tem;
@@ -919,7 +859,7 @@ ns_cursor_type_to_lisp (int arg)
}
/* This is the same as the xfns.c definition. */
-void
+static void
x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
{
set_frame_cursor_types (f, arg);
@@ -1142,11 +1082,8 @@ This function is an internal primitive--use `make-frame' instead. */)
struct ns_display_info *dpyinfo = NULL;
Lisp_Object parent;
struct kboard *kb;
- Lisp_Object tfont, tfontsize;
static int desc_ctr = 1;
- check_ns ();
-
/* x_get_arg modifies parms. */
parms = Fcopy_alist (parms);
@@ -1243,9 +1180,6 @@ This function is an internal primitive--use `make-frame' instead. */)
specbind (Qx_resource_name, name);
}
- f->resx = dpyinfo->resx;
- f->resy = dpyinfo->resy;
-
block_input ();
register_font_driver (&nsfont_driver, f);
x_default_parameter (f, parms, Qfont_backend, Qnil,
@@ -1254,10 +1188,10 @@ This function is an internal primitive--use `make-frame' instead. */)
{
/* use for default font name */
id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
- tfontsize = x_default_parameter (f, parms, Qfontsize,
+ x_default_parameter (f, parms, Qfontsize,
make_number (0 /*(int)[font pointSize]*/),
"fontSize", "FontSize", RES_TYPE_NUMBER);
- tfont = x_default_parameter (f, parms, Qfont,
+ x_default_parameter (f, parms, Qfont,
build_string ([[font fontName] UTF8String]),
"font", "Font", RES_TYPE_STRING);
}
@@ -1421,7 +1355,7 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
FRAME nil means use the selected frame. */)
(Lisp_Object frame)
{
- struct frame *f = check_ns_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
if (dpyinfo->x_focus_frame != f)
@@ -1442,18 +1376,8 @@ DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
doc: /* Pop up the font panel. */)
(Lisp_Object frame)
{
- id fm;
- struct frame *f;
-
- check_ns ();
- fm = [NSFontManager sharedFontManager];
- if (NILP (frame))
- f = SELECTED_FRAME ();
- else
- {
- CHECK_FRAME (frame);
- f = XFRAME (frame);
- }
+ struct frame *f = decode_window_system_frame (frame);
+ id fm = [NSFontManager sharedFontManager];
[fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont
isMultiple: NO];
@@ -1467,17 +1391,7 @@ DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel,
doc: /* Pop up the color panel. */)
(Lisp_Object frame)
{
- struct frame *f;
-
- check_ns ();
- if (NILP (frame))
- f = SELECTED_FRAME ();
- else
- {
- CHECK_FRAME (frame);
- f = XFRAME (frame);
- }
-
+ check_window_system (NULL);
[NSApp orderFrontColorPanel: NSApp];
return Qnil;
}
@@ -1495,6 +1409,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
{
static id fileDelegate = nil;
BOOL ret;
+ BOOL isSave = NILP (mustmatch) && NILP (dir_only_p);
id panel;
Lisp_Object fname;
@@ -1506,7 +1421,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
NSString *initS = NILP (init) || !STRINGP (init) ? nil :
[NSString stringWithUTF8String: SSDATA (init)];
- check_ns ();
+ check_window_system (NULL);
if (fileDelegate == nil)
fileDelegate = [EmacsFileDelegate new];
@@ -1516,7 +1431,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
if ([dirS characterAtIndex: 0] == '~')
dirS = [dirS stringByExpandingTildeInPath];
- panel = NILP (mustmatch) && NILP (dir_only_p) ?
+ panel = isSave ?
(id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel];
[panel setTitle: promptS];
@@ -1531,7 +1446,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
[panel setCanChooseDirectories: YES];
[panel setCanChooseFiles: NO];
}
- else
+ else if (! isSave)
{
/* This is not quite what the documentation says, but it is compatible
with the Gtk+ code. Also, the menu entry says "Open File...". */
@@ -1539,7 +1454,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
[panel setCanChooseFiles: YES];
}
- block_input ();
+ block_input ();
#if defined (NS_IMPL_COCOA) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
if (! NILP (mustmatch) || ! NILP (dir_only_p))
@@ -1564,10 +1479,10 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
ret = (ret == NSOKButton) || panelOK;
- if (ret)
+ if (ret)
{
- NSString *str = [panel getFilename];
- if (! str) str = [panel getDirectory];
+ NSString *str = ns_filename_from_panel (panel);
+ if (! str) str = ns_directory_from_panel (panel);
if (! str) ret = NO;
else fname = build_string ([str UTF8String]);
}
@@ -1597,11 +1512,10 @@ If OWNER is nil, Emacs is assumed. */)
{
const char *value;
- check_ns ();
+ check_window_system (NULL);
if (NILP (owner))
owner = build_string([ns_app_name UTF8String]);
CHECK_STRING (name);
-/*fprintf (stderr, "ns-get-resource checking resource '%s'\n", SSDATA (name)); */
value = ns_get_defaults_value (SSDATA (name));
@@ -1617,7 +1531,7 @@ If OWNER is nil, Emacs is assumed.
If VALUE is nil, the default is removed. */)
(Lisp_Object owner, Lisp_Object name, Lisp_Object value)
{
- check_ns ();
+ check_window_system (NULL);
if (NILP (owner))
owner = build_string ([ns_app_name UTF8String]);
CHECK_STRING (name);
@@ -1643,9 +1557,9 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
Sx_server_max_request_size,
0, 1, 0,
doc: /* This function is a no-op. It is only present for completeness. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- check_ns ();
+ check_ns_display_info (terminal);
/* This function has no real equivalent under NeXTstep. Return nil to
indicate this. */
return Qnil;
@@ -1653,11 +1567,15 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- doc: /* Return the vendor ID string of Nextstep display server DISPLAY.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+ doc: /* Return the "vendor ID" string of Nextstep display server TERMINAL.
+\(Labeling every distributor as a "vendor" embodies the false assumption
+that operating systems cannot be developed and distributed noncommercially.)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
+ check_ns_display_info (terminal);
#ifdef NS_IMPL_GNUSTEP
return build_string ("GNU");
#else
@@ -1667,16 +1585,17 @@ If omitted or nil, the selected frame's display is used. */)
DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- doc: /* Return the version numbers of the server of DISPLAY.
+ doc: /* Return the version numbers of the server of display TERMINAL.
The value is a list of three integers: the major and minor
-version numbers of the X Protocol in use, and the distributor-specific
-release number. See also the function `x-server-vendor'.
+version numbers of the X Protocol in use, and the distributor-specific release
+number. See also the function `x-server-vendor'.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
+ check_ns_display_info (terminal);
/*NOTE: it is unclear what would best correspond with "protocol";
we return 10.3, meaning Panther, since this is roughly the
level that GNUstep's APIs correspond to.
@@ -1688,56 +1607,66 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
- doc: /* Return the number of screens on Nextstep display server DISPLAY.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
-{
- int num;
-
- check_ns ();
- num = [[NSScreen screens] count];
+ doc: /* Return the number of screens on Nextstep display server TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
- return (num != 0) ? make_number (num) : Qnil;
+Note: "screen" here is not in Nextstep terminology but in X11's. For
+the number of physical monitors, use `(length
+(display-monitor-attributes-list TERMINAL))' instead. */)
+ (Lisp_Object terminal)
+{
+ check_ns_display_info (terminal);
+ return make_number (1);
}
-DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height,
- 0, 1, 0,
- doc: /* Return the height of Nextstep display server DISPLAY, in millimeters.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
+ doc: /* Return the height in millimeters of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the height in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns ();
- return make_number ((int)
- ([ns_get_screen (display) frame].size.height/(92.0/25.4)));
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
}
-DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width,
- 0, 1, 0,
- doc: /* Return the width of Nextstep display server DISPLAY, in millimeters.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
+ doc: /* Return the width in millimeters of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the width in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns ();
- return make_number ((int)
- ([ns_get_screen (display) frame].size.width/(92.0/25.4)));
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
Sx_display_backing_store, 0, 1, 0,
- doc: /* Return whether the Nextstep display DISPLAY supports backing store.
+ doc: /* Return an indication of whether the Nextstep display TERMINAL does backing store.
The value may be `buffered', `retained', or `non-retained'.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
- check_ns ();
- switch ([ns_get_window (display) backingType])
+ check_ns_display_info (terminal);
+ switch ([ns_get_window (terminal) backingType])
{
case NSBackingStoreBuffered:
return intern ("buffered");
@@ -1754,16 +1683,19 @@ If omitted or nil, the selected frame's display is used. */)
DEFUN ("x-display-visual-class", Fx_display_visual_class,
Sx_display_visual_class, 0, 1, 0,
- doc: /* Return the visual class of the Nextstep display server DISPLAY.
+ doc: /* Return the visual class of the Nextstep display TERMINAL.
The value is one of the symbols `static-gray', `gray-scale',
`static-color', `pseudo-color', `true-color', or `direct-color'.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
- check_ns ();
- depth = [ns_get_screen (display) depth];
+
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
return intern ("static-gray");
@@ -1783,14 +1715,14 @@ If omitted or nil, the selected frame's display is used. */)
DEFUN ("x-display-save-under", Fx_display_save_under,
Sx_display_save_under, 0, 1, 0,
- doc: /* Return t if DISPLAY supports the save-under feature.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be a frame, the display name as a string, or a terminal ID.
-If omitted or nil, the selected frame's display is used. */)
- (Lisp_Object display)
-{
- check_ns ();
- switch ([ns_get_window (display) backingType])
+ doc: /* Return t if TERMINAL supports the save-under feature.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
+{
+ check_ns_display_info (terminal);
+ switch ([ns_get_window (terminal) backingType])
{
case NSBackingStoreBuffered:
return Qt;
@@ -1838,12 +1770,13 @@ terminate Emacs if we can't open the connection.
DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
1, 1, 0,
- doc: /* Close the connection to the current Nextstep display server.
-The argument DISPLAY is currently ignored. */)
- (Lisp_Object display)
+ doc: /* Close the connection to TERMINAL's Nextstep display server.
+For TERMINAL, specify a terminal object, a frame or a display name (a
+string). If TERMINAL is nil, that stands for the selected frame's
+terminal. */)
+ (Lisp_Object terminal)
{
- check_ns ();
- /*ns_delete_terminal (dpyinfo->terminal); */
+ check_ns_display_info (terminal);
[NSApp terminate: NSApp];
return Qnil;
}
@@ -1868,7 +1801,7 @@ DEFUN ("ns-hide-others", Fns_hide_others, Sns_hide_others,
doc: /* Hides all applications other than Emacs. */)
(void)
{
- check_ns ();
+ check_window_system (NULL);
[NSApp hideOtherApplications: NSApp];
return Qnil;
}
@@ -1881,7 +1814,7 @@ If ON is equal to `activate', Emacs is unhidden and becomes
the active application. */)
(Lisp_Object on)
{
- check_ns ();
+ check_window_system (NULL);
if (EQ (on, intern ("activate")))
{
[NSApp unhide: NSApp];
@@ -1900,7 +1833,7 @@ DEFUN ("ns-emacs-info-panel", Fns_emacs_info_panel, Sns_emacs_info_panel,
doc: /* Shows the 'Info' or 'About' panel for Emacs. */)
(void)
{
- check_ns ();
+ check_window_system (NULL);
[NSApp orderFrontStandardAboutPanel: nil];
return Qnil;
}
@@ -1976,9 +1909,11 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
#else
Lisp_Object ret = Qnil;
NSMenu *svcs;
+#ifdef NS_IMPL_COCOA
id delegate;
+#endif
- check_ns ();
+ check_window_system (NULL);
svcs = [[NSMenu alloc] initWithTitle: @"Services"];
[NSApp setServicesMenu: svcs];
[NSApp registerServicesMenuSendTypes: ns_send_types
@@ -2031,7 +1966,7 @@ there was no result. */)
char *utfStr;
CHECK_STRING (service);
- check_ns ();
+ check_window_system (NULL);
utfStr = SSDATA (service);
svcName = [NSString stringWithUTF8String: utfStr];
@@ -2059,15 +1994,9 @@ DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc,
CHECK_STRING (str);
utfStr = [NSString stringWithUTF8String: SSDATA (str)];
- if (![utfStr respondsToSelector:
- @selector (precomposedStringWithCanonicalMapping)])
- {
- message1
- ("Warning: ns-convert-utf8-nfd-to-nfc unsupported under GNUstep.\n");
- return Qnil;
- }
- else
+#ifdef NS_IMPL_COCOA
utfStr = [utfStr precomposedStringWithCanonicalMapping];
+#endif
return build_string ([utfStr UTF8String]);
}
@@ -2155,7 +2084,7 @@ In case the execution fails, an error is signaled. */)
NSEvent *nxev;
CHECK_STRING (script);
- check_ns ();
+ check_window_system (NULL);
block_input ();
@@ -2204,15 +2133,6 @@ In case the execution fails, an error is signaled. */)
========================================================================== */
-
-/* called from image.c */
-FRAME_PTR
-check_x_frame (Lisp_Object frame)
-{
- return check_ns_frame (frame);
-}
-
-
/* called from frame.c */
struct ns_display_info *
check_x_display_info (Lisp_Object frame)
@@ -2231,6 +2151,9 @@ x_set_scroll_bar_default_width (struct frame *f)
}
+extern const char *x_get_string_resource (XrmDatabase, char *, char *);
+
+
/* terms impl this instead of x-get-resource directly */
const char *
x_get_string_resource (XrmDatabase rdb, char *name, char *class)
@@ -2238,7 +2161,7 @@ x_get_string_resource (XrmDatabase rdb, char *name, char *class)
/* remove appname prefix; TODO: allow for !="Emacs" */
char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
const char *res;
- check_ns ();
+ check_window_system (NULL);
if (inhibit_x_resources)
/* --quick was passed, so this is a no-op. */
@@ -2279,13 +2202,6 @@ x_pixel_height (struct frame *f)
}
-int
-x_screen_planes (struct frame *f)
-{
- return FRAME_NS_DISPLAY_INFO (f)->n_planes;
-}
-
-
void
x_sync (struct frame *f)
{
@@ -2308,7 +2224,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
NSColor * col;
- check_ns ();
+ check_window_system (NULL);
return ns_lisp_to_color (color, &col) ? Qnil : Qt;
}
@@ -2318,9 +2234,9 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
NSColor * col;
- CGFloat red, green, blue, alpha;
+ EmacsCGFloat red, green, blue, alpha;
- check_ns ();
+ check_window_system (NULL);
CHECK_STRING (color);
if (ns_lisp_to_color (color, &col))
@@ -2335,12 +2251,13 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
doc: /* Internal function called by `display-color-p', which see. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
NSString *colorSpace;
- check_ns ();
- depth = [ns_get_screen (display) depth];
+
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
colorSpace = NSColorSpaceFromDepth (depth);
return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
@@ -2349,18 +2266,19 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
}
-DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
- Sx_display_grayscale_p, 0, 1, 0,
+DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
+ 0, 1, 0,
doc: /* Return t if the Nextstep display supports shades of gray.
Note that color displays do support shades of gray.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
+ (Lisp_Object terminal)
{
NSWindowDepth depth;
- check_ns ();
- depth = [ns_get_screen (display) depth];
+
+ check_ns_display_info (terminal);
+ depth = [[[NSScreen screens] objectAtIndex:0] depth];
return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
}
@@ -2368,87 +2286,230 @@ If omitted or nil, that stands for the selected frame's display. */)
DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
0, 1, 0,
- doc: /* Return the width in pixels of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ doc: /* Return the width in pixels of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel width for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns ();
- return make_number ((int) [ns_get_screen (display) frame].size.width);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_width (dpyinfo));
}
DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
Sx_display_pixel_height, 0, 1, 0,
- doc: /* Return the height in pixels of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
-If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ doc: /* Return the height in pixels of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel height for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
+ (Lisp_Object terminal)
{
- check_ns ();
- return make_number ((int) [ns_get_screen (display) frame].size.height);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
+
+ return make_number (x_display_pixel_height (dpyinfo));
+}
+
+#ifdef NS_IMPL_COCOA
+/* Returns the name for the screen that DICT came from, or NULL.
+ Caller must free return value.
+*/
+
+static char *
+ns_screen_name (CGDirectDisplayID did)
+{
+ char *name = NULL;
+ NSDictionary *info = (NSDictionary *)
+ IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did),
+ kIODisplayOnlyPreferredName);
+ NSDictionary *names
+ = [info objectForKey:
+ [NSString stringWithUTF8String:kDisplayProductName]];
+
+ if ([names count] > 0) {
+ NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]];
+ if (n != nil)
+ name = xstrdup ([n UTF8String]);
+ }
+
+ [info release];
+ return name;
+}
+#endif
+
+static Lisp_Object
+ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
+ int n_monitors,
+ int primary_monitor,
+ const char *source)
+{
+ Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
+ Lisp_Object frame, rest;
+ NSArray *screens = [NSScreen screens];
+ int i;
+
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_NS_P (f))
+ {
+ NSView *view = FRAME_NS_VIEW (f);
+ NSScreen *screen = [[view window] screen];
+ NSUInteger k;
+
+ i = -1;
+ for (k = 0; i == -1 && k < [screens count]; ++k)
+ {
+ if ([screens objectAtIndex: k] == screen)
+ i = (int)k;
+ }
+
+ if (i > -1)
+ ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
+ }
+ }
+
+ return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
+ monitor_frames, source);
}
+DEFUN ("ns-display-monitor-attributes-list",
+ Fns_display_monitor_attributes_list,
+ Sns_display_monitor_attributes_list,
+ 0, 1, 0,
+ doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+In addition to the standard attribute keys listed in
+`display-monitor-attributes-list', the following keys are contained in
+the attributes:
-DEFUN ("display-usable-bounds", Fns_display_usable_bounds,
- Sns_display_usable_bounds, 0, 1, 0,
- doc: /* Return the bounds of the usable part of the screen.
-The return value is a list of integers (LEFT TOP WIDTH HEIGHT), which
-are the boundaries of the usable part of the screen, excluding areas
-reserved for the Mac menu, dock, and so forth.
+ source -- String describing the source from which multi-monitor
+ information is obtained, \"NS\" is always the source."
-The screen queried corresponds to DISPLAY, which should be either a
-frame, a display name (a string), or terminal ID. If omitted or nil,
-that stands for the selected frame's display. */)
- (Lisp_Object display)
+Internal use only, use `display-monitor-attributes-list' instead. */)
+ (Lisp_Object terminal)
{
- NSScreen *screen;
- NSRect vScreen;
+ struct terminal *term = get_terminal (terminal, 1);
+ NSArray *screens;
+ NSUInteger i, n_monitors;
+ struct MonitorInfo *monitors;
+ Lisp_Object attributes_list = Qnil;
+ CGFloat primary_display_height = 0;
- check_ns ();
- screen = ns_get_screen (display);
- if (!screen)
+ if (term->type != output_ns)
return Qnil;
- vScreen = [screen visibleFrame];
+ screens = [NSScreen screens];
+ n_monitors = [screens count];
+ if (n_monitors == 0)
+ return Qnil;
+
+ monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
+
+ for (i = 0; i < [screens count]; ++i)
+ {
+ NSScreen *s = [screens objectAtIndex:i];
+ struct MonitorInfo *m = &monitors[i];
+ NSRect fr = [s frame];
+ NSRect vfr = [s visibleFrame];
+ short y, vy;
+
+#ifdef NS_IMPL_COCOA
+ NSDictionary *dict = [s deviceDescription];
+ NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
+ CGDirectDisplayID did = [nid unsignedIntValue];
+#endif
+ if (i == 0)
+ {
+ primary_display_height = fr.size.height;
+ y = (short) fr.origin.y;
+ vy = (short) vfr.origin.y;
+ }
+ else
+ {
+ // Flip y coordinate as NS has y starting from the bottom.
+ y = (short) (primary_display_height - fr.size.height - fr.origin.y);
+ vy = (short) (primary_display_height -
+ vfr.size.height - vfr.origin.y);
+ }
+
+ m->geom.x = (short) fr.origin.x;
+ m->geom.y = y;
+ m->geom.width = (unsigned short) fr.size.width;
+ m->geom.height = (unsigned short) fr.size.height;
+
+ m->work.x = (short) vfr.origin.x;
+ // y is flipped on NS, so vy - y are pixels missing at the bottom,
+ // and fr.size.height - vfr.size.height are pixels missing in total.
+ // Pixels missing at top are
+ // fr.size.height - vfr.size.height - vy + y.
+ // work.y is then pixels missing at top + y.
+ m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
+ m->work.width = (unsigned short) vfr.size.width;
+ m->work.height = (unsigned short) vfr.size.height;
+
+#ifdef NS_IMPL_COCOA
+ m->name = ns_screen_name (did);
- /* NS coordinate system is upside-down.
- Transform to screen-specific coordinates. */
- return list4i (vScreen.origin.x,
- [screen frame].size.height
- - vScreen.size.height - vScreen.origin.y,
- vScreen.size.width, vScreen.size.height);
+ {
+ CGSize mms = CGDisplayScreenSize (did);
+ m->mm_width = (int) mms.width;
+ m->mm_height = (int) mms.height;
+ }
+
+#else
+ // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
+ m->mm_width = (int) (25.4 * fr.size.width / 92.0);
+ m->mm_height = (int) (25.4 * fr.size.height / 92.0);
+#endif
+ }
+
+ // Primary monitor is always first for NS.
+ attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
+ 0, "NS");
+
+ free_monitors (monitors, n_monitors);
+ return attributes_list;
}
DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
0, 1, 0,
- doc: /* Return the number of bitplanes of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
+ doc: /* Return the number of bitplanes of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- check_ns ();
+ check_ns_display_info (terminal);
return make_number
- (NSBitsPerPixelFromDepth ([ns_get_screen (display) depth]));
+ (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
}
-DEFUN ("x-display-color-cells", Fx_display_color_cells,
- Sx_display_color_cells, 0, 1, 0,
- doc: /* Returns the number of color cells of the Nextstep display DISPLAY.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame, a display name (a string), or terminal ID.
+DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
+ 0, 1, 0,
+ doc: /* Returns the number of color cells of the Nextstep display TERMINAL.
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
If omitted or nil, that stands for the selected frame's display. */)
- (Lisp_Object display)
+ (Lisp_Object terminal)
{
- struct ns_display_info *dpyinfo;
- check_ns ();
-
- dpyinfo = check_ns_display_info (display);
+ struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
/* We force 24+ bit depths to 24-bit to prevent an overflow. */
return make_number (1 << min (dpyinfo->n_planes, 24));
}
@@ -2561,7 +2622,7 @@ Text larger than the specified size is clipped. */)
CHECK_STRING (string);
str = SSDATA (string);
- f = check_x_frame (frame);
+ f = decode_window_system_frame (frame);
if (NILP (timeout))
timeout = make_number (5);
else
@@ -2617,6 +2678,75 @@ Value is t if tooltip was open, nil otherwise. */)
========================================================================== */
+/*
+ Handle arrow/function/control keys and copy/paste/cut in file dialogs.
+ Return YES if handled, NO if not.
+ */
+static BOOL
+handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
+{
+ NSString *s;
+ int i;
+ BOOL ret = NO;
+
+ if ([theEvent type] != NSKeyDown) return NO;
+ s = [theEvent characters];
+
+ for (i = 0; i < [s length]; ++i)
+ {
+ int ch = (int) [s characterAtIndex: i];
+ switch (ch)
+ {
+ case NSHomeFunctionKey:
+ case NSDownArrowFunctionKey:
+ case NSUpArrowFunctionKey:
+ case NSLeftArrowFunctionKey:
+ case NSRightArrowFunctionKey:
+ case NSPageUpFunctionKey:
+ case NSPageDownFunctionKey:
+ case NSEndFunctionKey:
+ [panel sendEvent: theEvent];
+ ret = YES;
+ break;
+ /* As we don't have the standard key commands for
+ copy/paste/cut/select-all in our edit menu, we must handle
+ them here. TODO: handle Emacs key bindings for copy/cut/select-all
+ here, paste works, because we have that in our Edit menu.
+ I.e. refactor out code in nsterm.m, keyDown: to figure out the
+ correct modifier.
+ */
+ case 'x': // Cut
+ case 'c': // Copy
+ case 'v': // Paste
+ case 'a': // Select all
+ if ([theEvent modifierFlags] & NSCommandKeyMask)
+ {
+ [NSApp sendAction:
+ (ch == 'x'
+ ? @selector(cut:)
+ : (ch == 'c'
+ ? @selector(copy:)
+ : (ch == 'v'
+ ? @selector(paste:)
+ : @selector(selectAll:))))
+ to:nil from:panel];
+ ret = YES;
+ }
+ default:
+ // Send all control keys, as the text field supports C-a, C-f, C-e
+ // C-b and more.
+ if ([theEvent modifierFlags] & NSControlKeyMask)
+ {
+ [panel sendEvent: theEvent];
+ ret = YES;
+ }
+ break;
+ }
+ }
+
+
+ return ret;
+}
@implementation EmacsSavePanel
#ifdef NS_IMPL_COCOA
@@ -2637,13 +2767,13 @@ Value is t if tooltip was open, nil otherwise. */)
[NSApp stop: self];
}
#endif
-- (NSString *) getFilename
-{
- return ns_filename_from_panel (self);
-}
-- (NSString *) getDirectory
+
+- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
- return ns_directory_from_panel (self);
+ BOOL ret = handlePanelKeys (self, theEvent);
+ if (! ret)
+ ret = [super performKeyEquivalent:theEvent];
+ return ret;
}
@end
@@ -2660,8 +2790,8 @@ Value is t if tooltip was open, nil otherwise. */)
[super ok: sender];
// If not choosing directories, and Open is pressed on a directory, return.
- if (! [self canChooseDirectories] && [self getDirectory] &&
- ! [self getFilename])
+ if (! [self canChooseDirectories] && ns_directory_from_panel (self) &&
+ ! ns_filename_from_panel (self))
return;
panelOK = 1;
@@ -2674,15 +2804,14 @@ Value is t if tooltip was open, nil otherwise. */)
}
#endif
-- (NSString *) getFilename
+- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
{
- return ns_filename_from_panel (self);
-}
-- (NSString *) getDirectory
-{
- return ns_directory_from_panel (self);
+ // NSOpenPanel inherits NSSavePanel, so passing self is OK.
+ BOOL ret = handlePanelKeys (self, theEvent);
+ if (! ret)
+ ret = [super performKeyEquivalent:theEvent];
+ return ret;
}
-
@end
@@ -2763,7 +2892,7 @@ be used as the image of the icon representing the frame. */);
defsubr (&Sx_server_version);
defsubr (&Sx_display_pixel_width);
defsubr (&Sx_display_pixel_height);
- defsubr (&Sns_display_usable_bounds);
+ defsubr (&Sns_display_monitor_attributes_list);
defsubr (&Sx_display_mm_width);
defsubr (&Sx_display_mm_height);
defsubr (&Sx_display_screens);
@@ -2790,9 +2919,6 @@ be used as the image of the icon representing the frame. */);
defsubr (&Sx_show_tip);
defsubr (&Sx_hide_tip);
- /* used only in fontset.c */
- check_window_system_func = check_ns;
-
as_status = 0;
as_script = Qnil;
as_result = 0;
diff --git a/src/nsfont.m b/src/nsfont.m
index ebee363651f..709f2cb0d86 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -119,7 +119,7 @@ ns_attribute_fvalue (NSFontDescriptor *fdesc, NSString *trait)
{
NSDictionary *tdict = [fdesc objectForKey: NSFontTraitsAttribute];
NSNumber *val = [tdict objectForKey: trait];
- return val == nil ? 0.0 : [val floatValue];
+ return val == nil ? 0.0F : [val floatValue];
}
@@ -138,23 +138,26 @@ ns_spec_to_descriptor (Lisp_Object font_spec)
/* add each attr in font_spec to fdAttrs.. */
n = min (FONT_WEIGHT_NUMERIC (font_spec), 200);
if (n != -1 && n != STYLE_REF)
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+ [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
forKey: NSFontWeightTrait];
n = min (FONT_SLANT_NUMERIC (font_spec), 200);
if (n != -1 && n != STYLE_REF)
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+ [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
forKey: NSFontSlantTrait];
n = min (FONT_WIDTH_NUMERIC (font_spec), 200);
if (n > -1 && (n > STYLE_REF + 10 || n < STYLE_REF - 10))
- [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0]
+ [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
forKey: NSFontWidthTrait];
if ([tdict count] > 0)
[fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
- fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs];
+ fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
+ retain] autorelease];
+
if (family != nil)
{
- fdesc = [fdesc fontDescriptorWithFamily: family];
+ NSFontDescriptor *fdesc2 = [fdesc fontDescriptorWithFamily: family];
+ fdesc = [[fdesc2 retain] autorelease];
}
[fdAttrs release];
@@ -237,10 +240,10 @@ ns_fallback_entity (void)
/* Utility: get width of a char c in screen font SFONT */
-static float
+static CGFloat
ns_char_width (NSFont *sfont, int c)
{
- float w = -1.0;
+ CGFloat w = -1.0;
NSString *cstr = [NSString stringWithFormat: @"%c", c];
#ifdef NS_IMPL_COCOA
@@ -266,7 +269,7 @@ static NSString *ascii_printable;
static int
ns_ascii_average_width (NSFont *sfont)
{
- float w = -1.0;
+ CGFloat w = -1.0;
if (!ascii_printable)
{
@@ -285,14 +288,14 @@ ns_ascii_average_width (NSFont *sfont)
w = [sfont advancementForGlyph: glyph].width;
#endif
- if (w < 0.0)
+ if (w < (CGFloat) 0.0)
{
NSDictionary *attrsDictionary =
[NSDictionary dictionaryWithObject: sfont forKey: NSFontAttributeName];
w = [ascii_printable sizeWithAttributes: attrsDictionary].width;
}
- return lrint (w / 95.0);
+ return lrint (w / (CGFloat) 95.0);
}
@@ -320,7 +323,7 @@ ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct)
off++;
}
//fprintf(stderr, "off = %d\ttot = %d\n", off,tot);
- return (float)off / tot < 1.0 - pct;
+ return (float)off / tot < 1.0F - pct;
}
@@ -511,8 +514,8 @@ static NSSet
if (ns_charset_covers(fset, charset, pct))
[families addObject: family];
}
- pct -= 0.2;
- if ([families count] > 0 || pct < 0.05)
+ pct -= 0.2F;
+ if ([families count] > 0 || pct < 0.05F)
break;
}
[charset release];
@@ -760,9 +763,9 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
family = [[NSFont userFixedPitchFontOfSize: 0] familyName];
/* Should be > 0.23 as some font descriptors (e.g. Terminus) set to that
when setting family in ns_spec_to_descriptor(). */
- if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50)
+ if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F)
traits |= NSBoldFontMask;
- if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05))
+ if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F))
traits |= NSItalicFontMask;
/* see http://cocoadev.com/forums/comments.php?DiscussionID=74 */
@@ -877,7 +880,7 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
font_info->max_bounds.width = lrint (font_info->width);
font_info->max_bounds.lbearing = lrint (brect.origin.x);
font_info->max_bounds.rbearing =
- lrint (brect.size.width - font_info->width);
+ lrint (brect.size.width - (CGFloat) font_info->width);
#ifdef NS_IMPL_COCOA
/* set up synthItal and the CG font */
@@ -1038,8 +1041,8 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
/* NOTE: focus and clip must be set
also, currently assumed (true in nsterm.m call) from ==0, to ==nchars */
{
- static char cbuf[1024];
- char *c = cbuf;
+ static unsigned char cbuf[1024];
+ unsigned char *c = cbuf;
#ifdef NS_IMPL_GNUSTEP
static float advances[1024];
float *adv = advances;
@@ -1206,7 +1209,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
[bgCol set];
DPSmoveto (context, r.origin.x, r.origin.y);
/*[context GSSetTextDrawingMode: GSTextFillStroke]; /// not implemented yet */
- DPSxshow (context, cbuf, advances, len);
+ DPSxshow (context, (const char *) cbuf, advances, len);
DPSstroke (context);
[col set];
/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
@@ -1216,7 +1219,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
/* draw with DPSxshow () */
DPSmoveto (context, r.origin.x, r.origin.y);
- DPSxshow (context, cbuf, advances, len);
+ DPSxshow (context, (const char *) cbuf, advances, len);
DPSstroke (context);
DPSgrestore (context);
@@ -1404,7 +1407,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
metrics = font_info->metrics[block];
for (g = block<<8, i =0; i<0x100 && g < numGlyphs; g++, i++, metrics++)
{
- float w, lb, rb;
+ CGFloat w, lb, rb;
NSRect r = [sfont boundingRectForGlyph: g];
w = max ([sfont advancementForGlyph: g].width, 2.0);
@@ -1416,7 +1419,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
if (lb < 0)
metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN);
if (font_info->ital)
- rb += 0.22 * font_info->height;
+ rb += (CGFloat) (0.22F * font_info->height);
metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN);
metrics->descent = r.origin.y < 0 ? -r.origin.y : 0;
diff --git a/src/nsimage.m b/src/nsimage.m
index 9d21ba8afca..a1703272ad2 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -334,7 +334,7 @@ static EmacsImage *ImageList = nil;
{
NSSize s = [self size];
unsigned char *planes[5];
- CGFloat r, g, b, a;
+ EmacsCGFloat r, g, b, a;
NSColor *rgbColor;
if (bmRep == nil || color == nil)
@@ -437,7 +437,7 @@ static EmacsImage *ImageList = nil;
else
{
NSColor *color = [bmRep colorAtX: x y: y];
- CGFloat r, g, b, a;
+ EmacsCGFloat r, g, b, a;
[color getRed: &r green: &g blue: &b alpha: &a];
return ((int)(a * 255.0) << 24)
| ((int)(r * 255.0) << 16) | ((int)(g * 255.0) << 8)
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 22ff4dd0b53..1d3d111e9a1 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -45,8 +45,6 @@ Carbon version by Yamamoto Mitsuharu. */
#include <sys/types.h>
#endif
-#define MenuStagger 10.0
-
#if 0
int menu_trace_num = 0;
#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
@@ -88,14 +86,6 @@ static int trackingMenu;
========================================================================== */
-/* FIXME: not currently used, but should normalize with other terms. */
-void
-x_activate_menubar (struct frame *f)
-{
- fprintf (stderr, "XXX: Received x_activate_menubar event.\n");
-}
-
-
/* Supposed to discard menubar and free storage. Since we share the
menubar among frames and update its context for the focused window,
there is nothing to do here. */
@@ -120,14 +110,13 @@ popup_activated (void)
2) deep_p, submenu = nil: Recompute all submenus.
3) deep_p, submenu = non-nil: Update contents of a single submenu.
-------------------------------------------------------------------------- */
-void
+static void
ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
{
NSAutoreleasePool *pool;
id menu = [NSApp mainMenu];
static EmacsMenu *last_submenu = nil;
BOOL needsSet = NO;
- const char *submenuTitle = [[submenu title] UTF8String];
bool owfi;
Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0;
@@ -138,7 +127,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
long t;
#endif
- NSTRACE (set_frame_menubar);
+ NSTRACE (ns_update_menubar);
if (f != SELECTED_FRAME ())
return;
@@ -191,7 +180,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
= alloca (previous_menu_items_used * sizeof *previous_items);
/* lisp preliminaries */
- buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
+ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
specbind (Qinhibit_quit, Qt);
specbind (Qdebug_on_next_call, Qnil);
record_unwind_save_match_data ();
@@ -247,7 +236,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
/* FIXME: we'd like to only parse the needed submenu, but this
was causing crashes in the _common parsing code.. need to make
sure proper initialization done.. */
-/* if (submenu && strcmp (submenuTitle, SSDATA (string)))
+/* if (submenu && strcmp ([[submenu title] UTF8String], SSDATA (string)))
continue; */
submenu_start[i] = menu_items_used;
@@ -267,7 +256,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
{
/* should have found a menu for this one but didn't */
fprintf (stderr, "ERROR: did not find lisp menu for submenu '%s'.\n",
- submenuTitle);
+ [[submenu title] UTF8String]);
discard_menu_items ();
unbind_to (specpdl_count, Qnil);
[pool release];
@@ -354,8 +343,6 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
string = AREF (items, i + 1);
if (NILP (string))
break;
-/* if (submenu && strcmp (submenuTitle, SSDATA (string)))
- continue; */
wv->name = SSDATA (string);
update_submenu_strings (wv->contents);
@@ -366,6 +353,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
create a new menu for each sub and fill it. */
if (submenu)
{
+ const char *submenuTitle = [[submenu title] UTF8String];
for (wv = first_wv->contents; wv; wv = wv->next)
{
if (!strcmp (submenuTitle, wv->name))
@@ -512,6 +500,31 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
ns_update_menubar (f, deep_p, nil);
}
+void
+x_activate_menubar (struct frame *f)
+{
+#ifdef NS_IMPL_COCOA
+ NSArray *a = [[NSApp mainMenu] itemArray];
+ /* Update each submenu separately so ns_update_menubar doesn't reset
+ the delegate. */
+ int i = 0;
+ while (i < [a count])
+ {
+ EmacsMenu *menu = (EmacsMenu *)[[a objectAtIndex:i] submenu];
+ const char *title = [[menu title] UTF8String];
+ if (strcmp (title, ns_get_pending_menu_title ()) == 0)
+ {
+ ns_update_menubar (f, true, menu);
+ break;
+ }
+ ++i;
+ }
+ ns_check_pending_open_menu ();
+#endif
+}
+
+
+
/* ==========================================================================
@@ -564,6 +577,14 @@ extern NSString *NSMenuDidBeginTrackingNotification;
trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
? 1 : 0);
}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+- (void)menuWillOpen:(NSMenu *)menu
+{
+ ns_check_menu_open (menu);
+}
+#endif
+
#endif
/* delegate method called when a submenu is being opened: run a 'deep' call
@@ -591,7 +612,12 @@ extern NSString *NSMenuDidBeginTrackingNotification;
if (trackingMenu == 0)
return;
/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
- ns_update_menubar (frame, 1, self);
+#if ! defined(NS_IMPL_COCOA) || \
+ MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+ /* Don't know how to do this for anything other than OSX >= 10.5
+ This is wrong, as it might run Lisp code in the event loop. */
+ ns_update_menubar (frame, true, self);
+#endif
}
@@ -714,7 +740,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
[self setSubmenu: submenu forItem: item];
[submenu fillWithWidgetValue: wv->contents];
[submenu release];
- [item setAction: nil];
+ [item setAction: (SEL)nil];
}
}
@@ -731,7 +757,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
{
NSString *titleStr = [NSString stringWithUTF8String: title];
NSMenuItem *item = [self addItemWithTitle: titleStr
- action: nil /*@selector (menuDown:) */
+ action: (SEL)nil /*@selector (menuDown:) */
keyEquivalent: @""];
EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr frame: f];
[self setSubmenu: submenu forItem: item];
@@ -1019,13 +1045,18 @@ update_frame_tool_bar (FRAME_PTR f)
Update toolbar contents
-------------------------------------------------------------------------- */
{
- int i;
+ int i, k = 0;
EmacsView *view = FRAME_NS_VIEW (f);
NSWindow *window = [view window];
EmacsToolbar *toolbar = [view toolbar];
block_input ();
+
+#ifdef NS_IMPL_COCOA
[toolbar clearActive];
+#else
+ [toolbar clearAll];
+#endif
/* update EmacsToolbar as in GtkUtils, build items list */
for (i = 0; i < f->n_tool_bar_items; ++i)
@@ -1041,6 +1072,15 @@ update_frame_tool_bar (FRAME_PTR f)
Lisp_Object helpObj;
const char *helpText;
+ /* Check if this is a separator. */
+ if (EQ (TOOLPROP (TOOL_BAR_ITEM_TYPE), Qt))
+ {
+ /* Skip separators. Newer OSX don't show them, and on GNUStep they
+ are wide as a button, thus overflowing the toolbar most of
+ the time. */
+ continue;
+ }
+
/* If image is a vector, choose the image according to the
button state. */
image = TOOLPROP (TOOL_BAR_ITEM_IMAGES);
@@ -1077,7 +1117,10 @@ update_frame_tool_bar (FRAME_PTR f)
continue;
}
- [toolbar addDisplayItemWithImage: img->pixmap idx: i helpText: helpText
+ [toolbar addDisplayItemWithImage: img->pixmap
+ idx: k++
+ tag: i
+ helpText: helpText
enabled: enabled_p];
#undef TOOLPROP
}
@@ -1085,6 +1128,7 @@ update_frame_tool_bar (FRAME_PTR f)
if (![toolbar isVisible])
[toolbar setVisible: YES];
+#ifdef NS_IMPL_COCOA
if ([toolbar changed])
{
/* inform app that toolbar has changed */
@@ -1106,6 +1150,7 @@ update_frame_tool_bar (FRAME_PTR f)
[toolbar setConfigurationFromDictionary: newDict];
[newDict release];
}
+#endif
FRAME_TOOLBAR_HEIGHT (f) =
NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
@@ -1133,6 +1178,7 @@ update_frame_tool_bar (FRAME_PTR f)
[self setDelegate: self];
identifierToItem = [[NSMutableDictionary alloc] initWithCapacity: 10];
activeIdentifiers = [[NSMutableArray alloc] initWithCapacity: 8];
+ prevIdentifiers = nil;
prevEnablement = enablement = 0L;
return self;
}
@@ -1154,18 +1200,29 @@ update_frame_tool_bar (FRAME_PTR f)
enablement = 0L;
}
+- (void) clearAll
+{
+ [self clearActive];
+ while ([[self items] count] > 0)
+ [self removeItemAtIndex: 0];
+}
+
- (BOOL) changed
{
return [activeIdentifiers isEqualToArray: prevIdentifiers] &&
enablement == prevEnablement ? NO : YES;
}
-- (void) addDisplayItemWithImage: (EmacsImage *)img idx: (int)idx
- helpText: (const char *)help enabled: (BOOL)enabled
+- (void) addDisplayItemWithImage: (EmacsImage *)img
+ idx: (int)idx
+ tag: (int)tag
+ helpText: (const char *)help
+ enabled: (BOOL)enabled
{
/* 1) come up w/identifier */
NSString *identifier
= [NSString stringWithFormat: @"%u", [img hash]];
+ [activeIdentifiers addObject: identifier];
/* 2) create / reuse item */
NSToolbarItem *item = [identifierToItem objectForKey: identifier];
@@ -1177,20 +1234,25 @@ update_frame_tool_bar (FRAME_PTR f)
[item setToolTip: [NSString stringWithUTF8String: help]];
[item setTarget: emacsView];
[item setAction: @selector (toolbarClicked:)];
+ [identifierToItem setObject: item forKey: identifier];
}
- [item setTag: idx];
+#ifdef NS_IMPL_GNUSTEP
+ [self insertItemWithItemIdentifier: identifier atIndex: idx];
+#endif
+
+ [item setTag: tag];
[item setEnabled: enabled];
/* 3) update state */
- [identifierToItem setObject: item forKey: identifier];
- [activeIdentifiers addObject: identifier];
enablement = (enablement << 1) | (enabled == YES);
}
/* This overrides super's implementation, which automatically sets
all items to enabled state (for some reason). */
-- (void)validateVisibleItems { }
+- (void)validateVisibleItems
+{
+}
/* delegate methods */
@@ -1213,7 +1275,8 @@ update_frame_tool_bar (FRAME_PTR f)
- (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar
{
/* return entire set... */
- return [identifierToItem allKeys];
+ return activeIdentifiers;
+ //return [identifierToItem allKeys];
}
/* optional and unneeded */
@@ -1300,6 +1363,7 @@ update_frame_tool_bar (FRAME_PTR f)
wr.size = [textField frame].size;
[win setFrame: wr display: YES];
+ [win setLevel: NSPopUpMenuWindowLevel];
[win orderFront: self];
[win display];
timer = [NSTimer scheduledTimerWithTimeInterval: (float)seconds target: self
@@ -1380,8 +1444,6 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
NSTRACE (x-popup-dialog);
- check_ns ();
-
isQ = NILP (header);
if (EQ (position, Qt)
@@ -1419,6 +1481,8 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
else
CHECK_WINDOW (window);
+ check_window_system (f);
+
p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2;
p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
@@ -1504,7 +1568,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
[img autorelease];
[imgView autorelease];
- aStyle = NSTitledWindowMask;
+ aStyle = NSTitledWindowMask|NSClosableWindowMask|NSUtilityWindowMask;
flag = YES;
rows = 0;
cols = 1;
@@ -1572,9 +1636,6 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
[self setOneShot: YES];
[self setReleasedWhenClosed: YES];
[self setHidesOnDeactivate: YES];
- [self setStyleMask:
- NSTitledWindowMask|NSClosableWindowMask|NSUtilityWindowMask];
-
return self;
}
diff --git a/src/nsselect.m b/src/nsselect.m
index 49380f87945..6053ee9ceb2 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -182,7 +182,7 @@ ns_get_local_selection (Lisp_Object selection_name,
Lisp_Object target_type)
{
Lisp_Object local_value;
- Lisp_Object handler_fn, value, type, check;
+ Lisp_Object handler_fn, value, check;
ptrdiff_t count;
local_value = assq_no_quit (selection_name, Vselection_alist);
@@ -203,7 +203,6 @@ ns_get_local_selection (Lisp_Object selection_name,
check = value;
if (CONSP (value) && SYMBOLP (XCAR (value)))
{
- type = XCAR (value);
check = XCDR (value);
}
@@ -354,8 +353,7 @@ On Nextstep, FRAME is unused. */)
Lisp_Object successful_p = Qnil, rest;
Lisp_Object target_symbol, data;
-
- check_ns ();
+ check_window_system (NULL);
CHECK_SYMBOL (selection);
if (NILP (value))
error ("selection value may not be nil.");
@@ -409,7 +407,7 @@ On MS-DOS, all this does is return non-nil if we own the selection. */)
(Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
{
id pb;
- check_ns ();
+ check_window_system (NULL);
CHECK_SYMBOL (selection);
if (NILP (assq_no_quit (selection, Vselection_alist))) return Qnil;
@@ -436,7 +434,7 @@ On Nextstep, TERMINAL is unused. */)
id pb;
NSArray *types;
- check_ns ();
+ check_window_system (NULL);
CHECK_SYMBOL (selection);
if (EQ (selection, Qnil)) selection = QPRIMARY;
if (EQ (selection, Qt)) selection = QSECONDARY;
@@ -464,7 +462,7 @@ frame's display, or the first available X display.
On Nextstep, TERMINAL is unused. */)
(Lisp_Object selection, Lisp_Object terminal)
{
- check_ns ();
+ check_window_system (NULL);
CHECK_SYMBOL (selection);
if (EQ (selection, Qnil)) selection = QPRIMARY;
if (EQ (selection, Qt)) selection = QSECONDARY;
@@ -492,7 +490,7 @@ On Nextstep, TIME-STAMP and TERMINAL are unused. */)
{
Lisp_Object val;
- check_ns ();
+ check_window_system (NULL);
CHECK_SYMBOL (selection_name);
CHECK_SYMBOL (target_type);
val = ns_get_local_selection (selection_name, target_type);
@@ -516,7 +514,7 @@ SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
(Lisp_Object selection)
{
id pb;
- check_ns ();
+ check_window_system (NULL);
pb = ns_symbol_to_pb (selection);
return pb != nil ? ns_string_from_pasteboard (pb) : Qnil;
}
@@ -529,7 +527,7 @@ SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
(Lisp_Object selection, Lisp_Object string)
{
id pb;
- check_ns ();
+ check_window_system (NULL);
pb = ns_symbol_to_pb (selection);
if (pb != nil) ns_string_to_pasteboard (pb, string);
return Qnil;
diff --git a/src/nsterm.h b/src/nsterm.h
index 6bd04b96684..fd8c9baa3e4 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -51,6 +51,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef __OBJC__
+/* CGFloat on GNUStep may be 4 or 8 byte, but functions expect float* for some
+ versions.
+ On Cocoa, functions expect CGFloat*. Make compatible type. */
+#if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \
+ GNUSTEP_GUI_MINOR_VERSION >= 22
+typedef CGFloat EmacsCGFloat;
+#else
+typedef float EmacsCGFloat;
+#endif
+
/* ==========================================================================
The Emacs application
@@ -60,6 +70,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* We override sendEvent: as a means to stop/start the event loop */
@interface EmacsApp : NSApplication
{
+#ifdef NS_IMPL_GNUSTEP
+@public
+ int nextappdefined;
+#endif
}
- (void)logNotification: (NSNotification *)notification;
- (void)sendEvent: (NSEvent *)theEvent;
@@ -68,8 +82,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
- (void)fd_handler: (id)unused;
- (void)timeout_handler: (NSTimer *)timedEntry;
- (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg;
+#ifdef NS_IMPL_GNUSTEP
+- (void)sendFromMainThread:(id)unused;
+#endif
@end
+#ifdef NS_IMPL_GNUSTEP
+/* Dummy class to get rid of startup warnings. */
+@interface EmacsDocument : NSDocument
+{
+}
+@end
+#endif
/* ==========================================================================
@@ -128,8 +152,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#endif
#ifdef NS_IMPL_GNUSTEP
-/* Not declared, but useful. */
-- (void) unlockFocusNeedsFlush: (BOOL)needs;
+- (void)windowDidMove: (id)sender;
#endif
@end
@@ -199,10 +222,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
}
- initForView: (EmacsView *)view withIdentifier: (NSString *)identifier;
- (void) clearActive;
+- (void) clearAll;
- (BOOL) changed;
-- (void) addDisplayItemWithImage: (EmacsImage *)img idx: (int)idx
+- (void) addDisplayItemWithImage: (EmacsImage *)img
+ idx: (int)idx
+ tag: (int)tag
helpText: (const char *)help
enabled: (BOOL)enabled;
+
/* delegate methods */
- (NSToolbarItem *)toolbar: (NSToolbar *)toolbar
itemForItemIdentifier: (NSString *)itemIdentifier
@@ -267,14 +294,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
@interface EmacsSavePanel : NSSavePanel
{
}
-- (NSString *) getFilename;
-- (NSString *) getDirectory;
@end
@interface EmacsOpenPanel : NSOpenPanel
{
}
-- (NSString *) getFilename;
-- (NSString *) getDirectory;
@end
@interface EmacsFileDelegate : NSObject
@@ -335,7 +358,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
NSResponder *prevResponder;
/* offset to the bottom of knob of last mouse down */
- float last_mouse_offset;
+ CGFloat last_mouse_offset;
float min_portion;
int pixel_height;
int last_hit_part;
@@ -577,8 +600,6 @@ extern Lisp_Object ns_display_name_list;
extern struct ns_display_info *ns_display_info_for_name (Lisp_Object name);
struct ns_display_info *check_x_display_info (Lisp_Object frame);
-FRAME_PTR check_x_frame (Lisp_Object frame);
-
struct ns_output
{
@@ -764,7 +785,6 @@ extern void ns_clear_frame (struct frame *f);
extern const char *ns_xlfd_to_fontname (const char *xlfd);
-extern void check_ns (void);
extern Lisp_Object ns_map_event_to_object (void);
#ifdef __OBJC__
extern Lisp_Object ns_string_from_pasteboard (id pb);
@@ -792,6 +812,9 @@ extern int ns_lisp_to_color (Lisp_Object color, NSColor **col);
extern NSColor *ns_lookup_indexed_color (unsigned long idx, struct frame *f);
extern unsigned long ns_index_color (NSColor *color, struct frame *f);
extern void ns_free_indexed_color (unsigned long idx, struct frame *f);
+extern const char *ns_get_pending_menu_title (void);
+extern void ns_check_menu_open (NSMenu *menu);
+extern void ns_check_pending_open_menu (void);
#endif
/* C access to ObjC functionality */
@@ -840,6 +863,7 @@ extern int x_display_pixel_height (struct ns_display_info *);
extern int x_display_pixel_width (struct ns_display_info *);
/* This in nsterm.m */
+extern void x_destroy_window (struct frame *f);
extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, EMACS_TIME *timeout,
sigset_t *sigmask);
diff --git a/src/nsterm.m b/src/nsterm.m
index 40e506eab27..9cf138837f6 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -60,6 +60,10 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
#include "buffer.h"
#include "font.h"
+#ifdef NS_IMPL_GNUSTEP
+#include "process.h"
+#endif
+
/* call tracing */
#if 0
int term_trace_num = 0;
@@ -196,7 +200,9 @@ static BOOL gsaved = NO;
static BOOL ns_fake_keydown = NO;
int ns_tmp_flags; /* FIXME */
struct nsfont_info *ns_tmp_font; /* FIXME */
+#ifdef NS_IMPL_COCOA
static BOOL ns_menu_bar_is_hidden = NO;
+#endif
/*static int debug_lock = 0; */
/* event loop */
@@ -228,6 +234,27 @@ static struct {
NULL, 0, 0
};
+#ifdef NS_IMPL_COCOA
+/*
+ * State for pending menu activation:
+ * MENU_NONE Normal state
+ * MENU_PENDING A menu has been clicked on, but has been canceled so we can
+ * run lisp to update the menu.
+ * MENU_OPENING Menu is up to date, and the click event is redone so the menu
+ * will open.
+ */
+#define MENU_NONE 0
+#define MENU_PENDING 1
+#define MENU_OPENING 2
+static int menu_will_open_state = MENU_NONE;
+
+/* Saved position for menu click. */
+static CGPoint menu_mouse_point;
+
+/* Title for the menu to open. */
+static char *menu_pending_title = 0;
+#endif
+
/* Convert modifiers in a NeXTstep event to emacs style modifiers. */
#define NS_FUNCTION_KEY_MASK 0x800000
#define NSLeftControlKeyMask (0x000001 | NSControlKeyMask)
@@ -298,8 +325,6 @@ static struct {
ns_send_appdefined (-1); \
}
-void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
-
/* TODO: get rid of need for these forward declarations */
static void ns_condemn_scroll_bars (struct frame *f);
static void ns_judge_scroll_bars (struct frame *f);
@@ -651,8 +676,6 @@ ns_update_begin (struct frame *f)
-------------------------------------------------------------------------- */
{
NSView *view = FRAME_NS_VIEW (f);
- NSRect r = [view frame];
- NSBezierPath *bp;
NSTRACE (ns_update_begin);
ns_update_auto_hide_menu_bar ();
@@ -664,9 +687,15 @@ ns_update_begin (struct frame *f)
is for the minibuffer. But the display engine may draw more because
we have set the frame as garbaged. So reset clip path to the whole
view. */
+#ifdef NS_IMPL_COCOA
+ {
+ NSBezierPath *bp;
+ NSRect r = [view frame];
bp = [[NSBezierPath bezierPathWithRect: r] retain];
[bp setClip];
[bp release];
+ }
+#endif
#ifdef NS_IMPL_GNUSTEP
uRect = NSMakeRect (0, 0, 0, 0);
@@ -753,20 +782,13 @@ ns_update_end (struct frame *f)
external (RIF) call; for whole frame, called after update_window_end
-------------------------------------------------------------------------- */
{
- NSView *view = FRAME_NS_VIEW (f);
+ EmacsView *view = FRAME_NS_VIEW (f);
/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
MOUSE_HL_INFO (f)->mouse_face_defer = 0;
block_input ();
-#ifdef NS_IMPL_GNUSTEP
- /* trigger flush only in the rectangle we tracked as being drawn */
- [view unlockFocusNeedsFlush: NO];
-/*fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", uRect.origin.x, uRect.origin.y, uRect.size.width, uRect.size.height); */
- [view lockFocusInRect: uRect];
-#endif
-
[view unlockFocus];
[[view window] flushWindow];
@@ -799,13 +821,6 @@ ns_focus (struct frame *f, NSRect *r, int n)
-------------------------------------------------------------------------- */
{
// NSTRACE (ns_focus);
-#ifdef NS_IMPL_GNUSTEP
- NSRect u;
- if (n == 2)
- u = NSUnionRect (r[0], r[1]);
- else if (r)
- u = *r;
-#endif
/* static int c =0;
fprintf (stderr, "focus: %d", c++);
if (r) fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", r->origin.x, r->origin.y, r->size.width, r->size.height);
@@ -824,33 +839,11 @@ ns_focus (struct frame *f, NSRect *r, int n)
}
if (view)
-#ifdef NS_IMPL_GNUSTEP
- r ? [view lockFocusInRect: u] : [view lockFocus];
-#else
[view lockFocus];
-#endif
focus_view = view;
/*if (view) debug_lock++; */
}
-#ifdef NS_IMPL_GNUSTEP
- else
- {
- /* more than one rect being drawn into */
- if (view && r)
- {
- [view unlockFocus]; /* add prev rect to redraw list */
- [view lockFocusInRect: u]; /* focus for draw in new rect */
- }
- }
-#endif
}
-#ifdef NS_IMPL_GNUSTEP
- else
- {
- /* in batch mode, but in GNUstep must still track rectangles explicitly */
- uRect = (r ? NSUnionRect (uRect, u) : [FRAME_NS_VIEW (f) visibleRect]);
- }
-#endif
/* clipping */
if (r)
@@ -993,8 +986,9 @@ ns_raise_frame (struct frame *f)
Bring window to foreground and make it active
-------------------------------------------------------------------------- */
{
- NSView *view = FRAME_NS_VIEW (f);
- check_ns ();
+ NSView *view;
+ check_window_system (f);
+ view = FRAME_NS_VIEW (f);
block_input ();
if (FRAME_VISIBLE_P (f))
[[view window] makeKeyAndOrderFront: NSApp];
@@ -1008,8 +1002,9 @@ ns_lower_frame (struct frame *f)
Send window to back
-------------------------------------------------------------------------- */
{
- NSView *view = FRAME_NS_VIEW (f);
- check_ns ();
+ NSView *view;
+ check_window_system (f);
+ view = FRAME_NS_VIEW (f);
block_input ();
[[view window] orderBack: NSApp];
unblock_input ();
@@ -1112,9 +1107,10 @@ x_make_frame_invisible (struct frame *f)
External: Hide the window (X11 semantics)
-------------------------------------------------------------------------- */
{
- NSView * view = FRAME_NS_VIEW (f);
+ NSView *view;
NSTRACE (x_make_frame_invisible);
- check_ns ();
+ check_window_system (f);
+ view = FRAME_NS_VIEW (f);
[[view window] orderOut: NSApp];
SET_FRAME_VISIBLE (f, 0);
SET_FRAME_ICONIFIED (f, 0);
@@ -1127,10 +1123,13 @@ x_iconify_frame (struct frame *f)
External: Iconify window
-------------------------------------------------------------------------- */
{
- NSView * view = FRAME_NS_VIEW (f);
- struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+ NSView *view;
+ struct ns_display_info *dpyinfo;
+
NSTRACE (x_iconify_frame);
- check_ns ();
+ check_window_system (f);
+ view = FRAME_NS_VIEW (f);
+ dpyinfo = FRAME_NS_DISPLAY_INFO (f);
if (dpyinfo->x_highlight_frame == f)
dpyinfo->x_highlight_frame = 0;
@@ -1155,11 +1154,15 @@ x_iconify_frame (struct frame *f)
void
x_free_frame_resources (struct frame *f)
{
- NSView *view = FRAME_NS_VIEW (f);
- struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+ NSView *view;
+ struct ns_display_info *dpyinfo;
+ Mouse_HLInfo *hlinfo;
+
NSTRACE (x_free_frame_resources);
- check_ns ();
+ check_window_system (f);
+ view = FRAME_NS_VIEW (f);
+ dpyinfo = FRAME_NS_DISPLAY_INFO (f);
+ hlinfo = MOUSE_HL_INFO (f);
[(EmacsView *)view setWindowClosing: YES]; /* may not have been informed */
@@ -1200,7 +1203,7 @@ x_destroy_window (struct frame *f)
-------------------------------------------------------------------------- */
{
NSTRACE (x_destroy_window);
- check_ns ();
+ check_window_system (f);
x_free_frame_resources (f);
ns_window_num--;
}
@@ -1288,12 +1291,17 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
/* If we have a toolbar, take its height into account. */
if (tb && ! [view isFullscreen])
+ {
/* NOTE: previously this would generate wrong result if toolbar not
yet displayed and fixing toolbar_height=32 helped, but
now (200903) seems no longer needed */
FRAME_TOOLBAR_HEIGHT (f) =
NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
- FRAME_NS_TITLEBAR_HEIGHT (f);
+#ifdef NS_IMPL_GNUSTEP
+ FRAME_TOOLBAR_HEIGHT (f) -= 3;
+#endif
+ }
else
FRAME_TOOLBAR_HEIGHT (f) = 0;
@@ -1519,7 +1527,7 @@ ns_get_color (const char *name, NSColor **col)
}
}
- if (r >= 0.0)
+ if (r >= 0.0F)
{
*col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0];
unblock_input ();
@@ -1580,7 +1588,7 @@ ns_color_to_lisp (NSColor *col)
Convert a color to a lisp string with the RGB equivalent
-------------------------------------------------------------------------- */
{
- CGFloat red, green, blue, alpha, gray;
+ EmacsCGFloat red, green, blue, alpha, gray;
char buf[1024];
const char *str;
NSTRACE (ns_color_to_lisp);
@@ -1622,7 +1630,7 @@ ns_query_color(void *col, XColor *color_def, int setPixel)
and set color_def pixel to the resulting index.
-------------------------------------------------------------------------- */
{
- CGFloat r, g, b, a;
+ EmacsCGFloat r, g, b, a;
[((NSColor *)col) getRed: &r green: &g blue: &b alpha: &a];
color_def->red = r * 65535;
@@ -1667,26 +1675,6 @@ ns_defined_color (struct frame *f,
}
-unsigned long
-ns_get_rgb_color (struct frame *f, float r, float g, float b, float a)
-/* --------------------------------------------------------------------------
- return an autoreleased RGB color
- -------------------------------------------------------------------------- */
-{
-/*static int c = 1; fprintf (stderr, "color request %d\n", c++); */
- if (r < 0.0) r = 0.0;
- else if (r > 1.0) r = 1.0;
- if (g < 0.0) g = 0.0;
- else if (g > 1.0) g = 1.0;
- if (b < 0.0) b = 0.0;
- else if (b > 1.0) b = 1.0;
- if (a < 0.0) a = 0.0;
- else if (a > 1.0) a = 1.0;
- return (unsigned long) ns_index_color(
- [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a], f);
-}
-
-
void
x_set_frame_alpha (struct frame *f)
/* --------------------------------------------------------------------------
@@ -1694,7 +1682,6 @@ x_set_frame_alpha (struct frame *f)
-------------------------------------------------------------------------- */
{
struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
- EmacsView *view = FRAME_NS_VIEW (f);
double alpha = 1.0;
double alpha_min = 1.0;
@@ -1716,7 +1703,10 @@ x_set_frame_alpha (struct frame *f)
alpha = alpha_min;
#ifdef NS_IMPL_COCOA
+ {
+ EmacsView *view = FRAME_NS_VIEW (f);
[[view window] setAlphaValue: alpha];
+ }
#endif
}
@@ -1769,7 +1759,7 @@ x_set_mouse_position (struct frame *f, int h, int v)
static int
-note_mouse_movement (struct frame *frame, float x, float y)
+note_mouse_movement (struct frame *frame, CGFloat x, CGFloat y)
/* ------------------------------------------------------------------------
Called by EmacsView on mouseMovement events. Passes on
to emacs mainstream code if we moved off of a rect of interest
@@ -1854,7 +1844,7 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
f = dpyinfo->x_focus_frame ? dpyinfo->x_focus_frame
: SELECTED_FRAME ();
- if (f && f->output_data.ns) /* TODO: 2nd check no longer needed? */
+ if (f && FRAME_NS_P (f))
{
view = FRAME_NS_VIEW (*fp);
@@ -2228,7 +2218,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
struct face *face = p->face;
- int rowY;
static EmacsImage **bimgs = NULL;
static int nBimgs = 0;
@@ -2242,7 +2231,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
}
/* Must clip because of partially visible lines. */
- rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
ns_clip_to_row (w, row, -1, YES);
if (!p->overlay_p)
@@ -2330,7 +2318,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
[ns_lookup_indexed_color(face->background, f) set];
NSRectFill (r);
[img setXBMColor: ns_lookup_indexed_color(face->foreground, f)];
-#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
[img drawInRect: r
fromRect: NSZeroRect
operation: NSCompositeSourceOver
@@ -2362,7 +2350,6 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
int fx, fy, h, cursor_height;
struct frame *f = WINDOW_XFRAME (w);
struct glyph *phys_cursor_glyph;
- int overspill;
struct glyph *cursor_glyph;
struct face *face;
NSColor *hollow_color = FRAME_BACKGROUND_COLOR (f);
@@ -2569,7 +2556,7 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
--------------------------------------------------------------------- */
static void
-ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x)
+ns_draw_underwave (struct glyph_string *s, EmacsCGFloat width, EmacsCGFloat x)
{
int wave_height = 3, wave_length = 2;
int y, dx, dy, odd, xmax;
@@ -2587,7 +2574,7 @@ ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x)
NSRectClip (waveClip);
/* Draw the waves */
- a.x = x - ((int)(x) % dx) + 0.5;
+ a.x = x - ((int)(x) % dx) + (EmacsCGFloat) 0.5;
b.x = a.x + dx;
odd = (int)(a.x/dx) % 2;
a.y = b.y = y + 0.5;
@@ -2727,7 +2714,8 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
}
static void
-ns_draw_box (NSRect r, float thickness, NSColor *col, char left_p, char right_p)
+ns_draw_box (NSRect r, CGFloat thickness, NSColor *col,
+ char left_p, char right_p)
/* --------------------------------------------------------------------------
Draw an unfilled rect inside r, optionally leaving left and/or right open.
Note we can't just use an NSDrawRect command, because of the possibility
@@ -3004,7 +2992,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
/* Draw the image.. do we need to draw placeholder if img ==nil? */
if (img != nil)
{
-#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height);
NSRect ir = NSMakeRect (s->slice.x, s->slice.y,
s->slice.width, s->slice.height);
@@ -3329,6 +3317,19 @@ ns_send_appdefined (int value)
{
/*NSTRACE (ns_send_appdefined); */
+#ifdef NS_IMPL_GNUSTEP
+ // GNUStep needs postEvent to happen on the main thread.
+ if (! [[NSThread currentThread] isMainThread])
+ {
+ EmacsApp *app = (EmacsApp *)NSApp;
+ app->nextappdefined = value;
+ [app performSelectorOnMainThread:@selector (sendFromMainThread:)
+ withObject:nil
+ waitUntilDone:YES];
+ return;
+ }
+#endif
+
/* Only post this event if we haven't already posted one. This will end
the [NXApp run] main loop after having processed all events queued at
this moment. */
@@ -3388,6 +3389,73 @@ check_native_fs ()
}
#endif
+/* GNUStep and OSX <= 10.4 does not have cancelTracking. */
+#if defined (NS_IMPL_COCOA) && \
+ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+const char *
+ns_get_pending_menu_title ()
+{
+ return menu_pending_title;
+}
+
+/* Check if menu open should be cancelled or continued as normal. */
+void
+ns_check_menu_open (NSMenu *menu)
+{
+ /* Click in menu bar? */
+ NSArray *a = [[NSApp mainMenu] itemArray];
+ int i;
+ BOOL found = NO;
+ for (i = 0; ! found && i < [a count]; i++)
+ found = menu == [[a objectAtIndex:i] submenu];
+ if (found)
+ {
+ if (menu_will_open_state == MENU_NONE && emacs_event)
+ {
+ NSEvent *theEvent = [NSApp currentEvent];
+ struct frame *emacsframe = SELECTED_FRAME ();
+
+ [menu cancelTracking];
+ menu_will_open_state = MENU_PENDING;
+ emacs_event->kind = MENU_BAR_ACTIVATE_EVENT;
+ EV_TRAILER (theEvent);
+
+ CGEventRef ourEvent = CGEventCreate (NULL);
+ menu_mouse_point = CGEventGetLocation (ourEvent);
+ CFRelease (ourEvent);
+ xfree (menu_pending_title);
+ menu_pending_title = xstrdup ([[menu title] UTF8String]);
+ }
+ else if (menu_will_open_state == MENU_OPENING)
+ {
+ menu_will_open_state = MENU_NONE;
+ }
+ }
+}
+
+/* Redo saved menu click if state is MENU_PENDING. */
+void
+ns_check_pending_open_menu ()
+{
+ if (menu_will_open_state == MENU_PENDING)
+ {
+ CGEventSourceRef source
+ = CGEventSourceCreate (kCGEventSourceStateHIDSystemState);
+
+ CGEventRef event = CGEventCreateMouseEvent (source,
+ kCGEventLeftMouseDown,
+ menu_mouse_point,
+ kCGMouseButtonLeft);
+ CGEventSetType (event, kCGEventLeftMouseDown);
+ CGEventPost (kCGHIDEventTap, event);
+ CFRelease (event);
+ CFRelease (source);
+
+ menu_will_open_state = MENU_OPENING;
+ }
+}
+#endif /* NS_IMPL_COCOA) && >= MAC_OS_X_VERSION_10_5 */
+
static int
ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
/* --------------------------------------------------------------------------
@@ -3813,15 +3881,31 @@ x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
int
x_display_pixel_height (struct ns_display_info *dpyinfo)
{
- NSScreen *screen = [NSScreen mainScreen];
- return [screen frame].size.height;
+ NSArray *screens = [NSScreen screens];
+ NSEnumerator *enumerator = [screens objectEnumerator];
+ NSScreen *screen;
+ NSRect frame;
+
+ frame = NSZeroRect;
+ while ((screen = [enumerator nextObject]) != nil)
+ frame = NSUnionRect (frame, [screen frame]);
+
+ return NSHeight (frame);
}
int
x_display_pixel_width (struct ns_display_info *dpyinfo)
{
- NSScreen *screen = [NSScreen mainScreen];
- return [screen frame].size.width;
+ NSArray *screens = [NSScreen screens];
+ NSEnumerator *enumerator = [screens objectEnumerator];
+ NSScreen *screen;
+ NSRect frame;
+
+ frame = NSZeroRect;
+ while ((screen = [enumerator nextObject]) != nil)
+ frame = NSUnionRect (frame, [screen frame]);
+
+ return NSWidth (frame);
}
@@ -4276,6 +4360,12 @@ ns_term_init (Lisp_Object display_name)
[NSApp run];
ns_do_open_file = YES;
+
+#if defined (NS_IMPL_GNUSTEP) && defined (SIGCHLD)
+ /* GNUstep steals SIGCHLD for use in NSTask, but we don't use NSTask.
+ We must re-catch it so subprocess works. */
+ catch_child_signal ();
+#endif
return dpyinfo;
}
@@ -4583,6 +4673,13 @@ not_in_argv (NSString *arg)
ns_send_appdefined (-2);
}
+#ifdef NS_IMPL_GNUSTEP
+- (void)sendFromMainThread:(id)unused
+{
+ ns_send_appdefined (nextappdefined);
+}
+#endif
+
- (void)fd_handler:(id)unused
/* --------------------------------------------------------------------------
Check data waiting on file descriptors and terminate if so
@@ -4747,7 +4844,7 @@ not_in_argv (NSString *arg)
NSEvent *e =[[self window] currentEvent];
struct face *face =FRAME_DEFAULT_FACE (emacsframe);
id newFont;
- float size;
+ CGFloat size;
NSTRACE (changeFont);
if (!emacs_event)
@@ -4866,7 +4963,16 @@ not_in_argv (NSString *arg)
{
/* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace',
because Emacs treats Delete and KP-Delete same (in simple.el). */
- if (fnKeysym == 0xFFFF && [theEvent keyCode] == 0x33)
+ if ((fnKeysym == 0xFFFF && [theEvent keyCode] == 0x33)
+#ifdef NS_IMPL_GNUSTEP
+ /* GNUstep uses incompatible keycodes, even for those that are
+ supposed to be hardware independent. Just check for delete.
+ Keypad delete does not have keysym 0xFFFF.
+ See http://savannah.gnu.org/bugs/?25395
+ */
+ || (fnKeysym == 0xFFFF && code == 127)
+#endif
+ )
code = 0xFF08; /* backspace */
else
code = fnKeysym;
@@ -5019,10 +5125,14 @@ not_in_argv (NSString *arg)
#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
/* if we get here we should send the key for input manager processing */
+ /* Disable warning, there is nothing a user can do about it anyway, and
+ it does not seem to matter. */
+#if 0
if (firstTime && [[NSInputManager currentInputManager]
wantsToDelayTextChangeNotifications] == NO)
fprintf (stderr,
"Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n");
+#endif
firstTime = NO;
#endif
if (NS_KEYLOG && !processingCompose)
@@ -5230,7 +5340,12 @@ not_in_argv (NSString *arg)
return NSMakeRange (NSNotFound, 0);
}
+#if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \
+ GNUSTEP_GUI_MINOR_VERSION > 22
- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
+#else
+- (unsigned int)characterIndexForPoint: (NSPoint)thePoint
+#endif
{
if (NS_KEYLOG)
NSLog (@"characterIndexForPoint request");
@@ -5269,7 +5384,7 @@ not_in_argv (NSString *arg)
if ([theEvent type] == NSScrollWheel)
{
- float delta = [theEvent deltaY];
+ CGFloat delta = [theEvent deltaY];
/* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
if (delta == 0)
return;
@@ -5453,7 +5568,6 @@ not_in_argv (NSString *arg)
if (oldr != rows || oldc != cols || neww != oldw || newh != oldh)
{
- struct frame *f = emacsframe;
NSView *view = FRAME_NS_VIEW (emacsframe);
NSWindow *win = [view window];
NSSize sz = [win resizeIncrements];
@@ -5662,7 +5776,6 @@ not_in_argv (NSString *arg)
NSRect r, wr;
Lisp_Object tem;
NSWindow *win;
- NSButton *toggleButton;
NSSize sz;
NSColor *col;
NSString *name;
@@ -5738,9 +5851,12 @@ not_in_argv (NSString *arg)
[win setToolbar: toolbar];
[toolbar setVisible: NO];
#ifdef NS_IMPL_COCOA
+ {
+ NSButton *toggleButton;
toggleButton = [win standardWindowButton: NSWindowToolbarButton];
[toggleButton setTarget: self];
[toggleButton setAction: @selector (toggleToolbar: )];
+ }
#endif
FRAME_TOOLBAR_HEIGHT (f) = 0;
@@ -5764,7 +5880,7 @@ not_in_argv (NSString *arg)
col = ns_lookup_indexed_color (NS_FACE_BACKGROUND
(FRAME_DEFAULT_FACE (emacsframe)), emacsframe);
[win setBackgroundColor: col];
- if ([col alphaComponent] != 1.0)
+ if ([col alphaComponent] != (EmacsCGFloat) 1.0)
[win setOpaque: NO];
[self allocateGState];
@@ -5857,7 +5973,7 @@ not_in_argv (NSString *arg)
result = ns_userRect.size.height ? ns_userRect : result;
ns_userRect = NSMakeRect (0, 0, 0, 0);
[self setFSValue: FULLSCREEN_NONE];
- maximized_width = maximized_width = -1;
+ maximized_width = maximized_height = -1;
}
if (fs_before_fs == -1) next_maximized = -1;
@@ -5950,7 +6066,9 @@ not_in_argv (NSString *arg)
{
[self setFSValue: fs_before_fs];
fs_before_fs = -1;
+#ifdef NS_IMPL_COCOA
[self updateCollectionBehaviour];
+#endif
if (FRAME_EXTERNAL_TOOL_BAR (emacsframe))
{
[toolbar setVisible:YES];
@@ -6009,7 +6127,9 @@ not_in_argv (NSString *arg)
if (fs_is_native)
{
+#ifdef NS_IMPL_COCOA
[[self window] toggleFullScreen:sender];
+#endif
return;
}
@@ -6055,7 +6175,7 @@ not_in_argv (NSString *arg)
[fw useOptimizedDrawing: YES];
[fw setResizeIncrements: sz];
[fw setBackgroundColor: col];
- if ([col alphaComponent] != 1.0)
+ if ([col alphaComponent] != (EmacsCGFloat) 1.0)
[fw setOpaque: NO];
f->border_width = 0;
@@ -6093,7 +6213,7 @@ not_in_argv (NSString *arg)
[w setContentView:[fw contentView]];
[w setResizeIncrements: sz];
[w setBackgroundColor: col];
- if ([col alphaComponent] != 1.0)
+ if ([col alphaComponent] != (EmacsCGFloat) 1.0)
[w setOpaque: NO];
f->border_width = bwidth;
@@ -6532,7 +6652,7 @@ not_in_argv (NSString *arg)
{
Lisp_Object str = Qnil;
struct frame *f = SELECTED_FRAME ();
- struct buffer *curbuf = XBUFFER (XWINDOW (f->selected_window)->buffer);
+ struct buffer *curbuf = XBUFFER (XWINDOW (f->selected_window)->contents);
if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
return NSAccessibilityTextFieldRole;
@@ -6787,10 +6907,11 @@ not_in_argv (NSString *arg)
}
else
{
- float pos, por;
+ float pos;
+ CGFloat por;
portion = max ((float)whole*min_portion/pixel_height, portion);
pos = (float)position / (whole - portion);
- por = (float)portion/whole;
+ por = (CGFloat)portion/whole;
#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
[self setKnobProportion: por];
[self setDoubleValue: pos];
@@ -6815,7 +6936,7 @@ not_in_argv (NSString *arg)
*part = last_hit_part;
*window = win;
XSETINT (*y, pixel_height);
- if ([self floatValue] > 0.999)
+ if ([self floatValue] > 0.999F)
XSETINT (*x, pixel_height);
else
XSETINT (*x, pixel_height * [self floatValue]);
@@ -6889,7 +7010,7 @@ not_in_argv (NSString *arg)
NSRect sr, kr;
/* hitPart is only updated AFTER event is passed on */
NSScrollerPart part = [self testPart: [e locationInWindow]];
- double inc = 0.0, loc, kloc, pos;
+ CGFloat inc = 0.0, loc, kloc, pos;
int edge = 0;
NSTRACE (EmacsScroller_mouseDown);
@@ -6988,7 +7109,6 @@ not_in_argv (NSString *arg)
{
NSRect sr;
double loc, pos;
- int edge = 0;
NSTRACE (EmacsScroller_mouseDragged);
@@ -6999,15 +7119,13 @@ not_in_argv (NSString *arg)
if (loc <= 0.0)
{
loc = 0.0;
- edge = -1;
}
else if (loc >= NSHeight (sr) + last_mouse_offset)
{
loc = NSHeight (sr) + last_mouse_offset;
- edge = 1;
}
- pos = /*(edge ? loc :*/ (loc - last_mouse_offset) / NSHeight (sr);
+ pos = (loc - last_mouse_offset) / NSHeight (sr);
[self sendScrollEventAtLoc: pos fromEvent: e];
}
@@ -7034,6 +7152,12 @@ not_in_argv (NSString *arg)
@end /* EmacsScroller */
+#ifdef NS_IMPL_GNUSTEP
+/* Dummy class to get rid of startup warnings. */
+@implementation EmacsDocument
+
+@end
+#endif
/* ==========================================================================
diff --git a/src/print.c b/src/print.c
index 74fab475ac0..979b732a057 100644
--- a/src/print.c
+++ b/src/print.c
@@ -227,9 +227,9 @@ printchar (unsigned int ch, Lisp_Object fun)
if (NILP (fun))
{
ptrdiff_t incr = len - (print_buffer_size - print_buffer_pos_byte);
- if (0 < incr)
- print_buffer =
- xpalloc (print_buffer, &print_buffer_size, incr, -1, 1);
+ if (incr > 0)
+ print_buffer = xpalloc (print_buffer, &print_buffer_size,
+ incr, -1, 1);
memcpy (print_buffer + print_buffer_pos_byte, str, len);
print_buffer_pos += 1;
print_buffer_pos_byte += len;
@@ -273,7 +273,7 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
if (NILP (printcharfun))
{
ptrdiff_t incr = size_byte - (print_buffer_size - print_buffer_pos_byte);
- if (0 < incr)
+ if (incr > 0)
print_buffer = xpalloc (print_buffer, &print_buffer_size, incr, -1, 1);
memcpy (print_buffer + print_buffer_pos_byte, ptr, size_byte);
print_buffer_pos += size;
@@ -1769,10 +1769,10 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
strout ("#<window ", -1, -1, printcharfun);
len = sprintf (buf, "%p", XWINDOW (obj));
strout (buf, len, len, printcharfun);
- if (!NILP (XWINDOW (obj)->buffer))
+ if (BUFFERP (XWINDOW (obj)->contents))
{
strout (" on ", -1, -1, printcharfun);
- print_string (BVAR (XBUFFER (XWINDOW (obj)->buffer), name),
+ print_string (BVAR (XBUFFER (XWINDOW (obj)->contents), name),
printcharfun);
}
PRINTCHAR ('>');
@@ -2078,17 +2078,15 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
strout ("#<save-value ", -1, -1, printcharfun);
- if (v->area)
+ if (v->save_type == SAVE_TYPE_MEMORY)
{
ptrdiff_t amount = v->data[1].integer;
#if GC_MARK_STACK
- /* If GC_MARK_STACK, valid_lisp_object_p is quite reliable,
- and so we try to print up to 8 objects we have saved.
- Although valid_lisp_object_p is slow, this shouldn't be
- a real bottleneck because we do not use this code under
- normal circumstances. */
+ /* valid_lisp_object_p is reliable, so try to print up
+ to 8 saved objects. This code is rarely used, so
+ it's OK that valid_lisp_object_p is slow. */
int limit = min (amount, 8);
Lisp_Object *area = v->data[0].pointer;
@@ -2113,9 +2111,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
#else /* not GC_MARK_STACK */
- /* If !GC_MARK_STACK, we have no reliable way to find
- whether Lisp_Object pointers points to an initialized
- objects, and so we do not ever trying to print them. */
+ /* There is no reliable way to determine whether the objects
+ are initialized, so do not try to print them. */
i = sprintf (buf, "with %"pD"d objects", amount);
strout (buf, i, i, printcharfun);
@@ -2124,33 +2121,37 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
}
else
{
- /* Print each `data[N]' slot according to its type. */
-
-#define PRINTX(index) \
- do { \
- i = 0; \
- if (v->type ## index == SAVE_UNUSED) \
- i = sprintf (buf, "<unused>"); \
- else if (v->type ## index == SAVE_INTEGER) \
- i = sprintf (buf, "<integer %"pD"d>", v->data[index].integer); \
- else if (v->type ## index == SAVE_POINTER) \
- i = sprintf (buf, "<pointer %p>", v->data[index].pointer); \
- else /* SAVE_OBJECT */ \
- print_object (v->data[index].object, printcharfun, escapeflag); \
- if (i) \
- strout (buf, i, i, printcharfun); \
- } while (0)
-
- PRINTX (0);
- PRINTCHAR (' ');
- PRINTX (1);
- PRINTCHAR (' ');
- PRINTX (2);
- PRINTCHAR (' ');
- PRINTX (3);
+ /* Print each slot according to its type. */
+ int index;
+ for (index = 0; index < SAVE_VALUE_SLOTS; index++)
+ {
+ if (index)
+ PRINTCHAR (' ');
-#undef PRINTX
+ switch (save_type (v, index))
+ {
+ case SAVE_UNUSED:
+ i = sprintf (buf, "<unused>");
+ break;
+
+ case SAVE_POINTER:
+ i = sprintf (buf, "<pointer %p>",
+ v->data[index].pointer);
+ break;
+
+ case SAVE_INTEGER:
+ i = sprintf (buf, "<integer %"pD"d>",
+ v->data[index].integer);
+ break;
+
+ case SAVE_OBJECT:
+ print_object (v->data[index].object, printcharfun,
+ escapeflag);
+ continue;
+ }
+ strout (buf, i, i, printcharfun);
+ }
}
PRINTCHAR ('>');
}
@@ -2201,7 +2202,16 @@ print_interval (INTERVAL interval, Lisp_Object printcharfun)
print_object (interval->plist, printcharfun, 1);
}
-
+/* Initialize debug_print stuff early to have it working from the very
+ beginning. */
+
+void
+init_print_once (void)
+{
+ DEFSYM (Qexternal_debugging_output, "external-debugging-output");
+ defsubr (&Sexternal_debugging_output);
+}
+
void
syms_of_print (void)
{
@@ -2333,12 +2343,10 @@ priorities. */);
defsubr (&Sprint);
defsubr (&Sterpri);
defsubr (&Swrite_char);
- defsubr (&Sexternal_debugging_output);
#ifdef WITH_REDIRECT_DEBUGGING_OUTPUT
defsubr (&Sredirect_debugging_output);
#endif
- DEFSYM (Qexternal_debugging_output, "external-debugging-output");
DEFSYM (Qprint_escape_newlines, "print-escape-newlines");
DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte");
DEFSYM (Qprint_escape_nonascii, "print-escape-nonascii");
diff --git a/src/process.c b/src/process.c
index e8e7a2be7be..c1726e7ad60 100644
--- a/src/process.c
+++ b/src/process.c
@@ -136,7 +136,7 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
/* Work around GCC 4.7.0 bug with strict overflow checking; see
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
These lines can be removed once the GCC bug is fixed. */
-#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
# pragma GCC diagnostic ignored "-Wstrict-overflow"
#endif
@@ -174,6 +174,8 @@ static Lisp_Object QClocal, QCremote, QCcoding;
static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
static Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
static Lisp_Object Qlast_nonmenu_event;
+static Lisp_Object Qinternal_default_process_sentinel;
+static Lisp_Object Qinternal_default_process_filter;
#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
#define NETCONN1_P(p) (EQ (p->type, Qnetwork))
@@ -334,7 +336,7 @@ pset_encoding_buf (struct Lisp_Process *p, Lisp_Object val)
static void
pset_filter (struct Lisp_Process *p, Lisp_Object val)
{
- p->filter = val;
+ p->filter = NILP (val) ? Qinternal_default_process_filter : val;
}
static void
pset_log (struct Lisp_Process *p, Lisp_Object val)
@@ -364,7 +366,7 @@ pset_plist (struct Lisp_Process *p, Lisp_Object val)
static void
pset_sentinel (struct Lisp_Process *p, Lisp_Object val)
{
- p->sentinel = val;
+ p->sentinel = NILP (val) ? Qinternal_default_process_sentinel : val;
}
static void
pset_status (struct Lisp_Process *p, Lisp_Object val)
@@ -846,6 +848,8 @@ make_process (Lisp_Object name)
}
name = name1;
pset_name (p, name);
+ pset_sentinel (p, Qinternal_default_process_sentinel);
+ pset_filter (p, Qinternal_default_process_filter);
XSETPROCESS (val, p);
Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist);
return val;
@@ -1146,10 +1150,10 @@ DEFUN ("process-mark", Fprocess_mark, Sprocess_mark,
DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
2, 2, 0,
- doc: /* Give PROCESS the filter function FILTER; nil means no filter.
+ doc: /* Give PROCESS the filter function FILTER; nil means default.
A value of t means stop accepting output from the process.
-When a process has a filter, its buffer is not used for output.
+When a process has a non-default filter, its buffer is not used for output.
Instead, each time it does output, the entire string of output is
passed to the filter.
@@ -1175,6 +1179,9 @@ The string argument is normally a multibyte string, except:
(debug)
(set-process-filter process ...) */
+ if (NILP (filter))
+ filter = Qinternal_default_process_filter;
+
if (p->infd >= 0)
{
if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
@@ -1194,7 +1201,7 @@ The string argument is normally a multibyte string, except:
DEFUN ("process-filter", Fprocess_filter, Sprocess_filter,
1, 1, 0,
- doc: /* Returns the filter function of PROCESS; nil if none.
+ doc: /* Return the filter function of PROCESS.
See `set-process-filter' for more info on filter functions. */)
(register Lisp_Object process)
{
@@ -1204,7 +1211,7 @@ See `set-process-filter' for more info on filter functions. */)
DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel,
2, 2, 0,
- doc: /* Give PROCESS the sentinel SENTINEL; nil for none.
+ doc: /* Give PROCESS the sentinel SENTINEL; nil for default.
The sentinel is called as a function when the process changes state.
It gets two arguments: the process, and a string describing the change. */)
(register Lisp_Object process, Lisp_Object sentinel)
@@ -1214,6 +1221,9 @@ It gets two arguments: the process, and a string describing the change. */)
CHECK_PROCESS (process);
p = XPROCESS (process);
+ if (NILP (sentinel))
+ sentinel = Qinternal_default_process_sentinel;
+
pset_sentinel (p, sentinel);
if (NETCONN1_P (p) || SERIALCONN1_P (p))
pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel));
@@ -1222,7 +1232,7 @@ It gets two arguments: the process, and a string describing the change. */)
DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel,
1, 1, 0,
- doc: /* Return the sentinel of PROCESS; nil if none.
+ doc: /* Return the sentinel of PROCESS.
See `set-process-sentinel' for more info on sentinels. */)
(register Lisp_Object process)
{
@@ -1575,8 +1585,8 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
pset_plist (XPROCESS (proc), Qnil);
pset_type (XPROCESS (proc), Qreal);
pset_buffer (XPROCESS (proc), buffer);
- pset_sentinel (XPROCESS (proc), Qnil);
- pset_filter (XPROCESS (proc), Qnil);
+ pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel);
+ pset_filter (XPROCESS (proc), Qinternal_default_process_filter);
pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2));
#ifdef HAVE_GNUTLS
@@ -1998,7 +2008,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
/* Back in the parent process. */
XPROCESS (process)->pid = pid;
- if (0 <= pid)
+ if (pid >= 0)
XPROCESS (process)->alive = 1;
/* Stop blocking signals in the parent. */
@@ -2346,7 +2356,7 @@ Returns nil upon error setting address, ADDRESS otherwise. */)
channel = XPROCESS (process)->infd;
len = get_lisp_to_sockaddr_size (address, &family);
- if (datagram_address[channel].len != len)
+ if (len == 0 || datagram_address[channel].len != len)
return Qnil;
conv_lisp_to_sockaddr (family, address, datagram_address[channel].sa, len);
return address;
@@ -3457,7 +3467,8 @@ usage: (make-network-process &rest ARGS) */)
{
int rfamily, rlen;
rlen = get_lisp_to_sockaddr_size (remote, &rfamily);
- if (rfamily == lres->ai_family && rlen == lres->ai_addrlen)
+ if (rlen != 0 && rfamily == lres->ai_family
+ && rlen == lres->ai_addrlen)
conv_lisp_to_sockaddr (rfamily, remote,
datagram_address[s].sa, rlen);
}
@@ -4077,7 +4088,7 @@ Return non-nil if we received any output before the timeout expired. */)
{
if (INTEGERP (seconds))
{
- if (0 < XINT (seconds))
+ if (XINT (seconds) > 0)
{
secs = XINT (seconds);
nsecs = 0;
@@ -4085,7 +4096,7 @@ Return non-nil if we received any output before the timeout expired. */)
}
else if (FLOATP (seconds))
{
- if (0 < XFLOAT_DATA (seconds))
+ if (XFLOAT_DATA (seconds) > 0)
{
EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds));
secs = min (EMACS_SECS (t), WAIT_READING_MAX);
@@ -4215,7 +4226,8 @@ server_accept_connection (Lisp_Object server, int channel)
process name of the server process concatenated with the caller
identification. */
- if (!NILP (ps->filter) && !EQ (ps->filter, Qt))
+ if (!(EQ (ps->filter, Qinternal_default_process_filter)
+ || EQ (ps->filter, Qt)))
buffer = Qnil;
else
{
@@ -4278,7 +4290,7 @@ server_accept_connection (Lisp_Object server, int channel)
/* Setup coding system for new process based on server process.
This seems to be the proper thing to do, as the coding system
of the new process should reflect the settings at the time the
- server socket was opened; not the current settings. */
+ server socket was opened; not the current settings. */
pset_decode_coding_system (p, ps->decode_coding_system);
pset_encode_coding_system (p, ps->encode_coding_system);
@@ -4297,11 +4309,10 @@ server_accept_connection (Lisp_Object server, int channel)
(STRINGP (host) ? host : build_string ("-")),
build_string ("\n")));
- if (!NILP (p->sentinel))
- exec_sentinel (proc,
- concat3 (build_string ("open from "),
- (STRINGP (host) ? host : build_string ("-")),
- build_string ("\n")));
+ exec_sentinel (proc,
+ concat3 (build_string ("open from "),
+ (STRINGP (host) ? host : build_string ("-")),
+ build_string ("\n")));
}
static Lisp_Object
@@ -4405,7 +4416,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
/* Since we may need to wait several times,
compute the absolute time to return at. */
- if (time_limit || 0 < nsecs)
+ if (time_limit || nsecs > 0)
{
timeout = make_emacs_time (time_limit, nsecs);
end_time = add_emacs_time (current_emacs_time (), timeout);
@@ -4427,8 +4438,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
- /* Compute time from now till when time limit is up */
- /* Exit if already run out */
+ /* Compute time from now till when time limit is up. */
+ /* Exit if already run out. */
if (nsecs < 0)
{
/* A negative timeout means
@@ -4437,7 +4448,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
timeout = make_emacs_time (0, 0);
}
- else if (time_limit || 0 < nsecs)
+ else if (time_limit || nsecs > 0)
{
EMACS_TIME now = current_emacs_time ();
if (EMACS_TIME_LE (end_time, now))
@@ -4489,7 +4500,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
break;
/* A negative timeout means do not wait at all. */
- if (0 <= nsecs)
+ if (nsecs >= 0)
{
if (EMACS_TIME_VALID_P (timer_delay))
{
@@ -4571,7 +4582,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
if (nread == 0)
break;
- if (0 < nread)
+ if (nread > 0)
{
total_nread += nread;
got_some_input = 1;
@@ -5029,8 +5040,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
}
}
#endif /* NON_BLOCKING_CONNECT */
- } /* end for each file descriptor */
- } /* end while exit conditions not met */
+ } /* End for each file descriptor. */
+ } /* End while exit conditions not met. */
unbind_to (count, Qnil);
@@ -5065,6 +5076,11 @@ read_process_output_error_handler (Lisp_Object error_val)
return Qt;
}
+static void
+read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
+ ssize_t nbytes,
+ struct coding_system *coding);
+
/* Read pending output from the process channel,
starting with our buffered-ahead character if we have one.
Yield number of decoded characters read.
@@ -5081,9 +5097,7 @@ read_process_output (Lisp_Object proc, register int channel)
{
register ssize_t nbytes;
char *chars;
- register Lisp_Object outstream;
register struct Lisp_Process *p = XPROCESS (proc);
- register ptrdiff_t opoint;
struct coding_system *coding = proc_decode_coding_system[channel];
int carryover = p->decoding_carryover;
int readmax = 4096;
@@ -5106,7 +5120,7 @@ read_process_output (Lisp_Object proc, register int channel)
else
#endif
{
- bool buffered = 0 <= proc_buffered_char[channel];
+ bool buffered = proc_buffered_char[channel] >= 0;
if (buffered)
{
chars[carryover] = proc_buffered_char[channel];
@@ -5171,122 +5185,144 @@ read_process_output (Lisp_Object proc, register int channel)
friends don't expect current-buffer to be changed from under them. */
record_unwind_current_buffer ();
- /* Read and dispose of the process output. */
- outstream = p->filter;
- if (!NILP (outstream))
- {
- Lisp_Object text;
- bool outer_running_asynch_code = running_asynch_code;
- int waiting = waiting_for_user_input_p;
+ read_and_dispose_of_process_output (p, chars, nbytes, coding);
+
+ /* Handling the process output should not deactivate the mark. */
+ Vdeactivate_mark = odeactivate;
+
+ unbind_to (count, Qnil);
+ return nbytes;
+}
- /* No need to gcpro these, because all we do with them later
- is test them for EQness, and none of them should be a string. */
+static void
+read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
+ ssize_t nbytes,
+ struct coding_system *coding)
+{
+ Lisp_Object outstream = p->filter;
+ Lisp_Object text;
+ bool outer_running_asynch_code = running_asynch_code;
+ int waiting = waiting_for_user_input_p;
+
+ /* No need to gcpro these, because all we do with them later
+ is test them for EQness, and none of them should be a string. */
#if 0
- Lisp_Object obuffer, okeymap;
- XSETBUFFER (obuffer, current_buffer);
- okeymap = BVAR (current_buffer, keymap);
+ Lisp_Object obuffer, okeymap;
+ XSETBUFFER (obuffer, current_buffer);
+ okeymap = BVAR (current_buffer, keymap);
#endif
- /* We inhibit quit here instead of just catching it so that
- hitting ^G when a filter happens to be running won't screw
- it up. */
- specbind (Qinhibit_quit, Qt);
- specbind (Qlast_nonmenu_event, Qt);
-
- /* In case we get recursively called,
- and we already saved the match data nonrecursively,
- save the same match data in safely recursive fashion. */
- if (outer_running_asynch_code)
- {
- Lisp_Object tem;
- /* Don't clobber the CURRENT match data, either! */
- tem = Fmatch_data (Qnil, Qnil, Qnil);
- restore_search_regs ();
- record_unwind_save_match_data ();
- Fset_match_data (tem, Qt);
- }
+ /* We inhibit quit here instead of just catching it so that
+ hitting ^G when a filter happens to be running won't screw
+ it up. */
+ specbind (Qinhibit_quit, Qt);
+ specbind (Qlast_nonmenu_event, Qt);
- /* For speed, if a search happens within this code,
- save the match data in a special nonrecursive fashion. */
- running_asynch_code = 1;
+ /* In case we get recursively called,
+ and we already saved the match data nonrecursively,
+ save the same match data in safely recursive fashion. */
+ if (outer_running_asynch_code)
+ {
+ Lisp_Object tem;
+ /* Don't clobber the CURRENT match data, either! */
+ tem = Fmatch_data (Qnil, Qnil, Qnil);
+ restore_search_regs ();
+ record_unwind_save_match_data ();
+ Fset_match_data (tem, Qt);
+ }
- decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
- text = coding->dst_object;
- Vlast_coding_system_used = CODING_ID_NAME (coding->id);
- /* A new coding system might be found. */
- if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
- {
- pset_decode_coding_system (p, Vlast_coding_system_used);
+ /* For speed, if a search happens within this code,
+ save the match data in a special nonrecursive fashion. */
+ running_asynch_code = 1;
- /* Don't call setup_coding_system for
- proc_decode_coding_system[channel] here. It is done in
- detect_coding called via decode_coding above. */
+ decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
+ text = coding->dst_object;
+ Vlast_coding_system_used = CODING_ID_NAME (coding->id);
+ /* A new coding system might be found. */
+ if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
+ {
+ pset_decode_coding_system (p, Vlast_coding_system_used);
- /* If a coding system for encoding is not yet decided, we set
- it as the same as coding-system for decoding.
+ /* Don't call setup_coding_system for
+ proc_decode_coding_system[channel] here. It is done in
+ detect_coding called via decode_coding above. */
- But, before doing that we must check if
- proc_encode_coding_system[p->outfd] surely points to a
- valid memory because p->outfd will be changed once EOF is
- sent to the process. */
- if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[p->outfd])
- {
- pset_encode_coding_system
- (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
- setup_coding_system (p->encode_coding_system,
- proc_encode_coding_system[p->outfd]);
- }
- }
+ /* If a coding system for encoding is not yet decided, we set
+ it as the same as coding-system for decoding.
- if (coding->carryover_bytes > 0)
+ But, before doing that we must check if
+ proc_encode_coding_system[p->outfd] surely points to a
+ valid memory because p->outfd will be changed once EOF is
+ sent to the process. */
+ if (NILP (p->encode_coding_system)
+ && proc_encode_coding_system[p->outfd])
{
- if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
- pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
- memcpy (SDATA (p->decoding_buf), coding->carryover,
- coding->carryover_bytes);
- p->decoding_carryover = coding->carryover_bytes;
+ pset_encode_coding_system
+ (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
+ setup_coding_system (p->encode_coding_system,
+ proc_encode_coding_system[p->outfd]);
}
- if (SBYTES (text) > 0)
- /* FIXME: It's wrong to wrap or not based on debug-on-error, and
- sometimes it's simply wrong to wrap (e.g. when called from
- accept-process-output). */
- internal_condition_case_1 (read_process_output_call,
- Fcons (outstream,
- Fcons (proc, Fcons (text, Qnil))),
- !NILP (Vdebug_on_error) ? Qnil : Qerror,
- read_process_output_error_handler);
-
- /* If we saved the match data nonrecursively, restore it now. */
- restore_search_regs ();
- running_asynch_code = outer_running_asynch_code;
+ }
- /* Restore waiting_for_user_input_p as it was
- when we were called, in case the filter clobbered it. */
- waiting_for_user_input_p = waiting;
+ if (coding->carryover_bytes > 0)
+ {
+ if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
+ pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
+ memcpy (SDATA (p->decoding_buf), coding->carryover,
+ coding->carryover_bytes);
+ p->decoding_carryover = coding->carryover_bytes;
+ }
+ if (SBYTES (text) > 0)
+ /* FIXME: It's wrong to wrap or not based on debug-on-error, and
+ sometimes it's simply wrong to wrap (e.g. when called from
+ accept-process-output). */
+ internal_condition_case_1 (read_process_output_call,
+ Fcons (outstream,
+ Fcons (make_lisp_proc (p),
+ Fcons (text, Qnil))),
+ !NILP (Vdebug_on_error) ? Qnil : Qerror,
+ read_process_output_error_handler);
+
+ /* If we saved the match data nonrecursively, restore it now. */
+ restore_search_regs ();
+ running_asynch_code = outer_running_asynch_code;
+
+ /* Restore waiting_for_user_input_p as it was
+ when we were called, in case the filter clobbered it. */
+ waiting_for_user_input_p = waiting;
#if 0 /* Call record_asynch_buffer_change unconditionally,
because we might have changed minor modes or other things
that affect key bindings. */
- if (! EQ (Fcurrent_buffer (), obuffer)
- || ! EQ (current_buffer->keymap, okeymap))
-#endif
- /* But do it only if the caller is actually going to read events.
- Otherwise there's no need to make him wake up, and it could
- cause trouble (for example it would make sit_for return). */
- if (waiting_for_user_input_p == -1)
- record_asynch_buffer_change ();
- }
+ if (! EQ (Fcurrent_buffer (), obuffer)
+ || ! EQ (current_buffer->keymap, okeymap))
+#endif
+ /* But do it only if the caller is actually going to read events.
+ Otherwise there's no need to make him wake up, and it could
+ cause trouble (for example it would make sit_for return). */
+ if (waiting_for_user_input_p == -1)
+ record_asynch_buffer_change ();
+}
- /* If no filter, write into buffer if it isn't dead. */
- else if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
+DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
+ Sinternal_default_process_filter, 2, 2, 0,
+ doc: /* Function used as default process filter. */)
+ (Lisp_Object proc, Lisp_Object text)
+{
+ struct Lisp_Process *p;
+ ptrdiff_t opoint;
+
+ CHECK_PROCESS (proc);
+ p = XPROCESS (proc);
+ CHECK_STRING (text);
+
+ if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
{
Lisp_Object old_read_only;
ptrdiff_t old_begv, old_zv;
ptrdiff_t old_begv_byte, old_zv_byte;
ptrdiff_t before, before_byte;
ptrdiff_t opoint_byte;
- Lisp_Object text;
struct buffer *b;
Fset_buffer (p->buffer);
@@ -5319,31 +5355,6 @@ read_process_output (Lisp_Object proc, register int channel)
if (! (BEGV <= PT && PT <= ZV))
Fwiden ();
- decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
- text = coding->dst_object;
- Vlast_coding_system_used = CODING_ID_NAME (coding->id);
- /* A new coding system might be found. See the comment in the
- similar code in the previous `if' block. */
- if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
- {
- pset_decode_coding_system (p, Vlast_coding_system_used);
- if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[p->outfd])
- {
- pset_encode_coding_system
- (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
- setup_coding_system (p->encode_coding_system,
- proc_encode_coding_system[p->outfd]);
- }
- }
- if (coding->carryover_bytes > 0)
- {
- if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
- pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
- memcpy (SDATA (p->decoding_buf), coding->carryover,
- coding->carryover_bytes);
- p->decoding_carryover = coding->carryover_bytes;
- }
/* Adjust the multibyteness of TEXT to that of the buffer. */
if (NILP (BVAR (current_buffer, enable_multibyte_characters))
!= ! STRING_MULTIBYTE (text))
@@ -5388,18 +5399,13 @@ read_process_output (Lisp_Object proc, register int channel)
if (old_begv != BEGV || old_zv != ZV)
Fnarrow_to_region (make_number (old_begv), make_number (old_zv));
-
bset_read_only (current_buffer, old_read_only);
SET_PT_BOTH (opoint, opoint_byte);
}
- /* Handling the process output should not deactivate the mark. */
- Vdeactivate_mark = odeactivate;
-
- unbind_to (count, Qnil);
- return nbytes;
+ return Qnil;
}
-/* Sending data to subprocess */
+/* Sending data to subprocess. */
/* In send_process, when a write fails temporarily,
wait_reading_process_output is called. It may execute user code,
@@ -5613,7 +5619,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
rv = sendto (outfd, cur_buf, cur_len,
0, datagram_address[outfd].sa,
datagram_address[outfd].len);
- if (0 <= rv)
+ if (rv >= 0)
written = rv;
else if (errno == EMSGSIZE)
report_file_error ("sending datagram", Fcons (proc, Qnil));
@@ -6308,7 +6314,8 @@ handle_child_signal (int sig)
struct Lisp_Process *p = XPROCESS (proc);
int status;
- if (p->alive && child_status_changed (p->pid, &status, WUNTRACED))
+ if (p->alive
+ && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED))
{
/* Change the status of the process that was found. */
p->tick = ++process_tick;
@@ -6339,13 +6346,6 @@ deliver_child_signal (int sig)
static Lisp_Object
-exec_sentinel_unwind (Lisp_Object data)
-{
- pset_sentinel (XPROCESS (XCAR (data)), XCDR (data));
- return Qnil;
-}
-
-static Lisp_Object
exec_sentinel_error_handler (Lisp_Object error_val)
{
cmd_error_internal (error_val, "error in process sentinel: ");
@@ -6382,13 +6382,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
record_unwind_current_buffer ();
sentinel = p->sentinel;
- if (NILP (sentinel))
- return;
- /* Zilch the sentinel while it's running, to avoid recursive invocations;
- assure that it gets restored no matter how the sentinel exits. */
- pset_sentinel (p, Qnil);
- record_unwind_protect (exec_sentinel_unwind, Fcons (proc, sentinel));
/* Inhibit quit so that random quits don't screw up a running filter. */
specbind (Qinhibit_quit, Qt);
specbind (Qlast_nonmenu_event, Qt); /* Why? --Stef */
@@ -6446,7 +6440,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
static void
status_notify (struct Lisp_Process *deleting_process)
{
- register Lisp_Object proc, buffer;
+ register Lisp_Object proc;
Lisp_Object tail, msg;
struct gcpro gcpro1, gcpro2;
@@ -6484,8 +6478,6 @@ status_notify (struct Lisp_Process *deleting_process)
&& p != deleting_process
&& read_process_output (proc, p->infd) > 0);
- buffer = p->buffer;
-
/* Get the text to use for the message. */
if (p->raw_status_new)
update_status (p);
@@ -6506,66 +6498,83 @@ status_notify (struct Lisp_Process *deleting_process)
}
/* The actions above may have further incremented p->tick.
- So set p->update_tick again
- so that an error in the sentinel will not cause
- this code to be run again. */
+ So set p->update_tick again so that an error in the sentinel will
+ not cause this code to be run again. */
p->update_tick = p->tick;
/* Now output the message suitably. */
- if (!NILP (p->sentinel))
- exec_sentinel (proc, msg);
- /* Don't bother with a message in the buffer
- when a process becomes runnable. */
- else if (!EQ (symbol, Qrun) && !NILP (buffer))
- {
- Lisp_Object tem;
- struct buffer *old = current_buffer;
- ptrdiff_t opoint, opoint_byte;
- ptrdiff_t before, before_byte;
-
- /* Avoid error if buffer is deleted
- (probably that's why the process is dead, too) */
- if (!BUFFER_LIVE_P (XBUFFER (buffer)))
- continue;
- Fset_buffer (buffer);
-
- opoint = PT;
- opoint_byte = PT_BYTE;
- /* Insert new output into buffer
- at the current end-of-output marker,
- thus preserving logical ordering of input and output. */
- if (XMARKER (p->mark)->buffer)
- Fgoto_char (p->mark);
- else
- SET_PT_BOTH (ZV, ZV_BYTE);
-
- before = PT;
- before_byte = PT_BYTE;
-
- tem = BVAR (current_buffer, read_only);
- bset_read_only (current_buffer, Qnil);
- insert_string ("\nProcess ");
- { /* FIXME: temporary kludge */
- Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
- insert_string (" ");
- Finsert (1, &msg);
- bset_read_only (current_buffer, tem);
- set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
-
- if (opoint >= before)
- SET_PT_BOTH (opoint + (PT - before),
- opoint_byte + (PT_BYTE - before_byte));
- else
- SET_PT_BOTH (opoint, opoint_byte);
-
- set_buffer_internal (old);
- }
+ exec_sentinel (proc, msg);
}
} /* end for */
- update_mode_lines++; /* in case buffers use %s in mode-line-format */
+ update_mode_lines++; /* In case buffers use %s in mode-line-format. */
UNGCPRO;
}
+DEFUN ("internal-default-process-sentinel", Finternal_default_process_sentinel,
+ Sinternal_default_process_sentinel, 2, 2, 0,
+ doc: /* Function used as default sentinel for processes. */)
+ (Lisp_Object proc, Lisp_Object msg)
+{
+ Lisp_Object buffer, symbol;
+ struct Lisp_Process *p;
+ CHECK_PROCESS (proc);
+ p = XPROCESS (proc);
+ buffer = p->buffer;
+ symbol = p->status;
+ if (CONSP (symbol))
+ symbol = XCAR (symbol);
+
+ if (!EQ (symbol, Qrun) && !NILP (buffer))
+ {
+ Lisp_Object tem;
+ struct buffer *old = current_buffer;
+ ptrdiff_t opoint, opoint_byte;
+ ptrdiff_t before, before_byte;
+
+ /* Avoid error if buffer is deleted
+ (probably that's why the process is dead, too). */
+ if (!BUFFER_LIVE_P (XBUFFER (buffer)))
+ return Qnil;
+ Fset_buffer (buffer);
+
+ if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
+ msg = (code_convert_string_norecord
+ (msg, Vlocale_coding_system, 1));
+
+ opoint = PT;
+ opoint_byte = PT_BYTE;
+ /* Insert new output into buffer
+ at the current end-of-output marker,
+ thus preserving logical ordering of input and output. */
+ if (XMARKER (p->mark)->buffer)
+ Fgoto_char (p->mark);
+ else
+ SET_PT_BOTH (ZV, ZV_BYTE);
+
+ before = PT;
+ before_byte = PT_BYTE;
+
+ tem = BVAR (current_buffer, read_only);
+ bset_read_only (current_buffer, Qnil);
+ insert_string ("\nProcess ");
+ { /* FIXME: temporary kludge. */
+ Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
+ insert_string (" ");
+ Finsert (1, &msg);
+ bset_read_only (current_buffer, tem);
+ set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
+
+ if (opoint >= before)
+ SET_PT_BOTH (opoint + (PT - before),
+ opoint_byte + (PT_BYTE - before_byte));
+ else
+ SET_PT_BOTH (opoint, opoint_byte);
+
+ set_buffer_internal (old);
+ }
+ return Qnil;
+}
+
DEFUN ("set-process-coding-system", Fset_process_coding_system,
Sset_process_coding_system, 1, 3, 0,
@@ -6729,7 +6738,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
time_limit = TYPE_MAXIMUM (time_t);
/* What does time_limit really mean? */
- if (time_limit || 0 < nsecs)
+ if (time_limit || nsecs > 0)
{
timeout = make_emacs_time (time_limit, nsecs);
end_time = add_emacs_time (current_emacs_time (), timeout);
@@ -6757,17 +6766,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
- /* Compute time from now till when time limit is up */
- /* Exit if already run out */
+ /* Compute time from now till when time limit is up. */
+ /* Exit if already run out. */
if (nsecs < 0)
{
/* A negative timeout means
gobble output available now
- but don't wait at all. */
+ but don't wait at all. */
timeout = make_emacs_time (0, 0);
}
- else if (time_limit || 0 < nsecs)
+ else if (time_limit || nsecs > 0)
{
EMACS_TIME now = current_emacs_time ();
if (EMACS_TIME_LE (end_time, now))
@@ -6805,7 +6814,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
&& requeued_events_pending_p ())
break;
- if (EMACS_TIME_VALID_P (timer_delay) && 0 <= nsecs)
+ if (EMACS_TIME_VALID_P (timer_delay) && nsecs >= 0)
{
if (EMACS_TIME_LT (timer_delay, timeout))
{
@@ -6956,9 +6965,8 @@ setup_process_coding_systems (Lisp_Object process)
if (!proc_decode_coding_system[inch])
proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system));
coding_system = p->decode_coding_system;
- if (! NILP (p->filter))
- ;
- else if (BUFFERP (p->buffer))
+ if (EQ (p->filter, Qinternal_default_process_filter)
+ && BUFFERP (p->buffer))
{
if (NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters)))
coding_system = raw_text_coding_system (coding_system);
@@ -7067,7 +7075,7 @@ kill_buffer_processes (Lisp_Object buffer)
DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p,
Swaiting_for_user_input_p, 0, 0, 0,
- doc: /* Returns non-nil if Emacs is waiting for input from the user.
+ doc: /* Return non-nil if Emacs is waiting for input from the user.
This is intended for use by asynchronous process output filters and sentinels. */)
(void)
{
@@ -7173,6 +7181,16 @@ integer or floating point values.
return system_process_attributes (pid);
}
+void
+catch_child_signal (void)
+{
+#ifdef SIGCHLD
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_child_signal);
+ sigaction (SIGCHLD, &action, 0);
+#endif
+}
+
/* This is not called "init_process" because that is the name of a
Mach system call, so it would cause problems on Darwin systems. */
@@ -7188,9 +7206,7 @@ init_process_emacs (void)
if (! noninteractive || initialized)
#endif
{
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_child_signal);
- sigaction (SIGCHLD, &action, 0);
+ catch_child_signal ();
}
max_desc = 0;
@@ -7368,6 +7384,10 @@ syms_of_process (void)
DEFSYM (Qcutime, "cutime");
DEFSYM (Qcstime, "cstime");
DEFSYM (Qctime, "ctime");
+ DEFSYM (Qinternal_default_process_sentinel,
+ "internal-default-process-sentinel");
+ DEFSYM (Qinternal_default_process_filter,
+ "internal-default-process-filter");
DEFSYM (Qpri, "pri");
DEFSYM (Qnice, "nice");
DEFSYM (Qthcount, "thcount");
@@ -7465,6 +7485,8 @@ The variable takes effect when `start-process' is called. */);
defsubr (&Ssignal_process);
defsubr (&Swaiting_for_user_input_p);
defsubr (&Sprocess_type);
+ defsubr (&Sinternal_default_process_sentinel);
+ defsubr (&Sinternal_default_process_filter);
defsubr (&Sset_process_coding_system);
defsubr (&Sprocess_coding_system);
defsubr (&Sset_process_filter_multibyte);
diff --git a/src/process.h b/src/process.h
index 7d13a8e5042..cf1e0ea1d44 100644
--- a/src/process.h
+++ b/src/process.h
@@ -220,6 +220,7 @@ extern void add_read_fd (int fd, fd_callback func, void *data);
extern void delete_read_fd (int fd);
extern void add_write_fd (int fd, fd_callback func, void *data);
extern void delete_write_fd (int fd);
+extern void catch_child_signal (void);
extern void update_processes_for_thread_death (Lisp_Object);
diff --git a/src/profiler.c b/src/profiler.c
index 85d9c1ca88a..aba81344c68 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -55,7 +55,7 @@ make_log (int heap_size, int max_stack_depth)
/* What is special about our hash-tables is that the keys are pre-filled
with the vectors we'll put in them. */
int i = ASIZE (h->key_and_value) / 2;
- while (0 < i)
+ while (i > 0)
set_hash_key_slot (h, --i,
Fmake_vector (make_number (max_stack_depth), Qnil));
return log;
@@ -138,10 +138,8 @@ static void evict_lower_half (log_t *log)
static void
record_backtrace (log_t *log, EMACS_INT count)
{
- struct backtrace *backlist = backtrace_list;
Lisp_Object backtrace;
- ptrdiff_t index, i = 0;
- ptrdiff_t asize;
+ ptrdiff_t index;
if (!INTEGERP (log->next_free))
/* FIXME: transfer the evicted counts to a special entry rather
@@ -151,16 +149,7 @@ record_backtrace (log_t *log, EMACS_INT count)
/* Get a "working memory" vector. */
backtrace = HASH_KEY (log, index);
- asize = ASIZE (backtrace);
-
- /* Copy the backtrace contents into working memory. */
- for (; i < asize && backlist; i++, backlist = backlist->next)
- /* FIXME: For closures we should ignore the environment. */
- ASET (backtrace, i, backlist->function);
-
- /* Make sure that unused space of working memory is filled with nil. */
- for (; i < asize; i++)
- ASET (backtrace, i, Qnil);
+ get_backtrace (backtrace);
{ /* We basically do a `gethash+puthash' here, except that we have to be
careful to avoid memory allocation since we're in a signal
@@ -232,7 +221,7 @@ static EMACS_INT current_sampling_interval;
static void
handle_profiler_signal (int signal)
{
- if (backtrace_list && EQ (backtrace_list->function, Qautomatic_gc))
+ if (EQ (backtrace_top_function (), Qautomatic_gc))
/* Special case the time-count inside GC because the hash-table
code is not prepared to be used while the GC is running.
More specifically it uses ASIZE at many places where it does
@@ -247,7 +236,7 @@ handle_profiler_signal (int signal)
if (profiler_timer_ok)
{
int overruns = timer_getoverrun (profiler_timer);
- eassert (0 <= overruns);
+ eassert (overruns >= 0);
count += overruns;
}
#endif
diff --git a/src/puresize.h b/src/puresize.h
index 2f717571c7c..25a11aafbcc 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -73,9 +73,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Signal an error if OBJ is pure. */
#define CHECK_IMPURE(obj) \
{ if (PURE_P (obj)) \
- pure_write_error (); }
+ pure_write_error (obj); }
-extern _Noreturn void pure_write_error (void);
+extern _Noreturn void pure_write_error (Lisp_Object);
/* Define PURE_P. */
diff --git a/src/regex.c b/src/regex.c
index b5522f19079..73a735cea65 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -33,10 +33,9 @@
/* Ignore some GCC warnings for now. This section should go away
once the Emacs and Gnulib regex code is merged. */
-#if (__GNUC__ == 4 && 5 <= __GNUC_MINOR__) || 4 < __GNUC__
+#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) || defined __clang__
# pragma GCC diagnostic ignored "-Wstrict-overflow"
# ifndef emacs
-# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
# pragma GCC diagnostic ignored "-Wunused-function"
# pragma GCC diagnostic ignored "-Wunused-macros"
# pragma GCC diagnostic ignored "-Wunused-result"
@@ -44,6 +43,10 @@
# endif
#endif
+#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && ! defined __clang__
+# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
#include <config.h>
#include <stddef.h>
@@ -710,51 +713,27 @@ typedef enum
at SOURCE. */
#define EXTRACT_NUMBER(destination, source) \
- do { \
- (destination) = *(source) & 0377; \
- (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
- } while (0)
+ ((destination) = extract_number (source))
-#ifdef DEBUG
-static void
-extract_number (int *dest, re_char *source)
+static int
+extract_number (re_char *source)
{
- int temp = SIGN_EXTEND_CHAR (*(source + 1));
- *dest = *source & 0377;
- *dest += temp << 8;
+ return (SIGN_EXTEND_CHAR (source[1]) << 8) + source[0];
}
-# ifndef EXTRACT_MACROS /* To debug the macros. */
-# undef EXTRACT_NUMBER
-# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
-# endif /* not EXTRACT_MACROS */
-
-#endif /* DEBUG */
-
/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
SOURCE must be an lvalue. */
#define EXTRACT_NUMBER_AND_INCR(destination, source) \
- do { \
- EXTRACT_NUMBER (destination, source); \
- (source) += 2; \
- } while (0)
+ ((destination) = extract_number_and_incr (&source))
-#ifdef DEBUG
-static void
-extract_number_and_incr (int *destination, re_char **source)
+static int
+extract_number_and_incr (re_char **source)
{
- extract_number (destination, *source);
+ int num = extract_number (*source);
*source += 2;
+ return num;
}
-
-# ifndef EXTRACT_MACROS
-# undef EXTRACT_NUMBER_AND_INCR
-# define EXTRACT_NUMBER_AND_INCR(dest, src) \
- extract_number_and_incr (&dest, &src)
-# endif /* not EXTRACT_MACROS */
-
-#endif /* DEBUG */
/* Store a multibyte character in three contiguous bytes starting
DESTINATION, and increment DESTINATION to the byte after where the
@@ -861,10 +840,8 @@ extract_number_and_incr (int *destination, re_char **source)
static int debug = -100000;
# define DEBUG_STATEMENT(e) e
-# define DEBUG_PRINT1(x) if (debug > 0) printf (x)
-# define DEBUG_PRINT2(x1, x2) if (debug > 0) printf (x1, x2)
-# define DEBUG_PRINT3(x1, x2, x3) if (debug > 0) printf (x1, x2, x3)
-# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug > 0) printf (x1, x2, x3, x4)
+# define DEBUG_PRINT(...) if (debug > 0) printf (__VA_ARGS__)
+# define DEBUG_COMPILES_ARGUMENTS
# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
if (debug > 0) print_partial_compiled_pattern (s, e)
# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
@@ -873,9 +850,8 @@ static int debug = -100000;
/* Print the fastmap in human-readable form. */
-void
-print_fastmap (fastmap)
- char *fastmap;
+static void
+print_fastmap (char *fastmap)
{
unsigned was_a_range = 0;
unsigned i = 0;
@@ -905,10 +881,8 @@ print_fastmap (fastmap)
/* Print a compiled pattern string in human-readable form, starting at
the START pointer into it and ending just before the pointer END. */
-void
-print_partial_compiled_pattern (start, end)
- re_char *start;
- re_char *end;
+static void
+print_partial_compiled_pattern (re_char *start, re_char *end)
{
int mcnt, mcnt2;
re_char *p = start;
@@ -923,7 +897,7 @@ print_partial_compiled_pattern (start, end)
/* Loop over pattern commands. */
while (p < pend)
{
- fprintf (stderr, "%d:\t", p - start);
+ fprintf (stderr, "%td:\t", p - start);
switch ((re_opcode_t) *p++)
{
@@ -1027,51 +1001,58 @@ print_partial_compiled_pattern (start, end)
break;
case on_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- fprintf (stderr, "/on_failure_jump to %d", p + mcnt - start);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ fprintf (stderr, "/on_failure_jump to %td", p + mcnt - start);
break;
case on_failure_keep_string_jump:
- extract_number_and_incr (&mcnt, &p);
- fprintf (stderr, "/on_failure_keep_string_jump to %d", p + mcnt - start);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ fprintf (stderr, "/on_failure_keep_string_jump to %td",
+ p + mcnt - start);
break;
case on_failure_jump_nastyloop:
- extract_number_and_incr (&mcnt, &p);
- fprintf (stderr, "/on_failure_jump_nastyloop to %d", p + mcnt - start);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ fprintf (stderr, "/on_failure_jump_nastyloop to %td",
+ p + mcnt - start);
break;
case on_failure_jump_loop:
- extract_number_and_incr (&mcnt, &p);
- fprintf (stderr, "/on_failure_jump_loop to %d", p + mcnt - start);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ fprintf (stderr, "/on_failure_jump_loop to %td",
+ p + mcnt - start);
break;
case on_failure_jump_smart:
- extract_number_and_incr (&mcnt, &p);
- fprintf (stderr, "/on_failure_jump_smart to %d", p + mcnt - start);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ fprintf (stderr, "/on_failure_jump_smart to %td",
+ p + mcnt - start);
break;
case jump:
- extract_number_and_incr (&mcnt, &p);
- fprintf (stderr, "/jump to %d", p + mcnt - start);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ fprintf (stderr, "/jump to %td", p + mcnt - start);
break;
case succeed_n:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- fprintf (stderr, "/succeed_n to %d, %d times", p - 2 + mcnt - start, mcnt2);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ EXTRACT_NUMBER_AND_INCR (mcnt2, p);
+ fprintf (stderr, "/succeed_n to %td, %d times",
+ p - 2 + mcnt - start, mcnt2);
break;
case jump_n:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- fprintf (stderr, "/jump_n to %d, %d times", p - 2 + mcnt - start, mcnt2);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ EXTRACT_NUMBER_AND_INCR (mcnt2, p);
+ fprintf (stderr, "/jump_n to %td, %d times",
+ p - 2 + mcnt - start, mcnt2);
break;
case set_number_at:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- fprintf (stderr, "/set_number_at location %d to %d", p - 2 + mcnt - start, mcnt2);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ EXTRACT_NUMBER_AND_INCR (mcnt2, p);
+ fprintf (stderr, "/set_number_at location %td to %d",
+ p - 2 + mcnt - start, mcnt2);
break;
case wordbound:
@@ -1151,13 +1132,12 @@ print_partial_compiled_pattern (start, end)
fprintf (stderr, "\n");
}
- fprintf (stderr, "%d:\tend of pattern.\n", p - start);
+ fprintf (stderr, "%td:\tend of pattern.\n", p - start);
}
-void
-print_compiled_pattern (bufp)
- struct re_pattern_buffer *bufp;
+static void
+print_compiled_pattern (struct re_pattern_buffer *bufp)
{
re_char *buffer = bufp->buffer;
@@ -1171,7 +1151,7 @@ print_compiled_pattern (bufp)
print_fastmap (bufp->fastmap);
}
- printf ("re_nsub: %d\t", bufp->re_nsub);
+ printf ("re_nsub: %zu\t", bufp->re_nsub);
printf ("regs_alloc: %d\t", bufp->regs_allocated);
printf ("can_be_null: %d\t", bufp->can_be_null);
printf ("no_sub: %d\t", bufp->no_sub);
@@ -1183,13 +1163,9 @@ print_compiled_pattern (bufp)
}
-void
-print_double_string (where, string1, size1, string2, size2)
- re_char *where;
- re_char *string1;
- re_char *string2;
- ssize_t size1;
- ssize_t size2;
+static void
+print_double_string (re_char *where, re_char *string1, ssize_t size1,
+ re_char *string2, ssize_t size2)
{
ssize_t this_char;
@@ -1216,10 +1192,12 @@ print_double_string (where, string1, size1, string2, size2)
# define assert(e)
# define DEBUG_STATEMENT(e)
-# define DEBUG_PRINT1(x)
-# define DEBUG_PRINT2(x1, x2)
-# define DEBUG_PRINT3(x1, x2, x3)
-# define DEBUG_PRINT4(x1, x2, x3, x4)
+# if __STDC_VERSION__ < 199901L
+# define DEBUG_COMPILES_ARGUMENTS
+# define DEBUG_PRINT /* 'DEBUG_PRINT (x, y)' discards X and Y. */ (void)
+# else
+# define DEBUG_PRINT(...)
+# endif
# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
@@ -1473,20 +1451,21 @@ typedef struct
while (REMAINING_AVAIL_SLOTS <= space) { \
if (!GROW_FAIL_STACK (fail_stack)) \
return -2; \
- DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", (fail_stack).size);\
- DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\
+ DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\
}
/* Push register NUM onto the stack. */
#define PUSH_FAILURE_REG(num) \
do { \
char *destination; \
+ long n = num; \
ENSURE_FAIL_STACK(3); \
- DEBUG_PRINT4 (" Push reg %d (spanning %p -> %p)\n", \
- num, regstart[num], regend[num]); \
- PUSH_FAILURE_POINTER (regstart[num]); \
- PUSH_FAILURE_POINTER (regend[num]); \
- PUSH_FAILURE_INT (num); \
+ DEBUG_PRINT (" Push reg %ld (spanning %p -> %p)\n", \
+ n, regstart[n], regend[n]); \
+ PUSH_FAILURE_POINTER (regstart[n]); \
+ PUSH_FAILURE_POINTER (regend[n]); \
+ PUSH_FAILURE_INT (n); \
} while (0)
/* Change the counter's value to VAL, but make sure that it will
@@ -1497,7 +1476,7 @@ do { \
int c; \
ENSURE_FAIL_STACK(3); \
EXTRACT_NUMBER (c, ptr); \
- DEBUG_PRINT4 (" Push number %p = %d -> %d\n", ptr, c, val); \
+ DEBUG_PRINT (" Push number %p = %d -> %d\n", ptr, c, val); \
PUSH_FAILURE_INT (c); \
PUSH_FAILURE_POINTER (ptr); \
PUSH_FAILURE_INT (-1); \
@@ -1515,14 +1494,14 @@ do { \
unsigned char *ptr = (unsigned char*) POP_FAILURE_POINTER (); \
pfreg = POP_FAILURE_INT (); \
STORE_NUMBER (ptr, pfreg); \
- DEBUG_PRINT3 (" Pop counter %p = %d\n", ptr, pfreg); \
+ DEBUG_PRINT (" Pop counter %p = %ld\n", ptr, pfreg); \
} \
else \
{ \
regend[pfreg] = POP_FAILURE_POINTER (); \
regstart[pfreg] = POP_FAILURE_POINTER (); \
- DEBUG_PRINT4 (" Pop reg %d (spanning %p -> %p)\n", \
- pfreg, regstart[pfreg], regend[pfreg]); \
+ DEBUG_PRINT (" Pop reg %ld (spanning %p -> %p)\n", \
+ pfreg, regstart[pfreg], regend[pfreg]); \
} \
} while (0)
@@ -1542,10 +1521,10 @@ do { \
cycle = 1; \
break; \
} \
- DEBUG_PRINT2 (" Other pattern: %p\n", FAILURE_PAT (failure)); \
+ DEBUG_PRINT (" Other pattern: %p\n", FAILURE_PAT (failure)); \
failure = NEXT_FAILURE_HANDLE(failure); \
} \
- DEBUG_PRINT2 (" Other string: %p\n", FAILURE_STR (failure)); \
+ DEBUG_PRINT (" Other string: %p\n", FAILURE_STR (failure)); \
} while (0)
/* Push the information about the state we will need
@@ -1564,23 +1543,23 @@ do { \
of 0 + -1 isn't done as unsigned. */ \
\
DEBUG_STATEMENT (nfailure_points_pushed++); \
- DEBUG_PRINT1 ("\nPUSH_FAILURE_POINT:\n"); \
- DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail); \
- DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ DEBUG_PRINT ("\nPUSH_FAILURE_POINT:\n"); \
+ DEBUG_PRINT (" Before push, next avail: %zd\n", (fail_stack).avail); \
+ DEBUG_PRINT (" size: %zd\n", (fail_stack).size);\
\
ENSURE_FAIL_STACK (NUM_NONREG_ITEMS); \
\
- DEBUG_PRINT1 ("\n"); \
+ DEBUG_PRINT ("\n"); \
\
- DEBUG_PRINT2 (" Push frame index: %d\n", fail_stack.frame); \
+ DEBUG_PRINT (" Push frame index: %zd\n", fail_stack.frame); \
PUSH_FAILURE_INT (fail_stack.frame); \
\
- DEBUG_PRINT2 (" Push string %p: `", string_place); \
+ DEBUG_PRINT (" Push string %p: `", string_place); \
DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, size2);\
- DEBUG_PRINT1 ("'\n"); \
+ DEBUG_PRINT ("'\n"); \
PUSH_FAILURE_POINTER (string_place); \
\
- DEBUG_PRINT2 (" Push pattern %p: ", pattern); \
+ DEBUG_PRINT (" Push pattern %p: ", pattern); \
DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern, pend); \
PUSH_FAILURE_POINTER (pattern); \
\
@@ -1613,28 +1592,28 @@ do { \
assert (!FAIL_STACK_EMPTY ()); \
\
/* Remove failure points and point to how many regs pushed. */ \
- DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
- DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
- DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ DEBUG_PRINT ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT (" Before pop, next avail: %zd\n", fail_stack.avail); \
+ DEBUG_PRINT (" size: %zd\n", fail_stack.size); \
\
/* Pop the saved registers. */ \
while (fail_stack.frame < fail_stack.avail) \
POP_FAILURE_REG_OR_COUNT (); \
\
- pat = POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" Popping pattern %p: ", pat); \
+ pat = POP_FAILURE_POINTER (); \
+ DEBUG_PRINT (" Popping pattern %p: ", pat); \
DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
\
/* If the saved string location is NULL, it came from an \
on_failure_keep_string_jump opcode, and we want to throw away the \
saved NULL, thus retaining our current position in the string. */ \
str = POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" Popping string %p: `", str); \
+ DEBUG_PRINT (" Popping string %p: `", str); \
DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
- DEBUG_PRINT1 ("'\n"); \
+ DEBUG_PRINT ("'\n"); \
\
fail_stack.frame = POP_FAILURE_INT (); \
- DEBUG_PRINT2 (" Popping frame index: %d\n", fail_stack.frame); \
+ DEBUG_PRINT (" Popping frame index: %zd\n", fail_stack.frame); \
\
assert (fail_stack.avail >= 0); \
assert (fail_stack.frame <= fail_stack.avail); \
@@ -2497,7 +2476,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
#ifdef DEBUG
debug++;
- DEBUG_PRINT1 ("\nCompiling pattern: ");
+ DEBUG_PRINT ("\nCompiling pattern: ");
if (debug > 0)
{
unsigned debug_count;
@@ -2650,7 +2629,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
goto normal_char;
handle_plus:
case '*':
- /* If there is no previous pattern... */
+ /* If there is no previous pattern... */
if (!laststart)
{
if (syntax & RE_CONTEXT_INVALID_OPS)
@@ -2758,7 +2737,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
}
}
else /* not greedy */
- { /* I wish the greedy and non-greedy cases could be merged. */
+ { /* I wish the greedy and non-greedy cases could be merged. */
GET_BUFFER_SPACE (7); /* We might use less. */
if (many_times_ok)
@@ -3062,7 +3041,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
/* Allocate space for COUNT + RANGE_TABLE. Needs two
bytes for flags, two for COUNT, and three bytes for
- each character. */
+ each character. */
GET_BUFFER_SPACE (4 + used * 3);
/* Indicate the existence of range table. */
@@ -3489,6 +3468,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
/* There is no way to specify the before_dot and after_dot
operators. rms says this is ok. --karl */
case '=':
+ laststart = b;
BUF_PUSH (at_dot);
break;
@@ -3537,12 +3517,14 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
case '<':
if (syntax & RE_NO_GNU_OPS)
goto normal_char;
+ laststart = b;
BUF_PUSH (wordbeg);
break;
case '>':
if (syntax & RE_NO_GNU_OPS)
goto normal_char;
+ laststart = b;
BUF_PUSH (wordend);
break;
@@ -3701,7 +3683,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
if (debug > 0)
{
re_compile_fastmap (bufp);
- DEBUG_PRINT1 ("\nCompiled pattern: \n");
+ DEBUG_PRINT ("\nCompiled pattern: \n");
print_compiled_pattern (bufp);
}
debug--;
@@ -4527,8 +4509,8 @@ static int bcmp_translate (re_char *s1, re_char *s2,
and `string2' into an offset from the beginning of that string. */
#define POINTER_TO_OFFSET(ptr) \
(FIRST_STRING_P (ptr) \
- ? ((regoff_t) ((ptr) - string1)) \
- : ((regoff_t) ((ptr) - string2 + size1)))
+ ? (ptr) - string1 \
+ : (ptr) - string2 + (ptrdiff_t) size1)
/* Call before fetching a character with *d. This switches over to
string2 if necessary.
@@ -4715,7 +4697,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
/* If we're at the end of the pattern, we can change. */
if (skip_one_char (p1))
{
- DEBUG_PRINT1 (" End of pattern: fast loop.\n");
+ DEBUG_PRINT (" End of pattern: fast loop.\n");
return 1;
}
break;
@@ -4731,7 +4713,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
{
if (c != RE_STRING_CHAR (p1 + 2, multibyte))
{
- DEBUG_PRINT3 (" '%c' != '%c' => fast loop.\n", c, p1[2]);
+ DEBUG_PRINT (" '%c' != '%c' => fast loop.\n", c, p1[2]);
return 1;
}
}
@@ -4756,14 +4738,14 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
that we can't change to pop_failure_jump. */
if (!not)
{
- DEBUG_PRINT1 (" No match => fast loop.\n");
+ DEBUG_PRINT (" No match => fast loop.\n");
return 1;
}
}
else if ((re_opcode_t) *p1 == anychar
&& c == '\n')
{
- DEBUG_PRINT1 (" . != \\n => fast loop.\n");
+ DEBUG_PRINT (" . != \\n => fast loop.\n");
return 1;
}
}
@@ -4806,7 +4788,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
if (idx == p2[1]
|| idx == CHARSET_BITMAP_SIZE (p1))
{
- DEBUG_PRINT1 (" No match => fast loop.\n");
+ DEBUG_PRINT (" No match => fast loop.\n");
return 1;
}
}
@@ -4823,7 +4805,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
if (idx == p2[1])
{
- DEBUG_PRINT1 (" No match => fast loop.\n");
+ DEBUG_PRINT (" No match => fast loop.\n");
return 1;
}
}
@@ -4943,7 +4925,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
ssize_t pos, struct re_registers *regs, ssize_t stop)
{
/* General temporaries. */
- ssize_t mcnt;
+ int mcnt;
size_t reg;
/* Just past the end of the corresponding string. */
@@ -4985,7 +4967,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
fail_stack_type fail_stack;
#endif
-#ifdef DEBUG
+#ifdef DEBUG_COMPILES_ARGUMENTS
unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
#endif
@@ -5030,12 +5012,12 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
and need to test it, it's not garbage. */
re_char *match_end = NULL;
-#ifdef DEBUG
+#ifdef DEBUG_COMPILES_ARGUMENTS
/* Counts the total number of registers pushed. */
unsigned num_regs_pushed = 0;
#endif
- DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+ DEBUG_PRINT ("\n\nEntering re_match_2.\n");
INIT_FAIL_STACK ();
@@ -5131,22 +5113,25 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
dend = end_match_1;
}
- DEBUG_PRINT1 ("The compiled pattern is: ");
+ DEBUG_PRINT ("The compiled pattern is: ");
DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
- DEBUG_PRINT1 ("The string to match is: `");
+ DEBUG_PRINT ("The string to match is: `");
DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
- DEBUG_PRINT1 ("'\n");
+ DEBUG_PRINT ("'\n");
/* This loops over pattern commands. It exits by returning from the
function if the match is complete, or it drops through if the match
fails at this starting point in the input data. */
for (;;)
{
- DEBUG_PRINT2 ("\n%p: ", p);
+ DEBUG_PRINT ("\n%p: ", p);
if (p == pend)
- { /* End of pattern means we might have succeeded. */
- DEBUG_PRINT1 ("end of pattern ... ");
+ {
+ ptrdiff_t dcnt;
+
+ /* End of pattern means we might have succeeded. */
+ DEBUG_PRINT ("end of pattern ... ");
/* If we haven't matched the entire string, and we want the
longest match, try backtracking. */
@@ -5166,7 +5151,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
else
best_match_p = !FIRST_STRING_P (d);
- DEBUG_PRINT1 ("backtracking.\n");
+ DEBUG_PRINT ("backtracking.\n");
if (!FAIL_STACK_EMPTY ())
{ /* More failure points to try. */
@@ -5177,7 +5162,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
best_regs_set = true;
match_end = d;
- DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+ DEBUG_PRINT ("\nSAVING match as best so far.\n");
for (reg = 1; reg < num_regs; reg++)
{
@@ -5199,7 +5184,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
For example, the pattern `x.*y.*z' against the
strings `x-' and `y-z-', if the two strings are
not consecutive in memory. */
- DEBUG_PRINT1 ("Restoring best registers.\n");
+ DEBUG_PRINT ("Restoring best registers.\n");
d = match_end;
dend = ((d >= string1 && d <= end1)
@@ -5214,7 +5199,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
} /* d != end_match_2 */
succeed_label:
- DEBUG_PRINT1 ("Accepting match.\n");
+ DEBUG_PRINT ("Accepting match.\n");
/* If caller wants register contents data back, do it. */
if (regs && !bufp->no_sub)
@@ -5274,10 +5259,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
regs->start[reg] = regs->end[reg] = -1;
else
{
- regs->start[reg]
- = (regoff_t) POINTER_TO_OFFSET (regstart[reg]);
- regs->end[reg]
- = (regoff_t) POINTER_TO_OFFSET (regend[reg]);
+ regs->start[reg] = POINTER_TO_OFFSET (regstart[reg]);
+ regs->end[reg] = POINTER_TO_OFFSET (regend[reg]);
}
}
@@ -5290,17 +5273,17 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
regs->start[reg] = regs->end[reg] = -1;
} /* regs && !bufp->no_sub */
- DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
- nfailure_points_pushed, nfailure_points_popped,
- nfailure_points_pushed - nfailure_points_popped);
- DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+ DEBUG_PRINT ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT ("%u registers pushed.\n", num_regs_pushed);
- mcnt = POINTER_TO_OFFSET (d) - pos;
+ dcnt = POINTER_TO_OFFSET (d) - pos;
- DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+ DEBUG_PRINT ("Returning %td from re_match_2.\n", dcnt);
FREE_VARIABLES ();
- return mcnt;
+ return dcnt;
}
/* Otherwise match next pattern command. */
@@ -5309,11 +5292,11 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
/* Ignore these. Used to ignore the n of succeed_n's which
currently have n == 0. */
case no_op:
- DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ DEBUG_PRINT ("EXECUTING no_op.\n");
break;
case succeed:
- DEBUG_PRINT1 ("EXECUTING succeed.\n");
+ DEBUG_PRINT ("EXECUTING succeed.\n");
goto succeed_label;
/* Match the next n pattern characters exactly. The following
@@ -5321,7 +5304,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
are the characters to match. */
case exactn:
mcnt = *p++;
- DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+ DEBUG_PRINT ("EXECUTING exactn %d.\n", mcnt);
/* Remember the start point to rollback upon failure. */
dfail = d;
@@ -5427,7 +5410,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
int buf_charlen;
re_wchar_t buf_ch;
- DEBUG_PRINT1 ("EXECUTING anychar.\n");
+ DEBUG_PRINT ("EXECUTING anychar.\n");
PREFETCH ();
buf_ch = RE_STRING_CHAR_AND_LENGTH (d, buf_charlen,
@@ -5440,7 +5423,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
&& buf_ch == '\000'))
goto fail;
- DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ DEBUG_PRINT (" Matched `%d'.\n", *d);
d += buf_charlen;
}
break;
@@ -5467,7 +5450,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
/* Whether matching against a unibyte character. */
boolean unibyte_char = false;
- DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+ DEBUG_PRINT ("EXECUTING charset%s.\n", not ? "_not" : "");
range_table_exists = CHARSET_RANGE_TABLE_EXISTS_P (&p[-1]);
@@ -5551,14 +5534,14 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
matched within the group is recorded (in the internal
registers data structure) under the register number. */
case start_memory:
- DEBUG_PRINT2 ("EXECUTING start_memory %d:\n", *p);
+ DEBUG_PRINT ("EXECUTING start_memory %d:\n", *p);
/* In case we need to undo this operation (via backtracking). */
- PUSH_FAILURE_REG ((unsigned int)*p);
+ PUSH_FAILURE_REG (*p);
regstart[*p] = d;
regend[*p] = NULL; /* probably unnecessary. -sm */
- DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+ DEBUG_PRINT (" regstart: %td\n", POINTER_TO_OFFSET (regstart[*p]));
/* Move past the register number and inner group count. */
p += 1;
@@ -5568,7 +5551,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
/* The stop_memory opcode represents the end of a group. Its
argument is the same as start_memory's: the register number. */
case stop_memory:
- DEBUG_PRINT2 ("EXECUTING stop_memory %d:\n", *p);
+ DEBUG_PRINT ("EXECUTING stop_memory %d:\n", *p);
assert (!REG_UNSET (regstart[*p]));
/* Strictly speaking, there should be code such as:
@@ -5586,7 +5569,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
is *not* undone. */
regend[*p] = d;
- DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+ DEBUG_PRINT (" regend: %td\n", POINTER_TO_OFFSET (regend[*p]));
/* Move past the register number and the inner group count. */
p += 1;
@@ -5599,7 +5582,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
{
register re_char *d2, *dend2;
int regno = *p++; /* Get which register to match against. */
- DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
+ DEBUG_PRINT ("EXECUTING duplicate %d.\n", regno);
/* Can't back reference a group which we've never matched. */
if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
@@ -5621,6 +5604,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
? regend[regno] : end_match_1);
for (;;)
{
+ ptrdiff_t dcnt;
+
/* If necessary, advance to next segment in register
contents. */
while (d2 == dend2)
@@ -5639,23 +5624,23 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
PREFETCH ();
/* How many characters left in this segment to match. */
- mcnt = dend - d;
+ dcnt = dend - d;
/* Want how many consecutive characters we can match in
one shot, so, if necessary, adjust the count. */
- if (mcnt > dend2 - d2)
- mcnt = dend2 - d2;
+ if (dcnt > dend2 - d2)
+ dcnt = dend2 - d2;
/* Compare that many; failure if mismatch, else move
past them. */
if (RE_TRANSLATE_P (translate)
- ? bcmp_translate (d, d2, mcnt, translate, target_multibyte)
- : memcmp (d, d2, mcnt))
+ ? bcmp_translate (d, d2, dcnt, translate, target_multibyte)
+ : memcmp (d, d2, dcnt))
{
d = dfail;
goto fail;
}
- d += mcnt, d2 += mcnt;
+ d += dcnt, d2 += dcnt;
}
}
break;
@@ -5664,7 +5649,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
/* begline matches the empty string at the beginning of the string
(unless `not_bol' is set in `bufp'), and after newlines. */
case begline:
- DEBUG_PRINT1 ("EXECUTING begline.\n");
+ DEBUG_PRINT ("EXECUTING begline.\n");
if (AT_STRINGS_BEG (d))
{
@@ -5683,7 +5668,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
/* endline is the dual of begline. */
case endline:
- DEBUG_PRINT1 ("EXECUTING endline.\n");
+ DEBUG_PRINT ("EXECUTING endline.\n");
if (AT_STRINGS_END (d))
{
@@ -5700,7 +5685,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
/* Match at the very beginning of the data. */
case begbuf:
- DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ DEBUG_PRINT ("EXECUTING begbuf.\n");
if (AT_STRINGS_BEG (d))
break;
goto fail;
@@ -5708,7 +5693,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
/* Match at the very end of the data. */
case endbuf:
- DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ DEBUG_PRINT ("EXECUTING endbuf.\n");
if (AT_STRINGS_END (d))
break;
goto fail;
@@ -5732,8 +5717,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
case; that seems worse than this. */
case on_failure_keep_string_jump:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 ("EXECUTING on_failure_keep_string_jump %d (to %p):\n",
- mcnt, p + mcnt);
+ DEBUG_PRINT ("EXECUTING on_failure_keep_string_jump %d (to %p):\n",
+ mcnt, p + mcnt);
PUSH_FAILURE_POINT (p - 3, NULL);
break;
@@ -5754,8 +5739,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
the loop. */
case on_failure_jump_nastyloop:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 ("EXECUTING on_failure_jump_nastyloop %d (to %p):\n",
- mcnt, p + mcnt);
+ DEBUG_PRINT ("EXECUTING on_failure_jump_nastyloop %d (to %p):\n",
+ mcnt, p + mcnt);
assert ((re_opcode_t)p[-4] == no_op);
{
@@ -5775,8 +5760,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
case on_failure_jump_loop:
on_failure:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 ("EXECUTING on_failure_jump_loop %d (to %p):\n",
- mcnt, p + mcnt);
+ DEBUG_PRINT ("EXECUTING on_failure_jump_loop %d (to %p):\n",
+ mcnt, p + mcnt);
{
int cycle = 0;
CHECK_INFINITE_LOOP (p - 3, d);
@@ -5807,8 +5792,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
pop_failure_jump back to this on_failure_jump. */
case on_failure_jump:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 ("EXECUTING on_failure_jump %d (to %p):\n",
- mcnt, p + mcnt);
+ DEBUG_PRINT ("EXECUTING on_failure_jump %d (to %p):\n",
+ mcnt, p + mcnt);
PUSH_FAILURE_POINT (p -3, d);
break;
@@ -5822,8 +5807,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
on_failure_keep_string_jump instead of on_failure_jump. */
case on_failure_jump_smart:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 ("EXECUTING on_failure_jump_smart %d (to %p).\n",
- mcnt, p + mcnt);
+ DEBUG_PRINT ("EXECUTING on_failure_jump_smart %d (to %p).\n",
+ mcnt, p + mcnt);
{
re_char *p1 = p; /* Next operation. */
/* Here, we discard `const', making re_match non-reentrant. */
@@ -5843,14 +5828,14 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
if (mutually_exclusive_p (bufp, p1, p2))
{
/* Use a fast `on_failure_keep_string_jump' loop. */
- DEBUG_PRINT1 (" smart exclusive => fast loop.\n");
+ DEBUG_PRINT (" smart exclusive => fast loop.\n");
*p3 = (unsigned char) on_failure_keep_string_jump;
STORE_NUMBER (p2 - 2, mcnt + 3);
}
else
{
/* Default to a safe `on_failure_jump' loop. */
- DEBUG_PRINT1 (" smart default => slow loop.\n");
+ DEBUG_PRINT (" smart default => slow loop.\n");
*p3 = (unsigned char) on_failure_jump;
}
DEBUG_STATEMENT (debug -= 2);
@@ -5862,9 +5847,9 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
unconditional_jump:
IMMEDIATE_QUIT_CHECK;
EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
- DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ DEBUG_PRINT ("EXECUTING jump %d ", mcnt);
p += mcnt; /* Do the jump. */
- DEBUG_PRINT2 ("(to %p).\n", p);
+ DEBUG_PRINT ("(to %p).\n", p);
break;
@@ -5873,7 +5858,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
case succeed_n:
/* Signedness doesn't matter since we only compare MCNT to 0. */
EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+ DEBUG_PRINT ("EXECUTING succeed_n %d.\n", mcnt);
/* Originally, mcnt is how many times we HAVE to succeed. */
if (mcnt != 0)
@@ -5892,7 +5877,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
case jump_n:
/* Signedness doesn't matter since we only compare MCNT to 0. */
EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+ DEBUG_PRINT ("EXECUTING jump_n %d.\n", mcnt);
/* Originally, this is how many times we CAN jump. */
if (mcnt != 0)
@@ -5911,14 +5896,14 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
case set_number_at:
{
unsigned char *p2; /* Location of the counter. */
- DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+ DEBUG_PRINT ("EXECUTING set_number_at.\n");
EXTRACT_NUMBER_AND_INCR (mcnt, p);
/* Here, we discard `const', making re_match non-reentrant. */
p2 = (unsigned char*) p + mcnt;
/* Signedness doesn't matter since we only copy MCNT's bits . */
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 (" Setting %p to %d.\n", p2, mcnt);
+ DEBUG_PRINT (" Setting %p to %d.\n", p2, mcnt);
PUSH_NUMBER (p2, mcnt);
break;
}
@@ -5927,7 +5912,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
case notwordbound:
{
boolean not = (re_opcode_t) *(p - 1) == notwordbound;
- DEBUG_PRINT2 ("EXECUTING %swordbound.\n", not?"not":"");
+ DEBUG_PRINT ("EXECUTING %swordbound.\n", not ? "not" : "");
/* We SUCCEED (or FAIL) in one of the following cases: */
@@ -5969,7 +5954,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
}
case wordbeg:
- DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+ DEBUG_PRINT ("EXECUTING wordbeg.\n");
/* We FAIL in one of the following cases: */
@@ -6014,7 +5999,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
break;
case wordend:
- DEBUG_PRINT1 ("EXECUTING wordend.\n");
+ DEBUG_PRINT ("EXECUTING wordend.\n");
/* We FAIL in one of the following cases: */
@@ -6059,7 +6044,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
break;
case symbeg:
- DEBUG_PRINT1 ("EXECUTING symbeg.\n");
+ DEBUG_PRINT ("EXECUTING symbeg.\n");
/* We FAIL in one of the following cases: */
@@ -6102,7 +6087,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
break;
case symend:
- DEBUG_PRINT1 ("EXECUTING symend.\n");
+ DEBUG_PRINT ("EXECUTING symend.\n");
/* We FAIL in one of the following cases: */
@@ -6149,7 +6134,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
{
boolean not = (re_opcode_t) *(p - 1) == notsyntaxspec;
mcnt = *p++;
- DEBUG_PRINT3 ("EXECUTING %ssyntaxspec %d.\n", not?"not":"", mcnt);
+ DEBUG_PRINT ("EXECUTING %ssyntaxspec %d.\n", not ? "not" : "",
+ mcnt);
PREFETCH ();
#ifdef emacs
{
@@ -6172,19 +6158,19 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
#ifdef emacs
case before_dot:
- DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ DEBUG_PRINT ("EXECUTING before_dot.\n");
if (PTR_BYTE_POS (d) >= PT_BYTE)
goto fail;
break;
case at_dot:
- DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ DEBUG_PRINT ("EXECUTING at_dot.\n");
if (PTR_BYTE_POS (d) != PT_BYTE)
goto fail;
break;
case after_dot:
- DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ DEBUG_PRINT ("EXECUTING after_dot.\n");
if (PTR_BYTE_POS (d) <= PT_BYTE)
goto fail;
break;
@@ -6194,8 +6180,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
{
boolean not = (re_opcode_t) *(p - 1) == notcategoryspec;
mcnt = *p++;
- DEBUG_PRINT3 ("EXECUTING %scategoryspec %d.\n",
- not?"not":"", mcnt);
+ DEBUG_PRINT ("EXECUTING %scategoryspec %d.\n",
+ not ? "not" : "", mcnt);
PREFETCH ();
{
@@ -6224,7 +6210,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
{
re_char *str, *pat;
/* A restart point is known. Restore to that state. */
- DEBUG_PRINT1 ("\nFAIL:\n");
+ DEBUG_PRINT ("\nFAIL:\n");
POP_FAILURE_POINT (str, pat);
switch (*pat++)
{
@@ -6269,7 +6255,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
FREE_VARIABLES ();
return -1; /* Failure to match. */
-} /* re_match_2 */
+}
/* Subroutine definitions for re_match_2. */
@@ -6402,8 +6388,8 @@ weak_function
re_exec (const char *s)
{
const size_t len = strlen (s);
- return
- 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
+ return (re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0)
+ >= 0);
}
#endif /* _REGEX_RE_COMP */
diff --git a/src/regex.h b/src/regex.h
index 36fb4321027..175eed10177 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -530,7 +530,7 @@ extern int re_exec (const char *);
/* GCC 2.95 and later have "__restrict"; C99 compilers have
"restrict", and "configure" may have defined "restrict". */
#ifndef __restrict
-# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
+# if ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
# if defined restrict || 199901L <= __STDC_VERSION__
# define __restrict restrict
# else
diff --git a/src/search.c b/src/search.c
index 4dd3260b735..b4e3cca8269 100644
--- a/src/search.c
+++ b/src/search.c
@@ -326,20 +326,20 @@ looking_at_1 (Lisp_Object string, bool posix)
if (i == -2)
matcher_overflow ();
- val = (0 <= i ? Qt : Qnil);
+ val = (i >= 0 ? Qt : Qnil);
if (NILP (Vinhibit_changing_match_data) && i >= 0)
+ {
for (i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
{
search_regs.start[i]
= BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
- search_regs.end[i]
- = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
- }
-
- /* Set last_thing_searched only when match data is changed. */
- if (NILP (Vinhibit_changing_match_data))
+ search_regs.end[i]
+ = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
+ }
+ /* Set last_thing_searched only when match data is changed. */
XSETBUFFER (last_thing_searched, current_buffer);
+ }
return val;
}
@@ -2450,7 +2450,7 @@ since only regular expressions have distinguished subexpressions. */)
else if (c >= '1' && c <= '9')
{
if (c - '0' < search_regs.num_regs
- && 0 <= search_regs.start[c - '0'])
+ && search_regs.start[c - '0'] >= 0)
{
substart = search_regs.start[c - '0'];
subend = search_regs.end[c - '0'];
@@ -2533,9 +2533,9 @@ since only regular expressions have distinguished subexpressions. */)
bool str_multibyte = STRING_MULTIBYTE (newtext);
bool really_changed = 0;
- substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length
- ? STRING_BYTES_BOUND
- : length * 2 + 100);
+ substed_alloc_size = (length <= (STRING_BYTES_BOUND - 100) / 2
+ ? length * 2 + 100
+ : STRING_BYTES_BOUND);
substed = xmalloc (substed_alloc_size);
substed_len = 0;
diff --git a/src/sysdep.c b/src/sysdep.c
index bff11fc9f75..1d3e646d359 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -282,7 +282,7 @@ get_child_status (pid_t child, int *status, int options, bool interruptible)
reap an unwanted process by mistake. For example, invoking
waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
so that another thread running glib won't find them. */
- eassert (0 < child);
+ eassert (child > 0);
while ((pid = waitpid (child, status, options)) < 0)
{
@@ -2691,7 +2691,7 @@ procfs_ttyname (int rdev)
while (!feof (fdev) && !ferror (fdev))
{
- if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor)
+ if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
&& major == MAJOR (rdev))
{
minor_beg = strtoul (minor, &endp, 0);
@@ -2731,7 +2731,7 @@ procfs_get_total_memory (void)
while (!feof (fmem) && !ferror (fmem))
{
- if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value)
+ if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2
&& strcmp (entry_name, "MemTotal:") == 0)
{
retval = entry_value;
diff --git a/src/systime.h b/src/systime.h
index fa5e7270cb5..c3bc00c1479 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -121,7 +121,7 @@ EMACS_TIME_SIGN (EMACS_TIME t)
SYSTIME_INLINE int
EMACS_TIME_VALID_P (EMACS_TIME t)
{
- return 0 <= t.tv_nsec;
+ return t.tv_nsec >= 0;
}
/* Convert the double D to the greatest EMACS_TIME not greater than D.
@@ -143,7 +143,7 @@ EMACS_TIME_TO_DOUBLE (EMACS_TIME t)
/* defined in sysdep.c */
extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME);
-extern struct timeval make_timeval (EMACS_TIME);
+extern struct timeval make_timeval (EMACS_TIME) ATTRIBUTE_CONST;
/* defined in keyboard.c */
extern void set_waiting_for_input (EMACS_TIME *);
diff --git a/src/term.c b/src/term.c
index 38706602a02..28b944c6436 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2909,7 +2909,7 @@ dissociate_if_controlling_tty (int fd)
{
/* If tcgetpgrp succeeds, fd is the controlling terminal,
so dissociate it by invoking setsid. */
- if (0 <= tcgetpgrp (fd) && setsid () < 0)
+ if (tcgetpgrp (fd) >= 0 && setsid () < 0)
{
#ifdef TIOCNOTTY
/* setsid failed, presumably because Emacs is already a process
diff --git a/src/termhooks.h b/src/termhooks.h
index 252dbabb6f9..4f3fa9cb47f 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -212,7 +212,7 @@ enum event_kind
, NS_NONKEY_EVENT
#endif
-#if defined (HAVE_INOTIFY) || defined (HAVE_NTGUI)
+#ifdef USE_FILE_NOTIFY
/* File or directory was changed. */
, FILE_NOTIFY_EVENT
#endif
diff --git a/src/textprop.c b/src/textprop.c
index 2b454485370..cc364d5a38c 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -597,8 +597,9 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop,
if (WINDOWP (object))
{
+ CHECK_LIVE_WINDOW (object);
w = XWINDOW (object);
- object = w->buffer;
+ object = w->contents;
}
if (BUFFERP (object))
{
diff --git a/src/thread.c b/src/thread.c
index 7de260ee3c0..1d282c3557a 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -1,5 +1,5 @@
/* Threading code.
- Copyright (C) 2012 Free Software Foundation, Inc.
+ Copyright (C) 2012, 2013 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@@ -507,16 +507,10 @@ thread_select (select_func *func, int max_fds, SELECT_TYPE *rfds,
static void
mark_one_thread (struct thread_state *thread)
{
- struct specbinding *bind;
struct handler *handler;
Lisp_Object tem;
- for (bind = thread->m_specpdl; bind != thread->m_specpdl_ptr; bind++)
- {
- mark_object (bind->symbol);
- mark_object (bind->old_value);
- mark_object (bind->saved_value);
- }
+ mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr);
#if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \
|| GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS)
@@ -541,8 +535,6 @@ mark_one_thread (struct thread_state *thread)
mark_object (handler->handler);
mark_object (handler->var);
}
-
- mark_backtrace (thread->m_backtrace_list);
#endif
if (thread->m_current_buffer)
diff --git a/src/thread.h b/src/thread.h
index 47fa87c77fa..9f0eead4637 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -72,9 +72,6 @@ struct thread_state
/* An address near the top of the stack. */
char *stack_top;
- struct backtrace *m_backtrace_list;
-#define backtrace_list (current_thread->m_backtrace_list)
-
struct catchtag *m_catchlist;
#define catchlist (current_thread->m_catchlist)
diff --git a/src/undo.c b/src/undo.c
index 63edc8e9b8d..d8711882fbf 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -445,12 +445,6 @@ truncate_undo_list (struct buffer *b)
unbind_to (count, Qnil);
}
-static _Noreturn void
-user_error (const char *msg)
-{
- xsignal1 (Quser_error, build_string (msg));
-}
-
void
syms_of_undo (void)
diff --git a/src/unexcw.c b/src/unexcw.c
index af93e158e14..1290c28d245 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "unexec.h"
-#include "w32common.h"
#include <lisp.h>
#include <stdio.h>
@@ -31,6 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define DOTEXE ".exe"
+extern void report_sheap_usage (int);
+
extern int bss_sbrk_did_unexec;
extern int __malloc_initialized;
@@ -73,7 +74,11 @@ read_exe_header (int fd, exe_header_t * exe_header_buffer)
assert (exe_header_buffer->file_header.e_magic == 0x5a4d);
assert (exe_header_buffer->file_header.nt_signature == 0x4550);
+#ifdef __x86_64__
+ assert (exe_header_buffer->file_header.f_magic == 0x8664);
+#else
assert (exe_header_buffer->file_header.f_magic == 0x014c);
+#endif
assert (exe_header_buffer->file_header.f_nscns > 0);
assert (exe_header_buffer->file_header.f_nscns <=
sizeof (exe_header_buffer->section_header) /
@@ -85,7 +90,11 @@ read_exe_header (int fd, exe_header_t * exe_header_buffer)
sizeof (exe_header_buffer->file_optional_header));
assert (ret == sizeof (exe_header_buffer->file_optional_header));
+#ifdef __x86_64__
+ assert (exe_header_buffer->file_optional_header.magic == 0x020b);
+#else
assert (exe_header_buffer->file_optional_header.magic == 0x010b);
+#endif
for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i)
{
@@ -132,7 +141,7 @@ fixup_executable (int fd)
exe_header->file_optional_header.ImageBase +
exe_header->section_header[i].s_paddr;
if (debug_unexcw)
- printf ("%8s start 0x%08x end 0x%08x\n",
+ printf ("%8s start %#lx end %#lx\n",
exe_header->section_header[i].s_name,
start_address, end_address);
if (my_edata >= (char *) start_address
@@ -149,7 +158,7 @@ fixup_executable (int fd)
assert (ret == my_edata - (char *) start_address);
++found_data;
if (debug_unexcw)
- printf (" .data, mem start 0x%08x mem length %d\n",
+ printf (" .data, mem start %#lx mem length %d\n",
start_address, my_edata - (char *) start_address);
if (debug_unexcw)
printf (" .data, file start %d file length %d\n",
@@ -233,7 +242,7 @@ fixup_executable (int fd)
__malloc_initialized = 1;
assert (ret == (my_endbss - (char *) start_address));
if (debug_unexcw)
- printf (" .bss, mem start 0x%08x mem length %d\n",
+ printf (" .bss, mem start %#lx mem length %d\n",
start_address, my_endbss - (char *) start_address);
if (debug_unexcw)
printf (" .bss, file start %d file length %d\n",
diff --git a/src/unexelf.c b/src/unexelf.c
index d3659404f9c..4e50bb86367 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -388,16 +388,19 @@ temacs:
#include <config.h>
#include <unexec.h>
-extern void fatal (const char *msgid, ...);
+extern _Noreturn void fatal (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
-#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <memory.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
-#include <memory.h>
-#include <errno.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <fcntl.h>
+
#if !defined (__NetBSD__) && !defined (__OpenBSD__)
#include <elf.h>
#endif /* not __NetBSD__ and not __OpenBSD__ */
@@ -519,6 +522,18 @@ typedef struct {
# define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
#endif
+/* The code often converts ElfW (Half) values like e_shentsize to ptrdiff_t;
+ check that this doesn't lose information. */
+#include <intprops.h>
+#include <verify.h>
+verify ((! TYPE_SIGNED (ElfW (Half))
+ || PTRDIFF_MIN <= TYPE_MINIMUM (ElfW (Half)))
+ && TYPE_MAXIMUM (ElfW (Half)) <= PTRDIFF_MAX);
+
+#ifdef UNEXELF_DEBUG
+# define DEBUG_LOG(expr) fprintf (stderr, #expr " 0x%jx\n", (uintmax_t) (expr))
+#endif
+
/* Get the address of a particular section or program header entry,
* accounting for the size of the entries.
*/
@@ -546,17 +561,21 @@ typedef struct {
Apr 23, 1996
*/
+static void *
+entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize)
+{
+ char *h = section_h;
+ return h + idx * entsize;
+}
+
#define OLD_SECTION_H(n) \
- (*(ElfW (Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
+ (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shentsize))
#define NEW_SECTION_H(n) \
- (*(ElfW (Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
+ (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shentsize))
#define NEW_PROGRAM_H(n) \
- (*(ElfW (Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
+ (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phentsize))
-#define PATCH_INDEX(n) \
- do { \
- if ((int) (n) >= old_bss_index) \
- (n)++; } while (0)
+#define PATCH_INDEX(n) ((n) += old_bss_index <= (n))
typedef unsigned char byte;
/* Round X up to a multiple of Y. */
@@ -564,7 +583,7 @@ typedef unsigned char byte;
static ElfW (Addr)
round_up (ElfW (Addr) x, ElfW (Addr) y)
{
- int rem = x % y;
+ ElfW (Addr) rem = x % y;
if (rem == 0)
return x;
return x - rem + y;
@@ -575,33 +594,28 @@ round_up (ElfW (Addr) x, ElfW (Addr) y)
about the file we are looking in.
If we don't find the section NAME, that is a fatal error
- if NOERROR is 0; we return -1 if NOERROR is nonzero. */
+ if NOERROR is false; return -1 if NOERROR is true. */
-static int
+static ptrdiff_t
find_section (const char *name, const char *section_names, const char *file_name,
- ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, int noerror)
+ ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h,
+ bool noerror)
{
- int idx;
+ ptrdiff_t idx;
for (idx = 1; idx < old_file_h->e_shnum; idx++)
{
-#ifdef DEBUG
- fprintf (stderr, "Looking for %s - found %s\n", name,
- section_names + OLD_SECTION_H (idx).sh_name);
+ char const *found_name = section_names + OLD_SECTION_H (idx).sh_name;
+#ifdef UNEXELF_DEBUG
+ fprintf (stderr, "Looking for %s - found %s\n", name, found_name);
#endif
- if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name,
- name))
- break;
- }
- if (idx == old_file_h->e_shnum)
- {
- if (noerror)
- return -1;
- else
- fatal ("Can't find %s in %s.\n", name, file_name);
+ if (strcmp (name, found_name) == 0)
+ return idx;
}
- return idx;
+ if (! noerror)
+ fatal ("Can't find %s in %s", name, file_name);
+ return -1;
}
/* ****************************************************************
@@ -616,11 +630,9 @@ find_section (const char *name, const char *section_names, const char *file_name
void
unexec (const char *new_name, const char *old_name)
{
- int new_file, old_file, new_file_size;
-
-#if defined (emacs) || !defined (DEBUG)
+ int new_file, old_file;
+ off_t new_file_size;
void *new_break;
-#endif
/* Pointers to the base of the image of the two files. */
caddr_t old_base, new_base;
@@ -647,14 +659,15 @@ unexec (const char *new_name, const char *old_name)
ElfW (Off) old_bss_offset;
ElfW (Word) new_data2_incr;
- int n, nn;
- int old_bss_index, old_sbss_index, old_plt_index;
- int old_data_index, new_data2_index;
+ ptrdiff_t n, nn;
+ ptrdiff_t old_bss_index, old_sbss_index, old_plt_index;
+ ptrdiff_t old_data_index, new_data2_index;
#if defined _SYSTYPE_SYSV || defined __sgi
- int old_mdebug_index;
+ ptrdiff_t old_mdebug_index;
#endif
struct stat stat_buf;
- int old_file_size;
+ off_t old_file_size;
+ int mask;
/* Open the old file, allocate a buffer of the right size, and read
in the file contents. */
@@ -662,15 +675,15 @@ unexec (const char *new_name, const char *old_name)
old_file = open (old_name, O_RDONLY);
if (old_file < 0)
- fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
+ fatal ("Can't open %s for reading: %s", old_name, strerror (errno));
- if (fstat (old_file, &stat_buf) == -1)
- fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
+ if (fstat (old_file, &stat_buf) != 0)
+ fatal ("Can't fstat (%s): %s", old_name, strerror (errno));
#if MAP_ANON == 0
mmap_fd = open ("/dev/zero", O_RDONLY);
if (mmap_fd < 0)
- fatal ("Can't open /dev/zero for reading: errno %d\n", errno, 0);
+ fatal ("Can't open /dev/zero for reading: %s", strerror (errno));
#endif
/* We cannot use malloc here because that may use sbrk. If it does,
@@ -678,13 +691,15 @@ unexec (const char *new_name, const char *old_name)
extra careful to use the correct value of sbrk(0) after
allocating all buffers in the code below, which we aren't. */
old_file_size = stat_buf.st_size;
+ if (! (0 <= old_file_size && old_file_size <= SIZE_MAX))
+ fatal ("File size out of range");
old_base = mmap (NULL, old_file_size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
if (old_base == MAP_FAILED)
- fatal ("Can't allocate buffer for %s\n", old_name, 0);
+ fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
- if (read (old_file, old_base, stat_buf.st_size) != stat_buf.st_size)
- fatal ("Didn't read all of %s: errno %d\n", old_name, errno);
+ if (read (old_file, old_base, old_file_size) != old_file_size)
+ fatal ("Didn't read all of %s: %s", old_name, strerror (errno));
/* Get pointers to headers & section names */
@@ -755,12 +770,8 @@ unexec (const char *new_name, const char *old_name)
old_data_index = find_section (".data", old_section_names,
old_name, old_file_h, old_section_h, 0);
-#if defined (emacs) || !defined (DEBUG)
new_break = sbrk (0);
new_bss_addr = (ElfW (Addr)) new_break;
-#else
- new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
-#endif
new_data2_addr = old_bss_addr;
new_data2_size = new_bss_addr - old_bss_addr;
new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset
@@ -771,38 +782,38 @@ unexec (const char *new_name, const char *old_name)
section) was unaligned. */
new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset);
-#ifdef DEBUG
- fprintf (stderr, "old_bss_index %d\n", old_bss_index);
- fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
- fprintf (stderr, "old_bss_size %x\n", old_bss_size);
- fprintf (stderr, "old_bss_offset %x\n", old_bss_offset);
- fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
- fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
- fprintf (stderr, "new_data2_size %x\n", new_data2_size);
- fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
- fprintf (stderr, "new_data2_incr %x\n", new_data2_incr);
+#ifdef UNEXELF_DEBUG
+ fprintf (stderr, "old_bss_index %td\n", old_bss_index);
+ DEBUG_LOG (old_bss_addr);
+ DEBUG_LOG (old_bss_size);
+ DEBUG_LOG (old_bss_offset);
+ DEBUG_LOG (new_bss_addr);
+ DEBUG_LOG (new_data2_addr);
+ DEBUG_LOG (new_data2_size);
+ DEBUG_LOG (new_data2_offset);
+ DEBUG_LOG (new_data2_incr);
#endif
- if ((uintptr_t) new_bss_addr < (uintptr_t) old_bss_addr + old_bss_size)
- fatal (".bss shrank when undumping???\n", 0, 0);
+ if (new_bss_addr < old_bss_addr + old_bss_size)
+ fatal (".bss shrank when undumping");
/* Set the output file to the right size. Allocate a buffer to hold
the image of the new file. Set pointers to various interesting
- objects. stat_buf still has old_file data. */
+ objects. */
new_file = open (new_name, O_RDWR | O_CREAT, 0666);
if (new_file < 0)
- fatal ("Can't creat (%s): errno %d\n", new_name, errno);
+ fatal ("Can't creat (%s): %s", new_name, strerror (errno));
- new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_incr;
+ new_file_size = old_file_size + old_file_h->e_shentsize + new_data2_incr;
if (ftruncate (new_file, new_file_size))
- fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
+ fatal ("Can't ftruncate (%s): %s", new_name, strerror (errno));
new_base = mmap (NULL, new_file_size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
if (new_base == MAP_FAILED)
- fatal ("Can't allocate buffer for %s\n", old_name, 0);
+ fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
new_file_h = (ElfW (Ehdr) *) new_base;
new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
@@ -825,11 +836,11 @@ unexec (const char *new_name, const char *old_name)
new_file_h->e_shoff += new_data2_incr;
new_file_h->e_shnum += 1;
-#ifdef DEBUG
- fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
- fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
- fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
- fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
+#ifdef UNEXELF_DEBUG
+ DEBUG_LOG (old_file_h->e_shoff);
+ fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum);
+ DEBUG_LOG (new_file_h->e_shoff);
+ fprintf (stderr, "New section count %td\n", (ptrdiff_t) new_file_h->e_shnum);
#endif
/* Fix up a new program header. Extend the writable data segment so
@@ -839,7 +850,7 @@ unexec (const char *new_name, const char *old_name)
to adjust the offset and address of any segment that is above
data2, just in case we decide to allow this later. */
- for (n = new_file_h->e_phnum - 1; n >= 0; n--)
+ for (n = new_file_h->e_phnum; --n >= 0; )
{
/* Compute maximum of all requirements for alignment of section. */
ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align;
@@ -857,7 +868,7 @@ unexec (const char *new_name, const char *old_name)
> (old_sbss_index == -1
? old_bss_addr
: round_up (old_bss_addr, alignment)))
- fatal ("Program segment above .bss in %s\n", old_name, 0);
+ fatal ("Program segment above .bss in %s", old_name);
if (NEW_PROGRAM_H (n).p_type == PT_LOAD
&& (round_up ((NEW_PROGRAM_H (n)).p_vaddr
@@ -867,7 +878,7 @@ unexec (const char *new_name, const char *old_name)
break;
}
if (n < 0)
- fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
+ fatal ("Couldn't find segment next to .bss in %s", old_name);
/* Make sure that the size includes any padding before the old .bss
section. */
@@ -875,7 +886,7 @@ unexec (const char *new_name, const char *old_name)
NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
#if 0 /* Maybe allow section after data2 - does this ever happen? */
- for (n = new_file_h->e_phnum - 1; n >= 0; n--)
+ for (n = new_file_h->e_phnum; --n >= 0; )
{
if (NEW_PROGRAM_H (n).p_vaddr
&& NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
@@ -894,7 +905,7 @@ unexec (const char *new_name, const char *old_name)
/* Walk through all section headers, insert the new data2 section right
before the new bss section. */
- for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++)
+ for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++)
{
caddr_t src;
/* If it is (s)bss section, insert the new data2 section before it. */
@@ -1076,8 +1087,9 @@ temacs:
if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
&& old_mdebug_index != -1)
{
- int diff = NEW_SECTION_H (nn).sh_offset
- - OLD_SECTION_H (old_mdebug_index).sh_offset;
+ ptrdiff_t new_offset = NEW_SECTION_H (nn).sh_offset;
+ ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset;
+ ptrdiff_t diff = new_offset - old_offset;
HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
if (diff)
@@ -1157,7 +1169,7 @@ temacs:
|| NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
{
ElfW (Shdr) *spt = &NEW_SECTION_H (nn);
- unsigned int num = spt->sh_size / spt->sh_entsize;
+ ptrdiff_t num = spt->sh_size / spt->sh_entsize;
ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset +
new_base);
for (; num--; sym++)
@@ -1173,7 +1185,7 @@ temacs:
}
/* Update the symbol values of _edata and _end. */
- for (n = new_file_h->e_shnum - 1; n; n--)
+ for (n = new_file_h->e_shnum; 0 < --n; )
{
byte *symnames;
ElfW (Sym) *symp, *symendp;
@@ -1233,7 +1245,7 @@ temacs:
/* This loop seeks out relocation sections for the data section, so
that it can undo relocations performed by the runtime linker. */
- for (n = new_file_h->e_shnum - 1; n; n--)
+ for (n = new_file_h->e_shnum; 0 < --n; )
{
ElfW (Shdr) section = NEW_SECTION_H (n);
@@ -1293,8 +1305,8 @@ temacs:
/* Write out new_file, and free the buffers. */
if (write (new_file, new_base, new_file_size) != new_file_size)
- fatal ("Didn't write %d bytes to %s: errno %d\n",
- new_file_size, new_name, errno);
+ fatal ("Didn't write %lu bytes to %s: %s",
+ (unsigned long) new_file_size, new_name, strerror (errno));
munmap (old_base, old_file_size);
munmap (new_base, new_file_size);
@@ -1304,18 +1316,18 @@ temacs:
close (mmap_fd);
#endif
- if (close (old_file))
- fatal ("Can't close (%s): errno %d\n", old_name, errno);
+ if (close (old_file) != 0)
+ fatal ("Can't close (%s): %s", old_name, strerror (errno));
- if (close (new_file))
- fatal ("Can't close (%s): errno %d\n", new_name, errno);
+ if (close (new_file) != 0)
+ fatal ("Can't close (%s): %s", new_name, strerror (errno));
- if (stat (new_name, &stat_buf) == -1)
- fatal ("Can't stat (%s): errno %d\n", new_name, errno);
+ if (stat (new_name, &stat_buf) != 0)
+ fatal ("Can't stat (%s): %s", new_name, strerror (errno));
- n = umask (777);
- umask (n);
- stat_buf.st_mode |= 0111 & ~n;
- if (chmod (new_name, stat_buf.st_mode) == -1)
- fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
+ mask = umask (777);
+ umask (mask);
+ stat_buf.st_mode |= 0111 & ~mask;
+ if (chmod (new_name, stat_buf.st_mode) != 0)
+ fatal ("Can't chmod (%s): %s", new_name, strerror (errno));
}
diff --git a/src/unexw32.c b/src/unexw32.c
index e8b553a87d3..a01ac799592 100644
--- a/src/unexw32.c
+++ b/src/unexw32.c
@@ -159,6 +159,14 @@ open_output_file (file_data *p_file, char *filename, unsigned long size)
HANDLE file_mapping;
void *file_base;
+ /* We delete any existing FILENAME because loadup.el will create a
+ hard link to it under the name emacs-XX.YY.ZZ.nn.exe. Evidently,
+ overwriting a file on Unix breaks any hard links to it, but that
+ doesn't happen on Windows. If we don't delete the file before
+ creating it, all the emacs-XX.YY.ZZ.nn.exe end up being hard
+ links to the same file, which defeats the purpose of these hard
+ links: being able to run previous builds. */
+ DeleteFile (filename);
file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (file == INVALID_HANDLE_VALUE)
diff --git a/src/w32.c b/src/w32.c
index 647faf94ef1..7a39a617ee3 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -29,10 +29,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <ctype.h>
#include <signal.h>
#include <sys/file.h>
+#include <time.h> /* must be before nt/inc/sys/time.h, for MinGW64 */
#include <sys/time.h>
#include <sys/utime.h>
#include <math.h>
-#include <time.h>
/* must include CRT headers *before* config.h */
@@ -65,11 +65,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#undef localtime
#include "lisp.h"
+#include "epaths.h" /* for SHELL */
#include <pwd.h>
#include <grp.h>
-#ifdef __GNUC__
+/* MinGW64 (_W64) defines these in its _mingw.h. */
+#if defined(__GNUC__) && !defined(_W64)
#define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#endif
@@ -96,6 +98,7 @@ typedef struct _MEMORY_STATUS_EX {
#ifndef _MSC_VER
#include <w32api.h>
#endif
+#if _WIN32_WINNT < 0x0500
#if !defined (__MINGW32__) || __W32API_MAJOR_VERSION < 3 || (__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION < 15)
/* This either is not in psapi.h or guarded by higher value of
_WIN32_WINNT than what we use. w32api supplied with MinGW 3.15
@@ -114,6 +117,7 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
SIZE_T PrivateUsage;
} PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX;
#endif
+#endif
#include <winioctl.h>
#include <aclapi.h>
@@ -127,11 +131,11 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
#define SDDL_REVISION_1 1
#endif /* SDDL_REVISION_1 */
-#ifdef _MSC_VER
-/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the
- associated macros, except on ntifs.h, which cannot be included
- because it triggers conflicts with other Windows API headers. So
- we define it here by hand. */
+#if defined(_MSC_VER) || defined(_W64)
+/* MSVC and MinGW64 don't provide the definition of
+ REPARSE_DATA_BUFFER and the associated macros, except on ntifs.h,
+ which cannot be included because it triggers conflicts with other
+ Windows API headers. So we define it here by hand. */
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
@@ -171,9 +175,12 @@ typedef struct _REPARSE_DATA_BUFFER {
#ifndef CTL_CODE
#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m))
#endif
+/* MinGW64 defines FSCTL_GET_REPARSE_POINT on winioctl.h. */
+#ifndef FSCTL_GET_REPARSE_POINT
#define FSCTL_GET_REPARSE_POINT \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
+#endif
/* TCP connection support. */
#include <sys/socket.h>
@@ -2012,7 +2019,7 @@ init_environment (char ** argv)
{"PRELOAD_WINSOCK", NULL},
{"emacs_dir", "C:/emacs"},
{"EMACSLOADPATH", NULL},
- {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"},
+ {"SHELL", "cmdproxy.exe"}, /* perhaps it is somewhere on PATH */
{"EMACSDATA", NULL},
{"EMACSPATH", NULL},
{"INFOPATH", NULL},
@@ -2088,9 +2095,12 @@ init_environment (char ** argv)
emacs_abort ();
*p = 0;
- if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0)
+ if ((p = _mbsrchr (modname, '\\'))
+ /* From bin means installed Emacs, from src means uninstalled. */
+ && (xstrcasecmp (p, "\\bin") == 0 || xstrcasecmp (p, "\\src") == 0))
{
char buf[SET_ENV_BUF_SIZE];
+ int within_build_tree = xstrcasecmp (p, "\\src") == 0;
*p = 0;
for (p = modname; *p; p = CharNext (p))
@@ -2098,6 +2108,15 @@ init_environment (char ** argv)
_snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
_putenv (strdup (buf));
+ /* If we are running from the Posix-like build tree, define
+ SHELL to point to our own cmdproxy. The loop below will
+ then disregard PATH_EXEC and the default value. */
+ if (within_build_tree)
+ {
+ _snprintf (buf, sizeof (buf) - 1,
+ "SHELL=%s/nt/cmdproxy.exe", modname);
+ _putenv (strdup (buf));
+ }
}
/* Handle running emacs from the build directory: src/oo-spd/i386/ */
@@ -2133,16 +2152,60 @@ init_environment (char ** argv)
if (!getenv (env_vars[i].name))
{
int dont_free = 0;
+ char bufc[SET_ENV_BUF_SIZE];
if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL
/* Also ignore empty environment variables. */
|| *lpval == 0)
{
xfree (lpval);
- lpval = env_vars[i].def_value;
- dwType = REG_EXPAND_SZ;
dont_free = 1;
- if (!strcmp (env_vars[i].name, "HOME") && !appdata)
+ if (strcmp (env_vars[i].name, "SHELL") == 0)
+ {
+ /* Look for cmdproxy.exe in every directory in
+ PATH_EXEC. FIXME: This does not find cmdproxy
+ in nt/ when we run uninstalled. */
+ char fname[MAX_PATH];
+ const char *pstart = PATH_EXEC, *pend;
+
+ do {
+ pend = _mbschr (pstart, ';');
+ if (!pend)
+ pend = pstart + strlen (pstart);
+ /* Be defensive against series of ;;; characters. */
+ if (pend > pstart)
+ {
+ strncpy (fname, pstart, pend - pstart);
+ fname[pend - pstart] = '/';
+ strcpy (&fname[pend - pstart + 1], "cmdproxy.exe");
+ ExpandEnvironmentStrings ((LPSTR) fname, bufc,
+ sizeof (bufc));
+ if (check_existing (bufc))
+ {
+ lpval = bufc;
+ dwType = REG_SZ;
+ break;
+ }
+ }
+ if (*pend)
+ pstart = pend + 1;
+ else
+ pstart = pend;
+ if (!*pstart)
+ {
+ /* If not found in any directory, use the
+ default as the last resort. */
+ lpval = env_vars[i].def_value;
+ dwType = REG_EXPAND_SZ;
+ }
+ } while (*pstart);
+ }
+ else
+ {
+ lpval = env_vars[i].def_value;
+ dwType = REG_EXPAND_SZ;
+ }
+ if (strcmp (env_vars[i].name, "HOME") == 0 && !appdata)
Vdelayed_warnings_list
= Fcons (listn (CONSTYPE_HEAP, 2,
intern ("initialization"),
@@ -2388,8 +2451,8 @@ get_emacs_configuration_options (void)
#include <sys/timeb.h>
/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
-void
-gettimeofday (struct timeval *tv, struct timezone *tz)
+int
+gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz)
{
struct _timeb tb;
_ftime (&tb);
@@ -2407,6 +2470,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
tz->tz_dsttime = tb.dstflag; /* type of dst correction */
}
+ return 0;
}
/* Emulate fdutimens. */
diff --git a/src/w32fns.c b/src/w32fns.c
index cef2009d7a1..d7ac0dd1a6c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -95,10 +95,6 @@ static HWND hourglass_hwnd = NULL;
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif
-/* Nonzero if using Windows. */
-
-static int w32_in_use;
-
Lisp_Object Qsuppress_icon;
Lisp_Object Qundefined_color;
Lisp_Object Qcancel_timer;
@@ -161,6 +157,8 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
typedef BOOL (WINAPI * GetMonitorInfo_Proc)
(IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
+typedef HMONITOR (WINAPI * MonitorFromWindow_Proc)
+ (IN HWND hwnd, IN DWORD dwFlags);
TrackMouseEvent_Proc track_mouse_event_fn = NULL;
ImmGetCompositionString_Proc get_composition_string_fn = NULL;
@@ -169,6 +167,7 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL;
ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
MonitorFromPoint_Proc monitor_from_point_fn = NULL;
GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+MonitorFromWindow_Proc monitor_from_window_fn = NULL;
#ifdef NTGUI_UNICODE
#define unicode_append_menu AppendMenuW
@@ -239,37 +238,6 @@ HINSTANCE hinst = NULL;
static unsigned int sound_type = 0xFFFFFFFF;
#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
-
-/* Error if we are not connected to MS-Windows. */
-void
-check_w32 (void)
-{
- if (! w32_in_use)
- error ("MS-Windows not in use or not initialized");
-}
-
-/* Nonzero if we can use mouse menus.
- You should not call this unless HAVE_MENUS is defined. */
-
-int
-have_menus_p (void)
-{
- return w32_in_use;
-}
-
-/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
- and checking validity for W32. */
-
-FRAME_PTR
-check_x_frame (Lisp_Object frame)
-{
- struct frame *f = decode_live_frame (frame);
-
- if (! FRAME_W32_P (f))
- error ("Non-W32 frame used");
- return f;
-}
-
/* Let the user specify a display with a frame.
nil stands for the selected frame--or, if that is not a w32 frame,
the first display on the list. */
@@ -371,6 +339,66 @@ x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
*yptr = rect.top;
}
+/* Returns the window rectangle appropriate for the given fullscreen mode.
+ The normal rect parameter was the window's rectangle prior to entering
+ fullscreen mode. If multiple monitor support is available, the nearest
+ monitor to the window is chosen. */
+
+void
+w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect)
+{
+ struct MONITOR_INFO mi = { sizeof(mi) };
+ if (monitor_from_window_fn && get_monitor_info_fn)
+ {
+ HMONITOR monitor =
+ monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
+ get_monitor_info_fn (monitor, &mi);
+ }
+ else
+ {
+ mi.rcMonitor.left = 0;
+ mi.rcMonitor.top = 0;
+ mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN);
+ mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN);
+ mi.rcWork.left = 0;
+ mi.rcWork.top = 0;
+ mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED);
+ mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED);
+ }
+
+ switch (fsmode)
+ {
+ case FULLSCREEN_BOTH:
+ rect->left = mi.rcMonitor.left;
+ rect->top = mi.rcMonitor.top;
+ rect->right = mi.rcMonitor.right;
+ rect->bottom = mi.rcMonitor.bottom;
+ break;
+ case FULLSCREEN_MAXIMIZED:
+ rect->left = mi.rcWork.left;
+ rect->top = mi.rcWork.top;
+ rect->right = mi.rcWork.right;
+ rect->bottom = mi.rcWork.bottom;
+ break;
+ case FULLSCREEN_WIDTH:
+ rect->left = mi.rcWork.left;
+ rect->top = normal.top;
+ rect->right = mi.rcWork.right;
+ rect->bottom = normal.bottom;
+ break;
+ case FULLSCREEN_HEIGHT:
+ rect->left = normal.left;
+ rect->top = mi.rcWork.top;
+ rect->right = normal.right;
+ rect->bottom = mi.rcWork.bottom;
+ break;
+ case FULLSCREEN_NONE:
+ default:
+ *rect = normal;
+ break;
+ }
+}
+
DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
@@ -3155,8 +3183,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
form.ptCurrentPos.y = w32_system_caret_y;
form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
- form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
- + WINDOW_HEADER_LINE_HEIGHT (w));
+ form.rcArea.top = WINDOW_TOP_EDGE_Y (w);
+ if (BUFFERP (w->contents))
+ form.rcArea.top += WINDOW_HEADER_LINE_HEIGHT (w);
form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
- WINDOW_RIGHT_MARGIN_WIDTH (w)
- WINDOW_RIGHT_FRINGE_WIDTH (w));
@@ -3708,6 +3737,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
/* Don't restrict the sizing of tip frames. */
if (hwnd == tip_window)
return 0;
+
+ /* Don't restrict the sizing of fullscreened frames, allowing them to be
+ flush with the sides of the screen. */
+ f = x_window_to_frame (dpyinfo, hwnd);
+ if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
+ return 0;
+
{
WINDOWPLACEMENT wp;
LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
@@ -4353,9 +4389,6 @@ This function is an internal primitive--use `make-frame' instead. */)
specbind (Qx_resource_name, name);
}
- f->resx = dpyinfo->resx;
- f->resy = dpyinfo->resy;
-
if (uniscribe_available)
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
@@ -4552,7 +4585,7 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
doc: /* Give FRAME input focus, raising to foreground if necessary. */)
(Lisp_Object frame)
{
- x_focus_on_frame (check_x_frame (frame));
+ x_focus_on_frame (decode_window_system_frame (frame));
return Qnil;
}
@@ -4563,7 +4596,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -4578,7 +4611,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -4896,7 +4929,6 @@ x_display_info_for_name (Lisp_Object name)
if (dpyinfo == 0)
error ("Cannot connect to server %s", SDATA (name));
- w32_in_use = 1;
XSETFASTINT (Vwindow_system_version, w32_major_version);
return dpyinfo;
@@ -4926,7 +4958,7 @@ terminate Emacs if we can't open the connection.
/* If initialization has already been done, return now to avoid
overwriting critical parts of one_w32_display_info. */
- if (w32_in_use)
+ if (window_system_available (NULL))
return Qnil;
if (! NILP (xrm_string))
@@ -4995,8 +5027,6 @@ terminate Emacs if we can't open the connection.
error ("Cannot connect to server %s", SDATA (display));
}
- w32_in_use = 1;
-
XSETFASTINT (Vwindow_system_version, w32_major_version);
return Qnil;
}
@@ -5080,7 +5110,7 @@ FRAME. Default is to change on the edit X window. */)
(Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
CHECK_STRING (prop);
@@ -5106,7 +5136,7 @@ DEFUN ("x-delete-window-property", Fx_delete_window_property,
FRAME nil or omitted means use the selected frame. Value is PROP. */)
(Lisp_Object prop, Lisp_Object frame)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
CHECK_STRING (prop);
@@ -5142,7 +5172,7 @@ no value of TYPE (always string in the MS Windows case). */)
(Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
int rc;
Lisp_Object prop_value = Qnil;
@@ -5343,8 +5373,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
Lisp_Object buffer;
struct buffer *old_buffer;
- check_w32 ();
-
/* Use this general default value to start with until we know if
this frame has a specified name. */
Vx_resource_name = Vinvocation_name;
@@ -5420,9 +5448,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
specbind (Qx_resource_name, name);
}
- f->resx = dpyinfo->resx;
- f->resy = dpyinfo->resy;
-
if (uniscribe_available)
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
@@ -5691,7 +5716,7 @@ Text larger than the specified size is clipped. */)
GCPRO4 (string, parms, frame, timeout);
CHECK_STRING (string);
- f = check_x_frame (frame);
+ f = decode_window_system_frame (frame);
if (NILP (timeout))
timeout = make_number (5);
else
@@ -5780,8 +5805,8 @@ Text larger than the specified size is clipped. */)
/* Set up the frame's root window. */
w = XWINDOW (FRAME_ROOT_WINDOW (f));
- wset_left_col (w, make_number (0));
- wset_top_line (w, make_number (0));
+ w->left_col = 0;
+ w->top_line = 0;
if (CONSP (Vx_max_tooltip_size)
&& INTEGERP (XCAR (Vx_max_tooltip_size))
@@ -5789,22 +5814,22 @@ Text larger than the specified size is clipped. */)
&& INTEGERP (XCDR (Vx_max_tooltip_size))
&& XINT (XCDR (Vx_max_tooltip_size)) > 0)
{
- wset_total_cols (w, XCAR (Vx_max_tooltip_size));
- wset_total_lines (w, XCDR (Vx_max_tooltip_size));
+ w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
+ w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
}
else
{
- wset_total_cols (w, make_number (80));
- wset_total_lines (w, make_number (40));
+ w->total_cols = 80;
+ w->total_lines = 40;
}
- FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
+ FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w);
adjust_glyphs (f);
w->pseudo_window_p = 1;
/* Display the tooltip text in a temporary buffer. */
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
+ set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
bset_truncate_lines (current_buffer, Qnil);
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
@@ -5866,7 +5891,7 @@ Text larger than the specified size is clipped. */)
/* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
not in pixels. */
width /= WINDOW_FRAME_COLUMN_WIDTH (w);
- wset_total_cols (w, make_number (width));
+ w->total_cols = width;
FRAME_TOTAL_COLS (f) = width;
adjust_glyphs (f);
w->pseudo_window_p = 1;
@@ -6342,7 +6367,7 @@ screen saver if defined.
If optional parameter FRAME is not specified, use selected frame. */)
(Lisp_Object command, Lisp_Object frame)
{
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
CHECK_NUMBER (command);
@@ -7300,8 +7325,6 @@ void
syms_of_w32fns (void)
{
globals_of_w32fns ();
- /* This is zero if not using MS-Windows. */
- w32_in_use = 0;
track_mouse_window = NULL;
w32_visible_system_caret_hwnd = NULL;
@@ -7623,8 +7646,6 @@ only be necessary if the default setting causes problems. */);
defsubr (&Sdefault_printer_name);
defsubr (&Sset_message_beep);
- check_window_system_func = check_w32;
-
hourglass_hwnd = NULL;
defsubr (&Sx_show_tip);
@@ -7667,6 +7688,8 @@ globals_of_w32fns (void)
GetProcAddress (user32_lib, "MonitorFromPoint");
get_monitor_info_fn = (GetMonitorInfo_Proc)
GetProcAddress (user32_lib, "GetMonitorInfoA");
+ monitor_from_window_fn = (MonitorFromWindow_Proc)
+ GetProcAddress (user32_lib, "MonitorFromWindow");
{
HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
@@ -7765,6 +7788,9 @@ emacs_abort (void)
#endif
if (stderr_fd >= 0)
write (stderr_fd, "\r\nBacktrace:\r\n", 14);
+#ifdef CYGWIN
+#define _open open
+#endif
errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
if (errfile_fd >= 0)
{
diff --git a/src/w32font.c b/src/w32font.c
index 5c5a15cc340..105daa06365 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -1967,7 +1967,7 @@ static void
fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec)
{
Lisp_Object tmp, extra;
- int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
+ int dpi = FRAME_RES_Y (f);
tmp = AREF (font_spec, FONT_DPI_INDEX);
if (INTEGERP (tmp))
@@ -2467,7 +2467,7 @@ If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts
in the font selection dialog. */)
(Lisp_Object frame, Lisp_Object exclude_proportional)
{
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
CHOOSEFONT cf;
LOGFONT lf;
TEXTMETRIC tm;
diff --git a/src/w32menu.c b/src/w32menu.c
index 03904cf20b8..346402b7c6b 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -140,8 +140,6 @@ otherwise it is "Question". */)
FRAME_PTR f = NULL;
Lisp_Object window;
- check_w32 ();
-
/* Decode the first argument: find the window or frame to use. */
if (EQ (position, Qt)
|| (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
@@ -194,6 +192,8 @@ otherwise it is "Question". */)
but I don't want to make one now. */
CHECK_WINDOW (window);
+ check_window_system (f);
+
#ifndef HAVE_DIALOGS
{
@@ -396,7 +396,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
if (! menubar_widget)
previous_menu_items_used = 0;
- buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
+ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
specbind (Qinhibit_quit, Qt);
/* Don't let the debugger step into this code
because it is not reentrant. */
diff --git a/src/w32term.c b/src/w32term.c
index 989ceb0f847..58b1d3ca308 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -109,9 +109,10 @@ struct w32_display_info *x_display_list;
Lisp_Object w32_display_name_list;
-#if _WIN32_WINNT < 0x0500
+#if _WIN32_WINNT < 0x0500 && !defined(_W64)
/* Pre Windows 2000, this was not available, but define it here so
- that Emacs compiled on such a platform will run on newer versions. */
+ that Emacs compiled on such a platform will run on newer versions.
+ MinGW64 (_W64) defines these unconditionally, so avoid redefining. */
typedef struct tagWCRANGE
{
@@ -5660,79 +5661,42 @@ x_check_fullscreen (struct frame *f)
static void
w32fullscreen_hook (FRAME_PTR f)
{
- static int normal_width, normal_height;
-
if (FRAME_VISIBLE_P (f))
{
- int width, height, top_pos, left_pos, pixel_height, pixel_width;
- int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f);
- RECT workarea_rect;
+ HWND hwnd = FRAME_W32_WINDOW(f);
+ DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
+ RECT rect;
- block_input ();
- if (normal_height <= 0)
- normal_height = cur_h;
- if (normal_width <= 0)
- normal_width = cur_w;
- x_real_positions (f, &f->left_pos, &f->top_pos);
- x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos);
+ block_input();
+ f->want_fullscreen &= ~FULLSCREEN_WAIT;
- SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
- pixel_height = workarea_rect.bottom - workarea_rect.top;
- pixel_width = workarea_rect.right - workarea_rect.left;
+ if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE)
+ GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
- switch (f->want_fullscreen)
- {
- case FULLSCREEN_BOTH:
- PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
- break;
- case FULLSCREEN_MAXIMIZED:
- height =
- FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
- - XINT (Ftool_bar_lines_needed (selected_frame))
- + (NILP (Vmenu_bar_mode) ? 1 : 0);
- width =
- FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width)
- - FRAME_SCROLL_BAR_COLS (f);
- left_pos = workarea_rect.left;
- top_pos = workarea_rect.top;
- break;
- case FULLSCREEN_WIDTH:
- width =
- FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width)
- - FRAME_SCROLL_BAR_COLS (f);
- if (normal_height > 0)
- height = normal_height;
- left_pos = workarea_rect.left;
- break;
- case FULLSCREEN_HEIGHT:
- height =
- FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
- - XINT (Ftool_bar_lines_needed (selected_frame))
- + (NILP (Vmenu_bar_mode) ? 1 : 0);
- if (normal_width > 0)
- width = normal_width;
- top_pos = workarea_rect.top;
- break;
- case FULLSCREEN_NONE:
- if (normal_height > 0)
- height = normal_height;
- else
- normal_height = height;
- if (normal_width > 0)
- width = normal_width;
- else
- normal_width = width;
- /* FIXME: Should restore the original position of the frame. */
- top_pos = left_pos = 0;
- break;
- }
+ if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH)
+ {
+ SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW);
+ SetWindowPos (hwnd, NULL, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+
+ w32_fullscreen_rect (hwnd, f->want_fullscreen,
+ FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
+ FRAME_PREV_FSMODE (f) = f->want_fullscreen;
+ if (f->want_fullscreen == FULLSCREEN_BOTH)
+ {
+ SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
+ SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+ else
+ {
+ SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top, 0);
+ }
- if (cur_w != width || cur_h != height)
- {
- x_set_offset (f, left_pos, top_pos, 1);
- x_set_window_size (f, 1, width, height);
- do_pending_window_change (0);
- }
f->want_fullscreen = FULLSCREEN_NONE;
unblock_input ();
}
@@ -6651,7 +6615,7 @@ w32_initialize (void)
Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
{
- DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
+ DWORD input_locale_id = ((DWORD_PTR) GetKeyboardLayout (0) & 0xffffffff);
w32_keyboard_codepage =
codepage_for_locale ((LCID) (input_locale_id & 0xffff));
}
diff --git a/src/w32term.h b/src/w32term.h
index a31c5de193d..9c27c09d03d 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -71,6 +71,8 @@ struct w32_palette_entry {
};
extern void w32_regenerate_palette (struct frame *f);
+extern void w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal,
+ RECT *rect);
/* For each display (currently only one on w32), we have a structure that
@@ -203,7 +205,6 @@ extern void x_focus_on_frame (struct frame *f);
extern struct w32_display_info *w32_term_init (Lisp_Object,
char *, char *);
-extern void check_w32 (void);
extern int w32_defined_color (FRAME_PTR f, const char *color,
XColor *color_def, int alloc);
extern void x_set_window_size (struct frame *f, int change_grav,
@@ -359,6 +360,12 @@ struct w32_output
/* The background for which the above relief GCs were set up.
They are changed only when a different background is involved. */
unsigned long relief_background;
+
+ /* Frame geometry and full-screen mode before it was resized by
+ specifying the 'fullscreen' frame parameter. Used to restore the
+ geometry when 'fullscreen' is reset to nil. */
+ WINDOWPLACEMENT normal_placement;
+ int prev_fsmode;
};
extern struct w32_output w32term_display;
@@ -390,6 +397,10 @@ extern struct w32_output w32term_display;
#define FRAME_SMALLEST_FONT_HEIGHT(F) \
FRAME_W32_DISPLAY_INFO(F)->smallest_font_height
+
+#define FRAME_NORMAL_PLACEMENT(F) ((F)->output_data.w32->normal_placement)
+#define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode)
+
/* W32-specific scroll bar stuff. */
@@ -727,7 +738,6 @@ struct image;
struct face;
XGCValues *XCreateGC (void *, Window, unsigned long, XGCValues *);
-struct frame * check_x_frame (Lisp_Object);
typedef DWORD (WINAPI * ClipboardSequence_Proc) (void);
typedef BOOL (WINAPI * AppendMenuW_Proc) (
diff --git a/src/window.c b/src/window.c
index 4109b752d8e..33bf70b75c8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -84,8 +84,8 @@ static int foreach_window_1 (struct window *,
int (* fn) (struct window *, void *),
void *);
static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
-static int window_resize_check (struct window *, int);
-static void window_resize_apply (struct window *, int);
+static int window_resize_check (struct window *, bool);
+static void window_resize_apply (struct window *, bool);
static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
static void select_window_1 (Lisp_Object, bool);
@@ -147,11 +147,6 @@ wset_display_table (struct window *w, Lisp_Object val)
w->display_table = val;
}
static void
-wset_hchild (struct window *w, Lisp_Object val)
-{
- w->hchild = val;
-}
-static void
wset_left_fringe_width (struct window *w, Lisp_Object val)
{
w->left_fringe_width = val;
@@ -217,11 +212,6 @@ wset_temslot (struct window *w, Lisp_Object val)
w->temslot = val;
}
static void
-wset_vchild (struct window *w, Lisp_Object val)
-{
- w->vchild = val;
-}
-static void
wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
{
w->vertical_scroll_bar_type = val;
@@ -231,6 +221,18 @@ wset_window_parameters (struct window *w, Lisp_Object val)
{
w->window_parameters = val;
}
+static void
+wset_combination (struct window *w, bool horflag, Lisp_Object val)
+{
+ /* Since leaf windows never becomes non-leaf, there should
+ be no buffer and markers in start and pointm fields of W. */
+ eassert (!BUFFERP (w->contents) && NILP (w->start) && NILP (w->pointm));
+ w->contents = val;
+ /* When an internal window is deleted and VAL is nil, HORFLAG
+ is meaningless. */
+ if (!NILP (val))
+ w->horizontal = horflag;
+}
struct window *
decode_live_window (register Lisp_Object window)
@@ -275,9 +277,9 @@ static void
adjust_window_count (struct window *w, int arg)
{
eassert (eabs (arg) == 1);
- if (BUFFERP (w->buffer))
+ if (BUFFERP (w->contents))
{
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
if (b->base_buffer)
b = b->base_buffer;
@@ -296,7 +298,11 @@ void
wset_buffer (struct window *w, Lisp_Object val)
{
adjust_window_count (w, -1);
- w->buffer = val;
+ if (BUFFERP (val))
+ /* Make sure that we do not assign the buffer
+ to an internal window. */
+ eassert (MARKERP (w->start) && MARKERP (w->pointm));
+ w->contents = val;
adjust_window_count (w, 1);
}
@@ -394,15 +400,8 @@ the first window of that frame. */)
window = XFRAME (frame_or_window)->root_window;
}
- while (NILP (XWINDOW (window)->buffer))
- {
- if (! NILP (XWINDOW (window)->hchild))
- window = XWINDOW (window)->hchild;
- else if (! NILP (XWINDOW (window)->vchild))
- window = XWINDOW (window)->vchild;
- else
- emacs_abort ();
- }
+ while (WINDOWP (XWINDOW (window)->contents))
+ window = XWINDOW (window)->contents;
return window;
}
@@ -486,17 +485,14 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
w = XWINDOW (window);
w->frozen_window_start_p = 0;
- if (NILP (norecord))
- {
- w->use_time = ++window_select_count;
- record_buffer (w->buffer);
- }
-
/* Make the selected window's buffer current. */
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
if (EQ (window, selected_window) && !inhibit_point_swap)
- return window;
+ /* `switch-to-buffer' uses (select-window (selected-window)) as a "clever"
+ way to call record_buffer from Elisp, so it's important that we call
+ record_buffer before returning here. */
+ goto record_and_return;
sf = SELECTED_FRAME ();
if (XFRAME (WINDOW_FRAME (w)) != sf)
@@ -515,9 +511,19 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
fset_selected_window (sf, window);
select_window_1 (window, inhibit_point_swap);
-
- bset_last_selected_window (XBUFFER (w->buffer), window);
+ bset_last_selected_window (XBUFFER (w->contents), window);
windows_or_buffers_changed++;
+
+ record_and_return:
+ /* record_buffer can run QUIT, so make sure it is run only after we have
+ re-established the invariant between selected_window and selected_frame,
+ otherwise the temporary broken invariant might "escape" (bug#14161). */
+ if (NILP (norecord))
+ {
+ w->use_time = ++window_select_count;
+ record_buffer (w->contents);
+ }
+
return window;
}
@@ -533,10 +539,10 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
if (!inhibit_point_swap)
{
struct window *ow = XWINDOW (selected_window);
- if (! NILP (ow->buffer))
- set_marker_both (ow->pointm, ow->buffer,
- BUF_PT (XBUFFER (ow->buffer)),
- BUF_PT_BYTE (XBUFFER (ow->buffer)));
+ if (BUFFERP (ow->contents))
+ set_marker_both (ow->pointm, ow->contents,
+ BUF_PT (XBUFFER (ow->contents)),
+ BUF_PT_BYTE (XBUFFER (ow->contents)));
}
selected_window = window;
@@ -581,7 +587,8 @@ If WINDOW is omitted or nil, it defaults to the selected window.
Return nil for an internal window or a deleted window. */)
(Lisp_Object window)
{
- return decode_any_window (window)->buffer;
+ struct window *w = decode_any_window (window);
+ return WINDOW_LEAF_P (w) ? w->contents : Qnil;
}
DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
@@ -601,7 +608,8 @@ Return nil if WINDOW is an internal window whose children form a
horizontal combination. */)
(Lisp_Object window)
{
- return decode_valid_window (window)->vchild;
+ struct window *w = decode_valid_window (window);
+ return WINDOW_VERTICAL_COMBINATION_P (w) ? w->contents : Qnil;
}
DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
@@ -612,7 +620,8 @@ Return nil if WINDOW is an internal window whose children form a
vertical combination. */)
(Lisp_Object window)
{
- return decode_valid_window (window)->hchild;
+ struct window *w = decode_valid_window (window);
+ return WINDOW_HORIZONTAL_COMBINATION_P (w) ? w->contents : Qnil;
}
DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0,
@@ -635,30 +644,37 @@ Return nil if WINDOW has no previous sibling. */)
DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
doc: /* Return combination limit of window WINDOW.
+WINDOW must be a valid window used in horizontal or vertical combination.
If the return value is nil, child windows of WINDOW can be recombined with
WINDOW's siblings. A return value of t means that child windows of
-WINDOW are never \(re-)combined with WINDOW's siblings.
-
-WINDOW must be a valid window. The return value is meaningful for
-internal windows only. */)
+WINDOW are never \(re-)combined with WINDOW's siblings. */)
(Lisp_Object window)
{
+ struct window *w;
+
CHECK_VALID_WINDOW (window);
- return XWINDOW (window)->combination_limit;
+ w = XWINDOW (window);
+ if (WINDOW_LEAF_P (w))
+ error ("Combination limit is meaningful for internal windows only");
+ return w->combination_limit;
}
DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
+WINDOW must be a valid window used in horizontal or vertical combination.
If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
siblings. LIMIT t means that child windows of WINDOW are never
\(re-)combined with WINDOW's siblings. Other values are reserved for
-future use.
-
-WINDOW must be a valid window. Setting the combination limit is
-meaningful for internal windows only. */)
+future use. */)
(Lisp_Object window, Lisp_Object limit)
{
- wset_combination_limit (decode_valid_window (window), limit);
+ struct window *w;
+
+ CHECK_VALID_WINDOW (window);
+ w = XWINDOW (window);
+ if (WINDOW_LEAF_P (w))
+ error ("Combination limit is meaningful for internal windows only");
+ wset_combination_limit (w, limit);
return limit;
}
@@ -685,7 +701,7 @@ On a graphical display, this total height is reported as an
integer multiple of the default character height. */)
(Lisp_Object window)
{
- return decode_valid_window (window)->total_lines;
+ return make_number (decode_valid_window (window)->total_lines);
}
DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0,
@@ -700,7 +716,7 @@ On a graphical display, this total width is reported as an
integer multiple of the default character width. */)
(Lisp_Object window)
{
- return decode_valid_window (window)->total_cols;
+ return make_number (decode_valid_window (window)->total_cols);
}
DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
@@ -739,7 +755,7 @@ value is 0 if there is no window to the left of WINDOW.
WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_valid_window (window)->left_col;
+ return make_number (decode_valid_window (window)->left_col);
}
DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
@@ -751,7 +767,7 @@ there is no window above WINDOW.
WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_valid_window (window)->top_line;
+ return make_number (decode_valid_window (window)->top_line);
}
/* Return the number of lines of W's body. Don't count any mode or
@@ -760,7 +776,7 @@ WINDOW must be a valid window and defaults to the selected one. */)
static int
window_body_lines (struct window *w)
{
- int height = XFASTINT (w->total_lines);
+ int height = w->total_lines;
if (!MINI_WINDOW_P (w))
{
@@ -782,7 +798,7 @@ int
window_body_cols (struct window *w)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- int width = XINT (w->total_cols);
+ int width = w->total_cols;
if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
/* Scroll bars occupy a few columns. */
@@ -853,7 +869,7 @@ set_window_hscroll (struct window *w, EMACS_INT hscroll)
/* Prevent redisplay shortcuts when changing the hscroll. */
if (w->hscroll != new_hscroll)
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
w->hscroll = new_hscroll;
return make_number (new_hscroll);
@@ -1368,7 +1384,7 @@ check_window_containing (struct window *w, void *user_data)
Lisp_Object
window_from_coordinates (struct frame *f, int x, int y,
- enum window_part *part, int tool_bar_p)
+ enum window_part *part, bool tool_bar_p)
{
Lisp_Object window;
struct check_window_data cw;
@@ -1434,7 +1450,7 @@ correct to return the top-level value of `point', outside of any
register struct window *w = decode_live_window (window);
if (w == XWINDOW (selected_window))
- return make_number (BUF_PT (XBUFFER (w->buffer)));
+ return make_number (BUF_PT (XBUFFER (w->contents)));
else
return Fmarker_position (w->pointm);
}
@@ -1476,12 +1492,17 @@ if it isn't already recorded. */)
Lisp_Object buf;
struct buffer *b;
- buf = w->buffer;
+ buf = w->contents;
CHECK_BUFFER (buf);
b = XBUFFER (buf);
if (! NILP (update)
- && (windows_or_buffers_changed || !w->window_end_valid)
+ && (windows_or_buffers_changed
+ || !w->window_end_valid
+ || b->clip_changed
+ || b->prevent_redisplay_optimizations_p
+ || w->last_modified < BUF_MODIFF (b)
+ || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
&& !noninteractive)
{
struct text_pos startp;
@@ -1539,7 +1560,7 @@ Return POS. */)
if (w == XWINDOW (selected_window))
{
- if (XBUFFER (w->buffer) == current_buffer)
+ if (XBUFFER (w->contents) == current_buffer)
Fgoto_char (pos);
else
{
@@ -1547,14 +1568,14 @@ Return POS. */)
/* ... but here we want to catch type error before buffer change. */
CHECK_NUMBER_COERCE_MARKER (pos);
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
Fgoto_char (pos);
set_buffer_internal (old_buffer);
}
}
else
{
- set_marker_restricted (w->pointm, pos, w->buffer);
+ set_marker_restricted (w->pointm, pos, w->contents);
/* We have to make sure that redisplay updates the window to show
the new value of point. */
++windows_or_buffers_changed;
@@ -1572,7 +1593,7 @@ overriding motion of point in order to display at this exact start. */)
{
register struct window *w = decode_live_window (window);
- set_marker_restricted (w->start, pos, w->buffer);
+ set_marker_restricted (w->start, pos, w->contents);
/* This is not right, but much easier than doing what is right. */
w->start_at_line_beg = 0;
if (NILP (noforce))
@@ -1616,7 +1637,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
int x, y;
w = decode_live_window (window);
- buf = XBUFFER (w->buffer);
+ buf = XBUFFER (w->contents);
SET_TEXT_POS_FROM_MARKER (top, w->start);
if (EQ (pos, Qt))
@@ -1685,13 +1706,14 @@ Return nil if window display is not up-to-date. In that case, use
if (noninteractive || w->pseudo_window_p)
return Qnil;
- CHECK_BUFFER (w->buffer);
- b = XBUFFER (w->buffer);
+ CHECK_BUFFER (w->contents);
+ b = XBUFFER (w->contents);
/* Fail if current matrix is not up-to-date. */
if (!w->window_end_valid
- || current_buffer->clip_changed
- || current_buffer->prevent_redisplay_optimizations_p
+ || windows_or_buffers_changed
+ || b->clip_changed
+ || b->prevent_redisplay_optimizations_p
|| w->last_modified < BUF_MODIFF (b)
|| w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
return Qnil;
@@ -1912,9 +1934,9 @@ window_display_table (struct window *w)
if (DISP_TABLE_P (w->display_table))
dp = XCHAR_TABLE (w->display_table);
- else if (BUFFERP (w->buffer))
+ else if (BUFFERP (w->contents))
{
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
if (DISP_TABLE_P (BVAR (b, display_table)))
dp = XCHAR_TABLE (BVAR (b, display_table));
@@ -1939,17 +1961,14 @@ WINDOW must be a live window and defaults to the selected one. */)
static void
unshow_buffer (register struct window *w)
{
- Lisp_Object buf;
- struct buffer *b;
+ Lisp_Object buf = w->contents;
+ struct buffer *b = XBUFFER (buf);
- buf = w->buffer;
- b = XBUFFER (buf);
- if (b != XMARKER (w->pointm)->buffer)
- emacs_abort ();
+ eassert (b == XMARKER (w->pointm)->buffer);
#if 0
if (w == XWINDOW (selected_window)
- || ! EQ (buf, XWINDOW (selected_window)->buffer))
+ || ! EQ (buf, XWINDOW (selected_window)->contents))
/* Do this except when the selected window's buffer
is being removed from some other window. */
#endif
@@ -1965,14 +1984,14 @@ unshow_buffer (register struct window *w)
/* Point in the selected window's buffer
is actually stored in that buffer, and the window's pointm isn't used.
So don't clobber point in that buffer. */
- if (! EQ (buf, XWINDOW (selected_window)->buffer)
+ if (! EQ (buf, XWINDOW (selected_window)->contents)
/* Don't clobber point in current buffer either (this could be
useful in connection with bug#12208).
&& XBUFFER (buf) != current_buffer */
/* This line helps to fix Horsley's testbug.el bug. */
&& !(WINDOWP (BVAR (b, last_selected_window))
&& w != XWINDOW (BVAR (b, last_selected_window))
- && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer)))
+ && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->contents)))
temp_set_point_both (b,
clip_to_bounds (BUF_BEGV (b),
marker_position (w->pointm),
@@ -2000,12 +2019,12 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
fset_root_window (XFRAME (o->frame), new);
- if (setflag)
- {
- wset_left_col (n, o->left_col);
- wset_top_line (n, o->top_line);
- wset_total_cols (n, o->total_cols);
- wset_total_lines (n, o->total_lines);
+ if (setflag)
+ {
+ n->left_col = o->left_col;
+ n->top_line = o->top_line;
+ n->total_cols = o->total_cols;
+ n->total_lines = o->total_lines;
wset_normal_cols (n, o->normal_cols);
wset_normal_cols (o, make_float (1.0));
wset_normal_lines (n, o->normal_lines);
@@ -2037,13 +2056,8 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
tem = o->parent;
wset_parent (n, tem);
- if (!NILP (tem))
- {
- if (EQ (XWINDOW (tem)->vchild, old))
- wset_vchild (XWINDOW (tem), new);
- if (EQ (XWINDOW (tem)->hchild, old))
- wset_hchild (XWINDOW (tem), new);
- }
+ if (!NILP (tem) && EQ (XWINDOW (tem)->contents, old))
+ wset_combination (XWINDOW (tem), XWINDOW (tem)->horizontal, new);
}
/* If window WINDOW and its parent window are iso-combined, merge
@@ -2055,29 +2069,26 @@ recombine_windows (Lisp_Object window)
{
struct window *w, *p, *c;
Lisp_Object parent, child;
- int horflag;
+ bool horflag;
w = XWINDOW (window);
parent = w->parent;
if (!NILP (parent) && NILP (w->combination_limit))
{
p = XWINDOW (parent);
- if (((!NILP (p->vchild) && !NILP (w->vchild))
- || (!NILP (p->hchild) && !NILP (w->hchild))))
+ if (WINDOWP (p->contents) && WINDOWP (w->contents)
+ && p->horizontal == w->horizontal)
/* WINDOW and PARENT are both either a vertical or a horizontal
combination. */
{
- horflag = NILP (w->vchild);
- child = horflag ? w->hchild : w->vchild;
+ horflag = WINDOW_HORIZONTAL_COMBINATION_P (w);
+ child = w->contents;
c = XWINDOW (child);
/* Splice WINDOW's children into its parent's children and
assign new normal sizes. */
if (NILP (w->prev))
- if (horflag)
- wset_hchild (p, child);
- else
- wset_vchild (p, child);
+ wset_combination (p, horflag, child);
else
{
wset_prev (c, w->prev);
@@ -2090,12 +2101,12 @@ recombine_windows (Lisp_Object window)
if (horflag)
wset_normal_cols (c,
- make_float (XFLOATINT (c->total_cols)
- / XFLOATINT (p->total_cols)));
+ make_float ((double) c->total_cols
+ / (double) p->total_cols));
else
wset_normal_lines (c,
- make_float (XFLOATINT (c->total_lines)
- / XFLOATINT (p->total_lines)));
+ make_float ((double) c->total_lines
+ / (double) p->total_lines));
if (NILP (c->next))
{
@@ -2115,8 +2126,7 @@ recombine_windows (Lisp_Object window)
}
/* WINDOW can be deleted now. */
- wset_vchild (w, Qnil);
- wset_hchild (w, Qnil);
+ wset_combination (w, 0, Qnil);
}
}
}
@@ -2202,7 +2212,7 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
struct frame *f = XFRAME (w->frame);
int candidate_p = 1;
- if (!BUFFERP (w->buffer))
+ if (!BUFFERP (w->contents))
candidate_p = 0;
else if (MINI_WINDOW_P (w)
&& (EQ (minibuf, Qlambda)
@@ -2542,7 +2552,7 @@ enum window_loop
GET_BUFFER_WINDOW, /* Arg is buffer */
REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
- CHECK_ALL_WINDOWS
+ CHECK_ALL_WINDOWS /* Arg is ignored */
};
static Lisp_Object
@@ -2606,7 +2616,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
switch (type)
{
case GET_BUFFER_WINDOW:
- if (EQ (w->buffer, obj)
+ if (EQ (w->contents, obj)
/* Don't find any minibuffer window except the one that
is currently in use. */
&& (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
@@ -2630,25 +2640,25 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
/* We could simply check whether the buffer shown by window
is live, and show another buffer in case it isn't. */
- if (EQ (w->buffer, obj))
+ if (EQ (w->contents, obj))
{
/* Undedicate WINDOW. */
wset_dedicated (w, Qnil);
/* Make WINDOW show the buffer returned by
other_buffer_safely, don't run any hooks. */
set_window_buffer
- (window, other_buffer_safely (w->buffer), 0, 0);
+ (window, other_buffer_safely (w->contents), 0, 0);
/* If WINDOW is the selected window, make its buffer
current. But do so only if the window shows the
current buffer (Bug#6454). */
if (EQ (window, selected_window)
- && XBUFFER (w->buffer) == current_buffer)
- Fset_buffer (w->buffer);
+ && XBUFFER (w->contents) == current_buffer)
+ Fset_buffer (w->contents);
}
break;
case REDISPLAY_BUFFER_WINDOWS:
- if (EQ (w->buffer, obj))
+ if (EQ (w->contents, obj))
{
mark_window_display_accurate (window, 0);
w->update_mode_line = 1;
@@ -2658,11 +2668,20 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
}
break;
- /* Check for a window that has a killed buffer. */
+ /* Check for a leaf window that has a killed buffer
+ or broken markers. */
case CHECK_ALL_WINDOWS:
- if (! NILP (w->buffer)
- && !BUFFER_LIVE_P (XBUFFER (w->buffer)))
- emacs_abort ();
+ if (BUFFERP (w->contents))
+ {
+ struct buffer *b = XBUFFER (w->contents);
+
+ if (!BUFFER_LIVE_P (b))
+ emacs_abort ();
+ if (!MARKERP (w->start) || XMARKER (w->start)->buffer != b)
+ emacs_abort ();
+ if (!MARKERP (w->pointm) || XMARKER (w->pointm)->buffer != b)
+ emacs_abort ();
+ }
break;
case WINDOW_LOOP_UNUSED:
@@ -2779,7 +2798,7 @@ window-start value is reasonable when this function is called. */)
else if (MINI_WINDOW_P (w)) /* && top > 0) */
error ("Can't expand minibuffer to full frame");
- if (!NILP (w->buffer))
+ if (BUFFERP (w->contents))
{
startpos = marker_position (w->start);
startbyte = marker_byte_position (w->start);
@@ -2851,12 +2870,11 @@ window-start value is reasonable when this function is called. */)
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
resize_failed = 0;
- if (NILP (w->buffer))
+ if (!WINDOW_LEAF_P (w))
{
/* Resize child windows vertically. */
- XSETINT (delta, XINT (r->total_lines)
- - XINT (w->total_lines));
- wset_top_line (w, r->top_line);
+ XSETINT (delta, r->total_lines - w->total_lines);
+ w->top_line = r->top_line;
resize_root_window (window, delta, Qnil, Qnil);
if (window_resize_check (w, 0))
window_resize_apply (w, 0);
@@ -2872,10 +2890,8 @@ window-start value is reasonable when this function is called. */)
/* Resize child windows horizontally. */
if (!resize_failed)
{
- wset_left_col (w, r->left_col);
- XSETINT (delta,
- XINT (r->total_cols) - XINT (w->total_cols));
- wset_left_col (w, r->left_col);
+ w->left_col = r->left_col;
+ XSETINT (delta, r->total_cols - w->total_cols);
resize_root_window (window, delta, Qt, Qnil);
if (window_resize_check (w, 1))
window_resize_apply (w, 1);
@@ -2913,28 +2929,21 @@ window-start value is reasonable when this function is called. */)
sibling = w->next;
s = XWINDOW (sibling);
wset_prev (s, Qnil);
- if (!NILP (XWINDOW (w->parent)->vchild))
- wset_vchild (XWINDOW (w->parent), sibling);
- else
- wset_hchild (XWINDOW (w->parent), sibling);
+ wset_combination (XWINDOW (w->parent),
+ XWINDOW (w->parent)->horizontal, sibling);
}
/* Delete ROOT and all child windows of ROOT. */
- if (!NILP (r->vchild))
- {
- delete_all_child_windows (r->vchild);
- wset_vchild (r, Qnil);
- }
- else if (!NILP (r->hchild))
+ if (WINDOWP (r->contents))
{
- delete_all_child_windows (r->hchild);
- wset_hchild (r, Qnil);
+ delete_all_child_windows (r->contents);
+ wset_combination (r, 0, Qnil);
}
replace_window (root, window, 1);
- /* This must become SWINDOW anyway ....... */
- if (!NILP (w->buffer) && !resize_failed)
+ /* This must become SWINDOW anyway ....... */
+ if (BUFFERP (w->contents) && !resize_failed)
{
/* Try to minimize scrolling, by setting the window start to the
point will cause the text at the old window start to be at the
@@ -2943,18 +2952,18 @@ window-start value is reasonable when this function is called. */)
when the display is not current, due to typeahead). */
new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
if (new_top != top
- && startpos >= BUF_BEGV (XBUFFER (w->buffer))
- && startpos <= BUF_ZV (XBUFFER (w->buffer)))
+ && startpos >= BUF_BEGV (XBUFFER (w->contents))
+ && startpos <= BUF_ZV (XBUFFER (w->contents)))
{
struct position pos;
struct buffer *obuf = current_buffer;
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
/* This computation used to temporarily move point, but that
can have unwanted side effects due to text properties. */
pos = *vmotion (startpos, startbyte, -top, w);
- set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
+ set_marker_both (w->start, w->contents, pos.bufpos, pos.bytepos);
w->window_end_valid = 0;
w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
|| FETCH_BYTE (pos.bytepos - 1) == '\n');
@@ -3148,12 +3157,13 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
reset from the buffer's local settings. */
void
-set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int keep_margins_p)
+set_window_buffer (Lisp_Object window, Lisp_Object buffer,
+ bool run_hooks_p, bool keep_margins_p)
{
struct window *w = XWINDOW (window);
struct buffer *b = XBUFFER (buffer);
ptrdiff_t count = SPECPDL_INDEX ();
- int samebuf = EQ (buffer, w->buffer);
+ int samebuf = EQ (buffer, w->contents);
wset_buffer (w, buffer);
@@ -3272,7 +3282,7 @@ This function runs `window-scroll-functions' before running
if (!BUFFER_LIVE_P (XBUFFER (buffer)))
error ("Attempt to display deleted buffer");
- tem = w->buffer;
+ tem = w->contents;
if (NILP (tem))
error ("Window is deleted");
else
@@ -3325,8 +3335,8 @@ displaying that buffer. */)
struct window *w = XWINDOW (object);
mark_window_display_accurate (object, 0);
w->update_mode_line = 1;
- if (BUFFERP (w->buffer))
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ if (BUFFERP (w->contents))
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
++update_mode_lines;
return Qt;
}
@@ -3395,7 +3405,7 @@ temp_output_buffer_show (register Lisp_Object buf)
record_unwind_protect (Fset_buffer, prev_buffer);
record_unwind_protect (select_window_norecord, prev_window);
Fselect_window (window, Qt);
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
Frun_hooks (1, &Qtemp_buffer_show_hook);
unbind_to (count, Qnil);
}
@@ -3406,7 +3416,7 @@ temp_output_buffer_show (register Lisp_Object buf)
WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
horizontal child). */
static void
-make_parent_window (Lisp_Object window, int horflag)
+make_parent_window (Lisp_Object window, bool horflag)
{
Lisp_Object parent;
register struct window *o, *p;
@@ -3416,7 +3426,7 @@ make_parent_window (Lisp_Object window, int horflag)
memcpy ((char *) p + sizeof (struct vectorlike_header),
(char *) o + sizeof (struct vectorlike_header),
word_size * VECSIZE (struct window));
- /* P's buffer slot may change from nil to a buffer. */
+ /* P's buffer slot may change from nil to a buffer... */
adjust_window_count (p, 1);
XSETWINDOW (parent, p);
@@ -3425,12 +3435,11 @@ make_parent_window (Lisp_Object window, int horflag)
wset_next (o, Qnil);
wset_prev (o, Qnil);
wset_parent (o, parent);
-
- wset_hchild (p, horflag ? window : Qnil);
- wset_vchild (p, horflag ? Qnil : window);
+ /* ...but now P becomes an internal window. */
wset_start (p, Qnil);
wset_pointm (p, Qnil);
wset_buffer (p, Qnil);
+ wset_combination (p, horflag, window);
wset_combination_limit (p, Qnil);
wset_window_parameters (p, Qnil);
}
@@ -3445,10 +3454,6 @@ make_window (void)
w = allocate_window ();
/* Initialize Lisp data. Note that allocate_window initializes all
Lisp data to nil, so do it only for slots which should not be nil. */
- wset_left_col (w, make_number (0));
- wset_top_line (w, make_number (0));
- wset_total_lines (w, make_number (0));
- wset_total_cols (w, make_number (0));
wset_normal_lines (w, make_float (1.0));
wset_normal_cols (w, make_float (1.0));
wset_new_total (w, make_number (0));
@@ -3519,14 +3524,14 @@ Note: This function does not operate on any child windows of WINDOW. */)
`window-min-height' or `window-min-width'. It does check that window
sizes do not drop below one line (two columns). */
static int
-window_resize_check (struct window *w, int horflag)
+window_resize_check (struct window *w, bool horflag)
{
struct window *c;
- if (!NILP (w->vchild))
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
/* W is a vertical combination. */
{
- c = XWINDOW (w->vchild);
+ c = XWINDOW (w->contents);
if (horflag)
/* All child windows of W must have the same width as W. */
{
@@ -3554,10 +3559,10 @@ window_resize_check (struct window *w, int horflag)
return (sum_of_sizes == XINT (w->new_total));
}
}
- else if (!NILP (w->hchild))
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
/* W is a horizontal combination. */
{
- c = XWINDOW (w->hchild);
+ c = XWINDOW (w->contents);
if (horflag)
/* The sum of the widths of the child windows of W must equal W's
width. */
@@ -3600,7 +3605,7 @@ window_resize_check (struct window *w, int horflag)
This function does not perform any error checks. Make sure you have
run window_resize_check on W before applying this function. */
static void
-window_resize_apply (struct window *w, int horflag)
+window_resize_apply (struct window *w, bool horflag)
{
struct window *c;
int pos;
@@ -3609,50 +3614,50 @@ window_resize_apply (struct window *w, int horflag)
parent window has been set *before*. */
if (horflag)
{
- wset_total_cols (w, w->new_total);
+ w->total_cols = XFASTINT (w->new_total);
if (NUMBERP (w->new_normal))
wset_normal_cols (w, w->new_normal);
- pos = XINT (w->left_col);
+ pos = w->left_col;
}
else
{
- wset_total_lines (w, w->new_total);
+ w->total_lines = XFASTINT (w->new_total);
if (NUMBERP (w->new_normal))
wset_normal_lines (w, w->new_normal);
- pos = XINT (w->top_line);
+ pos = w->top_line;
}
- if (!NILP (w->vchild))
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
/* W is a vertical combination. */
{
- c = XWINDOW (w->vchild);
+ c = XWINDOW (w->contents);
while (c)
{
if (horflag)
- wset_left_col (c, make_number (pos));
+ c->left_col = pos;
else
- wset_top_line (c, make_number (pos));
+ c->top_line = pos;
window_resize_apply (c, horflag);
if (!horflag)
- pos = pos + XINT (c->total_lines);
+ pos = pos + c->total_lines;
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
}
- else if (!NILP (w->hchild))
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
/* W is a horizontal combination. */
{
- c = XWINDOW (w->hchild);
+ c = XWINDOW (w->contents);
while (c)
{
if (horflag)
- wset_left_col (c, make_number (pos));
+ c->left_col = pos;
else
- wset_top_line (c, make_number (pos));
+ c->top_line = pos;
window_resize_apply (c, horflag);
if (horflag)
- pos = pos + XINT (c->total_cols);
+ pos = pos + c->total_cols;
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
}
@@ -3681,11 +3686,11 @@ be applied on the Elisp level. */)
{
struct frame *f = decode_live_frame (frame);
struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
- int horflag = !NILP (horizontal);
+ bool horflag = !NILP (horizontal);
if (!window_resize_check (r, horflag)
- || ! EQ (r->new_total,
- (horflag ? r->total_cols : r->total_lines)))
+ || (XINT (r->new_total)
+ != (horflag ? r->total_cols : r->total_lines)))
return Qnil;
block_input ();
@@ -3711,7 +3716,7 @@ be applied on the Elisp level. */)
satisfy the request. The result will be meaningful if and only if
F's windows have meaningful sizes when you call this. */
void
-resize_frame_windows (struct frame *f, int size, int horflag)
+resize_frame_windows (struct frame *f, int size, bool horflag)
{
Lisp_Object root = f->root_window;
struct window *r = XWINDOW (root);
@@ -3725,18 +3730,17 @@ resize_frame_windows (struct frame *f, int size, int horflag)
- ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
? 1 : 0)));
- wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
- if (NILP (r->vchild) && NILP (r->hchild))
+ r->top_line = FRAME_TOP_MARGIN (f);
+ if (WINDOW_LEAF_P (r))
/* For a leaf root window just set the size. */
if (horflag)
- wset_total_cols (r, make_number (new_size));
+ r->total_cols = new_size;
else
- wset_total_lines (r, make_number (new_size));
+ r->total_lines = new_size;
else
{
/* old_size is the old size of the frame's root window. */
- int old_size = XFASTINT (horflag ? r->total_cols
- : r->total_lines);
+ int old_size = horflag ? r->total_cols : r->total_lines;
Lisp_Object delta;
XSETINT (delta, new_size - old_size);
@@ -3766,9 +3770,9 @@ resize_frame_windows (struct frame *f, int size, int horflag)
root = f->selected_window;
Fdelete_other_windows_internal (root, Qnil);
if (horflag)
- wset_total_cols (XWINDOW (root), make_number (new_size));
+ XWINDOW (root)->total_cols = new_size;
else
- wset_total_lines (XWINDOW (root), make_number (new_size));
+ XWINDOW (root)->total_lines = new_size;
}
}
}
@@ -3778,13 +3782,12 @@ resize_frame_windows (struct frame *f, int size, int horflag)
{
m = XWINDOW (mini);
if (horflag)
- wset_total_cols (m, make_number (size));
+ m->total_cols = size;
else
{
/* Are we sure we always want 1 line here? */
- wset_total_lines (m, make_number (1));
- wset_top_line
- (m, make_number (XINT (r->top_line) + XINT (r->total_lines)));
+ m->total_lines = 1;
+ m->top_line = r->top_line + r->total_lines;
}
}
@@ -3825,7 +3828,7 @@ set correctly. See the code of `split-window' for how this is done. */)
register Lisp_Object new, frame, reference;
register struct window *o, *p, *n, *r;
struct frame *f;
- int horflag
+ bool horflag
/* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
= EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
int combination_limit = 0;
@@ -3843,9 +3846,9 @@ set correctly. See the code of `split-window' for how this is done. */)
combination_limit =
EQ (Vwindow_combination_limit, Qt)
|| NILP (o->parent)
- || NILP (horflag
- ? (XWINDOW (o->parent)->hchild)
- : (XWINDOW (o->parent)->vchild));
+ || (horflag
+ ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
+ : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent)));
/* We need a live reference window to initialize some parameters. */
if (WINDOW_LIVE_P (old))
@@ -3868,20 +3871,21 @@ set correctly. See the code of `split-window' for how this is done. */)
p = XWINDOW (o->parent);
/* Temporarily pretend we split the parent window. */
wset_new_total
- (p, make_number (XINT (horflag ? p->total_cols : p->total_lines)
+ (p, make_number ((horflag ? p->total_cols : p->total_lines)
- XINT (total_size)));
if (!window_resize_check (p, horflag))
error ("Window sizes don't fit");
else
/* Undo the temporary pretension. */
- wset_new_total (p, horflag ? p->total_cols : p->total_lines);
+ wset_new_total (p, make_number
+ (horflag ? p->total_cols : p->total_lines));
}
else
{
if (!window_resize_check (o, horflag))
error ("Resizing old window failed");
else if (XINT (total_size) + XINT (o->new_total)
- != XINT (horflag ? o->total_cols : o->total_lines))
+ != (horflag ? o->total_cols : o->total_lines))
error ("Sum of sizes of old and new window don't fit");
}
@@ -3901,7 +3905,8 @@ set correctly. See the code of `split-window' for how this is done. */)
that its children get merged into another window. */
wset_combination_limit (p, Qt);
/* These get applied below. */
- wset_new_total (p, horflag ? o->total_cols : o->total_lines);
+ wset_new_total (p, make_number
+ (horflag ? o->total_cols : o->total_lines));
wset_new_normal (p, new_normal);
}
else
@@ -3913,17 +3918,12 @@ set correctly. See the code of `split-window' for how this is done. */)
n = XWINDOW (new);
wset_frame (n, frame);
wset_parent (n, o->parent);
- wset_vchild (n, Qnil);
- wset_hchild (n, Qnil);
if (EQ (side, Qabove) || EQ (side, Qleft))
{
wset_prev (n, o->prev);
if (NILP (n->prev))
- if (horflag)
- wset_hchild (p, new);
- else
- wset_vchild (p, new);
+ wset_combination (p, horflag, new);
else
wset_next (XWINDOW (n->prev), new);
wset_next (n, old);
@@ -3953,13 +3953,13 @@ set correctly. See the code of `split-window' for how this is done. */)
/* Directly assign orthogonal coordinates and sizes. */
if (horflag)
{
- wset_top_line (n, o->top_line);
- wset_total_lines (n, o->total_lines);
+ n->top_line = o->top_line;
+ n->total_lines = o->total_lines;
}
else
{
- wset_left_col (n, o->left_col);
- wset_total_cols (n, o->total_cols);
+ n->left_col = o->left_col;
+ n->total_cols = o->total_cols;
}
/* Iso-coordinates and sizes are assigned by window_resize_apply,
@@ -3972,7 +3972,7 @@ set correctly. See the code of `split-window' for how this is done. */)
adjust_glyphs (f);
/* Set buffer of NEW to buffer of reference window. Don't run
any hooks. */
- set_window_buffer (new, r->buffer, 0, 1);
+ set_window_buffer (new, r->contents, 0, 1);
unblock_input ();
/* Maybe we should run the scroll functions in Elisp (which already
@@ -3994,13 +3994,11 @@ Signal an error when WINDOW is the only window on its frame. */)
register Lisp_Object parent, sibling, frame, root;
struct window *w, *p, *s, *r;
struct frame *f;
- int horflag;
- int before_sibling = 0;
+ bool horflag, before_sibling = 0;
w = decode_any_window (window);
XSETWINDOW (window, w);
- if (NILP (w->buffer)
- && NILP (w->hchild) && NILP (w->vchild))
+ if (NILP (w->contents))
/* It's a no-op to delete an already deleted window. */
return Qnil;
@@ -4014,7 +4012,7 @@ Signal an error when WINDOW is the only window on its frame. */)
error ("Attempt to delete sole window of parent");
p = XWINDOW (parent);
- horflag = NILP (p->vchild);
+ horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
frame = WINDOW_FRAME (w);
f = XFRAME (frame);
@@ -4032,10 +4030,7 @@ Signal an error when WINDOW is the only window on its frame. */)
sibling = w->next;
s = XWINDOW (sibling);
wset_prev (s, Qnil);
- if (horflag)
- wset_hchild (p, sibling);
- else
- wset_vchild (p, sibling);
+ wset_combination (p, horflag, sibling);
}
else
/* Get SIBLING above (on the left of) WINDOW. */
@@ -4048,8 +4043,8 @@ Signal an error when WINDOW is the only window on its frame. */)
}
if (window_resize_check (r, horflag)
- && EQ (r->new_total,
- (horflag ? r->total_cols : r->total_lines)))
+ && (XINT (r->new_total)
+ == (horflag ? r->total_cols : r->total_lines)))
/* We can delete WINDOW now. */
{
@@ -4074,17 +4069,12 @@ Signal an error when WINDOW is the only window on its frame. */)
wset_next (w, Qnil); /* Don't delete w->next too. */
free_window_matrices (w);
- if (!NILP (w->vchild))
+ if (WINDOWP (w->contents))
{
- delete_all_child_windows (w->vchild);
- wset_vchild (w, Qnil);
+ delete_all_child_windows (w->contents);
+ wset_combination (w, 0, Qnil);
}
- else if (!NILP (w->hchild))
- {
- delete_all_child_windows (w->hchild);
- wset_hchild (w, Qnil);
- }
- else if (!NILP (w->buffer))
+ else
{
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
@@ -4103,8 +4093,7 @@ Signal an error when WINDOW is the only window on its frame. */)
wset_normal_cols (s, p->normal_cols);
wset_normal_lines (s, p->normal_lines);
/* Mark PARENT as deleted. */
- wset_vchild (p, Qnil);
- wset_hchild (p, Qnil);
+ wset_combination (p, 0, Qnil);
/* Try to merge SIBLING into its new parent. */
recombine_windows (sibling);
}
@@ -4152,10 +4141,7 @@ Signal an error when WINDOW is the only window on its frame. */)
if (before_sibling)
{
wset_prev (s, window);
- if (horflag)
- wset_hchild (p, window);
- else
- wset_vchild (p, window);
+ wset_combination (p, horflag, window);
}
else
{
@@ -4195,10 +4181,8 @@ grow_mini_window (struct window *w, int delta)
window_resize_apply (r, 0);
/* Grow the mini-window. */
- wset_top_line
- (w, make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines)));
- wset_total_lines
- (w, make_number (XFASTINT (w->total_lines) - XINT (value)));
+ w->top_line = r->top_line + r->total_lines;
+ w->total_lines -= XINT (value);
w->last_modified = 0;
w->last_overlay_modified = 0;
@@ -4220,7 +4204,7 @@ shrink_mini_window (struct window *w)
eassert (MINI_WINDOW_P (w));
- size = XINT (w->total_lines);
+ size = w->total_lines;
if (size > 1)
{
root = FRAME_ROOT_WINDOW (f);
@@ -4233,9 +4217,8 @@ shrink_mini_window (struct window *w)
window_resize_apply (r, 0);
/* Shrink the mini-window. */
- wset_top_line (w, make_number (XFASTINT (r->top_line)
- + XFASTINT (r->total_lines)));
- wset_total_lines (w, make_number (1));
+ w->top_line = r->top_line + r->total_lines;
+ w->total_lines = 1;
w->last_modified = 0;
w->last_overlay_modified = 0;
@@ -4269,7 +4252,7 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
error ("Cannot resize a minibuffer-only frame");
r = XWINDOW (FRAME_ROOT_WINDOW (f));
- height = XINT (r->total_lines) + XINT (w->total_lines);
+ height = r->total_lines + w->total_lines;
if (window_resize_check (r, 0)
&& XINT (w->new_total) > 0
&& height == XINT (r->new_total) + XINT (w->new_total))
@@ -4277,9 +4260,8 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
block_input ();
window_resize_apply (r, 0);
- wset_total_lines (w, w->new_total);
- wset_top_line (w, make_number (XINT (r->top_line)
- + XINT (r->total_lines)));
+ w->total_lines = XFASTINT (w->new_total);
+ w->top_line = r->top_line + r->total_lines;
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
@@ -4302,10 +4284,8 @@ mark_window_cursors_off (struct window *w)
{
while (w)
{
- if (!NILP (w->hchild))
- mark_window_cursors_off (XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- mark_window_cursors_off (XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ mark_window_cursors_off (XWINDOW (w->contents));
else
w->phys_cursor_on_p = 0;
@@ -4319,13 +4299,12 @@ mark_window_cursors_off (struct window *w)
int
window_internal_height (struct window *w)
{
- int ht = XFASTINT (w->total_lines);
+ int ht = w->total_lines;
if (!MINI_WINDOW_P (w))
{
if (!NILP (w->parent)
- || !NILP (w->vchild)
- || !NILP (w->hchild)
+ || WINDOWP (w->contents)
|| !NILP (w->next)
|| !NILP (w->prev)
|| WINDOW_WANTS_MODELINE_P (w))
@@ -4464,7 +4443,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
else
spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
set_marker_restricted (w->start, make_number (spos),
- w->buffer);
+ w->contents);
w->start_at_line_beg = 1;
w->update_mode_line = 1;
w->last_modified = 0;
@@ -4588,7 +4567,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
/* If control gets here, then we vscrolled. */
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
/* Don't try to change the window start below. */
vscrolled = 1;
@@ -4608,7 +4587,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
}
/* Set the window start, and set up the window for redisplay. */
- set_marker_restricted_both (w->start, w->buffer, IT_CHARPOS (it),
+ set_marker_restricted_both (w->start, w->contents, IT_CHARPOS (it),
IT_BYTEPOS (it));
bytepos = marker_byte_position (w->start);
w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
@@ -4629,7 +4608,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
even if there is a header line. */
this_scroll_margin = max (0, scroll_margin);
this_scroll_margin
- = min (this_scroll_margin, XFASTINT (w->total_lines) / 4);
+ = min (this_scroll_margin, w->total_lines / 4);
this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
if (n > 0)
@@ -4806,9 +4785,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
{
/* Don't use a scroll margin that is negative or too large. */
int this_scroll_margin =
- max (0, min (scroll_margin, XINT (w->total_lines) / 4));
+ max (0, min (scroll_margin, w->total_lines / 4));
- set_marker_restricted_both (w->start, w->buffer, pos, pos_byte);
+ set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
w->start_at_line_beg = !NILP (bolp);
w->update_mode_line = 1;
w->last_modified = 0;
@@ -4902,10 +4881,10 @@ scroll_command (Lisp_Object n, int direction)
/* If selected window's buffer isn't current, make it current for
the moment. But don't screw up if window_scroll gets an error. */
- if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
+ if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer)
{
record_unwind_protect (save_excursion_restore, save_excursion_save ());
- Fset_buffer (XWINDOW (selected_window)->buffer);
+ Fset_buffer (XWINDOW (selected_window)->contents);
/* Make redisplay consider other windows than just selected_window. */
++windows_or_buffers_changed;
@@ -5020,7 +4999,7 @@ specifies the window to scroll. This takes precedence over
record_unwind_protect (save_excursion_restore, save_excursion_save ());
++windows_or_buffers_changed;
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
if (NILP (arg))
@@ -5114,10 +5093,10 @@ displayed_window_lines (struct window *w)
int bottom_y;
void *itdata = NULL;
- if (XBUFFER (w->buffer) != current_buffer)
+ if (XBUFFER (w->contents) != current_buffer)
{
old_buffer = current_buffer;
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
}
else
old_buffer = NULL;
@@ -5179,7 +5158,7 @@ and redisplay normally--don't erase and redraw the frame. */)
(register Lisp_Object arg)
{
struct window *w = XWINDOW (selected_window);
- struct buffer *buf = XBUFFER (w->buffer);
+ struct buffer *buf = XBUFFER (w->contents);
struct buffer *obuf = current_buffer;
int center_p = 0;
ptrdiff_t charpos, bytepos;
@@ -5223,7 +5202,7 @@ and redisplay normally--don't erase and redraw the frame. */)
/* Do this after making BUF current
in case scroll_margin is buffer-local. */
this_scroll_margin =
- max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4));
+ max (0, min (scroll_margin, w->total_lines / 4));
/* Handle centering on a graphical frame specially. Such frames can
have variable-height lines and centering point on the basis of
@@ -5345,7 +5324,7 @@ and redisplay normally--don't erase and redraw the frame. */)
}
/* Set the new window start. */
- set_marker_both (w->start, w->buffer, charpos, bytepos);
+ set_marker_both (w->start, w->contents, charpos, bytepos);
w->window_end_valid = 0;
w->optional_new_start = 1;
@@ -5389,9 +5368,8 @@ zero means top of window, negative means relative to bottom of window. */)
int this_scroll_margin;
#endif
- if (!(BUFFERP (w->buffer)
- && XBUFFER (w->buffer) == current_buffer))
- /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
+ if (!(BUFFERP (w->contents) && XBUFFER (w->contents) == current_buffer))
+ /* This test is needed to make sure PT/PT_BYTE make sense in w->contents
when passed below to set_marker_both. */
error ("move-to-window-line called from unrelated buffer");
@@ -5401,7 +5379,7 @@ zero means top of window, negative means relative to bottom of window. */)
{
int height = window_internal_height (w);
Fvertical_motion (make_number (- (height / 2)), window);
- set_marker_both (w->start, w->buffer, PT, PT_BYTE);
+ set_marker_both (w->start, w->contents, PT, PT_BYTE);
w->start_at_line_beg = !NILP (Fbolp ());
w->force_start = 1;
}
@@ -5551,9 +5529,9 @@ the return value is nil. Otherwise the value is t. */)
window-point of the final-selected-window to the window-point of
the current-selected-window. So we have to be careful which
point of the current-buffer we copy into old_point. */
- if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)
+ if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
&& WINDOWP (selected_window)
- && EQ (XWINDOW (selected_window)->buffer, new_current_buffer)
+ && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
&& !EQ (selected_window, data->current_window))
old_point = marker_position (XWINDOW (data->current_window)->pointm);
else
@@ -5567,7 +5545,7 @@ the return value is nil. Otherwise the value is t. */)
So if possible we want this arbitrary choice of "which point" to
be the one from the to-be-selected-window so as to prevent this
window's cursor from being copied from another window. */
- if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)
+ if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
/* If current_window = selected_window, its point is in BUF_PT. */
&& !EQ (selected_window, data->current_window))
old_point = marker_position (XWINDOW (data->current_window)->pointm);
@@ -5609,8 +5587,8 @@ the return value is nil. Otherwise the value is t. */)
p = SAVED_WINDOW_N (saved_windows, k);
window = p->window;
w = XWINDOW (window);
- if (!NILP (w->buffer)
- && !EQ (w->buffer, p->buffer)
+ if (BUFFERP (w->contents)
+ && !EQ (w->contents, p->buffer)
&& BUFFER_LIVE_P (XBUFFER (p->buffer)))
/* If a window we restore gets another buffer, record the
window's old buffer. */
@@ -5643,13 +5621,13 @@ the return value is nil. Otherwise the value is t. */)
window holds garbage.) We do this now, before
restoring the window contents, and prevent it from
being done later on when we select a new window. */
- if (! NILP (XWINDOW (selected_window)->buffer))
+ if (! NILP (XWINDOW (selected_window)->contents))
{
w = XWINDOW (selected_window);
set_marker_both (w->pointm,
- w->buffer,
- BUF_PT (XBUFFER (w->buffer)),
- BUF_PT_BYTE (XBUFFER (w->buffer)));
+ w->contents,
+ BUF_PT (XBUFFER (w->contents)),
+ BUF_PT_BYTE (XBUFFER (w->contents)));
}
windows_or_buffers_changed++;
@@ -5696,28 +5674,19 @@ the return value is nil. Otherwise the value is t. */)
{
wset_prev (w, Qnil);
if (!NILP (w->parent))
- {
- if (EQ (p->total_cols, XWINDOW (w->parent)->total_cols))
- {
- wset_vchild (XWINDOW (w->parent), p->window);
- wset_hchild (XWINDOW (w->parent), Qnil);
- }
- else
- {
- wset_hchild (XWINDOW (w->parent), p->window);
- wset_vchild (XWINDOW (w->parent), Qnil);
- }
- }
+ wset_combination (XWINDOW (w->parent),
+ (XINT (p->total_cols)
+ != XWINDOW (w->parent)->total_cols),
+ p->window);
}
- /* If we squirreled away the buffer in the window's height,
- restore it now. */
- if (BUFFERP (w->total_lines))
- wset_buffer (w, w->total_lines);
- wset_left_col (w, p->left_col);
- wset_top_line (w, p->top_line);
- wset_total_cols (w, p->total_cols);
- wset_total_lines (w, p->total_lines);
+ /* If we squirreled away the buffer, restore it now. */
+ if (BUFFERP (w->combination_limit))
+ wset_buffer (w, w->combination_limit);
+ w->left_col = XFASTINT (p->left_col);
+ w->top_line = XFASTINT (p->top_line);
+ w->total_cols = XFASTINT (p->total_cols);
+ w->total_lines = XFASTINT (p->total_lines);
wset_normal_cols (w, p->normal_cols);
wset_normal_lines (w, p->normal_lines);
w->hscroll = XFASTINT (p->hscroll);
@@ -5757,20 +5726,16 @@ the return value is nil. Otherwise the value is t. */)
w->last_modified = 0;
w->last_overlay_modified = 0;
- /* Reinstall the saved buffer and pointers into it. */
- if (NILP (p->buffer))
- /* An internal window. */
- wset_buffer (w, p->buffer);
- else if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
+ if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
/* If saved buffer is alive, install it. */
{
wset_buffer (w, p->buffer);
w->start_at_line_beg = !NILP (p->start_at_line_beg);
- set_marker_restricted (w->start, p->start, w->buffer);
+ set_marker_restricted (w->start, p->start, w->contents);
set_marker_restricted (w->pointm, p->pointm,
- w->buffer);
- Fset_marker (BVAR (XBUFFER (w->buffer), mark),
- p->mark, w->buffer);
+ w->contents);
+ Fset_marker (BVAR (XBUFFER (w->contents), mark),
+ p->mark, w->contents);
/* As documented in Fcurrent_window_configuration, don't
restore the location of point in the buffer which was
@@ -5779,23 +5744,21 @@ the return value is nil. Otherwise the value is t. */)
&& XBUFFER (p->buffer) == current_buffer)
Fgoto_char (w->pointm);
}
- else if (!NILP (w->buffer)
- && BUFFER_LIVE_P (XBUFFER (w->buffer)))
- /* Keep window's old buffer; make sure the markers are
- real. */
- {
- /* Set window markers at start of visible range. */
- if (XMARKER (w->start)->buffer == 0)
- set_marker_restricted_both (w->start, w->buffer, 0, 0);
- if (XMARKER (w->pointm)->buffer == 0)
- set_marker_restricted_both
- (w->pointm, w->buffer,
- BUF_PT (XBUFFER (w->buffer)),
- BUF_PT_BYTE (XBUFFER (w->buffer)));
- w->start_at_line_beg = 1;
- }
- else
- /* Window has no live buffer, get one. */
+ else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
+ /* Keep window's old buffer; make sure the markers are real. */
+ {
+ /* Set window markers at start of visible range. */
+ if (XMARKER (w->start)->buffer == 0)
+ set_marker_restricted_both (w->start, w->contents, 0, 0);
+ if (XMARKER (w->pointm)->buffer == 0)
+ set_marker_restricted_both
+ (w->pointm, w->contents,
+ BUF_PT (XBUFFER (w->contents)),
+ BUF_PT_BYTE (XBUFFER (w->contents)));
+ w->start_at_line_beg = 1;
+ }
+ else if (!NILP (w->start))
+ /* Leaf window has no live buffer, get one. */
{
/* Get the buffer via other_buffer_safely in order to
avoid showing an unimportant buffer and, if necessary, to
@@ -5804,8 +5767,8 @@ the return value is nil. Otherwise the value is t. */)
wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
/* This will set the markers to beginning of visible
range. */
- set_marker_restricted_both (w->start, w->buffer, 0, 0);
- set_marker_restricted_both (w->pointm, w->buffer, 0, 0);
+ set_marker_restricted_both (w->start, w->contents, 0, 0);
+ set_marker_restricted_both (w->pointm, w->contents, 0, 0);
w->start_at_line_beg = 1;
if (!NILP (w->dedicated))
/* Record this window as dead. */
@@ -5818,17 +5781,17 @@ the return value is nil. Otherwise the value is t. */)
fset_root_window (f, data->root_window);
/* Arrange *not* to restore point in the buffer that was
current when the window configuration was saved. */
- if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
+ if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
set_marker_restricted (XWINDOW (data->current_window)->pointm,
make_number (old_point),
- XWINDOW (data->current_window)->buffer);
+ XWINDOW (data->current_window)->contents);
/* In the following call to `select-window', prevent "swapping out
point" in the old selected window using the buffer that has
been restored into it. We already swapped out that point from
that window's old buffer. */
select_window (data->current_window, Qnil, 1);
- BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window)
+ BVAR (XBUFFER (XWINDOW (selected_window)->contents), last_selected_window)
= selected_window;
if (NILP (data->focus_frame)
@@ -5855,14 +5818,9 @@ the return value is nil. Otherwise the value is t. */)
/* Now, free glyph matrices in windows that were not reused. */
for (i = n = 0; i < n_leaf_windows; ++i)
{
- if (NILP (leaf_windows[i]->buffer))
- {
- /* Assert it's not reused as a combination. */
- eassert (NILP (leaf_windows[i]->hchild)
- && NILP (leaf_windows[i]->vchild));
- free_window_matrices (leaf_windows[i]);
- }
- else if (EQ (leaf_windows[i]->buffer, new_current_buffer))
+ if (NILP (leaf_windows[i]->contents))
+ free_window_matrices (leaf_windows[i]);
+ else if (EQ (leaf_windows[i]->contents, new_current_buffer))
++n;
}
@@ -5893,7 +5851,7 @@ the return value is nil. Otherwise the value is t. */)
Fset_buffer (new_current_buffer);
/* If the new current buffer doesn't appear in the selected
window, go to its old point (see bug#12208). */
- if (!EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
+ if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
Fgoto_char (make_number (old_point));
}
@@ -5904,8 +5862,10 @@ the return value is nil. Otherwise the value is t. */)
}
-/* Recursively delete all child windows reachable via the next, vchild,
- and hchild slots of WINDOW. */
+/* If WINDOW is an internal window, recursively delete all child windows
+ reachable via the next and contents slots of WINDOW. Otherwise setup
+ WINDOW to not show any buffer. */
+
void
delete_all_child_windows (Lisp_Object window)
{
@@ -5917,24 +5877,20 @@ delete_all_child_windows (Lisp_Object window)
/* Delete WINDOW's siblings (we traverse postorderly). */
delete_all_child_windows (w->next);
- /* See Fset_window_configuration for excuse. */
- wset_total_lines (w, w->buffer);
-
- if (!NILP (w->vchild))
- {
- delete_all_child_windows (w->vchild);
- wset_vchild (w, Qnil);
- }
- else if (!NILP (w->hchild))
+ if (WINDOWP (w->contents))
{
- delete_all_child_windows (w->hchild);
- wset_hchild (w, Qnil);
+ delete_all_child_windows (w->contents);
+ wset_combination (w, 0, Qnil);
}
- else if (!NILP (w->buffer))
+ else if (BUFFERP (w->contents))
{
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
unchain_marker (XMARKER (w->start));
+ /* Since combination limit makes sense for an internal windows
+ only, we use this slot to save the buffer for the sake of
+ possible resurrection in Fset_window_configuration. */
+ wset_combination_limit (w, w->contents);
wset_buffer (w, Qnil);
}
@@ -5947,10 +5903,8 @@ count_windows (register struct window *window)
register int count = 1;
if (!NILP (window->next))
count += count_windows (XWINDOW (window->next));
- if (!NILP (window->vchild))
- count += count_windows (XWINDOW (window->vchild));
- if (!NILP (window->hchild))
- count += count_windows (XWINDOW (window->hchild));
+ if (WINDOWP (window->contents))
+ count += count_windows (XWINDOW (window->contents));
return count;
}
@@ -5962,10 +5916,8 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
{
while (w)
{
- if (!NILP (w->hchild))
- i = get_leaf_windows (XWINDOW (w->hchild), flat, i);
- else if (!NILP (w->vchild))
- i = get_leaf_windows (XWINDOW (w->vchild), flat, i);
+ if (WINDOWP (w->contents))
+ i = get_leaf_windows (XWINDOW (w->contents), flat, i);
else
flat[i++] = w;
@@ -6005,8 +5957,7 @@ get_phys_cursor_glyph (struct window *w)
hpos = row->used[TEXT_AREA] - 1;
}
- if (row->used[TEXT_AREA] > hpos
- && 0 <= hpos)
+ if (0 <= hpos && hpos < row->used[TEXT_AREA])
glyph = row->glyphs[TEXT_AREA] + hpos;
else
glyph = NULL;
@@ -6022,18 +5973,18 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
register struct window *w;
register Lisp_Object tem, pers, par;
- for (;!NILP (window); window = w->next)
+ for (; !NILP (window); window = w->next)
{
p = SAVED_WINDOW_N (vector, i);
w = XWINDOW (window);
wset_temslot (w, make_number (i)); i++;
p->window = window;
- p->buffer = w->buffer;
- p->left_col = w->left_col;
- p->top_line = w->top_line;
- p->total_cols = w->total_cols;
- p->total_lines = w->total_lines;
+ p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
+ p->left_col = make_number (w->left_col);
+ p->top_line = make_number (w->top_line);
+ p->total_cols = make_number (w->total_cols);
+ p->total_lines = make_number (w->total_lines);
p->normal_cols = w->normal_cols;
p->normal_lines = w->normal_lines;
XSETFASTINT (p->hscroll, w->hscroll);
@@ -6096,15 +6047,15 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
}
}
- if (!NILP (w->buffer))
+ if (BUFFERP (w->contents))
{
/* Save w's value of point in the window configuration. If w
is the selected window, then get the value of point from
the buffer; pointm is garbage in the selected window. */
if (EQ (window, selected_window))
- p->pointm = build_marker (XBUFFER (w->buffer),
- BUF_PT (XBUFFER (w->buffer)),
- BUF_PT_BYTE (XBUFFER (w->buffer)));
+ p->pointm = build_marker (XBUFFER (w->contents),
+ BUF_PT (XBUFFER (w->contents)),
+ BUF_PT_BYTE (XBUFFER (w->contents)));
else
p->pointm = Fcopy_marker (w->pointm, Qnil);
XMARKER (p->pointm)->insertion_type
@@ -6113,7 +6064,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
p->start = Fcopy_marker (w->start, Qnil);
p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
- tem = BVAR (XBUFFER (w->buffer), mark);
+ tem = BVAR (XBUFFER (w->contents), mark);
p->mark = Fcopy_marker (tem, Qnil);
}
else
@@ -6134,10 +6085,8 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
else
p->prev = XWINDOW (w->prev)->temslot;
- if (!NILP (w->vchild))
- i = save_window_save (w->vchild, vector, i);
- if (!NILP (w->hchild))
- i = save_window_save (w->hchild, vector, i);
+ if (WINDOWP (w->contents))
+ i = save_window_save (w->contents, vector, i);
}
return i;
@@ -6454,7 +6403,7 @@ If PIXELS-P is non-nil, the return value is VSCROLL. */)
adjust_glyphs (f);
/* Prevent redisplay shortcuts. */
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
}
}
@@ -6488,10 +6437,8 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u
for (cont = 1; w && cont;)
{
- if (!NILP (w->hchild))
- cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data);
- else if (!NILP (w->vchild))
- cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data);
+ if (WINDOWP (w->contents))
+ cont = foreach_window_1 (XWINDOW (w->contents), fn, user_data);
else
cont = fn (w, user_data);
@@ -6527,7 +6474,7 @@ freeze_window_start (struct window *w, void *freeze_p)
means freeze the window start. */
void
-freeze_window_starts (struct frame *f, int freeze_p)
+freeze_window_starts (struct frame *f, bool freeze_p)
{
foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
}
diff --git a/src/window.h b/src/window.h
index dcef37abb4c..411756f045e 100644
--- a/src/window.h
+++ b/src/window.h
@@ -41,14 +41,13 @@ They are deleted only by calling delete-window on them (but
this can be done implicitly). Combination windows can be created
and deleted at any time.
-A leaf window has a non-nil buffer field, and also
- has markers in its start and pointm fields. Non-leaf windows
- have nil in these fields.
+A leaf window has a buffer stored in contents field and markers in its start
+and pointm fields. Non-leaf windows have nil in the latter two fields.
Non-leaf windows are either vertical or horizontal combinations.
A vertical combination window has children that are arranged on the frame
-one above the next. Its vchild field points to the uppermost child.
+one above the next. Its contents field points to the uppermost child.
The parent field of each of the children points to the vertical
combination window. The next field of each child points to the
child below it, or is nil for the lowest child. The prev field
@@ -56,7 +55,7 @@ of each child points to the child above it, or is nil for the
highest child.
A horizontal combination window has children that are side by side.
-Its hchild field points to the leftmost child. In each child
+Its contents field points to the leftmost child. In each child
the next field points to the child to the right and the prev field
points to the child to the left.
@@ -78,7 +77,7 @@ the root window is the minibuf window. On minibufferless screens or
minibuffer-only screens, the root window and the minibuffer window are
one and the same, so its prev and next members are nil.
-A dead window has its buffer, hchild, and vchild windows all nil. */
+A dead window has its contents field set to nil. */
struct cursor_pos
{
@@ -102,37 +101,22 @@ struct window
Lisp_Object next;
Lisp_Object prev;
- /* First child of this window: vchild is used if this is a vertical
- combination, hchild if this is a horizontal combination. Of the
- fields vchild, hchild and buffer, one and only one is non-nil
- unless the window is dead. */
- Lisp_Object hchild;
- Lisp_Object vchild;
-
/* The window this one is a child of. */
Lisp_Object parent;
- /* The upper left corner coordinates of this window, as integers
- relative to upper left corner of frame = 0, 0. */
- Lisp_Object left_col;
- Lisp_Object top_line;
-
- /* The size of the window. */
- Lisp_Object total_lines;
- Lisp_Object total_cols;
-
- /* The normal size of the window. */
+ /* The normal size of the window. These are fractions, but we do
+ not use C doubles to avoid creating new Lisp_Float objects while
+ interfacing Lisp in Fwindow_normal_size. */
Lisp_Object normal_lines;
Lisp_Object normal_cols;
- /* New sizes of the window. */
+ /* New sizes of the window. Note that Lisp code may set new_normal
+ to something beyond an integer, so C int can't be used here. */
Lisp_Object new_total;
Lisp_Object new_normal;
- /* The buffer displayed in this window. Of the fields vchild,
- hchild and buffer, one and only one is non-nil unless the window
- is dead. */
- Lisp_Object buffer;
+ /* May be buffer, window, or nil. */
+ Lisp_Object contents;
/* A marker pointing to where in the text to start displaying.
BIDI Note: This is the _logical-order_ start, i.e. the smallest
@@ -221,6 +205,15 @@ struct window
/* Number saying how recently window was selected. */
int use_time;
+ /* The upper left corner coordinates of this window,
+ relative to upper left corner of frame = 0, 0. */
+ int left_col;
+ int top_line;
+
+ /* The size of the window. */
+ int total_lines;
+ int total_cols;
+
/* Number of columns display within the window is scrolled to the left. */
ptrdiff_t hscroll;
@@ -279,6 +272,10 @@ struct window
/* Non-zero if this window is a minibuffer window. */
unsigned mini : 1;
+ /* Meaningful only if contents is a window, non-zero if this
+ internal window is used in horizontal combination. */
+ unsigned horizontal : 1;
+
/* Non-zero means must regenerate mode line of this window. */
unsigned update_mode_line : 1;
@@ -354,11 +351,6 @@ wset_frame (struct window *w, Lisp_Object val)
w->frame = val;
}
WINDOW_INLINE void
-wset_left_col (struct window *w, Lisp_Object val)
-{
- w->left_col = val;
-}
-WINDOW_INLINE void
wset_next (struct window *w, Lisp_Object val)
{
w->next = val;
@@ -374,21 +366,6 @@ wset_redisplay_end_trigger (struct window *w, Lisp_Object val)
w->redisplay_end_trigger = val;
}
WINDOW_INLINE void
-wset_top_line (struct window *w, Lisp_Object val)
-{
- w->top_line = val;
-}
-WINDOW_INLINE void
-wset_total_cols (struct window *w, Lisp_Object val)
-{
- w->total_cols = val;
-}
-WINDOW_INLINE void
-wset_total_lines (struct window *w, Lisp_Object val)
-{
- w->total_lines = val;
-}
-WINDOW_INLINE void
wset_vertical_scroll_bar (struct window *w, Lisp_Object val)
{
w->vertical_scroll_bar = val;
@@ -445,6 +422,21 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/* A handy macro. */
+/* Non-zero if W is leaf (carry the buffer). */
+
+#define WINDOW_LEAF_P(W) \
+ (BUFFERP ((W)->contents))
+
+/* Non-zero if W is a member of horizontal combination. */
+
+#define WINDOW_HORIZONTAL_COMBINATION_P(W) \
+ (WINDOWP ((W)->contents) && (W)->horizontal)
+
+/* Non-zero if W is a member of vertical combination. */
+
+#define WINDOW_VERTICAL_COMBINATION_P(W) \
+ (WINDOWP ((W)->contents) && !(W)->horizontal)
+
#define WINDOW_XFRAME(W) \
(XFRAME (WINDOW_FRAME ((W))))
@@ -461,14 +453,12 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/* Return the width of window W in canonical column units.
This includes scroll bars and fringes. */
-#define WINDOW_TOTAL_COLS(W) \
- (XFASTINT (W->total_cols))
+#define WINDOW_TOTAL_COLS(W) (W)->total_cols
/* Return the height of window W in canonical line units.
This includes header and mode lines, if any. */
-#define WINDOW_TOTAL_LINES(W) \
- (XFASTINT (W->total_lines))
+#define WINDOW_TOTAL_LINES(W) (W)->total_lines
/* Return the total pixel width of window W. */
@@ -495,8 +485,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/* Return the canonical frame column at which window W starts.
This includes a left-hand scroll bar, if any. */
-#define WINDOW_LEFT_EDGE_COL(W) \
- (XFASTINT (W->left_col))
+#define WINDOW_LEFT_EDGE_COL(W) (W)->left_col
/* Return the canonical frame column before which window W ends.
This includes a right-hand scroll bar, if any. */
@@ -507,8 +496,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/* Return the canonical frame line at which window W starts.
This includes a header line, if any. */
-#define WINDOW_TOP_EDGE_LINE(W) \
- (XFASTINT (W->top_line))
+#define WINDOW_TOP_EDGE_LINE(W) (W)->top_line
/* Return the canonical frame line before which window W ends.
This includes a mode line, if any. */
@@ -533,9 +521,14 @@ wset_next_buffers (struct window *w, Lisp_Object val)
/* 1 if W is a menu bar window. */
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
#define WINDOW_MENU_BAR_P(W) \
(WINDOWP (WINDOW_XFRAME (W)->menu_bar_window) \
&& (W) == XWINDOW (WINDOW_XFRAME (W)->menu_bar_window))
+#else
+/* No menu bar windows if X toolkit is in use. */
+#define WINDOW_MENU_BAR_P(W) (0)
+#endif
/* 1 if W is a tool bar window. */
@@ -891,10 +884,10 @@ extern Lisp_Object Vmouse_event;
extern Lisp_Object make_window (void);
extern Lisp_Object window_from_coordinates (struct frame *, int, int,
- enum window_part *, int);
-extern void resize_frame_windows (struct frame *, int, int);
+ enum window_part *, bool);
+extern void resize_frame_windows (struct frame *, int, bool);
extern void delete_all_child_windows (Lisp_Object);
-extern void freeze_window_starts (struct frame *, int);
+extern void freeze_window_starts (struct frame *, bool);
extern void grow_mini_window (struct window *, int);
extern void shrink_mini_window (struct window *);
extern int window_relative_x_coord (struct window *, enum window_part, int);
@@ -906,7 +899,7 @@ void run_window_configuration_change_hook (struct frame *f);
it's not allowed. */
void set_window_buffer (Lisp_Object window, Lisp_Object buffer,
- int run_hooks_p, int keep_margins_p);
+ bool run_hooks_p, bool keep_margins_p);
/* This is the window where the echo area message was displayed. It
is always a minibuffer window, but it may not be the same window
@@ -947,20 +940,17 @@ extern void check_frame_size (struct frame *frame, int *rows, int *cols);
struct glyph *get_phys_cursor_glyph (struct window *w);
/* Value is non-zero if WINDOW is a valid window. */
-#define WINDOW_VALID_P(WINDOW) \
- (WINDOWP (WINDOW) \
- && (!NILP (XWINDOW (WINDOW)->buffer) \
- || !NILP (XWINDOW (WINDOW)->vchild) \
- || !NILP (XWINDOW (WINDOW)->hchild)))
-
-/* A window of any sort, leaf or interior, is "valid" if one
- of its buffer, vchild, or hchild members is non-nil. */
+#define WINDOW_VALID_P(WINDOW) \
+ (WINDOWP (WINDOW) && !NILP (XWINDOW (WINDOW)->contents)) \
+
+/* A window of any sort, leaf or interior, is "valid" if its
+ contents slot is non-nil. */
#define CHECK_VALID_WINDOW(WINDOW) \
CHECK_TYPE (WINDOW_VALID_P (WINDOW), Qwindow_valid_p, WINDOW)
/* Value is non-zero if WINDOW is a live window. */
#define WINDOW_LIVE_P(WINDOW) \
- (WINDOWP (WINDOW) && !NILP (XWINDOW (WINDOW)->buffer))
+ (WINDOWP (WINDOW) && BUFFERP (XWINDOW (WINDOW)->contents))
/* A window is "live" if and only if it shows a buffer. */
#define CHECK_LIVE_WINDOW(WINDOW) \
diff --git a/src/xdisp.c b/src/xdisp.c
index a5bba1a81cd..5ae15cbd0b3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -580,7 +580,7 @@ static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
/* Ascent and height of the last line processed by move_it_to. */
-static int last_max_ascent, last_height;
+static int last_height;
/* Non-zero if there's a help-echo in the echo area. */
@@ -794,6 +794,7 @@ static void set_iterator_to_next (struct it *, int);
static void mark_window_display_accurate_1 (struct window *, int);
static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
static int display_prop_string_p (Lisp_Object, Lisp_Object);
+static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
static int cursor_row_p (struct glyph_row *);
static int redisplay_mode_lines (Lisp_Object, int);
static char *decode_mode_spec_coding (Lisp_Object, char *, int);
@@ -880,7 +881,6 @@ static void next_overlay_string (struct it *);
static void reseat (struct it *, struct text_pos, int);
static void reseat_1 (struct it *, struct text_pos, int);
static void back_to_previous_visible_line_start (struct it *);
-void reseat_at_previous_visible_line_start (struct it *);
static void reseat_at_next_visible_line_start (struct it *, int);
static int next_element_from_ellipsis (struct it *);
static int next_element_from_display_vector (struct it *);
@@ -899,7 +899,6 @@ static int get_next_display_element (struct it *);
static enum move_it_result
move_it_in_display_line_to (struct it *, ptrdiff_t, int,
enum move_operation_enum);
-void move_it_vertically_backward (struct it *, int);
static void get_visually_first_element (struct it *);
static void init_to_row_start (struct it *, struct window *,
struct glyph_row *);
@@ -979,7 +978,7 @@ window_text_bottom_y (struct window *w)
int
window_box_width (struct window *w, int area)
{
- int cols = XFASTINT (w->total_cols);
+ int cols = w->total_cols;
int pixels = 0;
if (!w->pseudo_window_p)
@@ -1283,10 +1282,10 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
return visible_p;
- if (XBUFFER (w->buffer) != current_buffer)
+ if (XBUFFER (w->contents) != current_buffer)
{
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
}
SET_TEXT_POS_FROM_MARKER (top, w->start);
@@ -1372,18 +1371,41 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
top_x = it.glyph_row->x;
else
{
- struct it it2;
+ struct it it2, it2_prev;
+ /* The idea is to get to the previous buffer
+ position, consume the character there, and use
+ the pixel coordinates we get after that. But if
+ the previous buffer position is also displayed
+ from a display vector, we need to consume all of
+ the glyphs from that display vector. */
start_display (&it2, w, top);
move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
- get_next_display_element (&it2);
- PRODUCE_GLYPHS (&it2);
- if (ITERATOR_AT_END_OF_LINE_P (&it2)
- || it2.current_x > it2.last_visible_x)
+ /* If we didn't get to CHARPOS - 1, there's some
+ replacing display property at that position, and
+ we stopped after it. That is exactly the place
+ whose coordinates we want. */
+ if (IT_CHARPOS (it2) != charpos - 1)
+ it2_prev = it2;
+ else
+ {
+ /* Iterate until we get out of the display
+ vector that displays the character at
+ CHARPOS - 1. */
+ do {
+ get_next_display_element (&it2);
+ PRODUCE_GLYPHS (&it2);
+ it2_prev = it2;
+ set_iterator_to_next (&it2, 1);
+ } while (it2.method == GET_FROM_DISPLAY_VECTOR
+ && IT_CHARPOS (it2) < charpos);
+ }
+ if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
+ || it2_prev.current_x > it2_prev.last_visible_x)
top_x = it.glyph_row->x;
else
{
- top_x = it2.current_x;
- top_y = it2.current_y;
+ top_x = it2_prev.current_x;
+ top_y = it2_prev.current_y;
}
}
}
@@ -1392,23 +1414,34 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
Lisp_Object cpos = make_number (charpos);
Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
Lisp_Object string = string_from_display_spec (spec);
+ struct text_pos tpos;
+ int replacing_spec_p;
bool newline_in_string
= (STRINGP (string)
&& memchr (SDATA (string), '\n', SBYTES (string)));
+
+ SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
+ replacing_spec_p
+ = (!NILP (spec)
+ && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
+ charpos, FRAME_WINDOW_P (it.f)));
/* The tricky code below is needed because there's a
discrepancy between move_it_to and how we set cursor
- when the display line ends in a newline from a
- display string. move_it_to will stop _after_ such
- display strings, whereas set_cursor_from_row
- conspires with cursor_row_p to place the cursor on
- the first glyph produced from the display string. */
+ when PT is at the beginning of a portion of text
+ covered by a display property or an overlay with a
+ display property, or the display line ends in a
+ newline from a display string. move_it_to will stop
+ _after_ such display strings, whereas
+ set_cursor_from_row conspires with cursor_row_p to
+ place the cursor on the first glyph produced from the
+ display string. */
/* We have overshoot PT because it is covered by a
- display property whose value is a string. If the
- string includes embedded newlines, we are also in the
- wrong display line. Backtrack to the correct line,
- where the display string begins. */
- if (newline_in_string)
+ display property that replaces the text it covers.
+ If the string includes embedded newlines, we are also
+ in the wrong display line. Backtrack to the correct
+ line, where the display property begins. */
+ if (replacing_spec_p)
{
Lisp_Object startpos, endpos;
EMACS_INT start, end;
@@ -1434,7 +1467,8 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
rightmost character on a line that is
continued or word-wrapped. */
if (it3.method == GET_FROM_BUFFER
- && it3.c == '\n')
+ && (it3.c == '\n'
+ || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
move_it_by_lines (&it3, 1);
else if (move_it_in_display_line_to (&it3, -1,
it3.current_x
@@ -1502,6 +1536,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
produced from the string, until we find the
rightmost glyph not from the string. */
if (it3_moved
+ && newline_in_string
&& IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
{
struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
@@ -2677,7 +2712,7 @@ init_iterator (struct it *it, struct window *w,
and IT->region_end_charpos to the start and end of a visible region
in window IT->w. Set both to -1 to indicate no region. */
markpos = markpos_of_region ();
- if (0 <= markpos
+ if (markpos >= 0
/* Maybe highlight only in selected window. */
&& (/* Either show region everywhere. */
highlight_nonselected_windows
@@ -4458,7 +4493,7 @@ handle_display_prop (struct it *it)
if it was a text property. */
if (!STRINGP (it->string))
- object = it->w->buffer;
+ object = it->w->contents;
display_replaced_p = handle_display_spec (it, propval, object, overlay,
position, bufpos,
@@ -4866,7 +4901,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
it->what = IT_IMAGE;
it->image_id = -1; /* no image */
it->position = start_pos;
- it->object = NILP (object) ? it->w->buffer : object;
+ it->object = NILP (object) ? it->w->contents : object;
it->method = GET_FROM_IMAGE;
it->from_overlay = Qnil;
it->face_id = face_id;
@@ -5012,7 +5047,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
it->what = IT_IMAGE;
it->image_id = lookup_image (it->f, value);
it->position = start_pos;
- it->object = NILP (object) ? it->w->buffer : object;
+ it->object = NILP (object) ? it->w->contents : object;
it->method = GET_FROM_IMAGE;
/* Say that we haven't consumed the characters with
@@ -5836,7 +5871,7 @@ pop_it (struct it *it)
it->object = p->u.stretch.object;
break;
case GET_FROM_BUFFER:
- it->object = it->w->buffer;
+ it->object = it->w->contents;
break;
case GET_FROM_STRING:
it->object = it->string;
@@ -5849,7 +5884,7 @@ pop_it (struct it *it)
else
{
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
}
}
it->end_charpos = p->end_charpos;
@@ -6290,7 +6325,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
IT_STRING_BYTEPOS (*it) = -1;
it->string = Qnil;
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
it->area = TEXT_AREA;
it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
it->sp = 0;
@@ -7141,7 +7176,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
else
{
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
}
it->dpvec = NULL;
@@ -7153,6 +7188,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
else if (it->dpvec_char_len > 0)
{
if (it->method == GET_FROM_STRING
+ && it->current.overlay_string_index >= 0
&& it->n_overlay_strings > 0)
it->ignore_overlay_strings_at_pos_p = 1;
it->len = it->dpvec_char_len;
@@ -7714,7 +7750,7 @@ next_element_from_ellipsis (struct it *it)
setting face_before_selective_p. */
it->saved_face_id = it->face_id;
it->method = GET_FROM_BUFFER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
reseat_at_next_visible_line_start (it, 1);
it->face_before_selective_p = 1;
}
@@ -7978,7 +8014,7 @@ next_element_from_buffer (struct it *it)
/* Record what we have and where it came from. */
it->what = IT_CHARACTER;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
it->position = it->current.pos;
/* Normally we return the character found above, except when we
@@ -8084,7 +8120,7 @@ next_element_from_composition (struct it *it)
return 0;
}
it->position = it->current.pos;
- it->object = it->w->buffer;
+ it->object = it->w->contents;
it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it), Qnil);
}
@@ -8925,7 +8961,6 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
- last_max_ascent = it->max_ascent;
it->max_ascent = it->max_descent = 0;
}
@@ -8952,7 +8987,6 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
- last_max_ascent = it->max_ascent;
}
if (backup_data)
@@ -9524,7 +9558,15 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
shown = buffer_window_count (current_buffer) > 0;
set_buffer_internal (oldbuf);
- if (!shown)
+ /* We called insert_1_both above with its 5th argument (PREPARE)
+ zero, which prevents insert_1_both from calling
+ prepare_to_modify_buffer, which in turns prevents us from
+ incrementing windows_or_buffers_changed even if *Messages* is
+ shown in some window. So we must manually incrementing
+ windows_or_buffers_changed here to make up for that. */
+ if (shown)
+ windows_or_buffers_changed++;
+ else
windows_or_buffers_changed = old_windows_or_buffers_changed;
message_log_need_newline = !nlflag;
Vdeactivate_mark = old_deactivate_mark;
@@ -9994,7 +10036,7 @@ with_echo_area_buffer_unwind_data (struct window *w)
Vwith_echo_area_save_vector = Qnil;
if (NILP (vector))
- vector = Fmake_vector (make_number (7), Qnil);
+ vector = Fmake_vector (make_number (9), Qnil);
XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
ASET (vector, i, Vdeactivate_mark); ++i;
@@ -10003,13 +10045,15 @@ with_echo_area_buffer_unwind_data (struct window *w)
if (w)
{
XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
- ASET (vector, i, w->buffer); ++i;
+ ASET (vector, i, w->contents); ++i;
ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
+ ASET (vector, i, make_number (marker_position (w->start))); ++i;
+ ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
}
else
{
- int end = i + 4;
+ int end = i + 6;
for (; i < end; ++i)
ASET (vector, i, Qnil);
}
@@ -10032,16 +10076,18 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
if (WINDOWP (AREF (vector, 3)))
{
struct window *w;
- Lisp_Object buffer, charpos, bytepos;
+ Lisp_Object buffer;
w = XWINDOW (AREF (vector, 3));
buffer = AREF (vector, 4);
- charpos = AREF (vector, 5);
- bytepos = AREF (vector, 6);
wset_buffer (w, buffer);
set_marker_both (w->pointm, buffer,
- XFASTINT (charpos), XFASTINT (bytepos));
+ XFASTINT (AREF (vector, 5)),
+ XFASTINT (AREF (vector, 6)));
+ set_marker_both (w->start, buffer,
+ XFASTINT (AREF (vector, 7)),
+ XFASTINT (AREF (vector, 8)));
}
Vwith_echo_area_save_vector = vector;
@@ -10255,9 +10301,9 @@ resize_mini_window (struct window *w, int exact_p)
eassert (MINI_WINDOW_P (w));
/* By default, start display at the beginning. */
- set_marker_both (w->start, w->buffer,
- BUF_BEGV (XBUFFER (w->buffer)),
- BUF_BEGV_BYTE (XBUFFER (w->buffer)));
+ set_marker_both (w->start, w->contents,
+ BUF_BEGV (XBUFFER (w->contents)),
+ BUF_BEGV_BYTE (XBUFFER (w->contents)));
/* Don't resize windows while redisplaying a window; it would
confuse redisplay functions when the size of the window they are
@@ -10284,10 +10330,10 @@ resize_mini_window (struct window *w, int exact_p)
struct text_pos start;
struct buffer *old_current_buffer = NULL;
- if (current_buffer != XBUFFER (w->buffer))
+ if (current_buffer != XBUFFER (w->contents))
{
old_current_buffer = current_buffer;
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
}
init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
@@ -10736,7 +10782,7 @@ buffer_shared_and_changed (void)
/* Nonzero if W doesn't reflect the actual state of current buffer due
to its text or overlays change. FIXME: this may be called when
- XBUFFER (w->buffer) != current_buffer, which looks suspicious. */
+ XBUFFER (w->contents) != current_buffer, which looks suspicious. */
static int
window_outdated (struct window *w)
@@ -10751,7 +10797,7 @@ window_outdated (struct window *w)
static int
window_buffer_changed (struct window *w)
{
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
eassert (BUFFER_LIVE_P (b));
@@ -11005,7 +11051,7 @@ x_consider_frame_title (Lisp_Object frame)
Fselect_window (f->selected_window, Qt);
set_buffer_internal_1
- (XBUFFER (XWINDOW (f->selected_window)->buffer));
+ (XBUFFER (XWINDOW (f->selected_window)->contents));
fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
mode_line_target = MODE_LINE_TITLE;
@@ -11124,7 +11170,7 @@ prepare_menu_bars (void)
if (windows_or_buffers_changed
&& FRAME_NS_P (f))
ns_set_doc_edited
- (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer));
+ (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
#endif
UNGCPRO;
}
@@ -11196,7 +11242,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
specbind (Qinhibit_menubar_update, Qt);
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
if (save_match_data)
record_unwind_save_match_data ();
if (NILP (Voverriding_local_map_menu_flag))
@@ -11400,7 +11446,7 @@ update_tool_bar (struct frame *f, int save_match_data)
/* Set current_buffer to the buffer of the selected
window of the frame, so that we get the right local
keymaps. */
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
/* Save match data, if we must. */
if (save_match_data)
@@ -12267,10 +12313,8 @@ hscroll_window_tree (Lisp_Object window)
{
struct window *w = XWINDOW (window);
- if (WINDOWP (w->hchild))
- hscrolled_p |= hscroll_window_tree (w->hchild);
- else if (WINDOWP (w->vchild))
- hscrolled_p |= hscroll_window_tree (w->vchild);
+ if (WINDOWP (w->contents))
+ hscrolled_p |= hscroll_window_tree (w->contents);
else if (w->cursor.vpos >= 0)
{
int h_margin;
@@ -12290,7 +12334,7 @@ hscroll_window_tree (Lisp_Object window)
/* Scroll when cursor is inside this scroll margin. */
h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
- if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
+ if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
/* For left-to-right rows, hscroll when cursor is either
(i) inside the right hscroll margin, or (ii) if it is
inside the left margin and the window is already
@@ -12325,7 +12369,7 @@ hscroll_window_tree (Lisp_Object window)
/* Find point in a display of infinite width. */
saved_current_buffer = current_buffer;
- current_buffer = XBUFFER (w->buffer);
+ current_buffer = XBUFFER (w->contents);
if (w == XWINDOW (selected_window))
pt = PT;
@@ -12378,7 +12422,7 @@ hscroll_window_tree (Lisp_Object window)
redisplay. */
if (w->hscroll != hscroll)
{
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
w->hscroll = hscroll;
hscrolled_p = 1;
}
@@ -12467,9 +12511,9 @@ debug_method_add (struct window *w, char const *fmt, ...)
if (trace_redisplay_p)
fprintf (stderr, "%p (%s): %s\n",
w,
- ((BUFFERP (w->buffer)
- && STRINGP (BVAR (XBUFFER (w->buffer), name)))
- ? SSDATA (BVAR (XBUFFER (w->buffer), name))
+ ((BUFFERP (w->contents)
+ && STRINGP (BVAR (XBUFFER (w->contents), name)))
+ ? SSDATA (BVAR (XBUFFER (w->contents), name))
: "no buffer"),
method + len);
}
@@ -12533,8 +12577,8 @@ text_outside_line_unchanged_p (struct window *w,
require to redisplay the whole paragraph. It might be worthwhile
to find the paragraph limits and widen the range of redisplayed
lines to that, but for now just give up this optimization. */
- if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
- && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
+ if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
+ && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
unchanged_p = 0;
}
@@ -12757,7 +12801,7 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
we set b->clip_changed to 1 to force updating the screen. If
b->clip_changed has already been set to 1, we can skip this
check. */
- if (!b->clip_changed && BUFFERP (w->buffer) && w->window_end_valid)
+ if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid)
{
ptrdiff_t pt;
@@ -12766,11 +12810,11 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
else
pt = marker_position (w->pointm);
- if ((w->current_matrix->buffer != XBUFFER (w->buffer)
+ if ((w->current_matrix->buffer != XBUFFER (w->contents)
|| pt != w->last_point)
&& check_point_in_composition (w->current_matrix->buffer,
w->last_point,
- XBUFFER (w->buffer), pt))
+ XBUFFER (w->contents), pt))
b->clip_changed = 1;
}
}
@@ -12802,7 +12846,6 @@ redisplay_internal (void)
struct frame *sf;
int polling_stopped_here = 0;
Lisp_Object tail, frame;
- struct backtrace backtrace;
/* Non-zero means redisplay has to consider all windows on all
frames. Zero means, only selected_window is considered. */
@@ -12846,12 +12889,7 @@ redisplay_internal (void)
specbind (Qinhibit_free_realized_faces, Qnil);
/* Record this function, so it appears on the profiler's backtraces. */
- backtrace.next = backtrace_list;
- backtrace.function = Qredisplay_internal;
- backtrace.args = &Qnil;
- backtrace.nargs = 0;
- backtrace.debug_on_exit = 0;
- backtrace_list = &backtrace;
+ record_in_backtrace (Qredisplay_internal, &Qnil, 0);
FOR_EACH_FRAME (tail, frame)
XFRAME (frame)->already_hscrolled_p = 0;
@@ -12948,8 +12986,6 @@ redisplay_internal (void)
unbind_to (count1, Qnil);
- FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
-
consider_all_windows_p = (update_mode_lines
|| buffer_shared_and_changed ()
|| cursor_type_changed);
@@ -13025,11 +13061,11 @@ redisplay_internal (void)
the whole window. The assignment to this_line_start_pos prevents
the optimization directly below this if-statement. */
if (((!NILP (Vtransient_mark_mode)
- && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
+ && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
!= (w->region_showing > 0))
|| (w->region_showing
&& w->region_showing
- != XINT (Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
+ != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
CHARPOS (this_line_start_pos) = 0;
/* Optimize the case that only the line containing the cursor in the
@@ -13047,7 +13083,7 @@ redisplay_internal (void)
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
/* Make sure recorded data applies to current buffer, etc. */
&& this_line_buffer == current_buffer
- && current_buffer == XBUFFER (w->buffer)
+ && current_buffer == XBUFFER (w->contents)
&& !w->force_start
&& !w->optional_new_start
/* Point must be on the line that we have info recorded about. */
@@ -13171,7 +13207,7 @@ redisplay_internal (void)
/* Make sure the cursor was last displayed
in this window. Otherwise we have to reposition it. */
&& 0 <= w->cursor.vpos
- && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
+ && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
{
if (!must_finish)
{
@@ -13338,7 +13374,7 @@ redisplay_internal (void)
Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
struct frame *mini_frame;
- displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
+ displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
/* Use list_of_error, not Qerror, so that
we catch only errors and don't run the debugger. */
internal_condition_case_1 (redisplay_window_1, selected_window,
@@ -13490,7 +13526,6 @@ redisplay_internal (void)
#endif /* HAVE_WINDOW_SYSTEM */
end_of_redisplay:
- backtrace_list = backtrace.next;
unbind_to (count, Qnil);
RESUME_POLLING;
}
@@ -13548,7 +13583,7 @@ unwind_redisplay (Lisp_Object old_frame)
static void
mark_window_display_accurate_1 (struct window *w, int accurate_p)
{
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
@@ -13595,11 +13630,9 @@ mark_window_display_accurate (Lisp_Object window, int accurate_p)
for (; !NILP (window); window = w->next)
{
w = XWINDOW (window);
- if (!NILP (w->vchild))
- mark_window_display_accurate (w->vchild, accurate_p);
- else if (!NILP (w->hchild))
- mark_window_display_accurate (w->hchild, accurate_p);
- else if (BUFFERP (w->buffer))
+ if (WINDOWP (w->contents))
+ mark_window_display_accurate (w->contents, accurate_p);
+ else
mark_window_display_accurate_1 (w, accurate_p);
}
@@ -13656,13 +13689,11 @@ redisplay_windows (Lisp_Object window)
{
struct window *w = XWINDOW (window);
- if (!NILP (w->hchild))
- redisplay_windows (w->hchild);
- else if (!NILP (w->vchild))
- redisplay_windows (w->vchild);
- else if (!NILP (w->buffer))
+ if (WINDOWP (w->contents))
+ redisplay_windows (w->contents);
+ else if (BUFFERP (w->contents))
{
- displayed_buffer = XBUFFER (w->buffer);
+ displayed_buffer = XBUFFER (w->contents);
/* Use list_of_error, not Qerror, so that
we catch only errors and don't run the debugger. */
internal_condition_case_1 (redisplay_window_0, window,
@@ -14309,7 +14340,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
&& !MATRIX_ROW_CONTINUATION_LINE_P (row)
&& row->x == 0)
{
- this_line_buffer = XBUFFER (w->buffer);
+ this_line_buffer = XBUFFER (w->contents);
CHARPOS (this_line_start_pos)
= MATRIX_ROW_START_CHARPOS (row) + delta;
@@ -14345,7 +14376,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
struct window *w = XWINDOW (window);
SET_MARKER_FROM_TEXT_POS (w->start, startp);
- if (current_buffer != XBUFFER (w->buffer))
+ if (current_buffer != XBUFFER (w->contents))
emacs_abort ();
if (!NILP (Vwindow_scroll_functions))
@@ -14354,7 +14385,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
make_number (CHARPOS (startp)));
SET_TEXT_POS_FROM_MARKER (startp, w->start);
/* In case the hook functions switch buffers. */
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
}
return startp;
@@ -15005,7 +15036,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
must_scroll = 1;
}
else if (rc != CURSOR_MOVEMENT_SUCCESS
- && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
+ && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
{
struct glyph_row *row1;
@@ -15068,7 +15099,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
else if (scroll_p)
rc = CURSOR_MOVEMENT_MUST_SCROLL;
else if (rc != CURSOR_MOVEMENT_SUCCESS
- && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
+ && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
{
/* With bidi-reordered rows, there could be more than
one candidate row whose start and end positions
@@ -15175,7 +15206,7 @@ set_vertical_scroll_bar (struct window *w)
|| (w == XWINDOW (minibuf_window)
&& NILP (echo_area_buffer[0])))
{
- struct buffer *buf = XBUFFER (w->buffer);
+ struct buffer *buf = XBUFFER (w->contents);
whole = BUF_ZV (buf) - BUF_BEGV (buf);
start = marker_position (w->start) - BUF_BEGV (buf);
/* I don't think this is guaranteed to be right. For the
@@ -15209,7 +15240,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
struct buffer *old = current_buffer;
struct text_pos lpoint, opoint, startp;
int update_mode_line;
@@ -15231,12 +15262,14 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
SET_TEXT_POS (lpoint, PT, PT_BYTE);
opoint = lpoint;
- /* W must be a leaf window here. */
- eassert (!NILP (w->buffer));
#ifdef GLYPH_DEBUG
*w->desired_matrix->method = 0;
#endif
+ /* Make sure that both W's markers are valid. */
+ eassert (XMARKER (w->start)->buffer == buffer);
+ eassert (XMARKER (w->pointm)->buffer == buffer);
+
restart:
reconsider_clip_changes (w, buffer);
@@ -15262,10 +15295,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
else if ((w != XWINDOW (minibuf_window)
|| minibuf_level == 0)
/* When buffer is nonempty, redisplay window normally. */
- && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
+ && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
/* Quail displays non-mini buffers in minibuffer window.
In that case, redisplay the window normally. */
- && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
+ && !NILP (Fmemq (w->contents, Vminibuffer_list)))
{
/* W is a mini-buffer window, but it's not active, so clear
it. */
@@ -15287,7 +15320,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
value. */
/* Really select the buffer, for the sake of buffer-local
variables. */
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
current_matrix_up_to_date_p
= (w->window_end_valid
@@ -15520,7 +15553,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
/* If we are highlighting the region, then we just changed
the region, so redisplay to show it. */
- if (0 <= markpos_of_region ())
+ if (markpos_of_region () >= 0)
{
clear_glyph_matrix (w->desired_matrix);
if (!try_window (window, startp, 0))
@@ -16221,7 +16254,7 @@ try_window_reusing_current_matrix (struct window *w)
return 0;
/* Can't do this if region may have changed. */
- if (0 <= markpos_of_region ()
+ if (markpos_of_region () >= 0
|| w->region_showing
|| !NILP (Vshow_trailing_whitespace))
return 0;
@@ -16578,7 +16611,7 @@ try_window_reusing_current_matrix (struct window *w)
bidi-reordered glyph rows. Let set_cursor_from_row
figure out where to put the cursor, and if it fails,
give up. */
- if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
+ if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
{
if (!set_cursor_from_row (w, row, w->current_matrix,
0, 0, 0, 0))
@@ -16829,7 +16862,7 @@ sync_frame_with_window_matrix_rows (struct window *w)
/* Preconditions: W must be a leaf window and full-width. Its frame
must have a frame matrix. */
- eassert (NILP (w->hchild) && NILP (w->vchild));
+ eassert (BUFFERP (w->contents));
eassert (WINDOW_FULL_WIDTH_P (w));
eassert (!FRAME_WINDOW_P (f));
@@ -16871,7 +16904,7 @@ row_containing_pos (struct window *w, ptrdiff_t charpos,
{
struct glyph_row *row = start;
struct glyph_row *best_row = NULL;
- ptrdiff_t mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
+ ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
int last_y;
/* If we happen to start on a header-line, skip that. */
@@ -16899,21 +16932,20 @@ row_containing_pos (struct window *w, ptrdiff_t charpos,
|| (MATRIX_ROW_END_CHARPOS (row) == charpos
/* The end position of a row equals the start
position of the next row. If CHARPOS is there, we
- would rather display it in the next line, except
- when this line ends in ZV. */
- && !row->ends_at_zv_p
- && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
+ would rather consider it displayed in the next
+ line, except when this line ends in ZV. */
+ && !row_for_charpos_p (row, charpos)))
&& charpos >= MATRIX_ROW_START_CHARPOS (row))
{
struct glyph *g;
- if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
+ if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
|| (!best_row && !row->continued_p))
return row;
- /* In bidi-reordered rows, there could be several rows
- occluding point, all of them belonging to the same
- continued line. We need to find the row which fits
- CHARPOS the best. */
+ /* In bidi-reordered rows, there could be several rows whose
+ edges surround CHARPOS, all of these rows belonging to
+ the same continued line. We need to find the row which
+ fits CHARPOS the best. */
for (g = row->glyphs[TEXT_AREA];
g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
g++)
@@ -17053,7 +17085,7 @@ try_window_id (struct window *w)
/* Can't use this if highlighting a region because a cursor movement
will do more than just set the cursor. */
- if (0 <= markpos_of_region ())
+ if (markpos_of_region () >= 0)
GIVE_UP (9);
/* Likewise if highlighting trailing whitespace. */
@@ -17073,7 +17105,7 @@ try_window_id (struct window *w)
wrapped line can change the wrap position, altering the line
above it. It might be worthwhile to handle this more
intelligently, but for now just redisplay from scratch. */
- if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
+ if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
GIVE_UP (21);
/* Under bidi reordering, adding or deleting a character in the
@@ -17084,8 +17116,8 @@ try_window_id (struct window *w)
to find the paragraph limits and widen the range of redisplayed
lines to that, but for now just give up this optimization and
redisplay from scratch. */
- if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
- && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
+ if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
+ && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
GIVE_UP (22);
/* Make sure beg_unchanged and end_unchanged are up to date. Do it
@@ -17950,7 +17982,7 @@ glyphs in short form, otherwise show glyphs in long form. */)
(Lisp_Object glyphs)
{
struct window *w = XWINDOW (selected_window);
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
@@ -18056,7 +18088,7 @@ static struct glyph_row *
get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
struct buffer *old = current_buffer;
const unsigned char *arrow_string = SDATA (overlay_arrow_string);
int arrow_len = SCHARS (overlay_arrow_string);
@@ -18717,15 +18749,15 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
/* Value is non-zero if glyph row ROW should be
- used to hold the cursor. */
+ considered to hold the buffer position CHARPOS. */
static int
-cursor_row_p (struct glyph_row *row)
+row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
{
int result = 1;
- if (PT == CHARPOS (row->end.pos)
- || PT == MATRIX_ROW_END_CHARPOS (row))
+ if (charpos == CHARPOS (row->end.pos)
+ || charpos == MATRIX_ROW_END_CHARPOS (row))
{
/* Suppose the row ends on a string.
Unless the row is continued, that means it ends on a newline
@@ -18751,7 +18783,7 @@ cursor_row_p (struct glyph_row *row)
if (STRINGP (glyph->object))
{
Lisp_Object prop
- = Fget_char_property (make_number (PT),
+ = Fget_char_property (make_number (charpos),
Qdisplay, Qnil);
result =
(!NILP (prop)
@@ -18805,6 +18837,15 @@ cursor_row_p (struct glyph_row *row)
return result;
}
+/* Value is non-zero if glyph row ROW should be
+ used to hold the cursor. */
+
+static int
+cursor_row_p (struct glyph_row *row)
+{
+ return row_for_charpos_p (row, PT);
+}
+
/* Push the property PROP so that it will be rendered at the current
@@ -19263,7 +19304,7 @@ display_line (struct it *it)
row->glyphs[TEXT_AREA]->charpos = -1;
row->displays_text_p = 0;
- if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
+ if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
&& (!MINI_WINDOW_P (it->w)
|| (minibuf_level && EQ (it->window, minibuf_window))))
row->indicate_empty_line_p = 1;
@@ -19988,18 +20029,17 @@ display_menu_bar (struct window *w)
return;
#endif /* HAVE_NS */
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
eassert (!FRAME_WINDOW_P (f));
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
it.first_visible_x = 0;
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
-#else /* not USE_X_TOOLKIT */
+#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
if (FRAME_WINDOW_P (f))
{
/* Menu bar lines are displayed in the desired matrix of the
dummy window menu_bar_window. */
struct window *menu_w;
- eassert (WINDOWP (f->menu_bar_window));
menu_w = XWINDOW (f->menu_bar_window);
init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
MENU_FACE_ID);
@@ -20007,6 +20047,7 @@ display_menu_bar (struct window *w)
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
}
else
+#endif /* not USE_X_TOOLKIT and not USE_GTK */
{
/* This is a TTY frame, i.e. character hpos/vpos are used as
pixel x/y. */
@@ -20015,7 +20056,6 @@ display_menu_bar (struct window *w)
it.first_visible_x = 0;
it.last_visible_x = FRAME_COLS (f);
}
-#endif /* not USE_X_TOOLKIT */
/* FIXME: This should be controlled by a user option. See the
comments in redisplay_tool_bar and display_mode_line about
@@ -20079,10 +20119,8 @@ redisplay_mode_lines (Lisp_Object window, int force)
{
struct window *w = XWINDOW (window);
- if (WINDOWP (w->hchild))
- nwindows += redisplay_mode_lines (w->hchild, force);
- else if (WINDOWP (w->vchild))
- nwindows += redisplay_mode_lines (w->vchild, force);
+ if (WINDOWP (w->contents))
+ nwindows += redisplay_mode_lines (w->contents, force);
else if (force
|| FRAME_GARBAGED_P (XFRAME (w->frame))
|| !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
@@ -20092,7 +20130,7 @@ redisplay_mode_lines (Lisp_Object window, int force)
/* Set the window's buffer for the mode line display. */
SET_TEXT_POS (lpoint, PT, PT_BYTE);
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (w->contents));
/* Point refers normally to the selected window. For any
other window, set up appropriate value. */
@@ -20874,7 +20912,7 @@ are the selected window and the WINDOW's buffer). */)
XSETWINDOW (window, w);
if (NILP (buffer))
- buffer = w->buffer;
+ buffer = w->contents;
CHECK_BUFFER (buffer);
/* Make formatting the modeline a non-op when noninteractive, otherwise
@@ -21009,7 +21047,7 @@ pint2hrstr (char *buf, int width, ptrdiff_t d)
char * psuffix;
char * p;
- if (1000 <= quotient)
+ if (quotient >= 1000)
{
/* Scale to the appropriate EXPONENT. */
do
@@ -21018,13 +21056,13 @@ pint2hrstr (char *buf, int width, ptrdiff_t d)
quotient /= 1000;
exponent++;
}
- while (1000 <= quotient);
+ while (quotient >= 1000);
/* Round to nearest and decide whether to use TENTHS or not. */
if (quotient <= 9)
{
tenths = remainder / 100;
- if (50 <= remainder % 100)
+ if (remainder % 100 >= 50)
{
if (tenths < 9)
tenths++;
@@ -21039,7 +21077,7 @@ pint2hrstr (char *buf, int width, ptrdiff_t d)
}
}
else
- if (500 <= remainder)
+ if (remainder >= 500)
{
if (quotient < 999)
quotient++;
@@ -22082,11 +22120,6 @@ else if the text is replaced by an ellipsis. */)
*/
-#define NUMVAL(X) \
- ((INTEGERP (X) || FLOATP (X)) \
- ? XFLOATINT (X) \
- : - 1)
-
static int
calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
struct font *font, int width_p, int *align_to)
@@ -22117,24 +22150,11 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
pixels = 0;
if (pixels > 0)
{
- double ppi;
-#ifdef HAVE_WINDOW_SYSTEM
- if (FRAME_WINDOW_P (it->f)
- && (ppi = (width_p
- ? FRAME_X_DISPLAY_INFO (it->f)->resx
- : FRAME_X_DISPLAY_INFO (it->f)->resy),
- ppi > 0))
- return OK_PIXELS (ppi / pixels);
-#endif
+ double ppi = (width_p ? FRAME_RES_X (it->f)
+ : FRAME_RES_Y (it->f));
- if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
- || (CONSP (Vdisplay_pixels_per_inch)
- && (ppi = (width_p
- ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
- : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
- ppi > 0)))
+ if (ppi > 0)
return OK_PIXELS (ppi / pixels);
-
return 0;
}
}
@@ -22198,7 +22218,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
}
- prop = buffer_local_value_1 (prop, it->w->buffer);
+ prop = buffer_local_value_1 (prop, it->w->contents);
if (EQ (prop, Qunbound))
prop = Qnil;
}
@@ -22250,7 +22270,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
return OK_PIXELS (pixels);
}
- car = buffer_local_value_1 (car, it->w->buffer);
+ car = buffer_local_value_1 (car, it->w->contents);
if (EQ (car, Qunbound))
car = Qnil;
}
@@ -22410,16 +22430,16 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id,
XChar2b *char2b, int display_p)
{
struct face *face = FACE_FROM_ID (f, face_id);
+ unsigned code = 0;
if (face->font)
{
- unsigned code = face->font->driver->encode_char (face->font, c);
+ code = face->font->driver->encode_char (face->font, c);
- if (code != FONT_INVALID_CODE)
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
- else
- STORE_XCHAR2B (char2b, 0, 0);
+ if (code == FONT_INVALID_CODE)
+ code = 0;
}
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
/* Make sure X resources of the face are allocated. */
#ifdef HAVE_X_WINDOWS
@@ -22443,31 +22463,30 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
XChar2b *char2b, int *two_byte_p)
{
struct face *face;
+ unsigned code = 0;
eassert (glyph->type == CHAR_GLYPH);
face = FACE_FROM_ID (f, glyph->face_id);
+ /* Make sure X resources of the face are allocated. */
+ eassert (face != NULL);
+ PREPARE_FACE_FOR_DISPLAY (f, face);
+
if (two_byte_p)
*two_byte_p = 0;
if (face->font)
{
- unsigned code;
-
if (CHAR_BYTE8_P (glyph->u.ch))
code = CHAR_TO_BYTE8 (glyph->u.ch);
else
code = face->font->driver->encode_char (face->font, glyph->u.ch);
- if (code != FONT_INVALID_CODE)
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
- else
- STORE_XCHAR2B (char2b, 0, 0);
+ if (code == FONT_INVALID_CODE)
+ code = 0;
}
- /* Make sure X resources of the face are allocated. */
- eassert (face != NULL);
- PREPARE_FACE_FOR_DISPLAY (f, face);
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
return face;
}
@@ -22777,9 +22796,12 @@ static struct font_metrics *
get_per_char_metric (struct font *font, XChar2b *char2b)
{
static struct font_metrics metrics;
- unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
+ unsigned code;
- if (! font || code == FONT_INVALID_CODE)
+ if (! font)
+ return NULL;
+ code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
+ if (code == FONT_INVALID_CODE)
return NULL;
font->driver->text_extents (font, &code, 1, &metrics);
return &metrics;
@@ -24100,7 +24122,7 @@ produce_stretch_glyph (struct it *it)
int n = width;
if (!STRINGP (object))
- object = it->w->buffer;
+ object = it->w->contents;
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (it->f))
append_stretch_glyph (it, object, width, height, ascent);
@@ -25496,7 +25518,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
int *active_cursor)
{
struct frame *f = XFRAME (w->frame);
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
int cursor_type = DEFAULT_CURSOR;
Lisp_Object alt_cursor;
int non_selected = 0;
@@ -26047,10 +26069,8 @@ update_cursor_in_window_tree (struct window *w, int on_p)
{
while (w)
{
- if (!NILP (w->hchild))
- update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
- else if (!NILP (w->vchild))
- update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
+ if (WINDOWP (w->contents))
+ update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
else
update_window_cursor (w, on_p);
@@ -27296,7 +27316,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
{
help_echo_string = help;
XSETWINDOW (help_echo_window, w);
- help_echo_object = w->buffer;
+ help_echo_object = w->contents;
help_echo_pos = charpos;
}
}
@@ -27332,7 +27352,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
{
Lisp_Object default_help
= buffer_local_value_1 (Qmode_line_default_help_echo,
- w->buffer);
+ w->contents);
if (STRINGP (default_help))
{
@@ -27607,7 +27627,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
/* Are we in a window whose display is up to date?
And verify the buffer's text has not changed. */
- b = XBUFFER (w->buffer);
+ b = XBUFFER (w->contents);
if (part == ON_TEXT
&& w->window_end_valid
&& w->last_modified == BUF_MODIFF (b)
@@ -27816,8 +27836,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
if (pos > 0)
{
mouse_face = get_char_property_and_overlay
- (make_number (pos), Qmouse_face, w->buffer, &overlay);
- buffer = w->buffer;
+ (make_number (pos), Qmouse_face, w->contents, &overlay);
+ buffer = w->contents;
disp_string = object;
}
}
@@ -27930,11 +27950,11 @@ note_mouse_highlight (struct frame *f, int x, int y)
if (p > 0)
{
help = Fget_char_property (make_number (p),
- Qhelp_echo, w->buffer);
+ Qhelp_echo, w->contents);
if (!NILP (help))
{
charpos = p;
- obj = w->buffer;
+ obj = w->contents;
}
}
}
@@ -27985,7 +28005,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
ptrdiff_t p = string_buffer_position (obj, start);
if (p > 0)
pointer = Fget_char_property (make_number (p),
- Qpointer, w->buffer);
+ Qpointer, w->contents);
}
}
else if (BUFFERP (obj)
@@ -28428,12 +28448,9 @@ expose_window_tree (struct window *w, XRectangle *r)
while (w && !FRAME_GARBAGED_P (f))
{
- if (!NILP (w->hchild))
+ if (WINDOWP (w->contents))
mouse_face_overwritten_p
- |= expose_window_tree (XWINDOW (w->hchild), r);
- else if (!NILP (w->vchild))
- mouse_face_overwritten_p
- |= expose_window_tree (XWINDOW (w->vchild), r);
+ |= expose_window_tree (XWINDOW (w->contents), r);
else
mouse_face_overwritten_p |= expose_window (w, r);
@@ -28498,11 +28515,11 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
#ifdef HAVE_X_WINDOWS
#ifndef MSDOS
-#ifndef USE_X_TOOLKIT
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
if (WINDOWP (f->menu_bar_window))
mouse_face_overwritten_p
|= expose_window (XWINDOW (f->menu_bar_window), &r);
-#endif /* not USE_X_TOOLKIT */
+#endif /* not USE_X_TOOLKIT and not USE_GTK */
#endif
#endif
@@ -29236,13 +29253,13 @@ init_xdisp (void)
echo_area_window = minibuf_window;
- wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
- wset_total_lines
- (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)));
- wset_total_cols (r, make_number (FRAME_COLS (f)));
- wset_top_line (m, make_number (FRAME_LINES (f) - 1));
- wset_total_lines (m, make_number (1));
- wset_total_cols (m, make_number (FRAME_COLS (f)));
+ r->top_line = FRAME_TOP_MARGIN (f);
+ r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+ r->total_cols = FRAME_COLS (f);
+
+ m->top_line = FRAME_LINES (f) - 1;
+ m->total_lines = 1;
+ m->total_cols = FRAME_COLS (f);
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]
diff --git a/src/xfaces.c b/src/xfaces.c
index 71709446c1d..b2ace1be14e 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -112,7 +112,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
merging faces of that character, that face is `realized'. The
realization process maps face attributes to what is physically
available on the system where Emacs runs. The result is a
- `realized face' in form of a struct face which is stored in the
+ `realized face' in the form of a struct face which is stored in the
face cache of the frame on which it was realized.
Face realization is done in the context of the character to display
@@ -231,7 +231,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#undef FRAME_X_DISPLAY_INFO
#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
#define x_display_info w32_display_info
-#define check_x check_w32
#define GCGraphicsExposures 0
#endif /* HAVE_NTGUI */
@@ -239,7 +238,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#undef FRAME_X_DISPLAY_INFO
#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
#define x_display_info ns_display_info
-#define check_x check_ns
#define GCGraphicsExposures 0
#endif /* HAVE_NS */
#endif /* HAVE_WINDOW_SYSTEM */
@@ -1592,7 +1590,7 @@ the face font sort order. */)
ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
- XFRAME (frame)->resy);
+ FRAME_RES_Y (XFRAME (frame)));
ASET (v, 2, make_number (point));
ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
@@ -1636,7 +1634,7 @@ the WIDTH times as wide as FACE on FRAME. */)
struct frame *f;
int size, avgwidth IF_LINT (= 0);
- check_x ();
+ check_window_system (NULL);
CHECK_STRING (pattern);
if (! NILP (maximum))
@@ -1645,8 +1643,8 @@ the WIDTH times as wide as FACE on FRAME. */)
if (!NILP (width))
CHECK_NUMBER (width);
- /* We can't simply call check_x_frame because this function may be
- called before any frame is created. */
+ /* We can't simply call decode_window_system_frame because
+ this function may be called before any frame is created. */
f = decode_live_frame (frame);
if (! FRAME_WINDOW_P (f))
{
@@ -2118,7 +2116,7 @@ set_lface_from_font (struct frame *f, Lisp_Object lface,
if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
{
- int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy);
+ int pt = PIXEL_TO_POINT (font->pixel_size * 10, FRAME_RES_Y (f));
eassert (pt > 0);
ASET (lface, LFACE_HEIGHT_INDEX, make_number (pt));
@@ -3395,21 +3393,22 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
}
}
-
-/* Get the value of X resource RESOURCE, class CLASS for the display
- of frame FRAME. This is here because ordinary `x-get-resource'
- doesn't take a frame argument. */
-
DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
- Sinternal_face_x_get_resource, 3, 3, 0, doc: /* */)
+ Sinternal_face_x_get_resource, 2, 3, 0,
+ doc: /* Get the value of X resource RESOURCE, class CLASS.
+Returned value is for the display of frame FRAME. If FRAME is not
+specified or nil, use selected frame. This function exists because
+ordinary `x-get-resource' doesn't take a frame argument. */)
(Lisp_Object resource, Lisp_Object class, Lisp_Object frame)
{
Lisp_Object value = Qnil;
+ struct frame *f;
+
CHECK_STRING (resource);
CHECK_STRING (class);
- CHECK_LIVE_FRAME (frame);
+ f = decode_live_frame (frame);
block_input ();
- value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)),
+ value = display_x_get_resource (FRAME_X_DISPLAY_INFO (f),
resource, class, Qnil, Qnil);
unblock_input ();
return value;
@@ -3924,8 +3923,8 @@ If FRAME is omitted or nil, use the selected frame. */)
struct frame *f;
Lisp_Object lface1, lface2;
- /* Don't use check_x_frame here because this function is called
- before X frames exist. At that time, if FRAME is nil,
+ /* Don't use decode_window_system_frame here because this function
+ is called before X frames exist. At that time, if FRAME is nil,
selected_frame will be used which is the frame dumped with
Emacs. That frame is not an X frame. */
f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
@@ -5963,7 +5962,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
/* W must display the current buffer. We could write this function
to use the frame and buffer of W, but right now it doesn't. */
- /* eassert (XBUFFER (w->buffer) == current_buffer); */
+ /* eassert (XBUFFER (w->contents) == current_buffer); */
XSETFASTINT (position, pos);
@@ -5973,9 +5972,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
/* Get the `face' or `mouse_face' text property at POS, and
determine the next position at which the property changes. */
- prop = Fget_text_property (position, propname, w->buffer);
+ prop = Fget_text_property (position, propname, w->contents);
XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
- end = Fnext_single_property_change (position, propname, w->buffer, limit1);
+ end = Fnext_single_property_change (position, propname, w->contents, limit1);
if (INTEGERP (end))
endpos = XINT (end);
@@ -6071,7 +6070,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
/* W must display the current buffer. We could write this function
to use the frame and buffer of W, but right now it doesn't. */
- /* eassert (XBUFFER (w->buffer) == current_buffer); */
+ /* eassert (XBUFFER (w->contents) == current_buffer); */
XSETFASTINT (position, pos);
@@ -6081,9 +6080,9 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
/* Get the `face' or `mouse_face' text property at POS, and
determine the next position at which the property changes. */
- prop = Fget_text_property (position, propname, w->buffer);
+ prop = Fget_text_property (position, propname, w->contents);
XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
- end = Fnext_single_property_change (position, propname, w->buffer, limit1);
+ end = Fnext_single_property_change (position, propname, w->contents, limit1);
if (INTEGERP (end))
endpos = XINT (end);
diff --git a/src/xfns.c b/src/xfns.c
index 100fd81a155..a1c709a6c26 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -59,6 +59,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "xsettings.h"
+#ifdef HAVE_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
+#ifdef HAVE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
#ifdef USE_GTK
#include "gtkutil.h"
#endif
@@ -123,10 +130,6 @@ extern LWLIB_ID widget_id_tick;
#define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
-/* Nonzero if using X. */
-
-int x_in_use;
-
static Lisp_Object Qsuppress_icon;
static Lisp_Object Qundefined_color;
static Lisp_Object Qcompound_text, Qcancel_timer;
@@ -139,38 +142,6 @@ static int dpyinfo_refcount;
static struct x_display_info *x_display_info_for_name (Lisp_Object);
-
-/* Error if we are not connected to X. */
-
-void
-check_x (void)
-{
- if (! x_in_use)
- error ("X windows are not in use or not initialized");
-}
-
-/* Nonzero if we can use mouse menus.
- You should not call this unless HAVE_MENUS is defined. */
-
-int
-have_menus_p (void)
-{
- return x_in_use;
-}
-
-/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
- and checking validity for X. */
-
-FRAME_PTR
-check_x_frame (Lisp_Object frame)
-{
- struct frame *f = decode_live_frame (frame);
-
- if (! FRAME_X_P (f))
- error ("Non-X frame used");
- return f;
-}
-
/* Let the user specify an X display with a Lisp object.
OBJECT may be nil, a frame or a terminal object.
nil stands for the selected frame--or, if that is not an X frame,
@@ -197,7 +168,7 @@ check_x_display_info (Lisp_Object object)
struct terminal *t = get_terminal (object, 1);
if (t->type != output_x_window)
- error ("Terminal %"pI"d is not an X display", XINT (object));
+ error ("Terminal %d is not an X display", t->id);
dpyinfo = t->display_info.x;
}
@@ -205,7 +176,7 @@ check_x_display_info (Lisp_Object object)
dpyinfo = x_display_info_for_name (object);
else
{
- FRAME_PTR f = check_x_frame (object);
+ FRAME_PTR f = decode_window_system_frame (object);
dpyinfo = FRAME_X_DISPLAY_INFO (f);
}
@@ -2992,7 +2963,7 @@ If FRAME is omitted or nil, use the selected frame.
Signal error if FRAME is not an X frame. */)
(Lisp_Object frame)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
block_input ();
x_wm_set_size_hint (f, 0, 0);
@@ -3182,9 +3153,6 @@ This function is an internal primitive--use `make-frame' instead. */)
specbind (Qx_resource_name, name);
}
- f->resx = dpyinfo->resx;
- f->resy = dpyinfo->resy;
-
#ifdef HAVE_FREETYPE
#ifdef HAVE_XFT
register_font_driver (&xftfont_driver, f);
@@ -3486,7 +3454,7 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
FRAME nil means use the selected frame. */)
(Lisp_Object frame)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Display *dpy = FRAME_X_DISPLAY (f);
block_input ();
@@ -3519,7 +3487,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -3534,7 +3502,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -3600,7 +3568,11 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
doc: /* Return the width in pixels of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel width for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3613,7 +3585,11 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
doc: /* Return the height in pixels of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel height for all
+physical monitors associated with TERMINAL. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3721,7 +3697,11 @@ DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1,
doc: /* Return the height in millimeters of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the height in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3733,7 +3713,11 @@ DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
doc: /* Return the width in millimeters of the X display TERMINAL.
The optional argument TERMINAL specifies which display to ask about.
TERMINAL should be a terminal object, a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the width in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object terminal)
{
struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3830,6 +3814,512 @@ If omitted or nil, that stands for the selected frame's display. */)
else
return Qnil;
}
+
+/* Store the geometry of the workarea on display DPYINFO into *RECT.
+ Return false if and only if the workarea information cannot be
+ obtained via the _NET_WORKAREA root window property. */
+
+#if ! GTK_CHECK_VERSION (3, 4, 0)
+static bool
+x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
+{
+ Display *dpy = dpyinfo->display;
+ long offset, max_len;
+ Atom target_type, actual_type;
+ unsigned long actual_size, bytes_remaining;
+ int rc, actual_format;
+ unsigned char *tmp_data = NULL;
+ bool result = false;
+
+ x_catch_errors (dpy);
+ offset = 0;
+ max_len = 1;
+ target_type = XA_CARDINAL;
+ rc = XGetWindowProperty (dpy, dpyinfo->root_window,
+ dpyinfo->Xatom_net_current_desktop,
+ offset, max_len, False, target_type,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+ if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
+ && actual_format == 32 && actual_size == max_len)
+ {
+ long current_desktop = ((long *) tmp_data)[0];
+
+ XFree (tmp_data);
+ tmp_data = NULL;
+
+ offset = 4 * current_desktop;
+ max_len = 4;
+ rc = XGetWindowProperty (dpy, dpyinfo->root_window,
+ dpyinfo->Xatom_net_workarea,
+ offset, max_len, False, target_type,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+ if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
+ && actual_format == 32 && actual_size == max_len)
+ {
+ long *values = (long *) tmp_data;
+
+ rect->x = values[0];
+ rect->y = values[1];
+ rect->width = values[2];
+ rect->height = values[3];
+
+ XFree (tmp_data);
+ tmp_data = NULL;
+
+ result = true;
+ }
+ }
+ if (tmp_data)
+ XFree (tmp_data);
+ x_uncatch_errors ();
+
+ return result;
+}
+#endif
+
+#ifndef USE_GTK
+
+/* Return monitor number where F is "most" or closest to. */
+static int
+x_get_monitor_for_frame (struct frame *f,
+ struct MonitorInfo *monitors,
+ int n_monitors)
+{
+ XRectangle frect;
+ int area = 0, dist = -1;
+ int best_area = -1, best_dist = -1;
+ int i;
+
+ if (n_monitors == 1) return 0;
+ frect.x = f->left_pos;
+ frect.y = f->top_pos;
+ frect.width = FRAME_PIXEL_WIDTH (f);
+ frect.height = FRAME_PIXEL_HEIGHT (f);
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ struct MonitorInfo *mi = &monitors[i];
+ XRectangle res;
+ int a = 0;
+
+ if (mi->geom.width == 0) continue;
+
+ if (x_intersect_rectangles (&mi->geom, &frect, &res))
+ {
+ a = res.width * res.height;
+ if (a > area)
+ {
+ area = a;
+ best_area = i;
+ }
+ }
+
+ if (a == 0 && area == 0)
+ {
+ int dx, dy, d;
+ if (frect.x + frect.width < mi->geom.x)
+ dx = mi->geom.x - frect.x + frect.width;
+ else if (frect.x > mi->geom.x + mi->geom.width)
+ dx = frect.x - mi->geom.x + mi->geom.width;
+ else
+ dx = 0;
+ if (frect.y + frect.height < mi->geom.y)
+ dy = mi->geom.y - frect.y + frect.height;
+ else if (frect.y > mi->geom.y + mi->geom.height)
+ dy = frect.y - mi->geom.y + mi->geom.height;
+ else
+ dy = 0;
+
+ d = dx*dx + dy*dy;
+ if (dist == -1 || dist > d)
+ {
+ dist = d;
+ best_dist = i;
+ }
+ }
+ }
+
+ return best_area != -1 ? best_area : (best_dist != -1 ? best_dist : 0);
+}
+
+static Lisp_Object
+x_make_monitor_attribute_list (struct MonitorInfo *monitors,
+ int n_monitors,
+ int primary_monitor,
+ struct x_display_info *dpyinfo,
+ const char *source)
+{
+ Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
+ Lisp_Object frame, rest;
+
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo
+ && !EQ (frame, tip_frame))
+ {
+ int i = x_get_monitor_for_frame (f, monitors, n_monitors);
+ ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
+ }
+ }
+
+ return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
+ monitor_frames, source);
+}
+
+static Lisp_Object
+x_get_monitor_attributes_fallback (struct x_display_info *dpyinfo)
+{
+ struct MonitorInfo monitor;
+ XRectangle workarea_r;
+
+ /* Fallback: treat (possibly) multiple physical monitors as if they
+ formed a single monitor as a whole. This should provide a
+ consistent result at least on single monitor environments. */
+ monitor.geom.x = monitor.geom.y = 0;
+ monitor.geom.width = x_display_pixel_width (dpyinfo);
+ monitor.geom.height = x_display_pixel_height (dpyinfo);
+ monitor.mm_width = WidthMMOfScreen (dpyinfo->screen);
+ monitor.mm_height = HeightMMOfScreen (dpyinfo->screen);
+ monitor.name = xstrdup ("combined screen");
+
+ if (x_get_net_workarea (dpyinfo, &workarea_r))
+ monitor.work = workarea_r;
+ else
+ monitor.work = monitor.geom;
+ return x_make_monitor_attribute_list (&monitor, 1, 0, dpyinfo, "fallback");
+}
+
+
+#ifdef HAVE_XINERAMA
+static Lisp_Object
+x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
+{
+ int n_monitors, i;
+ Lisp_Object attributes_list = Qnil;
+ Display *dpy = dpyinfo->display;
+ XineramaScreenInfo *info = XineramaQueryScreens (dpy, &n_monitors);
+ struct MonitorInfo *monitors;
+ double mm_width_per_pixel, mm_height_per_pixel;
+
+ if (! info || n_monitors == 0)
+ {
+ if (info)
+ XFree (info);
+ return attributes_list;
+ }
+
+ mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
+ / x_display_pixel_width (dpyinfo));
+ mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
+ / x_display_pixel_height (dpyinfo));
+ monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
+ for (i = 0; i < n_monitors; ++i)
+ {
+ struct MonitorInfo *mi = &monitors[i];
+ XRectangle workarea_r;
+
+ mi->geom.x = info[i].x_org;
+ mi->geom.y = info[i].y_org;
+ mi->geom.width = info[i].width;
+ mi->geom.height = info[i].height;
+ mi->mm_width = mi->geom.width * mm_width_per_pixel + 0.5;
+ mi->mm_height = mi->geom.height * mm_height_per_pixel + 0.5;
+ mi->name = 0;
+
+ /* Xinerama usually have primary monitor first, just use that. */
+ if (i == 0 && x_get_net_workarea (dpyinfo, &workarea_r))
+ {
+ mi->work = workarea_r;
+ if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
+ mi->work = mi->geom;
+ }
+ else
+ mi->work = mi->geom;
+ }
+ XFree (info);
+
+ attributes_list = x_make_monitor_attribute_list (monitors,
+ n_monitors,
+ 0,
+ dpyinfo,
+ "Xinerama");
+ free_monitors (monitors, n_monitors);
+ return attributes_list;
+}
+#endif /* HAVE_XINERAMA */
+
+
+#ifdef HAVE_XRANDR
+static Lisp_Object
+x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
+{
+ Lisp_Object attributes_list = Qnil;
+ XRRScreenResources *resources;
+ Display *dpy = dpyinfo->display;
+ int i, n_monitors, primary = -1;
+ RROutput pxid = None;
+ struct MonitorInfo *monitors;
+
+#ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
+ resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
+#else
+ resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
+#endif
+ if (! resources || resources->noutput == 0)
+ {
+ if (resources)
+ XRRFreeScreenResources (resources);
+ return Qnil;
+ }
+ n_monitors = resources->noutput;
+ monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
+
+#ifdef HAVE_XRRGETOUTPUTPRIMARY
+ pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
+#endif
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
+ resources->outputs[i]);
+ Connection conn = info ? info->connection : RR_Disconnected;
+ RRCrtc id = info ? info->crtc : None;
+
+ if (strcmp (info->name, "default") == 0)
+ {
+ /* Non XRandr 1.2 driver, does not give useful data. */
+ XRRFreeOutputInfo (info);
+ XRRFreeScreenResources (resources);
+ free_monitors (monitors, n_monitors);
+ return Qnil;
+ }
+
+ if (conn != RR_Disconnected && id != None)
+ {
+ XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, id);
+ struct MonitorInfo *mi = &monitors[i];
+ XRectangle workarea_r;
+
+ if (! crtc)
+ {
+ XRRFreeOutputInfo (info);
+ continue;
+ }
+
+ mi->geom.x = crtc->x;
+ mi->geom.y = crtc->y;
+ mi->geom.width = crtc->width;
+ mi->geom.height = crtc->height;
+ mi->mm_width = info->mm_width;
+ mi->mm_height = info->mm_height;
+ mi->name = xstrdup (info->name);
+
+ if (pxid != None && pxid == resources->outputs[i])
+ primary = i;
+ else if (primary == -1 && strcmp (info->name, "LVDS") == 0)
+ primary = i;
+
+ if (i == primary && x_get_net_workarea (dpyinfo, &workarea_r))
+ {
+ mi->work= workarea_r;
+ if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
+ mi->work = mi->geom;
+ }
+ else
+ mi->work = mi->geom;
+
+ XRRFreeCrtcInfo (crtc);
+ }
+ XRRFreeOutputInfo (info);
+ }
+ XRRFreeScreenResources (resources);
+
+ attributes_list = x_make_monitor_attribute_list (monitors,
+ n_monitors,
+ primary,
+ dpyinfo,
+ "XRandr");
+ free_monitors (monitors, n_monitors);
+ return attributes_list;
+}
+#endif /* HAVE_XRANDR */
+
+static Lisp_Object
+x_get_monitor_attributes (struct x_display_info *dpyinfo)
+{
+ Lisp_Object attributes_list = Qnil;
+ Display *dpy = dpyinfo->display;
+
+#ifdef HAVE_XRANDR
+ int xrr_event_base, xrr_error_base;
+ bool xrr_ok = false;
+ xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
+ if (xrr_ok)
+ {
+ int xrr_major, xrr_minor;
+ XRRQueryVersion (dpy, &xrr_major, &xrr_minor);
+ xrr_ok = (xrr_major == 1 && xrr_minor >= 2) || xrr_major > 1;
+ }
+
+ if (xrr_ok)
+ attributes_list = x_get_monitor_attributes_xrandr (dpyinfo);
+#endif /* HAVE_XRANDR */
+
+#ifdef HAVE_XINERAMA
+ if (NILP (attributes_list))
+ {
+ int xin_event_base, xin_error_base;
+ bool xin_ok = false;
+ xin_ok = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
+ if (xin_ok && XineramaIsActive (dpy))
+ attributes_list = x_get_monitor_attributes_xinerama (dpyinfo);
+ }
+#endif /* HAVE_XINERAMA */
+
+ if (NILP (attributes_list))
+ attributes_list = x_get_monitor_attributes_fallback (dpyinfo);
+
+ return attributes_list;
+}
+
+#endif /* !USE_GTK */
+
+DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list,
+ Sx_display_monitor_attributes_list,
+ 0, 1, 0,
+ doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+In addition to the standard attribute keys listed in
+`display-monitor-attributes-list', the following keys are contained in
+the attributes:
+
+ source -- String describing the source from which multi-monitor
+ information is obtained, one of \"Gdk\", \"XRandr\",
+ \"Xinerama\", or \"fallback\"
+
+Internal use only, use `display-monitor-attributes-list' instead. */)
+ (Lisp_Object terminal)
+{
+ struct x_display_info *dpyinfo = check_x_display_info (terminal);
+ Lisp_Object attributes_list = Qnil;
+
+#ifdef USE_GTK
+ double mm_width_per_pixel, mm_height_per_pixel;
+ GdkDisplay *gdpy;
+ GdkScreen *gscreen;
+ gint primary_monitor = 0, n_monitors, i;
+ Lisp_Object monitor_frames, rest, frame;
+ static const char *source = "Gdk";
+ struct MonitorInfo *monitors;
+
+ block_input ();
+ mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
+ / x_display_pixel_width (dpyinfo));
+ mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
+ / x_display_pixel_height (dpyinfo));
+ gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
+ gscreen = gdk_display_get_default_screen (gdpy);
+#if GTK_CHECK_VERSION (2, 20, 0)
+ primary_monitor = gdk_screen_get_primary_monitor (gscreen);
+#endif
+ n_monitors = gdk_screen_get_n_monitors (gscreen);
+ monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
+ monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
+
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo
+ && !EQ (frame, tip_frame))
+ {
+ GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
+
+ i = gdk_screen_get_monitor_at_window (gscreen, gwin);
+ ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
+ }
+ }
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ gint width_mm = -1, height_mm = -1;
+ GdkRectangle rec, work;
+ struct MonitorInfo *mi = &monitors[i];
+
+ gdk_screen_get_monitor_geometry (gscreen, i, &rec);
+
+#if GTK_CHECK_VERSION (2, 14, 0)
+ width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
+ height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
+#endif
+ if (width_mm < 0)
+ width_mm = rec.width * mm_width_per_pixel + 0.5;
+ if (height_mm < 0)
+ height_mm = rec.height * mm_height_per_pixel + 0.5;
+
+#if GTK_CHECK_VERSION (3, 4, 0)
+ gdk_screen_get_monitor_workarea (gscreen, i, &work);
+#else
+ /* Emulate the behavior of GTK+ 3.4. */
+ {
+ XRectangle workarea_r;
+
+ if (i == primary_monitor && x_get_net_workarea (dpyinfo, &workarea_r))
+ {
+ work.x = workarea_r.x;
+ work.y = workarea_r.y;
+ work.width = workarea_r.width;
+ work.height = workarea_r.height;
+ if (! gdk_rectangle_intersect (&rec, &work, &work))
+ work = rec;
+ }
+ else
+ work = rec;
+ }
+#endif
+
+
+ mi->geom.x = rec.x;
+ mi->geom.y = rec.y;
+ mi->geom.width = rec.width;
+ mi->geom.height = rec.height;
+ mi->work.x = work.x;
+ mi->work.y = work.y;
+ mi->work.width = work.width;
+ mi->work.height = work.height;
+ mi->mm_width = width_mm;
+ mi->mm_height = height_mm;
+
+#if GTK_CHECK_VERSION (2, 14, 0)
+ mi->name = gdk_screen_get_monitor_plug_name (gscreen, i);
+#endif
+ }
+
+ attributes_list = make_monitor_attribute_list (monitors,
+ n_monitors,
+ primary_monitor,
+ monitor_frames,
+ source);
+ unblock_input ();
+#else /* not USE_GTK */
+
+ block_input ();
+ attributes_list = x_get_monitor_attributes (dpyinfo);
+ unblock_input ();
+
+#endif /* not USE_GTK */
+
+ return attributes_list;
+}
+
int
x_pixel_width (register struct frame *f)
@@ -3999,7 +4489,6 @@ x_display_info_for_name (Lisp_Object name)
if (dpyinfo == 0)
error ("Cannot connect to X server %s", SDATA (name));
- x_in_use = 1;
XSETFASTINT (Vwindow_system_version, 11);
return dpyinfo;
@@ -4053,8 +4542,6 @@ An insecure way to solve the problem may be to use `xhost'.\n",
error ("Cannot connect to X server %s", SDATA (display));
}
- x_in_use = 1;
-
XSETFASTINT (Vwindow_system_version, 11);
return Qnil;
}
@@ -4146,7 +4633,7 @@ FRAME. Default is to change on the edit X window. */)
(Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
Atom target_type = XA_STRING;
int element_format = 8;
@@ -4224,7 +4711,7 @@ DEFUN ("x-delete-window-property", Fx_delete_window_property,
FRAME nil or omitted means use the selected frame. Value is PROP. */)
(Lisp_Object prop, Lisp_Object frame)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
CHECK_STRING (prop);
@@ -4260,7 +4747,7 @@ no value of TYPE (always string in the MS Windows case). */)
(Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
int rc;
Lisp_Object prop_value = Qnil;
@@ -4325,7 +4812,7 @@ no value of TYPE (always string in the MS Windows case). */)
property and those are indeed in 32 bit quantities if format is
32. */
- if (32 < BITS_PER_LONG && actual_format == 32)
+ if (BITS_PER_LONG > 32 && actual_format == 32)
{
unsigned long i;
int *idata = (int *) tmp_data;
@@ -4528,8 +5015,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
Lisp_Object buffer;
struct buffer *old_buffer;
- check_x ();
-
if (!dpyinfo->terminal->name)
error ("Terminal is not live, can't create new frames on it");
@@ -4631,9 +5116,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
specbind (Qx_resource_name, name);
}
- f->resx = dpyinfo->resx;
- f->resy = dpyinfo->resy;
-
register_font_driver (&xfont_driver, f);
#ifdef HAVE_FREETYPE
#ifdef HAVE_XFT
@@ -4929,7 +5411,7 @@ Text larger than the specified size is clipped. */)
if (SCHARS (string) == 0)
string = make_unibyte_string (" ", 1);
- f = check_x_frame (frame);
+ f = decode_window_system_frame (frame);
if (NILP (timeout))
timeout = make_number (5);
else
@@ -5027,29 +5509,29 @@ Text larger than the specified size is clipped. */)
/* Set up the frame's root window. */
w = XWINDOW (FRAME_ROOT_WINDOW (f));
- wset_left_col (w, make_number (0));
- wset_top_line (w, make_number (0));
+ w->left_col = 0;
+ w->top_line = 0;
if (CONSP (Vx_max_tooltip_size)
&& RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
&& RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
{
- wset_total_cols (w, XCAR (Vx_max_tooltip_size));
- wset_total_lines (w, XCDR (Vx_max_tooltip_size));
+ w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
+ w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
}
else
{
- wset_total_cols (w, make_number (80));
- wset_total_lines (w, make_number (40));
+ w->total_cols = 80;
+ w->total_lines = 40;
}
- FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
+ FRAME_TOTAL_COLS (f) = w->total_cols;
adjust_glyphs (f);
w->pseudo_window_p = 1;
/* Display the tooltip text in a temporary buffer. */
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
+ set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
bset_truncate_lines (current_buffer, Qnil);
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
@@ -5110,7 +5592,7 @@ Text larger than the specified size is clipped. */)
/* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
not in pixels. */
width /= WINDOW_FRAME_COLUMN_WIDTH (w);
- wset_total_cols (w, make_number (width));
+ w->total_cols = width;
FRAME_TOTAL_COLS (f) = width;
adjust_glyphs (f);
clear_glyph_matrix (w->desired_matrix);
@@ -5252,7 +5734,7 @@ DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
#ifdef USE_GTK
if (use_dialog_box
&& use_file_dialog
- && have_menus_p ()
+ && window_system_available (SELECTED_FRAME ())
&& xg_uses_old_file_dialog ())
return Qt;
#endif
@@ -5322,7 +5804,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
ptrdiff_t count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
- check_x ();
+ check_window_system (f);
GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
@@ -5492,7 +5974,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
char *cdef_file;
- check_x ();
+ check_window_system (f);
GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
@@ -5547,15 +6029,13 @@ FRAME is the frame on which to pop up the font chooser. If omitted or
nil, it defaults to the selected frame. */)
(Lisp_Object frame, Lisp_Object ignored)
{
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
Lisp_Object font;
Lisp_Object font_param;
char *default_name = NULL;
struct gcpro gcpro1, gcpro2;
ptrdiff_t count = SPECPDL_INDEX ();
- check_x ();
-
if (popup_activated ())
error ("Trying to use a menu from within a menu-entry");
@@ -5597,7 +6077,7 @@ nil, it defaults to the selected frame. */)
Keyboard
***********************************************************************/
-#ifdef HAVE_XKBGETKEYBOARD
+#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#include <X11/keysym.h>
#endif
@@ -5611,9 +6091,11 @@ usual X keysyms. Value is `lambda' if we cannot determine if both keys are
present and mapped to the usual X keysyms. */)
(Lisp_Object frame)
{
-#ifdef HAVE_XKBGETKEYBOARD
+#ifndef HAVE_XKB
+ return Qlambda;
+#else
XkbDescPtr kb;
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Display *dpy = FRAME_X_DISPLAY (f);
Lisp_Object have_keys;
int major, minor, op, event, error_code;
@@ -5689,9 +6171,7 @@ present and mapped to the usual X keysyms. */)
}
unblock_input ();
return have_keys;
-#else /* not HAVE_XKBGETKEYBOARD */
- return Qlambda;
-#endif /* not HAVE_XKBGETKEYBOARD */
+#endif
}
@@ -5743,9 +6223,6 @@ frame_parm_handler x_frame_parm_handlers[] =
void
syms_of_xfns (void)
{
- /* This is zero if not using X windows. */
- x_in_use = 0;
-
/* The section below is built by the lisp expression at the top of the file,
just above where these variables are declared. */
/*&&& init symbols here &&&*/
@@ -5916,6 +6393,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
defsubr (&Sx_display_visual_class);
defsubr (&Sx_display_backing_store);
defsubr (&Sx_display_save_under);
+ defsubr (&Sx_display_monitor_attributes_list);
defsubr (&Sx_wm_set_size_hint);
defsubr (&Sx_create_frame);
defsubr (&Sx_open_connection);
@@ -5925,9 +6403,6 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
defsubr (&Sx_focus_frame);
defsubr (&Sx_backspace_delete_keys_p);
- /* Setting callback functions for fontset handler. */
- check_window_system_func = check_x;
-
defsubr (&Sx_show_tip);
defsubr (&Sx_hide_tip);
tip_timer = Qnil;
diff --git a/src/xgselect.c b/src/xgselect.c
index 2c8e9671abb..0b5ad6ae70d 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <glib.h>
#include <errno.h>
#include "xterm.h"
+#include "frame.h"
int
xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
@@ -43,7 +44,7 @@ xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
int i, nfds, tmo_in_millisec;
USE_SAFE_ALLOCA;
- if (! (x_in_use
+ if (! (window_system_available (NULL)
&& g_main_context_pending (context = g_main_context_default ())))
return pselect (fds_lim, rfds, wfds, efds, timeout, sigmask);
diff --git a/src/xmenu.c b/src/xmenu.c
index 958cd220393..9993bd87d5b 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -223,8 +223,6 @@ for instance using the window manager, then this produces a quit and
FRAME_PTR f = NULL;
Lisp_Object window;
- check_x ();
-
/* Decode the first argument: find the window or frame to use. */
if (EQ (position, Qt)
|| (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
@@ -277,8 +275,7 @@ for instance using the window manager, then this produces a quit and
but I don't want to make one now. */
CHECK_WINDOW (window);
- if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f))
- error ("Can not put X dialog on this terminal");
+ check_window_system (f);
/* Force a redisplay before showing the dialog. If a frame is created
just before showing the dialog, its contents may not have been fully
@@ -485,7 +482,7 @@ If FRAME is nil or not given, use the selected frame. */)
(Lisp_Object frame)
{
XEvent ev;
- FRAME_PTR f = check_x_frame (frame);
+ FRAME_PTR f = decode_window_system_frame (frame);
Widget menubar;
block_input ();
@@ -569,7 +566,7 @@ If FRAME is nil or not given, use the selected frame. */)
block_input (). */
block_input ();
- f = check_x_frame (frame);
+ f = decode_window_system_frame (frame);
if (FRAME_EXTERNAL_MENU_BAR (f))
set_frame_menubar (f, 0, 1);
@@ -976,7 +973,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
if (! menubar_widget)
previous_menu_items_used = 0;
- buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
+ buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
specbind (Qinhibit_quit, Qt);
/* Don't let the debugger step into this code
because it is not reentrant. */
@@ -1055,7 +1052,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
wv->help = Qnil;
first_wv = wv;
- for (i = 0; 0 <= submenu_start[i]; i++)
+ for (i = 0; submenu_start[i] >= 0; i++)
{
menu_items_n_panes = submenu_n_panes[i];
wv = digest_single_submenu (submenu_start[i], submenu_end[i],
@@ -2479,7 +2476,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
#endif
record_unwind_protect (pop_down_menu,
- make_save_value ("pp", f, menu));
+ make_save_value (SAVE_TYPE_PTR_PTR, f, menu));
/* Help display under X won't work because XMenuActivate contains
a loop that doesn't give Emacs a chance to process it. */
diff --git a/src/xselect.c b/src/xselect.c
index 5b90d7def22..b422a22d68b 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1388,7 +1388,7 @@ x_get_window_property (Display *display, Window window, Atom property,
data = data1;
}
- if (32 < BITS_PER_LONG && *actual_format_ret == 32)
+ if (BITS_PER_LONG > 32 && *actual_format_ret == 32)
{
unsigned long i;
int *idata = (int *) (data + offset);
@@ -2450,7 +2450,7 @@ Use the display for FRAME or the current frame if FRAME is not given or nil.
If the value is 0 or the atom is not known, return the empty string. */)
(Lisp_Object value, Lisp_Object frame)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
char *name = 0;
char empty[] = "";
Lisp_Object ret = Qnil;
@@ -2485,7 +2485,7 @@ FRAME is on. If FRAME is nil, the selected frame is used. */)
(Lisp_Object atom, Lisp_Object frame)
{
Atom x_atom;
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
ptrdiff_t i;
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -2541,7 +2541,7 @@ x_handle_dnd_message (struct frame *f, XClientMessageEvent *event,
function expects them to be of size int (i.e. 32). So to be able to
use that function, put the data in the form it expects if format is 32. */
- if (32 < BITS_PER_LONG && event->format == 32)
+ if (BITS_PER_LONG > 32 && event->format == 32)
{
for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */
idata[i] = event->data.l[i];
@@ -2571,7 +2571,7 @@ x_handle_dnd_message (struct frame *f, XClientMessageEvent *event,
return 1;
}
-DEFUN ("x-send-client-message", Fx_send_client_event,
+DEFUN ("x-send-client-message", Fx_send_client_message,
Sx_send_client_message, 6, 6, 0,
doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
@@ -2618,7 +2618,7 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
struct x_display_info *dpyinfo = check_x_display_info (display);
Window wdest;
XEvent event;
- struct frame *f = check_x_frame (from);
+ struct frame *f = decode_window_system_frame (from);
int to_root;
CHECK_NUMBER (format);
@@ -2635,7 +2635,7 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
if (FRAMEP (dest) || NILP (dest))
{
- struct frame *fdest = check_x_frame (dest);
+ struct frame *fdest = decode_window_system_frame (dest);
wdest = FRAME_OUTER_WINDOW (fdest);
}
else if (STRINGP (dest))
diff --git a/src/xsettings.c b/src/xsettings.c
index 576a5032eac..f48c49dbafe 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -673,19 +673,14 @@ apply_xft_settings (struct x_display_info *dpyinfo,
if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi
&& settings->dpi > 0)
{
- Lisp_Object frame, tail;
-
FcPatternDel (pat, FC_DPI);
FcPatternAddDouble (pat, FC_DPI, settings->dpi);
++changed;
oldsettings.dpi = settings->dpi;
- /* Change the DPI on this display and all frames on the display. */
+ /* Changing the DPI on this display affects all frames on it.
+ Check FRAME_RES_X and FRAME_RES_Y in frame.h to see how. */
dpyinfo->resy = dpyinfo->resx = settings->dpi;
- FOR_EACH_FRAME (tail, frame)
- if (FRAME_X_P (XFRAME (frame))
- && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
- XFRAME (frame)->resy = XFRAME (frame)->resx = settings->dpi;
}
if (changed)
diff --git a/src/xterm.c b/src/xterm.c
index 88433b6c0b3..7038de7039f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -130,6 +130,10 @@ extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
#include "bitmaps/gray.xbm"
+#ifdef HAVE_XKB
+#include <X11/XKBlib.h>
+#endif
+
/* Default to using XIM if available. */
#ifdef USE_XIM
int use_xim = 1;
@@ -3218,7 +3222,11 @@ XTring_bell (struct frame *f)
else
{
block_input ();
+#ifdef HAVE_XKB
+ XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
+#else
XBell (FRAME_X_DISPLAY (f), 0);
+#endif
XFlush (FRAME_X_DISPLAY (f));
unblock_input ();
}
@@ -5076,7 +5084,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
/* Draw the empty space above the handle. Note that we can't clear
zero-height areas; that means "clear to end of window." */
- if (0 < start)
+ if (start > 0)
x_clear_area (FRAME_X_DISPLAY (f), w,
/* x, y, width, height, and exposures. */
VERTICAL_SCROLL_BAR_LEFT_BORDER,
@@ -9889,6 +9897,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
XSetLocaleModifiers ("");
+ /* If D-Bus is not already configured, inhibit D-Bus autolaunch,
+ as autolaunch can mess up Emacs's SIGCHLD handler.
+ FIXME: Rewrite subprocess handlers to use glib's child watchers.
+ See Bug#14474. */
+ if (! egetenv ("DBUS_SESSION_BUS_ADDRESS"))
+ xputenv ("DBUS_SESSION_BUS_ADDRESS=unix:path=/dev/null");
+
/* Emacs can only handle core input events, so make sure
Gtk doesn't use Xinput or Xinput2 extensions. */
xputenv ("GDK_CORE_DEVICE_EVENTS=1");
@@ -9913,7 +9928,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
dpy = DEFAULT_GDK_DISPLAY ();
-#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90
+#if ! GTK_CHECK_VERSION (2, 90, 0)
/* Load our own gtkrc if it exists. */
{
const char *file = "~/.emacs.d/gtkrc";
@@ -10243,6 +10258,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
{ "_NET_WM_WINDOW_OPACITY", &dpyinfo->Xatom_net_wm_window_opacity },
{ "_NET_ACTIVE_WINDOW", &dpyinfo->Xatom_net_active_window },
{ "_NET_FRAME_EXTENTS", &dpyinfo->Xatom_net_frame_extents },
+ { "_NET_CURRENT_DESKTOP", &dpyinfo->Xatom_net_current_desktop },
+ { "_NET_WORKAREA", &dpyinfo->Xatom_net_workarea },
/* Session management */
{ "SM_CLIENT_ID", &dpyinfo->Xatom_SM_CLIENT_ID },
{ "_XSETTINGS_SETTINGS", &dpyinfo->Xatom_xsettings_prop },
diff --git a/src/xterm.h b/src/xterm.h
index b241ff23559..4a5ebc66370 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -53,14 +53,26 @@ typedef GtkWidget *xt_or_gtk_widget;
#undef XSync
#define XSync(d, b) do { gdk_window_process_all_updates (); \
XSync (d, b); } while (0)
+#endif /* USE_GTK */
+
+/* True iff GTK's version is at least I.J.K. */
+#ifndef GTK_CHECK_VERSION
+# ifdef USE_GTK
+# define GTK_CHECK_VERSION(i, j, k) \
+ ((i) \
+ < GTK_MAJOR_VERSION + ((j) \
+ < GTK_MINOR_VERSION + ((k) \
+ <= GTK_MICRO_VERSION)))
+# else
+# define GTK_CHECK_VERSION(i, j, k) 0
+# endif
+#endif
/* The GtkTooltip API came in 2.12, but gtk-enable-tooltips in 2.14. */
-#if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 13
+#if GTK_CHECK_VERSION (2, 14, 0)
#define USE_GTK_TOOLTIP
#endif
-#endif /* USE_GTK */
-
/* Bookkeeping to distinguish X versions. */
@@ -346,7 +358,8 @@ struct x_display_info
Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen,
Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert,
Xatom_net_wm_state_sticky, Xatom_net_wm_state_hidden,
- Xatom_net_frame_extents;
+ Xatom_net_frame_extents,
+ Xatom_net_current_desktop, Xatom_net_workarea;
/* XSettings atoms and windows. */
Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
@@ -366,10 +379,6 @@ struct x_display_info
extern int use_xim;
#endif
-/* This checks to make sure we have a display. */
-
-extern void check_x (void);
-
extern struct frame *x_window_to_frame (struct x_display_info *, int);
extern struct frame *x_any_window_to_frame (struct x_display_info *, int);
extern struct frame *x_menubar_window_to_frame (struct x_display_info *,
@@ -927,7 +936,6 @@ void x_handle_property_notify (XPropertyEvent *);
/* From xfns.c. */
-struct frame *check_x_frame (Lisp_Object);
extern void x_free_gcs (struct frame *);
/* From xrdb.c. */
@@ -1012,7 +1020,6 @@ extern void x_clipboard_manager_save_all (void);
extern struct x_display_info * check_x_display_info (Lisp_Object);
extern Lisp_Object x_get_focus_frame (struct frame *);
-extern int x_in_use;
#ifdef USE_GTK
extern int xg_set_icon (struct frame *, Lisp_Object);