X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fframe.c;h=5ab9b6dff85a4973afaf284545a22fe1e3ee451c;hp=2fcd5396129f4b64bf02afa64330fdb8ccb96cfe;hb=14ac73276fa152e8f0b74602792afc0b9c3236c9;hpb=976b002b16336930724ae22476014583ad022e7d diff --git a/src/frame.c b/src/frame.c index 2fcd539..5ab9b6d 100644 --- a/src/frame.c +++ b/src/frame.c @@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */ #include "faces.h" #include "frame.h" #include "glyphs.h" +#include "gutter.h" #include "menubar.h" #include "redisplay.h" #include "scrollbar.h" @@ -85,7 +86,6 @@ Lisp_Object Qborder_color; Lisp_Object Qborder_width; Lisp_Object Qframep, Qframe_live_p; -Lisp_Object Qframe_x_p, Qframe_tty_p; Lisp_Object Qdelete_frame; Lisp_Object Qframe_title_format, Vframe_title_format; @@ -102,7 +102,7 @@ Lisp_Object Qvisible, Qiconic, Qinvisible, Qvisible_iconic, Qinvisible_iconic; Lisp_Object Qnomini, Qvisible_nomini, Qiconic_nomini, Qinvisible_nomini; Lisp_Object Qvisible_iconic_nomini, Qinvisible_iconic_nomini; -Lisp_Object Qset_specifier, Qset_glyph_image, Qset_face_property; +Lisp_Object Qset_specifier, Qset_face_property; Lisp_Object Qface_property_instance; Lisp_Object Qframe_property_alias; @@ -116,22 +116,26 @@ Lisp_Object Vframe_being_created; Lisp_Object Qframe_being_created; static void store_minibuf_frame_prop (struct frame *f, Lisp_Object val); - -EXFUN (Fset_frame_properties, 2); +static void frame_conversion_internal (struct frame *f, int pixel_to_char, + int *pixel_width, int *pixel_height, + int *char_width, int *char_height, + int real_face); +static struct display_line title_string_display_line; +/* Used by generate_title_string. Global because they get used so much that + the dynamic allocation time adds up. */ +static Charc_dynarr *title_string_charc_dynarr; static Lisp_Object -mark_frame (Lisp_Object obj, void (*markobj) (Lisp_Object)) +mark_frame (Lisp_Object obj) { struct frame *f = XFRAME (obj); -#define MARKED_SLOT(x) ((void) (markobj (f->x))); +#define MARKED_SLOT(x) mark_object (f->x) #include "frameslots.h" - mark_subwindow_cachels (f->subwindow_cachels, markobj); - if (FRAME_LIVE_P (f)) /* device is nil for a dead frame */ - MAYBE_FRAMEMETH (f, mark_frame, (f, markobj)); + MAYBE_FRAMEMETH (f, mark_frame, (f)); return Qnil; } @@ -155,13 +159,13 @@ print_frame (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) } DEFINE_LRECORD_IMPLEMENTATION ("frame", frame, - mark_frame, print_frame, 0, 0, 0, + mark_frame, print_frame, 0, 0, 0, 0, struct frame); static void nuke_all_frame_slots (struct frame *f) { -#define MARKED_SLOT(x) f->x = Qnil; +#define MARKED_SLOT(x) f->x = Qnil #include "frameslots.h" } @@ -198,15 +202,18 @@ allocate_frame_core (Lisp_Object device) XWINDOW (root_window)->pixel_width = 10; XWINDOW (root_window)->pixel_height = 9; - /* The size of the minibuffer window is now set in x_create_frame - in xfns.c. */ - f->root_window = root_window; f->selected_window = root_window; f->last_nonminibuf_window = root_window; /* cache of subwindows visible on frame */ - f->subwindow_cachels = Dynarr_new (subwindow_cachel); + f->subwindow_instance_cache = make_weak_list (WEAK_LIST_SIMPLE); + + /* associated exposure ignore list */ + f->subwindow_exposures = 0; + f->subwindow_exposures_tail = 0; + + FRAME_SET_PAGENUMBER (f, 1); /* Choose a buffer for the frame's root window. */ XWINDOW (root_window)->buffer = Qt; @@ -218,7 +225,7 @@ allocate_frame_core (Lisp_Object device) a space), try to find another one. */ if (string_char (XSTRING (Fbuffer_name (buf)), 0) == ' ') buf = Fother_buffer (buf, Qnil, Qnil); - Fset_window_buffer (root_window, buf); + Fset_window_buffer (root_window, buf, Qnil); } return f; @@ -241,7 +248,7 @@ setup_normal_frame (struct frame *f) f->has_minibuffer = 1; XWINDOW (mini_window)->buffer = Qt; - Fset_window_buffer (mini_window, Vminibuffer_zero); + Fset_window_buffer (mini_window, Vminibuffer_zero, Qt); } /* Make a frame using a separate minibuffer window on another frame. @@ -262,7 +269,9 @@ setup_frame_without_minibuffer (struct frame *f, Lisp_Object mini_window) FRAME_CONSOLE (XFRAME (XWINDOW (mini_window)->frame)))) error ("frame and minibuffer must be on the same console"); - if (NILP (mini_window)) + /* Do not create a default minibuffer frame on printer devices. */ + if (NILP (mini_window) + && DEVICE_DISPLAY_P (XDEVICE (FRAME_DEVICE (f)))) { struct console *con = XCONSOLE (FRAME_CONSOLE (f)); /* Use default-minibuffer-frame if possible. */ @@ -277,8 +286,13 @@ setup_frame_without_minibuffer (struct frame *f, Lisp_Object mini_window) } /* Install the chosen minibuffer window, with proper buffer. */ - store_minibuf_frame_prop (f, mini_window); - Fset_window_buffer (mini_window, Vminibuffer_zero); + if (!NILP (mini_window)) + { + store_minibuf_frame_prop (f, mini_window); + Fset_window_buffer (mini_window, Vminibuffer_zero, Qt); + } + else + f->minibuffer_window = Qnil; } /* Make a frame containing only a minibuffer window. */ @@ -308,7 +322,7 @@ setup_minibuffer_frame (struct frame *f) /* Put the proper buffer in that window. */ - Fset_window_buffer (mini_window, Vminibuffer_zero); + Fset_window_buffer (mini_window, Vminibuffer_zero, Qt); } static Lisp_Object @@ -372,7 +386,7 @@ See `set-frame-properties', `default-x-frame-plist', and else name = build_string ("emacs"); - if (!NILP (Fstring_match (make_string ((CONST Bufbyte *) "\\.", 2), name, + if (!NILP (Fstring_match (make_string ((const Bufbyte *) "\\.", 2), name, Qnil, Qnil))) signal_simple_error (". not allowed in frame names", name); @@ -409,7 +423,7 @@ See `set-frame-properties', `default-x-frame-plist', and update_frame_window_mirror (f); - if (initialized) + if (initialized && !DEVICE_STREAM_P (d)) { if (!NILP (f->minibuffer_window)) reset_face_cachels (XWINDOW (f->minibuffer_window)); @@ -458,7 +472,7 @@ See `set-frame-properties', `default-x-frame-plist', and #endif reset_face_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f))); reset_glyph_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f))); - reset_subwindow_cachels (f); + change_frame_size (f, f->height, f->width, 0); } @@ -491,6 +505,18 @@ See `set-frame-properties', `default-x-frame-plist', and MAYBE_FRAMEMETH (f, after_init_frame, (f, first_frame_on_device, first_frame_on_console)); + if (!DEVICE_STREAM_P (d)) + { + /* Now initialise the gutters. This won't change the frame size, + but is needed as input to the layout that change_frame_size + will eventually do. Unfortunately gutter sizing code relies + on the frame in question being visible so we can't do this + earlier. */ + init_frame_gutters (f); + + change_frame_size (f, f->height, f->width, 0); + } + if (first_frame_on_device) { if (first_frame_on_console) @@ -753,7 +779,7 @@ selected_frame (void) /* use this instead of XFRAME (DEVICE_SELECTED_FRAME (d)) to catch the possibility of there being no frames on the device (just created). There is no point doing this inside of redisplay because errors - cause an abort(), indicating a flaw in the logic, and error_check_frame() + cause an ABORT(), indicating a flaw in the logic, and error_check_frame() will catch this just as well. */ struct frame * @@ -891,16 +917,19 @@ set_frame_selected_window (struct frame *f, Lisp_Object window) f->selected_window = window; if (!MINI_WINDOW_P (XWINDOW (window)) || FRAME_MINIBUF_ONLY_P (f)) { -#ifdef HAVE_TOOLBARS if (!EQ (f->last_nonminibuf_window, window)) - MARK_TOOLBAR_CHANGED; + { +#ifdef HAVE_TOOLBARS + MARK_TOOLBAR_CHANGED; #endif + MARK_GUTTER_CHANGED; + } f->last_nonminibuf_window = window; } } DEFUN ("set-frame-selected-window", Fset_frame_selected_window, 2, 2, 0, /* -Set the selected window of frame object FRAME to WINDOW. +Set the selected window of FRAME to WINDOW. If FRAME is nil, the selected frame is used. If FRAME is the selected frame, this makes WINDOW the selected window. */ @@ -947,7 +976,7 @@ is_surrogate_for_selected_frame (struct frame *f) } static int -frame_matches_frametype (Lisp_Object frame, Lisp_Object type) +frame_matches_frame_spec (Lisp_Object frame, Lisp_Object type) { struct frame *f = XFRAME (frame); @@ -1008,160 +1037,141 @@ frame_matches_frametype (Lisp_Object frame, Lisp_Object type) } int -device_matches_console_spec (Lisp_Object frame, Lisp_Object device, - Lisp_Object console) +device_matches_device_spec (Lisp_Object device, Lisp_Object device_spec) { - if (EQ (console, Qwindow_system)) + if (EQ (device_spec, Qwindow_system)) return DEVICE_WIN_P (XDEVICE (device)); - if (NILP (console)) - console = (DEVICE_CONSOLE (XDEVICE (FRAME_DEVICE (XFRAME (frame))))); - if (DEVICEP (console)) - return EQ (device, console); - if (CONSOLEP (console)) - return EQ (DEVICE_CONSOLE (XDEVICE (device)), console); - if (valid_console_type_p (console)) - return EQ (DEVICE_TYPE (XDEVICE (device)), console); + if (DEVICEP (device_spec)) + return EQ (device, device_spec); + if (CONSOLEP (device_spec)) + return EQ (DEVICE_CONSOLE (XDEVICE (device)), device_spec); + if (valid_console_type_p (device_spec)) + return EQ (DEVICE_TYPE (XDEVICE (device)), device_spec); return 1; } /* Return the next frame in the frame list after FRAME. - FRAMETYPE and CONSOLE control which frames and devices + WHICH-FRAMES and WHICH-DEVICES control which frames and devices are considered; see `next-frame'. */ -static Lisp_Object -next_frame_internal (Lisp_Object frame, Lisp_Object frametype, - Lisp_Object console, int called_from_delete_device) +Lisp_Object +next_frame (Lisp_Object frame, Lisp_Object which_frames, Lisp_Object which_devices) { + Lisp_Object first = Qnil; + Lisp_Object devcons, concons; int passed = 0; - int started_over = 0; - /* If this frame is dead, it won't be in frame_list, and we'll loop - forever. Forestall that. */ CHECK_LIVE_FRAME (frame); - while (1) + DEVICE_LOOP_NO_BREAK (devcons, concons) { - Lisp_Object devcons, concons; + Lisp_Object device = XCAR (devcons); + Lisp_Object frmcons; - DEVICE_LOOP_NO_BREAK (devcons, concons) + if (!device_matches_device_spec (device, which_devices)) { - Lisp_Object device = XCAR (devcons); - Lisp_Object frmcons; + if (EQ (device, FRAME_DEVICE (XFRAME (frame)))) + passed = 1; + continue; + } - if (!device_matches_console_spec (frame, device, console)) - continue; + DEVICE_FRAME_LOOP (frmcons, XDEVICE (device)) + { + Lisp_Object f = XCAR (frmcons); - DEVICE_FRAME_LOOP (frmcons, XDEVICE (device)) + if (passed) { - Lisp_Object f = XCAR (frmcons); - if (passed) + if (frame_matches_frame_spec (f, which_frames)) + return f; + } + else + { + if (EQ (frame, f)) { - /* #### Doing this here is bad and is now - unnecessary. The real bug was that f->iconified - was never, ever updated unless a user explicitly - called frame-iconified-p. That has now been - fixed. With this change removed all of the other - changes made to support this routine having the - called_from_delete_device arg could be removed. - But it is too close to release to do that now. */ -#if 0 - /* Make sure the visibility and iconified flags are - up-to-date unless we're being deleted. */ - if (!called_from_delete_device) - { - Fframe_iconified_p (f); - Fframe_visible_p (f); - } -#endif - - /* Decide whether this frame is eligible to be returned. */ - - /* If we've looped all the way around without finding any - eligible frames, return the original frame. */ - if (EQ (f, frame)) - return f; - - if (frame_matches_frametype (f, frametype)) - return f; + passed = 1; + } + else + { + if (NILP (first) && frame_matches_frame_spec (f, which_frames)) + first = f; } - - if (EQ (frame, f)) - passed++; } } - /* We hit the end of the list, and need to start over again. */ - if (started_over) - return Qnil; - started_over++; } -} -Lisp_Object -next_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console) -{ - return next_frame_internal (frame, frametype, console, 0); + if (NILP (first)) + /* We went through the whole frame list without finding a single + acceptable frame. Return the original frame. */ + return frame; + else + /* There were no acceptable frames in the list after FRAME; otherwise, + we would have returned directly from the loop. Since FIRST is the last + acceptable frame in the list, return it. */ + return first; } /* Return the previous frame in the frame list before FRAME. - FRAMETYPE and CONSOLE control which frames and devices + WHICH-FRAMES and WHICH-DEVICES control which frames and devices are considered; see `next-frame'. */ Lisp_Object -prev_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console) +previous_frame (Lisp_Object frame, Lisp_Object which_frames, Lisp_Object which_devices) { Lisp_Object devcons, concons; - Lisp_Object prev; + Lisp_Object last = Qnil; - /* If this frame is dead, it won't be in frame_list, and we'll loop - forever. Forestall that. */ CHECK_LIVE_FRAME (frame); - prev = Qnil; DEVICE_LOOP_NO_BREAK (devcons, concons) { Lisp_Object device = XCAR (devcons); Lisp_Object frmcons; - if (!device_matches_console_spec (frame, device, console)) - continue; + if (!device_matches_device_spec (device, which_devices)) + { + if (EQ (device, FRAME_DEVICE (XFRAME (frame))) + && !NILP (last)) + return last; + continue; + } DEVICE_FRAME_LOOP (frmcons, XDEVICE (device)) { Lisp_Object f = XCAR (frmcons); - if (EQ (frame, f) && !NILP (prev)) - return prev; - - /* Decide whether this frame is eligible to be returned, - according to frametype. */ - - if (frame_matches_frametype (f, frametype)) - prev = f; - + if (EQ (frame, f)) + { + if (!NILP (last)) + return last; + } + else + { + if (frame_matches_frame_spec (f, which_frames)) + last = f; + } } } - /* We've scanned the entire list. */ - if (NILP (prev)) + if (NILP (last)) /* We went through the whole frame list without finding a single acceptable frame. Return the original frame. */ return frame; else /* There were no acceptable frames in the list before FRAME; otherwise, - we would have returned directly from the loop. Since PREV is the last + we would have returned directly from the loop. Since LAST is the last acceptable frame in the list, return it. */ - return prev; + return last; } DEFUN ("next-frame", Fnext_frame, 0, 3, 0, /* Return the next frame of the right type in the frame list after FRAME. -FRAMETYPE controls which frames are eligible to be returned; all +WHICH-FRAMES controls which frames are eligible to be returned; all others will be skipped. Note that if there is only one eligible frame, then `next-frame' called repeatedly will always return the same frame, and if there is no eligible frame, then FRAME is returned. -Possible values for FRAMETYPE are +Possible values for WHICH-FRAMES are 'visible Consider only frames that are visible. 'iconic Consider only frames that are iconic. @@ -1179,43 +1189,44 @@ Possible values for FRAMETYPE are frames. any other value Consider all frames. -If FRAMETYPE is omitted, 'nomini is used. A FRAMETYPE of 0 (a number) -is treated like 'iconic, for backwards compatibility. +If WHICH-FRAMES is omitted, 'nomini is used. A value for WHICH-FRAMES +of 0 (a number) is treated like 'iconic, for backwards compatibility. -If FRAMETYPE is a window, include only its own frame and any frame now -using that window as the minibuffer. +If WHICH-FRAMES is a window, include only its own frame and any frame +now using that window as the minibuffer. -Optional third argument CONSOLE controls which consoles or devices the -returned frame may be on. If CONSOLE is a console, return frames only -on that console. If CONSOLE is a device, return frames only on that -device. If CONSOLE is a console type, return frames only on consoles -of that type. If CONSOLE is 'window-system, return any frames on any -window-system consoles. If CONSOLE is nil or omitted, return frames only -on the FRAME's console. Otherwise, all frames are considered. +The optional third argument WHICH-DEVICES further clarifies on which +devices to search for frames as specified by WHICH-FRAMES. +If nil or omitted, search all devices on FRAME's console. +If a device, only search that device. +If a console, search all devices on that console. +If a device type, search all devices of that type. +If `window-system', search all window-system devices. +Any other non-nil value means search all devices. */ - (frame, frametype, console)) + (frame, which_frames, which_devices)) { XSETFRAME (frame, decode_frame (frame)); - return next_frame (frame, frametype, console); + return next_frame (frame, which_frames, which_devices); } DEFUN ("previous-frame", Fprevious_frame, 0, 3, 0, /* Return the next frame of the right type in the frame list after FRAME. -FRAMETYPE controls which frames are eligible to be returned; all +WHICH-FRAMES controls which frames are eligible to be returned; all others will be skipped. Note that if there is only one eligible frame, then `previous-frame' called repeatedly will always return the same frame, and if there is no eligible frame, then FRAME is returned. -See `next-frame' for an explanation of the FRAMETYPE and CONSOLE +See `next-frame' for an explanation of the WHICH-FRAMES and WHICH-DEVICES arguments. */ - (frame, frametype, console)) + (frame, which_frames, which_devices)) { XSETFRAME (frame, decode_frame (frame)); - return prev_frame (frame, frametype, console); + return previous_frame (frame, which_frames, which_devices); } /* Return any frame for which PREDICATE is non-zero, or return Qnil @@ -1247,23 +1258,15 @@ find_some_frame (int (*predicate) (Lisp_Object, void *), (Exception: if F is a stream frame, it's OK to delete if any other frames exist.) */ -static int -other_visible_frames_internal (struct frame *f, int called_from_delete_device) +int +other_visible_frames (struct frame *f) { Lisp_Object frame; XSETFRAME (frame, f); if (FRAME_STREAM_P (f)) - return !EQ (frame, next_frame_internal (frame, Qt, Qt, - called_from_delete_device)); - return !EQ (frame, next_frame_internal (frame, Qvisible_iconic_nomini, Qt, - called_from_delete_device)); -} - -int -other_visible_frames (struct frame *f) -{ - return other_visible_frames_internal (f, 0); + return !EQ (frame, next_frame (frame, Qt, Qt)); + return !EQ (frame, next_frame (frame, Qvisible_iconic_nomini, Qt)); } /* Delete frame F. @@ -1305,7 +1308,8 @@ delete_frame_internal (struct frame *f, int force, console = DEVICE_CONSOLE (d); con = XCONSOLE (console); - if (!called_from_delete_device) + if (!called_from_delete_device + && !DEVICE_IMPL_FLAG (d, XDEVIMPF_FRAMELESS_OK)) { /* If we're deleting the only non-minibuffer frame on the device, delete the device. */ @@ -1324,7 +1328,7 @@ delete_frame_internal (struct frame *f, int force, losing any way of communicating with the still running XEmacs process. So we put it back. */ if (!force && !allow_deletion_of_last_visible_frame && - !other_visible_frames_internal (f, called_from_delete_device)) + !other_visible_frames (f)) error ("Attempt to delete the sole visible or iconified frame"); /* Does this frame have a minibuffer, and is it the surrogate @@ -1450,22 +1454,17 @@ delete_frame_internal (struct frame *f, int force, next = DEVMETH_OR_GIVEN (d, get_frame_parent, (f), Qnil); if (NILP (next) || EQ (next, frame) || ! FRAME_LIVE_P (XFRAME (next))) - next = next_frame_internal (frame, Qvisible, device, - called_from_delete_device); + next = next_frame (frame, Qvisible, device); if (NILP (next) || EQ (next, frame)) - next = next_frame_internal (frame, Qvisible, console, - called_from_delete_device); + next = next_frame (frame, Qvisible, console); if (NILP (next) || EQ (next, frame)) - next = next_frame_internal (frame, Qvisible, Qt, - called_from_delete_device); + next = next_frame (frame, Qvisible, Qt); if (NILP (next) || EQ (next, frame)) - next = next_frame_internal (frame, Qt, device, - called_from_delete_device); + next = next_frame (frame, Qt, device); if (NILP (next) || EQ (next, frame)) - next = next_frame_internal (frame, Qt, console, - called_from_delete_device); + next = next_frame (frame, Qt, console); if (NILP (next) || EQ (next, frame)) - next = next_frame_internal (frame, Qt, Qt, called_from_delete_device); + next = next_frame (frame, Qt, Qt); /* if we haven't found another frame at this point then there aren't any. */ @@ -1487,11 +1486,9 @@ delete_frame_internal (struct frame *f, int force, */ if (!EQ (device, FRAME_DEVICE(XFRAME(next)))) { - Lisp_Object next_f = - next_frame_internal (frame, Qt, device, - called_from_delete_device); + Lisp_Object next_f = next_frame (frame, Qt, device); if (NILP (next_f) || EQ (next_f, frame)) - ; + set_device_selected_frame (d, Qnil); else set_device_selected_frame (d, next_f); } @@ -1506,7 +1503,7 @@ delete_frame_internal (struct frame *f, int force, { struct frame *sel_frame = selected_frame (); Fset_window_buffer (sel_frame->minibuffer_window, - XWINDOW (minibuf_window)->buffer); + XWINDOW (minibuf_window)->buffer, Qt); minibuf_window = sel_frame->minibuffer_window; /* If the dying minibuffer window was selected, @@ -1526,6 +1523,13 @@ delete_frame_internal (struct frame *f, int force, #ifdef HAVE_TOOLBARS free_frame_toolbars (f); #endif + free_frame_gutters (f); + /* Unfortunately deleting the frame will also delete the parent of + all of the subwindow instances current on the frame. I think this + can lead to bad things when trying to finalize the + instances. Thus we loop over all instance caches calling the + finalize method for each instance. */ + free_frame_subwindow_instances (f); /* This must be done before the window and window_mirror structures are freed. The scrollbar information is attached to them. */ @@ -1537,11 +1541,7 @@ delete_frame_internal (struct frame *f, int force, f->root_window = Qnil; /* clear out the cached glyph information */ - if (f->subwindow_cachels) - { - Dynarr_free (f->subwindow_cachels); - f->subwindow_cachels = 0; - } + f->subwindow_instance_cache = Qnil; /* Remove the frame now from the list. This way, any events generated on this frame by the maneuvers below will disperse themselves. */ @@ -1633,7 +1633,7 @@ delete_frame_internal (struct frame *f, int force, that is prohibited at the top; you can't delete surrogate minibuffer frames. */ if (NILP (frame_with_minibuf)) - abort (); + ABORT (); con->default_minibuffer_frame = frame_with_minibuf; } @@ -1707,7 +1707,7 @@ mouse_pixel_position_1 (struct device *d, Lisp_Object *frame, break; default: - abort (); /* method is incorrectly written */ + ABORT (); /* method is incorrectly written */ } return 0; @@ -1715,13 +1715,14 @@ mouse_pixel_position_1 (struct device *d, Lisp_Object *frame, DEFUN ("mouse-pixel-position", Fmouse_pixel_position, 0, 1, 0, /* Return a list (WINDOW X . Y) giving the current mouse window and position. -The position is given in pixel units, where (0, 0) is the upper-left corner. +The position is given in pixel units, where (0, 0) is the upper-left corner +of the window. When the cursor is not over a window, the return value is a list (nil nil). DEVICE specifies the device on which to read the mouse position, and defaults to the selected device. If the device is a mouseless terminal -or Emacs hasn't been programmed to read its mouse position, it returns +or XEmacs hasn't been programmed to read its mouse position, it returns the device's selected window for WINDOW and nil for X and Y. */ (device)) @@ -1838,7 +1839,7 @@ Note also: Warping the mouse is contrary to the ICCCM, so be very sure struct window *w; int pix_x, pix_y; - CHECK_WINDOW (window); + CHECK_LIVE_WINDOW (window); CHECK_INT (x); CHECK_INT (y); @@ -1862,7 +1863,7 @@ before calling this function on it, like this. { struct window *w; - CHECK_WINDOW (window); + CHECK_LIVE_WINDOW (window); CHECK_INT (x); CHECK_INT (y); @@ -1911,7 +1912,7 @@ you may do so. if (EQ (f->minibuffer_window, minibuf_window)) { Fset_window_buffer (sel_frame->minibuffer_window, - XWINDOW (minibuf_window)->buffer); + XWINDOW (minibuf_window)->buffer, Qt); minibuf_window = sel_frame->minibuffer_window; } @@ -1937,7 +1938,7 @@ If omitted, FRAME defaults to the currently selected frame. if (EQ (f->minibuffer_window, minibuf_window)) { Fset_window_buffer (sel_frame->minibuffer_window, - XWINDOW (minibuf_window)->buffer); + XWINDOW (minibuf_window)->buffer, Qt); minibuf_window = sel_frame->minibuffer_window; } @@ -1964,7 +1965,7 @@ Return non NIL if FRAME is now "visible" (actually in use for display). A frame that is not visible is not updated, and, if it works through a window system, may not show at all. N.B. Under X "visible" means Mapped. It the window is mapped but not -actually visible on screen then frame_visible returns 'hidden. +actually visible on screen then `frame-visible-p' returns 'hidden. */ (frame)) { @@ -2003,8 +2004,8 @@ frame is iconified, it will not be visible. DEFUN ("visible-frame-list", Fvisible_frame_list, 0, 1, 0, /* Return a list of all frames now "visible" (being updated). If DEVICE is specified only frames on that device will be returned. -Note that under virtual window managers not all these frame are necessarily -really updated. +Note that under virtual window managers not all these frames are +necessarily really updated. */ (device)) { @@ -2067,8 +2068,61 @@ doesn't support multiple overlapping frames, this function does nothing. return Qnil; } + +DEFUN ("disable-frame", Fdisable_frame, 1, 1, 0, /* +Disable frame FRAME, so that it cannot have the focus or receive user input. +This is normally used during modal dialog boxes. +WARNING: Be very careful not to wedge XEmacs! +Use an `unwind-protect' that re-enables the frame to avoid this. +*/ + (frame)) +{ + struct frame *f = decode_frame (frame); + + f->disabled = 1; + MAYBE_FRAMEMETH (f, disable_frame, (f)); + return Qnil; +} + +DEFUN ("enable-frame", Fenable_frame, 1, 1, 0, /* +Enable frame FRAME, so that it can have the focus and receive user input. +Frames are normally enabled, unless explicitly disabled using `disable-frame'. +*/ + (frame)) +{ + struct frame *f = decode_frame (frame); + f->disabled = 0; + MAYBE_FRAMEMETH (f, enable_frame, (f)); + return Qnil; +} + /* Ben thinks there is no need for `redirect-frame-focus' or `frame-focus', crockish FSFmacs functions. See summary on focus in event-stream.c. */ + +DEFUN ("print-job-page-number", Fprint_job_page_number, 1, 1, 0, /* +Return current page number for the print job FRAME. +*/ + (frame)) +{ + CHECK_PRINTER_FRAME (frame); + return make_int (FRAME_PAGENUMBER (XFRAME (frame))); +} + +DEFUN ("print-job-eject-page", Fprint_job_eject_page, 1, 1, 0, /* +Eject page in the print job FRAME. +*/ + (frame)) +{ + struct frame *f; + + CHECK_PRINTER_FRAME (frame); + f = XFRAME (frame); + FRAMEMETH (f, eject_page, (f)); + FRAME_SET_PAGENUMBER (f, 1 + FRAME_PAGENUMBER (f)); + f->clear = 1; + + return Qnil; +} /***************************************************************************/ @@ -2124,7 +2178,7 @@ dissect_as_face_setting (Lisp_Object sym, Lisp_Object *face_out, Lisp_Object *face_prop_out) { Lisp_Object list = Vbuilt_in_face_specifiers; - struct Lisp_String *s; + Lisp_String *s; if (!SYMBOLP (sym)) return 0; @@ -2134,7 +2188,7 @@ dissect_as_face_setting (Lisp_Object sym, Lisp_Object *face_out, while (!NILP (list)) { Lisp_Object prop = Fcar (list); - struct Lisp_String *prop_name; + Lisp_String *prop_name; if (!SYMBOLP (prop)) continue; @@ -2212,8 +2266,9 @@ The following symbols etc. have predefined meanings: minibuffer Gives the minibuffer behavior for this frame. Either t (frame has its own minibuffer), `only' (frame is - a minibuffer-only frame), or a window (frame uses that - window, which is on another frame, as the minibuffer). + a minibuffer-only frame), `none' (frame has no minibuffer) + or a window (frame uses that window, which is on another + frame, as the minibuffer). unsplittable If non-nil, frame cannot be split by `display-buffer'. @@ -2227,7 +2282,13 @@ The following symbols etc. have predefined meanings: left-toolbar-visible-p, right-toolbar-visible-p, toolbar-buttons-captioned-p, top-toolbar-border-width, bottom-toolbar-border-width, left-toolbar-border-width, right-toolbar-border-width, - modeline-shadow-thickness, has-modeline-p + modeline-shadow-thickness, has-modeline-p, + default-gutter, top-gutter, bottom-gutter, left-gutter, right-gutter, + default-gutter-height, default-gutter-width, top-gutter-height, + bottom-gutter-height, left-gutter-width, right-gutter-width, + default-gutter-visible-p, top-gutter-visible-p, bottom-gutter-visible-p, + left-gutter-visible-p, right-gutter-visible-p, top-gutter-border-width, + bottom-gutter-border-width, left-gutter-border-width, right-gutter-border-width, [Giving the name of any built-in specifier variable is equivalent to calling `set-specifier' on the specifier, with a locale of FRAME. Giving the name to `frame-property' @@ -2348,6 +2409,7 @@ recognized for particular types of frames. DEFUN ("frame-property", Fframe_property, 2, 3, 0, /* Return FRAME's value for property PROPERTY. +Return DEFAULT if there is no such property. See `set-frame-properties' for the built-in property names. */ (frame, property, default_)) @@ -2543,21 +2605,21 @@ Specify that the frame FRAME has LINES lines. Optional third arg non-nil means that redisplay should use LINES lines but that the idea of the actual height of the frame should not be changed. */ - (frame, rows, pretend)) + (frame, lines, pretend)) { struct frame *f = decode_frame (frame); int height, width; XSETFRAME (frame, f); - CHECK_INT (rows); + CHECK_INT (lines); if (window_system_pixelated_geometry (frame)) { - char_to_real_pixel_size (f, 0, XINT (rows), 0, &height); + char_to_real_pixel_size (f, 0, XINT (lines), 0, &height); width = FRAME_PIXWIDTH (f); } else { - height = XINT (rows); + height = XINT (lines); width = FRAME_WIDTH (f); } @@ -2565,6 +2627,37 @@ but that the idea of the actual height of the frame should not be changed. return frame; } +DEFUN ("set-frame-pixel-height", Fset_frame_pixel_height, 2, 3, 0, /* +Specify that the frame FRAME is HEIGHT pixels tall. +Optional third arg non-nil means that redisplay should be HEIGHT pixels tall +but that the idea of the actual height of the frame should not be changed. +*/ + (frame, height, pretend)) +{ + struct frame *f = decode_frame (frame); + int pheight, width; + XSETFRAME (frame, f); + CHECK_INT (height); + + if (!window_system_pixelated_geometry (frame)) + { + int h = XINT (height); + width = FRAME_WIDTH (f); + /* Simply using pixel_to_real_char_size here is not good + enough since we end up with a total frame size of HEIGHT + rather than a displayable height of HEIGHT. */ + frame_conversion_internal (f, 2, 0, &h, 0, &pheight, 0); + } + else + { + width = FRAME_PIXWIDTH (f); + pheight = XINT (height); + } + + internal_set_frame_size (f, width, pheight, !NILP (pretend)); + return frame; +} + DEFUN ("set-frame-width", Fset_frame_width, 2, 3, 0, /* Specify that the frame FRAME has COLS columns. Optional third arg non-nil means that redisplay should use COLS columns @@ -2592,8 +2685,39 @@ but that the idea of the actual width of the frame should not be changed. return frame; } +DEFUN ("set-frame-pixel-width", Fset_frame_pixel_width, 2, 3, 0, /* +Specify that the frame FRAME is WIDTH pixels wide. +Optional third arg non-nil means that redisplay should be WIDTH wide +but that the idea of the actual height of the frame should not be changed. +*/ + (frame, width, pretend)) +{ + struct frame *f = decode_frame (frame); + int height, pwidth; + XSETFRAME (frame, f); + CHECK_INT (width); + + if (!window_system_pixelated_geometry (frame)) + { + int w = XINT (width); + height = FRAME_HEIGHT (f); + /* Simply using pixel_to_real_char_size here is not good + enough since we end up with a total frame size of WIDTH + rather than a displayable height of WIDTH. */ + frame_conversion_internal (f, 2, &w, 0, &pwidth, 0, 0); + } + else + { + height = FRAME_PIXHEIGHT (f); + pwidth = XINT (width); + } + + internal_set_frame_size (f, pwidth, height, !NILP (pretend)); + return frame; +} + DEFUN ("set-frame-size", Fset_frame_size, 3, 4, 0, /* -Set the size of FRAME to COLS by ROWS. +Set the size of FRAME to COLS by ROWS, measured in characters. Optional fourth arg non-nil means that redisplay should use COLS by ROWS but that the idea of the actual size of the frame should not be changed. */ @@ -2617,6 +2741,38 @@ but that the idea of the actual size of the frame should not be changed. return frame; } +DEFUN ("set-frame-pixel-size", Fset_frame_pixel_size, 3, 4, 0, /* +Set the size of FRAME to WIDTH by HEIGHT, measured in pixels. +Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT +but that the idea of the actual size of the frame should not be changed. +*/ + (frame, width, height, pretend)) +{ + struct frame *f = decode_frame (frame); + int pheight, pwidth; + XSETFRAME (frame, f); + CHECK_INT (width); + CHECK_INT (height); + + if (!window_system_pixelated_geometry (frame)) + { + int w = XINT (width); + int h = XINT (height); + /* Simply using pixel_to_real_char_size here is not good enough + since we end up with a total frame size of WIDTH x HEIGHT + rather than a displayable height of WIDTH x HEIGHT. */ + frame_conversion_internal (f, 2, &w, &h, &pwidth, &pheight, 0); + } + else + { + pheight = XINT (height); + pwidth = XINT (width); + } + + internal_set_frame_size (f, pwidth, pheight, !NILP (pretend)); + return frame; +} + DEFUN ("set-frame-position", Fset_frame_position, 3, 3, 0, /* Set position of FRAME in pixels to XOFFSET by YOFFSET. This is actually the position of the upper left corner of the frame. @@ -2660,8 +2816,8 @@ frame_conversion_internal (struct frame *f, int pixel_to_char, window = FRAME_SELECTED_WINDOW (f); - egw = max (glyph_width (Vcontinuation_glyph, Vdefault_face, 0, window), - glyph_width (Vtruncation_glyph, Vdefault_face, 0, window)); + egw = max (glyph_width (Vcontinuation_glyph, window), + glyph_width (Vtruncation_glyph, window)); egw = max (egw, cpw); bdr = 2 * f->internal_border_width; obw = FRAME_SCROLLBAR_WIDTH (f) + FRAME_THEORETICAL_LEFT_TOOLBAR_WIDTH (f) + @@ -2673,7 +2829,21 @@ frame_conversion_internal (struct frame *f, int pixel_to_char, 2 * FRAME_THEORETICAL_TOP_TOOLBAR_BORDER_WIDTH (f) + 2 * FRAME_THEORETICAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f); - if (pixel_to_char) + /* Convert to chars so that the displayable area is pixel_width x + pixel_height. + + #### Consider rounding up to 0.5 characters to avoid adding too + much space. */ + if (pixel_to_char > 1) + { + if (char_width) + *char_width = ROUND_UP (*pixel_width, cpw) / cpw; + if (char_height) + *char_height = ROUND_UP (*pixel_height, cph) / cph; + } + /* Convert to chars so that the total frame size is pixel_width x + pixel_height. */ + else if (pixel_to_char) { if (char_width) *char_width = 1 + ((*pixel_width - egw) - bdr - obw) / cpw; @@ -2781,7 +2951,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth) `left' coordinates to be recomputed even though no frame size change occurs. --kyle */ if (in_display) - abort (); + ABORT (); XSETFRAME (frame, f); @@ -2836,9 +3006,9 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth) { int adjustment, trunc_width, cont_width; - trunc_width = glyph_width (Vtruncation_glyph, Vdefault_face, 0, + trunc_width = glyph_width (Vtruncation_glyph, FRAME_SELECTED_WINDOW (f)); - cont_width = glyph_width (Vcontinuation_glyph, Vdefault_face, 0, + cont_width = glyph_width (Vcontinuation_glyph, FRAME_SELECTED_WINDOW (f)); adjustment = max (trunc_width, cont_width); adjustment = max (adjustment, font_width); @@ -2852,7 +3022,14 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth) if (new_pixheight) { - XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = FRAME_TOP_BORDER_END (f); + /* Adjust for gutters here so that we always get set + properly. */ + new_pixheight -= + (FRAME_TOP_GUTTER_BOUNDS (f) + + FRAME_BOTTOM_GUTTER_BOUNDS (f)); + + XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top + = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f); if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f)) @@ -2878,7 +3055,10 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth) new_pixheight - minibuf_height, 0); XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top = - new_pixheight - minibuf_height + FRAME_TOP_BORDER_END (f); + FRAME_TOP_BORDER_END (f) + + FRAME_TOP_GUTTER_BOUNDS (f) + + FRAME_BOTTOM_GUTTER_BOUNDS (f) + + new_pixheight - minibuf_height; set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0); } @@ -2893,13 +3073,20 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth) if (new_pixwidth) { - XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = FRAME_LEFT_BORDER_END (f); + /* Adjust for gutters here so that we always get set + properly. */ + new_pixwidth -= + (FRAME_LEFT_GUTTER_BOUNDS (f) + + FRAME_RIGHT_GUTTER_BOUNDS (f)); + + XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = + FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f); set_window_pixwidth (FRAME_ROOT_WINDOW (f), new_pixwidth, 0); if (FRAME_HAS_MINIBUF_P (f)) { XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left = - FRAME_LEFT_BORDER_END (f); + FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f); set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), new_pixwidth, 0); } @@ -2918,6 +3105,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth) } MARK_FRAME_TOOLBARS_CHANGED (f); + MARK_FRAME_GUTTERS_CHANGED (f); MARK_FRAME_CHANGED (f); f->echo_area_garbaged = 1; } @@ -2930,9 +3118,15 @@ change_frame_size (struct frame *f, int newheight, int newwidth, int delay) So deal. */ check_frame_size (f, &newheight, &newwidth); + /* Unconditionally mark that the frame has changed size. This is + because many things need to know after the + fact. f->size_change_pending will get reset below. The most that + can happen is that we will cycle through redisplay once more + --andy. */ + MARK_FRAME_SIZE_CHANGED (f); + if (delay || in_display || gc_in_progress) { - MARK_FRAME_SIZE_CHANGED (f); f->new_width = newwidth; f->new_height = newheight; return; @@ -2953,6 +3147,37 @@ change_frame_size (struct frame *f, int newheight, int newwidth, int delay) } +/* The caller is responsible for freeing the returned string. */ +static Bufbyte * +generate_title_string (struct window *w, Lisp_Object format_str, + face_index findex, int type) +{ + struct display_line *dl; + struct display_block *db; + int elt = 0; + + dl = &title_string_display_line; + db = get_display_block_from_line (dl, TEXT); + Dynarr_reset (db->runes); + + generate_formatted_string_db (format_str, Qnil, w, dl, db, findex, 0, + -1, type); + + Dynarr_reset (title_string_charc_dynarr); + while (elt < Dynarr_length (db->runes)) + { + if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR) + Dynarr_add (title_string_charc_dynarr, + Dynarr_atp (db->runes, elt)->object.cglyph); + elt++; + } + + return + convert_charc_string_into_malloced_string + (Dynarr_atp (title_string_charc_dynarr, 0), + Dynarr_length (title_string_charc_dynarr), 0); +} + void update_frame_title (struct frame *f) { @@ -2976,8 +3201,8 @@ update_frame_title (struct frame *f) if (HAS_FRAMEMETH_P (f, set_title_from_bufbyte)) { - title = generate_formatted_string (w, title_format, Qnil, - DEFAULT_INDEX, CURRENT_DISP); + title = generate_title_string (w, title_format, + DEFAULT_INDEX, CURRENT_DISP); FRAMEMETH (f, set_title_from_bufbyte, (f, title)); } @@ -2988,8 +3213,8 @@ update_frame_title (struct frame *f) if (title) xfree (title); - title = generate_formatted_string (w, icon_format, Qnil, - DEFAULT_INDEX, CURRENT_DISP); + title = generate_title_string (w, icon_format, + DEFAULT_INDEX, CURRENT_DISP); } FRAMEMETH (f, set_icon_name_from_bufbyte, (f, title)); } @@ -3048,9 +3273,29 @@ icon_glyph_changed (Lisp_Object glyph, Lisp_Object property, } +/***************************************************************************/ +/* */ +/* initialization */ +/* */ +/***************************************************************************/ + +void +init_frame (void) +{ +#ifndef PDUMP + if (!initialized) +#endif + { + title_string_charc_dynarr = Dynarr_new (Charc); + xzero (title_string_display_line); + } +} + void syms_of_frame (void) { + INIT_LRECORD_IMPLEMENTATION (frame); + defsymbol (&Qdelete_frame_hook, "delete-frame-hook"); defsymbol (&Qselect_frame_hook, "select-frame-hook"); defsymbol (&Qdeselect_frame_hook, "deselect-frame-hook"); @@ -3063,8 +3308,6 @@ syms_of_frame (void) defsymbol (&Qframep, "framep"); defsymbol (&Qframe_live_p, "frame-live-p"); - defsymbol (&Qframe_x_p, "frame-x-p"); - defsymbol (&Qframe_tty_p, "frame-tty-p"); defsymbol (&Qdelete_frame, "delete-frame"); defsymbol (&Qsynchronize_minibuffers, "synchronize-minibuffers"); defsymbol (&Qbuffer_predicate, "buffer-predicate"); @@ -3113,7 +3356,6 @@ syms_of_frame (void) defsymbol (&Qborder_width, "border-width"); /* Qwidth, Qheight, Qleft, Qtop in general.c */ defsymbol (&Qset_specifier, "set-specifier"); - defsymbol (&Qset_glyph_image, "set-glyph-image"); defsymbol (&Qset_face_property, "set-face-property"); defsymbol (&Qface_property_instance, "face-property-instance"); defsymbol (&Qframe_property_alias, "frame-property-alias"); @@ -3151,6 +3393,8 @@ syms_of_frame (void) DEFSUBR (Fvisible_frame_list); DEFSUBR (Fraise_frame); DEFSUBR (Flower_frame); + DEFSUBR (Fdisable_frame); + DEFSUBR (Fenable_frame); DEFSUBR (Fframe_property); DEFSUBR (Fframe_properties); DEFSUBR (Fset_frame_properties); @@ -3161,8 +3405,13 @@ syms_of_frame (void) DEFSUBR (Fset_frame_height); DEFSUBR (Fset_frame_width); DEFSUBR (Fset_frame_size); + DEFSUBR (Fset_frame_pixel_height); + DEFSUBR (Fset_frame_pixel_width); + DEFSUBR (Fset_frame_pixel_size); DEFSUBR (Fset_frame_position); DEFSUBR (Fset_frame_pointer); + DEFSUBR (Fprint_job_page_number); + DEFSUBR (Fprint_job_eject_page); } void @@ -3276,27 +3525,34 @@ visible frames. Vsynchronize_minibuffers = Qnil; DEFVAR_LISP ("frame-title-format", &Vframe_title_format /* -Controls the title of the X window corresponding to the selected frame. +Controls the title of the window-system window of the selected frame. This is the same format as `modeline-format' with the exception that %- is ignored. */ ); - Vframe_title_format = Fpurecopy (build_string ("%S: %b")); +/* #### I would change this unilaterally but for the wrath of the Kyles +of the world. */ +#ifdef WIN32_NATIVE + Vframe_title_format = build_string ("%b - XEmacs"); +#else + Vframe_title_format = build_string ("%S: %b"); +#endif DEFVAR_LISP ("frame-icon-title-format", &Vframe_icon_title_format /* Controls the title of the icon corresponding to the selected frame. See also the variable `frame-title-format'. */ ); - Vframe_icon_title_format = Fpurecopy (build_string ("%b")); + Vframe_icon_title_format = build_string ("%b"); DEFVAR_LISP ("default-frame-name", &Vdefault_frame_name /* The default name to assign to newly-created frames. -This can be overridden by arguments to `make-frame'. -This must be a string. +This can be overridden by arguments to `make-frame'. This must be a string. +This is used primarily for picking up X resources, and is *not* the title +of the frame. (See `frame-title-format'.) */ ); #ifndef INFODOCK - Vdefault_frame_name = Fpurecopy (build_string ("emacs")); + Vdefault_frame_name = build_string ("emacs"); #else - Vdefault_frame_name = Fpurecopy (build_string ("InfoDock")); + Vdefault_frame_name = build_string ("InfoDock"); #endif DEFVAR_LISP ("default-frame-plist", &Vdefault_frame_plist /*