Mercurial > hg > xemacs-beta
comparison src/window.c @ 424:11054d720c21 r21-2-20
Import from CVS: tag r21-2-20
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:26:11 +0200 |
parents | 95016f13131a |
children |
comparison
equal
deleted
inserted
replaced
423:28d9c139be4c | 424:11054d720c21 |
---|---|
39 #include "elhash.h" | 39 #include "elhash.h" |
40 #include "commands.h" | 40 #include "commands.h" |
41 #include "gutter.h" | 41 #include "gutter.h" |
42 | 42 |
43 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp; | 43 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp; |
44 Lisp_Object Qscroll_up, Qscroll_down, Qdisplay_buffer; | 44 Lisp_Object Qdisplay_buffer; |
45 | 45 |
46 #ifdef MEMORY_USAGE_STATS | 46 #ifdef MEMORY_USAGE_STATS |
47 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay; | 47 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay; |
48 #ifdef HAVE_SCROLLBARS | 48 #ifdef HAVE_SCROLLBARS |
49 Lisp_Object Qscrollbar_instances; | 49 Lisp_Object Qscrollbar_instances; |
83 Lisp_Object Vvertical_divider_line_width; | 83 Lisp_Object Vvertical_divider_line_width; |
84 | 84 |
85 /* Spacing between outer egde of divider border and window edge */ | 85 /* Spacing between outer egde of divider border and window edge */ |
86 Lisp_Object Vvertical_divider_spacing; | 86 Lisp_Object Vvertical_divider_spacing; |
87 | 87 |
88 /* How much to scroll by per-line. */ | |
89 Lisp_Object Vwindow_pixel_scroll_increment; | |
90 | |
88 /* Scroll if point lands on the bottom line and that line is partially | 91 /* Scroll if point lands on the bottom line and that line is partially |
89 clipped. */ | 92 clipped. */ |
90 int scroll_on_clipped_lines; | 93 int scroll_on_clipped_lines; |
91 | 94 |
92 /* The minibuffer window of the selected frame. | 95 /* The minibuffer window of the selected frame. |
116 | 119 |
117 /* Number of lines of continuity in scrolling by screenfuls. */ | 120 /* Number of lines of continuity in scrolling by screenfuls. */ |
118 int next_screen_context_lines; | 121 int next_screen_context_lines; |
119 | 122 |
120 /* List of freed window configurations with 1 - 10 windows. */ | 123 /* List of freed window configurations with 1 - 10 windows. */ |
121 Lisp_Object Vwindow_configuration_free_list[10]; | 124 static Lisp_Object Vwindow_configuration_free_list[10]; |
122 | 125 |
123 #define SET_LAST_MODIFIED(w, cache_too) \ | 126 #define SET_LAST_MODIFIED(w, cache_too) \ |
124 do { \ | 127 do { \ |
125 (w)->last_modified[CURRENT_DISP] = Qzero; \ | 128 (w)->last_modified[CURRENT_DISP] = Qzero; \ |
126 (w)->last_modified[DESIRED_DISP] = Qzero; \ | 129 (w)->last_modified[DESIRED_DISP] = Qzero; \ |
136 (w)->last_facechange[CMOTION_DISP] = Qzero; \ | 139 (w)->last_facechange[CMOTION_DISP] = Qzero; \ |
137 } while (0) | 140 } while (0) |
138 | 141 |
139 | 142 |
140 #define MARK_DISP_VARIABLE(field) \ | 143 #define MARK_DISP_VARIABLE(field) \ |
141 markobj (window->field[CURRENT_DISP]); \ | 144 mark_object (window->field[CURRENT_DISP]); \ |
142 markobj (window->field[DESIRED_DISP]); \ | 145 mark_object (window->field[DESIRED_DISP]); \ |
143 markobj (window->field[CMOTION_DISP]); | 146 mark_object (window->field[CMOTION_DISP]); |
144 | 147 |
145 static Lisp_Object | 148 static Lisp_Object |
146 mark_window (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 149 mark_window (Lisp_Object obj) |
147 { | 150 { |
148 struct window *window = XWINDOW (obj); | 151 struct window *window = XWINDOW (obj); |
149 markobj (window->frame); | 152 mark_object (window->frame); |
150 markobj (window->mini_p); | 153 mark_object (window->mini_p); |
151 markobj (window->next); | 154 mark_object (window->next); |
152 markobj (window->prev); | 155 mark_object (window->prev); |
153 markobj (window->hchild); | 156 mark_object (window->hchild); |
154 markobj (window->vchild); | 157 mark_object (window->vchild); |
155 markobj (window->parent); | 158 mark_object (window->parent); |
156 markobj (window->buffer); | 159 mark_object (window->buffer); |
157 MARK_DISP_VARIABLE (start); | 160 MARK_DISP_VARIABLE (start); |
158 MARK_DISP_VARIABLE (pointm); | 161 MARK_DISP_VARIABLE (pointm); |
159 markobj (window->sb_point); /* #### move to scrollbar.c? */ | 162 mark_object (window->sb_point); /* #### move to scrollbar.c? */ |
160 markobj (window->use_time); | 163 mark_object (window->use_time); |
161 MARK_DISP_VARIABLE (last_modified); | 164 MARK_DISP_VARIABLE (last_modified); |
162 MARK_DISP_VARIABLE (last_point); | 165 MARK_DISP_VARIABLE (last_point); |
163 MARK_DISP_VARIABLE (last_start); | 166 MARK_DISP_VARIABLE (last_start); |
164 MARK_DISP_VARIABLE (last_facechange); | 167 MARK_DISP_VARIABLE (last_facechange); |
165 markobj (window->line_cache_last_updated); | 168 mark_object (window->line_cache_last_updated); |
166 markobj (window->redisplay_end_trigger); | 169 mark_object (window->redisplay_end_trigger); |
167 markobj (window->subwindow_instance_cache); | 170 mark_object (window->subwindow_instance_cache); |
168 | 171 |
169 mark_face_cachels (window->face_cachels, markobj); | 172 mark_face_cachels (window->face_cachels); |
170 mark_glyph_cachels (window->glyph_cachels, markobj); | 173 mark_glyph_cachels (window->glyph_cachels); |
171 | 174 |
172 #define WINDOW_SLOT(slot, compare) ((void) (markobj (window->slot))) | 175 #define WINDOW_SLOT(slot, compare) mark_object (window->slot) |
173 #include "winslots.h" | 176 #include "winslots.h" |
174 | 177 |
175 return Qnil; | 178 return Qnil; |
176 } | 179 } |
177 | 180 |
704 #endif | 707 #endif |
705 | 708 |
706 int | 709 int |
707 window_truncation_on (struct window *w) | 710 window_truncation_on (struct window *w) |
708 { | 711 { |
712 /* Minibuffer windows are never truncated. | |
713 ### is this the right way ? */ | |
714 if (MINI_WINDOW_P (w)) | |
715 return 0; | |
716 | |
709 /* Horizontally scrolled windows are truncated. */ | 717 /* Horizontally scrolled windows are truncated. */ |
710 if (w->hscroll) | 718 if (w->hscroll) |
711 return 1; | 719 return 1; |
712 | 720 |
713 /* If truncate_partial_width_windows is true and the window is not | 721 /* If truncate_partial_width_windows is true and the window is not |
721 if (!NILP (XBUFFER (w->buffer)->truncate_lines)) | 729 if (!NILP (XBUFFER (w->buffer)->truncate_lines)) |
722 return 1; | 730 return 1; |
723 | 731 |
724 return 0; | 732 return 0; |
725 } | 733 } |
734 | |
735 DEFUN ("window-truncated-p", Fwindow_truncated_p, 0, 1, 0, /* | |
736 Returns Non-Nil iff the window is truncated. | |
737 */ | |
738 (window)) | |
739 { | |
740 struct window *w = decode_window (window); | |
741 | |
742 return window_truncation_on (w) ? Qt : Qnil; | |
743 } | |
744 | |
726 | 745 |
727 static int | 746 static int |
728 have_undivided_common_edge (struct window *w_right, void *closure) | 747 have_undivided_common_edge (struct window *w_right, void *closure) |
729 { | 748 { |
730 struct window *w_left = (struct window *) closure; | 749 struct window *w_left = (struct window *) closure; |
1091 return Qnil; /* happens at startup */ | 1110 return Qnil; /* happens at startup */ |
1092 | 1111 |
1093 { | 1112 { |
1094 struct frame *f = decode_frame_or_selected (con_dev_or_frame); | 1113 struct frame *f = decode_frame_or_selected (con_dev_or_frame); |
1095 return FRAME_SELECTED_WINDOW (f); | 1114 return FRAME_SELECTED_WINDOW (f); |
1115 } | |
1116 } | |
1117 | |
1118 DEFUN ("last-nonminibuf-window", Flast_nonminibuf_window, 0, 1, 0, /* | |
1119 Return the last selected window that is not a minibuffer window. | |
1120 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, | |
1121 return the last non-minibuffer window used by that frame. If | |
1122 CON-DEV-OR-FRAME is a device, then the selected frame on that device | |
1123 will be used. If CON-DEV-OR-FRAME is a console, the selected frame on | |
1124 that console's selected device will be used. Otherwise, the selected | |
1125 frame is used. | |
1126 */ | |
1127 (con_dev_or_frame)) | |
1128 { | |
1129 if (NILP (con_dev_or_frame) && NILP (Fselected_device (Qnil))) | |
1130 return Qnil; /* happens at startup */ | |
1131 | |
1132 { | |
1133 struct frame *f = decode_frame_or_selected (con_dev_or_frame); | |
1134 return FRAME_LAST_NONMINIBUF_WINDOW (f); | |
1096 } | 1135 } |
1097 } | 1136 } |
1098 | 1137 |
1099 DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /* | 1138 DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /* |
1100 Return the window used now for minibuffers. | 1139 Return the window used now for minibuffers. |
3908 #undef CURCHARSIZE | 3947 #undef CURCHARSIZE |
3909 #undef MINCHARSIZE | 3948 #undef MINCHARSIZE |
3910 | 3949 |
3911 | 3950 |
3912 | 3951 |
3913 /* Scroll contents of window WINDOW up N lines. */ | 3952 /* Scroll contents of window WINDOW up N lines. If N < (top line height / |
3953 average line height) then we just adjust the top clip. */ | |
3914 void | 3954 void |
3915 window_scroll (Lisp_Object window, Lisp_Object n, int direction, | 3955 window_scroll (Lisp_Object window, Lisp_Object n, int direction, |
3916 Error_behavior errb) | 3956 Error_behavior errb) |
3917 { | 3957 { |
3918 struct window *w = XWINDOW (window); | 3958 struct window *w = XWINDOW (window); |
3919 struct buffer *b = XBUFFER (w->buffer); | 3959 struct buffer *b = XBUFFER (w->buffer); |
3920 int selected = EQ (window, Fselected_window (Qnil)); | 3960 int selected = EQ (window, Fselected_window (Qnil)); |
3921 int value = 0; | 3961 int value = 0; |
3922 Lisp_Object point, tem; | 3962 Lisp_Object point, tem; |
3963 display_line_dynarr *dla; | |
3964 int fheight, fwidth, modeline = 0; | |
3965 struct display_line* dl; | |
3923 | 3966 |
3924 if (selected) | 3967 if (selected) |
3925 point = make_int (BUF_PT (b)); | 3968 point = make_int (BUF_PT (b)); |
3926 else | 3969 else |
3927 { | 3970 { |
3947 { | 3990 { |
3948 Fvertical_motion (make_int (-window_char_height (w, 0) / 2), | 3991 Fvertical_motion (make_int (-window_char_height (w, 0) / 2), |
3949 window, Qnil); | 3992 window, Qnil); |
3950 Fset_marker (w->start[CURRENT_DISP], point, w->buffer); | 3993 Fset_marker (w->start[CURRENT_DISP], point, w->buffer); |
3951 w->start_at_line_beg = beginning_of_line_p (b, XINT (point)); | 3994 w->start_at_line_beg = beginning_of_line_p (b, XINT (point)); |
3995 WINDOW_TEXT_TOP_CLIP (w) = 0; | |
3952 MARK_WINDOWS_CHANGED (w); | 3996 MARK_WINDOWS_CHANGED (w); |
3953 } | 3997 } |
3954 | 3998 |
3955 if (!NILP (n)) | 3999 if (!NILP (n)) |
3956 { | 4000 { |
3990 | 4034 |
3991 if (direction == 1 && !value) | 4035 if (direction == 1 && !value) |
3992 { | 4036 { |
3993 return; | 4037 return; |
3994 } | 4038 } |
3995 else if (value > 0) | 4039 |
3996 { | 4040 /* Determine parameters to test for partial line scrolling with. */ |
3997 int vtarget; | 4041 dla = window_display_lines (w, CURRENT_DISP); |
3998 Bufpos startp, old_start; | 4042 |
3999 | 4043 if (INTP (Vwindow_pixel_scroll_increment)) |
4000 old_start = marker_position (w->start[CURRENT_DISP]); | 4044 fheight = XINT (Vwindow_pixel_scroll_increment); |
4001 startp = vmotion (w, old_start, value, &vtarget); | 4045 else if (!NILP (Vwindow_pixel_scroll_increment)); |
4002 | 4046 default_face_height_and_width (window, &fheight, &fwidth); |
4003 if (vtarget < value && | 4047 |
4004 (w->window_end_pos[CURRENT_DISP] == -1 | 4048 if (Dynarr_length (dla) >= 1) |
4005 || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b)))) | 4049 modeline = Dynarr_atp (dla, 0)->modeline; |
4050 | |
4051 dl = Dynarr_atp (dla, modeline); | |
4052 | |
4053 if (value > 0) | |
4054 { | |
4055 /* Go for partial display line scrolling. This just means bumping | |
4056 the clip by a reasonable amount and redisplaying, everything else | |
4057 remains unchanged. */ | |
4058 if (!NILP (Vwindow_pixel_scroll_increment) | |
4059 && | |
4060 Dynarr_length (dla) >= (1 + modeline) | |
4061 && | |
4062 (dl->ascent - dl->top_clip) - fheight * value > 0) | |
4006 { | 4063 { |
4007 maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb); | 4064 WINDOW_TEXT_TOP_CLIP (w) += value * fheight; |
4008 return; | 4065 MARK_WINDOWS_CHANGED (w); |
4009 } | 4066 } |
4010 else | 4067 else |
4011 { | 4068 { |
4012 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), | 4069 int vtarget; |
4013 w->buffer); | 4070 Bufpos startp, old_start; |
4014 w->force_start = 1; | 4071 |
4015 w->start_at_line_beg = beginning_of_line_p (b, startp); | 4072 if (WINDOW_TEXT_TOP_CLIP (w)) |
4016 MARK_WINDOWS_CHANGED (w); | |
4017 | |
4018 if (!point_would_be_visible (w, startp, XINT (point))) | |
4019 { | 4073 { |
4020 if (selected) | 4074 WINDOW_TEXT_TOP_CLIP (w) = 0; |
4021 BUF_SET_PT (b, startp); | 4075 MARK_WINDOWS_CHANGED (w); |
4022 else | 4076 } |
4023 set_marker_restricted (w->pointm[CURRENT_DISP], | 4077 |
4024 make_int (startp), | 4078 old_start = marker_position (w->start[CURRENT_DISP]); |
4025 w->buffer); | 4079 startp = vmotion (w, old_start, value, &vtarget); |
4080 | |
4081 if (vtarget < value && | |
4082 (w->window_end_pos[CURRENT_DISP] == -1 | |
4083 || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b)))) | |
4084 { | |
4085 maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb); | |
4086 return; | |
4087 } | |
4088 else | |
4089 { | |
4090 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), | |
4091 w->buffer); | |
4092 w->force_start = 1; | |
4093 w->start_at_line_beg = beginning_of_line_p (b, startp); | |
4094 MARK_WINDOWS_CHANGED (w); | |
4095 | |
4096 if (!point_would_be_visible (w, startp, XINT (point))) | |
4097 { | |
4098 if (selected) | |
4099 BUF_SET_PT (b, startp); | |
4100 else | |
4101 set_marker_restricted (w->pointm[CURRENT_DISP], | |
4102 make_int (startp), | |
4103 w->buffer); | |
4104 } | |
4026 } | 4105 } |
4027 } | 4106 } |
4028 } | 4107 } |
4029 else if (value < 0) | 4108 else if (value < 0) |
4030 { | 4109 { |
4031 int vtarget; | 4110 /* Go for partial display line scrolling. This just means bumping |
4032 Bufpos startp, old_start; | 4111 the clip by a reasonable amount and redisplaying, everything else |
4033 | 4112 remains unchanged. */ |
4034 old_start = marker_position (w->start[CURRENT_DISP]); | 4113 if (!NILP (Vwindow_pixel_scroll_increment) |
4035 startp = vmotion (w, old_start, value, &vtarget); | 4114 && |
4036 | 4115 Dynarr_length (dla) >= (1 + modeline) |
4037 if (vtarget > value | 4116 && |
4038 && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) | 4117 (dl->ascent - dl->top_clip) - fheight * value < |
4118 (dl->ascent + dl->descent - dl->clip) | |
4119 && | |
4120 WINDOW_TEXT_TOP_CLIP (w) + value * fheight > 0) | |
4039 { | 4121 { |
4040 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); | 4122 WINDOW_TEXT_TOP_CLIP (w) += value * fheight; |
4041 return; | 4123 MARK_WINDOWS_CHANGED (w); |
4042 } | 4124 } |
4043 else | 4125 else |
4044 { | 4126 { |
4045 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), | 4127 int vtarget; |
4046 w->buffer); | 4128 Bufpos startp, old_start; |
4047 w->force_start = 1; | 4129 |
4048 w->start_at_line_beg = beginning_of_line_p (b, startp); | 4130 if (WINDOW_TEXT_TOP_CLIP (w)) |
4049 MARK_WINDOWS_CHANGED (w); | |
4050 | |
4051 if (!point_would_be_visible (w, startp, XINT (point))) | |
4052 { | 4131 { |
4053 Bufpos new_point; | 4132 WINDOW_TEXT_TOP_CLIP (w) = 0; |
4054 | 4133 MARK_WINDOWS_CHANGED (w); |
4055 if (MINI_WINDOW_P (w)) | 4134 } |
4056 new_point = startp; | 4135 |
4057 else | 4136 old_start = marker_position (w->start[CURRENT_DISP]); |
4058 new_point = start_of_last_line (w, startp); | 4137 startp = vmotion (w, old_start, value, &vtarget); |
4059 | 4138 |
4060 if (selected) | 4139 if (vtarget > value |
4061 BUF_SET_PT (b, new_point); | 4140 && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) |
4062 else | 4141 { |
4063 set_marker_restricted (w->pointm[CURRENT_DISP], | 4142 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); |
4064 make_int (new_point), | 4143 return; |
4065 w->buffer); | 4144 } |
4145 else | |
4146 { | |
4147 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), | |
4148 w->buffer); | |
4149 w->force_start = 1; | |
4150 w->start_at_line_beg = beginning_of_line_p (b, startp); | |
4151 MARK_WINDOWS_CHANGED (w); | |
4152 | |
4153 if (!point_would_be_visible (w, startp, XINT (point))) | |
4154 { | |
4155 Bufpos new_point; | |
4156 | |
4157 if (MINI_WINDOW_P (w)) | |
4158 new_point = startp; | |
4159 else | |
4160 new_point = start_of_last_line (w, startp); | |
4161 | |
4162 if (selected) | |
4163 BUF_SET_PT (b, new_point); | |
4164 else | |
4165 set_marker_restricted (w->pointm[CURRENT_DISP], | |
4166 make_int (new_point), | |
4167 w->buffer); | |
4168 } | |
4066 } | 4169 } |
4067 } | 4170 } |
4068 } | 4171 } |
4069 else /* value == 0 && direction == -1 */ | 4172 else /* value == 0 && direction == -1 */ |
4070 { | 4173 { |
4174 if (WINDOW_TEXT_TOP_CLIP (w)) | |
4175 { | |
4176 WINDOW_TEXT_TOP_CLIP (w) = 0; | |
4177 MARK_WINDOWS_CHANGED (w); | |
4178 } | |
4071 if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) | 4179 if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) |
4072 { | 4180 { |
4073 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); | 4181 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); |
4074 return; | 4182 return; |
4075 } | 4183 } |
4103 make_int (new_point), | 4211 make_int (new_point), |
4104 w->buffer); | 4212 w->buffer); |
4105 } | 4213 } |
4106 } | 4214 } |
4107 } | 4215 } |
4108 | |
4109 } | 4216 } |
4110 | 4217 |
4111 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /* | 4218 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /* |
4112 Scroll text of current window upward N lines; or near full screen if no arg. | 4219 Scroll text of current window upward N lines; or near full screen if no arg. |
4113 A near full screen is `next-screen-context-lines' less than a full screen. | 4220 A near full screen is `next-screen-context-lines' less than a full screen. |
4620 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration) | 4727 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration) |
4621 #define GC_WINDOW_CONFIGURATIONP(x) GC_RECORDP (x, window_configuration) | 4728 #define GC_WINDOW_CONFIGURATIONP(x) GC_RECORDP (x, window_configuration) |
4622 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration) | 4729 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration) |
4623 | 4730 |
4624 static Lisp_Object | 4731 static Lisp_Object |
4625 mark_window_config (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 4732 mark_window_config (Lisp_Object obj) |
4626 { | 4733 { |
4627 struct window_config *config = XWINDOW_CONFIGURATION (obj); | 4734 struct window_config *config = XWINDOW_CONFIGURATION (obj); |
4628 int i; | 4735 int i; |
4629 markobj (config->current_window); | 4736 mark_object (config->current_window); |
4630 markobj (config->current_buffer); | 4737 mark_object (config->current_buffer); |
4631 markobj (config->minibuffer_scroll_window); | 4738 mark_object (config->minibuffer_scroll_window); |
4632 markobj (config->root_window); | 4739 mark_object (config->root_window); |
4633 | 4740 |
4634 for (i = 0; i < config->saved_windows_count; i++) | 4741 for (i = 0; i < config->saved_windows_count; i++) |
4635 { | 4742 { |
4636 struct saved_window *s = SAVED_WINDOW_N (config, i); | 4743 struct saved_window *s = SAVED_WINDOW_N (config, i); |
4637 markobj (s->window); | 4744 mark_object (s->window); |
4638 markobj (s->buffer); | 4745 mark_object (s->buffer); |
4639 markobj (s->start); | 4746 mark_object (s->start); |
4640 markobj (s->pointm); | 4747 mark_object (s->pointm); |
4641 markobj (s->sb_point); | 4748 mark_object (s->sb_point); |
4642 markobj (s->mark); | 4749 mark_object (s->mark); |
4643 #if 0 | 4750 #if 0 |
4644 /* #### This looked like this. I do not see why specifier cached | 4751 /* #### This looked like this. I do not see why specifier cached |
4645 values should not be marked, as such specifiers as toolbars | 4752 values should not be marked, as such specifiers as toolbars |
4646 might have GC-able instances. Freed configs are not marked, | 4753 might have GC-able instances. Freed configs are not marked, |
4647 aren't they? -- kkm */ | 4754 aren't they? -- kkm */ |
4648 markobj (s->dedicated); | 4755 mark_object (s->dedicated); |
4649 #else | 4756 #else |
4650 #define WINDOW_SLOT(slot, compare) ((void) (markobj (s->slot))) | 4757 #define WINDOW_SLOT(slot, compare) mark_object (s->slot) |
4651 #include "winslots.h" | 4758 #include "winslots.h" |
4652 #endif | 4759 #endif |
4653 } | 4760 } |
4654 return Qnil; | 4761 return Qnil; |
4655 } | 4762 } |
5048 w->line_cache_last_updated = Qzero; | 5155 w->line_cache_last_updated = Qzero; |
5049 SET_LAST_MODIFIED (w, 1); | 5156 SET_LAST_MODIFIED (w, 1); |
5050 SET_LAST_FACECHANGE (w); | 5157 SET_LAST_FACECHANGE (w); |
5051 w->config_mark = 0; | 5158 w->config_mark = 0; |
5052 | 5159 |
5053 #define WINDOW_SLOT(slot, compare) w->slot = p->slot; | 5160 #define WINDOW_SLOT(slot, compare) w->slot = p->slot |
5054 #include "winslots.h" | 5161 #include "winslots.h" |
5055 | 5162 |
5056 /* Reinstall the saved buffer and pointers into it. */ | 5163 /* Reinstall the saved buffer and pointers into it. */ |
5057 if (NILP (p->buffer)) | 5164 if (NILP (p->buffer)) |
5058 w->buffer = p->buffer; | 5165 w->buffer = p->buffer; |
5322 WINDOW_WIDTH (p) = WINDOW_WIDTH (w); | 5429 WINDOW_WIDTH (p) = WINDOW_WIDTH (w); |
5323 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w); | 5430 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w); |
5324 p->hscroll = w->hscroll; | 5431 p->hscroll = w->hscroll; |
5325 p->modeline_hscroll = w->modeline_hscroll; | 5432 p->modeline_hscroll = w->modeline_hscroll; |
5326 | 5433 |
5327 #define WINDOW_SLOT(slot, compare) p->slot = w->slot; | 5434 #define WINDOW_SLOT(slot, compare) p->slot = w->slot |
5328 #include "winslots.h" | 5435 #include "winslots.h" |
5329 | 5436 |
5330 if (!NILP (w->buffer)) | 5437 if (!NILP (w->buffer)) |
5331 { | 5438 { |
5332 /* Save w's value of point in the window configuration. | 5439 /* Save w's value of point in the window configuration. |
5464 Fcurrent_window_configuration (Qnil)); | 5571 Fcurrent_window_configuration (Qnil)); |
5465 val = Fprogn (args); | 5572 val = Fprogn (args); |
5466 return unbind_to (speccount, val); | 5573 return unbind_to (speccount, val); |
5467 } | 5574 } |
5468 | 5575 |
5576 DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /* | |
5577 Return the horizontal pixel position of POS in window. | |
5578 Beginning of line is column 0. This is calculated using the redisplay | |
5579 display tables. If WINDOW is nil, the current window is assumed. | |
5580 If POS is nil, point is assumed. Note that POS must be visible for | |
5581 a non-nil result to be returned. | |
5582 */ | |
5583 (window, pos)) | |
5584 { | |
5585 struct window* w = decode_window (window); | |
5586 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP); | |
5587 | |
5588 struct display_line *dl = 0; | |
5589 struct display_block *db = 0; | |
5590 struct rune* rb = 0; | |
5591 int y = w->last_point_y[CURRENT_DISP]; | |
5592 int x = w->last_point_x[CURRENT_DISP]; | |
5593 | |
5594 if (MINI_WINDOW_P (w)) | |
5595 return Qnil; | |
5596 | |
5597 if (y<0 || x<0 || y >= Dynarr_length (dla) || !NILP (pos)) | |
5598 { | |
5599 int first_line, i; | |
5600 Bufpos point; | |
5601 | |
5602 if (NILP (pos)) | |
5603 pos = Fwindow_point (window); | |
5604 | |
5605 CHECK_INT (pos); | |
5606 point = XINT (pos); | |
5607 | |
5608 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline) | |
5609 first_line = 1; | |
5610 else | |
5611 first_line = 0; | |
5612 | |
5613 for (i = first_line; i < Dynarr_length (dla); i++) | |
5614 { | |
5615 dl = Dynarr_atp (dla, i); | |
5616 /* find the vertical location first */ | |
5617 if (point >= dl->bufpos && point <= dl->end_bufpos) | |
5618 { | |
5619 db = get_display_block_from_line (dl, TEXT); | |
5620 for (i = 0; i < Dynarr_length (db->runes); i++) | |
5621 { | |
5622 rb = Dynarr_atp (db->runes, i); | |
5623 if (point <= rb->bufpos) | |
5624 goto found_bufpos; | |
5625 } | |
5626 return Qnil; | |
5627 } | |
5628 } | |
5629 return Qnil; | |
5630 found_bufpos: | |
5631 ; | |
5632 } | |
5633 else | |
5634 { | |
5635 /* optimised case */ | |
5636 dl = Dynarr_atp (dla, y); | |
5637 db = get_display_block_from_line (dl, TEXT); | |
5638 | |
5639 if (x >= Dynarr_length (db->runes)) | |
5640 return Qnil; | |
5641 | |
5642 rb = Dynarr_atp (db->runes, x); | |
5643 } | |
5644 | |
5645 return make_int (rb->xpos - WINDOW_LEFT (w)); | |
5646 } | |
5647 | |
5469 | 5648 |
5470 #ifdef DEBUG_XEMACS | 5649 #ifdef DEBUG_XEMACS |
5471 /* This is short and simple in elisp, but... it was written to debug | 5650 /* This is short and simple in elisp, but... it was written to debug |
5472 problems purely on the C side. That is where we need to call it so | 5651 problems purely on the C side. That is where we need to call it so |
5473 here it is. */ | 5652 here it is. */ |
5516 syms_of_window (void) | 5695 syms_of_window (void) |
5517 { | 5696 { |
5518 defsymbol (&Qwindowp, "windowp"); | 5697 defsymbol (&Qwindowp, "windowp"); |
5519 defsymbol (&Qwindow_live_p, "window-live-p"); | 5698 defsymbol (&Qwindow_live_p, "window-live-p"); |
5520 defsymbol (&Qwindow_configurationp, "window-configuration-p"); | 5699 defsymbol (&Qwindow_configurationp, "window-configuration-p"); |
5521 defsymbol (&Qscroll_up, "scroll-up"); | |
5522 defsymbol (&Qscroll_down, "scroll-down"); | |
5523 defsymbol (&Qtemp_buffer_show_hook, "temp-buffer-show-hook"); | 5700 defsymbol (&Qtemp_buffer_show_hook, "temp-buffer-show-hook"); |
5524 defsymbol (&Qdisplay_buffer, "display-buffer"); | 5701 defsymbol (&Qdisplay_buffer, "display-buffer"); |
5525 | 5702 |
5526 #ifdef MEMORY_USAGE_STATS | 5703 #ifdef MEMORY_USAGE_STATS |
5527 defsymbol (&Qface_cache, "face-cache"); | 5704 defsymbol (&Qface_cache, "face-cache"); |
5533 defsymbol (&Qother_redisplay, "other-redisplay"); | 5710 defsymbol (&Qother_redisplay, "other-redisplay"); |
5534 /* Qother in general.c */ | 5711 /* Qother in general.c */ |
5535 #endif | 5712 #endif |
5536 | 5713 |
5537 DEFSUBR (Fselected_window); | 5714 DEFSUBR (Fselected_window); |
5715 DEFSUBR (Flast_nonminibuf_window); | |
5538 DEFSUBR (Fminibuffer_window); | 5716 DEFSUBR (Fminibuffer_window); |
5539 DEFSUBR (Fwindow_minibuffer_p); | 5717 DEFSUBR (Fwindow_minibuffer_p); |
5540 DEFSUBR (Fwindowp); | 5718 DEFSUBR (Fwindowp); |
5541 DEFSUBR (Fwindow_live_p); | 5719 DEFSUBR (Fwindow_live_p); |
5542 DEFSUBR (Fwindow_first_hchild); | 5720 DEFSUBR (Fwindow_first_hchild); |
5543 DEFSUBR (Fwindow_first_vchild); | 5721 DEFSUBR (Fwindow_first_vchild); |
5544 DEFSUBR (Fwindow_next_child); | 5722 DEFSUBR (Fwindow_next_child); |
5545 DEFSUBR (Fwindow_previous_child); | 5723 DEFSUBR (Fwindow_previous_child); |
5546 DEFSUBR (Fwindow_parent); | 5724 DEFSUBR (Fwindow_parent); |
5547 DEFSUBR (Fwindow_lowest_p); | 5725 DEFSUBR (Fwindow_lowest_p); |
5726 DEFSUBR (Fwindow_truncated_p); | |
5548 DEFSUBR (Fwindow_highest_p); | 5727 DEFSUBR (Fwindow_highest_p); |
5549 DEFSUBR (Fwindow_leftmost_p); | 5728 DEFSUBR (Fwindow_leftmost_p); |
5550 DEFSUBR (Fwindow_rightmost_p); | 5729 DEFSUBR (Fwindow_rightmost_p); |
5551 DEFSUBR (Fpos_visible_in_window_p); | 5730 DEFSUBR (Fpos_visible_in_window_p); |
5552 DEFSUBR (Fwindow_buffer); | 5731 DEFSUBR (Fwindow_buffer); |
5611 #endif | 5790 #endif |
5612 DEFSUBR (Fwindow_configuration_p); | 5791 DEFSUBR (Fwindow_configuration_p); |
5613 DEFSUBR (Fset_window_configuration); | 5792 DEFSUBR (Fset_window_configuration); |
5614 DEFSUBR (Fcurrent_window_configuration); | 5793 DEFSUBR (Fcurrent_window_configuration); |
5615 DEFSUBR (Fsave_window_excursion); | 5794 DEFSUBR (Fsave_window_excursion); |
5795 DEFSUBR (Fcurrent_pixel_column); | |
5796 } | |
5797 | |
5798 void | |
5799 reinit_vars_of_window (void) | |
5800 { | |
5801 int i; | |
5802 /* Make sure all windows get marked */ | |
5803 minibuf_window = Qnil; | |
5804 staticpro_nodump (&minibuf_window); | |
5805 | |
5806 for (i = 0; i < countof (Vwindow_configuration_free_list); i++) | |
5807 { | |
5808 Vwindow_configuration_free_list[i] = | |
5809 make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1), | |
5810 &lrecord_window_configuration); | |
5811 staticpro_nodump (&Vwindow_configuration_free_list[i]); | |
5812 } | |
5616 } | 5813 } |
5617 | 5814 |
5618 void | 5815 void |
5619 vars_of_window (void) | 5816 vars_of_window (void) |
5620 { | 5817 { |
5621 /* Make sure all windows get marked */ | 5818 reinit_vars_of_window (); |
5622 minibuf_window = Qnil; | |
5623 staticpro (&minibuf_window); | |
5624 | 5819 |
5625 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* | 5820 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* |
5626 *Non-nil means to scroll if point lands on a line which is clipped. | 5821 *Non-nil means to scroll if point lands on a line which is clipped. |
5627 */ ); | 5822 */ ); |
5628 scroll_on_clipped_lines = 1; | 5823 scroll_on_clipped_lines = 1; |
5649 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer /* | 5844 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer /* |
5650 If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. | 5845 If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. |
5651 */ ); | 5846 */ ); |
5652 Vother_window_scroll_buffer = Qnil; | 5847 Vother_window_scroll_buffer = Qnil; |
5653 | 5848 |
5849 DEFVAR_LISP ("window-pixel-scroll-increment", &Vwindow_pixel_scroll_increment /* | |
5850 *Number of pixels to scroll by per requested line. | |
5851 If nil then normal line scrolling occurs regardless of line height. | |
5852 If t then scrolling is done in increments equal to the height of the default face. | |
5853 */ ); | |
5854 Vwindow_pixel_scroll_increment = Qt; | |
5855 | |
5654 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /* | 5856 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /* |
5655 *Number of lines of continuity when scrolling by screenfuls. | 5857 *Number of lines of continuity when scrolling by screenfuls. |
5656 */ ); | 5858 */ ); |
5657 next_screen_context_lines = 2; | 5859 next_screen_context_lines = 2; |
5658 | 5860 |
5663 | 5865 |
5664 DEFVAR_INT ("window-min-width", &window_min_width /* | 5866 DEFVAR_INT ("window-min-width", &window_min_width /* |
5665 *Delete any window less than this wide. | 5867 *Delete any window less than this wide. |
5666 */ ); | 5868 */ ); |
5667 window_min_width = 10; | 5869 window_min_width = 10; |
5668 | |
5669 { | |
5670 int i; | |
5671 | |
5672 for (i = 0; i < countof (Vwindow_configuration_free_list); i++) | |
5673 { | |
5674 Vwindow_configuration_free_list[i] = | |
5675 make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1), | |
5676 &lrecord_window_configuration); | |
5677 staticpro (&Vwindow_configuration_free_list[i]); | |
5678 } | |
5679 } | |
5680 } | 5870 } |
5681 | 5871 |
5682 void | 5872 void |
5683 specifier_vars_of_window (void) | 5873 specifier_vars_of_window (void) |
5684 { | 5874 { |