Mercurial > hg > xemacs-beta
comparison src/window.c @ 5178:97eb4942aec8
merge
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Mon, 29 Mar 2010 21:28:13 -0500 |
parents | 8b2f75cecb89 be6e5ea38dda |
children | 71ee43b8a74d |
comparison
equal
deleted
inserted
replaced
5177:b785049378e3 | 5178:97eb4942aec8 |
---|---|
53 | 53 |
54 Lisp_Object Qwindowp, Qwindow_live_p; | 54 Lisp_Object Qwindowp, Qwindow_live_p; |
55 Lisp_Object Qdisplay_buffer; | 55 Lisp_Object Qdisplay_buffer; |
56 | 56 |
57 #ifdef MEMORY_USAGE_STATS | 57 #ifdef MEMORY_USAGE_STATS |
58 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay; | 58 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qredisplay_structs; |
59 #ifdef HAVE_SCROLLBARS | 59 #ifdef HAVE_SCROLLBARS |
60 Lisp_Object Qscrollbar_instances; | 60 Lisp_Object Qscrollbar_instances; |
61 #endif | 61 #endif |
62 #endif | 62 #endif |
63 | 63 |
180 { XD_LISP_OBJECT, offsetof (face_cachel, background_pixmap) }, | 180 { XD_LISP_OBJECT, offsetof (face_cachel, background_pixmap) }, |
181 { XD_END } | 181 { XD_END } |
182 }; | 182 }; |
183 | 183 |
184 #ifdef NEW_GC | 184 #ifdef NEW_GC |
185 DEFINE_LRECORD_IMPLEMENTATION ("face-cachel", face_cachel, | 185 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("face-cachel", face_cachel, |
186 1, /*dumpable-flag*/ | 186 0, face_cachel_description_1, |
187 0, 0, 0, 0, 0, | 187 Lisp_Face_Cachel); |
188 face_cachel_description_1, | |
189 Lisp_Face_Cachel); | |
190 #endif /* NEW_GC */ | 188 #endif /* NEW_GC */ |
191 | 189 |
192 static const struct sized_memory_description face_cachel_description = { | 190 static const struct sized_memory_description face_cachel_description = { |
193 sizeof (face_cachel), | 191 sizeof (face_cachel), |
194 face_cachel_description_1 | 192 face_cachel_description_1 |
202 #endif /* not NEW_GC */ | 200 #endif /* not NEW_GC */ |
203 { XD_END } | 201 { XD_END } |
204 }; | 202 }; |
205 | 203 |
206 #ifdef NEW_GC | 204 #ifdef NEW_GC |
207 DEFINE_LRECORD_IMPLEMENTATION ("face-cachel-dynarr", face_cachel_dynarr, | 205 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("face-cachel-dynarr", face_cachel_dynarr, |
208 1, /*dumpable-flag*/ | 206 0, face_cachel_dynarr_description_1, |
209 0, 0, 0, 0, 0, | 207 face_cachel_dynarr); |
210 face_cachel_dynarr_description_1, | |
211 face_cachel_dynarr); | |
212 #else /* not NEW_GC */ | 208 #else /* not NEW_GC */ |
213 static const struct sized_memory_description face_cachel_dynarr_description = { | 209 static const struct sized_memory_description face_cachel_dynarr_description = { |
214 sizeof (face_cachel_dynarr), | 210 sizeof (face_cachel_dynarr), |
215 face_cachel_dynarr_description_1 | 211 face_cachel_dynarr_description_1 |
216 }; | 212 }; |
220 { XD_LISP_OBJECT, offsetof (glyph_cachel, glyph) }, | 216 { XD_LISP_OBJECT, offsetof (glyph_cachel, glyph) }, |
221 { XD_END } | 217 { XD_END } |
222 }; | 218 }; |
223 | 219 |
224 #ifdef NEW_GC | 220 #ifdef NEW_GC |
225 DEFINE_LRECORD_IMPLEMENTATION ("glyph-cachel", glyph_cachel, | 221 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("glyph-cachel", glyph_cachel, |
226 1, /*dumpable-flag*/ | 222 0, glyph_cachel_description_1, |
227 0, 0, 0, 0, 0, | 223 Lisp_Glyph_Cachel); |
228 glyph_cachel_description_1, | |
229 Lisp_Glyph_Cachel); | |
230 #endif /* NEW_GC */ | 224 #endif /* NEW_GC */ |
231 | 225 |
232 static const struct sized_memory_description glyph_cachel_description = { | 226 static const struct sized_memory_description glyph_cachel_description = { |
233 sizeof (glyph_cachel), | 227 sizeof (glyph_cachel), |
234 glyph_cachel_description_1 | 228 glyph_cachel_description_1 |
242 #endif /* not NEW_GC */ | 236 #endif /* not NEW_GC */ |
243 { XD_END } | 237 { XD_END } |
244 }; | 238 }; |
245 | 239 |
246 #ifdef NEW_GC | 240 #ifdef NEW_GC |
247 DEFINE_LRECORD_IMPLEMENTATION ("glyph-cachel-dynarr", glyph_cachel_dynarr, | 241 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("glyph-cachel-dynarr", |
248 1, /*dumpable-flag*/ | 242 glyph_cachel_dynarr, 0, |
249 0, 0, 0, 0, 0, | 243 glyph_cachel_dynarr_description_1, |
250 glyph_cachel_dynarr_description_1, | 244 glyph_cachel_dynarr); |
251 glyph_cachel_dynarr); | |
252 #else /* not NEW_GC */ | 245 #else /* not NEW_GC */ |
253 static const struct sized_memory_description glyph_cachel_dynarr_description = { | 246 static const struct sized_memory_description glyph_cachel_dynarr_description = { |
254 sizeof (glyph_cachel_dynarr), | 247 sizeof (glyph_cachel_dynarr), |
255 glyph_cachel_dynarr_description_1 | 248 glyph_cachel_dynarr_description_1 |
256 }; | 249 }; |
314 int UNUSED (escapeflag)) | 307 int UNUSED (escapeflag)) |
315 { | 308 { |
316 Lisp_Object buf; | 309 Lisp_Object buf; |
317 | 310 |
318 if (print_readably) | 311 if (print_readably) |
319 printing_unreadable_lcrecord (obj, 0); | 312 printing_unreadable_lisp_object (obj, 0); |
320 | 313 |
321 write_ascstring (printcharfun, "#<window"); | 314 write_ascstring (printcharfun, "#<window"); |
322 buf = XWINDOW_BUFFER (obj); | 315 buf = XWINDOW_BUFFER (obj); |
323 if (EQ (buf, Qt)) | 316 if (EQ (buf, Qt)) |
324 write_ascstring (printcharfun, " during creation"); | 317 write_ascstring (printcharfun, " during creation"); |
326 { | 319 { |
327 | 320 |
328 Lisp_Object name = XBUFFER (buf)->name; | 321 Lisp_Object name = XBUFFER (buf)->name; |
329 write_fmt_string_lisp (printcharfun, " on %S", 1, name); | 322 write_fmt_string_lisp (printcharfun, " on %S", 1, name); |
330 } | 323 } |
331 write_fmt_string (printcharfun, " 0x%x>", XWINDOW (obj)->header.uid); | 324 write_fmt_string (printcharfun, " 0x%x>", LISP_OBJECT_UID (obj)); |
332 } | 325 } |
333 | 326 |
334 static void | 327 static void |
335 finalize_window (void *header, int UNUSED (for_disksave)) | 328 finalize_window (Lisp_Object obj) |
336 { | 329 { |
337 struct window *w = (struct window *) header; | 330 struct window *w = XWINDOW (obj); |
338 | 331 |
339 if (w->line_start_cache) | 332 if (w->line_start_cache) |
340 { | 333 { |
341 Dynarr_free (w->line_start_cache); | 334 Dynarr_free (w->line_start_cache); |
342 w->line_start_cache = 0; | 335 w->line_start_cache = 0; |
373 make_saved_buffer_point_cache (void) | 366 make_saved_buffer_point_cache (void) |
374 { | 367 { |
375 return make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, HASH_TABLE_EQ); | 368 return make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, HASH_TABLE_EQ); |
376 } | 369 } |
377 | 370 |
378 DEFINE_LRECORD_IMPLEMENTATION ("window", window, | 371 DEFINE_NODUMP_LISP_OBJECT ("window", window, |
379 0, /*dumpable-flag*/ | 372 mark_window, print_window, finalize_window, |
380 mark_window, print_window, finalize_window, | 373 0, 0, window_description, struct window); |
381 0, 0, window_description, struct window); | |
382 | 374 |
383 #define INIT_DISP_VARIABLE(field, initialization) \ | 375 #define INIT_DISP_VARIABLE(field, initialization) \ |
384 p->field[CURRENT_DISP] = initialization; \ | 376 p->field[CURRENT_DISP] = initialization; \ |
385 p->field[DESIRED_DISP] = initialization; \ | 377 p->field[DESIRED_DISP] = initialization; \ |
386 p->field[CMOTION_DISP] = initialization; | 378 p->field[CMOTION_DISP] = initialization; |
395 here because the window must have its frame pointer set or | 387 here because the window must have its frame pointer set or |
396 reset_face_cachels will fail. */ | 388 reset_face_cachels will fail. */ |
397 Lisp_Object | 389 Lisp_Object |
398 allocate_window (void) | 390 allocate_window (void) |
399 { | 391 { |
400 struct window *p = ALLOC_LCRECORD_TYPE (struct window, &lrecord_window); | 392 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window); |
401 Lisp_Object val = wrap_window (p); | 393 struct window *p = XWINDOW (obj); |
402 | 394 |
403 #define WINDOW_SLOT(slot) p->slot = Qnil; | 395 #define WINDOW_SLOT(slot) p->slot = Qnil; |
404 #include "winslots.h" | 396 #include "winslots.h" |
405 | 397 |
406 INIT_DISP_VARIABLE (start, Fmake_marker ()); | 398 INIT_DISP_VARIABLE (start, Fmake_marker ()); |
430 p->line_cache_last_updated = Qzero; | 422 p->line_cache_last_updated = Qzero; |
431 | 423 |
432 p->windows_changed = 1; | 424 p->windows_changed = 1; |
433 p->shadow_thickness_changed = 1; | 425 p->shadow_thickness_changed = 1; |
434 | 426 |
435 return val; | 427 return obj; |
436 } | 428 } |
437 #undef INIT_DISP_VARIABLE | 429 #undef INIT_DISP_VARIABLE |
438 | 430 |
439 /************************************************************************/ | 431 /************************************************************************/ |
440 /* Window mirror structure */ | 432 /* Window mirror structure */ |
529 return wrap_window_mirror (mir->next); | 521 return wrap_window_mirror (mir->next); |
530 else | 522 else |
531 return Qnil; | 523 return Qnil; |
532 } | 524 } |
533 | 525 |
534 DEFINE_LRECORD_IMPLEMENTATION ("window-mirror", window_mirror, | 526 DEFINE_NODUMP_INTERNAL_LISP_OBJECT ("window-mirror", window_mirror, |
535 0, /*dumpable-flag*/ | 527 mark_window_mirror, |
536 mark_window_mirror, internal_object_printer, | 528 window_mirror_description, |
537 0, 0, 0, window_mirror_description, | 529 struct window_mirror); |
538 struct window_mirror); | |
539 | 530 |
540 /* Create a new window mirror structure and associated redisplay | 531 /* Create a new window mirror structure and associated redisplay |
541 structs. */ | 532 structs. */ |
542 static struct window_mirror * | 533 static struct window_mirror * |
543 new_window_mirror (struct frame *f) | 534 new_window_mirror (struct frame *f) |
544 { | 535 { |
545 struct window_mirror *t = | 536 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window_mirror); |
546 ALLOC_LCRECORD_TYPE (struct window_mirror, &lrecord_window_mirror); | 537 struct window_mirror *t = XWINDOW_MIRROR (obj); |
547 | 538 |
548 t->frame = f; | 539 t->frame = f; |
549 t->current_display_lines = Dynarr_new (display_line); | 540 t->current_display_lines = Dynarr_new (display_line); |
550 t->desired_display_lines = Dynarr_new (display_line); | 541 t->desired_display_lines = Dynarr_new (display_line); |
551 | 542 |
634 redisplay structures. */ | 625 redisplay structures. */ |
635 static struct window_mirror * | 626 static struct window_mirror * |
636 find_window_mirror_internal (Lisp_Object win, struct window_mirror *rmir, | 627 find_window_mirror_internal (Lisp_Object win, struct window_mirror *rmir, |
637 struct window *w) | 628 struct window *w) |
638 { | 629 { |
639 for (; !NILP (win); win = XWINDOW (win)->next, rmir = rmir->next) | 630 for (; !NILP (win) && rmir; win = XWINDOW (win)->next, rmir = rmir->next) |
640 { | 631 { |
641 if (w == XWINDOW (win)) | 632 if (w == XWINDOW (win)) |
642 return rmir; | 633 return rmir; |
643 | 634 |
644 if (!NILP (XWINDOW (win)->vchild)) | 635 if (!NILP (XWINDOW (win)->vchild)) |
685 #ifdef HAVE_SCROLLBARS | 676 #ifdef HAVE_SCROLLBARS |
686 release_window_mirror_scrollbars (mir); | 677 release_window_mirror_scrollbars (mir); |
687 #endif | 678 #endif |
688 free_display_structs (mir); | 679 free_display_structs (mir); |
689 mir = mir->next; | 680 mir = mir->next; |
690 /* not worth calling free_managed_lcrecord() -- window mirrors | 681 /* not worth calling free_normal_lisp_object() -- window mirrors |
691 are not created that frequently and it's dangerous. we don't | 682 are not created that frequently and it's dangerous. we don't |
692 know for sure that there aren't other pointers around -- e.g. | 683 know for sure that there aren't other pointers around -- e.g. |
693 in a scrollbar instance. */ | 684 in a scrollbar instance. */ |
694 } | 685 } |
695 } | 686 } |
713 find_window_mirror (struct window *w) | 704 find_window_mirror (struct window *w) |
714 { | 705 { |
715 struct frame *f = XFRAME (w->frame); | 706 struct frame *f = XFRAME (w->frame); |
716 if (f->mirror_dirty) | 707 if (f->mirror_dirty) |
717 update_frame_window_mirror (f); | 708 update_frame_window_mirror (f); |
709 return find_window_mirror_internal (f->root_window, | |
710 XWINDOW_MIRROR (f->root_mirror), w); | |
711 } | |
712 | |
713 /* Given a real window, return its mirror structure, if it exists. | |
714 Don't do any updating. */ | |
715 static struct window_mirror * | |
716 find_window_mirror_maybe (struct window *w) | |
717 { | |
718 struct frame *f = XFRAME (w->frame); | |
719 if (!WINDOW_MIRRORP (f->root_mirror)) | |
720 return 0; | |
718 return find_window_mirror_internal (f->root_window, | 721 return find_window_mirror_internal (f->root_window, |
719 XWINDOW_MIRROR (f->root_mirror), w); | 722 XWINDOW_MIRROR (f->root_mirror), w); |
720 } | 723 } |
721 | 724 |
722 /***************************************************************************** | 725 /***************************************************************************** |
759 display_line_dynarr * | 762 display_line_dynarr * |
760 window_display_lines (struct window *w, int which) | 763 window_display_lines (struct window *w, int which) |
761 { | 764 { |
762 struct window_mirror *t; | 765 struct window_mirror *t; |
763 | 766 |
764 if (XFRAME (w->frame)->mirror_dirty) | |
765 update_frame_window_mirror (XFRAME (w->frame)); | |
766 t = find_window_mirror (w); | 767 t = find_window_mirror (w); |
767 assert (t); | 768 assert (t); |
768 | 769 |
769 if (which == CURRENT_DISP) | 770 if (which == CURRENT_DISP) |
770 return t->current_display_lines; | 771 return t->current_display_lines; |
782 struct buffer * | 783 struct buffer * |
783 window_display_buffer (struct window *w) | 784 window_display_buffer (struct window *w) |
784 { | 785 { |
785 struct window_mirror *t; | 786 struct window_mirror *t; |
786 | 787 |
787 if (XFRAME (w->frame)->mirror_dirty) | |
788 update_frame_window_mirror (XFRAME (w->frame)); | |
789 t = find_window_mirror (w); | 788 t = find_window_mirror (w); |
790 assert (t); | 789 assert (t); |
791 | 790 |
792 return t->buffer; | 791 return t->buffer; |
793 } | 792 } |
795 void | 794 void |
796 set_window_display_buffer (struct window *w, struct buffer *b) | 795 set_window_display_buffer (struct window *w, struct buffer *b) |
797 { | 796 { |
798 struct window_mirror *t; | 797 struct window_mirror *t; |
799 | 798 |
800 if (XFRAME (w->frame)->mirror_dirty) | |
801 update_frame_window_mirror (XFRAME (w->frame)); | |
802 t = find_window_mirror (w); | 799 t = find_window_mirror (w); |
803 assert (t); | 800 assert (t); |
804 | 801 |
805 t->buffer = b; | 802 t->buffer = b; |
806 } | 803 } |
1811 (window)) | 1808 (window)) |
1812 { | 1809 { |
1813 struct window *w = decode_window (window); | 1810 struct window *w = decode_window (window); |
1814 struct frame *f = XFRAME (w->frame); | 1811 struct frame *f = XFRAME (w->frame); |
1815 | 1812 |
1816 int left = | 1813 int left = w->pixel_left - FRAME_PANED_LEFT_EDGE (f); |
1817 w->pixel_left - FRAME_LEFT_BORDER_END (f) - FRAME_LEFT_GUTTER_BOUNDS (f); | 1814 int top = w->pixel_top - FRAME_PANED_TOP_EDGE (f); |
1818 int top = | |
1819 w->pixel_top - FRAME_TOP_BORDER_END (f) - FRAME_TOP_GUTTER_BOUNDS (f); | |
1820 | 1815 |
1821 return list4 (make_int (left), | 1816 return list4 (make_int (left), |
1822 make_int (top), | 1817 make_int (top), |
1823 make_int (left + w->pixel_width), | 1818 make_int (left + w->pixel_width), |
1824 make_int (top + w->pixel_height)); | 1819 make_int (top + w->pixel_height)); |
2144 window_unmap_subwindows (w); | 2139 window_unmap_subwindows (w); |
2145 | 2140 |
2146 /* Free the extra data structures attached to windows immediately so | 2141 /* Free the extra data structures attached to windows immediately so |
2147 they don't sit around consuming excess space. They will be | 2142 they don't sit around consuming excess space. They will be |
2148 reinitialized by the window-configuration code as necessary. */ | 2143 reinitialized by the window-configuration code as necessary. */ |
2149 finalize_window ((void *) w, 0); | 2144 finalize_window (wrap_window (w)); |
2150 | 2145 |
2151 /* Nobody should be accessing anything in this object any more, | 2146 /* Nobody should be accessing anything in this object any more, |
2152 and making them Qnil allows for better GC'ing in case a pointer | 2147 and making them Qnil allows for better GC'ing in case a pointer |
2153 to the dead window continues to hang around. Zero all other | 2148 to the dead window continues to hang around. Zero all other |
2154 structs in case someone tries to access something through them. | 2149 structs in case someone tries to access something through them. |
3872 } | 3867 } |
3873 | 3868 |
3874 static void | 3869 static void |
3875 make_dummy_parent (Lisp_Object window) | 3870 make_dummy_parent (Lisp_Object window) |
3876 { | 3871 { |
3877 Lisp_Object new_; | |
3878 struct window *o = XWINDOW (window); | 3872 struct window *o = XWINDOW (window); |
3879 struct window *p = ALLOC_LCRECORD_TYPE (struct window, &lrecord_window); | 3873 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window); |
3880 | 3874 struct window *p = XWINDOW (obj); |
3881 new_ = wrap_window (p); | 3875 |
3882 COPY_LCRECORD (p, o); | 3876 copy_lisp_object (obj, window); |
3883 | 3877 |
3884 /* Don't copy the pointers to the line start cache or the face | 3878 /* Don't copy the pointers to the line start cache or the face |
3885 instances. */ | 3879 instances. */ |
3886 p->line_start_cache = Dynarr_new (line_start_cache); | 3880 p->line_start_cache = Dynarr_new (line_start_cache); |
3887 #ifdef NEW_GC | 3881 #ifdef NEW_GC |
3897 #endif /* not NEW_GC */ | 3891 #endif /* not NEW_GC */ |
3898 p->subwindow_instance_cache = | 3892 p->subwindow_instance_cache = |
3899 make_image_instance_cache_hash_table (); | 3893 make_image_instance_cache_hash_table (); |
3900 | 3894 |
3901 /* Put new into window structure in place of window */ | 3895 /* Put new into window structure in place of window */ |
3902 replace_window (window, new_); | 3896 replace_window (window, obj); |
3903 | 3897 |
3904 o->next = Qnil; | 3898 o->next = Qnil; |
3905 o->prev = Qnil; | 3899 o->prev = Qnil; |
3906 o->vchild = Qnil; | 3900 o->vchild = Qnil; |
3907 o->hchild = Qnil; | 3901 o->hchild = Qnil; |
3908 o->parent = new_; | 3902 o->parent = obj; |
3909 | 3903 |
3910 p->start[CURRENT_DISP] = Qnil; | 3904 p->start[CURRENT_DISP] = Qnil; |
3911 p->start[DESIRED_DISP] = Qnil; | 3905 p->start[DESIRED_DISP] = Qnil; |
3912 p->start[CMOTION_DISP] = Qnil; | 3906 p->start[CMOTION_DISP] = Qnil; |
3913 p->pointm[CURRENT_DISP] = Qnil; | 3907 p->pointm[CURRENT_DISP] = Qnil; |
5166 MARK_WINDOWS_CHANGED (w); | 5160 MARK_WINDOWS_CHANGED (w); |
5167 } | 5161 } |
5168 | 5162 |
5169 #ifdef MEMORY_USAGE_STATS | 5163 #ifdef MEMORY_USAGE_STATS |
5170 | 5164 |
5165 struct window_mirror_stats | |
5166 { | |
5167 struct usage_stats u; | |
5168 /* Ancilliary non-lisp */ | |
5169 Bytecount redisplay_structs; | |
5170 #ifdef HAVE_SCROLLBARS | |
5171 /* Ancilliary Lisp */ | |
5172 Bytecount scrollbar; | |
5173 #endif | |
5174 }; | |
5175 | |
5171 struct window_stats | 5176 struct window_stats |
5172 { | 5177 { |
5173 int face; | 5178 struct usage_stats u; |
5174 int glyph; | 5179 /* Ancillary non-Lisp */ |
5180 Bytecount line_start; | |
5181 /* The next two: ancillary non-Lisp under old-GC, ancillary Lisp under | |
5182 NEW_GC */ | |
5183 Bytecount face; | |
5184 Bytecount glyph; | |
5185 /* The next two are copied out of the window mirror, which is an ancillary | |
5186 Lisp structure; the first is non-Lisp, the second Lisp, but from our | |
5187 perspective, they are both counted as Lisp */ | |
5188 Bytecount redisplay_structs; | |
5175 #ifdef HAVE_SCROLLBARS | 5189 #ifdef HAVE_SCROLLBARS |
5176 int scrollbar; | 5190 Bytecount scrollbar; |
5177 #endif | 5191 #endif |
5178 int line_start; | 5192 /* Remaining memory associated with window mirror (ancillary Lisp) */ |
5179 int other_redisplay; | 5193 Bytecount window_mirror; |
5180 int other; | |
5181 }; | 5194 }; |
5182 | 5195 |
5183 static void | 5196 static void |
5184 compute_window_mirror_usage (struct window_mirror *mir, | 5197 compute_window_mirror_usage (struct window_mirror *mir, |
5185 struct window_stats *stats, | 5198 struct window_mirror_stats *stats) |
5186 struct overhead_stats *ovstats) | 5199 { |
5187 { | 5200 stats->redisplay_structs = |
5188 if (!mir) | 5201 compute_display_line_dynarr_usage (mir->current_display_lines, &stats->u) |
5189 return; | 5202 + |
5190 stats->other += LISPOBJ_STORAGE_SIZE (mir, sizeof (*mir), ovstats); | 5203 compute_display_line_dynarr_usage (mir->desired_display_lines, &stats->u); |
5191 #ifdef HAVE_SCROLLBARS | 5204 #ifdef HAVE_SCROLLBARS |
5192 { | 5205 stats->scrollbar = |
5193 struct device *d = XDEVICE (FRAME_DEVICE (mir->frame)); | 5206 compute_all_scrollbar_instance_usage (mir->scrollbar_vertical_instance) + |
5194 | 5207 compute_all_scrollbar_instance_usage (mir->scrollbar_horizontal_instance); |
5195 stats->scrollbar += | |
5196 compute_scrollbar_instance_usage (d, mir->scrollbar_vertical_instance, | |
5197 ovstats); | |
5198 stats->scrollbar += | |
5199 compute_scrollbar_instance_usage (d, mir->scrollbar_horizontal_instance, | |
5200 ovstats); | |
5201 } | |
5202 #endif /* HAVE_SCROLLBARS */ | 5208 #endif /* HAVE_SCROLLBARS */ |
5203 stats->other_redisplay += | 5209 } |
5204 compute_display_line_dynarr_usage (mir->current_display_lines, ovstats); | 5210 |
5205 stats->other_redisplay += | 5211 |
5206 compute_display_line_dynarr_usage (mir->desired_display_lines, ovstats); | 5212 static void |
5213 window_mirror_memory_usage (Lisp_Object window_mirror, | |
5214 struct generic_usage_stats *gustats) | |
5215 { | |
5216 struct window_mirror_stats *stats = (struct window_mirror_stats *) gustats; | |
5217 | |
5218 compute_window_mirror_usage (XWINDOW_MIRROR (window_mirror), stats); | |
5207 } | 5219 } |
5208 | 5220 |
5209 static void | 5221 static void |
5210 compute_window_usage (struct window *w, struct window_stats *stats, | 5222 compute_window_usage (struct window *w, struct window_stats *stats, |
5211 struct overhead_stats *ovstats) | 5223 struct usage_stats *ustats) |
5212 { | 5224 { |
5213 xzero (*stats); | 5225 stats->line_start = |
5214 stats->other += LISPOBJ_STORAGE_SIZE (w, sizeof (*w), ovstats); | 5226 compute_line_start_cache_dynarr_usage (w->line_start_cache, ustats); |
5215 stats->face += compute_face_cachel_usage (w->face_cachels, ovstats); | 5227 stats->face = compute_face_cachel_usage (w->face_cachels, |
5216 stats->glyph += compute_glyph_cachel_usage (w->glyph_cachels, ovstats); | 5228 IF_OLD_GC (ustats)); |
5217 stats->line_start += | 5229 stats->glyph = compute_glyph_cachel_usage (w->glyph_cachels, |
5218 compute_line_start_cache_dynarr_usage (w->line_start_cache, ovstats); | 5230 IF_OLD_GC (ustats)); |
5219 compute_window_mirror_usage (find_window_mirror (w), stats, ovstats); | 5231 { |
5220 } | 5232 struct window_mirror *wm; |
5221 | 5233 |
5222 DEFUN ("window-memory-usage", Fwindow_memory_usage, 1, 1, 0, /* | 5234 wm = find_window_mirror_maybe (w); |
5223 Return stats about the memory usage of window WINDOW. | 5235 if (wm) |
5224 The values returned are in the form of an alist of usage types and byte | 5236 { |
5225 counts. The byte counts attempt to encompass all the memory used | 5237 struct generic_usage_stats gustats; |
5226 by the window (separate from the memory logically associated with a | 5238 struct window_mirror_stats *wmstats; |
5227 buffer or frame), including internal structures and any malloc() | 5239 Bytecount total; |
5228 overhead associated with them. In practice, the byte counts are | 5240 total = lisp_object_memory_usage_full (wrap_window_mirror (wm), |
5229 underestimated because certain memory usage is very hard to determine | 5241 NULL, NULL, NULL, &gustats); |
5230 \(e.g. the amount of memory used inside the Xt library or inside the | 5242 wmstats = (struct window_mirror_stats *) &gustats; |
5231 X server) and because there is other stuff that might logically | 5243 stats->redisplay_structs = wmstats->redisplay_structs; |
5232 be associated with a window, buffer, or frame (e.g. window configurations, | 5244 total -= stats->redisplay_structs; |
5233 glyphs) but should not obviously be included in the usage counts. | |
5234 | |
5235 Multiple slices of the total memory usage may be returned, separated | |
5236 by a nil. Each slice represents a particular view of the memory, a | |
5237 particular way of partitioning it into groups. Within a slice, there | |
5238 is no overlap between the groups of memory, and each slice collectively | |
5239 represents all the memory concerned. | |
5240 */ | |
5241 (window)) | |
5242 { | |
5243 struct window_stats stats; | |
5244 struct overhead_stats ovstats; | |
5245 Lisp_Object val = Qnil; | |
5246 | |
5247 CHECK_WINDOW (window); /* dead windows should be allowed, no? */ | |
5248 xzero (ovstats); | |
5249 compute_window_usage (XWINDOW (window), &stats, &ovstats); | |
5250 | |
5251 val = acons (Qface_cache, make_int (stats.face), val); | |
5252 val = acons (Qglyph_cache, make_int (stats.glyph), val); | |
5253 #ifdef HAVE_SCROLLBARS | 5245 #ifdef HAVE_SCROLLBARS |
5254 val = acons (Qscrollbar_instances, make_int (stats.scrollbar), val); | 5246 stats->scrollbar = wmstats->scrollbar; |
5247 total -= stats->scrollbar; | |
5255 #endif | 5248 #endif |
5256 val = acons (Qline_start_cache, make_int (stats.line_start), val); | 5249 stats->window_mirror = total; |
5257 val = acons (Qother_redisplay, make_int (stats.other_redisplay), val); | 5250 } |
5258 val = acons (Qother, make_int (stats.other), val); | 5251 } |
5259 val = Fcons (Qnil, val); | 5252 } |
5260 val = acons (Qactually_requested, make_int (ovstats.was_requested), val); | 5253 |
5261 val = acons (Qmalloc_overhead, make_int (ovstats.malloc_overhead), val); | 5254 static void |
5262 val = acons (Qdynarr_overhead, make_int (ovstats.dynarr_overhead), val); | 5255 window_memory_usage (Lisp_Object window, struct generic_usage_stats *gustats) |
5263 | 5256 { |
5264 return Fnreverse (val); | 5257 struct window_stats *stats = (struct window_stats *) gustats; |
5258 | |
5259 compute_window_usage (XWINDOW (window), stats, &stats->u); | |
5265 } | 5260 } |
5266 | 5261 |
5267 #endif /* MEMORY_USAGE_STATS */ | 5262 #endif /* MEMORY_USAGE_STATS */ |
5263 | |
5264 | |
5268 | 5265 |
5269 /* Mark all subwindows of a window as deleted. The argument | 5266 /* Mark all subwindows of a window as deleted. The argument |
5270 W is actually the subwindow tree of the window in question. */ | 5267 W is actually the subwindow tree of the window in question. */ |
5271 | 5268 |
5272 void | 5269 void |
5416 { | 5413 { |
5417 Lisp_Object buffer = XWINDOW (window)->buffer; | 5414 Lisp_Object buffer = XWINDOW (window)->buffer; |
5418 if (!NILP (buffer) && BUFFERP (buffer)) | 5415 if (!NILP (buffer) && BUFFERP (buffer)) |
5419 stderr_out (" on %s", XSTRING_DATA (XBUFFER (buffer)->name)); | 5416 stderr_out (" on %s", XSTRING_DATA (XBUFFER (buffer)->name)); |
5420 } | 5417 } |
5421 stderr_out (" 0x%x>", XWINDOW (window)->header.uid); | 5418 stderr_out (" 0x%x>", LISP_OBJECT_UID (window)); |
5422 | 5419 |
5423 while (!NILP (child)) | 5420 while (!NILP (child)) |
5424 { | 5421 { |
5425 debug_print_window (child, level + 1); | 5422 debug_print_window (child, level + 1); |
5426 child = Fwindow_next_child (child); | 5423 child = Fwindow_next_child (child); |
5440 /************************************************************************/ | 5437 /************************************************************************/ |
5441 /* initialization */ | 5438 /* initialization */ |
5442 /************************************************************************/ | 5439 /************************************************************************/ |
5443 | 5440 |
5444 void | 5441 void |
5442 window_objects_create (void) | |
5443 { | |
5444 #ifdef MEMORY_USAGE_STATS | |
5445 OBJECT_HAS_METHOD (window, memory_usage); | |
5446 OBJECT_HAS_METHOD (window_mirror, memory_usage); | |
5447 #endif | |
5448 } | |
5449 | |
5450 void | |
5445 syms_of_window (void) | 5451 syms_of_window (void) |
5446 { | 5452 { |
5447 INIT_LRECORD_IMPLEMENTATION (window); | 5453 INIT_LISP_OBJECT (window); |
5448 INIT_LRECORD_IMPLEMENTATION (window_mirror); | 5454 INIT_LISP_OBJECT (window_mirror); |
5449 #ifdef NEW_GC | 5455 #ifdef NEW_GC |
5450 INIT_LRECORD_IMPLEMENTATION (face_cachel); | 5456 INIT_LISP_OBJECT (face_cachel); |
5451 INIT_LRECORD_IMPLEMENTATION (face_cachel_dynarr); | 5457 INIT_LISP_OBJECT (face_cachel_dynarr); |
5452 INIT_LRECORD_IMPLEMENTATION (glyph_cachel); | 5458 INIT_LISP_OBJECT (glyph_cachel); |
5453 INIT_LRECORD_IMPLEMENTATION (glyph_cachel_dynarr); | 5459 INIT_LISP_OBJECT (glyph_cachel_dynarr); |
5454 #endif /* NEW_GC */ | 5460 #endif /* NEW_GC */ |
5455 | 5461 |
5456 DEFSYMBOL (Qwindowp); | 5462 DEFSYMBOL (Qwindowp); |
5457 DEFSYMBOL (Qwindow_live_p); | 5463 DEFSYMBOL (Qwindow_live_p); |
5458 DEFSYMBOL (Qdisplay_buffer); | 5464 DEFSYMBOL (Qdisplay_buffer); |
5462 DEFSYMBOL (Qglyph_cache); | 5468 DEFSYMBOL (Qglyph_cache); |
5463 DEFSYMBOL (Qline_start_cache); | 5469 DEFSYMBOL (Qline_start_cache); |
5464 #ifdef HAVE_SCROLLBARS | 5470 #ifdef HAVE_SCROLLBARS |
5465 DEFSYMBOL (Qscrollbar_instances); | 5471 DEFSYMBOL (Qscrollbar_instances); |
5466 #endif | 5472 #endif |
5467 DEFSYMBOL (Qother_redisplay); | 5473 DEFSYMBOL (Qredisplay_structs); |
5468 /* Qother in general.c */ | |
5469 #endif | 5474 #endif |
5470 | 5475 |
5471 DEFSYMBOL (Qtruncate_partial_width_windows); | 5476 DEFSYMBOL (Qtruncate_partial_width_windows); |
5472 DEFSYMBOL (Qcurrent_window_configuration); | 5477 DEFSYMBOL (Qcurrent_window_configuration); |
5473 DEFSYMBOL (Qset_window_configuration); | 5478 DEFSYMBOL (Qset_window_configuration); |
5541 DEFSUBR (Fscroll_right); | 5546 DEFSUBR (Fscroll_right); |
5542 DEFSUBR (Fother_window_for_scrolling); | 5547 DEFSUBR (Fother_window_for_scrolling); |
5543 DEFSUBR (Fscroll_other_window); | 5548 DEFSUBR (Fscroll_other_window); |
5544 DEFSUBR (Fcenter_to_window_line); | 5549 DEFSUBR (Fcenter_to_window_line); |
5545 DEFSUBR (Fmove_to_window_line); | 5550 DEFSUBR (Fmove_to_window_line); |
5546 #ifdef MEMORY_USAGE_STATS | |
5547 DEFSUBR (Fwindow_memory_usage); | |
5548 #endif | |
5549 DEFSUBR (Fcurrent_pixel_column); | 5551 DEFSUBR (Fcurrent_pixel_column); |
5550 DEFSUBR (Fcurrent_pixel_row); | 5552 DEFSUBR (Fcurrent_pixel_row); |
5551 } | 5553 } |
5552 | 5554 |
5553 void | 5555 void |
5559 } | 5561 } |
5560 | 5562 |
5561 void | 5563 void |
5562 vars_of_window (void) | 5564 vars_of_window (void) |
5563 { | 5565 { |
5566 #ifdef MEMORY_USAGE_STATS | |
5567 Lisp_Object l; | |
5568 | |
5569 l = listu (Qline_start_cache, | |
5570 #ifdef NEW_GC | |
5571 Qt, | |
5572 #endif | |
5573 Qface_cache, Qglyph_cache, | |
5574 #ifndef NEW_GC | |
5575 Qt, | |
5576 #endif | |
5577 Qredisplay_structs, | |
5578 #ifdef HAVE_SCROLLBARS | |
5579 Qscrollbar_instances, | |
5580 #endif | |
5581 intern ("window-mirror"), | |
5582 Qunbound); | |
5583 | |
5584 OBJECT_HAS_PROPERTY (window, memusage_stats_list, l); | |
5585 | |
5586 l = listu (Qredisplay_structs, | |
5587 #ifdef HAVE_SCROLLBARS | |
5588 Qt, Qscrollbar_instances, | |
5589 #endif | |
5590 Qunbound); | |
5591 OBJECT_HAS_PROPERTY (window_mirror, memusage_stats_list, l); | |
5592 #endif /* MEMORY_USAGE_STATS */ | |
5593 | |
5564 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* | 5594 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* |
5565 *Non-nil means to scroll if point lands on a line which is clipped. | 5595 *Non-nil means to scroll if point lands on a line which is clipped. |
5566 */ ); | 5596 */ ); |
5567 scroll_on_clipped_lines = 1; | 5597 scroll_on_clipped_lines = 1; |
5568 | 5598 |