comparison src/window.c @ 448:3078fd1074e8 r21-2-39

Import from CVS: tag r21-2-39
author cvs
date Mon, 13 Aug 2007 11:38:25 +0200
parents 576fb035e263
children 98528da0b7fc
comparison
equal deleted inserted replaced
447:4fc5f13f3bd3 448:3078fd1074e8
2130 minibuffer does not count, only windows from WINDOW's frame count. 2130 minibuffer does not count, only windows from WINDOW's frame count.
2131 2131
2132 By default, only the windows in the selected frame are considered. 2132 By default, only the windows in the selected frame are considered.
2133 The optional argument WHICH-FRAMES changes this behavior: 2133 The optional argument WHICH-FRAMES changes this behavior:
2134 WHICH-FRAMES = `visible' means search windows on all visible frames. 2134 WHICH-FRAMES = `visible' means search windows on all visible frames.
2135 WHICH-FRAMES = 0 means search windows on all visible and iconified frames. 2135 WHICH-FRAMES = 0 means search windows on all visible and iconified frames.
2136 WHICH-FRAMES = t means search windows on all frames including invisible frames. 2136 WHICH-FRAMES = t means search windows on all frames including invisible frames.
2137 WHICH-FRAMES = a frame means search only windows on that frame. 2137 WHICH-FRAMES = a frame means search only windows on that frame.
2138 Anything else means restrict to the selected frame. 2138 Anything else means restrict to the selected frame.
2139 2139
2140 The optional fourth argument WHICH-DEVICES further clarifies on which 2140 The optional fourth argument WHICH-DEVICES further clarifies on which
2276 the minibuffer does not count, only windows from WINDOW's frame count. 2276 the minibuffer does not count, only windows from WINDOW's frame count.
2277 2277
2278 By default, only the windows in the selected frame are considered. 2278 By default, only the windows in the selected frame are considered.
2279 The optional argument WHICH-FRAMES changes this behavior: 2279 The optional argument WHICH-FRAMES changes this behavior:
2280 WHICH-FRAMES = `visible' means search windows on all visible frames. 2280 WHICH-FRAMES = `visible' means search windows on all visible frames.
2281 WHICH-FRAMES = 0 means search windows on all visible and iconified frames. 2281 WHICH-FRAMES = 0 means search windows on all visible and iconified frames.
2282 WHICH-FRAMES = t means search windows on all frames including invisible frames. 2282 WHICH-FRAMES = t means search windows on all frames including invisible frames.
2283 WHICH-FRAMES = a frame means search only windows on that frame. 2283 WHICH-FRAMES = a frame means search only windows on that frame.
2284 Anything else means restrict to the selected frame. 2284 Anything else means restrict to the selected frame.
2285 2285
2286 The optional fourth argument WHICH-DEVICES further clarifies on which 2286 The optional fourth argument WHICH-DEVICES further clarifies on which
2479 A negative COUNT moves in the opposite order. 2479 A negative COUNT moves in the opposite order.
2480 2480
2481 By default, only the windows in the selected frame are considered. 2481 By default, only the windows in the selected frame are considered.
2482 The optional argument WHICH-FRAMES changes this behavior: 2482 The optional argument WHICH-FRAMES changes this behavior:
2483 WHICH-FRAMES = `visible' means search windows on all visible frames. 2483 WHICH-FRAMES = `visible' means search windows on all visible frames.
2484 WHICH-FRAMES = 0 means search windows on all visible and iconified frames. 2484 WHICH-FRAMES = 0 means search windows on all visible and iconified frames.
2485 WHICH-FRAMES = t means search windows on all frames including invisible frames. 2485 WHICH-FRAMES = t means search windows on all frames including invisible frames.
2486 WHICH-FRAMES = a frame means search only windows on that frame. 2486 WHICH-FRAMES = a frame means search only windows on that frame.
2487 Anything else means restrict to the selected frame. 2487 Anything else means restrict to the selected frame.
2488 2488
2489 The optional argument WHICH-DEVICES further clarifies on which devices 2489 The optional argument WHICH-DEVICES further clarifies on which devices
2534 GET_BUFFER_WINDOW, /* Arg is buffer */ 2534 GET_BUFFER_WINDOW, /* Arg is buffer */
2535 GET_LRU_WINDOW, /* Arg is t for full-width windows only */ 2535 GET_LRU_WINDOW, /* Arg is t for full-width windows only */
2536 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */ 2536 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */
2537 DELETE_BUFFER_WINDOWS, /* Arg is buffer */ 2537 DELETE_BUFFER_WINDOWS, /* Arg is buffer */
2538 GET_LARGEST_WINDOW, 2538 GET_LARGEST_WINDOW,
2539 UNSHOW_BUFFER, /* Arg is buffer */
2540 GET_BUFFER_WINDOW_COUNT, /* Arg is buffer */ 2539 GET_BUFFER_WINDOW_COUNT, /* Arg is buffer */
2541 GET_BUFFER_MRU_WINDOW /* Arg is buffer */ 2540 GET_BUFFER_MRU_WINDOW /* Arg is buffer */
2542 }; 2541 };
2543 2542
2544 static Lisp_Object 2543 static Lisp_Object
2547 int mini, 2546 int mini,
2548 Lisp_Object which_frames, 2547 Lisp_Object which_frames,
2549 int dedicated_too, 2548 int dedicated_too,
2550 Lisp_Object which_devices) 2549 Lisp_Object which_devices)
2551 { 2550 {
2552 /* This function can GC if type == DELETE_BUFFER_WINDOWS or UNSHOW_BUFFER */ 2551 /* This function can GC if type == DELETE_BUFFER_WINDOWS */
2553 Lisp_Object w; 2552 Lisp_Object w;
2554 Lisp_Object best_window = Qnil; 2553 Lisp_Object best_window = Qnil;
2555 Lisp_Object next_window; 2554 Lisp_Object next_window;
2556 Lisp_Object last_window; 2555 Lisp_Object last_window;
2557 struct frame *frame; 2556 struct frame *frame;
2619 2618
2620 best_window = Qnil; 2619 best_window = Qnil;
2621 for (;;) 2620 for (;;)
2622 { 2621 {
2623 struct window *p = XWINDOW (w); 2622 struct window *p = XWINDOW (w);
2624 struct frame *w_frame = XFRAME (WINDOW_FRAME (p));
2625 2623
2626 /* Pick the next window now, since some operations will delete 2624 /* Pick the next window now, since some operations will delete
2627 the current window. */ 2625 the current window. */
2628 next_window = Fnext_window (w, mini ? Qt : Qnil, frame_arg, device); 2626 next_window = Fnext_window (w, mini ? Qt : Qnil, frame_arg, device);
2629 2627
2769 best_window = w; 2767 best_window = w;
2770 } 2768 }
2771 break; 2769 break;
2772 } 2770 }
2773 2771
2774 case UNSHOW_BUFFER:
2775 {
2776 if (EQ (p->buffer, obj))
2777 {
2778 /* Find another buffer to show in this window. */
2779 Lisp_Object another_buffer =
2780 Fother_buffer (obj, Qnil, Qnil);
2781 if (NILP (another_buffer))
2782 another_buffer
2783 = Fget_buffer_create (QSscratch);
2784 /* If this window is dedicated, and in a frame
2785 of its own, kill the frame. */
2786 if (EQ (w, FRAME_ROOT_WINDOW (w_frame))
2787 && !NILP (p->dedicated)
2788 && other_visible_frames (w_frame))
2789 {
2790 /* Skip the other windows on this frame.
2791 There might be one, the minibuffer! */
2792 if (! EQ (w, last_window))
2793 while (w_frame == XFRAME (WINDOW_FRAME
2794 (XWINDOW (next_window))))
2795 {
2796 /* As we go, check for the end of the
2797 loop. We mustn't start going
2798 around a second time. */
2799 if (EQ (next_window, last_window))
2800 {
2801 last_window = w;
2802 break;
2803 }
2804 next_window = Fnext_window (next_window,
2805 mini ? Qt : Qnil,
2806 frame_arg, Qt);
2807 }
2808 /* Now we can safely delete the frame. */
2809 delete_frame_internal (XFRAME (WINDOW_FRAME (p)),
2810 0, 0, 0);
2811 }
2812 else
2813 {
2814 /* Otherwise show a different buffer in the
2815 window. */
2816 p->dedicated = Qnil;
2817 Fset_window_buffer (w, another_buffer, Qnil);
2818 if (EQ (w, Fselected_window (Qnil)))
2819 Fset_buffer (p->buffer);
2820 }
2821 }
2822 break;
2823 }
2824
2825 default: 2772 default:
2826 abort (); 2773 abort ();
2827 } 2774 }
2828 2775
2829 if (EQ (w, last_window)) 2776 if (EQ (w, last_window))
3097 window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, 3044 window_loop (DELETE_BUFFER_WINDOWS, buffer, 0,
3098 which_frames, 0, which_devices); 3045 which_frames, 0, which_devices);
3099 return Qnil; 3046 return Qnil;
3100 } 3047 }
3101 3048
3049 static Lisp_Object
3050 list_windows (struct window *w, Lisp_Object value)
3051 {
3052 for (;;)
3053 {
3054 if (!NILP (w->hchild))
3055 value = list_windows (XWINDOW (w->hchild), value);
3056 else if (!NILP (w->vchild))
3057 value = list_windows (XWINDOW (w->vchild), value);
3058 else
3059 {
3060 Lisp_Object window;
3061 XSETWINDOW (window, w);
3062 value = Fcons (window, value);
3063 }
3064 if (NILP (w->next))
3065 break;
3066 w = XWINDOW (w->next);
3067 }
3068 return value;
3069 }
3070
3071 static Lisp_Object
3072 list_all_windows (Lisp_Object frame_spec, Lisp_Object device_spec)
3073 {
3074 Lisp_Object devcons, concons;
3075 Lisp_Object retval = Qnil;
3076
3077 DEVICE_LOOP_NO_BREAK (devcons, concons)
3078 {
3079 Lisp_Object frame_list, the_window;
3080 Lisp_Object device, tail;
3081
3082 device = XCAR (devcons);
3083 frame_list = DEVICE_FRAME_LIST (XDEVICE (device));
3084
3085 LIST_LOOP (tail, frame_list)
3086 {
3087 if ((NILP (frame_spec)
3088 && !EQ (XCAR (tail), DEVICE_SELECTED_FRAME (XDEVICE (device))))
3089 || (EQ (frame_spec, Qvisible)
3090 && !FRAME_VISIBLE_P (XFRAME (XCAR (tail))))
3091 || (FRAMEP (frame_spec)
3092 && !EQ (frame_spec, XCAR (tail)))
3093 || (!NILP (frame_spec)
3094 && !device_matches_device_spec (device,
3095 NILP (device_spec) ?
3096 Vselected_console :
3097 device_spec)))
3098 continue;
3099 the_window = FRAME_ROOT_WINDOW (XFRAME (XCAR (tail)));
3100 retval = list_windows (XWINDOW (the_window), retval);
3101 }
3102 }
3103 return Fnreverse (retval);
3104 }
3105
3102 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows, 1, 3, 3106 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows, 1, 3,
3103 "bReplace buffer in windows: ", /* 3107 "bReplace buffer in windows: ", /*
3104 Replace BUFFER with some other buffer in all windows showing it. 3108 Replace BUFFER with some other buffer in all windows showing it.
3105 3109
3106 Optional second argument WHICH-FRAMES controls which frames are affected. 3110 Optional second argument WHICH-FRAMES controls which frames are affected.
3122 Any other non-nil value means search all devices. 3126 Any other non-nil value means search all devices.
3123 */ 3127 */
3124 (buffer, which_frames, which_devices)) 3128 (buffer, which_frames, which_devices))
3125 { 3129 {
3126 /* This function can GC */ 3130 /* This function can GC */
3127 buffer = Fget_buffer (buffer); 3131 Lisp_Object window_list;
3128 CHECK_BUFFER (buffer); 3132 Lisp_Object tail;
3129 3133 struct gcpro gcpro1, gcpro2;
3130 /* WHICH-FRAMES values t and nil mean the opposite of what 3134
3131 window_loop expects. */
3132 if (EQ (which_frames, Qnil)) 3135 if (EQ (which_frames, Qnil))
3133 which_frames = Qt; 3136 which_frames = Qt;
3134 else if (EQ (which_frames, Qt)) 3137 else if (EQ (which_frames, Qt))
3135 which_frames = Qnil; 3138 which_frames = Qnil;
3136 3139 window_list = list_all_windows (which_frames, which_devices);
3137 /* Ignore dedicated windows. */ 3140
3138 window_loop (UNSHOW_BUFFER, buffer, 0, which_frames, 0, which_devices); 3141 buffer = Fget_buffer (buffer);
3142 CHECK_BUFFER (buffer);
3143
3144 GCPRO2 (window_list, buffer);
3145 LIST_LOOP (tail, window_list)
3146 {
3147 Lisp_Object window = XCAR (tail);
3148 if (!MINI_WINDOW_P (XWINDOW (window))
3149 && EQ (XWINDOW (window)->buffer, buffer))
3150 {
3151 Lisp_Object another_buffer = Fother_buffer (buffer, Qnil, Qnil);
3152 Lisp_Object frame = WINDOW_FRAME (XWINDOW (window));
3153 if (NILP (another_buffer))
3154 another_buffer = Fget_buffer_create (QSscratch);
3155 if (!NILP (XWINDOW (window)->dedicated)
3156 && EQ (window,
3157 FRAME_ROOT_WINDOW (XFRAME (frame)))
3158 && other_visible_frames (XFRAME (frame)))
3159 {
3160 delete_frame_internal (XFRAME (frame), 0, 0, 0); /* GC */
3161 }
3162 else
3163 {
3164 Fset_window_buffer (window, another_buffer, Qnil);
3165 if (EQ (window, Fselected_window (Qnil)))
3166 Fset_buffer (XWINDOW (window)->buffer);
3167 }
3168 }
3169 }
3170 UNGCPRO;
3139 return Qnil; 3171 return Qnil;
3140 } 3172 }
3141 3173
3142 /* The smallest acceptable dimensions for a window. Anything smaller 3174 /* The smallest acceptable dimensions for a window. Anything smaller
3143 might crash Emacs. */ 3175 might crash Emacs. */
3350 */ 3382 */
3351 (window, buffer, norecord)) 3383 (window, buffer, norecord))
3352 { 3384 {
3353 Lisp_Object tem; 3385 Lisp_Object tem;
3354 struct window *w = decode_window (window); 3386 struct window *w = decode_window (window);
3387 int old_buffer_local_face_property = 0;
3355 3388
3356 buffer = Fget_buffer (buffer); 3389 buffer = Fget_buffer (buffer);
3357 CHECK_BUFFER (buffer); 3390 CHECK_BUFFER (buffer);
3358 3391
3359 if (!BUFFER_LIVE_P (XBUFFER (buffer))) 3392 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
3381 { 3414 {
3382 if (!NILP (w->dedicated) && !EQ (tem, buffer)) 3415 if (!NILP (w->dedicated) && !EQ (tem, buffer))
3383 error ("Window is dedicated to buffer %s", 3416 error ("Window is dedicated to buffer %s",
3384 XSTRING_DATA (XBUFFER (tem)->name)); 3417 XSTRING_DATA (XBUFFER (tem)->name));
3385 3418
3419 old_buffer_local_face_property =
3420 XBUFFER (w->buffer)->buffer_local_face_property;
3386 unshow_buffer (w); 3421 unshow_buffer (w);
3387 } 3422 }
3388 3423
3389 w->buffer = buffer; 3424 w->buffer = buffer;
3390 w->window_end_pos[CURRENT_DISP] = 0; 3425 w->window_end_pos[CURRENT_DISP] = 0;
3402 marker_position (w->start[CURRENT_DISP])); 3437 marker_position (w->start[CURRENT_DISP]));
3403 w->force_start = 0; /* Lucid fix */ 3438 w->force_start = 0; /* Lucid fix */
3404 SET_LAST_MODIFIED (w, 1); 3439 SET_LAST_MODIFIED (w, 1);
3405 SET_LAST_FACECHANGE (w); 3440 SET_LAST_FACECHANGE (w);
3406 MARK_WINDOWS_CHANGED (w); 3441 MARK_WINDOWS_CHANGED (w);
3442 {
3443 int new_buffer_local_face_property =
3444 XBUFFER (w->buffer)->buffer_local_face_property;
3445
3446 if (new_buffer_local_face_property
3447 || new_buffer_local_face_property != old_buffer_local_face_property)
3448 MARK_WINDOW_FACES_CHANGED (w);
3449 }
3407 recompute_all_cached_specifiers_in_window (w); 3450 recompute_all_cached_specifiers_in_window (w);
3408 if (EQ (window, Fselected_window (Qnil))) 3451 if (EQ (window, Fselected_window (Qnil)))
3409 { 3452 {
3410 if (NILP (norecord)) 3453 if (NILP (norecord))
3411 Frecord_buffer (buffer); 3454 Frecord_buffer (buffer);
3647 window_char_height (o, 1) - csize); 3690 window_char_height (o, 1) - csize);
3648 if (NILP (o->parent) 3691 if (NILP (o->parent)
3649 || NILP (XWINDOW (o->parent)->vchild)) 3692 || NILP (XWINDOW (o->parent)->vchild))
3650 { 3693 {
3651 make_dummy_parent (window); 3694 make_dummy_parent (window);
3695 #if 0
3696 /* #### I can't understand why you have to reset face
3697 cachels here. This can cause crash so let's disable it
3698 and see the difference. See redisplay-tests.el --yh */
3652 reset_face_cachels (XWINDOW (window)); 3699 reset_face_cachels (XWINDOW (window));
3700 #endif
3653 new = o->parent; 3701 new = o->parent;
3654 XWINDOW (new)->vchild = window; 3702 XWINDOW (new)->vchild = window;
3655 XFRAME (o->frame)->mirror_dirty = 1; 3703 XFRAME (o->frame)->mirror_dirty = 1;
3656 } 3704 }
3657 } 3705 }
3664 window_char_width (o, 0) - csize); 3712 window_char_width (o, 0) - csize);
3665 if (NILP (o->parent) 3713 if (NILP (o->parent)
3666 || NILP (XWINDOW (o->parent)->hchild)) 3714 || NILP (XWINDOW (o->parent)->hchild))
3667 { 3715 {
3668 make_dummy_parent (window); 3716 make_dummy_parent (window);
3717 #if 0
3718 /* #### See above. */
3669 reset_face_cachels (XWINDOW (window)); 3719 reset_face_cachels (XWINDOW (window));
3720 #endif
3670 new = o->parent; 3721 new = o->parent;
3671 XWINDOW (new)->hchild = window; 3722 XWINDOW (new)->hchild = window;
3672 XFRAME (o->frame)->mirror_dirty = 1; 3723 XFRAME (o->frame)->mirror_dirty = 1;
3673 } 3724 }
3674 } 3725 }