X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fwindow.c;h=ccddef81ba797bf091733b68dfe28cc886374faf;hb=112b4eb6a71cd613a534b4246b4cc024ed9bf22e;hp=18ee8e4f13cb50d9c2c784c7544133901f614810;hpb=98a6e4055a1fa624c592ac06f79287d55196ca37;p=chise%2Fxemacs-chise.git- diff --git a/src/window.c b/src/window.c index 18ee8e4..ccddef8 100644 --- a/src/window.c +++ b/src/window.c @@ -111,14 +111,14 @@ Lisp_Object Vtemp_buffer_show_function; Lisp_Object Vtemp_buffer_show_hook; /* If a window gets smaller than either of these, it is removed. */ -int window_min_height; -int window_min_width; +Fixnum window_min_height; +Fixnum window_min_width; /* Hook run at end of temp_output_buffer_show. */ Lisp_Object Qtemp_buffer_show_hook; /* Number of lines of continuity in scrolling by screenfuls. */ -int next_screen_context_lines; +Fixnum next_screen_context_lines; /* List of freed window configurations with 1 - 10 windows. */ static Lisp_Object Vwindow_configuration_free_list[10]; @@ -281,9 +281,8 @@ allocate_window (void) p->face_cachels = Dynarr_new (face_cachel); p->glyph_cachels = Dynarr_new (glyph_cachel); p->line_start_cache = Dynarr_new (line_start_cache); - p->subwindow_instance_cache = make_lisp_hash_table (30, - HASH_TABLE_KEY_VALUE_WEAK, - HASH_TABLE_EQ); + p->subwindow_instance_cache = make_image_instance_cache_hash_table (); + p->line_cache_last_updated = Qzero; INIT_DISP_VARIABLE (last_point_x, 0); INIT_DISP_VARIABLE (last_point_y, 0); @@ -2132,7 +2131,7 @@ minibuffer does not count, only windows from WINDOW's frame count. By default, only the windows in the selected frame are considered. The optional argument WHICH-FRAMES changes this behavior: WHICH-FRAMES = `visible' means search windows on all visible frames. -WHICH-FRAMES = 0 means search windows on all visible and iconified frames. +WHICH-FRAMES = 0 means search windows on all visible and iconified frames. WHICH-FRAMES = t means search windows on all frames including invisible frames. WHICH-FRAMES = a frame means search only windows on that frame. Anything else means restrict to the selected frame. @@ -2278,7 +2277,7 @@ the minibuffer does not count, only windows from WINDOW's frame count. By default, only the windows in the selected frame are considered. The optional argument WHICH-FRAMES changes this behavior: WHICH-FRAMES = `visible' means search windows on all visible frames. -WHICH-FRAMES = 0 means search windows on all visible and iconified frames. +WHICH-FRAMES = 0 means search windows on all visible and iconified frames. WHICH-FRAMES = t means search windows on all frames including invisible frames. WHICH-FRAMES = a frame means search only windows on that frame. Anything else means restrict to the selected frame. @@ -2481,7 +2480,7 @@ A negative COUNT moves in the opposite order. By default, only the windows in the selected frame are considered. The optional argument WHICH-FRAMES changes this behavior: WHICH-FRAMES = `visible' means search windows on all visible frames. -WHICH-FRAMES = 0 means search windows on all visible and iconified frames. +WHICH-FRAMES = 0 means search windows on all visible and iconified frames. WHICH-FRAMES = t means search windows on all frames including invisible frames. WHICH-FRAMES = a frame means search only windows on that frame. Anything else means restrict to the selected frame. @@ -2536,7 +2535,6 @@ enum window_loop DELETE_OTHER_WINDOWS, /* Arg is window not to delete */ DELETE_BUFFER_WINDOWS, /* Arg is buffer */ GET_LARGEST_WINDOW, - UNSHOW_BUFFER, /* Arg is buffer */ GET_BUFFER_WINDOW_COUNT, /* Arg is buffer */ GET_BUFFER_MRU_WINDOW /* Arg is buffer */ }; @@ -2549,7 +2547,7 @@ window_loop (enum window_loop type, int dedicated_too, Lisp_Object which_devices) { - /* This function can GC if type == DELETE_BUFFER_WINDOWS or UNSHOW_BUFFER */ + /* This function can GC if type == DELETE_BUFFER_WINDOWS */ Lisp_Object w; Lisp_Object best_window = Qnil; Lisp_Object next_window; @@ -2621,7 +2619,6 @@ window_loop (enum window_loop type, for (;;) { struct window *p = XWINDOW (w); - struct frame *w_frame = XFRAME (WINDOW_FRAME (p)); /* Pick the next window now, since some operations will delete the current window. */ @@ -2771,57 +2768,6 @@ window_loop (enum window_loop type, break; } - case UNSHOW_BUFFER: - { - if (EQ (p->buffer, obj)) - { - /* Find another buffer to show in this window. */ - Lisp_Object another_buffer = - Fother_buffer (obj, Qnil, Qnil); - if (NILP (another_buffer)) - another_buffer - = Fget_buffer_create (QSscratch); - /* If this window is dedicated, and in a frame - of its own, kill the frame. */ - if (EQ (w, FRAME_ROOT_WINDOW (w_frame)) - && !NILP (p->dedicated) - && other_visible_frames (w_frame)) - { - /* Skip the other windows on this frame. - There might be one, the minibuffer! */ - if (! EQ (w, last_window)) - while (w_frame == XFRAME (WINDOW_FRAME - (XWINDOW (next_window)))) - { - /* As we go, check for the end of the - loop. We mustn't start going - around a second time. */ - if (EQ (next_window, last_window)) - { - last_window = w; - break; - } - next_window = Fnext_window (next_window, - mini ? Qt : Qnil, - frame_arg, Qt); - } - /* Now we can safely delete the frame. */ - delete_frame_internal (XFRAME (WINDOW_FRAME (p)), - 0, 0, 0); - } - else - { - /* Otherwise show a different buffer in the - window. */ - p->dedicated = Qnil; - Fset_window_buffer (w, another_buffer, Qnil); - if (EQ (w, Fselected_window (Qnil))) - Fset_buffer (p->buffer); - } - } - break; - } - default: abort (); } @@ -3099,6 +3045,63 @@ Any other non-nil value means search all devices. return Qnil; } +static Lisp_Object +list_windows (struct window *w, Lisp_Object value) +{ + for (;;) + { + if (!NILP (w->hchild)) + value = list_windows (XWINDOW (w->hchild), value); + else if (!NILP (w->vchild)) + value = list_windows (XWINDOW (w->vchild), value); + else + { + Lisp_Object window; + XSETWINDOW (window, w); + value = Fcons (window, value); + } + if (NILP (w->next)) + break; + w = XWINDOW (w->next); + } + return value; +} + +static Lisp_Object +list_all_windows (Lisp_Object frame_spec, Lisp_Object device_spec) +{ + Lisp_Object devcons, concons; + Lisp_Object retval = Qnil; + + DEVICE_LOOP_NO_BREAK (devcons, concons) + { + Lisp_Object frame_list, the_window; + Lisp_Object device, tail; + + device = XCAR (devcons); + frame_list = DEVICE_FRAME_LIST (XDEVICE (device)); + + LIST_LOOP (tail, frame_list) + { + if ((NILP (frame_spec) + && !EQ (XCAR (tail), DEVICE_SELECTED_FRAME (XDEVICE (device)))) + || (EQ (frame_spec, Qvisible) + && !FRAME_VISIBLE_P (XFRAME (XCAR (tail)))) + || (FRAMEP (frame_spec) + && !EQ (frame_spec, XCAR (tail))) + || (!NILP (frame_spec) + && !device_matches_device_spec (device, + NILP (device_spec) ? + Vselected_console : + device_spec))) + continue; + the_window = FRAME_ROOT_WINDOW (XFRAME (XCAR (tail))); + retval = list_windows (XWINDOW (the_window), retval); + } + } + return Fnreverse (retval); +} + DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows, 1, 3, "bReplace buffer in windows: ", /* Replace BUFFER with some other buffer in all windows showing it. @@ -3124,18 +3127,46 @@ Any other non-nil value means search all devices. (buffer, which_frames, which_devices)) { /* This function can GC */ - buffer = Fget_buffer (buffer); - CHECK_BUFFER (buffer); + Lisp_Object window_list; + Lisp_Object tail; + struct gcpro gcpro1, gcpro2; - /* WHICH-FRAMES values t and nil mean the opposite of what - window_loop expects. */ if (EQ (which_frames, Qnil)) which_frames = Qt; else if (EQ (which_frames, Qt)) which_frames = Qnil; + window_list = list_all_windows (which_frames, which_devices); - /* Ignore dedicated windows. */ - window_loop (UNSHOW_BUFFER, buffer, 0, which_frames, 0, which_devices); + buffer = Fget_buffer (buffer); + CHECK_BUFFER (buffer); + + GCPRO2 (window_list, buffer); + LIST_LOOP (tail, window_list) + { + Lisp_Object window = XCAR (tail); + if (!MINI_WINDOW_P (XWINDOW (window)) + && EQ (XWINDOW (window)->buffer, buffer)) + { + Lisp_Object another_buffer = Fother_buffer (buffer, Qnil, Qnil); + Lisp_Object frame = WINDOW_FRAME (XWINDOW (window)); + if (NILP (another_buffer)) + another_buffer = Fget_buffer_create (QSscratch); + if (!NILP (XWINDOW (window)->dedicated) + && EQ (window, + FRAME_ROOT_WINDOW (XFRAME (frame))) + && other_visible_frames (XFRAME (frame))) + { + delete_frame_internal (XFRAME (frame), 0, 0, 0); /* GC */ + } + else + { + Fset_window_buffer (window, another_buffer, Qnil); + if (EQ (window, Fselected_window (Qnil))) + Fset_buffer (XWINDOW (window)->buffer); + } + } + } + UNGCPRO; return Qnil; } @@ -3352,6 +3383,7 @@ global or per-frame buffer ordering. { Lisp_Object tem; struct window *w = decode_window (window); + int old_buffer_local_face_property = 0; buffer = Fget_buffer (buffer); CHECK_BUFFER (buffer); @@ -3383,6 +3415,8 @@ global or per-frame buffer ordering. error ("Window is dedicated to buffer %s", XSTRING_DATA (XBUFFER (tem)->name)); + old_buffer_local_face_property = + XBUFFER (w->buffer)->buffer_local_face_property; unshow_buffer (w); } @@ -3404,6 +3438,14 @@ global or per-frame buffer ordering. SET_LAST_MODIFIED (w, 1); SET_LAST_FACECHANGE (w); MARK_WINDOWS_CHANGED (w); + { + int new_buffer_local_face_property = + XBUFFER (w->buffer)->buffer_local_face_property; + + if (new_buffer_local_face_property + || new_buffer_local_face_property != old_buffer_local_face_property) + MARK_WINDOW_FACES_CHANGED (w); + } recompute_all_cached_specifiers_in_window (w); if (EQ (window, Fselected_window (Qnil))) { @@ -3561,9 +3603,7 @@ make_dummy_parent (Lisp_Object window) p->face_cachels = Dynarr_new (face_cachel); p->glyph_cachels = Dynarr_new (glyph_cachel); p->subwindow_instance_cache = - make_lisp_hash_table (30, - HASH_TABLE_KEY_VALUE_WEAK, - HASH_TABLE_EQ); + make_image_instance_cache_hash_table (); /* Put new into window structure in place of window */ replace_window (window, new); @@ -3649,7 +3689,12 @@ and put SIZE columns in the first of the pair. || NILP (XWINDOW (o->parent)->vchild)) { make_dummy_parent (window); +#if 0 + /* #### I can't understand why you have to reset face + cachels here. This can cause crash so let's disable it + and see the difference. See redisplay-tests.el --yh */ reset_face_cachels (XWINDOW (window)); +#endif new = o->parent; XWINDOW (new)->vchild = window; XFRAME (o->frame)->mirror_dirty = 1; @@ -3666,7 +3711,10 @@ and put SIZE columns in the first of the pair. || NILP (XWINDOW (o->parent)->hchild)) { make_dummy_parent (window); +#if 0 + /* #### See above. */ reset_face_cachels (XWINDOW (window)); +#endif new = o->parent; XWINDOW (new)->hchild = window; XFRAME (o->frame)->mirror_dirty = 1; @@ -4283,7 +4331,7 @@ window_scroll (Lisp_Object window, Lisp_Object count, int direction, && Dynarr_length (dla) >= (1 + modeline) && - (dl->ascent - dl->top_clip) - fheight * value > 0) + (dl->ascent - dl->top_clip) > fheight * value) { WINDOW_TEXT_TOP_CLIP (w) += value * fheight; MARK_WINDOWS_CHANGED (w); @@ -4958,7 +5006,7 @@ struct window_config /* Record the values of window-min-width and window-min-height so that window sizes remain consistent with them. */ int min_width, min_height; - int saved_windows_count; + unsigned int saved_windows_count; /* Zero-sized arrays aren't ANSI C */ struct saved_window saved_windows[1]; }; @@ -4973,7 +5021,7 @@ static Lisp_Object mark_window_config (Lisp_Object obj) { struct window_config *config = XWINDOW_CONFIGURATION (obj); - int i; + unsigned int i; mark_object (config->current_window); mark_object (config->current_buffer); mark_object (config->minibuffer_scroll_window); @@ -5002,12 +5050,11 @@ mark_window_config (Lisp_Object obj) return Qnil; } -static size_t -sizeof_window_config_for_n_windows (int n) +inline static size_t +sizeof_window_config_for_n_windows (unsigned int n) { - return (sizeof (struct window_config) + - /* n - 1 because zero-sized arrays aren't ANSI C */ - (n - 1) *sizeof (struct saved_window)); + return FLEXIBLE_ARRAY_STRUCT_SIZEOF (struct window_config, + struct saved_window, saved_windows, n); } static size_t @@ -5072,7 +5119,7 @@ static int window_config_equal (Lisp_Object conf1, Lisp_Object conf2) { struct window_config *fig1, *fig2; - int i; + unsigned int i; /* First check if they are truly the same. */ if (EQ (conf1, conf2)) @@ -5127,7 +5174,7 @@ mark_windows_in_use (struct frame *f, int mark) static Lisp_Object free_window_configuration (Lisp_Object window_config) { - int i; + unsigned int i; struct window_config *config = XWINDOW_CONFIGURATION (window_config); /* Free all the markers. It's not completely necessary that @@ -5179,7 +5226,7 @@ by `current-window-configuration' (which see). struct window_config *config; struct saved_window *p; Lisp_Object new_current_buffer; - int k; + unsigned int k; Lisp_Object frame; struct frame *f; struct gcpro gcpro1; @@ -5427,9 +5474,8 @@ by `current-window-configuration' (which see). set. */ if (NILP (w->subwindow_instance_cache)) w->subwindow_instance_cache = - make_lisp_hash_table (30, - HASH_TABLE_KEY_VALUE_WEAK, - HASH_TABLE_EQ); + make_image_instance_cache_hash_table (); + SET_LAST_MODIFIED (w, 1); SET_LAST_FACECHANGE (w); w->config_mark = 0; @@ -5678,7 +5724,7 @@ delete_all_subwindows (struct window *w) } -static int +static unsigned int count_windows (struct window *window) { return 1 + @@ -5793,7 +5839,7 @@ its value is -not- saved. Lisp_Object result; struct frame *f = decode_frame (frame); struct window_config *config; - int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); + unsigned int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); int minibuf_height; int real_font_height; @@ -5810,14 +5856,20 @@ its value is -not- saved. /* config->frame_width = FRAME_WIDTH (f); config->frame_height = FRAME_HEIGHT (f); */ - /* When using `push-window-configuration', often the minibuffer ends + /* #### When using `push-window-configuration', often the minibuffer ends up as the selected window because functions run as the result of user interaction e.g. hyper-apropos. It seems to me the sensible - thing to do is not record the minibuffer here. */ + thing to do is not record the minibuffer here. + + #### Unfortunately this is a change to previous behaviour, however logical + it may be, so revert for the moment. */ +#if 0 if (FRAME_MINIBUF_ONLY_P (f) || minibuf_level) config->current_window = FRAME_SELECTED_WINDOW (f); else config->current_window = FRAME_LAST_NONMINIBUF_WINDOW (f); +#endif + config->current_window = FRAME_SELECTED_WINDOW (f); XSETBUFFER (config->current_buffer, current_buffer); config->minibuffer_scroll_window = Vminibuffer_scroll_window; config->root_window = FRAME_ROOT_WINDOW (f); @@ -6099,7 +6151,7 @@ syms_of_window (void) void reinit_vars_of_window (void) { - int i; + unsigned int i; /* Make sure all windows get marked */ minibuf_window = Qnil; staticpro_nodump (&minibuf_window);