diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 121 | ||||
| -rw-r--r-- | src/alloc.c | 12 | ||||
| -rw-r--r-- | src/callproc.c | 104 | ||||
| -rw-r--r-- | src/character.c | 14 | ||||
| -rw-r--r-- | src/dispextern.h | 63 | ||||
| -rw-r--r-- | src/dispnew.c | 58 | ||||
| -rw-r--r-- | src/fileio.c | 118 | ||||
| -rw-r--r-- | src/frame.h | 10 | ||||
| -rw-r--r-- | src/gtkutil.c | 11 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/nsterm.m | 8 | ||||
| -rw-r--r-- | src/process.c | 72 | ||||
| -rw-r--r-- | src/process.h | 1 | ||||
| -rw-r--r-- | src/sysdep.c | 113 | ||||
| -rw-r--r-- | src/w32.c | 29 | ||||
| -rw-r--r-- | src/w32term.c | 9 | ||||
| -rw-r--r-- | src/window.c | 2 | ||||
| -rw-r--r-- | src/xdisp.c | 38 | ||||
| -rw-r--r-- | src/xterm.c | 9 |
19 files changed, 466 insertions, 327 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index e21d82bdc09..70d722a02a4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,124 @@ | |||
| 1 | 2013-08-24 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (get_next_display_element): Don't apply to characters | ||
| 4 | from a display vector the logic of setting it->end_of_box_run_p | ||
| 5 | suitable for characters from a buffer. (Bug#15175) | ||
| 6 | |||
| 7 | * w32.c (fdutimens): Call 'utime', which is implemented on w32.c | ||
| 8 | to handle directories, rather than '_utime' which doesn't. | ||
| 9 | (Bug#15176) | ||
| 10 | |||
| 11 | 2013-08-24 Jan Djärv <jan.h.d@swipnet.se> | ||
| 12 | |||
| 13 | * gtkutil.c (x_wm_set_size_hint): Don't set hints when maximized | ||
| 14 | or fullscreen (Bug#14627). | ||
| 15 | |||
| 16 | 2013-08-24 Paul Eggert <eggert@cs.ucla.edu> | ||
| 17 | |||
| 18 | System-dependent integer overflow fixes. | ||
| 19 | * process.c (Fset_process_window_size): Signal an error if | ||
| 20 | the window size is outside the range supported by the lower level. | ||
| 21 | * sysdep.c (set_window_size): Return negative on error, | ||
| 22 | nonnegative on success, rather than -1, 0, 1 on not in system, | ||
| 23 | failure, success. This is simpler. Caller changed. | ||
| 24 | (serial_configure): Remove unnecessary initialization of local. | ||
| 25 | (procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory | ||
| 26 | size fits in unsigned long; this isn't true on some 32-bit hosts. | ||
| 27 | Avoid buffer overrun if some future version of /proc/meminfo has a | ||
| 28 | variable name longer than 20 bytes. | ||
| 29 | (system_process_attributes) [__FreeBSD__]: | ||
| 30 | Don't assume hw.availpages fits in 'int'. | ||
| 31 | |||
| 32 | 2013-08-23 Paul Eggert <eggert@cs.ucla.edu> | ||
| 33 | |||
| 34 | Don't let very long directory names overrun the stack. | ||
| 35 | Fix some related minor problems involving "//", vfork. | ||
| 36 | * callproc.c (encode_current_directory): New function. | ||
| 37 | (call_process): Don't append "/"; not needed. | ||
| 38 | * fileio.c (file_name_as_directory_slop): New constant. | ||
| 39 | (file_name_as_directory): Allow SRC to be longer than SRCLEN; | ||
| 40 | this can save the caller having to alloca. | ||
| 41 | (Ffile_name_as_directory, Fdirectory_file_name, Fexpand_file_name): | ||
| 42 | Use SAFE_ALLOCA, not alloca. | ||
| 43 | (directory_file_name, Fexpand_file_name): Leave leading "//" | ||
| 44 | alone, since it can be special even on POSIX platforms. | ||
| 45 | * callproc.c (call_process): | ||
| 46 | * process.c (Fformat_network_address): | ||
| 47 | * sysdep.c (sys_subshell): | ||
| 48 | Use encode_current_directory rather than rolling our own. | ||
| 49 | (create_process): No need to encode directory; caller does that now. | ||
| 50 | * process.h (encode_current_directory): New decl. | ||
| 51 | * sysdep.c (sys_subshell): Work even if vfork trashes saved_handlers. | ||
| 52 | Rework to avoid 'goto xyzzy;'. | ||
| 53 | |||
| 54 | 2013-08-23 Eli Zaretskii <eliz@gnu.org> | ||
| 55 | |||
| 56 | * xdisp.c (handle_face_prop): If the default face was remapped use | ||
| 57 | the remapped face for strings from prefix properties. (Bug#15155) | ||
| 58 | |||
| 59 | 2013-08-23 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 60 | |||
| 61 | Minor cleanup for redisplay interface and few related functions. | ||
| 62 | * frame.h (enum text_cursor_kinds): Move from here... | ||
| 63 | * dispextern.h (enum text_cursor_kinds): ...to here. | ||
| 64 | (toplevel): Drop unnecessary declarations. | ||
| 65 | (struct redisplay_interface): Use bool and enum text_cursor_kinds | ||
| 66 | in update_window_end_hook and draw_window_cursor functions. | ||
| 67 | (display_and_set_cursor, x_update_cursor): Adjust prototypes. | ||
| 68 | * nsterm.m (ns_update_window_end, ns_draw_window_cursor): | ||
| 69 | * w32term.c (x_update_window_end,w32_draw_window_cursor): | ||
| 70 | * xterm.c (x_update_window_end, x_draw_window_cursor): | ||
| 71 | * xdisp.c (display_and_set_cursor, update_window_cursor) | ||
| 72 | (update_cursor_in_window_tree, x_update_cursor): Use bool and | ||
| 73 | enum text_cursor_kinds where appropriate. | ||
| 74 | |||
| 75 | 2013-08-23 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 76 | |||
| 77 | Redesign redisplay interface to drop updated_row and updated_area. | ||
| 78 | * dispextern.h (updated_row, updated_area): Remove declaration. | ||
| 79 | (struct redisplay_interface): Pass glyph row and row area parameters | ||
| 80 | to write_glyphs, insert_glyphs and clear_end_of_line functions. | ||
| 81 | (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): | ||
| 82 | Adjust prototypes. | ||
| 83 | * dispnew.c (updated_row, updated_area): Remove. | ||
| 84 | (redraw_overlapped_rows, update_window_line): Adjust user. | ||
| 85 | (update_marginal_area, update_text_area): Likewise. Pass updated row | ||
| 86 | as a parameter. Prefer enum glyph_row_area to int where appropriate. | ||
| 87 | * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): | ||
| 88 | Adjust users. | ||
| 89 | |||
| 90 | 2013-08-22 Paul Eggert <eggert@cs.ucla.edu> | ||
| 91 | |||
| 92 | * process.c (flush_pending_output): Remove stub. | ||
| 93 | All uses removed. | ||
| 94 | |||
| 95 | 2013-08-21 Paul Eggert <eggert@cs.ucla.edu> | ||
| 96 | |||
| 97 | * callproc.c: Fix race that killed background processes (Bug#15144). | ||
| 98 | (call_process): New arg TEMPFILE_INDEX. Callers changed. | ||
| 99 | Record deleted process-id in critical section, not afterwards. | ||
| 100 | Don't mistakenly kill process created by a call-process invocation | ||
| 101 | that discards output and does not wait. | ||
| 102 | |||
| 103 | 2013-08-21 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 104 | |||
| 105 | Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE | ||
| 106 | and GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES. | ||
| 107 | * alloc.c (toplevel): Remove unnecessary nested #if...#endif. | ||
| 108 | (mark_maybe_object) [!GC_MARK_STACK]: Define to emacs_abort | ||
| 109 | to shut up compiler in mark_object. | ||
| 110 | (dump_zombies): Convert to global and add EXTERNALLY_VISIBLE. | ||
| 111 | |||
| 112 | 2013-08-21 Paul Eggert <eggert@cs.ucla.edu> | ||
| 113 | |||
| 114 | * process.c (allocate_pty) [PTY_OPEN]: Set fd's FD_CLOEXEC flag. | ||
| 115 | We can't portably rely on PTY_OPEN doing that, even if | ||
| 116 | it calls posix_openpt with O_CLOEXEC. | ||
| 117 | |||
| 118 | 2013-08-20 Kenichi Handa <handa@gnu.org> | ||
| 119 | |||
| 120 | * character.c (string_char): Improve commentary. | ||
| 121 | |||
| 1 | 2013-08-20 Paul Eggert <eggert@cs.ucla.edu> | 122 | 2013-08-20 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 123 | ||
| 3 | * image.c (SIGNATURE_DIGESTSIZE): Remove. | 124 | * image.c (SIGNATURE_DIGESTSIZE): Remove. |
diff --git a/src/alloc.c b/src/alloc.c index 4cc9b3e1a13..9b5f2955aa5 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -314,7 +314,6 @@ static void *min_heap_address, *max_heap_address; | |||
| 314 | static struct mem_node mem_z; | 314 | static struct mem_node mem_z; |
| 315 | #define MEM_NIL &mem_z | 315 | #define MEM_NIL &mem_z |
| 316 | 316 | ||
| 317 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | ||
| 318 | static struct mem_node *mem_insert (void *, void *, enum mem_type); | 317 | static struct mem_node *mem_insert (void *, void *, enum mem_type); |
| 319 | static void mem_insert_fixup (struct mem_node *); | 318 | static void mem_insert_fixup (struct mem_node *); |
| 320 | static void mem_rotate_left (struct mem_node *); | 319 | static void mem_rotate_left (struct mem_node *); |
| @@ -322,7 +321,6 @@ static void mem_rotate_right (struct mem_node *); | |||
| 322 | static void mem_delete (struct mem_node *); | 321 | static void mem_delete (struct mem_node *); |
| 323 | static void mem_delete_fixup (struct mem_node *); | 322 | static void mem_delete_fixup (struct mem_node *); |
| 324 | static struct mem_node *mem_find (void *); | 323 | static struct mem_node *mem_find (void *); |
| 325 | #endif | ||
| 326 | 324 | ||
| 327 | #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ | 325 | #endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ |
| 328 | 326 | ||
| @@ -4237,6 +4235,10 @@ live_buffer_p (struct mem_node *m, void *p) | |||
| 4237 | 4235 | ||
| 4238 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 4236 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 4239 | 4237 | ||
| 4238 | /* Currently not used, but may be called from gdb. */ | ||
| 4239 | |||
| 4240 | void dump_zombies (void) EXTERNALLY_VISIBLE; | ||
| 4241 | |||
| 4240 | /* Array of objects that are kept alive because the C stack contains | 4242 | /* Array of objects that are kept alive because the C stack contains |
| 4241 | a pattern that looks like a reference to them . */ | 4243 | a pattern that looks like a reference to them . */ |
| 4242 | 4244 | ||
| @@ -4619,7 +4621,7 @@ check_gcpros (void) | |||
| 4619 | 4621 | ||
| 4620 | #elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 4622 | #elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 4621 | 4623 | ||
| 4622 | static void | 4624 | void |
| 4623 | dump_zombies (void) | 4625 | dump_zombies (void) |
| 4624 | { | 4626 | { |
| 4625 | int i; | 4627 | int i; |
| @@ -4766,6 +4768,10 @@ flush_stack_call_func (void (*func) (void *arg), void *arg) | |||
| 4766 | eassert (current_thread == self); | 4768 | eassert (current_thread == self); |
| 4767 | } | 4769 | } |
| 4768 | 4770 | ||
| 4771 | #else /* GC_MARK_STACK == 0 */ | ||
| 4772 | |||
| 4773 | #define mark_maybe_object(obj) emacs_abort () | ||
| 4774 | |||
| 4769 | #endif /* GC_MARK_STACK != 0 */ | 4775 | #endif /* GC_MARK_STACK != 0 */ |
| 4770 | 4776 | ||
| 4771 | 4777 | ||
diff --git a/src/callproc.c b/src/callproc.c index 2a9162cb5cc..d4b4a26ec3a 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -102,7 +102,7 @@ enum | |||
| 102 | CALLPROC_FDS | 102 | CALLPROC_FDS |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int); | 105 | static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t); |
| 106 | 106 | ||
| 107 | /* Block SIGCHLD. */ | 107 | /* Block SIGCHLD. */ |
| 108 | 108 | ||
| @@ -123,6 +123,37 @@ unblock_child_signal (void) | |||
| 123 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 123 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | /* Return the current buffer's working directory, or the home | ||
| 127 | directory if it's unreachable, as a string suitable for a system call. | ||
| 128 | Signal an error if the result would not be an accessible directory. */ | ||
| 129 | |||
| 130 | Lisp_Object | ||
| 131 | encode_current_directory (void) | ||
| 132 | { | ||
| 133 | Lisp_Object dir; | ||
| 134 | struct gcpro gcpro1; | ||
| 135 | |||
| 136 | dir = BVAR (current_buffer, directory); | ||
| 137 | GCPRO1 (dir); | ||
| 138 | |||
| 139 | dir = Funhandled_file_name_directory (dir); | ||
| 140 | |||
| 141 | /* If the file name handler says that dir is unreachable, use | ||
| 142 | a sensible default. */ | ||
| 143 | if (NILP (dir)) | ||
| 144 | dir = build_string ("~"); | ||
| 145 | |||
| 146 | dir = expand_and_dir_to_file (dir, Qnil); | ||
| 147 | |||
| 148 | if (STRING_MULTIBYTE (dir)) | ||
| 149 | dir = ENCODE_FILE (dir); | ||
| 150 | if (! file_accessible_directory_p (SSDATA (dir))) | ||
| 151 | report_file_error ("Setting current directory", | ||
| 152 | BVAR (current_buffer, directory)); | ||
| 153 | |||
| 154 | RETURN_UNGCPRO (dir); | ||
| 155 | } | ||
| 156 | |||
| 126 | /* If P is reapable, record it as a deleted process and kill it. | 157 | /* If P is reapable, record it as a deleted process and kill it. |
| 127 | Do this in a critical section. Unless PID is wedged it will be | 158 | Do this in a critical section. Unless PID is wedged it will be |
| 128 | reaped on receipt of the first SIGCHLD after the critical section. */ | 159 | reaped on receipt of the first SIGCHLD after the critical section. */ |
| @@ -248,14 +279,20 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 248 | report_file_error ("Opening process input file", infile); | 279 | report_file_error ("Opening process input file", infile); |
| 249 | record_unwind_protect_int (close_file_unwind, filefd); | 280 | record_unwind_protect_int (close_file_unwind, filefd); |
| 250 | UNGCPRO; | 281 | UNGCPRO; |
| 251 | return unbind_to (count, call_process (nargs, args, filefd)); | 282 | return unbind_to (count, call_process (nargs, args, filefd, -1)); |
| 252 | } | 283 | } |
| 253 | 284 | ||
| 254 | /* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. | 285 | /* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. |
| 286 | |||
| 287 | If TEMPFILE_INDEX is nonnegative, it is the specpdl index of an | ||
| 288 | unwinder that is intended to remove the input temporary file; in | ||
| 289 | this case NARGS must be at least 2 and ARGS[1] is the file's name. | ||
| 290 | |||
| 255 | At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ | 291 | At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ |
| 256 | 292 | ||
| 257 | static Lisp_Object | 293 | static Lisp_Object |
| 258 | call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd) | 294 | call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, |
| 295 | ptrdiff_t tempfile_index) | ||
| 259 | { | 296 | { |
| 260 | Lisp_Object buffer, current_dir, path; | 297 | Lisp_Object buffer, current_dir, path; |
| 261 | bool display_p; | 298 | bool display_p; |
| @@ -402,24 +439,10 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd) | |||
| 402 | { | 439 | { |
| 403 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 440 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 404 | 441 | ||
| 405 | current_dir = BVAR (current_buffer, directory); | 442 | current_dir = encode_current_directory (); |
| 406 | 443 | ||
| 407 | GCPRO4 (buffer, current_dir, error_file, output_file); | 444 | GCPRO4 (buffer, current_dir, error_file, output_file); |
| 408 | 445 | ||
| 409 | current_dir = Funhandled_file_name_directory (current_dir); | ||
| 410 | if (NILP (current_dir)) | ||
| 411 | /* If the file name handler says that current_dir is unreachable, use | ||
| 412 | a sensible default. */ | ||
| 413 | current_dir = build_string ("~/"); | ||
| 414 | current_dir = expand_and_dir_to_file (current_dir, Qnil); | ||
| 415 | current_dir = Ffile_name_as_directory (current_dir); | ||
| 416 | |||
| 417 | if (NILP (Ffile_accessible_directory_p (current_dir))) | ||
| 418 | report_file_error ("Setting current directory", | ||
| 419 | BVAR (current_buffer, directory)); | ||
| 420 | |||
| 421 | if (STRING_MULTIBYTE (current_dir)) | ||
| 422 | current_dir = ENCODE_FILE (current_dir); | ||
| 423 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) | 446 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) |
| 424 | error_file = ENCODE_FILE (error_file); | 447 | error_file = ENCODE_FILE (error_file); |
| 425 | if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) | 448 | if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) |
| @@ -661,7 +684,22 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd) | |||
| 661 | child_errno = errno; | 684 | child_errno = errno; |
| 662 | 685 | ||
| 663 | if (pid > 0) | 686 | if (pid > 0) |
| 664 | synch_process_pid = pid; | 687 | { |
| 688 | synch_process_pid = pid; | ||
| 689 | |||
| 690 | if (INTEGERP (buffer)) | ||
| 691 | { | ||
| 692 | if (tempfile_index < 0) | ||
| 693 | record_deleted_pid (pid, Qnil); | ||
| 694 | else | ||
| 695 | { | ||
| 696 | eassert (1 < nargs); | ||
| 697 | record_deleted_pid (pid, args[1]); | ||
| 698 | clear_unwind_protect (tempfile_index); | ||
| 699 | } | ||
| 700 | synch_process_pid = 0; | ||
| 701 | } | ||
| 702 | } | ||
| 665 | 703 | ||
| 666 | unblock_child_signal (); | 704 | unblock_child_signal (); |
| 667 | unblock_input (); | 705 | unblock_input (); |
| @@ -1030,7 +1068,7 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | |||
| 1030 | usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) | 1068 | usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) |
| 1031 | (ptrdiff_t nargs, Lisp_Object *args) | 1069 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1032 | { | 1070 | { |
| 1033 | struct gcpro gcpro1, gcpro2; | 1071 | struct gcpro gcpro1; |
| 1034 | Lisp_Object infile, val; | 1072 | Lisp_Object infile, val; |
| 1035 | ptrdiff_t count = SPECPDL_INDEX (); | 1073 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1036 | Lisp_Object start = args[0]; | 1074 | Lisp_Object start = args[0]; |
| @@ -1061,8 +1099,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1061 | record_unwind_protect_int (close_file_unwind, fd); | 1099 | record_unwind_protect_int (close_file_unwind, fd); |
| 1062 | } | 1100 | } |
| 1063 | 1101 | ||
| 1064 | val = infile; | 1102 | GCPRO1 (infile); |
| 1065 | GCPRO2 (infile, val); | ||
| 1066 | 1103 | ||
| 1067 | if (nargs > 3 && !NILP (args[3])) | 1104 | if (nargs > 3 && !NILP (args[3])) |
| 1068 | Fdelete_region (start, end); | 1105 | Fdelete_region (start, end); |
| @@ -1079,16 +1116,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1079 | } | 1116 | } |
| 1080 | args[1] = infile; | 1117 | args[1] = infile; |
| 1081 | 1118 | ||
| 1082 | val = call_process (nargs, args, fd); | 1119 | val = call_process (nargs, args, fd, empty_input ? -1 : count); |
| 1083 | |||
| 1084 | if (!empty_input && 4 < nargs | ||
| 1085 | && (INTEGERP (CONSP (args[4]) ? XCAR (args[4]) : args[4]))) | ||
| 1086 | { | ||
| 1087 | record_deleted_pid (synch_process_pid, infile); | ||
| 1088 | synch_process_pid = 0; | ||
| 1089 | clear_unwind_protect (count); | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | RETURN_UNGCPRO (unbind_to (count, val)); | 1120 | RETURN_UNGCPRO (unbind_to (count, val)); |
| 1093 | } | 1121 | } |
| 1094 | 1122 | ||
| @@ -1165,23 +1193,21 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1165 | static variables as if the superior had done alloca and will be | 1193 | static variables as if the superior had done alloca and will be |
| 1166 | cleaned up in the usual way. */ | 1194 | cleaned up in the usual way. */ |
| 1167 | { | 1195 | { |
| 1168 | register char *temp; | 1196 | char *temp; |
| 1169 | size_t i; /* size_t, because ptrdiff_t might overflow here! */ | 1197 | ptrdiff_t i; |
| 1170 | 1198 | ||
| 1171 | i = SBYTES (current_dir); | 1199 | i = SBYTES (current_dir); |
| 1172 | #ifdef MSDOS | 1200 | #ifdef MSDOS |
| 1173 | /* MSDOS must have all environment variables malloc'ed, because | 1201 | /* MSDOS must have all environment variables malloc'ed, because |
| 1174 | low-level libc functions that launch subsidiary processes rely | 1202 | low-level libc functions that launch subsidiary processes rely |
| 1175 | on that. */ | 1203 | on that. */ |
| 1176 | pwd_var = xmalloc (i + 6); | 1204 | pwd_var = xmalloc (i + 5); |
| 1177 | #else | 1205 | #else |
| 1178 | pwd_var = alloca (i + 6); | 1206 | pwd_var = alloca (i + 5); |
| 1179 | #endif | 1207 | #endif |
| 1180 | temp = pwd_var + 4; | 1208 | temp = pwd_var + 4; |
| 1181 | memcpy (pwd_var, "PWD=", 4); | 1209 | memcpy (pwd_var, "PWD=", 4); |
| 1182 | memcpy (temp, SDATA (current_dir), i); | 1210 | strcpy (temp, SSDATA (current_dir)); |
| 1183 | if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP; | ||
| 1184 | temp[i] = 0; | ||
| 1185 | 1211 | ||
| 1186 | #ifndef DOS_NT | 1212 | #ifndef DOS_NT |
| 1187 | /* We can't signal an Elisp error here; we're in a vfork. Since | 1213 | /* We can't signal an Elisp error here; we're in a vfork. Since |
diff --git a/src/character.c b/src/character.c index b2caaa290af..1bde2364e37 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -174,11 +174,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len) | |||
| 174 | 174 | ||
| 175 | if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10)) | 175 | if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10)) |
| 176 | { | 176 | { |
| 177 | /* 1-, 2-, and 3-byte sequences can be handled by the macro. */ | ||
| 177 | c = STRING_CHAR_ADVANCE (p); | 178 | c = STRING_CHAR_ADVANCE (p); |
| 178 | } | 179 | } |
| 179 | else if (! (*p & 0x08)) | 180 | else if (! (*p & 0x08)) |
| 180 | { | 181 | { |
| 181 | c = ((((p)[0] & 0xF) << 18) | 182 | /* A 4-byte sequence of this form: |
| 183 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ | ||
| 184 | c = ((((p)[0] & 0x7) << 18) | ||
| 182 | | (((p)[1] & 0x3F) << 12) | 185 | | (((p)[1] & 0x3F) << 12) |
| 183 | | (((p)[2] & 0x3F) << 6) | 186 | | (((p)[2] & 0x3F) << 6) |
| 184 | | ((p)[3] & 0x3F)); | 187 | | ((p)[3] & 0x3F)); |
| @@ -186,7 +189,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len) | |||
| 186 | } | 189 | } |
| 187 | else | 190 | else |
| 188 | { | 191 | { |
| 189 | c = ((((p)[1] & 0x3F) << 18) | 192 | /* A 5-byte sequence of this form: |
| 193 | |||
| 194 | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx | ||
| 195 | |||
| 196 | Note that the top 4 `x's are always 0, so shifting p[1] can | ||
| 197 | never exceed the maximum valid character codepoint. */ | ||
| 198 | c = (/* (((p)[0] & 0x3) << 24) ... always 0, so no need to shift. */ | ||
| 199 | (((p)[1] & 0x3F) << 18) | ||
| 190 | | (((p)[2] & 0x3F) << 12) | 200 | | (((p)[2] & 0x3F) << 12) |
| 191 | | (((p)[3] & 0x3F) << 6) | 201 | | (((p)[3] & 0x3F) << 6) |
| 192 | | ((p)[4] & 0x3F)); | 202 | | ((p)[4] & 0x3F)); |
diff --git a/src/dispextern.h b/src/dispextern.h index 7a4fa2ea774..6e1d85de924 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -95,18 +95,17 @@ typedef int Cursor; | |||
| 95 | #define NativeRectangle int | 95 | #define NativeRectangle int |
| 96 | #endif | 96 | #endif |
| 97 | 97 | ||
| 98 | /* Structure forward declarations. Some are here because function | 98 | /* Text cursor types. */ |
| 99 | prototypes below reference structure types before their definition | ||
| 100 | in this file. Some are here because not every file including | ||
| 101 | dispextern.h also includes frame.h and windows.h. */ | ||
| 102 | |||
| 103 | struct glyph; | ||
| 104 | struct glyph_row; | ||
| 105 | struct glyph_matrix; | ||
| 106 | struct glyph_pool; | ||
| 107 | struct frame; | ||
| 108 | struct window; | ||
| 109 | 99 | ||
| 100 | enum text_cursor_kinds | ||
| 101 | { | ||
| 102 | DEFAULT_CURSOR = -2, | ||
| 103 | NO_CURSOR = -1, | ||
| 104 | FILLED_BOX_CURSOR, | ||
| 105 | HOLLOW_BOX_CURSOR, | ||
| 106 | BAR_CURSOR, | ||
| 107 | HBAR_CURSOR | ||
| 108 | }; | ||
| 110 | 109 | ||
| 111 | /* Values returned from coordinates_in_window. */ | 110 | /* Values returned from coordinates_in_window. */ |
| 112 | 111 | ||
| @@ -1197,11 +1196,6 @@ extern bool fonts_changed_p; | |||
| 1197 | 1196 | ||
| 1198 | extern struct glyph space_glyph; | 1197 | extern struct glyph space_glyph; |
| 1199 | 1198 | ||
| 1200 | /* Glyph row and area updated by update_window_line. */ | ||
| 1201 | |||
| 1202 | extern struct glyph_row *updated_row; | ||
| 1203 | extern int updated_area; | ||
| 1204 | |||
| 1205 | /* Non-zero means last display completed. Zero means it was | 1199 | /* Non-zero means last display completed. Zero means it was |
| 1206 | preempted. */ | 1200 | preempted. */ |
| 1207 | 1201 | ||
| @@ -2713,12 +2707,17 @@ struct redisplay_interface | |||
| 2713 | 2707 | ||
| 2714 | /* Write or insert LEN glyphs from STRING at the nominal output | 2708 | /* Write or insert LEN glyphs from STRING at the nominal output |
| 2715 | position. */ | 2709 | position. */ |
| 2716 | void (*write_glyphs) (struct window *w, struct glyph *string, int len); | 2710 | void (*write_glyphs) (struct window *w, struct glyph_row *row, |
| 2717 | void (*insert_glyphs) (struct window *w, struct glyph *start, int len); | 2711 | struct glyph *string, enum glyph_row_area area, |
| 2712 | int len); | ||
| 2713 | void (*insert_glyphs) (struct window *w, struct glyph_row *row, | ||
| 2714 | struct glyph *start, enum glyph_row_area area, | ||
| 2715 | int len); | ||
| 2718 | 2716 | ||
| 2719 | /* Clear from nominal output position to X. X < 0 means clear | 2717 | /* Clear from nominal output position to X. X < 0 means clear |
| 2720 | to right end of display. */ | 2718 | to right end of display. */ |
| 2721 | void (*clear_end_of_line) (struct window *w, int x); | 2719 | void (*clear_end_of_line) (struct window *w, struct glyph_row *row, |
| 2720 | enum glyph_row_area area, int x); | ||
| 2722 | 2721 | ||
| 2723 | /* Function to call to scroll the display as described by RUN on | 2722 | /* Function to call to scroll the display as described by RUN on |
| 2724 | window W. */ | 2723 | window W. */ |
| @@ -2739,8 +2738,8 @@ struct redisplay_interface | |||
| 2739 | MOUSE_FACE_OVERWRITTEN_P non-zero means that some lines in W | 2738 | MOUSE_FACE_OVERWRITTEN_P non-zero means that some lines in W |
| 2740 | that contained glyphs in mouse-face were overwritten, so we | 2739 | that contained glyphs in mouse-face were overwritten, so we |
| 2741 | have to update the mouse highlight. */ | 2740 | have to update the mouse highlight. */ |
| 2742 | void (*update_window_end_hook) (struct window *w, int cursor_on_p, | 2741 | void (*update_window_end_hook) (struct window *w, bool cursor_on_p, |
| 2743 | int mouse_face_overwritten_p); | 2742 | bool mouse_face_overwritten_p); |
| 2744 | 2743 | ||
| 2745 | /* Move cursor to row/column position VPOS/HPOS, pixel coordinates | 2744 | /* Move cursor to row/column position VPOS/HPOS, pixel coordinates |
| 2746 | Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y | 2745 | Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y |
| @@ -2799,10 +2798,10 @@ struct redisplay_interface | |||
| 2799 | 0, don't draw cursor. If ACTIVE_P is 1, system caret | 2798 | 0, don't draw cursor. If ACTIVE_P is 1, system caret |
| 2800 | should track this cursor (when applicable). */ | 2799 | should track this cursor (when applicable). */ |
| 2801 | void (*draw_window_cursor) (struct window *w, | 2800 | void (*draw_window_cursor) (struct window *w, |
| 2802 | struct glyph_row *glyph_row, | 2801 | struct glyph_row *glyph_row, |
| 2803 | int x, int y, | 2802 | int x, int y, |
| 2804 | int cursor_type, int cursor_width, | 2803 | enum text_cursor_kinds cursor_type, |
| 2805 | int on_p, int active_p); | 2804 | int cursor_width, bool on_p, bool active_p); |
| 2806 | 2805 | ||
| 2807 | /* Draw vertical border for window W from (X,Y_0) to (X,Y_1). */ | 2806 | /* Draw vertical border for window W from (X,Y_0) to (X,Y_1). */ |
| 2808 | void (*draw_vertical_window_border) (struct window *w, | 2807 | void (*draw_vertical_window_border) (struct window *w, |
| @@ -3178,9 +3177,12 @@ extern void x_get_glyph_overhangs (struct glyph *, struct frame *, | |||
| 3178 | int *, int *); | 3177 | int *, int *); |
| 3179 | extern void x_produce_glyphs (struct it *); | 3178 | extern void x_produce_glyphs (struct it *); |
| 3180 | 3179 | ||
| 3181 | extern void x_write_glyphs (struct window *, struct glyph *, int); | 3180 | extern void x_write_glyphs (struct window *, struct glyph_row *, |
| 3182 | extern void x_insert_glyphs (struct window *, struct glyph *, int len); | 3181 | struct glyph *, enum glyph_row_area, int); |
| 3183 | extern void x_clear_end_of_line (struct window *, int); | 3182 | extern void x_insert_glyphs (struct window *, struct glyph_row *, |
| 3183 | struct glyph *, enum glyph_row_area, int); | ||
| 3184 | extern void x_clear_end_of_line (struct window *, struct glyph_row *, | ||
| 3185 | enum glyph_row_area, int); | ||
| 3184 | 3186 | ||
| 3185 | extern struct cursor_pos output_cursor; | 3187 | extern struct cursor_pos output_cursor; |
| 3186 | 3188 | ||
| @@ -3192,13 +3194,12 @@ extern void draw_phys_cursor_glyph (struct window *, | |||
| 3192 | extern void get_phys_cursor_geometry (struct window *, struct glyph_row *, | 3194 | extern void get_phys_cursor_geometry (struct window *, struct glyph_row *, |
| 3193 | struct glyph *, int *, int *, int *); | 3195 | struct glyph *, int *, int *, int *); |
| 3194 | extern void erase_phys_cursor (struct window *); | 3196 | extern void erase_phys_cursor (struct window *); |
| 3195 | extern void display_and_set_cursor (struct window *, | 3197 | extern void display_and_set_cursor (struct window *, bool, int, int, int, int); |
| 3196 | int, int, int, int, int); | ||
| 3197 | 3198 | ||
| 3198 | extern void set_output_cursor (struct cursor_pos *); | 3199 | extern void set_output_cursor (struct cursor_pos *); |
| 3199 | extern void x_cursor_to (struct window *, int, int, int, int); | 3200 | extern void x_cursor_to (struct window *, int, int, int, int); |
| 3200 | 3201 | ||
| 3201 | extern void x_update_cursor (struct frame *, int); | 3202 | extern void x_update_cursor (struct frame *, bool); |
| 3202 | extern void x_clear_cursor (struct window *); | 3203 | extern void x_clear_cursor (struct window *); |
| 3203 | extern void x_draw_vertical_border (struct window *w); | 3204 | extern void x_draw_vertical_border (struct window *w); |
| 3204 | 3205 | ||
diff --git a/src/dispnew.c b/src/dispnew.c index b7e44e425bf..3c6b89bde68 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -135,11 +135,6 @@ struct frame *last_nonminibuf_frame; | |||
| 135 | 135 | ||
| 136 | static bool delayed_size_change; | 136 | static bool delayed_size_change; |
| 137 | 137 | ||
| 138 | /* Glyph row updated in update_window_line, and area that is updated. */ | ||
| 139 | |||
| 140 | struct glyph_row *updated_row; | ||
| 141 | int updated_area; | ||
| 142 | |||
| 143 | /* A glyph for a space. */ | 138 | /* A glyph for a space. */ |
| 144 | 139 | ||
| 145 | struct glyph space_glyph; | 140 | struct glyph space_glyph; |
| @@ -3230,14 +3225,12 @@ redraw_overlapped_rows (struct window *w, int yb) | |||
| 3230 | 3225 | ||
| 3231 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | 3226 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) |
| 3232 | { | 3227 | { |
| 3233 | updated_row = row; | ||
| 3234 | updated_area = area; | ||
| 3235 | FRAME_RIF (f)->cursor_to (w, i, 0, row->y, | 3228 | FRAME_RIF (f)->cursor_to (w, i, 0, row->y, |
| 3236 | area == TEXT_AREA ? row->x : 0); | 3229 | area == TEXT_AREA ? row->x : 0); |
| 3237 | if (row->used[area]) | 3230 | if (row->used[area]) |
| 3238 | FRAME_RIF (f)->write_glyphs (w, row->glyphs[area], | 3231 | FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area], |
| 3239 | row->used[area]); | 3232 | area, row->used[area]); |
| 3240 | FRAME_RIF (f)->clear_end_of_line (w, -1); | 3233 | FRAME_RIF (f)->clear_end_of_line (w, row, area, -1); |
| 3241 | } | 3234 | } |
| 3242 | 3235 | ||
| 3243 | row->overlapped_p = 0; | 3236 | row->overlapped_p = 0; |
| @@ -3511,22 +3504,20 @@ update_window (struct window *w, bool force_p) | |||
| 3511 | AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */ | 3504 | AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */ |
| 3512 | 3505 | ||
| 3513 | static void | 3506 | static void |
| 3514 | update_marginal_area (struct window *w, int area, int vpos) | 3507 | update_marginal_area (struct window *w, struct glyph_row *updated_row, |
| 3508 | enum glyph_row_area area, int vpos) | ||
| 3515 | { | 3509 | { |
| 3516 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); | 3510 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); |
| 3517 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 3511 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 3518 | 3512 | ||
| 3519 | /* Let functions in xterm.c know what area subsequent X positions | ||
| 3520 | will be relative to. */ | ||
| 3521 | updated_area = area; | ||
| 3522 | |||
| 3523 | /* Set cursor to start of glyphs, write them, and clear to the end | 3513 | /* Set cursor to start of glyphs, write them, and clear to the end |
| 3524 | of the area. I don't think that something more sophisticated is | 3514 | of the area. I don't think that something more sophisticated is |
| 3525 | necessary here, since marginal areas will not be the default. */ | 3515 | necessary here, since marginal areas will not be the default. */ |
| 3526 | rif->cursor_to (w, vpos, 0, desired_row->y, 0); | 3516 | rif->cursor_to (w, vpos, 0, desired_row->y, 0); |
| 3527 | if (desired_row->used[area]) | 3517 | if (desired_row->used[area]) |
| 3528 | rif->write_glyphs (w, desired_row->glyphs[area], desired_row->used[area]); | 3518 | rif->write_glyphs (w, updated_row, desired_row->glyphs[area], |
| 3529 | rif->clear_end_of_line (w, -1); | 3519 | area, desired_row->used[area]); |
| 3520 | rif->clear_end_of_line (w, updated_row, area, -1); | ||
| 3530 | } | 3521 | } |
| 3531 | 3522 | ||
| 3532 | 3523 | ||
| @@ -3534,17 +3525,13 @@ update_marginal_area (struct window *w, int area, int vpos) | |||
| 3534 | Value is true if display has changed. */ | 3525 | Value is true if display has changed. */ |
| 3535 | 3526 | ||
| 3536 | static bool | 3527 | static bool |
| 3537 | update_text_area (struct window *w, int vpos) | 3528 | update_text_area (struct window *w, struct glyph_row *updated_row, int vpos) |
| 3538 | { | 3529 | { |
| 3539 | struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); | 3530 | struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); |
| 3540 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); | 3531 | struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); |
| 3541 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 3532 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 3542 | bool changed_p = 0; | 3533 | bool changed_p = 0; |
| 3543 | 3534 | ||
| 3544 | /* Let functions in xterm.c know what area subsequent X positions | ||
| 3545 | will be relative to. */ | ||
| 3546 | updated_area = TEXT_AREA; | ||
| 3547 | |||
| 3548 | /* If rows are at different X or Y, or rows have different height, | 3535 | /* If rows are at different X or Y, or rows have different height, |
| 3549 | or the current row is marked invalid, write the entire line. */ | 3536 | or the current row is marked invalid, write the entire line. */ |
| 3550 | if (!current_row->enabled_p | 3537 | if (!current_row->enabled_p |
| @@ -3567,11 +3554,11 @@ update_text_area (struct window *w, int vpos) | |||
| 3567 | rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x); | 3554 | rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x); |
| 3568 | 3555 | ||
| 3569 | if (desired_row->used[TEXT_AREA]) | 3556 | if (desired_row->used[TEXT_AREA]) |
| 3570 | rif->write_glyphs (w, desired_row->glyphs[TEXT_AREA], | 3557 | rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA], |
| 3571 | desired_row->used[TEXT_AREA]); | 3558 | TEXT_AREA, desired_row->used[TEXT_AREA]); |
| 3572 | 3559 | ||
| 3573 | /* Clear to end of window. */ | 3560 | /* Clear to end of window. */ |
| 3574 | rif->clear_end_of_line (w, -1); | 3561 | rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1); |
| 3575 | changed_p = 1; | 3562 | changed_p = 1; |
| 3576 | 3563 | ||
| 3577 | /* This erases the cursor. We do this here because | 3564 | /* This erases the cursor. We do this here because |
| @@ -3708,7 +3695,8 @@ update_text_area (struct window *w, int vpos) | |||
| 3708 | } | 3695 | } |
| 3709 | 3696 | ||
| 3710 | rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x); | 3697 | rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x); |
| 3711 | rif->write_glyphs (w, start, i - start_hpos); | 3698 | rif->write_glyphs (w, updated_row, start, |
| 3699 | TEXT_AREA, i - start_hpos); | ||
| 3712 | changed_p = 1; | 3700 | changed_p = 1; |
| 3713 | } | 3701 | } |
| 3714 | } | 3702 | } |
| @@ -3717,7 +3705,8 @@ update_text_area (struct window *w, int vpos) | |||
| 3717 | if (i < desired_row->used[TEXT_AREA]) | 3705 | if (i < desired_row->used[TEXT_AREA]) |
| 3718 | { | 3706 | { |
| 3719 | rif->cursor_to (w, vpos, i, desired_row->y, x); | 3707 | rif->cursor_to (w, vpos, i, desired_row->y, x); |
| 3720 | rif->write_glyphs (w, desired_glyph, desired_row->used[TEXT_AREA] - i); | 3708 | rif->write_glyphs (w, updated_row, desired_glyph, |
| 3709 | TEXT_AREA, desired_row->used[TEXT_AREA] - i); | ||
| 3721 | changed_p = 1; | 3710 | changed_p = 1; |
| 3722 | } | 3711 | } |
| 3723 | 3712 | ||
| @@ -3739,7 +3728,7 @@ update_text_area (struct window *w, int vpos) | |||
| 3739 | if (i >= desired_row->used[TEXT_AREA]) | 3728 | if (i >= desired_row->used[TEXT_AREA]) |
| 3740 | rif->cursor_to (w, vpos, i, desired_row->y, | 3729 | rif->cursor_to (w, vpos, i, desired_row->y, |
| 3741 | desired_row->pixel_width); | 3730 | desired_row->pixel_width); |
| 3742 | rif->clear_end_of_line (w, -1); | 3731 | rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1); |
| 3743 | changed_p = 1; | 3732 | changed_p = 1; |
| 3744 | } | 3733 | } |
| 3745 | else if (desired_row->pixel_width < current_row->pixel_width) | 3734 | else if (desired_row->pixel_width < current_row->pixel_width) |
| @@ -3767,7 +3756,7 @@ update_text_area (struct window *w, int vpos) | |||
| 3767 | } | 3756 | } |
| 3768 | else | 3757 | else |
| 3769 | xlim = current_row->pixel_width; | 3758 | xlim = current_row->pixel_width; |
| 3770 | rif->clear_end_of_line (w, xlim); | 3759 | rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim); |
| 3771 | changed_p = 1; | 3760 | changed_p = 1; |
| 3772 | } | 3761 | } |
| 3773 | } | 3762 | } |
| @@ -3786,10 +3775,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3786 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 3775 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 3787 | bool changed_p = 0; | 3776 | bool changed_p = 0; |
| 3788 | 3777 | ||
| 3789 | /* Set the row being updated. This is important to let xterm.c | ||
| 3790 | know what line height values are in effect. */ | ||
| 3791 | updated_row = desired_row; | ||
| 3792 | |||
| 3793 | /* A row can be completely invisible in case a desired matrix was | 3778 | /* A row can be completely invisible in case a desired matrix was |
| 3794 | built with a vscroll and then make_cursor_line_fully_visible shifts | 3779 | built with a vscroll and then make_cursor_line_fully_visible shifts |
| 3795 | the matrix. Make sure to make such rows current anyway, since | 3780 | the matrix. Make sure to make such rows current anyway, since |
| @@ -3803,7 +3788,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3803 | if (!desired_row->full_width_p && w->left_margin_cols > 0) | 3788 | if (!desired_row->full_width_p && w->left_margin_cols > 0) |
| 3804 | { | 3789 | { |
| 3805 | changed_p = 1; | 3790 | changed_p = 1; |
| 3806 | update_marginal_area (w, LEFT_MARGIN_AREA, vpos); | 3791 | update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos); |
| 3807 | /* Setting this flag will ensure the vertical border, if | 3792 | /* Setting this flag will ensure the vertical border, if |
| 3808 | any, between this window and the one on its left will be | 3793 | any, between this window and the one on its left will be |
| 3809 | redrawn. This is necessary because updating the left | 3794 | redrawn. This is necessary because updating the left |
| @@ -3812,7 +3797,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3812 | } | 3797 | } |
| 3813 | 3798 | ||
| 3814 | /* Update the display of the text area. */ | 3799 | /* Update the display of the text area. */ |
| 3815 | if (update_text_area (w, vpos)) | 3800 | if (update_text_area (w, desired_row, vpos)) |
| 3816 | { | 3801 | { |
| 3817 | changed_p = 1; | 3802 | changed_p = 1; |
| 3818 | if (current_row->mouse_face_p) | 3803 | if (current_row->mouse_face_p) |
| @@ -3823,7 +3808,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3823 | if (!desired_row->full_width_p && w->right_margin_cols > 0) | 3808 | if (!desired_row->full_width_p && w->right_margin_cols > 0) |
| 3824 | { | 3809 | { |
| 3825 | changed_p = 1; | 3810 | changed_p = 1; |
| 3826 | update_marginal_area (w, RIGHT_MARGIN_AREA, vpos); | 3811 | update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos); |
| 3827 | } | 3812 | } |
| 3828 | 3813 | ||
| 3829 | /* Draw truncation marks etc. */ | 3814 | /* Draw truncation marks etc. */ |
| @@ -3842,7 +3827,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) | |||
| 3842 | 3827 | ||
| 3843 | /* Update current_row from desired_row. */ | 3828 | /* Update current_row from desired_row. */ |
| 3844 | make_current (w->desired_matrix, w->current_matrix, vpos); | 3829 | make_current (w->desired_matrix, w->current_matrix, vpos); |
| 3845 | updated_row = NULL; | ||
| 3846 | return changed_p; | 3830 | return changed_p; |
| 3847 | } | 3831 | } |
| 3848 | 3832 | ||
diff --git a/src/fileio.c b/src/fileio.c index 08caf102266..7cad8d29da2 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -504,6 +504,10 @@ get a current directory to run processes in. */) | |||
| 504 | return Ffile_name_directory (filename); | 504 | return Ffile_name_directory (filename); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | /* Maximum number of bytes that DST will be longer than SRC | ||
| 508 | in file_name_as_directory. This occurs when SRCLEN == 0. */ | ||
| 509 | enum { file_name_as_directory_slop = 2 }; | ||
| 510 | |||
| 507 | /* Convert from file name SRC of length SRCLEN to directory name in | 511 | /* Convert from file name SRC of length SRCLEN to directory name in |
| 508 | DST. MULTIBYTE non-zero means the file name in SRC is a multibyte | 512 | DST. MULTIBYTE non-zero means the file name in SRC is a multibyte |
| 509 | string. On UNIX, just make sure there is a terminating /. Return | 513 | string. On UNIX, just make sure there is a terminating /. Return |
| @@ -521,14 +525,10 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen, | |||
| 521 | return 2; | 525 | return 2; |
| 522 | } | 526 | } |
| 523 | 527 | ||
| 524 | strcpy (dst, src); | 528 | memcpy (dst, src, srclen); |
| 525 | |||
| 526 | if (!IS_DIRECTORY_SEP (dst[srclen - 1])) | 529 | if (!IS_DIRECTORY_SEP (dst[srclen - 1])) |
| 527 | { | 530 | dst[srclen++] = DIRECTORY_SEP; |
| 528 | dst[srclen] = DIRECTORY_SEP; | 531 | dst[srclen] = 0; |
| 529 | dst[srclen + 1] = '\0'; | ||
| 530 | srclen++; | ||
| 531 | } | ||
| 532 | #ifdef DOS_NT | 532 | #ifdef DOS_NT |
| 533 | dostounix_filename (dst, multibyte); | 533 | dostounix_filename (dst, multibyte); |
| 534 | #endif | 534 | #endif |
| @@ -547,7 +547,8 @@ For a Unix-syntax file name, just appends a slash. */) | |||
| 547 | { | 547 | { |
| 548 | char *buf; | 548 | char *buf; |
| 549 | ptrdiff_t length; | 549 | ptrdiff_t length; |
| 550 | Lisp_Object handler; | 550 | Lisp_Object handler, val; |
| 551 | USE_SAFE_ALLOCA; | ||
| 551 | 552 | ||
| 552 | CHECK_STRING (file); | 553 | CHECK_STRING (file); |
| 553 | if (NILP (file)) | 554 | if (NILP (file)) |
| @@ -569,10 +570,12 @@ For a Unix-syntax file name, just appends a slash. */) | |||
| 569 | if (!NILP (Vw32_downcase_file_names)) | 570 | if (!NILP (Vw32_downcase_file_names)) |
| 570 | file = Fdowncase (file); | 571 | file = Fdowncase (file); |
| 571 | #endif | 572 | #endif |
| 572 | buf = alloca (SBYTES (file) + 10); | 573 | buf = SAFE_ALLOCA (SBYTES (file) + file_name_as_directory_slop + 1); |
| 573 | length = file_name_as_directory (buf, SSDATA (file), SBYTES (file), | 574 | length = file_name_as_directory (buf, SSDATA (file), SBYTES (file), |
| 574 | STRING_MULTIBYTE (file)); | 575 | STRING_MULTIBYTE (file)); |
| 575 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); | 576 | val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); |
| 577 | SAFE_FREE (); | ||
| 578 | return val; | ||
| 576 | } | 579 | } |
| 577 | 580 | ||
| 578 | /* Convert from directory name SRC of length SRCLEN to file name in | 581 | /* Convert from directory name SRC of length SRCLEN to file name in |
| @@ -584,18 +587,17 @@ static ptrdiff_t | |||
| 584 | directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) | 587 | directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) |
| 585 | { | 588 | { |
| 586 | /* Process as Unix format: just remove any final slash. | 589 | /* Process as Unix format: just remove any final slash. |
| 587 | But leave "/" unchanged; do not change it to "". */ | 590 | But leave "/" and "//" unchanged. */ |
| 588 | strcpy (dst, src); | 591 | while (srclen > 1 |
| 589 | if (srclen > 1 | ||
| 590 | && IS_DIRECTORY_SEP (dst[srclen - 1]) | ||
| 591 | #ifdef DOS_NT | 592 | #ifdef DOS_NT |
| 592 | && !IS_ANY_SEP (dst[srclen - 2]) | 593 | && !IS_ANY_SEP (src[srclen - 2]) |
| 593 | #endif | 594 | #endif |
| 594 | ) | 595 | && IS_DIRECTORY_SEP (src[srclen - 1]) |
| 595 | { | 596 | && ! (srclen == 2 && IS_DIRECTORY_SEP (src[0]))) |
| 596 | dst[srclen - 1] = 0; | 597 | srclen--; |
| 597 | srclen--; | 598 | |
| 598 | } | 599 | memcpy (dst, src, srclen); |
| 600 | dst[srclen] = 0; | ||
| 599 | #ifdef DOS_NT | 601 | #ifdef DOS_NT |
| 600 | dostounix_filename (dst, multibyte); | 602 | dostounix_filename (dst, multibyte); |
| 601 | #endif | 603 | #endif |
| @@ -613,7 +615,8 @@ In Unix-syntax, this function just removes the final slash. */) | |||
| 613 | { | 615 | { |
| 614 | char *buf; | 616 | char *buf; |
| 615 | ptrdiff_t length; | 617 | ptrdiff_t length; |
| 616 | Lisp_Object handler; | 618 | Lisp_Object handler, val; |
| 619 | USE_SAFE_ALLOCA; | ||
| 617 | 620 | ||
| 618 | CHECK_STRING (directory); | 621 | CHECK_STRING (directory); |
| 619 | 622 | ||
| @@ -636,10 +639,12 @@ In Unix-syntax, this function just removes the final slash. */) | |||
| 636 | if (!NILP (Vw32_downcase_file_names)) | 639 | if (!NILP (Vw32_downcase_file_names)) |
| 637 | directory = Fdowncase (directory); | 640 | directory = Fdowncase (directory); |
| 638 | #endif | 641 | #endif |
| 639 | buf = alloca (SBYTES (directory) + 20); | 642 | buf = SAFE_ALLOCA (SBYTES (directory) + 1); |
| 640 | length = directory_file_name (buf, SSDATA (directory), SBYTES (directory), | 643 | length = directory_file_name (buf, SSDATA (directory), SBYTES (directory), |
| 641 | STRING_MULTIBYTE (directory)); | 644 | STRING_MULTIBYTE (directory)); |
| 642 | return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); | 645 | val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); |
| 646 | SAFE_FREE (); | ||
| 647 | return val; | ||
| 643 | } | 648 | } |
| 644 | 649 | ||
| 645 | static const char make_temp_name_tbl[64] = | 650 | static const char make_temp_name_tbl[64] = |
| @@ -837,6 +842,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 837 | Lisp_Object handler, result, handled_name; | 842 | Lisp_Object handler, result, handled_name; |
| 838 | bool multibyte; | 843 | bool multibyte; |
| 839 | Lisp_Object hdir; | 844 | Lisp_Object hdir; |
| 845 | USE_SAFE_ALLOCA; | ||
| 840 | 846 | ||
| 841 | CHECK_STRING (name); | 847 | CHECK_STRING (name); |
| 842 | 848 | ||
| @@ -1011,11 +1017,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1011 | || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) | 1017 | || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) |
| 1012 | || p[3] == 0)))) | 1018 | || p[3] == 0)))) |
| 1013 | lose = 1; | 1019 | lose = 1; |
| 1014 | /* We want to replace multiple `/' in a row with a single | 1020 | /* Replace multiple slashes with a single one, except |
| 1015 | slash. */ | 1021 | leave leading "//" alone. */ |
| 1016 | else if (p > nm | 1022 | else if (IS_DIRECTORY_SEP (p[0]) |
| 1017 | && IS_DIRECTORY_SEP (p[0]) | 1023 | && IS_DIRECTORY_SEP (p[1]) |
| 1018 | && IS_DIRECTORY_SEP (p[1])) | 1024 | && (p != nm || IS_DIRECTORY_SEP (p[2]))) |
| 1019 | lose = 1; | 1025 | lose = 1; |
| 1020 | p++; | 1026 | p++; |
| 1021 | } | 1027 | } |
| @@ -1098,10 +1104,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1098 | else /* ~user/filename */ | 1104 | else /* ~user/filename */ |
| 1099 | { | 1105 | { |
| 1100 | char *o, *p; | 1106 | char *o, *p; |
| 1101 | for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++); | 1107 | for (p = nm; *p && !IS_DIRECTORY_SEP (*p); p++) |
| 1102 | o = alloca (p - nm + 1); | 1108 | continue; |
| 1109 | o = SAFE_ALLOCA (p - nm + 1); | ||
| 1103 | memcpy (o, nm, p - nm); | 1110 | memcpy (o, nm, p - nm); |
| 1104 | o [p - nm] = 0; | 1111 | o[p - nm] = 0; |
| 1105 | 1112 | ||
| 1106 | block_input (); | 1113 | block_input (); |
| 1107 | pw = getpwnam (o + 1); | 1114 | pw = getpwnam (o + 1); |
| @@ -1217,7 +1224,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1217 | if (!IS_DIRECTORY_SEP (nm[0])) | 1224 | if (!IS_DIRECTORY_SEP (nm[0])) |
| 1218 | { | 1225 | { |
| 1219 | ptrdiff_t newlen = strlen (newdir); | 1226 | ptrdiff_t newlen = strlen (newdir); |
| 1220 | char *tmp = alloca (newlen + strlen (nm) + 2); | 1227 | char *tmp = alloca (newlen + file_name_as_directory_slop |
| 1228 | + strlen (nm) + 1); | ||
| 1221 | file_name_as_directory (tmp, newdir, newlen, multibyte); | 1229 | file_name_as_directory (tmp, newdir, newlen, multibyte); |
| 1222 | strcat (tmp, nm); | 1230 | strcat (tmp, nm); |
| 1223 | nm = tmp; | 1231 | nm = tmp; |
| @@ -1271,31 +1279,18 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1271 | 1279 | ||
| 1272 | if (newdir) | 1280 | if (newdir) |
| 1273 | { | 1281 | { |
| 1274 | /* Get rid of any slash at the end of newdir, unless newdir is | 1282 | /* Ignore any slash at the end of newdir, unless newdir is |
| 1275 | just / or // (an incomplete UNC name). */ | 1283 | just "/" or "//". */ |
| 1276 | length = strlen (newdir); | 1284 | length = strlen (newdir); |
| 1277 | tlen = length + 1; | 1285 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) |
| 1278 | if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) | 1286 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) |
| 1279 | #ifdef WINDOWSNT | 1287 | length--; |
| 1280 | && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) | ||
| 1281 | #endif | ||
| 1282 | ) | ||
| 1283 | { | ||
| 1284 | char *temp = alloca (length); | ||
| 1285 | memcpy (temp, newdir, length - 1); | ||
| 1286 | temp[length - 1] = 0; | ||
| 1287 | length--; | ||
| 1288 | newdir = temp; | ||
| 1289 | } | ||
| 1290 | } | 1288 | } |
| 1291 | else | 1289 | else |
| 1292 | { | 1290 | length = 0; |
| 1293 | length = 0; | ||
| 1294 | tlen = 0; | ||
| 1295 | } | ||
| 1296 | 1291 | ||
| 1297 | /* Now concatenate the directory and name to new space in the stack frame. */ | 1292 | /* Now concatenate the directory and name to new space in the stack frame. */ |
| 1298 | tlen += strlen (nm) + 1; | 1293 | tlen = length + file_name_as_directory_slop + strlen (nm) + 1; |
| 1299 | #ifdef DOS_NT | 1294 | #ifdef DOS_NT |
| 1300 | /* Reserve space for drive specifier and escape prefix, since either | 1295 | /* Reserve space for drive specifier and escape prefix, since either |
| 1301 | or both may need to be inserted. (The Microsoft x86 compiler | 1296 | or both may need to be inserted. (The Microsoft x86 compiler |
| @@ -1303,7 +1298,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1303 | target = alloca (tlen + 4); | 1298 | target = alloca (tlen + 4); |
| 1304 | target += 4; | 1299 | target += 4; |
| 1305 | #else /* not DOS_NT */ | 1300 | #else /* not DOS_NT */ |
| 1306 | target = alloca (tlen); | 1301 | target = SAFE_ALLOCA (tlen); |
| 1307 | #endif /* not DOS_NT */ | 1302 | #endif /* not DOS_NT */ |
| 1308 | *target = 0; | 1303 | *target = 0; |
| 1309 | 1304 | ||
| @@ -1320,7 +1315,10 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1320 | if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0]) | 1315 | if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0]) |
| 1321 | && newdir[1] == '\0')) | 1316 | && newdir[1] == '\0')) |
| 1322 | #endif | 1317 | #endif |
| 1323 | strcpy (target, newdir); | 1318 | { |
| 1319 | memcpy (target, newdir, length); | ||
| 1320 | target[length] = 0; | ||
| 1321 | } | ||
| 1324 | } | 1322 | } |
| 1325 | else | 1323 | else |
| 1326 | file_name_as_directory (target, newdir, length, multibyte); | 1324 | file_name_as_directory (target, newdir, length, multibyte); |
| @@ -1380,8 +1378,9 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1380 | ++o; | 1378 | ++o; |
| 1381 | p += 3; | 1379 | p += 3; |
| 1382 | } | 1380 | } |
| 1383 | else if (p > target && IS_DIRECTORY_SEP (p[1])) | 1381 | else if (IS_DIRECTORY_SEP (p[1]) |
| 1384 | /* Collapse multiple `/' in a row. */ | 1382 | && (p != target || IS_DIRECTORY_SEP (p[2]))) |
| 1383 | /* Collapse multiple "/", except leave leading "//" alone. */ | ||
| 1385 | p++; | 1384 | p++; |
| 1386 | else | 1385 | else |
| 1387 | { | 1386 | { |
| @@ -1429,11 +1428,12 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1429 | { | 1428 | { |
| 1430 | handled_name = call3 (handler, Qexpand_file_name, | 1429 | handled_name = call3 (handler, Qexpand_file_name, |
| 1431 | result, default_directory); | 1430 | result, default_directory); |
| 1432 | if (STRINGP (handled_name)) | 1431 | if (! STRINGP (handled_name)) |
| 1433 | return handled_name; | 1432 | error ("Invalid handler in `file-name-handler-alist'"); |
| 1434 | error ("Invalid handler in `file-name-handler-alist'"); | 1433 | result = handled_name; |
| 1435 | } | 1434 | } |
| 1436 | 1435 | ||
| 1436 | SAFE_FREE (); | ||
| 1437 | return result; | 1437 | return result; |
| 1438 | } | 1438 | } |
| 1439 | 1439 | ||
diff --git a/src/frame.h b/src/frame.h index e44003b15ca..2dcb7562524 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -56,16 +56,6 @@ enum vertical_scroll_bar_type | |||
| 56 | vertical_scroll_bar_right | 56 | vertical_scroll_bar_right |
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | enum text_cursor_kinds | ||
| 60 | { | ||
| 61 | DEFAULT_CURSOR = -2, | ||
| 62 | NO_CURSOR = -1, | ||
| 63 | FILLED_BOX_CURSOR, | ||
| 64 | HOLLOW_BOX_CURSOR, | ||
| 65 | BAR_CURSOR, | ||
| 66 | HBAR_CURSOR | ||
| 67 | }; | ||
| 68 | |||
| 69 | enum fullscreen_type | 59 | enum fullscreen_type |
| 70 | { | 60 | { |
| 71 | FULLSCREEN_NONE, | 61 | FULLSCREEN_NONE, |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 7e304d417d8..8e255ac4bfb 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -1341,6 +1341,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) | |||
| 1341 | int base_width, base_height; | 1341 | int base_width, base_height; |
| 1342 | int min_rows = 0, min_cols = 0; | 1342 | int min_rows = 0, min_cols = 0; |
| 1343 | int win_gravity = f->win_gravity; | 1343 | int win_gravity = f->win_gravity; |
| 1344 | Lisp_Object fs_state, frame; | ||
| 1344 | 1345 | ||
| 1345 | /* Don't set size hints during initialization; that apparently leads | 1346 | /* Don't set size hints during initialization; that apparently leads |
| 1346 | to a race condition. See the thread at | 1347 | to a race condition. See the thread at |
| @@ -1348,6 +1349,16 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) | |||
| 1348 | if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f)) | 1349 | if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f)) |
| 1349 | return; | 1350 | return; |
| 1350 | 1351 | ||
| 1352 | XSETFRAME (frame, f); | ||
| 1353 | fs_state = Fframe_parameter (frame, Qfullscreen); | ||
| 1354 | if (EQ (fs_state, Qmaximized) || EQ (fs_state, Qfullboth)) | ||
| 1355 | { | ||
| 1356 | /* Don't set hints when maximized or fullscreen. Apparently KWin and | ||
| 1357 | Gtk3 don't get along and the frame shrinks (!). | ||
| 1358 | */ | ||
| 1359 | return; | ||
| 1360 | } | ||
| 1361 | |||
| 1351 | if (flags) | 1362 | if (flags) |
| 1352 | { | 1363 | { |
| 1353 | memset (&size_hints, 0, sizeof (size_hints)); | 1364 | memset (&size_hints, 0, sizeof (size_hints)); |
diff --git a/src/lisp.h b/src/lisp.h index 60a553cc7d1..51c09e0abb3 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4177,7 +4177,6 @@ extern void init_sys_modes (struct tty_display_info *); | |||
| 4177 | extern void reset_sys_modes (struct tty_display_info *); | 4177 | extern void reset_sys_modes (struct tty_display_info *); |
| 4178 | extern void init_all_sys_modes (void); | 4178 | extern void init_all_sys_modes (void); |
| 4179 | extern void reset_all_sys_modes (void); | 4179 | extern void reset_all_sys_modes (void); |
| 4180 | extern void flush_pending_output (int) ATTRIBUTE_CONST; | ||
| 4181 | extern void child_setup_tty (int); | 4180 | extern void child_setup_tty (int); |
| 4182 | extern void setup_pty (int); | 4181 | extern void setup_pty (int); |
| 4183 | extern int set_window_size (int, int, int); | 4182 | extern int set_window_size (int, int, int); |
diff --git a/src/nsterm.m b/src/nsterm.m index f374bfd90c6..287c119ba73 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -742,8 +742,8 @@ ns_update_window_begin (struct window *w) | |||
| 742 | 742 | ||
| 743 | 743 | ||
| 744 | static void | 744 | static void |
| 745 | ns_update_window_end (struct window *w, int cursor_on_p, | 745 | ns_update_window_end (struct window *w, bool cursor_on_p, |
| 746 | int mouse_face_overwritten_p) | 746 | bool mouse_face_overwritten_p) |
| 747 | /* -------------------------------------------------------------------------- | 747 | /* -------------------------------------------------------------------------- |
| 748 | Finished a grouped sequence of drawing calls | 748 | Finished a grouped sequence of drawing calls |
| 749 | external (RIF) call; for one window called before update_end | 749 | external (RIF) call; for one window called before update_end |
| @@ -2341,8 +2341,8 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, | |||
| 2341 | 2341 | ||
| 2342 | static void | 2342 | static void |
| 2343 | ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | 2343 | ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, |
| 2344 | int x, int y, int cursor_type, int cursor_width, | 2344 | int x, int y, enum text_cursor_kinds cursor_type, |
| 2345 | int on_p, int active_p) | 2345 | int cursor_width, bool on_p, bool active_p) |
| 2346 | /* -------------------------------------------------------------------------- | 2346 | /* -------------------------------------------------------------------------- |
| 2347 | External call (RIF): draw cursor. | 2347 | External call (RIF): draw cursor. |
| 2348 | Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. | 2348 | Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. |
diff --git a/src/process.c b/src/process.c index 1d1741d8b7e..3edc3b4f061 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -826,6 +826,15 @@ allocate_pty (char pty_name[PTY_NAME_SIZE]) | |||
| 826 | 826 | ||
| 827 | if (fd >= 0) | 827 | if (fd >= 0) |
| 828 | { | 828 | { |
| 829 | #ifdef PTY_OPEN | ||
| 830 | /* Set FD's close-on-exec flag. This is needed even if | ||
| 831 | PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX | ||
| 832 | doesn't require support for that combination. | ||
| 833 | Multithreaded platforms where posix_openpt ignores | ||
| 834 | O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt) | ||
| 835 | have a race condition between the PTY_OPEN and here. */ | ||
| 836 | fcntl (fd, F_SETFD, FD_CLOEXEC); | ||
| 837 | #endif | ||
| 829 | /* check to make certain that both sides are available | 838 | /* check to make certain that both sides are available |
| 830 | this avoids a nasty yet stupid bug in rlogins */ | 839 | this avoids a nasty yet stupid bug in rlogins */ |
| 831 | #ifdef PTY_TTY_NAME_SPRINTF | 840 | #ifdef PTY_TTY_NAME_SPRINTF |
| @@ -1322,15 +1331,18 @@ DEFUN ("process-thread", Fprocess_thread, Sprocess_thread, | |||
| 1322 | DEFUN ("set-process-window-size", Fset_process_window_size, | 1331 | DEFUN ("set-process-window-size", Fset_process_window_size, |
| 1323 | Sset_process_window_size, 3, 3, 0, | 1332 | Sset_process_window_size, 3, 3, 0, |
| 1324 | doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */) | 1333 | doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */) |
| 1325 | (register Lisp_Object process, Lisp_Object height, Lisp_Object width) | 1334 | (Lisp_Object process, Lisp_Object height, Lisp_Object width) |
| 1326 | { | 1335 | { |
| 1327 | CHECK_PROCESS (process); | 1336 | CHECK_PROCESS (process); |
| 1328 | CHECK_RANGED_INTEGER (height, 0, INT_MAX); | 1337 | |
| 1329 | CHECK_RANGED_INTEGER (width, 0, INT_MAX); | 1338 | /* All known platforms store window sizes as 'unsigned short'. */ |
| 1339 | CHECK_RANGED_INTEGER (height, 0, USHRT_MAX); | ||
| 1340 | CHECK_RANGED_INTEGER (width, 0, USHRT_MAX); | ||
| 1330 | 1341 | ||
| 1331 | if (XPROCESS (process)->infd < 0 | 1342 | if (XPROCESS (process)->infd < 0 |
| 1332 | || set_window_size (XPROCESS (process)->infd, | 1343 | || (set_window_size (XPROCESS (process)->infd, |
| 1333 | XINT (height), XINT (width)) <= 0) | 1344 | XINT (height), XINT (width)) |
| 1345 | < 0)) | ||
| 1334 | return Qnil; | 1346 | return Qnil; |
| 1335 | else | 1347 | else |
| 1336 | return Qt; | 1348 | return Qt; |
| @@ -1590,22 +1602,9 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1590 | function. The argument list is protected by the caller, so all | 1602 | function. The argument list is protected by the caller, so all |
| 1591 | we really have to worry about is buffer. */ | 1603 | we really have to worry about is buffer. */ |
| 1592 | { | 1604 | { |
| 1593 | struct gcpro gcpro1, gcpro2; | 1605 | struct gcpro gcpro1; |
| 1594 | 1606 | GCPRO1 (buffer); | |
| 1595 | current_dir = BVAR (current_buffer, directory); | 1607 | current_dir = encode_current_directory (); |
| 1596 | |||
| 1597 | GCPRO2 (buffer, current_dir); | ||
| 1598 | |||
| 1599 | current_dir = Funhandled_file_name_directory (current_dir); | ||
| 1600 | if (NILP (current_dir)) | ||
| 1601 | /* If the file name handler says that current_dir is unreachable, use | ||
| 1602 | a sensible default. */ | ||
| 1603 | current_dir = build_string ("~/"); | ||
| 1604 | current_dir = expand_and_dir_to_file (current_dir, Qnil); | ||
| 1605 | if (NILP (Ffile_accessible_directory_p (current_dir))) | ||
| 1606 | report_file_error ("Setting current directory", | ||
| 1607 | BVAR (current_buffer, directory)); | ||
| 1608 | |||
| 1609 | UNGCPRO; | 1608 | UNGCPRO; |
| 1610 | } | 1609 | } |
| 1611 | 1610 | ||
| @@ -1852,7 +1851,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1852 | bool pty_flag = 0; | 1851 | bool pty_flag = 0; |
| 1853 | char pty_name[PTY_NAME_SIZE]; | 1852 | char pty_name[PTY_NAME_SIZE]; |
| 1854 | Lisp_Object lisp_pty_name = Qnil; | 1853 | Lisp_Object lisp_pty_name = Qnil; |
| 1855 | Lisp_Object encoded_current_dir; | ||
| 1856 | 1854 | ||
| 1857 | inchannel = outchannel = -1; | 1855 | inchannel = outchannel = -1; |
| 1858 | 1856 | ||
| @@ -1914,15 +1912,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1914 | /* This may signal an error. */ | 1912 | /* This may signal an error. */ |
| 1915 | setup_process_coding_systems (process); | 1913 | setup_process_coding_systems (process); |
| 1916 | 1914 | ||
| 1917 | encoded_current_dir = ENCODE_FILE (current_dir); | ||
| 1918 | |||
| 1919 | block_input (); | 1915 | block_input (); |
| 1920 | block_child_signal (); | 1916 | block_child_signal (); |
| 1921 | 1917 | ||
| 1922 | #ifndef WINDOWSNT | 1918 | #ifndef WINDOWSNT |
| 1923 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 1919 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 1924 | { | 1920 | { |
| 1925 | Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; | 1921 | Lisp_Object volatile current_dir_volatile = current_dir; |
| 1926 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; | 1922 | Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; |
| 1927 | char **volatile new_argv_volatile = new_argv; | 1923 | char **volatile new_argv_volatile = new_argv; |
| 1928 | int volatile forkin_volatile = forkin; | 1924 | int volatile forkin_volatile = forkin; |
| @@ -1931,7 +1927,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1931 | 1927 | ||
| 1932 | pid = vfork (); | 1928 | pid = vfork (); |
| 1933 | 1929 | ||
| 1934 | encoded_current_dir = encoded_current_dir_volatile; | 1930 | current_dir = current_dir_volatile; |
| 1935 | lisp_pty_name = lisp_pty_name_volatile; | 1931 | lisp_pty_name = lisp_pty_name_volatile; |
| 1936 | new_argv = new_argv_volatile; | 1932 | new_argv = new_argv_volatile; |
| 1937 | forkin = forkin_volatile; | 1933 | forkin = forkin_volatile; |
| @@ -2043,11 +2039,9 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 2043 | if (pty_flag) | 2039 | if (pty_flag) |
| 2044 | child_setup_tty (xforkout); | 2040 | child_setup_tty (xforkout); |
| 2045 | #ifdef WINDOWSNT | 2041 | #ifdef WINDOWSNT |
| 2046 | pid = child_setup (xforkin, xforkout, xforkout, | 2042 | pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); |
| 2047 | new_argv, 1, encoded_current_dir); | ||
| 2048 | #else /* not WINDOWSNT */ | 2043 | #else /* not WINDOWSNT */ |
| 2049 | child_setup (xforkin, xforkout, xforkout, | 2044 | child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir); |
| 2050 | new_argv, 1, encoded_current_dir); | ||
| 2051 | #endif /* not WINDOWSNT */ | 2045 | #endif /* not WINDOWSNT */ |
| 2052 | } | 2046 | } |
| 2053 | 2047 | ||
| @@ -4012,15 +4006,12 @@ deactivate_process (Lisp_Object proc) | |||
| 4012 | } | 4006 | } |
| 4013 | #endif | 4007 | #endif |
| 4014 | 4008 | ||
| 4015 | inchannel = p->infd; | ||
| 4016 | |||
| 4017 | /* Beware SIGCHLD hereabouts. */ | 4009 | /* Beware SIGCHLD hereabouts. */ |
| 4018 | if (inchannel >= 0) | ||
| 4019 | flush_pending_output (inchannel); | ||
| 4020 | 4010 | ||
| 4021 | for (i = 0; i < PROCESS_OPEN_FDS; i++) | 4011 | for (i = 0; i < PROCESS_OPEN_FDS; i++) |
| 4022 | close_process_fd (&p->open_fd[i]); | 4012 | close_process_fd (&p->open_fd[i]); |
| 4023 | 4013 | ||
| 4014 | inchannel = p->infd; | ||
| 4024 | if (inchannel >= 0) | 4015 | if (inchannel >= 0) |
| 4025 | { | 4016 | { |
| 4026 | p->infd = -1; | 4017 | p->infd = -1; |
| @@ -5928,10 +5919,9 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5928 | return; | 5919 | return; |
| 5929 | } | 5920 | } |
| 5930 | 5921 | ||
| 5931 | switch (signo) | ||
| 5932 | { | ||
| 5933 | #ifdef SIGCONT | 5922 | #ifdef SIGCONT |
| 5934 | case SIGCONT: | 5923 | if (signo == SIGCONT) |
| 5924 | { | ||
| 5935 | p->raw_status_new = 0; | 5925 | p->raw_status_new = 0; |
| 5936 | pset_status (p, Qrun); | 5926 | pset_status (p, Qrun); |
| 5937 | p->tick = ++process_tick; | 5927 | p->tick = ++process_tick; |
| @@ -5940,14 +5930,8 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5940 | status_notify (NULL); | 5930 | status_notify (NULL); |
| 5941 | redisplay_preserve_echo_area (13); | 5931 | redisplay_preserve_echo_area (13); |
| 5942 | } | 5932 | } |
| 5943 | break; | ||
| 5944 | #endif /* ! defined (SIGCONT) */ | ||
| 5945 | case SIGINT: | ||
| 5946 | case SIGQUIT: | ||
| 5947 | case SIGKILL: | ||
| 5948 | flush_pending_output (p->infd); | ||
| 5949 | break; | ||
| 5950 | } | 5933 | } |
| 5934 | #endif | ||
| 5951 | 5935 | ||
| 5952 | /* If we don't have process groups, send the signal to the immediate | 5936 | /* If we don't have process groups, send the signal to the immediate |
| 5953 | subprocess. That isn't really right, but it's better than any | 5937 | subprocess. That isn't really right, but it's better than any |
diff --git a/src/process.h b/src/process.h index 95881d10f58..e8bafe689b1 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -221,6 +221,7 @@ enum | |||
| 221 | 221 | ||
| 222 | extern void block_child_signal (void); | 222 | extern void block_child_signal (void); |
| 223 | extern void unblock_child_signal (void); | 223 | extern void unblock_child_signal (void); |
| 224 | extern Lisp_Object encode_current_directory (void); | ||
| 224 | extern void record_kill_process (struct Lisp_Process *, Lisp_Object); | 225 | extern void record_kill_process (struct Lisp_Process *, Lisp_Object); |
| 225 | 226 | ||
| 226 | /* Defined in sysdep.c. */ | 227 | /* Defined in sysdep.c. */ |
diff --git a/src/sysdep.c b/src/sysdep.c index 201ba9d104d..0d732526528 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -337,16 +337,6 @@ child_status_changed (pid_t child, int *status, int options) | |||
| 337 | return get_child_status (child, status, WNOHANG | options, 0); | 337 | return get_child_status (child, status, WNOHANG | options, 0); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | /* | ||
| 341 | * flush any pending output | ||
| 342 | * (may flush input as well; it does not matter the way we use it) | ||
| 343 | */ | ||
| 344 | |||
| 345 | void | ||
| 346 | flush_pending_output (int channel) | ||
| 347 | { | ||
| 348 | /* FIXME: maybe this function should be removed */ | ||
| 349 | } | ||
| 350 | 340 | ||
| 351 | /* Set up the terminal at the other end of a pseudo-terminal that | 341 | /* Set up the terminal at the other end of a pseudo-terminal that |
| 352 | we will be controlling an inferior through. | 342 | we will be controlling an inferior through. |
| @@ -481,10 +471,20 @@ sys_subshell (void) | |||
| 481 | pid_t pid; | 471 | pid_t pid; |
| 482 | int status; | 472 | int status; |
| 483 | struct save_signal saved_handlers[5]; | 473 | struct save_signal saved_handlers[5]; |
| 484 | Lisp_Object dir; | 474 | char *str = SSDATA (encode_current_directory ()); |
| 485 | unsigned char *volatile str_volatile = 0; | 475 | |
| 486 | unsigned char *str; | 476 | #ifdef DOS_NT |
| 487 | int len; | 477 | pid = 0; |
| 478 | #else | ||
| 479 | { | ||
| 480 | char *volatile str_volatile = str; | ||
| 481 | pid = vfork (); | ||
| 482 | str = str_volatile; | ||
| 483 | } | ||
| 484 | #endif | ||
| 485 | |||
| 486 | if (pid < 0) | ||
| 487 | error ("Can't spawn subshell"); | ||
| 488 | 488 | ||
| 489 | saved_handlers[0].code = SIGINT; | 489 | saved_handlers[0].code = SIGINT; |
| 490 | saved_handlers[1].code = SIGQUIT; | 490 | saved_handlers[1].code = SIGQUIT; |
| @@ -496,31 +496,8 @@ sys_subshell (void) | |||
| 496 | saved_handlers[3].code = 0; | 496 | saved_handlers[3].code = 0; |
| 497 | #endif | 497 | #endif |
| 498 | 498 | ||
| 499 | /* Mentioning current_buffer->buffer would mean including buffer.h, | ||
| 500 | which somehow wedges the hp compiler. So instead... */ | ||
| 501 | |||
| 502 | dir = intern ("default-directory"); | ||
| 503 | if (NILP (Fboundp (dir))) | ||
| 504 | goto xyzzy; | ||
| 505 | dir = Fsymbol_value (dir); | ||
| 506 | if (!STRINGP (dir)) | ||
| 507 | goto xyzzy; | ||
| 508 | |||
| 509 | dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil); | ||
| 510 | str_volatile = str = alloca (SCHARS (dir) + 2); | ||
| 511 | len = SCHARS (dir); | ||
| 512 | memcpy (str, SDATA (dir), len); | ||
| 513 | if (str[len - 1] != '/') str[len++] = '/'; | ||
| 514 | str[len] = 0; | ||
| 515 | xyzzy: | ||
| 516 | |||
| 517 | #ifdef DOS_NT | 499 | #ifdef DOS_NT |
| 518 | pid = 0; | ||
| 519 | save_signal_handlers (saved_handlers); | 500 | save_signal_handlers (saved_handlers); |
| 520 | #else | ||
| 521 | pid = vfork (); | ||
| 522 | if (pid == -1) | ||
| 523 | error ("Can't spawn subshell"); | ||
| 524 | #endif | 501 | #endif |
| 525 | 502 | ||
| 526 | if (pid == 0) | 503 | if (pid == 0) |
| @@ -538,11 +515,10 @@ sys_subshell (void) | |||
| 538 | sh = "sh"; | 515 | sh = "sh"; |
| 539 | 516 | ||
| 540 | /* Use our buffer's default directory for the subshell. */ | 517 | /* Use our buffer's default directory for the subshell. */ |
| 541 | str = str_volatile; | 518 | if (chdir (str) != 0) |
| 542 | if (str && chdir ((char *) str) != 0) | ||
| 543 | { | 519 | { |
| 544 | #ifndef DOS_NT | 520 | #ifndef DOS_NT |
| 545 | emacs_perror ((char *) str); | 521 | emacs_perror (str); |
| 546 | _exit (EXIT_CANCELED); | 522 | _exit (EXIT_CANCELED); |
| 547 | #endif | 523 | #endif |
| 548 | } | 524 | } |
| @@ -556,8 +532,6 @@ sys_subshell (void) | |||
| 556 | if (epwd) | 532 | if (epwd) |
| 557 | { | 533 | { |
| 558 | strcpy (old_pwd, epwd); | 534 | strcpy (old_pwd, epwd); |
| 559 | if (str[len - 1] == '/') | ||
| 560 | str[len - 1] = '\0'; | ||
| 561 | setenv ("PWD", str, 1); | 535 | setenv ("PWD", str, 1); |
| 562 | } | 536 | } |
| 563 | st = system (sh); | 537 | st = system (sh); |
| @@ -1196,7 +1170,8 @@ get_tty_size (int fd, int *widthp, int *heightp) | |||
| 1196 | } | 1170 | } |
| 1197 | 1171 | ||
| 1198 | /* Set the logical window size associated with descriptor FD | 1172 | /* Set the logical window size associated with descriptor FD |
| 1199 | to HEIGHT and WIDTH. This is used mainly with ptys. */ | 1173 | to HEIGHT and WIDTH. This is used mainly with ptys. |
| 1174 | Return a negative value on failure. */ | ||
| 1200 | 1175 | ||
| 1201 | int | 1176 | int |
| 1202 | set_window_size (int fd, int height, int width) | 1177 | set_window_size (int fd, int height, int width) |
| @@ -1208,10 +1183,7 @@ set_window_size (int fd, int height, int width) | |||
| 1208 | size.ws_row = height; | 1183 | size.ws_row = height; |
| 1209 | size.ws_col = width; | 1184 | size.ws_col = width; |
| 1210 | 1185 | ||
| 1211 | if (ioctl (fd, TIOCSWINSZ, &size) == -1) | 1186 | return ioctl (fd, TIOCSWINSZ, &size); |
| 1212 | return 0; /* error */ | ||
| 1213 | else | ||
| 1214 | return 1; | ||
| 1215 | 1187 | ||
| 1216 | #else | 1188 | #else |
| 1217 | #ifdef TIOCSSIZE | 1189 | #ifdef TIOCSSIZE |
| @@ -1221,10 +1193,7 @@ set_window_size (int fd, int height, int width) | |||
| 1221 | size.ts_lines = height; | 1193 | size.ts_lines = height; |
| 1222 | size.ts_cols = width; | 1194 | size.ts_cols = width; |
| 1223 | 1195 | ||
| 1224 | if (ioctl (fd, TIOCGSIZE, &size) == -1) | 1196 | return ioctl (fd, TIOCGSIZE, &size); |
| 1225 | return 0; | ||
| 1226 | else | ||
| 1227 | return 1; | ||
| 1228 | #else | 1197 | #else |
| 1229 | return -1; | 1198 | return -1; |
| 1230 | #endif /* not SunOS-style */ | 1199 | #endif /* not SunOS-style */ |
| @@ -2485,7 +2454,7 @@ serial_configure (struct Lisp_Process *p, | |||
| 2485 | Lisp_Object childp2 = Qnil; | 2454 | Lisp_Object childp2 = Qnil; |
| 2486 | Lisp_Object tem = Qnil; | 2455 | Lisp_Object tem = Qnil; |
| 2487 | struct termios attr; | 2456 | struct termios attr; |
| 2488 | int err = -1; | 2457 | int err; |
| 2489 | char summary[4] = "???"; /* This usually becomes "8N1". */ | 2458 | char summary[4] = "???"; /* This usually becomes "8N1". */ |
| 2490 | 2459 | ||
| 2491 | childp2 = Fcopy_sequence (p->childp); | 2460 | childp2 = Fcopy_sequence (p->childp); |
| @@ -2852,29 +2821,41 @@ procfs_ttyname (int rdev) | |||
| 2852 | return build_string (name); | 2821 | return build_string (name); |
| 2853 | } | 2822 | } |
| 2854 | 2823 | ||
| 2855 | static unsigned long | 2824 | static uintmax_t |
| 2856 | procfs_get_total_memory (void) | 2825 | procfs_get_total_memory (void) |
| 2857 | { | 2826 | { |
| 2858 | FILE *fmem; | 2827 | FILE *fmem; |
| 2859 | unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ | 2828 | uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */ |
| 2829 | int c; | ||
| 2860 | 2830 | ||
| 2861 | block_input (); | 2831 | block_input (); |
| 2862 | fmem = emacs_fopen ("/proc/meminfo", "r"); | 2832 | fmem = emacs_fopen ("/proc/meminfo", "r"); |
| 2863 | 2833 | ||
| 2864 | if (fmem) | 2834 | if (fmem) |
| 2865 | { | 2835 | { |
| 2866 | unsigned long entry_value; | 2836 | uintmax_t entry_value; |
| 2867 | char entry_name[20]; /* the longest I saw is 13+1 */ | 2837 | bool done; |
| 2838 | |||
| 2839 | do | ||
| 2840 | switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value)) | ||
| 2841 | { | ||
| 2842 | case 1: | ||
| 2843 | retval = entry_value; | ||
| 2844 | done = 1; | ||
| 2845 | break; | ||
| 2846 | |||
| 2847 | case 0: | ||
| 2848 | while ((c = getc (fmem)) != EOF && c != '\n') | ||
| 2849 | continue; | ||
| 2850 | done = c == EOF; | ||
| 2851 | break; | ||
| 2852 | |||
| 2853 | default: | ||
| 2854 | done = 1; | ||
| 2855 | break; | ||
| 2856 | } | ||
| 2857 | while (!done); | ||
| 2868 | 2858 | ||
| 2869 | while (!feof (fmem) && !ferror (fmem)) | ||
| 2870 | { | ||
| 2871 | if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2 | ||
| 2872 | && strcmp (entry_name, "MemTotal:") == 0) | ||
| 2873 | { | ||
| 2874 | retval = entry_value; | ||
| 2875 | break; | ||
| 2876 | } | ||
| 2877 | } | ||
| 2878 | fclose (fmem); | 2859 | fclose (fmem); |
| 2879 | } | 2860 | } |
| 2880 | unblock_input (); | 2861 | unblock_input (); |
| @@ -3275,7 +3256,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 3275 | { | 3256 | { |
| 3276 | int proc_id; | 3257 | int proc_id; |
| 3277 | int pagesize = getpagesize (); | 3258 | int pagesize = getpagesize (); |
| 3278 | int npages; | 3259 | unsigned long npages; |
| 3279 | int fscale; | 3260 | int fscale; |
| 3280 | struct passwd *pw; | 3261 | struct passwd *pw; |
| 3281 | struct group *gr; | 3262 | struct group *gr; |
| @@ -2503,8 +2503,6 @@ gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz) | |||
| 2503 | int | 2503 | int |
| 2504 | fdutimens (int fd, char const *file, struct timespec const timespec[2]) | 2504 | fdutimens (int fd, char const *file, struct timespec const timespec[2]) |
| 2505 | { | 2505 | { |
| 2506 | struct _utimbuf ut; | ||
| 2507 | |||
| 2508 | if (!timespec) | 2506 | if (!timespec) |
| 2509 | { | 2507 | { |
| 2510 | errno = ENOSYS; | 2508 | errno = ENOSYS; |
| @@ -2515,12 +2513,28 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) | |||
| 2515 | errno = EBADF; | 2513 | errno = EBADF; |
| 2516 | return -1; | 2514 | return -1; |
| 2517 | } | 2515 | } |
| 2518 | ut.actime = timespec[0].tv_sec; | 2516 | /* _futime's prototype defines 2nd arg as having the type 'struct |
| 2519 | ut.modtime = timespec[1].tv_sec; | 2517 | _utimbuf', while utime needs to accept 'struct utimbuf' for |
| 2518 | compatibility with Posix. So we need to use 2 different (but | ||
| 2519 | equivalent) types to avoid compiler warnings, sigh. */ | ||
| 2520 | if (fd >= 0) | 2520 | if (fd >= 0) |
| 2521 | return _futime (fd, &ut); | 2521 | { |
| 2522 | struct _utimbuf _ut; | ||
| 2523 | |||
| 2524 | _ut.actime = timespec[0].tv_sec; | ||
| 2525 | _ut.modtime = timespec[1].tv_sec; | ||
| 2526 | return _futime (fd, &_ut); | ||
| 2527 | } | ||
| 2522 | else | 2528 | else |
| 2523 | return _utime (file, &ut); | 2529 | { |
| 2530 | struct utimbuf ut; | ||
| 2531 | |||
| 2532 | ut.actime = timespec[0].tv_sec; | ||
| 2533 | ut.modtime = timespec[1].tv_sec; | ||
| 2534 | /* Call 'utime', which is implemented below, not the MS library | ||
| 2535 | function, which fails on directories. */ | ||
| 2536 | return utime (file, &ut); | ||
| 2537 | } | ||
| 2524 | } | 2538 | } |
| 2525 | 2539 | ||
| 2526 | 2540 | ||
| @@ -4501,6 +4515,9 @@ fstat (int desc, struct stat * buf) | |||
| 4501 | return 0; | 4515 | return 0; |
| 4502 | } | 4516 | } |
| 4503 | 4517 | ||
| 4518 | /* A version of 'utime' which handles directories as well as | ||
| 4519 | files. */ | ||
| 4520 | |||
| 4504 | int | 4521 | int |
| 4505 | utime (const char *name, struct utimbuf *times) | 4522 | utime (const char *name, struct utimbuf *times) |
| 4506 | { | 4523 | { |
diff --git a/src/w32term.c b/src/w32term.c index 7d51850559b..7a15323551b 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -210,7 +210,6 @@ static int volatile input_signal_count; | |||
| 210 | int w32_message_fd = -1; | 210 | int w32_message_fd = -1; |
| 211 | #endif /* CYGWIN */ | 211 | #endif /* CYGWIN */ |
| 212 | 212 | ||
| 213 | static void x_update_window_end (struct window *, int, int); | ||
| 214 | static void w32_handle_tool_bar_click (struct frame *, | 213 | static void w32_handle_tool_bar_click (struct frame *, |
| 215 | struct input_event *); | 214 | struct input_event *); |
| 216 | static void w32_define_cursor (Window, Cursor); | 215 | static void w32_define_cursor (Window, Cursor); |
| @@ -676,8 +675,8 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1) | |||
| 676 | here. */ | 675 | here. */ |
| 677 | 676 | ||
| 678 | static void | 677 | static void |
| 679 | x_update_window_end (struct window *w, int cursor_on_p, | 678 | x_update_window_end (struct window *w, bool cursor_on_p, |
| 680 | int mouse_face_overwritten_p) | 679 | bool mouse_face_overwritten_p) |
| 681 | { | 680 | { |
| 682 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); | 681 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); |
| 683 | 682 | ||
| @@ -5300,8 +5299,8 @@ w32_clear_frame_area (struct frame *f, int x, int y, int width, int height) | |||
| 5300 | 5299 | ||
| 5301 | static void | 5300 | static void |
| 5302 | w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | 5301 | w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, |
| 5303 | int x, int y, int cursor_type, int cursor_width, | 5302 | int x, int y, enum text_cursor_kinds cursor_type, |
| 5304 | int on_p, int active_p) | 5303 | int cursor_width, bool on_p, bool active_p) |
| 5305 | { | 5304 | { |
| 5306 | if (on_p) | 5305 | if (on_p) |
| 5307 | { | 5306 | { |
diff --git a/src/window.c b/src/window.c index a1a069e0e7d..b02b30cd0b2 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -5408,7 +5408,7 @@ struct save_window_data | |||
| 5408 | Lisp_Object saved_windows; | 5408 | Lisp_Object saved_windows; |
| 5409 | 5409 | ||
| 5410 | /* All fields above are traced by the GC. | 5410 | /* All fields above are traced by the GC. |
| 5411 | From `fame-cols' down, the fields are ignored by the GC. */ | 5411 | From `frame-cols' down, the fields are ignored by the GC. */ |
| 5412 | 5412 | ||
| 5413 | int frame_cols, frame_lines, frame_menu_bar_lines; | 5413 | int frame_cols, frame_lines, frame_menu_bar_lines; |
| 5414 | int frame_tool_bar_lines; | 5414 | int frame_tool_bar_lines; |
diff --git a/src/xdisp.c b/src/xdisp.c index ea1cd7dd2bc..3ff4603b727 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3912,10 +3912,14 @@ handle_face_prop (struct it *it) | |||
| 3912 | /* For strings from a `display' property, use the face at | 3912 | /* For strings from a `display' property, use the face at |
| 3913 | IT's current buffer position as the base face to merge | 3913 | IT's current buffer position as the base face to merge |
| 3914 | with, so that overlay strings appear in the same face as | 3914 | with, so that overlay strings appear in the same face as |
| 3915 | surrounding text, unless they specify their own | 3915 | surrounding text, unless they specify their own faces. |
| 3916 | faces. */ | 3916 | For strings from wrap-prefix and line-prefix properties, |
| 3917 | use the default face, possibly remapped via | ||
| 3918 | Vface_remapping_alist. */ | ||
| 3917 | base_face_id = it->string_from_prefix_prop_p | 3919 | base_face_id = it->string_from_prefix_prop_p |
| 3918 | ? DEFAULT_FACE_ID | 3920 | ? (!NILP (Vface_remapping_alist) |
| 3921 | ? lookup_basic_face (it->f, DEFAULT_FACE_ID) | ||
| 3922 | : DEFAULT_FACE_ID) | ||
| 3919 | : underlying_face_id (it); | 3923 | : underlying_face_id (it); |
| 3920 | } | 3924 | } |
| 3921 | 3925 | ||
| @@ -7046,7 +7050,9 @@ get_next_display_element (struct it *it) | |||
| 7046 | } | 7050 | } |
| 7047 | } | 7051 | } |
| 7048 | } | 7052 | } |
| 7049 | else | 7053 | /* next_element_from_display_vector sets this flag according to |
| 7054 | faces of the display vector glyphs, see there. */ | ||
| 7055 | else if (it->method != GET_FROM_DISPLAY_VECTOR) | ||
| 7050 | { | 7056 | { |
| 7051 | int face_id = face_after_it_pos (it); | 7057 | int face_id = face_after_it_pos (it); |
| 7052 | it->end_of_box_run_p | 7058 | it->end_of_box_run_p |
| @@ -25763,12 +25769,12 @@ x_produce_glyphs (struct it *it) | |||
| 25763 | 25769 | ||
| 25764 | /* EXPORT for RIF: | 25770 | /* EXPORT for RIF: |
| 25765 | Output LEN glyphs starting at START at the nominal cursor position. | 25771 | Output LEN glyphs starting at START at the nominal cursor position. |
| 25766 | Advance the nominal cursor over the text. The global variable | 25772 | Advance the nominal cursor over the text. UPDATED_ROW is the glyph row |
| 25767 | updated_row is the glyph row being updated, and updated_area is the | 25773 | being updated, and UPDATED_AREA is the area of that row being updated. */ |
| 25768 | area of that row being updated. */ | ||
| 25769 | 25774 | ||
| 25770 | void | 25775 | void |
| 25771 | x_write_glyphs (struct window *w, struct glyph *start, int len) | 25776 | x_write_glyphs (struct window *w, struct glyph_row *updated_row, |
| 25777 | struct glyph *start, enum glyph_row_area updated_area, int len) | ||
| 25772 | { | 25778 | { |
| 25773 | int x, hpos, chpos = w->phys_cursor.hpos; | 25779 | int x, hpos, chpos = w->phys_cursor.hpos; |
| 25774 | 25780 | ||
| @@ -25811,7 +25817,8 @@ x_write_glyphs (struct window *w, struct glyph *start, int len) | |||
| 25811 | Insert LEN glyphs from START at the nominal cursor position. */ | 25817 | Insert LEN glyphs from START at the nominal cursor position. */ |
| 25812 | 25818 | ||
| 25813 | void | 25819 | void |
| 25814 | x_insert_glyphs (struct window *w, struct glyph *start, int len) | 25820 | x_insert_glyphs (struct window *w, struct glyph_row *updated_row, |
| 25821 | struct glyph *start, enum glyph_row_area updated_area, int len) | ||
| 25815 | { | 25822 | { |
| 25816 | struct frame *f; | 25823 | struct frame *f; |
| 25817 | int line_height, shift_by_width, shifted_region_width; | 25824 | int line_height, shift_by_width, shifted_region_width; |
| @@ -25863,11 +25870,12 @@ x_insert_glyphs (struct window *w, struct glyph *start, int len) | |||
| 25863 | (inclusive) to pixel column TO_X (exclusive). The idea is that | 25870 | (inclusive) to pixel column TO_X (exclusive). The idea is that |
| 25864 | everything from TO_X onward is already erased. | 25871 | everything from TO_X onward is already erased. |
| 25865 | 25872 | ||
| 25866 | TO_X is a pixel position relative to updated_area of currently | 25873 | TO_X is a pixel position relative to UPDATED_AREA of currently |
| 25867 | updated window W. TO_X == -1 means clear to the end of this area. */ | 25874 | updated window W. TO_X == -1 means clear to the end of this area. */ |
| 25868 | 25875 | ||
| 25869 | void | 25876 | void |
| 25870 | x_clear_end_of_line (struct window *w, int to_x) | 25877 | x_clear_end_of_line (struct window *w, struct glyph_row *updated_row, |
| 25878 | enum glyph_row_area updated_area, int to_x) | ||
| 25871 | { | 25879 | { |
| 25872 | struct frame *f; | 25880 | struct frame *f; |
| 25873 | int max_x, min_y, max_y; | 25881 | int max_x, min_y, max_y; |
| @@ -26463,7 +26471,7 @@ erase_phys_cursor (struct window *w) | |||
| 26463 | where to put the cursor is specified by HPOS, VPOS, X and Y. */ | 26471 | where to put the cursor is specified by HPOS, VPOS, X and Y. */ |
| 26464 | 26472 | ||
| 26465 | void | 26473 | void |
| 26466 | display_and_set_cursor (struct window *w, int on, | 26474 | display_and_set_cursor (struct window *w, bool on, |
| 26467 | int hpos, int vpos, int x, int y) | 26475 | int hpos, int vpos, int x, int y) |
| 26468 | { | 26476 | { |
| 26469 | struct frame *f = XFRAME (w->frame); | 26477 | struct frame *f = XFRAME (w->frame); |
| @@ -26547,7 +26555,7 @@ display_and_set_cursor (struct window *w, int on, | |||
| 26547 | of ON. */ | 26555 | of ON. */ |
| 26548 | 26556 | ||
| 26549 | static void | 26557 | static void |
| 26550 | update_window_cursor (struct window *w, int on) | 26558 | update_window_cursor (struct window *w, bool on) |
| 26551 | { | 26559 | { |
| 26552 | /* Don't update cursor in windows whose frame is in the process | 26560 | /* Don't update cursor in windows whose frame is in the process |
| 26553 | of being deleted. */ | 26561 | of being deleted. */ |
| @@ -26583,7 +26591,7 @@ update_window_cursor (struct window *w, int on) | |||
| 26583 | in the window tree rooted at W. */ | 26591 | in the window tree rooted at W. */ |
| 26584 | 26592 | ||
| 26585 | static void | 26593 | static void |
| 26586 | update_cursor_in_window_tree (struct window *w, int on_p) | 26594 | update_cursor_in_window_tree (struct window *w, bool on_p) |
| 26587 | { | 26595 | { |
| 26588 | while (w) | 26596 | while (w) |
| 26589 | { | 26597 | { |
| @@ -26602,7 +26610,7 @@ update_cursor_in_window_tree (struct window *w, int on_p) | |||
| 26602 | Don't change the cursor's position. */ | 26610 | Don't change the cursor's position. */ |
| 26603 | 26611 | ||
| 26604 | void | 26612 | void |
| 26605 | x_update_cursor (struct frame *f, int on_p) | 26613 | x_update_cursor (struct frame *f, bool on_p) |
| 26606 | { | 26614 | { |
| 26607 | update_cursor_in_window_tree (XWINDOW (f->root_window), on_p); | 26615 | update_cursor_in_window_tree (XWINDOW (f->root_window), on_p); |
| 26608 | } | 26616 | } |
diff --git a/src/xterm.c b/src/xterm.c index b5c5a5cb584..cea952f44d2 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -292,8 +292,6 @@ static void x_set_window_size_1 (struct frame *, int, int, int); | |||
| 292 | static void x_raise_frame (struct frame *); | 292 | static void x_raise_frame (struct frame *); |
| 293 | static void x_lower_frame (struct frame *); | 293 | static void x_lower_frame (struct frame *); |
| 294 | static const XColor *x_color_cells (Display *, int *); | 294 | static const XColor *x_color_cells (Display *, int *); |
| 295 | static void x_update_window_end (struct window *, int, int); | ||
| 296 | |||
| 297 | static int x_io_error_quitter (Display *); | 295 | static int x_io_error_quitter (Display *); |
| 298 | static struct terminal *x_create_terminal (struct x_display_info *); | 296 | static struct terminal *x_create_terminal (struct x_display_info *); |
| 299 | void x_delete_terminal (struct terminal *); | 297 | void x_delete_terminal (struct terminal *); |
| @@ -612,7 +610,8 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1) | |||
| 612 | here. */ | 610 | here. */ |
| 613 | 611 | ||
| 614 | static void | 612 | static void |
| 615 | x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritten_p) | 613 | x_update_window_end (struct window *w, bool cursor_on_p, |
| 614 | bool mouse_face_overwritten_p) | ||
| 616 | { | 615 | { |
| 617 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); | 616 | Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); |
| 618 | 617 | ||
| @@ -7372,7 +7371,9 @@ x_clear_frame_area (struct frame *f, int x, int y, int width, int height) | |||
| 7372 | /* RIF: Draw cursor on window W. */ | 7371 | /* RIF: Draw cursor on window W. */ |
| 7373 | 7372 | ||
| 7374 | static void | 7373 | static void |
| 7375 | x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, int y, int cursor_type, int cursor_width, int on_p, int active_p) | 7374 | x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, |
| 7375 | int y, enum text_cursor_kinds cursor_type, | ||
| 7376 | int cursor_width, bool on_p, bool active_p) | ||
| 7376 | { | 7377 | { |
| 7377 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 7378 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 7378 | 7379 | ||