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 {