diff options
| author | Joakim Verona | 2011-07-15 04:39:29 +0200 |
|---|---|---|
| committer | Joakim Verona | 2011-07-15 04:39:29 +0200 |
| commit | 4f616a2e7ed1db28da98df90266e9751a8ae9ee1 (patch) | |
| tree | 74a9dcbe13e945e712ae04a4a94c2202ca720591 /src | |
| parent | ff2be00005c3aeda6e11d7ed264ce86f02b60958 (diff) | |
| parent | ec2bc542a4d0127425625e8cb458684bd825675a (diff) | |
| download | emacs-4f616a2e7ed1db28da98df90266e9751a8ae9ee1.tar.gz emacs-4f616a2e7ed1db28da98df90266e9751a8ae9ee1.zip | |
merge from upstream
Diffstat (limited to 'src')
| -rw-r--r-- | src/.gdbinit | 16 | ||||
| -rw-r--r-- | src/ChangeLog | 777 | ||||
| -rw-r--r-- | src/ChangeLog.6 | 2 | ||||
| -rw-r--r-- | src/ChangeLog.9 | 2 | ||||
| -rw-r--r-- | src/Makefile.in | 14 | ||||
| -rw-r--r-- | src/alloc.c | 7 | ||||
| -rw-r--r-- | src/bidi.c | 1012 | ||||
| -rw-r--r-- | src/buffer.c | 154 | ||||
| -rw-r--r-- | src/buffer.h | 4 | ||||
| -rw-r--r-- | src/callint.c | 9 | ||||
| -rw-r--r-- | src/callproc.c | 6 | ||||
| -rw-r--r-- | src/character.c | 3 | ||||
| -rw-r--r-- | src/character.h | 39 | ||||
| -rw-r--r-- | src/chartab.c | 583 | ||||
| -rw-r--r-- | src/cm.c | 3 | ||||
| -rw-r--r-- | src/coding.c | 2 | ||||
| -rw-r--r-- | src/composite.c | 7 | ||||
| -rw-r--r-- | src/data.c | 3 | ||||
| -rw-r--r-- | src/dispextern.h | 50 | ||||
| -rw-r--r-- | src/dispnew.c | 6 | ||||
| -rw-r--r-- | src/editfns.c | 28 | ||||
| -rw-r--r-- | src/emacs.c | 7 | ||||
| -rw-r--r-- | src/eval.c | 50 | ||||
| -rw-r--r-- | src/fileio.c | 4 | ||||
| -rw-r--r-- | src/floatfns.c | 3 | ||||
| -rw-r--r-- | src/fns.c | 11 | ||||
| -rw-r--r-- | src/font.c | 34 | ||||
| -rw-r--r-- | src/gnutls.c | 55 | ||||
| -rw-r--r-- | src/gtkutil.c | 24 | ||||
| -rw-r--r-- | src/image.c | 4 | ||||
| -rw-r--r-- | src/indent.c | 20 | ||||
| -rw-r--r-- | src/intervals.c | 24 | ||||
| -rw-r--r-- | src/keyboard.c | 20 | ||||
| -rw-r--r-- | src/keymap.c | 553 | ||||
| -rw-r--r-- | src/keymap.h | 4 | ||||
| -rw-r--r-- | src/lread.c | 12 | ||||
| -rw-r--r-- | src/m/iris4d.h | 26 | ||||
| -rw-r--r-- | src/nsfns.m | 12 | ||||
| -rw-r--r-- | src/nsgui.h | 5 | ||||
| -rw-r--r-- | src/nsimage.m | 4 | ||||
| -rw-r--r-- | src/nsmenu.m | 3 | ||||
| -rw-r--r-- | src/nsselect.m | 8 | ||||
| -rw-r--r-- | src/nsterm.h | 41 | ||||
| -rw-r--r-- | src/nsterm.m | 65 | ||||
| -rw-r--r-- | src/process.c | 12 | ||||
| -rw-r--r-- | src/ralloc.c | 2 | ||||
| -rw-r--r-- | src/regex.c | 17 | ||||
| -rw-r--r-- | src/s/irix6-5.h | 7 | ||||
| -rw-r--r-- | src/search.c | 16 | ||||
| -rw-r--r-- | src/sysdep.c | 20 | ||||
| -rw-r--r-- | src/term.c | 53 | ||||
| -rw-r--r-- | src/termcap.c | 50 | ||||
| -rw-r--r-- | src/textprop.c | 10 | ||||
| -rw-r--r-- | src/tparam.c | 5 | ||||
| -rw-r--r-- | src/unexhp9k800.c | 172 | ||||
| -rw-r--r-- | src/w32.c | 8 | ||||
| -rw-r--r-- | src/w32fns.c | 13 | ||||
| -rw-r--r-- | src/widget.c | 6 | ||||
| -rw-r--r-- | src/window.c | 90 | ||||
| -rw-r--r-- | src/window.h | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 1274 | ||||
| -rw-r--r-- | src/xfaces.c | 22 | ||||
| -rw-r--r-- | src/xfns.c | 11 | ||||
| -rw-r--r-- | src/xgselect.c | 10 | ||||
| -rw-r--r-- | src/xmenu.c | 11 | ||||
| -rw-r--r-- | src/xrdb.c | 23 | ||||
| -rw-r--r-- | src/xselect.c | 11 | ||||
| -rw-r--r-- | src/xsettings.c | 419 |
68 files changed, 4240 insertions, 1742 deletions
diff --git a/src/.gdbinit b/src/.gdbinit index 2cf5663df91..0f51a00ea76 100644 --- a/src/.gdbinit +++ b/src/.gdbinit | |||
| @@ -677,7 +677,7 @@ end | |||
| 677 | 677 | ||
| 678 | define xvectype | 678 | define xvectype |
| 679 | xgetptr $ | 679 | xgetptr $ |
| 680 | set $size = ((struct Lisp_Vector *) $ptr)->size | 680 | set $size = ((struct Lisp_Vector *) $ptr)->header.size |
| 681 | output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag | 681 | output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag |
| 682 | echo \n | 682 | echo \n |
| 683 | end | 683 | end |
| @@ -818,7 +818,7 @@ end | |||
| 818 | define xvector | 818 | define xvector |
| 819 | xgetptr $ | 819 | xgetptr $ |
| 820 | print (struct Lisp_Vector *) $ptr | 820 | print (struct Lisp_Vector *) $ptr |
| 821 | output ($->size > 50) ? 0 : ($->contents[0])@($->size & ~gdb_array_mark_flag) | 821 | output ($->header.size > 50) ? 0 : ($->contents[0])@($->header.size & ~gdb_array_mark_flag) |
| 822 | echo \n | 822 | echo \n |
| 823 | end | 823 | end |
| 824 | document xvector | 824 | document xvector |
| @@ -853,7 +853,7 @@ end | |||
| 853 | define xcompiled | 853 | define xcompiled |
| 854 | xgetptr $ | 854 | xgetptr $ |
| 855 | print (struct Lisp_Vector *) $ptr | 855 | print (struct Lisp_Vector *) $ptr |
| 856 | output ($->contents[0])@($->size & 0xff) | 856 | output ($->contents[0])@($->header.size & 0xff) |
| 857 | end | 857 | end |
| 858 | document xcompiled | 858 | document xcompiled |
| 859 | Print $ as a compiled function pointer. | 859 | Print $ as a compiled function pointer. |
| @@ -903,7 +903,7 @@ define xchartable | |||
| 903 | print (struct Lisp_Char_Table *) $ptr | 903 | print (struct Lisp_Char_Table *) $ptr |
| 904 | printf "Purpose: " | 904 | printf "Purpose: " |
| 905 | xprintsym $->purpose | 905 | xprintsym $->purpose |
| 906 | printf " %d extra slots", ($->size & 0x1ff) - 68 | 906 | printf " %d extra slots", ($->header.size & 0x1ff) - 68 |
| 907 | echo \n | 907 | echo \n |
| 908 | end | 908 | end |
| 909 | document xchartable | 909 | document xchartable |
| @@ -927,7 +927,7 @@ end | |||
| 927 | define xboolvector | 927 | define xboolvector |
| 928 | xgetptr $ | 928 | xgetptr $ |
| 929 | print (struct Lisp_Bool_Vector *) $ptr | 929 | print (struct Lisp_Bool_Vector *) $ptr |
| 930 | output ($->size > 256) ? 0 : ($->data[0])@((($->size & ~gdb_array_mark_flag) + 7)/ 8) | 930 | output ($->header.size > 256) ? 0 : ($->data[0])@((($->header.size & ~gdb_array_mark_flag) + 7)/ 8) |
| 931 | echo \n | 931 | echo \n |
| 932 | end | 932 | end |
| 933 | document xboolvector | 933 | document xboolvector |
| @@ -1093,7 +1093,7 @@ define xpr | |||
| 1093 | # end | 1093 | # end |
| 1094 | end | 1094 | end |
| 1095 | if $type == Lisp_Vectorlike | 1095 | if $type == Lisp_Vectorlike |
| 1096 | set $size = ((struct Lisp_Vector *) $ptr)->size | 1096 | set $size = ((struct Lisp_Vector *) $ptr)->header.size |
| 1097 | if ($size & PVEC_FLAG) | 1097 | if ($size & PVEC_FLAG) |
| 1098 | set $vec = (enum pvec_type) ($size & PVEC_TYPE_MASK) | 1098 | set $vec = (enum pvec_type) ($size & PVEC_TYPE_MASK) |
| 1099 | if $vec == PVEC_NORMAL_VECTOR | 1099 | if $vec == PVEC_NORMAL_VECTOR |
| @@ -1202,7 +1202,7 @@ end | |||
| 1202 | 1202 | ||
| 1203 | define xfont | 1203 | define xfont |
| 1204 | xgetptr $ | 1204 | xgetptr $ |
| 1205 | set $size = (((struct Lisp_Vector *) $ptr)->size & 0x1FF) | 1205 | set $size = (((struct Lisp_Vector *) $ptr)->header.size & 0x1FF) |
| 1206 | if $size == FONT_SPEC_MAX | 1206 | if $size == FONT_SPEC_MAX |
| 1207 | print (struct font_spec *) $ptr | 1207 | print (struct font_spec *) $ptr |
| 1208 | else | 1208 | else |
| @@ -1229,7 +1229,7 @@ define xbacktrace | |||
| 1229 | printf "0x%x ", $ptr | 1229 | printf "0x%x ", $ptr |
| 1230 | if $type == Lisp_Vectorlike | 1230 | if $type == Lisp_Vectorlike |
| 1231 | xgetptr (*$bt->function) | 1231 | xgetptr (*$bt->function) |
| 1232 | set $size = ((struct Lisp_Vector *) $ptr)->size | 1232 | set $size = ((struct Lisp_Vector *) $ptr)->header.size |
| 1233 | output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag | 1233 | output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag |
| 1234 | else | 1234 | else |
| 1235 | printf "Lisp type %d", $type | 1235 | printf "Lisp type %d", $type |
diff --git a/src/ChangeLog b/src/ChangeLog index 1e537f3872e..21563806ece 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,764 @@ | |||
| 1 | 2011-07-14 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix minor problems found by static checking. | ||
| 4 | * bidi.c (bidi_cache_size): Now EMACS_INT, not size_t. | ||
| 5 | (elsz): Now a signed constant, not a size_t var. We prefer signed | ||
| 6 | types to unsigned, to avoid integer comparison confusion. Without | ||
| 7 | this change, GCC 4.6.1 with -Wunsafe-loop-optimizations complains | ||
| 8 | "cannot optimize loop, the loop counter may overflow", a symptom | ||
| 9 | of the confusion. | ||
| 10 | * indent.c (Fvertical_motion): Mark locals as initialized. | ||
| 11 | * xdisp.c (reseat_to_string): Fix pointer signedness issue. | ||
| 12 | |||
| 13 | 2011-07-14 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 14 | |||
| 15 | * search.c (Fre_search_backward): Mention `case-fold-search' in | ||
| 16 | all the re_search_* functions (bug#8138). | ||
| 17 | |||
| 18 | * keyboard.c (Fopen_dribble_file): Document when the file is | ||
| 19 | closed (bug#8056). | ||
| 20 | |||
| 21 | 2011-07-14 Eli Zaretskii <eliz@gnu.org> | ||
| 22 | |||
| 23 | * bidi.c (bidi_dump_cached_states): Fix format of displaying | ||
| 24 | bidi_cache_idx. | ||
| 25 | |||
| 26 | Support bidi reordering of display and overlay strings. | ||
| 27 | * xdisp.c (compute_display_string_pos) | ||
| 28 | (compute_display_string_end): Accept additional argument STRING. | ||
| 29 | (init_iterator, reseat_1): Initialize bidi_it->string.s to NULL. | ||
| 30 | (reseat_to_string): Initialize bidi_it->string.s and | ||
| 31 | bidi_it->string.schars. | ||
| 32 | (Fcurrent_bidi_paragraph_direction): Initialize itb.string.s to | ||
| 33 | NULL (avoids a crash in bidi_paragraph_init). Initialize | ||
| 34 | itb.string.lstring. | ||
| 35 | (init_iterator): Call bidi_init_it only of a valid | ||
| 36 | buffer position was specified. Initialize paragraph_embedding to | ||
| 37 | L2R. | ||
| 38 | (reseat_to_string): Initialize the bidi iterator. | ||
| 39 | (display_string): If we need to ignore text properties of | ||
| 40 | LISP_STRING, set IT->stop_charpos to IT->end_charpos. (The | ||
| 41 | original value of -1 will not work with bidi.) | ||
| 42 | (compute_display_string_pos): First arg is now struct | ||
| 43 | `text_pos *'; all callers changed. Support display properties on | ||
| 44 | Lisp strings. | ||
| 45 | (compute_display_string_end): Support display properties on Lisp | ||
| 46 | strings. | ||
| 47 | (init_iterator, reseat_1, reseat_to_string): Initialize the | ||
| 48 | string.bufpos member to 0 (zero, for compatibility with IT_CHARPOS | ||
| 49 | when iterating on a string not from display properties). | ||
| 50 | (compute_display_string_pos, compute_display_string_end): Fix | ||
| 51 | calculation of the object to scan. Fixes an error when using | ||
| 52 | arrow keys. | ||
| 53 | (next_element_from_buffer): Don't abort when IT_CHARPOS is before | ||
| 54 | base_level_stop; instead, set base_level_stop to BEGV. Fixes | ||
| 55 | crashes in vertical-motion. | ||
| 56 | (next_element_from_buffer): Improve commentary for when | ||
| 57 | the iterator is before prev_stop. | ||
| 58 | (init_iterator): Initialize bidi_p from the default value of | ||
| 59 | bidi-display-reordering, not from buffer-local value. Use the | ||
| 60 | buffer-local value only if initializing for buffer iteration. | ||
| 61 | (handle_invisible_prop): Support invisible properties on strings | ||
| 62 | that are being bidi-reordered. | ||
| 63 | (set_iterator_to_next): Support bidi reordering of C strings and | ||
| 64 | Lisp strings. | ||
| 65 | (next_element_from_string): Support bidi reordering of Lisp | ||
| 66 | strings. | ||
| 67 | (handle_stop_backwards): Support Lisp strings as well. | ||
| 68 | (display_string): Support display of R2L glyph rows. Use | ||
| 69 | IT_STRING_CHARPOS when displaying from a Lisp string. | ||
| 70 | (init_iterator): Don't initialize it->bidi_p for strings | ||
| 71 | here. | ||
| 72 | (reseat_to_string): Initialize it->bidi_p for strings here. | ||
| 73 | (next_element_from_string, next_element_from_c_string) | ||
| 74 | (next_element_from_buffer): Add xassert's for correspondence | ||
| 75 | between IT's object being iterated and it->bidi_it.string | ||
| 76 | structure. | ||
| 77 | (face_before_or_after_it_pos): Support bidi iteration. | ||
| 78 | (next_element_from_c_string): Handle the case of the first string | ||
| 79 | character that is not the first one in the visual order. | ||
| 80 | (get_visually_first_element): New function, refactored from common | ||
| 81 | parts of next_element_from_buffer, next_element_from_string, and | ||
| 82 | next_element_from_c_string. | ||
| 83 | (tool_bar_lines_needed, redisplay_tool_bar) | ||
| 84 | (display_menu_bar): Force left-to-right direction. Add a FIXME | ||
| 85 | comment for making that be controlled by a user option. | ||
| 86 | (push_it, pop_it): Save and restore the state of the | ||
| 87 | bidi iterator. Save and restore the bidi_p flag. | ||
| 88 | (pop_it): Iterate out of display property for string iteration as | ||
| 89 | well. | ||
| 90 | (iterate_out_of_display_property): Support iteration over strings. | ||
| 91 | (handle_single_display_spec): Set up it->bidi_it for iteration | ||
| 92 | over a display string, and call bidi_init_it. | ||
| 93 | (handle_single_display_spec, next_overlay_string) | ||
| 94 | (get_overlay_strings_1, push_display_prop): Set up the bidi | ||
| 95 | iterator for displaying display or overlay strings. | ||
| 96 | (forward_to_next_line_start): Don't use the shortcut if | ||
| 97 | bidi-iterating. | ||
| 98 | (back_to_previous_visible_line_start): If handle_display_prop | ||
| 99 | pushed the iterator stack, restore the internal state of the bidi | ||
| 100 | iterator by calling bidi_pop_it same number of times. | ||
| 101 | (reseat_at_next_visible_line_start): If ON_NEWLINE_P is non-zero, | ||
| 102 | and we are bidi-iterating, don't decrement the iterator position; | ||
| 103 | instead, set the first_elt flag in the bidi iterator, to produce | ||
| 104 | the same effect. | ||
| 105 | (reseat_1): Remove redundant setting of string_from_display_prop_p. | ||
| 106 | (push_display_prop): xassert that we are iterating a buffer. | ||
| 107 | (push_it, pop_it): Save and restore paragraph_embedding member. | ||
| 108 | (handle_single_display_spec, next_overlay_string) | ||
| 109 | (get_overlay_strings_1, reseat_1, reseat_to_string) | ||
| 110 | (push_display_prop): Set up the `unibyte' member of bidi_it.string | ||
| 111 | correctly. Don't assume unibyte strings are not bidi-reordered. | ||
| 112 | (compute_display_string_pos) | ||
| 113 | (compute_display_string_end): Fix handling the case of C string. | ||
| 114 | (push_it, pop_it): Save and restore from_disp_prop_p. | ||
| 115 | (handle_single_display_spec, push_display_prop): Set the | ||
| 116 | from_disp_prop_p flag. | ||
| 117 | (get_overlay_strings_1): Reset the from_disp_prop_p flag. | ||
| 118 | (pop_it): Call iterate_out_of_display_property only if we are | ||
| 119 | popping after iteration over a string that came from a display | ||
| 120 | property. Fix a typo in popping stretch info. Add an assertion | ||
| 121 | for verifying that the iterator position is in sync with the bidi | ||
| 122 | iterator. | ||
| 123 | (handle_single_display_spec, get_overlay_strings_1) | ||
| 124 | (push_display_prop): Fix initialization of paragraph direction for | ||
| 125 | string when that of the parent object is not yet determined. | ||
| 126 | (reseat_1): Call bidi_init_it to resync the bidi | ||
| 127 | iterator with IT's position. (Bug#7616) | ||
| 128 | (find_row_edges): If ROW->start.pos gives position | ||
| 129 | smaller than min_pos, use it as ROW->minpos. (Bug#7616) | ||
| 130 | (handle_stop, back_to_previous_visible_line_start, reseat_1): | ||
| 131 | Reset the from_disp_prop_p flag. | ||
| 132 | (SAVE_IT, RESTORE_IT): New macros. | ||
| 133 | (pos_visible_p, face_before_or_after_it_pos) | ||
| 134 | (back_to_previous_visible_line_start) | ||
| 135 | (move_it_in_display_line_to, move_it_in_display_line) | ||
| 136 | (move_it_to, move_it_vertically_backward, move_it_by_lines) | ||
| 137 | (try_scrolling, redisplay_window, display_line): Use them when | ||
| 138 | saving a temporary copy of the iterator and restoring it back. | ||
| 139 | (back_to_previous_visible_line_start, reseat_1) | ||
| 140 | (init_iterator): Empty the bidi cache "stack". | ||
| 141 | (move_it_in_display_line_to): If iterator ended up at | ||
| 142 | EOL, but we never saw any buffer positions smaller than | ||
| 143 | to_charpos, return MOVE_POS_MATCH_OR_ZV. Fixes vertical cursor | ||
| 144 | motion in bidi-reordered lines. | ||
| 145 | (move_it_in_display_line_to): Record prev_method and prev_pos | ||
| 146 | immediately before the call to set_iterator_to_next. Fixes cursor | ||
| 147 | motion in bidi-reordered lines with stretch glyphs and strings | ||
| 148 | displayed in margins. (Bug#8133) (Bug#8867) | ||
| 149 | Return MOVE_POS_MATCH_OR_ZV only if iterator position is past | ||
| 150 | TO_CHARPOS. | ||
| 151 | (pos_visible_p): Support positions in bidi-reordered lines. Save | ||
| 152 | and restore bidi cache. | ||
| 153 | |||
| 154 | * bidi.c (bidi_level_of_next_char): clen should be EMACS_NT, not int. | ||
| 155 | (bidi_paragraph_info): Delete unused struct. | ||
| 156 | (bidi_cache_idx, bidi_cache_last_idx): Declare EMACS_INT. | ||
| 157 | (bidi_cache_start): New variable. | ||
| 158 | (bidi_cache_reset): Reset bidi_cache_idx to bidi_cache_start, not | ||
| 159 | to zero. | ||
| 160 | (bidi_cache_fetch_state, bidi_cache_search) | ||
| 161 | (bidi_cache_find_level_change, bidi_cache_iterator_state) | ||
| 162 | (bidi_cache_find, bidi_peek_at_next_level) | ||
| 163 | (bidi_level_of_next_char, bidi_find_other_level_edge) | ||
| 164 | (bidi_move_to_visually_next): Compare cache index with | ||
| 165 | bidi_cache_start rather than with zero. | ||
| 166 | (bidi_fetch_char): Accept new argument STRING; all callers | ||
| 167 | changed. Support iteration over a string. Support strings with | ||
| 168 | display properties. Support unibyte strings. Fix the type of | ||
| 169 | `len' according to what STRING_CHAR_AND_LENGTH expects. | ||
| 170 | (bidi_paragraph_init, bidi_resolve_explicit_1) | ||
| 171 | (bidi_resolve_explicit, bidi_resolve_weak) | ||
| 172 | (bidi_level_of_next_char, bidi_move_to_visually_next): Support | ||
| 173 | iteration over a string. | ||
| 174 | (bidi_set_sor_type, bidi_resolve_explicit_1) | ||
| 175 | (bidi_resolve_explicit, bidi_type_of_next_char): ignore_bn_limit | ||
| 176 | can now be zero (for strings); special values 0 and -1 were | ||
| 177 | changed to -1 and -2, respectively. | ||
| 178 | (bidi_char_at_pos): New function. | ||
| 179 | (bidi_paragraph_init, bidi_resolve_explicit, bidi_resolve_weak): | ||
| 180 | Call it instead of FETCH_MULTIBYTE_CHAR. | ||
| 181 | (bidi_move_to_visually_next): Abort if charpos or bytepos were not | ||
| 182 | initialized to valid values. | ||
| 183 | (bidi_init_it): Don't initialize charpos and bytepos with invalid | ||
| 184 | values. | ||
| 185 | (bidi_level_of_next_char): Allow the sentinel "position" to pass | ||
| 186 | the test for valid cached positions. Fix the logic for looking up | ||
| 187 | the sentinel state in the cache. GCPRO the Lisp string we are | ||
| 188 | iterating. | ||
| 189 | (bidi_push_it, bidi_pop_it): New functions. | ||
| 190 | (bidi_initialize): Initialize the bidi cache start stack pointer. | ||
| 191 | (bidi_cache_ensure_space): New function, refactored from part of | ||
| 192 | bidi_cache_iterator_state. Don't assume the required size is just | ||
| 193 | one BIDI_CACHE_CHUNK away. | ||
| 194 | (bidi_cache_start_stack, bidi_push_it): Use IT_STACK_SIZE. | ||
| 195 | (bidi_count_bytes, bidi_char_at_pos): New functions. | ||
| 196 | (bidi_cache_search): Don't assume bidi_cache_last_idx is | ||
| 197 | always valid if bidi_cache_idx is valid. | ||
| 198 | (bidi_cache_find_level_change): xassert that bidi_cache_last_idx | ||
| 199 | is valid if it's going to be used. | ||
| 200 | (bidi_shelve_cache, bidi_unshelve_cache): New functions. | ||
| 201 | (bidi_cache_fetch_state, bidi_cache_search) | ||
| 202 | (bidi_cache_find_level_change, bidi_cache_ensure_space) | ||
| 203 | (bidi_cache_iterator_state, bidi_cache_find) | ||
| 204 | (bidi_find_other_level_edge, bidi_cache_start_stack): All | ||
| 205 | variables related to cache indices are now EMACS_INT. | ||
| 206 | |||
| 207 | * dispextern.h (struct bidi_string_data): New structure. | ||
| 208 | (struct bidi_it): New member `string'. Make flag members be 1-bit | ||
| 209 | fields, and put them last in the struct. | ||
| 210 | (compute_display_string_pos, compute_display_string_end): Update | ||
| 211 | prototypes. | ||
| 212 | (bidi_push_it, bidi_pop_it): Add prototypes. | ||
| 213 | (struct iterator_stack_entry): New members bidi_p, | ||
| 214 | paragraph_embedding, and from_disp_prop_p. | ||
| 215 | (struct it): Member bidi_p is now a bit field 1 bit wide. | ||
| 216 | (bidi_shelve_cache, bidi_unshelve_cache): Declare | ||
| 217 | prototypes. | ||
| 218 | |||
| 219 | * .gdbinit (xvectype, xvector, xcompiled, xchartable, xboolvector) | ||
| 220 | (xpr, xfont, xbacktrace): Use "header.size" when accessing vectors | ||
| 221 | and vector-like objects. | ||
| 222 | |||
| 223 | * dispnew.c (buffer_posn_from_coords): Save and restore the bidi | ||
| 224 | cache around display iteration. | ||
| 225 | |||
| 226 | * window.c (Fwindow_end, window_scroll_pixel_based) | ||
| 227 | (displayed_window_lines, Frecenter): Save and restore the bidi | ||
| 228 | cache around display iteration. | ||
| 229 | |||
| 230 | 2011-07-14 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 231 | |||
| 232 | * editfns.c (Fdelete_region): Clarify the use of the named | ||
| 233 | parameters (bug#6788). | ||
| 234 | |||
| 235 | 2011-07-14 Martin Rudalics <rudalics@gmx.at> | ||
| 236 | |||
| 237 | * indent.c (Fvertical_motion): Set and restore w->pointm when | ||
| 238 | saving and restoring the window's buffer (Bug#9006). | ||
| 239 | |||
| 240 | 2011-07-13 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 241 | |||
| 242 | * editfns.c (Fstring_to_char): Clarify just what is returned | ||
| 243 | (bug#6576). Text by Eli Zaretskii. | ||
| 244 | |||
| 245 | 2011-07-13 Juanma Barranquero <lekktu@gmail.com> | ||
| 246 | |||
| 247 | * gnutls.c (init_gnutls_functions): Honor gnutls_log_level (bug#9059). | ||
| 248 | |||
| 249 | 2011-07-13 Eli Zaretskii <eliz@gnu.org> | ||
| 250 | |||
| 251 | * buffer.c (mmap_find): Fix a typo. | ||
| 252 | |||
| 253 | 2011-07-13 Johan Bockgård <bojohan@gnu.org> | ||
| 254 | |||
| 255 | Fix execution of x selection hooks. | ||
| 256 | * xselect.c (Qx_lost_selection_functions) | ||
| 257 | (Qx_sent_selection_functions): New vars. | ||
| 258 | (syms_of_xselect): DEFSYM them. | ||
| 259 | (x_handle_selection_request): Pass Qx_sent_selection_functions | ||
| 260 | rather than Vx_sent_selection_functions to Frun_hook_with_args. | ||
| 261 | (x_handle_selection_clear,x_clear_frame_selections): | ||
| 262 | Pass Qx_lost_selection_functions rather than | ||
| 263 | Vx_lost_selection_functions to Frun_hook_with_args. | ||
| 264 | |||
| 265 | 2011-07-13 Paul Eggert <eggert@cs.ucla.edu> | ||
| 266 | |||
| 267 | * buffer.c (Fget_buffer_create): Initialize inhibit_shrinking. | ||
| 268 | The old code sometimes used this field without initializing it. | ||
| 269 | |||
| 270 | * alloc.c (gc_sweep): Don't read past end of array. | ||
| 271 | In theory, the old code could also have corrupted Emacs internals, | ||
| 272 | though it'd be very unlikely. | ||
| 273 | |||
| 274 | 2011-07-12 Andreas Schwab <schwab@linux-m68k.org> | ||
| 275 | |||
| 276 | * character.c (Fcharacterp): Don't advertise optional ignored | ||
| 277 | argument. (Bug#4026) | ||
| 278 | |||
| 279 | 2011-07-12 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 280 | |||
| 281 | * keymap.c (syms_of_keymap): Clarify that "modifier" is "modifier | ||
| 282 | key" (bug#4257). | ||
| 283 | |||
| 284 | * window.c (Fset_window_start): Doc fix (bug#4199). | ||
| 285 | (Fset_window_hscroll): Ditto. | ||
| 286 | |||
| 287 | 2011-07-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 288 | |||
| 289 | Fix minor new problems caught by GCC 4.6.1. | ||
| 290 | * term.c (init_tty): Remove unused local. | ||
| 291 | * xsettings.c (store_monospaced_changed): Define this function only | ||
| 292 | if (defined HAVE_GSETTINGS || defined HAVE_GCONF), as it's | ||
| 293 | not used otherwise. | ||
| 294 | |||
| 295 | 2011-07-12 Chong Yidong <cyd@stupidchicken.com> | ||
| 296 | |||
| 297 | * xdisp.c (Vresize_mini_windows): Minor doc fix (Bug#3300). | ||
| 298 | |||
| 299 | 2011-07-11 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 300 | |||
| 301 | * xdisp.c (syms_of_xdisp): Make it explicit that the mini-windows | ||
| 302 | are the mini-buffer and the echo area (bug#3320). | ||
| 303 | |||
| 304 | * term.c (init_tty): Remove support for supdup, c10 and perq | ||
| 305 | terminals, which are no longer supported (bug#1482). | ||
| 306 | |||
| 307 | 2011-07-10 Johan Bockgård <bojohan@gnu.org> | ||
| 308 | |||
| 309 | * xdisp.c (Ftool_bar_lines_needed): Fix WINDOWP check. | ||
| 310 | |||
| 311 | 2011-07-10 Jan Djärv <jan.h.d@swipnet.se> | ||
| 312 | |||
| 313 | * xmenu.c (menu_highlight_callback): Only pass frame to show_help_event | ||
| 314 | for non-popups (Bug#3642). | ||
| 315 | |||
| 316 | 2011-07-10 Andreas Schwab <schwab@linux-m68k.org> | ||
| 317 | |||
| 318 | * alloc.c (reset_malloc_hooks): Protoize. | ||
| 319 | * buffer.c (mmap_init, mmap_find, mmap_free_1, mmap_enlarge) | ||
| 320 | (mmap_set_vars, mmap_alloc, mmap_free, mmap_realloc): Likewise. | ||
| 321 | * cm.c (losecursor): Likewise. | ||
| 322 | * data.c (fmod): Likewise. | ||
| 323 | * dispnew.c (swap_glyphs_in_rows): Likewise. | ||
| 324 | * emacs.c (memory_warning_signal): Likewise. | ||
| 325 | * floatfns.c (float_error): Likewise. | ||
| 326 | * font.c (check_gstring, check_otf_features, otf_tag_symbol) | ||
| 327 | (otf_open, font_otf_capability, generate_otf_features) | ||
| 328 | (font_otf_DeviceTable, font_otf_ValueRecord, font_otf_Anchor): | ||
| 329 | Likewise. | ||
| 330 | * image.c (pbm_read_file): Likewise. | ||
| 331 | * indent.c (string_display_width): Likewise. | ||
| 332 | * intervals.c (check_for_interval, search_for_interval) | ||
| 333 | (inc_interval_count, count_intervals, root_interval) | ||
| 334 | (adjust_intervals_for_insertion, make_new_interval): Likewise. | ||
| 335 | * lread.c (defalias): Likewise. | ||
| 336 | * ralloc.c (r_alloc_check): Likewise. | ||
| 337 | * regex.c (set_image_of_range_1, set_image_of_range) | ||
| 338 | (regex_grow_registers): Likewise. | ||
| 339 | * sysdep.c (strerror): Likewise. | ||
| 340 | * termcap.c (valid_filename_p, tprint, main): Likewise. | ||
| 341 | * tparam.c (main): Likewise. | ||
| 342 | * unexhp9k800.c (run_time_remap, save_data_space) | ||
| 343 | (update_file_ptrs, read_header, write_header, calculate_checksum) | ||
| 344 | (copy_file, copy_rest, display_header): Likewise. | ||
| 345 | * widget.c (mark_shell_size_user_specified, create_frame_gcs): | ||
| 346 | Likewise. | ||
| 347 | * xdisp.c (check_it): Likewise. | ||
| 348 | * xfaces.c (register_color, unregister_color, unregister_colors): | ||
| 349 | Likewise. | ||
| 350 | * xfns.c (print_fontset_result): Likewise. | ||
| 351 | * xrdb.c (member, fatal, main): Likewise. | ||
| 352 | |||
| 353 | 2011-07-10 Paul Eggert <eggert@cs.ucla.edu> | ||
| 354 | |||
| 355 | Fix minor problems found by static checking (Bug#9031). | ||
| 356 | * chartab.c (char_table_set_range, map_sub_char_table): | ||
| 357 | Remove unused locals. | ||
| 358 | (uniprop_table): Now static. | ||
| 359 | * composite.c (_work_char): Remove unused static var. | ||
| 360 | |||
| 361 | 2011-07-09 Juanma Barranquero <lekktu@gmail.com> | ||
| 362 | |||
| 363 | * chartab.c (uniprop_table_uncompress): Remove unused local variable. | ||
| 364 | |||
| 365 | 2011-07-09 Jan Djärv <jan.h.d@swipnet.se> | ||
| 366 | |||
| 367 | * gtkutil.c (qttip_cb): Remove code without function. | ||
| 368 | |||
| 369 | 2011-07-09 Eli Zaretskii <eliz@gnu.org> | ||
| 370 | |||
| 371 | * w32.c (pthread_sigmask): New stub. | ||
| 372 | |||
| 373 | 2011-07-08 Paul Eggert <eggert@cs.ucla.edu> | ||
| 374 | |||
| 375 | Use pthread_sigmask, not sigprocmask (Bug#9010). | ||
| 376 | sigprocmask is portable only for single-threaded applications, and | ||
| 377 | Emacs can be multi-threaded when it uses GTK. | ||
| 378 | * Makefile.in (LIB_PTHREAD_SIGMASK): New macro. | ||
| 379 | (LIBES): Use it. | ||
| 380 | * callproc.c (Fcall_process): | ||
| 381 | * process.c (create_process): | ||
| 382 | * sysdep.c (sys_sigblock, sys_sigunblock, sys_sigsetmask): | ||
| 383 | Use pthread_sigmask, not sigprocmask. | ||
| 384 | |||
| 385 | 2011-07-08 Jan Djärv <jan.h.d@swipnet.se> | ||
| 386 | |||
| 387 | * gtkutil.c (qttip_cb): Set line wrap to FALSE for tooltip widget. | ||
| 388 | (xg_prepare_tooltip): Revert text in x->ttip_lbl, margins was | ||
| 389 | wrong (Bug#8591). | ||
| 390 | |||
| 391 | 2011-07-08 Jan Djärv <jan.h.d@swipnet.se> | ||
| 392 | |||
| 393 | * gtkutil.c (xg_prepare_tooltip): Fix indentation and comment. | ||
| 394 | Put text in x->ttip_lbl instead of gtk_tooltip_set_text (Bug#8591). | ||
| 395 | (xg_hide_tooltip): Fix comment. | ||
| 396 | |||
| 397 | * nsterm.m (initFrameFromEmacs): Don't use ns_return_types | ||
| 398 | in registerServicesMenuSendTypes. | ||
| 399 | (validRequestorForSendType): Don't check ns_return_types. | ||
| 400 | |||
| 401 | * nsfns.m (Fx_open_connection): Put NSStringPboardType into | ||
| 402 | ns_return_type. | ||
| 403 | |||
| 404 | 2011-07-08 Jason Rumney <jasonr@gnu.org> | ||
| 405 | |||
| 406 | * w32fns.c (w32_wnd_proc) [WM_TIMER, WM_SET_CURSOR]: Avoid using | ||
| 407 | frame struct members of non-existent frames (Bug#6284). | ||
| 408 | |||
| 409 | 2011-07-08 Jan Djärv <jan.h.d@swipnet.se> | ||
| 410 | |||
| 411 | * nsterm.m (keyDown): Call to wantsToDelayTextChangeNotifications and | ||
| 412 | variable firstTime not needed on OSX >= 10.6. | ||
| 413 | (setPosition): setFloatValue:knobProportion: is deprecated on OSX | ||
| 414 | >= 10.5. Use setKnobProportion, setDoubleValue. | ||
| 415 | |||
| 416 | * nsterm.h (MAC_OS_X_VERSION_10_3, MAC_OS_X_VERSION_10_4) | ||
| 417 | (MAC_OS_X_VERSION_10_5): Define if not defined. | ||
| 418 | (EmacsView, EmacsTooltip): Implements NSWindowDelegate on OSX >= 10.6. | ||
| 419 | (EmacsMenu): Implements NSMenuDelegate on OSX >= 10.6. | ||
| 420 | (EmacsToolbar): Implements NSToolbarDelegate on OSX >= 10.6. | ||
| 421 | |||
| 422 | * nsselect.m (ns_string_from_pasteboard): Don't use deprecated methods | ||
| 423 | cString and lossyCString on OSX >= 10.4 | ||
| 424 | |||
| 425 | * nsmenu.m (fillWithWidgetValue): Don't use depercated method | ||
| 426 | sizeToFit on OSX >= 10.2. | ||
| 427 | |||
| 428 | * nsimage.m (allocInitFromFile): Don't use deprecated method | ||
| 429 | bestRepresentationForDevice on OSX >= 10.6. | ||
| 430 | |||
| 431 | * nsfns.m (check_ns_display_info): Cast to long and use %ld in error | ||
| 432 | to avoid warning. | ||
| 433 | |||
| 434 | * emacs.c: Declare unexec_init_emacs_zone. | ||
| 435 | |||
| 436 | * nsgui.h: Fix compiler warning about gnulib redefining verify. | ||
| 437 | |||
| 438 | * nsselect.m (ns_get_local_selection): Change to extern (Bug#8842). | ||
| 439 | |||
| 440 | * nsmenu.m (ns_update_menubar): Remove useless setDelegate call | ||
| 441 | on svcsMenu (Bug#8842). | ||
| 442 | |||
| 443 | * nsfns.m (Fx_open_connection): Remove NSStringPboardType from | ||
| 444 | ns_return_types. | ||
| 445 | (Fns_list_services): Just return Qnil on 10.6, code not working there. | ||
| 446 | |||
| 447 | * nsterm.m (QUTF8_STRING): Declare. | ||
| 448 | (initFrameFromEmacs): Call registerServicesMenuSendTypes. | ||
| 449 | (validRequestorForSendType): Return type is (id). | ||
| 450 | Change indexOfObjectIdenticalTo to indexOfObject. | ||
| 451 | Check if we have local selection before returning self (Bug#8842). | ||
| 452 | (writeSelectionToPasteboard): Put local selection into paste board | ||
| 453 | if we have a local selection (Bug#8842). | ||
| 454 | (syms_of_nsterm): DEFSYM QUTF8_STRING. | ||
| 455 | |||
| 456 | * nsterm.h (MAC_OS_X_VERSION_10_6): Define here instead of nsterm.m. | ||
| 457 | (ns_get_local_selection): Declare. | ||
| 458 | |||
| 459 | 2011-07-07 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 460 | |||
| 461 | * keymap.c (describe_map_tree): Don't insert a double newline at | ||
| 462 | the end of the buffer (bug#1169) and return whether we inserted | ||
| 463 | something. | ||
| 464 | |||
| 465 | * callint.c (Fcall_interactively): Change "reading args" to | ||
| 466 | "providing args" to try to clarify what it does (bug#1010). | ||
| 467 | |||
| 468 | 2011-07-07 Kenichi Handa <handa@m17n.org> | ||
| 469 | |||
| 470 | * composite.c (composition_compute_stop_pos): Ignore a static | ||
| 471 | composition starting before CHARPOS (Bug#8915). | ||
| 472 | |||
| 473 | * xdisp.c (handle_composition_prop): Likewise. | ||
| 474 | |||
| 475 | 2011-07-07 Eli Zaretskii <eliz@gnu.org> | ||
| 476 | |||
| 477 | * term.c (produce_glyphs) <xassert>: Allow IT_GLYPHLESS in it->what. | ||
| 478 | (Bug#9015) | ||
| 479 | |||
| 480 | 2011-07-07 Kenichi Handa <handa@m17n.org> | ||
| 481 | |||
| 482 | * character.h (unicode_category_t): New enum type. | ||
| 483 | |||
| 484 | * chartab.c (uniprop_decoder_t, uniprop_encoder_t): New types. | ||
| 485 | (Qchar_code_property_table): New variable. | ||
| 486 | (UNIPROP_TABLE_P, UNIPROP_GET_DECODER) | ||
| 487 | (UNIPROP_COMPRESSED_FORM_P): New macros. | ||
| 488 | (char_table_ascii): Uncompress the compressed values. | ||
| 489 | (sub_char_table_ref): New arg is_uniprop. Callers changed. | ||
| 490 | Uncompress the compressed values. | ||
| 491 | (sub_char_table_ref_and_range): Likewise. | ||
| 492 | (char_table_ref_and_range): Uncompress the compressed values. | ||
| 493 | (sub_char_table_set): New arg is_uniprop. Callers changed. | ||
| 494 | Uncompress the compressed values. | ||
| 495 | (sub_char_table_set_range): Args changed. Callers changed. | ||
| 496 | (char_table_set_range): Adjuted for the above change. | ||
| 497 | (map_sub_char_table): Delete args default_val and parent. Add arg | ||
| 498 | top. Give decoded values to a Lisp function. | ||
| 499 | (map_char_table): Adjusted for the above change. Give decoded | ||
| 500 | values to a Lisp function. Gcpro more variables. | ||
| 501 | (uniprop_table_uncompress) | ||
| 502 | (uniprop_decode_value_run_length): New functions. | ||
| 503 | (uniprop_decoder, uniprop_decoder_count): New variables. | ||
| 504 | (uniprop_get_decoder, uniprop_encode_value_character) | ||
| 505 | (uniprop_encode_value_run_length, uniprop_encode_value_numeric): | ||
| 506 | New functions. | ||
| 507 | (uniprop_encoder, uniprop_encoder_count): New variables. | ||
| 508 | (uniprop_get_encoder, uniprop_table) | ||
| 509 | (Funicode_property_table_internal, Fget_unicode_property_internal) | ||
| 510 | (Fput_unicode_property_internal): New functions. | ||
| 511 | (syms_of_chartab): DEFSYM Qchar_code_property_table, defsubr | ||
| 512 | Sunicode_property_table_internal, Sget_unicode_property_internal, | ||
| 513 | and Sput_unicode_property_internal. Defvar_lisp | ||
| 514 | char-code-property-alist. | ||
| 515 | |||
| 516 | * composite.c (CHAR_COMPOSABLE_P): Adjusted for the change of | ||
| 517 | Vunicode_category_table. | ||
| 518 | |||
| 519 | * font.c (font_range): Adjusted for the change of | ||
| 520 | Vunicode_category_table. | ||
| 521 | |||
| 522 | 2011-07-07 Dan Nicolaescu <dann@ics.uci.edu> | ||
| 523 | |||
| 524 | * m/iris4d.h: Remove file, move contents ... | ||
| 525 | * s/irix6-5.h: ... here. | ||
| 526 | |||
| 527 | 2011-07-06 Paul Eggert <eggert@cs.ucla.edu> | ||
| 528 | |||
| 529 | Remove unportable assumption about struct layout (Bug#8884). | ||
| 530 | * alloc.c (mark_buffer): | ||
| 531 | * buffer.c (reset_buffer_local_variables, Fbuffer_local_variables) | ||
| 532 | (clone_per_buffer_values): Don't assume that | ||
| 533 | sizeof (struct buffer) is a multiple of sizeof (Lisp_Object). | ||
| 534 | This isn't true in general, and it's particularly not true | ||
| 535 | if Emacs is configured with --with-wide-int. | ||
| 536 | * buffer.h (FIRST_FIELD_PER_BUFFER, LAST_FIELD_PER_BUFFER): | ||
| 537 | New macros, used in the buffer.c change. | ||
| 538 | |||
| 539 | 2011-07-05 Jan Djärv <jan.h.d@swipnet.se> | ||
| 540 | |||
| 541 | * xsettings.c: Use both GConf and GSettings if both are available. | ||
| 542 | (store_config_changed_event): Add comment. | ||
| 543 | (dpyinfo_valid, store_font_name_changed, map_tool_bar_style) | ||
| 544 | (store_tool_bar_style_changed): New functions. | ||
| 545 | (store_monospaced_changed): Add comment. Call dpyinfo_valid. | ||
| 546 | (struct xsettings): Move font inside HAVE_XFT. | ||
| 547 | (GSETTINGS_TOOL_BAR_STYLE, GSETTINGS_FONT_NAME): New defines. | ||
| 548 | (GSETTINGS_MONO_FONT): Renamed from SYSTEM_MONO_FONT. | ||
| 549 | Move inside HAVE_XFT. | ||
| 550 | (something_changed_gsettingsCB): Renamed from something_changedCB. | ||
| 551 | Check for changes in GSETTINGS_TOOL_BAR_STYLE and GSETTINGS_FONT_NAME | ||
| 552 | also. | ||
| 553 | (GCONF_TOOL_BAR_STYLE, GCONF_FONT_NAME): New defines. | ||
| 554 | (GCONF_MONO_FONT): Renamed from SYSTEM_MONO_FONT. Move inside HAVE_XFT. | ||
| 555 | (something_changed_gconfCB): Renamed from something_changedCB. | ||
| 556 | Check for changes in GCONF_TOOL_BAR_STYLE and GCONF_FONT_NAME also. | ||
| 557 | (parse_settings): Move check for font inside HAVE_XFT. | ||
| 558 | (read_settings, apply_xft_settings): Add comment. | ||
| 559 | (read_and_apply_settings): Add comment. Call map_tool_bar_style and | ||
| 560 | store_tool_bar_style_changed. Move check for font inside HAVE_XFT and | ||
| 561 | call store_font_name_changed. | ||
| 562 | (xft_settings_event): Add comment. | ||
| 563 | (init_gsettings): Add comment. Get values for GSETTINGS_TOOL_BAR_STYLE | ||
| 564 | and GSETTINGS_FONT_NAME. Move check for fonts within HAVE_XFT. | ||
| 565 | (init_gconf): Add comment. Get values for GCONF_TOOL_BAR_STYLE | ||
| 566 | and GCONF_FONT_NAME. Move check for fonts within HAVE_XFT. | ||
| 567 | (xsettings_initialize): Call init_gsettings last. | ||
| 568 | (xsettings_get_system_font, xsettings_get_system_normal_font): Add | ||
| 569 | comment. | ||
| 570 | |||
| 571 | 2011-07-05 Paul Eggert <eggert@cs.ucla.edu> | ||
| 572 | |||
| 573 | Random fixes. E.g., (random) never returned negative values. | ||
| 574 | * fns.c (Frandom): Use GET_EMACS_TIME for random seed, and add the | ||
| 575 | subseconds part to the entropy, as that's a bit more random. | ||
| 576 | Prefer signed to unsigned, since the signedness doesn't matter and | ||
| 577 | in general we prefer signed. When given a limit, use a | ||
| 578 | denominator equal to INTMASK + 1, not to VALMASK + 1, because the | ||
| 579 | latter isn't right if USE_2_TAGS_FOR_INTS. | ||
| 580 | * sysdep.c (get_random): Return a value in the range 0..INTMASK, | ||
| 581 | not 0..VALMASK. Don't discard "excess" bits that random () returns. | ||
| 582 | |||
| 583 | 2011-07-04 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 584 | |||
| 585 | * textprop.c (text_property_stickiness): | ||
| 586 | Obey Vtext_property_default_nonsticky. | ||
| 587 | (syms_of_textprop): Add `display' to Vtext_property_default_nonsticky. | ||
| 588 | * w32fns.c (syms_of_w32fns): | ||
| 589 | * xfns.c (syms_of_xfns): Don't Add `display' since it's there by default. | ||
| 590 | |||
| 591 | 2011-07-04 Paul Eggert <eggert@cs.ucla.edu> | ||
| 592 | |||
| 593 | * fileio.c (barf_or_query_if_file_exists): Use S_ISDIR. | ||
| 594 | This is more efficient than Ffile_directory_p and avoids a minor race. | ||
| 595 | |||
| 596 | 2011-07-04 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 597 | |||
| 598 | * buffer.c (Foverlay_put): Say what the return value is | ||
| 599 | (bug#7835). | ||
| 600 | |||
| 601 | * fileio.c (barf_or_query_if_file_exists): Check first if the file | ||
| 602 | is a directory before asking whether to use the file name | ||
| 603 | (bug#7564). | ||
| 604 | (barf_or_query_if_file_exists): Make the "File is a directory" | ||
| 605 | error be more correct. | ||
| 606 | |||
| 607 | * fns.c (Frequire): Remove the mention of the .gz files, since | ||
| 608 | that's installation-specific, but keep the mention of | ||
| 609 | `get-load-suffixes'. | ||
| 610 | |||
| 611 | 2011-07-04 Paul Eggert <eggert@cs.ucla.edu> | ||
| 612 | |||
| 613 | * editfns.c (Fformat_time_string): Don't assume strlen fits in int. | ||
| 614 | Report string overflow if the output is too long. | ||
| 615 | |||
| 616 | 2011-07-04 Juanma Barranquero <lekktu@gmail.com> | ||
| 617 | |||
| 618 | * gnutls.c (Fgnutls_boot): Don't mention :verify-error. | ||
| 619 | (syms_of_gnutls): Remove duplicate DEFSYM for | ||
| 620 | Qgnutls_bootprop_verify_hostname_error, an error for | ||
| 621 | Qgnutls_bootprop_verify_error (which is no longer used). | ||
| 622 | |||
| 623 | * eval.c (find_handler_clause): Remove parameters `sig' and `data', | ||
| 624 | unused since 2011-01-26T20:02:07Z!monnier@iro.umontreal.ca. All callers changed. | ||
| 625 | Also (re)move comments that are misplaced or no longer relevant. | ||
| 626 | |||
| 627 | 2011-07-03 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 628 | |||
| 629 | * callint.c (Finteractive): Clarify the meaning of "@" (bug#8813). | ||
| 630 | |||
| 631 | 2011-07-03 Chong Yidong <cyd@stupidchicken.com> | ||
| 632 | |||
| 633 | * xfaces.c (Finternal_merge_in_global_face): Modify the foreground | ||
| 634 | and background color parameters if they have been changed. | ||
| 635 | |||
| 636 | 2011-07-03 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 637 | |||
| 638 | * editfns.c (Fformat): Clarify the - and 0 flags (bug#6659). | ||
| 639 | |||
| 640 | 2011-07-03 Paul Eggert <eggert@cs.ucla.edu> | ||
| 641 | |||
| 642 | * xsettings.c (SYSTEM_FONT): Define only when used. | ||
| 643 | No need to define when HAVE_GSETTINGS || !HAVE_XFT. | ||
| 644 | |||
| 645 | * keymap.c (access_keymap_1): Now static. | ||
| 646 | |||
| 647 | 2011-07-02 Chong Yidong <cyd@stupidchicken.com> | ||
| 648 | |||
| 649 | * keyboard.c (command_loop_1): If a down-mouse event is unbound, | ||
| 650 | leave any prefix arg for the up event (Bug#1586). | ||
| 651 | |||
| 652 | 2011-07-02 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 653 | |||
| 654 | * lread.c (syms_of_lread): Mention single symbols defined by | ||
| 655 | `defvar' or `defconst' (bug#7154). | ||
| 656 | |||
| 657 | * fns.c (Frequire): Mention .el.gz files (bug#7314). | ||
| 658 | (Frequire): Mention get-load-suffixes. | ||
| 659 | |||
| 660 | 2011-07-02 Martin Rudalics <rudalics@gmx.at> | ||
| 661 | |||
| 662 | * window.h (window): Remove clone_number slot. | ||
| 663 | * window.c (Fwindow_clone_number, Fset_window_clone_number): | ||
| 664 | Remove. | ||
| 665 | (make_parent_window, make_window, saved_window) | ||
| 666 | (Fset_window_configuration, save_window_save): Don't deal with | ||
| 667 | clone numbers. | ||
| 668 | * buffer.c (Qclone_number): Remove declaration. | ||
| 669 | (sort_overlays, overlay_strings): Don't deal with clone numbers. | ||
| 670 | |||
| 671 | 2011-07-02 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 672 | |||
| 673 | Add multiple inheritance to keymaps. | ||
| 674 | * keymap.c (Fmake_composed_keymap): New function. | ||
| 675 | (Fset_keymap_parent): Simplify. | ||
| 676 | (fix_submap_inheritance): Remove. | ||
| 677 | (access_keymap_1): New function extracted from access_keymap to handle | ||
| 678 | embedded parents and handle lists of maps. | ||
| 679 | (access_keymap): Use it. | ||
| 680 | (Fkeymap_prompt, map_keymap_internal, map_keymap, store_in_keymap) | ||
| 681 | (Fcopy_keymap): Handle embedded parents. | ||
| 682 | (Fcommand_remapping, define_as_prefix): Simplify. | ||
| 683 | (Fkey_binding): Simplify. | ||
| 684 | (syms_of_keymap): Move minibuffer-local-completion-map, | ||
| 685 | minibuffer-local-filename-completion-map, | ||
| 686 | minibuffer-local-must-match-map, and | ||
| 687 | minibuffer-local-filename-must-match-map to Elisp. | ||
| 688 | (syms_of_keymap): Defsubr make-composed-keymap. | ||
| 689 | * keyboard.c (menu_bar_items): Use map_keymap_canonical. | ||
| 690 | (parse_menu_item): Trivial simplification. | ||
| 691 | |||
| 692 | 2011-07-01 Glenn Morris <rgm@gnu.org> | ||
| 693 | |||
| 694 | * Makefile.in (SETTINGS_LIBS): Fix typo. | ||
| 695 | |||
| 696 | 2011-07-01 Kazuhiro Ito <kzhr@d1.dion.ne.jp> (tiny patch) | ||
| 697 | |||
| 698 | * coding.c (Fencode_coding_string): Record the last coding system | ||
| 699 | used, as the function doc string says (bug#8738). | ||
| 700 | |||
| 701 | 2011-07-01 Jan Djärv <jan.h.d@swipnet.se> | ||
| 702 | |||
| 703 | * xsettings.c (store_monospaced_changed): Take new font as arg and | ||
| 704 | check for change against current_mono_font. | ||
| 705 | (EMACS_TYPE_SETTINGS): Remove this and related defines. | ||
| 706 | (emacs_settings_constructor, emacs_settings_get_property) | ||
| 707 | (emacs_settings_set_property, emacs_settings_class_init) | ||
| 708 | (emacs_settings_init, gsettings_obj): Remove. | ||
| 709 | (something_changedCB): New function for HAVE_GSETTINGS. | ||
| 710 | (something_changedCB): HAVE_GCONF: Call store_monospaced_changed | ||
| 711 | with value as argument. | ||
| 712 | (init_gsettings): Check that GSETTINGS_SCHEMA exists before calling | ||
| 713 | g_settings_new (Bug#8967). Do not create gsettings_obj. | ||
| 714 | Remove calls to g_settings_bind. Connect something_changedCB to | ||
| 715 | "changed". | ||
| 716 | |||
| 717 | * xgselect.c: Add defined (HAVE_GSETTINGS). | ||
| 718 | (xgselect_initialize): Ditto. | ||
| 719 | |||
| 720 | * process.c: Add defined (HAVE_GSETTINGS) for xgselect.h | ||
| 721 | (wait_reading_process_output): Add defined (HAVE_GSETTINGS) for | ||
| 722 | xg_select. | ||
| 723 | |||
| 724 | 2011-07-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 725 | |||
| 726 | * eval.c (struct backtrace): Simplify and port the data structure. | ||
| 727 | Do not assume that "int nargs : BITS_PER_INT - 2;" produces a | ||
| 728 | signed bit field, as this assumption is not portable and it makes | ||
| 729 | Emacs crash when compiled with Sun C 5.8 on sparc. Do not use | ||
| 730 | "char debug_on_exit : 1" as this is not portable either; instead, | ||
| 731 | use the portable "unsigned int debug_on_exit : 1". Remove unused | ||
| 732 | member evalargs. Remove obsolete comments about cc bombing out. | ||
| 733 | |||
| 734 | 2011-06-30 Jan Djärv <jan.h.d@swipnet.se> | ||
| 735 | |||
| 736 | * xsettings.c: Include glib-object.h, gio/gio.h if HAVE_GSETTINGS. | ||
| 737 | Let HAVE_GSETTINGS override HAVE_GCONF. | ||
| 738 | (store_monospaced_changed): New function. | ||
| 739 | (EMACS_SETTINGS): A new type derived from GObject to handle | ||
| 740 | GSettings notifications. | ||
| 741 | (emacs_settings_constructor, emacs_settings_get_property) | ||
| 742 | (emacs_settings_set_property, emacs_settings_class_init): | ||
| 743 | New functions. | ||
| 744 | (gsettings_client, gsettings_obj): New variables. | ||
| 745 | (GSETTINGS_SCHEMA): New define. | ||
| 746 | (something_changedCB): Call store_monospaced_changed. | ||
| 747 | (init_gsettings): New function. | ||
| 748 | (xsettings_initialize): Call init_gsettings. | ||
| 749 | (syms_of_xsettings): Initialize gsettings_client, gsettings_obj | ||
| 750 | to NULL. | ||
| 751 | |||
| 752 | * Makefile.in (SETTINGS_CFLAGS, SETTINGS_LIBS): Renamed from | ||
| 753 | GCONF_CFLAGS/LIBS. | ||
| 754 | |||
| 755 | 2011-06-29 Martin Rudalics <rudalics@gmx.at> | ||
| 756 | |||
| 757 | * window.c (resize_root_window, grow_mini_window) | ||
| 758 | (shrink_mini_window): Rename Qresize_root_window to | ||
| 759 | Qwindow_resize_root_window and Qresize_root_window_vertically to | ||
| 760 | Qwindow_resize_root_window_vertically. | ||
| 761 | |||
| 1 | 2011-06-28 Paul Eggert <eggert@cs.ucla.edu> | 762 | 2011-06-28 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 763 | ||
| 3 | * gnutls.c (Qgnutls_bootprop_verify_error): Remove unused var. | 764 | * gnutls.c (Qgnutls_bootprop_verify_error): Remove unused var. |
| @@ -47,8 +808,8 @@ | |||
| 47 | min_width/height (Bug#8919). | 808 | min_width/height (Bug#8919). |
| 48 | 809 | ||
| 49 | * gtkutil.c (xg_create_frame_widgets): Pass f to emacs_fixed_new. | 810 | * gtkutil.c (xg_create_frame_widgets): Pass f to emacs_fixed_new. |
| 50 | (x_wm_set_size_hint): Remove call to emacs_fixed_set_min_size. Fix | 811 | (x_wm_set_size_hint): Remove call to emacs_fixed_set_min_size. |
| 51 | indentation. | 812 | Fix indentation. |
| 52 | 813 | ||
| 53 | 2011-06-26 Eli Zaretskii <eliz@gnu.org> | 814 | 2011-06-26 Eli Zaretskii <eliz@gnu.org> |
| 54 | 815 | ||
| @@ -1405,7 +2166,7 @@ | |||
| 1405 | (xpm_put_color_table_h): | 2166 | (xpm_put_color_table_h): |
| 1406 | * lisp.h (struct Lisp_Hash_Table): | 2167 | * lisp.h (struct Lisp_Hash_Table): |
| 1407 | * minibuf.c (Ftry_completion, Fall_completions, Ftest_completion): | 2168 | * minibuf.c (Ftry_completion, Fall_completions, Ftest_completion): |
| 1408 | * print.c (print): Use 'EMACS_UINT' and 'EMACS_INT' | 2169 | * print.c (print): Use 'EMACS_UINT' and 'EMACS_INT' |
| 1409 | for hashes and hash indexes, instead of 'unsigned' and 'int'. | 2170 | for hashes and hash indexes, instead of 'unsigned' and 'int'. |
| 1410 | * alloc.c (allocate_vectorlike): | 2171 | * alloc.c (allocate_vectorlike): |
| 1411 | Check for overflow in vector size calculations. | 2172 | Check for overflow in vector size calculations. |
| @@ -1609,7 +2370,7 @@ | |||
| 1609 | and %.0c. Fix bug with strchr succeeding on '\0' when looking for | 2370 | and %.0c. Fix bug with strchr succeeding on '\0' when looking for |
| 1610 | flags. Fix bug with (format "%c" 256.0). Avoid integer overflow when | 2371 | flags. Fix bug with (format "%c" 256.0). Avoid integer overflow when |
| 1611 | formatting out-of-range floating point numbers with int | 2372 | formatting out-of-range floating point numbers with int |
| 1612 | formats. (Bug#8668) | 2373 | formats. (Bug#8668) |
| 1613 | 2374 | ||
| 1614 | * lisp.h (FIXNUM_OVERFLOW_P): Work even if arg is a NaN. | 2375 | * lisp.h (FIXNUM_OVERFLOW_P): Work even if arg is a NaN. |
| 1615 | 2376 | ||
| @@ -1702,7 +2463,7 @@ | |||
| 1702 | 2463 | ||
| 1703 | * dispnew.c (shift_glyph_matrix, scrolling_window): Mark scrolled row | 2464 | * dispnew.c (shift_glyph_matrix, scrolling_window): Mark scrolled row |
| 1704 | for fringe update if it has periodic bitmap. | 2465 | for fringe update if it has periodic bitmap. |
| 1705 | (row_equal_p): Also compare left_fringe_offset, right_fringe_offset, | 2466 | (row_equal_p): Also compare left_fringe_offset, right_fringe_offset, |
| 1706 | and fringe_bitmap_periodic_p. | 2467 | and fringe_bitmap_periodic_p. |
| 1707 | 2468 | ||
| 1708 | * fringe.c (get_fringe_bitmap_data): New function. | 2469 | * fringe.c (get_fringe_bitmap_data): New function. |
| @@ -2573,9 +3334,9 @@ | |||
| 2573 | :verify-hostname-error, :verify-error, and :verify-flags | 3334 | :verify-hostname-error, :verify-error, and :verify-flags |
| 2574 | parameters of `gnutls-boot' and documented those parameters in the | 3335 | parameters of `gnutls-boot' and documented those parameters in the |
| 2575 | docstring. Start callback support. | 3336 | docstring. Start callback support. |
| 2576 | (emacs_gnutls_handshake): Add Woe32 support. Retry handshake | 3337 | (emacs_gnutls_handshake): Add Woe32 support. Retry handshake |
| 2577 | unless a fatal error occured. Call gnutls_alert_send_appropriate | 3338 | unless a fatal error occurred. Call gnutls_alert_send_appropriate |
| 2578 | on error. Return error code. | 3339 | on error. Return error code. |
| 2579 | (emacs_gnutls_write): Call emacs_gnutls_handle_error. | 3340 | (emacs_gnutls_write): Call emacs_gnutls_handle_error. |
| 2580 | (emacs_gnutls_read): Likewise. | 3341 | (emacs_gnutls_read): Likewise. |
| 2581 | (Fgnutls_boot): Return handshake error code. | 3342 | (Fgnutls_boot): Return handshake error code. |
diff --git a/src/ChangeLog.6 b/src/ChangeLog.6 index d7903568102..f9372aa666a 100644 --- a/src/ChangeLog.6 +++ b/src/ChangeLog.6 | |||
| @@ -4599,7 +4599,7 @@ | |||
| 4599 | 4599 | ||
| 4600 | 1995-08-14 Erik Naggum <erik@naggum.no> | 4600 | 1995-08-14 Erik Naggum <erik@naggum.no> |
| 4601 | 4601 | ||
| 4602 | * emacs.c (standard_args): Add option --eval to evalute an | 4602 | * emacs.c (standard_args): Add option --eval to evaluate an |
| 4603 | expression on the command line and print the result. | 4603 | expression on the command line and print the result. |
| 4604 | 4604 | ||
| 4605 | 1995-08-14 Richard Stallman <rms@mole.gnu.ai.mit.edu> | 4605 | 1995-08-14 Richard Stallman <rms@mole.gnu.ai.mit.edu> |
diff --git a/src/ChangeLog.9 b/src/ChangeLog.9 index 0c39de74a6a..f25434087c1 100644 --- a/src/ChangeLog.9 +++ b/src/ChangeLog.9 | |||
| @@ -5985,7 +5985,7 @@ | |||
| 5985 | GC_PROTECT_MALLOC_STATE]: New function. | 5985 | GC_PROTECT_MALLOC_STATE]: New function. |
| 5986 | (PROTECT_MALLOC_STATE): New macro. | 5986 | (PROTECT_MALLOC_STATE): New macro. |
| 5987 | (__malloc_initialize, morecore, _malloc_internal) | 5987 | (__malloc_initialize, morecore, _malloc_internal) |
| 5988 | (_free_internal) _realloc_internal): Use it to make _heapinfo | 5988 | (_free_internal, _realloc_internal): Use it to make _heapinfo |
| 5989 | read-only outside of gmalloc. | 5989 | read-only outside of gmalloc. |
| 5990 | 5990 | ||
| 5991 | * keymap.c: Update copyright. | 5991 | * keymap.c: Update copyright. |
diff --git a/src/Makefile.in b/src/Makefile.in index d1e212e92b7..27ae6aff4da 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -152,8 +152,8 @@ DBUS_LIBS = @DBUS_LIBS@ | |||
| 152 | ## dbusbind.o if HAVE_DBUS, else empty. | 152 | ## dbusbind.o if HAVE_DBUS, else empty. |
| 153 | DBUS_OBJ = @DBUS_OBJ@ | 153 | DBUS_OBJ = @DBUS_OBJ@ |
| 154 | 154 | ||
| 155 | GCONF_CFLAGS = @GCONF_CFLAGS@ | 155 | SETTINGS_CFLAGS = @SETTINGS_CFLAGS@ |
| 156 | GCONF_LIBS = @GCONF_LIBS@ | 156 | SETTINGS_LIBS = @SETTINGS_LIBS@ |
| 157 | 157 | ||
| 158 | ## gtkutil.o if USE_GTK, else empty. | 158 | ## gtkutil.o if USE_GTK, else empty. |
| 159 | GTK_OBJ=@GTK_OBJ@ | 159 | GTK_OBJ=@GTK_OBJ@ |
| @@ -275,6 +275,8 @@ LIBSELINUX_LIBS = @LIBSELINUX_LIBS@ | |||
| 275 | LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ | 275 | LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ |
| 276 | LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ | 276 | LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ |
| 277 | 277 | ||
| 278 | LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ | ||
| 279 | |||
| 278 | INTERVALS_H = dispextern.h intervals.h composite.h | 280 | INTERVALS_H = dispextern.h intervals.h composite.h |
| 279 | 281 | ||
| 280 | GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ | 282 | GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ |
| @@ -311,8 +313,10 @@ ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I$(srcdir) \ | |||
| 311 | $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \ | 313 | $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \ |
| 312 | $(C_SWITCH_X_SYSTEM) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ | 314 | $(C_SWITCH_X_SYSTEM) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ |
| 313 | $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \ | 315 | $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \ |
| 316 | |||
| 314 | $(WEBKIT_CFLAGS) $(CLUTTER_CFLAGS) \ | 317 | $(WEBKIT_CFLAGS) $(CLUTTER_CFLAGS) \ |
| 315 | $(GCONF_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ | 318 | $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ |
| 319 | |||
| 316 | $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \ | 320 | $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \ |
| 317 | $(LIBGNUTLS_CFLAGS) \ | 321 | $(LIBGNUTLS_CFLAGS) \ |
| 318 | $(C_WARNINGS_SWITCH) $(CFLAGS) | 322 | $(C_WARNINGS_SWITCH) $(CFLAGS) |
| @@ -391,9 +395,9 @@ LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \ | |||
| 391 | $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \ | 395 | $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \ |
| 392 | $(WEBKIT_LIBS) $(CLUTTER_LIBS) \ | 396 | $(WEBKIT_LIBS) $(CLUTTER_LIBS) \ |
| 393 | $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ | 397 | $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ |
| 394 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(GCONF_LIBS) $(LIBSELINUX_LIBS) \ | 398 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ |
| 395 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ | 399 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ |
| 396 | $(LIBGNUTLS_LIBS) \ | 400 | $(LIBGNUTLS_LIBS) $(LIB_PTHREAD_SIGMASK) \ |
| 397 | $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) | 401 | $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) |
| 398 | 402 | ||
| 399 | all: emacs$(EXEEXT) $(OTHER_FILES) | 403 | all: emacs$(EXEEXT) $(OTHER_FILES) |
diff --git a/src/alloc.c b/src/alloc.c index 43befd722bb..44f935c243d 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -1258,7 +1258,7 @@ emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2) | |||
| 1258 | calls malloc because it is the first call, and we have an endless loop. */ | 1258 | calls malloc because it is the first call, and we have an endless loop. */ |
| 1259 | 1259 | ||
| 1260 | void | 1260 | void |
| 1261 | reset_malloc_hooks () | 1261 | reset_malloc_hooks (void) |
| 1262 | { | 1262 | { |
| 1263 | __free_hook = old_free_hook; | 1263 | __free_hook = old_free_hook; |
| 1264 | __malloc_hook = old_malloc_hook; | 1264 | __malloc_hook = old_malloc_hook; |
| @@ -5619,7 +5619,8 @@ mark_buffer (Lisp_Object buf) | |||
| 5619 | /* buffer-local Lisp variables start at `undo_list', | 5619 | /* buffer-local Lisp variables start at `undo_list', |
| 5620 | tho only the ones from `name' on are GC'd normally. */ | 5620 | tho only the ones from `name' on are GC'd normally. */ |
| 5621 | for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name); | 5621 | for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name); |
| 5622 | (char *)ptr < (char *)buffer + sizeof (struct buffer); | 5622 | ptr <= &PER_BUFFER_VALUE (buffer, |
| 5623 | PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER)); | ||
| 5623 | ptr++) | 5624 | ptr++) |
| 5624 | mark_object (*ptr); | 5625 | mark_object (*ptr); |
| 5625 | 5626 | ||
| @@ -5732,7 +5733,7 @@ gc_sweep (void) | |||
| 5732 | int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; | 5733 | int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; |
| 5733 | 5734 | ||
| 5734 | /* Scan the mark bits an int at a time. */ | 5735 | /* Scan the mark bits an int at a time. */ |
| 5735 | for (i = 0; i <= ilim; i++) | 5736 | for (i = 0; i < ilim; i++) |
| 5736 | { | 5737 | { |
| 5737 | if (cblk->gcmarkbits[i] == -1) | 5738 | if (cblk->gcmarkbits[i] == -1) |
| 5738 | { | 5739 | { |
diff --git a/src/bidi.c b/src/bidi.c index 469afdb3819..c83ee549923 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Low-level bidirectional buffer-scanning functions for GNU Emacs. | 1 | /* Low-level bidirectional buffer/string-scanning functions for GNU Emacs. |
| 2 | Copyright (C) 2000-2001, 2004-2005, 2009-2011 | 2 | Copyright (C) 2000-2001, 2004-2005, 2009-2011 |
| 3 | Free Software Foundation, Inc. | 3 | Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -20,7 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 20 | /* Written by Eli Zaretskii <eliz@gnu.org>. | 20 | /* Written by Eli Zaretskii <eliz@gnu.org>. |
| 21 | 21 | ||
| 22 | A sequential implementation of the Unicode Bidirectional algorithm, | 22 | A sequential implementation of the Unicode Bidirectional algorithm, |
| 23 | as per UAX#9, a part of the Unicode Standard. | 23 | (UBA) as per UAX#9, a part of the Unicode Standard. |
| 24 | 24 | ||
| 25 | Unlike the reference and most other implementations, this one is | 25 | Unlike the reference and most other implementations, this one is |
| 26 | designed to be called once for every character in the buffer or | 26 | designed to be called once for every character in the buffer or |
| @@ -35,11 +35,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 35 | details about its algorithm that finds the next visual-order | 35 | details about its algorithm that finds the next visual-order |
| 36 | character by resolving their levels on the fly. | 36 | character by resolving their levels on the fly. |
| 37 | 37 | ||
| 38 | The two other entry points are bidi_paragraph_init and | 38 | Two other entry points are bidi_paragraph_init and |
| 39 | bidi_mirror_char. The first determines the base direction of a | 39 | bidi_mirror_char. The first determines the base direction of a |
| 40 | paragraph, while the second returns the mirrored version of its | 40 | paragraph, while the second returns the mirrored version of its |
| 41 | argument character. | 41 | argument character. |
| 42 | 42 | ||
| 43 | A few auxiliary entry points are used to initialize the bidi | ||
| 44 | iterator for iterating an object (buffer or string), push and pop | ||
| 45 | the bidi iterator state, and save and restore the state of the bidi | ||
| 46 | cache. | ||
| 47 | |||
| 43 | If you want to understand the code, you will have to read it | 48 | If you want to understand the code, you will have to read it |
| 44 | together with the relevant portions of UAX#9. The comments include | 49 | together with the relevant portions of UAX#9. The comments include |
| 45 | references to UAX#9 rules, for that very reason. | 50 | references to UAX#9 rules, for that very reason. |
| @@ -66,16 +71,6 @@ static Lisp_Object bidi_type_table, bidi_mirror_table; | |||
| 66 | #define RLM_CHAR 0x200F | 71 | #define RLM_CHAR 0x200F |
| 67 | #define BIDI_EOB -1 | 72 | #define BIDI_EOB -1 |
| 68 | 73 | ||
| 69 | /* Local data structures. (Look in dispextern.h for the rest.) */ | ||
| 70 | |||
| 71 | /* What we need to know about the current paragraph. */ | ||
| 72 | struct bidi_paragraph_info { | ||
| 73 | EMACS_INT start_bytepos; /* byte position where it begins */ | ||
| 74 | EMACS_INT end_bytepos; /* byte position where it ends */ | ||
| 75 | int embedding_level; /* its basic embedding level */ | ||
| 76 | bidi_dir_t base_dir; /* its base direction */ | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* Data type for describing the bidirectional character categories. */ | 74 | /* Data type for describing the bidirectional character categories. */ |
| 80 | typedef enum { | 75 | typedef enum { |
| 81 | UNKNOWN_BC, | 76 | UNKNOWN_BC, |
| @@ -90,43 +85,10 @@ int bidi_ignore_explicit_marks_for_paragraph_level = 1; | |||
| 90 | static Lisp_Object paragraph_start_re, paragraph_separate_re; | 85 | static Lisp_Object paragraph_start_re, paragraph_separate_re; |
| 91 | static Lisp_Object Qparagraph_start, Qparagraph_separate; | 86 | static Lisp_Object Qparagraph_start, Qparagraph_separate; |
| 92 | 87 | ||
| 93 | static void | 88 | |
| 94 | bidi_initialize (void) | 89 | /*********************************************************************** |
| 95 | { | 90 | Utilities |
| 96 | 91 | ***********************************************************************/ | |
| 97 | #include "biditype.h" | ||
| 98 | #include "bidimirror.h" | ||
| 99 | |||
| 100 | int i; | ||
| 101 | |||
| 102 | bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L)); | ||
| 103 | staticpro (&bidi_type_table); | ||
| 104 | |||
| 105 | for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++) | ||
| 106 | char_table_set_range (bidi_type_table, bidi_type[i].from, bidi_type[i].to, | ||
| 107 | make_number (bidi_type[i].type)); | ||
| 108 | |||
| 109 | bidi_mirror_table = Fmake_char_table (Qnil, Qnil); | ||
| 110 | staticpro (&bidi_mirror_table); | ||
| 111 | |||
| 112 | for (i = 0; i < sizeof bidi_mirror / sizeof bidi_mirror[0]; i++) | ||
| 113 | char_table_set (bidi_mirror_table, bidi_mirror[i].from, | ||
| 114 | make_number (bidi_mirror[i].to)); | ||
| 115 | |||
| 116 | Qparagraph_start = intern ("paragraph-start"); | ||
| 117 | staticpro (&Qparagraph_start); | ||
| 118 | paragraph_start_re = Fsymbol_value (Qparagraph_start); | ||
| 119 | if (!STRINGP (paragraph_start_re)) | ||
| 120 | paragraph_start_re = build_string ("\f\\|[ \t]*$"); | ||
| 121 | staticpro (¶graph_start_re); | ||
| 122 | Qparagraph_separate = intern ("paragraph-separate"); | ||
| 123 | staticpro (&Qparagraph_separate); | ||
| 124 | paragraph_separate_re = Fsymbol_value (Qparagraph_separate); | ||
| 125 | if (!STRINGP (paragraph_separate_re)) | ||
| 126 | paragraph_separate_re = build_string ("[ \t\f]*$"); | ||
| 127 | staticpro (¶graph_separate_re); | ||
| 128 | bidi_initialized = 1; | ||
| 129 | } | ||
| 130 | 92 | ||
| 131 | /* Return the bidi type of a character CH, subject to the current | 93 | /* Return the bidi type of a character CH, subject to the current |
| 132 | directional OVERRIDE. */ | 94 | directional OVERRIDE. */ |
| @@ -243,6 +205,77 @@ bidi_mirror_char (int c) | |||
| 243 | return c; | 205 | return c; |
| 244 | } | 206 | } |
| 245 | 207 | ||
| 208 | /* Determine the start-of-run (sor) directional type given the two | ||
| 209 | embedding levels on either side of the run boundary. Also, update | ||
| 210 | the saved info about previously seen characters, since that info is | ||
| 211 | generally valid for a single level run. */ | ||
| 212 | static inline void | ||
| 213 | bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) | ||
| 214 | { | ||
| 215 | int higher_level = level_before > level_after ? level_before : level_after; | ||
| 216 | |||
| 217 | /* The prev_was_pdf gork is required for when we have several PDFs | ||
| 218 | in a row. In that case, we want to compute the sor type for the | ||
| 219 | next level run only once: when we see the first PDF. That's | ||
| 220 | because the sor type depends only on the higher of the two levels | ||
| 221 | that we find on the two sides of the level boundary (see UAX#9, | ||
| 222 | clause X10), and so we don't need to know the final embedding | ||
| 223 | level to which we descend after processing all the PDFs. */ | ||
| 224 | if (!bidi_it->prev_was_pdf || level_before < level_after) | ||
| 225 | /* FIXME: should the default sor direction be user selectable? */ | ||
| 226 | bidi_it->sor = (higher_level & 1) != 0 ? R2L : L2R; | ||
| 227 | if (level_before > level_after) | ||
| 228 | bidi_it->prev_was_pdf = 1; | ||
| 229 | |||
| 230 | bidi_it->prev.type = UNKNOWN_BT; | ||
| 231 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = | ||
| 232 | bidi_it->last_strong.orig_type = UNKNOWN_BT; | ||
| 233 | bidi_it->prev_for_neutral.type = bidi_it->sor == R2L ? STRONG_R : STRONG_L; | ||
| 234 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; | ||
| 235 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; | ||
| 236 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 = | ||
| 237 | bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; | ||
| 238 | bidi_it->ignore_bn_limit = -1; /* meaning it's unknown */ | ||
| 239 | } | ||
| 240 | |||
| 241 | /* Push the current embedding level and override status; reset the | ||
| 242 | current level to LEVEL and the current override status to OVERRIDE. */ | ||
| 243 | static inline void | ||
| 244 | bidi_push_embedding_level (struct bidi_it *bidi_it, | ||
| 245 | int level, bidi_dir_t override) | ||
| 246 | { | ||
| 247 | bidi_it->stack_idx++; | ||
| 248 | xassert (bidi_it->stack_idx < BIDI_MAXLEVEL); | ||
| 249 | bidi_it->level_stack[bidi_it->stack_idx].level = level; | ||
| 250 | bidi_it->level_stack[bidi_it->stack_idx].override = override; | ||
| 251 | } | ||
| 252 | |||
| 253 | /* Pop the embedding level and directional override status from the | ||
| 254 | stack, and return the new level. */ | ||
| 255 | static inline int | ||
| 256 | bidi_pop_embedding_level (struct bidi_it *bidi_it) | ||
| 257 | { | ||
| 258 | /* UAX#9 says to ignore invalid PDFs. */ | ||
| 259 | if (bidi_it->stack_idx > 0) | ||
| 260 | bidi_it->stack_idx--; | ||
| 261 | return bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 262 | } | ||
| 263 | |||
| 264 | /* Record in SAVED_INFO the information about the current character. */ | ||
| 265 | static inline void | ||
| 266 | bidi_remember_char (struct bidi_saved_info *saved_info, | ||
| 267 | struct bidi_it *bidi_it) | ||
| 268 | { | ||
| 269 | saved_info->charpos = bidi_it->charpos; | ||
| 270 | saved_info->bytepos = bidi_it->bytepos; | ||
| 271 | saved_info->type = bidi_it->type; | ||
| 272 | bidi_check_type (bidi_it->type); | ||
| 273 | saved_info->type_after_w1 = bidi_it->type_after_w1; | ||
| 274 | bidi_check_type (bidi_it->type_after_w1); | ||
| 275 | saved_info->orig_type = bidi_it->orig_type; | ||
| 276 | bidi_check_type (bidi_it->orig_type); | ||
| 277 | } | ||
| 278 | |||
| 246 | /* Copy the bidi iterator from FROM to TO. To save cycles, this only | 279 | /* Copy the bidi iterator from FROM to TO. To save cycles, this only |
| 247 | copies the part of the level stack that is actually in use. */ | 280 | copies the part of the level stack that is actually in use. */ |
| 248 | static inline void | 281 | static inline void |
| @@ -259,22 +292,37 @@ bidi_copy_it (struct bidi_it *to, struct bidi_it *from) | |||
| 259 | to->level_stack[i] = from->level_stack[i]; | 292 | to->level_stack[i] = from->level_stack[i]; |
| 260 | } | 293 | } |
| 261 | 294 | ||
| 262 | /* Caching the bidi iterator states. */ | 295 | |
| 296 | /*********************************************************************** | ||
| 297 | Caching the bidi iterator states | ||
| 298 | ***********************************************************************/ | ||
| 263 | 299 | ||
| 264 | #define BIDI_CACHE_CHUNK 200 | 300 | #define BIDI_CACHE_CHUNK 200 |
| 265 | static struct bidi_it *bidi_cache; | 301 | static struct bidi_it *bidi_cache; |
| 266 | static size_t bidi_cache_size = 0; | 302 | static EMACS_INT bidi_cache_size = 0; |
| 267 | static size_t elsz = sizeof (struct bidi_it); | 303 | enum { elsz = sizeof (struct bidi_it) }; |
| 268 | static int bidi_cache_idx; /* next unused cache slot */ | 304 | static EMACS_INT bidi_cache_idx; /* next unused cache slot */ |
| 269 | static int bidi_cache_last_idx; /* slot of last cache hit */ | 305 | static EMACS_INT bidi_cache_last_idx; /* slot of last cache hit */ |
| 270 | 306 | static EMACS_INT bidi_cache_start = 0; /* start of cache for this | |
| 307 | "stack" level */ | ||
| 308 | |||
| 309 | /* Reset the cache state to the empty state. We only reset the part | ||
| 310 | of the cache relevant to iteration of the current object. Previous | ||
| 311 | objects, which are pushed on the display iterator's stack, are left | ||
| 312 | intact. This is called when the cached information is no more | ||
| 313 | useful for the current iteration, e.g. when we were reseated to a | ||
| 314 | new position on the same object. */ | ||
| 271 | static inline void | 315 | static inline void |
| 272 | bidi_cache_reset (void) | 316 | bidi_cache_reset (void) |
| 273 | { | 317 | { |
| 274 | bidi_cache_idx = 0; | 318 | bidi_cache_idx = bidi_cache_start; |
| 275 | bidi_cache_last_idx = -1; | 319 | bidi_cache_last_idx = -1; |
| 276 | } | 320 | } |
| 277 | 321 | ||
| 322 | /* Shrink the cache to its minimal size. Called when we init the bidi | ||
| 323 | iterator for reordering a buffer or a string that does not come | ||
| 324 | from display properties, because that means all the previously | ||
| 325 | cached info is of no further use. */ | ||
| 278 | static inline void | 326 | static inline void |
| 279 | bidi_cache_shrink (void) | 327 | bidi_cache_shrink (void) |
| 280 | { | 328 | { |
| @@ -288,11 +336,11 @@ bidi_cache_shrink (void) | |||
| 288 | } | 336 | } |
| 289 | 337 | ||
| 290 | static inline void | 338 | static inline void |
| 291 | bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) | 339 | bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it) |
| 292 | { | 340 | { |
| 293 | int current_scan_dir = bidi_it->scan_dir; | 341 | int current_scan_dir = bidi_it->scan_dir; |
| 294 | 342 | ||
| 295 | if (idx < 0 || idx >= bidi_cache_idx) | 343 | if (idx < bidi_cache_start || idx >= bidi_cache_idx) |
| 296 | abort (); | 344 | abort (); |
| 297 | 345 | ||
| 298 | bidi_copy_it (bidi_it, &bidi_cache[idx]); | 346 | bidi_copy_it (bidi_it, &bidi_cache[idx]); |
| @@ -304,13 +352,15 @@ bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) | |||
| 304 | level less or equal to LEVEL. if LEVEL is -1, disregard the | 352 | level less or equal to LEVEL. if LEVEL is -1, disregard the |
| 305 | resolved levels in cached states. DIR, if non-zero, means search | 353 | resolved levels in cached states. DIR, if non-zero, means search |
| 306 | in that direction from the last cache hit. */ | 354 | in that direction from the last cache hit. */ |
| 307 | static inline int | 355 | static inline EMACS_INT |
| 308 | bidi_cache_search (EMACS_INT charpos, int level, int dir) | 356 | bidi_cache_search (EMACS_INT charpos, int level, int dir) |
| 309 | { | 357 | { |
| 310 | int i, i_start; | 358 | EMACS_INT i, i_start; |
| 311 | 359 | ||
| 312 | if (bidi_cache_idx) | 360 | if (bidi_cache_idx > bidi_cache_start) |
| 313 | { | 361 | { |
| 362 | if (bidi_cache_last_idx == -1) | ||
| 363 | bidi_cache_last_idx = bidi_cache_idx - 1; | ||
| 314 | if (charpos < bidi_cache[bidi_cache_last_idx].charpos) | 364 | if (charpos < bidi_cache[bidi_cache_last_idx].charpos) |
| 315 | { | 365 | { |
| 316 | dir = -1; | 366 | dir = -1; |
| @@ -333,7 +383,7 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir) | |||
| 333 | if (dir < 0) | 383 | if (dir < 0) |
| 334 | { | 384 | { |
| 335 | /* Linear search for now; FIXME! */ | 385 | /* Linear search for now; FIXME! */ |
| 336 | for (i = i_start; i >= 0; i--) | 386 | for (i = i_start; i >= bidi_cache_start; i--) |
| 337 | if (bidi_cache[i].charpos <= charpos | 387 | if (bidi_cache[i].charpos <= charpos |
| 338 | && charpos < bidi_cache[i].charpos + bidi_cache[i].nchars | 388 | && charpos < bidi_cache[i].charpos + bidi_cache[i].nchars |
| 339 | && (level == -1 || bidi_cache[i].resolved_level <= level)) | 389 | && (level == -1 || bidi_cache[i].resolved_level <= level)) |
| @@ -355,8 +405,9 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir) | |||
| 355 | /* Find a cached state where the resolved level changes to a value | 405 | /* Find a cached state where the resolved level changes to a value |
| 356 | that is lower than LEVEL, and return its cache slot index. DIR is | 406 | that is lower than LEVEL, and return its cache slot index. DIR is |
| 357 | the direction to search, starting with the last used cache slot. | 407 | the direction to search, starting with the last used cache slot. |
| 358 | BEFORE, if non-zero, means return the index of the slot that is | 408 | If DIR is zero, we search backwards from the last occupied cache |
| 359 | ``before'' the level change in the search direction. That is, | 409 | slot. BEFORE, if non-zero, means return the index of the slot that |
| 410 | is ``before'' the level change in the search direction. That is, | ||
| 360 | given the cached levels like this: | 411 | given the cached levels like this: |
| 361 | 412 | ||
| 362 | 1122333442211 | 413 | 1122333442211 |
| @@ -366,14 +417,16 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir) | |||
| 366 | C, searching backwards (DIR = -1) for LEVEL = 2 will return the | 417 | C, searching backwards (DIR = -1) for LEVEL = 2 will return the |
| 367 | index of slot B or A, depending whether BEFORE is, respectively, | 418 | index of slot B or A, depending whether BEFORE is, respectively, |
| 368 | non-zero or zero. */ | 419 | non-zero or zero. */ |
| 369 | static int | 420 | static EMACS_INT |
| 370 | bidi_cache_find_level_change (int level, int dir, int before) | 421 | bidi_cache_find_level_change (int level, int dir, int before) |
| 371 | { | 422 | { |
| 372 | if (bidi_cache_idx) | 423 | if (bidi_cache_idx) |
| 373 | { | 424 | { |
| 374 | int i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1; | 425 | EMACS_INT i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1; |
| 375 | int incr = before ? 1 : 0; | 426 | int incr = before ? 1 : 0; |
| 376 | 427 | ||
| 428 | xassert (!dir || bidi_cache_last_idx >= 0); | ||
| 429 | |||
| 377 | if (!dir) | 430 | if (!dir) |
| 378 | dir = -1; | 431 | dir = -1; |
| 379 | else if (!incr) | 432 | else if (!incr) |
| @@ -381,7 +434,7 @@ bidi_cache_find_level_change (int level, int dir, int before) | |||
| 381 | 434 | ||
| 382 | if (dir < 0) | 435 | if (dir < 0) |
| 383 | { | 436 | { |
| 384 | while (i >= incr) | 437 | while (i >= bidi_cache_start + incr) |
| 385 | { | 438 | { |
| 386 | if (bidi_cache[i - incr].resolved_level >= 0 | 439 | if (bidi_cache[i - incr].resolved_level >= 0 |
| 387 | && bidi_cache[i - incr].resolved_level < level) | 440 | && bidi_cache[i - incr].resolved_level < level) |
| @@ -405,9 +458,22 @@ bidi_cache_find_level_change (int level, int dir, int before) | |||
| 405 | } | 458 | } |
| 406 | 459 | ||
| 407 | static inline void | 460 | static inline void |
| 461 | bidi_cache_ensure_space (EMACS_INT idx) | ||
| 462 | { | ||
| 463 | /* Enlarge the cache as needed. */ | ||
| 464 | if (idx >= bidi_cache_size) | ||
| 465 | { | ||
| 466 | while (idx >= bidi_cache_size) | ||
| 467 | bidi_cache_size += BIDI_CACHE_CHUNK; | ||
| 468 | bidi_cache = | ||
| 469 | (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz); | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | static inline void | ||
| 408 | bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | 474 | bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) |
| 409 | { | 475 | { |
| 410 | int idx; | 476 | EMACS_INT idx; |
| 411 | 477 | ||
| 412 | /* We should never cache on backward scans. */ | 478 | /* We should never cache on backward scans. */ |
| 413 | if (bidi_it->scan_dir == -1) | 479 | if (bidi_it->scan_dir == -1) |
| @@ -417,23 +483,17 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 417 | if (idx < 0) | 483 | if (idx < 0) |
| 418 | { | 484 | { |
| 419 | idx = bidi_cache_idx; | 485 | idx = bidi_cache_idx; |
| 420 | /* Enlarge the cache as needed. */ | 486 | bidi_cache_ensure_space (idx); |
| 421 | if (idx >= bidi_cache_size) | ||
| 422 | { | ||
| 423 | bidi_cache_size += BIDI_CACHE_CHUNK; | ||
| 424 | bidi_cache = | ||
| 425 | (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz); | ||
| 426 | } | ||
| 427 | /* Character positions should correspond to cache positions 1:1. | 487 | /* Character positions should correspond to cache positions 1:1. |
| 428 | If we are outside the range of cached positions, the cache is | 488 | If we are outside the range of cached positions, the cache is |
| 429 | useless and must be reset. */ | 489 | useless and must be reset. */ |
| 430 | if (idx > 0 && | 490 | if (idx > bidi_cache_start && |
| 431 | (bidi_it->charpos > (bidi_cache[idx - 1].charpos | 491 | (bidi_it->charpos > (bidi_cache[idx - 1].charpos |
| 432 | + bidi_cache[idx - 1].nchars) | 492 | + bidi_cache[idx - 1].nchars) |
| 433 | || bidi_it->charpos < bidi_cache[0].charpos)) | 493 | || bidi_it->charpos < bidi_cache[bidi_cache_start].charpos)) |
| 434 | { | 494 | { |
| 435 | bidi_cache_reset (); | 495 | bidi_cache_reset (); |
| 436 | idx = 0; | 496 | idx = bidi_cache_start; |
| 437 | } | 497 | } |
| 438 | if (bidi_it->nchars <= 0) | 498 | if (bidi_it->nchars <= 0) |
| 439 | abort (); | 499 | abort (); |
| @@ -468,9 +528,9 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 468 | static inline bidi_type_t | 528 | static inline bidi_type_t |
| 469 | bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) | 529 | bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) |
| 470 | { | 530 | { |
| 471 | int i = bidi_cache_search (charpos, level, bidi_it->scan_dir); | 531 | EMACS_INT i = bidi_cache_search (charpos, level, bidi_it->scan_dir); |
| 472 | 532 | ||
| 473 | if (i >= 0) | 533 | if (i >= bidi_cache_start) |
| 474 | { | 534 | { |
| 475 | bidi_dir_t current_scan_dir = bidi_it->scan_dir; | 535 | bidi_dir_t current_scan_dir = bidi_it->scan_dir; |
| 476 | 536 | ||
| @@ -488,69 +548,245 @@ bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) | |||
| 488 | static inline int | 548 | static inline int |
| 489 | bidi_peek_at_next_level (struct bidi_it *bidi_it) | 549 | bidi_peek_at_next_level (struct bidi_it *bidi_it) |
| 490 | { | 550 | { |
| 491 | if (bidi_cache_idx == 0 || bidi_cache_last_idx == -1) | 551 | if (bidi_cache_idx == bidi_cache_start || bidi_cache_last_idx == -1) |
| 492 | abort (); | 552 | abort (); |
| 493 | return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level; | 553 | return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level; |
| 494 | } | 554 | } |
| 495 | 555 | ||
| 496 | /* Check if buffer position CHARPOS/BYTEPOS is the end of a paragraph. | 556 | |
| 497 | Value is the non-negative length of the paragraph separator | 557 | /*********************************************************************** |
| 498 | following the buffer position, -1 if position is at the beginning | 558 | Pushing and popping the bidi iterator state |
| 499 | of a new paragraph, or -2 if position is neither at beginning nor | 559 | ***********************************************************************/ |
| 500 | at end of a paragraph. */ | 560 | /* 5-slot stack for saving the start of the previous level of the |
| 501 | static EMACS_INT | 561 | cache. xdisp.c maintains a 5-slot stack for its iterator state, |
| 502 | bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos) | 562 | and we need the same size of our stack. */ |
| 563 | static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE]; | ||
| 564 | static int bidi_cache_sp; | ||
| 565 | |||
| 566 | /* Push the bidi iterator state in preparation for reordering a | ||
| 567 | different object, e.g. display string found at certain buffer | ||
| 568 | position. Pushing the bidi iterator boils down to saving its | ||
| 569 | entire state on the cache and starting a new cache "stacked" on top | ||
| 570 | of the current cache. */ | ||
| 571 | void | ||
| 572 | bidi_push_it (struct bidi_it *bidi_it) | ||
| 503 | { | 573 | { |
| 504 | Lisp_Object sep_re; | 574 | /* Save the current iterator state in its entirety after the last |
| 505 | Lisp_Object start_re; | 575 | used cache slot. */ |
| 506 | EMACS_INT val; | 576 | bidi_cache_ensure_space (bidi_cache_idx); |
| 577 | memcpy (&bidi_cache[bidi_cache_idx++], bidi_it, sizeof (struct bidi_it)); | ||
| 507 | 578 | ||
| 508 | sep_re = paragraph_separate_re; | 579 | /* Push the current cache start onto the stack. */ |
| 509 | start_re = paragraph_start_re; | 580 | xassert (bidi_cache_sp < IT_STACK_SIZE); |
| 581 | bidi_cache_start_stack[bidi_cache_sp++] = bidi_cache_start; | ||
| 510 | 582 | ||
| 511 | val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil); | 583 | /* Start a new level of cache, and make it empty. */ |
| 512 | if (val < 0) | 584 | bidi_cache_start = bidi_cache_idx; |
| 585 | bidi_cache_last_idx = -1; | ||
| 586 | } | ||
| 587 | |||
| 588 | /* Restore the iterator state saved by bidi_push_it and return the | ||
| 589 | cache to the corresponding state. */ | ||
| 590 | void | ||
| 591 | bidi_pop_it (struct bidi_it *bidi_it) | ||
| 592 | { | ||
| 593 | if (bidi_cache_start <= 0) | ||
| 594 | abort (); | ||
| 595 | |||
| 596 | /* Reset the next free cache slot index to what it was before the | ||
| 597 | call to bidi_push_it. */ | ||
| 598 | bidi_cache_idx = bidi_cache_start - 1; | ||
| 599 | |||
| 600 | /* Restore the bidi iterator state saved in the cache. */ | ||
| 601 | memcpy (bidi_it, &bidi_cache[bidi_cache_idx], sizeof (struct bidi_it)); | ||
| 602 | |||
| 603 | /* Pop the previous cache start from the stack. */ | ||
| 604 | if (bidi_cache_sp <= 0) | ||
| 605 | abort (); | ||
| 606 | bidi_cache_start = bidi_cache_start_stack[--bidi_cache_sp]; | ||
| 607 | |||
| 608 | /* Invalidate the last-used cache slot data. */ | ||
| 609 | bidi_cache_last_idx = -1; | ||
| 610 | } | ||
| 611 | |||
| 612 | /* Stash away a copy of the cache and its control variables. */ | ||
| 613 | void * | ||
| 614 | bidi_shelve_cache (void) | ||
| 615 | { | ||
| 616 | unsigned char *databuf; | ||
| 617 | |||
| 618 | if (bidi_cache_idx == 0) | ||
| 619 | return NULL; | ||
| 620 | |||
| 621 | databuf = xmalloc (sizeof (bidi_cache_idx) | ||
| 622 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 623 | + sizeof (bidi_cache_start_stack) | ||
| 624 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) | ||
| 625 | + sizeof (bidi_cache_last_idx)); | ||
| 626 | memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); | ||
| 627 | memcpy (databuf + sizeof (bidi_cache_idx), | ||
| 628 | bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); | ||
| 629 | memcpy (databuf + sizeof (bidi_cache_idx) | ||
| 630 | + bidi_cache_idx * sizeof (struct bidi_it), | ||
| 631 | bidi_cache_start_stack, sizeof (bidi_cache_start_stack)); | ||
| 632 | memcpy (databuf + sizeof (bidi_cache_idx) | ||
| 633 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 634 | + sizeof (bidi_cache_start_stack), | ||
| 635 | &bidi_cache_sp, sizeof (bidi_cache_sp)); | ||
| 636 | memcpy (databuf + sizeof (bidi_cache_idx) | ||
| 637 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 638 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), | ||
| 639 | &bidi_cache_start, sizeof (bidi_cache_start)); | ||
| 640 | memcpy (databuf + sizeof (bidi_cache_idx) | ||
| 641 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 642 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | ||
| 643 | + sizeof (bidi_cache_start), | ||
| 644 | &bidi_cache_last_idx, sizeof (bidi_cache_last_idx)); | ||
| 645 | |||
| 646 | return databuf; | ||
| 647 | } | ||
| 648 | |||
| 649 | /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ | ||
| 650 | void | ||
| 651 | bidi_unshelve_cache (void *databuf) | ||
| 652 | { | ||
| 653 | unsigned char *p = databuf; | ||
| 654 | |||
| 655 | if (!p) | ||
| 513 | { | 656 | { |
| 514 | if (fast_looking_at (start_re, charpos, bytepos, ZV, ZV_BYTE, Qnil) >= 0) | 657 | /* A NULL pointer means an empty cache. */ |
| 515 | val = -1; | 658 | bidi_cache_start = 0; |
| 516 | else | 659 | bidi_cache_sp = 0; |
| 517 | val = -2; | 660 | bidi_cache_reset (); |
| 518 | } | 661 | } |
| 662 | else | ||
| 663 | { | ||
| 664 | memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); | ||
| 665 | bidi_cache_ensure_space (bidi_cache_idx); | ||
| 666 | memcpy (bidi_cache, p + sizeof (bidi_cache_idx), | ||
| 667 | bidi_cache_idx * sizeof (struct bidi_it)); | ||
| 668 | memcpy (bidi_cache_start_stack, | ||
| 669 | p + sizeof (bidi_cache_idx) | ||
| 670 | + bidi_cache_idx * sizeof (struct bidi_it), | ||
| 671 | sizeof (bidi_cache_start_stack)); | ||
| 672 | memcpy (&bidi_cache_sp, | ||
| 673 | p + sizeof (bidi_cache_idx) | ||
| 674 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 675 | + sizeof (bidi_cache_start_stack), | ||
| 676 | sizeof (bidi_cache_sp)); | ||
| 677 | memcpy (&bidi_cache_start, | ||
| 678 | p + sizeof (bidi_cache_idx) | ||
| 679 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 680 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), | ||
| 681 | sizeof (bidi_cache_start)); | ||
| 682 | memcpy (&bidi_cache_last_idx, | ||
| 683 | p + sizeof (bidi_cache_idx) | ||
| 684 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 685 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | ||
| 686 | + sizeof (bidi_cache_start), | ||
| 687 | sizeof (bidi_cache_last_idx)); | ||
| 688 | |||
| 689 | xfree (p); | ||
| 690 | } | ||
| 691 | } | ||
| 519 | 692 | ||
| 520 | return val; | 693 | |
| 694 | /*********************************************************************** | ||
| 695 | Initialization | ||
| 696 | ***********************************************************************/ | ||
| 697 | static void | ||
| 698 | bidi_initialize (void) | ||
| 699 | { | ||
| 700 | |||
| 701 | #include "biditype.h" | ||
| 702 | #include "bidimirror.h" | ||
| 703 | |||
| 704 | int i; | ||
| 705 | |||
| 706 | bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L)); | ||
| 707 | staticpro (&bidi_type_table); | ||
| 708 | |||
| 709 | for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++) | ||
| 710 | char_table_set_range (bidi_type_table, bidi_type[i].from, bidi_type[i].to, | ||
| 711 | make_number (bidi_type[i].type)); | ||
| 712 | |||
| 713 | bidi_mirror_table = Fmake_char_table (Qnil, Qnil); | ||
| 714 | staticpro (&bidi_mirror_table); | ||
| 715 | |||
| 716 | for (i = 0; i < sizeof bidi_mirror / sizeof bidi_mirror[0]; i++) | ||
| 717 | char_table_set (bidi_mirror_table, bidi_mirror[i].from, | ||
| 718 | make_number (bidi_mirror[i].to)); | ||
| 719 | |||
| 720 | Qparagraph_start = intern ("paragraph-start"); | ||
| 721 | staticpro (&Qparagraph_start); | ||
| 722 | paragraph_start_re = Fsymbol_value (Qparagraph_start); | ||
| 723 | if (!STRINGP (paragraph_start_re)) | ||
| 724 | paragraph_start_re = build_string ("\f\\|[ \t]*$"); | ||
| 725 | staticpro (¶graph_start_re); | ||
| 726 | Qparagraph_separate = intern ("paragraph-separate"); | ||
| 727 | staticpro (&Qparagraph_separate); | ||
| 728 | paragraph_separate_re = Fsymbol_value (Qparagraph_separate); | ||
| 729 | if (!STRINGP (paragraph_separate_re)) | ||
| 730 | paragraph_separate_re = build_string ("[ \t\f]*$"); | ||
| 731 | staticpro (¶graph_separate_re); | ||
| 732 | |||
| 733 | bidi_cache_sp = 0; | ||
| 734 | |||
| 735 | bidi_initialized = 1; | ||
| 521 | } | 736 | } |
| 522 | 737 | ||
| 523 | /* Determine the start-of-run (sor) directional type given the two | 738 | /* Do whatever UAX#9 clause X8 says should be done at paragraph's |
| 524 | embedding levels on either side of the run boundary. Also, update | 739 | end. */ |
| 525 | the saved info about previously seen characters, since that info is | ||
| 526 | generally valid for a single level run. */ | ||
| 527 | static inline void | 740 | static inline void |
| 528 | bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) | 741 | bidi_set_paragraph_end (struct bidi_it *bidi_it) |
| 529 | { | 742 | { |
| 530 | int higher_level = level_before > level_after ? level_before : level_after; | 743 | bidi_it->invalid_levels = 0; |
| 531 | 744 | bidi_it->invalid_rl_levels = -1; | |
| 532 | /* The prev_was_pdf gork is required for when we have several PDFs | 745 | bidi_it->stack_idx = 0; |
| 533 | in a row. In that case, we want to compute the sor type for the | 746 | bidi_it->resolved_level = bidi_it->level_stack[0].level; |
| 534 | next level run only once: when we see the first PDF. That's | 747 | } |
| 535 | because the sor type depends only on the higher of the two levels | ||
| 536 | that we find on the two sides of the level boundary (see UAX#9, | ||
| 537 | clause X10), and so we don't need to know the final embedding | ||
| 538 | level to which we descend after processing all the PDFs. */ | ||
| 539 | if (!bidi_it->prev_was_pdf || level_before < level_after) | ||
| 540 | /* FIXME: should the default sor direction be user selectable? */ | ||
| 541 | bidi_it->sor = (higher_level & 1) != 0 ? R2L : L2R; | ||
| 542 | if (level_before > level_after) | ||
| 543 | bidi_it->prev_was_pdf = 1; | ||
| 544 | 748 | ||
| 545 | bidi_it->prev.type = UNKNOWN_BT; | 749 | /* Initialize the bidi iterator from buffer/string position CHARPOS. */ |
| 750 | void | ||
| 751 | bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p, | ||
| 752 | struct bidi_it *bidi_it) | ||
| 753 | { | ||
| 754 | if (! bidi_initialized) | ||
| 755 | bidi_initialize (); | ||
| 756 | if (charpos >= 0) | ||
| 757 | bidi_it->charpos = charpos; | ||
| 758 | if (bytepos >= 0) | ||
| 759 | bidi_it->bytepos = bytepos; | ||
| 760 | bidi_it->frame_window_p = frame_window_p; | ||
| 761 | bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */ | ||
| 762 | bidi_it->first_elt = 1; | ||
| 763 | bidi_set_paragraph_end (bidi_it); | ||
| 764 | bidi_it->new_paragraph = 1; | ||
| 765 | bidi_it->separator_limit = -1; | ||
| 766 | bidi_it->type = NEUTRAL_B; | ||
| 767 | bidi_it->type_after_w1 = NEUTRAL_B; | ||
| 768 | bidi_it->orig_type = NEUTRAL_B; | ||
| 769 | bidi_it->prev_was_pdf = 0; | ||
| 770 | bidi_it->prev.type = bidi_it->prev.type_after_w1 = | ||
| 771 | bidi_it->prev.orig_type = UNKNOWN_BT; | ||
| 546 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = | 772 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = |
| 547 | bidi_it->last_strong.orig_type = UNKNOWN_BT; | 773 | bidi_it->last_strong.orig_type = UNKNOWN_BT; |
| 548 | bidi_it->prev_for_neutral.type = bidi_it->sor == R2L ? STRONG_R : STRONG_L; | 774 | bidi_it->next_for_neutral.charpos = -1; |
| 549 | bidi_it->prev_for_neutral.charpos = bidi_it->charpos; | 775 | bidi_it->next_for_neutral.type = |
| 550 | bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; | 776 | bidi_it->next_for_neutral.type_after_w1 = |
| 551 | bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 = | ||
| 552 | bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; | 777 | bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; |
| 553 | bidi_it->ignore_bn_limit = 0; /* meaning it's unknown */ | 778 | bidi_it->prev_for_neutral.charpos = -1; |
| 779 | bidi_it->prev_for_neutral.type = | ||
| 780 | bidi_it->prev_for_neutral.type_after_w1 = | ||
| 781 | bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; | ||
| 782 | bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ | ||
| 783 | bidi_it->disp_pos = -1; /* invalid/unknown */ | ||
| 784 | /* We can only shrink the cache if we are at the bottom level of its | ||
| 785 | "stack". */ | ||
| 786 | if (bidi_cache_start == 0) | ||
| 787 | bidi_cache_shrink (); | ||
| 788 | else | ||
| 789 | bidi_cache_reset (); | ||
| 554 | } | 790 | } |
| 555 | 791 | ||
| 556 | /* Perform initializations for reordering a new line of bidi text. */ | 792 | /* Perform initializations for reordering a new line of bidi text. */ |
| @@ -571,6 +807,57 @@ bidi_line_init (struct bidi_it *bidi_it) | |||
| 571 | bidi_cache_reset (); | 807 | bidi_cache_reset (); |
| 572 | } | 808 | } |
| 573 | 809 | ||
| 810 | |||
| 811 | /*********************************************************************** | ||
| 812 | Fetching characters | ||
| 813 | ***********************************************************************/ | ||
| 814 | |||
| 815 | /* Count bytes in string S between BEG/BEGBYTE and END. BEG and END | ||
| 816 | are zero-based character positions in S, BEGBYTE is byte position | ||
| 817 | corresponding to BEG. UNIBYTE, if non-zero, means S is a unibyte | ||
| 818 | string. */ | ||
| 819 | static inline EMACS_INT | ||
| 820 | bidi_count_bytes (const unsigned char *s, const EMACS_INT beg, | ||
| 821 | const EMACS_INT begbyte, const EMACS_INT end, int unibyte) | ||
| 822 | { | ||
| 823 | EMACS_INT pos = beg; | ||
| 824 | const unsigned char *p = s + begbyte, *start = p; | ||
| 825 | |||
| 826 | if (unibyte) | ||
| 827 | p = s + end; | ||
| 828 | else | ||
| 829 | { | ||
| 830 | if (!CHAR_HEAD_P (*p)) | ||
| 831 | abort (); | ||
| 832 | |||
| 833 | while (pos < end) | ||
| 834 | { | ||
| 835 | p += BYTES_BY_CHAR_HEAD (*p); | ||
| 836 | pos++; | ||
| 837 | } | ||
| 838 | } | ||
| 839 | |||
| 840 | return p - start; | ||
| 841 | } | ||
| 842 | |||
| 843 | /* Fetch and returns the character at byte position BYTEPOS. If S is | ||
| 844 | non-NULL, fetch the character from string S; otherwise fetch the | ||
| 845 | character from the current buffer. UNIBYTE non-zero means S is a | ||
| 846 | unibyte string. */ | ||
| 847 | static inline int | ||
| 848 | bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte) | ||
| 849 | { | ||
| 850 | if (s) | ||
| 851 | { | ||
| 852 | if (unibyte) | ||
| 853 | return s[bytepos]; | ||
| 854 | else | ||
| 855 | return STRING_CHAR (s + bytepos); | ||
| 856 | } | ||
| 857 | else | ||
| 858 | return FETCH_MULTIBYTE_CHAR (bytepos); | ||
| 859 | } | ||
| 860 | |||
| 574 | /* Fetch and return the character at BYTEPOS/CHARPOS. If that | 861 | /* Fetch and return the character at BYTEPOS/CHARPOS. If that |
| 575 | character is covered by a display string, treat the entire run of | 862 | character is covered by a display string, treat the entire run of |
| 576 | covered characters as a single character u+FFFC, and return their | 863 | covered characters as a single character u+FFFC, and return their |
| @@ -578,26 +865,34 @@ bidi_line_init (struct bidi_it *bidi_it) | |||
| 578 | character position of the next display string, or -1 if not yet | 865 | character position of the next display string, or -1 if not yet |
| 579 | computed. When the next character is at or beyond that position, | 866 | computed. When the next character is at or beyond that position, |
| 580 | the function updates DISP_POS with the position of the next display | 867 | the function updates DISP_POS with the position of the next display |
| 581 | string. */ | 868 | string. STRING->s is the C string to iterate, or NULL if iterating |
| 869 | over a buffer or a Lisp string; in the latter case, STRING->lstring | ||
| 870 | is the Lisp string. */ | ||
| 582 | static inline int | 871 | static inline int |
| 583 | bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, | 872 | bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, |
| 873 | struct bidi_string_data *string, | ||
| 584 | int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) | 874 | int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) |
| 585 | { | 875 | { |
| 586 | int ch; | 876 | int ch; |
| 877 | EMACS_INT endpos = | ||
| 878 | (string->s || STRINGP (string->lstring)) ? string->schars : ZV; | ||
| 879 | struct text_pos pos; | ||
| 587 | 880 | ||
| 588 | /* FIXME: Support strings in addition to buffers. */ | ||
| 589 | /* If we got past the last known position of display string, compute | 881 | /* If we got past the last known position of display string, compute |
| 590 | the position of the next one. That position could be at BYTEPOS. */ | 882 | the position of the next one. That position could be at CHARPOS. */ |
| 591 | if (charpos < ZV && charpos > *disp_pos) | 883 | if (charpos < endpos && charpos > *disp_pos) |
| 592 | *disp_pos = compute_display_string_pos (charpos, frame_window_p); | 884 | { |
| 885 | SET_TEXT_POS (pos, charpos, bytepos); | ||
| 886 | *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); | ||
| 887 | } | ||
| 593 | 888 | ||
| 594 | /* Fetch the character at BYTEPOS. */ | 889 | /* Fetch the character at BYTEPOS. */ |
| 595 | if (bytepos >= ZV_BYTE) | 890 | if (charpos >= endpos) |
| 596 | { | 891 | { |
| 597 | ch = BIDI_EOB; | 892 | ch = BIDI_EOB; |
| 598 | *ch_len = 1; | 893 | *ch_len = 1; |
| 599 | *nchars = 1; | 894 | *nchars = 1; |
| 600 | *disp_pos = ZV; | 895 | *disp_pos = endpos; |
| 601 | } | 896 | } |
| 602 | else if (charpos >= *disp_pos) | 897 | else if (charpos >= *disp_pos) |
| 603 | { | 898 | { |
| @@ -608,28 +903,105 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, | |||
| 608 | if (charpos > *disp_pos) | 903 | if (charpos > *disp_pos) |
| 609 | abort (); | 904 | abort (); |
| 610 | /* Return the Unicode Object Replacement Character to represent | 905 | /* Return the Unicode Object Replacement Character to represent |
| 611 | the entire run of characters covered by the display | 906 | the entire run of characters covered by the display string. */ |
| 612 | string. */ | ||
| 613 | ch = 0xFFFC; | 907 | ch = 0xFFFC; |
| 614 | disp_end_pos = compute_display_string_end (*disp_pos); | 908 | disp_end_pos = compute_display_string_end (*disp_pos, string); |
| 615 | *nchars = disp_end_pos - *disp_pos; | 909 | *nchars = disp_end_pos - *disp_pos; |
| 616 | *ch_len = CHAR_TO_BYTE (disp_end_pos) - bytepos; | 910 | if (*nchars <= 0) |
| 911 | abort (); | ||
| 912 | if (string->s) | ||
| 913 | *ch_len = bidi_count_bytes (string->s, *disp_pos, bytepos, | ||
| 914 | disp_end_pos, string->unibyte); | ||
| 915 | else if (STRINGP (string->lstring)) | ||
| 916 | *ch_len = bidi_count_bytes (SDATA (string->lstring), *disp_pos, | ||
| 917 | bytepos, disp_end_pos, string->unibyte); | ||
| 918 | else | ||
| 919 | *ch_len = CHAR_TO_BYTE (disp_end_pos) - bytepos; | ||
| 617 | } | 920 | } |
| 618 | else | 921 | else |
| 619 | { | 922 | { |
| 620 | ch = FETCH_MULTIBYTE_CHAR (bytepos); | 923 | if (string->s) |
| 924 | { | ||
| 925 | int len; | ||
| 926 | |||
| 927 | if (!string->unibyte) | ||
| 928 | { | ||
| 929 | ch = STRING_CHAR_AND_LENGTH (string->s + bytepos, len); | ||
| 930 | *ch_len = len; | ||
| 931 | } | ||
| 932 | else | ||
| 933 | { | ||
| 934 | ch = UNIBYTE_TO_CHAR (string->s[bytepos]); | ||
| 935 | *ch_len = 1; | ||
| 936 | } | ||
| 937 | } | ||
| 938 | else if (STRINGP (string->lstring)) | ||
| 939 | { | ||
| 940 | int len; | ||
| 941 | |||
| 942 | if (!string->unibyte) | ||
| 943 | { | ||
| 944 | ch = STRING_CHAR_AND_LENGTH (SDATA (string->lstring) + bytepos, | ||
| 945 | len); | ||
| 946 | *ch_len = len; | ||
| 947 | } | ||
| 948 | else | ||
| 949 | { | ||
| 950 | ch = UNIBYTE_TO_CHAR (SREF (string->lstring, bytepos)); | ||
| 951 | *ch_len = 1; | ||
| 952 | } | ||
| 953 | } | ||
| 954 | else | ||
| 955 | { | ||
| 956 | ch = FETCH_MULTIBYTE_CHAR (bytepos); | ||
| 957 | *ch_len = CHAR_BYTES (ch); | ||
| 958 | } | ||
| 621 | *nchars = 1; | 959 | *nchars = 1; |
| 622 | *ch_len = CHAR_BYTES (ch); | ||
| 623 | } | 960 | } |
| 624 | 961 | ||
| 625 | /* If we just entered a run of characters covered by a display | 962 | /* If we just entered a run of characters covered by a display |
| 626 | string, compute the position of the next display string. */ | 963 | string, compute the position of the next display string. */ |
| 627 | if (charpos + *nchars <= ZV && charpos + *nchars > *disp_pos) | 964 | if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos) |
| 628 | *disp_pos = compute_display_string_pos (charpos + *nchars, frame_window_p); | 965 | { |
| 966 | SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len); | ||
| 967 | *disp_pos = compute_display_string_pos (&pos, string, frame_window_p); | ||
| 968 | } | ||
| 629 | 969 | ||
| 630 | return ch; | 970 | return ch; |
| 631 | } | 971 | } |
| 632 | 972 | ||
| 973 | |||
| 974 | /*********************************************************************** | ||
| 975 | Determining paragraph direction | ||
| 976 | ***********************************************************************/ | ||
| 977 | |||
| 978 | /* Check if buffer position CHARPOS/BYTEPOS is the end of a paragraph. | ||
| 979 | Value is the non-negative length of the paragraph separator | ||
| 980 | following the buffer position, -1 if position is at the beginning | ||
| 981 | of a new paragraph, or -2 if position is neither at beginning nor | ||
| 982 | at end of a paragraph. */ | ||
| 983 | static EMACS_INT | ||
| 984 | bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos) | ||
| 985 | { | ||
| 986 | Lisp_Object sep_re; | ||
| 987 | Lisp_Object start_re; | ||
| 988 | EMACS_INT val; | ||
| 989 | |||
| 990 | sep_re = paragraph_separate_re; | ||
| 991 | start_re = paragraph_start_re; | ||
| 992 | |||
| 993 | val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil); | ||
| 994 | if (val < 0) | ||
| 995 | { | ||
| 996 | if (fast_looking_at (start_re, charpos, bytepos, ZV, ZV_BYTE, Qnil) >= 0) | ||
| 997 | val = -1; | ||
| 998 | else | ||
| 999 | val = -2; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | return val; | ||
| 1003 | } | ||
| 1004 | |||
| 633 | /* Find the beginning of this paragraph by looking back in the buffer. | 1005 | /* Find the beginning of this paragraph by looking back in the buffer. |
| 634 | Value is the byte position of the paragraph's beginning. */ | 1006 | Value is the byte position of the paragraph's beginning. */ |
| 635 | static EMACS_INT | 1007 | static EMACS_INT |
| @@ -670,13 +1042,19 @@ void | |||
| 670 | bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | 1042 | bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) |
| 671 | { | 1043 | { |
| 672 | EMACS_INT bytepos = bidi_it->bytepos; | 1044 | EMACS_INT bytepos = bidi_it->bytepos; |
| 1045 | int string_p = bidi_it->string.s != NULL || STRINGP (bidi_it->string.lstring); | ||
| 673 | EMACS_INT pstartbyte; | 1046 | EMACS_INT pstartbyte; |
| 1047 | /* Note that begbyte is a byte position, while end is a character | ||
| 1048 | position. Yes, this is ugly, but we are trying to avoid costly | ||
| 1049 | calls to BYTE_TO_CHAR and its ilk. */ | ||
| 1050 | EMACS_INT begbyte = string_p ? 0 : BEGV_BYTE; | ||
| 1051 | EMACS_INT end = string_p ? bidi_it->string.schars : ZV; | ||
| 674 | 1052 | ||
| 675 | /* Special case for an empty buffer. */ | 1053 | /* Special case for an empty buffer. */ |
| 676 | if (bytepos == BEGV_BYTE && bytepos == ZV_BYTE) | 1054 | if (bytepos == begbyte && bidi_it->charpos == end) |
| 677 | dir = L2R; | 1055 | dir = L2R; |
| 678 | /* We should never be called at EOB or before BEGV. */ | 1056 | /* We should never be called at EOB or before BEGV. */ |
| 679 | else if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE) | 1057 | else if (bidi_it->charpos >= end || bytepos < begbyte) |
| 680 | abort (); | 1058 | abort (); |
| 681 | 1059 | ||
| 682 | if (dir == L2R) | 1060 | if (dir == L2R) |
| @@ -695,6 +1073,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 695 | EMACS_INT ch_len, nchars; | 1073 | EMACS_INT ch_len, nchars; |
| 696 | EMACS_INT pos, disp_pos = -1; | 1074 | EMACS_INT pos, disp_pos = -1; |
| 697 | bidi_type_t type; | 1075 | bidi_type_t type; |
| 1076 | const unsigned char *s; | ||
| 698 | 1077 | ||
| 699 | if (!bidi_initialized) | 1078 | if (!bidi_initialized) |
| 700 | bidi_initialize (); | 1079 | bidi_initialize (); |
| @@ -712,7 +1091,10 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 712 | we are potentially in a new paragraph that doesn't yet | 1091 | we are potentially in a new paragraph that doesn't yet |
| 713 | exist. */ | 1092 | exist. */ |
| 714 | pos = bidi_it->charpos; | 1093 | pos = bidi_it->charpos; |
| 715 | if (bytepos > BEGV_BYTE && FETCH_CHAR (bytepos) == '\n') | 1094 | s = STRINGP (bidi_it->string.lstring) ? |
| 1095 | SDATA (bidi_it->string.lstring) : bidi_it->string.s; | ||
| 1096 | if (bytepos > begbyte | ||
| 1097 | && bidi_char_at_pos (bytepos, s, bidi_it->string.unibyte) == '\n') | ||
| 716 | { | 1098 | { |
| 717 | bytepos++; | 1099 | bytepos++; |
| 718 | pos++; | 1100 | pos++; |
| @@ -720,17 +1102,25 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 720 | 1102 | ||
| 721 | /* We are either at the beginning of a paragraph or in the | 1103 | /* We are either at the beginning of a paragraph or in the |
| 722 | middle of it. Find where this paragraph starts. */ | 1104 | middle of it. Find where this paragraph starts. */ |
| 723 | pstartbyte = bidi_find_paragraph_start (pos, bytepos); | 1105 | if (string_p) |
| 1106 | { | ||
| 1107 | /* We don't support changes of paragraph direction inside a | ||
| 1108 | string. It is treated as a single paragraph. */ | ||
| 1109 | pstartbyte = 0; | ||
| 1110 | } | ||
| 1111 | else | ||
| 1112 | pstartbyte = bidi_find_paragraph_start (pos, bytepos); | ||
| 724 | bidi_it->separator_limit = -1; | 1113 | bidi_it->separator_limit = -1; |
| 725 | bidi_it->new_paragraph = 0; | 1114 | bidi_it->new_paragraph = 0; |
| 726 | 1115 | ||
| 727 | /* The following loop is run more than once only if NO_DEFAULT_P | 1116 | /* The following loop is run more than once only if NO_DEFAULT_P |
| 728 | is non-zero. */ | 1117 | is non-zero, and only if we are iterating on a buffer. */ |
| 729 | do { | 1118 | do { |
| 730 | bytepos = pstartbyte; | 1119 | bytepos = pstartbyte; |
| 731 | pos = BYTE_TO_CHAR (bytepos); | 1120 | if (!string_p) |
| 732 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, bidi_it->frame_window_p, | 1121 | pos = BYTE_TO_CHAR (bytepos); |
| 733 | &ch_len, &nchars); | 1122 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, |
| 1123 | bidi_it->frame_window_p, &ch_len, &nchars); | ||
| 734 | type = bidi_get_type (ch, NEUTRAL_DIR); | 1124 | type = bidi_get_type (ch, NEUTRAL_DIR); |
| 735 | 1125 | ||
| 736 | for (pos += nchars, bytepos += ch_len; | 1126 | for (pos += nchars, bytepos += ch_len; |
| @@ -744,17 +1134,19 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 744 | || type == LRE || type == LRO)); | 1134 | || type == LRE || type == LRO)); |
| 745 | type = bidi_get_type (ch, NEUTRAL_DIR)) | 1135 | type = bidi_get_type (ch, NEUTRAL_DIR)) |
| 746 | { | 1136 | { |
| 747 | if (bytepos >= ZV_BYTE) | 1137 | if (pos >= end) |
| 748 | { | 1138 | { |
| 749 | /* Pretend there's a paragraph separator at end of | 1139 | /* Pretend there's a paragraph separator at end of |
| 750 | buffer. */ | 1140 | buffer/string. */ |
| 751 | type = NEUTRAL_B; | 1141 | type = NEUTRAL_B; |
| 752 | break; | 1142 | break; |
| 753 | } | 1143 | } |
| 754 | if (type == NEUTRAL_B && bidi_at_paragraph_end (pos, bytepos) >= -1) | 1144 | if (!string_p |
| 1145 | && type == NEUTRAL_B | ||
| 1146 | && bidi_at_paragraph_end (pos, bytepos) >= -1) | ||
| 755 | break; | 1147 | break; |
| 756 | /* Fetch next character and advance to get past it. */ | 1148 | /* Fetch next character and advance to get past it. */ |
| 757 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, | 1149 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string, |
| 758 | bidi_it->frame_window_p, &ch_len, &nchars); | 1150 | bidi_it->frame_window_p, &ch_len, &nchars); |
| 759 | pos += nchars; | 1151 | pos += nchars; |
| 760 | bytepos += ch_len; | 1152 | bytepos += ch_len; |
| @@ -763,7 +1155,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 763 | bidi_it->paragraph_dir = R2L; | 1155 | bidi_it->paragraph_dir = R2L; |
| 764 | else if (type == STRONG_L) | 1156 | else if (type == STRONG_L) |
| 765 | bidi_it->paragraph_dir = L2R; | 1157 | bidi_it->paragraph_dir = L2R; |
| 766 | if (no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR) | 1158 | if (!string_p |
| 1159 | && no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR) | ||
| 767 | { | 1160 | { |
| 768 | /* If this paragraph is at BEGV, default to L2R. */ | 1161 | /* If this paragraph is at BEGV, default to L2R. */ |
| 769 | if (pstartbyte == BEGV_BYTE) | 1162 | if (pstartbyte == BEGV_BYTE) |
| @@ -786,7 +1179,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 786 | pstartbyte = prevpbyte; | 1179 | pstartbyte = prevpbyte; |
| 787 | } | 1180 | } |
| 788 | } | 1181 | } |
| 789 | } while (no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR); | 1182 | } while (!string_p |
| 1183 | && no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR); | ||
| 790 | } | 1184 | } |
| 791 | else | 1185 | else |
| 792 | abort (); | 1186 | abort (); |
| @@ -804,110 +1198,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) | |||
| 804 | bidi_line_init (bidi_it); | 1198 | bidi_line_init (bidi_it); |
| 805 | } | 1199 | } |
| 806 | 1200 | ||
| 807 | /* Do whatever UAX#9 clause X8 says should be done at paragraph's | 1201 | |
| 808 | end. */ | 1202 | /*********************************************************************** |
| 809 | static inline void | 1203 | Resolving explicit and implicit levels. |
| 810 | bidi_set_paragraph_end (struct bidi_it *bidi_it) | 1204 | The rest of this file constitutes the core of the UBA implementation. |
| 811 | { | 1205 | ***********************************************************************/ |
| 812 | bidi_it->invalid_levels = 0; | ||
| 813 | bidi_it->invalid_rl_levels = -1; | ||
| 814 | bidi_it->stack_idx = 0; | ||
| 815 | bidi_it->resolved_level = bidi_it->level_stack[0].level; | ||
| 816 | } | ||
| 817 | |||
| 818 | /* Initialize the bidi iterator from buffer/string position CHARPOS. */ | ||
| 819 | void | ||
| 820 | bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p, | ||
| 821 | struct bidi_it *bidi_it) | ||
| 822 | { | ||
| 823 | if (! bidi_initialized) | ||
| 824 | bidi_initialize (); | ||
| 825 | bidi_it->charpos = charpos; | ||
| 826 | bidi_it->bytepos = bytepos; | ||
| 827 | bidi_it->frame_window_p = frame_window_p; | ||
| 828 | bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */ | ||
| 829 | bidi_it->first_elt = 1; | ||
| 830 | bidi_set_paragraph_end (bidi_it); | ||
| 831 | bidi_it->new_paragraph = 1; | ||
| 832 | bidi_it->separator_limit = -1; | ||
| 833 | bidi_it->type = NEUTRAL_B; | ||
| 834 | bidi_it->type_after_w1 = NEUTRAL_B; | ||
| 835 | bidi_it->orig_type = NEUTRAL_B; | ||
| 836 | bidi_it->prev_was_pdf = 0; | ||
| 837 | bidi_it->prev.type = bidi_it->prev.type_after_w1 = | ||
| 838 | bidi_it->prev.orig_type = UNKNOWN_BT; | ||
| 839 | bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = | ||
| 840 | bidi_it->last_strong.orig_type = UNKNOWN_BT; | ||
| 841 | bidi_it->next_for_neutral.charpos = -1; | ||
| 842 | bidi_it->next_for_neutral.type = | ||
| 843 | bidi_it->next_for_neutral.type_after_w1 = | ||
| 844 | bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; | ||
| 845 | bidi_it->prev_for_neutral.charpos = -1; | ||
| 846 | bidi_it->prev_for_neutral.type = | ||
| 847 | bidi_it->prev_for_neutral.type_after_w1 = | ||
| 848 | bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT; | ||
| 849 | bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */ | ||
| 850 | bidi_it->disp_pos = -1; /* invalid/unknown */ | ||
| 851 | bidi_cache_shrink (); | ||
| 852 | } | ||
| 853 | |||
| 854 | /* Push the current embedding level and override status; reset the | ||
| 855 | current level to LEVEL and the current override status to OVERRIDE. */ | ||
| 856 | static inline void | ||
| 857 | bidi_push_embedding_level (struct bidi_it *bidi_it, | ||
| 858 | int level, bidi_dir_t override) | ||
| 859 | { | ||
| 860 | bidi_it->stack_idx++; | ||
| 861 | if (bidi_it->stack_idx >= BIDI_MAXLEVEL) | ||
| 862 | abort (); | ||
| 863 | bidi_it->level_stack[bidi_it->stack_idx].level = level; | ||
| 864 | bidi_it->level_stack[bidi_it->stack_idx].override = override; | ||
| 865 | } | ||
| 866 | |||
| 867 | /* Pop the embedding level and directional override status from the | ||
| 868 | stack, and return the new level. */ | ||
| 869 | static inline int | ||
| 870 | bidi_pop_embedding_level (struct bidi_it *bidi_it) | ||
| 871 | { | ||
| 872 | /* UAX#9 says to ignore invalid PDFs. */ | ||
| 873 | if (bidi_it->stack_idx > 0) | ||
| 874 | bidi_it->stack_idx--; | ||
| 875 | return bidi_it->level_stack[bidi_it->stack_idx].level; | ||
| 876 | } | ||
| 877 | |||
| 878 | /* Record in SAVED_INFO the information about the current character. */ | ||
| 879 | static inline void | ||
| 880 | bidi_remember_char (struct bidi_saved_info *saved_info, | ||
| 881 | struct bidi_it *bidi_it) | ||
| 882 | { | ||
| 883 | saved_info->charpos = bidi_it->charpos; | ||
| 884 | saved_info->bytepos = bidi_it->bytepos; | ||
| 885 | saved_info->type = bidi_it->type; | ||
| 886 | bidi_check_type (bidi_it->type); | ||
| 887 | saved_info->type_after_w1 = bidi_it->type_after_w1; | ||
| 888 | bidi_check_type (bidi_it->type_after_w1); | ||
| 889 | saved_info->orig_type = bidi_it->orig_type; | ||
| 890 | bidi_check_type (bidi_it->orig_type); | ||
| 891 | } | ||
| 892 | |||
| 893 | /* Resolve the type of a neutral character according to the type of | ||
| 894 | surrounding strong text and the current embedding level. */ | ||
| 895 | static inline bidi_type_t | ||
| 896 | bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) | ||
| 897 | { | ||
| 898 | /* N1: European and Arabic numbers are treated as though they were R. */ | ||
| 899 | if (next_type == WEAK_EN || next_type == WEAK_AN) | ||
| 900 | next_type = STRONG_R; | ||
| 901 | if (prev_type == WEAK_EN || prev_type == WEAK_AN) | ||
| 902 | prev_type = STRONG_R; | ||
| 903 | |||
| 904 | if (next_type == prev_type) /* N1 */ | ||
| 905 | return next_type; | ||
| 906 | else if ((lev & 1) == 0) /* N2 */ | ||
| 907 | return STRONG_L; | ||
| 908 | else | ||
| 909 | return STRONG_R; | ||
| 910 | } | ||
| 911 | 1206 | ||
| 912 | static inline int | 1207 | static inline int |
| 913 | bidi_explicit_dir_char (int ch) | 1208 | bidi_explicit_dir_char (int ch) |
| @@ -934,19 +1229,35 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 934 | int current_level; | 1229 | int current_level; |
| 935 | int new_level; | 1230 | int new_level; |
| 936 | bidi_dir_t override; | 1231 | bidi_dir_t override; |
| 1232 | int string_p = bidi_it->string.s != NULL || STRINGP (bidi_it->string.lstring); | ||
| 937 | 1233 | ||
| 938 | /* If reseat()'ed, don't advance, so as to start iteration from the | 1234 | /* If reseat()'ed, don't advance, so as to start iteration from the |
| 939 | position where we were reseated. bidi_it->bytepos can be less | 1235 | position where we were reseated. bidi_it->bytepos can be less |
| 940 | than BEGV_BYTE after reseat to BEGV. */ | 1236 | than BEGV_BYTE after reseat to BEGV. */ |
| 941 | if (bidi_it->bytepos < BEGV_BYTE | 1237 | if (bidi_it->bytepos < (string_p ? 0 : BEGV_BYTE) |
| 942 | || bidi_it->first_elt) | 1238 | || bidi_it->first_elt) |
| 943 | { | 1239 | { |
| 944 | bidi_it->first_elt = 0; | 1240 | bidi_it->first_elt = 0; |
| 945 | if (bidi_it->charpos < BEGV) | 1241 | if (string_p) |
| 946 | bidi_it->charpos = BEGV; | 1242 | { |
| 947 | bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos); | 1243 | const unsigned char *p = |
| 1244 | STRINGP (bidi_it->string.lstring) | ||
| 1245 | ? SDATA (bidi_it->string.lstring) : bidi_it->string.s; | ||
| 1246 | |||
| 1247 | if (bidi_it->charpos < 0) | ||
| 1248 | bidi_it->charpos = 0; | ||
| 1249 | bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos, | ||
| 1250 | bidi_it->string.unibyte); | ||
| 1251 | } | ||
| 1252 | else | ||
| 1253 | { | ||
| 1254 | if (bidi_it->charpos < BEGV) | ||
| 1255 | bidi_it->charpos = BEGV; | ||
| 1256 | bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos); | ||
| 1257 | } | ||
| 948 | } | 1258 | } |
| 949 | else if (bidi_it->bytepos < ZV_BYTE) /* don't move at ZV */ | 1259 | /* Don't move at end of buffer/string. */ |
| 1260 | else if (bidi_it->charpos < (string_p ? bidi_it->string.schars : ZV)) | ||
| 950 | { | 1261 | { |
| 951 | /* Advance to the next character, skipping characters covered by | 1262 | /* Advance to the next character, skipping characters covered by |
| 952 | display strings (nchars > 1). */ | 1263 | display strings (nchars > 1). */ |
| @@ -962,12 +1273,12 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 962 | override = bidi_it->level_stack[bidi_it->stack_idx].override; | 1273 | override = bidi_it->level_stack[bidi_it->stack_idx].override; |
| 963 | new_level = current_level; | 1274 | new_level = current_level; |
| 964 | 1275 | ||
| 965 | if (bidi_it->bytepos >= ZV_BYTE) | 1276 | if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV)) |
| 966 | { | 1277 | { |
| 967 | curchar = BIDI_EOB; | 1278 | curchar = BIDI_EOB; |
| 968 | bidi_it->ch_len = 1; | 1279 | bidi_it->ch_len = 1; |
| 969 | bidi_it->nchars = 1; | 1280 | bidi_it->nchars = 1; |
| 970 | bidi_it->disp_pos = ZV; | 1281 | bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV); |
| 971 | } | 1282 | } |
| 972 | else | 1283 | else |
| 973 | { | 1284 | { |
| @@ -975,7 +1286,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 975 | display string, treat the entire run of covered characters as | 1286 | display string, treat the entire run of covered characters as |
| 976 | a single character u+FFFC. */ | 1287 | a single character u+FFFC. */ |
| 977 | curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, | 1288 | curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, |
| 978 | &bidi_it->disp_pos, bidi_it->frame_window_p, | 1289 | &bidi_it->disp_pos, &bidi_it->string, |
| 1290 | bidi_it->frame_window_p, | ||
| 979 | &bidi_it->ch_len, &bidi_it->nchars); | 1291 | &bidi_it->ch_len, &bidi_it->nchars); |
| 980 | } | 1292 | } |
| 981 | bidi_it->ch = curchar; | 1293 | bidi_it->ch = curchar; |
| @@ -1000,7 +1312,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1000 | bidi_it->type_after_w1 = type; | 1312 | bidi_it->type_after_w1 = type; |
| 1001 | bidi_check_type (bidi_it->type_after_w1); | 1313 | bidi_check_type (bidi_it->type_after_w1); |
| 1002 | type = WEAK_BN; /* X9/Retaining */ | 1314 | type = WEAK_BN; /* X9/Retaining */ |
| 1003 | if (bidi_it->ignore_bn_limit <= 0) | 1315 | if (bidi_it->ignore_bn_limit <= -1) |
| 1004 | { | 1316 | { |
| 1005 | if (current_level <= BIDI_MAXLEVEL - 4) | 1317 | if (current_level <= BIDI_MAXLEVEL - 4) |
| 1006 | { | 1318 | { |
| @@ -1033,7 +1345,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1033 | bidi_it->type_after_w1 = type; | 1345 | bidi_it->type_after_w1 = type; |
| 1034 | bidi_check_type (bidi_it->type_after_w1); | 1346 | bidi_check_type (bidi_it->type_after_w1); |
| 1035 | type = WEAK_BN; /* X9/Retaining */ | 1347 | type = WEAK_BN; /* X9/Retaining */ |
| 1036 | if (bidi_it->ignore_bn_limit <= 0) | 1348 | if (bidi_it->ignore_bn_limit <= -1) |
| 1037 | { | 1349 | { |
| 1038 | if (current_level <= BIDI_MAXLEVEL - 5) | 1350 | if (current_level <= BIDI_MAXLEVEL - 5) |
| 1039 | { | 1351 | { |
| @@ -1068,7 +1380,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1068 | bidi_it->type_after_w1 = type; | 1380 | bidi_it->type_after_w1 = type; |
| 1069 | bidi_check_type (bidi_it->type_after_w1); | 1381 | bidi_check_type (bidi_it->type_after_w1); |
| 1070 | type = WEAK_BN; /* X9/Retaining */ | 1382 | type = WEAK_BN; /* X9/Retaining */ |
| 1071 | if (bidi_it->ignore_bn_limit <= 0) | 1383 | if (bidi_it->ignore_bn_limit <= -1) |
| 1072 | { | 1384 | { |
| 1073 | if (!bidi_it->invalid_rl_levels) | 1385 | if (!bidi_it->invalid_rl_levels) |
| 1074 | { | 1386 | { |
| @@ -1111,13 +1423,17 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1111 | { | 1423 | { |
| 1112 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; | 1424 | int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; |
| 1113 | int new_level = bidi_resolve_explicit_1 (bidi_it); | 1425 | int new_level = bidi_resolve_explicit_1 (bidi_it); |
| 1426 | EMACS_INT eob = bidi_it->string.s ? bidi_it->string.schars : ZV; | ||
| 1427 | const unsigned char *s = STRINGP (bidi_it->string.lstring) | ||
| 1428 | ? SDATA (bidi_it->string.lstring) : bidi_it->string.s; | ||
| 1114 | 1429 | ||
| 1115 | if (prev_level < new_level | 1430 | if (prev_level < new_level |
| 1116 | && bidi_it->type == WEAK_BN | 1431 | && bidi_it->type == WEAK_BN |
| 1117 | && bidi_it->ignore_bn_limit == 0 /* only if not already known */ | 1432 | && bidi_it->ignore_bn_limit == -1 /* only if not already known */ |
| 1118 | && bidi_it->bytepos < ZV_BYTE /* not already at EOB */ | 1433 | && bidi_it->charpos < eob /* not already at EOB */ |
| 1119 | && bidi_explicit_dir_char (FETCH_MULTIBYTE_CHAR (bidi_it->bytepos | 1434 | && bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos |
| 1120 | + bidi_it->ch_len))) | 1435 | + bidi_it->ch_len, s, |
| 1436 | bidi_it->string.unibyte))) | ||
| 1121 | { | 1437 | { |
| 1122 | /* Avoid pushing and popping embedding levels if the level run | 1438 | /* Avoid pushing and popping embedding levels if the level run |
| 1123 | is empty, as this breaks level runs where it shouldn't. | 1439 | is empty, as this breaks level runs where it shouldn't. |
| @@ -1129,12 +1445,17 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1129 | 1445 | ||
| 1130 | bidi_copy_it (&saved_it, bidi_it); | 1446 | bidi_copy_it (&saved_it, bidi_it); |
| 1131 | 1447 | ||
| 1132 | while (bidi_explicit_dir_char (FETCH_MULTIBYTE_CHAR (bidi_it->bytepos | 1448 | while (bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos |
| 1133 | + bidi_it->ch_len))) | 1449 | + bidi_it->ch_len, s, |
| 1450 | bidi_it->string.unibyte))) | ||
| 1134 | { | 1451 | { |
| 1135 | /* This advances to the next character, skipping any | 1452 | /* This advances to the next character, skipping any |
| 1136 | characters covered by display strings. */ | 1453 | characters covered by display strings. */ |
| 1137 | level = bidi_resolve_explicit_1 (bidi_it); | 1454 | level = bidi_resolve_explicit_1 (bidi_it); |
| 1455 | /* If string.lstring was relocated inside bidi_resolve_explicit_1, | ||
| 1456 | a pointer to its data is no longer valid. */ | ||
| 1457 | if (STRINGP (bidi_it->string.lstring)) | ||
| 1458 | s = SDATA (bidi_it->string.lstring); | ||
| 1138 | } | 1459 | } |
| 1139 | 1460 | ||
| 1140 | if (bidi_it->nchars <= 0) | 1461 | if (bidi_it->nchars <= 0) |
| @@ -1142,10 +1463,10 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1142 | if (level == prev_level) /* empty embedding */ | 1463 | if (level == prev_level) /* empty embedding */ |
| 1143 | saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars; | 1464 | saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars; |
| 1144 | else /* this embedding is non-empty */ | 1465 | else /* this embedding is non-empty */ |
| 1145 | saved_it.ignore_bn_limit = -1; | 1466 | saved_it.ignore_bn_limit = -2; |
| 1146 | 1467 | ||
| 1147 | bidi_copy_it (bidi_it, &saved_it); | 1468 | bidi_copy_it (bidi_it, &saved_it); |
| 1148 | if (bidi_it->ignore_bn_limit > 0) | 1469 | if (bidi_it->ignore_bn_limit > -1) |
| 1149 | { | 1470 | { |
| 1150 | /* We pushed a level, but we shouldn't have. Undo that. */ | 1471 | /* We pushed a level, but we shouldn't have. Undo that. */ |
| 1151 | if (!bidi_it->invalid_rl_levels) | 1472 | if (!bidi_it->invalid_rl_levels) |
| @@ -1188,6 +1509,9 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1188 | int next_char; | 1509 | int next_char; |
| 1189 | bidi_type_t type_of_next; | 1510 | bidi_type_t type_of_next; |
| 1190 | struct bidi_it saved_it; | 1511 | struct bidi_it saved_it; |
| 1512 | EMACS_INT eob = | ||
| 1513 | (STRINGP (bidi_it->string.lstring) || bidi_it->string.s) | ||
| 1514 | ? bidi_it->string.schars : ZV; | ||
| 1191 | 1515 | ||
| 1192 | type = bidi_it->type; | 1516 | type = bidi_it->type; |
| 1193 | override = bidi_it->level_stack[bidi_it->stack_idx].override; | 1517 | override = bidi_it->level_stack[bidi_it->stack_idx].override; |
| @@ -1254,10 +1578,15 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1254 | && bidi_it->prev.orig_type == WEAK_EN) | 1578 | && bidi_it->prev.orig_type == WEAK_EN) |
| 1255 | || bidi_it->prev.type_after_w1 == WEAK_AN))) | 1579 | || bidi_it->prev.type_after_w1 == WEAK_AN))) |
| 1256 | { | 1580 | { |
| 1581 | const unsigned char *s = | ||
| 1582 | STRINGP (bidi_it->string.lstring) | ||
| 1583 | ? SDATA (bidi_it->string.lstring) : bidi_it->string.s; | ||
| 1584 | |||
| 1257 | next_char = | 1585 | next_char = |
| 1258 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE | 1586 | bidi_it->charpos + bidi_it->nchars >= eob |
| 1259 | ? BIDI_EOB : FETCH_MULTIBYTE_CHAR (bidi_it->bytepos | 1587 | ? BIDI_EOB |
| 1260 | + bidi_it->ch_len); | 1588 | : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s, |
| 1589 | bidi_it->string.unibyte); | ||
| 1261 | type_of_next = bidi_get_type (next_char, override); | 1590 | type_of_next = bidi_get_type (next_char, override); |
| 1262 | 1591 | ||
| 1263 | if (type_of_next == WEAK_BN | 1592 | if (type_of_next == WEAK_BN |
| @@ -1306,13 +1635,17 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1306 | else /* W5: ET/BN with EN after it. */ | 1635 | else /* W5: ET/BN with EN after it. */ |
| 1307 | { | 1636 | { |
| 1308 | EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; | 1637 | EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; |
| 1638 | const unsigned char *s = | ||
| 1639 | STRINGP (bidi_it->string.lstring) | ||
| 1640 | ? SDATA (bidi_it->string.lstring) : bidi_it->string.s; | ||
| 1309 | 1641 | ||
| 1310 | if (bidi_it->nchars <= 0) | 1642 | if (bidi_it->nchars <= 0) |
| 1311 | abort (); | 1643 | abort (); |
| 1312 | next_char = | 1644 | next_char = |
| 1313 | bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE | 1645 | bidi_it->charpos + bidi_it->nchars >= eob |
| 1314 | ? BIDI_EOB : FETCH_MULTIBYTE_CHAR (bidi_it->bytepos | 1646 | ? BIDI_EOB |
| 1315 | + bidi_it->ch_len); | 1647 | : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s, |
| 1648 | bidi_it->string.unibyte); | ||
| 1316 | type_of_next = bidi_get_type (next_char, override); | 1649 | type_of_next = bidi_get_type (next_char, override); |
| 1317 | 1650 | ||
| 1318 | if (type_of_next == WEAK_ET | 1651 | if (type_of_next == WEAK_ET |
| @@ -1373,6 +1706,25 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1373 | return type; | 1706 | return type; |
| 1374 | } | 1707 | } |
| 1375 | 1708 | ||
| 1709 | /* Resolve the type of a neutral character according to the type of | ||
| 1710 | surrounding strong text and the current embedding level. */ | ||
| 1711 | static inline bidi_type_t | ||
| 1712 | bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) | ||
| 1713 | { | ||
| 1714 | /* N1: European and Arabic numbers are treated as though they were R. */ | ||
| 1715 | if (next_type == WEAK_EN || next_type == WEAK_AN) | ||
| 1716 | next_type = STRONG_R; | ||
| 1717 | if (prev_type == WEAK_EN || prev_type == WEAK_AN) | ||
| 1718 | prev_type = STRONG_R; | ||
| 1719 | |||
| 1720 | if (next_type == prev_type) /* N1 */ | ||
| 1721 | return next_type; | ||
| 1722 | else if ((lev & 1) == 0) /* N2 */ | ||
| 1723 | return STRONG_L; | ||
| 1724 | else | ||
| 1725 | return STRONG_R; | ||
| 1726 | } | ||
| 1727 | |||
| 1376 | static bidi_type_t | 1728 | static bidi_type_t |
| 1377 | bidi_resolve_neutral (struct bidi_it *bidi_it) | 1729 | bidi_resolve_neutral (struct bidi_it *bidi_it) |
| 1378 | { | 1730 | { |
| @@ -1509,11 +1861,11 @@ bidi_type_of_next_char (struct bidi_it *bidi_it) | |||
| 1509 | 1861 | ||
| 1510 | /* Reset the limit until which to ignore BNs if we step out of the | 1862 | /* Reset the limit until which to ignore BNs if we step out of the |
| 1511 | area where we found only empty levels. */ | 1863 | area where we found only empty levels. */ |
| 1512 | if ((bidi_it->ignore_bn_limit > 0 | 1864 | if ((bidi_it->ignore_bn_limit > -1 |
| 1513 | && bidi_it->ignore_bn_limit <= bidi_it->charpos) | 1865 | && bidi_it->ignore_bn_limit <= bidi_it->charpos) |
| 1514 | || (bidi_it->ignore_bn_limit == -1 | 1866 | || (bidi_it->ignore_bn_limit == -2 |
| 1515 | && !bidi_explicit_dir_char (bidi_it->ch))) | 1867 | && !bidi_explicit_dir_char (bidi_it->ch))) |
| 1516 | bidi_it->ignore_bn_limit = 0; | 1868 | bidi_it->ignore_bn_limit = -1; |
| 1517 | 1869 | ||
| 1518 | type = bidi_resolve_neutral (bidi_it); | 1870 | type = bidi_resolve_neutral (bidi_it); |
| 1519 | 1871 | ||
| @@ -1530,12 +1882,16 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1530 | bidi_type_t type; | 1882 | bidi_type_t type; |
| 1531 | int level, prev_level = -1; | 1883 | int level, prev_level = -1; |
| 1532 | struct bidi_saved_info next_for_neutral; | 1884 | struct bidi_saved_info next_for_neutral; |
| 1533 | EMACS_INT next_char_pos; | 1885 | EMACS_INT next_char_pos = -2; |
| 1534 | 1886 | ||
| 1535 | if (bidi_it->scan_dir == 1) | 1887 | if (bidi_it->scan_dir == 1) |
| 1536 | { | 1888 | { |
| 1889 | EMACS_INT eob = | ||
| 1890 | (bidi_it->string.s || STRINGP (bidi_it->string.lstring)) | ||
| 1891 | ? bidi_it->string.schars : ZV; | ||
| 1892 | |||
| 1537 | /* There's no sense in trying to advance if we hit end of text. */ | 1893 | /* There's no sense in trying to advance if we hit end of text. */ |
| 1538 | if (bidi_it->bytepos >= ZV_BYTE) | 1894 | if (bidi_it->charpos >= eob) |
| 1539 | return bidi_it->resolved_level; | 1895 | return bidi_it->resolved_level; |
| 1540 | 1896 | ||
| 1541 | /* Record the info about the previous character. */ | 1897 | /* Record the info about the previous character. */ |
| @@ -1575,17 +1931,27 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1575 | /* Perhaps the character we want is already cached. If it is, the | 1931 | /* Perhaps the character we want is already cached. If it is, the |
| 1576 | call to bidi_cache_find below will return a type other than | 1932 | call to bidi_cache_find below will return a type other than |
| 1577 | UNKNOWN_BT. */ | 1933 | UNKNOWN_BT. */ |
| 1578 | if (bidi_cache_idx && !bidi_it->first_elt) | 1934 | if (bidi_cache_idx > bidi_cache_start && !bidi_it->first_elt) |
| 1579 | { | 1935 | { |
| 1936 | int bob = | ||
| 1937 | (bidi_it->string.s || STRINGP (bidi_it->string.lstring)) ? 0 : 1; | ||
| 1938 | |||
| 1580 | if (bidi_it->scan_dir > 0) | 1939 | if (bidi_it->scan_dir > 0) |
| 1581 | { | 1940 | { |
| 1582 | if (bidi_it->nchars <= 0) | 1941 | if (bidi_it->nchars <= 0) |
| 1583 | abort (); | 1942 | abort (); |
| 1584 | next_char_pos = bidi_it->charpos + bidi_it->nchars; | 1943 | next_char_pos = bidi_it->charpos + bidi_it->nchars; |
| 1585 | } | 1944 | } |
| 1586 | else | 1945 | else if (bidi_it->charpos >= bob) |
| 1946 | /* Implementation note: we allow next_char_pos to be as low as | ||
| 1947 | 0 for buffers or -1 for strings, and that is okay because | ||
| 1948 | that's the "position" of the sentinel iterator state we | ||
| 1949 | cached at the beginning of the iteration. */ | ||
| 1587 | next_char_pos = bidi_it->charpos - 1; | 1950 | next_char_pos = bidi_it->charpos - 1; |
| 1588 | type = bidi_cache_find (next_char_pos, -1, bidi_it); | 1951 | if (next_char_pos >= bob - 1) |
| 1952 | type = bidi_cache_find (next_char_pos, -1, bidi_it); | ||
| 1953 | else | ||
| 1954 | type = UNKNOWN_BT; | ||
| 1589 | } | 1955 | } |
| 1590 | else | 1956 | else |
| 1591 | type = UNKNOWN_BT; | 1957 | type = UNKNOWN_BT; |
| @@ -1652,13 +2018,14 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1652 | EMACS_INT cpos = bidi_it->charpos; | 2018 | EMACS_INT cpos = bidi_it->charpos; |
| 1653 | EMACS_INT disp_pos = bidi_it->disp_pos; | 2019 | EMACS_INT disp_pos = bidi_it->disp_pos; |
| 1654 | EMACS_INT nc = bidi_it->nchars; | 2020 | EMACS_INT nc = bidi_it->nchars; |
| 2021 | struct bidi_string_data bs = bidi_it->string; | ||
| 1655 | bidi_type_t chtype; | 2022 | bidi_type_t chtype; |
| 1656 | int fwp = bidi_it->frame_window_p; | 2023 | int fwp = bidi_it->frame_window_p; |
| 1657 | 2024 | ||
| 1658 | if (bidi_it->nchars <= 0) | 2025 | if (bidi_it->nchars <= 0) |
| 1659 | abort (); | 2026 | abort (); |
| 1660 | do { | 2027 | do { |
| 1661 | ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, fwp, | 2028 | ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &bs, fwp, |
| 1662 | &clen, &nc); | 2029 | &clen, &nc); |
| 1663 | if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) | 2030 | if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) |
| 1664 | chtype = NEUTRAL_B; | 2031 | chtype = NEUTRAL_B; |
| @@ -1756,10 +2123,11 @@ static void | |||
| 1756 | bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) | 2123 | bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) |
| 1757 | { | 2124 | { |
| 1758 | int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; | 2125 | int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; |
| 1759 | int idx; | 2126 | EMACS_INT idx; |
| 1760 | 2127 | ||
| 1761 | /* Try the cache first. */ | 2128 | /* Try the cache first. */ |
| 1762 | if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) >= 0) | 2129 | if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) |
| 2130 | >= bidi_cache_start) | ||
| 1763 | bidi_cache_fetch_state (idx, bidi_it); | 2131 | bidi_cache_fetch_state (idx, bidi_it); |
| 1764 | else | 2132 | else |
| 1765 | { | 2133 | { |
| @@ -1781,12 +2149,21 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 1781 | { | 2149 | { |
| 1782 | int old_level, new_level, next_level; | 2150 | int old_level, new_level, next_level; |
| 1783 | struct bidi_it sentinel; | 2151 | struct bidi_it sentinel; |
| 2152 | struct gcpro gcpro1; | ||
| 2153 | |||
| 2154 | if (bidi_it->charpos < 0 || bidi_it->bytepos < 0) | ||
| 2155 | abort (); | ||
| 1784 | 2156 | ||
| 1785 | if (bidi_it->scan_dir == 0) | 2157 | if (bidi_it->scan_dir == 0) |
| 1786 | { | 2158 | { |
| 1787 | bidi_it->scan_dir = 1; /* default to logical order */ | 2159 | bidi_it->scan_dir = 1; /* default to logical order */ |
| 1788 | } | 2160 | } |
| 1789 | 2161 | ||
| 2162 | /* The code below can call eval, and thus cause GC. If we are | ||
| 2163 | iterating a Lisp string, make sure it won't be GCed. */ | ||
| 2164 | if (STRINGP (bidi_it->string.lstring)) | ||
| 2165 | GCPRO1 (bidi_it->string.lstring); | ||
| 2166 | |||
| 1790 | /* If we just passed a newline, initialize for the next line. */ | 2167 | /* If we just passed a newline, initialize for the next line. */ |
| 1791 | if (!bidi_it->first_elt && bidi_it->orig_type == NEUTRAL_B) | 2168 | if (!bidi_it->first_elt && bidi_it->orig_type == NEUTRAL_B) |
| 1792 | bidi_line_init (bidi_it); | 2169 | bidi_line_init (bidi_it); |
| @@ -1794,7 +2171,7 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 1794 | /* Prepare the sentinel iterator state, and cache it. When we bump | 2171 | /* Prepare the sentinel iterator state, and cache it. When we bump |
| 1795 | into it, scanning backwards, we'll know that the last non-base | 2172 | into it, scanning backwards, we'll know that the last non-base |
| 1796 | level is exhausted. */ | 2173 | level is exhausted. */ |
| 1797 | if (bidi_cache_idx == 0) | 2174 | if (bidi_cache_idx == bidi_cache_start) |
| 1798 | { | 2175 | { |
| 1799 | bidi_copy_it (&sentinel, bidi_it); | 2176 | bidi_copy_it (&sentinel, bidi_it); |
| 1800 | if (bidi_it->first_elt) | 2177 | if (bidi_it->first_elt) |
| @@ -1869,26 +2246,34 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 1869 | reordering, whereas we _must_ know the paragraph base direction | 2246 | reordering, whereas we _must_ know the paragraph base direction |
| 1870 | _before_ we process the paragraph's text, since the base | 2247 | _before_ we process the paragraph's text, since the base |
| 1871 | direction affects the reordering. */ | 2248 | direction affects the reordering. */ |
| 1872 | if (bidi_it->scan_dir == 1 | 2249 | if (bidi_it->scan_dir == 1 && bidi_it->orig_type == NEUTRAL_B) |
| 1873 | && bidi_it->orig_type == NEUTRAL_B | ||
| 1874 | && bidi_it->bytepos < ZV_BYTE) | ||
| 1875 | { | 2250 | { |
| 1876 | EMACS_INT sep_len = | 2251 | /* The paragraph direction of the entire string, once |
| 1877 | bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars, | 2252 | determined, is in effect for the entire string. Setting the |
| 1878 | bidi_it->bytepos + bidi_it->ch_len); | 2253 | separator limit to the end of the string prevents |
| 1879 | if (bidi_it->nchars <= 0) | 2254 | bidi_paragraph_init from being called automatically on this |
| 1880 | abort (); | 2255 | string. */ |
| 1881 | if (sep_len >= 0) | 2256 | if (bidi_it->string.s || STRINGP (bidi_it->string.lstring)) |
| 2257 | bidi_it->separator_limit = bidi_it->string.schars; | ||
| 2258 | else if (bidi_it->bytepos < ZV_BYTE) | ||
| 1882 | { | 2259 | { |
| 1883 | bidi_it->new_paragraph = 1; | 2260 | EMACS_INT sep_len = |
| 1884 | /* Record the buffer position of the last character of the | 2261 | bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars, |
| 1885 | paragraph separator. */ | 2262 | bidi_it->bytepos + bidi_it->ch_len); |
| 1886 | bidi_it->separator_limit = | 2263 | if (bidi_it->nchars <= 0) |
| 1887 | bidi_it->charpos + bidi_it->nchars + sep_len; | 2264 | abort (); |
| 2265 | if (sep_len >= 0) | ||
| 2266 | { | ||
| 2267 | bidi_it->new_paragraph = 1; | ||
| 2268 | /* Record the buffer position of the last character of the | ||
| 2269 | paragraph separator. */ | ||
| 2270 | bidi_it->separator_limit = | ||
| 2271 | bidi_it->charpos + bidi_it->nchars + sep_len; | ||
| 2272 | } | ||
| 1888 | } | 2273 | } |
| 1889 | } | 2274 | } |
| 1890 | 2275 | ||
| 1891 | if (bidi_it->scan_dir == 1 && bidi_cache_idx) | 2276 | if (bidi_it->scan_dir == 1 && bidi_cache_idx > bidi_cache_start) |
| 1892 | { | 2277 | { |
| 1893 | /* If we are at paragraph's base embedding level and beyond the | 2278 | /* If we are at paragraph's base embedding level and beyond the |
| 1894 | last cached position, the cache's job is done and we can | 2279 | last cached position, the cache's job is done and we can |
| @@ -1904,6 +2289,9 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 1904 | else | 2289 | else |
| 1905 | bidi_cache_iterator_state (bidi_it, 1); | 2290 | bidi_cache_iterator_state (bidi_it, 1); |
| 1906 | } | 2291 | } |
| 2292 | |||
| 2293 | if (STRINGP (bidi_it->string.lstring)) | ||
| 2294 | UNGCPRO; | ||
| 1907 | } | 2295 | } |
| 1908 | 2296 | ||
| 1909 | /* This is meant to be called from within the debugger, whenever you | 2297 | /* This is meant to be called from within the debugger, whenever you |
| @@ -1920,7 +2308,7 @@ bidi_dump_cached_states (void) | |||
| 1920 | fprintf (stderr, "The cache is empty.\n"); | 2308 | fprintf (stderr, "The cache is empty.\n"); |
| 1921 | return; | 2309 | return; |
| 1922 | } | 2310 | } |
| 1923 | fprintf (stderr, "Total of %d state%s in cache:\n", | 2311 | fprintf (stderr, "Total of %"pD"d state%s in cache:\n", |
| 1924 | bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s"); | 2312 | bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s"); |
| 1925 | 2313 | ||
| 1926 | for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10) | 2314 | for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10) |
diff --git a/src/buffer.c b/src/buffer.c index 328963be78c..81c537b9c6a 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -146,7 +146,7 @@ static Lisp_Object Qoverlayp; | |||
| 146 | 146 | ||
| 147 | Lisp_Object Qpriority, Qbefore_string, Qafter_string; | 147 | Lisp_Object Qpriority, Qbefore_string, Qafter_string; |
| 148 | 148 | ||
| 149 | static Lisp_Object Qclone_number, Qevaporate; | 149 | static Lisp_Object Qevaporate; |
| 150 | 150 | ||
| 151 | Lisp_Object Qmodification_hooks; | 151 | Lisp_Object Qmodification_hooks; |
| 152 | Lisp_Object Qinsert_in_front_hooks; | 152 | Lisp_Object Qinsert_in_front_hooks; |
| @@ -361,6 +361,7 @@ even if it is dead. The return value is never nil. */) | |||
| 361 | BUF_END_UNCHANGED (b) = 0; | 361 | BUF_END_UNCHANGED (b) = 0; |
| 362 | BUF_BEG_UNCHANGED (b) = 0; | 362 | BUF_BEG_UNCHANGED (b) = 0; |
| 363 | *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ | 363 | *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ |
| 364 | b->text->inhibit_shrinking = 0; | ||
| 364 | 365 | ||
| 365 | b->newline_cache = 0; | 366 | b->newline_cache = 0; |
| 366 | b->width_run_cache = 0; | 367 | b->width_run_cache = 0; |
| @@ -471,8 +472,8 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to) | |||
| 471 | 472 | ||
| 472 | /* buffer-local Lisp variables start at `undo_list', | 473 | /* buffer-local Lisp variables start at `undo_list', |
| 473 | tho only the ones from `name' on are GC'd normally. */ | 474 | tho only the ones from `name' on are GC'd normally. */ |
| 474 | for (offset = PER_BUFFER_VAR_OFFSET (undo_list); | 475 | for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER); |
| 475 | offset < sizeof *to; | 476 | offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER); |
| 476 | offset += sizeof (Lisp_Object)) | 477 | offset += sizeof (Lisp_Object)) |
| 477 | { | 478 | { |
| 478 | Lisp_Object obj; | 479 | Lisp_Object obj; |
| @@ -830,8 +831,8 @@ reset_buffer_local_variables (register struct buffer *b, int permanent_too) | |||
| 830 | 831 | ||
| 831 | /* buffer-local Lisp variables start at `undo_list', | 832 | /* buffer-local Lisp variables start at `undo_list', |
| 832 | tho only the ones from `name' on are GC'd normally. */ | 833 | tho only the ones from `name' on are GC'd normally. */ |
| 833 | for (offset = PER_BUFFER_VAR_OFFSET (undo_list); | 834 | for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER); |
| 834 | offset < sizeof *b; | 835 | offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER); |
| 835 | offset += sizeof (Lisp_Object)) | 836 | offset += sizeof (Lisp_Object)) |
| 836 | { | 837 | { |
| 837 | int idx = PER_BUFFER_IDX (offset); | 838 | int idx = PER_BUFFER_IDX (offset); |
| @@ -1055,8 +1056,8 @@ No argument or nil as argument means use current buffer as BUFFER. */) | |||
| 1055 | 1056 | ||
| 1056 | /* buffer-local Lisp variables start at `undo_list', | 1057 | /* buffer-local Lisp variables start at `undo_list', |
| 1057 | tho only the ones from `name' on are GC'd normally. */ | 1058 | tho only the ones from `name' on are GC'd normally. */ |
| 1058 | for (offset = PER_BUFFER_VAR_OFFSET (undo_list); | 1059 | for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER); |
| 1059 | offset < sizeof (struct buffer); | 1060 | offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER); |
| 1060 | /* sizeof EMACS_INT == sizeof Lisp_Object */ | 1061 | /* sizeof EMACS_INT == sizeof Lisp_Object */ |
| 1061 | offset += (sizeof (EMACS_INT))) | 1062 | offset += (sizeof (EMACS_INT))) |
| 1062 | { | 1063 | { |
| @@ -2900,13 +2901,10 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w) | |||
| 2900 | overlays that are limited to some other window. */ | 2901 | overlays that are limited to some other window. */ |
| 2901 | if (w) | 2902 | if (w) |
| 2902 | { | 2903 | { |
| 2903 | Lisp_Object window, clone_number; | 2904 | Lisp_Object window; |
| 2904 | 2905 | ||
| 2905 | window = Foverlay_get (overlay, Qwindow); | 2906 | window = Foverlay_get (overlay, Qwindow); |
| 2906 | clone_number = Foverlay_get (overlay, Qclone_number); | 2907 | if (WINDOWP (window) && XWINDOW (window) != w) |
| 2907 | if (WINDOWP (window) && XWINDOW (window) != w | ||
| 2908 | && (! NUMBERP (clone_number) | ||
| 2909 | || XFASTINT (clone_number) != XFASTINT (w->clone_number))) | ||
| 2910 | continue; | 2908 | continue; |
| 2911 | } | 2909 | } |
| 2912 | 2910 | ||
| @@ -3035,7 +3033,7 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, | |||
| 3035 | EMACS_INT | 3033 | EMACS_INT |
| 3036 | overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr) | 3034 | overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr) |
| 3037 | { | 3035 | { |
| 3038 | Lisp_Object overlay, window, clone_number, str; | 3036 | Lisp_Object overlay, window, str; |
| 3039 | struct Lisp_Overlay *ov; | 3037 | struct Lisp_Overlay *ov; |
| 3040 | EMACS_INT startpos, endpos; | 3038 | EMACS_INT startpos, endpos; |
| 3041 | int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); | 3039 | int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| @@ -3054,12 +3052,8 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr) | |||
| 3054 | if (endpos != pos && startpos != pos) | 3052 | if (endpos != pos && startpos != pos) |
| 3055 | continue; | 3053 | continue; |
| 3056 | window = Foverlay_get (overlay, Qwindow); | 3054 | window = Foverlay_get (overlay, Qwindow); |
| 3057 | clone_number = Foverlay_get (overlay, Qclone_number); | 3055 | if (WINDOWP (window) && XWINDOW (window) != w) |
| 3058 | if (WINDOWP (window) && XWINDOW (window) != w | ||
| 3059 | && (! NUMBERP (clone_number) | ||
| 3060 | || XFASTINT (clone_number) != XFASTINT (w->clone_number))) | ||
| 3061 | continue; | 3056 | continue; |
| 3062 | |||
| 3063 | if (startpos == pos | 3057 | if (startpos == pos |
| 3064 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) | 3058 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) |
| 3065 | record_overlay_string (&overlay_heads, str, | 3059 | record_overlay_string (&overlay_heads, str, |
| @@ -3086,10 +3080,7 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr) | |||
| 3086 | if (endpos != pos && startpos != pos) | 3080 | if (endpos != pos && startpos != pos) |
| 3087 | continue; | 3081 | continue; |
| 3088 | window = Foverlay_get (overlay, Qwindow); | 3082 | window = Foverlay_get (overlay, Qwindow); |
| 3089 | clone_number = Foverlay_get (overlay, Qclone_number); | 3083 | if (WINDOWP (window) && XWINDOW (window) != w) |
| 3090 | if (WINDOWP (window) && XWINDOW (window) != w | ||
| 3091 | && (! NUMBERP (clone_number) | ||
| 3092 | || XFASTINT (clone_number) != XFASTINT (w->clone_number))) | ||
| 3093 | continue; | 3084 | continue; |
| 3094 | if (startpos == pos | 3085 | if (startpos == pos |
| 3095 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) | 3086 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) |
| @@ -4066,7 +4057,8 @@ DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0, | |||
| 4066 | } | 4057 | } |
| 4067 | 4058 | ||
| 4068 | DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0, | 4059 | DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0, |
| 4069 | doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE. */) | 4060 | doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE. |
| 4061 | VALUE will be returned.*/) | ||
| 4070 | (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value) | 4062 | (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value) |
| 4071 | { | 4063 | { |
| 4072 | Lisp_Object tail, buffer; | 4064 | Lisp_Object tail, buffer; |
| @@ -4475,24 +4467,40 @@ static int mmap_initialized_p; | |||
| 4475 | #define MMAP_ALLOCATED_P(start, end) 1 | 4467 | #define MMAP_ALLOCATED_P(start, end) 1 |
| 4476 | #endif | 4468 | #endif |
| 4477 | 4469 | ||
| 4478 | /* Function prototypes. */ | 4470 | /* Perform necessary intializations for the use of mmap. */ |
| 4479 | 4471 | ||
| 4480 | static int mmap_free_1 (struct mmap_region *); | 4472 | static void |
| 4481 | static int mmap_enlarge (struct mmap_region *, int); | 4473 | mmap_init (void) |
| 4482 | static struct mmap_region *mmap_find (POINTER_TYPE *, POINTER_TYPE *); | 4474 | { |
| 4483 | static POINTER_TYPE *mmap_alloc (POINTER_TYPE **, size_t); | 4475 | #if MAP_ANON == 0 |
| 4484 | static POINTER_TYPE *mmap_realloc (POINTER_TYPE **, size_t); | 4476 | /* The value of mmap_fd is initially 0 in temacs, and -1 |
| 4485 | static void mmap_free (POINTER_TYPE **ptr); | 4477 | in a dumped Emacs. */ |
| 4486 | static void mmap_init (void); | 4478 | if (mmap_fd <= 0) |
| 4479 | { | ||
| 4480 | /* No anonymous mmap -- we need the file descriptor. */ | ||
| 4481 | mmap_fd = open ("/dev/zero", O_RDONLY); | ||
| 4482 | if (mmap_fd == -1) | ||
| 4483 | fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); | ||
| 4484 | } | ||
| 4485 | #endif /* MAP_ANON == 0 */ | ||
| 4487 | 4486 | ||
| 4487 | if (mmap_initialized_p) | ||
| 4488 | return; | ||
| 4489 | mmap_initialized_p = 1; | ||
| 4490 | |||
| 4491 | #if MAP_ANON != 0 | ||
| 4492 | mmap_fd = -1; | ||
| 4493 | #endif | ||
| 4494 | |||
| 4495 | mmap_page_size = getpagesize (); | ||
| 4496 | } | ||
| 4488 | 4497 | ||
| 4489 | /* Return a region overlapping address range START...END, or null if | 4498 | /* Return a region overlapping address range START...END, or null if |
| 4490 | none. END is not including, i.e. the last byte in the range | 4499 | none. END is not including, i.e. the last byte in the range |
| 4491 | is at END - 1. */ | 4500 | is at END - 1. */ |
| 4492 | 4501 | ||
| 4493 | static struct mmap_region * | 4502 | static struct mmap_region * |
| 4494 | mmap_find (start, end) | 4503 | mmap_find (POINTER_TYPE *start, POINTER_TYPE *end) |
| 4495 | POINTER_TYPE *start, *end; | ||
| 4496 | { | 4504 | { |
| 4497 | struct mmap_region *r; | 4505 | struct mmap_region *r; |
| 4498 | char *s = (char *) start, *e = (char *) end; | 4506 | char *s = (char *) start, *e = (char *) end; |
| @@ -4521,8 +4529,7 @@ mmap_find (start, end) | |||
| 4521 | the region. Value is non-zero if successful. */ | 4529 | the region. Value is non-zero if successful. */ |
| 4522 | 4530 | ||
| 4523 | static int | 4531 | static int |
| 4524 | mmap_free_1 (r) | 4532 | mmap_free_1 (struct mmap_region *r) |
| 4525 | struct mmap_region *r; | ||
| 4526 | { | 4533 | { |
| 4527 | if (r->next) | 4534 | if (r->next) |
| 4528 | r->next->prev = r->prev; | 4535 | r->next->prev = r->prev; |
| @@ -4545,9 +4552,7 @@ mmap_free_1 (r) | |||
| 4545 | Value is non-zero if successful. */ | 4552 | Value is non-zero if successful. */ |
| 4546 | 4553 | ||
| 4547 | static int | 4554 | static int |
| 4548 | mmap_enlarge (r, npages) | 4555 | mmap_enlarge (struct mmap_region *r, int npages) |
| 4549 | struct mmap_region *r; | ||
| 4550 | int npages; | ||
| 4551 | { | 4556 | { |
| 4552 | char *region_end = (char *) r + r->nbytes_mapped; | 4557 | char *region_end = (char *) r + r->nbytes_mapped; |
| 4553 | size_t nbytes; | 4558 | size_t nbytes; |
| @@ -4611,8 +4616,7 @@ mmap_enlarge (r, npages) | |||
| 4611 | when Emacs starts. */ | 4616 | when Emacs starts. */ |
| 4612 | 4617 | ||
| 4613 | void | 4618 | void |
| 4614 | mmap_set_vars (restore_p) | 4619 | mmap_set_vars (int restore_p) |
| 4615 | int restore_p; | ||
| 4616 | { | 4620 | { |
| 4617 | struct mmap_region *r; | 4621 | struct mmap_region *r; |
| 4618 | 4622 | ||
| @@ -4645,9 +4649,7 @@ mmap_set_vars (restore_p) | |||
| 4645 | return null. */ | 4649 | return null. */ |
| 4646 | 4650 | ||
| 4647 | static POINTER_TYPE * | 4651 | static POINTER_TYPE * |
| 4648 | mmap_alloc (var, nbytes) | 4652 | mmap_alloc (POINTER_TYPE **var, size_t nbytes) |
| 4649 | POINTER_TYPE **var; | ||
| 4650 | size_t nbytes; | ||
| 4651 | { | 4653 | { |
| 4652 | void *p; | 4654 | void *p; |
| 4653 | size_t map; | 4655 | size_t map; |
| @@ -4684,15 +4686,29 @@ mmap_alloc (var, nbytes) | |||
| 4684 | } | 4686 | } |
| 4685 | 4687 | ||
| 4686 | 4688 | ||
| 4689 | /* Free a block of relocatable storage whose data is pointed to by | ||
| 4690 | PTR. Store 0 in *PTR to show there's no block allocated. */ | ||
| 4691 | |||
| 4692 | static void | ||
| 4693 | mmap_free (POINTER_TYPE **var) | ||
| 4694 | { | ||
| 4695 | mmap_init (); | ||
| 4696 | |||
| 4697 | if (*var) | ||
| 4698 | { | ||
| 4699 | mmap_free_1 (MMAP_REGION (*var)); | ||
| 4700 | *var = NULL; | ||
| 4701 | } | ||
| 4702 | } | ||
| 4703 | |||
| 4704 | |||
| 4687 | /* Given a pointer at address VAR to data allocated with mmap_alloc, | 4705 | /* Given a pointer at address VAR to data allocated with mmap_alloc, |
| 4688 | resize it to size NBYTES. Change *VAR to reflect the new block, | 4706 | resize it to size NBYTES. Change *VAR to reflect the new block, |
| 4689 | and return this value. If more memory cannot be allocated, then | 4707 | and return this value. If more memory cannot be allocated, then |
| 4690 | leave *VAR unchanged, and return null. */ | 4708 | leave *VAR unchanged, and return null. */ |
| 4691 | 4709 | ||
| 4692 | static POINTER_TYPE * | 4710 | static POINTER_TYPE * |
| 4693 | mmap_realloc (var, nbytes) | 4711 | mmap_realloc (POINTER_TYPE **var, size_t nbytes) |
| 4694 | POINTER_TYPE **var; | ||
| 4695 | size_t nbytes; | ||
| 4696 | { | 4712 | { |
| 4697 | POINTER_TYPE *result; | 4713 | POINTER_TYPE *result; |
| 4698 | 4714 | ||
| @@ -4762,51 +4778,6 @@ mmap_realloc (var, nbytes) | |||
| 4762 | } | 4778 | } |
| 4763 | 4779 | ||
| 4764 | 4780 | ||
| 4765 | /* Free a block of relocatable storage whose data is pointed to by | ||
| 4766 | PTR. Store 0 in *PTR to show there's no block allocated. */ | ||
| 4767 | |||
| 4768 | static void | ||
| 4769 | mmap_free (var) | ||
| 4770 | POINTER_TYPE **var; | ||
| 4771 | { | ||
| 4772 | mmap_init (); | ||
| 4773 | |||
| 4774 | if (*var) | ||
| 4775 | { | ||
| 4776 | mmap_free_1 (MMAP_REGION (*var)); | ||
| 4777 | *var = NULL; | ||
| 4778 | } | ||
| 4779 | } | ||
| 4780 | |||
| 4781 | |||
| 4782 | /* Perform necessary intializations for the use of mmap. */ | ||
| 4783 | |||
| 4784 | static void | ||
| 4785 | mmap_init () | ||
| 4786 | { | ||
| 4787 | #if MAP_ANON == 0 | ||
| 4788 | /* The value of mmap_fd is initially 0 in temacs, and -1 | ||
| 4789 | in a dumped Emacs. */ | ||
| 4790 | if (mmap_fd <= 0) | ||
| 4791 | { | ||
| 4792 | /* No anonymous mmap -- we need the file descriptor. */ | ||
| 4793 | mmap_fd = open ("/dev/zero", O_RDONLY); | ||
| 4794 | if (mmap_fd == -1) | ||
| 4795 | fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); | ||
| 4796 | } | ||
| 4797 | #endif /* MAP_ANON == 0 */ | ||
| 4798 | |||
| 4799 | if (mmap_initialized_p) | ||
| 4800 | return; | ||
| 4801 | mmap_initialized_p = 1; | ||
| 4802 | |||
| 4803 | #if MAP_ANON != 0 | ||
| 4804 | mmap_fd = -1; | ||
| 4805 | #endif | ||
| 4806 | |||
| 4807 | mmap_page_size = getpagesize (); | ||
| 4808 | } | ||
| 4809 | |||
| 4810 | #endif /* USE_MMAP_FOR_BUFFERS */ | 4781 | #endif /* USE_MMAP_FOR_BUFFERS */ |
| 4811 | 4782 | ||
| 4812 | 4783 | ||
| @@ -5229,7 +5200,6 @@ syms_of_buffer (void) | |||
| 5229 | DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks"); | 5200 | DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks"); |
| 5230 | DEFSYM (Qget_file_buffer, "get-file-buffer"); | 5201 | DEFSYM (Qget_file_buffer, "get-file-buffer"); |
| 5231 | DEFSYM (Qpriority, "priority"); | 5202 | DEFSYM (Qpriority, "priority"); |
| 5232 | DEFSYM (Qclone_number, "clone-number"); | ||
| 5233 | DEFSYM (Qbefore_string, "before-string"); | 5203 | DEFSYM (Qbefore_string, "before-string"); |
| 5234 | DEFSYM (Qafter_string, "after-string"); | 5204 | DEFSYM (Qafter_string, "after-string"); |
| 5235 | DEFSYM (Qfirst_change_hook, "first-change-hook"); | 5205 | DEFSYM (Qfirst_change_hook, "first-change-hook"); |
diff --git a/src/buffer.h b/src/buffer.h index 4643e0d9d0e..06864dd5789 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -612,6 +612,7 @@ struct buffer | |||
| 612 | /* Everything from here down must be a Lisp_Object. */ | 612 | /* Everything from here down must be a Lisp_Object. */ |
| 613 | /* buffer-local Lisp variables start at `undo_list', | 613 | /* buffer-local Lisp variables start at `undo_list', |
| 614 | tho only the ones from `name' on are GC'd normally. */ | 614 | tho only the ones from `name' on are GC'd normally. */ |
| 615 | #define FIRST_FIELD_PER_BUFFER undo_list | ||
| 615 | 616 | ||
| 616 | /* Changes in the buffer are recorded here for undo. | 617 | /* Changes in the buffer are recorded here for undo. |
| 617 | t means don't record anything. | 618 | t means don't record anything. |
| @@ -846,6 +847,9 @@ struct buffer | |||
| 846 | t means to use hollow box cursor. | 847 | t means to use hollow box cursor. |
| 847 | See `cursor-type' for other values. */ | 848 | See `cursor-type' for other values. */ |
| 848 | Lisp_Object BUFFER_INTERNAL_FIELD (cursor_in_non_selected_windows); | 849 | Lisp_Object BUFFER_INTERNAL_FIELD (cursor_in_non_selected_windows); |
| 850 | |||
| 851 | /* This must be the last field in the above list. */ | ||
| 852 | #define LAST_FIELD_PER_BUFFER cursor_in_non_selected_windows | ||
| 849 | }; | 853 | }; |
| 850 | 854 | ||
| 851 | 855 | ||
diff --git a/src/callint.c b/src/callint.c index 4d0a2a07921..26b161a25b3 100644 --- a/src/callint.c +++ b/src/callint.c | |||
| @@ -105,9 +105,10 @@ Z -- Coding system, nil if no prefix arg. | |||
| 105 | 105 | ||
| 106 | In addition, if the string begins with `*', an error is signaled if | 106 | In addition, if the string begins with `*', an error is signaled if |
| 107 | the buffer is read-only. | 107 | the buffer is read-only. |
| 108 | If the string begins with `@', Emacs searches the key sequence which | 108 | If `@' appears at the beginning of the string, and if the key sequence |
| 109 | invoked the command for its first mouse click (or any other event | 109 | used to invoke the command includes any mouse events, then the window |
| 110 | which specifies a window). | 110 | associated with the first of those events is selected before the |
| 111 | command is run. | ||
| 111 | If the string begins with `^' and `shift-select-mode' is non-nil, | 112 | If the string begins with `^' and `shift-select-mode' is non-nil, |
| 112 | Emacs first calls the function `handle-shift-selection'. | 113 | Emacs first calls the function `handle-shift-selection'. |
| 113 | You may use `@', `*', and `^' together. They are processed in the | 114 | You may use `@', `*', and `^' together. They are processed in the |
| @@ -233,7 +234,7 @@ fix_command (Lisp_Object input, Lisp_Object values) | |||
| 233 | } | 234 | } |
| 234 | 235 | ||
| 235 | DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0, | 236 | DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0, |
| 236 | doc: /* Call FUNCTION, reading args according to its interactive calling specs. | 237 | doc: /* Call FUNCTION, providing args according to its interactive calling specs. |
| 237 | Return the value FUNCTION returns. | 238 | Return the value FUNCTION returns. |
| 238 | The function contains a specification of how to do the argument reading. | 239 | The function contains a specification of how to do the argument reading. |
| 239 | In the case of user-defined functions, this is specified by placing a call | 240 | In the case of user-defined functions, this is specified by placing a call |
diff --git a/src/callproc.c b/src/callproc.c index b339f343f62..ad3eddbdd39 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -596,7 +596,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 596 | sigemptyset (&blocked); | 596 | sigemptyset (&blocked); |
| 597 | sigaddset (&blocked, SIGPIPE); | 597 | sigaddset (&blocked, SIGPIPE); |
| 598 | sigaction (SIGPIPE, 0, &sigpipe_action); | 598 | sigaction (SIGPIPE, 0, &sigpipe_action); |
| 599 | sigprocmask (SIG_BLOCK, &blocked, &procmask); | 599 | pthread_sigmask (SIG_BLOCK, &blocked, &procmask); |
| 600 | #endif | 600 | #endif |
| 601 | 601 | ||
| 602 | BLOCK_INPUT; | 602 | BLOCK_INPUT; |
| @@ -633,7 +633,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 633 | in the child. */ | 633 | in the child. */ |
| 634 | //signal (SIGPIPE, SIG_DFL); | 634 | //signal (SIGPIPE, SIG_DFL); |
| 635 | #ifdef HAVE_WORKING_VFORK | 635 | #ifdef HAVE_WORKING_VFORK |
| 636 | sigprocmask (SIG_SETMASK, &procmask, 0); | 636 | pthread_sigmask (SIG_SETMASK, &procmask, 0); |
| 637 | #endif | 637 | #endif |
| 638 | 638 | ||
| 639 | child_setup (filefd, fd1, fd_error, (char **) new_argv, | 639 | child_setup (filefd, fd1, fd_error, (char **) new_argv, |
| @@ -645,7 +645,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 645 | #ifdef HAVE_WORKING_VFORK | 645 | #ifdef HAVE_WORKING_VFORK |
| 646 | /* Restore the signal state. */ | 646 | /* Restore the signal state. */ |
| 647 | sigaction (SIGPIPE, &sigpipe_action, 0); | 647 | sigaction (SIGPIPE, &sigpipe_action, 0); |
| 648 | sigprocmask (SIG_SETMASK, &procmask, 0); | 648 | pthread_sigmask (SIG_SETMASK, &procmask, 0); |
| 649 | #endif | 649 | #endif |
| 650 | 650 | ||
| 651 | #endif /* not WINDOWSNT */ | 651 | #endif /* not WINDOWSNT */ |
diff --git a/src/character.c b/src/character.c index 7fc5d647ff5..8e9b3e3775e 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -258,7 +258,8 @@ multibyte_char_to_unibyte_safe (int c) | |||
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 2, 0, | 260 | DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 2, 0, |
| 261 | doc: /* Return non-nil if OBJECT is a character. */) | 261 | doc: /* Return non-nil if OBJECT is a character. |
| 262 | usage: (characterp OBJECT) */) | ||
| 262 | (Lisp_Object object, Lisp_Object ignore) | 263 | (Lisp_Object object, Lisp_Object ignore) |
| 263 | { | 264 | { |
| 264 | return (CHARACTERP (object) ? Qt : Qnil); | 265 | return (CHARACTERP (object) ? Qt : Qnil); |
diff --git a/src/character.h b/src/character.h index 3bc21ac0f2b..063b5147dc9 100644 --- a/src/character.h +++ b/src/character.h | |||
| @@ -597,6 +597,45 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 597 | : (c) <= 0xDFFF ? 2 \ | 597 | : (c) <= 0xDFFF ? 2 \ |
| 598 | : 0) | 598 | : 0) |
| 599 | 599 | ||
| 600 | /* Data type for Unicode general category. | ||
| 601 | |||
| 602 | The order of members must be in sync with the 8th element of the | ||
| 603 | member of unidata-prop-alist (in admin/unidata/unidata-getn.el) for | ||
| 604 | Unicode character property `general-category'. */ | ||
| 605 | |||
| 606 | typedef enum { | ||
| 607 | UNICODE_CATEGORY_UNKNOWN = 0, | ||
| 608 | UNICODE_CATEGORY_Lu, | ||
| 609 | UNICODE_CATEGORY_Ll, | ||
| 610 | UNICODE_CATEGORY_Lt, | ||
| 611 | UNICODE_CATEGORY_Lm, | ||
| 612 | UNICODE_CATEGORY_Lo, | ||
| 613 | UNICODE_CATEGORY_Mn, | ||
| 614 | UNICODE_CATEGORY_Mc, | ||
| 615 | UNICODE_CATEGORY_Me, | ||
| 616 | UNICODE_CATEGORY_Nd, | ||
| 617 | UNICODE_CATEGORY_Nl, | ||
| 618 | UNICODE_CATEGORY_No, | ||
| 619 | UNICODE_CATEGORY_Pc, | ||
| 620 | UNICODE_CATEGORY_Pd, | ||
| 621 | UNICODE_CATEGORY_Ps, | ||
| 622 | UNICODE_CATEGORY_Pe, | ||
| 623 | UNICODE_CATEGORY_Pi, | ||
| 624 | UNICODE_CATEGORY_Pf, | ||
| 625 | UNICODE_CATEGORY_Po, | ||
| 626 | UNICODE_CATEGORY_Sm, | ||
| 627 | UNICODE_CATEGORY_Sc, | ||
| 628 | UNICODE_CATEGORY_Sk, | ||
| 629 | UNICODE_CATEGORY_So, | ||
| 630 | UNICODE_CATEGORY_Zs, | ||
| 631 | UNICODE_CATEGORY_Zl, | ||
| 632 | UNICODE_CATEGORY_Zp, | ||
| 633 | UNICODE_CATEGORY_Cc, | ||
| 634 | UNICODE_CATEGORY_Cf, | ||
| 635 | UNICODE_CATEGORY_Cs, | ||
| 636 | UNICODE_CATEGORY_Co, | ||
| 637 | UNICODE_CATEGORY_Cn | ||
| 638 | } unicode_category_t; | ||
| 600 | 639 | ||
| 601 | extern int char_resolve_modifier_mask (int); | 640 | extern int char_resolve_modifier_mask (int); |
| 602 | extern int char_string (unsigned, unsigned char *); | 641 | extern int char_string (unsigned, unsigned char *); |
diff --git a/src/chartab.c b/src/chartab.c index ed5b238646e..efe23eca83f 100644 --- a/src/chartab.c +++ b/src/chartab.c | |||
| @@ -53,7 +53,38 @@ static const int chartab_bits[4] = | |||
| 53 | #define CHARTAB_IDX(c, depth, min_char) \ | 53 | #define CHARTAB_IDX(c, depth, min_char) \ |
| 54 | (((c) - (min_char)) >> chartab_bits[(depth)]) | 54 | (((c) - (min_char)) >> chartab_bits[(depth)]) |
| 55 | 55 | ||
| 56 | |||
| 57 | /* Preamble for uniprop (Unicode character property) tables. See the | ||
| 58 | comment of "Unicode character property tables". */ | ||
| 59 | |||
| 60 | /* Purpose of uniprop tables. */ | ||
| 61 | static Lisp_Object Qchar_code_property_table; | ||
| 62 | |||
| 63 | /* Types of decoder and encoder functions for uniprop values. */ | ||
| 64 | typedef Lisp_Object (*uniprop_decoder_t) (Lisp_Object, Lisp_Object); | ||
| 65 | typedef Lisp_Object (*uniprop_encoder_t) (Lisp_Object, Lisp_Object); | ||
| 66 | |||
| 67 | static Lisp_Object uniprop_table_uncompress (Lisp_Object, int); | ||
| 68 | static uniprop_decoder_t uniprop_get_decoder (Lisp_Object); | ||
| 69 | |||
| 70 | /* 1 iff TABLE is a uniprop table. */ | ||
| 71 | #define UNIPROP_TABLE_P(TABLE) \ | ||
| 72 | (EQ (XCHAR_TABLE (TABLE)->purpose, Qchar_code_property_table) \ | ||
| 73 | && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (TABLE)) == 5) | ||
| 56 | 74 | ||
| 75 | /* Return a decoder for values in the uniprop table TABLE. */ | ||
| 76 | #define UNIPROP_GET_DECODER(TABLE) \ | ||
| 77 | (UNIPROP_TABLE_P (TABLE) ? uniprop_get_decoder (TABLE) : NULL) | ||
| 78 | |||
| 79 | /* Nonzero iff OBJ is a string representing uniprop values of 128 | ||
| 80 | succeeding characters (the bottom level of a char-table) by a | ||
| 81 | compressed format. We are sure that no property value has a string | ||
| 82 | starting with '\001' nor '\002'. */ | ||
| 83 | #define UNIPROP_COMPRESSED_FORM_P(OBJ) \ | ||
| 84 | (STRINGP (OBJ) && SCHARS (OBJ) > 0 \ | ||
| 85 | && ((SREF (OBJ, 0) == 1 || (SREF (OBJ, 0) == 2)))) | ||
| 86 | |||
| 87 | |||
| 57 | DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0, | 88 | DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0, |
| 58 | doc: /* Return a newly created char-table, with purpose PURPOSE. | 89 | doc: /* Return a newly created char-table, with purpose PURPOSE. |
| 59 | Each element is initialized to INIT, which defaults to nil. | 90 | Each element is initialized to INIT, which defaults to nil. |
| @@ -107,7 +138,7 @@ make_sub_char_table (int depth, int min_char, Lisp_Object defalt) | |||
| 107 | static Lisp_Object | 138 | static Lisp_Object |
| 108 | char_table_ascii (Lisp_Object table) | 139 | char_table_ascii (Lisp_Object table) |
| 109 | { | 140 | { |
| 110 | Lisp_Object sub; | 141 | Lisp_Object sub, val; |
| 111 | 142 | ||
| 112 | sub = XCHAR_TABLE (table)->contents[0]; | 143 | sub = XCHAR_TABLE (table)->contents[0]; |
| 113 | if (! SUB_CHAR_TABLE_P (sub)) | 144 | if (! SUB_CHAR_TABLE_P (sub)) |
| @@ -115,7 +146,10 @@ char_table_ascii (Lisp_Object table) | |||
| 115 | sub = XSUB_CHAR_TABLE (sub)->contents[0]; | 146 | sub = XSUB_CHAR_TABLE (sub)->contents[0]; |
| 116 | if (! SUB_CHAR_TABLE_P (sub)) | 147 | if (! SUB_CHAR_TABLE_P (sub)) |
| 117 | return sub; | 148 | return sub; |
| 118 | return XSUB_CHAR_TABLE (sub)->contents[0]; | 149 | val = XSUB_CHAR_TABLE (sub)->contents[0]; |
| 150 | if (UNIPROP_TABLE_P (table) && UNIPROP_COMPRESSED_FORM_P (val)) | ||
| 151 | val = uniprop_table_uncompress (sub, 0); | ||
| 152 | return val; | ||
| 119 | } | 153 | } |
| 120 | 154 | ||
| 121 | static Lisp_Object | 155 | static Lisp_Object |
| @@ -169,16 +203,19 @@ copy_char_table (Lisp_Object table) | |||
| 169 | } | 203 | } |
| 170 | 204 | ||
| 171 | static Lisp_Object | 205 | static Lisp_Object |
| 172 | sub_char_table_ref (Lisp_Object table, int c) | 206 | sub_char_table_ref (Lisp_Object table, int c, int is_uniprop) |
| 173 | { | 207 | { |
| 174 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); | 208 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); |
| 175 | int depth = XINT (tbl->depth); | 209 | int depth = XINT (tbl->depth); |
| 176 | int min_char = XINT (tbl->min_char); | 210 | int min_char = XINT (tbl->min_char); |
| 177 | Lisp_Object val; | 211 | Lisp_Object val; |
| 212 | int idx = CHARTAB_IDX (c, depth, min_char); | ||
| 178 | 213 | ||
| 179 | val = tbl->contents[CHARTAB_IDX (c, depth, min_char)]; | 214 | val = tbl->contents[idx]; |
| 215 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val)) | ||
| 216 | val = uniprop_table_uncompress (table, idx); | ||
| 180 | if (SUB_CHAR_TABLE_P (val)) | 217 | if (SUB_CHAR_TABLE_P (val)) |
| 181 | val = sub_char_table_ref (val, c); | 218 | val = sub_char_table_ref (val, c, is_uniprop); |
| 182 | return val; | 219 | return val; |
| 183 | } | 220 | } |
| 184 | 221 | ||
| @@ -198,7 +235,7 @@ char_table_ref (Lisp_Object table, int c) | |||
| 198 | { | 235 | { |
| 199 | val = tbl->contents[CHARTAB_IDX (c, 0, 0)]; | 236 | val = tbl->contents[CHARTAB_IDX (c, 0, 0)]; |
| 200 | if (SUB_CHAR_TABLE_P (val)) | 237 | if (SUB_CHAR_TABLE_P (val)) |
| 201 | val = sub_char_table_ref (val, c); | 238 | val = sub_char_table_ref (val, c, UNIPROP_TABLE_P (table)); |
| 202 | } | 239 | } |
| 203 | if (NILP (val)) | 240 | if (NILP (val)) |
| 204 | { | 241 | { |
| @@ -210,7 +247,8 @@ char_table_ref (Lisp_Object table, int c) | |||
| 210 | } | 247 | } |
| 211 | 248 | ||
| 212 | static Lisp_Object | 249 | static Lisp_Object |
| 213 | sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp_Object defalt) | 250 | sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, |
| 251 | Lisp_Object defalt, int is_uniprop) | ||
| 214 | { | 252 | { |
| 215 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); | 253 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); |
| 216 | int depth = XINT (tbl->depth); | 254 | int depth = XINT (tbl->depth); |
| @@ -219,8 +257,10 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp | |||
| 219 | Lisp_Object val; | 257 | Lisp_Object val; |
| 220 | 258 | ||
| 221 | val = tbl->contents[chartab_idx]; | 259 | val = tbl->contents[chartab_idx]; |
| 260 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val)) | ||
| 261 | val = uniprop_table_uncompress (table, chartab_idx); | ||
| 222 | if (SUB_CHAR_TABLE_P (val)) | 262 | if (SUB_CHAR_TABLE_P (val)) |
| 223 | val = sub_char_table_ref_and_range (val, c, from, to, defalt); | 263 | val = sub_char_table_ref_and_range (val, c, from, to, defalt, is_uniprop); |
| 224 | else if (NILP (val)) | 264 | else if (NILP (val)) |
| 225 | val = defalt; | 265 | val = defalt; |
| 226 | 266 | ||
| @@ -232,8 +272,11 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp | |||
| 232 | c = min_char + idx * chartab_chars[depth] - 1; | 272 | c = min_char + idx * chartab_chars[depth] - 1; |
| 233 | idx--; | 273 | idx--; |
| 234 | this_val = tbl->contents[idx]; | 274 | this_val = tbl->contents[idx]; |
| 275 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | ||
| 276 | this_val = uniprop_table_uncompress (table, idx); | ||
| 235 | if (SUB_CHAR_TABLE_P (this_val)) | 277 | if (SUB_CHAR_TABLE_P (this_val)) |
| 236 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt); | 278 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt, |
| 279 | is_uniprop); | ||
| 237 | else if (NILP (this_val)) | 280 | else if (NILP (this_val)) |
| 238 | this_val = defalt; | 281 | this_val = defalt; |
| 239 | 282 | ||
| @@ -251,8 +294,11 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp | |||
| 251 | 294 | ||
| 252 | chartab_idx++; | 295 | chartab_idx++; |
| 253 | this_val = tbl->contents[chartab_idx]; | 296 | this_val = tbl->contents[chartab_idx]; |
| 297 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | ||
| 298 | this_val = uniprop_table_uncompress (table, chartab_idx); | ||
| 254 | if (SUB_CHAR_TABLE_P (this_val)) | 299 | if (SUB_CHAR_TABLE_P (this_val)) |
| 255 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt); | 300 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt, |
| 301 | is_uniprop); | ||
| 256 | else if (NILP (this_val)) | 302 | else if (NILP (this_val)) |
| 257 | this_val = defalt; | 303 | this_val = defalt; |
| 258 | if (! EQ (this_val, val)) | 304 | if (! EQ (this_val, val)) |
| @@ -277,17 +323,20 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to) | |||
| 277 | struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); | 323 | struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); |
| 278 | int chartab_idx = CHARTAB_IDX (c, 0, 0), idx; | 324 | int chartab_idx = CHARTAB_IDX (c, 0, 0), idx; |
| 279 | Lisp_Object val; | 325 | Lisp_Object val; |
| 326 | int is_uniprop = UNIPROP_TABLE_P (table); | ||
| 280 | 327 | ||
| 281 | val = tbl->contents[chartab_idx]; | 328 | val = tbl->contents[chartab_idx]; |
| 282 | if (*from < 0) | 329 | if (*from < 0) |
| 283 | *from = 0; | 330 | *from = 0; |
| 284 | if (*to < 0) | 331 | if (*to < 0) |
| 285 | *to = MAX_CHAR; | 332 | *to = MAX_CHAR; |
| 333 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val)) | ||
| 334 | val = uniprop_table_uncompress (table, chartab_idx); | ||
| 286 | if (SUB_CHAR_TABLE_P (val)) | 335 | if (SUB_CHAR_TABLE_P (val)) |
| 287 | val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt); | 336 | val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt, |
| 337 | is_uniprop); | ||
| 288 | else if (NILP (val)) | 338 | else if (NILP (val)) |
| 289 | val = tbl->defalt; | 339 | val = tbl->defalt; |
| 290 | |||
| 291 | idx = chartab_idx; | 340 | idx = chartab_idx; |
| 292 | while (*from < idx * chartab_chars[0]) | 341 | while (*from < idx * chartab_chars[0]) |
| 293 | { | 342 | { |
| @@ -296,9 +345,11 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to) | |||
| 296 | c = idx * chartab_chars[0] - 1; | 345 | c = idx * chartab_chars[0] - 1; |
| 297 | idx--; | 346 | idx--; |
| 298 | this_val = tbl->contents[idx]; | 347 | this_val = tbl->contents[idx]; |
| 348 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | ||
| 349 | this_val = uniprop_table_uncompress (table, idx); | ||
| 299 | if (SUB_CHAR_TABLE_P (this_val)) | 350 | if (SUB_CHAR_TABLE_P (this_val)) |
| 300 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, | 351 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, |
| 301 | tbl->defalt); | 352 | tbl->defalt, is_uniprop); |
| 302 | else if (NILP (this_val)) | 353 | else if (NILP (this_val)) |
| 303 | this_val = tbl->defalt; | 354 | this_val = tbl->defalt; |
| 304 | 355 | ||
| @@ -315,9 +366,11 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to) | |||
| 315 | chartab_idx++; | 366 | chartab_idx++; |
| 316 | c = chartab_idx * chartab_chars[0]; | 367 | c = chartab_idx * chartab_chars[0]; |
| 317 | this_val = tbl->contents[chartab_idx]; | 368 | this_val = tbl->contents[chartab_idx]; |
| 369 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val)) | ||
| 370 | this_val = uniprop_table_uncompress (table, chartab_idx); | ||
| 318 | if (SUB_CHAR_TABLE_P (this_val)) | 371 | if (SUB_CHAR_TABLE_P (this_val)) |
| 319 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, | 372 | this_val = sub_char_table_ref_and_range (this_val, c, from, to, |
| 320 | tbl->defalt); | 373 | tbl->defalt, is_uniprop); |
| 321 | else if (NILP (this_val)) | 374 | else if (NILP (this_val)) |
| 322 | this_val = tbl->defalt; | 375 | this_val = tbl->defalt; |
| 323 | if (! EQ (this_val, val)) | 376 | if (! EQ (this_val, val)) |
| @@ -332,7 +385,7 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to) | |||
| 332 | 385 | ||
| 333 | 386 | ||
| 334 | static void | 387 | static void |
| 335 | sub_char_table_set (Lisp_Object table, int c, Lisp_Object val) | 388 | sub_char_table_set (Lisp_Object table, int c, Lisp_Object val, int is_uniprop) |
| 336 | { | 389 | { |
| 337 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); | 390 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); |
| 338 | int depth = XINT ((tbl)->depth); | 391 | int depth = XINT ((tbl)->depth); |
| @@ -347,11 +400,17 @@ sub_char_table_set (Lisp_Object table, int c, Lisp_Object val) | |||
| 347 | sub = tbl->contents[i]; | 400 | sub = tbl->contents[i]; |
| 348 | if (! SUB_CHAR_TABLE_P (sub)) | 401 | if (! SUB_CHAR_TABLE_P (sub)) |
| 349 | { | 402 | { |
| 350 | sub = make_sub_char_table (depth + 1, | 403 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (sub)) |
| 351 | min_char + i * chartab_chars[depth], sub); | 404 | sub = uniprop_table_uncompress (table, i); |
| 352 | tbl->contents[i] = sub; | 405 | else |
| 406 | { | ||
| 407 | sub = make_sub_char_table (depth + 1, | ||
| 408 | min_char + i * chartab_chars[depth], | ||
| 409 | sub); | ||
| 410 | tbl->contents[i] = sub; | ||
| 411 | } | ||
| 353 | } | 412 | } |
| 354 | sub_char_table_set (sub, c, val); | 413 | sub_char_table_set (sub, c, val, is_uniprop); |
| 355 | } | 414 | } |
| 356 | } | 415 | } |
| 357 | 416 | ||
| @@ -376,7 +435,7 @@ char_table_set (Lisp_Object table, int c, Lisp_Object val) | |||
| 376 | sub = make_sub_char_table (1, i * chartab_chars[0], sub); | 435 | sub = make_sub_char_table (1, i * chartab_chars[0], sub); |
| 377 | tbl->contents[i] = sub; | 436 | tbl->contents[i] = sub; |
| 378 | } | 437 | } |
| 379 | sub_char_table_set (sub, c, val); | 438 | sub_char_table_set (sub, c, val, UNIPROP_TABLE_P (table)); |
| 380 | if (ASCII_CHAR_P (c)) | 439 | if (ASCII_CHAR_P (c)) |
| 381 | tbl->ascii = char_table_ascii (table); | 440 | tbl->ascii = char_table_ascii (table); |
| 382 | } | 441 | } |
| @@ -384,30 +443,40 @@ char_table_set (Lisp_Object table, int c, Lisp_Object val) | |||
| 384 | } | 443 | } |
| 385 | 444 | ||
| 386 | static void | 445 | static void |
| 387 | sub_char_table_set_range (Lisp_Object *table, int depth, int min_char, int from, int to, Lisp_Object val) | 446 | sub_char_table_set_range (Lisp_Object table, int from, int to, Lisp_Object val, |
| 447 | int is_uniprop) | ||
| 388 | { | 448 | { |
| 389 | int max_char = min_char + chartab_chars[depth] - 1; | 449 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); |
| 390 | 450 | int depth = XINT ((tbl)->depth); | |
| 391 | if (depth == 3 || (from <= min_char && to >= max_char)) | 451 | int min_char = XINT ((tbl)->min_char); |
| 392 | *table = val; | 452 | int chars_in_block = chartab_chars[depth]; |
| 393 | else | 453 | int i, c, lim = chartab_size[depth]; |
| 454 | |||
| 455 | if (from < min_char) | ||
| 456 | from = min_char; | ||
| 457 | i = CHARTAB_IDX (from, depth, min_char); | ||
| 458 | c = min_char + chars_in_block * i; | ||
| 459 | for (; i < lim; i++, c += chars_in_block) | ||
| 394 | { | 460 | { |
| 395 | int i; | 461 | if (c > to) |
| 396 | unsigned j; | 462 | break; |
| 397 | 463 | if (from <= c && c + chars_in_block - 1 <= to) | |
| 398 | depth++; | 464 | tbl->contents[i] = val; |
| 399 | if (! SUB_CHAR_TABLE_P (*table)) | 465 | else |
| 400 | *table = make_sub_char_table (depth, min_char, *table); | 466 | { |
| 401 | if (from < min_char) | 467 | Lisp_Object sub = tbl->contents[i]; |
| 402 | from = min_char; | 468 | if (! SUB_CHAR_TABLE_P (sub)) |
| 403 | if (to > max_char) | 469 | { |
| 404 | to = max_char; | 470 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (sub)) |
| 405 | i = CHARTAB_IDX (from, depth, min_char); | 471 | sub = uniprop_table_uncompress (table, i); |
| 406 | j = CHARTAB_IDX (to, depth, min_char); | 472 | else |
| 407 | min_char += chartab_chars[depth] * i; | 473 | { |
| 408 | for (j++; i < j; i++, min_char += chartab_chars[depth]) | 474 | sub = make_sub_char_table (depth + 1, c, sub); |
| 409 | sub_char_table_set_range (XSUB_CHAR_TABLE (*table)->contents + i, | 475 | tbl->contents[i] = sub; |
| 410 | depth, min_char, from, to, val); | 476 | } |
| 477 | } | ||
| 478 | sub_char_table_set_range (sub, from, to, val, is_uniprop); | ||
| 479 | } | ||
| 411 | } | 480 | } |
| 412 | } | 481 | } |
| 413 | 482 | ||
| @@ -416,17 +485,33 @@ Lisp_Object | |||
| 416 | char_table_set_range (Lisp_Object table, int from, int to, Lisp_Object val) | 485 | char_table_set_range (Lisp_Object table, int from, int to, Lisp_Object val) |
| 417 | { | 486 | { |
| 418 | struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); | 487 | struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); |
| 419 | Lisp_Object *contents = tbl->contents; | ||
| 420 | int i; | ||
| 421 | 488 | ||
| 422 | if (from == to) | 489 | if (from == to) |
| 423 | char_table_set (table, from, val); | 490 | char_table_set (table, from, val); |
| 424 | else | 491 | else |
| 425 | { | 492 | { |
| 426 | unsigned lim = to / chartab_chars[0] + 1; | 493 | int is_uniprop = UNIPROP_TABLE_P (table); |
| 427 | for (i = CHARTAB_IDX (from, 0, 0); i < lim; i++) | 494 | int lim = CHARTAB_IDX (to, 0, 0); |
| 428 | sub_char_table_set_range (contents + i, 0, i * chartab_chars[0], | 495 | int i, c; |
| 429 | from, to, val); | 496 | |
| 497 | for (i = CHARTAB_IDX (from, 0, 0), c = 0; i <= lim; | ||
| 498 | i++, c += chartab_chars[0]) | ||
| 499 | { | ||
| 500 | if (c > to) | ||
| 501 | break; | ||
| 502 | if (from <= c && c + chartab_chars[0] - 1 <= to) | ||
| 503 | tbl->contents[i] = val; | ||
| 504 | else | ||
| 505 | { | ||
| 506 | Lisp_Object sub = tbl->contents[i]; | ||
| 507 | if (! SUB_CHAR_TABLE_P (sub)) | ||
| 508 | { | ||
| 509 | sub = make_sub_char_table (1, i * chartab_chars[0], sub); | ||
| 510 | tbl->contents[i] = sub; | ||
| 511 | } | ||
| 512 | sub_char_table_set_range (sub, from, to, val, is_uniprop); | ||
| 513 | } | ||
| 514 | } | ||
| 430 | if (ASCII_CHAR_P (from)) | 515 | if (ASCII_CHAR_P (from)) |
| 431 | tbl->ascii = char_table_ascii (table); | 516 | tbl->ascii = char_table_ascii (table); |
| 432 | } | 517 | } |
| @@ -504,6 +589,8 @@ DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot, | |||
| 504 | (Lisp_Object char_table, Lisp_Object n, Lisp_Object value) | 589 | (Lisp_Object char_table, Lisp_Object n, Lisp_Object value) |
| 505 | { | 590 | { |
| 506 | CHECK_CHAR_TABLE (char_table); | 591 | CHECK_CHAR_TABLE (char_table); |
| 592 | if (EQ (XCHAR_TABLE (char_table)->purpose, Qchar_code_property_table)) | ||
| 593 | error ("Can't change extra-slot of char-code-property-table"); | ||
| 507 | CHECK_NUMBER (n); | 594 | CHECK_NUMBER (n); |
| 508 | if (XINT (n) < 0 | 595 | if (XINT (n) < 0 |
| 509 | || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table))) | 596 | || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table))) |
| @@ -532,8 +619,9 @@ a cons of character codes (for characters in the range), or a character code. * | |||
| 532 | 619 | ||
| 533 | CHECK_CHARACTER_CAR (range); | 620 | CHECK_CHARACTER_CAR (range); |
| 534 | CHECK_CHARACTER_CDR (range); | 621 | CHECK_CHARACTER_CDR (range); |
| 535 | val = char_table_ref_and_range (char_table, XFASTINT (XCAR (range)), | 622 | from = XFASTINT (XCAR (range)); |
| 536 | &from, &to); | 623 | to = XFASTINT (XCDR (range)); |
| 624 | val = char_table_ref_and_range (char_table, from, &from, &to); | ||
| 537 | /* Not yet implemented. */ | 625 | /* Not yet implemented. */ |
| 538 | } | 626 | } |
| 539 | else | 627 | else |
| @@ -655,8 +743,7 @@ equivalent and can be merged. It defaults to `equal'. */) | |||
| 655 | /* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table), | 743 | /* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table), |
| 656 | calling it for each character or group of characters that share a | 744 | calling it for each character or group of characters that share a |
| 657 | value. RANGE is a cons (FROM . TO) specifying the range of target | 745 | value. RANGE is a cons (FROM . TO) specifying the range of target |
| 658 | characters, VAL is a value of FROM in TABLE, DEFAULT_VAL is the | 746 | characters, VAL is a value of FROM in TABLE, TOP is the top |
| 659 | default value of the char-table, PARENT is the parent of the | ||
| 660 | char-table. | 747 | char-table. |
| 661 | 748 | ||
| 662 | ARG is passed to C_FUNCTION when that is called. | 749 | ARG is passed to C_FUNCTION when that is called. |
| @@ -669,10 +756,8 @@ equivalent and can be merged. It defaults to `equal'. */) | |||
| 669 | static Lisp_Object | 756 | static Lisp_Object |
| 670 | map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), | 757 | map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), |
| 671 | Lisp_Object function, Lisp_Object table, Lisp_Object arg, Lisp_Object val, | 758 | Lisp_Object function, Lisp_Object table, Lisp_Object arg, Lisp_Object val, |
| 672 | Lisp_Object range, Lisp_Object default_val, Lisp_Object parent) | 759 | Lisp_Object range, Lisp_Object top) |
| 673 | { | 760 | { |
| 674 | /* Pointer to the elements of TABLE. */ | ||
| 675 | Lisp_Object *contents; | ||
| 676 | /* Depth of TABLE. */ | 761 | /* Depth of TABLE. */ |
| 677 | int depth; | 762 | int depth; |
| 678 | /* Minimum and maxinum characters covered by TABLE. */ | 763 | /* Minimum and maxinum characters covered by TABLE. */ |
| @@ -681,20 +766,20 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), | |||
| 681 | int chars_in_block; | 766 | int chars_in_block; |
| 682 | int from = XINT (XCAR (range)), to = XINT (XCDR (range)); | 767 | int from = XINT (XCAR (range)), to = XINT (XCDR (range)); |
| 683 | int i, c; | 768 | int i, c; |
| 769 | int is_uniprop = UNIPROP_TABLE_P (top); | ||
| 770 | uniprop_decoder_t decoder = UNIPROP_GET_DECODER (top); | ||
| 684 | 771 | ||
| 685 | if (SUB_CHAR_TABLE_P (table)) | 772 | if (SUB_CHAR_TABLE_P (table)) |
| 686 | { | 773 | { |
| 687 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); | 774 | struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); |
| 688 | 775 | ||
| 689 | depth = XINT (tbl->depth); | 776 | depth = XINT (tbl->depth); |
| 690 | contents = tbl->contents; | ||
| 691 | min_char = XINT (tbl->min_char); | 777 | min_char = XINT (tbl->min_char); |
| 692 | max_char = min_char + chartab_chars[depth - 1] - 1; | 778 | max_char = min_char + chartab_chars[depth - 1] - 1; |
| 693 | } | 779 | } |
| 694 | else | 780 | else |
| 695 | { | 781 | { |
| 696 | depth = 0; | 782 | depth = 0; |
| 697 | contents = XCHAR_TABLE (table)->contents; | ||
| 698 | min_char = 0; | 783 | min_char = 0; |
| 699 | max_char = MAX_CHAR; | 784 | max_char = MAX_CHAR; |
| 700 | } | 785 | } |
| @@ -710,28 +795,33 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), | |||
| 710 | for (c = min_char + chars_in_block * i; c <= max_char; | 795 | for (c = min_char + chars_in_block * i; c <= max_char; |
| 711 | i++, c += chars_in_block) | 796 | i++, c += chars_in_block) |
| 712 | { | 797 | { |
| 713 | Lisp_Object this = contents[i]; | 798 | Lisp_Object this = (SUB_CHAR_TABLE_P (table) |
| 799 | ? XSUB_CHAR_TABLE (table)->contents[i] | ||
| 800 | : XCHAR_TABLE (table)->contents[i]); | ||
| 714 | int nextc = c + chars_in_block; | 801 | int nextc = c + chars_in_block; |
| 715 | 802 | ||
| 803 | if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this)) | ||
| 804 | this = uniprop_table_uncompress (table, i); | ||
| 716 | if (SUB_CHAR_TABLE_P (this)) | 805 | if (SUB_CHAR_TABLE_P (this)) |
| 717 | { | 806 | { |
| 718 | if (to >= nextc) | 807 | if (to >= nextc) |
| 719 | XSETCDR (range, make_number (nextc - 1)); | 808 | XSETCDR (range, make_number (nextc - 1)); |
| 720 | val = map_sub_char_table (c_function, function, this, arg, | 809 | val = map_sub_char_table (c_function, function, this, arg, |
| 721 | val, range, default_val, parent); | 810 | val, range, top); |
| 722 | } | 811 | } |
| 723 | else | 812 | else |
| 724 | { | 813 | { |
| 725 | if (NILP (this)) | 814 | if (NILP (this)) |
| 726 | this = default_val; | 815 | this = XCHAR_TABLE (top)->defalt; |
| 727 | if (!EQ (val, this)) | 816 | if (!EQ (val, this)) |
| 728 | { | 817 | { |
| 729 | int different_value = 1; | 818 | int different_value = 1; |
| 730 | 819 | ||
| 731 | if (NILP (val)) | 820 | if (NILP (val)) |
| 732 | { | 821 | { |
| 733 | if (! NILP (parent)) | 822 | if (! NILP (XCHAR_TABLE (top)->parent)) |
| 734 | { | 823 | { |
| 824 | Lisp_Object parent = XCHAR_TABLE (top)->parent; | ||
| 735 | Lisp_Object temp = XCHAR_TABLE (parent)->parent; | 825 | Lisp_Object temp = XCHAR_TABLE (parent)->parent; |
| 736 | 826 | ||
| 737 | /* This is to get a value of FROM in PARENT | 827 | /* This is to get a value of FROM in PARENT |
| @@ -742,8 +832,7 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), | |||
| 742 | XSETCDR (range, make_number (c - 1)); | 832 | XSETCDR (range, make_number (c - 1)); |
| 743 | val = map_sub_char_table (c_function, function, | 833 | val = map_sub_char_table (c_function, function, |
| 744 | parent, arg, val, range, | 834 | parent, arg, val, range, |
| 745 | XCHAR_TABLE (parent)->defalt, | 835 | parent); |
| 746 | XCHAR_TABLE (parent)->parent); | ||
| 747 | if (EQ (val, this)) | 836 | if (EQ (val, this)) |
| 748 | different_value = 0; | 837 | different_value = 0; |
| 749 | } | 838 | } |
| @@ -756,14 +845,22 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), | |||
| 756 | if (c_function) | 845 | if (c_function) |
| 757 | (*c_function) (arg, XCAR (range), val); | 846 | (*c_function) (arg, XCAR (range), val); |
| 758 | else | 847 | else |
| 759 | call2 (function, XCAR (range), val); | 848 | { |
| 849 | if (decoder) | ||
| 850 | val = decoder (top, val); | ||
| 851 | call2 (function, XCAR (range), val); | ||
| 852 | } | ||
| 760 | } | 853 | } |
| 761 | else | 854 | else |
| 762 | { | 855 | { |
| 763 | if (c_function) | 856 | if (c_function) |
| 764 | (*c_function) (arg, range, val); | 857 | (*c_function) (arg, range, val); |
| 765 | else | 858 | else |
| 766 | call2 (function, range, val); | 859 | { |
| 860 | if (decoder) | ||
| 861 | val = decoder (top, val); | ||
| 862 | call2 (function, range, val); | ||
| 863 | } | ||
| 767 | } | 864 | } |
| 768 | } | 865 | } |
| 769 | val = this; | 866 | val = this; |
| @@ -783,35 +880,39 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), | |||
| 783 | ARG is passed to C_FUNCTION when that is called. */ | 880 | ARG is passed to C_FUNCTION when that is called. */ |
| 784 | 881 | ||
| 785 | void | 882 | void |
| 786 | map_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object function, Lisp_Object table, Lisp_Object arg) | 883 | map_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), |
| 884 | Lisp_Object function, Lisp_Object table, Lisp_Object arg) | ||
| 787 | { | 885 | { |
| 788 | Lisp_Object range, val; | 886 | Lisp_Object range, val, parent; |
| 789 | struct gcpro gcpro1, gcpro2, gcpro3; | 887 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 888 | uniprop_decoder_t decoder = UNIPROP_GET_DECODER (table); | ||
| 790 | 889 | ||
| 791 | range = Fcons (make_number (0), make_number (MAX_CHAR)); | 890 | range = Fcons (make_number (0), make_number (MAX_CHAR)); |
| 792 | GCPRO3 (table, arg, range); | 891 | parent = XCHAR_TABLE (table)->parent; |
| 892 | |||
| 893 | GCPRO4 (table, arg, range, parent); | ||
| 793 | val = XCHAR_TABLE (table)->ascii; | 894 | val = XCHAR_TABLE (table)->ascii; |
| 794 | if (SUB_CHAR_TABLE_P (val)) | 895 | if (SUB_CHAR_TABLE_P (val)) |
| 795 | val = XSUB_CHAR_TABLE (val)->contents[0]; | 896 | val = XSUB_CHAR_TABLE (val)->contents[0]; |
| 796 | val = map_sub_char_table (c_function, function, table, arg, val, range, | 897 | val = map_sub_char_table (c_function, function, table, arg, val, range, |
| 797 | XCHAR_TABLE (table)->defalt, | 898 | table); |
| 798 | XCHAR_TABLE (table)->parent); | 899 | |
| 799 | /* If VAL is nil and TABLE has a parent, we must consult the parent | 900 | /* If VAL is nil and TABLE has a parent, we must consult the parent |
| 800 | recursively. */ | 901 | recursively. */ |
| 801 | while (NILP (val) && ! NILP (XCHAR_TABLE (table)->parent)) | 902 | while (NILP (val) && ! NILP (XCHAR_TABLE (table)->parent)) |
| 802 | { | 903 | { |
| 803 | Lisp_Object parent = XCHAR_TABLE (table)->parent; | 904 | Lisp_Object temp; |
| 804 | Lisp_Object temp = XCHAR_TABLE (parent)->parent; | ||
| 805 | int from = XINT (XCAR (range)); | 905 | int from = XINT (XCAR (range)); |
| 806 | 906 | ||
| 907 | parent = XCHAR_TABLE (table)->parent; | ||
| 908 | temp = XCHAR_TABLE (parent)->parent; | ||
| 807 | /* This is to get a value of FROM in PARENT without checking the | 909 | /* This is to get a value of FROM in PARENT without checking the |
| 808 | parent of PARENT. */ | 910 | parent of PARENT. */ |
| 809 | XCHAR_TABLE (parent)->parent = Qnil; | 911 | XCHAR_TABLE (parent)->parent = Qnil; |
| 810 | val = CHAR_TABLE_REF (parent, from); | 912 | val = CHAR_TABLE_REF (parent, from); |
| 811 | XCHAR_TABLE (parent)->parent = temp; | 913 | XCHAR_TABLE (parent)->parent = temp; |
| 812 | val = map_sub_char_table (c_function, function, parent, arg, val, range, | 914 | val = map_sub_char_table (c_function, function, parent, arg, val, range, |
| 813 | XCHAR_TABLE (parent)->defalt, | 915 | parent); |
| 814 | XCHAR_TABLE (parent)->parent); | ||
| 815 | table = parent; | 916 | table = parent; |
| 816 | } | 917 | } |
| 817 | 918 | ||
| @@ -822,14 +923,22 @@ map_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp | |||
| 822 | if (c_function) | 923 | if (c_function) |
| 823 | (*c_function) (arg, XCAR (range), val); | 924 | (*c_function) (arg, XCAR (range), val); |
| 824 | else | 925 | else |
| 825 | call2 (function, XCAR (range), val); | 926 | { |
| 927 | if (decoder) | ||
| 928 | val = decoder (table, val); | ||
| 929 | call2 (function, XCAR (range), val); | ||
| 930 | } | ||
| 826 | } | 931 | } |
| 827 | else | 932 | else |
| 828 | { | 933 | { |
| 829 | if (c_function) | 934 | if (c_function) |
| 830 | (*c_function) (arg, range, val); | 935 | (*c_function) (arg, range, val); |
| 831 | else | 936 | else |
| 832 | call2 (function, range, val); | 937 | { |
| 938 | if (decoder) | ||
| 939 | val = decoder (table, val); | ||
| 940 | call2 (function, range, val); | ||
| 941 | } | ||
| 833 | } | 942 | } |
| 834 | } | 943 | } |
| 835 | 944 | ||
| @@ -984,9 +1093,314 @@ map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object), | |||
| 984 | } | 1093 | } |
| 985 | 1094 | ||
| 986 | 1095 | ||
| 1096 | /* Unicode character property tables. | ||
| 1097 | |||
| 1098 | This section provides a convenient and efficient way to get a | ||
| 1099 | Unicode character property from C code (from Lisp, you must use | ||
| 1100 | get-char-code-property). | ||
| 1101 | |||
| 1102 | The typical usage is to get a char-table for a specific property at | ||
| 1103 | a proper initialization time as this: | ||
| 1104 | |||
| 1105 | Lisp_Object bidi_class_table = uniprop_table (intern ("bidi-class")); | ||
| 1106 | |||
| 1107 | and get a property value for character CH as this: | ||
| 1108 | |||
| 1109 | Lisp_Object bidi_class = CHAR_TABLE_REF (CH, bidi_class_table); | ||
| 1110 | |||
| 1111 | In this case, what you actually get is an index number to the | ||
| 1112 | vector of property values (symbols nil, L, R, etc). | ||
| 1113 | |||
| 1114 | A table for Unicode character property has these characteristics: | ||
| 1115 | |||
| 1116 | o The purpose is `char-code-property-table', which implies that the | ||
| 1117 | table has 5 extra slots. | ||
| 1118 | |||
| 1119 | o The second extra slot is a Lisp function, an index (integer) to | ||
| 1120 | the array uniprop_decoder[], or nil. If it is a Lisp function, we | ||
| 1121 | can't use such a table from C (at the moment). If it is nil, it | ||
| 1122 | means that we don't have to decode values. | ||
| 1123 | |||
| 1124 | o The third extra slot is a Lisp function, an index (integer) to | ||
| 1125 | the array uniprop_enncoder[], or nil. If it is a Lisp function, we | ||
| 1126 | can't use such a table from C (at the moment). If it is nil, it | ||
| 1127 | means that we don't have to encode values. */ | ||
| 1128 | |||
| 1129 | |||
| 1130 | /* Uncompress the IDXth element of sub-char-table TABLE. */ | ||
| 1131 | |||
| 1132 | static Lisp_Object | ||
| 1133 | uniprop_table_uncompress (Lisp_Object table, int idx) | ||
| 1134 | { | ||
| 1135 | Lisp_Object val = XSUB_CHAR_TABLE (table)->contents[idx]; | ||
| 1136 | int min_char = (XINT (XSUB_CHAR_TABLE (table)->min_char) | ||
| 1137 | + chartab_chars[2] * idx); | ||
| 1138 | Lisp_Object sub = make_sub_char_table (3, min_char, Qnil); | ||
| 1139 | struct Lisp_Sub_Char_Table *subtbl = XSUB_CHAR_TABLE (sub); | ||
| 1140 | const unsigned char *p, *pend; | ||
| 1141 | |||
| 1142 | XSUB_CHAR_TABLE (table)->contents[idx] = sub; | ||
| 1143 | p = SDATA (val), pend = p + SBYTES (val); | ||
| 1144 | if (*p == 1) | ||
| 1145 | { | ||
| 1146 | /* SIMPLE TABLE */ | ||
| 1147 | p++; | ||
| 1148 | idx = STRING_CHAR_ADVANCE (p); | ||
| 1149 | while (p < pend && idx < chartab_chars[2]) | ||
| 1150 | { | ||
| 1151 | int v = STRING_CHAR_ADVANCE (p); | ||
| 1152 | subtbl->contents[idx++] = v > 0 ? make_number (v) : Qnil; | ||
| 1153 | } | ||
| 1154 | } | ||
| 1155 | else if (*p == 2) | ||
| 1156 | { | ||
| 1157 | /* RUN-LENGTH TABLE */ | ||
| 1158 | p++; | ||
| 1159 | for (idx = 0; p < pend; ) | ||
| 1160 | { | ||
| 1161 | int v = STRING_CHAR_ADVANCE (p); | ||
| 1162 | int count = 1; | ||
| 1163 | int len; | ||
| 1164 | |||
| 1165 | if (p < pend) | ||
| 1166 | { | ||
| 1167 | count = STRING_CHAR_AND_LENGTH (p, len); | ||
| 1168 | if (count < 128) | ||
| 1169 | count = 1; | ||
| 1170 | else | ||
| 1171 | { | ||
| 1172 | count -= 128; | ||
| 1173 | p += len; | ||
| 1174 | } | ||
| 1175 | } | ||
| 1176 | while (count-- > 0) | ||
| 1177 | subtbl->contents[idx++] = make_number (v); | ||
| 1178 | } | ||
| 1179 | } | ||
| 1180 | /* It seems that we don't need this function because C code won't need | ||
| 1181 | to get a property that is compressed in this form. */ | ||
| 1182 | #if 0 | ||
| 1183 | else if (*p == 0) | ||
| 1184 | { | ||
| 1185 | /* WORD-LIST TABLE */ | ||
| 1186 | } | ||
| 1187 | #endif | ||
| 1188 | return sub; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | |||
| 1192 | /* Decode VALUE as an elemnet of char-table TABLE. */ | ||
| 1193 | |||
| 1194 | static Lisp_Object | ||
| 1195 | uniprop_decode_value_run_length (Lisp_Object table, Lisp_Object value) | ||
| 1196 | { | ||
| 1197 | if (VECTORP (XCHAR_TABLE (table)->extras[4])) | ||
| 1198 | { | ||
| 1199 | Lisp_Object valvec = XCHAR_TABLE (table)->extras[4]; | ||
| 1200 | |||
| 1201 | if (XINT (value) >= 0 && XINT (value) < ASIZE (valvec)) | ||
| 1202 | value = AREF (valvec, XINT (value)); | ||
| 1203 | } | ||
| 1204 | return value; | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | static uniprop_decoder_t uniprop_decoder [] = | ||
| 1208 | { uniprop_decode_value_run_length }; | ||
| 1209 | |||
| 1210 | static int uniprop_decoder_count | ||
| 1211 | = (sizeof uniprop_decoder) / sizeof (uniprop_decoder[0]); | ||
| 1212 | |||
| 1213 | |||
| 1214 | /* Return the decoder of char-table TABLE or nil if none. */ | ||
| 1215 | |||
| 1216 | static uniprop_decoder_t | ||
| 1217 | uniprop_get_decoder (Lisp_Object table) | ||
| 1218 | { | ||
| 1219 | int i; | ||
| 1220 | |||
| 1221 | if (! INTEGERP (XCHAR_TABLE (table)->extras[1])) | ||
| 1222 | return NULL; | ||
| 1223 | i = XINT (XCHAR_TABLE (table)->extras[1]); | ||
| 1224 | if (i < 0 || i >= uniprop_decoder_count) | ||
| 1225 | return NULL; | ||
| 1226 | return uniprop_decoder[i]; | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | |||
| 1230 | /* Encode VALUE as an element of char-table TABLE which contains | ||
| 1231 | characters as elements. */ | ||
| 1232 | |||
| 1233 | static Lisp_Object | ||
| 1234 | uniprop_encode_value_character (Lisp_Object table, Lisp_Object value) | ||
| 1235 | { | ||
| 1236 | if (! NILP (value) && ! CHARACTERP (value)) | ||
| 1237 | wrong_type_argument (Qintegerp, value); | ||
| 1238 | return value; | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | |||
| 1242 | /* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH | ||
| 1243 | compression. */ | ||
| 1244 | |||
| 1245 | static Lisp_Object | ||
| 1246 | uniprop_encode_value_run_length (Lisp_Object table, Lisp_Object value) | ||
| 1247 | { | ||
| 1248 | Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents; | ||
| 1249 | int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]); | ||
| 1250 | |||
| 1251 | for (i = 0; i < size; i++) | ||
| 1252 | if (EQ (value, value_table[i])) | ||
| 1253 | break; | ||
| 1254 | if (i == size) | ||
| 1255 | wrong_type_argument (build_string ("Unicode property value"), value); | ||
| 1256 | return make_number (i); | ||
| 1257 | } | ||
| 1258 | |||
| 1259 | |||
| 1260 | /* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH | ||
| 1261 | compression and contains numbers as elements . */ | ||
| 1262 | |||
| 1263 | static Lisp_Object | ||
| 1264 | uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value) | ||
| 1265 | { | ||
| 1266 | Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents; | ||
| 1267 | int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]); | ||
| 1268 | |||
| 1269 | CHECK_NUMBER (value); | ||
| 1270 | for (i = 0; i < size; i++) | ||
| 1271 | if (EQ (value, value_table[i])) | ||
| 1272 | break; | ||
| 1273 | value = make_number (i); | ||
| 1274 | if (i == size) | ||
| 1275 | { | ||
| 1276 | Lisp_Object args[2]; | ||
| 1277 | |||
| 1278 | args[0] = XCHAR_TABLE (table)->extras[4]; | ||
| 1279 | args[1] = Fmake_vector (make_number (1), value); | ||
| 1280 | XCHAR_TABLE (table)->extras[4] = Fvconcat (2, args); | ||
| 1281 | } | ||
| 1282 | return make_number (i); | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | static uniprop_encoder_t uniprop_encoder[] = | ||
| 1286 | { uniprop_encode_value_character, | ||
| 1287 | uniprop_encode_value_run_length, | ||
| 1288 | uniprop_encode_value_numeric }; | ||
| 1289 | |||
| 1290 | static int uniprop_encoder_count | ||
| 1291 | = (sizeof uniprop_encoder) / sizeof (uniprop_encoder[0]); | ||
| 1292 | |||
| 1293 | |||
| 1294 | /* Return the encoder of char-table TABLE or nil if none. */ | ||
| 1295 | |||
| 1296 | static uniprop_decoder_t | ||
| 1297 | uniprop_get_encoder (Lisp_Object table) | ||
| 1298 | { | ||
| 1299 | int i; | ||
| 1300 | |||
| 1301 | if (! INTEGERP (XCHAR_TABLE (table)->extras[2])) | ||
| 1302 | return NULL; | ||
| 1303 | i = XINT (XCHAR_TABLE (table)->extras[2]); | ||
| 1304 | if (i < 0 || i >= uniprop_encoder_count) | ||
| 1305 | return NULL; | ||
| 1306 | return uniprop_encoder[i]; | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | /* Return a char-table for Unicode character property PROP. This | ||
| 1310 | function may load a Lisp file and thus may cause | ||
| 1311 | garbage-collection. */ | ||
| 1312 | |||
| 1313 | static Lisp_Object | ||
| 1314 | uniprop_table (Lisp_Object prop) | ||
| 1315 | { | ||
| 1316 | Lisp_Object val, table, result; | ||
| 1317 | |||
| 1318 | val = Fassq (prop, Vchar_code_property_alist); | ||
| 1319 | if (! CONSP (val)) | ||
| 1320 | return Qnil; | ||
| 1321 | table = XCDR (val); | ||
| 1322 | if (STRINGP (table)) | ||
| 1323 | { | ||
| 1324 | struct gcpro gcpro1; | ||
| 1325 | GCPRO1 (val); | ||
| 1326 | result = Fload (concat2 (build_string ("international/"), table), | ||
| 1327 | Qt, Qt, Qt, Qt); | ||
| 1328 | UNGCPRO; | ||
| 1329 | if (NILP (result)) | ||
| 1330 | return Qnil; | ||
| 1331 | table = XCDR (val); | ||
| 1332 | } | ||
| 1333 | if (! CHAR_TABLE_P (table) | ||
| 1334 | || ! UNIPROP_TABLE_P (table)) | ||
| 1335 | return Qnil; | ||
| 1336 | val = XCHAR_TABLE (table)->extras[1]; | ||
| 1337 | if (INTEGERP (val) | ||
| 1338 | ? (XINT (val) < 0 || XINT (val) >= uniprop_decoder_count) | ||
| 1339 | : ! NILP (val)) | ||
| 1340 | return Qnil; | ||
| 1341 | /* Prepare ASCII values in advance for CHAR_TABLE_REF. */ | ||
| 1342 | XCHAR_TABLE (table)->ascii = char_table_ascii (table); | ||
| 1343 | return table; | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | DEFUN ("unicode-property-table-internal", Funicode_property_table_internal, | ||
| 1347 | Sunicode_property_table_internal, 1, 1, 0, | ||
| 1348 | doc: /* Return a char-table for Unicode character property PROP. | ||
| 1349 | Use `get-unicode-property-internal' and | ||
| 1350 | `put-unicode-property-internal' instead of `aref' and `aset' to get | ||
| 1351 | and put an element value. */) | ||
| 1352 | (Lisp_Object prop) | ||
| 1353 | { | ||
| 1354 | Lisp_Object table = uniprop_table (prop); | ||
| 1355 | |||
| 1356 | if (CHAR_TABLE_P (table)) | ||
| 1357 | return table; | ||
| 1358 | return Fcdr (Fassq (prop, Vchar_code_property_alist)); | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | DEFUN ("get-unicode-property-internal", Fget_unicode_property_internal, | ||
| 1362 | Sget_unicode_property_internal, 2, 2, 0, | ||
| 1363 | doc: /* Return an element of CHAR-TABLE for character CH. | ||
| 1364 | CHAR-TABLE must be what returned by `unicode-property-table-internal'. */) | ||
| 1365 | (Lisp_Object char_table, Lisp_Object ch) | ||
| 1366 | { | ||
| 1367 | Lisp_Object val; | ||
| 1368 | uniprop_decoder_t decoder; | ||
| 1369 | |||
| 1370 | CHECK_CHAR_TABLE (char_table); | ||
| 1371 | CHECK_CHARACTER (ch); | ||
| 1372 | if (! UNIPROP_TABLE_P (char_table)) | ||
| 1373 | error ("Invalid Unicode property table"); | ||
| 1374 | val = CHAR_TABLE_REF (char_table, XINT (ch)); | ||
| 1375 | decoder = uniprop_get_decoder (char_table); | ||
| 1376 | return (decoder ? decoder (char_table, val) : val); | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | DEFUN ("put-unicode-property-internal", Fput_unicode_property_internal, | ||
| 1380 | Sput_unicode_property_internal, 3, 3, 0, | ||
| 1381 | doc: /* Set an element of CHAR-TABLE for character CH to VALUE. | ||
| 1382 | CHAR-TABLE must be what returned by `unicode-property-table-internal'. */) | ||
| 1383 | (Lisp_Object char_table, Lisp_Object ch, Lisp_Object value) | ||
| 1384 | { | ||
| 1385 | uniprop_encoder_t encoder; | ||
| 1386 | |||
| 1387 | CHECK_CHAR_TABLE (char_table); | ||
| 1388 | CHECK_CHARACTER (ch); | ||
| 1389 | if (! UNIPROP_TABLE_P (char_table)) | ||
| 1390 | error ("Invalid Unicode property table"); | ||
| 1391 | encoder = uniprop_get_encoder (char_table); | ||
| 1392 | if (encoder) | ||
| 1393 | value = encoder (char_table, value); | ||
| 1394 | CHAR_TABLE_SET (char_table, XINT (ch), value); | ||
| 1395 | return Qnil; | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | |||
| 987 | void | 1399 | void |
| 988 | syms_of_chartab (void) | 1400 | syms_of_chartab (void) |
| 989 | { | 1401 | { |
| 1402 | DEFSYM (Qchar_code_property_table, "char-code-property-table"); | ||
| 1403 | |||
| 990 | defsubr (&Smake_char_table); | 1404 | defsubr (&Smake_char_table); |
| 991 | defsubr (&Schar_table_parent); | 1405 | defsubr (&Schar_table_parent); |
| 992 | defsubr (&Schar_table_subtype); | 1406 | defsubr (&Schar_table_subtype); |
| @@ -998,4 +1412,19 @@ syms_of_chartab (void) | |||
| 998 | defsubr (&Sset_char_table_default); | 1412 | defsubr (&Sset_char_table_default); |
| 999 | defsubr (&Soptimize_char_table); | 1413 | defsubr (&Soptimize_char_table); |
| 1000 | defsubr (&Smap_char_table); | 1414 | defsubr (&Smap_char_table); |
| 1415 | defsubr (&Sunicode_property_table_internal); | ||
| 1416 | defsubr (&Sget_unicode_property_internal); | ||
| 1417 | defsubr (&Sput_unicode_property_internal); | ||
| 1418 | |||
| 1419 | /* Each element has the form (PROP . TABLE). | ||
| 1420 | PROP is a symbol representing a character property. | ||
| 1421 | TABLE is a char-table containing the property value for each character. | ||
| 1422 | TABLE may be a name of file to load to build a char-table. | ||
| 1423 | This variable should be modified only through | ||
| 1424 | `define-char-code-property'. */ | ||
| 1425 | |||
| 1426 | DEFVAR_LISP ("char-code-property-alist", Vchar_code_property_alist, | ||
| 1427 | doc: /* Alist of character property name vs char-table containing property values. | ||
| 1428 | Internal use only. */); | ||
| 1429 | Vchar_code_property_alist = Qnil; | ||
| 1001 | } | 1430 | } |
| @@ -305,7 +305,8 @@ done: | |||
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | #if 0 | 307 | #if 0 |
| 308 | losecursor () | 308 | void |
| 309 | losecursor (void) | ||
| 309 | { | 310 | { |
| 310 | curY = -1; | 311 | curY = -1; |
| 311 | } | 312 | } |
diff --git a/src/coding.c b/src/coding.c index 9939774ea82..65c8a767c2b 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -9000,7 +9000,7 @@ not fully specified.) */) | |||
| 9000 | (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer) | 9000 | (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer) |
| 9001 | { | 9001 | { |
| 9002 | return code_convert_string (string, coding_system, buffer, | 9002 | return code_convert_string (string, coding_system, buffer, |
| 9003 | 1, ! NILP (nocopy), 1); | 9003 | 1, ! NILP (nocopy), 0); |
| 9004 | } | 9004 | } |
| 9005 | 9005 | ||
| 9006 | 9006 | ||
diff --git a/src/composite.c b/src/composite.c index de9775d18f5..d402d5ad0c4 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -967,7 +967,6 @@ autocmp_chars (Lisp_Object rule, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT | |||
| 967 | } | 967 | } |
| 968 | 968 | ||
| 969 | static Lisp_Object _work_val; | 969 | static Lisp_Object _work_val; |
| 970 | static int _work_char; | ||
| 971 | 970 | ||
| 972 | /* 1 iff the character C is composable. Characters of general | 971 | /* 1 iff the character C is composable. Characters of general |
| 973 | category Z? or C? are not composable except for ZWNJ and ZWJ. */ | 972 | category Z? or C? are not composable except for ZWNJ and ZWJ. */ |
| @@ -976,9 +975,8 @@ static int _work_char; | |||
| 976 | ((C) > ' ' \ | 975 | ((C) > ' ' \ |
| 977 | && ((C) == 0x200C || (C) == 0x200D \ | 976 | && ((C) == 0x200C || (C) == 0x200D \ |
| 978 | || (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \ | 977 | || (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \ |
| 979 | (SYMBOLP (_work_val) \ | 978 | (INTEGERP (_work_val) \ |
| 980 | && (_work_char = SDATA (SYMBOL_NAME (_work_val))[0]) != 'C' \ | 979 | && (XINT (_work_val) <= UNICODE_CATEGORY_So))))) |
| 981 | && _work_char != 'Z')))) | ||
| 982 | 980 | ||
| 983 | /* Update cmp_it->stop_pos to the next position after CHARPOS (and | 981 | /* Update cmp_it->stop_pos to the next position after CHARPOS (and |
| 984 | BYTEPOS) where character composition may happen. If BYTEPOS is | 982 | BYTEPOS) where character composition may happen. If BYTEPOS is |
| @@ -1027,6 +1025,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos, | |||
| 1027 | /* FIXME: Bidi is not yet handled well in static composition. */ | 1025 | /* FIXME: Bidi is not yet handled well in static composition. */ |
| 1028 | if (charpos < endpos | 1026 | if (charpos < endpos |
| 1029 | && find_composition (charpos, endpos, &start, &end, &prop, string) | 1027 | && find_composition (charpos, endpos, &start, &end, &prop, string) |
| 1028 | && start >= charpos | ||
| 1030 | && COMPOSITION_VALID_P (start, end, prop)) | 1029 | && COMPOSITION_VALID_P (start, end, prop)) |
| 1031 | { | 1030 | { |
| 1032 | cmp_it->stop_pos = endpos = start; | 1031 | cmp_it->stop_pos = endpos = start; |
diff --git a/src/data.c b/src/data.c index 6b4ea32ac9e..7bc04592c57 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2736,8 +2736,7 @@ Both must be integers or markers. */) | |||
| 2736 | 2736 | ||
| 2737 | #ifndef HAVE_FMOD | 2737 | #ifndef HAVE_FMOD |
| 2738 | double | 2738 | double |
| 2739 | fmod (f1, f2) | 2739 | fmod (double f1, double f2) |
| 2740 | double f1, f2; | ||
| 2741 | { | 2740 | { |
| 2742 | double r = f1; | 2741 | double r = f1; |
| 2743 | 2742 | ||
diff --git a/src/dispextern.h b/src/dispextern.h index 31ad7af4a84..ec1bdab815c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1779,7 +1779,11 @@ extern int face_change_count; | |||
| 1779 | /* Data type for describing the bidirectional character types. The | 1779 | /* Data type for describing the bidirectional character types. The |
| 1780 | first 7 must be at the beginning, because they are the only values | 1780 | first 7 must be at the beginning, because they are the only values |
| 1781 | valid in the `bidi_type' member of `struct glyph'; we only reserve | 1781 | valid in the `bidi_type' member of `struct glyph'; we only reserve |
| 1782 | 3 bits for it, so we cannot use there values larger than 7. */ | 1782 | 3 bits for it, so we cannot use there values larger than 7. |
| 1783 | |||
| 1784 | The order of members must be in sync with the 8th element of the | ||
| 1785 | member of unidata-prop-alist (in admin/unidata/unidata-getn.el) for | ||
| 1786 | Unicode character property `bidi-class'. */ | ||
| 1783 | typedef enum { | 1787 | typedef enum { |
| 1784 | UNKNOWN_BT = 0, | 1788 | UNKNOWN_BT = 0, |
| 1785 | STRONG_L, /* strong left-to-right */ | 1789 | STRONG_L, /* strong left-to-right */ |
| @@ -1822,9 +1826,21 @@ struct bidi_stack { | |||
| 1822 | bidi_dir_t override; | 1826 | bidi_dir_t override; |
| 1823 | }; | 1827 | }; |
| 1824 | 1828 | ||
| 1829 | /* Data type for storing information about a string being iterated on. */ | ||
| 1830 | struct bidi_string_data { | ||
| 1831 | Lisp_Object lstring; /* Lisp string to reorder, or nil */ | ||
| 1832 | const unsigned char *s; /* string data, or NULL if reordering buffer */ | ||
| 1833 | EMACS_INT schars; /* the number of characters in the string, | ||
| 1834 | excluding the terminating null */ | ||
| 1835 | EMACS_INT bufpos; /* buffer position of lstring, or 0 if N/A */ | ||
| 1836 | unsigned from_disp_str : 1; /* 1 means the string comes from a | ||
| 1837 | display property */ | ||
| 1838 | unsigned unibyte : 1; /* 1 means the string is unibyte */ | ||
| 1839 | }; | ||
| 1840 | |||
| 1825 | /* Data type for reordering bidirectional text. */ | 1841 | /* Data type for reordering bidirectional text. */ |
| 1826 | struct bidi_it { | 1842 | struct bidi_it { |
| 1827 | EMACS_INT bytepos; /* iterator's position in buffer */ | 1843 | EMACS_INT bytepos; /* iterator's position in buffer/string */ |
| 1828 | EMACS_INT charpos; | 1844 | EMACS_INT charpos; |
| 1829 | int ch; /* character at that position, or u+FFFC | 1845 | int ch; /* character at that position, or u+FFFC |
| 1830 | ("object replacement character") for a run | 1846 | ("object replacement character") for a run |
| @@ -1854,12 +1870,13 @@ struct bidi_it { | |||
| 1854 | iterator state is saved, pushed, or popped. So only put here | 1870 | iterator state is saved, pushed, or popped. So only put here |
| 1855 | stuff that is not part of the bidi iterator's state! */ | 1871 | stuff that is not part of the bidi iterator's state! */ |
| 1856 | struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */ | 1872 | struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */ |
| 1857 | int first_elt; /* if non-zero, examine current char first */ | 1873 | struct bidi_string_data string; /* string to reorder */ |
| 1858 | bidi_dir_t paragraph_dir; /* current paragraph direction */ | 1874 | bidi_dir_t paragraph_dir; /* current paragraph direction */ |
| 1859 | int new_paragraph; /* if non-zero, we expect a new paragraph */ | ||
| 1860 | int frame_window_p; /* non-zero if displaying on a GUI frame */ | ||
| 1861 | EMACS_INT separator_limit; /* where paragraph separator should end */ | 1875 | EMACS_INT separator_limit; /* where paragraph separator should end */ |
| 1862 | EMACS_INT disp_pos; /* position of display string after ch */ | 1876 | EMACS_INT disp_pos; /* position of display string after ch */ |
| 1877 | unsigned first_elt : 1; /* if non-zero, examine current char first */ | ||
| 1878 | unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */ | ||
| 1879 | unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */ | ||
| 1863 | }; | 1880 | }; |
| 1864 | 1881 | ||
| 1865 | /* Value is non-zero when the bidi iterator is at base paragraph | 1882 | /* Value is non-zero when the bidi iterator is at base paragraph |
| @@ -2139,6 +2156,10 @@ struct it | |||
| 2139 | Don't handle some `display' properties in these strings. */ | 2156 | Don't handle some `display' properties in these strings. */ |
| 2140 | unsigned string_from_display_prop_p : 1; | 2157 | unsigned string_from_display_prop_p : 1; |
| 2141 | 2158 | ||
| 2159 | /* 1 means we are iterating an object that came from a value of a | ||
| 2160 | `display' property. */ | ||
| 2161 | unsigned from_disp_prop_p : 1; | ||
| 2162 | |||
| 2142 | /* When METHOD == next_element_from_display_vector, | 2163 | /* When METHOD == next_element_from_display_vector, |
| 2143 | this is 1 if we're doing an ellipsis. Otherwise meaningless. */ | 2164 | this is 1 if we're doing an ellipsis. Otherwise meaningless. */ |
| 2144 | unsigned ellipsis_p : 1; | 2165 | unsigned ellipsis_p : 1; |
| @@ -2158,7 +2179,9 @@ struct it | |||
| 2158 | Lisp_Object *dpvec, *dpend; | 2179 | Lisp_Object *dpvec, *dpend; |
| 2159 | 2180 | ||
| 2160 | /* Length in bytes of the char that filled dpvec. A value of zero | 2181 | /* Length in bytes of the char that filled dpvec. A value of zero |
| 2161 | means that no such character is involved. */ | 2182 | means that no such character is involved. A negative value means |
| 2183 | the rest of the line from the current iterator position onwards | ||
| 2184 | is hidden by selective display or ellipsis. */ | ||
| 2162 | int dpvec_char_len; | 2185 | int dpvec_char_len; |
| 2163 | 2186 | ||
| 2164 | /* Face id to use for all characters in display vector. -1 if unused. */ | 2187 | /* Face id to use for all characters in display vector. -1 if unused. */ |
| @@ -2256,10 +2279,13 @@ struct it | |||
| 2256 | Lisp_Object from_overlay; | 2279 | Lisp_Object from_overlay; |
| 2257 | enum glyph_row_area area; | 2280 | enum glyph_row_area area; |
| 2258 | enum it_method method; | 2281 | enum it_method method; |
| 2282 | bidi_dir_t paragraph_embedding; | ||
| 2259 | unsigned multibyte_p : 1; | 2283 | unsigned multibyte_p : 1; |
| 2260 | unsigned string_from_display_prop_p : 1; | 2284 | unsigned string_from_display_prop_p : 1; |
| 2261 | unsigned display_ellipsis_p : 1; | 2285 | unsigned display_ellipsis_p : 1; |
| 2262 | unsigned avoid_cursor_p : 1; | 2286 | unsigned avoid_cursor_p : 1; |
| 2287 | unsigned bidi_p:1; | ||
| 2288 | unsigned from_disp_prop_p : 1; | ||
| 2263 | enum line_wrap_method line_wrap; | 2289 | enum line_wrap_method line_wrap; |
| 2264 | 2290 | ||
| 2265 | /* properties from display property that are reset by another display property. */ | 2291 | /* properties from display property that are reset by another display property. */ |
| @@ -2484,7 +2510,7 @@ struct it | |||
| 2484 | 2510 | ||
| 2485 | /* Non-zero means we need to reorder bidirectional text for display | 2511 | /* Non-zero means we need to reorder bidirectional text for display |
| 2486 | in the visual order. */ | 2512 | in the visual order. */ |
| 2487 | int bidi_p; | 2513 | unsigned bidi_p : 1; |
| 2488 | 2514 | ||
| 2489 | /* For iterating over bidirectional text. */ | 2515 | /* For iterating over bidirectional text. */ |
| 2490 | struct bidi_it bidi_it; | 2516 | struct bidi_it bidi_it; |
| @@ -2966,6 +2992,10 @@ extern void bidi_init_it (EMACS_INT, EMACS_INT, int, struct bidi_it *); | |||
| 2966 | extern void bidi_move_to_visually_next (struct bidi_it *); | 2992 | extern void bidi_move_to_visually_next (struct bidi_it *); |
| 2967 | extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); | 2993 | extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); |
| 2968 | extern int bidi_mirror_char (int); | 2994 | extern int bidi_mirror_char (int); |
| 2995 | extern void bidi_push_it (struct bidi_it *); | ||
| 2996 | extern void bidi_pop_it (struct bidi_it *); | ||
| 2997 | extern void *bidi_shelve_cache (void); | ||
| 2998 | extern void bidi_unshelve_cache (void *); | ||
| 2969 | 2999 | ||
| 2970 | /* Defined in xdisp.c */ | 3000 | /* Defined in xdisp.c */ |
| 2971 | 3001 | ||
| @@ -3023,8 +3053,10 @@ extern void reseat_at_previous_visible_line_start (struct it *); | |||
| 3023 | extern Lisp_Object lookup_glyphless_char_display (int, struct it *); | 3053 | extern Lisp_Object lookup_glyphless_char_display (int, struct it *); |
| 3024 | extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, | 3054 | extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, |
| 3025 | struct font *, int, int *); | 3055 | struct font *, int, int *); |
| 3026 | extern EMACS_INT compute_display_string_pos (EMACS_INT, int); | 3056 | extern EMACS_INT compute_display_string_pos (struct text_pos *, |
| 3027 | extern EMACS_INT compute_display_string_end (EMACS_INT); | 3057 | struct bidi_string_data *, int); |
| 3058 | extern EMACS_INT compute_display_string_end (EMACS_INT, | ||
| 3059 | struct bidi_string_data *); | ||
| 3028 | 3060 | ||
| 3029 | #ifdef HAVE_WINDOW_SYSTEM | 3061 | #ifdef HAVE_WINDOW_SYSTEM |
| 3030 | 3062 | ||
diff --git a/src/dispnew.c b/src/dispnew.c index bde90d847ce..bfd4b3a7ecf 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -1065,8 +1065,7 @@ increment_row_positions (struct glyph_row *row, | |||
| 1065 | B without changing glyph pointers in A and B. */ | 1065 | B without changing glyph pointers in A and B. */ |
| 1066 | 1066 | ||
| 1067 | static void | 1067 | static void |
| 1068 | swap_glyphs_in_rows (a, b) | 1068 | swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b) |
| 1069 | struct glyph_row *a, *b; | ||
| 1070 | { | 1069 | { |
| 1071 | int area; | 1070 | int area; |
| 1072 | 1071 | ||
| @@ -5284,10 +5283,12 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5284 | struct image *img = 0; | 5283 | struct image *img = 0; |
| 5285 | #endif | 5284 | #endif |
| 5286 | int x0, x1, to_x; | 5285 | int x0, x1, to_x; |
| 5286 | void *itdata = NULL; | ||
| 5287 | 5287 | ||
| 5288 | /* We used to set current_buffer directly here, but that does the | 5288 | /* We used to set current_buffer directly here, but that does the |
| 5289 | wrong thing with `face-remapping-alist' (bug#2044). */ | 5289 | wrong thing with `face-remapping-alist' (bug#2044). */ |
| 5290 | Fset_buffer (w->buffer); | 5290 | Fset_buffer (w->buffer); |
| 5291 | itdata = bidi_shelve_cache (); | ||
| 5291 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | 5292 | SET_TEXT_POS_FROM_MARKER (startp, w->start); |
| 5292 | CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); | 5293 | CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); |
| 5293 | BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); | 5294 | BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); |
| @@ -5321,6 +5322,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5321 | argument is ZV to prevent move_it_in_display_line from matching | 5322 | argument is ZV to prevent move_it_in_display_line from matching |
| 5322 | based on buffer positions. */ | 5323 | based on buffer positions. */ |
| 5323 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); | 5324 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); |
| 5325 | bidi_unshelve_cache (itdata); | ||
| 5324 | 5326 | ||
| 5325 | Fset_buffer (old_current_buffer); | 5327 | Fset_buffer (old_current_buffer); |
| 5326 | 5328 | ||
diff --git a/src/editfns.c b/src/editfns.c index 5328b714b0f..b20c38faacd 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -194,8 +194,12 @@ DEFUN ("byte-to-string", Fbyte_to_string, Sbyte_to_string, 1, 1, 0, | |||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0, | 196 | DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0, |
| 197 | doc: /* Convert arg STRING to a character, the first character of that string. | 197 | doc: /* Return the first character in STRING. |
| 198 | A multibyte character is handled correctly. */) | 198 | A multibyte character is handled correctly. |
| 199 | The value returned is a Unicode codepoint if it is below #x110000 (in | ||
| 200 | hex). Codepoints beyond that are Emacs extensions of Unicode. In | ||
| 201 | particular, eight-bit characters are returned as codepoints in the | ||
| 202 | range #x3FFF80 through #x3FFFFF, inclusive. */) | ||
| 199 | (register Lisp_Object string) | 203 | (register Lisp_Object string) |
| 200 | { | 204 | { |
| 201 | register Lisp_Object val; | 205 | register Lisp_Object val; |
| @@ -1700,7 +1704,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */) | |||
| 1700 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) | 1704 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) |
| 1701 | { | 1705 | { |
| 1702 | time_t value; | 1706 | time_t value; |
| 1703 | int size; | 1707 | ptrdiff_t size; |
| 1704 | int usec; | 1708 | int usec; |
| 1705 | int ns; | 1709 | int ns; |
| 1706 | struct tm *tm; | 1710 | struct tm *tm; |
| @@ -1717,7 +1721,9 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */) | |||
| 1717 | Vlocale_coding_system, 1); | 1721 | Vlocale_coding_system, 1); |
| 1718 | 1722 | ||
| 1719 | /* This is probably enough. */ | 1723 | /* This is probably enough. */ |
| 1720 | size = SBYTES (format_string) * 6 + 50; | 1724 | size = SBYTES (format_string); |
| 1725 | if (size <= (STRING_BYTES_BOUND - 50) / 6) | ||
| 1726 | size = size * 6 + 50; | ||
| 1721 | 1727 | ||
| 1722 | BLOCK_INPUT; | 1728 | BLOCK_INPUT; |
| 1723 | tm = ut ? gmtime (&value) : localtime (&value); | 1729 | tm = ut ? gmtime (&value) : localtime (&value); |
| @@ -1730,7 +1736,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */) | |||
| 1730 | while (1) | 1736 | while (1) |
| 1731 | { | 1737 | { |
| 1732 | char *buf = (char *) alloca (size + 1); | 1738 | char *buf = (char *) alloca (size + 1); |
| 1733 | int result; | 1739 | size_t result; |
| 1734 | 1740 | ||
| 1735 | buf[0] = '\1'; | 1741 | buf[0] = '\1'; |
| 1736 | BLOCK_INPUT; | 1742 | BLOCK_INPUT; |
| @@ -1749,6 +1755,8 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */) | |||
| 1749 | SBYTES (format_string), | 1755 | SBYTES (format_string), |
| 1750 | tm, ut, ns); | 1756 | tm, ut, ns); |
| 1751 | UNBLOCK_INPUT; | 1757 | UNBLOCK_INPUT; |
| 1758 | if (STRING_BYTES_BOUND <= result) | ||
| 1759 | string_overflow (); | ||
| 1752 | size = result + 1; | 1760 | size = result + 1; |
| 1753 | } | 1761 | } |
| 1754 | } | 1762 | } |
| @@ -3152,10 +3160,9 @@ It returns the number of characters changed. */) | |||
| 3152 | } | 3160 | } |
| 3153 | 3161 | ||
| 3154 | DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r", | 3162 | DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r", |
| 3155 | doc: /* Delete the text between point and mark. | 3163 | doc: /* Delete the text between START and END. |
| 3156 | 3164 | If called interactively, delete the region between point and mark. | |
| 3157 | When called from a program, expects two arguments, | 3165 | This command deletes buffer text without modifying the kill ring. */) |
| 3158 | positions (integers or markers) specifying the stretch to be deleted. */) | ||
| 3159 | (Lisp_Object start, Lisp_Object end) | 3166 | (Lisp_Object start, Lisp_Object end) |
| 3160 | { | 3167 | { |
| 3161 | validate_region (&start, &end); | 3168 | validate_region (&start, &end); |
| @@ -3557,7 +3564,8 @@ The width specifier supplies a lower limit for the length of the | |||
| 3557 | printed representation. The padding, if any, normally goes on the | 3564 | printed representation. The padding, if any, normally goes on the |
| 3558 | left, but it goes on the right if the - flag is present. The padding | 3565 | left, but it goes on the right if the - flag is present. The padding |
| 3559 | character is normally a space, but it is 0 if the 0 flag is present. | 3566 | character is normally a space, but it is 0 if the 0 flag is present. |
| 3560 | The - flag takes precedence over the 0 flag. | 3567 | The 0 flag is ignored if the - flag is present, or the format sequence |
| 3568 | is something other than %d, %e, %f, and %g. | ||
| 3561 | 3569 | ||
| 3562 | For %e, %f, and %g sequences, the number after the "." in the | 3570 | For %e, %f, and %g sequences, the number after the "." in the |
| 3563 | precision specifier says how many decimal places to show; if zero, the | 3571 | precision specifier says how many decimal places to show; if zero, the |
diff --git a/src/emacs.c b/src/emacs.c index bfefa2bfa51..1de10c0b5dc 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -131,6 +131,10 @@ Lisp_Object empty_unibyte_string, empty_multibyte_string; | |||
| 131 | on subsequent starts. */ | 131 | on subsequent starts. */ |
| 132 | int initialized; | 132 | int initialized; |
| 133 | 133 | ||
| 134 | #ifdef DARWIN_OS | ||
| 135 | extern void unexec_init_emacs_zone (void); | ||
| 136 | #endif | ||
| 137 | |||
| 134 | #ifdef DOUG_LEA_MALLOC | 138 | #ifdef DOUG_LEA_MALLOC |
| 135 | /* Preserves a pointer to the memory allocated that copies that | 139 | /* Preserves a pointer to the memory allocated that copies that |
| 136 | static data inside glibc's malloc. */ | 140 | static data inside glibc's malloc. */ |
| @@ -352,8 +356,7 @@ fatal_error_signal (int sig) | |||
| 352 | 356 | ||
| 353 | /* Handler for SIGDANGER. */ | 357 | /* Handler for SIGDANGER. */ |
| 354 | void | 358 | void |
| 355 | memory_warning_signal (sig) | 359 | memory_warning_signal (int sig) |
| 356 | int sig; | ||
| 357 | { | 360 | { |
| 358 | signal (sig, memory_warning_signal); | 361 | signal (sig, memory_warning_signal); |
| 359 | SIGNAL_THREAD_CHECK (sig); | 362 | SIGNAL_THREAD_CHECK (sig); |
diff --git a/src/eval.c b/src/eval.c index 6ca8eacb100..90d0df61858 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -32,25 +32,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 32 | #include "xterm.h" | 32 | #include "xterm.h" |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | /* This definition is duplicated in alloc.c and keyboard.c. */ | ||
| 36 | /* Putting it in lisp.h makes cc bomb out! */ | ||
| 37 | |||
| 38 | struct backtrace | 35 | struct backtrace |
| 39 | { | 36 | { |
| 40 | struct backtrace *next; | 37 | struct backtrace *next; |
| 41 | Lisp_Object *function; | 38 | Lisp_Object *function; |
| 42 | Lisp_Object *args; /* Points to vector of args. */ | 39 | Lisp_Object *args; /* Points to vector of args. */ |
| 43 | #define NARGS_BITS (BITS_PER_INT - 2) | 40 | ptrdiff_t nargs; /* Length of vector. */ |
| 44 | /* Let's not use size_t because we want to allow negative values (for | ||
| 45 | UNEVALLED). Also let's steal 2 bits so we save a word (or more for | ||
| 46 | alignment). In any case I doubt Emacs would survive a function call with | ||
| 47 | more than 500M arguments. */ | ||
| 48 | int nargs : NARGS_BITS; /* Length of vector. | ||
| 49 | If nargs is UNEVALLED, args points | ||
| 50 | to slot holding list of unevalled args. */ | ||
| 51 | char evalargs : 1; | ||
| 52 | /* Nonzero means call value of debugger when done with this operation. */ | 41 | /* Nonzero means call value of debugger when done with this operation. */ |
| 53 | char debug_on_exit : 1; | 42 | unsigned int debug_on_exit : 1; |
| 54 | }; | 43 | }; |
| 55 | 44 | ||
| 56 | static struct backtrace *backtrace_list; | 45 | static struct backtrace *backtrace_list; |
| @@ -1651,8 +1640,7 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1651 | } | 1640 | } |
| 1652 | 1641 | ||
| 1653 | 1642 | ||
| 1654 | static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object, | 1643 | static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object); |
| 1655 | Lisp_Object, Lisp_Object); | ||
| 1656 | static int maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, | 1644 | static int maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, |
| 1657 | Lisp_Object data); | 1645 | Lisp_Object data); |
| 1658 | 1646 | ||
| @@ -1728,8 +1716,7 @@ See also the function `condition-case'. */) | |||
| 1728 | 1716 | ||
| 1729 | for (h = handlerlist; h; h = h->next) | 1717 | for (h = handlerlist; h; h = h->next) |
| 1730 | { | 1718 | { |
| 1731 | clause = find_handler_clause (h->handler, conditions, | 1719 | clause = find_handler_clause (h->handler, conditions); |
| 1732 | error_symbol, data); | ||
| 1733 | if (!NILP (clause)) | 1720 | if (!NILP (clause)) |
| 1734 | break; | 1721 | break; |
| 1735 | } | 1722 | } |
| @@ -1900,8 +1887,10 @@ skip_debugger (Lisp_Object conditions, Lisp_Object data) | |||
| 1900 | } | 1887 | } |
| 1901 | 1888 | ||
| 1902 | /* Call the debugger if calling it is currently enabled for CONDITIONS. | 1889 | /* Call the debugger if calling it is currently enabled for CONDITIONS. |
| 1903 | SIG and DATA describe the signal, as in find_handler_clause. */ | 1890 | SIG and DATA describe the signal. There are two ways to pass them: |
| 1904 | 1891 | = SIG is the error symbol, and DATA is the rest of the data. | |
| 1892 | = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA). | ||
| 1893 | This is for memory-full errors only. */ | ||
| 1905 | static int | 1894 | static int |
| 1906 | maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) | 1895 | maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) |
| 1907 | { | 1896 | { |
| @@ -1928,19 +1917,8 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) | |||
| 1928 | return 0; | 1917 | return 0; |
| 1929 | } | 1918 | } |
| 1930 | 1919 | ||
| 1931 | /* Value of Qlambda means we have called debugger and user has continued. | ||
| 1932 | There are two ways to pass SIG and DATA: | ||
| 1933 | = SIG is the error symbol, and DATA is the rest of the data. | ||
| 1934 | = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA). | ||
| 1935 | This is for memory-full errors only. | ||
| 1936 | |||
| 1937 | We need to increase max_specpdl_size temporarily around | ||
| 1938 | anything we do that can push on the specpdl, so as not to get | ||
| 1939 | a second error here in case we're handling specpdl overflow. */ | ||
| 1940 | |||
| 1941 | static Lisp_Object | 1920 | static Lisp_Object |
| 1942 | find_handler_clause (Lisp_Object handlers, Lisp_Object conditions, | 1921 | find_handler_clause (Lisp_Object handlers, Lisp_Object conditions) |
| 1943 | Lisp_Object sig, Lisp_Object data) | ||
| 1944 | { | 1922 | { |
| 1945 | register Lisp_Object h; | 1923 | register Lisp_Object h; |
| 1946 | 1924 | ||
| @@ -2291,7 +2269,6 @@ eval_sub (Lisp_Object form) | |||
| 2291 | backtrace.function = &original_fun; /* This also protects them from gc. */ | 2269 | backtrace.function = &original_fun; /* This also protects them from gc. */ |
| 2292 | backtrace.args = &original_args; | 2270 | backtrace.args = &original_args; |
| 2293 | backtrace.nargs = UNEVALLED; | 2271 | backtrace.nargs = UNEVALLED; |
| 2294 | backtrace.evalargs = 1; | ||
| 2295 | backtrace.debug_on_exit = 0; | 2272 | backtrace.debug_on_exit = 0; |
| 2296 | 2273 | ||
| 2297 | if (debug_on_next_call) | 2274 | if (debug_on_next_call) |
| @@ -2325,10 +2302,7 @@ eval_sub (Lisp_Object form) | |||
| 2325 | xsignal2 (Qwrong_number_of_arguments, original_fun, numargs); | 2302 | xsignal2 (Qwrong_number_of_arguments, original_fun, numargs); |
| 2326 | 2303 | ||
| 2327 | else if (XSUBR (fun)->max_args == UNEVALLED) | 2304 | else if (XSUBR (fun)->max_args == UNEVALLED) |
| 2328 | { | 2305 | val = (XSUBR (fun)->function.aUNEVALLED) (args_left); |
| 2329 | backtrace.evalargs = 0; | ||
| 2330 | val = (XSUBR (fun)->function.aUNEVALLED) (args_left); | ||
| 2331 | } | ||
| 2332 | else if (XSUBR (fun)->max_args == MANY) | 2306 | else if (XSUBR (fun)->max_args == MANY) |
| 2333 | { | 2307 | { |
| 2334 | /* Pass a vector of evaluated arguments. */ | 2308 | /* Pass a vector of evaluated arguments. */ |
| @@ -2984,7 +2958,6 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2984 | backtrace.function = &args[0]; | 2958 | backtrace.function = &args[0]; |
| 2985 | backtrace.args = &args[1]; | 2959 | backtrace.args = &args[1]; |
| 2986 | backtrace.nargs = nargs - 1; | 2960 | backtrace.nargs = nargs - 1; |
| 2987 | backtrace.evalargs = 0; | ||
| 2988 | backtrace.debug_on_exit = 0; | 2961 | backtrace.debug_on_exit = 0; |
| 2989 | 2962 | ||
| 2990 | if (debug_on_next_call) | 2963 | if (debug_on_next_call) |
| @@ -3141,7 +3114,6 @@ apply_lambda (Lisp_Object fun, Lisp_Object args) | |||
| 3141 | 3114 | ||
| 3142 | backtrace_list->args = arg_vector; | 3115 | backtrace_list->args = arg_vector; |
| 3143 | backtrace_list->nargs = i; | 3116 | backtrace_list->nargs = i; |
| 3144 | backtrace_list->evalargs = 0; | ||
| 3145 | tem = funcall_lambda (fun, numargs, arg_vector); | 3117 | tem = funcall_lambda (fun, numargs, arg_vector); |
| 3146 | 3118 | ||
| 3147 | /* Do the debug-on-exit now, while arg_vector still exists. */ | 3119 | /* Do the debug-on-exit now, while arg_vector still exists. */ |
| @@ -3190,7 +3162,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 3190 | shouldn't bind any arguments, instead just call the byte-code | 3162 | shouldn't bind any arguments, instead just call the byte-code |
| 3191 | interpreter directly; it will push arguments as necessary. | 3163 | interpreter directly; it will push arguments as necessary. |
| 3192 | 3164 | ||
| 3193 | Byte-code objects with either a non-existant, or a nil value for | 3165 | Byte-code objects with either a non-existent, or a nil value for |
| 3194 | the `push args' slot (the default), have dynamically-bound | 3166 | the `push args' slot (the default), have dynamically-bound |
| 3195 | arguments, and use the argument-binding code below instead (as do | 3167 | arguments, and use the argument-binding code below instead (as do |
| 3196 | all interpreted functions, even lexically bound ones). */ | 3168 | all interpreted functions, even lexically bound ones). */ |
diff --git a/src/fileio.c b/src/fileio.c index 27fef42960a..c6f8dfe4683 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -1755,6 +1755,10 @@ barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring, | |||
| 1755 | regardless of what access permissions it has. */ | 1755 | regardless of what access permissions it has. */ |
| 1756 | if (lstat (SSDATA (encoded_filename), &statbuf) >= 0) | 1756 | if (lstat (SSDATA (encoded_filename), &statbuf) >= 0) |
| 1757 | { | 1757 | { |
| 1758 | if (S_ISDIR (statbuf.st_mode)) | ||
| 1759 | xsignal2 (Qfile_error, | ||
| 1760 | build_string ("File is a directory"), absname); | ||
| 1761 | |||
| 1758 | if (! interactive) | 1762 | if (! interactive) |
| 1759 | xsignal2 (Qfile_already_exists, | 1763 | xsignal2 (Qfile_already_exists, |
| 1760 | build_string ("File already exists"), absname); | 1764 | build_string ("File already exists"), absname); |
diff --git a/src/floatfns.c b/src/floatfns.c index b5c8b4af5c3..e003f492fe6 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -961,8 +961,7 @@ Rounds the value toward zero. */) | |||
| 961 | 961 | ||
| 962 | #ifdef FLOAT_CATCH_SIGILL | 962 | #ifdef FLOAT_CATCH_SIGILL |
| 963 | static void | 963 | static void |
| 964 | float_error (signo) | 964 | float_error (int signo) |
| 965 | int signo; | ||
| 966 | { | 965 | { |
| 967 | if (! in_float) | 966 | if (! in_float) |
| 968 | fatal_error_signal (signo); | 967 | fatal_error_signal (signo); |
| @@ -79,10 +79,14 @@ Other values of LIMIT are ignored. */) | |||
| 79 | { | 79 | { |
| 80 | EMACS_INT val; | 80 | EMACS_INT val; |
| 81 | Lisp_Object lispy_val; | 81 | Lisp_Object lispy_val; |
| 82 | EMACS_UINT denominator; | ||
| 83 | 82 | ||
| 84 | if (EQ (limit, Qt)) | 83 | if (EQ (limit, Qt)) |
| 85 | seed_random (getpid () + time (NULL)); | 84 | { |
| 85 | EMACS_TIME t; | ||
| 86 | EMACS_GET_TIME (t); | ||
| 87 | seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_USECS (t)); | ||
| 88 | } | ||
| 89 | |||
| 86 | if (NATNUMP (limit) && XFASTINT (limit) != 0) | 90 | if (NATNUMP (limit) && XFASTINT (limit) != 0) |
| 87 | { | 91 | { |
| 88 | /* Try to take our random number from the higher bits of VAL, | 92 | /* Try to take our random number from the higher bits of VAL, |
| @@ -92,7 +96,7 @@ Other values of LIMIT are ignored. */) | |||
| 92 | it's possible to get a quotient larger than n; discarding | 96 | it's possible to get a quotient larger than n; discarding |
| 93 | these values eliminates the bias that would otherwise appear | 97 | these values eliminates the bias that would otherwise appear |
| 94 | when using a large n. */ | 98 | when using a large n. */ |
| 95 | denominator = ((EMACS_UINT) 1 << VALBITS) / XFASTINT (limit); | 99 | EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit); |
| 96 | do | 100 | do |
| 97 | val = get_random () / denominator; | 101 | val = get_random () / denominator; |
| 98 | while (val >= XFASTINT (limit)); | 102 | while (val >= XFASTINT (limit)); |
| @@ -2613,6 +2617,7 @@ is not loaded; so load the file FILENAME. | |||
| 2613 | If FILENAME is omitted, the printname of FEATURE is used as the file name, | 2617 | If FILENAME is omitted, the printname of FEATURE is used as the file name, |
| 2614 | and `load' will try to load this name appended with the suffix `.elc' or | 2618 | and `load' will try to load this name appended with the suffix `.elc' or |
| 2615 | `.el', in that order. The name without appended suffix will not be used. | 2619 | `.el', in that order. The name without appended suffix will not be used. |
| 2620 | See `get-load-suffixes' for the complete list of suffixes. | ||
| 2616 | If the optional third argument NOERROR is non-nil, | 2621 | If the optional third argument NOERROR is non-nil, |
| 2617 | then return nil if the file is not found instead of signaling an error. | 2622 | then return nil if the file is not found instead of signaling an error. |
| 2618 | Normally the return value is FEATURE. | 2623 | Normally the return value is FEATURE. |
diff --git a/src/font.c b/src/font.c index 14390335f3c..5f8d22157d6 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -1738,8 +1738,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec | |||
| 1738 | #define LGSTRING_GLYPH_SIZE 8 | 1738 | #define LGSTRING_GLYPH_SIZE 8 |
| 1739 | 1739 | ||
| 1740 | static int | 1740 | static int |
| 1741 | check_gstring (gstring) | 1741 | check_gstring (Lisp_Object gstring) |
| 1742 | Lisp_Object gstring; | ||
| 1743 | { | 1742 | { |
| 1744 | Lisp_Object val; | 1743 | Lisp_Object val; |
| 1745 | int i, j; | 1744 | int i, j; |
| @@ -1793,8 +1792,7 @@ check_gstring (gstring) | |||
| 1793 | } | 1792 | } |
| 1794 | 1793 | ||
| 1795 | static void | 1794 | static void |
| 1796 | check_otf_features (otf_features) | 1795 | check_otf_features (Lisp_Object otf_features) |
| 1797 | Lisp_Object otf_features; | ||
| 1798 | { | 1796 | { |
| 1799 | Lisp_Object val; | 1797 | Lisp_Object val; |
| 1800 | 1798 | ||
| @@ -1827,8 +1825,7 @@ check_otf_features (otf_features) | |||
| 1827 | Lisp_Object otf_list; | 1825 | Lisp_Object otf_list; |
| 1828 | 1826 | ||
| 1829 | static Lisp_Object | 1827 | static Lisp_Object |
| 1830 | otf_tag_symbol (tag) | 1828 | otf_tag_symbol (OTF_Tag tag) |
| 1831 | OTF_Tag tag; | ||
| 1832 | { | 1829 | { |
| 1833 | char name[5]; | 1830 | char name[5]; |
| 1834 | 1831 | ||
| @@ -1837,8 +1834,7 @@ otf_tag_symbol (tag) | |||
| 1837 | } | 1834 | } |
| 1838 | 1835 | ||
| 1839 | static OTF * | 1836 | static OTF * |
| 1840 | otf_open (file) | 1837 | otf_open (Lisp_Object file) |
| 1841 | Lisp_Object file; | ||
| 1842 | { | 1838 | { |
| 1843 | Lisp_Object val = Fassoc (file, otf_list); | 1839 | Lisp_Object val = Fassoc (file, otf_list); |
| 1844 | OTF *otf; | 1840 | OTF *otf; |
| @@ -1860,8 +1856,7 @@ otf_open (file) | |||
| 1860 | (struct font_driver).otf_capability. */ | 1856 | (struct font_driver).otf_capability. */ |
| 1861 | 1857 | ||
| 1862 | Lisp_Object | 1858 | Lisp_Object |
| 1863 | font_otf_capability (font) | 1859 | font_otf_capability (struct font *font) |
| 1864 | struct font *font; | ||
| 1865 | { | 1860 | { |
| 1866 | OTF *otf; | 1861 | OTF *otf; |
| 1867 | Lisp_Object capability = Fcons (Qnil, Qnil); | 1862 | Lisp_Object capability = Fcons (Qnil, Qnil); |
| @@ -1935,9 +1930,7 @@ font_otf_capability (font) | |||
| 1935 | FEATURES. */ | 1930 | FEATURES. */ |
| 1936 | 1931 | ||
| 1937 | static void | 1932 | static void |
| 1938 | generate_otf_features (spec, features) | 1933 | generate_otf_features (Lisp_Object spec, char *features) |
| 1939 | Lisp_Object spec; | ||
| 1940 | char *features; | ||
| 1941 | { | 1934 | { |
| 1942 | Lisp_Object val; | 1935 | Lisp_Object val; |
| 1943 | char *p; | 1936 | char *p; |
| @@ -1972,8 +1965,7 @@ generate_otf_features (spec, features) | |||
| 1972 | } | 1965 | } |
| 1973 | 1966 | ||
| 1974 | Lisp_Object | 1967 | Lisp_Object |
| 1975 | font_otf_DeviceTable (device_table) | 1968 | font_otf_DeviceTable (OTF_DeviceTable *device_table) |
| 1976 | OTF_DeviceTable *device_table; | ||
| 1977 | { | 1969 | { |
| 1978 | int len = device_table->StartSize - device_table->EndSize + 1; | 1970 | int len = device_table->StartSize - device_table->EndSize + 1; |
| 1979 | 1971 | ||
| @@ -1982,9 +1974,7 @@ font_otf_DeviceTable (device_table) | |||
| 1982 | } | 1974 | } |
| 1983 | 1975 | ||
| 1984 | Lisp_Object | 1976 | Lisp_Object |
| 1985 | font_otf_ValueRecord (value_format, value_record) | 1977 | font_otf_ValueRecord (int value_format, OTF_ValueRecord *value_record) |
| 1986 | int value_format; | ||
| 1987 | OTF_ValueRecord *value_record; | ||
| 1988 | { | 1978 | { |
| 1989 | Lisp_Object val = Fmake_vector (make_number (8), Qnil); | 1979 | Lisp_Object val = Fmake_vector (make_number (8), Qnil); |
| 1990 | 1980 | ||
| @@ -2008,8 +1998,7 @@ font_otf_ValueRecord (value_format, value_record) | |||
| 2008 | } | 1998 | } |
| 2009 | 1999 | ||
| 2010 | Lisp_Object | 2000 | Lisp_Object |
| 2011 | font_otf_Anchor (anchor) | 2001 | font_otf_Anchor (OTF_Anchor *anchor) |
| 2012 | OTF_Anchor *anchor; | ||
| 2013 | { | 2002 | { |
| 2014 | Lisp_Object val; | 2003 | Lisp_Object val; |
| 2015 | 2004 | ||
| @@ -3739,8 +3728,9 @@ font_range (EMACS_INT pos, EMACS_INT *limit, struct window *w, struct face *face | |||
| 3739 | else | 3728 | else |
| 3740 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte); | 3729 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte); |
| 3741 | category = CHAR_TABLE_REF (Vunicode_category_table, c); | 3730 | category = CHAR_TABLE_REF (Vunicode_category_table, c); |
| 3742 | if (EQ (category, QCf) | 3731 | if (INTEGERP (category) |
| 3743 | || CHAR_VARIATION_SELECTOR_P (c)) | 3732 | && (XINT (category) == UNICODE_CATEGORY_Cf |
| 3733 | || CHAR_VARIATION_SELECTOR_P (c))) | ||
| 3744 | continue; | 3734 | continue; |
| 3745 | if (NILP (font_object)) | 3735 | if (NILP (font_object)) |
| 3746 | { | 3736 | { |
diff --git a/src/gnutls.c b/src/gnutls.c index 2a055ac40f0..3761951b866 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -143,10 +143,12 @@ static int | |||
| 143 | init_gnutls_functions (Lisp_Object libraries) | 143 | init_gnutls_functions (Lisp_Object libraries) |
| 144 | { | 144 | { |
| 145 | HMODULE library; | 145 | HMODULE library; |
| 146 | Lisp_Object gnutls_log_level = Fsymbol_value (Qgnutls_log_level); | ||
| 147 | int max_log_level = 1; | ||
| 146 | 148 | ||
| 147 | if (!(library = w32_delayed_load (libraries, Qgnutls_dll))) | 149 | if (!(library = w32_delayed_load (libraries, Qgnutls_dll))) |
| 148 | { | 150 | { |
| 149 | GNUTLS_LOG (1, 1, "GnuTLS library not found"); | 151 | GNUTLS_LOG (1, max_log_level, "GnuTLS library not found"); |
| 150 | return 0; | 152 | return 0; |
| 151 | } | 153 | } |
| 152 | 154 | ||
| @@ -189,7 +191,10 @@ init_gnutls_functions (Lisp_Object libraries) | |||
| 189 | LOAD_GNUTLS_FN (library, gnutls_x509_crt_import); | 191 | LOAD_GNUTLS_FN (library, gnutls_x509_crt_import); |
| 190 | LOAD_GNUTLS_FN (library, gnutls_x509_crt_init); | 192 | LOAD_GNUTLS_FN (library, gnutls_x509_crt_init); |
| 191 | 193 | ||
| 192 | GNUTLS_LOG2 (1, 1, "GnuTLS library loaded:", | 194 | if (NUMBERP (gnutls_log_level)) |
| 195 | max_log_level = XINT (gnutls_log_level); | ||
| 196 | |||
| 197 | GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:", | ||
| 193 | SDATA (Fget (Qgnutls_dll, QCloaded_from))); | 198 | SDATA (Fget (Qgnutls_dll, QCloaded_from))); |
| 194 | return 1; | 199 | return 1; |
| 195 | } | 200 | } |
| @@ -379,7 +384,7 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte) | |||
| 379 | /* non-fatal error */ | 384 | /* non-fatal error */ |
| 380 | return -1; | 385 | return -1; |
| 381 | else { | 386 | else { |
| 382 | /* a fatal error occured */ | 387 | /* a fatal error occurred */ |
| 383 | return 0; | 388 | return 0; |
| 384 | } | 389 | } |
| 385 | } | 390 | } |
| @@ -638,9 +643,6 @@ certificates for `gnutls-x509pki'. | |||
| 638 | :verify-flags is a bitset as per GnuTLS' | 643 | :verify-flags is a bitset as per GnuTLS' |
| 639 | gnutls_certificate_set_verify_flags. | 644 | gnutls_certificate_set_verify_flags. |
| 640 | 645 | ||
| 641 | :verify-error, if non-nil, makes failure of the certificate validation | ||
| 642 | an error. Otherwise it will be just a series of warnings. | ||
| 643 | |||
| 644 | :verify-hostname-error, if non-nil, makes a hostname mismatch an | 646 | :verify-hostname-error, if non-nil, makes a hostname mismatch an |
| 645 | error. Otherwise it will be just a warning. | 647 | error. Otherwise it will be just a warning. |
| 646 | 648 | ||
| @@ -1100,36 +1102,35 @@ syms_of_gnutls (void) | |||
| 1100 | { | 1102 | { |
| 1101 | gnutls_global_initialized = 0; | 1103 | gnutls_global_initialized = 0; |
| 1102 | 1104 | ||
| 1103 | DEFSYM(Qgnutls_dll, "gnutls"); | 1105 | DEFSYM (Qgnutls_dll, "gnutls"); |
| 1104 | DEFSYM(Qgnutls_log_level, "gnutls-log-level"); | 1106 | DEFSYM (Qgnutls_log_level, "gnutls-log-level"); |
| 1105 | DEFSYM(Qgnutls_code, "gnutls-code"); | 1107 | DEFSYM (Qgnutls_code, "gnutls-code"); |
| 1106 | DEFSYM(Qgnutls_anon, "gnutls-anon"); | 1108 | DEFSYM (Qgnutls_anon, "gnutls-anon"); |
| 1107 | DEFSYM(Qgnutls_x509pki, "gnutls-x509pki"); | 1109 | DEFSYM (Qgnutls_x509pki, "gnutls-x509pki"); |
| 1108 | DEFSYM(Qgnutls_bootprop_hostname, ":hostname"); | 1110 | DEFSYM (Qgnutls_bootprop_hostname, ":hostname"); |
| 1109 | DEFSYM(Qgnutls_bootprop_priority, ":priority"); | 1111 | DEFSYM (Qgnutls_bootprop_priority, ":priority"); |
| 1110 | DEFSYM(Qgnutls_bootprop_trustfiles, ":trustfiles"); | 1112 | DEFSYM (Qgnutls_bootprop_trustfiles, ":trustfiles"); |
| 1111 | DEFSYM(Qgnutls_bootprop_keylist, ":keylist"); | 1113 | DEFSYM (Qgnutls_bootprop_keylist, ":keylist"); |
| 1112 | DEFSYM(Qgnutls_bootprop_crlfiles, ":crlfiles"); | 1114 | DEFSYM (Qgnutls_bootprop_crlfiles, ":crlfiles"); |
| 1113 | DEFSYM(Qgnutls_bootprop_callbacks, ":callbacks"); | 1115 | DEFSYM (Qgnutls_bootprop_callbacks, ":callbacks"); |
| 1114 | DEFSYM(Qgnutls_bootprop_callbacks_verify, "verify"); | 1116 | DEFSYM (Qgnutls_bootprop_callbacks_verify, "verify"); |
| 1115 | DEFSYM(Qgnutls_bootprop_loglevel, ":loglevel"); | 1117 | DEFSYM (Qgnutls_bootprop_loglevel, ":loglevel"); |
| 1116 | DEFSYM(Qgnutls_bootprop_verify_flags, ":verify-flags"); | 1118 | DEFSYM (Qgnutls_bootprop_verify_flags, ":verify-flags"); |
| 1117 | DEFSYM(Qgnutls_bootprop_verify_hostname_error, ":verify-error"); | 1119 | DEFSYM (Qgnutls_bootprop_verify_hostname_error, ":verify-hostname-error"); |
| 1118 | DEFSYM(Qgnutls_bootprop_verify_hostname_error, ":verify-hostname-error"); | 1120 | |
| 1119 | 1121 | DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted"); | |
| 1120 | DEFSYM(Qgnutls_e_interrupted, "gnutls-e-interrupted"); | ||
| 1121 | Fput (Qgnutls_e_interrupted, Qgnutls_code, | 1122 | Fput (Qgnutls_e_interrupted, Qgnutls_code, |
| 1122 | make_number (GNUTLS_E_INTERRUPTED)); | 1123 | make_number (GNUTLS_E_INTERRUPTED)); |
| 1123 | 1124 | ||
| 1124 | DEFSYM(Qgnutls_e_again, "gnutls-e-again"); | 1125 | DEFSYM (Qgnutls_e_again, "gnutls-e-again"); |
| 1125 | Fput (Qgnutls_e_again, Qgnutls_code, | 1126 | Fput (Qgnutls_e_again, Qgnutls_code, |
| 1126 | make_number (GNUTLS_E_AGAIN)); | 1127 | make_number (GNUTLS_E_AGAIN)); |
| 1127 | 1128 | ||
| 1128 | DEFSYM(Qgnutls_e_invalid_session, "gnutls-e-invalid-session"); | 1129 | DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session"); |
| 1129 | Fput (Qgnutls_e_invalid_session, Qgnutls_code, | 1130 | Fput (Qgnutls_e_invalid_session, Qgnutls_code, |
| 1130 | make_number (GNUTLS_E_INVALID_SESSION)); | 1131 | make_number (GNUTLS_E_INVALID_SESSION)); |
| 1131 | 1132 | ||
| 1132 | DEFSYM(Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake"); | 1133 | DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake"); |
| 1133 | Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code, | 1134 | Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code, |
| 1134 | make_number (GNUTLS_E_APPLICATION_ERROR_MIN)); | 1135 | make_number (GNUTLS_E_APPLICATION_ERROR_MIN)); |
| 1135 | 1136 | ||
diff --git a/src/gtkutil.c b/src/gtkutil.c index 48571bef275..1a16246f2b8 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -633,6 +633,9 @@ qttip_cb (GtkWidget *widget, | |||
| 633 | struct x_output *x = f->output_data.x; | 633 | struct x_output *x = f->output_data.x; |
| 634 | if (x->ttip_widget == NULL) | 634 | if (x->ttip_widget == NULL) |
| 635 | { | 635 | { |
| 636 | GtkWidget *p; | ||
| 637 | GList *list, *iter; | ||
| 638 | |||
| 636 | g_object_set (G_OBJECT (widget), "has-tooltip", FALSE, NULL); | 639 | g_object_set (G_OBJECT (widget), "has-tooltip", FALSE, NULL); |
| 637 | x->ttip_widget = tooltip; | 640 | x->ttip_widget = tooltip; |
| 638 | g_object_ref (G_OBJECT (tooltip)); | 641 | g_object_ref (G_OBJECT (tooltip)); |
| @@ -640,6 +643,18 @@ qttip_cb (GtkWidget *widget, | |||
| 640 | g_object_ref (G_OBJECT (x->ttip_lbl)); | 643 | g_object_ref (G_OBJECT (x->ttip_lbl)); |
| 641 | gtk_tooltip_set_custom (tooltip, x->ttip_lbl); | 644 | gtk_tooltip_set_custom (tooltip, x->ttip_lbl); |
| 642 | x->ttip_window = GTK_WINDOW (gtk_widget_get_toplevel (x->ttip_lbl)); | 645 | x->ttip_window = GTK_WINDOW (gtk_widget_get_toplevel (x->ttip_lbl)); |
| 646 | |||
| 647 | /* Change stupid Gtk+ default line wrapping. */ | ||
| 648 | p = gtk_widget_get_parent (x->ttip_lbl); | ||
| 649 | list = gtk_container_get_children (GTK_CONTAINER (p)); | ||
| 650 | for (iter = list; iter; iter = g_list_next (iter)) | ||
| 651 | { | ||
| 652 | GtkWidget *w = GTK_WIDGET (iter->data); | ||
| 653 | if (GTK_IS_LABEL (w)) | ||
| 654 | gtk_label_set_line_wrap (GTK_LABEL (w), FALSE); | ||
| 655 | } | ||
| 656 | g_list_free (list); | ||
| 657 | |||
| 643 | /* ATK needs an empty title for some reason. */ | 658 | /* ATK needs an empty title for some reason. */ |
| 644 | gtk_window_set_title (x->ttip_window, ""); | 659 | gtk_window_set_title (x->ttip_window, ""); |
| 645 | /* Realize so we can safely get screen later on. */ | 660 | /* Realize so we can safely get screen later on. */ |
| @@ -659,8 +674,8 @@ qttip_cb (GtkWidget *widget, | |||
| 659 | 674 | ||
| 660 | int | 675 | int |
| 661 | xg_prepare_tooltip (FRAME_PTR f, | 676 | xg_prepare_tooltip (FRAME_PTR f, |
| 662 | Lisp_Object string, | 677 | Lisp_Object string, |
| 663 | int *width, | 678 | int *width, |
| 664 | int *height) | 679 | int *height) |
| 665 | { | 680 | { |
| 666 | #ifndef USE_GTK_TOOLTIP | 681 | #ifndef USE_GTK_TOOLTIP |
| @@ -697,10 +712,9 @@ xg_prepare_tooltip (FRAME_PTR f, | |||
| 697 | (gtk_widget_get_display (GTK_WIDGET (x->ttip_window))), | 712 | (gtk_widget_get_display (GTK_WIDGET (x->ttip_window))), |
| 698 | "gdk-display-current-tooltip", NULL); | 713 | "gdk-display-current-tooltip", NULL); |
| 699 | 714 | ||
| 700 | /* Put out dummy widget in so we can get callbacks for unrealize and | 715 | /* Put our dummy widget in so we can get callbacks for unrealize and |
| 701 | hierarchy-changed. */ | 716 | hierarchy-changed. */ |
| 702 | gtk_tooltip_set_custom (x->ttip_widget, widget); | 717 | gtk_tooltip_set_custom (x->ttip_widget, widget); |
| 703 | |||
| 704 | gtk_tooltip_set_text (x->ttip_widget, SSDATA (encoded_string)); | 718 | gtk_tooltip_set_text (x->ttip_widget, SSDATA (encoded_string)); |
| 705 | gtk_widget_get_preferred_size (GTK_WIDGET (x->ttip_window), NULL, &req); | 719 | gtk_widget_get_preferred_size (GTK_WIDGET (x->ttip_window), NULL, &req); |
| 706 | if (width) *width = req.width; | 720 | if (width) *width = req.width; |
| @@ -731,7 +745,7 @@ xg_show_tooltip (FRAME_PTR f, int root_x, int root_y) | |||
| 731 | } | 745 | } |
| 732 | 746 | ||
| 733 | /* Hide tooltip if shown. Do nothing if not shown. | 747 | /* Hide tooltip if shown. Do nothing if not shown. |
| 734 | Return non-zero if tip was hidden, non-ero if not (i.e. not using | 748 | Return non-zero if tip was hidden, non-zero if not (i.e. not using |
| 735 | system tooltips). */ | 749 | system tooltips). */ |
| 736 | 750 | ||
| 737 | int | 751 | int |
diff --git a/src/image.c b/src/image.c index 6e8440fb431..fa39ff12681 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -5007,9 +5007,7 @@ pbm_scan_number (unsigned char **s, unsigned char *end) | |||
| 5007 | occurred. *SIZE is set to the size of the file. */ | 5007 | occurred. *SIZE is set to the size of the file. */ |
| 5008 | 5008 | ||
| 5009 | static char * | 5009 | static char * |
| 5010 | pbm_read_file (file, size) | 5010 | pbm_read_file (Lisp_Object file, int *size) |
| 5011 | Lisp_Object file; | ||
| 5012 | int *size; | ||
| 5013 | { | 5011 | { |
| 5014 | FILE *fp = NULL; | 5012 | FILE *fp = NULL; |
| 5015 | char *buf = NULL; | 5013 | char *buf = NULL; |
diff --git a/src/indent.c b/src/indent.c index 02d99d14ded..aaeaaf591ef 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -725,8 +725,7 @@ current_column_1 (void) | |||
| 725 | If END is nil, that stands for the end of STRING. */ | 725 | If END is nil, that stands for the end of STRING. */ |
| 726 | 726 | ||
| 727 | static double | 727 | static double |
| 728 | string_display_width (string, beg, end) | 728 | string_display_width (Lisp_Object string, Lisp_Object beg, Lisp_Object end) |
| 729 | Lisp_Object string, beg, end; | ||
| 730 | { | 729 | { |
| 731 | register int col; | 730 | register int col; |
| 732 | register unsigned char *ptr, *stop; | 731 | register unsigned char *ptr, *stop; |
| @@ -1986,9 +1985,11 @@ whether or not it is currently displayed in some window. */) | |||
| 1986 | struct text_pos pt; | 1985 | struct text_pos pt; |
| 1987 | struct window *w; | 1986 | struct window *w; |
| 1988 | Lisp_Object old_buffer; | 1987 | Lisp_Object old_buffer; |
| 1989 | struct gcpro gcpro1; | 1988 | EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0); |
| 1989 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 1990 | Lisp_Object lcols = Qnil; | 1990 | Lisp_Object lcols = Qnil; |
| 1991 | double cols IF_LINT (= 0); | 1991 | double cols IF_LINT (= 0); |
| 1992 | void *itdata = NULL; | ||
| 1992 | 1993 | ||
| 1993 | /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ | 1994 | /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ |
| 1994 | if (CONSP (lines) && (NUMBERP (XCAR (lines)))) | 1995 | if (CONSP (lines) && (NUMBERP (XCAR (lines)))) |
| @@ -2006,12 +2007,16 @@ whether or not it is currently displayed in some window. */) | |||
| 2006 | w = XWINDOW (window); | 2007 | w = XWINDOW (window); |
| 2007 | 2008 | ||
| 2008 | old_buffer = Qnil; | 2009 | old_buffer = Qnil; |
| 2009 | GCPRO1 (old_buffer); | 2010 | GCPRO3 (old_buffer, old_charpos, old_bytepos); |
| 2010 | if (XBUFFER (w->buffer) != current_buffer) | 2011 | if (XBUFFER (w->buffer) != current_buffer) |
| 2011 | { | 2012 | { |
| 2012 | /* Set the window's buffer temporarily to the current buffer. */ | 2013 | /* Set the window's buffer temporarily to the current buffer. */ |
| 2013 | old_buffer = w->buffer; | 2014 | old_buffer = w->buffer; |
| 2015 | old_charpos = XMARKER (w->pointm)->charpos; | ||
| 2016 | old_bytepos = XMARKER (w->pointm)->bytepos; | ||
| 2014 | XSETBUFFER (w->buffer, current_buffer); | 2017 | XSETBUFFER (w->buffer, current_buffer); |
| 2018 | set_marker_both | ||
| 2019 | (w->pointm, w->buffer, BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer)); | ||
| 2015 | } | 2020 | } |
| 2016 | 2021 | ||
| 2017 | if (noninteractive) | 2022 | if (noninteractive) |
| @@ -2025,6 +2030,7 @@ whether or not it is currently displayed in some window. */) | |||
| 2025 | EMACS_INT it_start; | 2030 | EMACS_INT it_start; |
| 2026 | int first_x, it_overshoot_expected IF_LINT (= 0); | 2031 | int first_x, it_overshoot_expected IF_LINT (= 0); |
| 2027 | 2032 | ||
| 2033 | itdata = bidi_shelve_cache (); | ||
| 2028 | SET_TEXT_POS (pt, PT, PT_BYTE); | 2034 | SET_TEXT_POS (pt, PT, PT_BYTE); |
| 2029 | start_display (&it, w, pt); | 2035 | start_display (&it, w, pt); |
| 2030 | first_x = it.first_visible_x; | 2036 | first_x = it.first_visible_x; |
| @@ -2129,10 +2135,14 @@ whether or not it is currently displayed in some window. */) | |||
| 2129 | } | 2135 | } |
| 2130 | 2136 | ||
| 2131 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); | 2137 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); |
| 2138 | bidi_unshelve_cache (itdata); | ||
| 2132 | } | 2139 | } |
| 2133 | 2140 | ||
| 2134 | if (BUFFERP (old_buffer)) | 2141 | if (BUFFERP (old_buffer)) |
| 2135 | w->buffer = old_buffer; | 2142 | { |
| 2143 | w->buffer = old_buffer; | ||
| 2144 | set_marker_both (w->pointm, w->buffer, old_charpos, old_bytepos); | ||
| 2145 | } | ||
| 2136 | 2146 | ||
| 2137 | RETURN_UNGCPRO (make_number (it.vpos)); | 2147 | RETURN_UNGCPRO (make_number (it.vpos)); |
| 2138 | } | 2148 | } |
diff --git a/src/intervals.c b/src/intervals.c index 4de001f2ffc..2063655cdb9 100644 --- a/src/intervals.c +++ b/src/intervals.c | |||
| @@ -247,8 +247,7 @@ static int zero_length; | |||
| 247 | INTERVAL search_interval, found_interval; | 247 | INTERVAL search_interval, found_interval; |
| 248 | 248 | ||
| 249 | void | 249 | void |
| 250 | check_for_interval (i) | 250 | check_for_interval (INTERVAL i) |
| 251 | register INTERVAL i; | ||
| 252 | { | 251 | { |
| 253 | if (i == search_interval) | 252 | if (i == search_interval) |
| 254 | { | 253 | { |
| @@ -258,8 +257,7 @@ check_for_interval (i) | |||
| 258 | } | 257 | } |
| 259 | 258 | ||
| 260 | INTERVAL | 259 | INTERVAL |
| 261 | search_for_interval (i, tree) | 260 | search_for_interval (INTERVAL i, INTERVAL tree) |
| 262 | register INTERVAL i, tree; | ||
| 263 | { | 261 | { |
| 264 | icount = 0; | 262 | icount = 0; |
| 265 | search_interval = i; | 263 | search_interval = i; |
| @@ -269,8 +267,7 @@ search_for_interval (i, tree) | |||
| 269 | } | 267 | } |
| 270 | 268 | ||
| 271 | static void | 269 | static void |
| 272 | inc_interval_count (i) | 270 | inc_interval_count (INTERVAL i) |
| 273 | INTERVAL i; | ||
| 274 | { | 271 | { |
| 275 | icount++; | 272 | icount++; |
| 276 | if (LENGTH (i) == 0) | 273 | if (LENGTH (i) == 0) |
| @@ -280,8 +277,7 @@ inc_interval_count (i) | |||
| 280 | } | 277 | } |
| 281 | 278 | ||
| 282 | int | 279 | int |
| 283 | count_intervals (i) | 280 | count_intervals (INTERVAL i) |
| 284 | register INTERVAL i; | ||
| 285 | { | 281 | { |
| 286 | icount = 0; | 282 | icount = 0; |
| 287 | idepth = 0; | 283 | idepth = 0; |
| @@ -292,8 +288,7 @@ count_intervals (i) | |||
| 292 | } | 288 | } |
| 293 | 289 | ||
| 294 | static INTERVAL | 290 | static INTERVAL |
| 295 | root_interval (interval) | 291 | root_interval (INTERVAL interval) |
| 296 | INTERVAL interval; | ||
| 297 | { | 292 | { |
| 298 | register INTERVAL i = interval; | 293 | register INTERVAL i = interval; |
| 299 | 294 | ||
| @@ -804,9 +799,8 @@ update_interval (register INTERVAL i, EMACS_INT pos) | |||
| 804 | to the root. */ | 799 | to the root. */ |
| 805 | 800 | ||
| 806 | static INTERVAL | 801 | static INTERVAL |
| 807 | adjust_intervals_for_insertion (tree, position, length) | 802 | adjust_intervals_for_insertion (INTERVAL tree, EMACS_INT position, |
| 808 | INTERVAL tree; | 803 | EMACS_INT length) |
| 809 | EMACS_INT position, length; | ||
| 810 | { | 804 | { |
| 811 | register EMACS_INT relative_position; | 805 | register EMACS_INT relative_position; |
| 812 | register INTERVAL this; | 806 | register INTERVAL this; |
| @@ -1615,9 +1609,7 @@ reproduce_tree_obj (INTERVAL source, Lisp_Object parent) | |||
| 1615 | interval. */ | 1609 | interval. */ |
| 1616 | 1610 | ||
| 1617 | static INTERVAL | 1611 | static INTERVAL |
| 1618 | make_new_interval (intervals, start, length) | 1612 | make_new_interval (INTERVAL intervals, EMACS_INT start, EMACS_INT length) |
| 1619 | INTERVAL intervals; | ||
| 1620 | EMACS_INT start, length; | ||
| 1621 | { | 1613 | { |
| 1622 | INTERVAL slot; | 1614 | INTERVAL slot; |
| 1623 | 1615 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index 2d9643d455c..60c6283dab5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1540,7 +1540,18 @@ command_loop_1 (void) | |||
| 1540 | message_with_string ("%s is undefined", keys, 0); | 1540 | message_with_string ("%s is undefined", keys, 0); |
| 1541 | KVAR (current_kboard, defining_kbd_macro) = Qnil; | 1541 | KVAR (current_kboard, defining_kbd_macro) = Qnil; |
| 1542 | update_mode_lines = 1; | 1542 | update_mode_lines = 1; |
| 1543 | KVAR (current_kboard, Vprefix_arg) = Qnil; | 1543 | /* If this is a down-mouse event, don't reset prefix-arg; |
| 1544 | pass it to the command run by the up event. */ | ||
| 1545 | if (EVENT_HAS_PARAMETERS (last_command_event)) | ||
| 1546 | { | ||
| 1547 | Lisp_Object breakdown | ||
| 1548 | = parse_modifiers (EVENT_HEAD (last_command_event)); | ||
| 1549 | int modifiers = XINT (XCAR (XCDR (breakdown))); | ||
| 1550 | if (!(modifiers & down_modifier)) | ||
| 1551 | KVAR (current_kboard, Vprefix_arg) = Qnil; | ||
| 1552 | } | ||
| 1553 | else | ||
| 1554 | KVAR (current_kboard, Vprefix_arg) = Qnil; | ||
| 1544 | } | 1555 | } |
| 1545 | else | 1556 | else |
| 1546 | { | 1557 | { |
| @@ -7478,7 +7489,7 @@ menu_bar_items (Lisp_Object old) | |||
| 7478 | if (CONSP (def)) | 7489 | if (CONSP (def)) |
| 7479 | { | 7490 | { |
| 7480 | menu_bar_one_keymap_changed_items = Qnil; | 7491 | menu_bar_one_keymap_changed_items = Qnil; |
| 7481 | map_keymap (def, menu_bar_item, Qnil, NULL, 1); | 7492 | map_keymap_canonical (def, menu_bar_item, Qnil, NULL); |
| 7482 | } | 7493 | } |
| 7483 | } | 7494 | } |
| 7484 | 7495 | ||
| @@ -7819,7 +7830,7 @@ parse_menu_item (Lisp_Object item, int inmenubar) | |||
| 7819 | /* If we got no definition, this item is just unselectable text which | 7830 | /* If we got no definition, this item is just unselectable text which |
| 7820 | is OK in a submenu but not in the menubar. */ | 7831 | is OK in a submenu but not in the menubar. */ |
| 7821 | if (NILP (def)) | 7832 | if (NILP (def)) |
| 7822 | return (inmenubar ? 0 : 1); | 7833 | return (!inmenubar); |
| 7823 | 7834 | ||
| 7824 | /* See if this is a separate pane or a submenu. */ | 7835 | /* See if this is a separate pane or a submenu. */ |
| 7825 | def = AREF (item_properties, ITEM_PROPERTY_DEF); | 7836 | def = AREF (item_properties, ITEM_PROPERTY_DEF); |
| @@ -10640,7 +10651,8 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0, | |||
| 10640 | DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1, | 10651 | DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1, |
| 10641 | "FOpen dribble file: ", | 10652 | "FOpen dribble file: ", |
| 10642 | doc: /* Start writing all keyboard characters to a dribble file called FILE. | 10653 | doc: /* Start writing all keyboard characters to a dribble file called FILE. |
| 10643 | If FILE is nil, close any open dribble file. */) | 10654 | If FILE is nil, close any open dribble file. |
| 10655 | The file will be closed when Emacs exits. */) | ||
| 10644 | (Lisp_Object file) | 10656 | (Lisp_Object file) |
| 10645 | { | 10657 | { |
| 10646 | if (dribble) | 10658 | if (dribble) |
diff --git a/src/keymap.c b/src/keymap.c index ac7f651e283..0169276bef9 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -16,6 +16,27 @@ GNU General Public License for more details. | |||
| 16 | You should have received a copy of the GNU General Public License | 16 | You should have received a copy of the GNU General Public License |
| 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 18 | 18 | ||
| 19 | /* Old BUGS: | ||
| 20 | - [M-C-a] != [?\M-\C-a] | ||
| 21 | - [M-f2] != [?\e f2]. | ||
| 22 | - (define-key map [menu-bar foo] <bla>) does not always place <bla> | ||
| 23 | at the head of the menu (if `foo' was already bound earlier and | ||
| 24 | then unbound, for example). | ||
| 25 | TODO: | ||
| 26 | - allow many more Meta -> ESC mappings (like Hyper -> C-e for Emacspeak) | ||
| 27 | - Think about the various defaulting that's currently hard-coded in | ||
| 28 | keyboard.c (uppercase->lowercase, char->charset, button-events, ...) | ||
| 29 | and make it more generic. Maybe we should allow mappings of the | ||
| 30 | form (PREDICATE . BINDING) as generalization of the default binding, | ||
| 31 | tho probably a cleaner way to attack this is to allow functional | ||
| 32 | keymaps (i.e. keymaps that are implemented as functions that implement | ||
| 33 | a few different methods like `lookup', `map', ...). | ||
| 34 | - Make [a] equivalent to [?a]. | ||
| 35 | BEWARE: | ||
| 36 | - map-keymap should work meaningfully even if entries are added/removed | ||
| 37 | to the keymap while iterating through it: | ||
| 38 | start - removed <= visited <= start + added | ||
| 39 | */ | ||
| 19 | 40 | ||
| 20 | #include <config.h> | 41 | #include <config.h> |
| 21 | #include <stdio.h> | 42 | #include <stdio.h> |
| @@ -73,7 +94,6 @@ static Lisp_Object where_is_cache_keymaps; | |||
| 73 | 94 | ||
| 74 | static Lisp_Object Flookup_key (Lisp_Object, Lisp_Object, Lisp_Object); | 95 | static Lisp_Object Flookup_key (Lisp_Object, Lisp_Object, Lisp_Object); |
| 75 | static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object); | 96 | static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object); |
| 76 | static void fix_submap_inheritance (Lisp_Object, Lisp_Object, Lisp_Object); | ||
| 77 | 97 | ||
| 78 | static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object); | 98 | static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object); |
| 79 | static void describe_command (Lisp_Object, Lisp_Object); | 99 | static void describe_command (Lisp_Object, Lisp_Object); |
| @@ -130,6 +150,17 @@ in case you use it as a menu with `x-popup-menu'. */) | |||
| 130 | return Fcons (Qkeymap, Qnil); | 150 | return Fcons (Qkeymap, Qnil); |
| 131 | } | 151 | } |
| 132 | 152 | ||
| 153 | DEFUN ("make-composed-keymap", Fmake_composed_keymap, Smake_composed_keymap, | ||
| 154 | 0, MANY, 0, | ||
| 155 | doc: /* Construct and return a new keymap composed of KEYMAPS. | ||
| 156 | When looking up a key in the returned map, the key is looked in each | ||
| 157 | keymap in turn until a binding is found. | ||
| 158 | usage: (make-composed-keymap &rest KEYMAPS) */) | ||
| 159 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 160 | { | ||
| 161 | return Fcons (Qkeymap, Flist (nargs, args)); | ||
| 162 | } | ||
| 163 | |||
| 133 | /* This function is used for installing the standard key bindings | 164 | /* This function is used for installing the standard key bindings |
| 134 | at initialization time. | 165 | at initialization time. |
| 135 | 166 | ||
| @@ -174,6 +205,12 @@ when reading a key-sequence to be looked-up in this keymap. */) | |||
| 174 | Lisp_Object tem = XCAR (map); | 205 | Lisp_Object tem = XCAR (map); |
| 175 | if (STRINGP (tem)) | 206 | if (STRINGP (tem)) |
| 176 | return tem; | 207 | return tem; |
| 208 | else if (KEYMAPP (tem)) | ||
| 209 | { | ||
| 210 | tem = Fkeymap_prompt (tem); | ||
| 211 | if (!NILP (tem)) | ||
| 212 | return tem; | ||
| 213 | } | ||
| 177 | map = XCDR (map); | 214 | map = XCDR (map); |
| 178 | } | 215 | } |
| 179 | return Qnil; | 216 | return Qnil; |
| @@ -300,23 +337,16 @@ Return PARENT. PARENT should be nil or another keymap. */) | |||
| 300 | { | 337 | { |
| 301 | Lisp_Object list, prev; | 338 | Lisp_Object list, prev; |
| 302 | struct gcpro gcpro1, gcpro2; | 339 | struct gcpro gcpro1, gcpro2; |
| 303 | int i; | ||
| 304 | 340 | ||
| 305 | /* Force a keymap flush for the next call to where-is. | 341 | /* Flush any reverse-map cache. */ |
| 306 | Since this can be called from within where-is, we don't set where_is_cache | 342 | where_is_cache = Qnil; where_is_cache_keymaps = Qt; |
| 307 | directly but only where_is_cache_keymaps, since where_is_cache shouldn't | ||
| 308 | be changed during where-is, while where_is_cache_keymaps is only used at | ||
| 309 | the very beginning of where-is and can thus be changed here without any | ||
| 310 | adverse effect. | ||
| 311 | This is a very minor correctness (rather than safety) issue. */ | ||
| 312 | where_is_cache_keymaps = Qt; | ||
| 313 | 343 | ||
| 314 | GCPRO2 (keymap, parent); | 344 | GCPRO2 (keymap, parent); |
| 315 | keymap = get_keymap (keymap, 1, 1); | 345 | keymap = get_keymap (keymap, 1, 1); |
| 316 | 346 | ||
| 317 | if (!NILP (parent)) | 347 | if (!NILP (parent)) |
| 318 | { | 348 | { |
| 319 | parent = get_keymap (parent, 1, 1); | 349 | parent = get_keymap (parent, 1, 0); |
| 320 | 350 | ||
| 321 | /* Check for cycles. */ | 351 | /* Check for cycles. */ |
| 322 | if (keymap_memberp (keymap, parent)) | 352 | if (keymap_memberp (keymap, parent)) |
| @@ -332,121 +362,35 @@ Return PARENT. PARENT should be nil or another keymap. */) | |||
| 332 | If we came to the end, add the parent in PREV. */ | 362 | If we came to the end, add the parent in PREV. */ |
| 333 | if (!CONSP (list) || KEYMAPP (list)) | 363 | if (!CONSP (list) || KEYMAPP (list)) |
| 334 | { | 364 | { |
| 335 | /* If we already have the right parent, return now | ||
| 336 | so that we avoid the loops below. */ | ||
| 337 | if (EQ (XCDR (prev), parent)) | ||
| 338 | RETURN_UNGCPRO (parent); | ||
| 339 | |||
| 340 | CHECK_IMPURE (prev); | 365 | CHECK_IMPURE (prev); |
| 341 | XSETCDR (prev, parent); | 366 | XSETCDR (prev, parent); |
| 342 | break; | 367 | RETURN_UNGCPRO (parent); |
| 343 | } | 368 | } |
| 344 | prev = list; | 369 | prev = list; |
| 345 | } | 370 | } |
| 346 | |||
| 347 | /* Scan through for submaps, and set their parents too. */ | ||
| 348 | |||
| 349 | for (list = XCDR (keymap); CONSP (list); list = XCDR (list)) | ||
| 350 | { | ||
| 351 | /* Stop the scan when we come to the parent. */ | ||
| 352 | if (EQ (XCAR (list), Qkeymap)) | ||
| 353 | break; | ||
| 354 | |||
| 355 | /* If this element holds a prefix map, deal with it. */ | ||
| 356 | if (CONSP (XCAR (list)) | ||
| 357 | && CONSP (XCDR (XCAR (list)))) | ||
| 358 | fix_submap_inheritance (keymap, XCAR (XCAR (list)), | ||
| 359 | XCDR (XCAR (list))); | ||
| 360 | |||
| 361 | if (VECTORP (XCAR (list))) | ||
| 362 | for (i = 0; i < ASIZE (XCAR (list)); i++) | ||
| 363 | if (CONSP (XVECTOR (XCAR (list))->contents[i])) | ||
| 364 | fix_submap_inheritance (keymap, make_number (i), | ||
| 365 | XVECTOR (XCAR (list))->contents[i]); | ||
| 366 | |||
| 367 | if (CHAR_TABLE_P (XCAR (list))) | ||
| 368 | { | ||
| 369 | map_char_table (fix_submap_inheritance, Qnil, XCAR (list), keymap); | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | RETURN_UNGCPRO (parent); | ||
| 374 | } | ||
| 375 | |||
| 376 | /* EVENT is defined in MAP as a prefix, and SUBMAP is its definition. | ||
| 377 | if EVENT is also a prefix in MAP's parent, | ||
| 378 | make sure that SUBMAP inherits that definition as its own parent. */ | ||
| 379 | |||
| 380 | static void | ||
| 381 | fix_submap_inheritance (Lisp_Object map, Lisp_Object event, Lisp_Object submap) | ||
| 382 | { | ||
| 383 | Lisp_Object map_parent, parent_entry; | ||
| 384 | |||
| 385 | /* SUBMAP is a cons that we found as a key binding. | ||
| 386 | Discard the other things found in a menu key binding. */ | ||
| 387 | |||
| 388 | submap = get_keymap (get_keyelt (submap, 0), 0, 0); | ||
| 389 | |||
| 390 | /* If it isn't a keymap now, there's no work to do. */ | ||
| 391 | if (!CONSP (submap)) | ||
| 392 | return; | ||
| 393 | |||
| 394 | map_parent = keymap_parent (map, 0); | ||
| 395 | if (!NILP (map_parent)) | ||
| 396 | parent_entry = | ||
| 397 | get_keymap (access_keymap (map_parent, event, 0, 0, 0), 0, 0); | ||
| 398 | else | ||
| 399 | parent_entry = Qnil; | ||
| 400 | |||
| 401 | /* If MAP's parent has something other than a keymap, | ||
| 402 | our own submap shadows it completely. */ | ||
| 403 | if (!CONSP (parent_entry)) | ||
| 404 | return; | ||
| 405 | |||
| 406 | if (! EQ (parent_entry, submap)) | ||
| 407 | { | ||
| 408 | Lisp_Object submap_parent; | ||
| 409 | submap_parent = submap; | ||
| 410 | while (1) | ||
| 411 | { | ||
| 412 | Lisp_Object tem; | ||
| 413 | |||
| 414 | tem = keymap_parent (submap_parent, 0); | ||
| 415 | |||
| 416 | if (KEYMAPP (tem)) | ||
| 417 | { | ||
| 418 | if (keymap_memberp (tem, parent_entry)) | ||
| 419 | /* Fset_keymap_parent could create a cycle. */ | ||
| 420 | return; | ||
| 421 | submap_parent = tem; | ||
| 422 | } | ||
| 423 | else | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | Fset_keymap_parent (submap_parent, parent_entry); | ||
| 427 | } | ||
| 428 | } | 371 | } |
| 429 | 372 | ||
| 373 | |||
| 430 | /* Look up IDX in MAP. IDX may be any sort of event. | 374 | /* Look up IDX in MAP. IDX may be any sort of event. |
| 431 | Note that this does only one level of lookup; IDX must be a single | 375 | Note that this does only one level of lookup; IDX must be a single |
| 432 | event, not a sequence. | 376 | event, not a sequence. |
| 433 | 377 | ||
| 378 | MAP must be a keymap or a list of keymaps. | ||
| 379 | |||
| 434 | If T_OK is non-zero, bindings for Qt are treated as default | 380 | If T_OK is non-zero, bindings for Qt are treated as default |
| 435 | bindings; any key left unmentioned by other tables and bindings is | 381 | bindings; any key left unmentioned by other tables and bindings is |
| 436 | given the binding of Qt. | 382 | given the binding of Qt. |
| 437 | 383 | ||
| 438 | If T_OK is zero, bindings for Qt are not treated specially. | 384 | If T_OK is zero, bindings for Qt are not treated specially. |
| 439 | 385 | ||
| 440 | If NOINHERIT, don't accept a subkeymap found in an inherited keymap. */ | 386 | If NOINHERIT, don't accept a subkeymap found in an inherited keymap. |
| 441 | |||
| 442 | Lisp_Object | ||
| 443 | access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int autoload) | ||
| 444 | { | ||
| 445 | Lisp_Object val; | ||
| 446 | 387 | ||
| 447 | /* Qunbound in VAL means we have found no binding yet. */ | 388 | Returns Qunbound if no binding was found (and returns Qnil if a nil |
| 448 | val = Qunbound; | 389 | binding was found). */ |
| 449 | 390 | ||
| 391 | static Lisp_Object | ||
| 392 | access_keymap_1 (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int autoload) | ||
| 393 | { | ||
| 450 | /* If idx is a list (some sort of mouse click, perhaps?), | 394 | /* If idx is a list (some sort of mouse click, perhaps?), |
| 451 | the index we want to use is the car of the list, which | 395 | the index we want to use is the car of the list, which |
| 452 | ought to be a symbol. */ | 396 | ought to be a symbol. */ |
| @@ -461,21 +405,21 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au | |||
| 461 | with more than 24 bits of integer. */ | 405 | with more than 24 bits of integer. */ |
| 462 | XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); | 406 | XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); |
| 463 | 407 | ||
| 464 | /* Handle the special meta -> esc mapping. */ | 408 | /* Handle the special meta -> esc mapping. */ |
| 465 | if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier) | 409 | if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier) |
| 466 | { | 410 | { |
| 467 | /* See if there is a meta-map. If there's none, there is | 411 | /* See if there is a meta-map. If there's none, there is |
| 468 | no binding for IDX, unless a default binding exists in MAP. */ | 412 | no binding for IDX, unless a default binding exists in MAP. */ |
| 469 | struct gcpro gcpro1; | 413 | struct gcpro gcpro1; |
| 470 | Lisp_Object event_meta_map; | 414 | Lisp_Object event_meta_binding, event_meta_map; |
| 471 | GCPRO1 (map); | 415 | GCPRO1 (map); |
| 472 | /* A strange value in which Meta is set would cause | 416 | /* A strange value in which Meta is set would cause |
| 473 | infinite recursion. Protect against that. */ | 417 | infinite recursion. Protect against that. */ |
| 474 | if (XINT (meta_prefix_char) & CHAR_META) | 418 | if (XINT (meta_prefix_char) & CHAR_META) |
| 475 | meta_prefix_char = make_number (27); | 419 | meta_prefix_char = make_number (27); |
| 476 | event_meta_map = get_keymap (access_keymap (map, meta_prefix_char, | 420 | event_meta_binding = access_keymap_1 (map, meta_prefix_char, t_ok, |
| 477 | t_ok, noinherit, autoload), | 421 | noinherit, autoload); |
| 478 | 0, autoload); | 422 | event_meta_map = get_keymap (event_meta_binding, 0, autoload); |
| 479 | UNGCPRO; | 423 | UNGCPRO; |
| 480 | if (CONSP (event_meta_map)) | 424 | if (CONSP (event_meta_map)) |
| 481 | { | 425 | { |
| @@ -486,8 +430,8 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au | |||
| 486 | /* Set IDX to t, so that we only find a default binding. */ | 430 | /* Set IDX to t, so that we only find a default binding. */ |
| 487 | idx = Qt; | 431 | idx = Qt; |
| 488 | else | 432 | else |
| 489 | /* We know there is no binding. */ | 433 | /* An explicit nil binding, or no binding at all. */ |
| 490 | return Qnil; | 434 | return NILP (event_meta_binding) ? Qnil : Qunbound; |
| 491 | } | 435 | } |
| 492 | 436 | ||
| 493 | /* t_binding is where we put a default binding that applies, | 437 | /* t_binding is where we put a default binding that applies, |
| @@ -495,25 +439,52 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au | |||
| 495 | for this key sequence. */ | 439 | for this key sequence. */ |
| 496 | { | 440 | { |
| 497 | Lisp_Object tail; | 441 | Lisp_Object tail; |
| 498 | Lisp_Object t_binding = Qnil; | 442 | Lisp_Object t_binding = Qunbound; |
| 443 | Lisp_Object retval = Qunbound; | ||
| 444 | Lisp_Object retval_tail = Qnil; | ||
| 499 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 445 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 500 | 446 | ||
| 501 | GCPRO4 (map, tail, idx, t_binding); | 447 | GCPRO4 (tail, idx, t_binding, retval); |
| 502 | 448 | ||
| 503 | for (tail = XCDR (map); | 449 | for (tail = (CONSP (map) && EQ (Qkeymap, XCAR (map))) ? XCDR (map) : map; |
| 504 | (CONSP (tail) | 450 | (CONSP (tail) |
| 505 | || (tail = get_keymap (tail, 0, autoload), CONSP (tail))); | 451 | || (tail = get_keymap (tail, 0, autoload), CONSP (tail))); |
| 506 | tail = XCDR (tail)) | 452 | tail = XCDR (tail)) |
| 507 | { | 453 | { |
| 508 | Lisp_Object binding; | 454 | /* Qunbound in VAL means we have found no binding. */ |
| 455 | Lisp_Object val = Qunbound; | ||
| 456 | Lisp_Object binding = XCAR (tail); | ||
| 457 | Lisp_Object submap = get_keymap (binding, 0, autoload); | ||
| 509 | 458 | ||
| 510 | binding = XCAR (tail); | 459 | if (EQ (binding, Qkeymap)) |
| 511 | if (SYMBOLP (binding)) | 460 | { |
| 461 | if (noinherit || NILP (retval)) | ||
| 462 | /* If NOINHERIT, stop here, the rest is inherited. */ | ||
| 463 | break; | ||
| 464 | else if (!EQ (retval, Qunbound)) | ||
| 465 | { | ||
| 466 | Lisp_Object parent_entry; | ||
| 467 | eassert (KEYMAPP (retval)); | ||
| 468 | parent_entry | ||
| 469 | = get_keymap (access_keymap_1 (tail, idx, | ||
| 470 | t_ok, 0, autoload), | ||
| 471 | 0, autoload); | ||
| 472 | if (KEYMAPP (parent_entry)) | ||
| 473 | { | ||
| 474 | if (CONSP (retval_tail)) | ||
| 475 | XSETCDR (retval_tail, parent_entry); | ||
| 476 | else | ||
| 477 | { | ||
| 478 | retval_tail = Fcons (retval, parent_entry); | ||
| 479 | retval = Fcons (Qkeymap, retval_tail); | ||
| 480 | } | ||
| 481 | } | ||
| 482 | break; | ||
| 483 | } | ||
| 484 | } | ||
| 485 | else if (CONSP (submap)) | ||
| 512 | { | 486 | { |
| 513 | /* If NOINHERIT, stop finding prefix definitions | 487 | val = access_keymap_1 (submap, idx, t_ok, noinherit, autoload); |
| 514 | after we pass a second occurrence of the `keymap' symbol. */ | ||
| 515 | if (noinherit && EQ (binding, Qkeymap)) | ||
| 516 | RETURN_UNGCPRO (Qnil); | ||
| 517 | } | 488 | } |
| 518 | else if (CONSP (binding)) | 489 | else if (CONSP (binding)) |
| 519 | { | 490 | { |
| @@ -556,23 +527,47 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au | |||
| 556 | (i.e. it shadows any parent binding but not bindings in | 527 | (i.e. it shadows any parent binding but not bindings in |
| 557 | keymaps of lower precedence). */ | 528 | keymaps of lower precedence). */ |
| 558 | val = Qnil; | 529 | val = Qnil; |
| 530 | |||
| 559 | val = get_keyelt (val, autoload); | 531 | val = get_keyelt (val, autoload); |
| 560 | if (KEYMAPP (val)) | 532 | |
| 561 | fix_submap_inheritance (map, idx, val); | 533 | if (!KEYMAPP (val)) |
| 562 | RETURN_UNGCPRO (val); | 534 | { |
| 535 | if (NILP (retval) || EQ (retval, Qunbound)) | ||
| 536 | retval = val; | ||
| 537 | if (!NILP (val)) | ||
| 538 | break; /* Shadows everything that follows. */ | ||
| 539 | } | ||
| 540 | else if (NILP (retval) || EQ (retval, Qunbound)) | ||
| 541 | retval = val; | ||
| 542 | else if (CONSP (retval_tail)) | ||
| 543 | { | ||
| 544 | XSETCDR (retval_tail, Fcons (val, Qnil)); | ||
| 545 | retval_tail = XCDR (retval_tail); | ||
| 546 | } | ||
| 547 | else | ||
| 548 | { | ||
| 549 | retval_tail = Fcons (val, Qnil); | ||
| 550 | retval = Fcons (Qkeymap, Fcons (retval, retval_tail)); | ||
| 551 | } | ||
| 563 | } | 552 | } |
| 564 | QUIT; | 553 | QUIT; |
| 565 | } | 554 | } |
| 566 | UNGCPRO; | 555 | UNGCPRO; |
| 567 | return get_keyelt (t_binding, autoload); | 556 | return EQ (Qunbound, retval) ? get_keyelt (t_binding, autoload) : retval; |
| 568 | } | 557 | } |
| 569 | } | 558 | } |
| 570 | 559 | ||
| 560 | Lisp_Object | ||
| 561 | access_keymap (Lisp_Object map, Lisp_Object idx, | ||
| 562 | int t_ok, int noinherit, int autoload) | ||
| 563 | { | ||
| 564 | Lisp_Object val = access_keymap_1 (map, idx, t_ok, noinherit, autoload); | ||
| 565 | return EQ (val, Qunbound) ? Qnil : val; | ||
| 566 | } | ||
| 567 | |||
| 571 | static void | 568 | static void |
| 572 | map_keymap_item (map_keymap_function_t fun, Lisp_Object args, Lisp_Object key, Lisp_Object val, void *data) | 569 | map_keymap_item (map_keymap_function_t fun, Lisp_Object args, Lisp_Object key, Lisp_Object val, void *data) |
| 573 | { | 570 | { |
| 574 | /* We should maybe try to detect bindings shadowed by previous | ||
| 575 | ones and things like that. */ | ||
| 576 | if (EQ (val, Qt)) | 571 | if (EQ (val, Qt)) |
| 577 | val = Qnil; | 572 | val = Qnil; |
| 578 | (*fun) (key, val, args, data); | 573 | (*fun) (key, val, args, data); |
| @@ -583,8 +578,8 @@ map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val) | |||
| 583 | { | 578 | { |
| 584 | if (!NILP (val)) | 579 | if (!NILP (val)) |
| 585 | { | 580 | { |
| 586 | map_keymap_function_t fun = | 581 | map_keymap_function_t fun |
| 587 | (map_keymap_function_t) XSAVE_VALUE (XCAR (args))->pointer; | 582 | = (map_keymap_function_t) XSAVE_VALUE (XCAR (args))->pointer; |
| 588 | args = XCDR (args); | 583 | args = XCDR (args); |
| 589 | /* If the key is a range, make a copy since map_char_table modifies | 584 | /* If the key is a range, make a copy since map_char_table modifies |
| 590 | it in place. */ | 585 | it in place. */ |
| @@ -612,7 +607,9 @@ map_keymap_internal (Lisp_Object map, | |||
| 612 | { | 607 | { |
| 613 | Lisp_Object binding = XCAR (tail); | 608 | Lisp_Object binding = XCAR (tail); |
| 614 | 609 | ||
| 615 | if (CONSP (binding)) | 610 | if (KEYMAPP (binding)) /* An embedded parent. */ |
| 611 | break; | ||
| 612 | else if (CONSP (binding)) | ||
| 616 | map_keymap_item (fun, args, XCAR (binding), XCDR (binding), data); | 613 | map_keymap_item (fun, args, XCAR (binding), XCDR (binding), data); |
| 617 | else if (VECTORP (binding)) | 614 | else if (VECTORP (binding)) |
| 618 | { | 615 | { |
| @@ -644,7 +641,7 @@ map_keymap_call (Lisp_Object key, Lisp_Object val, Lisp_Object fun, void *dummy) | |||
| 644 | call2 (fun, key, val); | 641 | call2 (fun, key, val); |
| 645 | } | 642 | } |
| 646 | 643 | ||
| 647 | /* Same as map_keymap_internal, but doesn't traverses parent keymaps as well. | 644 | /* Same as map_keymap_internal, but traverses parent keymaps as well. |
| 648 | A non-zero AUTOLOAD indicates that autoloaded keymaps should be loaded. */ | 645 | A non-zero AUTOLOAD indicates that autoloaded keymaps should be loaded. */ |
| 649 | void | 646 | void |
| 650 | map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, void *data, int autoload) | 647 | map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, void *data, int autoload) |
| @@ -654,8 +651,15 @@ map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, void * | |||
| 654 | map = get_keymap (map, 1, autoload); | 651 | map = get_keymap (map, 1, autoload); |
| 655 | while (CONSP (map)) | 652 | while (CONSP (map)) |
| 656 | { | 653 | { |
| 657 | map = map_keymap_internal (map, fun, args, data); | 654 | if (KEYMAPP (XCAR (map))) |
| 658 | map = get_keymap (map, 0, autoload); | 655 | { |
| 656 | map_keymap (XCAR (map), fun, args, data, autoload); | ||
| 657 | map = XCDR (map); | ||
| 658 | } | ||
| 659 | else | ||
| 660 | map = map_keymap_internal (map, fun, args, data); | ||
| 661 | if (!CONSP (map)) | ||
| 662 | map = get_keymap (map, 0, autoload); | ||
| 659 | } | 663 | } |
| 660 | UNGCPRO; | 664 | UNGCPRO; |
| 661 | } | 665 | } |
| @@ -791,16 +795,10 @@ get_keyelt (Lisp_Object object, int autoload) | |||
| 791 | } | 795 | } |
| 792 | 796 | ||
| 793 | /* If the contents are (KEYMAP . ELEMENT), go indirect. */ | 797 | /* If the contents are (KEYMAP . ELEMENT), go indirect. */ |
| 798 | else if (KEYMAPP (XCAR (object))) | ||
| 799 | error ("Wow, indirect keymap entry!!"); | ||
| 794 | else | 800 | else |
| 795 | { | 801 | return object; |
| 796 | struct gcpro gcpro1; | ||
| 797 | Lisp_Object map; | ||
| 798 | GCPRO1 (object); | ||
| 799 | map = get_keymap (Fcar_safe (object), 0, autoload); | ||
| 800 | UNGCPRO; | ||
| 801 | return (!CONSP (map) ? object /* Invalid keymap */ | ||
| 802 | : access_keymap (map, Fcdr (object), 0, 0, autoload)); | ||
| 803 | } | ||
| 804 | } | 802 | } |
| 805 | } | 803 | } |
| 806 | 804 | ||
| @@ -811,6 +809,9 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def) | |||
| 811 | where_is_cache = Qnil; | 809 | where_is_cache = Qnil; |
| 812 | where_is_cache_keymaps = Qt; | 810 | where_is_cache_keymaps = Qt; |
| 813 | 811 | ||
| 812 | if (EQ (idx, Qkeymap)) | ||
| 813 | error ("`keymap' is reserved for embedded parent maps"); | ||
| 814 | |||
| 814 | /* If we are preparing to dump, and DEF is a menu element | 815 | /* If we are preparing to dump, and DEF is a menu element |
| 815 | with a menu item indicator, copy it to ensure it is not pure. */ | 816 | with a menu item indicator, copy it to ensure it is not pure. */ |
| 816 | if (CONSP (def) && PURE_P (def) | 817 | if (CONSP (def) && PURE_P (def) |
| @@ -903,7 +904,16 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def) | |||
| 903 | } | 904 | } |
| 904 | else if (CONSP (elt)) | 905 | else if (CONSP (elt)) |
| 905 | { | 906 | { |
| 906 | if (EQ (idx, XCAR (elt))) | 907 | if (EQ (Qkeymap, XCAR (elt))) |
| 908 | { /* A sub keymap. This might be due to a lookup that found | ||
| 909 | two matching bindings (maybe because of a sub keymap). | ||
| 910 | It almost never happens (since the second binding normally | ||
| 911 | only happens in the inherited part of the keymap), but | ||
| 912 | if it does, we want to update the sub-keymap since the | ||
| 913 | main one might be temporary (built by access_keymap). */ | ||
| 914 | tail = insertion_point = elt; | ||
| 915 | } | ||
| 916 | else if (EQ (idx, XCAR (elt))) | ||
| 907 | { | 917 | { |
| 908 | CHECK_IMPURE (elt); | 918 | CHECK_IMPURE (elt); |
| 909 | XSETCDR (elt, def); | 919 | XSETCDR (elt, def); |
| @@ -1068,7 +1078,13 @@ is not copied. */) | |||
| 1068 | ASET (elt, i, copy_keymap_item (AREF (elt, i))); | 1078 | ASET (elt, i, copy_keymap_item (AREF (elt, i))); |
| 1069 | } | 1079 | } |
| 1070 | else if (CONSP (elt)) | 1080 | else if (CONSP (elt)) |
| 1071 | elt = Fcons (XCAR (elt), copy_keymap_item (XCDR (elt))); | 1081 | { |
| 1082 | if (EQ (XCAR (elt), Qkeymap)) | ||
| 1083 | /* This is a sub keymap. */ | ||
| 1084 | elt = Fcopy_keymap (elt); | ||
| 1085 | else | ||
| 1086 | elt = Fcons (XCAR (elt), copy_keymap_item (XCDR (elt))); | ||
| 1087 | } | ||
| 1072 | XSETCDR (tail, Fcons (elt, Qnil)); | 1088 | XSETCDR (tail, Fcons (elt, Qnil)); |
| 1073 | tail = XCDR (tail); | 1089 | tail = XCDR (tail); |
| 1074 | keymap = XCDR (keymap); | 1090 | keymap = XCDR (keymap); |
| @@ -1234,23 +1250,15 @@ remapping in all currently active keymaps. */) | |||
| 1234 | ASET (command_remapping_vector, 1, command); | 1250 | ASET (command_remapping_vector, 1, command); |
| 1235 | 1251 | ||
| 1236 | if (NILP (keymaps)) | 1252 | if (NILP (keymaps)) |
| 1237 | return Fkey_binding (command_remapping_vector, Qnil, Qt, position); | 1253 | command = Fkey_binding (command_remapping_vector, Qnil, Qt, position); |
| 1238 | else | 1254 | else |
| 1239 | { | 1255 | command = Flookup_key (Fcons (Qkeymap, keymaps), |
| 1240 | Lisp_Object maps, binding; | 1256 | command_remapping_vector, Qnil); |
| 1241 | 1257 | return INTEGERP (command) ? Qnil : command; | |
| 1242 | for (maps = keymaps; CONSP (maps); maps = XCDR (maps)) | ||
| 1243 | { | ||
| 1244 | binding = Flookup_key (XCAR (maps), command_remapping_vector, Qnil); | ||
| 1245 | if (!NILP (binding) && !INTEGERP (binding)) | ||
| 1246 | return binding; | ||
| 1247 | } | ||
| 1248 | return Qnil; | ||
| 1249 | } | ||
| 1250 | } | 1258 | } |
| 1251 | 1259 | ||
| 1252 | /* Value is number if KEY is too long; nil if valid but has no definition. */ | 1260 | /* Value is number if KEY is too long; nil if valid but has no definition. */ |
| 1253 | /* GC is possible in this function if it autoloads a keymap. */ | 1261 | /* GC is possible in this function. */ |
| 1254 | 1262 | ||
| 1255 | DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0, | 1263 | DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0, |
| 1256 | doc: /* In keymap KEYMAP, look up key sequence KEY. Return the definition. | 1264 | doc: /* In keymap KEYMAP, look up key sequence KEY. Return the definition. |
| @@ -1325,10 +1333,6 @@ define_as_prefix (Lisp_Object keymap, Lisp_Object c) | |||
| 1325 | Lisp_Object cmd; | 1333 | Lisp_Object cmd; |
| 1326 | 1334 | ||
| 1327 | cmd = Fmake_sparse_keymap (Qnil); | 1335 | cmd = Fmake_sparse_keymap (Qnil); |
| 1328 | /* If this key is defined as a prefix in an inherited keymap, | ||
| 1329 | make it a prefix in this map, and make its definition | ||
| 1330 | inherit the other prefix definition. */ | ||
| 1331 | cmd = nconc2 (cmd, access_keymap (keymap, c, 0, 0, 0)); | ||
| 1332 | store_in_keymap (keymap, c, cmd); | 1336 | store_in_keymap (keymap, c, cmd); |
| 1333 | 1337 | ||
| 1334 | return cmd; | 1338 | return cmd; |
| @@ -1530,7 +1534,7 @@ like in the respective argument of `key-binding'. */) | |||
| 1530 | { | 1534 | { |
| 1531 | int count = SPECPDL_INDEX (); | 1535 | int count = SPECPDL_INDEX (); |
| 1532 | 1536 | ||
| 1533 | Lisp_Object keymaps; | 1537 | Lisp_Object keymaps = Fcons (current_global_map, Qnil); |
| 1534 | 1538 | ||
| 1535 | /* If a mouse click position is given, our variables are based on | 1539 | /* If a mouse click position is given, our variables are based on |
| 1536 | the buffer clicked on, not the current buffer. So we may have to | 1540 | the buffer clicked on, not the current buffer. So we may have to |
| @@ -1560,12 +1564,11 @@ like in the respective argument of `key-binding'. */) | |||
| 1560 | } | 1564 | } |
| 1561 | } | 1565 | } |
| 1562 | 1566 | ||
| 1563 | keymaps = Fcons (current_global_map, Qnil); | ||
| 1564 | |||
| 1565 | if (!NILP (olp)) | 1567 | if (!NILP (olp)) |
| 1566 | { | 1568 | { |
| 1567 | if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) | 1569 | if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) |
| 1568 | keymaps = Fcons (KVAR (current_kboard, Voverriding_terminal_local_map), keymaps); | 1570 | keymaps = Fcons (KVAR (current_kboard, Voverriding_terminal_local_map), |
| 1571 | keymaps); | ||
| 1569 | /* The doc said that overriding-terminal-local-map should | 1572 | /* The doc said that overriding-terminal-local-map should |
| 1570 | override overriding-local-map. The code used them both, | 1573 | override overriding-local-map. The code used them both, |
| 1571 | but it seems clearer to use just one. rms, jan 2005. */ | 1574 | but it seems clearer to use just one. rms, jan 2005. */ |
| @@ -1576,23 +1579,19 @@ like in the respective argument of `key-binding'. */) | |||
| 1576 | { | 1579 | { |
| 1577 | Lisp_Object *maps; | 1580 | Lisp_Object *maps; |
| 1578 | int nmaps, i; | 1581 | int nmaps, i; |
| 1579 | 1582 | EMACS_INT pt | |
| 1580 | Lisp_Object keymap, local_map; | 1583 | = INTEGERP (position) ? XINT (position) |
| 1581 | EMACS_INT pt; | ||
| 1582 | |||
| 1583 | pt = INTEGERP (position) ? XINT (position) | ||
| 1584 | : MARKERP (position) ? marker_position (position) | 1584 | : MARKERP (position) ? marker_position (position) |
| 1585 | : PT; | 1585 | : PT; |
| 1586 | 1586 | /* This usually returns the buffer's local map, | |
| 1587 | /* Get the buffer local maps, possibly overriden by text or | 1587 | but that can be overridden by a `local-map' property. */ |
| 1588 | overlay properties */ | 1588 | Lisp_Object local_map = get_local_map (pt, current_buffer, Qlocal_map); |
| 1589 | 1589 | /* This returns nil unless there is a `keymap' property. */ | |
| 1590 | local_map = get_local_map (pt, current_buffer, Qlocal_map); | 1590 | Lisp_Object keymap = get_local_map (pt, current_buffer, Qkeymap); |
| 1591 | keymap = get_local_map (pt, current_buffer, Qkeymap); | ||
| 1592 | 1591 | ||
| 1593 | if (CONSP (position)) | 1592 | if (CONSP (position)) |
| 1594 | { | 1593 | { |
| 1595 | Lisp_Object string; | 1594 | Lisp_Object string = POSN_STRING (position); |
| 1596 | 1595 | ||
| 1597 | /* For a mouse click, get the local text-property keymap | 1596 | /* For a mouse click, get the local text-property keymap |
| 1598 | of the place clicked on, rather than point. */ | 1597 | of the place clicked on, rather than point. */ |
| @@ -1619,8 +1618,7 @@ like in the respective argument of `key-binding'. */) | |||
| 1619 | consider `local-map' and `keymap' properties of | 1618 | consider `local-map' and `keymap' properties of |
| 1620 | that string. */ | 1619 | that string. */ |
| 1621 | 1620 | ||
| 1622 | if (string = POSN_STRING (position), | 1621 | if (CONSP (string) && STRINGP (XCAR (string))) |
| 1623 | (CONSP (string) && STRINGP (XCAR (string)))) | ||
| 1624 | { | 1622 | { |
| 1625 | Lisp_Object pos, map; | 1623 | Lisp_Object pos, map; |
| 1626 | 1624 | ||
| @@ -1691,12 +1689,7 @@ specified buffer position instead of point are used. | |||
| 1691 | */) | 1689 | */) |
| 1692 | (Lisp_Object key, Lisp_Object accept_default, Lisp_Object no_remap, Lisp_Object position) | 1690 | (Lisp_Object key, Lisp_Object accept_default, Lisp_Object no_remap, Lisp_Object position) |
| 1693 | { | 1691 | { |
| 1694 | Lisp_Object *maps, value; | 1692 | Lisp_Object value; |
| 1695 | int nmaps, i; | ||
| 1696 | struct gcpro gcpro1, gcpro2; | ||
| 1697 | int count = SPECPDL_INDEX (); | ||
| 1698 | |||
| 1699 | GCPRO2 (key, position); | ||
| 1700 | 1693 | ||
| 1701 | if (NILP (position) && VECTORP (key)) | 1694 | if (NILP (position) && VECTORP (key)) |
| 1702 | { | 1695 | { |
| @@ -1715,145 +1708,9 @@ specified buffer position instead of point are used. | |||
| 1715 | } | 1708 | } |
| 1716 | } | 1709 | } |
| 1717 | 1710 | ||
| 1718 | /* Key sequences beginning with mouse clicks | 1711 | value = Flookup_key (Fcons (Qkeymap, Fcurrent_active_maps (Qt, position)), |
| 1719 | are read using the keymaps of the buffer clicked on, not | 1712 | key, accept_default); |
| 1720 | the current buffer. So we may have to switch the buffer | ||
| 1721 | here. */ | ||
| 1722 | |||
| 1723 | if (CONSP (position)) | ||
| 1724 | { | ||
| 1725 | Lisp_Object window; | ||
| 1726 | 1713 | ||
| 1727 | window = POSN_WINDOW (position); | ||
| 1728 | |||
| 1729 | if (WINDOWP (window) | ||
| 1730 | && BUFFERP (XWINDOW (window)->buffer) | ||
| 1731 | && XBUFFER (XWINDOW (window)->buffer) != current_buffer) | ||
| 1732 | { | ||
| 1733 | /* Arrange to go back to the original buffer once we're done | ||
| 1734 | processing the key sequence. We don't use | ||
| 1735 | save_excursion_{save,restore} here, in analogy to | ||
| 1736 | `read-key-sequence' to avoid saving point. Maybe this | ||
| 1737 | would not be a problem here, but it is easier to keep | ||
| 1738 | things the same. | ||
| 1739 | */ | ||
| 1740 | |||
| 1741 | record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); | ||
| 1742 | |||
| 1743 | set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); | ||
| 1744 | } | ||
| 1745 | } | ||
| 1746 | |||
| 1747 | if (! NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) | ||
| 1748 | { | ||
| 1749 | value = Flookup_key (KVAR (current_kboard, Voverriding_terminal_local_map), | ||
| 1750 | key, accept_default); | ||
| 1751 | if (! NILP (value) && !INTEGERP (value)) | ||
| 1752 | goto done; | ||
| 1753 | } | ||
| 1754 | else if (! NILP (Voverriding_local_map)) | ||
| 1755 | { | ||
| 1756 | value = Flookup_key (Voverriding_local_map, key, accept_default); | ||
| 1757 | if (! NILP (value) && !INTEGERP (value)) | ||
| 1758 | goto done; | ||
| 1759 | } | ||
| 1760 | else | ||
| 1761 | { | ||
| 1762 | Lisp_Object keymap, local_map; | ||
| 1763 | EMACS_INT pt; | ||
| 1764 | |||
| 1765 | pt = INTEGERP (position) ? XINT (position) | ||
| 1766 | : MARKERP (position) ? marker_position (position) | ||
| 1767 | : PT; | ||
| 1768 | |||
| 1769 | local_map = get_local_map (pt, current_buffer, Qlocal_map); | ||
| 1770 | keymap = get_local_map (pt, current_buffer, Qkeymap); | ||
| 1771 | |||
| 1772 | if (CONSP (position)) | ||
| 1773 | { | ||
| 1774 | Lisp_Object string; | ||
| 1775 | |||
| 1776 | /* For a mouse click, get the local text-property keymap | ||
| 1777 | of the place clicked on, rather than point. */ | ||
| 1778 | |||
| 1779 | if (POSN_INBUFFER_P (position)) | ||
| 1780 | { | ||
| 1781 | Lisp_Object pos; | ||
| 1782 | |||
| 1783 | pos = POSN_BUFFER_POSN (position); | ||
| 1784 | if (INTEGERP (pos) | ||
| 1785 | && XINT (pos) >= BEG && XINT (pos) <= Z) | ||
| 1786 | { | ||
| 1787 | local_map = get_local_map (XINT (pos), | ||
| 1788 | current_buffer, Qlocal_map); | ||
| 1789 | |||
| 1790 | keymap = get_local_map (XINT (pos), | ||
| 1791 | current_buffer, Qkeymap); | ||
| 1792 | } | ||
| 1793 | } | ||
| 1794 | |||
| 1795 | /* If on a mode line string with a local keymap, | ||
| 1796 | or for a click on a string, i.e. overlay string or a | ||
| 1797 | string displayed via the `display' property, | ||
| 1798 | consider `local-map' and `keymap' properties of | ||
| 1799 | that string. */ | ||
| 1800 | |||
| 1801 | if (string = POSN_STRING (position), | ||
| 1802 | (CONSP (string) && STRINGP (XCAR (string)))) | ||
| 1803 | { | ||
| 1804 | Lisp_Object pos, map; | ||
| 1805 | |||
| 1806 | pos = XCDR (string); | ||
| 1807 | string = XCAR (string); | ||
| 1808 | if (INTEGERP (pos) | ||
| 1809 | && XINT (pos) >= 0 | ||
| 1810 | && XINT (pos) < SCHARS (string)) | ||
| 1811 | { | ||
| 1812 | map = Fget_text_property (pos, Qlocal_map, string); | ||
| 1813 | if (!NILP (map)) | ||
| 1814 | local_map = map; | ||
| 1815 | |||
| 1816 | map = Fget_text_property (pos, Qkeymap, string); | ||
| 1817 | if (!NILP (map)) | ||
| 1818 | keymap = map; | ||
| 1819 | } | ||
| 1820 | } | ||
| 1821 | |||
| 1822 | } | ||
| 1823 | |||
| 1824 | if (! NILP (keymap)) | ||
| 1825 | { | ||
| 1826 | value = Flookup_key (keymap, key, accept_default); | ||
| 1827 | if (! NILP (value) && !INTEGERP (value)) | ||
| 1828 | goto done; | ||
| 1829 | } | ||
| 1830 | |||
| 1831 | nmaps = current_minor_maps (0, &maps); | ||
| 1832 | /* Note that all these maps are GCPRO'd | ||
| 1833 | in the places where we found them. */ | ||
| 1834 | |||
| 1835 | for (i = 0; i < nmaps; i++) | ||
| 1836 | if (! NILP (maps[i])) | ||
| 1837 | { | ||
| 1838 | value = Flookup_key (maps[i], key, accept_default); | ||
| 1839 | if (! NILP (value) && !INTEGERP (value)) | ||
| 1840 | goto done; | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | if (! NILP (local_map)) | ||
| 1844 | { | ||
| 1845 | value = Flookup_key (local_map, key, accept_default); | ||
| 1846 | if (! NILP (value) && !INTEGERP (value)) | ||
| 1847 | goto done; | ||
| 1848 | } | ||
| 1849 | } | ||
| 1850 | |||
| 1851 | value = Flookup_key (current_global_map, key, accept_default); | ||
| 1852 | |||
| 1853 | done: | ||
| 1854 | unbind_to (count, Qnil); | ||
| 1855 | |||
| 1856 | UNGCPRO; | ||
| 1857 | if (NILP (value) || INTEGERP (value)) | 1714 | if (NILP (value) || INTEGERP (value)) |
| 1858 | return Qnil; | 1715 | return Qnil; |
| 1859 | 1716 | ||
| @@ -3094,9 +2951,11 @@ You type Translation\n\ | |||
| 3094 | to look through. | 2951 | to look through. |
| 3095 | 2952 | ||
| 3096 | If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW, | 2953 | If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW, |
| 3097 | don't omit it; instead, mention it but say it is shadowed. */ | 2954 | don't omit it; instead, mention it but say it is shadowed. |
| 3098 | 2955 | ||
| 3099 | void | 2956 | Return whether something was inserted or not. */ |
| 2957 | |||
| 2958 | int | ||
| 3100 | describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow, | 2959 | describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow, |
| 3101 | Lisp_Object prefix, const char *title, int nomenu, int transl, | 2960 | Lisp_Object prefix, const char *title, int nomenu, int transl, |
| 3102 | int always_title, int mention_shadow) | 2961 | int always_title, int mention_shadow) |
| @@ -3206,10 +3065,8 @@ key binding\n\ | |||
| 3206 | skip: ; | 3065 | skip: ; |
| 3207 | } | 3066 | } |
| 3208 | 3067 | ||
| 3209 | if (something) | ||
| 3210 | insert_string ("\n"); | ||
| 3211 | |||
| 3212 | UNGCPRO; | 3068 | UNGCPRO; |
| 3069 | return something; | ||
| 3213 | } | 3070 | } |
| 3214 | 3071 | ||
| 3215 | static int previous_description_column; | 3072 | static int previous_description_column; |
| @@ -3829,31 +3686,6 @@ don't alter it yourself. */); | |||
| 3829 | Vminibuffer_local_ns_map = Fmake_sparse_keymap (Qnil); | 3686 | Vminibuffer_local_ns_map = Fmake_sparse_keymap (Qnil); |
| 3830 | Fset_keymap_parent (Vminibuffer_local_ns_map, Vminibuffer_local_map); | 3687 | Fset_keymap_parent (Vminibuffer_local_ns_map, Vminibuffer_local_map); |
| 3831 | 3688 | ||
| 3832 | DEFVAR_LISP ("minibuffer-local-completion-map", Vminibuffer_local_completion_map, | ||
| 3833 | doc: /* Local keymap for minibuffer input with completion. */); | ||
| 3834 | Vminibuffer_local_completion_map = Fmake_sparse_keymap (Qnil); | ||
| 3835 | Fset_keymap_parent (Vminibuffer_local_completion_map, Vminibuffer_local_map); | ||
| 3836 | |||
| 3837 | DEFVAR_LISP ("minibuffer-local-filename-completion-map", | ||
| 3838 | Vminibuffer_local_filename_completion_map, | ||
| 3839 | doc: /* Local keymap for minibuffer input with completion for filenames. */); | ||
| 3840 | Vminibuffer_local_filename_completion_map = Fmake_sparse_keymap (Qnil); | ||
| 3841 | Fset_keymap_parent (Vminibuffer_local_filename_completion_map, | ||
| 3842 | Vminibuffer_local_completion_map); | ||
| 3843 | |||
| 3844 | |||
| 3845 | DEFVAR_LISP ("minibuffer-local-must-match-map", Vminibuffer_local_must_match_map, | ||
| 3846 | doc: /* Local keymap for minibuffer input with completion, for exact match. */); | ||
| 3847 | Vminibuffer_local_must_match_map = Fmake_sparse_keymap (Qnil); | ||
| 3848 | Fset_keymap_parent (Vminibuffer_local_must_match_map, | ||
| 3849 | Vminibuffer_local_completion_map); | ||
| 3850 | |||
| 3851 | DEFVAR_LISP ("minibuffer-local-filename-must-match-map", | ||
| 3852 | Vminibuffer_local_filename_must_match_map, | ||
| 3853 | doc: /* Local keymap for minibuffer input with completion for filenames with exact match. */); | ||
| 3854 | Vminibuffer_local_filename_must_match_map = Fmake_sparse_keymap (Qnil); | ||
| 3855 | Fset_keymap_parent (Vminibuffer_local_filename_must_match_map, | ||
| 3856 | Vminibuffer_local_must_match_map); | ||
| 3857 | 3689 | ||
| 3858 | DEFVAR_LISP ("minor-mode-map-alist", Vminor_mode_map_alist, | 3690 | DEFVAR_LISP ("minor-mode-map-alist", Vminor_mode_map_alist, |
| 3859 | doc: /* Alist of keymaps to use for minor modes. | 3691 | doc: /* Alist of keymaps to use for minor modes. |
| @@ -3880,11 +3712,11 @@ the same way. The "active" keymaps in each alist are used before | |||
| 3880 | Vemulation_mode_map_alists = Qnil; | 3712 | Vemulation_mode_map_alists = Qnil; |
| 3881 | 3713 | ||
| 3882 | DEFVAR_LISP ("where-is-preferred-modifier", Vwhere_is_preferred_modifier, | 3714 | DEFVAR_LISP ("where-is-preferred-modifier", Vwhere_is_preferred_modifier, |
| 3883 | doc: /* Preferred modifier to use for `where-is'. | 3715 | doc: /* Preferred modifier key to use for `where-is'. |
| 3884 | When a single binding is requested, `where-is' will return one that | 3716 | When a single binding is requested, `where-is' will return one that |
| 3885 | uses this modifier if possible. If nil, or if no such binding exists, | 3717 | uses this modifier key if possible. If nil, or if no such binding |
| 3886 | bindings using keys without modifiers (or only with meta) will be | 3718 | exists, bindings using keys without modifiers (or only with meta) will |
| 3887 | preferred. */); | 3719 | be preferred. */); |
| 3888 | Vwhere_is_preferred_modifier = Qnil; | 3720 | Vwhere_is_preferred_modifier = Qnil; |
| 3889 | where_is_preferred_modifier = 0; | 3721 | where_is_preferred_modifier = 0; |
| 3890 | 3722 | ||
| @@ -3922,6 +3754,7 @@ preferred. */); | |||
| 3922 | defsubr (&Sset_keymap_parent); | 3754 | defsubr (&Sset_keymap_parent); |
| 3923 | defsubr (&Smake_keymap); | 3755 | defsubr (&Smake_keymap); |
| 3924 | defsubr (&Smake_sparse_keymap); | 3756 | defsubr (&Smake_sparse_keymap); |
| 3757 | defsubr (&Smake_composed_keymap); | ||
| 3925 | defsubr (&Smap_keymap_internal); | 3758 | defsubr (&Smap_keymap_internal); |
| 3926 | defsubr (&Smap_keymap); | 3759 | defsubr (&Smap_keymap); |
| 3927 | defsubr (&Scopy_keymap); | 3760 | defsubr (&Scopy_keymap); |
diff --git a/src/keymap.h b/src/keymap.h index 2b9d58b39dc..2c826b64e1f 100644 --- a/src/keymap.h +++ b/src/keymap.h | |||
| @@ -36,8 +36,8 @@ EXFUN (Fcurrent_active_maps, 2); | |||
| 36 | extern Lisp_Object access_keymap (Lisp_Object, Lisp_Object, int, int, int); | 36 | extern Lisp_Object access_keymap (Lisp_Object, Lisp_Object, int, int, int); |
| 37 | extern Lisp_Object get_keymap (Lisp_Object, int, int); | 37 | extern Lisp_Object get_keymap (Lisp_Object, int, int); |
| 38 | EXFUN (Fset_keymap_parent, 2); | 38 | EXFUN (Fset_keymap_parent, 2); |
| 39 | extern void describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object, | 39 | extern int describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object, |
| 40 | const char *, int, int, int, int); | 40 | const char *, int, int, int, int); |
| 41 | extern int current_minor_maps (Lisp_Object **, Lisp_Object **); | 41 | extern int current_minor_maps (Lisp_Object **, Lisp_Object **); |
| 42 | extern void initial_define_key (Lisp_Object, int, const char *); | 42 | extern void initial_define_key (Lisp_Object, int, const char *); |
| 43 | extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); | 43 | extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); |
diff --git a/src/lread.c b/src/lread.c index f937fa39f0f..6cb217a21c6 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -4000,9 +4000,7 @@ defsubr (struct Lisp_Subr *sname) | |||
| 4000 | 4000 | ||
| 4001 | #ifdef NOTDEF /* use fset in subr.el now */ | 4001 | #ifdef NOTDEF /* use fset in subr.el now */ |
| 4002 | void | 4002 | void |
| 4003 | defalias (sname, string) | 4003 | defalias (struct Lisp_Subr *sname, char *string) |
| 4004 | struct Lisp_Subr *sname; | ||
| 4005 | char *string; | ||
| 4006 | { | 4004 | { |
| 4007 | Lisp_Object sym; | 4005 | Lisp_Object sym; |
| 4008 | sym = intern (string); | 4006 | sym = intern (string); |
| @@ -4420,9 +4418,11 @@ The remaining ENTRIES in the alist element describe the functions and | |||
| 4420 | variables defined in that file, the features provided, and the | 4418 | variables defined in that file, the features provided, and the |
| 4421 | features required. Each entry has the form `(provide . FEATURE)', | 4419 | features required. Each entry has the form `(provide . FEATURE)', |
| 4422 | `(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)', | 4420 | `(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)', |
| 4423 | `(defface . SYMBOL)', or `(t . SYMBOL)'. In addition, an entry `(t | 4421 | `(defface . SYMBOL)', or `(t . SYMBOL)'. Entries like `(t . SYMBOL)' |
| 4424 | . SYMBOL)' may precede an entry `(defun . FUNCTION)', and means that | 4422 | may precede a `(defun . FUNCTION)' entry, and means that SYMBOL was an |
| 4425 | SYMBOL was an autoload before this file redefined it as a function. | 4423 | autoload before this file redefined it as a function. In addition, |
| 4424 | entries may also be single symbols, which means that SYMBOL was | ||
| 4425 | defined by `defvar' or `defconst'. | ||
| 4426 | 4426 | ||
| 4427 | During preloading, the file name recorded is relative to the main Lisp | 4427 | During preloading, the file name recorded is relative to the main Lisp |
| 4428 | directory. These file names are converted to absolute at startup. */); | 4428 | directory. These file names are converted to absolute at startup. */); |
diff --git a/src/m/iris4d.h b/src/m/iris4d.h deleted file mode 100644 index 881f71f846f..00000000000 --- a/src/m/iris4d.h +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | /* machine description file for Iris-4D machines. Use with s/irix*.h. | ||
| 2 | |||
| 3 | Copyright (C) 1987, 2001-2011 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | |||
| 21 | /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which | ||
| 22 | were stored in a Lisp_Object (as Emacs uses fewer than 32 bits for | ||
| 23 | the value field of a LISP_OBJECT). */ | ||
| 24 | #define DATA_START 0x10000000 | ||
| 25 | #define DATA_SEG_BITS 0x10000000 | ||
| 26 | |||
diff --git a/src/nsfns.m b/src/nsfns.m index cdf350066be..0452086201e 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -162,7 +162,7 @@ check_ns_display_info (Lisp_Object frame) | |||
| 162 | struct terminal *t = get_terminal (frame, 1); | 162 | struct terminal *t = get_terminal (frame, 1); |
| 163 | 163 | ||
| 164 | if (t->type != output_ns) | 164 | if (t->type != output_ns) |
| 165 | error ("Terminal %d is not a Nextstep display", XINT (frame)); | 165 | error ("Terminal %ld is not a Nextstep display", (long) XINT (frame)); |
| 166 | 166 | ||
| 167 | return t->display_info.ns; | 167 | return t->display_info.ns; |
| 168 | } | 168 | } |
| @@ -1728,8 +1728,9 @@ terminate Emacs if we can't open the connection. | |||
| 1728 | 1728 | ||
| 1729 | /* Register our external input/output types, used for determining | 1729 | /* Register our external input/output types, used for determining |
| 1730 | applicable services and also drag/drop eligibility. */ | 1730 | applicable services and also drag/drop eligibility. */ |
| 1731 | ns_send_types = [[NSArray arrayWithObject: NSStringPboardType] retain]; | 1731 | ns_send_types = [[NSArray arrayWithObjects: NSStringPboardType, nil] retain]; |
| 1732 | ns_return_types = [[NSArray arrayWithObject: NSStringPboardType] retain]; | 1732 | ns_return_types = [[NSArray arrayWithObjects: NSStringPboardType, nil] |
| 1733 | retain]; | ||
| 1733 | ns_drag_types = [[NSArray arrayWithObjects: | 1734 | ns_drag_types = [[NSArray arrayWithObjects: |
| 1734 | NSStringPboardType, | 1735 | NSStringPboardType, |
| 1735 | NSTabularTextPboardType, | 1736 | NSTabularTextPboardType, |
| @@ -1876,6 +1877,10 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0, | |||
| 1876 | doc: /* List available Nextstep services by querying NSApp. */) | 1877 | doc: /* List available Nextstep services by querying NSApp. */) |
| 1877 | (void) | 1878 | (void) |
| 1878 | { | 1879 | { |
| 1880 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 | ||
| 1881 | /* You can't get services like this in 10.6+. */ | ||
| 1882 | return Qnil; | ||
| 1883 | #else | ||
| 1879 | Lisp_Object ret = Qnil; | 1884 | Lisp_Object ret = Qnil; |
| 1880 | NSMenu *svcs; | 1885 | NSMenu *svcs; |
| 1881 | id delegate; | 1886 | id delegate; |
| @@ -1919,6 +1924,7 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0, | |||
| 1919 | 1924 | ||
| 1920 | ret = interpret_services_menu (svcs, Qnil, ret); | 1925 | ret = interpret_services_menu (svcs, Qnil, ret); |
| 1921 | return ret; | 1926 | return ret; |
| 1927 | #endif | ||
| 1922 | } | 1928 | } |
| 1923 | 1929 | ||
| 1924 | 1930 | ||
diff --git a/src/nsgui.h b/src/nsgui.h index a6955630941..999dc27e310 100644 --- a/src/nsgui.h +++ b/src/nsgui.h | |||
| @@ -30,6 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 30 | #undef init_process | 30 | #undef init_process |
| 31 | #endif /* NS_IMPL_COCOA */ | 31 | #endif /* NS_IMPL_COCOA */ |
| 32 | 32 | ||
| 33 | #undef verify | ||
| 34 | |||
| 33 | #import <AppKit/AppKit.h> | 35 | #import <AppKit/AppKit.h> |
| 34 | 36 | ||
| 35 | #ifdef NS_IMPL_COCOA | 37 | #ifdef NS_IMPL_COCOA |
| @@ -44,6 +46,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 44 | 46 | ||
| 45 | #endif /* __OBJC__ */ | 47 | #endif /* __OBJC__ */ |
| 46 | 48 | ||
| 49 | #undef verify | ||
| 50 | #undef _GL_VERIFY_H | ||
| 51 | #include <verify.h> | ||
| 47 | 52 | ||
| 48 | /* menu-related */ | 53 | /* menu-related */ |
| 49 | #define free_widget_value(wv) xfree (wv) | 54 | #define free_widget_value(wv) xfree (wv) |
diff --git a/src/nsimage.m b/src/nsimage.m index c38cefdc5d5..2cb0c3bff76 100644 --- a/src/nsimage.m +++ b/src/nsimage.m | |||
| @@ -189,7 +189,11 @@ static EmacsImage *ImageList = nil; | |||
| 189 | image = [[EmacsImage alloc] initByReferencingFile: | 189 | image = [[EmacsImage alloc] initByReferencingFile: |
| 190 | [NSString stringWithUTF8String: SDATA (found)]]; | 190 | [NSString stringWithUTF8String: SDATA (found)]]; |
| 191 | 191 | ||
| 192 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 | ||
| 193 | imgRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]]; | ||
| 194 | #else | ||
| 192 | imgRep = [image bestRepresentationForDevice: nil]; | 195 | imgRep = [image bestRepresentationForDevice: nil]; |
| 196 | #endif | ||
| 193 | if (imgRep == nil) | 197 | if (imgRep == nil) |
| 194 | { | 198 | { |
| 195 | [image release]; | 199 | [image release]; |
diff --git a/src/nsmenu.m b/src/nsmenu.m index 2a2f952e751..6a9ee7dd4f5 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -457,7 +457,6 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu) | |||
| 457 | { | 457 | { |
| 458 | /* but we need to make sure it will update on demand */ | 458 | /* but we need to make sure it will update on demand */ |
| 459 | [svcsMenu setFrame: f]; | 459 | [svcsMenu setFrame: f]; |
| 460 | [svcsMenu setDelegate: svcsMenu]; | ||
| 461 | } | 460 | } |
| 462 | else | 461 | else |
| 463 | #endif | 462 | #endif |
| @@ -696,9 +695,11 @@ set_frame_menubar (struct frame *f, int first_time, int deep_p) | |||
| 696 | if ([[self window] isVisible]) | 695 | if ([[self window] isVisible]) |
| 697 | [self sizeToFit]; | 696 | [self sizeToFit]; |
| 698 | #else | 697 | #else |
| 698 | #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2 | ||
| 699 | if ([self supermenu] == nil) | 699 | if ([self supermenu] == nil) |
| 700 | [self sizeToFit]; | 700 | [self sizeToFit]; |
| 701 | #endif | 701 | #endif |
| 702 | #endif | ||
| 702 | } | 703 | } |
| 703 | 704 | ||
| 704 | 705 | ||
diff --git a/src/nsselect.m b/src/nsselect.m index 950fb1f1f14..867cf3252e5 100644 --- a/src/nsselect.m +++ b/src/nsselect.m | |||
| @@ -175,7 +175,7 @@ ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype) | |||
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | 177 | ||
| 178 | static Lisp_Object | 178 | Lisp_Object |
| 179 | ns_get_local_selection (Lisp_Object selection_name, | 179 | ns_get_local_selection (Lisp_Object selection_name, |
| 180 | Lisp_Object target_type) | 180 | Lisp_Object target_type) |
| 181 | { | 181 | { |
| @@ -352,16 +352,22 @@ ns_string_from_pasteboard (id pb) | |||
| 352 | utfStr = [mstr UTF8String]; | 352 | utfStr = [mstr UTF8String]; |
| 353 | length = [mstr lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; | 353 | length = [mstr lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; |
| 354 | 354 | ||
| 355 | #if ! defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4 | ||
| 355 | if (!utfStr) | 356 | if (!utfStr) |
| 356 | { | 357 | { |
| 357 | utfStr = [mstr cString]; | 358 | utfStr = [mstr cString]; |
| 358 | length = strlen (utfStr); | 359 | length = strlen (utfStr); |
| 359 | } | 360 | } |
| 361 | #endif | ||
| 360 | } | 362 | } |
| 361 | NS_HANDLER | 363 | NS_HANDLER |
| 362 | { | 364 | { |
| 363 | message1 ("ns_string_from_pasteboard: UTF8String failed\n"); | 365 | message1 ("ns_string_from_pasteboard: UTF8String failed\n"); |
| 366 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 | ||
| 367 | utfStr = "Conversion failed"; | ||
| 368 | #else | ||
| 364 | utfStr = [str lossyCString]; | 369 | utfStr = [str lossyCString]; |
| 370 | #endif | ||
| 365 | length = strlen (utfStr); | 371 | length = strlen (utfStr); |
| 366 | } | 372 | } |
| 367 | NS_ENDHANDLER | 373 | NS_ENDHANDLER |
diff --git a/src/nsterm.h b/src/nsterm.h index 7459087c988..f419391a11e 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -25,6 +25,21 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | 25 | ||
| 26 | #ifdef HAVE_NS | 26 | #ifdef HAVE_NS |
| 27 | 27 | ||
| 28 | #ifdef NS_IMPL_COCOA | ||
| 29 | #ifndef MAC_OS_X_VERSION_10_3 | ||
| 30 | #define MAC_OS_X_VERSION_10_3 1030 | ||
| 31 | #endif | ||
| 32 | #ifndef MAC_OS_X_VERSION_10_4 | ||
| 33 | #define MAC_OS_X_VERSION_10_4 1040 | ||
| 34 | #endif | ||
| 35 | #ifndef MAC_OS_X_VERSION_10_5 | ||
| 36 | #define MAC_OS_X_VERSION_10_5 1050 | ||
| 37 | #endif | ||
| 38 | #ifndef MAC_OS_X_VERSION_10_6 | ||
| 39 | #define MAC_OS_X_VERSION_10_6 1060 | ||
| 40 | #endif | ||
| 41 | #endif /* NS_IMPL_COCOA */ | ||
| 42 | |||
| 28 | #ifdef __OBJC__ | 43 | #ifdef __OBJC__ |
| 29 | 44 | ||
| 30 | /* ========================================================================== | 45 | /* ========================================================================== |
| @@ -55,7 +70,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 55 | 70 | ||
| 56 | @class EmacsToolbar; | 71 | @class EmacsToolbar; |
| 57 | 72 | ||
| 58 | @interface EmacsView : NSView <NSTextInput> /* 10.6+: NSWindowDelegate */ | 73 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 |
| 74 | @interface EmacsView : NSView <NSTextInput, NSWindowDelegate> | ||
| 75 | #else | ||
| 76 | @interface EmacsView : NSView <NSTextInput> | ||
| 77 | #endif | ||
| 59 | { | 78 | { |
| 60 | char *old_title; | 79 | char *old_title; |
| 61 | BOOL windowClosing; | 80 | BOOL windowClosing; |
| @@ -106,7 +125,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 106 | 125 | ||
| 107 | ========================================================================== */ | 126 | ========================================================================== */ |
| 108 | 127 | ||
| 109 | @interface EmacsMenu : NSMenu /* 10.6+: <NSMenuDelegate> */ | 128 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 |
| 129 | @interface EmacsMenu : NSMenu <NSMenuDelegate> | ||
| 130 | #else | ||
| 131 | @interface EmacsMenu : NSMenu | ||
| 132 | #endif | ||
| 110 | { | 133 | { |
| 111 | struct frame *frame; | 134 | struct frame *frame; |
| 112 | unsigned long keyEquivModMask; | 135 | unsigned long keyEquivModMask; |
| @@ -133,7 +156,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 133 | 156 | ||
| 134 | @class EmacsImage; | 157 | @class EmacsImage; |
| 135 | 158 | ||
| 136 | @interface EmacsToolbar : NSToolbar /* 10.6+: <NSToolbarDelegate> */ | 159 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 |
| 160 | @interface EmacsToolbar : NSToolbar <NSToolbarDelegate> | ||
| 161 | #else | ||
| 162 | @interface EmacsToolbar : NSToolbar | ||
| 163 | #endif | ||
| 137 | { | 164 | { |
| 138 | EmacsView *emacsView; | 165 | EmacsView *emacsView; |
| 139 | NSMutableDictionary *identifierToItem; | 166 | NSMutableDictionary *identifierToItem; |
| @@ -176,7 +203,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 176 | - (Lisp_Object)runDialogAt: (NSPoint)p; | 203 | - (Lisp_Object)runDialogAt: (NSPoint)p; |
| 177 | @end | 204 | @end |
| 178 | 205 | ||
| 179 | @interface EmacsTooltip : NSObject /* 10.6+: <NSWindowDelegate> */ | 206 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 |
| 207 | @interface EmacsTooltip : NSObject <NSWindowDelegate> | ||
| 208 | #else | ||
| 209 | @interface EmacsTooltip : NSObject | ||
| 210 | #endif | ||
| 180 | { | 211 | { |
| 181 | NSWindow *win; | 212 | NSWindow *win; |
| 182 | NSTextField *textField; | 213 | NSTextField *textField; |
| @@ -700,6 +731,8 @@ extern void check_ns (void); | |||
| 700 | extern Lisp_Object ns_map_event_to_object (); | 731 | extern Lisp_Object ns_map_event_to_object (); |
| 701 | extern Lisp_Object ns_string_from_pasteboard (); | 732 | extern Lisp_Object ns_string_from_pasteboard (); |
| 702 | extern void ns_string_to_pasteboard (); | 733 | extern void ns_string_to_pasteboard (); |
| 734 | extern Lisp_Object ns_get_local_selection (Lisp_Object selection_name, | ||
| 735 | Lisp_Object target_type); | ||
| 703 | extern void nxatoms_of_nsselect (); | 736 | extern void nxatoms_of_nsselect (); |
| 704 | extern int ns_lisp_to_cursor_type (); | 737 | extern int ns_lisp_to_cursor_type (); |
| 705 | extern Lisp_Object ns_cursor_type_to_lisp (int arg); | 738 | extern Lisp_Object ns_cursor_type_to_lisp (int arg); |
diff --git a/src/nsterm.m b/src/nsterm.m index 52e0dc6c2a8..546247ab74a 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -134,11 +134,12 @@ static unsigned convert_ns_to_X_keysym[] = | |||
| 134 | 0x1B, 0x1B /* escape */ | 134 | 0x1B, 0x1B /* escape */ |
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | |||
| 138 | static Lisp_Object Qmodifier_value; | 137 | static Lisp_Object Qmodifier_value; |
| 139 | Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone; | 138 | Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone; |
| 140 | extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft; | 139 | extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft; |
| 141 | 140 | ||
| 141 | static Lisp_Object QUTF8_STRING; | ||
| 142 | |||
| 142 | /* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold, | 143 | /* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold, |
| 143 | the maximum font size to NOT antialias. On GNUstep there is currently | 144 | the maximum font size to NOT antialias. On GNUstep there is currently |
| 144 | no way to control this behavior. */ | 145 | no way to control this behavior. */ |
| @@ -4514,7 +4515,9 @@ ns_term_shutdown (int sig) | |||
| 4514 | unsigned fnKeysym = 0; | 4515 | unsigned fnKeysym = 0; |
| 4515 | int flags; | 4516 | int flags; |
| 4516 | static NSMutableArray *nsEvArray; | 4517 | static NSMutableArray *nsEvArray; |
| 4518 | #if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 | ||
| 4517 | static BOOL firstTime = YES; | 4519 | static BOOL firstTime = YES; |
| 4520 | #endif | ||
| 4518 | int left_is_none; | 4521 | int left_is_none; |
| 4519 | 4522 | ||
| 4520 | NSTRACE (keyDown); | 4523 | NSTRACE (keyDown); |
| @@ -4702,13 +4705,15 @@ ns_term_shutdown (int sig) | |||
| 4702 | } | 4705 | } |
| 4703 | } | 4706 | } |
| 4704 | 4707 | ||
| 4708 | |||
| 4709 | #if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 | ||
| 4705 | /* if we get here we should send the key for input manager processing */ | 4710 | /* if we get here we should send the key for input manager processing */ |
| 4706 | if (firstTime && [[NSInputManager currentInputManager] | 4711 | if (firstTime && [[NSInputManager currentInputManager] |
| 4707 | wantsToDelayTextChangeNotifications] == NO) | 4712 | wantsToDelayTextChangeNotifications] == NO) |
| 4708 | fprintf (stderr, | 4713 | fprintf (stderr, |
| 4709 | "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n"); | 4714 | "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n"); |
| 4710 | firstTime = NO; | 4715 | firstTime = NO; |
| 4711 | 4716 | #endif | |
| 4712 | if (NS_KEYLOG && !processingCompose) | 4717 | if (NS_KEYLOG && !processingCompose) |
| 4713 | fprintf (stderr, "keyDown: Begin compose sequence.\n"); | 4718 | fprintf (stderr, "keyDown: Begin compose sequence.\n"); |
| 4714 | 4719 | ||
| @@ -5364,6 +5369,9 @@ ns_term_shutdown (int sig) | |||
| 5364 | 5369 | ||
| 5365 | [self allocateGState]; | 5370 | [self allocateGState]; |
| 5366 | 5371 | ||
| 5372 | [NSApp registerServicesMenuSendTypes: ns_send_types | ||
| 5373 | returnTypes: nil]; | ||
| 5374 | |||
| 5367 | ns_window_num++; | 5375 | ns_window_num++; |
| 5368 | return self; | 5376 | return self; |
| 5369 | } | 5377 | } |
| @@ -5735,13 +5743,16 @@ ns_term_shutdown (int sig) | |||
| 5735 | } | 5743 | } |
| 5736 | 5744 | ||
| 5737 | 5745 | ||
| 5738 | - validRequestorForSendType: (NSString *)typeSent | 5746 | - (id) validRequestorForSendType: (NSString *)typeSent |
| 5739 | returnType: (NSString *)typeReturned | 5747 | returnType: (NSString *)typeReturned |
| 5740 | { | 5748 | { |
| 5741 | NSTRACE (validRequestorForSendType); | 5749 | NSTRACE (validRequestorForSendType); |
| 5742 | if ([ns_send_types indexOfObjectIdenticalTo: typeSent] != NSNotFound && | 5750 | if (typeSent != nil && [ns_send_types indexOfObject: typeSent] != NSNotFound |
| 5743 | [ns_return_types indexOfObjectIdenticalTo: typeSent] != NSNotFound) | 5751 | && typeReturned == nil) |
| 5744 | return self; | 5752 | { |
| 5753 | if (! NILP (ns_get_local_selection (QPRIMARY, QUTF8_STRING))) | ||
| 5754 | return self; | ||
| 5755 | } | ||
| 5745 | 5756 | ||
| 5746 | return [super validRequestorForSendType: typeSent | 5757 | return [super validRequestorForSendType: typeSent |
| 5747 | returnType: typeReturned]; | 5758 | returnType: typeReturned]; |
| @@ -5765,8 +5776,28 @@ ns_term_shutdown (int sig) | |||
| 5765 | 5776 | ||
| 5766 | - (BOOL) writeSelectionToPasteboard: (NSPasteboard *)pb types: (NSArray *)types | 5777 | - (BOOL) writeSelectionToPasteboard: (NSPasteboard *)pb types: (NSArray *)types |
| 5767 | { | 5778 | { |
| 5768 | /* supposed to write for as many of types as we are able */ | 5779 | NSArray *typesDeclared; |
| 5769 | return NO; | 5780 | Lisp_Object val; |
| 5781 | |||
| 5782 | /* We only support NSStringPboardType */ | ||
| 5783 | if ([types containsObject:NSStringPboardType] == NO) { | ||
| 5784 | return NO; | ||
| 5785 | } | ||
| 5786 | |||
| 5787 | val = ns_get_local_selection (QPRIMARY, QUTF8_STRING); | ||
| 5788 | if (CONSP (val) && SYMBOLP (XCAR (val))) | ||
| 5789 | { | ||
| 5790 | val = XCDR (val); | ||
| 5791 | if (CONSP (val) && NILP (XCDR (val))) | ||
| 5792 | val = XCAR (val); | ||
| 5793 | } | ||
| 5794 | if (! STRINGP (val)) | ||
| 5795 | return NO; | ||
| 5796 | |||
| 5797 | typesDeclared = [NSArray arrayWithObject:NSStringPboardType]; | ||
| 5798 | [pb declareTypes:typesDeclared owner:nil]; | ||
| 5799 | ns_string_to_pasteboard (pb, val); | ||
| 5800 | return YES; | ||
| 5770 | } | 5801 | } |
| 5771 | 5802 | ||
| 5772 | 5803 | ||
| @@ -6038,14 +6069,26 @@ ns_term_shutdown (int sig) | |||
| 6038 | em_whole = whole; | 6069 | em_whole = whole; |
| 6039 | 6070 | ||
| 6040 | if (portion >= whole) | 6071 | if (portion >= whole) |
| 6041 | [self setFloatValue: 0.0 knobProportion: 1.0]; | 6072 | { |
| 6073 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 | ||
| 6074 | [self setKnobProportion: 1.0]; | ||
| 6075 | [self setDoubleValue: 1.0]; | ||
| 6076 | #else | ||
| 6077 | [self setFloatValue: 0.0 knobProportion: 1.0]; | ||
| 6078 | #endif | ||
| 6079 | } | ||
| 6042 | else | 6080 | else |
| 6043 | { | 6081 | { |
| 6044 | float pos, por; | 6082 | float pos, por; |
| 6045 | portion = max ((float)whole*min_portion/pixel_height, portion); | 6083 | portion = max ((float)whole*min_portion/pixel_height, portion); |
| 6046 | pos = (float)position / (whole - portion); | 6084 | pos = (float)position / (whole - portion); |
| 6047 | por = (float)portion/whole; | 6085 | por = (float)portion/whole; |
| 6086 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 | ||
| 6087 | [self setKnobProportion: por]; | ||
| 6088 | [self setDoubleValue: pos]; | ||
| 6089 | #else | ||
| 6048 | [self setFloatValue: pos knobProportion: por]; | 6090 | [self setFloatValue: pos knobProportion: por]; |
| 6091 | #endif | ||
| 6049 | } | 6092 | } |
| 6050 | return self; | 6093 | return self; |
| 6051 | } | 6094 | } |
| @@ -6390,6 +6433,8 @@ syms_of_nsterm (void) | |||
| 6390 | DEFSYM (Qsuper, "super"); | 6433 | DEFSYM (Qsuper, "super"); |
| 6391 | DEFSYM (Qcontrol, "control"); | 6434 | DEFSYM (Qcontrol, "control"); |
| 6392 | DEFSYM (Qnone, "none"); | 6435 | DEFSYM (Qnone, "none"); |
| 6436 | DEFSYM (QUTF8_STRING, "UTF8_STRING"); | ||
| 6437 | |||
| 6393 | Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); | 6438 | Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); |
| 6394 | Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); | 6439 | Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); |
| 6395 | Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); | 6440 | Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); |
diff --git a/src/process.c b/src/process.c index 0fe7068af3b..1a884357b86 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -102,9 +102,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 102 | #include "gnutls.h" | 102 | #include "gnutls.h" |
| 103 | #endif | 103 | #endif |
| 104 | 104 | ||
| 105 | #if defined (USE_GTK) || defined (HAVE_GCONF) | 105 | #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) |
| 106 | #include "xgselect.h" | 106 | #include "xgselect.h" |
| 107 | #endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ | 107 | #endif |
| 108 | #ifdef HAVE_NS | 108 | #ifdef HAVE_NS |
| 109 | #include "nsterm.h" | 109 | #include "nsterm.h" |
| 110 | #endif | 110 | #endif |
| @@ -1652,7 +1652,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1652 | sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); | 1652 | sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); |
| 1653 | #endif | 1653 | #endif |
| 1654 | #endif /* HAVE_WORKING_VFORK */ | 1654 | #endif /* HAVE_WORKING_VFORK */ |
| 1655 | sigprocmask (SIG_BLOCK, &blocked, &procmask); | 1655 | pthread_sigmask (SIG_BLOCK, &blocked, &procmask); |
| 1656 | 1656 | ||
| 1657 | FD_SET (inchannel, &input_wait_mask); | 1657 | FD_SET (inchannel, &input_wait_mask); |
| 1658 | FD_SET (inchannel, &non_keyboard_wait_mask); | 1658 | FD_SET (inchannel, &non_keyboard_wait_mask); |
| @@ -1808,7 +1808,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1808 | signal (SIGPIPE, SIG_DFL); | 1808 | signal (SIGPIPE, SIG_DFL); |
| 1809 | 1809 | ||
| 1810 | /* Stop blocking signals in the child. */ | 1810 | /* Stop blocking signals in the child. */ |
| 1811 | sigprocmask (SIG_SETMASK, &procmask, 0); | 1811 | pthread_sigmask (SIG_SETMASK, &procmask, 0); |
| 1812 | 1812 | ||
| 1813 | if (pty_flag) | 1813 | if (pty_flag) |
| 1814 | child_setup_tty (xforkout); | 1814 | child_setup_tty (xforkout); |
| @@ -1900,7 +1900,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1900 | #endif | 1900 | #endif |
| 1901 | #endif /* HAVE_WORKING_VFORK */ | 1901 | #endif /* HAVE_WORKING_VFORK */ |
| 1902 | /* Stop blocking signals in the parent. */ | 1902 | /* Stop blocking signals in the parent. */ |
| 1903 | sigprocmask (SIG_SETMASK, &procmask, 0); | 1903 | pthread_sigmask (SIG_SETMASK, &procmask, 0); |
| 1904 | 1904 | ||
| 1905 | /* Now generate the error if vfork failed. */ | 1905 | /* Now generate the error if vfork failed. */ |
| 1906 | if (pid < 0) | 1906 | if (pid < 0) |
| @@ -4527,7 +4527,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, | |||
| 4527 | process_output_skip = 0; | 4527 | process_output_skip = 0; |
| 4528 | } | 4528 | } |
| 4529 | #endif | 4529 | #endif |
| 4530 | #if defined (USE_GTK) || defined (HAVE_GCONF) | 4530 | #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) |
| 4531 | nfds = xg_select | 4531 | nfds = xg_select |
| 4532 | #elif defined (HAVE_NS) | 4532 | #elif defined (HAVE_NS) |
| 4533 | nfds = ns_select | 4533 | nfds = ns_select |
diff --git a/src/ralloc.c b/src/ralloc.c index 9c601a0ac24..64a47416202 100644 --- a/src/ralloc.c +++ b/src/ralloc.c | |||
| @@ -1079,7 +1079,7 @@ r_alloc_reinit (void) | |||
| 1079 | #include <assert.h> | 1079 | #include <assert.h> |
| 1080 | 1080 | ||
| 1081 | void | 1081 | void |
| 1082 | r_alloc_check () | 1082 | r_alloc_check (void) |
| 1083 | { | 1083 | { |
| 1084 | int found = 0; | 1084 | int found = 0; |
| 1085 | heap_ptr h, ph = 0; | 1085 | heap_ptr h, ph = 0; |
diff --git a/src/regex.c b/src/regex.c index 479239897bc..625c59ccf0b 100644 --- a/src/regex.c +++ b/src/regex.c | |||
| @@ -2202,10 +2202,9 @@ extend_range_table_work_area (struct range_table_work_area *work_area) | |||
| 2202 | Returns -1 if successful, REG_ESPACE if ran out of space. */ | 2202 | Returns -1 if successful, REG_ESPACE if ran out of space. */ |
| 2203 | 2203 | ||
| 2204 | static int | 2204 | static int |
| 2205 | set_image_of_range_1 (work_area, start, end, translate) | 2205 | set_image_of_range_1 (struct range_table_work_area *work_area, |
| 2206 | RE_TRANSLATE_TYPE translate; | 2206 | re_wchar_t start, re_wchar_t end, |
| 2207 | struct range_table_work_area *work_area; | 2207 | RE_TRANSLATE_TYPE translate) |
| 2208 | re_wchar_t start, end; | ||
| 2209 | { | 2208 | { |
| 2210 | /* `one_case' indicates a character, or a run of characters, | 2209 | /* `one_case' indicates a character, or a run of characters, |
| 2211 | each of which is an isolate (no case-equivalents). | 2210 | each of which is an isolate (no case-equivalents). |
| @@ -2355,10 +2354,9 @@ set_image_of_range_1 (work_area, start, end, translate) | |||
| 2355 | Returns -1 if successful, REG_ESPACE if ran out of space. */ | 2354 | Returns -1 if successful, REG_ESPACE if ran out of space. */ |
| 2356 | 2355 | ||
| 2357 | static int | 2356 | static int |
| 2358 | set_image_of_range (work_area, start, end, translate) | 2357 | set_image_of_range (struct range_table_work_area *work_area, |
| 2359 | RE_TRANSLATE_TYPE translate; | 2358 | re_wchar_t start, re_wchar_t end, |
| 2360 | struct range_table_work_area *work_area; | 2359 | RE_TRANSLATE_TYPE translate) |
| 2361 | re_wchar_t start, end; | ||
| 2362 | { | 2360 | { |
| 2363 | re_wchar_t cmin, cmax; | 2361 | re_wchar_t cmin, cmax; |
| 2364 | 2362 | ||
| @@ -2445,8 +2443,7 @@ static re_char **best_regstart, **best_regend; | |||
| 2445 | but don't make them smaller. */ | 2443 | but don't make them smaller. */ |
| 2446 | 2444 | ||
| 2447 | static | 2445 | static |
| 2448 | regex_grow_registers (num_regs) | 2446 | regex_grow_registers (int num_regs) |
| 2449 | int num_regs; | ||
| 2450 | { | 2447 | { |
| 2451 | if (num_regs > regs_allocated_size) | 2448 | if (num_regs > regs_allocated_size) |
| 2452 | { | 2449 | { |
diff --git a/src/s/irix6-5.h b/src/s/irix6-5.h index d283571d8fb..26eb7dcde77 100644 --- a/src/s/irix6-5.h +++ b/src/s/irix6-5.h | |||
| @@ -96,3 +96,10 @@ char *_getpty(); | |||
| 96 | /* Tested on Irix 6.5. SCM worked on earlier versions. */ | 96 | /* Tested on Irix 6.5. SCM worked on earlier versions. */ |
| 97 | #define GC_SETJMP_WORKS 1 | 97 | #define GC_SETJMP_WORKS 1 |
| 98 | #define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS | 98 | #define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS |
| 99 | |||
| 100 | |||
| 101 | /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which | ||
| 102 | were stored in a Lisp_Object (as Emacs uses fewer than 32 bits for | ||
| 103 | the value field of a LISP_OBJECT). */ | ||
| 104 | #define DATA_START 0x10000000 | ||
| 105 | #define DATA_SEG_BITS 0x10000000 | ||
diff --git a/src/search.c b/src/search.c index d29a51c695b..a56df784cd2 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -2284,6 +2284,10 @@ The match found must start at or after that position. | |||
| 2284 | Optional third argument, if t, means if fail just return nil (no error). | 2284 | Optional third argument, if t, means if fail just return nil (no error). |
| 2285 | If not nil and not t, move to limit of search and return nil. | 2285 | If not nil and not t, move to limit of search and return nil. |
| 2286 | Optional fourth argument is repeat count--search for successive occurrences. | 2286 | Optional fourth argument is repeat count--search for successive occurrences. |
| 2287 | |||
| 2288 | Search case-sensitivity is determined by the value of the variable | ||
| 2289 | `case-fold-search', which see. | ||
| 2290 | |||
| 2287 | See also the functions `match-beginning', `match-end', `match-string', | 2291 | See also the functions `match-beginning', `match-end', `match-string', |
| 2288 | and `replace-match'. */) | 2292 | and `replace-match'. */) |
| 2289 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) | 2293 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) |
| @@ -2300,6 +2304,10 @@ The match found must not extend after that position. | |||
| 2300 | Optional third argument, if t, means if fail just return nil (no error). | 2304 | Optional third argument, if t, means if fail just return nil (no error). |
| 2301 | If not nil and not t, move to limit of search and return nil. | 2305 | If not nil and not t, move to limit of search and return nil. |
| 2302 | Optional fourth argument is repeat count--search for successive occurrences. | 2306 | Optional fourth argument is repeat count--search for successive occurrences. |
| 2307 | |||
| 2308 | Search case-sensitivity is determined by the value of the variable | ||
| 2309 | `case-fold-search', which see. | ||
| 2310 | |||
| 2303 | See also the functions `match-beginning', `match-end', `match-string', | 2311 | See also the functions `match-beginning', `match-end', `match-string', |
| 2304 | and `replace-match'. */) | 2312 | and `replace-match'. */) |
| 2305 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) | 2313 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) |
| @@ -2319,6 +2327,10 @@ The match found must start at or after that position. | |||
| 2319 | Optional third argument, if t, means if fail just return nil (no error). | 2327 | Optional third argument, if t, means if fail just return nil (no error). |
| 2320 | If not nil and not t, move to limit of search and return nil. | 2328 | If not nil and not t, move to limit of search and return nil. |
| 2321 | Optional fourth argument is repeat count--search for successive occurrences. | 2329 | Optional fourth argument is repeat count--search for successive occurrences. |
| 2330 | |||
| 2331 | Search case-sensitivity is determined by the value of the variable | ||
| 2332 | `case-fold-search', which see. | ||
| 2333 | |||
| 2322 | See also the functions `match-beginning', `match-end', `match-string', | 2334 | See also the functions `match-beginning', `match-end', `match-string', |
| 2323 | and `replace-match'. */) | 2335 | and `replace-match'. */) |
| 2324 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) | 2336 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) |
| @@ -2336,6 +2348,10 @@ The match found must not extend after that position. | |||
| 2336 | Optional third argument, if t, means if fail just return nil (no error). | 2348 | Optional third argument, if t, means if fail just return nil (no error). |
| 2337 | If not nil and not t, move to limit of search and return nil. | 2349 | If not nil and not t, move to limit of search and return nil. |
| 2338 | Optional fourth argument is repeat count--search for successive occurrences. | 2350 | Optional fourth argument is repeat count--search for successive occurrences. |
| 2351 | |||
| 2352 | Search case-sensitivity is determined by the value of the variable | ||
| 2353 | `case-fold-search', which see. | ||
| 2354 | |||
| 2339 | See also the functions `match-beginning', `match-end', `match-string', | 2355 | See also the functions `match-beginning', `match-end', `match-string', |
| 2340 | and `replace-match'. */) | 2356 | and `replace-match'. */) |
| 2341 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) | 2357 | (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) |
diff --git a/src/sysdep.c b/src/sysdep.c index 3a73b1a467b..fc2f846b0dc 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -1534,7 +1534,7 @@ sigset_t | |||
| 1534 | sys_sigblock (sigset_t new_mask) | 1534 | sys_sigblock (sigset_t new_mask) |
| 1535 | { | 1535 | { |
| 1536 | sigset_t old_mask; | 1536 | sigset_t old_mask; |
| 1537 | sigprocmask (SIG_BLOCK, &new_mask, &old_mask); | 1537 | pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask); |
| 1538 | return (old_mask); | 1538 | return (old_mask); |
| 1539 | } | 1539 | } |
| 1540 | 1540 | ||
| @@ -1542,7 +1542,7 @@ sigset_t | |||
| 1542 | sys_sigunblock (sigset_t new_mask) | 1542 | sys_sigunblock (sigset_t new_mask) |
| 1543 | { | 1543 | { |
| 1544 | sigset_t old_mask; | 1544 | sigset_t old_mask; |
| 1545 | sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask); | 1545 | pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask); |
| 1546 | return (old_mask); | 1546 | return (old_mask); |
| 1547 | } | 1547 | } |
| 1548 | 1548 | ||
| @@ -1550,7 +1550,7 @@ sigset_t | |||
| 1550 | sys_sigsetmask (sigset_t new_mask) | 1550 | sys_sigsetmask (sigset_t new_mask) |
| 1551 | { | 1551 | { |
| 1552 | sigset_t old_mask; | 1552 | sigset_t old_mask; |
| 1553 | sigprocmask (SIG_SETMASK, &new_mask, &old_mask); | 1553 | pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask); |
| 1554 | return (old_mask); | 1554 | return (old_mask); |
| 1555 | } | 1555 | } |
| 1556 | 1556 | ||
| @@ -1783,7 +1783,8 @@ seed_random (long int arg) | |||
| 1783 | } | 1783 | } |
| 1784 | 1784 | ||
| 1785 | /* | 1785 | /* |
| 1786 | * Build a full Emacs-sized word out of whatever we've got. | 1786 | * Return a nonnegative random integer out of whatever we've got. |
| 1787 | * It contains enough bits to make a random (signed) Emacs fixnum. | ||
| 1787 | * This suffices even for a 64-bit architecture with a 15-bit rand. | 1788 | * This suffices even for a 64-bit architecture with a 15-bit rand. |
| 1788 | */ | 1789 | */ |
| 1789 | EMACS_INT | 1790 | EMACS_INT |
| @@ -1791,16 +1792,17 @@ get_random (void) | |||
| 1791 | { | 1792 | { |
| 1792 | EMACS_UINT val = 0; | 1793 | EMACS_UINT val = 0; |
| 1793 | int i; | 1794 | int i; |
| 1794 | for (i = 0; i < (VALBITS + RAND_BITS - 1) / RAND_BITS; i++) | 1795 | for (i = 0; i < (FIXNUM_BITS + RAND_BITS - 1) / RAND_BITS; i++) |
| 1795 | val = (val << RAND_BITS) ^ random (); | 1796 | val = (random () ^ (val << RAND_BITS) |
| 1796 | return val & (((EMACS_INT) 1 << VALBITS) - 1); | 1797 | ^ (val >> (BITS_PER_EMACS_INT - RAND_BITS))); |
| 1798 | val ^= val >> (BITS_PER_EMACS_INT - FIXNUM_BITS); | ||
| 1799 | return val & INTMASK; | ||
| 1797 | } | 1800 | } |
| 1798 | 1801 | ||
| 1799 | #ifndef HAVE_STRERROR | 1802 | #ifndef HAVE_STRERROR |
| 1800 | #ifndef WINDOWSNT | 1803 | #ifndef WINDOWSNT |
| 1801 | char * | 1804 | char * |
| 1802 | strerror (errnum) | 1805 | strerror (int errnum) |
| 1803 | int errnum; | ||
| 1804 | { | 1806 | { |
| 1805 | extern char *sys_errlist[]; | 1807 | extern char *sys_errlist[]; |
| 1806 | extern int sys_nerr; | 1808 | extern int sys_nerr; |
diff --git a/src/term.c b/src/term.c index 9205719b5f4..22056451cb9 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -1546,7 +1546,8 @@ produce_glyphs (struct it *it) | |||
| 1546 | /* Nothing but characters are supported on terminal frames. */ | 1546 | /* Nothing but characters are supported on terminal frames. */ |
| 1547 | xassert (it->what == IT_CHARACTER | 1547 | xassert (it->what == IT_CHARACTER |
| 1548 | || it->what == IT_COMPOSITION | 1548 | || it->what == IT_COMPOSITION |
| 1549 | || it->what == IT_STRETCH); | 1549 | || it->what == IT_STRETCH |
| 1550 | || it->what == IT_GLYPHLESS); | ||
| 1550 | 1551 | ||
| 1551 | if (it->what == IT_STRETCH) | 1552 | if (it->what == IT_STRETCH) |
| 1552 | { | 1553 | { |
| @@ -3096,7 +3097,6 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) | |||
| 3096 | char *area = NULL; | 3097 | char *area = NULL; |
| 3097 | char **address = &area; | 3098 | char **address = &area; |
| 3098 | int buffer_size = 4096; | 3099 | int buffer_size = 4096; |
| 3099 | register char *p = NULL; | ||
| 3100 | int status; | 3100 | int status; |
| 3101 | struct tty_display_info *tty = NULL; | 3101 | struct tty_display_info *tty = NULL; |
| 3102 | struct terminal *terminal = NULL; | 3102 | struct terminal *terminal = NULL; |
| @@ -3504,55 +3504,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ | |||
| 3504 | Down (tty) = 0; | 3504 | Down (tty) = 0; |
| 3505 | } | 3505 | } |
| 3506 | 3506 | ||
| 3507 | /* Special handling for certain terminal types known to need it */ | ||
| 3508 | |||
| 3509 | if (!strcmp (terminal_type, "supdup")) | ||
| 3510 | { | ||
| 3511 | terminal->memory_below_frame = 1; | ||
| 3512 | tty->Wcm->cm_losewrap = 1; | ||
| 3513 | } | ||
| 3514 | if (!strncmp (terminal_type, "c10", 3) | ||
| 3515 | || !strcmp (terminal_type, "perq")) | ||
| 3516 | { | ||
| 3517 | /* Supply a makeshift :wi string. | ||
| 3518 | This string is not valid in general since it works only | ||
| 3519 | for windows starting at the upper left corner; | ||
| 3520 | but that is all Emacs uses. | ||
| 3521 | |||
| 3522 | This string works only if the frame is using | ||
| 3523 | the top of the video memory, because addressing is memory-relative. | ||
| 3524 | So first check the :ti string to see if that is true. | ||
| 3525 | |||
| 3526 | It would be simpler if the :wi string could go in the termcap | ||
| 3527 | entry, but it can't because it is not fully valid. | ||
| 3528 | If it were in the termcap entry, it would confuse other programs. */ | ||
| 3529 | if (!tty->TS_set_window) | ||
| 3530 | { | ||
| 3531 | const char *m = tty->TS_termcap_modes; | ||
| 3532 | while (*m && strcmp (m, "\033v ")) | ||
| 3533 | m++; | ||
| 3534 | if (*m) | ||
| 3535 | tty->TS_set_window = "\033v%C %C %C %C "; | ||
| 3536 | } | ||
| 3537 | /* Termcap entry often fails to have :in: flag */ | ||
| 3538 | terminal->must_write_spaces = 1; | ||
| 3539 | /* :ti string typically fails to have \E^G! in it */ | ||
| 3540 | /* This limits scope of insert-char to one line. */ | ||
| 3541 | strcpy (area, tty->TS_termcap_modes); | ||
| 3542 | strcat (area, "\033\007!"); | ||
| 3543 | tty->TS_termcap_modes = area; | ||
| 3544 | area += strlen (area) + 1; | ||
| 3545 | p = AbsPosition (tty); | ||
| 3546 | /* Change all %+ parameters to %C, to handle | ||
| 3547 | values above 96 correctly for the C100. */ | ||
| 3548 | while (*p) | ||
| 3549 | { | ||
| 3550 | if (p[0] == '%' && p[1] == '+') | ||
| 3551 | p[1] = 'C'; | ||
| 3552 | p++; | ||
| 3553 | } | ||
| 3554 | } | ||
| 3555 | |||
| 3556 | tty->specified_window = FrameRows (tty); | 3507 | tty->specified_window = FrameRows (tty); |
| 3557 | 3508 | ||
| 3558 | if (Wcm_init (tty) == -1) /* can't do cursor motion */ | 3509 | if (Wcm_init (tty) == -1) /* can't do cursor motion */ |
diff --git a/src/termcap.c b/src/termcap.c index e191f6b3af3..96b9303d62d 100644 --- a/src/termcap.c +++ b/src/termcap.c | |||
| @@ -338,8 +338,7 @@ static int name_match (char *line, char *name); | |||
| 338 | 338 | ||
| 339 | #ifdef MSDOS /* MW, May 1993 */ | 339 | #ifdef MSDOS /* MW, May 1993 */ |
| 340 | static int | 340 | static int |
| 341 | valid_filename_p (fn) | 341 | valid_filename_p (char *fn) |
| 342 | char *fn; | ||
| 343 | { | 342 | { |
| 344 | return *fn == '/' || fn[1] == ':'; | 343 | return *fn == '/' || fn[1] == ':'; |
| 345 | } | 344 | } |
| @@ -669,9 +668,29 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end) | |||
| 669 | 668 | ||
| 670 | #include <stdio.h> | 669 | #include <stdio.h> |
| 671 | 670 | ||
| 672 | main (argc, argv) | 671 | static void |
| 673 | int argc; | 672 | tprint (char *cap) |
| 674 | char **argv; | 673 | { |
| 674 | char *x = tgetstr (cap, 0); | ||
| 675 | register char *y; | ||
| 676 | |||
| 677 | printf ("%s: ", cap); | ||
| 678 | if (x) | ||
| 679 | { | ||
| 680 | for (y = x; *y; y++) | ||
| 681 | if (*y <= ' ' || *y == 0177) | ||
| 682 | printf ("\\%0o", *y); | ||
| 683 | else | ||
| 684 | putchar (*y); | ||
| 685 | free (x); | ||
| 686 | } | ||
| 687 | else | ||
| 688 | printf ("none"); | ||
| 689 | putchar ('\n'); | ||
| 690 | } | ||
| 691 | |||
| 692 | int | ||
| 693 | main (int argc, char **argv) | ||
| 675 | { | 694 | { |
| 676 | char *term; | 695 | char *term; |
| 677 | char *buf; | 696 | char *buf; |
| @@ -693,27 +712,8 @@ main (argc, argv) | |||
| 693 | 712 | ||
| 694 | printf ("co: %d\n", tgetnum ("co")); | 713 | printf ("co: %d\n", tgetnum ("co")); |
| 695 | printf ("am: %d\n", tgetflag ("am")); | 714 | printf ("am: %d\n", tgetflag ("am")); |
| 696 | } | ||
| 697 | |||
| 698 | tprint (cap) | ||
| 699 | char *cap; | ||
| 700 | { | ||
| 701 | char *x = tgetstr (cap, 0); | ||
| 702 | register char *y; | ||
| 703 | 715 | ||
| 704 | printf ("%s: ", cap); | 716 | return 0; |
| 705 | if (x) | ||
| 706 | { | ||
| 707 | for (y = x; *y; y++) | ||
| 708 | if (*y <= ' ' || *y == 0177) | ||
| 709 | printf ("\\%0o", *y); | ||
| 710 | else | ||
| 711 | putchar (*y); | ||
| 712 | free (x); | ||
| 713 | } | ||
| 714 | else | ||
| 715 | printf ("none"); | ||
| 716 | putchar ('\n'); | ||
| 717 | } | 717 | } |
| 718 | 718 | ||
| 719 | #endif /* TEST */ | 719 | #endif /* TEST */ |
diff --git a/src/textprop.c b/src/textprop.c index 87f1675047b..29425f7a550 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -1707,10 +1707,14 @@ text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer) | |||
| 1707 | { | 1707 | { |
| 1708 | Lisp_Object prev_pos, front_sticky; | 1708 | Lisp_Object prev_pos, front_sticky; |
| 1709 | int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */ | 1709 | int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */ |
| 1710 | Lisp_Object defalt = Fassq (prop, Vtext_property_default_nonsticky); | ||
| 1710 | 1711 | ||
| 1711 | if (NILP (buffer)) | 1712 | if (NILP (buffer)) |
| 1712 | XSETBUFFER (buffer, current_buffer); | 1713 | XSETBUFFER (buffer, current_buffer); |
| 1713 | 1714 | ||
| 1715 | if (CONSP (defalt) && !NILP (XCDR (defalt))) | ||
| 1716 | is_rear_sticky = 0; | ||
| 1717 | |||
| 1714 | if (XINT (pos) > BUF_BEGV (XBUFFER (buffer))) | 1718 | if (XINT (pos) > BUF_BEGV (XBUFFER (buffer))) |
| 1715 | /* Consider previous character. */ | 1719 | /* Consider previous character. */ |
| 1716 | { | 1720 | { |
| @@ -2230,9 +2234,11 @@ If a character in a buffer has PROPERTY, new text inserted adjacent to | |||
| 2230 | the character doesn't inherit PROPERTY if NONSTICKINESS is non-nil, | 2234 | the character doesn't inherit PROPERTY if NONSTICKINESS is non-nil, |
| 2231 | inherits it if NONSTICKINESS is nil. The `front-sticky' and | 2235 | inherits it if NONSTICKINESS is nil. The `front-sticky' and |
| 2232 | `rear-nonsticky' properties of the character override NONSTICKINESS. */); | 2236 | `rear-nonsticky' properties of the character override NONSTICKINESS. */); |
| 2233 | /* Text property `syntax-table' should be nonsticky by default. */ | 2237 | /* Text properties `syntax-table'and `display' should be nonsticky |
| 2238 | by default. */ | ||
| 2234 | Vtext_property_default_nonsticky | 2239 | Vtext_property_default_nonsticky |
| 2235 | = Fcons (Fcons (intern_c_string ("syntax-table"), Qt), Qnil); | 2240 | = Fcons (Fcons (intern_c_string ("syntax-table"), Qt), |
| 2241 | Fcons (Fcons (intern_c_string ("display"), Qt), Qnil)); | ||
| 2236 | 2242 | ||
| 2237 | staticpro (&interval_insert_behind_hooks); | 2243 | staticpro (&interval_insert_behind_hooks); |
| 2238 | staticpro (&interval_insert_in_front_hooks); | 2244 | staticpro (&interval_insert_in_front_hooks); |
diff --git a/src/tparam.c b/src/tparam.c index 6aae0b97db9..ed28cd7397f 100644 --- a/src/tparam.c +++ b/src/tparam.c | |||
| @@ -265,9 +265,8 @@ tparam1 (const char *string, char *outstring, int len, | |||
| 265 | 265 | ||
| 266 | #ifdef DEBUG | 266 | #ifdef DEBUG |
| 267 | 267 | ||
| 268 | main (argc, argv) | 268 | int |
| 269 | int argc; | 269 | main (int argc, char **argv) |
| 270 | char **argv; | ||
| 271 | { | 270 | { |
| 272 | char buf[50]; | 271 | char buf[50]; |
| 273 | int args[3]; | 272 | int args[3]; |
diff --git a/src/unexhp9k800.c b/src/unexhp9k800.c index f27415a252c..ce65faffd4e 100644 --- a/src/unexhp9k800.c +++ b/src/unexhp9k800.c | |||
| @@ -64,8 +64,7 @@ static long brk_on_dump = 0; | |||
| 64 | 64 | ||
| 65 | /* Called from main, if we use shared libraries. */ | 65 | /* Called from main, if we use shared libraries. */ |
| 66 | int | 66 | int |
| 67 | run_time_remap (ignored) | 67 | run_time_remap (char *ignored) |
| 68 | char *ignored; | ||
| 69 | { | 68 | { |
| 70 | brk ((char *) brk_on_dump); | 69 | brk ((char *) brk_on_dump); |
| 71 | } | 70 | } |
| @@ -74,74 +73,11 @@ run_time_remap (ignored) | |||
| 74 | #define roundup(x,n) (((x) + ((n) - 1)) & ~((n) - 1)) /* n is power of 2 */ | 73 | #define roundup(x,n) (((x) + ((n) - 1)) & ~((n) - 1)) /* n is power of 2 */ |
| 75 | #define min(x,y) (((x) < (y)) ? (x) : (y)) | 74 | #define min(x,y) (((x) < (y)) ? (x) : (y)) |
| 76 | 75 | ||
| 77 | |||
| 78 | /* Create a new a.out file, same as old but with current data space */ | ||
| 79 | void | ||
| 80 | unexec (const char *new_name, /* name of the new a.out file to be created */ | ||
| 81 | const char *old_name) /* name of the old a.out file */ | ||
| 82 | { | ||
| 83 | int old, new; | ||
| 84 | int old_size, new_size; | ||
| 85 | struct header hdr; | ||
| 86 | struct som_exec_auxhdr auxhdr; | ||
| 87 | long i; | ||
| 88 | |||
| 89 | /* For the greatest flexibility, should create a temporary file in | ||
| 90 | the same directory as the new file. When everything is complete, | ||
| 91 | rename the temp file to the new name. | ||
| 92 | This way, a program could update its own a.out file even while | ||
| 93 | it is still executing. If problems occur, everything is still | ||
| 94 | intact. NOT implemented. */ | ||
| 95 | |||
| 96 | /* Open the input and output a.out files */ | ||
| 97 | old = open (old_name, O_RDONLY); | ||
| 98 | if (old < 0) | ||
| 99 | { perror (old_name); exit (1); } | ||
| 100 | new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777); | ||
| 101 | if (new < 0) | ||
| 102 | { perror (new_name); exit (1); } | ||
| 103 | |||
| 104 | /* Read the old headers */ | ||
| 105 | read_header (old, &hdr, &auxhdr); | ||
| 106 | |||
| 107 | brk_on_dump = (long) sbrk (0); | ||
| 108 | |||
| 109 | /* Decide how large the new and old data areas are */ | ||
| 110 | old_size = auxhdr.exec_dsize; | ||
| 111 | /* I suspect these two statements are separate | ||
| 112 | to avoid a compiler bug in hpux version 8. */ | ||
| 113 | i = (long) sbrk (0); | ||
| 114 | new_size = i - auxhdr.exec_dmem; | ||
| 115 | |||
| 116 | /* Copy the old file to the new, up to the data space */ | ||
| 117 | lseek (old, 0, 0); | ||
| 118 | copy_file (old, new, auxhdr.exec_dfile); | ||
| 119 | |||
| 120 | /* Skip the old data segment and write a new one */ | ||
| 121 | lseek (old, old_size, 1); | ||
| 122 | save_data_space (new, &hdr, &auxhdr, new_size); | ||
| 123 | |||
| 124 | /* Copy the rest of the file */ | ||
| 125 | copy_rest (old, new); | ||
| 126 | |||
| 127 | /* Update file pointers since we probably changed size of data area */ | ||
| 128 | update_file_ptrs (new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size); | ||
| 129 | |||
| 130 | /* Save the modified header */ | ||
| 131 | write_header (new, &hdr, &auxhdr); | ||
| 132 | |||
| 133 | /* Close the binary file */ | ||
| 134 | close (old); | ||
| 135 | close (new); | ||
| 136 | } | ||
| 137 | |||
| 138 | /* Save current data space in the file, update header. */ | 76 | /* Save current data space in the file, update header. */ |
| 139 | 77 | ||
| 140 | save_data_space (file, hdr, auxhdr, size) | 78 | static void |
| 141 | int file; | 79 | save_data_space (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr, |
| 142 | struct header *hdr; | 80 | int size) |
| 143 | struct som_exec_auxhdr *auxhdr; | ||
| 144 | int size; | ||
| 145 | { | 81 | { |
| 146 | /* Write the entire data space out to the file */ | 82 | /* Write the entire data space out to the file */ |
| 147 | if (write (file, auxhdr->exec_dmem, size) != size) | 83 | if (write (file, auxhdr->exec_dmem, size) != size) |
| @@ -154,12 +90,9 @@ save_data_space (file, hdr, auxhdr, size) | |||
| 154 | 90 | ||
| 155 | /* Update the values of file pointers when something is inserted. */ | 91 | /* Update the values of file pointers when something is inserted. */ |
| 156 | 92 | ||
| 157 | update_file_ptrs (file, hdr, auxhdr, location, offset) | 93 | static void |
| 158 | int file; | 94 | update_file_ptrs (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr, |
| 159 | struct header *hdr; | 95 | unsigned int location, int offset) |
| 160 | struct som_exec_auxhdr *auxhdr; | ||
| 161 | unsigned int location; | ||
| 162 | int offset; | ||
| 163 | { | 96 | { |
| 164 | struct subspace_dictionary_record subspace; | 97 | struct subspace_dictionary_record subspace; |
| 165 | int i; | 98 | int i; |
| @@ -205,10 +138,8 @@ update_file_ptrs (file, hdr, auxhdr, location, offset) | |||
| 205 | 138 | ||
| 206 | /* Read in the header records from an a.out file. */ | 139 | /* Read in the header records from an a.out file. */ |
| 207 | 140 | ||
| 208 | read_header (file, hdr, auxhdr) | 141 | static void |
| 209 | int file; | 142 | read_header (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr) |
| 210 | struct header *hdr; | ||
| 211 | struct som_exec_auxhdr *auxhdr; | ||
| 212 | { | 143 | { |
| 213 | 144 | ||
| 214 | /* Read the header in */ | 145 | /* Read the header in */ |
| @@ -233,10 +164,8 @@ read_header (file, hdr, auxhdr) | |||
| 233 | 164 | ||
| 234 | /* Write out the header records into an a.out file. */ | 165 | /* Write out the header records into an a.out file. */ |
| 235 | 166 | ||
| 236 | write_header (file, hdr, auxhdr) | 167 | static void |
| 237 | int file; | 168 | write_header (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr) |
| 238 | struct header *hdr; | ||
| 239 | struct som_exec_auxhdr *auxhdr; | ||
| 240 | { | 169 | { |
| 241 | /* Update the checksum */ | 170 | /* Update the checksum */ |
| 242 | hdr->checksum = calculate_checksum (hdr); | 171 | hdr->checksum = calculate_checksum (hdr); |
| @@ -252,8 +181,8 @@ write_header (file, hdr, auxhdr) | |||
| 252 | 181 | ||
| 253 | /* Calculate the checksum of a SOM header record. */ | 182 | /* Calculate the checksum of a SOM header record. */ |
| 254 | 183 | ||
| 255 | calculate_checksum (hdr) | 184 | static int |
| 256 | struct header *hdr; | 185 | calculate_checksum (struct header *hdr) |
| 257 | { | 186 | { |
| 258 | int checksum, i, *ptr; | 187 | int checksum, i, *ptr; |
| 259 | 188 | ||
| @@ -267,9 +196,8 @@ calculate_checksum (hdr) | |||
| 267 | 196 | ||
| 268 | /* Copy size bytes from the old file to the new one. */ | 197 | /* Copy size bytes from the old file to the new one. */ |
| 269 | 198 | ||
| 270 | copy_file (old, new, size) | 199 | static void |
| 271 | int new, old; | 200 | copy_file (int old, int new, int size) |
| 272 | int size; | ||
| 273 | { | 201 | { |
| 274 | int len; | 202 | int len; |
| 275 | int buffer[8192]; /* word aligned will be faster */ | 203 | int buffer[8192]; /* word aligned will be faster */ |
| @@ -286,8 +214,8 @@ copy_file (old, new, size) | |||
| 286 | 214 | ||
| 287 | /* Copy the rest of the file, up to EOF. */ | 215 | /* Copy the rest of the file, up to EOF. */ |
| 288 | 216 | ||
| 289 | copy_rest (old, new) | 217 | static void |
| 290 | int new, old; | 218 | copy_rest (int old, int new) |
| 291 | { | 219 | { |
| 292 | int buffer[4096]; | 220 | int buffer[4096]; |
| 293 | int len; | 221 | int len; |
| @@ -301,9 +229,8 @@ copy_rest (old, new) | |||
| 301 | } | 229 | } |
| 302 | 230 | ||
| 303 | #ifdef DEBUG | 231 | #ifdef DEBUG |
| 304 | display_header (hdr, auxhdr) | 232 | static void |
| 305 | struct header *hdr; | 233 | display_header (struct header *hdr, struct som_exec_auxhdr *auxhdr) |
| 306 | struct som_exec_auxhdr *auxhdr; | ||
| 307 | { | 234 | { |
| 308 | /* Display the header information (debug) */ | 235 | /* Display the header information (debug) */ |
| 309 | printf ("\n\nFILE HEADER\n"); | 236 | printf ("\n\nFILE HEADER\n"); |
| @@ -320,3 +247,64 @@ display_header (hdr, auxhdr) | |||
| 320 | hdr->unloadable_sp_location, hdr->unloadable_sp_size); | 247 | hdr->unloadable_sp_location, hdr->unloadable_sp_size); |
| 321 | } | 248 | } |
| 322 | #endif /* DEBUG */ | 249 | #endif /* DEBUG */ |
| 250 | |||
| 251 | |||
| 252 | /* Create a new a.out file, same as old but with current data space */ | ||
| 253 | void | ||
| 254 | unexec (const char *new_name, /* name of the new a.out file to be created */ | ||
| 255 | const char *old_name) /* name of the old a.out file */ | ||
| 256 | { | ||
| 257 | int old, new; | ||
| 258 | int old_size, new_size; | ||
| 259 | struct header hdr; | ||
| 260 | struct som_exec_auxhdr auxhdr; | ||
| 261 | long i; | ||
| 262 | |||
| 263 | /* For the greatest flexibility, should create a temporary file in | ||
| 264 | the same directory as the new file. When everything is complete, | ||
| 265 | rename the temp file to the new name. | ||
| 266 | This way, a program could update its own a.out file even while | ||
| 267 | it is still executing. If problems occur, everything is still | ||
| 268 | intact. NOT implemented. */ | ||
| 269 | |||
| 270 | /* Open the input and output a.out files */ | ||
| 271 | old = open (old_name, O_RDONLY); | ||
| 272 | if (old < 0) | ||
| 273 | { perror (old_name); exit (1); } | ||
| 274 | new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777); | ||
| 275 | if (new < 0) | ||
| 276 | { perror (new_name); exit (1); } | ||
| 277 | |||
| 278 | /* Read the old headers */ | ||
| 279 | read_header (old, &hdr, &auxhdr); | ||
| 280 | |||
| 281 | brk_on_dump = (long) sbrk (0); | ||
| 282 | |||
| 283 | /* Decide how large the new and old data areas are */ | ||
| 284 | old_size = auxhdr.exec_dsize; | ||
| 285 | /* I suspect these two statements are separate | ||
| 286 | to avoid a compiler bug in hpux version 8. */ | ||
| 287 | i = (long) sbrk (0); | ||
| 288 | new_size = i - auxhdr.exec_dmem; | ||
| 289 | |||
| 290 | /* Copy the old file to the new, up to the data space */ | ||
| 291 | lseek (old, 0, 0); | ||
| 292 | copy_file (old, new, auxhdr.exec_dfile); | ||
| 293 | |||
| 294 | /* Skip the old data segment and write a new one */ | ||
| 295 | lseek (old, old_size, 1); | ||
| 296 | save_data_space (new, &hdr, &auxhdr, new_size); | ||
| 297 | |||
| 298 | /* Copy the rest of the file */ | ||
| 299 | copy_rest (old, new); | ||
| 300 | |||
| 301 | /* Update file pointers since we probably changed size of data area */ | ||
| 302 | update_file_ptrs (new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size); | ||
| 303 | |||
| 304 | /* Save the modified header */ | ||
| 305 | write_header (new, &hdr, &auxhdr); | ||
| 306 | |||
| 307 | /* Close the binary file */ | ||
| 308 | close (old); | ||
| 309 | close (new); | ||
| 310 | } | ||
| @@ -1452,6 +1452,14 @@ sigprocmask (int how, const sigset_t *set, sigset_t *oset) | |||
| 1452 | } | 1452 | } |
| 1453 | 1453 | ||
| 1454 | int | 1454 | int |
| 1455 | pthread_sigmask (int how, const sigset_t *set, sigset_t *oset) | ||
| 1456 | { | ||
| 1457 | if (sigprocmask (how, set, oset) == -1) | ||
| 1458 | return EINVAL; | ||
| 1459 | return 0; | ||
| 1460 | } | ||
| 1461 | |||
| 1462 | int | ||
| 1455 | setpgrp (int pid, int gid) | 1463 | setpgrp (int pid, int gid) |
| 1456 | { | 1464 | { |
| 1457 | return 0; | 1465 | return 0; |
diff --git a/src/w32fns.c b/src/w32fns.c index e4b11b70441..f48e5764b4c 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -3273,7 +3273,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 3273 | { | 3273 | { |
| 3274 | /* Free memory used by owner-drawn and help-echo strings. */ | 3274 | /* Free memory used by owner-drawn and help-echo strings. */ |
| 3275 | w32_free_menu_strings (hwnd); | 3275 | w32_free_menu_strings (hwnd); |
| 3276 | f->output_data.w32->menubar_active = 0; | 3276 | if (f) |
| 3277 | f->output_data.w32->menubar_active = 0; | ||
| 3277 | menubar_in_use = 0; | 3278 | menubar_in_use = 0; |
| 3278 | } | 3279 | } |
| 3279 | } | 3280 | } |
| @@ -3623,10 +3624,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 3623 | if (LOWORD (lParam) == HTCLIENT) | 3624 | if (LOWORD (lParam) == HTCLIENT) |
| 3624 | { | 3625 | { |
| 3625 | f = x_window_to_frame (dpyinfo, hwnd); | 3626 | f = x_window_to_frame (dpyinfo, hwnd); |
| 3626 | if (f->output_data.w32->hourglass_p && !menubar_in_use | 3627 | if (f && f->output_data.w32->hourglass_p |
| 3627 | && !current_popup_menu) | 3628 | && !menubar_in_use && !current_popup_menu) |
| 3628 | SetCursor (f->output_data.w32->hourglass_cursor); | 3629 | SetCursor (f->output_data.w32->hourglass_cursor); |
| 3629 | else | 3630 | else if (f) |
| 3630 | SetCursor (f->output_data.w32->current_cursor); | 3631 | SetCursor (f->output_data.w32->current_cursor); |
| 3631 | return 0; | 3632 | return 0; |
| 3632 | } | 3633 | } |
| @@ -6805,10 +6806,6 @@ syms_of_w32fns (void) | |||
| 6805 | DEFSYM (Qfont_param, "font-parameter"); | 6806 | DEFSYM (Qfont_param, "font-parameter"); |
| 6806 | /* This is the end of symbol initialization. */ | 6807 | /* This is the end of symbol initialization. */ |
| 6807 | 6808 | ||
| 6808 | /* Text property `display' should be nonsticky by default. */ | ||
| 6809 | Vtext_property_default_nonsticky | ||
| 6810 | = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky); | ||
| 6811 | |||
| 6812 | 6809 | ||
| 6813 | Fput (Qundefined_color, Qerror_conditions, | 6810 | Fput (Qundefined_color, Qerror_conditions, |
| 6814 | pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); | 6811 | pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); |
diff --git a/src/widget.c b/src/widget.c index 6d871ad7cb2..a09ec2631ad 100644 --- a/src/widget.c +++ b/src/widget.c | |||
| @@ -224,8 +224,7 @@ get_wm_shell (Widget w) | |||
| 224 | #if 0 /* Currently not used. */ | 224 | #if 0 /* Currently not used. */ |
| 225 | 225 | ||
| 226 | static void | 226 | static void |
| 227 | mark_shell_size_user_specified (wmshell) | 227 | mark_shell_size_user_specified (Widget wmshell) |
| 228 | Widget wmshell; | ||
| 229 | { | 228 | { |
| 230 | if (! XtIsWMShell (wmshell)) abort (); | 229 | if (! XtIsWMShell (wmshell)) abort (); |
| 231 | /* This is kind of sleazy, but I can't see how else to tell it to make it | 230 | /* This is kind of sleazy, but I can't see how else to tell it to make it |
| @@ -510,8 +509,7 @@ update_wm_hints (EmacsFrame ew) | |||
| 510 | #if 0 | 509 | #if 0 |
| 511 | 510 | ||
| 512 | static void | 511 | static void |
| 513 | create_frame_gcs (ew) | 512 | create_frame_gcs (EmacsFrame ew) |
| 514 | EmacsFrame ew; | ||
| 515 | { | 513 | { |
| 516 | struct frame *s = ew->emacs_frame.frame; | 514 | struct frame *s = ew->emacs_frame.frame; |
| 517 | 515 | ||
diff --git a/src/window.c b/src/window.c index 3c867145620..d39efa8071d 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -56,7 +56,7 @@ Lisp_Object Qwindowp, Qwindow_live_p; | |||
| 56 | static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; | 56 | static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; |
| 57 | static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; | 57 | static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; |
| 58 | static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; | 58 | static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; |
| 59 | static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; | 59 | static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; |
| 60 | static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; | 60 | static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; |
| 61 | static Lisp_Object Qsafe, Qabove, Qbelow; | 61 | static Lisp_Object Qsafe, Qabove, Qbelow; |
| 62 | static Lisp_Object Qauto_buffer_name; | 62 | static Lisp_Object Qauto_buffer_name; |
| @@ -410,14 +410,6 @@ buffer of the selected window before each command. */) | |||
| 410 | return select_window (window, norecord, 0); | 410 | return select_window (window, norecord, 0); |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | DEFUN ("window-clone-number", Fwindow_clone_number, Swindow_clone_number, 0, 1, 0, | ||
| 414 | doc: /* Return WINDOW's clone number. | ||
| 415 | WINDOW can be any window and defaults to the selected one. */) | ||
| 416 | (Lisp_Object window) | ||
| 417 | { | ||
| 418 | return decode_any_window (window)->clone_number; | ||
| 419 | } | ||
| 420 | |||
| 421 | DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0, | 413 | DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0, |
| 422 | doc: /* Return the buffer that WINDOW is displaying. | 414 | doc: /* Return the buffer that WINDOW is displaying. |
| 423 | WINDOW can be any window and defaults to the selected one. | 415 | WINDOW can be any window and defaults to the selected one. |
| @@ -693,6 +685,7 @@ WINDOW must be a live window and defaults to the selected one. */) | |||
| 693 | 685 | ||
| 694 | DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0, | 686 | DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0, |
| 695 | doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL. | 687 | doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL. |
| 688 | If WINDOW is nil, the selected window is used. | ||
| 696 | Return NCOL. NCOL should be zero or positive. | 689 | Return NCOL. NCOL should be zero or positive. |
| 697 | 690 | ||
| 698 | Note that if `automatic-hscrolling' is non-nil, you cannot scroll the | 691 | Note that if `automatic-hscrolling' is non-nil, you cannot scroll the |
| @@ -1360,6 +1353,7 @@ if it isn't already recorded. */) | |||
| 1360 | struct text_pos startp; | 1353 | struct text_pos startp; |
| 1361 | struct it it; | 1354 | struct it it; |
| 1362 | struct buffer *old_buffer = NULL; | 1355 | struct buffer *old_buffer = NULL; |
| 1356 | void *itdata = NULL; | ||
| 1363 | 1357 | ||
| 1364 | /* Cannot use Fvertical_motion because that function doesn't | 1358 | /* Cannot use Fvertical_motion because that function doesn't |
| 1365 | cope with variable-height lines. */ | 1359 | cope with variable-height lines. */ |
| @@ -1381,11 +1375,13 @@ if it isn't already recorded. */) | |||
| 1381 | else | 1375 | else |
| 1382 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | 1376 | SET_TEXT_POS_FROM_MARKER (startp, w->start); |
| 1383 | 1377 | ||
| 1378 | itdata = bidi_shelve_cache (); | ||
| 1384 | start_display (&it, w, startp); | 1379 | start_display (&it, w, startp); |
| 1385 | move_it_vertically (&it, window_box_height (w)); | 1380 | move_it_vertically (&it, window_box_height (w)); |
| 1386 | if (it.current_y < it.last_visible_y) | 1381 | if (it.current_y < it.last_visible_y) |
| 1387 | move_it_past_eol (&it); | 1382 | move_it_past_eol (&it); |
| 1388 | value = make_number (IT_CHARPOS (it)); | 1383 | value = make_number (IT_CHARPOS (it)); |
| 1384 | bidi_unshelve_cache (itdata); | ||
| 1389 | 1385 | ||
| 1390 | if (old_buffer) | 1386 | if (old_buffer) |
| 1391 | set_buffer_internal (old_buffer); | 1387 | set_buffer_internal (old_buffer); |
| @@ -1420,7 +1416,7 @@ Return POS. */) | |||
| 1420 | 1416 | ||
| 1421 | DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0, | 1417 | DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0, |
| 1422 | doc: /* Make display in WINDOW start at position POS in WINDOW's buffer. | 1418 | doc: /* Make display in WINDOW start at position POS in WINDOW's buffer. |
| 1423 | WINDOW defaults to the selected window. Return POS. | 1419 | If WINDOW is nil, the selected window is used. Return POS. |
| 1424 | Optional third arg NOFORCE non-nil inhibits next redisplay from | 1420 | Optional third arg NOFORCE non-nil inhibits next redisplay from |
| 1425 | overriding motion of point in order to display at this exact start. */) | 1421 | overriding motion of point in order to display at this exact start. */) |
| 1426 | (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce) | 1422 | (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce) |
| @@ -2578,7 +2574,7 @@ selected frame and no others. */) | |||
| 2578 | static Lisp_Object | 2574 | static Lisp_Object |
| 2579 | resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) | 2575 | resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) |
| 2580 | { | 2576 | { |
| 2581 | return call4 (Qresize_root_window, window, delta, horizontal, ignore); | 2577 | return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore); |
| 2582 | } | 2578 | } |
| 2583 | 2579 | ||
| 2584 | 2580 | ||
| @@ -3089,18 +3085,6 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int | |||
| 3089 | unbind_to (count, Qnil); | 3085 | unbind_to (count, Qnil); |
| 3090 | } | 3086 | } |
| 3091 | 3087 | ||
| 3092 | DEFUN ("set-window-clone-number", Fset_window_clone_number, Sset_window_clone_number, 2, 2, 0, | ||
| 3093 | doc: /* Set WINDOW's clone number to CLONE-NUMBER. | ||
| 3094 | WINDOW can be any window and defaults to the selected one. */) | ||
| 3095 | (Lisp_Object window, Lisp_Object clone_number) | ||
| 3096 | { | ||
| 3097 | register struct window *w = decode_any_window (window); | ||
| 3098 | |||
| 3099 | CHECK_NUMBER (clone_number); | ||
| 3100 | w->clone_number = clone_number; | ||
| 3101 | return w->clone_number; | ||
| 3102 | } | ||
| 3103 | |||
| 3104 | DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, | 3088 | DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, |
| 3105 | doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. | 3089 | doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. |
| 3106 | WINDOW has to be a live window and defaults to the selected one. | 3090 | WINDOW has to be a live window and defaults to the selected one. |
| @@ -3291,7 +3275,6 @@ make_parent_window (Lisp_Object window, int horflag) | |||
| 3291 | 3275 | ||
| 3292 | ++sequence_number; | 3276 | ++sequence_number; |
| 3293 | XSETFASTINT (p->sequence_number, sequence_number); | 3277 | XSETFASTINT (p->sequence_number, sequence_number); |
| 3294 | XSETFASTINT (p->clone_number, sequence_number); | ||
| 3295 | 3278 | ||
| 3296 | replace_window (window, parent, 1); | 3279 | replace_window (window, parent, 1); |
| 3297 | 3280 | ||
| @@ -3337,7 +3320,6 @@ make_window (void) | |||
| 3337 | XSETFASTINT (w->use_time, 0); | 3320 | XSETFASTINT (w->use_time, 0); |
| 3338 | ++sequence_number; | 3321 | ++sequence_number; |
| 3339 | XSETFASTINT (w->sequence_number, sequence_number); | 3322 | XSETFASTINT (w->sequence_number, sequence_number); |
| 3340 | XSETFASTINT (w->clone_number, sequence_number); | ||
| 3341 | w->temslot = w->last_modified = w->last_overlay_modified = Qnil; | 3323 | w->temslot = w->last_modified = w->last_overlay_modified = Qnil; |
| 3342 | XSETFASTINT (w->last_point, 0); | 3324 | XSETFASTINT (w->last_point, 0); |
| 3343 | w->last_had_star = w->vertical_scroll_bar = Qnil; | 3325 | w->last_had_star = w->vertical_scroll_bar = Qnil; |
| @@ -4076,7 +4058,8 @@ grow_mini_window (struct window *w, int delta) | |||
| 4076 | 4058 | ||
| 4077 | root = FRAME_ROOT_WINDOW (f); | 4059 | root = FRAME_ROOT_WINDOW (f); |
| 4078 | r = XWINDOW (root); | 4060 | r = XWINDOW (root); |
| 4079 | value = call2 (Qresize_root_window_vertically, root, make_number (- delta)); | 4061 | value = call2 (Qwindow_resize_root_window_vertically, |
| 4062 | root, make_number (- delta)); | ||
| 4080 | if (INTEGERP (value) && window_resize_check (r, 0)) | 4063 | if (INTEGERP (value) && window_resize_check (r, 0)) |
| 4081 | { | 4064 | { |
| 4082 | BLOCK_INPUT; | 4065 | BLOCK_INPUT; |
| @@ -4110,7 +4093,7 @@ shrink_mini_window (struct window *w) | |||
| 4110 | { | 4093 | { |
| 4111 | root = FRAME_ROOT_WINDOW (f); | 4094 | root = FRAME_ROOT_WINDOW (f); |
| 4112 | r = XWINDOW (root); | 4095 | r = XWINDOW (root); |
| 4113 | value = call2 (Qresize_root_window_vertically, | 4096 | value = call2 (Qwindow_resize_root_window_vertically, |
| 4114 | root, make_number (size - 1)); | 4097 | root, make_number (size - 1)); |
| 4115 | if (INTEGERP (value) && window_resize_check (r, 0)) | 4098 | if (INTEGERP (value) && window_resize_check (r, 0)) |
| 4116 | { | 4099 | { |
| @@ -4261,6 +4244,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4261 | /* True if we fiddled the window vscroll field without really scrolling. */ | 4244 | /* True if we fiddled the window vscroll field without really scrolling. */ |
| 4262 | int vscrolled = 0; | 4245 | int vscrolled = 0; |
| 4263 | int x, y, rtop, rbot, rowh, vpos; | 4246 | int x, y, rtop, rbot, rowh, vpos; |
| 4247 | void *itdata = NULL; | ||
| 4264 | 4248 | ||
| 4265 | SET_TEXT_POS_FROM_MARKER (start, w->start); | 4249 | SET_TEXT_POS_FROM_MARKER (start, w->start); |
| 4266 | 4250 | ||
| @@ -4271,6 +4255,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4271 | 4255 | ||
| 4272 | if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos)) | 4256 | if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos)) |
| 4273 | { | 4257 | { |
| 4258 | itdata = bidi_shelve_cache (); | ||
| 4274 | /* Move backward half the height of the window. Performance note: | 4259 | /* Move backward half the height of the window. Performance note: |
| 4275 | vmotion used here is about 10% faster, but would give wrong | 4260 | vmotion used here is about 10% faster, but would give wrong |
| 4276 | results for variable height lines. */ | 4261 | results for variable height lines. */ |
| @@ -4291,6 +4276,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4291 | } | 4276 | } |
| 4292 | 4277 | ||
| 4293 | start = it.current.pos; | 4278 | start = it.current.pos; |
| 4279 | bidi_unshelve_cache (itdata); | ||
| 4294 | } | 4280 | } |
| 4295 | else if (auto_window_vscroll_p) | 4281 | else if (auto_window_vscroll_p) |
| 4296 | { | 4282 | { |
| @@ -4353,6 +4339,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4353 | Fset_window_vscroll (window, make_number (0), Qt); | 4339 | Fset_window_vscroll (window, make_number (0), Qt); |
| 4354 | } | 4340 | } |
| 4355 | 4341 | ||
| 4342 | itdata = bidi_shelve_cache (); | ||
| 4356 | /* If scroll_preserve_screen_position is non-nil, we try to set | 4343 | /* If scroll_preserve_screen_position is non-nil, we try to set |
| 4357 | point in the same window line as it is now, so get that line. */ | 4344 | point in the same window line as it is now, so get that line. */ |
| 4358 | if (!NILP (Vscroll_preserve_screen_position)) | 4345 | if (!NILP (Vscroll_preserve_screen_position)) |
| @@ -4431,12 +4418,16 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4431 | - it.current_y + it.max_ascent + it.max_descent); | 4418 | - it.current_y + it.max_ascent + it.max_descent); |
| 4432 | adjust_glyphs (it.f); | 4419 | adjust_glyphs (it.f); |
| 4433 | } | 4420 | } |
| 4434 | else if (noerror) | ||
| 4435 | return; | ||
| 4436 | else if (n < 0) /* could happen with empty buffers */ | ||
| 4437 | xsignal0 (Qbeginning_of_buffer); | ||
| 4438 | else | 4421 | else |
| 4439 | xsignal0 (Qend_of_buffer); | 4422 | { |
| 4423 | bidi_unshelve_cache (itdata); | ||
| 4424 | if (noerror) | ||
| 4425 | return; | ||
| 4426 | else if (n < 0) /* could happen with empty buffers */ | ||
| 4427 | xsignal0 (Qbeginning_of_buffer); | ||
| 4428 | else | ||
| 4429 | xsignal0 (Qend_of_buffer); | ||
| 4430 | } | ||
| 4440 | } | 4431 | } |
| 4441 | else | 4432 | else |
| 4442 | { | 4433 | { |
| @@ -4444,10 +4435,14 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4444 | /* The first line was only partially visible, make it fully | 4435 | /* The first line was only partially visible, make it fully |
| 4445 | visible. */ | 4436 | visible. */ |
| 4446 | w->vscroll = 0; | 4437 | w->vscroll = 0; |
| 4447 | else if (noerror) | ||
| 4448 | return; | ||
| 4449 | else | 4438 | else |
| 4450 | xsignal0 (Qbeginning_of_buffer); | 4439 | { |
| 4440 | bidi_unshelve_cache (itdata); | ||
| 4441 | if (noerror) | ||
| 4442 | return; | ||
| 4443 | else | ||
| 4444 | xsignal0 (Qbeginning_of_buffer); | ||
| 4445 | } | ||
| 4451 | } | 4446 | } |
| 4452 | 4447 | ||
| 4453 | /* If control gets here, then we vscrolled. */ | 4448 | /* If control gets here, then we vscrolled. */ |
| @@ -4591,6 +4586,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4591 | SET_PT_BOTH (charpos, bytepos); | 4586 | SET_PT_BOTH (charpos, bytepos); |
| 4592 | } | 4587 | } |
| 4593 | } | 4588 | } |
| 4589 | bidi_unshelve_cache (itdata); | ||
| 4594 | } | 4590 | } |
| 4595 | 4591 | ||
| 4596 | 4592 | ||
| @@ -4993,6 +4989,7 @@ displayed_window_lines (struct window *w) | |||
| 4993 | int height = window_box_height (w); | 4989 | int height = window_box_height (w); |
| 4994 | struct buffer *old_buffer; | 4990 | struct buffer *old_buffer; |
| 4995 | int bottom_y; | 4991 | int bottom_y; |
| 4992 | void *itdata = NULL; | ||
| 4996 | 4993 | ||
| 4997 | if (XBUFFER (w->buffer) != current_buffer) | 4994 | if (XBUFFER (w->buffer) != current_buffer) |
| 4998 | { | 4995 | { |
| @@ -5012,9 +5009,11 @@ displayed_window_lines (struct window *w) | |||
| 5012 | else | 5009 | else |
| 5013 | SET_TEXT_POS_FROM_MARKER (start, w->start); | 5010 | SET_TEXT_POS_FROM_MARKER (start, w->start); |
| 5014 | 5011 | ||
| 5012 | itdata = bidi_shelve_cache (); | ||
| 5015 | start_display (&it, w, start); | 5013 | start_display (&it, w, start); |
| 5016 | move_it_vertically (&it, height); | 5014 | move_it_vertically (&it, height); |
| 5017 | bottom_y = line_bottom_y (&it); | 5015 | bottom_y = line_bottom_y (&it); |
| 5016 | bidi_unshelve_cache (itdata); | ||
| 5018 | 5017 | ||
| 5019 | /* rms: On a non-window display, | 5018 | /* rms: On a non-window display, |
| 5020 | the value of it.vpos at the bottom of the screen | 5019 | the value of it.vpos at the bottom of the screen |
| @@ -5113,12 +5112,14 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5113 | { | 5112 | { |
| 5114 | struct it it; | 5113 | struct it it; |
| 5115 | struct text_pos pt; | 5114 | struct text_pos pt; |
| 5115 | void *itdata = bidi_shelve_cache (); | ||
| 5116 | 5116 | ||
| 5117 | SET_TEXT_POS (pt, PT, PT_BYTE); | 5117 | SET_TEXT_POS (pt, PT, PT_BYTE); |
| 5118 | start_display (&it, w, pt); | 5118 | start_display (&it, w, pt); |
| 5119 | move_it_vertically_backward (&it, window_box_height (w) / 2); | 5119 | move_it_vertically_backward (&it, window_box_height (w) / 2); |
| 5120 | charpos = IT_CHARPOS (it); | 5120 | charpos = IT_CHARPOS (it); |
| 5121 | bytepos = IT_BYTEPOS (it); | 5121 | bytepos = IT_BYTEPOS (it); |
| 5122 | bidi_unshelve_cache (itdata); | ||
| 5122 | } | 5123 | } |
| 5123 | else if (iarg < 0) | 5124 | else if (iarg < 0) |
| 5124 | { | 5125 | { |
| @@ -5127,6 +5128,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5127 | int nlines = -iarg; | 5128 | int nlines = -iarg; |
| 5128 | int extra_line_spacing; | 5129 | int extra_line_spacing; |
| 5129 | int h = window_box_height (w); | 5130 | int h = window_box_height (w); |
| 5131 | void *itdata = bidi_shelve_cache (); | ||
| 5130 | 5132 | ||
| 5131 | iarg = - max (-iarg, this_scroll_margin); | 5133 | iarg = - max (-iarg, this_scroll_margin); |
| 5132 | 5134 | ||
| @@ -5164,7 +5166,10 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5164 | h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing); | 5166 | h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing); |
| 5165 | } | 5167 | } |
| 5166 | if (h <= 0) | 5168 | if (h <= 0) |
| 5167 | return Qnil; | 5169 | { |
| 5170 | bidi_unshelve_cache (itdata); | ||
| 5171 | return Qnil; | ||
| 5172 | } | ||
| 5168 | 5173 | ||
| 5169 | /* Now find the new top line (starting position) of the window. */ | 5174 | /* Now find the new top line (starting position) of the window. */ |
| 5170 | start_display (&it, w, pt); | 5175 | start_display (&it, w, pt); |
| @@ -5184,6 +5189,8 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5184 | 5189 | ||
| 5185 | charpos = IT_CHARPOS (it); | 5190 | charpos = IT_CHARPOS (it); |
| 5186 | bytepos = IT_BYTEPOS (it); | 5191 | bytepos = IT_BYTEPOS (it); |
| 5192 | |||
| 5193 | bidi_unshelve_cache (itdata); | ||
| 5187 | } | 5194 | } |
| 5188 | else | 5195 | else |
| 5189 | { | 5196 | { |
| @@ -5350,8 +5357,7 @@ struct saved_window | |||
| 5350 | { | 5357 | { |
| 5351 | struct vectorlike_header header; | 5358 | struct vectorlike_header header; |
| 5352 | 5359 | ||
| 5353 | Lisp_Object window, clone_number; | 5360 | Lisp_Object window, buffer, start, pointm, mark; |
| 5354 | Lisp_Object buffer, start, pointm, mark; | ||
| 5355 | Lisp_Object left_col, top_line, total_cols, total_lines; | 5361 | Lisp_Object left_col, top_line, total_cols, total_lines; |
| 5356 | Lisp_Object normal_cols, normal_lines; | 5362 | Lisp_Object normal_cols, normal_lines; |
| 5357 | Lisp_Object hscroll, min_hscroll; | 5363 | Lisp_Object hscroll, min_hscroll; |
| @@ -5570,7 +5576,6 @@ the return value is nil. Otherwise the value is t. */) | |||
| 5570 | } | 5576 | } |
| 5571 | } | 5577 | } |
| 5572 | 5578 | ||
| 5573 | w->clone_number = p->clone_number; | ||
| 5574 | /* If we squirreled away the buffer in the window's height, | 5579 | /* If we squirreled away the buffer in the window's height, |
| 5575 | restore it now. */ | 5580 | restore it now. */ |
| 5576 | if (BUFFERP (w->total_lines)) | 5581 | if (BUFFERP (w->total_lines)) |
| @@ -5853,7 +5858,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i) | |||
| 5853 | 5858 | ||
| 5854 | XSETFASTINT (w->temslot, i); i++; | 5859 | XSETFASTINT (w->temslot, i); i++; |
| 5855 | p->window = window; | 5860 | p->window = window; |
| 5856 | p->clone_number = w->clone_number; | ||
| 5857 | p->buffer = w->buffer; | 5861 | p->buffer = w->buffer; |
| 5858 | p->left_col = w->left_col; | 5862 | p->left_col = w->left_col; |
| 5859 | p->top_line = w->top_line; | 5863 | p->top_line = w->top_line; |
| @@ -6457,8 +6461,8 @@ syms_of_window (void) | |||
| 6457 | DEFSYM (Qwindow_live_p, "window-live-p"); | 6461 | DEFSYM (Qwindow_live_p, "window-live-p"); |
| 6458 | DEFSYM (Qwindow_deletable_p, "window-deletable-p"); | 6462 | DEFSYM (Qwindow_deletable_p, "window-deletable-p"); |
| 6459 | DEFSYM (Qdelete_window, "delete-window"); | 6463 | DEFSYM (Qdelete_window, "delete-window"); |
| 6460 | DEFSYM (Qresize_root_window, "resize-root-window"); | 6464 | DEFSYM (Qwindow_resize_root_window, "window--resize-root-window"); |
| 6461 | DEFSYM (Qresize_root_window_vertically, "resize-root-window-vertically"); | 6465 | DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically"); |
| 6462 | DEFSYM (Qsafe, "safe"); | 6466 | DEFSYM (Qsafe, "safe"); |
| 6463 | DEFSYM (Qdisplay_buffer, "display-buffer"); | 6467 | DEFSYM (Qdisplay_buffer, "display-buffer"); |
| 6464 | DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows"); | 6468 | DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows"); |
| @@ -6598,7 +6602,6 @@ function `window-nest' and altered by the function `set-window-nest'. */); | |||
| 6598 | defsubr (&Sset_frame_selected_window); | 6602 | defsubr (&Sset_frame_selected_window); |
| 6599 | defsubr (&Spos_visible_in_window_p); | 6603 | defsubr (&Spos_visible_in_window_p); |
| 6600 | defsubr (&Swindow_line_height); | 6604 | defsubr (&Swindow_line_height); |
| 6601 | defsubr (&Swindow_clone_number); | ||
| 6602 | defsubr (&Swindow_buffer); | 6605 | defsubr (&Swindow_buffer); |
| 6603 | defsubr (&Swindow_parent); | 6606 | defsubr (&Swindow_parent); |
| 6604 | defsubr (&Swindow_top_child); | 6607 | defsubr (&Swindow_top_child); |
| @@ -6648,7 +6651,6 @@ function `window-nest' and altered by the function `set-window-nest'. */); | |||
| 6648 | defsubr (&Sdelete_window_internal); | 6651 | defsubr (&Sdelete_window_internal); |
| 6649 | defsubr (&Sresize_mini_window_internal); | 6652 | defsubr (&Sresize_mini_window_internal); |
| 6650 | defsubr (&Sset_window_buffer); | 6653 | defsubr (&Sset_window_buffer); |
| 6651 | defsubr (&Sset_window_clone_number); | ||
| 6652 | defsubr (&Srun_window_configuration_change_hook); | 6654 | defsubr (&Srun_window_configuration_change_hook); |
| 6653 | defsubr (&Sselect_window); | 6655 | defsubr (&Sselect_window); |
| 6654 | defsubr (&Sforce_window_update); | 6656 | defsubr (&Sforce_window_update); |
diff --git a/src/window.h b/src/window.h index c3f59e4b116..485734e907e 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -165,10 +165,6 @@ struct window | |||
| 165 | /* Unique number of window assigned when it was created. */ | 165 | /* Unique number of window assigned when it was created. */ |
| 166 | Lisp_Object sequence_number; | 166 | Lisp_Object sequence_number; |
| 167 | 167 | ||
| 168 | /* Sequence number of window this window was cloned from. Identic | ||
| 169 | to sequence number if window was not cloned. */ | ||
| 170 | Lisp_Object clone_number; | ||
| 171 | |||
| 172 | /* No permanent meaning; used by save-window-excursion's | 168 | /* No permanent meaning; used by save-window-excursion's |
| 173 | bookkeeping. */ | 169 | bookkeeping. */ |
| 174 | Lisp_Object temslot; | 170 | Lisp_Object temslot; |
diff --git a/src/xdisp.c b/src/xdisp.c index 31506e2247b..c02de7225e1 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -129,9 +129,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 129 | argument. | 129 | argument. |
| 130 | 130 | ||
| 131 | Iteration over things to be displayed is then simple. It is | 131 | Iteration over things to be displayed is then simple. It is |
| 132 | started by initializing an iterator with a call to init_iterator. | 132 | started by initializing an iterator with a call to init_iterator, |
| 133 | Calls to get_next_display_element fill the iterator structure with | 133 | passing it the buffer position where to start iteration. For |
| 134 | relevant information about the next thing to display. Calls to | 134 | iteration over strings, pass -1 as the position to init_iterator, |
| 135 | and call reseat_to_string when the string is ready, to initialize | ||
| 136 | the iterator for that string. Thereafter, calls to | ||
| 137 | get_next_display_element fill the iterator structure with relevant | ||
| 138 | information about the next thing to display. Calls to | ||
| 135 | set_iterator_to_next move the iterator to the next thing. | 139 | set_iterator_to_next move the iterator to the next thing. |
| 136 | 140 | ||
| 137 | Besides this, an iterator also contains information about the | 141 | Besides this, an iterator also contains information about the |
| @@ -592,6 +596,29 @@ int current_mode_line_height, current_header_line_height; | |||
| 592 | 596 | ||
| 593 | #define TEXT_PROP_DISTANCE_LIMIT 100 | 597 | #define TEXT_PROP_DISTANCE_LIMIT 100 |
| 594 | 598 | ||
| 599 | /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the | ||
| 600 | iterator state and later restore it. This is needed because the | ||
| 601 | bidi iterator on bidi.c keeps a stacked cache of its states, which | ||
| 602 | is really a singleton. When we use scratch iterator objects to | ||
| 603 | move around the buffer, we can cause the bidi cache to be pushed or | ||
| 604 | popped, and therefore we need to restore the cache state when we | ||
| 605 | return to the original iterator. */ | ||
| 606 | #define SAVE_IT(ITCOPY,ITORIG,CACHE) \ | ||
| 607 | do { \ | ||
| 608 | if (CACHE) \ | ||
| 609 | xfree (CACHE); \ | ||
| 610 | ITCOPY = ITORIG; \ | ||
| 611 | CACHE = bidi_shelve_cache(); \ | ||
| 612 | } while (0) | ||
| 613 | |||
| 614 | #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \ | ||
| 615 | do { \ | ||
| 616 | if (pITORIG != pITCOPY) \ | ||
| 617 | *(pITORIG) = *(pITCOPY); \ | ||
| 618 | bidi_unshelve_cache (CACHE); \ | ||
| 619 | CACHE = NULL; \ | ||
| 620 | } while (0) | ||
| 621 | |||
| 595 | #if GLYPH_DEBUG | 622 | #if GLYPH_DEBUG |
| 596 | 623 | ||
| 597 | /* Non-zero means print traces of redisplay if compiled with | 624 | /* Non-zero means print traces of redisplay if compiled with |
| @@ -1198,6 +1225,7 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y, | |||
| 1198 | int *rtop, int *rbot, int *rowh, int *vpos) | 1225 | int *rtop, int *rbot, int *rowh, int *vpos) |
| 1199 | { | 1226 | { |
| 1200 | struct it it; | 1227 | struct it it; |
| 1228 | void *itdata = bidi_shelve_cache (); | ||
| 1201 | struct text_pos top; | 1229 | struct text_pos top; |
| 1202 | int visible_p = 0; | 1230 | int visible_p = 0; |
| 1203 | struct buffer *old_buffer = NULL; | 1231 | struct buffer *old_buffer = NULL; |
| @@ -1228,13 +1256,21 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y, | |||
| 1228 | move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, | 1256 | move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, |
| 1229 | (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); | 1257 | (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); |
| 1230 | 1258 | ||
| 1231 | if (charpos >= 0 && IT_CHARPOS (it) >= charpos) | 1259 | if (charpos >= 0 |
| 1260 | && (((!it.bidi_p || it.bidi_it.scan_dir == 1) | ||
| 1261 | && IT_CHARPOS (it) >= charpos) | ||
| 1262 | /* When scanning backwards under bidi iteration, move_it_to | ||
| 1263 | stops at or _before_ CHARPOS, because it stops at or to | ||
| 1264 | the _right_ of the character at CHARPOS. */ | ||
| 1265 | || (it.bidi_p && it.bidi_it.scan_dir == -1 | ||
| 1266 | && IT_CHARPOS (it) <= charpos))) | ||
| 1232 | { | 1267 | { |
| 1233 | /* We have reached CHARPOS, or passed it. How the call to | 1268 | /* We have reached CHARPOS, or passed it. How the call to |
| 1234 | move_it_to can overshoot: (i) If CHARPOS is on invisible | 1269 | move_it_to can overshoot: (i) If CHARPOS is on invisible text |
| 1235 | text, move_it_to stops at the end of the invisible text, | 1270 | or covered by a display property, move_it_to stops at the end |
| 1236 | after CHARPOS. (ii) If CHARPOS is in a display vector, | 1271 | of the invisible text, to the right of CHARPOS. (ii) If |
| 1237 | move_it_to stops on its last glyph. */ | 1272 | CHARPOS is in a display vector, move_it_to stops on its last |
| 1273 | glyph. */ | ||
| 1238 | int top_x = it.current_x; | 1274 | int top_x = it.current_x; |
| 1239 | int top_y = it.current_y; | 1275 | int top_y = it.current_y; |
| 1240 | enum it_method it_method = it.method; | 1276 | enum it_method it_method = it.method; |
| @@ -1283,15 +1319,18 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y, | |||
| 1283 | } | 1319 | } |
| 1284 | else | 1320 | else |
| 1285 | { | 1321 | { |
| 1322 | /* We were asked to provide info about WINDOW_END. */ | ||
| 1286 | struct it it2; | 1323 | struct it it2; |
| 1324 | void *it2data = NULL; | ||
| 1287 | 1325 | ||
| 1288 | it2 = it; | 1326 | SAVE_IT (it2, it, it2data); |
| 1289 | if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n') | 1327 | if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n') |
| 1290 | move_it_by_lines (&it, 1); | 1328 | move_it_by_lines (&it, 1); |
| 1291 | if (charpos < IT_CHARPOS (it) | 1329 | if (charpos < IT_CHARPOS (it) |
| 1292 | || (it.what == IT_EOB && charpos == IT_CHARPOS (it))) | 1330 | || (it.what == IT_EOB && charpos == IT_CHARPOS (it))) |
| 1293 | { | 1331 | { |
| 1294 | visible_p = 1; | 1332 | visible_p = 1; |
| 1333 | RESTORE_IT (&it2, &it2, it2data); | ||
| 1295 | move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS); | 1334 | move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS); |
| 1296 | *x = it2.current_x; | 1335 | *x = it2.current_x; |
| 1297 | *y = it2.current_y + it2.max_ascent - it2.ascent; | 1336 | *y = it2.current_y + it2.max_ascent - it2.ascent; |
| @@ -1304,7 +1343,10 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y, | |||
| 1304 | WINDOW_HEADER_LINE_HEIGHT (w)))); | 1343 | WINDOW_HEADER_LINE_HEIGHT (w)))); |
| 1305 | *vpos = it2.vpos; | 1344 | *vpos = it2.vpos; |
| 1306 | } | 1345 | } |
| 1346 | else | ||
| 1347 | xfree (it2data); | ||
| 1307 | } | 1348 | } |
| 1349 | bidi_unshelve_cache (itdata); | ||
| 1308 | 1350 | ||
| 1309 | if (old_buffer) | 1351 | if (old_buffer) |
| 1310 | set_buffer_internal_1 (old_buffer); | 1352 | set_buffer_internal_1 (old_buffer); |
| @@ -2212,8 +2254,7 @@ safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2) | |||
| 2212 | This is for debugging. It is too slow to do unconditionally. */ | 2254 | This is for debugging. It is too slow to do unconditionally. */ |
| 2213 | 2255 | ||
| 2214 | static void | 2256 | static void |
| 2215 | check_it (it) | 2257 | check_it (struct it *it) |
| 2216 | struct it *it; | ||
| 2217 | { | 2258 | { |
| 2218 | if (it->method == GET_FROM_STRING) | 2259 | if (it->method == GET_FROM_STRING) |
| 2219 | { | 2260 | { |
| @@ -2343,6 +2384,10 @@ init_iterator (struct it *it, struct window *w, | |||
| 2343 | it->base_face_id = remapped_base_face_id; | 2384 | it->base_face_id = remapped_base_face_id; |
| 2344 | it->string = Qnil; | 2385 | it->string = Qnil; |
| 2345 | IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1; | 2386 | IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1; |
| 2387 | it->paragraph_embedding = L2R; | ||
| 2388 | it->bidi_it.string.lstring = Qnil; | ||
| 2389 | it->bidi_it.string.s = NULL; | ||
| 2390 | it->bidi_it.string.bufpos = 0; | ||
| 2346 | 2391 | ||
| 2347 | /* The window in which we iterate over current_buffer: */ | 2392 | /* The window in which we iterate over current_buffer: */ |
| 2348 | XSETWINDOW (it->window, w); | 2393 | XSETWINDOW (it->window, w); |
| @@ -2399,13 +2444,6 @@ init_iterator (struct it *it, struct window *w, | |||
| 2399 | /* Are multibyte characters enabled in current_buffer? */ | 2444 | /* Are multibyte characters enabled in current_buffer? */ |
| 2400 | it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 2445 | it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 2401 | 2446 | ||
| 2402 | /* Do we need to reorder bidirectional text? Not if this is a | ||
| 2403 | unibyte buffer: by definition, none of the single-byte characters | ||
| 2404 | are strong R2L, so no reordering is needed. And bidi.c doesn't | ||
| 2405 | support unibyte buffers anyway. */ | ||
| 2406 | it->bidi_p | ||
| 2407 | = !NILP (BVAR (current_buffer, bidi_display_reordering)) && it->multibyte_p; | ||
| 2408 | |||
| 2409 | /* Non-zero if we should highlight the region. */ | 2447 | /* Non-zero if we should highlight the region. */ |
| 2410 | highlight_region_p | 2448 | highlight_region_p |
| 2411 | = (!NILP (Vtransient_mark_mode) | 2449 | = (!NILP (Vtransient_mark_mode) |
| @@ -2555,21 +2593,6 @@ init_iterator (struct it *it, struct window *w, | |||
| 2555 | it->start_of_box_run_p = 1; | 2593 | it->start_of_box_run_p = 1; |
| 2556 | } | 2594 | } |
| 2557 | 2595 | ||
| 2558 | /* If we are to reorder bidirectional text, init the bidi | ||
| 2559 | iterator. */ | ||
| 2560 | if (it->bidi_p) | ||
| 2561 | { | ||
| 2562 | /* Note the paragraph direction that this buffer wants to | ||
| 2563 | use. */ | ||
| 2564 | if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qleft_to_right)) | ||
| 2565 | it->paragraph_embedding = L2R; | ||
| 2566 | else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qright_to_left)) | ||
| 2567 | it->paragraph_embedding = R2L; | ||
| 2568 | else | ||
| 2569 | it->paragraph_embedding = NEUTRAL_DIR; | ||
| 2570 | bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 2571 | } | ||
| 2572 | |||
| 2573 | /* If a buffer position was specified, set the iterator there, | 2596 | /* If a buffer position was specified, set the iterator there, |
| 2574 | getting overlays and face properties from that position. */ | 2597 | getting overlays and face properties from that position. */ |
| 2575 | if (charpos >= BUF_BEG (current_buffer)) | 2598 | if (charpos >= BUF_BEG (current_buffer)) |
| @@ -2585,6 +2608,32 @@ init_iterator (struct it *it, struct window *w, | |||
| 2585 | IT_BYTEPOS (*it) = bytepos; | 2608 | IT_BYTEPOS (*it) = bytepos; |
| 2586 | 2609 | ||
| 2587 | it->start = it->current; | 2610 | it->start = it->current; |
| 2611 | /* Do we need to reorder bidirectional text? Not if this is a | ||
| 2612 | unibyte buffer: by definition, none of the single-byte | ||
| 2613 | characters are strong R2L, so no reordering is needed. And | ||
| 2614 | bidi.c doesn't support unibyte buffers anyway. */ | ||
| 2615 | it->bidi_p = | ||
| 2616 | !NILP (BVAR (current_buffer, bidi_display_reordering)) | ||
| 2617 | && it->multibyte_p; | ||
| 2618 | |||
| 2619 | /* If we are to reorder bidirectional text, init the bidi | ||
| 2620 | iterator. */ | ||
| 2621 | if (it->bidi_p) | ||
| 2622 | { | ||
| 2623 | /* Note the paragraph direction that this buffer wants to | ||
| 2624 | use. */ | ||
| 2625 | if (EQ (BVAR (current_buffer, bidi_paragraph_direction), | ||
| 2626 | Qleft_to_right)) | ||
| 2627 | it->paragraph_embedding = L2R; | ||
| 2628 | else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), | ||
| 2629 | Qright_to_left)) | ||
| 2630 | it->paragraph_embedding = R2L; | ||
| 2631 | else | ||
| 2632 | it->paragraph_embedding = NEUTRAL_DIR; | ||
| 2633 | bidi_unshelve_cache (NULL); | ||
| 2634 | bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), | ||
| 2635 | &it->bidi_it); | ||
| 2636 | } | ||
| 2588 | 2637 | ||
| 2589 | /* Compute faces etc. */ | 2638 | /* Compute faces etc. */ |
| 2590 | reseat (it, it->current.pos, 1); | 2639 | reseat (it, it->current.pos, 1); |
| @@ -2906,6 +2955,7 @@ handle_stop (struct it *it) | |||
| 2906 | { | 2955 | { |
| 2907 | it->ignore_overlay_strings_at_pos_p = 1; | 2956 | it->ignore_overlay_strings_at_pos_p = 1; |
| 2908 | it->string_from_display_prop_p = 0; | 2957 | it->string_from_display_prop_p = 0; |
| 2958 | it->from_disp_prop_p = 0; | ||
| 2909 | handle_overlay_change_p = 0; | 2959 | handle_overlay_change_p = 0; |
| 2910 | } | 2960 | } |
| 2911 | handled = HANDLED_RECOMPUTE_PROPS; | 2961 | handled = HANDLED_RECOMPUTE_PROPS; |
| @@ -3087,37 +3137,50 @@ next_overlay_change (EMACS_INT pos) | |||
| 3087 | return endpos; | 3137 | return endpos; |
| 3088 | } | 3138 | } |
| 3089 | 3139 | ||
| 3090 | /* Return the character position of a display string at or after CHARPOS. | 3140 | /* Return the character position of a display string at or after |
| 3091 | If no display string exists at or after CHARPOS, return ZV. A | 3141 | position specified by POSITION. If no display string exists at or |
| 3092 | display string is either an overlay with `display' property whose | 3142 | after POSITION, return ZV. A display string is either an overlay |
| 3093 | value is a string, or a `display' text property whose value is a | 3143 | with `display' property whose value is a string, or a `display' |
| 3094 | string. FRAME_WINDOW_P is non-zero when we are displaying a window | 3144 | text property whose value is a string. STRING is data about the |
| 3145 | string to iterate; if STRING->lstring is nil, we are iterating a | ||
| 3146 | buffer. FRAME_WINDOW_P is non-zero when we are displaying a window | ||
| 3095 | on a GUI frame. */ | 3147 | on a GUI frame. */ |
| 3096 | EMACS_INT | 3148 | EMACS_INT |
| 3097 | compute_display_string_pos (EMACS_INT charpos, int frame_window_p) | 3149 | compute_display_string_pos (struct text_pos *position, |
| 3150 | struct bidi_string_data *string, int frame_window_p) | ||
| 3098 | { | 3151 | { |
| 3099 | /* FIXME: Support display properties on strings (object = Qnil means | 3152 | /* OBJECT = nil means current buffer. */ |
| 3100 | current buffer). */ | 3153 | Lisp_Object object = |
| 3101 | Lisp_Object object = Qnil; | 3154 | (string && STRINGP (string->lstring)) ? string->lstring : Qnil; |
| 3102 | Lisp_Object pos, spec; | 3155 | Lisp_Object pos, spec; |
| 3103 | struct text_pos position; | 3156 | int string_p = (string && (STRINGP (string->lstring) || string->s)); |
| 3104 | EMACS_INT bufpos; | 3157 | EMACS_INT eob = string_p ? string->schars : ZV; |
| 3105 | 3158 | EMACS_INT begb = string_p ? 0 : BEGV; | |
| 3106 | if (charpos >= ZV) | 3159 | EMACS_INT bufpos, charpos = CHARPOS (*position); |
| 3107 | return ZV; | 3160 | struct text_pos tpos; |
| 3161 | |||
| 3162 | if (charpos >= eob | ||
| 3163 | /* We don't support display properties whose values are strings | ||
| 3164 | that have display string properties. */ | ||
| 3165 | || string->from_disp_str | ||
| 3166 | /* C strings cannot have display properties. */ | ||
| 3167 | || (string->s && !STRINGP (object))) | ||
| 3168 | return eob; | ||
| 3108 | 3169 | ||
| 3109 | /* If the character at CHARPOS is where the display string begins, | 3170 | /* If the character at CHARPOS is where the display string begins, |
| 3110 | return CHARPOS. */ | 3171 | return CHARPOS. */ |
| 3111 | pos = make_number (charpos); | 3172 | pos = make_number (charpos); |
| 3112 | CHARPOS (position) = charpos; | 3173 | if (STRINGP (object)) |
| 3113 | BYTEPOS (position) = CHAR_TO_BYTE (charpos); | 3174 | bufpos = string->bufpos; |
| 3114 | bufpos = charpos; /* FIXME! support strings as well */ | 3175 | else |
| 3176 | bufpos = charpos; | ||
| 3177 | tpos = *position; | ||
| 3115 | if (!NILP (spec = Fget_char_property (pos, Qdisplay, object)) | 3178 | if (!NILP (spec = Fget_char_property (pos, Qdisplay, object)) |
| 3116 | && (charpos <= BEGV | 3179 | && (charpos <= begb |
| 3117 | || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay, | 3180 | || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay, |
| 3118 | object), | 3181 | object), |
| 3119 | spec)) | 3182 | spec)) |
| 3120 | && handle_display_spec (NULL, spec, object, Qnil, &position, bufpos, | 3183 | && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3121 | frame_window_p)) | 3184 | frame_window_p)) |
| 3122 | return charpos; | 3185 | return charpos; |
| 3123 | 3186 | ||
| @@ -3125,17 +3188,21 @@ compute_display_string_pos (EMACS_INT charpos, int frame_window_p) | |||
| 3125 | that will replace the underlying text when displayed. */ | 3188 | that will replace the underlying text when displayed. */ |
| 3126 | do { | 3189 | do { |
| 3127 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); | 3190 | pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); |
| 3128 | CHARPOS (position) = XFASTINT (pos); | 3191 | CHARPOS (tpos) = XFASTINT (pos); |
| 3129 | BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position)); | 3192 | if (STRINGP (object)) |
| 3130 | if (CHARPOS (position) >= ZV) | 3193 | BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos)); |
| 3194 | else | ||
| 3195 | BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos)); | ||
| 3196 | if (CHARPOS (tpos) >= eob) | ||
| 3131 | break; | 3197 | break; |
| 3132 | spec = Fget_char_property (pos, Qdisplay, object); | 3198 | spec = Fget_char_property (pos, Qdisplay, object); |
| 3133 | bufpos = CHARPOS (position); /* FIXME! support strings as well */ | 3199 | if (!STRINGP (object)) |
| 3200 | bufpos = CHARPOS (tpos); | ||
| 3134 | } while (NILP (spec) | 3201 | } while (NILP (spec) |
| 3135 | || !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos, | 3202 | || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3136 | frame_window_p)); | 3203 | frame_window_p)); |
| 3137 | 3204 | ||
| 3138 | return CHARPOS (position); | 3205 | return CHARPOS (tpos); |
| 3139 | } | 3206 | } |
| 3140 | 3207 | ||
| 3141 | /* Return the character position of the end of the display string that | 3208 | /* Return the character position of the end of the display string that |
| @@ -3143,15 +3210,17 @@ compute_display_string_pos (EMACS_INT charpos, int frame_window_p) | |||
| 3143 | `display' property whose value is a string or a `display' text | 3210 | `display' property whose value is a string or a `display' text |
| 3144 | property whose value is a string. */ | 3211 | property whose value is a string. */ |
| 3145 | EMACS_INT | 3212 | EMACS_INT |
| 3146 | compute_display_string_end (EMACS_INT charpos) | 3213 | compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string) |
| 3147 | { | 3214 | { |
| 3148 | /* FIXME: Support display properties on strings (object = Qnil means | 3215 | /* OBJECT = nil means current buffer. */ |
| 3149 | current buffer). */ | 3216 | Lisp_Object object = |
| 3150 | Lisp_Object object = Qnil; | 3217 | (string && STRINGP (string->lstring)) ? string->lstring : Qnil; |
| 3151 | Lisp_Object pos = make_number (charpos); | 3218 | Lisp_Object pos = make_number (charpos); |
| 3219 | EMACS_INT eob = | ||
| 3220 | (STRINGP (object) || (string && string->s)) ? string->schars : ZV; | ||
| 3152 | 3221 | ||
| 3153 | if (charpos >= ZV) | 3222 | if (charpos >= eob || (string->s && !STRINGP (object))) |
| 3154 | return ZV; | 3223 | return eob; |
| 3155 | 3224 | ||
| 3156 | if (NILP (Fget_char_property (pos, Qdisplay, object))) | 3225 | if (NILP (Fget_char_property (pos, Qdisplay, object))) |
| 3157 | abort (); | 3226 | abort (); |
| @@ -3444,21 +3513,23 @@ underlying_face_id (struct it *it) | |||
| 3444 | 3513 | ||
| 3445 | 3514 | ||
| 3446 | /* Compute the face one character before or after the current position | 3515 | /* Compute the face one character before or after the current position |
| 3447 | of IT. BEFORE_P non-zero means get the face in front of IT's | 3516 | of IT, in the visual order. BEFORE_P non-zero means get the face |
| 3448 | position. Value is the id of the face. */ | 3517 | in front (to the left in L2R paragraphs, to the right in R2L |
| 3518 | paragraphs) of IT's screen position. Value is the ID of the face. */ | ||
| 3449 | 3519 | ||
| 3450 | static int | 3520 | static int |
| 3451 | face_before_or_after_it_pos (struct it *it, int before_p) | 3521 | face_before_or_after_it_pos (struct it *it, int before_p) |
| 3452 | { | 3522 | { |
| 3453 | int face_id, limit; | 3523 | int face_id, limit; |
| 3454 | EMACS_INT next_check_charpos; | 3524 | EMACS_INT next_check_charpos; |
| 3455 | struct text_pos pos; | 3525 | struct it it_copy; |
| 3526 | void *it_copy_data = NULL; | ||
| 3456 | 3527 | ||
| 3457 | xassert (it->s == NULL); | 3528 | xassert (it->s == NULL); |
| 3458 | 3529 | ||
| 3459 | if (STRINGP (it->string)) | 3530 | if (STRINGP (it->string)) |
| 3460 | { | 3531 | { |
| 3461 | EMACS_INT bufpos; | 3532 | EMACS_INT bufpos, charpos; |
| 3462 | int base_face_id; | 3533 | int base_face_id; |
| 3463 | 3534 | ||
| 3464 | /* No face change past the end of the string (for the case | 3535 | /* No face change past the end of the string (for the case |
| @@ -3468,16 +3539,59 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3468 | || (IT_STRING_CHARPOS (*it) == 0 && before_p)) | 3539 | || (IT_STRING_CHARPOS (*it) == 0 && before_p)) |
| 3469 | return it->face_id; | 3540 | return it->face_id; |
| 3470 | 3541 | ||
| 3471 | /* Set pos to the position before or after IT's current position. */ | 3542 | if (!it->bidi_p) |
| 3472 | if (before_p) | 3543 | { |
| 3473 | pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string); | 3544 | /* Set charpos to the position before or after IT's current |
| 3545 | position, in the logical order, which in the non-bidi | ||
| 3546 | case is the same as the visual order. */ | ||
| 3547 | if (before_p) | ||
| 3548 | charpos = IT_STRING_CHARPOS (*it) - 1; | ||
| 3549 | else if (it->what == IT_COMPOSITION) | ||
| 3550 | /* For composition, we must check the character after the | ||
| 3551 | composition. */ | ||
| 3552 | charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars; | ||
| 3553 | else | ||
| 3554 | charpos = IT_STRING_CHARPOS (*it) + 1; | ||
| 3555 | } | ||
| 3474 | else | 3556 | else |
| 3475 | /* For composition, we must check the character after the | 3557 | { |
| 3476 | composition. */ | 3558 | if (before_p) |
| 3477 | pos = (it->what == IT_COMPOSITION | 3559 | { |
| 3478 | ? string_pos (IT_STRING_CHARPOS (*it) | 3560 | /* With bidi iteration, the character before the current |
| 3479 | + it->cmp_it.nchars, it->string) | 3561 | in the visual order cannot be found by simple |
| 3480 | : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string)); | 3562 | iteration, because "reverse" reordering is not |
| 3563 | supported. Instead, we need to use the move_it_* | ||
| 3564 | family of functions. */ | ||
| 3565 | /* Ignore face changes before the first visible | ||
| 3566 | character on this display line. */ | ||
| 3567 | if (it->current_x <= it->first_visible_x) | ||
| 3568 | return it->face_id; | ||
| 3569 | SAVE_IT (it_copy, *it, it_copy_data); | ||
| 3570 | /* Implementation note: Since move_it_in_display_line | ||
| 3571 | works in the iterator geometry, and thinks the first | ||
| 3572 | character is always the leftmost, even in R2L lines, | ||
| 3573 | we don't need to distinguish between the R2L and L2R | ||
| 3574 | cases here. */ | ||
| 3575 | move_it_in_display_line (&it_copy, SCHARS (it_copy.string), | ||
| 3576 | it_copy.current_x - 1, MOVE_TO_X); | ||
| 3577 | charpos = IT_STRING_CHARPOS (it_copy); | ||
| 3578 | RESTORE_IT (it, it, it_copy_data); | ||
| 3579 | } | ||
| 3580 | else | ||
| 3581 | { | ||
| 3582 | /* Set charpos to the string position of the character | ||
| 3583 | that comes after IT's current position in the visual | ||
| 3584 | order. */ | ||
| 3585 | int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1); | ||
| 3586 | |||
| 3587 | it_copy = *it; | ||
| 3588 | while (n--) | ||
| 3589 | bidi_move_to_visually_next (&it_copy.bidi_it); | ||
| 3590 | |||
| 3591 | charpos = it_copy.bidi_it.charpos; | ||
| 3592 | } | ||
| 3593 | } | ||
| 3594 | xassert (0 <= charpos && charpos <= SCHARS (it->string)); | ||
| 3481 | 3595 | ||
| 3482 | if (it->current.overlay_string_index >= 0) | 3596 | if (it->current.overlay_string_index >= 0) |
| 3483 | bufpos = IT_CHARPOS (*it); | 3597 | bufpos = IT_CHARPOS (*it); |
| @@ -3489,7 +3603,7 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3489 | /* Get the face for ASCII, or unibyte. */ | 3603 | /* Get the face for ASCII, or unibyte. */ |
| 3490 | face_id = face_at_string_position (it->w, | 3604 | face_id = face_at_string_position (it->w, |
| 3491 | it->string, | 3605 | it->string, |
| 3492 | CHARPOS (pos), | 3606 | charpos, |
| 3493 | bufpos, | 3607 | bufpos, |
| 3494 | it->region_beg_charpos, | 3608 | it->region_beg_charpos, |
| 3495 | it->region_end_charpos, | 3609 | it->region_end_charpos, |
| @@ -3501,16 +3615,19 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3501 | suitable for unibyte text if IT->string is unibyte. */ | 3615 | suitable for unibyte text if IT->string is unibyte. */ |
| 3502 | if (STRING_MULTIBYTE (it->string)) | 3616 | if (STRING_MULTIBYTE (it->string)) |
| 3503 | { | 3617 | { |
| 3504 | const unsigned char *p = SDATA (it->string) + BYTEPOS (pos); | 3618 | struct text_pos pos1 = string_pos (charpos, it->string); |
| 3619 | const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1); | ||
| 3505 | int c, len; | 3620 | int c, len; |
| 3506 | struct face *face = FACE_FROM_ID (it->f, face_id); | 3621 | struct face *face = FACE_FROM_ID (it->f, face_id); |
| 3507 | 3622 | ||
| 3508 | c = string_char_and_length (p, &len); | 3623 | c = string_char_and_length (p, &len); |
| 3509 | face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string); | 3624 | face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string); |
| 3510 | } | 3625 | } |
| 3511 | } | 3626 | } |
| 3512 | else | 3627 | else |
| 3513 | { | 3628 | { |
| 3629 | struct text_pos pos; | ||
| 3630 | |||
| 3514 | if ((IT_CHARPOS (*it) >= ZV && !before_p) | 3631 | if ((IT_CHARPOS (*it) >= ZV && !before_p) |
| 3515 | || (IT_CHARPOS (*it) <= BEGV && before_p)) | 3632 | || (IT_CHARPOS (*it) <= BEGV && before_p)) |
| 3516 | return it->face_id; | 3633 | return it->face_id; |
| @@ -3518,17 +3635,63 @@ face_before_or_after_it_pos (struct it *it, int before_p) | |||
| 3518 | limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT; | 3635 | limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT; |
| 3519 | pos = it->current.pos; | 3636 | pos = it->current.pos; |
| 3520 | 3637 | ||
| 3521 | if (before_p) | 3638 | if (!it->bidi_p) |
| 3522 | DEC_TEXT_POS (pos, it->multibyte_p); | 3639 | { |
| 3640 | if (before_p) | ||
| 3641 | DEC_TEXT_POS (pos, it->multibyte_p); | ||
| 3642 | else | ||
| 3643 | { | ||
| 3644 | if (it->what == IT_COMPOSITION) | ||
| 3645 | { | ||
| 3646 | /* For composition, we must check the position after | ||
| 3647 | the composition. */ | ||
| 3648 | pos.charpos += it->cmp_it.nchars; | ||
| 3649 | pos.bytepos += it->len; | ||
| 3650 | } | ||
| 3651 | else | ||
| 3652 | INC_TEXT_POS (pos, it->multibyte_p); | ||
| 3653 | } | ||
| 3654 | } | ||
| 3523 | else | 3655 | else |
| 3524 | { | 3656 | { |
| 3525 | if (it->what == IT_COMPOSITION) | 3657 | if (before_p) |
| 3526 | /* For composition, we must check the position after the | 3658 | { |
| 3527 | composition. */ | 3659 | /* With bidi iteration, the character before the current |
| 3528 | pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len; | 3660 | in the visual order cannot be found by simple |
| 3661 | iteration, because "reverse" reordering is not | ||
| 3662 | supported. Instead, we need to use the move_it_* | ||
| 3663 | family of functions. */ | ||
| 3664 | /* Ignore face changes before the first visible | ||
| 3665 | character on this display line. */ | ||
| 3666 | if (it->current_x <= it->first_visible_x) | ||
| 3667 | return it->face_id; | ||
| 3668 | SAVE_IT (it_copy, *it, it_copy_data); | ||
| 3669 | /* Implementation note: Since move_it_in_display_line | ||
| 3670 | works in the iterator geometry, and thinks the first | ||
| 3671 | character is always the leftmost, even in R2L lines, | ||
| 3672 | we don't need to distinguish between the R2L and L2R | ||
| 3673 | cases here. */ | ||
| 3674 | move_it_in_display_line (&it_copy, ZV, | ||
| 3675 | it_copy.current_x - 1, MOVE_TO_X); | ||
| 3676 | pos = it_copy.current.pos; | ||
| 3677 | RESTORE_IT (it, it, it_copy_data); | ||
| 3678 | } | ||
| 3529 | else | 3679 | else |
| 3530 | INC_TEXT_POS (pos, it->multibyte_p); | 3680 | { |
| 3681 | /* Set charpos to the buffer position of the character | ||
| 3682 | that comes after IT's current position in the visual | ||
| 3683 | order. */ | ||
| 3684 | int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1); | ||
| 3685 | |||
| 3686 | it_copy = *it; | ||
| 3687 | while (n--) | ||
| 3688 | bidi_move_to_visually_next (&it_copy.bidi_it); | ||
| 3689 | |||
| 3690 | SET_TEXT_POS (pos, | ||
| 3691 | it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos); | ||
| 3692 | } | ||
| 3531 | } | 3693 | } |
| 3694 | xassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV); | ||
| 3532 | 3695 | ||
| 3533 | /* Determine face for CHARSET_ASCII, or unibyte. */ | 3696 | /* Determine face for CHARSET_ASCII, or unibyte. */ |
| 3534 | face_id = face_at_buffer_position (it->w, | 3697 | face_id = face_at_buffer_position (it->w, |
| @@ -3579,6 +3742,8 @@ handle_invisible_prop (struct it *it) | |||
| 3579 | if (!NILP (prop) | 3742 | if (!NILP (prop) |
| 3580 | && IT_STRING_CHARPOS (*it) < it->end_charpos) | 3743 | && IT_STRING_CHARPOS (*it) < it->end_charpos) |
| 3581 | { | 3744 | { |
| 3745 | EMACS_INT endpos; | ||
| 3746 | |||
| 3582 | handled = HANDLED_RECOMPUTE_PROPS; | 3747 | handled = HANDLED_RECOMPUTE_PROPS; |
| 3583 | 3748 | ||
| 3584 | /* Get the position at which the next change of the | 3749 | /* Get the position at which the next change of the |
| @@ -3593,12 +3758,37 @@ handle_invisible_prop (struct it *it) | |||
| 3593 | change in the property is at position end_charpos. | 3758 | change in the property is at position end_charpos. |
| 3594 | Move IT's current position to that position. */ | 3759 | Move IT's current position to that position. */ |
| 3595 | if (INTEGERP (end_charpos) | 3760 | if (INTEGERP (end_charpos) |
| 3596 | && XFASTINT (end_charpos) < XFASTINT (limit)) | 3761 | && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit)) |
| 3597 | { | 3762 | { |
| 3598 | struct text_pos old; | 3763 | struct text_pos old; |
| 3764 | EMACS_INT oldpos; | ||
| 3765 | |||
| 3599 | old = it->current.string_pos; | 3766 | old = it->current.string_pos; |
| 3600 | IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos); | 3767 | oldpos = CHARPOS (old); |
| 3601 | compute_string_pos (&it->current.string_pos, old, it->string); | 3768 | if (it->bidi_p) |
| 3769 | { | ||
| 3770 | if (it->bidi_it.first_elt | ||
| 3771 | && it->bidi_it.charpos < SCHARS (it->string)) | ||
| 3772 | bidi_paragraph_init (it->paragraph_embedding, | ||
| 3773 | &it->bidi_it, 1); | ||
| 3774 | /* Bidi-iterate out of the invisible text. */ | ||
| 3775 | do | ||
| 3776 | { | ||
| 3777 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 3778 | } | ||
| 3779 | while (oldpos <= it->bidi_it.charpos | ||
| 3780 | && it->bidi_it.charpos < endpos); | ||
| 3781 | |||
| 3782 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 3783 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 3784 | if (IT_CHARPOS (*it) >= endpos) | ||
| 3785 | it->prev_stop = endpos; | ||
| 3786 | } | ||
| 3787 | else | ||
| 3788 | { | ||
| 3789 | IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos); | ||
| 3790 | compute_string_pos (&it->current.string_pos, old, it->string); | ||
| 3791 | } | ||
| 3602 | } | 3792 | } |
| 3603 | else | 3793 | else |
| 3604 | { | 3794 | { |
| @@ -4250,6 +4440,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4250 | it->method = GET_FROM_IMAGE; | 4440 | it->method = GET_FROM_IMAGE; |
| 4251 | it->from_overlay = Qnil; | 4441 | it->from_overlay = Qnil; |
| 4252 | it->face_id = face_id; | 4442 | it->face_id = face_id; |
| 4443 | it->from_disp_prop_p = 1; | ||
| 4253 | 4444 | ||
| 4254 | /* Say that we haven't consumed the characters with | 4445 | /* Say that we haven't consumed the characters with |
| 4255 | `display' property yet. The call to pop_it in | 4446 | `display' property yet. The call to pop_it in |
| @@ -4332,6 +4523,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4332 | when we are finished with the glyph property value. */ | 4523 | when we are finished with the glyph property value. */ |
| 4333 | push_it (it, position); | 4524 | push_it (it, position); |
| 4334 | it->from_overlay = overlay; | 4525 | it->from_overlay = overlay; |
| 4526 | it->from_disp_prop_p = 1; | ||
| 4335 | 4527 | ||
| 4336 | if (NILP (location)) | 4528 | if (NILP (location)) |
| 4337 | it->area = TEXT_AREA; | 4529 | it->area = TEXT_AREA; |
| @@ -4349,12 +4541,34 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4349 | it->end_charpos = it->string_nchars = SCHARS (it->string); | 4541 | it->end_charpos = it->string_nchars = SCHARS (it->string); |
| 4350 | it->method = GET_FROM_STRING; | 4542 | it->method = GET_FROM_STRING; |
| 4351 | it->stop_charpos = 0; | 4543 | it->stop_charpos = 0; |
| 4544 | it->prev_stop = 0; | ||
| 4545 | it->base_level_stop = 0; | ||
| 4352 | it->string_from_display_prop_p = 1; | 4546 | it->string_from_display_prop_p = 1; |
| 4353 | /* Say that we haven't consumed the characters with | 4547 | /* Say that we haven't consumed the characters with |
| 4354 | `display' property yet. The call to pop_it in | 4548 | `display' property yet. The call to pop_it in |
| 4355 | set_iterator_to_next will clean this up. */ | 4549 | set_iterator_to_next will clean this up. */ |
| 4356 | if (BUFFERP (object)) | 4550 | if (BUFFERP (object)) |
| 4357 | *position = start_pos; | 4551 | *position = start_pos; |
| 4552 | |||
| 4553 | /* Force paragraph direction to be that of the parent | ||
| 4554 | object. If the parent object's paragraph direction is | ||
| 4555 | not yet determined, default to L2R. */ | ||
| 4556 | if (it->bidi_p && it->bidi_it.paragraph_dir == R2L) | ||
| 4557 | it->paragraph_embedding = it->bidi_it.paragraph_dir; | ||
| 4558 | else | ||
| 4559 | it->paragraph_embedding = L2R; | ||
| 4560 | |||
| 4561 | /* Set up the bidi iterator for this display string. */ | ||
| 4562 | if (it->bidi_p) | ||
| 4563 | { | ||
| 4564 | it->bidi_it.string.lstring = it->string; | ||
| 4565 | it->bidi_it.string.s = NULL; | ||
| 4566 | it->bidi_it.string.schars = it->end_charpos; | ||
| 4567 | it->bidi_it.string.bufpos = bufpos; | ||
| 4568 | it->bidi_it.string.from_disp_str = 1; | ||
| 4569 | it->bidi_it.string.unibyte = !it->multibyte_p; | ||
| 4570 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 4571 | } | ||
| 4358 | } | 4572 | } |
| 4359 | else if (CONSP (value) && EQ (XCAR (value), Qspace)) | 4573 | else if (CONSP (value) && EQ (XCAR (value), Qspace)) |
| 4360 | { | 4574 | { |
| @@ -4610,6 +4824,11 @@ handle_composition_prop (struct it *it) | |||
| 4610 | && COMPOSITION_VALID_P (start, end, prop) | 4824 | && COMPOSITION_VALID_P (start, end, prop) |
| 4611 | && (STRINGP (it->string) || (PT <= start || PT >= end))) | 4825 | && (STRINGP (it->string) || (PT <= start || PT >= end))) |
| 4612 | { | 4826 | { |
| 4827 | if (start < pos) | ||
| 4828 | /* As we can't handle this situation (perhaps font-lock added | ||
| 4829 | a new composition), we just return here hoping that next | ||
| 4830 | redisplay will detect this composition much earlier. */ | ||
| 4831 | return HANDLED_NORMALLY; | ||
| 4613 | if (start != pos) | 4832 | if (start != pos) |
| 4614 | { | 4833 | { |
| 4615 | if (STRINGP (it->string)) | 4834 | if (STRINGP (it->string)) |
| @@ -4718,6 +4937,20 @@ next_overlay_string (struct it *it) | |||
| 4718 | it->stop_charpos = 0; | 4937 | it->stop_charpos = 0; |
| 4719 | if (it->cmp_it.stop_pos >= 0) | 4938 | if (it->cmp_it.stop_pos >= 0) |
| 4720 | it->cmp_it.stop_pos = 0; | 4939 | it->cmp_it.stop_pos = 0; |
| 4940 | it->prev_stop = 0; | ||
| 4941 | it->base_level_stop = 0; | ||
| 4942 | |||
| 4943 | /* Set up the bidi iterator for this overlay string. */ | ||
| 4944 | if (it->bidi_p) | ||
| 4945 | { | ||
| 4946 | it->bidi_it.string.lstring = it->string; | ||
| 4947 | it->bidi_it.string.s = NULL; | ||
| 4948 | it->bidi_it.string.schars = SCHARS (it->string); | ||
| 4949 | it->bidi_it.string.bufpos = it->overlay_strings_charpos; | ||
| 4950 | it->bidi_it.string.from_disp_str = it->string_from_display_prop_p; | ||
| 4951 | it->bidi_it.string.unibyte = !it->multibyte_p; | ||
| 4952 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 4953 | } | ||
| 4721 | } | 4954 | } |
| 4722 | 4955 | ||
| 4723 | CHECK_IT (it); | 4956 | CHECK_IT (it); |
| @@ -4984,8 +5217,32 @@ get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p) | |||
| 4984 | it->stop_charpos = 0; | 5217 | it->stop_charpos = 0; |
| 4985 | xassert (STRINGP (it->string)); | 5218 | xassert (STRINGP (it->string)); |
| 4986 | it->end_charpos = SCHARS (it->string); | 5219 | it->end_charpos = SCHARS (it->string); |
| 5220 | it->prev_stop = 0; | ||
| 5221 | it->base_level_stop = 0; | ||
| 4987 | it->multibyte_p = STRING_MULTIBYTE (it->string); | 5222 | it->multibyte_p = STRING_MULTIBYTE (it->string); |
| 4988 | it->method = GET_FROM_STRING; | 5223 | it->method = GET_FROM_STRING; |
| 5224 | it->from_disp_prop_p = 0; | ||
| 5225 | |||
| 5226 | /* Force paragraph direction to be that of the parent | ||
| 5227 | buffer. */ | ||
| 5228 | if (it->bidi_p && it->bidi_it.paragraph_dir == R2L) | ||
| 5229 | it->paragraph_embedding = it->bidi_it.paragraph_dir; | ||
| 5230 | else | ||
| 5231 | it->paragraph_embedding = L2R; | ||
| 5232 | |||
| 5233 | /* Set up the bidi iterator for this overlay string. */ | ||
| 5234 | if (it->bidi_p) | ||
| 5235 | { | ||
| 5236 | EMACS_INT pos = (charpos > 0 ? charpos : IT_CHARPOS (*it)); | ||
| 5237 | |||
| 5238 | it->bidi_it.string.lstring = it->string; | ||
| 5239 | it->bidi_it.string.s = NULL; | ||
| 5240 | it->bidi_it.string.schars = SCHARS (it->string); | ||
| 5241 | it->bidi_it.string.bufpos = pos; | ||
| 5242 | it->bidi_it.string.from_disp_str = it->string_from_display_prop_p; | ||
| 5243 | it->bidi_it.string.unibyte = !it->multibyte_p; | ||
| 5244 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 5245 | } | ||
| 4989 | return 1; | 5246 | return 1; |
| 4990 | } | 5247 | } |
| 4991 | 5248 | ||
| @@ -5064,19 +5321,30 @@ push_it (struct it *it, struct text_pos *position) | |||
| 5064 | p->string_from_display_prop_p = it->string_from_display_prop_p; | 5321 | p->string_from_display_prop_p = it->string_from_display_prop_p; |
| 5065 | p->display_ellipsis_p = 0; | 5322 | p->display_ellipsis_p = 0; |
| 5066 | p->line_wrap = it->line_wrap; | 5323 | p->line_wrap = it->line_wrap; |
| 5324 | p->bidi_p = it->bidi_p; | ||
| 5325 | p->paragraph_embedding = it->paragraph_embedding; | ||
| 5326 | p->from_disp_prop_p = it->from_disp_prop_p; | ||
| 5067 | ++it->sp; | 5327 | ++it->sp; |
| 5328 | |||
| 5329 | /* Save the state of the bidi iterator as well. */ | ||
| 5330 | if (it->bidi_p) | ||
| 5331 | bidi_push_it (&it->bidi_it); | ||
| 5068 | } | 5332 | } |
| 5069 | 5333 | ||
| 5070 | static void | 5334 | static void |
| 5071 | iterate_out_of_display_property (struct it *it) | 5335 | iterate_out_of_display_property (struct it *it) |
| 5072 | { | 5336 | { |
| 5337 | int buffer_p = BUFFERP (it->object); | ||
| 5338 | EMACS_INT eob = (buffer_p ? ZV : it->end_charpos); | ||
| 5339 | EMACS_INT bob = (buffer_p ? BEGV : 0); | ||
| 5340 | |||
| 5073 | /* Maybe initialize paragraph direction. If we are at the beginning | 5341 | /* Maybe initialize paragraph direction. If we are at the beginning |
| 5074 | of a new paragraph, next_element_from_buffer may not have a | 5342 | of a new paragraph, next_element_from_buffer may not have a |
| 5075 | chance to do that. */ | 5343 | chance to do that. */ |
| 5076 | if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) | 5344 | if (it->bidi_it.first_elt && it->bidi_it.charpos < eob) |
| 5077 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | 5345 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); |
| 5078 | /* prev_stop can be zero, so check against BEGV as well. */ | 5346 | /* prev_stop can be zero, so check against BEGV as well. */ |
| 5079 | while (it->bidi_it.charpos >= BEGV | 5347 | while (it->bidi_it.charpos >= bob |
| 5080 | && it->prev_stop <= it->bidi_it.charpos | 5348 | && it->prev_stop <= it->bidi_it.charpos |
| 5081 | && it->bidi_it.charpos < CHARPOS (it->position)) | 5349 | && it->bidi_it.charpos < CHARPOS (it->position)) |
| 5082 | bidi_move_to_visually_next (&it->bidi_it); | 5350 | bidi_move_to_visually_next (&it->bidi_it); |
| @@ -5090,7 +5358,10 @@ iterate_out_of_display_property (struct it *it) | |||
| 5090 | { | 5358 | { |
| 5091 | SET_TEXT_POS (it->position, | 5359 | SET_TEXT_POS (it->position, |
| 5092 | it->bidi_it.charpos, it->bidi_it.bytepos); | 5360 | it->bidi_it.charpos, it->bidi_it.bytepos); |
| 5093 | it->current.pos = it->position; | 5361 | if (buffer_p) |
| 5362 | it->current.pos = it->position; | ||
| 5363 | else | ||
| 5364 | it->current.string_pos = it->position; | ||
| 5094 | } | 5365 | } |
| 5095 | } | 5366 | } |
| 5096 | 5367 | ||
| @@ -5104,6 +5375,7 @@ static void | |||
| 5104 | pop_it (struct it *it) | 5375 | pop_it (struct it *it) |
| 5105 | { | 5376 | { |
| 5106 | struct iterator_stack_entry *p; | 5377 | struct iterator_stack_entry *p; |
| 5378 | int from_display_prop = it->from_disp_prop_p; | ||
| 5107 | 5379 | ||
| 5108 | xassert (it->sp > 0); | 5380 | xassert (it->sp > 0); |
| 5109 | --it->sp; | 5381 | --it->sp; |
| @@ -5131,22 +5403,10 @@ pop_it (struct it *it) | |||
| 5131 | it->object = p->u.xwidget.object; | 5403 | it->object = p->u.xwidget.object; |
| 5132 | break; | 5404 | break; |
| 5133 | case GET_FROM_STRETCH: | 5405 | case GET_FROM_STRETCH: |
| 5134 | it->object = p->u.comp.object; | 5406 | it->object = p->u.stretch.object; |
| 5135 | break; | 5407 | break; |
| 5136 | case GET_FROM_BUFFER: | 5408 | case GET_FROM_BUFFER: |
| 5137 | it->object = it->w->buffer; | 5409 | it->object = it->w->buffer; |
| 5138 | if (it->bidi_p) | ||
| 5139 | { | ||
| 5140 | /* Bidi-iterate until we get out of the portion of text, if | ||
| 5141 | any, covered by a `display' text property or an overlay | ||
| 5142 | with `display' property. (We cannot just jump there, | ||
| 5143 | because the internal coherency of the bidi iterator state | ||
| 5144 | can not be preserved across such jumps.) We also must | ||
| 5145 | determine the paragraph base direction if the overlay we | ||
| 5146 | just processed is at the beginning of a new | ||
| 5147 | paragraph. */ | ||
| 5148 | iterate_out_of_display_property (it); | ||
| 5149 | } | ||
| 5150 | break; | 5410 | break; |
| 5151 | case GET_FROM_STRING: | 5411 | case GET_FROM_STRING: |
| 5152 | it->object = it->string; | 5412 | it->object = it->string; |
| @@ -5172,6 +5432,30 @@ pop_it (struct it *it) | |||
| 5172 | it->voffset = p->voffset; | 5432 | it->voffset = p->voffset; |
| 5173 | it->string_from_display_prop_p = p->string_from_display_prop_p; | 5433 | it->string_from_display_prop_p = p->string_from_display_prop_p; |
| 5174 | it->line_wrap = p->line_wrap; | 5434 | it->line_wrap = p->line_wrap; |
| 5435 | it->bidi_p = p->bidi_p; | ||
| 5436 | it->paragraph_embedding = p->paragraph_embedding; | ||
| 5437 | it->from_disp_prop_p = p->from_disp_prop_p; | ||
| 5438 | if (it->bidi_p) | ||
| 5439 | { | ||
| 5440 | bidi_pop_it (&it->bidi_it); | ||
| 5441 | /* Bidi-iterate until we get out of the portion of text, if any, | ||
| 5442 | covered by a `display' text property or by an overlay with | ||
| 5443 | `display' property. (We cannot just jump there, because the | ||
| 5444 | internal coherency of the bidi iterator state can not be | ||
| 5445 | preserved across such jumps.) We also must determine the | ||
| 5446 | paragraph base direction if the overlay we just processed is | ||
| 5447 | at the beginning of a new paragraph. */ | ||
| 5448 | if (from_display_prop | ||
| 5449 | && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING)) | ||
| 5450 | iterate_out_of_display_property (it); | ||
| 5451 | |||
| 5452 | xassert ((BUFFERP (it->object) | ||
| 5453 | && IT_CHARPOS (*it) == it->bidi_it.charpos | ||
| 5454 | && IT_BYTEPOS (*it) == it->bidi_it.bytepos) | ||
| 5455 | || (STRINGP (it->object) | ||
| 5456 | && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos | ||
| 5457 | && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)); | ||
| 5458 | } | ||
| 5175 | } | 5459 | } |
| 5176 | 5460 | ||
| 5177 | 5461 | ||
| @@ -5255,15 +5539,16 @@ forward_to_next_line_start (struct it *it, int *skipped_p) | |||
| 5255 | 5539 | ||
| 5256 | xassert (!STRINGP (it->string)); | 5540 | xassert (!STRINGP (it->string)); |
| 5257 | 5541 | ||
| 5258 | /* If there isn't any `display' property in sight, and no | 5542 | /* If we are not bidi-reordering, and there isn't any `display' |
| 5259 | overlays, we can just use the position of the newline in | 5543 | property in sight, and no overlays, we can just use the |
| 5260 | buffer text. */ | 5544 | position of the newline in buffer text. */ |
| 5261 | if (it->stop_charpos >= limit | 5545 | if (!it->bidi_p |
| 5262 | || ((pos = Fnext_single_property_change (make_number (start), | 5546 | && (it->stop_charpos >= limit |
| 5263 | Qdisplay, | 5547 | || ((pos = Fnext_single_property_change (make_number (start), |
| 5264 | Qnil, make_number (limit)), | 5548 | Qdisplay, Qnil, |
| 5265 | NILP (pos)) | 5549 | make_number (limit)), |
| 5266 | && next_overlay_change (start) == ZV)) | 5550 | NILP (pos)) |
| 5551 | && next_overlay_change (start) == ZV))) | ||
| 5267 | { | 5552 | { |
| 5268 | IT_CHARPOS (*it) = limit; | 5553 | IT_CHARPOS (*it) = limit; |
| 5269 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit); | 5554 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit); |
| @@ -5321,10 +5606,13 @@ back_to_previous_visible_line_start (struct it *it) | |||
| 5321 | 5606 | ||
| 5322 | { | 5607 | { |
| 5323 | struct it it2; | 5608 | struct it it2; |
| 5609 | void *it2data = NULL; | ||
| 5324 | EMACS_INT pos; | 5610 | EMACS_INT pos; |
| 5325 | EMACS_INT beg, end; | 5611 | EMACS_INT beg, end; |
| 5326 | Lisp_Object val, overlay; | 5612 | Lisp_Object val, overlay; |
| 5327 | 5613 | ||
| 5614 | SAVE_IT (it2, *it, it2data); | ||
| 5615 | |||
| 5328 | /* If newline is part of a composition, continue from start of composition */ | 5616 | /* If newline is part of a composition, continue from start of composition */ |
| 5329 | if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil) | 5617 | if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil) |
| 5330 | && beg < IT_CHARPOS (*it)) | 5618 | && beg < IT_CHARPOS (*it)) |
| @@ -5332,20 +5620,25 @@ back_to_previous_visible_line_start (struct it *it) | |||
| 5332 | 5620 | ||
| 5333 | /* If newline is replaced by a display property, find start of overlay | 5621 | /* If newline is replaced by a display property, find start of overlay |
| 5334 | or interval and continue search from that point. */ | 5622 | or interval and continue search from that point. */ |
| 5335 | it2 = *it; | ||
| 5336 | pos = --IT_CHARPOS (it2); | 5623 | pos = --IT_CHARPOS (it2); |
| 5337 | --IT_BYTEPOS (it2); | 5624 | --IT_BYTEPOS (it2); |
| 5338 | it2.sp = 0; | 5625 | it2.sp = 0; |
| 5626 | bidi_unshelve_cache (NULL); | ||
| 5339 | it2.string_from_display_prop_p = 0; | 5627 | it2.string_from_display_prop_p = 0; |
| 5628 | it2.from_disp_prop_p = 0; | ||
| 5340 | if (handle_display_prop (&it2) == HANDLED_RETURN | 5629 | if (handle_display_prop (&it2) == HANDLED_RETURN |
| 5341 | && !NILP (val = get_char_property_and_overlay | 5630 | && !NILP (val = get_char_property_and_overlay |
| 5342 | (make_number (pos), Qdisplay, Qnil, &overlay)) | 5631 | (make_number (pos), Qdisplay, Qnil, &overlay)) |
| 5343 | && (OVERLAYP (overlay) | 5632 | && (OVERLAYP (overlay) |
| 5344 | ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) | 5633 | ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) |
| 5345 | : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) | 5634 | : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) |
| 5346 | goto replaced; | 5635 | { |
| 5636 | RESTORE_IT (it, it, it2data); | ||
| 5637 | goto replaced; | ||
| 5638 | } | ||
| 5347 | 5639 | ||
| 5348 | /* Newline is not replaced by anything -- so we are done. */ | 5640 | /* Newline is not replaced by anything -- so we are done. */ |
| 5641 | RESTORE_IT (it, it, it2data); | ||
| 5349 | break; | 5642 | break; |
| 5350 | 5643 | ||
| 5351 | replaced: | 5644 | replaced: |
| @@ -5412,14 +5705,29 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p) | |||
| 5412 | { | 5705 | { |
| 5413 | if (IT_STRING_CHARPOS (*it) > 0) | 5706 | if (IT_STRING_CHARPOS (*it) > 0) |
| 5414 | { | 5707 | { |
| 5415 | --IT_STRING_CHARPOS (*it); | 5708 | if (!it->bidi_p) |
| 5416 | --IT_STRING_BYTEPOS (*it); | 5709 | { |
| 5710 | --IT_STRING_CHARPOS (*it); | ||
| 5711 | --IT_STRING_BYTEPOS (*it); | ||
| 5712 | } | ||
| 5713 | else | ||
| 5714 | /* Setting this flag will cause | ||
| 5715 | bidi_move_to_visually_next not to advance, but | ||
| 5716 | instead deliver the current character (newline), | ||
| 5717 | which is what the ON_NEWLINE_P flag wants. */ | ||
| 5718 | it->bidi_it.first_elt = 1; | ||
| 5417 | } | 5719 | } |
| 5418 | } | 5720 | } |
| 5419 | else if (IT_CHARPOS (*it) > BEGV) | 5721 | else if (IT_CHARPOS (*it) > BEGV) |
| 5420 | { | 5722 | { |
| 5421 | --IT_CHARPOS (*it); | 5723 | if (!it->bidi_p) |
| 5422 | --IT_BYTEPOS (*it); | 5724 | { |
| 5725 | --IT_CHARPOS (*it); | ||
| 5726 | --IT_BYTEPOS (*it); | ||
| 5727 | } | ||
| 5728 | /* With bidi iteration, the call to `reseat' will cause | ||
| 5729 | bidi_move_to_visually_next deliver the current character, | ||
| 5730 | the newline, instead of advancing. */ | ||
| 5423 | reseat (it, it->current.pos, 0); | 5731 | reseat (it, it->current.pos, 0); |
| 5424 | } | 5732 | } |
| 5425 | } | 5733 | } |
| @@ -5501,19 +5809,24 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p) | |||
| 5501 | IT_STRING_CHARPOS (*it) = -1; | 5809 | IT_STRING_CHARPOS (*it) = -1; |
| 5502 | IT_STRING_BYTEPOS (*it) = -1; | 5810 | IT_STRING_BYTEPOS (*it) = -1; |
| 5503 | it->string = Qnil; | 5811 | it->string = Qnil; |
| 5504 | it->string_from_display_prop_p = 0; | ||
| 5505 | it->method = GET_FROM_BUFFER; | 5812 | it->method = GET_FROM_BUFFER; |
| 5506 | it->object = it->w->buffer; | 5813 | it->object = it->w->buffer; |
| 5507 | it->area = TEXT_AREA; | 5814 | it->area = TEXT_AREA; |
| 5508 | it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 5815 | it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 5509 | it->sp = 0; | 5816 | it->sp = 0; |
| 5510 | it->string_from_display_prop_p = 0; | 5817 | it->string_from_display_prop_p = 0; |
| 5818 | it->from_disp_prop_p = 0; | ||
| 5511 | it->face_before_selective_p = 0; | 5819 | it->face_before_selective_p = 0; |
| 5512 | if (it->bidi_p) | 5820 | if (it->bidi_p) |
| 5513 | { | 5821 | { |
| 5514 | it->bidi_it.first_elt = 1; | 5822 | bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), |
| 5823 | &it->bidi_it); | ||
| 5824 | bidi_unshelve_cache (NULL); | ||
| 5515 | it->bidi_it.paragraph_dir = NEUTRAL_DIR; | 5825 | it->bidi_it.paragraph_dir = NEUTRAL_DIR; |
| 5516 | it->bidi_it.disp_pos = -1; | 5826 | it->bidi_it.string.s = NULL; |
| 5827 | it->bidi_it.string.lstring = Qnil; | ||
| 5828 | it->bidi_it.string.bufpos = 0; | ||
| 5829 | it->bidi_it.string.unibyte = 0; | ||
| 5517 | } | 5830 | } |
| 5518 | 5831 | ||
| 5519 | if (set_stop_p) | 5832 | if (set_stop_p) |
| @@ -5564,6 +5877,10 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, | |||
| 5564 | if (multibyte >= 0) | 5877 | if (multibyte >= 0) |
| 5565 | it->multibyte_p = multibyte > 0; | 5878 | it->multibyte_p = multibyte > 0; |
| 5566 | 5879 | ||
| 5880 | /* Bidirectional reordering of strings is controlled by the default | ||
| 5881 | value of bidi-display-reordering. */ | ||
| 5882 | it->bidi_p = !NILP (BVAR (&buffer_defaults, bidi_display_reordering)); | ||
| 5883 | |||
| 5567 | if (s == NULL) | 5884 | if (s == NULL) |
| 5568 | { | 5885 | { |
| 5569 | xassert (STRINGP (string)); | 5886 | xassert (STRINGP (string)); |
| @@ -5572,6 +5889,18 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, | |||
| 5572 | it->end_charpos = it->string_nchars = SCHARS (string); | 5889 | it->end_charpos = it->string_nchars = SCHARS (string); |
| 5573 | it->method = GET_FROM_STRING; | 5890 | it->method = GET_FROM_STRING; |
| 5574 | it->current.string_pos = string_pos (charpos, string); | 5891 | it->current.string_pos = string_pos (charpos, string); |
| 5892 | |||
| 5893 | if (it->bidi_p) | ||
| 5894 | { | ||
| 5895 | it->bidi_it.string.lstring = string; | ||
| 5896 | it->bidi_it.string.s = NULL; | ||
| 5897 | it->bidi_it.string.schars = it->end_charpos; | ||
| 5898 | it->bidi_it.string.bufpos = 0; | ||
| 5899 | it->bidi_it.string.from_disp_str = 0; | ||
| 5900 | it->bidi_it.string.unibyte = !it->multibyte_p; | ||
| 5901 | bidi_init_it (charpos, IT_STRING_BYTEPOS (*it), | ||
| 5902 | FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 5903 | } | ||
| 5575 | } | 5904 | } |
| 5576 | else | 5905 | else |
| 5577 | { | 5906 | { |
| @@ -5592,13 +5921,28 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, | |||
| 5592 | it->end_charpos = it->string_nchars = strlen (s); | 5921 | it->end_charpos = it->string_nchars = strlen (s); |
| 5593 | } | 5922 | } |
| 5594 | 5923 | ||
| 5924 | if (it->bidi_p) | ||
| 5925 | { | ||
| 5926 | it->bidi_it.string.lstring = Qnil; | ||
| 5927 | it->bidi_it.string.s = (const unsigned char *) s; | ||
| 5928 | it->bidi_it.string.schars = it->end_charpos; | ||
| 5929 | it->bidi_it.string.bufpos = 0; | ||
| 5930 | it->bidi_it.string.from_disp_str = 0; | ||
| 5931 | it->bidi_it.string.unibyte = !it->multibyte_p; | ||
| 5932 | bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), | ||
| 5933 | &it->bidi_it); | ||
| 5934 | } | ||
| 5595 | it->method = GET_FROM_C_STRING; | 5935 | it->method = GET_FROM_C_STRING; |
| 5596 | } | 5936 | } |
| 5597 | 5937 | ||
| 5598 | /* PRECISION > 0 means don't return more than PRECISION characters | 5938 | /* PRECISION > 0 means don't return more than PRECISION characters |
| 5599 | from the string. */ | 5939 | from the string. */ |
| 5600 | if (precision > 0 && it->end_charpos - charpos > precision) | 5940 | if (precision > 0 && it->end_charpos - charpos > precision) |
| 5601 | it->end_charpos = it->string_nchars = charpos + precision; | 5941 | { |
| 5942 | it->end_charpos = it->string_nchars = charpos + precision; | ||
| 5943 | if (it->bidi_p) | ||
| 5944 | it->bidi_it.string.schars = it->end_charpos; | ||
| 5945 | } | ||
| 5602 | 5946 | ||
| 5603 | /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH | 5947 | /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH |
| 5604 | characters have been returned. FIELD_WIDTH == 0 means don't pad, | 5948 | characters have been returned. FIELD_WIDTH == 0 means don't pad, |
| @@ -5606,6 +5950,9 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, | |||
| 5606 | padding with `-' at the end of a mode line. */ | 5950 | padding with `-' at the end of a mode line. */ |
| 5607 | if (field_width < 0) | 5951 | if (field_width < 0) |
| 5608 | field_width = INFINITY; | 5952 | field_width = INFINITY; |
| 5953 | /* Implementation note: We deliberately don't enlarge | ||
| 5954 | it->bidi_it.string.schars here to fit it->end_charpos, because | ||
| 5955 | the bidi iterator cannot produce characters out of thin air. */ | ||
| 5609 | if (field_width > it->end_charpos - charpos) | 5956 | if (field_width > it->end_charpos - charpos) |
| 5610 | it->end_charpos = charpos + field_width; | 5957 | it->end_charpos = charpos + field_width; |
| 5611 | 5958 | ||
| @@ -5614,6 +5961,14 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string, | |||
| 5614 | it->dp = XCHAR_TABLE (Vstandard_display_table); | 5961 | it->dp = XCHAR_TABLE (Vstandard_display_table); |
| 5615 | 5962 | ||
| 5616 | it->stop_charpos = charpos; | 5963 | it->stop_charpos = charpos; |
| 5964 | it->prev_stop = charpos; | ||
| 5965 | it->base_level_stop = 0; | ||
| 5966 | if (it->bidi_p) | ||
| 5967 | { | ||
| 5968 | it->bidi_it.first_elt = 1; | ||
| 5969 | it->bidi_it.paragraph_dir = NEUTRAL_DIR; | ||
| 5970 | it->bidi_it.disp_pos = -1; | ||
| 5971 | } | ||
| 5617 | if (s == NULL && it->multibyte_p) | 5972 | if (s == NULL && it->multibyte_p) |
| 5618 | { | 5973 | { |
| 5619 | EMACS_INT endpos = SCHARS (it->string); | 5974 | EMACS_INT endpos = SCHARS (it->string); |
| @@ -6249,8 +6604,22 @@ set_iterator_to_next (struct it *it, int reseat_p) | |||
| 6249 | 6604 | ||
| 6250 | case GET_FROM_C_STRING: | 6605 | case GET_FROM_C_STRING: |
| 6251 | /* Current display element of IT is from a C string. */ | 6606 | /* Current display element of IT is from a C string. */ |
| 6252 | IT_BYTEPOS (*it) += it->len; | 6607 | if (!it->bidi_p |
| 6253 | IT_CHARPOS (*it) += 1; | 6608 | /* If the string position is beyond string's end, it means |
| 6609 | next_element_from_c_string is padding the string with | ||
| 6610 | blanks, in which case we bypass the bidi iterator, | ||
| 6611 | because it cannot deal with such virtual characters. */ | ||
| 6612 | || IT_CHARPOS (*it) >= it->bidi_it.string.schars) | ||
| 6613 | { | ||
| 6614 | IT_BYTEPOS (*it) += it->len; | ||
| 6615 | IT_CHARPOS (*it) += 1; | ||
| 6616 | } | ||
| 6617 | else | ||
| 6618 | { | ||
| 6619 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6620 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6621 | IT_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6622 | } | ||
| 6254 | break; | 6623 | break; |
| 6255 | 6624 | ||
| 6256 | case GET_FROM_DISPLAY_VECTOR: | 6625 | case GET_FROM_DISPLAY_VECTOR: |
| @@ -6304,23 +6673,95 @@ set_iterator_to_next (struct it *it, int reseat_p) | |||
| 6304 | xassert (it->s == NULL && STRINGP (it->string)); | 6673 | xassert (it->s == NULL && STRINGP (it->string)); |
| 6305 | if (it->cmp_it.id >= 0) | 6674 | if (it->cmp_it.id >= 0) |
| 6306 | { | 6675 | { |
| 6307 | IT_STRING_CHARPOS (*it) += it->cmp_it.nchars; | 6676 | int i; |
| 6308 | IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes; | 6677 | |
| 6309 | if (it->cmp_it.to < it->cmp_it.nglyphs) | 6678 | if (! it->bidi_p) |
| 6310 | it->cmp_it.from = it->cmp_it.to; | 6679 | { |
| 6680 | IT_STRING_CHARPOS (*it) += it->cmp_it.nchars; | ||
| 6681 | IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes; | ||
| 6682 | if (it->cmp_it.to < it->cmp_it.nglyphs) | ||
| 6683 | it->cmp_it.from = it->cmp_it.to; | ||
| 6684 | else | ||
| 6685 | { | ||
| 6686 | it->cmp_it.id = -1; | ||
| 6687 | composition_compute_stop_pos (&it->cmp_it, | ||
| 6688 | IT_STRING_CHARPOS (*it), | ||
| 6689 | IT_STRING_BYTEPOS (*it), | ||
| 6690 | it->end_charpos, it->string); | ||
| 6691 | } | ||
| 6692 | } | ||
| 6693 | else if (! it->cmp_it.reversed_p) | ||
| 6694 | { | ||
| 6695 | for (i = 0; i < it->cmp_it.nchars; i++) | ||
| 6696 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6697 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6698 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6699 | |||
| 6700 | if (it->cmp_it.to < it->cmp_it.nglyphs) | ||
| 6701 | it->cmp_it.from = it->cmp_it.to; | ||
| 6702 | else | ||
| 6703 | { | ||
| 6704 | EMACS_INT stop = it->end_charpos; | ||
| 6705 | if (it->bidi_it.scan_dir < 0) | ||
| 6706 | stop = -1; | ||
| 6707 | composition_compute_stop_pos (&it->cmp_it, | ||
| 6708 | IT_STRING_CHARPOS (*it), | ||
| 6709 | IT_STRING_BYTEPOS (*it), stop, | ||
| 6710 | it->string); | ||
| 6711 | } | ||
| 6712 | } | ||
| 6311 | else | 6713 | else |
| 6312 | { | 6714 | { |
| 6313 | it->cmp_it.id = -1; | 6715 | for (i = 0; i < it->cmp_it.nchars; i++) |
| 6314 | composition_compute_stop_pos (&it->cmp_it, | 6716 | bidi_move_to_visually_next (&it->bidi_it); |
| 6315 | IT_STRING_CHARPOS (*it), | 6717 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; |
| 6316 | IT_STRING_BYTEPOS (*it), | 6718 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; |
| 6317 | it->end_charpos, it->string); | 6719 | if (it->cmp_it.from > 0) |
| 6720 | it->cmp_it.to = it->cmp_it.from; | ||
| 6721 | else | ||
| 6722 | { | ||
| 6723 | EMACS_INT stop = it->end_charpos; | ||
| 6724 | if (it->bidi_it.scan_dir < 0) | ||
| 6725 | stop = -1; | ||
| 6726 | composition_compute_stop_pos (&it->cmp_it, | ||
| 6727 | IT_STRING_CHARPOS (*it), | ||
| 6728 | IT_STRING_BYTEPOS (*it), stop, | ||
| 6729 | it->string); | ||
| 6730 | } | ||
| 6318 | } | 6731 | } |
| 6319 | } | 6732 | } |
| 6320 | else | 6733 | else |
| 6321 | { | 6734 | { |
| 6322 | IT_STRING_BYTEPOS (*it) += it->len; | 6735 | if (!it->bidi_p |
| 6323 | IT_STRING_CHARPOS (*it) += 1; | 6736 | /* If the string position is beyond string's end, it |
| 6737 | means next_element_from_string is padding the string | ||
| 6738 | with blanks, in which case we bypass the bidi | ||
| 6739 | iterator, because it cannot deal with such virtual | ||
| 6740 | characters. */ | ||
| 6741 | || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars) | ||
| 6742 | { | ||
| 6743 | IT_STRING_BYTEPOS (*it) += it->len; | ||
| 6744 | IT_STRING_CHARPOS (*it) += 1; | ||
| 6745 | } | ||
| 6746 | else | ||
| 6747 | { | ||
| 6748 | int prev_scan_dir = it->bidi_it.scan_dir; | ||
| 6749 | |||
| 6750 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6751 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6752 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6753 | if (prev_scan_dir != it->bidi_it.scan_dir) | ||
| 6754 | { | ||
| 6755 | EMACS_INT stop = it->end_charpos; | ||
| 6756 | |||
| 6757 | if (it->bidi_it.scan_dir < 0) | ||
| 6758 | stop = -1; | ||
| 6759 | composition_compute_stop_pos (&it->cmp_it, | ||
| 6760 | IT_STRING_CHARPOS (*it), | ||
| 6761 | IT_STRING_BYTEPOS (*it), stop, | ||
| 6762 | it->string); | ||
| 6763 | } | ||
| 6764 | } | ||
| 6324 | } | 6765 | } |
| 6325 | 6766 | ||
| 6326 | consider_string_end: | 6767 | consider_string_end: |
| @@ -6427,6 +6868,107 @@ next_element_from_display_vector (struct it *it) | |||
| 6427 | return 1; | 6868 | return 1; |
| 6428 | } | 6869 | } |
| 6429 | 6870 | ||
| 6871 | /* Get the first element of string/buffer in the visual order, after | ||
| 6872 | being reseated to a new position in a string or a buffer. */ | ||
| 6873 | static void | ||
| 6874 | get_visually_first_element (struct it *it) | ||
| 6875 | { | ||
| 6876 | int string_p = STRINGP (it->string) || it->s; | ||
| 6877 | EMACS_INT eob = (string_p ? it->bidi_it.string.schars : ZV); | ||
| 6878 | EMACS_INT bob = (string_p ? 0 : BEGV); | ||
| 6879 | |||
| 6880 | if (STRINGP (it->string)) | ||
| 6881 | { | ||
| 6882 | it->bidi_it.charpos = IT_STRING_CHARPOS (*it); | ||
| 6883 | it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it); | ||
| 6884 | } | ||
| 6885 | else | ||
| 6886 | { | ||
| 6887 | it->bidi_it.charpos = IT_CHARPOS (*it); | ||
| 6888 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 6889 | } | ||
| 6890 | |||
| 6891 | if (it->bidi_it.charpos == eob) | ||
| 6892 | { | ||
| 6893 | /* Nothing to do, but reset the FIRST_ELT flag, like | ||
| 6894 | bidi_paragraph_init does, because we are not going to | ||
| 6895 | call it. */ | ||
| 6896 | it->bidi_it.first_elt = 0; | ||
| 6897 | } | ||
| 6898 | else if (it->bidi_it.charpos == bob | ||
| 6899 | || (!string_p | ||
| 6900 | /* FIXME: Should support all Unicode line separators. */ | ||
| 6901 | && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' | ||
| 6902 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n'))) | ||
| 6903 | { | ||
| 6904 | /* If we are at the beginning of a line/string, we can produce | ||
| 6905 | the next element right away. */ | ||
| 6906 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6907 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6908 | } | ||
| 6909 | else | ||
| 6910 | { | ||
| 6911 | EMACS_INT orig_bytepos = it->bidi_it.bytepos; | ||
| 6912 | |||
| 6913 | /* We need to prime the bidi iterator starting at the line's or | ||
| 6914 | string's beginning, before we will be able to produce the | ||
| 6915 | next element. */ | ||
| 6916 | if (string_p) | ||
| 6917 | it->bidi_it.charpos = it->bidi_it.bytepos = 0; | ||
| 6918 | else | ||
| 6919 | { | ||
| 6920 | it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it), | ||
| 6921 | -1); | ||
| 6922 | it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos); | ||
| 6923 | } | ||
| 6924 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6925 | do | ||
| 6926 | { | ||
| 6927 | /* Now return to buffer/string position where we were asked | ||
| 6928 | to get the next display element, and produce that. */ | ||
| 6929 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6930 | } | ||
| 6931 | while (it->bidi_it.bytepos != orig_bytepos | ||
| 6932 | && it->bidi_it.charpos < eob); | ||
| 6933 | } | ||
| 6934 | |||
| 6935 | /* Adjust IT's position information to where we ended up. */ | ||
| 6936 | if (STRINGP (it->string)) | ||
| 6937 | { | ||
| 6938 | IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6939 | IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6940 | } | ||
| 6941 | else | ||
| 6942 | { | ||
| 6943 | IT_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6944 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6945 | } | ||
| 6946 | |||
| 6947 | if (STRINGP (it->string) || !it->s) | ||
| 6948 | { | ||
| 6949 | EMACS_INT stop, charpos, bytepos; | ||
| 6950 | |||
| 6951 | if (STRINGP (it->string)) | ||
| 6952 | { | ||
| 6953 | xassert (!it->s); | ||
| 6954 | stop = SCHARS (it->string); | ||
| 6955 | if (stop > it->end_charpos) | ||
| 6956 | stop = it->end_charpos; | ||
| 6957 | charpos = IT_STRING_CHARPOS (*it); | ||
| 6958 | bytepos = IT_STRING_BYTEPOS (*it); | ||
| 6959 | } | ||
| 6960 | else | ||
| 6961 | { | ||
| 6962 | stop = it->end_charpos; | ||
| 6963 | charpos = IT_CHARPOS (*it); | ||
| 6964 | bytepos = IT_BYTEPOS (*it); | ||
| 6965 | } | ||
| 6966 | if (it->bidi_it.scan_dir < 0) | ||
| 6967 | stop = -1; | ||
| 6968 | composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop, | ||
| 6969 | it->string); | ||
| 6970 | } | ||
| 6971 | } | ||
| 6430 | 6972 | ||
| 6431 | /* Load IT with the next display element from Lisp string IT->string. | 6973 | /* Load IT with the next display element from Lisp string IT->string. |
| 6432 | IT->current.string_pos is the current position within the string. | 6974 | IT->current.string_pos is the current position within the string. |
| @@ -6439,18 +6981,79 @@ next_element_from_string (struct it *it) | |||
| 6439 | struct text_pos position; | 6981 | struct text_pos position; |
| 6440 | 6982 | ||
| 6441 | xassert (STRINGP (it->string)); | 6983 | xassert (STRINGP (it->string)); |
| 6984 | xassert (!it->bidi_p || it->string == it->bidi_it.string.lstring); | ||
| 6442 | xassert (IT_STRING_CHARPOS (*it) >= 0); | 6985 | xassert (IT_STRING_CHARPOS (*it) >= 0); |
| 6443 | position = it->current.string_pos; | 6986 | position = it->current.string_pos; |
| 6444 | 6987 | ||
| 6988 | /* With bidi reordering, the character to display might not be the | ||
| 6989 | character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means | ||
| 6990 | that we were reseat()ed to a new string, whose paragraph | ||
| 6991 | direction is not known. */ | ||
| 6992 | if (it->bidi_p && it->bidi_it.first_elt) | ||
| 6993 | { | ||
| 6994 | get_visually_first_element (it); | ||
| 6995 | SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it)); | ||
| 6996 | } | ||
| 6997 | |||
| 6445 | /* Time to check for invisible text? */ | 6998 | /* Time to check for invisible text? */ |
| 6446 | if (IT_STRING_CHARPOS (*it) < it->end_charpos | 6999 | if (IT_STRING_CHARPOS (*it) < it->end_charpos) |
| 6447 | && IT_STRING_CHARPOS (*it) == it->stop_charpos) | ||
| 6448 | { | 7000 | { |
| 6449 | handle_stop (it); | 7001 | if (IT_STRING_CHARPOS (*it) >= it->stop_charpos) |
| 7002 | { | ||
| 7003 | if (!(!it->bidi_p | ||
| 7004 | || BIDI_AT_BASE_LEVEL (it->bidi_it) | ||
| 7005 | || IT_STRING_CHARPOS (*it) == it->stop_charpos)) | ||
| 7006 | { | ||
| 7007 | /* With bidi non-linear iteration, we could find | ||
| 7008 | ourselves far beyond the last computed stop_charpos, | ||
| 7009 | with several other stop positions in between that we | ||
| 7010 | missed. Scan them all now, in buffer's logical | ||
| 7011 | order, until we find and handle the last stop_charpos | ||
| 7012 | that precedes our current position. */ | ||
| 7013 | handle_stop_backwards (it, it->stop_charpos); | ||
| 7014 | return GET_NEXT_DISPLAY_ELEMENT (it); | ||
| 7015 | } | ||
| 7016 | else | ||
| 7017 | { | ||
| 7018 | if (it->bidi_p) | ||
| 7019 | { | ||
| 7020 | /* Take note of the stop position we just moved | ||
| 7021 | across, for when we will move back across it. */ | ||
| 7022 | it->prev_stop = it->stop_charpos; | ||
| 7023 | /* If we are at base paragraph embedding level, take | ||
| 7024 | note of the last stop position seen at this | ||
| 7025 | level. */ | ||
| 7026 | if (BIDI_AT_BASE_LEVEL (it->bidi_it)) | ||
| 7027 | it->base_level_stop = it->stop_charpos; | ||
| 7028 | } | ||
| 7029 | handle_stop (it); | ||
| 6450 | 7030 | ||
| 6451 | /* Since a handler may have changed IT->method, we must | 7031 | /* Since a handler may have changed IT->method, we must |
| 6452 | recurse here. */ | 7032 | recurse here. */ |
| 6453 | return GET_NEXT_DISPLAY_ELEMENT (it); | 7033 | return GET_NEXT_DISPLAY_ELEMENT (it); |
| 7034 | } | ||
| 7035 | } | ||
| 7036 | else if (it->bidi_p | ||
| 7037 | /* If we are before prev_stop, we may have overstepped | ||
| 7038 | on our way backwards a stop_pos, and if so, we need | ||
| 7039 | to handle that stop_pos. */ | ||
| 7040 | && IT_STRING_CHARPOS (*it) < it->prev_stop | ||
| 7041 | /* We can sometimes back up for reasons that have nothing | ||
| 7042 | to do with bidi reordering. E.g., compositions. The | ||
| 7043 | code below is only needed when we are above the base | ||
| 7044 | embedding level, so test for that explicitly. */ | ||
| 7045 | && !BIDI_AT_BASE_LEVEL (it->bidi_it)) | ||
| 7046 | { | ||
| 7047 | /* If we lost track of base_level_stop, we have no better place | ||
| 7048 | for handle_stop_backwards to start from than BEGV. This | ||
| 7049 | happens, e.g., when we were reseated to the previous | ||
| 7050 | screenful of text by vertical-motion. */ | ||
| 7051 | if (it->base_level_stop <= 0 | ||
| 7052 | || IT_STRING_CHARPOS (*it) < it->base_level_stop) | ||
| 7053 | it->base_level_stop = 0; | ||
| 7054 | handle_stop_backwards (it, it->base_level_stop); | ||
| 7055 | return GET_NEXT_DISPLAY_ELEMENT (it); | ||
| 7056 | } | ||
| 6454 | } | 7057 | } |
| 6455 | 7058 | ||
| 6456 | if (it->current.overlay_string_index >= 0) | 7059 | if (it->current.overlay_string_index >= 0) |
| @@ -6464,7 +7067,10 @@ next_element_from_string (struct it *it) | |||
| 6464 | return 0; | 7067 | return 0; |
| 6465 | } | 7068 | } |
| 6466 | else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it), | 7069 | else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it), |
| 6467 | IT_STRING_BYTEPOS (*it), SCHARS (it->string)) | 7070 | IT_STRING_BYTEPOS (*it), |
| 7071 | it->bidi_it.scan_dir < 0 | ||
| 7072 | ? -1 | ||
| 7073 | : SCHARS (it->string)) | ||
| 6468 | && next_element_from_composition (it)) | 7074 | && next_element_from_composition (it)) |
| 6469 | { | 7075 | { |
| 6470 | return 1; | 7076 | return 1; |
| @@ -6499,7 +7105,10 @@ next_element_from_string (struct it *it) | |||
| 6499 | CHARPOS (position) = BYTEPOS (position) = -1; | 7105 | CHARPOS (position) = BYTEPOS (position) = -1; |
| 6500 | } | 7106 | } |
| 6501 | else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it), | 7107 | else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it), |
| 6502 | IT_STRING_BYTEPOS (*it), it->string_nchars) | 7108 | IT_STRING_BYTEPOS (*it), |
| 7109 | it->bidi_it.scan_dir < 0 | ||
| 7110 | ? -1 | ||
| 7111 | : it->string_nchars) | ||
| 6503 | && next_element_from_composition (it)) | 7112 | && next_element_from_composition (it)) |
| 6504 | { | 7113 | { |
| 6505 | return 1; | 7114 | return 1; |
| @@ -6538,12 +7147,20 @@ next_element_from_c_string (struct it *it) | |||
| 6538 | int success_p = 1; | 7147 | int success_p = 1; |
| 6539 | 7148 | ||
| 6540 | xassert (it->s); | 7149 | xassert (it->s); |
| 7150 | xassert (!it->bidi_p || it->s == it->bidi_it.string.s); | ||
| 6541 | it->what = IT_CHARACTER; | 7151 | it->what = IT_CHARACTER; |
| 6542 | BYTEPOS (it->position) = CHARPOS (it->position) = 0; | 7152 | BYTEPOS (it->position) = CHARPOS (it->position) = 0; |
| 6543 | it->object = Qnil; | 7153 | it->object = Qnil; |
| 6544 | 7154 | ||
| 6545 | /* IT's position can be greater IT->string_nchars in case a field | 7155 | /* With bidi reordering, the character to display might not be the |
| 6546 | width or precision has been specified when the iterator was | 7156 | character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that |
| 7157 | we were reseated to a new string, whose paragraph direction is | ||
| 7158 | not known. */ | ||
| 7159 | if (it->bidi_p && it->bidi_it.first_elt) | ||
| 7160 | get_visually_first_element (it); | ||
| 7161 | |||
| 7162 | /* IT's position can be greater than IT->string_nchars in case a | ||
| 7163 | field width or precision has been specified when the iterator was | ||
| 6547 | initialized. */ | 7164 | initialized. */ |
| 6548 | if (IT_CHARPOS (*it) >= it->end_charpos) | 7165 | if (IT_CHARPOS (*it) >= it->end_charpos) |
| 6549 | { | 7166 | { |
| @@ -6630,18 +7247,19 @@ next_element_from_stretch (struct it *it) | |||
| 6630 | return 1; | 7247 | return 1; |
| 6631 | } | 7248 | } |
| 6632 | 7249 | ||
| 6633 | /* Scan forward from CHARPOS in the current buffer, until we find a | 7250 | /* Scan forward from CHARPOS in the current buffer/string, until we |
| 6634 | stop position > current IT's position. Then handle the stop | 7251 | find a stop position > current IT's position. Then handle the stop |
| 6635 | position before that. This is called when we bump into a stop | 7252 | position before that. This is called when we bump into a stop |
| 6636 | position while reordering bidirectional text. CHARPOS should be | 7253 | position while reordering bidirectional text. CHARPOS should be |
| 6637 | the last previously processed stop_pos (or BEGV, if none were | 7254 | the last previously processed stop_pos (or BEGV/0, if none were |
| 6638 | processed yet) whose position is less that IT's current | 7255 | processed yet) whose position is less that IT's current |
| 6639 | position. */ | 7256 | position. */ |
| 6640 | 7257 | ||
| 6641 | static void | 7258 | static void |
| 6642 | handle_stop_backwards (struct it *it, EMACS_INT charpos) | 7259 | handle_stop_backwards (struct it *it, EMACS_INT charpos) |
| 6643 | { | 7260 | { |
| 6644 | EMACS_INT where_we_are = IT_CHARPOS (*it); | 7261 | int bufp = !STRINGP (it->string); |
| 7262 | EMACS_INT where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it)); | ||
| 6645 | struct display_pos save_current = it->current; | 7263 | struct display_pos save_current = it->current; |
| 6646 | struct text_pos save_position = it->position; | 7264 | struct text_pos save_position = it->position; |
| 6647 | struct text_pos pos1; | 7265 | struct text_pos pos1; |
| @@ -6652,8 +7270,13 @@ handle_stop_backwards (struct it *it, EMACS_INT charpos) | |||
| 6652 | do | 7270 | do |
| 6653 | { | 7271 | { |
| 6654 | it->prev_stop = charpos; | 7272 | it->prev_stop = charpos; |
| 6655 | SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos)); | 7273 | if (bufp) |
| 6656 | reseat_1 (it, pos1, 0); | 7274 | { |
| 7275 | SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos)); | ||
| 7276 | reseat_1 (it, pos1, 0); | ||
| 7277 | } | ||
| 7278 | else | ||
| 7279 | it->current.string_pos = string_pos (charpos, it->string); | ||
| 6657 | compute_stop_pos (it); | 7280 | compute_stop_pos (it); |
| 6658 | /* We must advance forward, right? */ | 7281 | /* We must advance forward, right? */ |
| 6659 | if (it->stop_charpos <= it->prev_stop) | 7282 | if (it->stop_charpos <= it->prev_stop) |
| @@ -6682,6 +7305,10 @@ next_element_from_buffer (struct it *it) | |||
| 6682 | int success_p = 1; | 7305 | int success_p = 1; |
| 6683 | 7306 | ||
| 6684 | xassert (IT_CHARPOS (*it) >= BEGV); | 7307 | xassert (IT_CHARPOS (*it) >= BEGV); |
| 7308 | xassert (NILP (it->string) && !it->s); | ||
| 7309 | xassert (!it->bidi_p | ||
| 7310 | || (it->bidi_it.string.lstring == Qnil | ||
| 7311 | && it->bidi_it.string.s == NULL)); | ||
| 6685 | 7312 | ||
| 6686 | /* With bidi reordering, the character to display might not be the | 7313 | /* With bidi reordering, the character to display might not be the |
| 6687 | character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that | 7314 | character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that |
| @@ -6689,59 +7316,8 @@ next_element_from_buffer (struct it *it) | |||
| 6689 | a different paragraph. */ | 7316 | a different paragraph. */ |
| 6690 | if (it->bidi_p && it->bidi_it.first_elt) | 7317 | if (it->bidi_p && it->bidi_it.first_elt) |
| 6691 | { | 7318 | { |
| 6692 | it->bidi_it.charpos = IT_CHARPOS (*it); | 7319 | get_visually_first_element (it); |
| 6693 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 6694 | if (it->bidi_it.bytepos == ZV_BYTE) | ||
| 6695 | { | ||
| 6696 | /* Nothing to do, but reset the FIRST_ELT flag, like | ||
| 6697 | bidi_paragraph_init does, because we are not going to | ||
| 6698 | call it. */ | ||
| 6699 | it->bidi_it.first_elt = 0; | ||
| 6700 | } | ||
| 6701 | else if (it->bidi_it.bytepos == BEGV_BYTE | ||
| 6702 | /* FIXME: Should support all Unicode line separators. */ | ||
| 6703 | || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' | ||
| 6704 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') | ||
| 6705 | { | ||
| 6706 | /* If we are at the beginning of a line, we can produce the | ||
| 6707 | next element right away. */ | ||
| 6708 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6709 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6710 | } | ||
| 6711 | else | ||
| 6712 | { | ||
| 6713 | EMACS_INT orig_bytepos = IT_BYTEPOS (*it); | ||
| 6714 | |||
| 6715 | /* We need to prime the bidi iterator starting at the line's | ||
| 6716 | beginning, before we will be able to produce the next | ||
| 6717 | element. */ | ||
| 6718 | IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1); | ||
| 6719 | IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it)); | ||
| 6720 | it->bidi_it.charpos = IT_CHARPOS (*it); | ||
| 6721 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | ||
| 6722 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); | ||
| 6723 | do | ||
| 6724 | { | ||
| 6725 | /* Now return to buffer position where we were asked to | ||
| 6726 | get the next display element, and produce that. */ | ||
| 6727 | bidi_move_to_visually_next (&it->bidi_it); | ||
| 6728 | } | ||
| 6729 | while (it->bidi_it.bytepos != orig_bytepos | ||
| 6730 | && it->bidi_it.bytepos < ZV_BYTE); | ||
| 6731 | } | ||
| 6732 | |||
| 6733 | it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */ | ||
| 6734 | /* Adjust IT's position information to where we ended up. */ | ||
| 6735 | IT_CHARPOS (*it) = it->bidi_it.charpos; | ||
| 6736 | IT_BYTEPOS (*it) = it->bidi_it.bytepos; | ||
| 6737 | SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); | 7320 | SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); |
| 6738 | { | ||
| 6739 | EMACS_INT stop = it->end_charpos; | ||
| 6740 | if (it->bidi_it.scan_dir < 0) | ||
| 6741 | stop = -1; | ||
| 6742 | composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it), | ||
| 6743 | IT_BYTEPOS (*it), stop, Qnil); | ||
| 6744 | } | ||
| 6745 | } | 7321 | } |
| 6746 | 7322 | ||
| 6747 | if (IT_CHARPOS (*it) >= it->stop_charpos) | 7323 | if (IT_CHARPOS (*it) >= it->stop_charpos) |
| @@ -6800,17 +7376,23 @@ next_element_from_buffer (struct it *it) | |||
| 6800 | } | 7376 | } |
| 6801 | } | 7377 | } |
| 6802 | else if (it->bidi_p | 7378 | else if (it->bidi_p |
| 7379 | /* If we are before prev_stop, we may have overstepped on | ||
| 7380 | our way backwards a stop_pos, and if so, we need to | ||
| 7381 | handle that stop_pos. */ | ||
| 7382 | && IT_CHARPOS (*it) < it->prev_stop | ||
| 6803 | /* We can sometimes back up for reasons that have nothing | 7383 | /* We can sometimes back up for reasons that have nothing |
| 6804 | to do with bidi reordering. E.g., compositions. The | 7384 | to do with bidi reordering. E.g., compositions. The |
| 6805 | code below is only needed when we are above the base | 7385 | code below is only needed when we are above the base |
| 6806 | embedding level, so test for that explicitly. */ | 7386 | embedding level, so test for that explicitly. */ |
| 6807 | && !BIDI_AT_BASE_LEVEL (it->bidi_it) | 7387 | && !BIDI_AT_BASE_LEVEL (it->bidi_it)) |
| 6808 | && IT_CHARPOS (*it) < it->prev_stop) | 7388 | { |
| 6809 | { | 7389 | /* If we lost track of base_level_stop, we have no better place |
| 6810 | if (it->base_level_stop <= 0) | 7390 | for handle_stop_backwards to start from than BEGV. This |
| 7391 | happens, e.g., when we were reseated to the previous | ||
| 7392 | screenful of text by vertical-motion. */ | ||
| 7393 | if (it->base_level_stop <= 0 | ||
| 7394 | || IT_CHARPOS (*it) < it->base_level_stop) | ||
| 6811 | it->base_level_stop = BEGV; | 7395 | it->base_level_stop = BEGV; |
| 6812 | if (IT_CHARPOS (*it) < it->base_level_stop) | ||
| 6813 | abort (); | ||
| 6814 | handle_stop_backwards (it, it->base_level_stop); | 7396 | handle_stop_backwards (it, it->base_level_stop); |
| 6815 | return GET_NEXT_DISPLAY_ELEMENT (it); | 7397 | return GET_NEXT_DISPLAY_ELEMENT (it); |
| 6816 | } | 7398 | } |
| @@ -7014,9 +7596,11 @@ move_it_in_display_line_to (struct it *it, | |||
| 7014 | enum move_it_result result = MOVE_UNDEFINED; | 7596 | enum move_it_result result = MOVE_UNDEFINED; |
| 7015 | struct glyph_row *saved_glyph_row; | 7597 | struct glyph_row *saved_glyph_row; |
| 7016 | struct it wrap_it, atpos_it, atx_it; | 7598 | struct it wrap_it, atpos_it, atx_it; |
| 7599 | void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL; | ||
| 7017 | int may_wrap = 0; | 7600 | int may_wrap = 0; |
| 7018 | enum it_method prev_method = it->method; | 7601 | enum it_method prev_method = it->method; |
| 7019 | EMACS_INT prev_pos = IT_CHARPOS (*it); | 7602 | EMACS_INT prev_pos = IT_CHARPOS (*it); |
| 7603 | int saw_smaller_pos = prev_pos < to_charpos; | ||
| 7020 | 7604 | ||
| 7021 | /* Don't produce glyphs in produce_glyphs. */ | 7605 | /* Don't produce glyphs in produce_glyphs. */ |
| 7022 | saved_glyph_row = it->glyph_row; | 7606 | saved_glyph_row = it->glyph_row; |
| @@ -7057,15 +7641,16 @@ move_it_in_display_line_to (struct it *it, | |||
| 7057 | ((IT)->current_x = x, (IT)->max_ascent = ascent, \ | 7641 | ((IT)->current_x = x, (IT)->max_ascent = ascent, \ |
| 7058 | (IT)->max_descent = descent) | 7642 | (IT)->max_descent = descent) |
| 7059 | 7643 | ||
| 7060 | /* Stop if we move beyond TO_CHARPOS (after an image or stretch | 7644 | /* Stop if we move beyond TO_CHARPOS (after an image or a |
| 7061 | glyph). */ | 7645 | display string or stretch glyph). */ |
| 7062 | if ((op & MOVE_TO_POS) != 0 | 7646 | if ((op & MOVE_TO_POS) != 0 |
| 7063 | && BUFFERP (it->object) | 7647 | && BUFFERP (it->object) |
| 7064 | && it->method == GET_FROM_BUFFER | 7648 | && it->method == GET_FROM_BUFFER |
| 7065 | && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos) | 7649 | && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos) |
| 7066 | || (it->bidi_p | 7650 | || (it->bidi_p |
| 7067 | && (prev_method == GET_FROM_IMAGE | 7651 | && (prev_method == GET_FROM_IMAGE |
| 7068 | || prev_method == GET_FROM_STRETCH) | 7652 | || prev_method == GET_FROM_STRETCH |
| 7653 | || prev_method == GET_FROM_STRING) | ||
| 7069 | /* Passed TO_CHARPOS from left to right. */ | 7654 | /* Passed TO_CHARPOS from left to right. */ |
| 7070 | && ((prev_pos < to_charpos | 7655 | && ((prev_pos < to_charpos |
| 7071 | && IT_CHARPOS (*it) > to_charpos) | 7656 | && IT_CHARPOS (*it) > to_charpos) |
| @@ -7082,12 +7667,9 @@ move_it_in_display_line_to (struct it *it, | |||
| 7082 | /* If wrap_it is valid, the current position might be in a | 7667 | /* If wrap_it is valid, the current position might be in a |
| 7083 | word that is wrapped. So, save the iterator in | 7668 | word that is wrapped. So, save the iterator in |
| 7084 | atpos_it and continue to see if wrapping happens. */ | 7669 | atpos_it and continue to see if wrapping happens. */ |
| 7085 | atpos_it = *it; | 7670 | SAVE_IT (atpos_it, *it, atpos_data); |
| 7086 | } | 7671 | } |
| 7087 | 7672 | ||
| 7088 | prev_method = it->method; | ||
| 7089 | if (it->method == GET_FROM_BUFFER) | ||
| 7090 | prev_pos = IT_CHARPOS (*it); | ||
| 7091 | /* Stop when ZV reached. | 7673 | /* Stop when ZV reached. |
| 7092 | We used to stop here when TO_CHARPOS reached as well, but that is | 7674 | We used to stop here when TO_CHARPOS reached as well, but that is |
| 7093 | too soon if this glyph does not fit on this line. So we handle it | 7675 | too soon if this glyph does not fit on this line. So we handle it |
| @@ -7119,18 +7701,18 @@ move_it_in_display_line_to (struct it *it, | |||
| 7119 | already found, we are done. */ | 7701 | already found, we are done. */ |
| 7120 | if (atpos_it.sp >= 0) | 7702 | if (atpos_it.sp >= 0) |
| 7121 | { | 7703 | { |
| 7122 | *it = atpos_it; | 7704 | RESTORE_IT (it, &atpos_it, atpos_data); |
| 7123 | result = MOVE_POS_MATCH_OR_ZV; | 7705 | result = MOVE_POS_MATCH_OR_ZV; |
| 7124 | goto done; | 7706 | goto done; |
| 7125 | } | 7707 | } |
| 7126 | if (atx_it.sp >= 0) | 7708 | if (atx_it.sp >= 0) |
| 7127 | { | 7709 | { |
| 7128 | *it = atx_it; | 7710 | RESTORE_IT (it, &atx_it, atx_data); |
| 7129 | result = MOVE_X_REACHED; | 7711 | result = MOVE_X_REACHED; |
| 7130 | goto done; | 7712 | goto done; |
| 7131 | } | 7713 | } |
| 7132 | /* Otherwise, we can wrap here. */ | 7714 | /* Otherwise, we can wrap here. */ |
| 7133 | wrap_it = *it; | 7715 | SAVE_IT (wrap_it, *it, wrap_data); |
| 7134 | may_wrap = 0; | 7716 | may_wrap = 0; |
| 7135 | } | 7717 | } |
| 7136 | } | 7718 | } |
| @@ -7151,6 +7733,9 @@ move_it_in_display_line_to (struct it *it, | |||
| 7151 | 7733 | ||
| 7152 | if (it->area != TEXT_AREA) | 7734 | if (it->area != TEXT_AREA) |
| 7153 | { | 7735 | { |
| 7736 | prev_method = it->method; | ||
| 7737 | if (it->method == GET_FROM_BUFFER) | ||
| 7738 | prev_pos = IT_CHARPOS (*it); | ||
| 7154 | set_iterator_to_next (it, 1); | 7739 | set_iterator_to_next (it, 1); |
| 7155 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) | 7740 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) |
| 7156 | SET_TEXT_POS (this_line_min_pos, | 7741 | SET_TEXT_POS (this_line_min_pos, |
| @@ -7198,7 +7783,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 7198 | goto buffer_pos_reached; | 7783 | goto buffer_pos_reached; |
| 7199 | if (atpos_it.sp < 0) | 7784 | if (atpos_it.sp < 0) |
| 7200 | { | 7785 | { |
| 7201 | atpos_it = *it; | 7786 | SAVE_IT (atpos_it, *it, atpos_data); |
| 7202 | IT_RESET_X_ASCENT_DESCENT (&atpos_it); | 7787 | IT_RESET_X_ASCENT_DESCENT (&atpos_it); |
| 7203 | } | 7788 | } |
| 7204 | } | 7789 | } |
| @@ -7212,7 +7797,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 7212 | } | 7797 | } |
| 7213 | if (atx_it.sp < 0) | 7798 | if (atx_it.sp < 0) |
| 7214 | { | 7799 | { |
| 7215 | atx_it = *it; | 7800 | SAVE_IT (atx_it, *it, atx_data); |
| 7216 | IT_RESET_X_ASCENT_DESCENT (&atx_it); | 7801 | IT_RESET_X_ASCENT_DESCENT (&atx_it); |
| 7217 | } | 7802 | } |
| 7218 | } | 7803 | } |
| @@ -7256,12 +7841,15 @@ move_it_in_display_line_to (struct it *it, | |||
| 7256 | if (it->line_wrap == WORD_WRAP | 7841 | if (it->line_wrap == WORD_WRAP |
| 7257 | && atpos_it.sp < 0) | 7842 | && atpos_it.sp < 0) |
| 7258 | { | 7843 | { |
| 7259 | atpos_it = *it; | 7844 | SAVE_IT (atpos_it, *it, atpos_data); |
| 7260 | atpos_it.current_x = x_before_this_char; | 7845 | atpos_it.current_x = x_before_this_char; |
| 7261 | atpos_it.hpos = hpos_before_this_char; | 7846 | atpos_it.hpos = hpos_before_this_char; |
| 7262 | } | 7847 | } |
| 7263 | } | 7848 | } |
| 7264 | 7849 | ||
| 7850 | prev_method = it->method; | ||
| 7851 | if (it->method == GET_FROM_BUFFER) | ||
| 7852 | prev_pos = IT_CHARPOS (*it); | ||
| 7265 | set_iterator_to_next (it, 1); | 7853 | set_iterator_to_next (it, 1); |
| 7266 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) | 7854 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) |
| 7267 | SET_TEXT_POS (this_line_min_pos, | 7855 | SET_TEXT_POS (this_line_min_pos, |
| @@ -7301,7 +7889,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 7301 | 7889 | ||
| 7302 | if (wrap_it.sp >= 0) | 7890 | if (wrap_it.sp >= 0) |
| 7303 | { | 7891 | { |
| 7304 | *it = wrap_it; | 7892 | RESTORE_IT (it, &wrap_it, wrap_data); |
| 7305 | atpos_it.sp = -1; | 7893 | atpos_it.sp = -1; |
| 7306 | atx_it.sp = -1; | 7894 | atx_it.sp = -1; |
| 7307 | } | 7895 | } |
| @@ -7318,7 +7906,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 7318 | goto buffer_pos_reached; | 7906 | goto buffer_pos_reached; |
| 7319 | if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0) | 7907 | if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0) |
| 7320 | { | 7908 | { |
| 7321 | atpos_it = *it; | 7909 | SAVE_IT (atpos_it, *it, atpos_data); |
| 7322 | IT_RESET_X_ASCENT_DESCENT (&atpos_it); | 7910 | IT_RESET_X_ASCENT_DESCENT (&atpos_it); |
| 7323 | } | 7911 | } |
| 7324 | } | 7912 | } |
| @@ -7355,10 +7943,20 @@ move_it_in_display_line_to (struct it *it, | |||
| 7355 | /* Is this a line end? If yes, we're done. */ | 7943 | /* Is this a line end? If yes, we're done. */ |
| 7356 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 7944 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| 7357 | { | 7945 | { |
| 7358 | result = MOVE_NEWLINE_OR_CR; | 7946 | /* If we are past TO_CHARPOS, but never saw any character |
| 7947 | positions smaller than TO_CHARPOS, return | ||
| 7948 | MOVE_POS_MATCH_OR_ZV, like the unidirectional display | ||
| 7949 | did. */ | ||
| 7950 | if ((op & MOVE_TO_POS) != 0 | ||
| 7951 | && !saw_smaller_pos | ||
| 7952 | && IT_CHARPOS (*it) > to_charpos) | ||
| 7953 | result = MOVE_POS_MATCH_OR_ZV; | ||
| 7954 | else | ||
| 7955 | result = MOVE_NEWLINE_OR_CR; | ||
| 7359 | break; | 7956 | break; |
| 7360 | } | 7957 | } |
| 7361 | 7958 | ||
| 7959 | prev_method = it->method; | ||
| 7362 | if (it->method == GET_FROM_BUFFER) | 7960 | if (it->method == GET_FROM_BUFFER) |
| 7363 | prev_pos = IT_CHARPOS (*it); | 7961 | prev_pos = IT_CHARPOS (*it); |
| 7364 | /* The current display element has been consumed. Advance | 7962 | /* The current display element has been consumed. Advance |
| @@ -7366,6 +7964,8 @@ move_it_in_display_line_to (struct it *it, | |||
| 7366 | set_iterator_to_next (it, 1); | 7964 | set_iterator_to_next (it, 1); |
| 7367 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) | 7965 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) |
| 7368 | SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); | 7966 | SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); |
| 7967 | if (IT_CHARPOS (*it) < to_charpos) | ||
| 7968 | saw_smaller_pos = 1; | ||
| 7369 | 7969 | ||
| 7370 | /* Stop if lines are truncated and IT's current x-position is | 7970 | /* Stop if lines are truncated and IT's current x-position is |
| 7371 | past the right edge of the window now. */ | 7971 | past the right edge of the window now. */ |
| @@ -7398,12 +7998,19 @@ move_it_in_display_line_to (struct it *it, | |||
| 7398 | /* If we scanned beyond to_pos and didn't find a point to wrap at, | 7998 | /* If we scanned beyond to_pos and didn't find a point to wrap at, |
| 7399 | restore the saved iterator. */ | 7999 | restore the saved iterator. */ |
| 7400 | if (atpos_it.sp >= 0) | 8000 | if (atpos_it.sp >= 0) |
| 7401 | *it = atpos_it; | 8001 | RESTORE_IT (it, &atpos_it, atpos_data); |
| 7402 | else if (atx_it.sp >= 0) | 8002 | else if (atx_it.sp >= 0) |
| 7403 | *it = atx_it; | 8003 | RESTORE_IT (it, &atx_it, atx_data); |
| 7404 | 8004 | ||
| 7405 | done: | 8005 | done: |
| 7406 | 8006 | ||
| 8007 | if (atpos_data) | ||
| 8008 | xfree (atpos_data); | ||
| 8009 | if (atx_data) | ||
| 8010 | xfree (atx_data); | ||
| 8011 | if (wrap_data) | ||
| 8012 | xfree (wrap_data); | ||
| 8013 | |||
| 7407 | /* Restore the iterator settings altered at the beginning of this | 8014 | /* Restore the iterator settings altered at the beginning of this |
| 7408 | function. */ | 8015 | function. */ |
| 7409 | it->glyph_row = saved_glyph_row; | 8016 | it->glyph_row = saved_glyph_row; |
| @@ -7419,8 +8026,12 @@ move_it_in_display_line (struct it *it, | |||
| 7419 | if (it->line_wrap == WORD_WRAP | 8026 | if (it->line_wrap == WORD_WRAP |
| 7420 | && (op & MOVE_TO_X)) | 8027 | && (op & MOVE_TO_X)) |
| 7421 | { | 8028 | { |
| 7422 | struct it save_it = *it; | 8029 | struct it save_it; |
| 7423 | int skip = move_it_in_display_line_to (it, to_charpos, to_x, op); | 8030 | void *save_data = NULL; |
| 8031 | int skip; | ||
| 8032 | |||
| 8033 | SAVE_IT (save_it, *it, save_data); | ||
| 8034 | skip = move_it_in_display_line_to (it, to_charpos, to_x, op); | ||
| 7424 | /* When word-wrap is on, TO_X may lie past the end | 8035 | /* When word-wrap is on, TO_X may lie past the end |
| 7425 | of a wrapped line. Then it->current is the | 8036 | of a wrapped line. Then it->current is the |
| 7426 | character on the next line, so backtrack to the | 8037 | character on the next line, so backtrack to the |
| @@ -7428,10 +8039,12 @@ move_it_in_display_line (struct it *it, | |||
| 7428 | if (skip == MOVE_LINE_CONTINUED) | 8039 | if (skip == MOVE_LINE_CONTINUED) |
| 7429 | { | 8040 | { |
| 7430 | int prev_x = max (it->current_x - 1, 0); | 8041 | int prev_x = max (it->current_x - 1, 0); |
| 7431 | *it = save_it; | 8042 | RESTORE_IT (it, &save_it, save_data); |
| 7432 | move_it_in_display_line_to | 8043 | move_it_in_display_line_to |
| 7433 | (it, -1, prev_x, MOVE_TO_X); | 8044 | (it, -1, prev_x, MOVE_TO_X); |
| 7434 | } | 8045 | } |
| 8046 | else | ||
| 8047 | xfree (save_data); | ||
| 7435 | } | 8048 | } |
| 7436 | else | 8049 | else |
| 7437 | move_it_in_display_line_to (it, to_charpos, to_x, op); | 8050 | move_it_in_display_line_to (it, to_charpos, to_x, op); |
| @@ -7446,14 +8059,15 @@ move_it_in_display_line (struct it *it, | |||
| 7446 | description of enum move_operation_enum. | 8059 | description of enum move_operation_enum. |
| 7447 | 8060 | ||
| 7448 | If TO_CHARPOS is in invisible text, e.g. a truncated part of a | 8061 | If TO_CHARPOS is in invisible text, e.g. a truncated part of a |
| 7449 | screen line, this function will set IT to the next position > | 8062 | screen line, this function will set IT to the next position that is |
| 7450 | TO_CHARPOS. */ | 8063 | displayed to the right of TO_CHARPOS on the screen. */ |
| 7451 | 8064 | ||
| 7452 | void | 8065 | void |
| 7453 | move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op) | 8066 | move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op) |
| 7454 | { | 8067 | { |
| 7455 | enum move_it_result skip, skip2 = MOVE_X_REACHED; | 8068 | enum move_it_result skip, skip2 = MOVE_X_REACHED; |
| 7456 | int line_height, line_start_x = 0, reached = 0; | 8069 | int line_height, line_start_x = 0, reached = 0; |
| 8070 | void *backup_data = NULL; | ||
| 7457 | 8071 | ||
| 7458 | for (;;) | 8072 | for (;;) |
| 7459 | { | 8073 | { |
| @@ -7506,7 +8120,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos | |||
| 7506 | struct it it_backup; | 8120 | struct it it_backup; |
| 7507 | 8121 | ||
| 7508 | if (it->line_wrap == WORD_WRAP) | 8122 | if (it->line_wrap == WORD_WRAP) |
| 7509 | it_backup = *it; | 8123 | SAVE_IT (it_backup, *it, backup_data); |
| 7510 | 8124 | ||
| 7511 | /* TO_Y specified means stop at TO_X in the line containing | 8125 | /* TO_Y specified means stop at TO_X in the line containing |
| 7512 | TO_Y---or at TO_CHARPOS if this is reached first. The | 8126 | TO_Y---or at TO_CHARPOS if this is reached first. The |
| @@ -7540,7 +8154,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos | |||
| 7540 | reached = 6; | 8154 | reached = 6; |
| 7541 | break; | 8155 | break; |
| 7542 | } | 8156 | } |
| 7543 | it_backup = *it; | 8157 | SAVE_IT (it_backup, *it, backup_data); |
| 7544 | TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it))); | 8158 | TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it))); |
| 7545 | skip2 = move_it_in_display_line_to (it, to_charpos, -1, | 8159 | skip2 = move_it_in_display_line_to (it, to_charpos, -1, |
| 7546 | op & MOVE_TO_POS); | 8160 | op & MOVE_TO_POS); |
| @@ -7554,7 +8168,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos | |||
| 7554 | /* If TO_Y is in this line and TO_X was reached | 8168 | /* If TO_Y is in this line and TO_X was reached |
| 7555 | above, we scanned too far. We have to restore | 8169 | above, we scanned too far. We have to restore |
| 7556 | IT's settings to the ones before skipping. */ | 8170 | IT's settings to the ones before skipping. */ |
| 7557 | *it = it_backup; | 8171 | RESTORE_IT (it, &it_backup, backup_data); |
| 7558 | reached = 6; | 8172 | reached = 6; |
| 7559 | } | 8173 | } |
| 7560 | else | 8174 | else |
| @@ -7581,7 +8195,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos | |||
| 7581 | && it->line_wrap == WORD_WRAP) | 8195 | && it->line_wrap == WORD_WRAP) |
| 7582 | { | 8196 | { |
| 7583 | int prev_x = max (it->current_x - 1, 0); | 8197 | int prev_x = max (it->current_x - 1, 0); |
| 7584 | *it = it_backup; | 8198 | RESTORE_IT (it, &it_backup, backup_data); |
| 7585 | skip = move_it_in_display_line_to | 8199 | skip = move_it_in_display_line_to |
| 7586 | (it, -1, prev_x, MOVE_TO_X); | 8200 | (it, -1, prev_x, MOVE_TO_X); |
| 7587 | } | 8201 | } |
| @@ -7688,6 +8302,9 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos | |||
| 7688 | last_max_ascent = it->max_ascent; | 8302 | last_max_ascent = it->max_ascent; |
| 7689 | } | 8303 | } |
| 7690 | 8304 | ||
| 8305 | if (backup_data) | ||
| 8306 | xfree (backup_data); | ||
| 8307 | |||
| 7691 | TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); | 8308 | TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); |
| 7692 | } | 8309 | } |
| 7693 | 8310 | ||
| @@ -7705,6 +8322,7 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 7705 | { | 8322 | { |
| 7706 | int nlines, h; | 8323 | int nlines, h; |
| 7707 | struct it it2, it3; | 8324 | struct it it2, it3; |
| 8325 | void *it2data = NULL, *it3data = NULL; | ||
| 7708 | EMACS_INT start_pos; | 8326 | EMACS_INT start_pos; |
| 7709 | 8327 | ||
| 7710 | move_further_back: | 8328 | move_further_back: |
| @@ -7733,7 +8351,7 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 7733 | start of the next line so that we get its height. We need this | 8351 | start of the next line so that we get its height. We need this |
| 7734 | height to be able to tell whether we reached the specified | 8352 | height to be able to tell whether we reached the specified |
| 7735 | y-distance. */ | 8353 | y-distance. */ |
| 7736 | it2 = *it; | 8354 | SAVE_IT (it2, *it, it2data); |
| 7737 | it2.max_ascent = it2.max_descent = 0; | 8355 | it2.max_ascent = it2.max_descent = 0; |
| 7738 | do | 8356 | do |
| 7739 | { | 8357 | { |
| @@ -7742,7 +8360,7 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 7742 | } | 8360 | } |
| 7743 | while (!IT_POS_VALID_AFTER_MOVE_P (&it2)); | 8361 | while (!IT_POS_VALID_AFTER_MOVE_P (&it2)); |
| 7744 | xassert (IT_CHARPOS (*it) >= BEGV); | 8362 | xassert (IT_CHARPOS (*it) >= BEGV); |
| 7745 | it3 = it2; | 8363 | SAVE_IT (it3, it2, it3data); |
| 7746 | 8364 | ||
| 7747 | move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS); | 8365 | move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS); |
| 7748 | xassert (IT_CHARPOS (*it) >= BEGV); | 8366 | xassert (IT_CHARPOS (*it) >= BEGV); |
| @@ -7761,8 +8379,10 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 7761 | { | 8379 | { |
| 7762 | /* DY == 0 means move to the start of the screen line. The | 8380 | /* DY == 0 means move to the start of the screen line. The |
| 7763 | value of nlines is > 0 if continuation lines were involved. */ | 8381 | value of nlines is > 0 if continuation lines were involved. */ |
| 8382 | RESTORE_IT (it, it, it2data); | ||
| 7764 | if (nlines > 0) | 8383 | if (nlines > 0) |
| 7765 | move_it_by_lines (it, nlines); | 8384 | move_it_by_lines (it, nlines); |
| 8385 | xfree (it3data); | ||
| 7766 | } | 8386 | } |
| 7767 | else | 8387 | else |
| 7768 | { | 8388 | { |
| @@ -7770,9 +8390,13 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 7770 | Note that H has been subtracted in front of the if-statement. */ | 8390 | Note that H has been subtracted in front of the if-statement. */ |
| 7771 | int target_y = it->current_y + h - dy; | 8391 | int target_y = it->current_y + h - dy; |
| 7772 | int y0 = it3.current_y; | 8392 | int y0 = it3.current_y; |
| 7773 | int y1 = line_bottom_y (&it3); | 8393 | int y1; |
| 7774 | int line_height = y1 - y0; | 8394 | int line_height; |
| 7775 | 8395 | ||
| 8396 | RESTORE_IT (&it3, &it3, it3data); | ||
| 8397 | y1 = line_bottom_y (&it3); | ||
| 8398 | line_height = y1 - y0; | ||
| 8399 | RESTORE_IT (it, it, it2data); | ||
| 7776 | /* If we did not reach target_y, try to move further backward if | 8400 | /* If we did not reach target_y, try to move further backward if |
| 7777 | we can. If we moved too far backward, try to move forward. */ | 8401 | we can. If we moved too far backward, try to move forward. */ |
| 7778 | if (target_y < it->current_y | 8402 | if (target_y < it->current_y |
| @@ -7899,6 +8523,7 @@ move_it_by_lines (struct it *it, int dvpos) | |||
| 7899 | else | 8523 | else |
| 7900 | { | 8524 | { |
| 7901 | struct it it2; | 8525 | struct it it2; |
| 8526 | void *it2data = NULL; | ||
| 7902 | EMACS_INT start_charpos, i; | 8527 | EMACS_INT start_charpos, i; |
| 7903 | 8528 | ||
| 7904 | /* Start at the beginning of the screen line containing IT's | 8529 | /* Start at the beginning of the screen line containing IT's |
| @@ -7934,7 +8559,7 @@ move_it_by_lines (struct it *it, int dvpos) | |||
| 7934 | 8559 | ||
| 7935 | /* Above call may have moved too far if continuation lines | 8560 | /* Above call may have moved too far if continuation lines |
| 7936 | are involved. Scan forward and see if it did. */ | 8561 | are involved. Scan forward and see if it did. */ |
| 7937 | it2 = *it; | 8562 | SAVE_IT (it2, *it, it2data); |
| 7938 | it2.vpos = it2.current_y = 0; | 8563 | it2.vpos = it2.current_y = 0; |
| 7939 | move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS); | 8564 | move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS); |
| 7940 | it->vpos -= it2.vpos; | 8565 | it->vpos -= it2.vpos; |
| @@ -7945,12 +8570,18 @@ move_it_by_lines (struct it *it, int dvpos) | |||
| 7945 | if (it2.vpos > -dvpos) | 8570 | if (it2.vpos > -dvpos) |
| 7946 | { | 8571 | { |
| 7947 | int delta = it2.vpos + dvpos; | 8572 | int delta = it2.vpos + dvpos; |
| 7948 | it2 = *it; | 8573 | |
| 8574 | RESTORE_IT (&it2, &it2, it2data); | ||
| 8575 | SAVE_IT (it2, *it, it2data); | ||
| 7949 | move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS); | 8576 | move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS); |
| 7950 | /* Move back again if we got too far ahead. */ | 8577 | /* Move back again if we got too far ahead. */ |
| 7951 | if (IT_CHARPOS (*it) >= start_charpos) | 8578 | if (IT_CHARPOS (*it) >= start_charpos) |
| 7952 | *it = it2; | 8579 | RESTORE_IT (it, &it2, it2data); |
| 8580 | else | ||
| 8581 | xfree (it2data); | ||
| 7953 | } | 8582 | } |
| 8583 | else | ||
| 8584 | RESTORE_IT (it, it, it2data); | ||
| 7954 | } | 8585 | } |
| 7955 | } | 8586 | } |
| 7956 | 8587 | ||
| @@ -10437,7 +11068,7 @@ display_tool_bar_line (struct it *it, int height) | |||
| 10437 | ++i; | 11068 | ++i; |
| 10438 | } | 11069 | } |
| 10439 | 11070 | ||
| 10440 | /* Stop at line ends. */ | 11071 | /* Stop at line end. */ |
| 10441 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 11072 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| 10442 | break; | 11073 | break; |
| 10443 | 11074 | ||
| @@ -10520,6 +11151,7 @@ tool_bar_lines_needed (struct frame *f, int *n_rows) | |||
| 10520 | it.first_visible_x = 0; | 11151 | it.first_visible_x = 0; |
| 10521 | it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); | 11152 | it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); |
| 10522 | reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); | 11153 | reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); |
| 11154 | it.paragraph_embedding = L2R; | ||
| 10523 | 11155 | ||
| 10524 | while (!ITERATOR_AT_END_P (&it)) | 11156 | while (!ITERATOR_AT_END_P (&it)) |
| 10525 | { | 11157 | { |
| @@ -10553,7 +11185,7 @@ DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed, | |||
| 10553 | f = XFRAME (frame); | 11185 | f = XFRAME (frame); |
| 10554 | 11186 | ||
| 10555 | if (WINDOWP (f->tool_bar_window) | 11187 | if (WINDOWP (f->tool_bar_window) |
| 10556 | || (w = XWINDOW (f->tool_bar_window), | 11188 | && (w = XWINDOW (f->tool_bar_window), |
| 10557 | WINDOW_TOTAL_LINES (w) > 0)) | 11189 | WINDOW_TOTAL_LINES (w) > 0)) |
| 10558 | { | 11190 | { |
| 10559 | update_tool_bar (f, 1); | 11191 | update_tool_bar (f, 1); |
| @@ -10602,6 +11234,14 @@ redisplay_tool_bar (struct frame *f) | |||
| 10602 | /* Build a string that represents the contents of the tool-bar. */ | 11234 | /* Build a string that represents the contents of the tool-bar. */ |
| 10603 | build_desired_tool_bar_string (f); | 11235 | build_desired_tool_bar_string (f); |
| 10604 | reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); | 11236 | reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); |
| 11237 | /* FIXME: This should be controlled by a user option. But it | ||
| 11238 | doesn't make sense to have an R2L tool bar if the menu bar cannot | ||
| 11239 | be drawn also R2L, and making the menu bar R2L is tricky due | ||
| 11240 | toolkit-specific code that implements it. If an R2L tool bar is | ||
| 11241 | ever supported, display_tool_bar_line should also be augmented to | ||
| 11242 | call unproduce_glyphs like display_line and display_string | ||
| 11243 | do. */ | ||
| 11244 | it.paragraph_embedding = L2R; | ||
| 10605 | 11245 | ||
| 10606 | if (f->n_tool_bar_rows == 0) | 11246 | if (f->n_tool_bar_rows == 0) |
| 10607 | { | 11247 | { |
| @@ -13296,14 +13936,18 @@ try_scrolling (Lisp_Object window, int just_this_one_p, | |||
| 13296 | which was computed as distance from window bottom to | 13936 | which was computed as distance from window bottom to |
| 13297 | point. This matters when lines at window top and lines | 13937 | point. This matters when lines at window top and lines |
| 13298 | below window bottom have different height. */ | 13938 | below window bottom have different height. */ |
| 13299 | struct it it1 = it; | 13939 | struct it it1; |
| 13940 | void *it1data = NULL; | ||
| 13300 | /* We use a temporary it1 because line_bottom_y can modify | 13941 | /* We use a temporary it1 because line_bottom_y can modify |
| 13301 | its argument, if it moves one line down; see there. */ | 13942 | its argument, if it moves one line down; see there. */ |
| 13302 | int start_y = line_bottom_y (&it1); | 13943 | int start_y; |
| 13303 | 13944 | ||
| 13945 | SAVE_IT (it1, it, it1data); | ||
| 13946 | start_y = line_bottom_y (&it1); | ||
| 13304 | do { | 13947 | do { |
| 13948 | RESTORE_IT (&it, &it, it1data); | ||
| 13305 | move_it_by_lines (&it, 1); | 13949 | move_it_by_lines (&it, 1); |
| 13306 | it1 = it; | 13950 | SAVE_IT (it1, it, it1data); |
| 13307 | } while (line_bottom_y (&it1) - start_y < amount_to_scroll); | 13951 | } while (line_bottom_y (&it1) - start_y < amount_to_scroll); |
| 13308 | } | 13952 | } |
| 13309 | 13953 | ||
| @@ -14411,10 +15055,13 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 14411 | && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV) | 15055 | && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV) |
| 14412 | { | 15056 | { |
| 14413 | struct it it1; | 15057 | struct it it1; |
| 15058 | void *it1data = NULL; | ||
| 14414 | 15059 | ||
| 15060 | SAVE_IT (it1, it, it1data); | ||
| 14415 | start_display (&it1, w, startp); | 15061 | start_display (&it1, w, startp); |
| 14416 | move_it_vertically (&it1, margin); | 15062 | move_it_vertically (&it1, margin); |
| 14417 | margin_pos = IT_CHARPOS (it1); | 15063 | margin_pos = IT_CHARPOS (it1); |
| 15064 | RESTORE_IT (&it, &it, it1data); | ||
| 14418 | } | 15065 | } |
| 14419 | scrolling_up = PT > margin_pos; | 15066 | scrolling_up = PT > margin_pos; |
| 14420 | aggressive = | 15067 | aggressive = |
| @@ -17306,6 +17953,8 @@ cursor_row_p (struct glyph_row *row) | |||
| 17306 | static int | 17953 | static int |
| 17307 | push_display_prop (struct it *it, Lisp_Object prop) | 17954 | push_display_prop (struct it *it, Lisp_Object prop) |
| 17308 | { | 17955 | { |
| 17956 | xassert (it->method == GET_FROM_BUFFER); | ||
| 17957 | |||
| 17309 | push_it (it, NULL); | 17958 | push_it (it, NULL); |
| 17310 | 17959 | ||
| 17311 | if (STRINGP (prop)) | 17960 | if (STRINGP (prop)) |
| @@ -17323,6 +17972,29 @@ push_display_prop (struct it *it, Lisp_Object prop) | |||
| 17323 | it->end_charpos = it->string_nchars = SCHARS (it->string); | 17972 | it->end_charpos = it->string_nchars = SCHARS (it->string); |
| 17324 | it->method = GET_FROM_STRING; | 17973 | it->method = GET_FROM_STRING; |
| 17325 | it->stop_charpos = 0; | 17974 | it->stop_charpos = 0; |
| 17975 | it->prev_stop = 0; | ||
| 17976 | it->base_level_stop = 0; | ||
| 17977 | it->string_from_display_prop_p = 1; | ||
| 17978 | it->from_disp_prop_p = 1; | ||
| 17979 | |||
| 17980 | /* Force paragraph direction to be that of the parent | ||
| 17981 | buffer. */ | ||
| 17982 | if (it->bidi_p && it->bidi_it.paragraph_dir == R2L) | ||
| 17983 | it->paragraph_embedding = it->bidi_it.paragraph_dir; | ||
| 17984 | else | ||
| 17985 | it->paragraph_embedding = L2R; | ||
| 17986 | |||
| 17987 | /* Set up the bidi iterator for this display string. */ | ||
| 17988 | if (it->bidi_p) | ||
| 17989 | { | ||
| 17990 | it->bidi_it.string.lstring = it->string; | ||
| 17991 | it->bidi_it.string.s = NULL; | ||
| 17992 | it->bidi_it.string.schars = it->end_charpos; | ||
| 17993 | it->bidi_it.string.bufpos = IT_CHARPOS (*it); | ||
| 17994 | it->bidi_it.string.from_disp_str = 1; | ||
| 17995 | it->bidi_it.string.unibyte = !it->multibyte_p; | ||
| 17996 | bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it); | ||
| 17997 | } | ||
| 17326 | } | 17998 | } |
| 17327 | else if (CONSP (prop) && EQ (XCAR (prop), Qspace)) | 17999 | else if (CONSP (prop) && EQ (XCAR (prop), Qspace)) |
| 17328 | { | 18000 | { |
| @@ -17369,6 +18041,7 @@ static void | |||
| 17369 | handle_line_prefix (struct it *it) | 18041 | handle_line_prefix (struct it *it) |
| 17370 | { | 18042 | { |
| 17371 | Lisp_Object prefix; | 18043 | Lisp_Object prefix; |
| 18044 | |||
| 17372 | if (it->continuation_lines_width > 0) | 18045 | if (it->continuation_lines_width > 0) |
| 17373 | { | 18046 | { |
| 17374 | prefix = get_it_property (it, Qwrap_prefix); | 18047 | prefix = get_it_property (it, Qwrap_prefix); |
| @@ -17394,9 +18067,9 @@ handle_line_prefix (struct it *it) | |||
| 17394 | 18067 | ||
| 17395 | 18068 | ||
| 17396 | /* Remove N glyphs at the start of a reversed IT->glyph_row. Called | 18069 | /* Remove N glyphs at the start of a reversed IT->glyph_row. Called |
| 17397 | only for R2L lines from display_line, when it decides that too many | 18070 | only for R2L lines from display_line and display_string, when they |
| 17398 | glyphs were produced by PRODUCE_GLYPHS, and the line needs to be | 18071 | decide that too many glyphs were produced by PRODUCE_GLYPHS, and |
| 17399 | continued. */ | 18072 | the line/string needs to be continued on the next glyph row. */ |
| 17400 | static void | 18073 | static void |
| 17401 | unproduce_glyphs (struct it *it, int n) | 18074 | unproduce_glyphs (struct it *it, int n) |
| 17402 | { | 18075 | { |
| @@ -17426,12 +18099,13 @@ find_row_edges (struct it *it, struct glyph_row *row, | |||
| 17426 | lines' rows is implemented for bidi-reordered rows. */ | 18099 | lines' rows is implemented for bidi-reordered rows. */ |
| 17427 | 18100 | ||
| 17428 | /* ROW->minpos is the value of min_pos, the minimal buffer position | 18101 | /* ROW->minpos is the value of min_pos, the minimal buffer position |
| 17429 | we have in ROW. */ | 18102 | we have in ROW, or ROW->start.pos if that is smaller. */ |
| 17430 | if (min_pos <= ZV) | 18103 | if (min_pos <= ZV && min_pos < row->start.pos.charpos) |
| 17431 | SET_TEXT_POS (row->minpos, min_pos, min_bpos); | 18104 | SET_TEXT_POS (row->minpos, min_pos, min_bpos); |
| 17432 | else | 18105 | else |
| 17433 | /* We didn't find _any_ valid buffer positions in any of the | 18106 | /* We didn't find buffer positions smaller than ROW->start, or |
| 17434 | glyphs, so we must trust the iterator's computed positions. */ | 18107 | didn't find _any_ valid buffer positions in any of the glyphs, |
| 18108 | so we must trust the iterator's computed positions. */ | ||
| 17435 | row->minpos = row->start.pos; | 18109 | row->minpos = row->start.pos; |
| 17436 | if (max_pos <= 0) | 18110 | if (max_pos <= 0) |
| 17437 | { | 18111 | { |
| @@ -17506,6 +18180,7 @@ display_line (struct it *it) | |||
| 17506 | struct glyph_row *row = it->glyph_row; | 18180 | struct glyph_row *row = it->glyph_row; |
| 17507 | Lisp_Object overlay_arrow_string; | 18181 | Lisp_Object overlay_arrow_string; |
| 17508 | struct it wrap_it; | 18182 | struct it wrap_it; |
| 18183 | void *wrap_data = NULL; | ||
| 17509 | int may_wrap = 0, wrap_x IF_LINT (= 0); | 18184 | int may_wrap = 0, wrap_x IF_LINT (= 0); |
| 17510 | int wrap_row_used = -1; | 18185 | int wrap_row_used = -1; |
| 17511 | int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0); | 18186 | int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0); |
| @@ -17660,7 +18335,7 @@ display_line (struct it *it) | |||
| 17660 | may_wrap = 1; | 18335 | may_wrap = 1; |
| 17661 | else if (may_wrap) | 18336 | else if (may_wrap) |
| 17662 | { | 18337 | { |
| 17663 | wrap_it = *it; | 18338 | SAVE_IT (wrap_it, *it, wrap_data); |
| 17664 | wrap_x = x; | 18339 | wrap_x = x; |
| 17665 | wrap_row_used = row->used[TEXT_AREA]; | 18340 | wrap_row_used = row->used[TEXT_AREA]; |
| 17666 | wrap_row_ascent = row->ascent; | 18341 | wrap_row_ascent = row->ascent; |
| @@ -17830,7 +18505,7 @@ display_line (struct it *it) | |||
| 17830 | if (row->reversed_p) | 18505 | if (row->reversed_p) |
| 17831 | unproduce_glyphs (it, | 18506 | unproduce_glyphs (it, |
| 17832 | row->used[TEXT_AREA] - wrap_row_used); | 18507 | row->used[TEXT_AREA] - wrap_row_used); |
| 17833 | *it = wrap_it; | 18508 | RESTORE_IT (it, &wrap_it, wrap_data); |
| 17834 | it->continuation_lines_width += wrap_x; | 18509 | it->continuation_lines_width += wrap_x; |
| 17835 | row->used[TEXT_AREA] = wrap_row_used; | 18510 | row->used[TEXT_AREA] = wrap_row_used; |
| 17836 | row->ascent = wrap_row_ascent; | 18511 | row->ascent = wrap_row_ascent; |
| @@ -18236,6 +18911,8 @@ See also `bidi-paragraph-direction'. */) | |||
| 18236 | itb.charpos = pos; | 18911 | itb.charpos = pos; |
| 18237 | itb.bytepos = bytepos; | 18912 | itb.bytepos = bytepos; |
| 18238 | itb.nchars = -1; | 18913 | itb.nchars = -1; |
| 18914 | itb.string.s = NULL; | ||
| 18915 | itb.string.lstring = Qnil; | ||
| 18239 | itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */ | 18916 | itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */ |
| 18240 | itb.first_elt = 1; | 18917 | itb.first_elt = 1; |
| 18241 | itb.separator_limit = -1; | 18918 | itb.separator_limit = -1; |
| @@ -18325,6 +19002,11 @@ display_menu_bar (struct window *w) | |||
| 18325 | } | 19002 | } |
| 18326 | #endif /* not USE_X_TOOLKIT */ | 19003 | #endif /* not USE_X_TOOLKIT */ |
| 18327 | 19004 | ||
| 19005 | /* FIXME: This should be controlled by a user option. See the | ||
| 19006 | comments in redisplay_tool_bar and display_mode_line about | ||
| 19007 | this. */ | ||
| 19008 | it.paragraph_embedding = L2R; | ||
| 19009 | |||
| 18328 | if (! mode_line_inverse_video) | 19010 | if (! mode_line_inverse_video) |
| 18329 | /* Force the menu-bar to be displayed in the default face. */ | 19011 | /* Force the menu-bar to be displayed in the default face. */ |
| 18330 | it.base_face_id = it.face_id = DEFAULT_FACE_ID; | 19012 | it.base_face_id = it.face_id = DEFAULT_FACE_ID; |
| @@ -18502,6 +19184,11 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) | |||
| 18502 | /* Force the mode-line to be displayed in the default face. */ | 19184 | /* Force the mode-line to be displayed in the default face. */ |
| 18503 | it.base_face_id = it.face_id = DEFAULT_FACE_ID; | 19185 | it.base_face_id = it.face_id = DEFAULT_FACE_ID; |
| 18504 | 19186 | ||
| 19187 | /* FIXME: This should be controlled by a user option. But | ||
| 19188 | supporting such an option is not trivial, since the mode line is | ||
| 19189 | made up of many separate strings. */ | ||
| 19190 | it.paragraph_embedding = L2R; | ||
| 19191 | |||
| 18505 | record_unwind_protect (unwind_format_mode_line, | 19192 | record_unwind_protect (unwind_format_mode_line, |
| 18506 | format_mode_line_unwind_data (NULL, Qnil, 0)); | 19193 | format_mode_line_unwind_data (NULL, Qnil, 0)); |
| 18507 | 19194 | ||
| @@ -20047,6 +20734,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20047 | int hpos_at_start = it->hpos; | 20734 | int hpos_at_start = it->hpos; |
| 20048 | int saved_face_id = it->face_id; | 20735 | int saved_face_id = it->face_id; |
| 20049 | struct glyph_row *row = it->glyph_row; | 20736 | struct glyph_row *row = it->glyph_row; |
| 20737 | EMACS_INT it_charpos; | ||
| 20050 | 20738 | ||
| 20051 | /* Initialize the iterator IT for iteration over STRING beginning | 20739 | /* Initialize the iterator IT for iteration over STRING beginning |
| 20052 | with index START. */ | 20740 | with index START. */ |
| @@ -20055,10 +20743,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20055 | if (string && STRINGP (lisp_string)) | 20743 | if (string && STRINGP (lisp_string)) |
| 20056 | /* LISP_STRING is the one returned by decode_mode_spec. We should | 20744 | /* LISP_STRING is the one returned by decode_mode_spec. We should |
| 20057 | ignore its text properties. */ | 20745 | ignore its text properties. */ |
| 20058 | it->stop_charpos = -1; | 20746 | it->stop_charpos = it->end_charpos; |
| 20059 | 20747 | ||
| 20060 | /* If displaying STRING, set up the face of the iterator | 20748 | /* If displaying STRING, set up the face of the iterator from |
| 20061 | from LISP_STRING, if that's given. */ | 20749 | FACE_STRING, if that's given. */ |
| 20062 | if (STRINGP (face_string)) | 20750 | if (STRINGP (face_string)) |
| 20063 | { | 20751 | { |
| 20064 | EMACS_INT endptr; | 20752 | EMACS_INT endptr; |
| @@ -20092,6 +20780,11 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20092 | row->phys_height = it->max_phys_ascent + it->max_phys_descent; | 20780 | row->phys_height = it->max_phys_ascent + it->max_phys_descent; |
| 20093 | row->extra_line_spacing = it->max_extra_line_spacing; | 20781 | row->extra_line_spacing = it->max_extra_line_spacing; |
| 20094 | 20782 | ||
| 20783 | if (STRINGP (it->string)) | ||
| 20784 | it_charpos = IT_STRING_CHARPOS (*it); | ||
| 20785 | else | ||
| 20786 | it_charpos = IT_CHARPOS (*it); | ||
| 20787 | |||
| 20095 | /* This condition is for the case that we are called with current_x | 20788 | /* This condition is for the case that we are called with current_x |
| 20096 | past last_visible_x. */ | 20789 | past last_visible_x. */ |
| 20097 | while (it->current_x < max_x) | 20790 | while (it->current_x < max_x) |
| @@ -20104,10 +20797,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20104 | 20797 | ||
| 20105 | /* Produce glyphs. */ | 20798 | /* Produce glyphs. */ |
| 20106 | x_before = it->current_x; | 20799 | x_before = it->current_x; |
| 20107 | n_glyphs_before = it->glyph_row->used[TEXT_AREA]; | 20800 | n_glyphs_before = row->used[TEXT_AREA]; |
| 20108 | PRODUCE_GLYPHS (it); | 20801 | PRODUCE_GLYPHS (it); |
| 20109 | 20802 | ||
| 20110 | nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before; | 20803 | nglyphs = row->used[TEXT_AREA] - n_glyphs_before; |
| 20111 | i = 0; | 20804 | i = 0; |
| 20112 | x = x_before; | 20805 | x = x_before; |
| 20113 | while (i < nglyphs) | 20806 | while (i < nglyphs) |
| @@ -20121,12 +20814,18 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20121 | if (CHAR_GLYPH_PADDING_P (*glyph)) | 20814 | if (CHAR_GLYPH_PADDING_P (*glyph)) |
| 20122 | { | 20815 | { |
| 20123 | /* A wide character is unbreakable. */ | 20816 | /* A wide character is unbreakable. */ |
| 20124 | it->glyph_row->used[TEXT_AREA] = n_glyphs_before; | 20817 | if (row->reversed_p) |
| 20818 | unproduce_glyphs (it, row->used[TEXT_AREA] | ||
| 20819 | - n_glyphs_before); | ||
| 20820 | row->used[TEXT_AREA] = n_glyphs_before; | ||
| 20125 | it->current_x = x_before; | 20821 | it->current_x = x_before; |
| 20126 | } | 20822 | } |
| 20127 | else | 20823 | else |
| 20128 | { | 20824 | { |
| 20129 | it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i; | 20825 | if (row->reversed_p) |
| 20826 | unproduce_glyphs (it, row->used[TEXT_AREA] | ||
| 20827 | - (n_glyphs_before + i)); | ||
| 20828 | row->used[TEXT_AREA] = n_glyphs_before + i; | ||
| 20130 | it->current_x = x; | 20829 | it->current_x = x; |
| 20131 | } | 20830 | } |
| 20132 | break; | 20831 | break; |
| @@ -20136,7 +20835,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20136 | /* Glyph is at least partially visible. */ | 20835 | /* Glyph is at least partially visible. */ |
| 20137 | ++it->hpos; | 20836 | ++it->hpos; |
| 20138 | if (x < it->first_visible_x) | 20837 | if (x < it->first_visible_x) |
| 20139 | it->glyph_row->x = x - it->first_visible_x; | 20838 | row->x = x - it->first_visible_x; |
| 20140 | } | 20839 | } |
| 20141 | else | 20840 | else |
| 20142 | { | 20841 | { |
| @@ -20168,6 +20867,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20168 | } | 20867 | } |
| 20169 | 20868 | ||
| 20170 | set_iterator_to_next (it, 1); | 20869 | set_iterator_to_next (it, 1); |
| 20870 | if (STRINGP (it->string)) | ||
| 20871 | it_charpos = IT_STRING_CHARPOS (*it); | ||
| 20872 | else | ||
| 20873 | it_charpos = IT_CHARPOS (*it); | ||
| 20171 | 20874 | ||
| 20172 | /* Stop if truncating at the right edge. */ | 20875 | /* Stop if truncating at the right edge. */ |
| 20173 | if (it->line_wrap == TRUNCATE | 20876 | if (it->line_wrap == TRUNCATE |
| @@ -20175,7 +20878,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20175 | { | 20878 | { |
| 20176 | /* Add truncation mark, but don't do it if the line is | 20879 | /* Add truncation mark, but don't do it if the line is |
| 20177 | truncated at a padding space. */ | 20880 | truncated at a padding space. */ |
| 20178 | if (IT_CHARPOS (*it) < it->string_nchars) | 20881 | if (it_charpos < it->string_nchars) |
| 20179 | { | 20882 | { |
| 20180 | if (!FRAME_WINDOW_P (it->f)) | 20883 | if (!FRAME_WINDOW_P (it->f)) |
| 20181 | { | 20884 | { |
| @@ -20183,9 +20886,20 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20183 | 20886 | ||
| 20184 | if (it->current_x > it->last_visible_x) | 20887 | if (it->current_x > it->last_visible_x) |
| 20185 | { | 20888 | { |
| 20186 | for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii) | 20889 | if (!row->reversed_p) |
| 20187 | if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii])) | 20890 | { |
| 20188 | break; | 20891 | for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii) |
| 20892 | if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii])) | ||
| 20893 | break; | ||
| 20894 | } | ||
| 20895 | else | ||
| 20896 | { | ||
| 20897 | for (ii = 0; ii < row->used[TEXT_AREA]; ii++) | ||
| 20898 | if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii])) | ||
| 20899 | break; | ||
| 20900 | unproduce_glyphs (it, ii + 1); | ||
| 20901 | ii = row->used[TEXT_AREA] - (ii + 1); | ||
| 20902 | } | ||
| 20189 | for (n = row->used[TEXT_AREA]; ii < n; ++ii) | 20903 | for (n = row->used[TEXT_AREA]; ii < n; ++ii) |
| 20190 | { | 20904 | { |
| 20191 | row->used[TEXT_AREA] = ii; | 20905 | row->used[TEXT_AREA] = ii; |
| @@ -20194,7 +20908,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20194 | } | 20908 | } |
| 20195 | produce_special_glyphs (it, IT_TRUNCATION); | 20909 | produce_special_glyphs (it, IT_TRUNCATION); |
| 20196 | } | 20910 | } |
| 20197 | it->glyph_row->truncated_on_right_p = 1; | 20911 | row->truncated_on_right_p = 1; |
| 20198 | } | 20912 | } |
| 20199 | break; | 20913 | break; |
| 20200 | } | 20914 | } |
| @@ -20202,11 +20916,11 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 20202 | 20916 | ||
| 20203 | /* Maybe insert a truncation at the left. */ | 20917 | /* Maybe insert a truncation at the left. */ |
| 20204 | if (it->first_visible_x | 20918 | if (it->first_visible_x |
| 20205 | && IT_CHARPOS (*it) > 0) | 20919 | && it_charpos > 0) |
| 20206 | { | 20920 | { |
| 20207 | if (!FRAME_WINDOW_P (it->f)) | 20921 | if (!FRAME_WINDOW_P (it->f)) |
| 20208 | insert_left_trunc_glyphs (it); | 20922 | insert_left_trunc_glyphs (it); |
| 20209 | it->glyph_row->truncated_on_left_p = 1; | 20923 | row->truncated_on_left_p = 1; |
| 20210 | } | 20924 | } |
| 20211 | 20925 | ||
| 20212 | it->face_id = saved_face_id; | 20926 | it->face_id = saved_face_id; |
| @@ -27051,18 +27765,18 @@ but does not change the fact they are interpreted as raw bytes. */); | |||
| 27051 | unibyte_display_via_language_environment = 0; | 27765 | unibyte_display_via_language_environment = 0; |
| 27052 | 27766 | ||
| 27053 | DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height, | 27767 | DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height, |
| 27054 | doc: /* *Maximum height for resizing mini-windows. | 27768 | doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area). |
| 27055 | If a float, it specifies a fraction of the mini-window frame's height. | 27769 | If a float, it specifies a fraction of the mini-window frame's height. |
| 27056 | If an integer, it specifies a number of lines. */); | 27770 | If an integer, it specifies a number of lines. */); |
| 27057 | Vmax_mini_window_height = make_float (0.25); | 27771 | Vmax_mini_window_height = make_float (0.25); |
| 27058 | 27772 | ||
| 27059 | DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows, | 27773 | DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows, |
| 27060 | doc: /* *How to resize mini-windows. | 27774 | doc: /* How to resize mini-windows (the minibuffer and the echo area). |
| 27061 | A value of nil means don't automatically resize mini-windows. | 27775 | A value of nil means don't automatically resize mini-windows. |
| 27062 | A value of t means resize them to fit the text displayed in them. | 27776 | A value of t means resize them to fit the text displayed in them. |
| 27063 | A value of `grow-only', the default, means let mini-windows grow | 27777 | A value of `grow-only', the default, means let mini-windows grow only; |
| 27064 | only, until their display becomes empty, at which point the windows | 27778 | they return to their normal size when the minibuffer is closed, or the |
| 27065 | go back to their normal size. */); | 27779 | echo area becomes empty. */); |
| 27066 | Vresize_mini_windows = Qgrow_only; | 27780 | Vresize_mini_windows = Qgrow_only; |
| 27067 | 27781 | ||
| 27068 | DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist, | 27782 | DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist, |
diff --git a/src/xfaces.c b/src/xfaces.c index 4f06bd3ba55..c1e75ab3e59 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -536,8 +536,7 @@ int color_count[256]; | |||
| 536 | /* Register color PIXEL as allocated. */ | 536 | /* Register color PIXEL as allocated. */ |
| 537 | 537 | ||
| 538 | void | 538 | void |
| 539 | register_color (pixel) | 539 | register_color (unsigned long pixel) |
| 540 | unsigned long pixel; | ||
| 541 | { | 540 | { |
| 542 | xassert (pixel < 256); | 541 | xassert (pixel < 256); |
| 543 | ++color_count[pixel]; | 542 | ++color_count[pixel]; |
| @@ -547,8 +546,7 @@ register_color (pixel) | |||
| 547 | /* Register color PIXEL as deallocated. */ | 546 | /* Register color PIXEL as deallocated. */ |
| 548 | 547 | ||
| 549 | void | 548 | void |
| 550 | unregister_color (pixel) | 549 | unregister_color (unsigned long pixel) |
| 551 | unsigned long pixel; | ||
| 552 | { | 550 | { |
| 553 | xassert (pixel < 256); | 551 | xassert (pixel < 256); |
| 554 | if (color_count[pixel] > 0) | 552 | if (color_count[pixel] > 0) |
| @@ -561,9 +559,7 @@ unregister_color (pixel) | |||
| 561 | /* Register N colors from PIXELS as deallocated. */ | 559 | /* Register N colors from PIXELS as deallocated. */ |
| 562 | 560 | ||
| 563 | void | 561 | void |
| 564 | unregister_colors (pixels, n) | 562 | unregister_colors (unsigned long *pixels, int n) |
| 565 | unsigned long *pixels; | ||
| 566 | int n; | ||
| 567 | { | 563 | { |
| 568 | int i; | 564 | int i; |
| 569 | for (i = 0; i < n; ++i) | 565 | for (i = 0; i < n; ++i) |
| @@ -3813,6 +3809,18 @@ Default face attributes override any local face attributes. */) | |||
| 3813 | Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name), | 3809 | Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name), |
| 3814 | Qnil)); | 3810 | Qnil)); |
| 3815 | } | 3811 | } |
| 3812 | |||
| 3813 | if (STRINGP (gvec[LFACE_FOREGROUND_INDEX])) | ||
| 3814 | Fmodify_frame_parameters (frame, | ||
| 3815 | Fcons (Fcons (Qforeground_color, | ||
| 3816 | gvec[LFACE_FOREGROUND_INDEX]), | ||
| 3817 | Qnil)); | ||
| 3818 | |||
| 3819 | if (STRINGP (gvec[LFACE_BACKGROUND_INDEX])) | ||
| 3820 | Fmodify_frame_parameters (frame, | ||
| 3821 | Fcons (Fcons (Qbackground_color, | ||
| 3822 | gvec[LFACE_BACKGROUND_INDEX]), | ||
| 3823 | Qnil)); | ||
| 3816 | } | 3824 | } |
| 3817 | } | 3825 | } |
| 3818 | 3826 | ||
diff --git a/src/xfns.c b/src/xfns.c index b4153973e0d..11bf9ab57e1 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -2001,11 +2001,8 @@ xic_create_fontsetname (const char *base_fontname, int motif) | |||
| 2001 | 2001 | ||
| 2002 | #ifdef DEBUG_XIC_FONTSET | 2002 | #ifdef DEBUG_XIC_FONTSET |
| 2003 | static void | 2003 | static void |
| 2004 | print_fontset_result (xfs, name, missing_list, missing_count) | 2004 | print_fontset_result (XFontSet xfs, char *name, char **missing_list, |
| 2005 | XFontSet xfs; | 2005 | int missing_count) |
| 2006 | char *name; | ||
| 2007 | char **missing_list; | ||
| 2008 | int missing_count; | ||
| 2009 | { | 2006 | { |
| 2010 | if (xfs) | 2007 | if (xfs) |
| 2011 | fprintf (stderr, "XIC Fontset created: %s\n", name); | 2008 | fprintf (stderr, "XIC Fontset created: %s\n", name); |
| @@ -5805,10 +5802,6 @@ syms_of_xfns (void) | |||
| 5805 | DEFSYM (Qfont_param, "font-parameter"); | 5802 | DEFSYM (Qfont_param, "font-parameter"); |
| 5806 | /* This is the end of symbol initialization. */ | 5803 | /* This is the end of symbol initialization. */ |
| 5807 | 5804 | ||
| 5808 | /* Text property `display' should be nonsticky by default. */ | ||
| 5809 | Vtext_property_default_nonsticky | ||
| 5810 | = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky); | ||
| 5811 | |||
| 5812 | Fput (Qundefined_color, Qerror_conditions, | 5805 | Fput (Qundefined_color, Qerror_conditions, |
| 5813 | pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); | 5806 | pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); |
| 5814 | Fput (Qundefined_color, Qerror_message, | 5807 | Fput (Qundefined_color, Qerror_message, |
diff --git a/src/xgselect.c b/src/xgselect.c index 0d154f6496a..9ccdd37489f 100644 --- a/src/xgselect.c +++ b/src/xgselect.c | |||
| @@ -15,14 +15,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. |
| 16 | 16 | ||
| 17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 18 | along with GNU Emacs. If not, see <http§://www.gnu.org/licenses/>. */ |
| 19 | 19 | ||
| 20 | #include <config.h> | 20 | #include <config.h> |
| 21 | 21 | ||
| 22 | #include <setjmp.h> | 22 | #include <setjmp.h> |
| 23 | #include "xgselect.h" | 23 | #include "xgselect.h" |
| 24 | 24 | ||
| 25 | #if defined (USE_GTK) || defined (HAVE_GCONF) | 25 | #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) |
| 26 | 26 | ||
| 27 | #include <glib.h> | 27 | #include <glib.h> |
| 28 | #include <errno.h> | 28 | #include <errno.h> |
| @@ -149,13 +149,13 @@ xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | |||
| 149 | 149 | ||
| 150 | return retval; | 150 | return retval; |
| 151 | } | 151 | } |
| 152 | #endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ | 152 | #endif /* USE_GTK || HAVE_GCONF || HAVE_GSETTINGS */ |
| 153 | 153 | ||
| 154 | void | 154 | void |
| 155 | xgselect_initialize (void) | 155 | xgselect_initialize (void) |
| 156 | { | 156 | { |
| 157 | #if defined (USE_GTK) || defined (HAVE_GCONF) | 157 | #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) |
| 158 | gfds_size = 128; | 158 | gfds_size = 128; |
| 159 | gfds = xmalloc (sizeof (*gfds)*gfds_size); | 159 | gfds = xmalloc (sizeof (*gfds)*gfds_size); |
| 160 | #endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ | 160 | #endif |
| 161 | } | 161 | } |
diff --git a/src/xmenu.c b/src/xmenu.c index fc629b35104..b4338c1d653 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -740,10 +740,13 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data) | |||
| 740 | help = call_data ? cb_data->help : Qnil; | 740 | help = call_data ? cb_data->help : Qnil; |
| 741 | 741 | ||
| 742 | /* If popup_activated_flag is greater than 1 we are in a popup menu. | 742 | /* If popup_activated_flag is greater than 1 we are in a popup menu. |
| 743 | Don't show help for them, they won't appear before the | 743 | Don't pass the frame to show_help_event for those. |
| 744 | popup is popped down. */ | 744 | Passing frame creates an Emacs event. As we are looping in |
| 745 | if (popup_activated_flag <= 1) | 745 | popup_widget_loop, it won't be handeled. Passing NULL shows the tip |
| 746 | show_help_event (cb_data->cl_data->f, widget, help); | 746 | directly without using an Emacs event. This is what the Lucid code |
| 747 | does below. */ | ||
| 748 | show_help_event (popup_activated_flag <= 1 ? cb_data->cl_data->f : NULL, | ||
| 749 | widget, help); | ||
| 747 | } | 750 | } |
| 748 | #else | 751 | #else |
| 749 | static void | 752 | static void |
diff --git a/src/xrdb.c b/src/xrdb.c index e18ff65f799..6a16e3260bd 100644 --- a/src/xrdb.c +++ b/src/xrdb.c | |||
| @@ -651,9 +651,7 @@ typedef char **List; | |||
| 651 | #define free_arglist(list) | 651 | #define free_arglist(list) |
| 652 | 652 | ||
| 653 | static List | 653 | static List |
| 654 | member (elt, list) | 654 | member (char *elt, List list) |
| 655 | char *elt; | ||
| 656 | List list; | ||
| 657 | { | 655 | { |
| 658 | List p; | 656 | List p; |
| 659 | 657 | ||
| @@ -665,20 +663,17 @@ member (elt, list) | |||
| 665 | } | 663 | } |
| 666 | 664 | ||
| 667 | static void | 665 | static void |
| 668 | fatal (msg, prog, x1, x2, x3, x4, x5) | 666 | fatal (char *msg, char *prog) |
| 669 | char *msg, *prog; | ||
| 670 | int x1, x2, x3, x4, x5; | ||
| 671 | { | 667 | { |
| 672 | if (errno) | 668 | if (errno) |
| 673 | perror (prog); | 669 | perror (prog); |
| 674 | 670 | ||
| 675 | (void) fprintf (stderr, msg, prog, x1, x2, x3, x4, x5); | 671 | (void) fprintf (stderr, msg, prog); |
| 676 | exit (1); | 672 | exit (1); |
| 677 | } | 673 | } |
| 678 | 674 | ||
| 679 | main (argc, argv) | 675 | int |
| 680 | int argc; | 676 | main (int argc, char **argv) |
| 681 | char **argv; | ||
| 682 | { | 677 | { |
| 683 | Display *display; | 678 | Display *display; |
| 684 | char *displayname, *resource_string, *class, *name; | 679 | char *displayname, *resource_string, *class, *name; |
| @@ -749,5 +744,7 @@ main (argc, argv) | |||
| 749 | printf ("\tExit.\n\n"); | 744 | printf ("\tExit.\n\n"); |
| 750 | 745 | ||
| 751 | XCloseDisplay (display); | 746 | XCloseDisplay (display); |
| 747 | |||
| 748 | return 0; | ||
| 752 | } | 749 | } |
| 753 | #endif /* TESTRM */ | 750 | #endif /* TESTRM */ |
diff --git a/src/xselect.c b/src/xselect.c index 7f4e0b40f62..5e5bdb55eca 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -112,6 +112,7 @@ static Lisp_Object QUTF8_STRING; /* This is a type of selection. */ | |||
| 112 | static Lisp_Object Qcompound_text_with_extensions; | 112 | static Lisp_Object Qcompound_text_with_extensions; |
| 113 | 113 | ||
| 114 | static Lisp_Object Qforeign_selection; | 114 | static Lisp_Object Qforeign_selection; |
| 115 | static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions; | ||
| 115 | 116 | ||
| 116 | /* If this is a smaller number than the max-request-size of the display, | 117 | /* If this is a smaller number than the max-request-size of the display, |
| 117 | emacs will use INCR selection transfer when the selection is larger | 118 | emacs will use INCR selection transfer when the selection is larger |
| @@ -855,7 +856,7 @@ x_handle_selection_request (struct input_event *event) | |||
| 855 | && !EQ (Vx_sent_selection_functions, Qunbound)) | 856 | && !EQ (Vx_sent_selection_functions, Qunbound)) |
| 856 | { | 857 | { |
| 857 | Lisp_Object args[4]; | 858 | Lisp_Object args[4]; |
| 858 | args[0] = Vx_sent_selection_functions; | 859 | args[0] = Qx_sent_selection_functions; |
| 859 | args[1] = selection_symbol; | 860 | args[1] = selection_symbol; |
| 860 | args[2] = target_symbol; | 861 | args[2] = target_symbol; |
| 861 | args[3] = success ? Qt : Qnil; | 862 | args[3] = success ? Qt : Qnil; |
| @@ -979,7 +980,7 @@ x_handle_selection_clear (struct input_event *event) | |||
| 979 | /* Run the `x-lost-selection-functions' abnormal hook. */ | 980 | /* Run the `x-lost-selection-functions' abnormal hook. */ |
| 980 | { | 981 | { |
| 981 | Lisp_Object args[2]; | 982 | Lisp_Object args[2]; |
| 982 | args[0] = Vx_lost_selection_functions; | 983 | args[0] = Qx_lost_selection_functions; |
| 983 | args[1] = selection_symbol; | 984 | args[1] = selection_symbol; |
| 984 | Frun_hook_with_args (2, args); | 985 | Frun_hook_with_args (2, args); |
| 985 | } | 986 | } |
| @@ -1020,7 +1021,7 @@ x_clear_frame_selections (FRAME_PTR f) | |||
| 1020 | { | 1021 | { |
| 1021 | /* Run the `x-lost-selection-functions' abnormal hook. */ | 1022 | /* Run the `x-lost-selection-functions' abnormal hook. */ |
| 1022 | Lisp_Object args[2]; | 1023 | Lisp_Object args[2]; |
| 1023 | args[0] = Vx_lost_selection_functions; | 1024 | args[0] = Qx_lost_selection_functions; |
| 1024 | args[1] = Fcar (Fcar (t->Vselection_alist)); | 1025 | args[1] = Fcar (Fcar (t->Vselection_alist)); |
| 1025 | Frun_hook_with_args (2, args); | 1026 | Frun_hook_with_args (2, args); |
| 1026 | 1027 | ||
| @@ -1033,7 +1034,7 @@ x_clear_frame_selections (FRAME_PTR f) | |||
| 1033 | && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest)))))))) | 1034 | && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest)))))))) |
| 1034 | { | 1035 | { |
| 1035 | Lisp_Object args[2]; | 1036 | Lisp_Object args[2]; |
| 1036 | args[0] = Vx_lost_selection_functions; | 1037 | args[0] = Qx_lost_selection_functions; |
| 1037 | args[1] = XCAR (XCAR (XCDR (rest))); | 1038 | args[1] = XCAR (XCAR (XCDR (rest))); |
| 1038 | Frun_hook_with_args (2, args); | 1039 | Frun_hook_with_args (2, args); |
| 1039 | XSETCDR (rest, XCDR (XCDR (rest))); | 1040 | XSETCDR (rest, XCDR (XCDR (rest))); |
| @@ -2679,4 +2680,6 @@ A value of 0 means wait as long as necessary. This is initialized from the | |||
| 2679 | DEFSYM (QNULL, "NULL"); | 2680 | DEFSYM (QNULL, "NULL"); |
| 2680 | DEFSYM (Qcompound_text_with_extensions, "compound-text-with-extensions"); | 2681 | DEFSYM (Qcompound_text_with_extensions, "compound-text-with-extensions"); |
| 2681 | DEFSYM (Qforeign_selection, "foreign-selection"); | 2682 | DEFSYM (Qforeign_selection, "foreign-selection"); |
| 2683 | DEFSYM (Qx_lost_selection_functions, "x-lost-selection-functions"); | ||
| 2684 | DEFSYM (Qx_sent_selection_functions, "x-sent-selection-functions"); | ||
| 2682 | } | 2685 | } |
diff --git a/src/xsettings.c b/src/xsettings.c index 5412cf426f8..dadbe68b4cb 100644 --- a/src/xsettings.c +++ b/src/xsettings.c | |||
| @@ -34,9 +34,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 34 | 34 | ||
| 35 | #include <X11/Xproto.h> | 35 | #include <X11/Xproto.h> |
| 36 | 36 | ||
| 37 | #ifdef HAVE_GSETTINGS | ||
| 38 | #include <glib-object.h> | ||
| 39 | #include <gio/gio.h> | ||
| 40 | #endif | ||
| 41 | |||
| 37 | #ifdef HAVE_GCONF | 42 | #ifdef HAVE_GCONF |
| 38 | #include <gconf/gconf-client.h> | 43 | #include <gconf/gconf-client.h> |
| 39 | #endif | 44 | #endif |
| 45 | |||
| 40 | #ifdef HAVE_XFT | 46 | #ifdef HAVE_XFT |
| 41 | #include <X11/Xft/Xft.h> | 47 | #include <X11/Xft/Xft.h> |
| 42 | #endif | 48 | #endif |
| @@ -48,10 +54,7 @@ static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render, | |||
| 48 | Qtool_bar_style; | 54 | Qtool_bar_style; |
| 49 | static Lisp_Object current_tool_bar_style; | 55 | static Lisp_Object current_tool_bar_style; |
| 50 | 56 | ||
| 51 | #ifdef HAVE_GCONF | 57 | /* Store an config changed event in to the event queue. */ |
| 52 | static GConfClient *gconf_client; | ||
| 53 | #endif | ||
| 54 | |||
| 55 | 58 | ||
| 56 | static void | 59 | static void |
| 57 | store_config_changed_event (Lisp_Object arg, Lisp_Object display_name) | 60 | store_config_changed_event (Lisp_Object arg, Lisp_Object display_name) |
| @@ -64,6 +67,99 @@ store_config_changed_event (Lisp_Object arg, Lisp_Object display_name) | |||
| 64 | kbd_buffer_store_event (&event); | 67 | kbd_buffer_store_event (&event); |
| 65 | } | 68 | } |
| 66 | 69 | ||
| 70 | /* Return non-zero if DPYINFO is still valid. */ | ||
| 71 | static int | ||
| 72 | dpyinfo_valid (struct x_display_info *dpyinfo) | ||
| 73 | { | ||
| 74 | int found = 0; | ||
| 75 | if (dpyinfo != NULL) | ||
| 76 | { | ||
| 77 | struct x_display_info *d; | ||
| 78 | for (d = x_display_list; !found && d; d = d->next) | ||
| 79 | found = d == dpyinfo && d->display == dpyinfo->display; | ||
| 80 | } | ||
| 81 | return found; | ||
| 82 | } | ||
| 83 | |||
| 84 | /* Store a monospace font change event if the monospaced font changed. */ | ||
| 85 | |||
| 86 | #if defined HAVE_XFT && (defined HAVE_GSETTINGS || defined HAVE_GCONF) | ||
| 87 | static void | ||
| 88 | store_monospaced_changed (const char *newfont) | ||
| 89 | { | ||
| 90 | if (current_mono_font != NULL && strcmp (newfont, current_mono_font) == 0) | ||
| 91 | return; /* No change. */ | ||
| 92 | |||
| 93 | xfree (current_mono_font); | ||
| 94 | current_mono_font = xstrdup (newfont); | ||
| 95 | |||
| 96 | if (dpyinfo_valid (first_dpyinfo) && use_system_font) | ||
| 97 | { | ||
| 98 | store_config_changed_event (Qmonospace_font_name, | ||
| 99 | XCAR (first_dpyinfo->name_list_element)); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | #endif | ||
| 103 | |||
| 104 | /* Store a font name change event if the font name changed. */ | ||
| 105 | |||
| 106 | #ifdef HAVE_XFT | ||
| 107 | static void | ||
| 108 | store_font_name_changed (const char *newfont) | ||
| 109 | { | ||
| 110 | if (current_font != NULL && strcmp (newfont, current_font) == 0) | ||
| 111 | return; /* No change. */ | ||
| 112 | |||
| 113 | xfree (current_font); | ||
| 114 | current_font = xstrdup (newfont); | ||
| 115 | |||
| 116 | if (dpyinfo_valid (first_dpyinfo)) | ||
| 117 | { | ||
| 118 | store_config_changed_event (Qfont_name, | ||
| 119 | XCAR (first_dpyinfo->name_list_element)); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | #endif /* HAVE_XFT */ | ||
| 123 | |||
| 124 | /* Map TOOL_BAR_STYLE from a string to its correspinding Lisp value. | ||
| 125 | Return Qnil if TOOL_BAR_STYLE is not known. */ | ||
| 126 | |||
| 127 | static Lisp_Object | ||
| 128 | map_tool_bar_style (const char *tool_bar_style) | ||
| 129 | { | ||
| 130 | Lisp_Object style = Qnil; | ||
| 131 | if (tool_bar_style) | ||
| 132 | { | ||
| 133 | if (strcmp (tool_bar_style, "both") == 0) | ||
| 134 | style = Qboth; | ||
| 135 | else if (strcmp (tool_bar_style, "both-horiz") == 0) | ||
| 136 | style = Qboth_horiz; | ||
| 137 | else if (strcmp (tool_bar_style, "icons") == 0) | ||
| 138 | style = Qimage; | ||
| 139 | else if (strcmp (tool_bar_style, "text") == 0) | ||
| 140 | style = Qtext; | ||
| 141 | } | ||
| 142 | |||
| 143 | return style; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* Store a tool bar style change event if the tool bar style changed. */ | ||
| 147 | |||
| 148 | static void | ||
| 149 | store_tool_bar_style_changed (const char *newstyle, | ||
| 150 | struct x_display_info *dpyinfo) | ||
| 151 | { | ||
| 152 | Lisp_Object style = map_tool_bar_style (newstyle); | ||
| 153 | if (EQ (current_tool_bar_style, style)) | ||
| 154 | return; /* No change. */ | ||
| 155 | |||
| 156 | current_tool_bar_style = style; | ||
| 157 | if (dpyinfo_valid (dpyinfo)) | ||
| 158 | store_config_changed_event (Qtool_bar_style, | ||
| 159 | XCAR (dpyinfo->name_list_element)); | ||
| 160 | } | ||
| 161 | |||
| 162 | |||
| 67 | #define XSETTINGS_FONT_NAME "Gtk/FontName" | 163 | #define XSETTINGS_FONT_NAME "Gtk/FontName" |
| 68 | #define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle" | 164 | #define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle" |
| 69 | 165 | ||
| @@ -83,55 +179,128 @@ struct xsettings | |||
| 83 | FcBool aa, hinting; | 179 | FcBool aa, hinting; |
| 84 | int rgba, lcdfilter, hintstyle; | 180 | int rgba, lcdfilter, hintstyle; |
| 85 | double dpi; | 181 | double dpi; |
| 86 | #endif | ||
| 87 | 182 | ||
| 88 | char *font; | 183 | char *font; |
| 184 | #endif | ||
| 185 | |||
| 89 | char *tb_style; | 186 | char *tb_style; |
| 90 | 187 | ||
| 91 | unsigned seen; | 188 | unsigned seen; |
| 92 | }; | 189 | }; |
| 93 | 190 | ||
| 191 | #ifdef HAVE_GSETTINGS | ||
| 192 | #define GSETTINGS_SCHEMA "org.gnome.desktop.interface" | ||
| 193 | #define GSETTINGS_TOOL_BAR_STYLE "toolbar-style" | ||
| 194 | |||
| 195 | #ifdef HAVE_XFT | ||
| 196 | #define GSETTINGS_MONO_FONT "monospace-font-name" | ||
| 197 | #define GSETTINGS_FONT_NAME "font-name" | ||
| 198 | #endif | ||
| 199 | |||
| 200 | |||
| 201 | /* The single GSettings instance, or NULL if not connected to GSettings. */ | ||
| 202 | |||
| 203 | static GSettings *gsettings_client; | ||
| 204 | |||
| 205 | /* Callback called when something changed in GSettings. */ | ||
| 206 | |||
| 207 | static void | ||
| 208 | something_changed_gsettingsCB (GSettings *settings, | ||
| 209 | gchar *key, | ||
| 210 | gpointer user_data) | ||
| 211 | { | ||
| 212 | GVariant *val; | ||
| 213 | |||
| 214 | if (strcmp (key, GSETTINGS_TOOL_BAR_STYLE) == 0) | ||
| 215 | { | ||
| 216 | val = g_settings_get_value (settings, GSETTINGS_TOOL_BAR_STYLE); | ||
| 217 | if (val) | ||
| 218 | { | ||
| 219 | g_variant_ref_sink (val); | ||
| 220 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | ||
| 221 | { | ||
| 222 | const gchar *newstyle = g_variant_get_string (val, NULL); | ||
| 223 | store_tool_bar_style_changed (newstyle, first_dpyinfo); | ||
| 224 | } | ||
| 225 | g_variant_unref (val); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | #ifdef HAVE_XFT | ||
| 229 | else if (strcmp (key, GSETTINGS_MONO_FONT) == 0) | ||
| 230 | { | ||
| 231 | val = g_settings_get_value (settings, GSETTINGS_MONO_FONT); | ||
| 232 | if (val) | ||
| 233 | { | ||
| 234 | g_variant_ref_sink (val); | ||
| 235 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | ||
| 236 | { | ||
| 237 | const gchar *newfont = g_variant_get_string (val, NULL); | ||
| 238 | store_monospaced_changed (newfont); | ||
| 239 | } | ||
| 240 | g_variant_unref (val); | ||
| 241 | } | ||
| 242 | } | ||
| 243 | else if (strcmp (key, GSETTINGS_FONT_NAME) == 0) | ||
| 244 | { | ||
| 245 | val = g_settings_get_value (settings, GSETTINGS_FONT_NAME); | ||
| 246 | if (val) | ||
| 247 | { | ||
| 248 | g_variant_ref_sink (val); | ||
| 249 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | ||
| 250 | { | ||
| 251 | const gchar *newfont = g_variant_get_string (val, NULL); | ||
| 252 | store_font_name_changed (newfont); | ||
| 253 | } | ||
| 254 | g_variant_unref (val); | ||
| 255 | } | ||
| 256 | } | ||
| 257 | #endif /* HAVE_XFT */ | ||
| 258 | } | ||
| 259 | |||
| 260 | #endif /* HAVE_GSETTINGS */ | ||
| 261 | |||
| 94 | #ifdef HAVE_GCONF | 262 | #ifdef HAVE_GCONF |
| 263 | #define GCONF_TOOL_BAR_STYLE "/desktop/gnome/interface/toolbar_style" | ||
| 264 | #ifdef HAVE_XFT | ||
| 265 | #define GCONF_MONO_FONT "/desktop/gnome/interface/monospace_font_name" | ||
| 266 | #define GCONF_FONT_NAME "/desktop/gnome/interface/font_name" | ||
| 267 | #endif | ||
| 95 | 268 | ||
| 96 | #define SYSTEM_MONO_FONT "/desktop/gnome/interface/monospace_font_name" | 269 | /* The single GConf instance, or NULL if not connected to GConf. */ |
| 97 | #define SYSTEM_FONT "/desktop/gnome/interface/font_name" | 270 | |
| 271 | static GConfClient *gconf_client; | ||
| 98 | 272 | ||
| 99 | /* Callback called when something changed in GConf that we care about, | 273 | /* Callback called when something changed in GConf that we care about. */ |
| 100 | that is SYSTEM_MONO_FONT. */ | ||
| 101 | 274 | ||
| 102 | static void | 275 | static void |
| 103 | something_changedCB (GConfClient *client, | 276 | something_changed_gconfCB (GConfClient *client, |
| 104 | guint cnxn_id, | 277 | guint cnxn_id, |
| 105 | GConfEntry *entry, | 278 | GConfEntry *entry, |
| 106 | gpointer user_data) | 279 | gpointer user_data) |
| 107 | { | 280 | { |
| 108 | GConfValue *v = gconf_entry_get_value (entry); | 281 | GConfValue *v = gconf_entry_get_value (entry); |
| 282 | const char *key = gconf_entry_get_key (entry); | ||
| 109 | 283 | ||
| 110 | if (!v) return; | 284 | if (!v || v->type != GCONF_VALUE_STRING || ! key) return; |
| 111 | if (v->type == GCONF_VALUE_STRING) | 285 | if (strcmp (key, GCONF_TOOL_BAR_STYLE) == 0) |
| 112 | { | 286 | { |
| 113 | const char *value = gconf_value_get_string (v); | 287 | const char *value = gconf_value_get_string (v); |
| 114 | if (current_mono_font != NULL && strcmp (value, current_mono_font) == 0) | 288 | store_tool_bar_style_changed (value, first_dpyinfo); |
| 115 | return; /* No change. */ | ||
| 116 | |||
| 117 | xfree (current_mono_font); | ||
| 118 | current_mono_font = xstrdup (value); | ||
| 119 | } | 289 | } |
| 120 | 290 | #ifdef HAVE_XFT | |
| 121 | 291 | else if (strcmp (key, GCONF_MONO_FONT) == 0) | |
| 122 | if (first_dpyinfo != NULL) | 292 | { |
| 293 | const char *value = gconf_value_get_string (v); | ||
| 294 | store_monospaced_changed (value); | ||
| 295 | } | ||
| 296 | else if (strcmp (key, GCONF_FONT_NAME) == 0) | ||
| 123 | { | 297 | { |
| 124 | /* Check if display still open */ | 298 | const char *value = gconf_value_get_string (v); |
| 125 | struct x_display_info *dpyinfo; | 299 | store_font_name_changed (value); |
| 126 | int found = 0; | ||
| 127 | for (dpyinfo = x_display_list; !found && dpyinfo; dpyinfo = dpyinfo->next) | ||
| 128 | found = dpyinfo == first_dpyinfo; | ||
| 129 | |||
| 130 | if (found && use_system_font) | ||
| 131 | store_config_changed_event (Qmonospace_font_name, | ||
| 132 | XCAR (first_dpyinfo->name_list_element)); | ||
| 133 | } | 300 | } |
| 301 | #endif /* HAVE_XFT */ | ||
| 134 | } | 302 | } |
| 303 | |||
| 135 | #endif /* HAVE_GCONF */ | 304 | #endif /* HAVE_GCONF */ |
| 136 | 305 | ||
| 137 | #ifdef HAVE_XFT | 306 | #ifdef HAVE_XFT |
| @@ -277,10 +446,10 @@ parse_settings (unsigned char *prop, | |||
| 277 | want_this = | 446 | want_this = |
| 278 | #ifdef HAVE_XFT | 447 | #ifdef HAVE_XFT |
| 279 | (nlen > 6 && strncmp (name, "Xft/", 4) == 0) | 448 | (nlen > 6 && strncmp (name, "Xft/", 4) == 0) |
| 449 | || strcmp (XSETTINGS_FONT_NAME, name) == 0 | ||
| 280 | || | 450 | || |
| 281 | #endif | 451 | #endif |
| 282 | (strcmp (XSETTINGS_FONT_NAME, name) == 0) | 452 | strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0; |
| 283 | || (strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0); | ||
| 284 | 453 | ||
| 285 | switch (type) | 454 | switch (type) |
| 286 | { | 455 | { |
| @@ -322,17 +491,17 @@ parse_settings (unsigned char *prop, | |||
| 322 | if (want_this) | 491 | if (want_this) |
| 323 | { | 492 | { |
| 324 | ++settings_seen; | 493 | ++settings_seen; |
| 325 | if (strcmp (name, XSETTINGS_FONT_NAME) == 0) | 494 | if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0) |
| 326 | { | ||
| 327 | settings->font = xstrdup (sval); | ||
| 328 | settings->seen |= SEEN_FONT; | ||
| 329 | } | ||
| 330 | else if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0) | ||
| 331 | { | 495 | { |
| 332 | settings->tb_style = xstrdup (sval); | 496 | settings->tb_style = xstrdup (sval); |
| 333 | settings->seen |= SEEN_TB_STYLE; | 497 | settings->seen |= SEEN_TB_STYLE; |
| 334 | } | 498 | } |
| 335 | #ifdef HAVE_XFT | 499 | #ifdef HAVE_XFT |
| 500 | else if (strcmp (name, XSETTINGS_FONT_NAME) == 0) | ||
| 501 | { | ||
| 502 | settings->font = xstrdup (sval); | ||
| 503 | settings->seen |= SEEN_FONT; | ||
| 504 | } | ||
| 336 | else if (strcmp (name, "Xft/Antialias") == 0) | 505 | else if (strcmp (name, "Xft/Antialias") == 0) |
| 337 | { | 506 | { |
| 338 | settings->seen |= SEEN_AA; | 507 | settings->seen |= SEEN_AA; |
| @@ -397,6 +566,10 @@ parse_settings (unsigned char *prop, | |||
| 397 | return settings_seen; | 566 | return settings_seen; |
| 398 | } | 567 | } |
| 399 | 568 | ||
| 569 | /* Read settings from the XSettings property window on display for DPYINFO. | ||
| 570 | Store settings read in SETTINGS. | ||
| 571 | Return non-zero if successful, zero if not. */ | ||
| 572 | |||
| 400 | static int | 573 | static int |
| 401 | read_settings (struct x_display_info *dpyinfo, struct xsettings *settings) | 574 | read_settings (struct x_display_info *dpyinfo, struct xsettings *settings) |
| 402 | { | 575 | { |
| @@ -426,6 +599,8 @@ read_settings (struct x_display_info *dpyinfo, struct xsettings *settings) | |||
| 426 | return rc != 0; | 599 | return rc != 0; |
| 427 | } | 600 | } |
| 428 | 601 | ||
| 602 | /* Apply Xft settings in SETTINGS to the Xft library. | ||
| 603 | If SEND_EVENT_P is non-zero store a Lisp event that Xft settings changed. */ | ||
| 429 | 604 | ||
| 430 | static void | 605 | static void |
| 431 | apply_xft_settings (struct x_display_info *dpyinfo, | 606 | apply_xft_settings (struct x_display_info *dpyinfo, |
| @@ -444,9 +619,9 @@ apply_xft_settings (struct x_display_info *dpyinfo, | |||
| 444 | pat); | 619 | pat); |
| 445 | FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa); | 620 | FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa); |
| 446 | FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting); | 621 | FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting); |
| 447 | # ifdef FC_HINT_STYLE | 622 | #ifdef FC_HINT_STYLE |
| 448 | FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle); | 623 | FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle); |
| 449 | # endif | 624 | #endif |
| 450 | FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter); | 625 | FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter); |
| 451 | FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba); | 626 | FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba); |
| 452 | FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi); | 627 | FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi); |
| @@ -485,7 +660,7 @@ apply_xft_settings (struct x_display_info *dpyinfo, | |||
| 485 | oldsettings.lcdfilter = settings->lcdfilter; | 660 | oldsettings.lcdfilter = settings->lcdfilter; |
| 486 | } | 661 | } |
| 487 | 662 | ||
| 488 | # ifdef FC_HINT_STYLE | 663 | #ifdef FC_HINT_STYLE |
| 489 | if ((settings->seen & SEEN_HINTSTYLE) != 0 | 664 | if ((settings->seen & SEEN_HINTSTYLE) != 0 |
| 490 | && oldsettings.hintstyle != settings->hintstyle) | 665 | && oldsettings.hintstyle != settings->hintstyle) |
| 491 | { | 666 | { |
| @@ -494,7 +669,7 @@ apply_xft_settings (struct x_display_info *dpyinfo, | |||
| 494 | ++changed; | 669 | ++changed; |
| 495 | oldsettings.hintstyle = settings->hintstyle; | 670 | oldsettings.hintstyle = settings->hintstyle; |
| 496 | } | 671 | } |
| 497 | # endif | 672 | #endif |
| 498 | 673 | ||
| 499 | if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi | 674 | if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi |
| 500 | && settings->dpi > 0) | 675 | && settings->dpi > 0) |
| @@ -545,11 +720,13 @@ apply_xft_settings (struct x_display_info *dpyinfo, | |||
| 545 | #endif /* HAVE_XFT */ | 720 | #endif /* HAVE_XFT */ |
| 546 | } | 721 | } |
| 547 | 722 | ||
| 723 | /* Read XSettings from the display for DPYINFO. | ||
| 724 | If SEND_EVENT_P is non-zero store a Lisp event settings that changed. */ | ||
| 725 | |||
| 548 | static void | 726 | static void |
| 549 | read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p) | 727 | read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p) |
| 550 | { | 728 | { |
| 551 | struct xsettings settings; | 729 | struct xsettings settings; |
| 552 | Lisp_Object dpyname = XCAR (dpyinfo->name_list_element); | ||
| 553 | 730 | ||
| 554 | if (!read_settings (dpyinfo, &settings)) | 731 | if (!read_settings (dpyinfo, &settings)) |
| 555 | return; | 732 | return; |
| @@ -557,38 +734,29 @@ read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p) | |||
| 557 | apply_xft_settings (dpyinfo, True, &settings); | 734 | apply_xft_settings (dpyinfo, True, &settings); |
| 558 | if (settings.seen & SEEN_TB_STYLE) | 735 | if (settings.seen & SEEN_TB_STYLE) |
| 559 | { | 736 | { |
| 560 | Lisp_Object style = Qnil; | 737 | if (send_event_p) |
| 561 | if (strcmp (settings.tb_style, "both") == 0) | 738 | store_tool_bar_style_changed (settings.tb_style, dpyinfo); |
| 562 | style = Qboth; | 739 | else |
| 563 | else if (strcmp (settings.tb_style, "both-horiz") == 0) | 740 | current_tool_bar_style = map_tool_bar_style (settings.tb_style); |
| 564 | style = Qboth_horiz; | ||
| 565 | else if (strcmp (settings.tb_style, "icons") == 0) | ||
| 566 | style = Qimage; | ||
| 567 | else if (strcmp (settings.tb_style, "text") == 0) | ||
| 568 | style = Qtext; | ||
| 569 | if (!NILP (style) && !EQ (style, current_tool_bar_style)) | ||
| 570 | { | ||
| 571 | current_tool_bar_style = style; | ||
| 572 | if (send_event_p) | ||
| 573 | store_config_changed_event (Qtool_bar_style, dpyname); | ||
| 574 | } | ||
| 575 | xfree (settings.tb_style); | 741 | xfree (settings.tb_style); |
| 576 | } | 742 | } |
| 577 | 743 | #ifdef HAVE_XFT | |
| 578 | if (settings.seen & SEEN_FONT) | 744 | if (settings.seen & SEEN_FONT) |
| 579 | { | 745 | { |
| 580 | if (!current_font || strcmp (current_font, settings.font) != 0) | 746 | if (send_event_p) |
| 747 | store_font_name_changed (settings.font); | ||
| 748 | else | ||
| 581 | { | 749 | { |
| 582 | xfree (current_font); | 750 | xfree (current_font); |
| 583 | current_font = settings.font; | 751 | current_font = xstrdup (settings.font); |
| 584 | if (send_event_p) | ||
| 585 | store_config_changed_event (Qfont_name, dpyname); | ||
| 586 | } | 752 | } |
| 587 | else | 753 | xfree (settings.font); |
| 588 | xfree (settings.font); | ||
| 589 | } | 754 | } |
| 755 | #endif | ||
| 590 | } | 756 | } |
| 591 | 757 | ||
| 758 | /* Check if EVENT for the display in DPYINFO is XSettings related. */ | ||
| 759 | |||
| 592 | void | 760 | void |
| 593 | xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) | 761 | xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) |
| 594 | { | 762 | { |
| @@ -630,41 +798,130 @@ xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) | |||
| 630 | read_and_apply_settings (dpyinfo, True); | 798 | read_and_apply_settings (dpyinfo, True); |
| 631 | } | 799 | } |
| 632 | 800 | ||
| 801 | /* Initialize GSettings and read startup values. */ | ||
| 802 | |||
| 803 | static void | ||
| 804 | init_gsettings (void) | ||
| 805 | { | ||
| 806 | #ifdef HAVE_GSETTINGS | ||
| 807 | GVariant *val; | ||
| 808 | const gchar *const *schemas; | ||
| 809 | int schema_found = 0; | ||
| 810 | |||
| 811 | #ifdef HAVE_G_TYPE_INIT | ||
| 812 | g_type_init (); | ||
| 813 | #endif | ||
| 814 | |||
| 815 | schemas = g_settings_list_schemas(); | ||
| 816 | if (schemas == NULL) return; | ||
| 817 | while (! schema_found && *schemas != NULL) | ||
| 818 | schema_found = strcmp (*schemas++, GSETTINGS_SCHEMA) == 0; | ||
| 819 | if (!schema_found) return; | ||
| 820 | |||
| 821 | gsettings_client = g_settings_new (GSETTINGS_SCHEMA); | ||
| 822 | if (!gsettings_client) return; | ||
| 823 | g_object_ref_sink (G_OBJECT (gsettings_client)); | ||
| 824 | g_signal_connect (G_OBJECT (gsettings_client), "changed", | ||
| 825 | G_CALLBACK (something_changed_gsettingsCB), NULL); | ||
| 826 | |||
| 827 | val = g_settings_get_value (gsettings_client, GSETTINGS_TOOL_BAR_STYLE); | ||
| 828 | if (val) | ||
| 829 | { | ||
| 830 | g_variant_ref_sink (val); | ||
| 831 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | ||
| 832 | current_tool_bar_style | ||
| 833 | = map_tool_bar_style (g_variant_get_string (val, NULL)); | ||
| 834 | g_variant_unref (val); | ||
| 835 | } | ||
| 836 | |||
| 837 | #ifdef HAVE_XFT | ||
| 838 | val = g_settings_get_value (gsettings_client, GSETTINGS_MONO_FONT); | ||
| 839 | if (val) | ||
| 840 | { | ||
| 841 | g_variant_ref_sink (val); | ||
| 842 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | ||
| 843 | current_mono_font = xstrdup (g_variant_get_string (val, NULL)); | ||
| 844 | g_variant_unref (val); | ||
| 845 | } | ||
| 846 | |||
| 847 | val = g_settings_get_value (gsettings_client, GSETTINGS_FONT_NAME); | ||
| 848 | if (val) | ||
| 849 | { | ||
| 850 | g_variant_ref_sink (val); | ||
| 851 | if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)) | ||
| 852 | current_font = xstrdup (g_variant_get_string (val, NULL)); | ||
| 853 | g_variant_unref (val); | ||
| 854 | } | ||
| 855 | #endif /* HAVE_XFT */ | ||
| 856 | |||
| 857 | #endif /* HAVE_GSETTINGS */ | ||
| 858 | } | ||
| 859 | |||
| 860 | /* Init GConf and read startup values. */ | ||
| 633 | 861 | ||
| 634 | static void | 862 | static void |
| 635 | init_gconf (void) | 863 | init_gconf (void) |
| 636 | { | 864 | { |
| 637 | #if defined (HAVE_GCONF) && defined (HAVE_XFT) | 865 | #if defined (HAVE_GCONF) |
| 638 | char *s; | 866 | char *s; |
| 639 | 867 | ||
| 640 | #ifdef HAVE_G_TYPE_INIT | 868 | #ifdef HAVE_G_TYPE_INIT |
| 641 | g_type_init (); | 869 | g_type_init (); |
| 642 | #endif | 870 | #endif |
| 871 | |||
| 643 | gconf_client = gconf_client_get_default (); | 872 | gconf_client = gconf_client_get_default (); |
| 644 | s = gconf_client_get_string (gconf_client, SYSTEM_MONO_FONT, NULL); | 873 | gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE); |
| 874 | gconf_client_add_dir (gconf_client, | ||
| 875 | GCONF_TOOL_BAR_STYLE, | ||
| 876 | GCONF_CLIENT_PRELOAD_ONELEVEL, | ||
| 877 | NULL); | ||
| 878 | gconf_client_notify_add (gconf_client, | ||
| 879 | GCONF_TOOL_BAR_STYLE, | ||
| 880 | something_changed_gconfCB, | ||
| 881 | NULL, NULL, NULL); | ||
| 882 | |||
| 883 | s = gconf_client_get_string (gconf_client, GCONF_TOOL_BAR_STYLE, NULL); | ||
| 884 | if (s) | ||
| 885 | { | ||
| 886 | current_tool_bar_style = map_tool_bar_style (s); | ||
| 887 | g_free (s); | ||
| 888 | } | ||
| 889 | |||
| 890 | #ifdef HAVE_XFT | ||
| 891 | s = gconf_client_get_string (gconf_client, GCONF_MONO_FONT, NULL); | ||
| 645 | if (s) | 892 | if (s) |
| 646 | { | 893 | { |
| 647 | current_mono_font = xstrdup (s); | 894 | current_mono_font = xstrdup (s); |
| 648 | g_free (s); | 895 | g_free (s); |
| 649 | } | 896 | } |
| 650 | s = gconf_client_get_string (gconf_client, SYSTEM_FONT, NULL); | 897 | s = gconf_client_get_string (gconf_client, GCONF_FONT_NAME, NULL); |
| 651 | if (s) | 898 | if (s) |
| 652 | { | 899 | { |
| 653 | current_font = xstrdup (s); | 900 | current_font = xstrdup (s); |
| 654 | g_free (s); | 901 | g_free (s); |
| 655 | } | 902 | } |
| 656 | gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE); | ||
| 657 | gconf_client_add_dir (gconf_client, | 903 | gconf_client_add_dir (gconf_client, |
| 658 | SYSTEM_MONO_FONT, | 904 | GCONF_MONO_FONT, |
| 905 | GCONF_CLIENT_PRELOAD_ONELEVEL, | ||
| 906 | NULL); | ||
| 907 | gconf_client_notify_add (gconf_client, | ||
| 908 | GCONF_MONO_FONT, | ||
| 909 | something_changed_gconfCB, | ||
| 910 | NULL, NULL, NULL); | ||
| 911 | gconf_client_add_dir (gconf_client, | ||
| 912 | GCONF_FONT_NAME, | ||
| 659 | GCONF_CLIENT_PRELOAD_ONELEVEL, | 913 | GCONF_CLIENT_PRELOAD_ONELEVEL, |
| 660 | NULL); | 914 | NULL); |
| 661 | gconf_client_notify_add (gconf_client, | 915 | gconf_client_notify_add (gconf_client, |
| 662 | SYSTEM_MONO_FONT, | 916 | GCONF_FONT_NAME, |
| 663 | something_changedCB, | 917 | something_changed_gconfCB, |
| 664 | NULL, NULL, NULL); | 918 | NULL, NULL, NULL); |
| 665 | #endif /* HAVE_GCONF && HAVE_XFT */ | 919 | #endif /* HAVE_XFT */ |
| 920 | #endif /* HAVE_GCONF */ | ||
| 666 | } | 921 | } |
| 667 | 922 | ||
| 923 | /* Init Xsettings and read startup values. */ | ||
| 924 | |||
| 668 | static void | 925 | static void |
| 669 | init_xsettings (struct x_display_info *dpyinfo) | 926 | init_xsettings (struct x_display_info *dpyinfo) |
| 670 | { | 927 | { |
| @@ -689,8 +946,12 @@ xsettings_initialize (struct x_display_info *dpyinfo) | |||
| 689 | if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo; | 946 | if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo; |
| 690 | init_gconf (); | 947 | init_gconf (); |
| 691 | init_xsettings (dpyinfo); | 948 | init_xsettings (dpyinfo); |
| 949 | init_gsettings (); | ||
| 692 | } | 950 | } |
| 693 | 951 | ||
| 952 | /* Return the system monospaced font. | ||
| 953 | May be NULL if not known. */ | ||
| 954 | |||
| 694 | const char * | 955 | const char * |
| 695 | xsettings_get_system_font (void) | 956 | xsettings_get_system_font (void) |
| 696 | { | 957 | { |
| @@ -698,6 +959,9 @@ xsettings_get_system_font (void) | |||
| 698 | } | 959 | } |
| 699 | 960 | ||
| 700 | #ifdef USE_LUCID | 961 | #ifdef USE_LUCID |
| 962 | /* Return the system font. | ||
| 963 | May be NULL if not known. */ | ||
| 964 | |||
| 701 | const char * | 965 | const char * |
| 702 | xsettings_get_system_normal_font (void) | 966 | xsettings_get_system_normal_font (void) |
| 703 | { | 967 | { |
| @@ -746,6 +1010,9 @@ syms_of_xsettings (void) | |||
| 746 | current_mono_font = NULL; | 1010 | current_mono_font = NULL; |
| 747 | current_font = NULL; | 1011 | current_font = NULL; |
| 748 | first_dpyinfo = NULL; | 1012 | first_dpyinfo = NULL; |
| 1013 | #ifdef HAVE_GSETTINGS | ||
| 1014 | gsettings_client = NULL; | ||
| 1015 | #endif | ||
| 749 | #ifdef HAVE_GCONF | 1016 | #ifdef HAVE_GCONF |
| 750 | gconf_client = NULL; | 1017 | gconf_client = NULL; |
| 751 | #endif | 1018 | #endif |
| @@ -769,7 +1036,7 @@ If this variable is nil, Emacs ignores system font changes. */); | |||
| 769 | 1036 | ||
| 770 | #ifdef HAVE_XFT | 1037 | #ifdef HAVE_XFT |
| 771 | Fprovide (intern_c_string ("font-render-setting"), Qnil); | 1038 | Fprovide (intern_c_string ("font-render-setting"), Qnil); |
| 772 | #ifdef HAVE_GCONF | 1039 | #if defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) |
| 773 | Fprovide (intern_c_string ("system-font-setting"), Qnil); | 1040 | Fprovide (intern_c_string ("system-font-setting"), Qnil); |
| 774 | #endif | 1041 | #endif |
| 775 | #endif | 1042 | #endif |