This source file includes following definitions.
- CHECK_WINDOW_CONFIGURATION
- wset_combination_limit
- wset_dedicated
- wset_display_table
- wset_new_normal
- wset_new_total
- wset_normal_cols
- wset_normal_lines
- wset_parent
- wset_pointm
- wset_old_pointm
- wset_start
- wset_temslot
- wset_vertical_scroll_bar_type
- wset_window_parameters
- wset_combination
- window_outdated
- decode_live_window
- decode_any_window
- decode_valid_window
- adjust_window_count
- wset_buffer
- wset_old_buffer
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- select_window
- select_window_1
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- window_body_unit_from_symbol
- window_body_height
- window_body_width
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- set_window_hscroll
- coordinates_in_window
- window_relative_x_coord
- check_window_containing
- window_from_coordinates
- window_point
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- window_parameter
- DEFUN
- window_display_table
- unshow_buffer
- replace_window
- recombine_windows
- delete_deletable_window
- add_window_to_list
- window_list
- candidate_window_p
- decode_next_window_args
- next_window
- window_list_1
- window_loop
- check_all_windows
- resize_root_window
- window_pixel_to_total
- replace_buffer_in_windows
- replace_buffer_in_windows_safely
- run_funs
- select_window_norecord
- select_frame_norecord
- run_window_configuration_change_hook
- DEFUN
- DEFUN
- window_sub_list
- window_change_record_windows
- window_change_record
- run_window_change_functions_1
- run_window_change_functions
- set_window_buffer
- display_buffer
- DEFUN
- temp_output_buffer_show
- allocate_window
- make_parent_window
- make_window
- window_resize_check
- window_resize_apply
- window_resize_apply_total
- resize_frame_windows
- DEFUN
- resize_mini_window_apply
- grow_mini_window
- shrink_mini_window
- DEFUN
- mark_window_cursors_off
- window_wants_mode_line
- window_wants_header_line
- window_wants_tab_line
- window_internal_height
- window_scroll
- window_scroll_margin
- sanitize_next_screen_context_lines
- window_scroll_for_long_lines
- window_scroll_pixel_based
- window_scroll_line_based
- scroll_command
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- displayed_window_lines
- DEFUN
- DEFUN
- DEFUN
- restore_window_configuration
- delete_all_child_windows
- count_windows
- get_leaf_windows
- get_phys_cursor_glyph
- save_window_save
- DEFUN
- apply_window_adjustment
- extract_dimension
- set_window_margins
- DEFUN
- set_window_fringes
- DEFUN
- set_window_scroll_bars
- DEFUN
- foreach_window
- foreach_window_1
- compare_window_configurations
- init_window_once
- init_window_once_for_pdumper
- init_window
- syms_of_window
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23
24 #if 10 <= __GNUC__
25 # pragma GCC diagnostic ignored "-Wanalyzer-null-dereference"
26 #endif
27
28 #include "lisp.h"
29 #include "buffer.h"
30 #include "keyboard.h"
31 #include "keymap.h"
32 #include "frame.h"
33 #include "window.h"
34 #include "commands.h"
35 #include "indent.h"
36 #include "termchar.h"
37 #include "disptab.h"
38 #include "dispextern.h"
39 #include "blockinput.h"
40 #include "termhooks.h"
41 #include "xwidget.h"
42 #ifdef HAVE_WINDOW_SYSTEM
43 #include TERM_HEADER
44 #endif
45 #ifdef MSDOS
46 #include "msdos.h"
47 #endif
48 #include "pdumper.h"
49
50 static ptrdiff_t count_windows (struct window *);
51 static ptrdiff_t get_leaf_windows (struct window *, struct window **,
52 ptrdiff_t);
53 static void window_scroll_pixel_based (Lisp_Object, int, bool, bool);
54 static void window_scroll_line_based (Lisp_Object, int, bool, bool);
55 static void window_scroll_for_long_lines (struct window *, int, bool);
56 static void foreach_window (struct frame *,
57 bool (* fn) (struct window *, void *),
58 void *);
59 static bool foreach_window_1 (struct window *,
60 bool (* fn) (struct window *, void *),
61 void *);
62 static bool window_resize_check (struct window *, bool);
63 static void window_resize_apply (struct window *, bool);
64 static void select_window_1 (Lisp_Object, bool);
65 static void run_window_configuration_change_hook (struct frame *);
66
67 static struct window *set_window_fringes (struct window *, Lisp_Object,
68 Lisp_Object, Lisp_Object,
69 Lisp_Object);
70 static struct window *set_window_margins (struct window *, Lisp_Object,
71 Lisp_Object);
72 static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
73 Lisp_Object, Lisp_Object,
74 Lisp_Object, Lisp_Object);
75 static void apply_window_adjustment (struct window *);
76
77
78
79
80
81
82
83
84 Lisp_Object selected_window;
85
86
87
88
89 static Lisp_Object old_selected_window;
90
91
92
93
94 Lisp_Object Vwindow_list;
95
96
97 static bool window_change_record_frames;
98
99
100
101
102
103 Lisp_Object minibuf_window;
104
105
106
107 Lisp_Object minibuf_selected_window;
108
109
110 static EMACS_INT sequence_number;
111
112
113 static int window_scroll_pixel_based_preserve_x;
114 static int window_scroll_pixel_based_preserve_y;
115
116
117 static EMACS_INT window_scroll_preserve_hpos;
118 static EMACS_INT window_scroll_preserve_vpos;
119
120 static void
121 CHECK_WINDOW_CONFIGURATION (Lisp_Object x)
122 {
123 CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x);
124 }
125
126
127 static void
128 wset_combination_limit (struct window *w, Lisp_Object val)
129 {
130 w->combination_limit = val;
131 }
132
133 static void
134 wset_dedicated (struct window *w, Lisp_Object val)
135 {
136 w->dedicated = val;
137 }
138
139 static void
140 wset_display_table (struct window *w, Lisp_Object val)
141 {
142 w->display_table = val;
143 }
144
145 static void
146 wset_new_normal (struct window *w, Lisp_Object val)
147 {
148 w->new_normal = val;
149 }
150
151 static void
152 wset_new_total (struct window *w, Lisp_Object val)
153 {
154 w->new_total = val;
155 }
156
157 static void
158 wset_normal_cols (struct window *w, Lisp_Object val)
159 {
160 w->normal_cols = val;
161 }
162
163 static void
164 wset_normal_lines (struct window *w, Lisp_Object val)
165 {
166 w->normal_lines = val;
167 }
168
169 static void
170 wset_parent (struct window *w, Lisp_Object val)
171 {
172 w->parent = val;
173 }
174
175 static void
176 wset_pointm (struct window *w, Lisp_Object val)
177 {
178 w->pointm = val;
179 }
180
181 static void
182 wset_old_pointm (struct window *w, Lisp_Object val)
183 {
184 w->old_pointm = val;
185 }
186
187 static void
188 wset_start (struct window *w, Lisp_Object val)
189 {
190 w->start = val;
191 }
192
193 static void
194 wset_temslot (struct window *w, Lisp_Object val)
195 {
196 w->temslot = val;
197 }
198
199 static void
200 wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
201 {
202 w->vertical_scroll_bar_type = val;
203 }
204
205 static void
206 wset_window_parameters (struct window *w, Lisp_Object val)
207 {
208 w->window_parameters = val;
209 }
210
211 static void
212 wset_combination (struct window *w, bool horflag, Lisp_Object val)
213 {
214
215
216 eassert (!BUFFERP (w->contents) && NILP (w->start) && NILP (w->pointm));
217 w->contents = val;
218
219
220 if (!NILP (val))
221 w->horizontal = horflag;
222 }
223
224
225
226
227 bool
228 window_outdated (struct window *w)
229 {
230 struct buffer *b = XBUFFER (w->contents);
231 return (w->last_modified < BUF_MODIFF (b)
232 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b));
233 }
234
235 struct window *
236 decode_live_window (register Lisp_Object window)
237 {
238 if (NILP (window))
239 return XWINDOW (selected_window);
240
241 CHECK_LIVE_WINDOW (window);
242 return XWINDOW (window);
243 }
244
245 struct window *
246 decode_any_window (register Lisp_Object window)
247 {
248 struct window *w;
249
250 if (NILP (window))
251 return XWINDOW (selected_window);
252
253 CHECK_WINDOW (window);
254 w = XWINDOW (window);
255 return w;
256 }
257
258 static struct window *
259 decode_valid_window (register Lisp_Object window)
260 {
261 struct window *w;
262
263 if (NILP (window))
264 return XWINDOW (selected_window);
265
266 CHECK_VALID_WINDOW (window);
267 w = XWINDOW (window);
268 return w;
269 }
270
271
272
273
274 static void
275 adjust_window_count (struct window *w, int arg)
276 {
277 eassert (eabs (arg) == 1);
278 if (BUFFERP (w->contents))
279 {
280 struct buffer *b = XBUFFER (w->contents);
281
282 if (b->base_buffer)
283 b = b->base_buffer;
284 b->window_count += arg;
285 eassert (b->window_count >= 0);
286
287 w->window_end_valid = false;
288 w->base_line_pos = 0;
289 }
290 }
291
292
293
294
295 void
296 wset_buffer (struct window *w, Lisp_Object val)
297 {
298 adjust_window_count (w, -1);
299 if (BUFFERP (val))
300
301
302 eassert (MARKERP (w->start) && MARKERP (w->pointm));
303 w->contents = val;
304 adjust_window_count (w, 1);
305 }
306
307 static void
308 wset_old_buffer (struct window *w, Lisp_Object val)
309 {
310 w->old_buffer = val;
311 }
312
313 DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
314 doc: )
315 (Lisp_Object object)
316 {
317 return WINDOWP (object) ? Qt : Qnil;
318 }
319
320 DEFUN ("window-valid-p", Fwindow_valid_p, Swindow_valid_p, 1, 1, 0,
321 doc:
322
323 )
324 (Lisp_Object object)
325 {
326 return WINDOW_VALID_P (object) ? Qt : Qnil;
327 }
328
329 DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0,
330 doc:
331
332 )
333 (Lisp_Object object)
334 {
335 return WINDOW_LIVE_P (object) ? Qt : Qnil;
336 }
337
338
339 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 0, 1, 0,
340 doc:
341 )
342 (Lisp_Object window)
343 {
344 return decode_valid_window (window)->frame;
345 }
346
347 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
348 doc:
349
350
351 )
352 (Lisp_Object frame_or_window)
353 {
354 Lisp_Object window;
355
356 if (NILP (frame_or_window))
357 window = SELECTED_FRAME ()->root_window;
358 else if (WINDOW_VALID_P (frame_or_window))
359 window = XFRAME (XWINDOW (frame_or_window)->frame)->root_window;
360 else
361 {
362 CHECK_LIVE_FRAME (frame_or_window);
363 window = XFRAME (frame_or_window)->root_window;
364 }
365
366 return window;
367 }
368
369 DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
370 doc:
371 )
372 (Lisp_Object frame)
373 {
374 return FRAME_MINIBUF_WINDOW (decode_live_frame (frame));
375 }
376
377 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p,
378 Swindow_minibuffer_p, 0, 1, 0,
379 doc:
380 )
381 (Lisp_Object window)
382 {
383 return MINI_WINDOW_P (decode_valid_window (window)) ? Qt : Qnil;
384 }
385
386
387 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
388 doc:
389
390
391
392 )
393 (Lisp_Object frame_or_window)
394 {
395 Lisp_Object window;
396
397 if (NILP (frame_or_window))
398 window = SELECTED_FRAME ()->root_window;
399 else if (WINDOW_VALID_P (frame_or_window))
400 window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
401 else
402 {
403 CHECK_LIVE_FRAME (frame_or_window);
404 window = XFRAME (frame_or_window)->root_window;
405 }
406
407 while (WINDOWP (XWINDOW (window)->contents))
408 window = XWINDOW (window)->contents;
409
410 return window;
411 }
412
413 DEFUN ("frame-selected-window", Fframe_selected_window,
414 Sframe_selected_window, 0, 1, 0,
415 doc:
416
417
418
419 )
420 (Lisp_Object frame_or_window)
421 {
422 Lisp_Object window;
423
424 if (NILP (frame_or_window))
425 window = SELECTED_FRAME ()->selected_window;
426 else if (WINDOW_VALID_P (frame_or_window))
427 window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->selected_window;
428 else
429 {
430 CHECK_LIVE_FRAME (frame_or_window);
431 window = XFRAME (frame_or_window)->selected_window;
432 }
433
434 return window;
435 }
436
437 DEFUN ("frame-old-selected-window", Fframe_old_selected_window,
438 Sframe_old_selected_window, 0, 1, 0,
439 doc:
440
441
442
443 )
444 (Lisp_Object frame)
445 {
446 if (NILP (frame))
447 frame = selected_frame;
448 CHECK_LIVE_FRAME (frame);
449
450 return XFRAME (frame)->old_selected_window;
451 }
452
453 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
454 Sset_frame_selected_window, 2, 3, 0,
455 doc:
456
457
458
459
460 )
461 (Lisp_Object frame, Lisp_Object window, Lisp_Object norecord)
462 {
463 if (NILP (frame))
464 frame = selected_frame;
465
466 CHECK_LIVE_FRAME (frame);
467 CHECK_LIVE_WINDOW (window);
468
469 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
470 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
471
472 if (EQ (frame, selected_frame))
473 return Fselect_window (window, norecord);
474 else
475 {
476 fset_selected_window (XFRAME (frame), window);
477
478 return window;
479 }
480 }
481
482 DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
483 doc:
484
485
486
487 )
488 (void)
489 {
490 return selected_window;
491 }
492
493 DEFUN ("old-selected-window", Fold_selected_window,
494 Sold_selected_window, 0, 0, 0,
495 doc:
496
497 )
498 (void)
499 {
500 return old_selected_window;
501 }
502
503 EMACS_INT window_select_count;
504
505
506
507
508
509
510 static Lisp_Object
511 select_window (Lisp_Object window, Lisp_Object norecord,
512 bool inhibit_point_swap)
513 {
514 struct window *w;
515 struct frame *sf;
516 Lisp_Object frame;
517 struct frame *f;
518
519 CHECK_LIVE_WINDOW (window);
520
521 w = XWINDOW (window);
522 frame = WINDOW_FRAME (w);
523 f = XFRAME (frame);
524
525 if (FRAME_TOOLTIP_P (f))
526
527 error ("Cannot select a tooltip window");
528
529
530 f->select_mini_window_flag = false;
531
532
533 Fset_buffer (w->contents);
534
535 if (EQ (window, selected_window) && !inhibit_point_swap)
536
537
538
539 goto record_and_return;
540
541 if (NILP (norecord) || EQ (norecord, Qmark_for_redisplay))
542 {
543
544 wset_redisplay (XWINDOW (selected_window));
545 wset_redisplay (w);
546 }
547 else
548 redisplay_other_windows ();
549
550 sf = SELECTED_FRAME ();
551 if (f != sf)
552 {
553 fset_selected_window (f, window);
554
555
556
557
558 Fselect_frame (frame, norecord);
559
560 eassert (EQ (window, selected_window)
561 || (EQ (window, f->minibuffer_window)
562 && NILP (Fminibufferp (XWINDOW (window)->contents, Qt))));
563 return window;
564 }
565 else
566 fset_selected_window (sf, window);
567
568 select_window_1 (window, inhibit_point_swap);
569 bset_last_selected_window (XBUFFER (w->contents), window);
570
571 record_and_return:
572
573
574
575
576 if (NILP (norecord))
577 {
578 w->use_time = ++window_select_count;
579 record_buffer (w->contents);
580 }
581
582 return window;
583 }
584
585
586
587
588 static void
589 select_window_1 (Lisp_Object window, bool inhibit_point_swap)
590 {
591
592
593
594 if (!inhibit_point_swap)
595 {
596 struct window *ow = XWINDOW (selected_window);
597 if (BUFFERP (ow->contents))
598 set_marker_both (ow->pointm, ow->contents,
599 BUF_PT (XBUFFER (ow->contents)),
600 BUF_PT_BYTE (XBUFFER (ow->contents)));
601 }
602
603 selected_window = window;
604
605
606
607
608
609
610 set_point_from_marker (XWINDOW (window)->pointm);
611 }
612
613 DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
614 doc:
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636 )
637 (Lisp_Object window, Lisp_Object norecord)
638 {
639 return select_window (window, norecord, false);
640 }
641
642 DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
643 doc:
644
645 )
646 (Lisp_Object window)
647 {
648 struct window *w = decode_any_window (window);
649
650 return WINDOW_LEAF_P (w) ? w->contents : Qnil;
651 }
652
653 DEFUN ("window-old-buffer", Fwindow_old_buffer, Swindow_old_buffer, 0, 1, 0,
654 doc:
655
656
657
658
659
660 )
661 (Lisp_Object window)
662 {
663 struct window *w = decode_live_window (window);
664
665 return (NILP (w->old_buffer)
666
667 ? Qnil
668 : (w->change_stamp != WINDOW_XFRAME (w)->change_stamp)
669
670 ? Qt
671
672
673 : w->old_buffer);
674 }
675
676 DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
677 doc:
678
679 )
680 (Lisp_Object window)
681 {
682 return decode_valid_window (window)->parent;
683 }
684
685 DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 0, 1, 0,
686 doc:
687
688
689
690 )
691 (Lisp_Object window)
692 {
693 struct window *w = decode_valid_window (window);
694 return WINDOW_VERTICAL_COMBINATION_P (w) ? w->contents : Qnil;
695 }
696
697 DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
698 doc:
699
700
701
702 )
703 (Lisp_Object window)
704 {
705 struct window *w = decode_valid_window (window);
706 return WINDOW_HORIZONTAL_COMBINATION_P (w) ? w->contents : Qnil;
707 }
708
709 DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0,
710 doc:
711
712 )
713 (Lisp_Object window)
714 {
715 return decode_valid_window (window)->next;
716 }
717
718 DEFUN ("window-prev-sibling", Fwindow_prev_sibling, Swindow_prev_sibling, 0, 1, 0,
719 doc:
720
721 )
722 (Lisp_Object window)
723 {
724 return decode_valid_window (window)->prev;
725 }
726
727 DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
728 doc:
729
730
731
732 )
733 (Lisp_Object window)
734 {
735 struct window *w;
736
737 CHECK_VALID_WINDOW (window);
738 w = XWINDOW (window);
739 if (WINDOW_LEAF_P (w))
740 error ("Combination limit is meaningful for internal windows only");
741 return w->combination_limit;
742 }
743
744 DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
745 doc:
746
747
748
749
750 )
751 (Lisp_Object window, Lisp_Object limit)
752 {
753 struct window *w;
754
755 CHECK_VALID_WINDOW (window);
756 w = XWINDOW (window);
757 if (WINDOW_LEAF_P (w))
758 error ("Combination limit is meaningful for internal windows only");
759 wset_combination_limit (w, limit);
760 return limit;
761 }
762
763 DEFUN ("window-use-time", Fwindow_use_time, Swindow_use_time, 0, 1, 0,
764 doc:
765
766
767
768
769
770
771
772
773 )
774 (Lisp_Object window)
775 {
776 return make_fixnum (decode_live_window (window)->use_time);
777 }
778
779 DEFUN ("window-bump-use-time", Fwindow_bump_use_time,
780 Swindow_bump_use_time, 0, 1, 0,
781 doc:
782
783
784
785
786
787 )
788 (Lisp_Object window)
789 {
790 struct window *w = decode_live_window (window);
791 struct window *sw = XWINDOW (selected_window);
792
793 if (w != sw && sw->use_time == window_select_count)
794 {
795 w->use_time = window_select_count;
796 sw->use_time = ++window_select_count;
797
798 return make_fixnum (w->use_time);
799 }
800 else
801 return Qnil;
802 }
803
804 DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
805 doc:
806
807
808
809
810
811 )
812 (Lisp_Object window)
813 {
814 return make_fixnum (decode_valid_window (window)->pixel_width);
815 }
816
817 DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0,
818 doc:
819
820
821
822
823 )
824 (Lisp_Object window)
825 {
826 return make_fixnum (decode_valid_window (window)->pixel_height);
827 }
828
829 DEFUN ("window-old-pixel-width", Fwindow_old_pixel_width,
830 Swindow_old_pixel_width, 0, 1, 0,
831 doc:
832
833
834
835
836 )
837 (Lisp_Object window)
838 {
839 return (make_fixnum
840 (decode_valid_window (window)->old_pixel_width));
841 }
842
843 DEFUN ("window-old-pixel-height", Fwindow_old_pixel_height,
844 Swindow_old_pixel_height, 0, 1, 0,
845 doc:
846
847
848
849
850 )
851 (Lisp_Object window)
852 {
853 return (make_fixnum
854 (decode_valid_window (window)->old_pixel_height));
855 }
856
857 DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0,
858 doc:
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876 )
877 (Lisp_Object window, Lisp_Object round)
878 {
879 struct window *w = decode_valid_window (window);
880
881 if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
882 return make_fixnum (w->total_lines);
883 else
884 {
885 int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
886
887 return make_fixnum (EQ (round, Qceiling)
888 ? ((w->pixel_height + unit - 1) /unit)
889 : (w->pixel_height / unit));
890 }
891 }
892
893 DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 2, 0,
894 doc:
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913 )
914 (Lisp_Object window, Lisp_Object round)
915 {
916 struct window *w = decode_valid_window (window);
917
918 if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
919 return make_fixnum (w->total_cols);
920 else
921 {
922 int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
923
924 return make_fixnum (EQ (round, Qceiling)
925 ? ((w->pixel_width + unit - 1) /unit)
926 : (w->pixel_width / unit));
927 }
928 }
929
930 DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
931 doc:
932
933
934
935
936
937 )
938 (Lisp_Object window)
939 {
940 return decode_valid_window (window)->new_total;
941 }
942
943 DEFUN ("window-normal-size", Fwindow_normal_size, Swindow_normal_size, 0, 2, 0,
944 doc:
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964 )
965 (Lisp_Object window, Lisp_Object horizontal)
966 {
967 struct window *w = decode_valid_window (window);
968
969 return NILP (horizontal) ? w->normal_lines : w->normal_cols;
970 }
971
972 DEFUN ("window-new-normal", Fwindow_new_normal, Swindow_new_normal, 0, 1, 0,
973 doc:
974
975
976
977
978 )
979 (Lisp_Object window)
980 {
981 return decode_valid_window (window)->new_normal;
982 }
983
984 DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
985 doc:
986
987
988
989
990
991 )
992 (Lisp_Object window)
993 {
994 return decode_valid_window (window)->new_pixel;
995 }
996
997 DEFUN ("window-pixel-left", Fwindow_pixel_left, Swindow_pixel_left, 0, 1, 0,
998 doc:
999 )
1000 (Lisp_Object window)
1001 {
1002 return make_fixnum (decode_valid_window (window)->pixel_left);
1003 }
1004
1005 DEFUN ("window-pixel-top", Fwindow_pixel_top, Swindow_pixel_top, 0, 1, 0,
1006 doc:
1007 )
1008 (Lisp_Object window)
1009 {
1010 return make_fixnum (decode_valid_window (window)->pixel_top);
1011 }
1012
1013 DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
1014 doc:
1015
1016
1017
1018
1019 )
1020 (Lisp_Object window)
1021 {
1022 return make_fixnum (decode_valid_window (window)->left_col);
1023 }
1024
1025 DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
1026 doc:
1027
1028
1029
1030
1031 )
1032 (Lisp_Object window)
1033 {
1034 return make_fixnum (decode_valid_window (window)->top_line);
1035 }
1036
1037 static enum window_body_unit
1038 window_body_unit_from_symbol (Lisp_Object unit)
1039 {
1040 return
1041 EQ (unit, Qremap)
1042 ? WINDOW_BODY_IN_REMAPPED_CHARS
1043 : (NILP (unit)
1044 ? WINDOW_BODY_IN_CANONICAL_CHARS
1045 : WINDOW_BODY_IN_PIXELS);
1046 }
1047
1048
1049
1050
1051 int
1052 window_body_height (struct window *w, enum window_body_unit pixelwise)
1053 {
1054 int height = (w->pixel_height
1055 - WINDOW_TAB_LINE_HEIGHT (w)
1056 - WINDOW_HEADER_LINE_HEIGHT (w)
1057 - (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
1058 ? WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
1059 : 0)
1060 - WINDOW_MODE_LINE_HEIGHT (w)
1061 - WINDOW_BOTTOM_DIVIDER_WIDTH (w));
1062
1063 int denom = 1;
1064 if (pixelwise == WINDOW_BODY_IN_REMAPPED_CHARS)
1065 {
1066 if (!NILP (Vface_remapping_alist))
1067 {
1068 struct frame *f = XFRAME (WINDOW_FRAME (w));
1069 int face_id = lookup_named_face (NULL, f, Qdefault, true);
1070 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1071 if (face && face->font && face->font->height)
1072 denom = face->font->height;
1073 }
1074
1075 else
1076 pixelwise = WINDOW_BODY_IN_CANONICAL_CHARS;
1077 }
1078
1079 if (pixelwise == WINDOW_BODY_IN_CANONICAL_CHARS)
1080 denom = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
1081
1082
1083 return max (height / denom, 0);
1084 }
1085
1086
1087
1088
1089
1090
1091 int
1092 window_body_width (struct window *w, enum window_body_unit pixelwise)
1093 {
1094 struct frame *f = XFRAME (WINDOW_FRAME (w));
1095
1096 int width = (w->pixel_width
1097 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1098 - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
1099 ? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
1100 : (
1101 !FRAME_WINDOW_P (f)
1102 && !WINDOW_RIGHTMOST_P (w)
1103 && !WINDOW_RIGHT_DIVIDER_WIDTH (w)))
1104 - WINDOW_MARGINS_WIDTH (w)
1105 - (FRAME_WINDOW_P (f)
1106 ? WINDOW_FRINGES_WIDTH (w)
1107 : 0));
1108
1109 int denom = 1;
1110 if (pixelwise == WINDOW_BODY_IN_REMAPPED_CHARS)
1111 {
1112 if (!NILP (Vface_remapping_alist))
1113 {
1114 int face_id = lookup_named_face (NULL, f, Qdefault, true);
1115 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1116 if (face && face->font)
1117 {
1118 if (face->font->average_width)
1119 denom = face->font->average_width;
1120 else if (face->font->space_width)
1121 denom = face->font->space_width;
1122 }
1123 }
1124
1125 else
1126 pixelwise = WINDOW_BODY_IN_CANONICAL_CHARS;
1127 }
1128
1129 if (pixelwise == WINDOW_BODY_IN_CANONICAL_CHARS)
1130 denom = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
1131
1132
1133 return max (width / denom, 0);
1134 }
1135
1136 DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0,
1137 doc:
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153 )
1154 (Lisp_Object window, Lisp_Object pixelwise)
1155 {
1156 return (make_fixnum
1157 (window_body_width (decode_live_window (window),
1158 window_body_unit_from_symbol (pixelwise))));
1159 }
1160
1161 DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0,
1162 doc:
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 )
1174 (Lisp_Object window, Lisp_Object pixelwise)
1175 {
1176 return (make_fixnum
1177 (window_body_height (decode_live_window (window),
1178 window_body_unit_from_symbol (pixelwise))));
1179 }
1180
1181 DEFUN ("window-old-body-pixel-width",
1182 Fwindow_old_body_pixel_width,
1183 Swindow_old_body_pixel_width, 0, 1, 0,
1184 doc:
1185
1186
1187
1188
1189 )
1190 (Lisp_Object window)
1191 {
1192 return (make_fixnum
1193 (decode_live_window (window)->old_body_pixel_width));
1194 }
1195
1196 DEFUN ("window-old-body-pixel-height",
1197 Fwindow_old_body_pixel_height,
1198 Swindow_old_body_pixel_height, 0, 1, 0,
1199 doc:
1200
1201
1202
1203
1204 )
1205 (Lisp_Object window)
1206 {
1207 return (make_fixnum
1208 (decode_live_window (window)->old_body_pixel_height));
1209 }
1210
1211 DEFUN ("window-mode-line-height", Fwindow_mode_line_height,
1212 Swindow_mode_line_height, 0, 1, 0,
1213 doc:
1214 )
1215 (Lisp_Object window)
1216 {
1217 return make_fixnum (WINDOW_MODE_LINE_HEIGHT (decode_live_window (window)));
1218 }
1219
1220 DEFUN ("window-header-line-height", Fwindow_header_line_height,
1221 Swindow_header_line_height, 0, 1, 0,
1222 doc:
1223 )
1224 (Lisp_Object window)
1225 {
1226 return make_fixnum (WINDOW_HEADER_LINE_HEIGHT (decode_live_window (window)));
1227 }
1228
1229 DEFUN ("window-tab-line-height", Fwindow_tab_line_height,
1230 Swindow_tab_line_height, 0, 1, 0,
1231 doc:
1232 )
1233 (Lisp_Object window)
1234 {
1235 return make_fixnum (WINDOW_TAB_LINE_HEIGHT (decode_live_window (window)));
1236 }
1237
1238 DEFUN ("window-right-divider-width", Fwindow_right_divider_width,
1239 Swindow_right_divider_width, 0, 1, 0,
1240 doc:
1241 )
1242 (Lisp_Object window)
1243 {
1244 return make_fixnum (WINDOW_RIGHT_DIVIDER_WIDTH (decode_live_window (window)));
1245 }
1246
1247 DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width,
1248 Swindow_bottom_divider_width, 0, 1, 0,
1249 doc:
1250 )
1251 (Lisp_Object window)
1252 {
1253 return make_fixnum (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window)));
1254 }
1255
1256 DEFUN ("window-scroll-bar-width", Fwindow_scroll_bar_width,
1257 Swindow_scroll_bar_width, 0, 1, 0,
1258 doc:
1259 )
1260 (Lisp_Object window)
1261 {
1262 return make_fixnum (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window)));
1263 }
1264
1265 DEFUN ("window-scroll-bar-height", Fwindow_scroll_bar_height,
1266 Swindow_scroll_bar_height, 0, 1, 0,
1267 doc:
1268 )
1269 (Lisp_Object window)
1270 {
1271 return make_fixnum (WINDOW_SCROLL_BAR_AREA_HEIGHT (decode_live_window (window)));
1272 }
1273
1274 DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
1275 doc:
1276 )
1277 (Lisp_Object window)
1278 {
1279 return make_fixnum (decode_live_window (window)->hscroll);
1280 }
1281
1282
1283
1284 static Lisp_Object
1285 set_window_hscroll (struct window *w, EMACS_INT hscroll)
1286 {
1287
1288
1289
1290
1291
1292
1293 ptrdiff_t hscroll_max = min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX);
1294 ptrdiff_t new_hscroll = clip_to_bounds (0, hscroll, hscroll_max);
1295
1296
1297 if (w->hscroll != new_hscroll)
1298 {
1299 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true;
1300 wset_redisplay (w);
1301 }
1302
1303 w->hscroll = new_hscroll;
1304 w->suspend_auto_hscroll = true;
1305
1306 return make_fixnum (new_hscroll);
1307 }
1308
1309 DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
1310 doc:
1311
1312
1313
1314
1315
1316 )
1317 (Lisp_Object window, Lisp_Object ncol)
1318 {
1319 CHECK_FIXNUM (ncol);
1320 return set_window_hscroll (decode_live_window (window), XFIXNUM (ncol));
1321 }
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343 static enum window_part
1344 coordinates_in_window (register struct window *w, int x, int y)
1345 {
1346 struct frame *f = XFRAME (WINDOW_FRAME (w));
1347 enum window_part part;
1348 int ux = FRAME_COLUMN_WIDTH (f);
1349 int left_x = WINDOW_LEFT_EDGE_X (w);
1350 int right_x = WINDOW_RIGHT_EDGE_X (w);
1351 int top_y = WINDOW_TOP_EDGE_Y (w);
1352 int bottom_y = WINDOW_BOTTOM_EDGE_Y (w);
1353
1354
1355 int grabbable_width = ux;
1356 int lmargin_width, rmargin_width, text_left, text_right;
1357
1358
1359 if (y < top_y || y >= bottom_y || x < left_x || x >= right_x)
1360 return ON_NOTHING;
1361
1362
1363
1364 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w) > 0
1365 && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1366 && y <= bottom_y)
1367 return ON_BOTTOM_DIVIDER;
1368
1369 else if (!WINDOW_RIGHTMOST_P (w)
1370 && WINDOW_RIGHT_DIVIDER_WIDTH (w) > 0
1371 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1372 && x <= right_x)
1373 return ON_RIGHT_DIVIDER;
1374
1375
1376 else if ((WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
1377 && y >= (bottom_y
1378 - WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
1379 - CURRENT_MODE_LINE_HEIGHT (w)
1380 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1381 && y <= (bottom_y
1382 - CURRENT_MODE_LINE_HEIGHT (w)
1383 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))))
1384 return ON_HORIZONTAL_SCROLL_BAR;
1385
1386 else if ((window_wants_mode_line (w)
1387 && y >= (bottom_y
1388 - CURRENT_MODE_LINE_HEIGHT (w)
1389 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1390 && y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1391 && (part = ON_MODE_LINE))
1392 || (window_wants_tab_line (w)
1393 && y < top_y + CURRENT_TAB_LINE_HEIGHT (w)
1394 && (part = ON_TAB_LINE))
1395 || (window_wants_header_line (w)
1396 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
1397 + (window_wants_tab_line (w)
1398 ? CURRENT_TAB_LINE_HEIGHT (w)
1399 : 0)
1400 && (part = ON_HEADER_LINE)))
1401 {
1402
1403
1404
1405
1406
1407 if ((WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0)
1408 && ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
1409 && !WINDOW_LEFTMOST_P (w)
1410 && eabs (x - left_x) < grabbable_width)
1411 || (!WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
1412 && !WINDOW_RIGHTMOST_P (w)
1413 && eabs (x - right_x) < grabbable_width)))
1414 return ON_VERTICAL_BORDER;
1415 else
1416 return part;
1417 }
1418
1419
1420
1421 if (w->pseudo_window_p)
1422 {
1423 left_x = 0;
1424 right_x = WINDOW_PIXEL_WIDTH (w) - 1;
1425 }
1426 else
1427 {
1428 left_x = WINDOW_BOX_LEFT_EDGE_X (w);
1429 right_x = WINDOW_BOX_RIGHT_EDGE_X (w) - 1;
1430 }
1431
1432
1433 if (x < left_x || x > right_x)
1434 return ON_VERTICAL_SCROLL_BAR;
1435
1436 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
1437 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
1438
1439 text_left = window_box_left (w, TEXT_AREA);
1440 text_right = text_left + window_box_width (w, TEXT_AREA);
1441
1442 if (FRAME_WINDOW_P (f))
1443 {
1444 if (!w->pseudo_window_p
1445 && WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
1446 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
1447 && !WINDOW_RIGHTMOST_P (w)
1448 && (eabs (x - right_x) < grabbable_width))
1449 return ON_VERTICAL_BORDER;
1450 }
1451
1452
1453 else if (!w->pseudo_window_p
1454 && WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
1455 && !WINDOW_RIGHTMOST_P (w)
1456
1457
1458 && x > right_x - ux)
1459 return ON_VERTICAL_BORDER;
1460
1461 if (x < text_left)
1462 {
1463 if (lmargin_width > 0
1464 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1465 ? (x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w))
1466 : (x < left_x + lmargin_width)))
1467 return ON_LEFT_MARGIN;
1468 else
1469 return ON_LEFT_FRINGE;
1470 }
1471
1472 if (x >= text_right)
1473 {
1474 if (rmargin_width > 0
1475 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1476 ? (x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w))
1477 : (x >= right_x - rmargin_width)))
1478 return ON_RIGHT_MARGIN;
1479 else
1480 return ON_RIGHT_FRINGE;
1481 }
1482
1483
1484 return ON_TEXT;
1485 }
1486
1487
1488
1489 int
1490 window_relative_x_coord (struct window *w, enum window_part part, int x)
1491 {
1492 int left_x = (w->pseudo_window_p) ? 0 : WINDOW_BOX_LEFT_EDGE_X (w);
1493
1494 switch (part)
1495 {
1496 case ON_TEXT:
1497 return x - window_box_left (w, TEXT_AREA);
1498
1499 case ON_TAB_LINE:
1500 case ON_HEADER_LINE:
1501 case ON_MODE_LINE:
1502 case ON_LEFT_FRINGE:
1503 return x - left_x;
1504
1505 case ON_RIGHT_FRINGE:
1506 return x - left_x - WINDOW_LEFT_FRINGE_WIDTH (w);
1507
1508 case ON_LEFT_MARGIN:
1509 return (x - left_x
1510 - ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1511 ? WINDOW_LEFT_FRINGE_WIDTH (w) : 0));
1512
1513 case ON_RIGHT_MARGIN:
1514 return (x + 1
1515 - ((w->pseudo_window_p)
1516 ? WINDOW_PIXEL_WIDTH (w)
1517 : WINDOW_BOX_RIGHT_EDGE_X (w))
1518 + window_box_width (w, RIGHT_MARGIN_AREA)
1519 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1520 ? WINDOW_RIGHT_FRINGE_WIDTH (w) : 0));
1521
1522 case ON_NOTHING:
1523 case ON_VERTICAL_BORDER:
1524 case ON_VERTICAL_SCROLL_BAR:
1525 case ON_HORIZONTAL_SCROLL_BAR:
1526 case ON_RIGHT_DIVIDER:
1527 case ON_BOTTOM_DIVIDER:
1528 return 0;
1529
1530 default:
1531 emacs_abort ();
1532 }
1533 }
1534
1535
1536 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
1537 Scoordinates_in_window_p, 2, 2, 0,
1538 doc:
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556 )
1557 (register Lisp_Object coordinates, Lisp_Object window)
1558 {
1559 struct window *w;
1560 struct frame *f;
1561 int x, y;
1562 Lisp_Object lx, ly;
1563
1564 w = decode_live_window (window);
1565 f = XFRAME (w->frame);
1566 CHECK_CONS (coordinates);
1567 lx = Fcar (coordinates);
1568 ly = Fcdr (coordinates);
1569 CHECK_NUMBER (lx);
1570 CHECK_NUMBER (ly);
1571 x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f);
1572 y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f);
1573
1574 switch (coordinates_in_window (w, x, y))
1575 {
1576 case ON_NOTHING:
1577 return Qnil;
1578
1579 case ON_TEXT:
1580
1581
1582 x -= window_box_left (w, TEXT_AREA);
1583 y -= WINDOW_TOP_EDGE_Y (w);
1584 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f, x),
1585 FRAME_CANON_Y_FROM_PIXEL_Y (f, y));
1586
1587 case ON_MODE_LINE:
1588 return Qmode_line;
1589
1590 case ON_VERTICAL_BORDER:
1591 return Qvertical_line;
1592
1593 case ON_HEADER_LINE:
1594 return Qheader_line;
1595
1596 case ON_TAB_LINE:
1597 return Qtab_line;
1598
1599 case ON_LEFT_FRINGE:
1600 return Qleft_fringe;
1601
1602 case ON_RIGHT_FRINGE:
1603 return Qright_fringe;
1604
1605 case ON_LEFT_MARGIN:
1606 return Qleft_margin;
1607
1608 case ON_RIGHT_MARGIN:
1609 return Qright_margin;
1610
1611 case ON_VERTICAL_SCROLL_BAR:
1612
1613 return Qnil;
1614
1615 case ON_HORIZONTAL_SCROLL_BAR:
1616 return Qnil;
1617
1618 case ON_RIGHT_DIVIDER:
1619 return Qright_divider;
1620
1621 case ON_BOTTOM_DIVIDER:
1622 return Qbottom_divider;
1623
1624 default:
1625 emacs_abort ();
1626 }
1627 }
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639 struct check_window_data
1640 {
1641 Lisp_Object *window;
1642 int x, y;
1643 enum window_part *part;
1644 };
1645
1646 static bool
1647 check_window_containing (struct window *w, void *user_data)
1648 {
1649 struct check_window_data *cw = user_data;
1650 enum window_part found = coordinates_in_window (w, cw->x, cw->y);
1651 if (found == ON_NOTHING)
1652 return true;
1653 else
1654 {
1655 *cw->part = found;
1656 XSETWINDOW (*cw->window, w);
1657 return false;
1658 }
1659 }
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681 Lisp_Object
1682 window_from_coordinates (struct frame *f, int x, int y,
1683 enum window_part *part, bool tab_bar_p, bool tool_bar_p)
1684 {
1685 Lisp_Object window;
1686 struct check_window_data cw;
1687 enum window_part dummy;
1688
1689 if (part == 0)
1690 part = &dummy;
1691
1692 window = Qnil;
1693 cw.window = &window, cw.x = x, cw.y = y; cw.part = part;
1694 foreach_window (f, check_window_containing, &cw);
1695
1696 #if defined (HAVE_WINDOW_SYSTEM)
1697
1698
1699 if (NILP (window)
1700 && tab_bar_p
1701 && WINDOWP (f->tab_bar_window)
1702 && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)) > 0
1703 && (coordinates_in_window (XWINDOW (f->tab_bar_window), x, y)
1704 != ON_NOTHING))
1705 {
1706 *part = ON_TEXT;
1707 window = f->tab_bar_window;
1708 }
1709 #endif
1710
1711 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
1712
1713
1714 if (NILP (window)
1715 && tool_bar_p
1716 && WINDOWP (f->tool_bar_window)
1717 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0
1718 && (coordinates_in_window (XWINDOW (f->tool_bar_window), x, y)
1719 != ON_NOTHING))
1720 {
1721 *part = ON_TEXT;
1722 window = f->tool_bar_window;
1723 }
1724 #endif
1725
1726 return window;
1727 }
1728
1729 DEFUN ("window-at", Fwindow_at, Swindow_at, 2, 3, 0,
1730 doc:
1731
1732
1733
1734
1735
1736 )
1737 (Lisp_Object x, Lisp_Object y, Lisp_Object frame)
1738 {
1739 struct frame *f = decode_live_frame (frame);
1740
1741 CHECK_NUMBER (x);
1742 CHECK_NUMBER (y);
1743
1744 return window_from_coordinates (f,
1745 (FRAME_PIXEL_X_FROM_CANON_X (f, x)
1746 + FRAME_INTERNAL_BORDER_WIDTH (f)),
1747 (FRAME_PIXEL_Y_FROM_CANON_Y (f, y)
1748 + FRAME_INTERNAL_BORDER_WIDTH (f)),
1749 0, false, false);
1750 }
1751
1752 ptrdiff_t
1753 window_point (struct window *w)
1754 {
1755 return (w == XWINDOW (selected_window)
1756 ? BUF_PT (XBUFFER (w->contents))
1757 : XMARKER (w->pointm)->charpos);
1758 }
1759
1760 DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0,
1761 doc:
1762
1763
1764
1765
1766
1767
1768
1769
1770 )
1771 (Lisp_Object window)
1772 {
1773 return make_fixnum (window_point (decode_live_window (window)));
1774 }
1775
1776 DEFUN ("window-old-point", Fwindow_old_point, Swindow_old_point, 0, 1, 0,
1777 doc:
1778 )
1779 (Lisp_Object window)
1780 {
1781 return Fmarker_position (decode_live_window (window)->old_pointm);
1782 }
1783
1784 DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
1785 doc:
1786
1787 )
1788 (Lisp_Object window)
1789 {
1790 return Fmarker_position (decode_live_window (window)->start);
1791 }
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804 DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 2, 0,
1805 doc:
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815 )
1816 (Lisp_Object window, Lisp_Object update)
1817 {
1818 Lisp_Object value;
1819 struct window *w = decode_live_window (window);
1820 Lisp_Object buf;
1821 struct buffer *b;
1822
1823 buf = w->contents;
1824 CHECK_BUFFER (buf);
1825 b = XBUFFER (buf);
1826
1827 if (! NILP (update)
1828 && (windows_or_buffers_changed
1829 || !w->window_end_valid
1830 || b->clip_changed
1831 || b->prevent_redisplay_optimizations_p
1832 || window_outdated (w))
1833
1834
1835
1836
1837 && !(noninteractive || FRAME_INITIAL_P (WINDOW_XFRAME (w))))
1838 {
1839 struct text_pos startp;
1840 struct it it;
1841 struct buffer *old_buffer = NULL;
1842 void *itdata = NULL;
1843
1844
1845
1846 if (b != current_buffer)
1847 {
1848 old_buffer = current_buffer;
1849 set_buffer_internal (b);
1850 }
1851
1852
1853
1854
1855
1856
1857 CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
1858
1859 itdata = bidi_shelve_cache ();
1860 start_display (&it, w, startp);
1861 move_it_vertically (&it, window_box_height (w));
1862 if (it.current_y < it.last_visible_y)
1863 move_it_past_eol (&it);
1864 value = make_fixnum (IT_CHARPOS (it));
1865 bidi_unshelve_cache (itdata, false);
1866
1867 if (old_buffer)
1868 set_buffer_internal (old_buffer);
1869 }
1870 else
1871 XSETINT (value, BUF_Z (b) - w->window_end_pos);
1872
1873 return value;
1874 }
1875
1876 DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0,
1877 doc:
1878
1879 )
1880 (Lisp_Object window, Lisp_Object pos)
1881 {
1882 register struct window *w = decode_live_window (window);
1883
1884
1885
1886 if (w == XWINDOW (selected_window))
1887 {
1888 if (XBUFFER (w->contents) == current_buffer)
1889 Fgoto_char (pos);
1890 else
1891 {
1892 struct buffer *old_buffer = current_buffer;
1893
1894
1895 CHECK_FIXNUM_COERCE_MARKER (pos);
1896 set_buffer_internal (XBUFFER (w->contents));
1897 Fgoto_char (pos);
1898 set_buffer_internal (old_buffer);
1899 }
1900 }
1901 else
1902 {
1903 set_marker_restricted (w->pointm, pos, w->contents);
1904
1905
1906 wset_redisplay (w);
1907 }
1908
1909 return pos;
1910 }
1911
1912 DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
1913 doc:
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932 )
1933 (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce)
1934 {
1935 register struct window *w = decode_live_window (window);
1936
1937 set_marker_restricted (w->start, pos, w->contents);
1938
1939 w->start_at_line_beg = false;
1940 if (NILP (noforce))
1941 w->force_start = true;
1942 wset_update_mode_line (w);
1943
1944 w->window_end_valid = false;
1945 wset_redisplay (w);
1946
1947 return pos;
1948 }
1949
1950 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
1951 Spos_visible_in_window_p, 0, 3, 0,
1952 doc:
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971 )
1972 (Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
1973 {
1974 struct window *w;
1975 EMACS_INT posint;
1976 struct buffer *buf;
1977 struct text_pos top;
1978 Lisp_Object in_window = Qnil;
1979 int rtop, rbot, rowh, vpos;
1980 bool fully_p = true;
1981 int x, y;
1982
1983 w = decode_live_window (window);
1984 buf = XBUFFER (w->contents);
1985 SET_TEXT_POS_FROM_MARKER (top, w->start);
1986
1987 if (EQ (pos, Qt))
1988 posint = -1;
1989 else if (!NILP (pos))
1990 posint = fix_position (pos);
1991 else if (w == XWINDOW (selected_window))
1992 posint = PT;
1993 else
1994 posint = marker_position (w->pointm);
1995
1996
1997
1998 if ((EQ (pos, Qt)
1999 || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf)))
2000 && CHARPOS (top) >= BUF_BEGV (buf)
2001 && CHARPOS (top) <= BUF_ZV (buf)
2002 && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos))
2003 {
2004 fully_p = !rtop && !rbot;
2005 if (!NILP (partially) || fully_p)
2006 in_window = Qt;
2007 }
2008
2009 if (!NILP (in_window) && !NILP (partially))
2010 {
2011 Lisp_Object part = Qnil;
2012 if (!fully_p)
2013 part = list4i (rtop, rbot, rowh, vpos);
2014 in_window = Fcons (make_fixnum (x),
2015 Fcons (make_fixnum (y), part));
2016 }
2017
2018 return in_window;
2019 }
2020
2021 DEFUN ("window-line-height", Fwindow_line_height,
2022 Swindow_line_height, 0, 2, 0,
2023 doc:
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039 )
2040 (Lisp_Object line, Lisp_Object window)
2041 {
2042 register struct window *w;
2043 register struct buffer *b;
2044 struct glyph_row *row, *end_row;
2045 int max_y, crop, i;
2046 EMACS_INT n;
2047
2048 w = decode_live_window (window);
2049
2050 if (noninteractive || w->pseudo_window_p)
2051 return Qnil;
2052
2053 CHECK_BUFFER (w->contents);
2054 b = XBUFFER (w->contents);
2055
2056
2057 if (!w->window_end_valid
2058 || windows_or_buffers_changed
2059 || b->clip_changed
2060 || b->prevent_redisplay_optimizations_p
2061 || window_outdated (w))
2062 return Qnil;
2063
2064 if (NILP (line))
2065 {
2066 i = w->cursor.vpos;
2067 if (i < 0 || i >= w->current_matrix->nrows
2068 || (row = MATRIX_ROW (w->current_matrix, i), !row->enabled_p))
2069 return Qnil;
2070 max_y = window_text_bottom_y (w);
2071 goto found_row;
2072 }
2073
2074 if (EQ (line, Qtab_line))
2075 {
2076 if (!window_wants_tab_line (w))
2077 return Qnil;
2078 row = MATRIX_TAB_LINE_ROW (w->current_matrix);
2079 return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
2080 }
2081
2082 if (EQ (line, Qheader_line))
2083 {
2084 if (!window_wants_header_line (w))
2085 return Qnil;
2086 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
2087 return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
2088 }
2089
2090 if (EQ (line, Qmode_line))
2091 {
2092 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
2093 return (row->enabled_p ?
2094 list4i (row->height,
2095 0,
2096 (WINDOW_TAB_LINE_HEIGHT (w)
2097 + WINDOW_HEADER_LINE_HEIGHT (w)
2098 + window_text_bottom_y (w)),
2099 0)
2100 : Qnil);
2101 }
2102
2103 CHECK_FIXNUM (line);
2104 n = XFIXNUM (line);
2105
2106 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2107 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2108 max_y = window_text_bottom_y (w);
2109 i = 0;
2110
2111 while ((n < 0 || i < n)
2112 && row <= end_row && row->enabled_p
2113 && row->y + row->height < max_y)
2114 row++, i++;
2115
2116 if (row > end_row || !row->enabled_p)
2117 return Qnil;
2118
2119 if (++n < 0)
2120 {
2121 if (-n > i)
2122 return Qnil;
2123 row += n;
2124 i += n;
2125 }
2126
2127 found_row:
2128 crop = max (0, (row->y + row->height) - max_y);
2129 return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
2130 }
2131
2132 DEFUN ("window-lines-pixel-dimensions", Fwindow_lines_pixel_dimensions, Swindow_lines_pixel_dimensions, 0, 6, 0,
2133 doc:
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174 )
2175 (Lisp_Object window, Lisp_Object first, Lisp_Object last, Lisp_Object body, Lisp_Object inverse, Lisp_Object left)
2176 {
2177 struct window *w = decode_live_window (window);
2178 struct buffer *b;
2179 struct glyph_row *row, *end_row;
2180 int max_y = NILP (body) ? WINDOW_PIXEL_HEIGHT (w) : window_text_bottom_y (w);
2181 Lisp_Object rows = Qnil;
2182 int window_width = NILP (body)
2183 ? w->pixel_width : window_body_width (w, WINDOW_BODY_IN_PIXELS);
2184 int tab_line_height = WINDOW_TAB_LINE_HEIGHT (w);
2185 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
2186 int subtract = NILP (body) ? 0 : (tab_line_height + header_line_height);
2187 bool invert = !NILP (inverse);
2188 bool left_flag = !NILP (left);
2189
2190 if (noninteractive || w->pseudo_window_p)
2191 return Qnil;
2192
2193 CHECK_BUFFER (w->contents);
2194 b = XBUFFER (w->contents);
2195
2196
2197 if (!w->window_end_valid
2198 || windows_or_buffers_changed
2199 || b->clip_changed
2200 || b->prevent_redisplay_optimizations_p
2201 || window_outdated (w))
2202 return Qnil;
2203
2204 row = (!NILP (first)
2205 ? MATRIX_ROW (w->current_matrix,
2206 check_integer_range (first, 0,
2207 w->current_matrix->nrows))
2208 : NILP (body)
2209 ? MATRIX_ROW (w->current_matrix, 0)
2210 : MATRIX_FIRST_TEXT_ROW (w->current_matrix));
2211 end_row = (!NILP (last)
2212 ? MATRIX_ROW (w->current_matrix,
2213 check_integer_range (last, 0,
2214 w->current_matrix->nrows))
2215 : NILP (body)
2216 ? MATRIX_ROW (w->current_matrix, w->current_matrix->nrows)
2217 : MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w));
2218
2219 while (row <= end_row && row->enabled_p
2220 && row->y + row->height < max_y)
2221 {
2222
2223 if (left_flag)
2224 {
2225 struct glyph *glyph = row->glyphs[TEXT_AREA];
2226
2227 rows = Fcons (Fcons (make_fixnum
2228 (invert
2229 ? glyph->pixel_width
2230 : window_width - glyph->pixel_width),
2231 make_fixnum (row->y + row->height - subtract)),
2232 rows);
2233 }
2234 else
2235 rows = Fcons (Fcons (make_fixnum
2236 (invert
2237 ? window_width - row->pixel_width
2238 : row->pixel_width),
2239 make_fixnum (row->y + row->height - subtract)),
2240 rows);
2241 row++;
2242 }
2243
2244 return Fnreverse (rows);
2245 }
2246
2247 DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
2248 0, 1, 0,
2249 doc:
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264 )
2265 (Lisp_Object window)
2266 {
2267 return decode_live_window (window)->dedicated;
2268 }
2269
2270 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p,
2271 Sset_window_dedicated_p, 2, 2, 0,
2272 doc:
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288 )
2289 (Lisp_Object window, Lisp_Object flag)
2290 {
2291 wset_dedicated (decode_live_window (window), flag);
2292 return flag;
2293 }
2294
2295 DEFUN ("window-prev-buffers", Fwindow_prev_buffers, Swindow_prev_buffers,
2296 0, 1, 0,
2297 doc:
2298
2299
2300
2301
2302 )
2303 (Lisp_Object window)
2304 {
2305 return decode_live_window (window)->prev_buffers;
2306 }
2307
2308 DEFUN ("set-window-prev-buffers", Fset_window_prev_buffers,
2309 Sset_window_prev_buffers, 2, 2, 0,
2310 doc:
2311
2312
2313
2314
2315 )
2316 (Lisp_Object window, Lisp_Object prev_buffers)
2317 {
2318 wset_prev_buffers (decode_live_window (window), prev_buffers);
2319 return prev_buffers;
2320 }
2321
2322 DEFUN ("window-next-buffers", Fwindow_next_buffers, Swindow_next_buffers,
2323 0, 1, 0,
2324 doc:
2325 )
2326 (Lisp_Object window)
2327 {
2328 return decode_live_window (window)->next_buffers;
2329 }
2330
2331 DEFUN ("set-window-next-buffers", Fset_window_next_buffers,
2332 Sset_window_next_buffers, 2, 2, 0,
2333 doc:
2334
2335 )
2336 (Lisp_Object window, Lisp_Object next_buffers)
2337 {
2338 wset_next_buffers (decode_live_window (window), next_buffers);
2339 return next_buffers;
2340 }
2341
2342 DEFUN ("window-parameters", Fwindow_parameters, Swindow_parameters,
2343 0, 1, 0,
2344 doc:
2345
2346 )
2347 (Lisp_Object window)
2348 {
2349 return Fcopy_alist (decode_valid_window (window)->window_parameters);
2350 }
2351
2352 Lisp_Object
2353 window_parameter (struct window *w, Lisp_Object parameter)
2354 {
2355 Lisp_Object result = assq_no_quit (parameter, w->window_parameters);
2356
2357 return CDR_SAFE (result);
2358 }
2359
2360
2361 DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter,
2362 2, 2, 0,
2363 doc:
2364 )
2365 (Lisp_Object window, Lisp_Object parameter)
2366 {
2367 struct window *w = decode_any_window (window);
2368
2369 return window_parameter (w, parameter);
2370 }
2371
2372 DEFUN ("set-window-parameter", Fset_window_parameter,
2373 Sset_window_parameter, 3, 3, 0,
2374 doc:
2375
2376 )
2377 (Lisp_Object window, Lisp_Object parameter, Lisp_Object value)
2378 {
2379 register struct window *w = decode_any_window (window);
2380 Lisp_Object old_alist_elt;
2381
2382 old_alist_elt = Fassq (parameter, w->window_parameters);
2383 if (NILP (old_alist_elt))
2384 wset_window_parameters
2385 (w, Fcons (Fcons (parameter, value), w->window_parameters));
2386 else
2387 Fsetcdr (old_alist_elt, value);
2388 return value;
2389 }
2390
2391 DEFUN ("window-display-table", Fwindow_display_table, Swindow_display_table,
2392 0, 1, 0,
2393 doc:
2394 )
2395 (Lisp_Object window)
2396 {
2397 return decode_live_window (window)->display_table;
2398 }
2399
2400
2401
2402
2403
2404
2405 struct Lisp_Char_Table *
2406 window_display_table (struct window *w)
2407 {
2408 struct Lisp_Char_Table *dp = NULL;
2409
2410 if (DISP_TABLE_P (w->display_table))
2411 dp = XCHAR_TABLE (w->display_table);
2412 else if (BUFFERP (w->contents))
2413 {
2414 struct buffer *b = XBUFFER (w->contents);
2415
2416 if (DISP_TABLE_P (BVAR (b, display_table)))
2417 dp = XCHAR_TABLE (BVAR (b, display_table));
2418 else if (DISP_TABLE_P (Vstandard_display_table))
2419 dp = XCHAR_TABLE (Vstandard_display_table);
2420 }
2421
2422 return dp;
2423 }
2424
2425 DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_display_table, 2, 2, 0,
2426 doc:
2427 )
2428 (register Lisp_Object window, Lisp_Object table)
2429 {
2430 wset_display_table (decode_live_window (window), table);
2431 return table;
2432 }
2433
2434
2435
2436 static void
2437 unshow_buffer (register struct window *w)
2438 {
2439 Lisp_Object buf = w->contents;
2440 struct buffer *b = XBUFFER (buf);
2441
2442 eassert (b == XMARKER (w->pointm)->buffer);
2443
2444 #if false
2445 if (w == XWINDOW (selected_window)
2446 || ! EQ (buf, XWINDOW (selected_window)->contents))
2447
2448
2449 #endif
2450
2451
2452
2453
2454
2455
2456
2457 b->last_window_start = marker_position (w->start);
2458
2459
2460
2461
2462 if (! EQ (buf, XWINDOW (selected_window)->contents)
2463
2464
2465
2466
2467 && !(WINDOWP (BVAR (b, last_selected_window))
2468 && w != XWINDOW (BVAR (b, last_selected_window))
2469 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->contents)))
2470 temp_set_point_both (b,
2471 clip_to_bounds (BUF_BEGV (b),
2472 marker_position (w->pointm),
2473 BUF_ZV (b)),
2474 clip_to_bounds (BUF_BEGV_BYTE (b),
2475 marker_byte_position (w->pointm),
2476 BUF_ZV_BYTE (b)));
2477
2478 if (WINDOWP (BVAR (b, last_selected_window))
2479 && w == XWINDOW (BVAR (b, last_selected_window)))
2480 bset_last_selected_window (b, Qnil);
2481 }
2482
2483
2484
2485
2486 static void
2487 replace_window (Lisp_Object old, Lisp_Object new, bool setflag)
2488 {
2489 Lisp_Object tem;
2490 struct window *o = XWINDOW (old), *n = XWINDOW (new);
2491
2492
2493
2494 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
2495 fset_root_window (XFRAME (o->frame), new);
2496
2497 if (setflag)
2498 {
2499 n->pixel_left = o->pixel_left;
2500 n->pixel_top = o->pixel_top;
2501 n->pixel_width = o->pixel_width;
2502 n->pixel_height = o->pixel_height;
2503 n->left_col = o->left_col;
2504 n->top_line = o->top_line;
2505 n->total_cols = o->total_cols;
2506 n->total_lines = o->total_lines;
2507 wset_normal_cols (n, o->normal_cols);
2508 wset_normal_cols (o, make_float (1.0));
2509 wset_normal_lines (n, o->normal_lines);
2510 wset_normal_lines (o, make_float (1.0));
2511 n->desired_matrix = n->current_matrix = 0;
2512 n->vscroll = 0;
2513 memset (&n->cursor, 0, sizeof (n->cursor));
2514 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
2515 n->last_cursor_vpos = 0;
2516 #ifdef HAVE_WINDOW_SYSTEM
2517 n->phys_cursor_type = NO_CURSOR;
2518 n->phys_cursor_width = -1;
2519 #endif
2520 n->must_be_updated_p = false;
2521 n->pseudo_window_p = false;
2522 n->window_end_vpos = 0;
2523 n->window_end_pos = 0;
2524 n->window_end_valid = false;
2525 }
2526
2527 tem = o->next;
2528 wset_next (n, tem);
2529 if (!NILP (tem))
2530 wset_prev (XWINDOW (tem), new);
2531
2532 tem = o->prev;
2533 wset_prev (n, tem);
2534 if (!NILP (tem))
2535 wset_next (XWINDOW (tem), new);
2536
2537 tem = o->parent;
2538 wset_parent (n, tem);
2539 if (!NILP (tem) && EQ (XWINDOW (tem)->contents, old))
2540 wset_combination (XWINDOW (tem), XWINDOW (tem)->horizontal, new);
2541 }
2542
2543
2544
2545
2546
2547 static void
2548 recombine_windows (Lisp_Object window)
2549 {
2550 struct window *w, *p, *c;
2551 Lisp_Object parent, child;
2552 bool horflag;
2553
2554 w = XWINDOW (window);
2555 parent = w->parent;
2556 if (!NILP (parent) && NILP (w->combination_limit))
2557 {
2558 p = XWINDOW (parent);
2559 if (WINDOWP (p->contents) && WINDOWP (w->contents)
2560 && p->horizontal == w->horizontal)
2561
2562
2563 {
2564 horflag = WINDOW_HORIZONTAL_COMBINATION_P (w);
2565 child = w->contents;
2566 c = XWINDOW (child);
2567
2568
2569
2570 if (NILP (w->prev))
2571 wset_combination (p, horflag, child);
2572 else
2573 {
2574 wset_prev (c, w->prev);
2575 wset_next (XWINDOW (w->prev), child);
2576 }
2577
2578 while (c)
2579 {
2580 wset_parent (c, parent);
2581
2582 if (horflag)
2583 wset_normal_cols
2584 (c, make_float ((double) c->pixel_width
2585 / (double) p->pixel_width));
2586 else
2587 wset_normal_lines
2588 (c, make_float ((double) c->pixel_height
2589 / (double) p->pixel_height));
2590
2591 if (NILP (c->next))
2592 {
2593 if (!NILP (w->next))
2594 {
2595 wset_next (c, w->next);
2596 wset_prev (XWINDOW (c->next), child);
2597 }
2598
2599 c = 0;
2600 }
2601 else
2602 {
2603 child = c->next;
2604 c = XWINDOW (child);
2605 }
2606 }
2607
2608
2609 wset_combination (w, false, Qnil);
2610 }
2611 }
2612 }
2613
2614
2615 static void
2616 delete_deletable_window (Lisp_Object window)
2617 {
2618 if (!NILP (call1 (Qwindow_deletable_p, window)))
2619 call1 (Qdelete_window, window);
2620 }
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630 static bool
2631 add_window_to_list (struct window *w, void *user_data)
2632 {
2633 Lisp_Object *list = user_data;
2634 Lisp_Object window;
2635 XSETWINDOW (window, w);
2636 *list = Fcons (window, *list);
2637 return true;
2638 }
2639
2640
2641
2642
2643
2644
2645 Lisp_Object
2646 window_list (void)
2647 {
2648 if (!CONSP (Vwindow_list))
2649 {
2650 Lisp_Object tail, frame;
2651 specpdl_ref count = SPECPDL_INDEX ();
2652
2653 Vwindow_list = Qnil;
2654
2655
2656
2657 specbind (Qinhibit_quit, Qt);
2658 FOR_EACH_FRAME (tail, frame)
2659 {
2660 Lisp_Object arglist = Qnil;
2661
2662
2663
2664
2665 foreach_window (XFRAME (frame), add_window_to_list, &arglist);
2666 arglist = Fnreverse (arglist);
2667 Vwindow_list = nconc2 (Vwindow_list, arglist);
2668 }
2669
2670 unbind_to (count, Qnil);
2671 }
2672
2673 return Vwindow_list;
2674 }
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693 static bool
2694 candidate_window_p (Lisp_Object window, Lisp_Object owindow,
2695 Lisp_Object minibuf, Lisp_Object all_frames)
2696 {
2697 struct window *w = XWINDOW (window);
2698 struct frame *f = XFRAME (w->frame);
2699 bool candidate_p = true;
2700
2701 if (!BUFFERP (w->contents))
2702 candidate_p = false;
2703 else if (MINI_WINDOW_P (w)
2704 && (EQ (minibuf, Qlambda)
2705 || (WINDOW_LIVE_P (minibuf) && !EQ (minibuf, window))))
2706 {
2707
2708
2709 candidate_p = false;
2710 }
2711 else if (EQ (all_frames, Qt))
2712 candidate_p = true;
2713 else if (NILP (all_frames))
2714 {
2715 eassert (WINDOWP (owindow));
2716 candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
2717 }
2718 else if (EQ (all_frames, Qvisible))
2719 {
2720 candidate_p = FRAME_VISIBLE_P (f)
2721 && (FRAME_TERMINAL (XFRAME (w->frame))
2722 == FRAME_TERMINAL (XFRAME (selected_frame)));
2723
2724 }
2725 else if (FIXNUMP (all_frames) && XFIXNUM (all_frames) == 0)
2726 {
2727 candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)
2728 #ifdef HAVE_X_WINDOWS
2729
2730
2731
2732
2733
2734
2735 || (FRAME_X_P (f) && f->output_data.x->asked_for_visible
2736 && !f->output_data.x->has_been_visible)
2737 #endif
2738 )
2739 && (FRAME_TERMINAL (XFRAME (w->frame))
2740 == FRAME_TERMINAL (XFRAME (selected_frame)));
2741 }
2742 else if (WINDOWP (all_frames))
2743
2744
2745
2746 candidate_p = ((EQ (XWINDOW (all_frames)->frame, w->frame)
2747 || (EQ (f->minibuffer_window, all_frames)
2748 && EQ (XWINDOW (all_frames)->frame, FRAME_FOCUS_FRAME (f))))
2749 && (EQ (minibuf, Qt)
2750 || !is_minibuffer (0, XWINDOW (all_frames)->contents)));
2751 else if (FRAMEP (all_frames))
2752 candidate_p = EQ (all_frames, w->frame);
2753
2754 return candidate_p;
2755 }
2756
2757
2758
2759
2760
2761
2762 static void
2763 decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames)
2764 {
2765 struct window *w = decode_live_window (*window);
2766 Lisp_Object miniwin = XFRAME (w->frame)->minibuffer_window;
2767
2768 XSETWINDOW (*window, w);
2769
2770
2771
2772 if (WINDOW_LIVE_P (miniwin) && NILP (*minibuf))
2773 *minibuf = (this_minibuffer_depth (XWINDOW (miniwin)->contents)
2774 ? miniwin : Qlambda);
2775 else if (!EQ (*minibuf, Qt))
2776 *minibuf = Qlambda;
2777
2778
2779
2780
2781
2782
2783 if (NILP (*all_frames))
2784 *all_frames
2785
2786
2787 = ((WINDOW_LIVE_P (miniwin) && !EQ (*minibuf, Qlambda))
2788 ? miniwin : Qnil);
2789 else if (EQ (*all_frames, Qvisible))
2790 ;
2791 else if (BASE_EQ (*all_frames, make_fixnum (0)))
2792 ;
2793 else if (FRAMEP (*all_frames))
2794 ;
2795 else if (!EQ (*all_frames, Qt))
2796 *all_frames = Qnil;
2797 }
2798
2799
2800
2801
2802
2803
2804
2805 static Lisp_Object
2806 next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames,
2807 bool next_p)
2808 {
2809 specpdl_ref count = SPECPDL_INDEX ();
2810
2811 decode_next_window_args (&window, &minibuf, &all_frames);
2812
2813
2814
2815 if (FRAMEP (all_frames)
2816 && !EQ (all_frames, XWINDOW (window)->frame))
2817 return Fframe_first_window (all_frames);
2818
2819
2820 specbind (Qinhibit_quit, Qt);
2821
2822 if (next_p)
2823 {
2824 Lisp_Object list;
2825
2826
2827 list = Fmemq (window, window_list ());
2828
2829
2830 if (CONSP (list))
2831 for (list = XCDR (list); CONSP (list); list = XCDR (list))
2832 if (candidate_window_p (XCAR (list), window, minibuf, all_frames))
2833 break;
2834
2835
2836 if (!CONSP (list))
2837 for (list = Vwindow_list;
2838 CONSP (list) && !EQ (XCAR (list), window);
2839 list = XCDR (list))
2840 if (candidate_window_p (XCAR (list), window, minibuf, all_frames))
2841 break;
2842
2843 if (CONSP (list))
2844 window = XCAR (list);
2845 }
2846 else
2847 {
2848 Lisp_Object candidate, list;
2849
2850
2851
2852
2853
2854 candidate = Qnil;
2855 for (list = window_list (); CONSP (list); list = XCDR (list))
2856 {
2857 if (EQ (XCAR (list), window))
2858 {
2859 if (WINDOWP (candidate))
2860 break;
2861 }
2862 else if (candidate_window_p (XCAR (list), window, minibuf,
2863 all_frames))
2864 candidate = XCAR (list);
2865 }
2866
2867 if (WINDOWP (candidate))
2868 window = candidate;
2869 }
2870
2871 unbind_to (count, Qnil);
2872
2873 return window;
2874 }
2875
2876
2877 DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
2878 doc:
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909 )
2910 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2911 {
2912 return next_window (window, minibuf, all_frames, true);
2913 }
2914
2915
2916 DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
2917 doc:
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949 )
2950 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2951 {
2952 return next_window (window, minibuf, all_frames, false);
2953 }
2954
2955
2956
2957
2958
2959 static Lisp_Object
2960 window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2961 {
2962 Lisp_Object tail, list, rest;
2963 specpdl_ref count = SPECPDL_INDEX ();
2964
2965 decode_next_window_args (&window, &minibuf, &all_frames);
2966 list = Qnil;
2967
2968
2969 specbind (Qinhibit_quit, Qt);
2970
2971 for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
2972 if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
2973 list = Fcons (XCAR (tail), list);
2974
2975
2976 list = Fnreverse (list);
2977 rest = Fmemq (window, list);
2978 if (!NILP (rest) && !EQ (rest, list))
2979 {
2980 for (tail = list; !EQ (XCDR (tail), rest); tail = XCDR (tail))
2981 ;
2982 XSETCDR (tail, Qnil);
2983 list = nconc2 (rest, list);
2984 }
2985
2986 unbind_to (count, Qnil);
2987
2988 return list;
2989 }
2990
2991
2992 DEFUN ("window-list", Fwindow_list, Swindow_list, 0, 3, 0,
2993 doc:
2994
2995
2996
2997
2998
2999 )
3000 (Lisp_Object frame, Lisp_Object minibuf, Lisp_Object window)
3001 {
3002 if (NILP (window))
3003 window = FRAMEP (frame) ? XFRAME (frame)->selected_window : selected_window;
3004 CHECK_WINDOW (window);
3005 if (NILP (frame))
3006 frame = selected_frame;
3007
3008 if (!EQ (frame, XWINDOW (window)->frame))
3009 error ("Window is on a different frame");
3010
3011 return window_list_1 (window, minibuf, frame);
3012 }
3013
3014
3015 DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
3016 doc:
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045 )
3046 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
3047 {
3048 return window_list_1 (window, minibuf, all_frames);
3049 }
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059 enum window_loop
3060 {
3061 WINDOW_LOOP_UNUSED,
3062 GET_BUFFER_WINDOW,
3063 REPLACE_BUFFER_IN_WINDOWS_SAFELY,
3064 REDISPLAY_BUFFER_WINDOWS,
3065 CHECK_ALL_WINDOWS
3066 };
3067
3068 static Lisp_Object
3069 window_loop (enum window_loop type, Lisp_Object obj, bool mini,
3070 Lisp_Object frames)
3071 {
3072 Lisp_Object window, windows, best_window, frame_arg;
3073 bool frame_best_window_flag = false;
3074 struct frame *f;
3075
3076
3077
3078
3079 if (FRAMEP (frames))
3080 f = XFRAME (frames);
3081 else if (NILP (frames))
3082 f = SELECTED_FRAME ();
3083 else
3084 f = NULL;
3085
3086 if (f)
3087 frame_arg = Qlambda;
3088 else if (BASE_EQ (frames, make_fixnum (0)))
3089 frame_arg = frames;
3090 else if (EQ (frames, Qvisible))
3091 frame_arg = frames;
3092 else
3093 frame_arg = Qt;
3094
3095
3096
3097
3098
3099
3100 if (WINDOWP (obj))
3101 window = obj;
3102 else if (f)
3103 window = FRAME_SELECTED_WINDOW (f);
3104 else
3105 window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
3106
3107 windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
3108 best_window = Qnil;
3109
3110 for (; CONSP (windows); windows = XCDR (windows))
3111 {
3112 struct window *w;
3113
3114 window = XCAR (windows);
3115 w = XWINDOW (window);
3116
3117
3118
3119
3120 if (!MINI_WINDOW_P (w)
3121
3122
3123 || type == REPLACE_BUFFER_IN_WINDOWS_SAFELY
3124 || (mini && minibuf_level > 0))
3125 switch (type)
3126 {
3127 case GET_BUFFER_WINDOW:
3128 if (EQ (w->contents, obj)
3129
3130
3131 && (!MINI_WINDOW_P (w) || EQ (window, minibuf_window)))
3132 {
3133 if (EQ (window, selected_window))
3134
3135 return window;
3136 else if (EQ (XWINDOW (window)->frame, selected_frame)
3137 && !frame_best_window_flag)
3138
3139
3140 {
3141 best_window = window;
3142 frame_best_window_flag = true;
3143 }
3144 else if (NILP (best_window))
3145 best_window = window;
3146 }
3147 break;
3148
3149 case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
3150
3151
3152 if (EQ (w->contents, obj))
3153 {
3154
3155 wset_dedicated (w, Qnil);
3156
3157
3158 set_window_buffer
3159 (window, other_buffer_safely (w->contents), false, false);
3160
3161
3162
3163 if (EQ (window, selected_window)
3164 && XBUFFER (w->contents) == current_buffer)
3165 Fset_buffer (w->contents);
3166 }
3167 break;
3168
3169 case REDISPLAY_BUFFER_WINDOWS:
3170 if (EQ (w->contents, obj))
3171 {
3172 mark_window_display_accurate (window, false);
3173 w->update_mode_line = true;
3174 XBUFFER (obj)->prevent_redisplay_optimizations_p = true;
3175 update_mode_lines = 27;
3176 best_window = window;
3177 }
3178 break;
3179
3180
3181
3182 case CHECK_ALL_WINDOWS:
3183 if (BUFFERP (w->contents))
3184 {
3185 struct buffer *b = XBUFFER (w->contents);
3186
3187 if (!BUFFER_LIVE_P (b))
3188 emacs_abort ();
3189 if (!MARKERP (w->start) || XMARKER (w->start)->buffer != b)
3190 emacs_abort ();
3191 if (!MARKERP (w->pointm) || XMARKER (w->pointm)->buffer != b)
3192 emacs_abort ();
3193 }
3194 break;
3195
3196 case WINDOW_LOOP_UNUSED:
3197 break;
3198 }
3199 }
3200
3201 return best_window;
3202 }
3203
3204
3205
3206 extern void check_all_windows (void) EXTERNALLY_VISIBLE;
3207 void
3208 check_all_windows (void)
3209 {
3210 window_loop (CHECK_ALL_WINDOWS, Qnil, true, Qt);
3211 }
3212
3213 DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 0, 2, 0,
3214 doc:
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230 )
3231 (Lisp_Object buffer_or_name, Lisp_Object all_frames)
3232 {
3233 Lisp_Object buffer;
3234
3235 if (NILP (buffer_or_name))
3236 buffer = Fcurrent_buffer ();
3237 else
3238 buffer = Fget_buffer (buffer_or_name);
3239
3240 if (BUFFERP (buffer))
3241 return window_loop (GET_BUFFER_WINDOW, buffer, true, all_frames);
3242 else
3243 return Qnil;
3244 }
3245
3246
3247 static Lisp_Object
3248 resize_root_window (Lisp_Object window, Lisp_Object delta,
3249 Lisp_Object horizontal, Lisp_Object ignore,
3250 Lisp_Object pixelwise)
3251 {
3252 return call5 (Qwindow__resize_root_window, window, delta,
3253 horizontal, ignore, pixelwise);
3254 }
3255
3256
3257 static Lisp_Object
3258 window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
3259 {
3260 return call2 (Qwindow__pixel_to_total, frame, horizontal);
3261 }
3262
3263
3264 DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal,
3265 Sdelete_other_windows_internal, 0, 2, "",
3266 doc:
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278 )
3279 (Lisp_Object window, Lisp_Object root)
3280 {
3281 struct window *w = decode_valid_window (window);
3282 struct window *r, *s;
3283 Lisp_Object frame = w->frame;
3284 struct frame *f = XFRAME (frame);
3285 Lisp_Object sibling, pwindow, delta;
3286 Lisp_Object swindow UNINIT;
3287 ptrdiff_t startpos UNINIT, startbyte UNINIT;
3288 int top UNINIT;
3289 int new_top;
3290 bool resize_failed = false;
3291
3292 XSETWINDOW (window, w);
3293
3294 if (NILP (root))
3295
3296 {
3297 root = FRAME_ROOT_WINDOW (f);
3298 r = XWINDOW (root);
3299 }
3300 else
3301
3302 {
3303 r = decode_valid_window (root);
3304 pwindow = XWINDOW (window)->parent;
3305 while (!NILP (pwindow))
3306 if (EQ (pwindow, root))
3307 break;
3308 else
3309 pwindow = XWINDOW (pwindow)->parent;
3310 if (!EQ (pwindow, root))
3311 error ("Specified root is not an ancestor of specified window");
3312 }
3313
3314 if (EQ (window, root))
3315
3316 return Qnil;
3317
3318
3319
3320 else if (MINI_WINDOW_P (w))
3321 error ("Can't expand minibuffer to full frame");
3322
3323 if (BUFFERP (w->contents))
3324 {
3325 startpos = marker_position (w->start);
3326 startbyte = marker_byte_position (w->start);
3327 top = (WINDOW_TOP_EDGE_LINE (w)
3328 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))));
3329
3330 if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
3331 {
3332 if (EQ (selected_frame, frame))
3333 Fselect_window (window, Qnil);
3334 else
3335
3336
3337
3338 fset_selected_window (f, window);
3339 }
3340 }
3341 else
3342 {
3343
3344
3345
3346
3347 swindow = FRAME_SELECTED_WINDOW (f);
3348 while (true)
3349 {
3350 pwindow = swindow;
3351 while (!NILP (pwindow) && !EQ (window, pwindow))
3352 pwindow = XWINDOW (pwindow)->parent;
3353
3354 if (EQ (window, pwindow))
3355
3356
3357 break;
3358 else
3359
3360 swindow = Fprevious_window (swindow, Qlambda, Qnil);
3361 }
3362
3363 if (!EQ (swindow, FRAME_SELECTED_WINDOW (f)))
3364 {
3365 if (EQ (selected_frame, frame))
3366 Fselect_window (swindow, Qnil);
3367 else
3368 fset_selected_window (f, swindow);
3369 }
3370 }
3371
3372 block_input ();
3373 if (!FRAME_INITIAL_P (f))
3374 {
3375 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
3376
3377
3378
3379
3380
3381
3382
3383
3384 if (EQ (hlinfo->mouse_face_window, window))
3385 reset_mouse_highlight (hlinfo);
3386 }
3387 free_window_matrices (r);
3388
3389 fset_redisplay (f);
3390 Vwindow_list = Qnil;
3391
3392 if (!WINDOW_LEAF_P (w))
3393 {
3394
3395 XSETINT (delta, r->pixel_height - w->pixel_height);
3396 w->pixel_top = r->pixel_top;
3397 w->top_line = r->top_line;
3398 resize_root_window (window, delta, Qnil, Qnil, Qt);
3399 if (window_resize_check (w, false))
3400 window_resize_apply (w, false);
3401 else
3402 {
3403 resize_root_window (window, delta, Qnil, Qt, Qt);
3404 if (window_resize_check (w, false))
3405 window_resize_apply (w, false);
3406 else
3407 resize_failed = true;
3408 }
3409
3410
3411 if (!resize_failed)
3412 {
3413 w->left_col = r->left_col;
3414 w->pixel_left = r->pixel_left;
3415 XSETINT (delta, r->pixel_width - w->pixel_width);
3416 resize_root_window (window, delta, Qt, Qnil, Qt);
3417 if (window_resize_check (w, true))
3418 window_resize_apply (w, true);
3419 else
3420 {
3421 resize_root_window (window, delta, Qt, Qt, Qt);
3422 if (window_resize_check (w, true))
3423 window_resize_apply (w, true);
3424 else
3425 resize_failed = true;
3426 }
3427 }
3428
3429 if (resize_failed)
3430
3431 {
3432 window = swindow;
3433 w = XWINDOW (window);
3434 }
3435 }
3436
3437
3438 if (!NILP (w->prev))
3439
3440 {
3441 sibling = w->prev;
3442 s = XWINDOW (sibling);
3443 wset_next (s, w->next);
3444 if (!NILP (s->next))
3445 wset_prev (XWINDOW (s->next), sibling);
3446 }
3447 else
3448
3449 {
3450 sibling = w->next;
3451 s = XWINDOW (sibling);
3452 wset_prev (s, Qnil);
3453 wset_combination (XWINDOW (w->parent),
3454 XWINDOW (w->parent)->horizontal, sibling);
3455 }
3456
3457
3458 if (WINDOWP (r->contents))
3459 {
3460 delete_all_child_windows (r->contents);
3461 wset_combination (r, false, Qnil);
3462 }
3463
3464 replace_window (root, window, true);
3465
3466
3467
3468
3469 window_pixel_to_total (frame, Qnil);
3470 window_pixel_to_total (frame, Qt);
3471
3472
3473 if (BUFFERP (w->contents) && !resize_failed)
3474 {
3475
3476
3477
3478
3479
3480 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
3481 if (new_top != top
3482 && startpos >= BUF_BEGV (XBUFFER (w->contents))
3483 && startpos <= BUF_ZV (XBUFFER (w->contents)))
3484 {
3485 struct position pos;
3486 struct buffer *obuf = current_buffer;
3487
3488 Fset_buffer (w->contents);
3489
3490
3491 pos = *vmotion (startpos, startbyte, -top, w);
3492
3493 set_marker_both (w->start, w->contents, pos.bufpos, pos.bytepos);
3494 w->window_end_valid = false;
3495 w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
3496 || FETCH_BYTE (pos.bytepos - 1) == '\n');
3497
3498
3499 w->optional_new_start = true;
3500
3501 set_buffer_internal (obuf);
3502 }
3503 }
3504
3505 adjust_frame_glyphs (f);
3506 unblock_input ();
3507
3508 FRAME_WINDOW_CHANGE (f) = true;
3509
3510 return Qnil;
3511 }
3512
3513
3514 void
3515 replace_buffer_in_windows (Lisp_Object buffer)
3516 {
3517
3518
3519 if (!NILP (Ffboundp (Qreplace_buffer_in_windows)))
3520 call1 (Qreplace_buffer_in_windows, buffer);
3521 }
3522
3523
3524
3525
3526 void
3527 replace_buffer_in_windows_safely (Lisp_Object buffer)
3528 {
3529 if (buffer_window_count (XBUFFER (buffer)))
3530 {
3531 Lisp_Object tail, frame;
3532
3533
3534
3535
3536 FOR_EACH_FRAME (tail, frame)
3537 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, true, frame);
3538 }
3539 }
3540
3541
3542
3543 static void
3544 run_funs (Lisp_Object funs)
3545 {
3546 for (; CONSP (funs); funs = XCDR (funs))
3547 if (!EQ (XCAR (funs), Qt))
3548 call0 (XCAR (funs));
3549 }
3550
3551 static void
3552 select_window_norecord (Lisp_Object window)
3553 {
3554 if (WINDOW_LIVE_P (window))
3555 Fselect_window (window, Qt);
3556 }
3557
3558 static void
3559 select_frame_norecord (Lisp_Object frame)
3560 {
3561 if (FRAME_LIVE_P (XFRAME (frame)))
3562 Fselect_frame (frame, Qt);
3563 }
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574 static void
3575 run_window_configuration_change_hook (struct frame *f)
3576 {
3577 specpdl_ref count = SPECPDL_INDEX ();
3578 Lisp_Object frame, global_wcch
3579 = Fdefault_value (Qwindow_configuration_change_hook);
3580 XSETFRAME (frame, f);
3581
3582 if (NILP (Vrun_hooks)
3583 || !f->can_set_window_size
3584 || !f->after_make_frame)
3585 return;
3586
3587
3588 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
3589 {
3590 record_unwind_current_buffer ();
3591 Fset_buffer (Fwindow_buffer (Qnil));
3592 }
3593
3594 if (SELECTED_FRAME () != f)
3595 {
3596 record_unwind_protect (select_frame_norecord, selected_frame);
3597 select_frame_norecord (frame);
3598 }
3599
3600
3601 {
3602 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
3603 for (; CONSP (windows); windows = XCDR (windows))
3604 {
3605 Lisp_Object window = XCAR (windows);
3606 Lisp_Object buffer = Fwindow_buffer (window);
3607 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
3608 buffer)))
3609 {
3610 specpdl_ref inner_count = SPECPDL_INDEX ();
3611 record_unwind_protect (select_window_norecord, selected_window);
3612 select_window_norecord (window);
3613 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
3614 buffer));
3615 unbind_to (inner_count, Qnil);
3616 }
3617 }
3618 }
3619
3620 run_funs (global_wcch);
3621 unbind_to (count, Qnil);
3622 }
3623
3624 DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
3625 Srun_window_configuration_change_hook, 0, 1, 0,
3626 doc:
3627
3628
3629
3630 )
3631 (Lisp_Object frame)
3632 {
3633 run_window_configuration_change_hook (decode_live_frame (frame));
3634 return Qnil;
3635 }
3636
3637 DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions,
3638 Srun_window_scroll_functions, 0, 1, 0,
3639 doc:
3640
3641
3642
3643 )
3644 (Lisp_Object window)
3645 {
3646 struct window *w = decode_live_window (window);
3647 specpdl_ref count = SPECPDL_INDEX ();
3648
3649 record_unwind_current_buffer ();
3650 Fset_buffer (w->contents);
3651 if (!NILP (Vwindow_scroll_functions))
3652 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3653 Fmarker_position (w->start));
3654 unbind_to (count, Qnil);
3655
3656 return Qnil;
3657 }
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668 static Lisp_Object
3669 window_sub_list (Lisp_Object window, Lisp_Object windows)
3670 {
3671
3672 struct window *w = XWINDOW (window);
3673
3674 while (w)
3675 {
3676 if (WINDOW_INTERNAL_P (w))
3677 windows = window_sub_list (w->contents, windows);
3678 else
3679 windows = Fcons (window, windows);
3680
3681 window = w->next;
3682 w = NILP (window) ? 0 : XWINDOW (window);
3683 }
3684
3685 return windows;
3686 }
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703 static ptrdiff_t
3704 window_change_record_windows (Lisp_Object window, int stamp, ptrdiff_t number)
3705 {
3706 struct window *w = XWINDOW (window);
3707
3708 while (w)
3709 {
3710 if (WINDOW_INTERNAL_P (w))
3711 number = window_change_record_windows (w->contents, stamp, number);
3712 else
3713 {
3714 number += 1;
3715 w->change_stamp = stamp;
3716 wset_old_buffer (w, w->contents);
3717 w->old_pixel_width = w->pixel_width;
3718 w->old_pixel_height = w->pixel_height;
3719 w->old_body_pixel_width
3720 = window_body_width (w, WINDOW_BODY_IN_PIXELS);
3721 w->old_body_pixel_height
3722 = window_body_height (w, WINDOW_BODY_IN_PIXELS);
3723 }
3724
3725 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3726 }
3727
3728 return number;
3729 }
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743 static void
3744 window_change_record (void)
3745 {
3746 if (window_change_record_frames)
3747 {
3748 Lisp_Object tail, frame;
3749
3750 FOR_EACH_FRAME (tail, frame)
3751 {
3752 struct frame *f = XFRAME (frame);
3753
3754
3755 fset_old_selected_window (f, FRAME_SELECTED_WINDOW (f));
3756
3757
3758
3759
3760 f->change_stamp += 1;
3761 if (f->change_stamp == 0)
3762 f->change_stamp = 1;
3763
3764
3765
3766
3767 f->number_of_windows
3768 = window_change_record_windows (f->root_window, f->change_stamp, 0);
3769
3770
3771 FRAME_WINDOW_CHANGE (f) = false;
3772 FRAME_WINDOW_STATE_CHANGE (f) = false;
3773 }
3774 }
3775
3776
3777
3778 old_selected_window = selected_window;
3779 old_selected_frame = selected_frame;
3780 }
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792 static void
3793 run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer,
3794 Lisp_Object window_or_frame)
3795 {
3796 Lisp_Object funs = Qnil;
3797
3798 if (NILP (buffer))
3799 funs = Fdefault_value (symbol);
3800 else if (!NILP (Fassoc (symbol, BVAR (XBUFFER (buffer), local_var_alist),
3801 Qnil)))
3802
3803 funs = buffer_local_value (symbol, buffer);
3804
3805 while (CONSP (funs))
3806 {
3807 if (!EQ (XCAR (funs), Qt)
3808 && (NILP (buffer)
3809 ? FRAME_LIVE_P (XFRAME (window_or_frame))
3810 : WINDOW_LIVE_P (window_or_frame)))
3811 {
3812
3813
3814
3815 window_change_record_frames = true;
3816 safe_call1 (XCAR (funs), window_or_frame);
3817 }
3818
3819 funs = XCDR (funs);
3820 }
3821 }
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886 void
3887 run_window_change_functions (void)
3888 {
3889 Lisp_Object tail, frame;
3890 bool selected_frame_change = !EQ (selected_frame, old_selected_frame);
3891 bool run_window_state_change_hook = false;
3892 specpdl_ref count = SPECPDL_INDEX ();
3893
3894 window_change_record_frames = false;
3895 record_unwind_protect_void (window_change_record);
3896 specbind (Qinhibit_redisplay, Qt);
3897
3898 FOR_EACH_FRAME (tail, frame)
3899 {
3900 struct frame *f = XFRAME (frame);
3901 Lisp_Object root = FRAME_ROOT_WINDOW (f);
3902 bool frame_window_change = FRAME_WINDOW_CHANGE (f);
3903 bool window_buffer_change, window_size_change;
3904 bool frame_buffer_change = false, frame_size_change = false;
3905 bool frame_selected_change
3906 = (selected_frame_change
3907 && (EQ (frame, old_selected_frame)
3908 || EQ (frame, selected_frame)));
3909 bool frame_selected_window_change
3910 = !EQ (FRAME_OLD_SELECTED_WINDOW (f), FRAME_SELECTED_WINDOW (f));
3911 bool frame_window_state_change = FRAME_WINDOW_STATE_CHANGE (f);
3912 bool window_deleted = false;
3913 Lisp_Object windows;
3914 ptrdiff_t number_of_windows;
3915
3916 if (!FRAME_LIVE_P (f)
3917 || !f->can_set_window_size
3918 || !f->after_make_frame
3919 || FRAME_TOOLTIP_P (f)
3920 || !(frame_window_change
3921 || frame_selected_change
3922 || frame_selected_window_change
3923 || frame_window_state_change))
3924
3925
3926
3927 continue;
3928
3929
3930 windows = Fnreverse (window_sub_list (root, Qnil));
3931 number_of_windows = 0;
3932
3933
3934
3935
3936 for (; CONSP (windows); windows = XCDR (windows))
3937 {
3938 Lisp_Object window = XCAR (windows);
3939 struct window *w = XWINDOW (window);
3940 Lisp_Object buffer = WINDOW_BUFFER (w);
3941
3942
3943
3944 number_of_windows += 1;
3945
3946 if (!WINDOW_LIVE_P (window))
3947 continue;
3948
3949
3950
3951
3952 window_buffer_change =
3953 (frame_window_change
3954 && (!EQ (buffer, w->old_buffer)
3955 || w->change_stamp != f->change_stamp));
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965 window_size_change =
3966 (frame_window_change
3967 && (window_buffer_change
3968 || w->pixel_width != w->old_pixel_width
3969 || w->pixel_height != w->old_pixel_height
3970 || (window_body_width (w, WINDOW_BODY_IN_PIXELS)
3971 != w->old_body_pixel_width)
3972 || (window_body_height (w, WINDOW_BODY_IN_PIXELS)
3973 != w->old_body_pixel_height)));
3974
3975
3976
3977 frame_buffer_change = frame_buffer_change || window_buffer_change;
3978 frame_size_change = frame_size_change || window_size_change;
3979
3980 if (window_buffer_change)
3981 run_window_change_functions_1
3982 (Qwindow_buffer_change_functions, buffer, window);
3983
3984 if (window_size_change && WINDOW_LIVE_P (window))
3985 run_window_change_functions_1
3986 (Qwindow_size_change_functions, buffer, window);
3987
3988
3989
3990
3991 if (((frame_selected_change
3992 && (EQ (window, old_selected_window)
3993 || EQ (window, selected_window)))
3994 || (frame_selected_window_change
3995 && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))
3996 || EQ (window, FRAME_SELECTED_WINDOW (f)))))
3997 && WINDOW_LIVE_P (window))
3998 run_window_change_functions_1
3999 (Qwindow_selection_change_functions, buffer, window);
4000
4001
4002
4003
4004 if ((window_buffer_change
4005 || window_size_change
4006 || ((frame_selected_change
4007 && (EQ (window, old_selected_window)
4008 || EQ (window, selected_window)))
4009 || (frame_selected_window_change
4010 && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))
4011 || EQ (window, FRAME_SELECTED_WINDOW (f))))))
4012 && WINDOW_LIVE_P (window))
4013 run_window_change_functions_1
4014 (Qwindow_state_change_functions, buffer, window);
4015 }
4016
4017
4018
4019
4020
4021
4022
4023
4024 window_deleted = number_of_windows < f->number_of_windows;
4025
4026
4027 if ((frame_buffer_change || window_deleted) && FRAME_LIVE_P (f))
4028 run_window_change_functions_1
4029 (Qwindow_buffer_change_functions, Qnil, frame);
4030
4031
4032
4033 if (frame_size_change && FRAME_LIVE_P (f))
4034 run_window_change_functions_1
4035 (Qwindow_size_change_functions, Qnil, frame);
4036
4037
4038
4039 if ((frame_selected_change || frame_selected_window_change)
4040 && FRAME_LIVE_P (f))
4041 run_window_change_functions_1
4042 (Qwindow_selection_change_functions, Qnil, frame);
4043
4044 #if defined HAVE_TEXT_CONVERSION
4045
4046
4047
4048
4049 if ((frame_selected_window_change || frame_buffer_change)
4050 && FRAME_LIVE_P (f)
4051 && FRAME_WINDOW_P (f))
4052 report_selected_window_change (f);
4053
4054 #endif
4055
4056
4057
4058
4059 if ((frame_selected_change || frame_selected_window_change
4060 || frame_buffer_change || window_deleted
4061 || frame_size_change || frame_window_state_change)
4062 && FRAME_LIVE_P (f))
4063 {
4064 run_window_change_functions_1
4065 (Qwindow_state_change_functions, Qnil, frame);
4066
4067 run_window_state_change_hook = true;
4068
4069
4070 window_change_record_frames = true;
4071 }
4072
4073
4074
4075 if ((frame_size_change || window_deleted) && FRAME_LIVE_P (f))
4076
4077
4078 run_window_configuration_change_hook (f);
4079 }
4080
4081
4082
4083 if (run_window_state_change_hook && !NILP (Vwindow_state_change_hook))
4084 safe_run_hooks (Qwindow_state_change_hook);
4085
4086
4087
4088 unbind_to (count, Qnil);
4089 }
4090
4091
4092
4093
4094
4095
4096
4097 void
4098 set_window_buffer (Lisp_Object window, Lisp_Object buffer,
4099 bool run_hooks_p, bool keep_margins_p)
4100 {
4101 struct window *w = XWINDOW (window);
4102 struct buffer *b = XBUFFER (buffer);
4103 specpdl_ref count = SPECPDL_INDEX ();
4104 bool samebuf = EQ (buffer, w->contents);
4105
4106 wset_buffer (w, buffer);
4107
4108 if (EQ (window, selected_window))
4109 bset_last_selected_window (b, window);
4110
4111
4112 b->display_error_modiff = 0;
4113
4114
4115 if (INTEGERP (BVAR (b, display_count)))
4116 bset_display_count (b, Fadd1 (BVAR (b, display_count)));
4117 bset_display_time (b, Fcurrent_time ());
4118
4119 w->window_end_pos = 0;
4120 w->window_end_vpos = 0;
4121 w->last_cursor_vpos = 0;
4122
4123 if (!(keep_margins_p && samebuf))
4124 {
4125
4126
4127
4128 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
4129 w->suspend_auto_hscroll = false;
4130 w->vscroll = 0;
4131 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
4132 set_marker_both (w->old_pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
4133 set_marker_restricted (w->start,
4134 make_fixnum (b->last_window_start),
4135 buffer);
4136 w->start_at_line_beg = false;
4137 w->force_start = false;
4138 }
4139
4140 wset_redisplay (w);
4141 wset_update_mode_line (w);
4142
4143
4144
4145 record_unwind_current_buffer ();
4146 Fset_buffer (buffer);
4147
4148 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
4149 XMARKER (w->old_pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
4150
4151 if (!keep_margins_p)
4152 {
4153
4154
4155 if (!w->fringes_persistent)
4156 set_window_fringes (w, BVAR (b, left_fringe_width),
4157 BVAR (b, right_fringe_width),
4158 BVAR (b, fringes_outside_margins), Qnil);
4159 if (!w->scroll_bars_persistent)
4160 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
4161 BVAR (b, vertical_scroll_bar_type),
4162 BVAR (b, scroll_bar_height),
4163 BVAR (b, horizontal_scroll_bar_type), Qnil);
4164
4165 set_window_margins (w, BVAR (b, left_margin_cols),
4166 BVAR (b, right_margin_cols));
4167 apply_window_adjustment (w);
4168 }
4169
4170 if (run_hooks_p && !NILP (Vwindow_scroll_functions))
4171 run_hook_with_args_2 (Qwindow_scroll_functions, window,
4172 Fmarker_position (w->start));
4173
4174
4175
4176
4177
4178
4179
4180 if (!samebuf && !MINI_WINDOW_P (w) && !WINDOW_PSEUDO_P (w))
4181 FRAME_WINDOW_CHANGE (XFRAME (w->frame)) = true;
4182
4183 unbind_to (count, Qnil);
4184 }
4185
4186 DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
4187 doc:
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201 )
4202 (register Lisp_Object window, Lisp_Object buffer_or_name, Lisp_Object keep_margins)
4203 {
4204 register Lisp_Object tem, buffer;
4205 register struct window *w = decode_live_window (window);
4206
4207 XSETWINDOW (window, w);
4208 buffer = Fget_buffer (buffer_or_name);
4209 CHECK_BUFFER (buffer);
4210 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
4211 error ("Attempt to display deleted buffer");
4212
4213 tem = w->contents;
4214 if (NILP (tem))
4215 error ("Window is deleted");
4216 else
4217 {
4218 if (!EQ (tem, buffer))
4219 {
4220 if (EQ (w->dedicated, Qt))
4221
4222
4223 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
4224 else
4225
4226
4227 wset_dedicated (w, Qnil);
4228
4229 call1 (Qrecord_window_buffer, window);
4230 }
4231
4232 unshow_buffer (w);
4233 }
4234
4235 set_window_buffer (window, buffer, true, !NILP (keep_margins));
4236
4237 return Qnil;
4238 }
4239
4240 static Lisp_Object
4241 display_buffer (Lisp_Object buffer, Lisp_Object not_this_window_p, Lisp_Object override_frame)
4242 {
4243 return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame);
4244 }
4245
4246 DEFUN ("force-window-update", Fforce_window_update, Sforce_window_update,
4247 0, 1, 0,
4248 doc:
4249
4250
4251 )
4252 (Lisp_Object object)
4253 {
4254 if (NILP (object))
4255 {
4256 windows_or_buffers_changed = 29;
4257 update_mode_lines = 28;
4258 return Qt;
4259 }
4260
4261 if (WINDOW_LIVE_P (object))
4262 {
4263 struct window *w = XWINDOW (object);
4264 mark_window_display_accurate (object, false);
4265 w->update_mode_line = true;
4266 if (BUFFERP (w->contents))
4267 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true;
4268 update_mode_lines = 29;
4269 return Qt;
4270 }
4271
4272 if (STRINGP (object))
4273 object = Fget_buffer (object);
4274 if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object))
4275 && buffer_window_count (XBUFFER (object)))
4276 {
4277
4278
4279 object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, false, Qvisible);
4280 return NILP (object) ? Qnil : Qt;
4281 }
4282
4283
4284
4285
4286 return Qnil;
4287 }
4288
4289
4290 void
4291 temp_output_buffer_show (register Lisp_Object buf)
4292 {
4293 register struct buffer *old = current_buffer;
4294 register Lisp_Object window;
4295 register struct window *w;
4296
4297 bset_directory (XBUFFER (buf), BVAR (current_buffer, directory));
4298
4299 Fset_buffer (buf);
4300 BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF;
4301 BEGV = BEG;
4302 ZV = Z;
4303 SET_PT (BEG);
4304 set_buffer_internal (old);
4305
4306 if (!NILP (Vtemp_buffer_show_function))
4307 call1 (Vtemp_buffer_show_function, buf);
4308 else if (WINDOW_LIVE_P (window = display_buffer (buf, Qnil, Qnil)))
4309 {
4310 if (!EQ (XWINDOW (window)->frame, selected_frame))
4311 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
4312 Vminibuf_scroll_window = window;
4313 w = XWINDOW (window);
4314 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
4315 w->suspend_auto_hscroll = false;
4316 set_marker_restricted_both (w->start, buf, BEG, BEG);
4317 set_marker_restricted_both (w->pointm, buf, BEG, BEG);
4318 set_marker_restricted_both (w->old_pointm, buf, BEG, BEG);
4319
4320
4321
4322 {
4323 specpdl_ref count = SPECPDL_INDEX ();
4324 Lisp_Object prev_window, prev_buffer;
4325 prev_window = selected_window;
4326 XSETBUFFER (prev_buffer, old);
4327
4328
4329
4330
4331
4332 record_unwind_protect (restore_buffer, prev_buffer);
4333 record_unwind_protect (select_window_norecord, prev_window);
4334 Fselect_window (window, Qt);
4335 Fset_buffer (w->contents);
4336 run_hook (Qtemp_buffer_show_hook);
4337 unbind_to (count, Qnil);
4338 }
4339 }
4340 }
4341
4342
4343
4344 static struct window *
4345 allocate_window (void)
4346 {
4347 return ALLOCATE_ZEROED_PSEUDOVECTOR (struct window, mode_line_help_echo,
4348 PVEC_WINDOW);
4349 }
4350
4351
4352
4353
4354 static void
4355 make_parent_window (Lisp_Object window, bool horflag)
4356 {
4357 Lisp_Object parent;
4358 register struct window *o, *p;
4359
4360 o = XWINDOW (window);
4361 p = allocate_window ();
4362 memcpy ((char *) p + sizeof (union vectorlike_header),
4363 (char *) o + sizeof (union vectorlike_header),
4364 word_size * VECSIZE (struct window));
4365
4366 adjust_window_count (p, 1);
4367 XSETWINDOW (parent, p);
4368
4369 p->sequence_number = ++sequence_number;
4370
4371 replace_window (window, parent, true);
4372
4373 wset_next (o, Qnil);
4374 wset_prev (o, Qnil);
4375 wset_parent (o, parent);
4376
4377 wset_start (p, Qnil);
4378 wset_pointm (p, Qnil);
4379 wset_old_pointm (p, Qnil);
4380 wset_buffer (p, Qnil);
4381 wset_combination (p, horflag, window);
4382 wset_combination_limit (p, Qnil);
4383 wset_window_parameters (p, Qnil);
4384 }
4385
4386
4387 Lisp_Object
4388 make_window (void)
4389 {
4390 Lisp_Object window;
4391 register struct window *w;
4392
4393 w = allocate_window ();
4394
4395
4396 wset_normal_lines (w, make_float (1.0));
4397 wset_normal_cols (w, make_float (1.0));
4398 wset_new_total (w, make_fixnum (0));
4399 wset_new_normal (w, make_fixnum (0));
4400 wset_new_pixel (w, make_fixnum (0));
4401 wset_start (w, Fmake_marker ());
4402 wset_pointm (w, Fmake_marker ());
4403 wset_old_pointm (w, Fmake_marker ());
4404 wset_vertical_scroll_bar_type (w, Qt);
4405 wset_horizontal_scroll_bar_type (w, Qt);
4406
4407
4408 wset_prev_buffers (w, Qnil);
4409 wset_next_buffers (w, Qnil);
4410
4411
4412
4413 w->nrows_scale_factor = w->ncols_scale_factor = 1;
4414 w->left_fringe_width = w->right_fringe_width = -1;
4415 w->mode_line_height = w->tab_line_height = w->header_line_height = -1;
4416 #ifdef HAVE_WINDOW_SYSTEM
4417 w->phys_cursor_type = NO_CURSOR;
4418 w->phys_cursor_width = -1;
4419 #endif
4420 w->sequence_number = ++sequence_number;
4421 w->scroll_bar_width = -1;
4422 w->scroll_bar_height = -1;
4423 w->column_number_displayed = -1;
4424
4425 Vwindow_list = Qnil;
4426
4427 XSETWINDOW (window, w);
4428 return window;
4429 }
4430
4431 DEFUN ("set-window-new-pixel", Fset_window_new_pixel, Sset_window_new_pixel, 2, 3, 0,
4432 doc:
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443 )
4444 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
4445 {
4446 struct window *w = decode_valid_window (window);
4447 EMACS_INT size_min = NILP (add) ? 0 : - XFIXNUM (w->new_pixel);
4448 EMACS_INT size_max = size_min + min (INT_MAX, MOST_POSITIVE_FIXNUM);
4449
4450 int checked_size = check_integer_range (size, size_min, size_max);
4451 if (NILP (add))
4452 wset_new_pixel (w, size);
4453 else
4454 wset_new_pixel (w, make_fixnum (XFIXNUM (w->new_pixel) + checked_size));
4455
4456 return w->new_pixel;
4457 }
4458
4459 DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
4460 doc:
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471 )
4472 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
4473 {
4474 struct window *w = decode_valid_window (window);
4475
4476 CHECK_FIXNUM (size);
4477 if (NILP (add))
4478 wset_new_total (w, size);
4479 else
4480 wset_new_total (w, make_fixnum (XFIXNUM (w->new_total) + XFIXNUM (size)));
4481
4482 return w->new_total;
4483 }
4484
4485 DEFUN ("set-window-new-normal", Fset_window_new_normal, Sset_window_new_normal, 1, 2, 0,
4486 doc:
4487
4488
4489
4490
4491
4492
4493 )
4494 (Lisp_Object window, Lisp_Object size)
4495 {
4496 wset_new_normal (decode_valid_window (window), size);
4497 return size;
4498 }
4499
4500
4501
4502
4503
4504
4505
4506
4507 static bool
4508 window_resize_check (struct window *w, bool horflag)
4509 {
4510 struct frame *f = XFRAME (w->frame);
4511 struct window *c;
4512
4513 if (WINDOW_VERTICAL_COMBINATION_P (w))
4514
4515 {
4516 c = XWINDOW (w->contents);
4517 if (horflag)
4518
4519 {
4520 while (c)
4521 {
4522 if (XFIXNUM (c->new_pixel) != XFIXNUM (w->new_pixel)
4523 || !window_resize_check (c, horflag))
4524 return false;
4525
4526 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4527 }
4528
4529 return true;
4530 }
4531 else
4532
4533
4534 {
4535 int remaining_pixels = XFIXNUM (w->new_pixel);
4536
4537 while (c)
4538 {
4539 if (!window_resize_check (c, horflag))
4540 return false;
4541
4542 remaining_pixels -= XFIXNUM (c->new_pixel);
4543 if (remaining_pixels < 0)
4544 return false;
4545 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4546 }
4547
4548 return remaining_pixels == 0;
4549 }
4550 }
4551 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
4552
4553 {
4554 c = XWINDOW (w->contents);
4555 if (horflag)
4556
4557
4558 {
4559 int remaining_pixels = XFIXNUM (w->new_pixel);
4560
4561 while (c)
4562 {
4563 if (!window_resize_check (c, horflag))
4564 return false;
4565
4566 remaining_pixels -= XFIXNUM (c->new_pixel);
4567 if (remaining_pixels < 0)
4568 return false;
4569 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4570 }
4571
4572 return remaining_pixels == 0;
4573 }
4574 else
4575
4576 {
4577 while (c)
4578 {
4579 if (XFIXNUM (c->new_pixel) != XFIXNUM (w->new_pixel)
4580 || !window_resize_check (c, horflag))
4581 return false;
4582
4583 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4584 }
4585
4586 return true;
4587 }
4588 }
4589 else
4590
4591
4592
4593 return (XFIXNUM (w->new_pixel) >= (horflag
4594 ? 2 * FRAME_COLUMN_WIDTH (f)
4595 : FRAME_LINE_HEIGHT (f)));
4596 }
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606 static void
4607 window_resize_apply (struct window *w, bool horflag)
4608 {
4609 struct window *c;
4610 int edge;
4611 int unit = (horflag
4612 ? FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))
4613 : FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
4614
4615
4616
4617 if (horflag)
4618 {
4619 w->pixel_width = XFIXNAT (w->new_pixel);
4620 w->total_cols = w->pixel_width / unit;
4621 if (NUMBERP (w->new_normal))
4622 wset_normal_cols (w, w->new_normal);
4623
4624 edge = w->pixel_left;
4625 }
4626 else
4627 {
4628 w->pixel_height = XFIXNAT (w->new_pixel);
4629 w->total_lines = w->pixel_height / unit;
4630 if (NUMBERP (w->new_normal))
4631 wset_normal_lines (w, w->new_normal);
4632
4633 edge = w->pixel_top;
4634 }
4635
4636 if (WINDOW_VERTICAL_COMBINATION_P (w))
4637
4638 {
4639 c = XWINDOW (w->contents);
4640 while (c)
4641 {
4642 if (horflag)
4643 {
4644 c->pixel_left = edge;
4645 c->left_col = edge / unit;
4646 }
4647 else
4648 {
4649 c->pixel_top = edge;
4650 c->top_line = edge / unit;
4651 }
4652 window_resize_apply (c, horflag);
4653 if (!horflag)
4654 edge = edge + c->pixel_height;
4655
4656 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4657 }
4658 }
4659 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
4660
4661 {
4662 c = XWINDOW (w->contents);
4663 while (c)
4664 {
4665 if (horflag)
4666 {
4667 c->pixel_left = edge;
4668 c->left_col = edge / unit;
4669 }
4670 else
4671 {
4672 c->pixel_top = edge;
4673 c->top_line = edge / unit;
4674 }
4675
4676 window_resize_apply (c, horflag);
4677 if (horflag)
4678 edge = edge + c->pixel_width;
4679
4680 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4681 }
4682 }
4683 else
4684
4685 w->window_end_valid = false;
4686
4687 if (!WINDOW_PSEUDO_P (w))
4688 FRAME_WINDOW_CHANGE (WINDOW_XFRAME (w)) = true;
4689 }
4690
4691
4692
4693
4694
4695
4696 static void
4697 window_resize_apply_total (struct window *w, bool horflag)
4698 {
4699 struct window *c;
4700 int edge;
4701
4702
4703
4704 if (horflag)
4705 {
4706 w->total_cols = XFIXNAT (w->new_total);
4707 edge = w->left_col;
4708 }
4709 else
4710 {
4711 w->total_lines = XFIXNAT (w->new_total);
4712 edge = w->top_line;
4713 }
4714
4715 if (WINDOW_VERTICAL_COMBINATION_P (w))
4716
4717 {
4718 c = XWINDOW (w->contents);
4719 while (c)
4720 {
4721 if (horflag)
4722 c->left_col = edge;
4723 else
4724 c->top_line = edge;
4725
4726 window_resize_apply_total (c, horflag);
4727 if (!horflag)
4728 edge = edge + c->total_lines;
4729
4730 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4731 }
4732 }
4733 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
4734
4735 {
4736 c = XWINDOW (w->contents);
4737 while (c)
4738 {
4739 if (horflag)
4740 c->left_col = edge;
4741 else
4742 c->top_line = edge;
4743
4744 window_resize_apply_total (c, horflag);
4745 if (horflag)
4746 edge = edge + c->total_cols;
4747
4748 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4749 }
4750 }
4751 }
4752
4753 DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
4754 doc:
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771 )
4772 (Lisp_Object frame, Lisp_Object horizontal)
4773 {
4774 struct frame *f = decode_live_frame (frame);
4775 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
4776 bool horflag = !NILP (horizontal);
4777
4778 if (!window_resize_check (r, horflag)
4779 || (XFIXNUM (r->new_pixel)
4780 != (horflag ? r->pixel_width : r->pixel_height)))
4781 return Qnil;
4782
4783 block_input ();
4784 window_resize_apply (r, horflag);
4785
4786 fset_redisplay (f);
4787
4788 adjust_frame_glyphs (f);
4789 unblock_input ();
4790
4791 return Qt;
4792 }
4793
4794
4795 DEFUN ("window-resize-apply-total", Fwindow_resize_apply_total, Swindow_resize_apply_total, 0, 2, 0,
4796 doc:
4797
4798
4799
4800
4801
4802
4803
4804 )
4805 (Lisp_Object frame, Lisp_Object horizontal)
4806 {
4807 struct frame *f = decode_live_frame (frame);
4808 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
4809
4810 block_input ();
4811
4812 r->left_col = 0;
4813 r->top_line = FRAME_TOP_MARGIN (f);
4814 window_resize_apply_total (r, !NILP (horizontal));
4815
4816 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4817 {
4818 struct window *m = XWINDOW (f->minibuffer_window);
4819
4820 if (NILP (horizontal))
4821 {
4822 m->top_line = r->top_line + r->total_lines;
4823 m->total_lines = XFIXNAT (m->new_total);
4824 }
4825 else
4826 m->total_cols = XFIXNAT (m->new_total);
4827 }
4828
4829 unblock_input ();
4830
4831 return Qt;
4832 }
4833
4834
4835
4836
4837 void
4838 resize_frame_windows (struct frame *f, int size, bool horflag)
4839 {
4840 Lisp_Object root = f->root_window;
4841 struct window *r = XWINDOW (root);
4842 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
4843 int new_size, new_pixel_size;
4844 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
4845 Lisp_Object mini = f->minibuffer_window;
4846 struct window *m = WINDOWP (mini) ? XWINDOW (mini) : NULL;
4847 int mini_height = ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4848 ? (unit + m->pixel_height
4849 - window_body_height (m, WINDOW_BODY_IN_PIXELS))
4850 : 0);
4851
4852 new_pixel_size = max (horflag ? size : size - mini_height, unit);
4853 new_size = new_pixel_size / unit;
4854
4855 if (new_pixel_size == old_pixel_size
4856 && (horflag || r->pixel_top == FRAME_TOP_MARGIN_HEIGHT (f)))
4857 ;
4858 else if (WINDOW_LEAF_P (r))
4859 {
4860
4861 if (horflag)
4862 {
4863 r->total_cols = new_size;
4864 r->pixel_width = new_pixel_size;
4865 }
4866 else
4867 {
4868 r->top_line = FRAME_TOP_MARGIN (f);
4869 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4870
4871 r->total_lines = new_size;
4872 r->pixel_height = new_pixel_size;
4873 }
4874
4875 FRAME_WINDOW_CHANGE (f)
4876 = !WINDOW_PSEUDO_P (r) && new_pixel_size != old_pixel_size;
4877 }
4878 else
4879 {
4880 Lisp_Object delta;
4881
4882 if (!horflag)
4883 {
4884 r->top_line = FRAME_TOP_MARGIN (f);
4885 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4886 }
4887
4888 XSETINT (delta, new_pixel_size - old_pixel_size);
4889
4890
4891 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil, Qt);
4892 if (window_resize_check (r, horflag)
4893 && new_pixel_size == XFIXNUM (r->new_pixel))
4894 {
4895 window_resize_apply (r, horflag);
4896 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4897 }
4898 else
4899 {
4900
4901 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt, Qt);
4902 if (window_resize_check (r, horflag)
4903 && new_pixel_size == XFIXNUM (r->new_pixel))
4904 {
4905 window_resize_apply (r, horflag);
4906 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4907 }
4908 }
4909 }
4910
4911 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4912 {
4913 m = XWINDOW (mini);
4914 if (horflag)
4915 {
4916 m->total_cols = new_size;
4917 m->pixel_width = new_pixel_size;
4918 }
4919 else
4920 {
4921 m->total_lines = mini_height / unit;
4922 m->pixel_height = mini_height;
4923 m->top_line = r->top_line + r->total_lines;
4924 m->pixel_top = r->pixel_top + r->pixel_height;
4925 }
4926 }
4927
4928 fset_redisplay (f);
4929 }
4930
4931
4932 DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
4933 doc:
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953 )
4954 (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size)
4955 {
4956
4957
4958
4959
4960
4961
4962 Lisp_Object new, frame, reference;
4963 struct window *o, *p, *n, *r, *c;
4964 struct frame *f;
4965 bool horflag
4966
4967 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
4968
4969 CHECK_WINDOW (old);
4970 o = XWINDOW (old);
4971 frame = WINDOW_FRAME (o);
4972 f = XFRAME (frame);
4973
4974 CHECK_FIXNUM (pixel_size);
4975 EMACS_INT total_size
4976 = XFIXNUM (pixel_size) / (horflag
4977 ? FRAME_COLUMN_WIDTH (f)
4978 : FRAME_LINE_HEIGHT (f));
4979
4980
4981
4982
4983 bool combination_limit
4984 = (EQ (Vwindow_combination_limit, Qt)
4985 || NILP (o->parent)
4986 || (horflag
4987 ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
4988 : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent))));
4989
4990
4991 if (WINDOW_LIVE_P (old))
4992
4993 reference = old;
4994 else
4995
4996 reference = FRAME_SELECTED_WINDOW (f);
4997 r = XWINDOW (reference);
4998
4999
5000 if (MINI_WINDOW_P (o))
5001 error ("Attempt to split minibuffer window");
5002 else if (total_size < (horflag ? 2 : 1))
5003 error ("Size of new window too small (after split)");
5004 else if (!combination_limit && !NILP (Vwindow_combination_resize))
5005
5006
5007 {
5008 p = XWINDOW (o->parent);
5009
5010 wset_new_pixel
5011 (p, make_fixnum ((horflag ? p->pixel_width : p->pixel_height)
5012 - XFIXNUM (pixel_size)));
5013 if (!window_resize_check (p, horflag))
5014 error ("Window sizes don't fit");
5015 else
5016
5017 wset_new_pixel (p, make_fixnum (horflag ? p->pixel_width : p->pixel_height));
5018 }
5019 else
5020 {
5021 if (!window_resize_check (o, horflag))
5022 error ("Resizing old window failed");
5023 else if (XFIXNUM (pixel_size) + XFIXNUM (o->new_pixel)
5024 != (horflag ? o->pixel_width : o->pixel_height))
5025 error ("Sum of sizes of old and new window don't fit");
5026 }
5027
5028
5029 if (combination_limit)
5030 {
5031
5032
5033
5034 Lisp_Object new_normal
5035 = horflag ? o->normal_cols : o->normal_lines;
5036
5037 make_parent_window (old, horflag);
5038 p = XWINDOW (o->parent);
5039 if (EQ (Vwindow_combination_limit, Qt))
5040
5041
5042 wset_combination_limit (p, Qt);
5043
5044 wset_new_pixel
5045 (p, make_fixnum (horflag ? o->pixel_width : o->pixel_height));
5046 wset_new_total
5047 (p, make_fixnum (horflag ? o->total_cols : o->total_lines));
5048 wset_new_normal (p, new_normal);
5049 }
5050 else
5051 p = XWINDOW (o->parent);
5052
5053 fset_redisplay (f);
5054 new = make_window ();
5055 n = XWINDOW (new);
5056 wset_frame (n, frame);
5057 wset_parent (n, o->parent);
5058
5059 if (EQ (side, Qabove) || EQ (side, Qleft))
5060 {
5061 wset_prev (n, o->prev);
5062 if (NILP (n->prev))
5063 wset_combination (p, horflag, new);
5064 else
5065 wset_next (XWINDOW (n->prev), new);
5066 wset_next (n, old);
5067 wset_prev (o, new);
5068 }
5069 else
5070 {
5071 wset_next (n, o->next);
5072 if (!NILP (n->next))
5073 wset_prev (XWINDOW (n->next), new);
5074 wset_prev (n, old);
5075 wset_next (o, new);
5076 }
5077
5078 n->window_end_valid = false;
5079 n->last_cursor_vpos = 0;
5080
5081
5082 n->left_margin_cols = r->left_margin_cols;
5083 n->right_margin_cols = r->right_margin_cols;
5084 n->left_fringe_width = r->left_fringe_width;
5085 n->right_fringe_width = r->right_fringe_width;
5086 n->fringes_outside_margins = r->fringes_outside_margins;
5087 n->scroll_bar_width = r->scroll_bar_width;
5088 n->scroll_bar_height = r->scroll_bar_height;
5089 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
5090 wset_horizontal_scroll_bar_type (n, r->horizontal_scroll_bar_type);
5091
5092
5093 if (horflag)
5094 {
5095 n->pixel_top = o->pixel_top;
5096 n->top_line = o->top_line;
5097 n->pixel_height = o->pixel_height;
5098 n->total_lines = o->total_lines;
5099 }
5100 else
5101 {
5102 n->pixel_left = o->pixel_left;
5103 n->left_col = o->left_col;
5104 n->pixel_width = o->pixel_width;
5105 n->total_cols = o->total_cols;
5106 }
5107
5108
5109
5110 wset_new_pixel (n, pixel_size);
5111 EMACS_INT sum = 0;
5112 c = XWINDOW (p->contents);
5113 while (c)
5114 {
5115 if (c != n)
5116 sum = sum + XFIXNUM (c->new_total);
5117 c = NILP (c->next) ? 0 : XWINDOW (c->next);
5118 }
5119 wset_new_total (n, make_fixnum ((horflag
5120 ? p->total_cols
5121 : p->total_lines)
5122 - sum));
5123 wset_new_normal (n, normal_size);
5124
5125 block_input ();
5126 window_resize_apply (p, horflag);
5127 adjust_frame_glyphs (f);
5128
5129 set_window_buffer (new, r->contents, true, true);
5130 FRAME_WINDOW_CHANGE (f) = true;
5131 unblock_input ();
5132
5133 return new;
5134 }
5135
5136
5137 DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0,
5138 doc:
5139
5140 )
5141 (Lisp_Object window)
5142 {
5143 Lisp_Object parent, sibling, frame, root;
5144 struct window *w, *p, *s, *r;
5145 struct frame *f;
5146 bool horflag, before_sibling = false;
5147
5148 w = decode_any_window (window);
5149 XSETWINDOW (window, w);
5150 if (NILP (w->contents))
5151
5152 return Qnil;
5153
5154 parent = w->parent;
5155 if (NILP (parent))
5156
5157 error ("Attempt to delete minibuffer or sole ordinary window");
5158 else if (NILP (w->prev) && NILP (w->next))
5159
5160
5161 error ("Attempt to delete sole window of parent");
5162
5163 p = XWINDOW (parent);
5164 horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
5165
5166 frame = WINDOW_FRAME (w);
5167 f = XFRAME (frame);
5168
5169 root = FRAME_ROOT_WINDOW (f);
5170 r = XWINDOW (root);
5171
5172
5173 if (NILP (w->prev))
5174
5175 {
5176
5177
5178 before_sibling = true;
5179 sibling = w->next;
5180 s = XWINDOW (sibling);
5181 wset_prev (s, Qnil);
5182 wset_combination (p, horflag, sibling);
5183 }
5184 else
5185
5186 {
5187 sibling = w->prev;
5188 s = XWINDOW (sibling);
5189 wset_next (s, w->next);
5190 if (!NILP (s->next))
5191 wset_prev (XWINDOW (s->next), sibling);
5192 }
5193
5194 if (window_resize_check (r, horflag)
5195 && (XFIXNUM (r->new_pixel)
5196 == (horflag ? r->pixel_width : r->pixel_height)))
5197
5198 {
5199
5200
5201 block_input ();
5202 xwidget_view_delete_all_in_window (w);
5203 window_resize_apply (p, horflag);
5204
5205
5206 if (!FRAME_INITIAL_P (f))
5207 {
5208 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
5209
5210 if (EQ (hlinfo->mouse_face_window, window))
5211 hlinfo->mouse_face_window = Qnil;
5212 }
5213
5214 fset_redisplay (f);
5215 Vwindow_list = Qnil;
5216
5217 wset_next (w, Qnil);
5218 free_window_matrices (w);
5219
5220 if (WINDOWP (w->contents))
5221 {
5222 delete_all_child_windows (w->contents);
5223 wset_combination (w, false, Qnil);
5224 }
5225 else
5226 {
5227 unshow_buffer (w);
5228 unchain_marker (XMARKER (w->pointm));
5229 unchain_marker (XMARKER (w->old_pointm));
5230 unchain_marker (XMARKER (w->start));
5231 wset_buffer (w, Qnil);
5232 }
5233
5234 if (NILP (s->prev) && NILP (s->next))
5235
5236
5237 {
5238
5239 replace_window (parent, sibling, false);
5240
5241
5242 wset_normal_cols (s, p->normal_cols);
5243 wset_normal_lines (s, p->normal_lines);
5244
5245 wset_combination (p, false, Qnil);
5246
5247 recombine_windows (sibling);
5248 }
5249
5250 adjust_frame_glyphs (f);
5251
5252 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
5253
5254
5255
5256 {
5257
5258 Lisp_Object new_selected_window = Fframe_first_window (frame);
5259
5260 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
5261 Fselect_window (new_selected_window, Qt);
5262 else
5263
5264
5265
5266 fset_selected_window (f, new_selected_window);
5267 }
5268
5269 unblock_input ();
5270 FRAME_WINDOW_CHANGE (f) = true;
5271 }
5272 else
5273
5274 {
5275 if (before_sibling)
5276 {
5277 wset_prev (s, window);
5278 wset_combination (p, horflag, window);
5279 }
5280 else
5281 {
5282 wset_next (s, window);
5283 if (!NILP (w->next))
5284 wset_prev (XWINDOW (w->next), window);
5285 }
5286 error ("Deletion failed");
5287 }
5288
5289 return Qnil;
5290 }
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302 static void
5303 resize_mini_window_apply (struct window *w, int delta)
5304 {
5305 struct frame *f = XFRAME (w->frame);
5306 Lisp_Object root = FRAME_ROOT_WINDOW (f);
5307 struct window *r = XWINDOW (root);
5308
5309 block_input ();
5310 w->pixel_height = w->pixel_height + delta;
5311 w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
5312
5313 window_resize_apply (r, false);
5314
5315 w->pixel_top = r->pixel_top + r->pixel_height;
5316 w->top_line = r->top_line + r->total_lines;
5317
5318
5319
5320 fset_redisplay (f);
5321 adjust_frame_glyphs (f);
5322 unblock_input ();
5323 }
5324
5325
5326
5327
5328
5329
5330
5331
5332 void
5333 grow_mini_window (struct window *w, int delta)
5334 {
5335 struct frame *f = XFRAME (w->frame);
5336 int old_height = window_body_height (w, WINDOW_BODY_IN_PIXELS);
5337 int min_height = FRAME_LINE_HEIGHT (f);
5338
5339 eassert (MINI_WINDOW_P (w));
5340
5341
5342 if (old_height + delta < min_height)
5343 delta = old_height > min_height ? min_height - old_height : 0;
5344
5345 if (delta != 0)
5346 {
5347 Lisp_Object root = FRAME_ROOT_WINDOW (f);
5348 struct window *r = XWINDOW (root);
5349 Lisp_Object grow;
5350
5351 FRAME_WINDOWS_FROZEN (f) = true;
5352 grow = call3 (Qwindow__resize_root_window_vertically,
5353 root, make_fixnum (- delta), Qt);
5354
5355 if (FIXNUMP (grow) && window_resize_check (r, false))
5356 resize_mini_window_apply (w, -XFIXNUM (grow));
5357 }
5358 }
5359
5360
5361
5362
5363
5364
5365
5366 void
5367 shrink_mini_window (struct window *w)
5368 {
5369 struct frame *f = XFRAME (w->frame);
5370 int delta = (window_body_height (w, WINDOW_BODY_IN_PIXELS)
5371 - FRAME_LINE_HEIGHT (f));
5372
5373 eassert (MINI_WINDOW_P (w));
5374
5375 if (delta > 0)
5376 {
5377 Lisp_Object root = FRAME_ROOT_WINDOW (f);
5378 struct window *r = XWINDOW (root);
5379 Lisp_Object grow;
5380
5381 FRAME_WINDOWS_FROZEN (f) = false;
5382 grow = call3 (Qwindow__resize_root_window_vertically,
5383 root, make_fixnum (delta), Qt);
5384
5385 if (FIXNUMP (grow) && window_resize_check (r, false))
5386 resize_mini_window_apply (w, -XFIXNUM (grow));
5387 }
5388 else if (delta < 0)
5389
5390
5391 grow_mini_window (w, -delta);
5392
5393 }
5394
5395 DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal,
5396 Sresize_mini_window_internal, 1, 1, 0,
5397 doc: )
5398 (Lisp_Object window)
5399 {
5400 struct window *w = XWINDOW (window);
5401 struct window *r;
5402 struct frame *f;
5403 int old_height, delta;
5404
5405 CHECK_LIVE_WINDOW (window);
5406 f = XFRAME (w->frame);
5407
5408 if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
5409 error ("Not a valid minibuffer window");
5410 else if (FRAME_MINIBUF_ONLY_P (f))
5411 error ("Cannot resize a minibuffer-only frame");
5412
5413 r = XWINDOW (FRAME_ROOT_WINDOW (f));
5414 old_height = r->pixel_height + w->pixel_height;
5415 delta = XFIXNUM (w->new_pixel) - w->pixel_height;
5416 if (window_resize_check (r, false)
5417 && XFIXNUM (w->new_pixel) > 0
5418 && old_height == XFIXNUM (r->new_pixel) + XFIXNUM (w->new_pixel))
5419 {
5420 resize_mini_window_apply (w, delta);
5421
5422 return Qt;
5423 }
5424 else
5425 error ("Cannot resize mini window");
5426 }
5427
5428
5429
5430
5431
5432
5433 void
5434 mark_window_cursors_off (struct window *w)
5435 {
5436 while (w)
5437 {
5438 if (WINDOWP (w->contents))
5439 mark_window_cursors_off (XWINDOW (w->contents));
5440 else
5441 w->phys_cursor_on_p = false;
5442
5443 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5444 }
5445 }
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460 bool
5461 window_wants_mode_line (struct window *w)
5462 {
5463 Lisp_Object window_mode_line_format =
5464 window_parameter (w, Qmode_line_format);
5465
5466 return (WINDOW_LEAF_P (w)
5467 && !MINI_WINDOW_P (w)
5468 && !WINDOW_PSEUDO_P (w)
5469 && !EQ (window_mode_line_format, Qnone)
5470 && (!NILP (window_mode_line_format)
5471 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), mode_line_format)))
5472 && WINDOW_PIXEL_HEIGHT (w) > WINDOW_FRAME_LINE_HEIGHT (w));
5473 }
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490 bool
5491 window_wants_header_line (struct window *w)
5492 {
5493 Lisp_Object window_header_line_format =
5494 window_parameter (w, Qheader_line_format);
5495
5496 return (WINDOW_LEAF_P (w)
5497 && !MINI_WINDOW_P (w)
5498 && !WINDOW_PSEUDO_P (w)
5499 && !EQ (window_header_line_format, Qnone)
5500 && (!NILP (window_header_line_format)
5501 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), header_line_format)))
5502 && (WINDOW_PIXEL_HEIGHT (w)
5503 > (window_wants_mode_line (w)
5504 ? 2 * WINDOW_FRAME_LINE_HEIGHT (w)
5505 : WINDOW_FRAME_LINE_HEIGHT (w))));
5506 }
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524 bool
5525 window_wants_tab_line (struct window *w)
5526 {
5527 Lisp_Object window_tab_line_format =
5528 window_parameter (w, Qtab_line_format);
5529
5530 return (WINDOW_LEAF_P (w)
5531 && !MINI_WINDOW_P (w)
5532 && !WINDOW_PSEUDO_P (w)
5533 && !EQ (window_tab_line_format, Qnone)
5534 && (!NILP (window_tab_line_format)
5535 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), tab_line_format)))
5536 && (WINDOW_PIXEL_HEIGHT (w)
5537 > (((window_wants_mode_line (w) ? 1 : 0)
5538 + (window_wants_header_line (w) ? 1 : 0)
5539 + 1) * WINDOW_FRAME_LINE_HEIGHT (w))));
5540 }
5541
5542
5543
5544
5545
5546
5547 int
5548 window_internal_height (struct window *w)
5549 {
5550 int ht = w->total_lines;
5551
5552 if (window_wants_mode_line (w))
5553 --ht;
5554
5555 if (window_wants_header_line (w))
5556 --ht;
5557
5558 if (window_wants_tab_line (w))
5559 --ht;
5560
5561 return ht;
5562 }
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576 static void
5577 window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror)
5578 {
5579 struct window *w = XWINDOW (window);
5580 struct buffer *b = XBUFFER (w->contents);
5581 bool long_lines_truncated =
5582 b->long_line_optimizations_p && !NILP (BVAR (b, truncate_lines));
5583 specpdl_ref count = SPECPDL_INDEX ();
5584
5585 n = clip_to_bounds (INT_MIN, n, INT_MAX);
5586
5587 wset_redisplay (w);
5588
5589
5590 if (b->long_line_optimizations_p
5591 && !long_lines_truncated
5592 && !NILP (Vtruncate_partial_width_windows)
5593 && w->total_cols < FRAME_COLS (XFRAME (WINDOW_FRAME (w))))
5594 {
5595 if (FIXNUMP (Vtruncate_partial_width_windows))
5596 long_lines_truncated =
5597 w->total_cols < XFIXNAT (Vtruncate_partial_width_windows);
5598 else
5599 long_lines_truncated = true;
5600 }
5601
5602 if (whole && (fast_but_imprecise_scrolling || long_lines_truncated))
5603 specbind (Qfontification_functions, Qnil);
5604
5605 if (whole && long_lines_truncated)
5606 window_scroll_for_long_lines (w, n, noerror);
5607 else if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
5608 {
5609
5610
5611
5612
5613 record_unwind_protect_void (unwind_display_working_on_window);
5614 display_working_on_window_p = true;
5615 window_scroll_pixel_based (window, n, whole, noerror);
5616 }
5617 else
5618 window_scroll_line_based (window, n, whole, noerror);
5619
5620 unbind_to (count, Qnil);
5621
5622
5623 XWINDOW (window)->window_end_valid = false;
5624 }
5625
5626
5627
5628
5629
5630 int
5631 window_scroll_margin (struct window *window, enum margin_unit unit)
5632 {
5633 if (scroll_margin > 0)
5634 {
5635 int frame_line_height = default_line_pixel_height (window);
5636 int window_lines = window_box_height (window) / frame_line_height;
5637
5638 double ratio = 0.25;
5639 if (FLOATP (Vmaximum_scroll_margin))
5640 {
5641 ratio = XFLOAT_DATA (Vmaximum_scroll_margin);
5642 ratio = max (0.0, ratio);
5643 ratio = min (ratio, 0.5);
5644 }
5645 int max_margin = min ((window_lines - 1)/2,
5646 (int) (window_lines * ratio));
5647 int margin = clip_to_bounds (0, scroll_margin, max_margin);
5648 return (unit == MARGIN_IN_PIXELS)
5649 ? margin * frame_line_height
5650 : margin;
5651 }
5652 else
5653 return 0;
5654 }
5655
5656 static int
5657 sanitize_next_screen_context_lines (void)
5658 {
5659 return clip_to_bounds (0, next_screen_context_lines, 1000000);
5660 }
5661
5662
5663
5664
5665 static void
5666 window_scroll_for_long_lines (struct window *w, int n, bool noerror)
5667 {
5668 ptrdiff_t startpos = marker_position (w->start);
5669 ptrdiff_t startbyte = marker_byte_position (w->start);
5670 int nscls = sanitize_next_screen_context_lines ();
5671 register int ht = window_internal_height (w);
5672
5673 n *= max (1, ht - nscls);
5674
5675
5676 struct position pos;
5677 int rtop, rbot, dummy_rowh, dummy_vpos, dummy_x, dummy_y;
5678 if (!(PT >= startpos
5679 && PT <= ZV
5680 && startpos <= ZV
5681 && pos_visible_p (w, PT, &dummy_x, &dummy_y, &rtop, &rbot, &dummy_rowh,
5682 &dummy_vpos)
5683 && !rtop && !rbot))
5684 {
5685 pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
5686 startpos = pos.bufpos;
5687 startbyte = pos.bytepos;
5688 }
5689 SET_PT_BOTH (startpos, startbyte);
5690
5691 bool lose = n < 0 && PT == BEGV;
5692 pos = *vmotion (PT, PT_BYTE, n, w);
5693 if (lose)
5694 {
5695 if (noerror)
5696 return;
5697 else
5698 xsignal0 (Qbeginning_of_buffer);
5699 }
5700
5701 bool bolp = pos.bufpos == BEGV || FETCH_BYTE (pos.bytepos - 1) == '\n';
5702 if (pos.bufpos < ZV)
5703 {
5704 set_marker_restricted_both (w->start, w->contents,
5705 pos.bufpos, pos.bytepos);
5706 w->start_at_line_beg = bolp;
5707 wset_update_mode_line (w);
5708
5709
5710 w->force_start = true;
5711 SET_PT_BOTH (pos.bufpos, pos.bytepos);
5712 if (n > 0)
5713 pos = *vmotion (PT, PT_BYTE, ht / 2, w);
5714 else if (n < 0)
5715 pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
5716 SET_PT_BOTH (pos.bufpos, pos.bytepos);
5717 }
5718 else
5719 {
5720 if (noerror)
5721 return;
5722 else
5723 xsignal0 (Qend_of_buffer);
5724 }
5725 }
5726
5727
5728
5729
5730
5731 static void
5732 window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5733 {
5734 struct it it;
5735 struct window *w = XWINDOW (window);
5736 struct text_pos start;
5737 int this_scroll_margin;
5738
5739 bool vscrolled = false;
5740 int x, y, rtop, rbot, rowh, vpos;
5741 void *itdata = NULL;
5742 int frame_line_height = default_line_pixel_height (w);
5743 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
5744 Fwindow_old_point (window)));
5745
5746 SET_TEXT_POS_FROM_MARKER (start, w->start);
5747
5748
5749
5750
5751 if (CHARPOS (start) > ZV || CHARPOS (start) < BEGV)
5752 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5753
5754
5755
5756
5757
5758
5759 if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
5760 {
5761 itdata = bidi_shelve_cache ();
5762
5763
5764
5765 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5766 it.current_y = it.last_visible_y;
5767 move_it_vertically_backward (&it, window_box_height (w) / 2);
5768
5769
5770
5771
5772
5773
5774 if (it.current_y <= 0)
5775 {
5776 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5777 move_it_vertically_backward (&it, 0);
5778 it.current_y = 0;
5779 }
5780
5781 start = it.current.pos;
5782 bidi_unshelve_cache (itdata, false);
5783 }
5784 else if (auto_window_vscroll_p)
5785 {
5786 if (rtop || rbot)
5787 {
5788 int px;
5789 int dy = frame_line_height;
5790
5791
5792
5793
5794
5795 if (whole)
5796 {
5797 int ht = window_box_height (w);
5798 int nscls = sanitize_next_screen_context_lines ();
5799 dy = max (dy, (ht / dy - nscls) * dy);
5800 }
5801 dy *= n;
5802
5803 if (n < 0)
5804 {
5805
5806 if (w->vscroll < 0 && rtop > 0)
5807 {
5808 px = max (0, -w->vscroll - min (rtop, -dy));
5809 Fset_window_vscroll (window, make_fixnum (px), Qt,
5810 Qnil);
5811 return;
5812 }
5813 }
5814 if (n > 0)
5815 {
5816
5817 if (rbot > 0 && (w->vscroll < 0 || vpos == 0))
5818 {
5819 px = max (0, -w->vscroll + min (rbot, dy));
5820 Fset_window_vscroll (window, make_fixnum (px), Qt,
5821 Qnil);
5822 return;
5823 }
5824
5825
5826 if (rbot > 0 || w->vscroll < 0)
5827 {
5828 ptrdiff_t spos;
5829
5830 Fset_window_vscroll (window, make_fixnum (0), Qt,
5831 Qnil);
5832
5833
5834 if (rbot > 0)
5835 spos = XFIXNUM (Fline_beginning_position (Qnil));
5836 else
5837 spos = min (XFIXNUM (Fline_end_position (Qnil)) + 1, ZV);
5838 set_marker_restricted (w->start, make_fixnum (spos),
5839 w->contents);
5840 w->start_at_line_beg = true;
5841 wset_update_mode_line (w);
5842
5843
5844 w->force_start = true;
5845 return;
5846 }
5847 }
5848 }
5849
5850 Fset_window_vscroll (window, make_fixnum (0), Qt, Qnil);
5851 }
5852
5853 itdata = bidi_shelve_cache ();
5854
5855
5856 if (!NILP (Vscroll_preserve_screen_position))
5857 {
5858
5859
5860
5861
5862
5863 if (window_scroll_pixel_based_preserve_y < 0
5864 || !SYMBOLP (KVAR (current_kboard, Vlast_command))
5865 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
5866 {
5867 start_display (&it, w, start);
5868 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
5869 window_scroll_pixel_based_preserve_y = it.current_y;
5870 window_scroll_pixel_based_preserve_x = it.current_x;
5871 }
5872 }
5873 else
5874 window_scroll_pixel_based_preserve_y
5875 = window_scroll_pixel_based_preserve_x = -1;
5876
5877
5878
5879 start_display (&it, w, start);
5880 if (whole)
5881 {
5882 ptrdiff_t start_pos = IT_CHARPOS (it);
5883 int flh = frame_line_height;
5884 int ht = window_box_height (w);
5885 int nscls = sanitize_next_screen_context_lines ();
5886
5887
5888
5889
5890
5891 int dy = n * max (flh, (ht / flh - nscls) * flh);
5892 int goal_y;
5893 void *it_data;
5894
5895
5896
5897
5898 if (dy <= 0)
5899 {
5900 goal_y = it.current_y + dy;
5901 move_it_vertically_backward (&it, -dy);
5902
5903
5904
5905
5906
5907 if (goal_y - it.current_y > 0.5 * flh)
5908 {
5909 it_data = bidi_shelve_cache ();
5910 struct it it1 = it;
5911 if (line_bottom_y (&it1) - goal_y < goal_y - it.current_y)
5912 move_it_by_lines (&it, 1);
5913 bidi_unshelve_cache (it_data, true);
5914 }
5915
5916
5917 while (start_pos == IT_CHARPOS (it)
5918 && start_pos > BEGV)
5919 move_it_by_lines (&it, -1);
5920 }
5921 else if (dy > 0)
5922 {
5923 goal_y = it.current_y + dy;
5924 move_it_to (&it, ZV, -1, goal_y, -1, MOVE_TO_POS | MOVE_TO_Y);
5925
5926
5927
5928
5929
5930 if (!NILP (Vscroll_preserve_screen_position)
5931 && goal_y - it.current_y > 0.5 * flh)
5932 {
5933 it_data = bidi_shelve_cache ();
5934 struct it it2 = it;
5935
5936 move_it_by_lines (&it, 1);
5937 if (it.current_y > goal_y + 0.5 * flh)
5938 {
5939 it = it2;
5940 bidi_unshelve_cache (it_data, false);
5941 }
5942 else
5943 bidi_unshelve_cache (it_data, true);
5944 }
5945
5946
5947 while (start_pos == IT_CHARPOS (it)
5948 && start_pos < ZV)
5949 move_it_by_lines (&it, 1);
5950 }
5951 }
5952 else
5953 move_it_by_lines (&it, n);
5954
5955
5956
5957
5958 if ((n > 0 && IT_CHARPOS (it) == ZV)
5959 || (n < 0 && IT_CHARPOS (it) == CHARPOS (start)))
5960 {
5961 if (IT_CHARPOS (it) == ZV)
5962 {
5963 if (it.current_y < it.last_visible_y
5964 && (it.current_y + it.max_ascent + it.max_descent
5965 > it.last_visible_y))
5966 {
5967
5968
5969 w->vscroll = (it.last_visible_y
5970 - it.current_y + it.max_ascent + it.max_descent);
5971 adjust_frame_glyphs (it.f);
5972 }
5973 else
5974 {
5975 bidi_unshelve_cache (itdata, false);
5976 if (noerror)
5977 return;
5978 else if (n < 0)
5979 xsignal0 (Qbeginning_of_buffer);
5980 else
5981 xsignal0 (Qend_of_buffer);
5982 }
5983 }
5984 else
5985 {
5986 if (w->vscroll != 0)
5987
5988
5989 w->vscroll = 0;
5990 else
5991 {
5992 bidi_unshelve_cache (itdata, false);
5993 if (noerror)
5994 return;
5995 else
5996 xsignal0 (Qbeginning_of_buffer);
5997 }
5998 }
5999
6000
6001
6002 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true;
6003
6004
6005 vscrolled = true;
6006 }
6007
6008 if (! vscrolled)
6009 {
6010 ptrdiff_t pos = IT_CHARPOS (it);
6011 ptrdiff_t bytepos;
6012
6013
6014
6015 if (in_display_vector_p (&it))
6016 {
6017 ++pos;
6018 move_it_to (&it, pos, -1, -1, -1, MOVE_TO_POS);
6019 }
6020
6021
6022 set_marker_restricted_both (w->start, w->contents, IT_CHARPOS (it),
6023 IT_BYTEPOS (it));
6024 bytepos = marker_byte_position (w->start);
6025 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
6026 wset_update_mode_line (w);
6027
6028
6029 w->force_start = true;
6030 }
6031
6032
6033
6034 it.current_y = it.vpos = 0;
6035
6036
6037
6038
6039 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
6040
6041 if (n > 0)
6042 {
6043 int last_y = it.last_visible_y - this_scroll_margin - 1;
6044
6045
6046
6047 if (IT_CHARPOS (it) < PT)
6048 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
6049 if (IT_CHARPOS (it) == PT
6050 && it.current_y >= this_scroll_margin
6051 && it.current_y <= last_y - WINDOW_TAB_LINE_HEIGHT (w)
6052 - WINDOW_HEADER_LINE_HEIGHT (w)
6053 && (NILP (Vscroll_preserve_screen_position)
6054 || EQ (Vscroll_preserve_screen_position, Qt)))
6055
6056 ;
6057 else
6058 {
6059 if (window_scroll_pixel_based_preserve_y >= 0)
6060 {
6061
6062 int goal_y = min (last_y, window_scroll_pixel_based_preserve_y);
6063
6064
6065
6066 move_it_to (&it, -1,
6067 window_scroll_pixel_based_preserve_x,
6068 goal_y - WINDOW_TAB_LINE_HEIGHT (w)
6069 - WINDOW_HEADER_LINE_HEIGHT (w),
6070 -1, MOVE_TO_Y | MOVE_TO_X);
6071 }
6072
6073
6074 while (it.current_y < this_scroll_margin)
6075 {
6076 int prev = it.current_y;
6077 move_it_by_lines (&it, 1);
6078 if (prev == it.current_y)
6079 break;
6080 }
6081 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
6082
6083
6084 if (window_scroll_pixel_based_preserve_y >= 0
6085 && window_scroll_pixel_based_preserve_y < this_scroll_margin)
6086 window_scroll_pixel_based_preserve_y = this_scroll_margin;
6087 }
6088 }
6089 else if (n < 0)
6090 {
6091 ptrdiff_t charpos, bytepos;
6092 bool partial_p;
6093
6094
6095
6096 charpos = IT_CHARPOS (it);
6097 bytepos = IT_BYTEPOS (it);
6098
6099
6100
6101 move_it_to (&it, PT, -1,
6102
6103
6104
6105 (it.last_visible_y - WINDOW_TAB_LINE_HEIGHT (w)
6106 - WINDOW_HEADER_LINE_HEIGHT (w)
6107 - partial_line_height (&it) - this_scroll_margin - 1),
6108 -1,
6109 MOVE_TO_POS | MOVE_TO_Y);
6110
6111
6112 charpos = IT_CHARPOS (it);
6113 bytepos = IT_BYTEPOS (it);
6114
6115
6116
6117
6118
6119
6120 if (charpos != PT)
6121 {
6122 struct it it2;
6123 void *it_data;
6124
6125 it2 = it;
6126 it_data = bidi_shelve_cache ();
6127 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
6128 if (IT_CHARPOS (it) == PT && it.current_y == it2.current_y)
6129 {
6130 charpos = IT_CHARPOS (it);
6131 bytepos = IT_BYTEPOS (it);
6132 bidi_unshelve_cache (it_data, true);
6133 }
6134 else
6135 {
6136 it = it2;
6137 bidi_unshelve_cache (it_data, false);
6138 }
6139 }
6140
6141
6142 if (it.what == IT_EOB)
6143 partial_p =
6144 it.current_y + it.ascent + it.descent
6145 > it.last_visible_y - this_scroll_margin
6146 - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
6147 else
6148 {
6149 move_it_by_lines (&it, 1);
6150 partial_p =
6151 it.current_y
6152 > it.last_visible_y - this_scroll_margin
6153 - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
6154 }
6155
6156 if (charpos == PT && !partial_p
6157 && (NILP (Vscroll_preserve_screen_position)
6158 || EQ (Vscroll_preserve_screen_position, Qt)))
6159
6160 ;
6161 else if (window_scroll_pixel_based_preserve_y >= 0)
6162 {
6163 int goal_y = min (it.last_visible_y - this_scroll_margin - 1,
6164 window_scroll_pixel_based_preserve_y);
6165
6166
6167
6168 if (goal_y < this_scroll_margin)
6169 goal_y = this_scroll_margin;
6170 SET_TEXT_POS_FROM_MARKER (start, w->start);
6171 start_display (&it, w, start);
6172
6173
6174
6175 move_it_to (&it, -1, window_scroll_pixel_based_preserve_x,
6176 goal_y, -1, MOVE_TO_Y | MOVE_TO_X);
6177 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
6178 }
6179 else
6180 {
6181 if (partial_p)
6182
6183
6184 {
6185 move_it_by_lines (&it, -2);
6186 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
6187 }
6188 else
6189
6190 SET_PT_BOTH (charpos, bytepos);
6191 }
6192 }
6193 bidi_unshelve_cache (itdata, false);
6194
6195 if (adjust_old_pointm)
6196 Fset_marker (w->old_pointm,
6197 ((w == XWINDOW (selected_window))
6198 ? make_fixnum (BUF_PT (XBUFFER (w->contents)))
6199 : Fmarker_position (w->pointm)),
6200 w->contents);
6201 }
6202
6203
6204
6205
6206
6207 static void
6208 window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
6209 {
6210 struct window *w = XWINDOW (window);
6211
6212
6213
6214
6215
6216 Lisp_Object opoint_marker = Fpoint_marker ();
6217 register ptrdiff_t pos, pos_byte;
6218 register int ht = window_internal_height (w);
6219 register Lisp_Object tem;
6220 bool lose;
6221 Lisp_Object bolp;
6222 ptrdiff_t startpos = marker_position (w->start);
6223 ptrdiff_t startbyte = marker_byte_position (w->start);
6224 Lisp_Object original_pos = Qnil;
6225 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
6226 Fwindow_old_point (window)));
6227
6228
6229
6230 if (whole)
6231 {
6232 int nscls = sanitize_next_screen_context_lines ();
6233 n *= max (1, ht - nscls);
6234 }
6235
6236 if (!NILP (Vscroll_preserve_screen_position))
6237 {
6238 if (window_scroll_preserve_vpos <= 0
6239 || !SYMBOLP (KVAR (current_kboard, Vlast_command))
6240 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
6241 {
6242 struct position posit
6243 = *compute_motion (startpos, startbyte, 0, 0, false,
6244 PT, ht, 0, -1, w->hscroll, 0, w);
6245
6246 window_scroll_preserve_vpos = posit.vpos;
6247 window_scroll_preserve_hpos = posit.hpos + w->hscroll;
6248 }
6249
6250 original_pos = Fcons (make_fixnum (window_scroll_preserve_hpos),
6251 make_fixnum (window_scroll_preserve_vpos));
6252 }
6253
6254 XSETFASTINT (tem, PT);
6255 tem = Fpos_visible_in_window_p (tem, window, Qnil);
6256
6257 if (NILP (tem))
6258 {
6259 Fvertical_motion (make_fixnum (- (ht / 2)), window, Qnil);
6260 startpos = PT;
6261 startbyte = PT_BYTE;
6262 }
6263
6264 SET_PT_BOTH (startpos, startbyte);
6265 lose = n < 0 && PT == BEGV;
6266 Fvertical_motion (make_fixnum (n), window, Qnil);
6267 pos = PT;
6268 pos_byte = PT_BYTE;
6269 bolp = Fbolp ();
6270 SET_PT_BOTH (marker_position (opoint_marker),
6271 marker_byte_position (opoint_marker));
6272
6273 if (lose)
6274 {
6275 if (noerror)
6276 return;
6277 else
6278 xsignal0 (Qbeginning_of_buffer);
6279 }
6280
6281 if (pos < ZV)
6282 {
6283 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
6284
6285 set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
6286 w->start_at_line_beg = !NILP (bolp);
6287 wset_update_mode_line (w);
6288
6289
6290 w->force_start = true;
6291
6292 if (!NILP (Vscroll_preserve_screen_position)
6293 && this_scroll_margin == 0
6294 && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
6295 {
6296 SET_PT_BOTH (pos, pos_byte);
6297 Fvertical_motion (original_pos, window, Qnil);
6298 }
6299
6300
6301 else if (n > 0)
6302 {
6303 int top_margin;
6304
6305 if (this_scroll_margin > 0)
6306 {
6307 SET_PT_BOTH (pos, pos_byte);
6308 Fvertical_motion (make_fixnum (this_scroll_margin), window, Qnil);
6309 top_margin = PT;
6310 }
6311 else
6312 top_margin = pos;
6313
6314 if (top_margin <= marker_position (opoint_marker))
6315 SET_PT_BOTH (marker_position (opoint_marker),
6316 marker_byte_position (opoint_marker));
6317 else if (!NILP (Vscroll_preserve_screen_position))
6318 {
6319 int nlines = window_scroll_preserve_vpos;
6320
6321 SET_PT_BOTH (pos, pos_byte);
6322 if (window_scroll_preserve_vpos < this_scroll_margin)
6323 nlines = this_scroll_margin;
6324 else if (window_scroll_preserve_vpos
6325 >= w->total_lines - this_scroll_margin)
6326 nlines = w->total_lines - this_scroll_margin - 1;
6327 Fvertical_motion (Fcons (make_fixnum (window_scroll_preserve_hpos),
6328 make_fixnum (nlines)), window, Qnil);
6329 }
6330 else
6331 SET_PT (top_margin);
6332 }
6333 else if (n < 0)
6334 {
6335 int bottom_margin;
6336
6337
6338
6339 SET_PT_BOTH (pos, pos_byte);
6340 tem = Fvertical_motion (make_fixnum (ht - this_scroll_margin), window,
6341 Qnil);
6342 if (XFIXNAT (tem) == ht - this_scroll_margin)
6343 bottom_margin = PT;
6344 else
6345 bottom_margin = PT + 1;
6346
6347 if (bottom_margin > marker_position (opoint_marker))
6348 SET_PT_BOTH (marker_position (opoint_marker),
6349 marker_byte_position (opoint_marker));
6350 else
6351 {
6352 if (!NILP (Vscroll_preserve_screen_position))
6353 {
6354 int nlines = window_scroll_preserve_vpos;
6355
6356 SET_PT_BOTH (pos, pos_byte);
6357 if (window_scroll_preserve_vpos < this_scroll_margin)
6358 nlines = this_scroll_margin;
6359 else if (window_scroll_preserve_vpos
6360 >= ht - this_scroll_margin)
6361 nlines = ht - this_scroll_margin - 1;
6362 Fvertical_motion (Fcons (make_fixnum (window_scroll_preserve_hpos),
6363 make_fixnum (nlines)), window, Qnil);
6364 }
6365 else
6366 Fvertical_motion (make_fixnum (-1), window, Qnil);
6367 }
6368 }
6369 }
6370 else
6371 {
6372 if (noerror)
6373 return;
6374 else
6375 xsignal0 (Qend_of_buffer);
6376 }
6377
6378 if (adjust_old_pointm)
6379 Fset_marker (w->old_pointm,
6380 ((w == XWINDOW (selected_window))
6381 ? make_fixnum (BUF_PT (XBUFFER (w->contents)))
6382 : Fmarker_position (w->pointm)),
6383 w->contents);
6384 }
6385
6386
6387
6388
6389
6390
6391
6392
6393 static void
6394 scroll_command (Lisp_Object window, Lisp_Object n, int direction)
6395 {
6396 struct window *w;
6397 bool other_window;
6398 specpdl_ref count = SPECPDL_INDEX ();
6399
6400 eassert (eabs (direction) == 1);
6401
6402 w = XWINDOW (window);
6403 other_window = ! EQ (window, selected_window);
6404
6405
6406
6407
6408
6409
6410
6411 if (other_window || XBUFFER (w->contents) != current_buffer)
6412 {
6413 record_unwind_protect_excursion ();
6414 if (XBUFFER (w->contents) != current_buffer)
6415 Fset_buffer (w->contents);
6416 }
6417
6418 if (other_window)
6419 {
6420 SET_PT_BOTH (marker_position (w->pointm),
6421 marker_byte_position (w->pointm));
6422 SET_PT_BOTH (marker_position (w->old_pointm),
6423 marker_byte_position (w->old_pointm));
6424 }
6425
6426 if (NILP (n))
6427 window_scroll (window, direction, true, false);
6428 else if (EQ (n, Qminus))
6429 window_scroll (window, -direction, true, false);
6430 else
6431 {
6432 n = Fprefix_numeric_value (n);
6433 window_scroll (window, XFIXNUM (n) * direction, false, false);
6434 }
6435
6436 if (other_window)
6437 {
6438 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
6439 set_marker_both (w->old_pointm, Qnil, PT, PT_BYTE);
6440 }
6441
6442 unbind_to (count, Qnil);
6443 }
6444
6445 DEFUN ("scroll-up", Fscroll_up, Sscroll_up, 0, 1, "^P",
6446 doc:
6447
6448
6449
6450
6451 )
6452 (Lisp_Object arg)
6453 {
6454 scroll_command (selected_window, arg, 1);
6455 return Qnil;
6456 }
6457
6458 DEFUN ("scroll-down", Fscroll_down, Sscroll_down, 0, 1, "^P",
6459 doc:
6460
6461
6462
6463
6464 )
6465 (Lisp_Object arg)
6466 {
6467 scroll_command (selected_window, arg, -1);
6468 return Qnil;
6469 }
6470
6471 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling, Sother_window_for_scrolling, 0, 0, 0,
6472 doc:
6473
6474
6475
6476
6477
6478 )
6479 (void)
6480 {
6481 Lisp_Object window;
6482
6483 if (MINI_WINDOW_P (XWINDOW (selected_window))
6484 && !NILP (Vminibuf_scroll_window))
6485 window = Vminibuf_scroll_window;
6486
6487 else if (BUFFERP (Vother_window_scroll_buffer)
6488 && BUFFER_LIVE_P (XBUFFER (Vother_window_scroll_buffer)))
6489 {
6490 window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
6491 if (NILP (window))
6492 window = display_buffer (Vother_window_scroll_buffer, Qt, Qnil);
6493 }
6494 else if (FUNCTIONP (Vother_window_scroll_default))
6495
6496 window = call0 (Vother_window_scroll_default);
6497 else
6498 {
6499
6500 window = Fnext_window (selected_window, Qlambda, Qnil);
6501
6502 if (EQ (window, selected_window))
6503
6504
6505 window = Fnext_window (window, Qlambda, Qvisible);
6506 }
6507
6508 CHECK_LIVE_WINDOW (window);
6509
6510 if (EQ (window, selected_window))
6511 error ("There is no other window");
6512
6513 return window;
6514 }
6515
6516
6517 DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np",
6518 doc:
6519
6520
6521
6522
6523
6524
6525 )
6526 (register Lisp_Object arg, Lisp_Object set_minimum)
6527 {
6528 struct window *w = XWINDOW (selected_window);
6529 EMACS_INT requested_arg =
6530 (NILP (arg)
6531 ? window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) - 2
6532 : XFIXNUM (Fprefix_numeric_value (arg)));
6533 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
6534
6535 if (!NILP (set_minimum))
6536 w->min_hscroll = w->hscroll;
6537
6538 w->suspend_auto_hscroll = true;
6539
6540 return result;
6541 }
6542
6543 DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 2, "^P\np",
6544 doc:
6545
6546
6547
6548
6549
6550
6551 )
6552 (register Lisp_Object arg, Lisp_Object set_minimum)
6553 {
6554 struct window *w = XWINDOW (selected_window);
6555 EMACS_INT requested_arg =
6556 (NILP (arg)
6557 ? window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) - 2
6558 : XFIXNUM (Fprefix_numeric_value (arg)));
6559 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
6560
6561 if (!NILP (set_minimum))
6562 w->min_hscroll = w->hscroll;
6563
6564 w->suspend_auto_hscroll = true;
6565
6566 return result;
6567 }
6568
6569 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window, Sminibuffer_selected_window, 0, 0, 0,
6570 doc:
6571 )
6572 (void)
6573 {
6574 if (minibuf_level > 0
6575 && MINI_WINDOW_P (XWINDOW (selected_window))
6576 && WINDOW_LIVE_P (minibuf_selected_window))
6577 return minibuf_selected_window;
6578
6579 return Qnil;
6580 }
6581
6582
6583
6584
6585 static int
6586 displayed_window_lines (struct window *w)
6587 {
6588 struct it it;
6589 struct text_pos start;
6590 int height = window_box_height (w);
6591 struct buffer *old_buffer;
6592 int bottom_y;
6593 void *itdata = NULL;
6594
6595 if (XBUFFER (w->contents) != current_buffer)
6596 {
6597 old_buffer = current_buffer;
6598 set_buffer_internal (XBUFFER (w->contents));
6599 }
6600 else
6601 old_buffer = NULL;
6602
6603
6604
6605
6606 CLIP_TEXT_POS_FROM_MARKER (start, w->start);
6607
6608 itdata = bidi_shelve_cache ();
6609
6610 specpdl_ref count = SPECPDL_INDEX ();
6611 record_unwind_protect_void (unwind_display_working_on_window);
6612 display_working_on_window_p = true;
6613 start_display (&it, w, start);
6614 move_it_vertically (&it, height);
6615 bottom_y = line_bottom_y (&it);
6616 unbind_to (count, Qnil);
6617 bidi_unshelve_cache (itdata, false);
6618
6619
6620 if (bottom_y < height)
6621 {
6622 int uy = FRAME_LINE_HEIGHT (it.f);
6623 it.vpos += (height - bottom_y + uy - 1) / uy;
6624 }
6625 else if (bottom_y == height)
6626 it.vpos++;
6627
6628 if (old_buffer)
6629 set_buffer_internal (old_buffer);
6630
6631 return it.vpos;
6632 }
6633
6634
6635 DEFUN ("recenter", Frecenter, Srecenter, 0, 2, "P\np",
6636 doc:
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650 )
6651 (Lisp_Object arg, Lisp_Object redisplay)
6652 {
6653 struct window *w = XWINDOW (selected_window);
6654 struct buffer *buf = XBUFFER (w->contents);
6655 bool center_p = false;
6656 ptrdiff_t charpos, bytepos;
6657 EMACS_INT iarg UNINIT;
6658 int this_scroll_margin;
6659
6660
6661
6662
6663 if (buf != current_buffer)
6664 error ("`recenter'ing a window that does not display current-buffer.");
6665
6666
6667 buf->display_error_modiff = 0;
6668
6669 if (NILP (arg))
6670 {
6671 if (!NILP (redisplay)
6672 && !NILP (Vrecenter_redisplay)
6673 && (!EQ (Vrecenter_redisplay, Qtty)
6674 || !NILP (Ftty_type (selected_frame))))
6675 {
6676 ptrdiff_t i;
6677
6678
6679 for (i = 0; i < n_compositions; i++)
6680 composition_table[i]->font = NULL;
6681 #if defined (HAVE_WINDOW_SYSTEM)
6682 WINDOW_XFRAME (w)->minimize_tab_bar_window_p = 1;
6683 #endif
6684 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
6685 WINDOW_XFRAME (w)->minimize_tool_bar_window_p = 1;
6686 #endif
6687 Fredraw_frame (WINDOW_FRAME (w));
6688 SET_FRAME_GARBAGED (WINDOW_XFRAME (w));
6689 }
6690
6691 center_p = true;
6692 }
6693 else if (CONSP (arg))
6694 center_p = true;
6695 else
6696 {
6697 arg = Fprefix_numeric_value (arg);
6698 CHECK_FIXNUM (arg);
6699 iarg = XFIXNUM (arg);
6700 }
6701
6702
6703
6704 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
6705
6706
6707
6708
6709
6710 if (!FRAME_INITIAL_P (XFRAME (w->frame))
6711 && !current_buffer->long_line_optimizations_p)
6712 {
6713 specpdl_ref count = SPECPDL_INDEX ();
6714
6715 record_unwind_protect_void (unwind_display_working_on_window);
6716 display_working_on_window_p = true;
6717 if (center_p)
6718 {
6719 struct it it;
6720 struct text_pos pt;
6721 void *itdata = bidi_shelve_cache ();
6722
6723 SET_TEXT_POS (pt, PT, PT_BYTE);
6724 start_display (&it, w, pt);
6725 move_it_vertically_backward (&it, window_box_height (w) / 2);
6726 charpos = IT_CHARPOS (it);
6727 bytepos = IT_BYTEPOS (it);
6728 bidi_unshelve_cache (itdata, false);
6729 }
6730 else if (iarg < 0)
6731 {
6732 struct it it;
6733 struct text_pos pt;
6734 ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg);
6735 int extra_line_spacing;
6736 int h = window_box_height (w);
6737 int ht = window_internal_height (w);
6738 void *itdata = bidi_shelve_cache ();
6739
6740 nlines = clip_to_bounds (this_scroll_margin + 1, nlines,
6741 ht - this_scroll_margin);
6742
6743 SET_TEXT_POS (pt, PT, PT_BYTE);
6744 start_display (&it, w, pt);
6745
6746
6747 move_it_by_lines (&it, 0);
6748
6749
6750
6751
6752 it.current_y = 0;
6753 it.vpos = 0;
6754 move_it_by_lines (&it, nlines);
6755
6756 if (it.vpos == nlines)
6757 h -= it.current_y;
6758 else
6759 {
6760
6761 h -= line_bottom_y (&it);
6762 it.vpos++;
6763 }
6764
6765
6766 extra_line_spacing = it.max_extra_line_spacing;
6767
6768
6769
6770 if (it.vpos < nlines)
6771 {
6772 nlines -= it.vpos;
6773 extra_line_spacing = it.extra_line_spacing;
6774 h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
6775 }
6776 if (h <= 0)
6777 {
6778 bidi_unshelve_cache (itdata, false);
6779 unbind_to (count, Qnil);
6780 return Qnil;
6781 }
6782
6783
6784 start_display (&it, w, pt);
6785 it.current_y = 0;
6786 move_it_vertically_backward (&it, h);
6787
6788
6789
6790
6791
6792
6793
6794
6795 h += extra_line_spacing;
6796 while (-it.current_y > h && it.what != IT_EOB)
6797 move_it_by_lines (&it, 1);
6798
6799 charpos = IT_CHARPOS (it);
6800 bytepos = IT_BYTEPOS (it);
6801
6802 bidi_unshelve_cache (itdata, false);
6803 }
6804 else
6805 {
6806 struct it it;
6807 struct text_pos pt;
6808 ptrdiff_t nlines = min (PTRDIFF_MAX, iarg);
6809 int ht = window_internal_height (w);
6810 void *itdata = bidi_shelve_cache ();
6811
6812 nlines = clip_to_bounds (this_scroll_margin, nlines,
6813 ht - this_scroll_margin - 1);
6814
6815 SET_TEXT_POS (pt, PT, PT_BYTE);
6816 start_display (&it, w, pt);
6817
6818
6819 move_it_by_lines (&it, 0);
6820
6821
6822 if (nlines > 0)
6823 {
6824 it.current_y = 0;
6825 it.vpos = 0;
6826 move_it_by_lines (&it, -nlines);
6827 }
6828
6829 charpos = IT_CHARPOS (it);
6830 bytepos = IT_BYTEPOS (it);
6831
6832 bidi_unshelve_cache (itdata, false);
6833 }
6834 unbind_to (count, Qnil);
6835 }
6836 else
6837 {
6838 struct position pos;
6839 int ht = window_internal_height (w);
6840
6841 if (center_p)
6842 iarg = ht / 2;
6843 else if (iarg < 0)
6844 iarg += ht;
6845
6846
6847 iarg = clip_to_bounds (this_scroll_margin, iarg,
6848 ht - this_scroll_margin - 1);
6849
6850 pos = *vmotion (PT, PT_BYTE, - iarg, w);
6851 charpos = pos.bufpos;
6852 bytepos = pos.bytepos;
6853 }
6854
6855
6856 set_marker_both (w->start, w->contents, charpos, bytepos);
6857 w->window_end_valid = false;
6858
6859 w->optional_new_start = true;
6860
6861 w->start_at_line_beg = (bytepos == BEGV_BYTE
6862 || FETCH_BYTE (bytepos - 1) == '\n');
6863
6864 wset_redisplay (w);
6865
6866 return Qnil;
6867 }
6868
6869 DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
6870 0, 2, 0,
6871 doc:
6872
6873
6874
6875
6876
6877
6878
6879 )
6880 (Lisp_Object window, Lisp_Object pixelwise)
6881 {
6882 struct window *w = decode_live_window (window);
6883
6884 if (NILP (pixelwise))
6885 return make_fixnum (window_box_width (w, TEXT_AREA)
6886 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
6887 else
6888 return make_fixnum (window_box_width (w, TEXT_AREA));
6889 }
6890
6891 DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
6892 0, 2, 0,
6893 doc:
6894
6895
6896
6897
6898
6899
6900 )
6901 (Lisp_Object window, Lisp_Object pixelwise)
6902 {
6903 struct window *w = decode_live_window (window);
6904
6905 if (NILP (pixelwise))
6906 return make_fixnum (window_box_height (w)
6907 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
6908 else
6909 return make_fixnum (window_box_height (w));
6910 }
6911
6912 DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
6913 1, 1, "P",
6914 doc:
6915
6916
6917
6918
6919
6920
6921
6922 )
6923 (Lisp_Object arg)
6924 {
6925 struct window *w = XWINDOW (selected_window);
6926 int lines, start;
6927 Lisp_Object window;
6928 #if false
6929 int this_scroll_margin;
6930 #endif
6931
6932 if (!(BUFFERP (w->contents) && XBUFFER (w->contents) == current_buffer))
6933
6934
6935 error ("move-to-window-line called from unrelated buffer");
6936
6937 window = selected_window;
6938 start = marker_position (w->start);
6939 if (start < BEGV || start > ZV)
6940 {
6941 int height = window_internal_height (w);
6942 Fvertical_motion (make_fixnum (- (height / 2)), window, Qnil);
6943 set_marker_both (w->start, w->contents, PT, PT_BYTE);
6944 w->start_at_line_beg = !NILP (Fbolp ());
6945 w->force_start = true;
6946 }
6947 else
6948 Fgoto_char (w->start);
6949
6950 lines = displayed_window_lines (w);
6951
6952 if (NILP (arg))
6953 XSETFASTINT (arg, lines / 2);
6954 else
6955 {
6956 EMACS_INT iarg = XFIXNUM (Fprefix_numeric_value (arg));
6957
6958 if (iarg < 0)
6959 iarg = iarg + lines;
6960
6961 #if false
6962
6963
6964
6965
6966
6967 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
6968
6969
6970 iarg = max (iarg, this_scroll_margin);
6971 iarg = min (iarg, lines - this_scroll_margin - 1);
6972 #endif
6973
6974 arg = make_fixnum (iarg);
6975 }
6976
6977
6978 if (w->vscroll)
6979 XSETINT (arg, XFIXNUM (arg) + 1);
6980
6981 return Fvertical_motion (arg, window, Qnil);
6982 }
6983
6984
6985
6986
6987
6988
6989
6990 struct save_window_data
6991 {
6992 union vectorlike_header header;
6993 Lisp_Object selected_frame;
6994 Lisp_Object current_window;
6995 Lisp_Object f_current_buffer;
6996 Lisp_Object minibuf_scroll_window;
6997 Lisp_Object minibuf_selected_window;
6998 Lisp_Object root_window;
6999 Lisp_Object focus_frame;
7000
7001
7002 Lisp_Object saved_windows;
7003
7004
7005
7006
7007
7008 int frame_cols, frame_lines;
7009
7010
7011 int frame_menu_bar_lines, frame_tab_bar_lines, frame_tool_bar_lines;
7012 int frame_text_width, frame_text_height;
7013
7014
7015 int frame_menu_bar_height, frame_tab_bar_height, frame_tool_bar_height;
7016 } GCALIGNED_STRUCT;
7017
7018
7019 struct saved_window
7020 {
7021 union vectorlike_header header;
7022
7023 Lisp_Object window, buffer, start, pointm, old_pointm;
7024 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
7025 Lisp_Object left_col, top_line, total_cols, total_lines;
7026 Lisp_Object normal_cols, normal_lines;
7027 Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll;
7028 Lisp_Object vscroll;
7029 Lisp_Object parent, prev;
7030 Lisp_Object start_at_line_beg;
7031 Lisp_Object display_table;
7032 Lisp_Object left_margin_cols, right_margin_cols;
7033 Lisp_Object left_fringe_width, right_fringe_width;
7034 Lisp_Object fringes_outside_margins, fringes_persistent;
7035 Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
7036 Lisp_Object scroll_bar_height, horizontal_scroll_bar_type;
7037 Lisp_Object scroll_bars_persistent, dedicated;
7038 Lisp_Object combination_limit, window_parameters;
7039 };
7040
7041 #define SAVED_WINDOW_N(swv,n) \
7042 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
7043
7044 DEFUN ("window-configuration-p", Fwindow_configuration_p, Swindow_configuration_p, 1, 1, 0,
7045 doc: )
7046 (Lisp_Object object)
7047 {
7048 return WINDOW_CONFIGURATIONP (object) ? Qt : Qnil;
7049 }
7050
7051 DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_configuration_frame, 1, 1, 0,
7052 doc: )
7053 (Lisp_Object config)
7054 {
7055 register struct save_window_data *data;
7056 struct Lisp_Vector *saved_windows;
7057
7058 CHECK_WINDOW_CONFIGURATION (config);
7059
7060 data = (struct save_window_data *) XVECTOR (config);
7061 saved_windows = XVECTOR (data->saved_windows);
7062 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
7063 }
7064
7065 DEFUN ("set-window-configuration", Fset_window_configuration,
7066 Sset_window_configuration, 1, 3, 0,
7067 doc:
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079 )
7080 (Lisp_Object configuration, Lisp_Object dont_set_frame,
7081 Lisp_Object dont_set_miniwindow)
7082 {
7083 register struct save_window_data *data;
7084 struct Lisp_Vector *saved_windows;
7085 Lisp_Object new_current_buffer;
7086 Lisp_Object frame;
7087 Lisp_Object old_frame = selected_frame;
7088 struct frame *f;
7089 ptrdiff_t old_point = -1;
7090 USE_SAFE_ALLOCA;
7091
7092 CHECK_WINDOW_CONFIGURATION (configuration);
7093
7094 data = (struct save_window_data *) XVECTOR (configuration);
7095 saved_windows = XVECTOR (data->saved_windows);
7096
7097 new_current_buffer = data->f_current_buffer;
7098 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
7099 new_current_buffer = Qnil;
7100 else
7101 {
7102 if (XBUFFER (new_current_buffer) == current_buffer)
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
7114 && WINDOWP (selected_window)
7115 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
7116 && !EQ (selected_window, data->current_window))
7117 old_point = marker_position (XWINDOW (data->current_window)->pointm);
7118 else
7119 old_point = PT;
7120 else
7121
7122
7123
7124
7125
7126
7127
7128
7129 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
7130
7131 && !EQ (selected_window, data->current_window))
7132 old_point = marker_position (XWINDOW (data->current_window)->pointm);
7133 else
7134 old_point = BUF_PT (XBUFFER (new_current_buffer));
7135 }
7136
7137 frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
7138 f = XFRAME (frame);
7139
7140
7141
7142 if (FRAME_LIVE_P (f))
7143 {
7144 Lisp_Object window;
7145 Lisp_Object dead_windows = Qnil;
7146 Lisp_Object tem, par, pers;
7147 struct window *w;
7148 struct saved_window *p;
7149 struct window *root_window;
7150 struct window **leaf_windows;
7151 ptrdiff_t i, k, n_leaf_windows;
7152
7153
7154
7155 for (k = 0; k < saved_windows->header.size; k++)
7156 {
7157 p = SAVED_WINDOW_N (saved_windows, k);
7158 window = p->window;
7159 w = XWINDOW (window);
7160
7161 if (BUFFERP (w->contents)
7162 && !EQ (w->contents, p->buffer)
7163 && BUFFER_LIVE_P (XBUFFER (p->buffer))
7164 && (NILP (Fminibufferp (p->buffer, Qnil))))
7165
7166
7167 call1 (Qrecord_window_buffer, window);
7168 }
7169
7170
7171 f->can_set_window_size = false;
7172
7173
7174 block_input ();
7175
7176
7177
7178
7179
7180
7181 if (! NILP (XWINDOW (selected_window)->contents))
7182 {
7183 w = XWINDOW (selected_window);
7184 set_marker_both (w->pointm,
7185 w->contents,
7186 BUF_PT (XBUFFER (w->contents)),
7187 BUF_PT_BYTE (XBUFFER (w->contents)));
7188 }
7189
7190 fset_redisplay (f);
7191
7192
7193
7194
7195
7196 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
7197 ptrdiff_t nwindows = count_windows (root_window);
7198 SAFE_NALLOCA (leaf_windows, 1, nwindows);
7199 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
7200
7201
7202
7203
7204
7205
7206
7207
7208 delete_all_child_windows (FRAME_ROOT_WINDOW (f));
7209
7210 for (k = 0; k < saved_windows->header.size; k++)
7211 {
7212 p = SAVED_WINDOW_N (saved_windows, k);
7213 window = p->window;
7214 w = XWINDOW (window);
7215 wset_next (w, Qnil);
7216
7217 if (!NILP (p->parent))
7218 wset_parent
7219 (w, SAVED_WINDOW_N (saved_windows, XFIXNAT (p->parent))->window);
7220 else
7221 wset_parent (w, Qnil);
7222
7223 if (!NILP (p->prev))
7224 {
7225 wset_prev
7226 (w, SAVED_WINDOW_N (saved_windows, XFIXNAT (p->prev))->window);
7227 wset_next (XWINDOW (w->prev), p->window);
7228 }
7229 else
7230 {
7231 wset_prev (w, Qnil);
7232 if (!NILP (w->parent))
7233 wset_combination (XWINDOW (w->parent),
7234 (XFIXNUM (p->total_cols)
7235 != XWINDOW (w->parent)->total_cols),
7236 p->window);
7237 }
7238
7239
7240 if (BUFFERP (w->combination_limit))
7241 wset_buffer (w, w->combination_limit);
7242 w->pixel_left = XFIXNAT (p->pixel_left);
7243 w->pixel_top = XFIXNAT (p->pixel_top);
7244 w->pixel_width = XFIXNAT (p->pixel_width);
7245 w->pixel_height = XFIXNAT (p->pixel_height);
7246 w->left_col = XFIXNAT (p->left_col);
7247 w->top_line = XFIXNAT (p->top_line);
7248 w->total_cols = XFIXNAT (p->total_cols);
7249 w->total_lines = XFIXNAT (p->total_lines);
7250 wset_normal_cols (w, p->normal_cols);
7251 wset_normal_lines (w, p->normal_lines);
7252 w->hscroll = XFIXNAT (p->hscroll);
7253 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
7254 w->min_hscroll = XFIXNAT (p->min_hscroll);
7255 w->hscroll_whole = XFIXNAT (p->hscroll_whole);
7256 w->vscroll = -XFIXNAT (p->vscroll);
7257 wset_display_table (w, p->display_table);
7258 w->left_margin_cols = XFIXNUM (p->left_margin_cols);
7259 w->right_margin_cols = XFIXNUM (p->right_margin_cols);
7260 w->left_fringe_width = XFIXNUM (p->left_fringe_width);
7261 w->right_fringe_width = XFIXNUM (p->right_fringe_width);
7262 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
7263 w->fringes_persistent = !NILP (p->fringes_persistent);
7264 w->scroll_bar_width = XFIXNUM (p->scroll_bar_width);
7265 w->scroll_bar_height = XFIXNUM (p->scroll_bar_height);
7266 w->scroll_bars_persistent = !NILP (p->scroll_bars_persistent);
7267 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
7268 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
7269 wset_dedicated (w, p->dedicated);
7270 wset_combination_limit (w, p->combination_limit);
7271
7272
7273 for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
7274 {
7275 pers = XCAR (tem);
7276 if (CONSP (pers))
7277 {
7278 if (NILP (XCDR (pers)))
7279 {
7280 par = Fassq (XCAR (pers), w->window_parameters);
7281 if (CONSP (par) && !NILP (XCDR (par)))
7282
7283
7284
7285 Fsetcdr (par, Qnil);
7286 }
7287 else
7288
7289 Fset_window_parameter (window, XCAR (pers), XCDR (pers));
7290 }
7291 }
7292
7293 if ((NILP (dont_set_miniwindow) || !MINI_WINDOW_P (w))
7294 && BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
7295
7296
7297 {
7298 wset_buffer (w, p->buffer);
7299 w->start_at_line_beg = !NILP (p->start_at_line_beg);
7300 set_marker_restricted (w->start, p->start, w->contents);
7301 set_marker_restricted (w->pointm, p->pointm, w->contents);
7302 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
7303
7304
7305
7306 if (!EQ (p->buffer, new_current_buffer)
7307 && XBUFFER (p->buffer) == current_buffer)
7308 Fgoto_char (w->pointm);
7309 }
7310 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
7311
7312 {
7313
7314 if (XMARKER (w->start)->buffer == 0)
7315 set_marker_restricted_both (w->start, w->contents, 0, 0);
7316 if (XMARKER (w->pointm)->buffer == 0)
7317 set_marker_restricted_both
7318 (w->pointm, w->contents,
7319 BUF_PT (XBUFFER (w->contents)),
7320 BUF_PT_BYTE (XBUFFER (w->contents)));
7321 if (XMARKER (w->old_pointm)->buffer == 0)
7322 set_marker_restricted_both
7323 (w->old_pointm, w->contents,
7324 BUF_PT (XBUFFER (w->contents)),
7325 BUF_PT_BYTE (XBUFFER (w->contents)));
7326 w->start_at_line_beg = true;
7327 }
7328 else if (!NILP (w->start))
7329
7330 {
7331
7332
7333
7334
7335 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
7336
7337
7338 set_marker_restricted_both (w->start, w->contents, 0, 0);
7339 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
7340 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
7341 w->start_at_line_beg = true;
7342 if (!NILP (w->dedicated))
7343
7344 dead_windows = Fcons (window, dead_windows);
7345
7346 wset_dedicated (w, Qnil);
7347 }
7348 }
7349
7350 fset_root_window (f, data->root_window);
7351
7352
7353 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
7354 set_marker_restricted (XWINDOW (data->current_window)->pointm,
7355 make_fixnum (old_point),
7356 XWINDOW (data->current_window)->contents);
7357
7358
7359
7360
7361
7362
7363
7364
7365 select_window (data->current_window, Qt, true);
7366 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
7367 last_selected_window)
7368 = selected_window;
7369
7370
7371
7372
7373
7374
7375
7376 Vwindow_list = Qnil;
7377
7378 if (NILP (data->focus_frame)
7379 || (FRAMEP (data->focus_frame)
7380 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
7381 Fredirect_frame_focus (frame, data->focus_frame);
7382
7383
7384 for (i = 0; i < n_leaf_windows; i++)
7385 if (NILP (leaf_windows[i]->contents))
7386 free_window_matrices (leaf_windows[i]);
7387
7388
7389
7390
7391 f->can_set_window_size = true;
7392 adjust_frame_size (f, -1, -1, 4, false, Qset_window_configuration);
7393
7394 adjust_frame_glyphs (f);
7395 unblock_input ();
7396
7397
7398 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
7399 {
7400 window = XCAR (dead_windows);
7401 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
7402 delete_deletable_window (window);
7403 }
7404
7405
7406
7407 if (WINDOW_LIVE_P (data->current_window))
7408 select_window (data->current_window, Qnil, false);
7409
7410
7411
7412
7413
7414
7415 if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
7416 do_switch_frame (NILP (dont_set_frame)
7417 ? data->selected_frame
7418 : old_frame
7419 , 0, 0, Qnil);
7420 }
7421
7422 FRAME_WINDOW_CHANGE (f) = true;
7423
7424 if (!NILP (new_current_buffer))
7425 {
7426 Fset_buffer (new_current_buffer);
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442 if (!EQ (XWINDOW (selected_window)->contents, new_current_buffer))
7443 Fgoto_char (make_fixnum (old_point));
7444 }
7445
7446 Vminibuf_scroll_window = data->minibuf_scroll_window;
7447 minibuf_selected_window = data->minibuf_selected_window;
7448
7449 SAFE_FREE ();
7450 return FRAME_LIVE_P (f) ? Qt : Qnil;
7451 }
7452
7453 void
7454 restore_window_configuration (Lisp_Object configuration)
7455 {
7456 if (CONSP (configuration))
7457 Fset_window_configuration (XCAR (configuration),
7458 Fcar_safe (XCDR (configuration)),
7459 Fcar_safe (Fcdr_safe (XCDR (configuration))));
7460 else
7461 Fset_window_configuration (configuration, Qnil, Qnil);
7462 }
7463
7464
7465
7466
7467
7468
7469 void
7470 delete_all_child_windows (Lisp_Object window)
7471 {
7472 register struct window *w;
7473
7474 w = XWINDOW (window);
7475
7476 if (!NILP (w->next))
7477
7478 delete_all_child_windows (w->next);
7479
7480 if (WINDOWP (w->contents))
7481 {
7482 delete_all_child_windows (w->contents);
7483 wset_combination (w, false, Qnil);
7484 }
7485 else if (BUFFERP (w->contents))
7486 {
7487 unshow_buffer (w);
7488 unchain_marker (XMARKER (w->pointm));
7489 unchain_marker (XMARKER (w->old_pointm));
7490 unchain_marker (XMARKER (w->start));
7491
7492
7493
7494 wset_combination_limit (w, w->contents);
7495 wset_buffer (w, Qnil);
7496 }
7497
7498 Vwindow_list = Qnil;
7499 }
7500
7501 static ptrdiff_t
7502 count_windows (struct window *window)
7503 {
7504 ptrdiff_t count = 1;
7505 if (!NILP (window->next))
7506 count += count_windows (XWINDOW (window->next));
7507 if (WINDOWP (window->contents))
7508 count += count_windows (XWINDOW (window->contents));
7509 return count;
7510 }
7511
7512
7513
7514
7515 static ptrdiff_t
7516 get_leaf_windows (struct window *w, struct window **flat, ptrdiff_t i)
7517 {
7518 while (w)
7519 {
7520 if (WINDOWP (w->contents))
7521 i = get_leaf_windows (XWINDOW (w->contents), flat, i);
7522 else
7523 flat[i++] = w;
7524
7525 w = NILP (w->next) ? 0 : XWINDOW (w->next);
7526 }
7527
7528 return i;
7529 }
7530
7531
7532
7533
7534
7535 struct glyph *
7536 get_phys_cursor_glyph (struct window *w)
7537 {
7538 struct glyph_row *row;
7539 struct glyph *glyph;
7540 int hpos = w->phys_cursor.hpos;
7541
7542 if (!(w->phys_cursor.vpos >= 0
7543 && w->phys_cursor.vpos < w->current_matrix->nrows))
7544 return NULL;
7545
7546 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
7547 if (!row->enabled_p)
7548 return NULL;
7549
7550 if (w->hscroll)
7551 {
7552
7553
7554
7555 if (!row->reversed_p && hpos < 0)
7556 hpos = 0;
7557 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
7558 hpos = row->used[TEXT_AREA] - 1;
7559 }
7560
7561 if (0 <= hpos && hpos < row->used[TEXT_AREA])
7562 glyph = row->glyphs[TEXT_AREA] + hpos;
7563 else
7564 glyph = NULL;
7565
7566 return glyph;
7567 }
7568
7569
7570 static ptrdiff_t
7571 save_window_save (Lisp_Object window, struct Lisp_Vector *vector, ptrdiff_t i)
7572 {
7573 struct saved_window *p;
7574 struct window *w;
7575 Lisp_Object tem, pers, par;
7576
7577 for (; !NILP (window); window = w->next)
7578 {
7579 p = SAVED_WINDOW_N (vector, i);
7580 w = XWINDOW (window);
7581
7582 wset_temslot (w, make_fixnum (i)); i++;
7583 p->window = window;
7584 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
7585 p->pixel_left = make_fixnum (w->pixel_left);
7586 p->pixel_top = make_fixnum (w->pixel_top);
7587 p->pixel_width = make_fixnum (w->pixel_width);
7588 p->pixel_height = make_fixnum (w->pixel_height);
7589 p->left_col = make_fixnum (w->left_col);
7590 p->top_line = make_fixnum (w->top_line);
7591 p->total_cols = make_fixnum (w->total_cols);
7592 p->total_lines = make_fixnum (w->total_lines);
7593 p->normal_cols = w->normal_cols;
7594 p->normal_lines = w->normal_lines;
7595 XSETFASTINT (p->hscroll, w->hscroll);
7596 p->suspend_auto_hscroll = w->suspend_auto_hscroll ? Qt : Qnil;
7597 XSETFASTINT (p->min_hscroll, w->min_hscroll);
7598 XSETFASTINT (p->hscroll_whole, w->hscroll_whole);
7599 XSETFASTINT (p->vscroll, -w->vscroll);
7600 p->display_table = w->display_table;
7601 p->left_margin_cols = make_fixnum (w->left_margin_cols);
7602 p->right_margin_cols = make_fixnum (w->right_margin_cols);
7603 p->left_fringe_width = make_fixnum (w->left_fringe_width);
7604 p->right_fringe_width = make_fixnum (w->right_fringe_width);
7605 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
7606 p->fringes_persistent = w->fringes_persistent ? Qt : Qnil;
7607 p->scroll_bar_width = make_fixnum (w->scroll_bar_width);
7608 p->scroll_bar_height = make_fixnum (w->scroll_bar_height);
7609 p->scroll_bars_persistent = w->scroll_bars_persistent ? Qt : Qnil;
7610 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
7611 p->horizontal_scroll_bar_type = w->horizontal_scroll_bar_type;
7612 p->dedicated = w->dedicated;
7613 p->combination_limit = w->combination_limit;
7614 p->window_parameters = Qnil;
7615
7616 if (!NILP (Vwindow_persistent_parameters))
7617 {
7618
7619 Lisp_Object tortoise, hare;
7620
7621 hare = tortoise = Vwindow_persistent_parameters;
7622 while (CONSP (hare))
7623 {
7624 hare = XCDR (hare);
7625 if (!CONSP (hare))
7626 break;
7627
7628 hare = XCDR (hare);
7629 tortoise = XCDR (tortoise);
7630
7631 if (BASE_EQ (hare, tortoise))
7632
7633 {
7634 Vwindow_persistent_parameters = Qnil;
7635 break;
7636 }
7637 }
7638
7639 for (tem = Vwindow_persistent_parameters; CONSP (tem);
7640 tem = XCDR (tem))
7641 {
7642 pers = XCAR (tem);
7643
7644 if (CONSP (pers) && !NILP (XCDR (pers)))
7645 {
7646 par = Fassq (XCAR (pers), w->window_parameters);
7647 if (NILP (par))
7648
7649
7650 p->window_parameters = Fcons (Fcons (XCAR (pers), Qnil),
7651 p->window_parameters);
7652 else
7653
7654
7655 p->window_parameters = Fcons (Fcons (XCAR (par),
7656 XCDR (par)),
7657 p->window_parameters);
7658 }
7659 }
7660 }
7661
7662 if (BUFFERP (w->contents))
7663 {
7664 bool window_point_insertion_type
7665 = !NILP (buffer_local_value
7666 (Qwindow_point_insertion_type, w->contents));
7667
7668
7669
7670
7671 if (EQ (window, selected_window))
7672 p->pointm = build_marker (XBUFFER (w->contents),
7673 BUF_PT (XBUFFER (w->contents)),
7674 BUF_PT_BYTE (XBUFFER (w->contents)));
7675 else
7676 p->pointm = Fcopy_marker (w->pointm, Qnil);
7677 p->old_pointm = Fcopy_marker (w->old_pointm, Qnil);
7678 XMARKER (p->pointm)->insertion_type = window_point_insertion_type;
7679 XMARKER (p->old_pointm)->insertion_type = window_point_insertion_type;
7680
7681 p->start = Fcopy_marker (w->start, Qnil);
7682 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
7683 }
7684 else
7685 {
7686 p->pointm = Qnil;
7687 p->old_pointm = Qnil;
7688 p->start = Qnil;
7689 p->start_at_line_beg = Qnil;
7690 }
7691
7692 p->parent = NILP (w->parent) ? Qnil : XWINDOW (w->parent)->temslot;
7693 p->prev = NILP (w->prev) ? Qnil : XWINDOW (w->prev)->temslot;
7694
7695 if (WINDOWP (w->contents))
7696 i = save_window_save (w->contents, vector, i);
7697 }
7698
7699 return i;
7700 }
7701
7702 DEFUN ("current-window-configuration", Fcurrent_window_configuration,
7703 Scurrent_window_configuration, 0, 1, 0,
7704 doc:
7705
7706
7707
7708
7709
7710
7711
7712
7713 )
7714 (Lisp_Object frame)
7715 {
7716 struct frame *f = decode_live_frame (frame);
7717 ptrdiff_t n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
7718 struct save_window_data *data
7719 = ALLOCATE_PSEUDOVECTOR (struct save_window_data, saved_windows,
7720 PVEC_WINDOW_CONFIGURATION);
7721 data->frame_cols = FRAME_COLS (f);
7722 data->frame_lines = FRAME_LINES (f);
7723 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
7724 data->frame_tab_bar_lines = FRAME_TAB_BAR_LINES (f);
7725 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
7726 data->frame_text_width = FRAME_TEXT_WIDTH (f);
7727 data->frame_text_height = FRAME_TEXT_HEIGHT (f);
7728 data->frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
7729 data->frame_tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
7730 data->frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
7731 data->selected_frame = selected_frame;
7732 data->current_window = FRAME_SELECTED_WINDOW (f);
7733 XSETBUFFER (data->f_current_buffer, current_buffer);
7734 data->minibuf_scroll_window = minibuf_level > 0 ? Vminibuf_scroll_window : Qnil;
7735 data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
7736 data->root_window = FRAME_ROOT_WINDOW (f);
7737 data->focus_frame = FRAME_FOCUS_FRAME (f);
7738 Lisp_Object tem = make_nil_vector (n_windows);
7739 data->saved_windows = tem;
7740 for (ptrdiff_t i = 0; i < n_windows; i++)
7741 ASET (tem, i, make_nil_vector (VECSIZE (struct saved_window)));
7742 save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
7743 XSETWINDOW_CONFIGURATION (tem, data);
7744 return tem;
7745 }
7746
7747
7748
7749 static void
7750 apply_window_adjustment (struct window *w)
7751 {
7752 eassert (w);
7753 clear_glyph_matrix (w->current_matrix);
7754 w->window_end_valid = false;
7755 wset_redisplay (w);
7756 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w)));
7757 }
7758
7759
7760
7761
7762
7763
7764 static int
7765 extract_dimension (Lisp_Object dimension)
7766 {
7767 if (NILP (dimension))
7768 return -1;
7769 return check_integer_range (dimension, 0, INT_MAX);
7770 }
7771
7772 static struct window *
7773 set_window_margins (struct window *w, Lisp_Object left_width,
7774 Lisp_Object right_width)
7775 {
7776 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
7777 int left = NILP (left_width) ? 0 : extract_dimension (left_width);
7778 int right = NILP (right_width) ? 0 : extract_dimension (right_width);
7779
7780 if (w->left_margin_cols != left || w->right_margin_cols != right)
7781 {
7782
7783 if ((WINDOW_PIXEL_WIDTH (w)
7784 - WINDOW_FRINGES_WIDTH (w)
7785 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7786 - (left + right) * unit)
7787 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7788 {
7789 w->left_margin_cols = left;
7790 w->right_margin_cols = right;
7791
7792 return w;
7793 }
7794 else
7795 return NULL;
7796 }
7797 else
7798 return NULL;
7799 }
7800
7801 DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
7802 2, 3, 0,
7803 doc:
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813 )
7814 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width)
7815 {
7816 struct window *w = set_window_margins (decode_live_window (window),
7817 left_width, right_width);
7818 return w ? (apply_window_adjustment (w), Qt) : Qnil;
7819 }
7820
7821
7822 DEFUN ("window-margins", Fwindow_margins, Swindow_margins,
7823 0, 1, 0,
7824 doc:
7825
7826
7827
7828
7829 )
7830 (Lisp_Object window)
7831 {
7832 struct window *w = decode_live_window (window);
7833 return Fcons (w->left_margin_cols
7834 ? make_fixnum (w->left_margin_cols) : Qnil,
7835 w->right_margin_cols
7836 ? make_fixnum (w->right_margin_cols) : Qnil);
7837 }
7838
7839
7840
7841
7842
7843
7844
7845 static struct window *
7846 set_window_fringes (struct window *w,
7847 Lisp_Object left_width, Lisp_Object right_width,
7848 Lisp_Object outside_margins, Lisp_Object persistent)
7849 {
7850
7851 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w)))
7852 return NULL;
7853 else
7854 {
7855 struct frame *f = XFRAME (WINDOW_FRAME (w));
7856 int old_left = WINDOW_LEFT_FRINGE_WIDTH (w);
7857 int old_right = WINDOW_RIGHT_FRINGE_WIDTH (w);
7858 int new_left = extract_dimension (left_width);
7859 int new_right = extract_dimension (right_width);
7860 bool outside = !NILP (outside_margins);
7861 bool changed = false;
7862 bool failed = false;
7863
7864
7865
7866 if ((WINDOW_PIXEL_WIDTH (w)
7867 - WINDOW_MARGINS_WIDTH (w)
7868 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7869 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
7870 - (new_left == -1 ? FRAME_LEFT_FRINGE_WIDTH (f) : new_left)
7871 - (new_right == -1 ? FRAME_RIGHT_FRINGE_WIDTH (f) : new_right))
7872 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7873 {
7874 w->left_fringe_width = new_left;
7875 w->right_fringe_width = new_right;
7876 changed = new_left != old_left || new_right != old_right;
7877 }
7878 else
7879 failed = true;
7880
7881
7882 if (outside != w->fringes_outside_margins)
7883 {
7884 w->fringes_outside_margins = outside;
7885 changed = true;
7886 }
7887
7888
7889
7890 if (!failed)
7891 w->fringes_persistent = !NILP (persistent);
7892
7893
7894
7895
7896
7897 if (changed)
7898 {
7899 windows_or_buffers_changed = 35;
7900 return w;
7901 }
7902 else
7903 return NULL;
7904 }
7905 }
7906
7907 DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
7908 2, 5, 0,
7909 doc:
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930 )
7931 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width,
7932 Lisp_Object outside_margins, Lisp_Object persistent)
7933 {
7934 struct window *w
7935 = set_window_fringes (decode_live_window (window), left_width,
7936 right_width, outside_margins, persistent);
7937 return w ? (apply_window_adjustment (w), Qt) : Qnil;
7938 }
7939
7940
7941 DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
7942 0, 1, 0,
7943 doc:
7944
7945
7946
7947 )
7948 (Lisp_Object window)
7949 {
7950 struct window *w = decode_live_window (window);
7951
7952 return list4 (make_fixnum (WINDOW_LEFT_FRINGE_WIDTH (w)),
7953 make_fixnum (WINDOW_RIGHT_FRINGE_WIDTH (w)),
7954 WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ? Qt : Qnil,
7955 w->fringes_persistent ? Qt : Qnil);
7956 }
7957
7958
7959
7960
7961
7962
7963
7964 static struct window *
7965 set_window_scroll_bars (struct window *w, Lisp_Object width,
7966 Lisp_Object vertical_type, Lisp_Object height,
7967 Lisp_Object horizontal_type, Lisp_Object persistent)
7968 {
7969
7970 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w)))
7971 return NULL;
7972 else
7973 {
7974 struct frame *f = XFRAME (WINDOW_FRAME (w));
7975 int new_width = extract_dimension (width);
7976 bool changed = false;
7977 bool failed = false;
7978
7979 if (new_width == 0)
7980 vertical_type = Qnil;
7981 else if (!(NILP (vertical_type)
7982 || EQ (vertical_type, Qleft)
7983 || EQ (vertical_type, Qright)
7984 || EQ (vertical_type, Qt)))
7985 error ("Invalid type of vertical scroll bar");
7986
7987
7988
7989 if ((WINDOW_PIXEL_WIDTH (w)
7990 - WINDOW_MARGINS_WIDTH (w)
7991 - WINDOW_FRINGES_WIDTH (w)
7992 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
7993 - (new_width == -1 ? FRAME_SCROLL_BAR_AREA_WIDTH (f) : new_width))
7994 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7995 {
7996 changed = (!EQ (vertical_type, w->vertical_scroll_bar_type)
7997 || new_width != WINDOW_SCROLL_BAR_AREA_WIDTH (w));
7998 wset_vertical_scroll_bar_type (w, vertical_type);
7999 w->scroll_bar_width = new_width;
8000 }
8001 else
8002 failed = true;
8003
8004 #if USE_HORIZONTAL_SCROLL_BARS
8005 int new_height = extract_dimension (height);
8006
8007 if ((MINI_WINDOW_P (w) && !EQ (horizontal_type, Qbottom))
8008 || new_height == 0)
8009 horizontal_type = Qnil;
8010
8011 if (!(NILP (horizontal_type)
8012 || EQ (horizontal_type, Qbottom)
8013 || EQ (horizontal_type, Qt)))
8014 error ("Invalid type of horizontal scroll bar");
8015
8016
8017 if ((WINDOW_PIXEL_HEIGHT (w)
8018 - WINDOW_TAB_LINE_HEIGHT (w)
8019 - WINDOW_HEADER_LINE_HEIGHT (w)
8020 - WINDOW_MODE_LINE_HEIGHT (w)
8021 - (new_height == -1 ? FRAME_SCROLL_BAR_AREA_HEIGHT (f) : new_height))
8022 >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
8023 {
8024 changed = (changed
8025 || !EQ (horizontal_type, w->horizontal_scroll_bar_type)
8026 || new_height != WINDOW_SCROLL_BAR_AREA_HEIGHT (w));
8027 wset_horizontal_scroll_bar_type (w, horizontal_type);
8028 w->scroll_bar_height = new_height;
8029 }
8030 else
8031 failed = true;
8032 #else
8033 wset_horizontal_scroll_bar_type (w, Qnil);
8034 #endif
8035
8036
8037
8038 if (!failed)
8039 w->scroll_bars_persistent = !NILP (persistent);
8040
8041
8042
8043
8044
8045 if (changed)
8046 wset_redisplay (w);
8047
8048 return changed ? w : NULL;
8049 }
8050 }
8051
8052 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
8053 Sset_window_scroll_bars, 1, 6, 0,
8054 doc:
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081 )
8082 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
8083 Lisp_Object height, Lisp_Object horizontal_type, Lisp_Object persistent)
8084 {
8085 struct window *w
8086 = set_window_scroll_bars (decode_live_window (window),
8087 width, vertical_type, height,
8088 horizontal_type, persistent);
8089 return w ? (apply_window_adjustment (w), Qt) : Qnil;
8090 }
8091
8092
8093 DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
8094 0, 1, 0,
8095 doc:
8096
8097
8098
8099
8100
8101 )
8102 (Lisp_Object window)
8103 {
8104 struct window *w = decode_live_window (window);
8105
8106 return Fcons (((w->scroll_bar_width >= 0)
8107 ? make_fixnum (w->scroll_bar_width)
8108 : Qnil),
8109 Fcons (make_fixnum (WINDOW_SCROLL_BAR_COLS (w)),
8110 list5 (w->vertical_scroll_bar_type,
8111 ((w->scroll_bar_height >= 0)
8112 ? make_fixnum (w->scroll_bar_height)
8113 : Qnil),
8114 make_fixnum (WINDOW_SCROLL_BAR_LINES (w)),
8115 w->horizontal_scroll_bar_type,
8116 w->scroll_bars_persistent ? Qt : Qnil)));
8117 }
8118
8119
8120
8121
8122
8123 DEFUN ("window-vscroll", Fwindow_vscroll, Swindow_vscroll, 0, 2, 0,
8124 doc:
8125
8126
8127
8128
8129 )
8130 (Lisp_Object window, Lisp_Object pixels_p)
8131 {
8132 Lisp_Object result;
8133 struct window *w = decode_live_window (window);
8134 struct frame *f = XFRAME (w->frame);
8135
8136 if (FRAME_WINDOW_P (f))
8137 result = (NILP (pixels_p)
8138 ? FRAME_CANON_Y_FROM_PIXEL_Y (f, -w->vscroll)
8139 : make_fixnum (-w->vscroll));
8140 else
8141 result = make_fixnum (0);
8142 return result;
8143 }
8144
8145
8146 DEFUN ("set-window-vscroll", Fset_window_vscroll, Sset_window_vscroll,
8147 2, 4, 0,
8148 doc:
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160 )
8161 (Lisp_Object window, Lisp_Object vscroll, Lisp_Object pixels_p,
8162 Lisp_Object preserve_vscroll_p)
8163 {
8164 struct window *w = decode_live_window (window);
8165 struct frame *f = XFRAME (w->frame);
8166
8167 CHECK_NUMBER (vscroll);
8168
8169 if (FRAME_WINDOW_P (f))
8170 {
8171 int old_dy = w->vscroll;
8172
8173 w->vscroll = - (NILP (pixels_p)
8174 ? FRAME_LINE_HEIGHT (f) * XFLOATINT (vscroll)
8175 : XFLOATINT (vscroll));
8176 w->vscroll = min (w->vscroll, 0);
8177
8178 if (w->vscroll != old_dy)
8179 {
8180
8181
8182 if (w->vscroll < 0 && w->vscroll < old_dy)
8183 adjust_frame_glyphs (f);
8184
8185
8186 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true;
8187
8188
8189 wset_redisplay (w);
8190 }
8191
8192 w->preserve_vscroll_p = !NILP (preserve_vscroll_p);
8193 }
8194
8195 return Fwindow_vscroll (window, pixels_p);
8196 }
8197
8198
8199
8200
8201
8202
8203 static void
8204 foreach_window (struct frame *f, bool (*fn) (struct window *, void *),
8205 void *user_data)
8206 {
8207
8208 if (WINDOWP (FRAME_ROOT_WINDOW (f)))
8209 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data);
8210 }
8211
8212
8213
8214
8215
8216
8217
8218 static bool
8219 foreach_window_1 (struct window *w, bool (*fn) (struct window *, void *),
8220 void *user_data)
8221 {
8222 bool cont;
8223
8224 for (cont = true; w && cont;)
8225 {
8226 if (WINDOWP (w->contents))
8227 cont = foreach_window_1 (XWINDOW (w->contents), fn, user_data);
8228 else
8229 cont = fn (w, user_data);
8230
8231 w = NILP (w->next) ? 0 : XWINDOW (w->next);
8232 }
8233
8234 return cont;
8235 }
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250 static bool
8251 compare_window_configurations (Lisp_Object configuration1,
8252 Lisp_Object configuration2)
8253 {
8254 struct save_window_data *d1, *d2;
8255 struct Lisp_Vector *sws1, *sws2;
8256 ptrdiff_t i;
8257
8258 CHECK_WINDOW_CONFIGURATION (configuration1);
8259 CHECK_WINDOW_CONFIGURATION (configuration2);
8260
8261 d1 = (struct save_window_data *) XVECTOR (configuration1);
8262 d2 = (struct save_window_data *) XVECTOR (configuration2);
8263 sws1 = XVECTOR (d1->saved_windows);
8264 sws2 = XVECTOR (d2->saved_windows);
8265
8266
8267 if (d1->frame_cols != d2->frame_cols
8268 || d1->frame_lines != d2->frame_lines
8269 || d1->frame_menu_bar_lines != d2->frame_menu_bar_lines
8270 || !EQ (d1->selected_frame, d2->selected_frame)
8271 || !EQ (d1->f_current_buffer, d2->f_current_buffer)
8272 || !EQ (d1->focus_frame, d2->focus_frame)
8273
8274 || sws1->header.size != sws2->header.size)
8275 return false;
8276
8277 for (i = 0; i < sws1->header.size; i++)
8278 {
8279 struct saved_window *sw1, *sw2;
8280
8281 sw1 = SAVED_WINDOW_N (sws1, i);
8282 sw2 = SAVED_WINDOW_N (sws2, i);
8283
8284 if (
8285
8286
8287 EQ (d1->current_window, sw1->window)
8288 != EQ (d2->current_window, sw2->window)
8289
8290 || !EQ (sw1->buffer, sw2->buffer)
8291 || !EQ (sw1->pixel_left, sw2->pixel_left)
8292 || !EQ (sw1->pixel_top, sw2->pixel_top)
8293 || !EQ (sw1->pixel_height, sw2->pixel_height)
8294 || !EQ (sw1->pixel_width, sw2->pixel_width)
8295 || !EQ (sw1->left_col, sw2->left_col)
8296 || !EQ (sw1->top_line, sw2->top_line)
8297 || !EQ (sw1->total_cols, sw2->total_cols)
8298 || !EQ (sw1->total_lines, sw2->total_lines)
8299 || !EQ (sw1->display_table, sw2->display_table)
8300
8301
8302 || !EQ (sw1->parent, sw2->parent)
8303 || !EQ (sw1->prev, sw2->prev)
8304 || !EQ (sw1->left_margin_cols, sw2->left_margin_cols)
8305 || !EQ (sw1->right_margin_cols, sw2->right_margin_cols)
8306 || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
8307 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
8308 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
8309 || !EQ (sw1->fringes_persistent, sw2->fringes_persistent)
8310 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
8311 || !EQ (sw1->scroll_bar_height, sw2->scroll_bar_height)
8312 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)
8313 || !EQ (sw1->horizontal_scroll_bar_type, sw2->horizontal_scroll_bar_type)
8314 || !EQ (sw1->scroll_bars_persistent, sw2->scroll_bars_persistent))
8315 return false;
8316 }
8317
8318 return true;
8319 }
8320
8321 DEFUN ("window-configuration-equal-p", Fwindow_configuration_equal_p,
8322 Swindow_configuration_equal_p, 2, 2, 0,
8323 doc:
8324
8325 )
8326 (Lisp_Object x, Lisp_Object y)
8327 {
8328 if (compare_window_configurations (x, y))
8329 return Qt;
8330 return Qnil;
8331 }
8332
8333
8334 static void init_window_once_for_pdumper (void);
8335
8336 void
8337 init_window_once (void)
8338 {
8339 minibuf_window = Qnil;
8340 staticpro (&minibuf_window);
8341
8342 selected_window = Qnil;
8343 staticpro (&selected_window);
8344
8345 Vwindow_list = Qnil;
8346 staticpro (&Vwindow_list);
8347
8348 minibuf_selected_window = Qnil;
8349 staticpro (&minibuf_selected_window);
8350 old_selected_window = Qnil;
8351 staticpro (&old_selected_window);
8352
8353 pdumper_do_now_and_after_late_load (init_window_once_for_pdumper);
8354 }
8355
8356 static void init_window_once_for_pdumper (void)
8357 {
8358 window_scroll_pixel_based_preserve_x = -1;
8359 window_scroll_pixel_based_preserve_y = -1;
8360 window_scroll_preserve_hpos = -1;
8361 window_scroll_preserve_vpos = -1;
8362 PDUMPER_IGNORE (sequence_number);
8363
8364 PDUMPER_RESET_LV (minibuf_window, Qnil);
8365 PDUMPER_RESET_LV (selected_window, Qnil);
8366 PDUMPER_RESET_LV (Vwindow_list, Qnil);
8367 PDUMPER_RESET_LV (minibuf_selected_window, Qnil);
8368
8369
8370
8371
8372
8373
8374 bool old_mode_line_in_non_selected_windows;
8375
8376
8377 bool saved_dumped_with_pdumper = dumped_with_pdumper_p ();
8378 if (saved_dumped_with_pdumper)
8379 {
8380 old_mode_line_in_non_selected_windows
8381 = mode_line_in_non_selected_windows;
8382 mode_line_in_non_selected_windows = false;
8383 }
8384 struct frame *f = make_initial_frame ();
8385 if (saved_dumped_with_pdumper)
8386 mode_line_in_non_selected_windows =
8387 old_mode_line_in_non_selected_windows;
8388 XSETFRAME (selected_frame, f);
8389 old_selected_frame = Vterminal_frame = selected_frame;
8390 minibuf_window = f->minibuffer_window;
8391 old_selected_window = selected_window = f->selected_window;
8392 }
8393
8394 void
8395 init_window (void)
8396 {
8397 Vwindow_list = Qnil;
8398 }
8399
8400 void
8401 syms_of_window (void)
8402 {
8403 DEFSYM (Qscroll_up, "scroll-up");
8404 DEFSYM (Qscroll_down, "scroll-down");
8405 DEFSYM (Qscroll_command, "scroll-command");
8406
8407 Fput (Qscroll_up, Qscroll_command, Qt);
8408 Fput (Qscroll_down, Qscroll_command, Qt);
8409
8410 DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook");
8411 DEFSYM (Qwindow_state_change_hook, "window-state-change-hook");
8412 DEFSYM (Qwindow_state_change_functions, "window-state-change-functions");
8413 DEFSYM (Qwindow_size_change_functions, "window-size-change-functions");
8414 DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions");
8415 DEFSYM (Qwindow_selection_change_functions, "window-selection-change-functions");
8416 DEFSYM (Qwindowp, "windowp");
8417 DEFSYM (Qwindow_configuration_p, "window-configuration-p");
8418 DEFSYM (Qwindow_live_p, "window-live-p");
8419 DEFSYM (Qwindow_valid_p, "window-valid-p");
8420 DEFSYM (Qwindow_deletable_p, "window-deletable-p");
8421 DEFSYM (Qdelete_window, "delete-window");
8422 DEFSYM (Qwindow__resize_root_window, "window--resize-root-window");
8423 DEFSYM (Qwindow__resize_root_window_vertically,
8424 "window--resize-root-window-vertically");
8425 DEFSYM (Qwindow__resize_mini_frame, "window--resize-mini-frame");
8426 DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total");
8427 DEFSYM (Qsafe, "safe");
8428 DEFSYM (Qdisplay_buffer, "display-buffer");
8429 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
8430 DEFSYM (Qrecord_window_buffer, "record-window-buffer");
8431 DEFSYM (Qget_mru_window, "get-mru-window");
8432 DEFSYM (Qwindow_size, "window-size");
8433 DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
8434 DEFSYM (Qabove, "above");
8435 DEFSYM (Qclone_of, "clone-of");
8436 DEFSYM (Qfloor, "floor");
8437 DEFSYM (Qceiling, "ceiling");
8438 DEFSYM (Qmark_for_redisplay, "mark-for-redisplay");
8439 DEFSYM (Qmode_line_format, "mode-line-format");
8440 DEFSYM (Qheader_line_format, "header-line-format");
8441 DEFSYM (Qtab_line_format, "tab-line-format");
8442 DEFSYM (Qno_other_window, "no-other-window");
8443
8444 DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
8445 doc:
8446
8447
8448
8449 );
8450 Vtemp_buffer_show_function = Qnil;
8451
8452 DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window,
8453 doc: );
8454 Vminibuf_scroll_window = Qnil;
8455
8456 DEFVAR_BOOL ("mode-line-in-non-selected-windows", mode_line_in_non_selected_windows,
8457 doc:
8458
8459 );
8460 mode_line_in_non_selected_windows = true;
8461
8462 DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer,
8463 doc: );
8464 Vother_window_scroll_buffer = Qnil;
8465
8466 DEFVAR_LISP ("other-window-scroll-default", Vother_window_scroll_default,
8467 doc:
8468
8469
8470
8471 );
8472 Vother_window_scroll_default = Qnil;
8473
8474 DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
8475 doc: );
8476 auto_window_vscroll_p = true;
8477
8478 DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
8479 doc: );
8480 next_screen_context_lines = 2;
8481
8482 DEFVAR_LISP ("scroll-preserve-screen-position",
8483 Vscroll_preserve_screen_position,
8484 doc:
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498 );
8499 Vscroll_preserve_screen_position = Qnil;
8500
8501 DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type,
8502 doc:
8503 );
8504 Vwindow_point_insertion_type = Qnil;
8505 DEFSYM (Qwindow_point_insertion_type, "window-point-insertion-type");
8506
8507 DEFVAR_LISP ("window-buffer-change-functions", Vwindow_buffer_change_functions,
8508 doc:
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519 );
8520 Vwindow_buffer_change_functions = Qnil;
8521
8522 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
8523 doc:
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537 );
8538 Vwindow_size_change_functions = Qnil;
8539
8540 DEFVAR_LISP ("window-selection-change-functions", Vwindow_selection_change_functions,
8541 doc:
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551 );
8552 Vwindow_selection_change_functions = Qnil;
8553
8554 DEFVAR_LISP ("window-state-change-functions", Vwindow_state_change_functions,
8555 doc:
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568 );
8569 Vwindow_state_change_functions = Qnil;
8570
8571 DEFVAR_LISP ("window-state-change-hook", Vwindow_state_change_hook,
8572 doc:
8573
8574
8575
8576
8577
8578
8579
8580
8581 );
8582 Vwindow_state_change_hook = Qnil;
8583
8584 DEFVAR_LISP ("window-configuration-change-hook", Vwindow_configuration_change_hook,
8585 doc:
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597 );
8598 Vwindow_configuration_change_hook = Qnil;
8599
8600 DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
8601 doc:
8602
8603
8604 );
8605 Vrecenter_redisplay = Qtty;
8606
8607 DEFVAR_LISP ("window-combination-resize", Vwindow_combination_resize,
8608 doc:
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622 );
8623 Vwindow_combination_resize = Qnil;
8624
8625 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
8626 doc:
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660 );
8661 Vwindow_combination_limit = Qwindow_size;
8662
8663 DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
8664 doc:
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685 );
8686 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
8687
8688 DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise,
8689 doc:
8690
8691
8692
8693
8694
8695
8696 );
8697 window_resize_pixelwise = false;
8698
8699 DEFVAR_BOOL ("fast-but-imprecise-scrolling",
8700 fast_but_imprecise_scrolling,
8701 doc:
8702
8703
8704
8705
8706
8707 );
8708 fast_but_imprecise_scrolling = false;
8709
8710 defsubr (&Sselected_window);
8711 defsubr (&Sold_selected_window);
8712 defsubr (&Sminibuffer_window);
8713 defsubr (&Swindow_minibuffer_p);
8714 defsubr (&Swindowp);
8715 defsubr (&Swindow_valid_p);
8716 defsubr (&Swindow_live_p);
8717 defsubr (&Swindow_frame);
8718 defsubr (&Sframe_root_window);
8719 defsubr (&Sframe_first_window);
8720 defsubr (&Sframe_selected_window);
8721 defsubr (&Sframe_old_selected_window);
8722 defsubr (&Sset_frame_selected_window);
8723 defsubr (&Spos_visible_in_window_p);
8724 defsubr (&Swindow_line_height);
8725 defsubr (&Swindow_buffer);
8726 defsubr (&Swindow_old_buffer);
8727 defsubr (&Swindow_parent);
8728 defsubr (&Swindow_top_child);
8729 defsubr (&Swindow_left_child);
8730 defsubr (&Swindow_next_sibling);
8731 defsubr (&Swindow_prev_sibling);
8732 defsubr (&Swindow_combination_limit);
8733 defsubr (&Sset_window_combination_limit);
8734 defsubr (&Swindow_use_time);
8735 defsubr (&Swindow_pixel_width);
8736 defsubr (&Swindow_pixel_height);
8737 defsubr (&Swindow_old_pixel_width);
8738 defsubr (&Swindow_old_pixel_height);
8739 defsubr (&Swindow_old_body_pixel_width);
8740 defsubr (&Swindow_old_body_pixel_height);
8741 defsubr (&Swindow_total_width);
8742 defsubr (&Swindow_total_height);
8743 defsubr (&Swindow_normal_size);
8744 defsubr (&Swindow_new_pixel);
8745 defsubr (&Swindow_new_total);
8746 defsubr (&Swindow_new_normal);
8747 defsubr (&Swindow_pixel_left);
8748 defsubr (&Swindow_pixel_top);
8749 defsubr (&Swindow_left_column);
8750 defsubr (&Swindow_top_line);
8751 defsubr (&Sset_window_new_pixel);
8752 defsubr (&Sset_window_new_total);
8753 defsubr (&Sset_window_new_normal);
8754 defsubr (&Swindow_resize_apply);
8755 defsubr (&Swindow_resize_apply_total);
8756 defsubr (&Swindow_body_height);
8757 defsubr (&Swindow_body_width);
8758 defsubr (&Swindow_hscroll);
8759 defsubr (&Sset_window_hscroll);
8760 defsubr (&Swindow_mode_line_height);
8761 defsubr (&Swindow_header_line_height);
8762 defsubr (&Swindow_tab_line_height);
8763 defsubr (&Swindow_right_divider_width);
8764 defsubr (&Swindow_bottom_divider_width);
8765 defsubr (&Swindow_scroll_bar_width);
8766 defsubr (&Swindow_scroll_bar_height);
8767 defsubr (&Scoordinates_in_window_p);
8768 defsubr (&Swindow_at);
8769 defsubr (&Swindow_point);
8770 defsubr (&Swindow_old_point);
8771 defsubr (&Swindow_start);
8772 defsubr (&Swindow_end);
8773 defsubr (&Sset_window_point);
8774 defsubr (&Sset_window_start);
8775 defsubr (&Swindow_dedicated_p);
8776 defsubr (&Swindow_lines_pixel_dimensions);
8777 defsubr (&Sset_window_dedicated_p);
8778 defsubr (&Swindow_display_table);
8779 defsubr (&Sset_window_display_table);
8780 defsubr (&Snext_window);
8781 defsubr (&Sprevious_window);
8782 defsubr (&Sget_buffer_window);
8783 defsubr (&Sdelete_other_windows_internal);
8784 defsubr (&Sdelete_window_internal);
8785 defsubr (&Sresize_mini_window_internal);
8786 defsubr (&Sset_window_buffer);
8787 defsubr (&Srun_window_configuration_change_hook);
8788 defsubr (&Srun_window_scroll_functions);
8789 defsubr (&Sselect_window);
8790 defsubr (&Sforce_window_update);
8791 defsubr (&Ssplit_window_internal);
8792 defsubr (&Sscroll_up);
8793 defsubr (&Sscroll_down);
8794 defsubr (&Sscroll_left);
8795 defsubr (&Sscroll_right);
8796 defsubr (&Sother_window_for_scrolling);
8797 defsubr (&Sminibuffer_selected_window);
8798 defsubr (&Srecenter);
8799 defsubr (&Swindow_text_width);
8800 defsubr (&Swindow_text_height);
8801 defsubr (&Smove_to_window_line);
8802 defsubr (&Swindow_configuration_p);
8803 defsubr (&Swindow_configuration_frame);
8804 defsubr (&Sset_window_configuration);
8805 defsubr (&Scurrent_window_configuration);
8806 defsubr (&Sset_window_margins);
8807 defsubr (&Swindow_margins);
8808 defsubr (&Sset_window_fringes);
8809 defsubr (&Swindow_fringes);
8810 defsubr (&Sset_window_scroll_bars);
8811 defsubr (&Swindow_scroll_bars);
8812 defsubr (&Swindow_vscroll);
8813 defsubr (&Sset_window_vscroll);
8814 defsubr (&Swindow_configuration_equal_p);
8815 defsubr (&Swindow_bump_use_time);
8816 defsubr (&Swindow_list);
8817 defsubr (&Swindow_list_1);
8818 defsubr (&Swindow_prev_buffers);
8819 defsubr (&Sset_window_prev_buffers);
8820 defsubr (&Swindow_next_buffers);
8821 defsubr (&Sset_window_next_buffers);
8822 defsubr (&Swindow_parameters);
8823 defsubr (&Swindow_parameter);
8824 defsubr (&Sset_window_parameter);
8825 }