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 call1 (Qreplace_buffer_in_windows, buffer);
3518 }
3519
3520
3521
3522
3523 void
3524 replace_buffer_in_windows_safely (Lisp_Object buffer)
3525 {
3526 if (buffer_window_count (XBUFFER (buffer)))
3527 {
3528 Lisp_Object tail, frame;
3529
3530
3531
3532
3533 FOR_EACH_FRAME (tail, frame)
3534 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, true, frame);
3535 }
3536 }
3537
3538
3539
3540 static void
3541 run_funs (Lisp_Object funs)
3542 {
3543 for (; CONSP (funs); funs = XCDR (funs))
3544 if (!EQ (XCAR (funs), Qt))
3545 call0 (XCAR (funs));
3546 }
3547
3548 static void
3549 select_window_norecord (Lisp_Object window)
3550 {
3551 if (WINDOW_LIVE_P (window))
3552 Fselect_window (window, Qt);
3553 }
3554
3555 static void
3556 select_frame_norecord (Lisp_Object frame)
3557 {
3558 if (FRAME_LIVE_P (XFRAME (frame)))
3559 Fselect_frame (frame, Qt);
3560 }
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571 static void
3572 run_window_configuration_change_hook (struct frame *f)
3573 {
3574 specpdl_ref count = SPECPDL_INDEX ();
3575 Lisp_Object frame, global_wcch
3576 = Fdefault_value (Qwindow_configuration_change_hook);
3577 XSETFRAME (frame, f);
3578
3579 if (NILP (Vrun_hooks)
3580 || !f->can_set_window_size
3581 || !f->after_make_frame)
3582 return;
3583
3584
3585 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
3586 {
3587 record_unwind_current_buffer ();
3588 Fset_buffer (Fwindow_buffer (Qnil));
3589 }
3590
3591 if (SELECTED_FRAME () != f)
3592 {
3593 record_unwind_protect (select_frame_norecord, selected_frame);
3594 select_frame_norecord (frame);
3595 }
3596
3597
3598 {
3599 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
3600 for (; CONSP (windows); windows = XCDR (windows))
3601 {
3602 Lisp_Object window = XCAR (windows);
3603 Lisp_Object buffer = Fwindow_buffer (window);
3604 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
3605 buffer)))
3606 {
3607 specpdl_ref inner_count = SPECPDL_INDEX ();
3608 record_unwind_protect (select_window_norecord, selected_window);
3609 select_window_norecord (window);
3610 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
3611 buffer));
3612 unbind_to (inner_count, Qnil);
3613 }
3614 }
3615 }
3616
3617 run_funs (global_wcch);
3618 unbind_to (count, Qnil);
3619 }
3620
3621 DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
3622 Srun_window_configuration_change_hook, 0, 1, 0,
3623 doc:
3624
3625
3626
3627 )
3628 (Lisp_Object frame)
3629 {
3630 run_window_configuration_change_hook (decode_live_frame (frame));
3631 return Qnil;
3632 }
3633
3634 DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions,
3635 Srun_window_scroll_functions, 0, 1, 0,
3636 doc:
3637
3638
3639
3640 )
3641 (Lisp_Object window)
3642 {
3643 struct window *w = decode_live_window (window);
3644 specpdl_ref count = SPECPDL_INDEX ();
3645
3646 record_unwind_current_buffer ();
3647 Fset_buffer (w->contents);
3648 if (!NILP (Vwindow_scroll_functions))
3649 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3650 Fmarker_position (w->start));
3651 unbind_to (count, Qnil);
3652
3653 return Qnil;
3654 }
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665 static Lisp_Object
3666 window_sub_list (Lisp_Object window, Lisp_Object windows)
3667 {
3668
3669 struct window *w = XWINDOW (window);
3670
3671 while (w)
3672 {
3673 if (WINDOW_INTERNAL_P (w))
3674 windows = window_sub_list (w->contents, windows);
3675 else
3676 windows = Fcons (window, windows);
3677
3678 window = w->next;
3679 w = NILP (window) ? 0 : XWINDOW (window);
3680 }
3681
3682 return windows;
3683 }
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700 static ptrdiff_t
3701 window_change_record_windows (Lisp_Object window, int stamp, ptrdiff_t number)
3702 {
3703 struct window *w = XWINDOW (window);
3704
3705 while (w)
3706 {
3707 if (WINDOW_INTERNAL_P (w))
3708 number = window_change_record_windows (w->contents, stamp, number);
3709 else
3710 {
3711 number += 1;
3712 w->change_stamp = stamp;
3713 wset_old_buffer (w, w->contents);
3714 w->old_pixel_width = w->pixel_width;
3715 w->old_pixel_height = w->pixel_height;
3716 w->old_body_pixel_width
3717 = window_body_width (w, WINDOW_BODY_IN_PIXELS);
3718 w->old_body_pixel_height
3719 = window_body_height (w, WINDOW_BODY_IN_PIXELS);
3720 }
3721
3722 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3723 }
3724
3725 return number;
3726 }
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740 static void
3741 window_change_record (void)
3742 {
3743 if (window_change_record_frames)
3744 {
3745 Lisp_Object tail, frame;
3746
3747 FOR_EACH_FRAME (tail, frame)
3748 {
3749 struct frame *f = XFRAME (frame);
3750
3751
3752 fset_old_selected_window (f, FRAME_SELECTED_WINDOW (f));
3753
3754
3755
3756
3757 f->change_stamp += 1;
3758 if (f->change_stamp == 0)
3759 f->change_stamp = 1;
3760
3761
3762
3763
3764 f->number_of_windows
3765 = window_change_record_windows (f->root_window, f->change_stamp, 0);
3766
3767
3768 FRAME_WINDOW_CHANGE (f) = false;
3769 FRAME_WINDOW_STATE_CHANGE (f) = false;
3770 }
3771 }
3772
3773
3774
3775 old_selected_window = selected_window;
3776 old_selected_frame = selected_frame;
3777 }
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789 static void
3790 run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer,
3791 Lisp_Object window_or_frame)
3792 {
3793 Lisp_Object funs = Qnil;
3794
3795 if (NILP (buffer))
3796 funs = Fdefault_value (symbol);
3797 else if (!NILP (Fassoc (symbol, BVAR (XBUFFER (buffer), local_var_alist),
3798 Qnil)))
3799
3800 funs = buffer_local_value (symbol, buffer);
3801
3802 while (CONSP (funs))
3803 {
3804 if (!EQ (XCAR (funs), Qt)
3805 && (NILP (buffer)
3806 ? FRAME_LIVE_P (XFRAME (window_or_frame))
3807 : WINDOW_LIVE_P (window_or_frame)))
3808 {
3809
3810
3811
3812 window_change_record_frames = true;
3813 safe_call1 (XCAR (funs), window_or_frame);
3814 }
3815
3816 funs = XCDR (funs);
3817 }
3818 }
3819
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 void
3881 run_window_change_functions (void)
3882 {
3883 Lisp_Object tail, frame;
3884 bool selected_frame_change = !EQ (selected_frame, old_selected_frame);
3885 bool run_window_state_change_hook = false;
3886 specpdl_ref count = SPECPDL_INDEX ();
3887
3888 window_change_record_frames = false;
3889 record_unwind_protect_void (window_change_record);
3890 specbind (Qinhibit_redisplay, Qt);
3891
3892 FOR_EACH_FRAME (tail, frame)
3893 {
3894 struct frame *f = XFRAME (frame);
3895 Lisp_Object root = FRAME_ROOT_WINDOW (f);
3896 bool frame_window_change = FRAME_WINDOW_CHANGE (f);
3897 bool window_buffer_change, window_size_change;
3898 bool frame_buffer_change = false, frame_size_change = false;
3899 bool frame_selected_change
3900 = (selected_frame_change
3901 && (EQ (frame, old_selected_frame)
3902 || EQ (frame, selected_frame)));
3903 bool frame_selected_window_change
3904 = !EQ (FRAME_OLD_SELECTED_WINDOW (f), FRAME_SELECTED_WINDOW (f));
3905 bool frame_window_state_change = FRAME_WINDOW_STATE_CHANGE (f);
3906 bool window_deleted = false;
3907 Lisp_Object windows;
3908 ptrdiff_t number_of_windows;
3909
3910 if (!FRAME_LIVE_P (f)
3911 || !f->can_set_window_size
3912 || !f->after_make_frame
3913 || FRAME_TOOLTIP_P (f)
3914 || !(frame_window_change
3915 || frame_selected_change
3916 || frame_selected_window_change
3917 || frame_window_state_change))
3918
3919
3920
3921 continue;
3922
3923
3924 windows = Fnreverse (window_sub_list (root, Qnil));
3925 number_of_windows = 0;
3926
3927
3928
3929
3930 for (; CONSP (windows); windows = XCDR (windows))
3931 {
3932 Lisp_Object window = XCAR (windows);
3933 struct window *w = XWINDOW (window);
3934 Lisp_Object buffer = WINDOW_BUFFER (w);
3935
3936
3937
3938 number_of_windows += 1;
3939
3940 if (!WINDOW_LIVE_P (window))
3941 continue;
3942
3943
3944
3945
3946 window_buffer_change =
3947 (frame_window_change
3948 && (!EQ (buffer, w->old_buffer)
3949 || w->change_stamp != f->change_stamp));
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959 window_size_change =
3960 (frame_window_change
3961 && (window_buffer_change
3962 || w->pixel_width != w->old_pixel_width
3963 || w->pixel_height != w->old_pixel_height
3964 || (window_body_width (w, WINDOW_BODY_IN_PIXELS)
3965 != w->old_body_pixel_width)
3966 || (window_body_height (w, WINDOW_BODY_IN_PIXELS)
3967 != w->old_body_pixel_height)));
3968
3969
3970
3971 frame_buffer_change = frame_buffer_change || window_buffer_change;
3972 frame_size_change = frame_size_change || window_size_change;
3973
3974 if (window_buffer_change)
3975 run_window_change_functions_1
3976 (Qwindow_buffer_change_functions, buffer, window);
3977
3978 if (window_size_change && WINDOW_LIVE_P (window))
3979 run_window_change_functions_1
3980 (Qwindow_size_change_functions, buffer, window);
3981
3982
3983
3984
3985 if (((frame_selected_change
3986 && (EQ (window, old_selected_window)
3987 || EQ (window, selected_window)))
3988 || (frame_selected_window_change
3989 && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))
3990 || EQ (window, FRAME_SELECTED_WINDOW (f)))))
3991 && WINDOW_LIVE_P (window))
3992 run_window_change_functions_1
3993 (Qwindow_selection_change_functions, buffer, window);
3994
3995
3996
3997
3998 if ((window_buffer_change
3999 || window_size_change
4000 || ((frame_selected_change
4001 && (EQ (window, old_selected_window)
4002 || EQ (window, selected_window)))
4003 || (frame_selected_window_change
4004 && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))
4005 || EQ (window, FRAME_SELECTED_WINDOW (f))))))
4006 && WINDOW_LIVE_P (window))
4007 run_window_change_functions_1
4008 (Qwindow_state_change_functions, buffer, window);
4009 }
4010
4011
4012
4013
4014
4015
4016
4017
4018 window_deleted = number_of_windows < f->number_of_windows;
4019
4020
4021 if ((frame_buffer_change || window_deleted) && FRAME_LIVE_P (f))
4022 run_window_change_functions_1
4023 (Qwindow_buffer_change_functions, Qnil, frame);
4024
4025
4026
4027 if (frame_size_change && FRAME_LIVE_P (f))
4028 run_window_change_functions_1
4029 (Qwindow_size_change_functions, Qnil, frame);
4030
4031
4032
4033 if ((frame_selected_change || frame_selected_window_change)
4034 && FRAME_LIVE_P (f))
4035 run_window_change_functions_1
4036 (Qwindow_selection_change_functions, Qnil, frame);
4037
4038
4039
4040
4041 if ((frame_selected_change || frame_selected_window_change
4042 || frame_buffer_change || window_deleted
4043 || frame_size_change || frame_window_state_change)
4044 && FRAME_LIVE_P (f))
4045 {
4046 run_window_change_functions_1
4047 (Qwindow_state_change_functions, Qnil, frame);
4048
4049 run_window_state_change_hook = true;
4050
4051
4052 window_change_record_frames = true;
4053 }
4054
4055
4056
4057 if ((frame_size_change || window_deleted) && FRAME_LIVE_P (f))
4058
4059
4060 run_window_configuration_change_hook (f);
4061 }
4062
4063
4064
4065 if (run_window_state_change_hook && !NILP (Vwindow_state_change_hook))
4066 safe_run_hooks (Qwindow_state_change_hook);
4067
4068
4069
4070 unbind_to (count, Qnil);
4071 }
4072
4073
4074
4075
4076
4077
4078
4079 void
4080 set_window_buffer (Lisp_Object window, Lisp_Object buffer,
4081 bool run_hooks_p, bool keep_margins_p)
4082 {
4083 struct window *w = XWINDOW (window);
4084 struct buffer *b = XBUFFER (buffer);
4085 specpdl_ref count = SPECPDL_INDEX ();
4086 bool samebuf = EQ (buffer, w->contents);
4087
4088 wset_buffer (w, buffer);
4089
4090 if (EQ (window, selected_window))
4091 bset_last_selected_window (b, window);
4092
4093
4094 b->display_error_modiff = 0;
4095
4096
4097 if (INTEGERP (BVAR (b, display_count)))
4098 bset_display_count (b, Fadd1 (BVAR (b, display_count)));
4099 bset_display_time (b, Fcurrent_time ());
4100
4101 w->window_end_pos = 0;
4102 w->window_end_vpos = 0;
4103 w->last_cursor_vpos = 0;
4104
4105 if (!(keep_margins_p && samebuf))
4106 {
4107
4108
4109
4110 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
4111 w->suspend_auto_hscroll = false;
4112 w->vscroll = 0;
4113 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
4114 set_marker_both (w->old_pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
4115 set_marker_restricted (w->start,
4116 make_fixnum (b->last_window_start),
4117 buffer);
4118 w->start_at_line_beg = false;
4119 w->force_start = false;
4120 }
4121
4122 wset_redisplay (w);
4123 wset_update_mode_line (w);
4124
4125
4126
4127 record_unwind_current_buffer ();
4128 Fset_buffer (buffer);
4129
4130 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
4131 XMARKER (w->old_pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
4132
4133 if (!keep_margins_p)
4134 {
4135
4136
4137 if (!w->fringes_persistent)
4138 set_window_fringes (w, BVAR (b, left_fringe_width),
4139 BVAR (b, right_fringe_width),
4140 BVAR (b, fringes_outside_margins), Qnil);
4141 if (!w->scroll_bars_persistent)
4142 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
4143 BVAR (b, vertical_scroll_bar_type),
4144 BVAR (b, scroll_bar_height),
4145 BVAR (b, horizontal_scroll_bar_type), Qnil);
4146
4147 set_window_margins (w, BVAR (b, left_margin_cols),
4148 BVAR (b, right_margin_cols));
4149 apply_window_adjustment (w);
4150 }
4151
4152 if (run_hooks_p && !NILP (Vwindow_scroll_functions))
4153 run_hook_with_args_2 (Qwindow_scroll_functions, window,
4154 Fmarker_position (w->start));
4155
4156
4157
4158
4159
4160
4161
4162 if (!samebuf && !MINI_WINDOW_P (w) && !WINDOW_PSEUDO_P (w))
4163 FRAME_WINDOW_CHANGE (XFRAME (w->frame)) = true;
4164
4165 unbind_to (count, Qnil);
4166 }
4167
4168 DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
4169 doc:
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183 )
4184 (register Lisp_Object window, Lisp_Object buffer_or_name, Lisp_Object keep_margins)
4185 {
4186 register Lisp_Object tem, buffer;
4187 register struct window *w = decode_live_window (window);
4188
4189 XSETWINDOW (window, w);
4190 buffer = Fget_buffer (buffer_or_name);
4191 CHECK_BUFFER (buffer);
4192 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
4193 error ("Attempt to display deleted buffer");
4194
4195 tem = w->contents;
4196 if (NILP (tem))
4197 error ("Window is deleted");
4198 else
4199 {
4200 if (!EQ (tem, buffer))
4201 {
4202 if (EQ (w->dedicated, Qt))
4203
4204
4205 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
4206 else
4207
4208
4209 wset_dedicated (w, Qnil);
4210
4211 call1 (Qrecord_window_buffer, window);
4212 }
4213
4214 unshow_buffer (w);
4215 }
4216
4217 set_window_buffer (window, buffer, true, !NILP (keep_margins));
4218
4219 return Qnil;
4220 }
4221
4222 static Lisp_Object
4223 display_buffer (Lisp_Object buffer, Lisp_Object not_this_window_p, Lisp_Object override_frame)
4224 {
4225 return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame);
4226 }
4227
4228 DEFUN ("force-window-update", Fforce_window_update, Sforce_window_update,
4229 0, 1, 0,
4230 doc:
4231
4232
4233 )
4234 (Lisp_Object object)
4235 {
4236 if (NILP (object))
4237 {
4238 windows_or_buffers_changed = 29;
4239 update_mode_lines = 28;
4240 return Qt;
4241 }
4242
4243 if (WINDOW_LIVE_P (object))
4244 {
4245 struct window *w = XWINDOW (object);
4246 mark_window_display_accurate (object, false);
4247 w->update_mode_line = true;
4248 if (BUFFERP (w->contents))
4249 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true;
4250 update_mode_lines = 29;
4251 return Qt;
4252 }
4253
4254 if (STRINGP (object))
4255 object = Fget_buffer (object);
4256 if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object))
4257 && buffer_window_count (XBUFFER (object)))
4258 {
4259
4260
4261 object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, false, Qvisible);
4262 return NILP (object) ? Qnil : Qt;
4263 }
4264
4265
4266
4267
4268 return Qnil;
4269 }
4270
4271
4272 void
4273 temp_output_buffer_show (register Lisp_Object buf)
4274 {
4275 register struct buffer *old = current_buffer;
4276 register Lisp_Object window;
4277 register struct window *w;
4278
4279 bset_directory (XBUFFER (buf), BVAR (current_buffer, directory));
4280
4281 Fset_buffer (buf);
4282 BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF;
4283 BEGV = BEG;
4284 ZV = Z;
4285 SET_PT (BEG);
4286 set_buffer_internal (old);
4287
4288 if (!NILP (Vtemp_buffer_show_function))
4289 call1 (Vtemp_buffer_show_function, buf);
4290 else if (WINDOW_LIVE_P (window = display_buffer (buf, Qnil, Qnil)))
4291 {
4292 if (!EQ (XWINDOW (window)->frame, selected_frame))
4293 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
4294 Vminibuf_scroll_window = window;
4295 w = XWINDOW (window);
4296 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
4297 w->suspend_auto_hscroll = false;
4298 set_marker_restricted_both (w->start, buf, BEG, BEG);
4299 set_marker_restricted_both (w->pointm, buf, BEG, BEG);
4300 set_marker_restricted_both (w->old_pointm, buf, BEG, BEG);
4301
4302
4303
4304 {
4305 specpdl_ref count = SPECPDL_INDEX ();
4306 Lisp_Object prev_window, prev_buffer;
4307 prev_window = selected_window;
4308 XSETBUFFER (prev_buffer, old);
4309
4310
4311
4312
4313
4314 record_unwind_protect (restore_buffer, prev_buffer);
4315 record_unwind_protect (select_window_norecord, prev_window);
4316 Fselect_window (window, Qt);
4317 Fset_buffer (w->contents);
4318 run_hook (Qtemp_buffer_show_hook);
4319 unbind_to (count, Qnil);
4320 }
4321 }
4322 }
4323
4324
4325
4326 static struct window *
4327 allocate_window (void)
4328 {
4329 return ALLOCATE_ZEROED_PSEUDOVECTOR (struct window, mode_line_help_echo,
4330 PVEC_WINDOW);
4331 }
4332
4333
4334
4335
4336 static void
4337 make_parent_window (Lisp_Object window, bool horflag)
4338 {
4339 Lisp_Object parent;
4340 register struct window *o, *p;
4341
4342 o = XWINDOW (window);
4343 p = allocate_window ();
4344 memcpy ((char *) p + sizeof (union vectorlike_header),
4345 (char *) o + sizeof (union vectorlike_header),
4346 word_size * VECSIZE (struct window));
4347
4348 adjust_window_count (p, 1);
4349 XSETWINDOW (parent, p);
4350
4351 p->sequence_number = ++sequence_number;
4352
4353 replace_window (window, parent, true);
4354
4355 wset_next (o, Qnil);
4356 wset_prev (o, Qnil);
4357 wset_parent (o, parent);
4358
4359 wset_start (p, Qnil);
4360 wset_pointm (p, Qnil);
4361 wset_old_pointm (p, Qnil);
4362 wset_buffer (p, Qnil);
4363 wset_combination (p, horflag, window);
4364 wset_combination_limit (p, Qnil);
4365 wset_window_parameters (p, Qnil);
4366 }
4367
4368
4369 Lisp_Object
4370 make_window (void)
4371 {
4372 Lisp_Object window;
4373 register struct window *w;
4374
4375 w = allocate_window ();
4376
4377
4378 wset_normal_lines (w, make_float (1.0));
4379 wset_normal_cols (w, make_float (1.0));
4380 wset_new_total (w, make_fixnum (0));
4381 wset_new_normal (w, make_fixnum (0));
4382 wset_new_pixel (w, make_fixnum (0));
4383 wset_start (w, Fmake_marker ());
4384 wset_pointm (w, Fmake_marker ());
4385 wset_old_pointm (w, Fmake_marker ());
4386 wset_vertical_scroll_bar_type (w, Qt);
4387 wset_horizontal_scroll_bar_type (w, Qt);
4388
4389
4390 wset_prev_buffers (w, Qnil);
4391 wset_next_buffers (w, Qnil);
4392
4393
4394
4395 w->nrows_scale_factor = w->ncols_scale_factor = 1;
4396 w->left_fringe_width = w->right_fringe_width = -1;
4397 w->mode_line_height = w->tab_line_height = w->header_line_height = -1;
4398 #ifdef HAVE_WINDOW_SYSTEM
4399 w->phys_cursor_type = NO_CURSOR;
4400 w->phys_cursor_width = -1;
4401 #endif
4402 w->sequence_number = ++sequence_number;
4403 w->scroll_bar_width = -1;
4404 w->scroll_bar_height = -1;
4405 w->column_number_displayed = -1;
4406
4407 Vwindow_list = Qnil;
4408
4409 XSETWINDOW (window, w);
4410 return window;
4411 }
4412
4413 DEFUN ("set-window-new-pixel", Fset_window_new_pixel, Sset_window_new_pixel, 2, 3, 0,
4414 doc:
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425 )
4426 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
4427 {
4428 struct window *w = decode_valid_window (window);
4429 EMACS_INT size_min = NILP (add) ? 0 : - XFIXNUM (w->new_pixel);
4430 EMACS_INT size_max = size_min + min (INT_MAX, MOST_POSITIVE_FIXNUM);
4431
4432 int checked_size = check_integer_range (size, size_min, size_max);
4433 if (NILP (add))
4434 wset_new_pixel (w, size);
4435 else
4436 wset_new_pixel (w, make_fixnum (XFIXNUM (w->new_pixel) + checked_size));
4437
4438 return w->new_pixel;
4439 }
4440
4441 DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
4442 doc:
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453 )
4454 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
4455 {
4456 struct window *w = decode_valid_window (window);
4457
4458 CHECK_FIXNUM (size);
4459 if (NILP (add))
4460 wset_new_total (w, size);
4461 else
4462 wset_new_total (w, make_fixnum (XFIXNUM (w->new_total) + XFIXNUM (size)));
4463
4464 return w->new_total;
4465 }
4466
4467 DEFUN ("set-window-new-normal", Fset_window_new_normal, Sset_window_new_normal, 1, 2, 0,
4468 doc:
4469
4470
4471
4472
4473
4474
4475 )
4476 (Lisp_Object window, Lisp_Object size)
4477 {
4478 wset_new_normal (decode_valid_window (window), size);
4479 return size;
4480 }
4481
4482
4483
4484
4485
4486
4487
4488
4489 static bool
4490 window_resize_check (struct window *w, bool horflag)
4491 {
4492 struct frame *f = XFRAME (w->frame);
4493 struct window *c;
4494
4495 if (WINDOW_VERTICAL_COMBINATION_P (w))
4496
4497 {
4498 c = XWINDOW (w->contents);
4499 if (horflag)
4500
4501 {
4502 while (c)
4503 {
4504 if (XFIXNUM (c->new_pixel) != XFIXNUM (w->new_pixel)
4505 || !window_resize_check (c, horflag))
4506 return false;
4507
4508 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4509 }
4510
4511 return true;
4512 }
4513 else
4514
4515
4516 {
4517 int remaining_pixels = XFIXNUM (w->new_pixel);
4518
4519 while (c)
4520 {
4521 if (!window_resize_check (c, horflag))
4522 return false;
4523
4524 remaining_pixels -= XFIXNUM (c->new_pixel);
4525 if (remaining_pixels < 0)
4526 return false;
4527 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4528 }
4529
4530 return remaining_pixels == 0;
4531 }
4532 }
4533 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
4534
4535 {
4536 c = XWINDOW (w->contents);
4537 if (horflag)
4538
4539
4540 {
4541 int remaining_pixels = XFIXNUM (w->new_pixel);
4542
4543 while (c)
4544 {
4545 if (!window_resize_check (c, horflag))
4546 return false;
4547
4548 remaining_pixels -= XFIXNUM (c->new_pixel);
4549 if (remaining_pixels < 0)
4550 return false;
4551 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4552 }
4553
4554 return remaining_pixels == 0;
4555 }
4556 else
4557
4558 {
4559 while (c)
4560 {
4561 if (XFIXNUM (c->new_pixel) != XFIXNUM (w->new_pixel)
4562 || !window_resize_check (c, horflag))
4563 return false;
4564
4565 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4566 }
4567
4568 return true;
4569 }
4570 }
4571 else
4572
4573
4574
4575 return (XFIXNUM (w->new_pixel) >= (horflag
4576 ? 2 * FRAME_COLUMN_WIDTH (f)
4577 : FRAME_LINE_HEIGHT (f)));
4578 }
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588 static void
4589 window_resize_apply (struct window *w, bool horflag)
4590 {
4591 struct window *c;
4592 int edge;
4593 int unit = (horflag
4594 ? FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))
4595 : FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
4596
4597
4598
4599 if (horflag)
4600 {
4601 w->pixel_width = XFIXNAT (w->new_pixel);
4602 w->total_cols = w->pixel_width / unit;
4603 if (NUMBERP (w->new_normal))
4604 wset_normal_cols (w, w->new_normal);
4605
4606 edge = w->pixel_left;
4607 }
4608 else
4609 {
4610 w->pixel_height = XFIXNAT (w->new_pixel);
4611 w->total_lines = w->pixel_height / unit;
4612 if (NUMBERP (w->new_normal))
4613 wset_normal_lines (w, w->new_normal);
4614
4615 edge = w->pixel_top;
4616 }
4617
4618 if (WINDOW_VERTICAL_COMBINATION_P (w))
4619
4620 {
4621 c = XWINDOW (w->contents);
4622 while (c)
4623 {
4624 if (horflag)
4625 {
4626 c->pixel_left = edge;
4627 c->left_col = edge / unit;
4628 }
4629 else
4630 {
4631 c->pixel_top = edge;
4632 c->top_line = edge / unit;
4633 }
4634 window_resize_apply (c, horflag);
4635 if (!horflag)
4636 edge = edge + c->pixel_height;
4637
4638 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4639 }
4640 }
4641 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
4642
4643 {
4644 c = XWINDOW (w->contents);
4645 while (c)
4646 {
4647 if (horflag)
4648 {
4649 c->pixel_left = edge;
4650 c->left_col = edge / unit;
4651 }
4652 else
4653 {
4654 c->pixel_top = edge;
4655 c->top_line = edge / unit;
4656 }
4657
4658 window_resize_apply (c, horflag);
4659 if (horflag)
4660 edge = edge + c->pixel_width;
4661
4662 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4663 }
4664 }
4665 else
4666
4667 w->window_end_valid = false;
4668
4669 if (!WINDOW_PSEUDO_P (w))
4670 FRAME_WINDOW_CHANGE (WINDOW_XFRAME (w)) = true;
4671 }
4672
4673
4674
4675
4676
4677
4678 static void
4679 window_resize_apply_total (struct window *w, bool horflag)
4680 {
4681 struct window *c;
4682 int edge;
4683
4684
4685
4686 if (horflag)
4687 {
4688 w->total_cols = XFIXNAT (w->new_total);
4689 edge = w->left_col;
4690 }
4691 else
4692 {
4693 w->total_lines = XFIXNAT (w->new_total);
4694 edge = w->top_line;
4695 }
4696
4697 if (WINDOW_VERTICAL_COMBINATION_P (w))
4698
4699 {
4700 c = XWINDOW (w->contents);
4701 while (c)
4702 {
4703 if (horflag)
4704 c->left_col = edge;
4705 else
4706 c->top_line = edge;
4707
4708 window_resize_apply_total (c, horflag);
4709 if (!horflag)
4710 edge = edge + c->total_lines;
4711
4712 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4713 }
4714 }
4715 else if (WINDOW_HORIZONTAL_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_cols;
4729
4730 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4731 }
4732 }
4733 }
4734
4735 DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
4736 doc:
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753 )
4754 (Lisp_Object frame, Lisp_Object horizontal)
4755 {
4756 struct frame *f = decode_live_frame (frame);
4757 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
4758 bool horflag = !NILP (horizontal);
4759
4760 if (!window_resize_check (r, horflag)
4761 || (XFIXNUM (r->new_pixel)
4762 != (horflag ? r->pixel_width : r->pixel_height)))
4763 return Qnil;
4764
4765 block_input ();
4766 window_resize_apply (r, horflag);
4767
4768 fset_redisplay (f);
4769
4770 adjust_frame_glyphs (f);
4771 unblock_input ();
4772
4773 return Qt;
4774 }
4775
4776
4777 DEFUN ("window-resize-apply-total", Fwindow_resize_apply_total, Swindow_resize_apply_total, 0, 2, 0,
4778 doc:
4779
4780
4781
4782
4783
4784
4785
4786 )
4787 (Lisp_Object frame, Lisp_Object horizontal)
4788 {
4789 struct frame *f = decode_live_frame (frame);
4790 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
4791
4792 block_input ();
4793
4794 r->left_col = 0;
4795 r->top_line = FRAME_TOP_MARGIN (f);
4796 window_resize_apply_total (r, !NILP (horizontal));
4797
4798 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4799 {
4800 struct window *m = XWINDOW (f->minibuffer_window);
4801
4802 if (NILP (horizontal))
4803 {
4804 m->top_line = r->top_line + r->total_lines;
4805 m->total_lines = XFIXNAT (m->new_total);
4806 }
4807 else
4808 m->total_cols = XFIXNAT (m->new_total);
4809 }
4810
4811 unblock_input ();
4812
4813 return Qt;
4814 }
4815
4816
4817
4818
4819
4820 void
4821 resize_frame_windows (struct frame *f, int size, bool horflag)
4822 {
4823 Lisp_Object root = f->root_window;
4824 struct window *r = XWINDOW (root);
4825 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
4826 int new_size, new_pixel_size;
4827 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
4828 Lisp_Object mini = f->minibuffer_window;
4829 struct window *m = WINDOWP (mini) ? XWINDOW (mini) : NULL;
4830 int mini_height = ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4831 ? (unit + m->pixel_height
4832 - window_body_height (m, WINDOW_BODY_IN_PIXELS))
4833 : 0);
4834
4835 new_pixel_size = max (horflag ? size : size - mini_height, unit);
4836 new_size = new_pixel_size / unit;
4837
4838 if (new_pixel_size == old_pixel_size
4839 && (horflag || r->pixel_top == FRAME_TOP_MARGIN_HEIGHT (f)))
4840 ;
4841 else if (WINDOW_LEAF_P (r))
4842 {
4843
4844 if (horflag)
4845 {
4846 r->total_cols = new_size;
4847 r->pixel_width = new_pixel_size;
4848 }
4849 else
4850 {
4851 r->top_line = FRAME_TOP_MARGIN (f);
4852 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4853
4854 r->total_lines = new_size;
4855 r->pixel_height = new_pixel_size;
4856 }
4857
4858 FRAME_WINDOW_CHANGE (f)
4859 = !WINDOW_PSEUDO_P (r) && new_pixel_size != old_pixel_size;
4860 }
4861 else
4862 {
4863 Lisp_Object delta;
4864
4865 if (!horflag)
4866 {
4867 r->top_line = FRAME_TOP_MARGIN (f);
4868 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4869 }
4870
4871 XSETINT (delta, new_pixel_size - old_pixel_size);
4872
4873
4874 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil, Qt);
4875 if (window_resize_check (r, horflag)
4876 && new_pixel_size == XFIXNUM (r->new_pixel))
4877 {
4878 window_resize_apply (r, horflag);
4879 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4880 }
4881 else
4882 {
4883
4884 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt, Qt);
4885 if (window_resize_check (r, horflag)
4886 && new_pixel_size == XFIXNUM (r->new_pixel))
4887 {
4888 window_resize_apply (r, horflag);
4889 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4890 }
4891 }
4892 }
4893
4894 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4895 {
4896 m = XWINDOW (mini);
4897 if (horflag)
4898 {
4899 m->total_cols = new_size;
4900 m->pixel_width = new_pixel_size;
4901 }
4902 else
4903 {
4904 m->total_lines = mini_height / unit;
4905 m->pixel_height = mini_height;
4906 m->top_line = r->top_line + r->total_lines;
4907 m->pixel_top = r->pixel_top + r->pixel_height;
4908 }
4909 }
4910
4911 fset_redisplay (f);
4912 }
4913
4914
4915 DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
4916 doc:
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936 )
4937 (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size)
4938 {
4939
4940
4941
4942
4943
4944
4945 Lisp_Object new, frame, reference;
4946 struct window *o, *p, *n, *r, *c;
4947 struct frame *f;
4948 bool horflag
4949
4950 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
4951
4952 CHECK_WINDOW (old);
4953 o = XWINDOW (old);
4954 frame = WINDOW_FRAME (o);
4955 f = XFRAME (frame);
4956
4957 CHECK_FIXNUM (pixel_size);
4958 EMACS_INT total_size
4959 = XFIXNUM (pixel_size) / (horflag
4960 ? FRAME_COLUMN_WIDTH (f)
4961 : FRAME_LINE_HEIGHT (f));
4962
4963
4964
4965
4966 bool combination_limit
4967 = (EQ (Vwindow_combination_limit, Qt)
4968 || NILP (o->parent)
4969 || (horflag
4970 ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
4971 : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent))));
4972
4973
4974 if (WINDOW_LIVE_P (old))
4975
4976 reference = old;
4977 else
4978
4979 reference = FRAME_SELECTED_WINDOW (f);
4980 r = XWINDOW (reference);
4981
4982
4983 if (MINI_WINDOW_P (o))
4984 error ("Attempt to split minibuffer window");
4985 else if (total_size < (horflag ? 2 : 1))
4986 error ("Size of new window too small (after split)");
4987 else if (!combination_limit && !NILP (Vwindow_combination_resize))
4988
4989
4990 {
4991 p = XWINDOW (o->parent);
4992
4993 wset_new_pixel
4994 (p, make_fixnum ((horflag ? p->pixel_width : p->pixel_height)
4995 - XFIXNUM (pixel_size)));
4996 if (!window_resize_check (p, horflag))
4997 error ("Window sizes don't fit");
4998 else
4999
5000 wset_new_pixel (p, make_fixnum (horflag ? p->pixel_width : p->pixel_height));
5001 }
5002 else
5003 {
5004 if (!window_resize_check (o, horflag))
5005 error ("Resizing old window failed");
5006 else if (XFIXNUM (pixel_size) + XFIXNUM (o->new_pixel)
5007 != (horflag ? o->pixel_width : o->pixel_height))
5008 error ("Sum of sizes of old and new window don't fit");
5009 }
5010
5011
5012 if (combination_limit)
5013 {
5014
5015
5016
5017 Lisp_Object new_normal
5018 = horflag ? o->normal_cols : o->normal_lines;
5019
5020 make_parent_window (old, horflag);
5021 p = XWINDOW (o->parent);
5022 if (EQ (Vwindow_combination_limit, Qt))
5023
5024
5025 wset_combination_limit (p, Qt);
5026
5027 wset_new_pixel
5028 (p, make_fixnum (horflag ? o->pixel_width : o->pixel_height));
5029 wset_new_total
5030 (p, make_fixnum (horflag ? o->total_cols : o->total_lines));
5031 wset_new_normal (p, new_normal);
5032 }
5033 else
5034 p = XWINDOW (o->parent);
5035
5036 fset_redisplay (f);
5037 new = make_window ();
5038 n = XWINDOW (new);
5039 wset_frame (n, frame);
5040 wset_parent (n, o->parent);
5041
5042 if (EQ (side, Qabove) || EQ (side, Qleft))
5043 {
5044 wset_prev (n, o->prev);
5045 if (NILP (n->prev))
5046 wset_combination (p, horflag, new);
5047 else
5048 wset_next (XWINDOW (n->prev), new);
5049 wset_next (n, old);
5050 wset_prev (o, new);
5051 }
5052 else
5053 {
5054 wset_next (n, o->next);
5055 if (!NILP (n->next))
5056 wset_prev (XWINDOW (n->next), new);
5057 wset_prev (n, old);
5058 wset_next (o, new);
5059 }
5060
5061 n->window_end_valid = false;
5062 n->last_cursor_vpos = 0;
5063
5064
5065 n->left_margin_cols = r->left_margin_cols;
5066 n->right_margin_cols = r->right_margin_cols;
5067 n->left_fringe_width = r->left_fringe_width;
5068 n->right_fringe_width = r->right_fringe_width;
5069 n->fringes_outside_margins = r->fringes_outside_margins;
5070 n->scroll_bar_width = r->scroll_bar_width;
5071 n->scroll_bar_height = r->scroll_bar_height;
5072 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
5073 wset_horizontal_scroll_bar_type (n, r->horizontal_scroll_bar_type);
5074
5075
5076 if (horflag)
5077 {
5078 n->pixel_top = o->pixel_top;
5079 n->top_line = o->top_line;
5080 n->pixel_height = o->pixel_height;
5081 n->total_lines = o->total_lines;
5082 }
5083 else
5084 {
5085 n->pixel_left = o->pixel_left;
5086 n->left_col = o->left_col;
5087 n->pixel_width = o->pixel_width;
5088 n->total_cols = o->total_cols;
5089 }
5090
5091
5092
5093 wset_new_pixel (n, pixel_size);
5094 EMACS_INT sum = 0;
5095 c = XWINDOW (p->contents);
5096 while (c)
5097 {
5098 if (c != n)
5099 sum = sum + XFIXNUM (c->new_total);
5100 c = NILP (c->next) ? 0 : XWINDOW (c->next);
5101 }
5102 wset_new_total (n, make_fixnum ((horflag
5103 ? p->total_cols
5104 : p->total_lines)
5105 - sum));
5106 wset_new_normal (n, normal_size);
5107
5108 block_input ();
5109 window_resize_apply (p, horflag);
5110 adjust_frame_glyphs (f);
5111
5112 set_window_buffer (new, r->contents, true, true);
5113 FRAME_WINDOW_CHANGE (f) = true;
5114 unblock_input ();
5115
5116 return new;
5117 }
5118
5119
5120 DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0,
5121 doc:
5122
5123 )
5124 (Lisp_Object window)
5125 {
5126 Lisp_Object parent, sibling, frame, root;
5127 struct window *w, *p, *s, *r;
5128 struct frame *f;
5129 bool horflag, before_sibling = false;
5130
5131 w = decode_any_window (window);
5132 XSETWINDOW (window, w);
5133 if (NILP (w->contents))
5134
5135 return Qnil;
5136
5137 parent = w->parent;
5138 if (NILP (parent))
5139
5140 error ("Attempt to delete minibuffer or sole ordinary window");
5141 else if (NILP (w->prev) && NILP (w->next))
5142
5143
5144 error ("Attempt to delete sole window of parent");
5145
5146 p = XWINDOW (parent);
5147 horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
5148
5149 frame = WINDOW_FRAME (w);
5150 f = XFRAME (frame);
5151
5152 root = FRAME_ROOT_WINDOW (f);
5153 r = XWINDOW (root);
5154
5155
5156 if (NILP (w->prev))
5157
5158 {
5159
5160
5161 before_sibling = true;
5162 sibling = w->next;
5163 s = XWINDOW (sibling);
5164 wset_prev (s, Qnil);
5165 wset_combination (p, horflag, sibling);
5166 }
5167 else
5168
5169 {
5170 sibling = w->prev;
5171 s = XWINDOW (sibling);
5172 wset_next (s, w->next);
5173 if (!NILP (s->next))
5174 wset_prev (XWINDOW (s->next), sibling);
5175 }
5176
5177 if (window_resize_check (r, horflag)
5178 && (XFIXNUM (r->new_pixel)
5179 == (horflag ? r->pixel_width : r->pixel_height)))
5180
5181 {
5182
5183
5184 block_input ();
5185 xwidget_view_delete_all_in_window (w);
5186 window_resize_apply (p, horflag);
5187
5188
5189 if (!FRAME_INITIAL_P (f))
5190 {
5191 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
5192
5193 if (EQ (hlinfo->mouse_face_window, window))
5194 hlinfo->mouse_face_window = Qnil;
5195 }
5196
5197 fset_redisplay (f);
5198 Vwindow_list = Qnil;
5199
5200 wset_next (w, Qnil);
5201 free_window_matrices (w);
5202
5203 if (WINDOWP (w->contents))
5204 {
5205 delete_all_child_windows (w->contents);
5206 wset_combination (w, false, Qnil);
5207 }
5208 else
5209 {
5210 unshow_buffer (w);
5211 unchain_marker (XMARKER (w->pointm));
5212 unchain_marker (XMARKER (w->old_pointm));
5213 unchain_marker (XMARKER (w->start));
5214 wset_buffer (w, Qnil);
5215 }
5216
5217 if (NILP (s->prev) && NILP (s->next))
5218
5219
5220 {
5221
5222 replace_window (parent, sibling, false);
5223
5224
5225 wset_normal_cols (s, p->normal_cols);
5226 wset_normal_lines (s, p->normal_lines);
5227
5228 wset_combination (p, false, Qnil);
5229
5230 recombine_windows (sibling);
5231 }
5232
5233 adjust_frame_glyphs (f);
5234
5235 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
5236
5237
5238
5239 {
5240
5241 Lisp_Object new_selected_window = Fframe_first_window (frame);
5242
5243 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
5244 Fselect_window (new_selected_window, Qt);
5245 else
5246
5247
5248
5249 fset_selected_window (f, new_selected_window);
5250 }
5251
5252 unblock_input ();
5253 FRAME_WINDOW_CHANGE (f) = true;
5254 }
5255 else
5256
5257 {
5258 if (before_sibling)
5259 {
5260 wset_prev (s, window);
5261 wset_combination (p, horflag, window);
5262 }
5263 else
5264 {
5265 wset_next (s, window);
5266 if (!NILP (w->next))
5267 wset_prev (XWINDOW (w->next), window);
5268 }
5269 error ("Deletion failed");
5270 }
5271
5272 return Qnil;
5273 }
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285 static void
5286 resize_mini_window_apply (struct window *w, int delta)
5287 {
5288 struct frame *f = XFRAME (w->frame);
5289 Lisp_Object root = FRAME_ROOT_WINDOW (f);
5290 struct window *r = XWINDOW (root);
5291
5292 block_input ();
5293 w->pixel_height = w->pixel_height + delta;
5294 w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
5295
5296 window_resize_apply (r, false);
5297
5298 w->pixel_top = r->pixel_top + r->pixel_height;
5299 w->top_line = r->top_line + r->total_lines;
5300
5301
5302
5303 fset_redisplay (f);
5304 adjust_frame_glyphs (f);
5305 unblock_input ();
5306 }
5307
5308
5309
5310
5311
5312
5313
5314
5315 void
5316 grow_mini_window (struct window *w, int delta)
5317 {
5318 struct frame *f = XFRAME (w->frame);
5319 int old_height = window_body_height (w, WINDOW_BODY_IN_PIXELS);
5320 int min_height = FRAME_LINE_HEIGHT (f);
5321
5322 eassert (MINI_WINDOW_P (w));
5323
5324
5325 if (old_height + delta < min_height)
5326 delta = old_height > min_height ? min_height - old_height : 0;
5327
5328 if (delta != 0)
5329 {
5330 Lisp_Object root = FRAME_ROOT_WINDOW (f);
5331 struct window *r = XWINDOW (root);
5332 Lisp_Object grow;
5333
5334 FRAME_WINDOWS_FROZEN (f) = true;
5335 grow = call3 (Qwindow__resize_root_window_vertically,
5336 root, make_fixnum (- delta), Qt);
5337
5338 if (FIXNUMP (grow) && window_resize_check (r, false))
5339 resize_mini_window_apply (w, -XFIXNUM (grow));
5340 }
5341 }
5342
5343
5344
5345
5346
5347
5348
5349 void
5350 shrink_mini_window (struct window *w)
5351 {
5352 struct frame *f = XFRAME (w->frame);
5353 int delta = (window_body_height (w, WINDOW_BODY_IN_PIXELS)
5354 - FRAME_LINE_HEIGHT (f));
5355
5356 eassert (MINI_WINDOW_P (w));
5357
5358 if (delta > 0)
5359 {
5360 Lisp_Object root = FRAME_ROOT_WINDOW (f);
5361 struct window *r = XWINDOW (root);
5362 Lisp_Object grow;
5363
5364 FRAME_WINDOWS_FROZEN (f) = false;
5365 grow = call3 (Qwindow__resize_root_window_vertically,
5366 root, make_fixnum (delta), Qt);
5367
5368 if (FIXNUMP (grow) && window_resize_check (r, false))
5369 resize_mini_window_apply (w, -XFIXNUM (grow));
5370 }
5371 else if (delta < 0)
5372
5373
5374 grow_mini_window (w, -delta);
5375
5376 }
5377
5378 DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal,
5379 Sresize_mini_window_internal, 1, 1, 0,
5380 doc: )
5381 (Lisp_Object window)
5382 {
5383 struct window *w = XWINDOW (window);
5384 struct window *r;
5385 struct frame *f;
5386 int old_height, delta;
5387
5388 CHECK_LIVE_WINDOW (window);
5389 f = XFRAME (w->frame);
5390
5391 if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
5392 error ("Not a valid minibuffer window");
5393 else if (FRAME_MINIBUF_ONLY_P (f))
5394 error ("Cannot resize a minibuffer-only frame");
5395
5396 r = XWINDOW (FRAME_ROOT_WINDOW (f));
5397 old_height = r->pixel_height + w->pixel_height;
5398 delta = XFIXNUM (w->new_pixel) - w->pixel_height;
5399 if (window_resize_check (r, false)
5400 && XFIXNUM (w->new_pixel) > 0
5401 && old_height == XFIXNUM (r->new_pixel) + XFIXNUM (w->new_pixel))
5402 {
5403 resize_mini_window_apply (w, delta);
5404
5405 return Qt;
5406 }
5407 else
5408 error ("Cannot resize mini window");
5409 }
5410
5411
5412
5413
5414
5415
5416 void
5417 mark_window_cursors_off (struct window *w)
5418 {
5419 while (w)
5420 {
5421 if (WINDOWP (w->contents))
5422 mark_window_cursors_off (XWINDOW (w->contents));
5423 else
5424 w->phys_cursor_on_p = false;
5425
5426 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5427 }
5428 }
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443 bool
5444 window_wants_mode_line (struct window *w)
5445 {
5446 Lisp_Object window_mode_line_format =
5447 window_parameter (w, Qmode_line_format);
5448
5449 return (WINDOW_LEAF_P (w)
5450 && !MINI_WINDOW_P (w)
5451 && !WINDOW_PSEUDO_P (w)
5452 && !EQ (window_mode_line_format, Qnone)
5453 && (!NILP (window_mode_line_format)
5454 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), mode_line_format)))
5455 && WINDOW_PIXEL_HEIGHT (w) > WINDOW_FRAME_LINE_HEIGHT (w));
5456 }
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473 bool
5474 window_wants_header_line (struct window *w)
5475 {
5476 Lisp_Object window_header_line_format =
5477 window_parameter (w, Qheader_line_format);
5478
5479 return (WINDOW_LEAF_P (w)
5480 && !MINI_WINDOW_P (w)
5481 && !WINDOW_PSEUDO_P (w)
5482 && !EQ (window_header_line_format, Qnone)
5483 && (!NILP (window_header_line_format)
5484 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), header_line_format)))
5485 && (WINDOW_PIXEL_HEIGHT (w)
5486 > (window_wants_mode_line (w)
5487 ? 2 * WINDOW_FRAME_LINE_HEIGHT (w)
5488 : WINDOW_FRAME_LINE_HEIGHT (w))));
5489 }
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507 bool
5508 window_wants_tab_line (struct window *w)
5509 {
5510 Lisp_Object window_tab_line_format =
5511 window_parameter (w, Qtab_line_format);
5512
5513 return (WINDOW_LEAF_P (w)
5514 && !MINI_WINDOW_P (w)
5515 && !WINDOW_PSEUDO_P (w)
5516 && !EQ (window_tab_line_format, Qnone)
5517 && (!NILP (window_tab_line_format)
5518 || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), tab_line_format)))
5519 && (WINDOW_PIXEL_HEIGHT (w)
5520 > (((window_wants_mode_line (w) ? 1 : 0)
5521 + (window_wants_header_line (w) ? 1 : 0)
5522 + 1) * WINDOW_FRAME_LINE_HEIGHT (w))));
5523 }
5524
5525
5526
5527
5528
5529
5530 int
5531 window_internal_height (struct window *w)
5532 {
5533 int ht = w->total_lines;
5534
5535 if (window_wants_mode_line (w))
5536 --ht;
5537
5538 if (window_wants_header_line (w))
5539 --ht;
5540
5541 if (window_wants_tab_line (w))
5542 --ht;
5543
5544 return ht;
5545 }
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559 static void
5560 window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror)
5561 {
5562 struct window *w = XWINDOW (window);
5563 struct buffer *b = XBUFFER (w->contents);
5564 bool long_lines_truncated =
5565 b->long_line_optimizations_p && !NILP (BVAR (b, truncate_lines));
5566 specpdl_ref count = SPECPDL_INDEX ();
5567
5568 n = clip_to_bounds (INT_MIN, n, INT_MAX);
5569
5570 wset_redisplay (w);
5571
5572
5573 if (b->long_line_optimizations_p
5574 && !long_lines_truncated
5575 && !NILP (Vtruncate_partial_width_windows)
5576 && w->total_cols < FRAME_COLS (XFRAME (WINDOW_FRAME (w))))
5577 {
5578 if (FIXNUMP (Vtruncate_partial_width_windows))
5579 long_lines_truncated =
5580 w->total_cols < XFIXNAT (Vtruncate_partial_width_windows);
5581 else
5582 long_lines_truncated = true;
5583 }
5584
5585 if (whole && (fast_but_imprecise_scrolling || long_lines_truncated))
5586 specbind (Qfontification_functions, Qnil);
5587
5588 if (whole && long_lines_truncated)
5589 window_scroll_for_long_lines (w, n, noerror);
5590 else if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
5591 {
5592
5593
5594
5595
5596 record_unwind_protect_void (unwind_display_working_on_window);
5597 display_working_on_window_p = true;
5598 window_scroll_pixel_based (window, n, whole, noerror);
5599 }
5600 else
5601 window_scroll_line_based (window, n, whole, noerror);
5602
5603 unbind_to (count, Qnil);
5604
5605
5606 XWINDOW (window)->window_end_valid = false;
5607 }
5608
5609
5610
5611
5612
5613 int
5614 window_scroll_margin (struct window *window, enum margin_unit unit)
5615 {
5616 if (scroll_margin > 0)
5617 {
5618 int frame_line_height = default_line_pixel_height (window);
5619 int window_lines = window_box_height (window) / frame_line_height;
5620
5621 double ratio = 0.25;
5622 if (FLOATP (Vmaximum_scroll_margin))
5623 {
5624 ratio = XFLOAT_DATA (Vmaximum_scroll_margin);
5625 ratio = max (0.0, ratio);
5626 ratio = min (ratio, 0.5);
5627 }
5628 int max_margin = min ((window_lines - 1)/2,
5629 (int) (window_lines * ratio));
5630 int margin = clip_to_bounds (0, scroll_margin, max_margin);
5631 return (unit == MARGIN_IN_PIXELS)
5632 ? margin * frame_line_height
5633 : margin;
5634 }
5635 else
5636 return 0;
5637 }
5638
5639 static int
5640 sanitize_next_screen_context_lines (void)
5641 {
5642 return clip_to_bounds (0, next_screen_context_lines, 1000000);
5643 }
5644
5645
5646
5647
5648 static void
5649 window_scroll_for_long_lines (struct window *w, int n, bool noerror)
5650 {
5651 ptrdiff_t startpos = marker_position (w->start);
5652 ptrdiff_t startbyte = marker_byte_position (w->start);
5653 int nscls = sanitize_next_screen_context_lines ();
5654 register int ht = window_internal_height (w);
5655
5656 n *= max (1, ht - nscls);
5657
5658
5659 struct position pos;
5660 int rtop, rbot, dummy_rowh, dummy_vpos, dummy_x, dummy_y;
5661 if (!(PT >= startpos
5662 && PT <= ZV
5663 && startpos <= ZV
5664 && pos_visible_p (w, PT, &dummy_x, &dummy_y, &rtop, &rbot, &dummy_rowh,
5665 &dummy_vpos)
5666 && !rtop && !rbot))
5667 {
5668 pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
5669 startpos = pos.bufpos;
5670 startbyte = pos.bytepos;
5671 }
5672 SET_PT_BOTH (startpos, startbyte);
5673
5674 bool lose = n < 0 && PT == BEGV;
5675 pos = *vmotion (PT, PT_BYTE, n, w);
5676 if (lose)
5677 {
5678 if (noerror)
5679 return;
5680 else
5681 xsignal0 (Qbeginning_of_buffer);
5682 }
5683
5684 bool bolp = pos.bufpos == BEGV || FETCH_BYTE (pos.bytepos - 1) == '\n';
5685 if (pos.bufpos < ZV)
5686 {
5687 set_marker_restricted_both (w->start, w->contents,
5688 pos.bufpos, pos.bytepos);
5689 w->start_at_line_beg = bolp;
5690 wset_update_mode_line (w);
5691
5692
5693 w->force_start = true;
5694 SET_PT_BOTH (pos.bufpos, pos.bytepos);
5695 if (n > 0)
5696 pos = *vmotion (PT, PT_BYTE, ht / 2, w);
5697 else if (n < 0)
5698 pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
5699 SET_PT_BOTH (pos.bufpos, pos.bytepos);
5700 }
5701 else
5702 {
5703 if (noerror)
5704 return;
5705 else
5706 xsignal0 (Qend_of_buffer);
5707 }
5708 }
5709
5710
5711
5712
5713
5714 static void
5715 window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
5716 {
5717 struct it it;
5718 struct window *w = XWINDOW (window);
5719 struct text_pos start;
5720 int this_scroll_margin;
5721
5722 bool vscrolled = false;
5723 int x, y, rtop, rbot, rowh, vpos;
5724 void *itdata = NULL;
5725 int frame_line_height = default_line_pixel_height (w);
5726 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
5727 Fwindow_old_point (window)));
5728
5729 SET_TEXT_POS_FROM_MARKER (start, w->start);
5730
5731
5732
5733
5734 if (CHARPOS (start) > ZV || CHARPOS (start) < BEGV)
5735 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5736
5737
5738
5739
5740
5741
5742 if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
5743 {
5744 itdata = bidi_shelve_cache ();
5745
5746
5747
5748 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5749 it.current_y = it.last_visible_y;
5750 move_it_vertically_backward (&it, window_box_height (w) / 2);
5751
5752
5753
5754
5755
5756
5757 if (it.current_y <= 0)
5758 {
5759 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
5760 move_it_vertically_backward (&it, 0);
5761 it.current_y = 0;
5762 }
5763
5764 start = it.current.pos;
5765 bidi_unshelve_cache (itdata, false);
5766 }
5767 else if (auto_window_vscroll_p)
5768 {
5769 if (rtop || rbot)
5770 {
5771 int px;
5772 int dy = frame_line_height;
5773
5774
5775
5776
5777
5778 if (whole)
5779 {
5780 int ht = window_box_height (w);
5781 int nscls = sanitize_next_screen_context_lines ();
5782 dy = max (dy, (ht / dy - nscls) * dy);
5783 }
5784 dy *= n;
5785
5786 if (n < 0)
5787 {
5788
5789 if (w->vscroll < 0 && rtop > 0)
5790 {
5791 px = max (0, -w->vscroll - min (rtop, -dy));
5792 Fset_window_vscroll (window, make_fixnum (px), Qt,
5793 Qnil);
5794 return;
5795 }
5796 }
5797 if (n > 0)
5798 {
5799
5800 if (rbot > 0 && (w->vscroll < 0 || vpos == 0))
5801 {
5802 px = max (0, -w->vscroll + min (rbot, dy));
5803 Fset_window_vscroll (window, make_fixnum (px), Qt,
5804 Qnil);
5805 return;
5806 }
5807
5808
5809 if (rbot > 0 || w->vscroll < 0)
5810 {
5811 ptrdiff_t spos;
5812
5813 Fset_window_vscroll (window, make_fixnum (0), Qt,
5814 Qnil);
5815
5816
5817 if (rbot > 0)
5818 spos = XFIXNUM (Fline_beginning_position (Qnil));
5819 else
5820 spos = min (XFIXNUM (Fline_end_position (Qnil)) + 1, ZV);
5821 set_marker_restricted (w->start, make_fixnum (spos),
5822 w->contents);
5823 w->start_at_line_beg = true;
5824 wset_update_mode_line (w);
5825
5826
5827 w->force_start = true;
5828 return;
5829 }
5830 }
5831 }
5832
5833 Fset_window_vscroll (window, make_fixnum (0), Qt, Qnil);
5834 }
5835
5836 itdata = bidi_shelve_cache ();
5837
5838
5839 if (!NILP (Vscroll_preserve_screen_position))
5840 {
5841
5842
5843
5844
5845
5846 if (window_scroll_pixel_based_preserve_y < 0
5847 || !SYMBOLP (KVAR (current_kboard, Vlast_command))
5848 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
5849 {
5850 start_display (&it, w, start);
5851 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
5852 window_scroll_pixel_based_preserve_y = it.current_y;
5853 window_scroll_pixel_based_preserve_x = it.current_x;
5854 }
5855 }
5856 else
5857 window_scroll_pixel_based_preserve_y
5858 = window_scroll_pixel_based_preserve_x = -1;
5859
5860
5861
5862 start_display (&it, w, start);
5863 if (whole)
5864 {
5865 ptrdiff_t start_pos = IT_CHARPOS (it);
5866 int flh = frame_line_height;
5867 int ht = window_box_height (w);
5868 int nscls = sanitize_next_screen_context_lines ();
5869
5870
5871
5872
5873
5874 int dy = n * max (flh, (ht / flh - nscls) * flh);
5875 int goal_y;
5876 void *it_data;
5877
5878
5879
5880
5881 if (dy <= 0)
5882 {
5883 goal_y = it.current_y + dy;
5884 move_it_vertically_backward (&it, -dy);
5885
5886
5887
5888
5889
5890 if (goal_y - it.current_y > 0.5 * flh)
5891 {
5892 it_data = bidi_shelve_cache ();
5893 struct it it1 = it;
5894 if (line_bottom_y (&it1) - goal_y < goal_y - it.current_y)
5895 move_it_by_lines (&it, 1);
5896 bidi_unshelve_cache (it_data, true);
5897 }
5898
5899
5900 while (start_pos == IT_CHARPOS (it)
5901 && start_pos > BEGV)
5902 move_it_by_lines (&it, -1);
5903 }
5904 else if (dy > 0)
5905 {
5906 goal_y = it.current_y + dy;
5907 move_it_to (&it, ZV, -1, goal_y, -1, MOVE_TO_POS | MOVE_TO_Y);
5908
5909
5910
5911
5912
5913 if (!NILP (Vscroll_preserve_screen_position)
5914 && goal_y - it.current_y > 0.5 * flh)
5915 {
5916 it_data = bidi_shelve_cache ();
5917 struct it it2 = it;
5918
5919 move_it_by_lines (&it, 1);
5920 if (it.current_y > goal_y + 0.5 * flh)
5921 {
5922 it = it2;
5923 bidi_unshelve_cache (it_data, false);
5924 }
5925 else
5926 bidi_unshelve_cache (it_data, true);
5927 }
5928
5929
5930 while (start_pos == IT_CHARPOS (it)
5931 && start_pos < ZV)
5932 move_it_by_lines (&it, 1);
5933 }
5934 }
5935 else
5936 move_it_by_lines (&it, n);
5937
5938
5939
5940
5941 if ((n > 0 && IT_CHARPOS (it) == ZV)
5942 || (n < 0 && IT_CHARPOS (it) == CHARPOS (start)))
5943 {
5944 if (IT_CHARPOS (it) == ZV)
5945 {
5946 if (it.current_y < it.last_visible_y
5947 && (it.current_y + it.max_ascent + it.max_descent
5948 > it.last_visible_y))
5949 {
5950
5951
5952 w->vscroll = (it.last_visible_y
5953 - it.current_y + it.max_ascent + it.max_descent);
5954 adjust_frame_glyphs (it.f);
5955 }
5956 else
5957 {
5958 bidi_unshelve_cache (itdata, false);
5959 if (noerror)
5960 return;
5961 else if (n < 0)
5962 xsignal0 (Qbeginning_of_buffer);
5963 else
5964 xsignal0 (Qend_of_buffer);
5965 }
5966 }
5967 else
5968 {
5969 if (w->vscroll != 0)
5970
5971
5972 w->vscroll = 0;
5973 else
5974 {
5975 bidi_unshelve_cache (itdata, false);
5976 if (noerror)
5977 return;
5978 else
5979 xsignal0 (Qbeginning_of_buffer);
5980 }
5981 }
5982
5983
5984
5985 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true;
5986
5987
5988 vscrolled = true;
5989 }
5990
5991 if (! vscrolled)
5992 {
5993 ptrdiff_t pos = IT_CHARPOS (it);
5994 ptrdiff_t bytepos;
5995
5996
5997
5998 if (in_display_vector_p (&it))
5999 {
6000 ++pos;
6001 move_it_to (&it, pos, -1, -1, -1, MOVE_TO_POS);
6002 }
6003
6004
6005 set_marker_restricted_both (w->start, w->contents, IT_CHARPOS (it),
6006 IT_BYTEPOS (it));
6007 bytepos = marker_byte_position (w->start);
6008 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
6009 wset_update_mode_line (w);
6010
6011
6012 w->force_start = true;
6013 }
6014
6015
6016
6017 it.current_y = it.vpos = 0;
6018
6019
6020
6021
6022 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
6023
6024 if (n > 0)
6025 {
6026 int last_y = it.last_visible_y - this_scroll_margin - 1;
6027
6028
6029
6030 if (IT_CHARPOS (it) < PT)
6031 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
6032 if (IT_CHARPOS (it) == PT
6033 && it.current_y >= this_scroll_margin
6034 && it.current_y <= last_y - WINDOW_TAB_LINE_HEIGHT (w)
6035 - WINDOW_HEADER_LINE_HEIGHT (w)
6036 && (NILP (Vscroll_preserve_screen_position)
6037 || EQ (Vscroll_preserve_screen_position, Qt)))
6038
6039 ;
6040 else
6041 {
6042 if (window_scroll_pixel_based_preserve_y >= 0)
6043 {
6044
6045 int goal_y = min (last_y, window_scroll_pixel_based_preserve_y);
6046
6047
6048
6049 move_it_to (&it, -1,
6050 window_scroll_pixel_based_preserve_x,
6051 goal_y - WINDOW_TAB_LINE_HEIGHT (w)
6052 - WINDOW_HEADER_LINE_HEIGHT (w),
6053 -1, MOVE_TO_Y | MOVE_TO_X);
6054 }
6055
6056
6057 while (it.current_y < this_scroll_margin)
6058 {
6059 int prev = it.current_y;
6060 move_it_by_lines (&it, 1);
6061 if (prev == it.current_y)
6062 break;
6063 }
6064 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
6065
6066
6067 if (window_scroll_pixel_based_preserve_y >= 0
6068 && window_scroll_pixel_based_preserve_y < this_scroll_margin)
6069 window_scroll_pixel_based_preserve_y = this_scroll_margin;
6070 }
6071 }
6072 else if (n < 0)
6073 {
6074 ptrdiff_t charpos, bytepos;
6075 bool partial_p;
6076
6077
6078
6079 charpos = IT_CHARPOS (it);
6080 bytepos = IT_BYTEPOS (it);
6081
6082
6083
6084 move_it_to (&it, PT, -1,
6085
6086
6087
6088 (it.last_visible_y - WINDOW_TAB_LINE_HEIGHT (w)
6089 - WINDOW_HEADER_LINE_HEIGHT (w)
6090 - partial_line_height (&it) - this_scroll_margin - 1),
6091 -1,
6092 MOVE_TO_POS | MOVE_TO_Y);
6093
6094
6095 charpos = IT_CHARPOS (it);
6096 bytepos = IT_BYTEPOS (it);
6097
6098
6099
6100
6101
6102
6103 if (charpos != PT)
6104 {
6105 struct it it2;
6106 void *it_data;
6107
6108 it2 = it;
6109 it_data = bidi_shelve_cache ();
6110 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
6111 if (IT_CHARPOS (it) == PT && it.current_y == it2.current_y)
6112 {
6113 charpos = IT_CHARPOS (it);
6114 bytepos = IT_BYTEPOS (it);
6115 bidi_unshelve_cache (it_data, true);
6116 }
6117 else
6118 {
6119 it = it2;
6120 bidi_unshelve_cache (it_data, false);
6121 }
6122 }
6123
6124
6125 if (it.what == IT_EOB)
6126 partial_p =
6127 it.current_y + it.ascent + it.descent
6128 > it.last_visible_y - this_scroll_margin
6129 - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
6130 else
6131 {
6132 move_it_by_lines (&it, 1);
6133 partial_p =
6134 it.current_y
6135 > it.last_visible_y - this_scroll_margin
6136 - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
6137 }
6138
6139 if (charpos == PT && !partial_p
6140 && (NILP (Vscroll_preserve_screen_position)
6141 || EQ (Vscroll_preserve_screen_position, Qt)))
6142
6143 ;
6144 else if (window_scroll_pixel_based_preserve_y >= 0)
6145 {
6146 int goal_y = min (it.last_visible_y - this_scroll_margin - 1,
6147 window_scroll_pixel_based_preserve_y);
6148
6149
6150
6151 if (goal_y < this_scroll_margin)
6152 goal_y = this_scroll_margin;
6153 SET_TEXT_POS_FROM_MARKER (start, w->start);
6154 start_display (&it, w, start);
6155
6156
6157
6158 move_it_to (&it, -1, window_scroll_pixel_based_preserve_x,
6159 goal_y, -1, MOVE_TO_Y | MOVE_TO_X);
6160 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
6161 }
6162 else
6163 {
6164 if (partial_p)
6165
6166
6167 {
6168 move_it_by_lines (&it, -2);
6169 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
6170 }
6171 else
6172
6173 SET_PT_BOTH (charpos, bytepos);
6174 }
6175 }
6176 bidi_unshelve_cache (itdata, false);
6177
6178 if (adjust_old_pointm)
6179 Fset_marker (w->old_pointm,
6180 ((w == XWINDOW (selected_window))
6181 ? make_fixnum (BUF_PT (XBUFFER (w->contents)))
6182 : Fmarker_position (w->pointm)),
6183 w->contents);
6184 }
6185
6186
6187
6188
6189
6190 static void
6191 window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
6192 {
6193 struct window *w = XWINDOW (window);
6194
6195
6196
6197
6198
6199 Lisp_Object opoint_marker = Fpoint_marker ();
6200 register ptrdiff_t pos, pos_byte;
6201 register int ht = window_internal_height (w);
6202 register Lisp_Object tem;
6203 bool lose;
6204 Lisp_Object bolp;
6205 ptrdiff_t startpos = marker_position (w->start);
6206 ptrdiff_t startbyte = marker_byte_position (w->start);
6207 Lisp_Object original_pos = Qnil;
6208 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
6209 Fwindow_old_point (window)));
6210
6211
6212
6213 if (whole)
6214 {
6215 int nscls = sanitize_next_screen_context_lines ();
6216 n *= max (1, ht - nscls);
6217 }
6218
6219 if (!NILP (Vscroll_preserve_screen_position))
6220 {
6221 if (window_scroll_preserve_vpos <= 0
6222 || !SYMBOLP (KVAR (current_kboard, Vlast_command))
6223 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
6224 {
6225 struct position posit
6226 = *compute_motion (startpos, startbyte, 0, 0, false,
6227 PT, ht, 0, -1, w->hscroll, 0, w);
6228
6229 window_scroll_preserve_vpos = posit.vpos;
6230 window_scroll_preserve_hpos = posit.hpos + w->hscroll;
6231 }
6232
6233 original_pos = Fcons (make_fixnum (window_scroll_preserve_hpos),
6234 make_fixnum (window_scroll_preserve_vpos));
6235 }
6236
6237 XSETFASTINT (tem, PT);
6238 tem = Fpos_visible_in_window_p (tem, window, Qnil);
6239
6240 if (NILP (tem))
6241 {
6242 Fvertical_motion (make_fixnum (- (ht / 2)), window, Qnil);
6243 startpos = PT;
6244 startbyte = PT_BYTE;
6245 }
6246
6247 SET_PT_BOTH (startpos, startbyte);
6248 lose = n < 0 && PT == BEGV;
6249 Fvertical_motion (make_fixnum (n), window, Qnil);
6250 pos = PT;
6251 pos_byte = PT_BYTE;
6252 bolp = Fbolp ();
6253 SET_PT_BOTH (marker_position (opoint_marker),
6254 marker_byte_position (opoint_marker));
6255
6256 if (lose)
6257 {
6258 if (noerror)
6259 return;
6260 else
6261 xsignal0 (Qbeginning_of_buffer);
6262 }
6263
6264 if (pos < ZV)
6265 {
6266 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
6267
6268 set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
6269 w->start_at_line_beg = !NILP (bolp);
6270 wset_update_mode_line (w);
6271
6272
6273 w->force_start = true;
6274
6275 if (!NILP (Vscroll_preserve_screen_position)
6276 && this_scroll_margin == 0
6277 && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
6278 {
6279 SET_PT_BOTH (pos, pos_byte);
6280 Fvertical_motion (original_pos, window, Qnil);
6281 }
6282
6283
6284 else if (n > 0)
6285 {
6286 int top_margin;
6287
6288 if (this_scroll_margin > 0)
6289 {
6290 SET_PT_BOTH (pos, pos_byte);
6291 Fvertical_motion (make_fixnum (this_scroll_margin), window, Qnil);
6292 top_margin = PT;
6293 }
6294 else
6295 top_margin = pos;
6296
6297 if (top_margin <= marker_position (opoint_marker))
6298 SET_PT_BOTH (marker_position (opoint_marker),
6299 marker_byte_position (opoint_marker));
6300 else if (!NILP (Vscroll_preserve_screen_position))
6301 {
6302 int nlines = window_scroll_preserve_vpos;
6303
6304 SET_PT_BOTH (pos, pos_byte);
6305 if (window_scroll_preserve_vpos < this_scroll_margin)
6306 nlines = this_scroll_margin;
6307 else if (window_scroll_preserve_vpos
6308 >= w->total_lines - this_scroll_margin)
6309 nlines = w->total_lines - this_scroll_margin - 1;
6310 Fvertical_motion (Fcons (make_fixnum (window_scroll_preserve_hpos),
6311 make_fixnum (nlines)), window, Qnil);
6312 }
6313 else
6314 SET_PT (top_margin);
6315 }
6316 else if (n < 0)
6317 {
6318 int bottom_margin;
6319
6320
6321
6322 SET_PT_BOTH (pos, pos_byte);
6323 tem = Fvertical_motion (make_fixnum (ht - this_scroll_margin), window,
6324 Qnil);
6325 if (XFIXNAT (tem) == ht - this_scroll_margin)
6326 bottom_margin = PT;
6327 else
6328 bottom_margin = PT + 1;
6329
6330 if (bottom_margin > marker_position (opoint_marker))
6331 SET_PT_BOTH (marker_position (opoint_marker),
6332 marker_byte_position (opoint_marker));
6333 else
6334 {
6335 if (!NILP (Vscroll_preserve_screen_position))
6336 {
6337 int nlines = window_scroll_preserve_vpos;
6338
6339 SET_PT_BOTH (pos, pos_byte);
6340 if (window_scroll_preserve_vpos < this_scroll_margin)
6341 nlines = this_scroll_margin;
6342 else if (window_scroll_preserve_vpos
6343 >= ht - this_scroll_margin)
6344 nlines = ht - this_scroll_margin - 1;
6345 Fvertical_motion (Fcons (make_fixnum (window_scroll_preserve_hpos),
6346 make_fixnum (nlines)), window, Qnil);
6347 }
6348 else
6349 Fvertical_motion (make_fixnum (-1), window, Qnil);
6350 }
6351 }
6352 }
6353 else
6354 {
6355 if (noerror)
6356 return;
6357 else
6358 xsignal0 (Qend_of_buffer);
6359 }
6360
6361 if (adjust_old_pointm)
6362 Fset_marker (w->old_pointm,
6363 ((w == XWINDOW (selected_window))
6364 ? make_fixnum (BUF_PT (XBUFFER (w->contents)))
6365 : Fmarker_position (w->pointm)),
6366 w->contents);
6367 }
6368
6369
6370
6371
6372
6373
6374
6375
6376 static void
6377 scroll_command (Lisp_Object window, Lisp_Object n, int direction)
6378 {
6379 struct window *w;
6380 bool other_window;
6381 specpdl_ref count = SPECPDL_INDEX ();
6382
6383 eassert (eabs (direction) == 1);
6384
6385 w = XWINDOW (window);
6386 other_window = ! EQ (window, selected_window);
6387
6388
6389
6390
6391
6392
6393
6394 if (other_window || XBUFFER (w->contents) != current_buffer)
6395 {
6396 record_unwind_protect_excursion ();
6397 if (XBUFFER (w->contents) != current_buffer)
6398 Fset_buffer (w->contents);
6399 }
6400
6401 if (other_window)
6402 {
6403 SET_PT_BOTH (marker_position (w->pointm),
6404 marker_byte_position (w->pointm));
6405 SET_PT_BOTH (marker_position (w->old_pointm),
6406 marker_byte_position (w->old_pointm));
6407 }
6408
6409 if (NILP (n))
6410 window_scroll (window, direction, true, false);
6411 else if (EQ (n, Qminus))
6412 window_scroll (window, -direction, true, false);
6413 else
6414 {
6415 n = Fprefix_numeric_value (n);
6416 window_scroll (window, XFIXNUM (n) * direction, false, false);
6417 }
6418
6419 if (other_window)
6420 {
6421 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
6422 set_marker_both (w->old_pointm, Qnil, PT, PT_BYTE);
6423 }
6424
6425 unbind_to (count, Qnil);
6426 }
6427
6428 DEFUN ("scroll-up", Fscroll_up, Sscroll_up, 0, 1, "^P",
6429 doc:
6430
6431
6432
6433
6434 )
6435 (Lisp_Object arg)
6436 {
6437 scroll_command (selected_window, arg, 1);
6438 return Qnil;
6439 }
6440
6441 DEFUN ("scroll-down", Fscroll_down, Sscroll_down, 0, 1, "^P",
6442 doc:
6443
6444
6445
6446
6447 )
6448 (Lisp_Object arg)
6449 {
6450 scroll_command (selected_window, arg, -1);
6451 return Qnil;
6452 }
6453
6454 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling, Sother_window_for_scrolling, 0, 0, 0,
6455 doc:
6456
6457
6458
6459
6460
6461 )
6462 (void)
6463 {
6464 Lisp_Object window;
6465
6466 if (MINI_WINDOW_P (XWINDOW (selected_window))
6467 && !NILP (Vminibuf_scroll_window))
6468 window = Vminibuf_scroll_window;
6469
6470 else if (BUFFERP (Vother_window_scroll_buffer)
6471 && BUFFER_LIVE_P (XBUFFER (Vother_window_scroll_buffer)))
6472 {
6473 window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
6474 if (NILP (window))
6475 window = display_buffer (Vother_window_scroll_buffer, Qt, Qnil);
6476 }
6477 else if (FUNCTIONP (Vother_window_scroll_default))
6478
6479 window = call0 (Vother_window_scroll_default);
6480 else
6481 {
6482
6483 window = Fnext_window (selected_window, Qlambda, Qnil);
6484
6485 if (EQ (window, selected_window))
6486
6487
6488 window = Fnext_window (window, Qlambda, Qvisible);
6489 }
6490
6491 CHECK_LIVE_WINDOW (window);
6492
6493 if (EQ (window, selected_window))
6494 error ("There is no other window");
6495
6496 return window;
6497 }
6498
6499
6500 DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np",
6501 doc:
6502
6503
6504
6505
6506
6507
6508 )
6509 (register Lisp_Object arg, Lisp_Object set_minimum)
6510 {
6511 struct window *w = XWINDOW (selected_window);
6512 EMACS_INT requested_arg =
6513 (NILP (arg)
6514 ? window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) - 2
6515 : XFIXNUM (Fprefix_numeric_value (arg)));
6516 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
6517
6518 if (!NILP (set_minimum))
6519 w->min_hscroll = w->hscroll;
6520
6521 w->suspend_auto_hscroll = true;
6522
6523 return result;
6524 }
6525
6526 DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 2, "^P\np",
6527 doc:
6528
6529
6530
6531
6532
6533
6534 )
6535 (register Lisp_Object arg, Lisp_Object set_minimum)
6536 {
6537 struct window *w = XWINDOW (selected_window);
6538 EMACS_INT requested_arg =
6539 (NILP (arg)
6540 ? window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) - 2
6541 : XFIXNUM (Fprefix_numeric_value (arg)));
6542 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
6543
6544 if (!NILP (set_minimum))
6545 w->min_hscroll = w->hscroll;
6546
6547 w->suspend_auto_hscroll = true;
6548
6549 return result;
6550 }
6551
6552 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window, Sminibuffer_selected_window, 0, 0, 0,
6553 doc:
6554 )
6555 (void)
6556 {
6557 if (minibuf_level > 0
6558 && MINI_WINDOW_P (XWINDOW (selected_window))
6559 && WINDOW_LIVE_P (minibuf_selected_window))
6560 return minibuf_selected_window;
6561
6562 return Qnil;
6563 }
6564
6565
6566
6567
6568 static int
6569 displayed_window_lines (struct window *w)
6570 {
6571 struct it it;
6572 struct text_pos start;
6573 int height = window_box_height (w);
6574 struct buffer *old_buffer;
6575 int bottom_y;
6576 void *itdata = NULL;
6577
6578 if (XBUFFER (w->contents) != current_buffer)
6579 {
6580 old_buffer = current_buffer;
6581 set_buffer_internal (XBUFFER (w->contents));
6582 }
6583 else
6584 old_buffer = NULL;
6585
6586
6587
6588
6589 CLIP_TEXT_POS_FROM_MARKER (start, w->start);
6590
6591 itdata = bidi_shelve_cache ();
6592
6593 specpdl_ref count = SPECPDL_INDEX ();
6594 record_unwind_protect_void (unwind_display_working_on_window);
6595 display_working_on_window_p = true;
6596 start_display (&it, w, start);
6597 move_it_vertically (&it, height);
6598 bottom_y = line_bottom_y (&it);
6599 unbind_to (count, Qnil);
6600 bidi_unshelve_cache (itdata, false);
6601
6602
6603 if (bottom_y < height)
6604 {
6605 int uy = FRAME_LINE_HEIGHT (it.f);
6606 it.vpos += (height - bottom_y + uy - 1) / uy;
6607 }
6608 else if (bottom_y == height)
6609 it.vpos++;
6610
6611 if (old_buffer)
6612 set_buffer_internal (old_buffer);
6613
6614 return it.vpos;
6615 }
6616
6617
6618 DEFUN ("recenter", Frecenter, Srecenter, 0, 2, "P\np",
6619 doc:
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633 )
6634 (Lisp_Object arg, Lisp_Object redisplay)
6635 {
6636 struct window *w = XWINDOW (selected_window);
6637 struct buffer *buf = XBUFFER (w->contents);
6638 bool center_p = false;
6639 ptrdiff_t charpos, bytepos;
6640 EMACS_INT iarg UNINIT;
6641 int this_scroll_margin;
6642
6643
6644
6645
6646 if (buf != current_buffer)
6647 error ("`recenter'ing a window that does not display current-buffer.");
6648
6649
6650 buf->display_error_modiff = 0;
6651
6652 if (NILP (arg))
6653 {
6654 if (!NILP (redisplay)
6655 && !NILP (Vrecenter_redisplay)
6656 && (!EQ (Vrecenter_redisplay, Qtty)
6657 || !NILP (Ftty_type (selected_frame))))
6658 {
6659 ptrdiff_t i;
6660
6661
6662 for (i = 0; i < n_compositions; i++)
6663 composition_table[i]->font = NULL;
6664 #if defined (HAVE_WINDOW_SYSTEM)
6665 WINDOW_XFRAME (w)->minimize_tab_bar_window_p = 1;
6666 #endif
6667 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
6668 WINDOW_XFRAME (w)->minimize_tool_bar_window_p = 1;
6669 #endif
6670 Fredraw_frame (WINDOW_FRAME (w));
6671 SET_FRAME_GARBAGED (WINDOW_XFRAME (w));
6672 }
6673
6674 center_p = true;
6675 }
6676 else if (CONSP (arg))
6677 center_p = true;
6678 else
6679 {
6680 arg = Fprefix_numeric_value (arg);
6681 CHECK_FIXNUM (arg);
6682 iarg = XFIXNUM (arg);
6683 }
6684
6685
6686
6687 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
6688
6689
6690
6691
6692
6693 if (!FRAME_INITIAL_P (XFRAME (w->frame))
6694 && !current_buffer->long_line_optimizations_p)
6695 {
6696 specpdl_ref count = SPECPDL_INDEX ();
6697
6698 record_unwind_protect_void (unwind_display_working_on_window);
6699 display_working_on_window_p = true;
6700 if (center_p)
6701 {
6702 struct it it;
6703 struct text_pos pt;
6704 void *itdata = bidi_shelve_cache ();
6705
6706 SET_TEXT_POS (pt, PT, PT_BYTE);
6707 start_display (&it, w, pt);
6708 move_it_vertically_backward (&it, window_box_height (w) / 2);
6709 charpos = IT_CHARPOS (it);
6710 bytepos = IT_BYTEPOS (it);
6711 bidi_unshelve_cache (itdata, false);
6712 }
6713 else if (iarg < 0)
6714 {
6715 struct it it;
6716 struct text_pos pt;
6717 ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg);
6718 int extra_line_spacing;
6719 int h = window_box_height (w);
6720 int ht = window_internal_height (w);
6721 void *itdata = bidi_shelve_cache ();
6722
6723 nlines = clip_to_bounds (this_scroll_margin + 1, nlines,
6724 ht - this_scroll_margin);
6725
6726 SET_TEXT_POS (pt, PT, PT_BYTE);
6727 start_display (&it, w, pt);
6728
6729
6730 move_it_by_lines (&it, 0);
6731
6732
6733
6734
6735 it.current_y = 0;
6736 it.vpos = 0;
6737 move_it_by_lines (&it, nlines);
6738
6739 if (it.vpos == nlines)
6740 h -= it.current_y;
6741 else
6742 {
6743
6744 h -= line_bottom_y (&it);
6745 it.vpos++;
6746 }
6747
6748
6749 extra_line_spacing = it.max_extra_line_spacing;
6750
6751
6752
6753 if (it.vpos < nlines)
6754 {
6755 nlines -= it.vpos;
6756 extra_line_spacing = it.extra_line_spacing;
6757 h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
6758 }
6759 if (h <= 0)
6760 {
6761 bidi_unshelve_cache (itdata, false);
6762 unbind_to (count, Qnil);
6763 return Qnil;
6764 }
6765
6766
6767 start_display (&it, w, pt);
6768 it.current_y = 0;
6769 move_it_vertically_backward (&it, h);
6770
6771
6772
6773
6774
6775
6776
6777
6778 h += extra_line_spacing;
6779 while (-it.current_y > h && it.what != IT_EOB)
6780 move_it_by_lines (&it, 1);
6781
6782 charpos = IT_CHARPOS (it);
6783 bytepos = IT_BYTEPOS (it);
6784
6785 bidi_unshelve_cache (itdata, false);
6786 }
6787 else
6788 {
6789 struct it it;
6790 struct text_pos pt;
6791 ptrdiff_t nlines = min (PTRDIFF_MAX, iarg);
6792 int ht = window_internal_height (w);
6793 void *itdata = bidi_shelve_cache ();
6794
6795 nlines = clip_to_bounds (this_scroll_margin, nlines,
6796 ht - this_scroll_margin - 1);
6797
6798 SET_TEXT_POS (pt, PT, PT_BYTE);
6799 start_display (&it, w, pt);
6800
6801
6802 move_it_by_lines (&it, 0);
6803
6804
6805 if (nlines > 0)
6806 {
6807 it.current_y = 0;
6808 it.vpos = 0;
6809 move_it_by_lines (&it, -nlines);
6810 }
6811
6812 charpos = IT_CHARPOS (it);
6813 bytepos = IT_BYTEPOS (it);
6814
6815 bidi_unshelve_cache (itdata, false);
6816 }
6817 unbind_to (count, Qnil);
6818 }
6819 else
6820 {
6821 struct position pos;
6822 int ht = window_internal_height (w);
6823
6824 if (center_p)
6825 iarg = ht / 2;
6826 else if (iarg < 0)
6827 iarg += ht;
6828
6829
6830 iarg = clip_to_bounds (this_scroll_margin, iarg,
6831 ht - this_scroll_margin - 1);
6832
6833 pos = *vmotion (PT, PT_BYTE, - iarg, w);
6834 charpos = pos.bufpos;
6835 bytepos = pos.bytepos;
6836 }
6837
6838
6839 set_marker_both (w->start, w->contents, charpos, bytepos);
6840 w->window_end_valid = false;
6841
6842 w->optional_new_start = true;
6843
6844 w->start_at_line_beg = (bytepos == BEGV_BYTE
6845 || FETCH_BYTE (bytepos - 1) == '\n');
6846
6847 wset_redisplay (w);
6848
6849 return Qnil;
6850 }
6851
6852 DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
6853 0, 2, 0,
6854 doc:
6855
6856
6857
6858
6859
6860
6861
6862 )
6863 (Lisp_Object window, Lisp_Object pixelwise)
6864 {
6865 struct window *w = decode_live_window (window);
6866
6867 if (NILP (pixelwise))
6868 return make_fixnum (window_box_width (w, TEXT_AREA)
6869 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
6870 else
6871 return make_fixnum (window_box_width (w, TEXT_AREA));
6872 }
6873
6874 DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
6875 0, 2, 0,
6876 doc:
6877
6878
6879
6880
6881
6882
6883 )
6884 (Lisp_Object window, Lisp_Object pixelwise)
6885 {
6886 struct window *w = decode_live_window (window);
6887
6888 if (NILP (pixelwise))
6889 return make_fixnum (window_box_height (w)
6890 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
6891 else
6892 return make_fixnum (window_box_height (w));
6893 }
6894
6895 DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
6896 1, 1, "P",
6897 doc:
6898
6899
6900
6901
6902
6903
6904
6905 )
6906 (Lisp_Object arg)
6907 {
6908 struct window *w = XWINDOW (selected_window);
6909 int lines, start;
6910 Lisp_Object window;
6911 #if false
6912 int this_scroll_margin;
6913 #endif
6914
6915 if (!(BUFFERP (w->contents) && XBUFFER (w->contents) == current_buffer))
6916
6917
6918 error ("move-to-window-line called from unrelated buffer");
6919
6920 window = selected_window;
6921 start = marker_position (w->start);
6922 if (start < BEGV || start > ZV)
6923 {
6924 int height = window_internal_height (w);
6925 Fvertical_motion (make_fixnum (- (height / 2)), window, Qnil);
6926 set_marker_both (w->start, w->contents, PT, PT_BYTE);
6927 w->start_at_line_beg = !NILP (Fbolp ());
6928 w->force_start = true;
6929 }
6930 else
6931 Fgoto_char (w->start);
6932
6933 lines = displayed_window_lines (w);
6934
6935 if (NILP (arg))
6936 XSETFASTINT (arg, lines / 2);
6937 else
6938 {
6939 EMACS_INT iarg = XFIXNUM (Fprefix_numeric_value (arg));
6940
6941 if (iarg < 0)
6942 iarg = iarg + lines;
6943
6944 #if false
6945
6946
6947
6948
6949
6950 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
6951
6952
6953 iarg = max (iarg, this_scroll_margin);
6954 iarg = min (iarg, lines - this_scroll_margin - 1);
6955 #endif
6956
6957 arg = make_fixnum (iarg);
6958 }
6959
6960
6961 if (w->vscroll)
6962 XSETINT (arg, XFIXNUM (arg) + 1);
6963
6964 return Fvertical_motion (arg, window, Qnil);
6965 }
6966
6967
6968
6969
6970
6971
6972
6973 struct save_window_data
6974 {
6975 union vectorlike_header header;
6976 Lisp_Object selected_frame;
6977 Lisp_Object current_window;
6978 Lisp_Object f_current_buffer;
6979 Lisp_Object minibuf_scroll_window;
6980 Lisp_Object minibuf_selected_window;
6981 Lisp_Object root_window;
6982 Lisp_Object focus_frame;
6983
6984
6985 Lisp_Object saved_windows;
6986
6987
6988
6989
6990
6991 int frame_cols, frame_lines;
6992
6993
6994 int frame_menu_bar_lines, frame_tab_bar_lines, frame_tool_bar_lines;
6995 int frame_text_width, frame_text_height;
6996
6997
6998 int frame_menu_bar_height, frame_tab_bar_height, frame_tool_bar_height;
6999 } GCALIGNED_STRUCT;
7000
7001
7002 struct saved_window
7003 {
7004 union vectorlike_header header;
7005
7006 Lisp_Object window, buffer, start, pointm, old_pointm;
7007 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
7008 Lisp_Object left_col, top_line, total_cols, total_lines;
7009 Lisp_Object normal_cols, normal_lines;
7010 Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll;
7011 Lisp_Object vscroll;
7012 Lisp_Object parent, prev;
7013 Lisp_Object start_at_line_beg;
7014 Lisp_Object display_table;
7015 Lisp_Object left_margin_cols, right_margin_cols;
7016 Lisp_Object left_fringe_width, right_fringe_width;
7017 Lisp_Object fringes_outside_margins, fringes_persistent;
7018 Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
7019 Lisp_Object scroll_bar_height, horizontal_scroll_bar_type;
7020 Lisp_Object scroll_bars_persistent, dedicated;
7021 Lisp_Object combination_limit, window_parameters;
7022 };
7023
7024 #define SAVED_WINDOW_N(swv,n) \
7025 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
7026
7027 DEFUN ("window-configuration-p", Fwindow_configuration_p, Swindow_configuration_p, 1, 1, 0,
7028 doc: )
7029 (Lisp_Object object)
7030 {
7031 return WINDOW_CONFIGURATIONP (object) ? Qt : Qnil;
7032 }
7033
7034 DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_configuration_frame, 1, 1, 0,
7035 doc: )
7036 (Lisp_Object config)
7037 {
7038 register struct save_window_data *data;
7039 struct Lisp_Vector *saved_windows;
7040
7041 CHECK_WINDOW_CONFIGURATION (config);
7042
7043 data = (struct save_window_data *) XVECTOR (config);
7044 saved_windows = XVECTOR (data->saved_windows);
7045 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
7046 }
7047
7048 DEFUN ("set-window-configuration", Fset_window_configuration,
7049 Sset_window_configuration, 1, 3, 0,
7050 doc:
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062 )
7063 (Lisp_Object configuration, Lisp_Object dont_set_frame,
7064 Lisp_Object dont_set_miniwindow)
7065 {
7066 register struct save_window_data *data;
7067 struct Lisp_Vector *saved_windows;
7068 Lisp_Object new_current_buffer;
7069 Lisp_Object frame;
7070 Lisp_Object old_frame = selected_frame;
7071 struct frame *f;
7072 ptrdiff_t old_point = -1;
7073 USE_SAFE_ALLOCA;
7074
7075 CHECK_WINDOW_CONFIGURATION (configuration);
7076
7077 data = (struct save_window_data *) XVECTOR (configuration);
7078 saved_windows = XVECTOR (data->saved_windows);
7079
7080 new_current_buffer = data->f_current_buffer;
7081 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
7082 new_current_buffer = Qnil;
7083 else
7084 {
7085 if (XBUFFER (new_current_buffer) == current_buffer)
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
7097 && WINDOWP (selected_window)
7098 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
7099 && !EQ (selected_window, data->current_window))
7100 old_point = marker_position (XWINDOW (data->current_window)->pointm);
7101 else
7102 old_point = PT;
7103 else
7104
7105
7106
7107
7108
7109
7110
7111
7112 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
7113
7114 && !EQ (selected_window, data->current_window))
7115 old_point = marker_position (XWINDOW (data->current_window)->pointm);
7116 else
7117 old_point = BUF_PT (XBUFFER (new_current_buffer));
7118 }
7119
7120 frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
7121 f = XFRAME (frame);
7122
7123
7124
7125 if (FRAME_LIVE_P (f))
7126 {
7127 Lisp_Object window;
7128 Lisp_Object dead_windows = Qnil;
7129 Lisp_Object tem, par, pers;
7130 struct window *w;
7131 struct saved_window *p;
7132 struct window *root_window;
7133 struct window **leaf_windows;
7134 ptrdiff_t i, k, n_leaf_windows;
7135
7136
7137
7138 for (k = 0; k < saved_windows->header.size; k++)
7139 {
7140 p = SAVED_WINDOW_N (saved_windows, k);
7141 window = p->window;
7142 w = XWINDOW (window);
7143
7144 if (BUFFERP (w->contents)
7145 && !EQ (w->contents, p->buffer)
7146 && BUFFER_LIVE_P (XBUFFER (p->buffer))
7147 && (NILP (Fminibufferp (p->buffer, Qnil))))
7148
7149
7150 call1 (Qrecord_window_buffer, window);
7151 }
7152
7153
7154 f->can_set_window_size = false;
7155
7156
7157 block_input ();
7158
7159
7160
7161
7162
7163
7164 if (! NILP (XWINDOW (selected_window)->contents))
7165 {
7166 w = XWINDOW (selected_window);
7167 set_marker_both (w->pointm,
7168 w->contents,
7169 BUF_PT (XBUFFER (w->contents)),
7170 BUF_PT_BYTE (XBUFFER (w->contents)));
7171 }
7172
7173 fset_redisplay (f);
7174
7175
7176
7177
7178
7179 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
7180 ptrdiff_t nwindows = count_windows (root_window);
7181 SAFE_NALLOCA (leaf_windows, 1, nwindows);
7182 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
7183
7184
7185
7186
7187
7188
7189
7190
7191 delete_all_child_windows (FRAME_ROOT_WINDOW (f));
7192
7193 for (k = 0; k < saved_windows->header.size; k++)
7194 {
7195 p = SAVED_WINDOW_N (saved_windows, k);
7196 window = p->window;
7197 w = XWINDOW (window);
7198 wset_next (w, Qnil);
7199
7200 if (!NILP (p->parent))
7201 wset_parent
7202 (w, SAVED_WINDOW_N (saved_windows, XFIXNAT (p->parent))->window);
7203 else
7204 wset_parent (w, Qnil);
7205
7206 if (!NILP (p->prev))
7207 {
7208 wset_prev
7209 (w, SAVED_WINDOW_N (saved_windows, XFIXNAT (p->prev))->window);
7210 wset_next (XWINDOW (w->prev), p->window);
7211 }
7212 else
7213 {
7214 wset_prev (w, Qnil);
7215 if (!NILP (w->parent))
7216 wset_combination (XWINDOW (w->parent),
7217 (XFIXNUM (p->total_cols)
7218 != XWINDOW (w->parent)->total_cols),
7219 p->window);
7220 }
7221
7222
7223 if (BUFFERP (w->combination_limit))
7224 wset_buffer (w, w->combination_limit);
7225 w->pixel_left = XFIXNAT (p->pixel_left);
7226 w->pixel_top = XFIXNAT (p->pixel_top);
7227 w->pixel_width = XFIXNAT (p->pixel_width);
7228 w->pixel_height = XFIXNAT (p->pixel_height);
7229 w->left_col = XFIXNAT (p->left_col);
7230 w->top_line = XFIXNAT (p->top_line);
7231 w->total_cols = XFIXNAT (p->total_cols);
7232 w->total_lines = XFIXNAT (p->total_lines);
7233 wset_normal_cols (w, p->normal_cols);
7234 wset_normal_lines (w, p->normal_lines);
7235 w->hscroll = XFIXNAT (p->hscroll);
7236 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
7237 w->min_hscroll = XFIXNAT (p->min_hscroll);
7238 w->hscroll_whole = XFIXNAT (p->hscroll_whole);
7239 w->vscroll = -XFIXNAT (p->vscroll);
7240 wset_display_table (w, p->display_table);
7241 w->left_margin_cols = XFIXNUM (p->left_margin_cols);
7242 w->right_margin_cols = XFIXNUM (p->right_margin_cols);
7243 w->left_fringe_width = XFIXNUM (p->left_fringe_width);
7244 w->right_fringe_width = XFIXNUM (p->right_fringe_width);
7245 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
7246 w->fringes_persistent = !NILP (p->fringes_persistent);
7247 w->scroll_bar_width = XFIXNUM (p->scroll_bar_width);
7248 w->scroll_bar_height = XFIXNUM (p->scroll_bar_height);
7249 w->scroll_bars_persistent = !NILP (p->scroll_bars_persistent);
7250 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
7251 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
7252 wset_dedicated (w, p->dedicated);
7253 wset_combination_limit (w, p->combination_limit);
7254
7255
7256 for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
7257 {
7258 pers = XCAR (tem);
7259 if (CONSP (pers))
7260 {
7261 if (NILP (XCDR (pers)))
7262 {
7263 par = Fassq (XCAR (pers), w->window_parameters);
7264 if (CONSP (par) && !NILP (XCDR (par)))
7265
7266
7267
7268 Fsetcdr (par, Qnil);
7269 }
7270 else
7271
7272 Fset_window_parameter (window, XCAR (pers), XCDR (pers));
7273 }
7274 }
7275
7276 if ((NILP (dont_set_miniwindow) || !MINI_WINDOW_P (w))
7277 && BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
7278
7279
7280 {
7281 wset_buffer (w, p->buffer);
7282 w->start_at_line_beg = !NILP (p->start_at_line_beg);
7283 set_marker_restricted (w->start, p->start, w->contents);
7284 set_marker_restricted (w->pointm, p->pointm, w->contents);
7285 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
7286
7287
7288
7289 if (!EQ (p->buffer, new_current_buffer)
7290 && XBUFFER (p->buffer) == current_buffer)
7291 Fgoto_char (w->pointm);
7292 }
7293 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
7294
7295 {
7296
7297 if (XMARKER (w->start)->buffer == 0)
7298 set_marker_restricted_both (w->start, w->contents, 0, 0);
7299 if (XMARKER (w->pointm)->buffer == 0)
7300 set_marker_restricted_both
7301 (w->pointm, w->contents,
7302 BUF_PT (XBUFFER (w->contents)),
7303 BUF_PT_BYTE (XBUFFER (w->contents)));
7304 if (XMARKER (w->old_pointm)->buffer == 0)
7305 set_marker_restricted_both
7306 (w->old_pointm, w->contents,
7307 BUF_PT (XBUFFER (w->contents)),
7308 BUF_PT_BYTE (XBUFFER (w->contents)));
7309 w->start_at_line_beg = true;
7310 }
7311 else if (!NILP (w->start))
7312
7313 {
7314
7315
7316
7317
7318 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
7319
7320
7321 set_marker_restricted_both (w->start, w->contents, 0, 0);
7322 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
7323 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
7324 w->start_at_line_beg = true;
7325 if (!NILP (w->dedicated))
7326
7327 dead_windows = Fcons (window, dead_windows);
7328
7329 wset_dedicated (w, Qnil);
7330 }
7331 }
7332
7333 fset_root_window (f, data->root_window);
7334
7335
7336 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
7337 set_marker_restricted (XWINDOW (data->current_window)->pointm,
7338 make_fixnum (old_point),
7339 XWINDOW (data->current_window)->contents);
7340
7341
7342
7343
7344
7345
7346
7347
7348 select_window (data->current_window, Qt, true);
7349 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
7350 last_selected_window)
7351 = selected_window;
7352
7353
7354
7355
7356
7357
7358
7359 Vwindow_list = Qnil;
7360
7361 if (NILP (data->focus_frame)
7362 || (FRAMEP (data->focus_frame)
7363 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
7364 Fredirect_frame_focus (frame, data->focus_frame);
7365
7366
7367 for (i = 0; i < n_leaf_windows; i++)
7368 if (NILP (leaf_windows[i]->contents))
7369 free_window_matrices (leaf_windows[i]);
7370
7371
7372
7373
7374 f->can_set_window_size = true;
7375 adjust_frame_size (f, -1, -1, 4, false, Qset_window_configuration);
7376
7377 adjust_frame_glyphs (f);
7378 unblock_input ();
7379
7380
7381 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
7382 {
7383 window = XCAR (dead_windows);
7384 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
7385 delete_deletable_window (window);
7386 }
7387
7388
7389
7390 if (WINDOW_LIVE_P (data->current_window))
7391 select_window (data->current_window, Qnil, false);
7392
7393
7394
7395
7396
7397
7398 if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
7399 do_switch_frame (NILP (dont_set_frame)
7400 ? data->selected_frame
7401 : old_frame
7402 , 0, 0, Qnil);
7403 }
7404
7405 FRAME_WINDOW_CHANGE (f) = true;
7406
7407 if (!NILP (new_current_buffer))
7408 {
7409 Fset_buffer (new_current_buffer);
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425 if (!EQ (XWINDOW (selected_window)->contents, new_current_buffer))
7426 Fgoto_char (make_fixnum (old_point));
7427 }
7428
7429 Vminibuf_scroll_window = data->minibuf_scroll_window;
7430 minibuf_selected_window = data->minibuf_selected_window;
7431
7432 SAFE_FREE ();
7433 return FRAME_LIVE_P (f) ? Qt : Qnil;
7434 }
7435
7436 void
7437 restore_window_configuration (Lisp_Object configuration)
7438 {
7439 if (CONSP (configuration))
7440 Fset_window_configuration (XCAR (configuration),
7441 Fcar_safe (XCDR (configuration)),
7442 Fcar_safe (Fcdr_safe (XCDR (configuration))));
7443 else
7444 Fset_window_configuration (configuration, Qnil, Qnil);
7445 }
7446
7447
7448
7449
7450
7451
7452 void
7453 delete_all_child_windows (Lisp_Object window)
7454 {
7455 register struct window *w;
7456
7457 w = XWINDOW (window);
7458
7459 if (!NILP (w->next))
7460
7461 delete_all_child_windows (w->next);
7462
7463 if (WINDOWP (w->contents))
7464 {
7465 delete_all_child_windows (w->contents);
7466 wset_combination (w, false, Qnil);
7467 }
7468 else if (BUFFERP (w->contents))
7469 {
7470 unshow_buffer (w);
7471 unchain_marker (XMARKER (w->pointm));
7472 unchain_marker (XMARKER (w->old_pointm));
7473 unchain_marker (XMARKER (w->start));
7474
7475
7476
7477 wset_combination_limit (w, w->contents);
7478 wset_buffer (w, Qnil);
7479 }
7480
7481 Vwindow_list = Qnil;
7482 }
7483
7484 static ptrdiff_t
7485 count_windows (struct window *window)
7486 {
7487 ptrdiff_t count = 1;
7488 if (!NILP (window->next))
7489 count += count_windows (XWINDOW (window->next));
7490 if (WINDOWP (window->contents))
7491 count += count_windows (XWINDOW (window->contents));
7492 return count;
7493 }
7494
7495
7496
7497
7498 static ptrdiff_t
7499 get_leaf_windows (struct window *w, struct window **flat, ptrdiff_t i)
7500 {
7501 while (w)
7502 {
7503 if (WINDOWP (w->contents))
7504 i = get_leaf_windows (XWINDOW (w->contents), flat, i);
7505 else
7506 flat[i++] = w;
7507
7508 w = NILP (w->next) ? 0 : XWINDOW (w->next);
7509 }
7510
7511 return i;
7512 }
7513
7514
7515
7516
7517
7518 struct glyph *
7519 get_phys_cursor_glyph (struct window *w)
7520 {
7521 struct glyph_row *row;
7522 struct glyph *glyph;
7523 int hpos = w->phys_cursor.hpos;
7524
7525 if (!(w->phys_cursor.vpos >= 0
7526 && w->phys_cursor.vpos < w->current_matrix->nrows))
7527 return NULL;
7528
7529 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
7530 if (!row->enabled_p)
7531 return NULL;
7532
7533 if (w->hscroll)
7534 {
7535
7536
7537
7538 if (!row->reversed_p && hpos < 0)
7539 hpos = 0;
7540 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
7541 hpos = row->used[TEXT_AREA] - 1;
7542 }
7543
7544 if (0 <= hpos && hpos < row->used[TEXT_AREA])
7545 glyph = row->glyphs[TEXT_AREA] + hpos;
7546 else
7547 glyph = NULL;
7548
7549 return glyph;
7550 }
7551
7552
7553 static ptrdiff_t
7554 save_window_save (Lisp_Object window, struct Lisp_Vector *vector, ptrdiff_t i)
7555 {
7556 struct saved_window *p;
7557 struct window *w;
7558 Lisp_Object tem, pers, par;
7559
7560 for (; !NILP (window); window = w->next)
7561 {
7562 p = SAVED_WINDOW_N (vector, i);
7563 w = XWINDOW (window);
7564
7565 wset_temslot (w, make_fixnum (i)); i++;
7566 p->window = window;
7567 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
7568 p->pixel_left = make_fixnum (w->pixel_left);
7569 p->pixel_top = make_fixnum (w->pixel_top);
7570 p->pixel_width = make_fixnum (w->pixel_width);
7571 p->pixel_height = make_fixnum (w->pixel_height);
7572 p->left_col = make_fixnum (w->left_col);
7573 p->top_line = make_fixnum (w->top_line);
7574 p->total_cols = make_fixnum (w->total_cols);
7575 p->total_lines = make_fixnum (w->total_lines);
7576 p->normal_cols = w->normal_cols;
7577 p->normal_lines = w->normal_lines;
7578 XSETFASTINT (p->hscroll, w->hscroll);
7579 p->suspend_auto_hscroll = w->suspend_auto_hscroll ? Qt : Qnil;
7580 XSETFASTINT (p->min_hscroll, w->min_hscroll);
7581 XSETFASTINT (p->hscroll_whole, w->hscroll_whole);
7582 XSETFASTINT (p->vscroll, -w->vscroll);
7583 p->display_table = w->display_table;
7584 p->left_margin_cols = make_fixnum (w->left_margin_cols);
7585 p->right_margin_cols = make_fixnum (w->right_margin_cols);
7586 p->left_fringe_width = make_fixnum (w->left_fringe_width);
7587 p->right_fringe_width = make_fixnum (w->right_fringe_width);
7588 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
7589 p->fringes_persistent = w->fringes_persistent ? Qt : Qnil;
7590 p->scroll_bar_width = make_fixnum (w->scroll_bar_width);
7591 p->scroll_bar_height = make_fixnum (w->scroll_bar_height);
7592 p->scroll_bars_persistent = w->scroll_bars_persistent ? Qt : Qnil;
7593 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
7594 p->horizontal_scroll_bar_type = w->horizontal_scroll_bar_type;
7595 p->dedicated = w->dedicated;
7596 p->combination_limit = w->combination_limit;
7597 p->window_parameters = Qnil;
7598
7599 if (!NILP (Vwindow_persistent_parameters))
7600 {
7601
7602 Lisp_Object tortoise, hare;
7603
7604 hare = tortoise = Vwindow_persistent_parameters;
7605 while (CONSP (hare))
7606 {
7607 hare = XCDR (hare);
7608 if (!CONSP (hare))
7609 break;
7610
7611 hare = XCDR (hare);
7612 tortoise = XCDR (tortoise);
7613
7614 if (BASE_EQ (hare, tortoise))
7615
7616 {
7617 Vwindow_persistent_parameters = Qnil;
7618 break;
7619 }
7620 }
7621
7622 for (tem = Vwindow_persistent_parameters; CONSP (tem);
7623 tem = XCDR (tem))
7624 {
7625 pers = XCAR (tem);
7626
7627 if (CONSP (pers) && !NILP (XCDR (pers)))
7628 {
7629 par = Fassq (XCAR (pers), w->window_parameters);
7630 if (NILP (par))
7631
7632
7633 p->window_parameters = Fcons (Fcons (XCAR (pers), Qnil),
7634 p->window_parameters);
7635 else
7636
7637
7638 p->window_parameters = Fcons (Fcons (XCAR (par),
7639 XCDR (par)),
7640 p->window_parameters);
7641 }
7642 }
7643 }
7644
7645 if (BUFFERP (w->contents))
7646 {
7647 bool window_point_insertion_type
7648 = !NILP (buffer_local_value
7649 (Qwindow_point_insertion_type, w->contents));
7650
7651
7652
7653
7654 if (EQ (window, selected_window))
7655 p->pointm = build_marker (XBUFFER (w->contents),
7656 BUF_PT (XBUFFER (w->contents)),
7657 BUF_PT_BYTE (XBUFFER (w->contents)));
7658 else
7659 p->pointm = Fcopy_marker (w->pointm, Qnil);
7660 p->old_pointm = Fcopy_marker (w->old_pointm, Qnil);
7661 XMARKER (p->pointm)->insertion_type = window_point_insertion_type;
7662 XMARKER (p->old_pointm)->insertion_type = window_point_insertion_type;
7663
7664 p->start = Fcopy_marker (w->start, Qnil);
7665 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
7666 }
7667 else
7668 {
7669 p->pointm = Qnil;
7670 p->old_pointm = Qnil;
7671 p->start = Qnil;
7672 p->start_at_line_beg = Qnil;
7673 }
7674
7675 p->parent = NILP (w->parent) ? Qnil : XWINDOW (w->parent)->temslot;
7676 p->prev = NILP (w->prev) ? Qnil : XWINDOW (w->prev)->temslot;
7677
7678 if (WINDOWP (w->contents))
7679 i = save_window_save (w->contents, vector, i);
7680 }
7681
7682 return i;
7683 }
7684
7685 DEFUN ("current-window-configuration", Fcurrent_window_configuration,
7686 Scurrent_window_configuration, 0, 1, 0,
7687 doc:
7688
7689
7690
7691
7692
7693
7694
7695
7696 )
7697 (Lisp_Object frame)
7698 {
7699 struct frame *f = decode_live_frame (frame);
7700 ptrdiff_t n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
7701 struct save_window_data *data
7702 = ALLOCATE_PSEUDOVECTOR (struct save_window_data, saved_windows,
7703 PVEC_WINDOW_CONFIGURATION);
7704 data->frame_cols = FRAME_COLS (f);
7705 data->frame_lines = FRAME_LINES (f);
7706 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
7707 data->frame_tab_bar_lines = FRAME_TAB_BAR_LINES (f);
7708 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
7709 data->frame_text_width = FRAME_TEXT_WIDTH (f);
7710 data->frame_text_height = FRAME_TEXT_HEIGHT (f);
7711 data->frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
7712 data->frame_tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
7713 data->frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
7714 data->selected_frame = selected_frame;
7715 data->current_window = FRAME_SELECTED_WINDOW (f);
7716 XSETBUFFER (data->f_current_buffer, current_buffer);
7717 data->minibuf_scroll_window = minibuf_level > 0 ? Vminibuf_scroll_window : Qnil;
7718 data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
7719 data->root_window = FRAME_ROOT_WINDOW (f);
7720 data->focus_frame = FRAME_FOCUS_FRAME (f);
7721 Lisp_Object tem = make_nil_vector (n_windows);
7722 data->saved_windows = tem;
7723 for (ptrdiff_t i = 0; i < n_windows; i++)
7724 ASET (tem, i, make_nil_vector (VECSIZE (struct saved_window)));
7725 save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
7726 XSETWINDOW_CONFIGURATION (tem, data);
7727 return tem;
7728 }
7729
7730
7731
7732 static void
7733 apply_window_adjustment (struct window *w)
7734 {
7735 eassert (w);
7736 clear_glyph_matrix (w->current_matrix);
7737 w->window_end_valid = false;
7738 wset_redisplay (w);
7739 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w)));
7740 }
7741
7742
7743
7744
7745
7746
7747 static int
7748 extract_dimension (Lisp_Object dimension)
7749 {
7750 if (NILP (dimension))
7751 return -1;
7752 return check_integer_range (dimension, 0, INT_MAX);
7753 }
7754
7755 static struct window *
7756 set_window_margins (struct window *w, Lisp_Object left_width,
7757 Lisp_Object right_width)
7758 {
7759 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
7760 int left = NILP (left_width) ? 0 : extract_dimension (left_width);
7761 int right = NILP (right_width) ? 0 : extract_dimension (right_width);
7762
7763 if (w->left_margin_cols != left || w->right_margin_cols != right)
7764 {
7765
7766 if ((WINDOW_PIXEL_WIDTH (w)
7767 - WINDOW_FRINGES_WIDTH (w)
7768 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7769 - (left + right) * unit)
7770 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7771 {
7772 w->left_margin_cols = left;
7773 w->right_margin_cols = right;
7774
7775 return w;
7776 }
7777 else
7778 return NULL;
7779 }
7780 else
7781 return NULL;
7782 }
7783
7784 DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
7785 2, 3, 0,
7786 doc:
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796 )
7797 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width)
7798 {
7799 struct window *w = set_window_margins (decode_live_window (window),
7800 left_width, right_width);
7801 return w ? (apply_window_adjustment (w), Qt) : Qnil;
7802 }
7803
7804
7805 DEFUN ("window-margins", Fwindow_margins, Swindow_margins,
7806 0, 1, 0,
7807 doc:
7808
7809
7810
7811
7812 )
7813 (Lisp_Object window)
7814 {
7815 struct window *w = decode_live_window (window);
7816 return Fcons (w->left_margin_cols
7817 ? make_fixnum (w->left_margin_cols) : Qnil,
7818 w->right_margin_cols
7819 ? make_fixnum (w->right_margin_cols) : Qnil);
7820 }
7821
7822
7823
7824
7825
7826
7827
7828 static struct window *
7829 set_window_fringes (struct window *w,
7830 Lisp_Object left_width, Lisp_Object right_width,
7831 Lisp_Object outside_margins, Lisp_Object persistent)
7832 {
7833
7834 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w)))
7835 return NULL;
7836 else
7837 {
7838 struct frame *f = XFRAME (WINDOW_FRAME (w));
7839 int old_left = WINDOW_LEFT_FRINGE_WIDTH (w);
7840 int old_right = WINDOW_RIGHT_FRINGE_WIDTH (w);
7841 int new_left = extract_dimension (left_width);
7842 int new_right = extract_dimension (right_width);
7843 bool outside = !NILP (outside_margins);
7844 bool changed = false;
7845 bool failed = false;
7846
7847
7848
7849 if ((WINDOW_PIXEL_WIDTH (w)
7850 - WINDOW_MARGINS_WIDTH (w)
7851 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7852 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
7853 - (new_left == -1 ? FRAME_LEFT_FRINGE_WIDTH (f) : new_left)
7854 - (new_right == -1 ? FRAME_RIGHT_FRINGE_WIDTH (f) : new_right))
7855 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7856 {
7857 w->left_fringe_width = new_left;
7858 w->right_fringe_width = new_right;
7859 changed = new_left != old_left || new_right != old_right;
7860 }
7861 else
7862 failed = true;
7863
7864
7865 if (outside != w->fringes_outside_margins)
7866 {
7867 w->fringes_outside_margins = outside;
7868 changed = true;
7869 }
7870
7871
7872
7873 if (!failed)
7874 w->fringes_persistent = !NILP (persistent);
7875
7876
7877
7878
7879
7880 if (changed)
7881 {
7882 windows_or_buffers_changed = 35;
7883 return w;
7884 }
7885 else
7886 return NULL;
7887 }
7888 }
7889
7890 DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
7891 2, 5, 0,
7892 doc:
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913 )
7914 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width,
7915 Lisp_Object outside_margins, Lisp_Object persistent)
7916 {
7917 struct window *w
7918 = set_window_fringes (decode_live_window (window), left_width,
7919 right_width, outside_margins, persistent);
7920 return w ? (apply_window_adjustment (w), Qt) : Qnil;
7921 }
7922
7923
7924 DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
7925 0, 1, 0,
7926 doc:
7927
7928
7929
7930 )
7931 (Lisp_Object window)
7932 {
7933 struct window *w = decode_live_window (window);
7934
7935 return list4 (make_fixnum (WINDOW_LEFT_FRINGE_WIDTH (w)),
7936 make_fixnum (WINDOW_RIGHT_FRINGE_WIDTH (w)),
7937 WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ? Qt : Qnil,
7938 w->fringes_persistent ? Qt : Qnil);
7939 }
7940
7941
7942
7943
7944
7945
7946
7947 static struct window *
7948 set_window_scroll_bars (struct window *w, Lisp_Object width,
7949 Lisp_Object vertical_type, Lisp_Object height,
7950 Lisp_Object horizontal_type, Lisp_Object persistent)
7951 {
7952
7953 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w)))
7954 return NULL;
7955 else
7956 {
7957 struct frame *f = XFRAME (WINDOW_FRAME (w));
7958 int new_width = extract_dimension (width);
7959 bool changed = false;
7960 bool failed = false;
7961
7962 if (new_width == 0)
7963 vertical_type = Qnil;
7964 else if (!(NILP (vertical_type)
7965 || EQ (vertical_type, Qleft)
7966 || EQ (vertical_type, Qright)
7967 || EQ (vertical_type, Qt)))
7968 error ("Invalid type of vertical scroll bar");
7969
7970
7971
7972 if ((WINDOW_PIXEL_WIDTH (w)
7973 - WINDOW_MARGINS_WIDTH (w)
7974 - WINDOW_FRINGES_WIDTH (w)
7975 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
7976 - (new_width == -1 ? FRAME_SCROLL_BAR_AREA_WIDTH (f) : new_width))
7977 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7978 {
7979 changed = (!EQ (vertical_type, w->vertical_scroll_bar_type)
7980 || new_width != WINDOW_SCROLL_BAR_AREA_WIDTH (w));
7981 wset_vertical_scroll_bar_type (w, vertical_type);
7982 w->scroll_bar_width = new_width;
7983 }
7984 else
7985 failed = true;
7986
7987 #if USE_HORIZONTAL_SCROLL_BARS
7988 int new_height = extract_dimension (height);
7989
7990 if ((MINI_WINDOW_P (w) && !EQ (horizontal_type, Qbottom))
7991 || new_height == 0)
7992 horizontal_type = Qnil;
7993
7994 if (!(NILP (horizontal_type)
7995 || EQ (horizontal_type, Qbottom)
7996 || EQ (horizontal_type, Qt)))
7997 error ("Invalid type of horizontal scroll bar");
7998
7999
8000 if ((WINDOW_PIXEL_HEIGHT (w)
8001 - WINDOW_TAB_LINE_HEIGHT (w)
8002 - WINDOW_HEADER_LINE_HEIGHT (w)
8003 - WINDOW_MODE_LINE_HEIGHT (w)
8004 - (new_height == -1 ? FRAME_SCROLL_BAR_AREA_HEIGHT (f) : new_height))
8005 >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
8006 {
8007 changed = (changed
8008 || !EQ (horizontal_type, w->horizontal_scroll_bar_type)
8009 || new_height != WINDOW_SCROLL_BAR_AREA_HEIGHT (w));
8010 wset_horizontal_scroll_bar_type (w, horizontal_type);
8011 w->scroll_bar_height = new_height;
8012 }
8013 else
8014 failed = true;
8015 #else
8016 wset_horizontal_scroll_bar_type (w, Qnil);
8017 #endif
8018
8019
8020
8021 if (!failed)
8022 w->scroll_bars_persistent = !NILP (persistent);
8023
8024
8025
8026
8027
8028 if (changed)
8029 wset_redisplay (w);
8030
8031 return changed ? w : NULL;
8032 }
8033 }
8034
8035 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
8036 Sset_window_scroll_bars, 1, 6, 0,
8037 doc:
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064 )
8065 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
8066 Lisp_Object height, Lisp_Object horizontal_type, Lisp_Object persistent)
8067 {
8068 struct window *w
8069 = set_window_scroll_bars (decode_live_window (window),
8070 width, vertical_type, height,
8071 horizontal_type, persistent);
8072 return w ? (apply_window_adjustment (w), Qt) : Qnil;
8073 }
8074
8075
8076 DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
8077 0, 1, 0,
8078 doc:
8079
8080
8081
8082
8083
8084 )
8085 (Lisp_Object window)
8086 {
8087 struct window *w = decode_live_window (window);
8088
8089 return Fcons (((w->scroll_bar_width >= 0)
8090 ? make_fixnum (w->scroll_bar_width)
8091 : Qnil),
8092 Fcons (make_fixnum (WINDOW_SCROLL_BAR_COLS (w)),
8093 list5 (w->vertical_scroll_bar_type,
8094 ((w->scroll_bar_height >= 0)
8095 ? make_fixnum (w->scroll_bar_height)
8096 : Qnil),
8097 make_fixnum (WINDOW_SCROLL_BAR_LINES (w)),
8098 w->horizontal_scroll_bar_type,
8099 w->scroll_bars_persistent ? Qt : Qnil)));
8100 }
8101
8102
8103
8104
8105
8106 DEFUN ("window-vscroll", Fwindow_vscroll, Swindow_vscroll, 0, 2, 0,
8107 doc:
8108
8109
8110
8111
8112 )
8113 (Lisp_Object window, Lisp_Object pixels_p)
8114 {
8115 Lisp_Object result;
8116 struct window *w = decode_live_window (window);
8117 struct frame *f = XFRAME (w->frame);
8118
8119 if (FRAME_WINDOW_P (f))
8120 result = (NILP (pixels_p)
8121 ? FRAME_CANON_Y_FROM_PIXEL_Y (f, -w->vscroll)
8122 : make_fixnum (-w->vscroll));
8123 else
8124 result = make_fixnum (0);
8125 return result;
8126 }
8127
8128
8129 DEFUN ("set-window-vscroll", Fset_window_vscroll, Sset_window_vscroll,
8130 2, 4, 0,
8131 doc:
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143 )
8144 (Lisp_Object window, Lisp_Object vscroll, Lisp_Object pixels_p,
8145 Lisp_Object preserve_vscroll_p)
8146 {
8147 struct window *w = decode_live_window (window);
8148 struct frame *f = XFRAME (w->frame);
8149
8150 CHECK_NUMBER (vscroll);
8151
8152 if (FRAME_WINDOW_P (f))
8153 {
8154 int old_dy = w->vscroll;
8155
8156 w->vscroll = - (NILP (pixels_p)
8157 ? FRAME_LINE_HEIGHT (f) * XFLOATINT (vscroll)
8158 : XFLOATINT (vscroll));
8159 w->vscroll = min (w->vscroll, 0);
8160
8161 if (w->vscroll != old_dy)
8162 {
8163
8164
8165 if (w->vscroll < 0 && w->vscroll < old_dy)
8166 adjust_frame_glyphs (f);
8167
8168
8169 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = true;
8170
8171
8172 wset_redisplay (w);
8173 }
8174
8175 w->preserve_vscroll_p = !NILP (preserve_vscroll_p);
8176 }
8177
8178 return Fwindow_vscroll (window, pixels_p);
8179 }
8180
8181
8182
8183
8184
8185
8186 static void
8187 foreach_window (struct frame *f, bool (*fn) (struct window *, void *),
8188 void *user_data)
8189 {
8190
8191 if (WINDOWP (FRAME_ROOT_WINDOW (f)))
8192 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data);
8193 }
8194
8195
8196
8197
8198
8199
8200
8201 static bool
8202 foreach_window_1 (struct window *w, bool (*fn) (struct window *, void *),
8203 void *user_data)
8204 {
8205 bool cont;
8206
8207 for (cont = true; w && cont;)
8208 {
8209 if (WINDOWP (w->contents))
8210 cont = foreach_window_1 (XWINDOW (w->contents), fn, user_data);
8211 else
8212 cont = fn (w, user_data);
8213
8214 w = NILP (w->next) ? 0 : XWINDOW (w->next);
8215 }
8216
8217 return cont;
8218 }
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233 static bool
8234 compare_window_configurations (Lisp_Object configuration1,
8235 Lisp_Object configuration2)
8236 {
8237 struct save_window_data *d1, *d2;
8238 struct Lisp_Vector *sws1, *sws2;
8239 ptrdiff_t i;
8240
8241 CHECK_WINDOW_CONFIGURATION (configuration1);
8242 CHECK_WINDOW_CONFIGURATION (configuration2);
8243
8244 d1 = (struct save_window_data *) XVECTOR (configuration1);
8245 d2 = (struct save_window_data *) XVECTOR (configuration2);
8246 sws1 = XVECTOR (d1->saved_windows);
8247 sws2 = XVECTOR (d2->saved_windows);
8248
8249
8250 if (d1->frame_cols != d2->frame_cols
8251 || d1->frame_lines != d2->frame_lines
8252 || d1->frame_menu_bar_lines != d2->frame_menu_bar_lines
8253 || !EQ (d1->selected_frame, d2->selected_frame)
8254 || !EQ (d1->f_current_buffer, d2->f_current_buffer)
8255 || !EQ (d1->focus_frame, d2->focus_frame)
8256
8257 || sws1->header.size != sws2->header.size)
8258 return false;
8259
8260 for (i = 0; i < sws1->header.size; i++)
8261 {
8262 struct saved_window *sw1, *sw2;
8263
8264 sw1 = SAVED_WINDOW_N (sws1, i);
8265 sw2 = SAVED_WINDOW_N (sws2, i);
8266
8267 if (
8268
8269
8270 EQ (d1->current_window, sw1->window)
8271 != EQ (d2->current_window, sw2->window)
8272
8273 || !EQ (sw1->buffer, sw2->buffer)
8274 || !EQ (sw1->pixel_left, sw2->pixel_left)
8275 || !EQ (sw1->pixel_top, sw2->pixel_top)
8276 || !EQ (sw1->pixel_height, sw2->pixel_height)
8277 || !EQ (sw1->pixel_width, sw2->pixel_width)
8278 || !EQ (sw1->left_col, sw2->left_col)
8279 || !EQ (sw1->top_line, sw2->top_line)
8280 || !EQ (sw1->total_cols, sw2->total_cols)
8281 || !EQ (sw1->total_lines, sw2->total_lines)
8282 || !EQ (sw1->display_table, sw2->display_table)
8283
8284
8285 || !EQ (sw1->parent, sw2->parent)
8286 || !EQ (sw1->prev, sw2->prev)
8287 || !EQ (sw1->left_margin_cols, sw2->left_margin_cols)
8288 || !EQ (sw1->right_margin_cols, sw2->right_margin_cols)
8289 || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
8290 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
8291 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
8292 || !EQ (sw1->fringes_persistent, sw2->fringes_persistent)
8293 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
8294 || !EQ (sw1->scroll_bar_height, sw2->scroll_bar_height)
8295 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)
8296 || !EQ (sw1->horizontal_scroll_bar_type, sw2->horizontal_scroll_bar_type)
8297 || !EQ (sw1->scroll_bars_persistent, sw2->scroll_bars_persistent))
8298 return false;
8299 }
8300
8301 return true;
8302 }
8303
8304 DEFUN ("window-configuration-equal-p", Fwindow_configuration_equal_p,
8305 Swindow_configuration_equal_p, 2, 2, 0,
8306 doc:
8307
8308 )
8309 (Lisp_Object x, Lisp_Object y)
8310 {
8311 if (compare_window_configurations (x, y))
8312 return Qt;
8313 return Qnil;
8314 }
8315
8316
8317 static void init_window_once_for_pdumper (void);
8318
8319 void
8320 init_window_once (void)
8321 {
8322 minibuf_window = Qnil;
8323 staticpro (&minibuf_window);
8324
8325 selected_window = Qnil;
8326 staticpro (&selected_window);
8327
8328 Vwindow_list = Qnil;
8329 staticpro (&Vwindow_list);
8330
8331 minibuf_selected_window = Qnil;
8332 staticpro (&minibuf_selected_window);
8333 old_selected_window = Qnil;
8334 staticpro (&old_selected_window);
8335
8336 pdumper_do_now_and_after_late_load (init_window_once_for_pdumper);
8337 }
8338
8339 static void init_window_once_for_pdumper (void)
8340 {
8341 window_scroll_pixel_based_preserve_x = -1;
8342 window_scroll_pixel_based_preserve_y = -1;
8343 window_scroll_preserve_hpos = -1;
8344 window_scroll_preserve_vpos = -1;
8345 PDUMPER_IGNORE (sequence_number);
8346
8347 PDUMPER_RESET_LV (minibuf_window, Qnil);
8348 PDUMPER_RESET_LV (selected_window, Qnil);
8349 PDUMPER_RESET_LV (Vwindow_list, Qnil);
8350 PDUMPER_RESET_LV (minibuf_selected_window, Qnil);
8351
8352
8353
8354
8355
8356
8357 bool old_mode_line_in_non_selected_windows;
8358
8359
8360 bool saved_dumped_with_pdumper = dumped_with_pdumper_p ();
8361 if (saved_dumped_with_pdumper)
8362 {
8363 old_mode_line_in_non_selected_windows
8364 = mode_line_in_non_selected_windows;
8365 mode_line_in_non_selected_windows = false;
8366 }
8367 struct frame *f = make_initial_frame ();
8368 if (saved_dumped_with_pdumper)
8369 mode_line_in_non_selected_windows =
8370 old_mode_line_in_non_selected_windows;
8371 XSETFRAME (selected_frame, f);
8372 old_selected_frame = Vterminal_frame = selected_frame;
8373 minibuf_window = f->minibuffer_window;
8374 old_selected_window = selected_window = f->selected_window;
8375 }
8376
8377 void
8378 init_window (void)
8379 {
8380 Vwindow_list = Qnil;
8381 }
8382
8383 void
8384 syms_of_window (void)
8385 {
8386 DEFSYM (Qscroll_up, "scroll-up");
8387 DEFSYM (Qscroll_down, "scroll-down");
8388 DEFSYM (Qscroll_command, "scroll-command");
8389
8390 Fput (Qscroll_up, Qscroll_command, Qt);
8391 Fput (Qscroll_down, Qscroll_command, Qt);
8392
8393 DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook");
8394 DEFSYM (Qwindow_state_change_hook, "window-state-change-hook");
8395 DEFSYM (Qwindow_state_change_functions, "window-state-change-functions");
8396 DEFSYM (Qwindow_size_change_functions, "window-size-change-functions");
8397 DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions");
8398 DEFSYM (Qwindow_selection_change_functions, "window-selection-change-functions");
8399 DEFSYM (Qwindowp, "windowp");
8400 DEFSYM (Qwindow_configuration_p, "window-configuration-p");
8401 DEFSYM (Qwindow_live_p, "window-live-p");
8402 DEFSYM (Qwindow_valid_p, "window-valid-p");
8403 DEFSYM (Qwindow_deletable_p, "window-deletable-p");
8404 DEFSYM (Qdelete_window, "delete-window");
8405 DEFSYM (Qwindow__resize_root_window, "window--resize-root-window");
8406 DEFSYM (Qwindow__resize_root_window_vertically,
8407 "window--resize-root-window-vertically");
8408 DEFSYM (Qwindow__resize_mini_frame, "window--resize-mini-frame");
8409 DEFSYM (Qwindow__pixel_to_total, "window--pixel-to-total");
8410 DEFSYM (Qsafe, "safe");
8411 DEFSYM (Qdisplay_buffer, "display-buffer");
8412 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
8413 DEFSYM (Qrecord_window_buffer, "record-window-buffer");
8414 DEFSYM (Qget_mru_window, "get-mru-window");
8415 DEFSYM (Qwindow_size, "window-size");
8416 DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
8417 DEFSYM (Qabove, "above");
8418 DEFSYM (Qclone_of, "clone-of");
8419 DEFSYM (Qfloor, "floor");
8420 DEFSYM (Qceiling, "ceiling");
8421 DEFSYM (Qmark_for_redisplay, "mark-for-redisplay");
8422 DEFSYM (Qmode_line_format, "mode-line-format");
8423 DEFSYM (Qheader_line_format, "header-line-format");
8424 DEFSYM (Qtab_line_format, "tab-line-format");
8425 DEFSYM (Qno_other_window, "no-other-window");
8426
8427 DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
8428 doc:
8429
8430
8431
8432 );
8433 Vtemp_buffer_show_function = Qnil;
8434
8435 DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window,
8436 doc: );
8437 Vminibuf_scroll_window = Qnil;
8438
8439 DEFVAR_BOOL ("mode-line-in-non-selected-windows", mode_line_in_non_selected_windows,
8440 doc:
8441
8442 );
8443 mode_line_in_non_selected_windows = true;
8444
8445 DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer,
8446 doc: );
8447 Vother_window_scroll_buffer = Qnil;
8448
8449 DEFVAR_LISP ("other-window-scroll-default", Vother_window_scroll_default,
8450 doc:
8451
8452
8453
8454 );
8455 Vother_window_scroll_default = Qnil;
8456
8457 DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
8458 doc: );
8459 auto_window_vscroll_p = true;
8460
8461 DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
8462 doc: );
8463 next_screen_context_lines = 2;
8464
8465 DEFVAR_LISP ("scroll-preserve-screen-position",
8466 Vscroll_preserve_screen_position,
8467 doc:
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481 );
8482 Vscroll_preserve_screen_position = Qnil;
8483
8484 DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type,
8485 doc:
8486 );
8487 Vwindow_point_insertion_type = Qnil;
8488 DEFSYM (Qwindow_point_insertion_type, "window-point-insertion-type");
8489
8490 DEFVAR_LISP ("window-buffer-change-functions", Vwindow_buffer_change_functions,
8491 doc:
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502 );
8503 Vwindow_buffer_change_functions = Qnil;
8504
8505 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
8506 doc:
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520 );
8521 Vwindow_size_change_functions = Qnil;
8522
8523 DEFVAR_LISP ("window-selection-change-functions", Vwindow_selection_change_functions,
8524 doc:
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534 );
8535 Vwindow_selection_change_functions = Qnil;
8536
8537 DEFVAR_LISP ("window-state-change-functions", Vwindow_state_change_functions,
8538 doc:
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551 );
8552 Vwindow_state_change_functions = Qnil;
8553
8554 DEFVAR_LISP ("window-state-change-hook", Vwindow_state_change_hook,
8555 doc:
8556
8557
8558
8559
8560
8561
8562
8563
8564 );
8565 Vwindow_state_change_hook = Qnil;
8566
8567 DEFVAR_LISP ("window-configuration-change-hook", Vwindow_configuration_change_hook,
8568 doc:
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580 );
8581 Vwindow_configuration_change_hook = Qnil;
8582
8583 DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
8584 doc:
8585
8586
8587 );
8588 Vrecenter_redisplay = Qtty;
8589
8590 DEFVAR_LISP ("window-combination-resize", Vwindow_combination_resize,
8591 doc:
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605 );
8606 Vwindow_combination_resize = Qnil;
8607
8608 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
8609 doc:
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643 );
8644 Vwindow_combination_limit = Qwindow_size;
8645
8646 DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
8647 doc:
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668 );
8669 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
8670
8671 DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise,
8672 doc:
8673
8674
8675
8676
8677
8678
8679 );
8680 window_resize_pixelwise = false;
8681
8682 DEFVAR_BOOL ("fast-but-imprecise-scrolling",
8683 fast_but_imprecise_scrolling,
8684 doc:
8685
8686
8687
8688
8689
8690 );
8691 fast_but_imprecise_scrolling = false;
8692
8693 defsubr (&Sselected_window);
8694 defsubr (&Sold_selected_window);
8695 defsubr (&Sminibuffer_window);
8696 defsubr (&Swindow_minibuffer_p);
8697 defsubr (&Swindowp);
8698 defsubr (&Swindow_valid_p);
8699 defsubr (&Swindow_live_p);
8700 defsubr (&Swindow_frame);
8701 defsubr (&Sframe_root_window);
8702 defsubr (&Sframe_first_window);
8703 defsubr (&Sframe_selected_window);
8704 defsubr (&Sframe_old_selected_window);
8705 defsubr (&Sset_frame_selected_window);
8706 defsubr (&Spos_visible_in_window_p);
8707 defsubr (&Swindow_line_height);
8708 defsubr (&Swindow_buffer);
8709 defsubr (&Swindow_old_buffer);
8710 defsubr (&Swindow_parent);
8711 defsubr (&Swindow_top_child);
8712 defsubr (&Swindow_left_child);
8713 defsubr (&Swindow_next_sibling);
8714 defsubr (&Swindow_prev_sibling);
8715 defsubr (&Swindow_combination_limit);
8716 defsubr (&Sset_window_combination_limit);
8717 defsubr (&Swindow_use_time);
8718 defsubr (&Swindow_pixel_width);
8719 defsubr (&Swindow_pixel_height);
8720 defsubr (&Swindow_old_pixel_width);
8721 defsubr (&Swindow_old_pixel_height);
8722 defsubr (&Swindow_old_body_pixel_width);
8723 defsubr (&Swindow_old_body_pixel_height);
8724 defsubr (&Swindow_total_width);
8725 defsubr (&Swindow_total_height);
8726 defsubr (&Swindow_normal_size);
8727 defsubr (&Swindow_new_pixel);
8728 defsubr (&Swindow_new_total);
8729 defsubr (&Swindow_new_normal);
8730 defsubr (&Swindow_pixel_left);
8731 defsubr (&Swindow_pixel_top);
8732 defsubr (&Swindow_left_column);
8733 defsubr (&Swindow_top_line);
8734 defsubr (&Sset_window_new_pixel);
8735 defsubr (&Sset_window_new_total);
8736 defsubr (&Sset_window_new_normal);
8737 defsubr (&Swindow_resize_apply);
8738 defsubr (&Swindow_resize_apply_total);
8739 defsubr (&Swindow_body_height);
8740 defsubr (&Swindow_body_width);
8741 defsubr (&Swindow_hscroll);
8742 defsubr (&Sset_window_hscroll);
8743 defsubr (&Swindow_mode_line_height);
8744 defsubr (&Swindow_header_line_height);
8745 defsubr (&Swindow_tab_line_height);
8746 defsubr (&Swindow_right_divider_width);
8747 defsubr (&Swindow_bottom_divider_width);
8748 defsubr (&Swindow_scroll_bar_width);
8749 defsubr (&Swindow_scroll_bar_height);
8750 defsubr (&Scoordinates_in_window_p);
8751 defsubr (&Swindow_at);
8752 defsubr (&Swindow_point);
8753 defsubr (&Swindow_old_point);
8754 defsubr (&Swindow_start);
8755 defsubr (&Swindow_end);
8756 defsubr (&Sset_window_point);
8757 defsubr (&Sset_window_start);
8758 defsubr (&Swindow_dedicated_p);
8759 defsubr (&Swindow_lines_pixel_dimensions);
8760 defsubr (&Sset_window_dedicated_p);
8761 defsubr (&Swindow_display_table);
8762 defsubr (&Sset_window_display_table);
8763 defsubr (&Snext_window);
8764 defsubr (&Sprevious_window);
8765 defsubr (&Sget_buffer_window);
8766 defsubr (&Sdelete_other_windows_internal);
8767 defsubr (&Sdelete_window_internal);
8768 defsubr (&Sresize_mini_window_internal);
8769 defsubr (&Sset_window_buffer);
8770 defsubr (&Srun_window_configuration_change_hook);
8771 defsubr (&Srun_window_scroll_functions);
8772 defsubr (&Sselect_window);
8773 defsubr (&Sforce_window_update);
8774 defsubr (&Ssplit_window_internal);
8775 defsubr (&Sscroll_up);
8776 defsubr (&Sscroll_down);
8777 defsubr (&Sscroll_left);
8778 defsubr (&Sscroll_right);
8779 defsubr (&Sother_window_for_scrolling);
8780 defsubr (&Sminibuffer_selected_window);
8781 defsubr (&Srecenter);
8782 defsubr (&Swindow_text_width);
8783 defsubr (&Swindow_text_height);
8784 defsubr (&Smove_to_window_line);
8785 defsubr (&Swindow_configuration_p);
8786 defsubr (&Swindow_configuration_frame);
8787 defsubr (&Sset_window_configuration);
8788 defsubr (&Scurrent_window_configuration);
8789 defsubr (&Sset_window_margins);
8790 defsubr (&Swindow_margins);
8791 defsubr (&Sset_window_fringes);
8792 defsubr (&Swindow_fringes);
8793 defsubr (&Sset_window_scroll_bars);
8794 defsubr (&Swindow_scroll_bars);
8795 defsubr (&Swindow_vscroll);
8796 defsubr (&Sset_window_vscroll);
8797 defsubr (&Swindow_configuration_equal_p);
8798 defsubr (&Swindow_bump_use_time);
8799 defsubr (&Swindow_list);
8800 defsubr (&Swindow_list_1);
8801 defsubr (&Swindow_prev_buffers);
8802 defsubr (&Sset_window_prev_buffers);
8803 defsubr (&Swindow_next_buffers);
8804 defsubr (&Sset_window_next_buffers);
8805 defsubr (&Swindow_parameters);
8806 defsubr (&Swindow_parameter);
8807 defsubr (&Sset_window_parameter);
8808 }