X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/2ab04b956544fc24132cee405f93c1a757ebca56..3a45383a47009a5e6a15a4005ad95ecf63539182:/src/frame.c diff --git a/src/frame.c b/src/frame.c index bd97c5f18c..9389eccb6f 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1,6 +1,6 @@ /* Generic frame functions. -Copyright (C) 1993-1995, 1997, 1999-2011 Free Software Foundation, Inc. +Copyright (C) 1993-1995, 1997, 1999-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -131,16 +131,16 @@ set_menu_bar_lines_1 (Lisp_Object window, int n) { struct window *w = XWINDOW (window); - XSETFASTINT (w->last_modified, 0); - XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n); - XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n); + w->last_modified = 0; + XSETFASTINT (WVAR (w, top_line), XFASTINT (WVAR (w, top_line)) + n); + XSETFASTINT (WVAR (w, total_lines), XFASTINT (WVAR (w, total_lines)) - n); /* Handle just the top child in a vertical split. */ - if (!NILP (w->vchild)) - set_menu_bar_lines_1 (w->vchild, n); + if (!NILP (WVAR (w, vchild))) + set_menu_bar_lines_1 (WVAR (w, vchild), n); /* Adjust all children in a horizontal split. */ - for (window = w->hchild; !NILP (window); window = w->next) + for (window = WVAR (w, hchild); !NILP (window); window = WVAR (w, next)) { w = XWINDOW (window); set_menu_bar_lines_1 (window, n); @@ -170,7 +170,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) windows_or_buffers_changed++; FRAME_WINDOW_SIZES_CHANGED (f) = 1; FRAME_MENU_BAR_LINES (f) = nlines; - set_menu_bar_lines_1 (f->root_window, nlines - olines); + set_menu_bar_lines_1 (FVAR (f, root_window), nlines - olines); adjust_glyphs (f); } } @@ -267,82 +267,42 @@ make_frame (int mini_p) f = allocate_frame (); XSETFRAME (frame, f); - f->desired_matrix = 0; - f->current_matrix = 0; - f->desired_pool = 0; - f->current_pool = 0; - f->glyphs_initialized_p = 0; - f->decode_mode_spec_buffer = 0; - f->visible = 0; - f->async_visible = 0; - f->output_data.nothing = 0; - f->iconified = 0; - f->async_iconified = 0; + /* Initialize Lisp data. Note that allocate_frame initializes all + Lisp data to nil, so do it only for slots which should not be nil. */ + FVAR (f, tool_bar_position) = Qtop; + + /* Initialize non-Lisp data. Note that allocate_frame zeroes out all + non-Lisp data, so do it only for slots which should not be zero. + To avoid subtle bugs and for the sake of readability, it's better to + initialize enum members explicitly even if their values are zero. */ f->wants_modeline = 1; - f->auto_raise = 0; - f->auto_lower = 0; - f->no_split = 0; f->garbaged = 1; f->has_minibuffer = mini_p; - f->focus_frame = Qnil; - f->explicit_name = 0; - f->can_have_scroll_bars = 0; f->vertical_scroll_bar_type = vertical_scroll_bar_none; - f->param_alist = Qnil; - f->scroll_bars = Qnil; - f->condemned_scroll_bars = Qnil; - f->face_alist = Qnil; - f->face_cache = NULL; - f->menu_bar_items = Qnil; - f->menu_bar_vector = Qnil; - f->menu_bar_items_used = 0; - f->buffer_predicate = Qnil; - f->buffer_list = Qnil; - f->buried_buffer_list = Qnil; - f->namebuf = 0; - f->title = Qnil; - f->menu_bar_window = Qnil; - f->tool_bar_window = Qnil; - f->tool_bar_items = Qnil; - f->tool_bar_position = Qtop; - f->desired_tool_bar_string = f->current_tool_bar_string = Qnil; - f->n_tool_bar_items = 0; - f->left_fringe_width = f->right_fringe_width = 0; - f->fringe_cols = 0; - f->menu_bar_lines = 0; - f->tool_bar_lines = 0; - f->scroll_bar_actual_width = 0; - f->border_width = 0; - f->internal_border_width = 0; f->column_width = 1; /* !FRAME_WINDOW_P value */ f->line_height = 1; /* !FRAME_WINDOW_P value */ - f->x_pixels_diff = f->y_pixels_diff = 0; #ifdef HAVE_WINDOW_SYSTEM f->want_fullscreen = FULLSCREEN_NONE; #endif - f->size_hint_flags = 0; - f->win_gravity = 0; - f->font_driver_list = NULL; - f->font_data_list = NULL; root_window = make_window (); if (mini_p) { mini_window = make_window (); - XWINDOW (root_window)->next = mini_window; - XWINDOW (mini_window)->prev = root_window; - XWINDOW (mini_window)->mini_p = Qt; - XWINDOW (mini_window)->frame = frame; - f->minibuffer_window = mini_window; + WVAR (XWINDOW (root_window), next) = mini_window; + WVAR (XWINDOW (mini_window), prev) = root_window; + XWINDOW (mini_window)->mini = 1; + WVAR (XWINDOW (mini_window), frame) = frame; + FVAR (f, minibuffer_window) = mini_window; } else { mini_window = Qnil; - XWINDOW (root_window)->next = Qnil; - f->minibuffer_window = Qnil; + WVAR (XWINDOW (root_window), next) = Qnil; + FVAR (f, minibuffer_window) = Qnil; } - XWINDOW (root_window)->frame = frame; + WVAR (XWINDOW (root_window), frame) = frame; /* 10 is arbitrary, just so that there is "something there." @@ -351,21 +311,21 @@ make_frame (int mini_p) SET_FRAME_COLS (f, 10); FRAME_LINES (f) = 10; - XSETFASTINT (XWINDOW (root_window)->total_cols, 10); - XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10)); + XSETFASTINT (WVAR (XWINDOW (root_window), total_cols), 10); + XSETFASTINT (WVAR (XWINDOW (root_window), total_lines), (mini_p ? 9 : 10)); if (mini_p) { - XSETFASTINT (XWINDOW (mini_window)->total_cols, 10); - XSETFASTINT (XWINDOW (mini_window)->top_line, 9); - XSETFASTINT (XWINDOW (mini_window)->total_lines, 1); + XSETFASTINT (WVAR (XWINDOW (mini_window), total_cols), 10); + XSETFASTINT (WVAR (XWINDOW (mini_window), top_line), 9); + XSETFASTINT (WVAR (XWINDOW (mini_window), total_lines), 1); } /* Choose a buffer for the frame's root window. */ { Lisp_Object buf; - XWINDOW (root_window)->buffer = Qt; + WVAR (XWINDOW (root_window), buffer) = Qt; buf = Fcurrent_buffer (); /* If buf is a 'hidden' buffer (i.e. one whose name starts with a space), try to find another one. */ @@ -379,12 +339,12 @@ make_frame (int mini_p) etc. Running Lisp functions at this point surely ends in a SEGV. */ set_window_buffer (root_window, buf, 0, 0); - f->buffer_list = Fcons (buf, Qnil); + FVAR (f, buffer_list) = Fcons (buf, Qnil); } if (mini_p) { - XWINDOW (mini_window)->buffer = Qt; + WVAR (XWINDOW (mini_window), buffer) = Qt; set_window_buffer (mini_window, (NILP (Vminibuffer_list) ? get_minibuffer (0) @@ -392,14 +352,11 @@ make_frame (int mini_p) 0, 0); } - f->root_window = root_window; - f->selected_window = root_window; + FVAR (f, root_window) = root_window; + FVAR (f, selected_window) = root_window; /* Make sure this window seems more recently used than a newly-created, never-selected window. */ - ++window_select_count; - XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count); - - f->default_face_done_p = 0; + XWINDOW (FVAR (f, selected_window))->use_time = ++window_select_count; return f; } @@ -419,7 +376,7 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis CHECK_LIVE_WINDOW (mini_window); if (!NILP (mini_window) - && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb) + && FRAME_KBOARD (XFRAME (WVAR (XWINDOW (mini_window), frame))) != kb) error ("Frame and minibuffer must be on the same terminal"); /* Make a frame containing just a root window. */ @@ -441,14 +398,15 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis UNGCPRO; } - mini_window = XFRAME (KVAR (kb, Vdefault_minibuffer_frame))->minibuffer_window; + mini_window = FVAR (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)), + minibuffer_window); } - f->minibuffer_window = mini_window; + FVAR (f, minibuffer_window) = mini_window; /* Make the chosen minibuffer window display the proper minibuffer, unless it is already showing a minibuffer. */ - if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list))) + if (NILP (Fmemq (WVAR (XWINDOW (mini_window), buffer), Vminibuffer_list))) Fset_window_buffer (mini_window, (NILP (Vminibuffer_list) ? get_minibuffer (0) @@ -479,11 +437,11 @@ make_minibuffer_frame (void) Avoid infinite looping on the window chain by marking next pointer as nil. */ - mini_window = f->minibuffer_window = f->root_window; - XWINDOW (mini_window)->mini_p = Qt; - XWINDOW (mini_window)->next = Qnil; - XWINDOW (mini_window)->prev = Qnil; - XWINDOW (mini_window)->frame = frame; + mini_window = FVAR (f, minibuffer_window) = FVAR (f, root_window); + XWINDOW (mini_window)->mini = 1; + WVAR (XWINDOW (mini_window), next) = Qnil; + WVAR (XWINDOW (mini_window), prev) = Qnil; + WVAR (XWINDOW (mini_window), frame) = frame; /* Put the proper buffer in that window. */ @@ -520,7 +478,7 @@ make_initial_frame (void) Vframe_list = Fcons (frame, Vframe_list); tty_frame_count = 1; - f->name = make_pure_c_string ("F1"); + FVAR (f, name) = build_pure_c_string ("F1"); f->visible = 1; f->async_visible = 1; @@ -561,9 +519,7 @@ make_terminal_frame (struct terminal *terminal) XSETFRAME (frame, f); Vframe_list = Fcons (frame, Vframe_list); - tty_frame_count++; - sprintf (name, "F%"pMd, tty_frame_count); - f->name = build_string (name); + FVAR (f, name) = make_formatted_string (name, "F%"pMd, ++tty_frame_count); f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */ f->async_visible = 1; /* Don't let visible be cleared later. */ @@ -614,7 +570,7 @@ get_future_frame_param (Lisp_Object parameter, result = Fassq (parameter, supplied_parms); if (NILP (result)) - result = Fassq (parameter, XFRAME (selected_frame)->param_alist); + result = Fassq (parameter, FVAR (XFRAME (selected_frame), param_alist)); if (NILP (result) && current_value != NULL) result = build_string (current_value); if (!NILP (result) && !STRINGP (result)) @@ -630,8 +586,8 @@ DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame, doc: /* Create an additional terminal frame, possibly on another terminal. This function takes one argument, an alist specifying frame parameters. -You can create multiple frames on a single text-only terminal, but -only one of them (the selected terminal frame) is actually displayed. +You can create multiple frames on a single text terminal, but only one +of them (the selected terminal frame) is actually displayed. In practice, generally you don't need to specify any parameters, except when you want to create a new frame on another terminal. @@ -690,8 +646,8 @@ affects all frames on the same terminal device. */) : NULL)); if (!NILP (tty)) { - name = (char *) alloca (SBYTES (tty) + 1); - strncpy (name, SSDATA (tty), SBYTES (tty)); + name = alloca (SBYTES (tty) + 1); + memcpy (name, SSDATA (tty), SBYTES (tty)); name[SBYTES (tty)] = 0; } @@ -701,8 +657,8 @@ affects all frames on the same terminal device. */) : NULL)); if (!NILP (tty_type)) { - type = (char *) alloca (SBYTES (tty_type) + 1); - strncpy (type, SSDATA (tty_type), SBYTES (tty_type)); + type = alloca (SBYTES (tty_type) + 1); + memcpy (type, SSDATA (tty_type), SBYTES (tty_type)); type[SBYTES (tty_type)] = 0; } @@ -733,11 +689,11 @@ affects all frames on the same terminal device. */) /* Make the frame face alist be frame-specific, so that each frame could change its face definitions independently. */ - f->face_alist = Fcopy_alist (sf->face_alist); + FVAR (f, face_alist) = Fcopy_alist (FVAR (sf, face_alist)); /* Simple Fcopy_alist isn't enough, because we need the contents of the vectors which are the CDRs of associations in face_alist to be copied as well. */ - for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem)) + for (tem = FVAR (f, face_alist); CONSP (tem); tem = XCDR (tem)) XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem)))); return frame; } @@ -841,7 +797,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) last_nonminibuf_frame = XFRAME (selected_frame); - Fselect_window (XFRAME (frame)->selected_window, norecord); + Fselect_window (FVAR (XFRAME (frame), selected_window), norecord); /* We want to make sure that the next event generates a frame-switch event to the appropriate frame. This seems kludgy to me, but @@ -865,8 +821,8 @@ something to select a different frame, or until the next time this function is called. If you are using a window system, the previously selected frame may be restored as the selected frame when returning to the command loop, because it still may have -the window system's input focus. On a text-only terminal, the -next redisplay will display FRAME. +the window system's input focus. On a text terminal, the next +redisplay will display FRAME. This function returns FRAME, or nil if FRAME has been deleted. */) (Lisp_Object frame, Lisp_Object norecord) @@ -1118,41 +1074,32 @@ Otherwise, include all frames. */) static int other_visible_frames (FRAME_PTR f) { - /* We know the selected frame is visible, - so if F is some other frame, it can't be the sole visible one. */ - if (f == SELECTED_FRAME ()) - { - Lisp_Object frames; - int count = 0; + Lisp_Object frames; - for (frames = Vframe_list; - CONSP (frames); - frames = XCDR (frames)) - { - Lisp_Object this; + for (frames = Vframe_list; CONSP (frames); frames = XCDR (frames)) + { + Lisp_Object this = XCAR (frames); + if (f == XFRAME (this)) + continue; - this = XCAR (frames); - /* Verify that the frame's window still exists - and we can still talk to it. And note any recent change - in visibility. */ + /* Verify that we can still talk to the frame's X window, + and note any recent change in visibility. */ #ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (XFRAME (this))) - { - x_sync (XFRAME (this)); - FRAME_SAMPLE_VISIBILITY (XFRAME (this)); - } + if (FRAME_WINDOW_P (XFRAME (this))) + { + x_sync (XFRAME (this)); + FRAME_SAMPLE_VISIBILITY (XFRAME (this)); + } #endif - if (FRAME_VISIBLE_P (XFRAME (this)) - || FRAME_ICONIFIED_P (XFRAME (this)) - /* Allow deleting the terminal frame when at least - one X frame exists! */ - || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f))) - count++; - } - return count > 1; + if (FRAME_VISIBLE_P (XFRAME (this)) + || FRAME_ICONIFIED_P (XFRAME (this)) + /* Allow deleting the terminal frame when at least one X + frame exists. */ + || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f))) + return 1; } - return 1; + return 0; } /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME @@ -1161,10 +1108,6 @@ other_visible_frames (FRAME_PTR f) described for Fdelete_frame. */ Lisp_Object delete_frame (Lisp_Object frame, Lisp_Object force) - /* If we use `register' here, gcc-4.0.2 on amd64 using - -DUSE_LISP_UNION_TYPE complains further down that we're getting the - address of `force'. Go figure. */ - { struct frame *f; struct frame *sf = SELECTED_FRAME (); @@ -1267,7 +1210,17 @@ delete_frame (Lisp_Object frame, Lisp_Object force) FOR_EACH_FRAME (tail, frame1) { if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1))) - break; + { + /* Do not change a text terminal's top-frame. */ + struct frame *f1 = XFRAME (frame1); + if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1)) + { + Lisp_Object top_frame = FRAME_TTY (f1)->top_frame; + if (!EQ (top_frame, frame)) + frame1 = top_frame; + } + break; + } } } #ifdef NS_IMPL_COCOA @@ -1285,11 +1238,11 @@ delete_frame (Lisp_Object frame, Lisp_Object force) } /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) + if (EQ (FVAR (f, minibuffer_window), minibuf_window)) { - Fset_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer, Qnil); - minibuf_window = sf->minibuffer_window; + Fset_window_buffer (FVAR (sf, minibuffer_window), + WVAR (XWINDOW (minibuf_window), buffer), Qnil); + minibuf_window = FVAR (sf, minibuffer_window); /* If the dying minibuffer window was selected, select the new one. */ @@ -1298,8 +1251,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force) } /* Don't let echo_area_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, echo_area_window)) - echo_area_window = sf->minibuffer_window; + if (EQ (FVAR (f, minibuffer_window), echo_area_window)) + echo_area_window = FVAR (sf, minibuffer_window); /* Clear any X selections for this frame. */ #ifdef HAVE_X_WINDOWS @@ -1320,8 +1273,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force) /* Mark all the windows that used to be on FRAME as deleted, and then remove the reference to them. */ - delete_all_child_windows (f->root_window); - f->root_window = Qnil; + delete_all_child_windows (FVAR (f, root_window)); + FVAR (f, root_window) = Qnil; Vframe_list = Fdelq (frame, Vframe_list); FRAME_SET_VISIBLE (f, 0); @@ -1330,7 +1283,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force) garbage collection. The frame object itself may not be garbage collected until much later, because recent_keys and other data structures can still refer to it. */ - f->menu_bar_vector = Qnil; + FVAR (f, menu_bar_vector) = Qnil; free_font_driver_list (f); xfree (f->namebuf); @@ -1612,8 +1565,8 @@ before calling this function on it, like this. (Lisp_Object frame, Lisp_Object x, Lisp_Object y) { CHECK_LIVE_FRAME (frame); - CHECK_NUMBER (x); - CHECK_NUMBER (y); + CHECK_TYPE_RANGED_INTEGER (int, x); + CHECK_TYPE_RANGED_INTEGER (int, y); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1653,8 +1606,8 @@ before calling this function on it, like this. (Lisp_Object frame, Lisp_Object x, Lisp_Object y) { CHECK_LIVE_FRAME (frame); - CHECK_NUMBER (x); - CHECK_NUMBER (y); + CHECK_TYPE_RANGED_INTEGER (int, x); + CHECK_TYPE_RANGED_INTEGER (int, y); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1703,7 +1656,7 @@ If omitted, FRAME defaults to the currently selected frame. */) } #endif - make_frame_visible_1 (XFRAME (frame)->root_window); + make_frame_visible_1 (FVAR (XFRAME (frame), root_window)); /* Make menu bar update for the Buffers and Frames menus. */ windows_or_buffers_changed++; @@ -1719,17 +1672,17 @@ make_frame_visible_1 (Lisp_Object window) { struct window *w; - for (;!NILP (window); window = w->next) + for (;!NILP (window); window = WVAR (w, next)) { w = XWINDOW (window); - if (!NILP (w->buffer)) - BVAR (XBUFFER (w->buffer), display_time) = Fcurrent_time (); + if (!NILP (WVAR (w, buffer))) + BVAR (XBUFFER (WVAR (w, buffer)), display_time) = Fcurrent_time (); - if (!NILP (w->vchild)) - make_frame_visible_1 (w->vchild); - if (!NILP (w->hchild)) - make_frame_visible_1 (w->hchild); + if (!NILP (WVAR (w, vchild))) + make_frame_visible_1 (WVAR (w, vchild)); + if (!NILP (WVAR (w, hchild))) + make_frame_visible_1 (WVAR (w, hchild)); } } @@ -1743,8 +1696,8 @@ usually not displayed at all, even in a window system's \"taskbar\". Normally you may not make FRAME invisible if all other frames are invisible, but if the second optional argument FORCE is non-nil, you may do so. -This function has no effect on text-only terminal frames. Such frames -are always considered visible, whether or not they are currently being +This function has no effect on text terminal frames. Such frames are +always considered visible, whether or not they are currently being displayed in the terminal. */) (Lisp_Object frame, Lisp_Object force) { @@ -1756,19 +1709,13 @@ displayed in the terminal. */) if (NILP (force) && !other_visible_frames (XFRAME (frame))) error ("Attempt to make invisible the sole visible or iconified frame"); -#if 0 /* This isn't logically necessary, and it can do GC. */ - /* Don't let the frame remain selected. */ - if (EQ (frame, selected_frame)) - do_switch_frame (next_frame (frame, Qt), 0, 0, Qnil) -#endif - /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) + if (EQ (FVAR (XFRAME (frame), minibuffer_window), minibuf_window)) { struct frame *sf = XFRAME (selected_frame); - Fset_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer, Qnil); - minibuf_window = sf->minibuffer_window; + Fset_window_buffer (FVAR (sf, minibuffer_window), + WVAR (XWINDOW (minibuf_window), buffer), Qnil); + minibuf_window = FVAR (sf, minibuffer_window); } /* I think this should be done with a hook. */ @@ -1801,12 +1748,12 @@ If omitted, FRAME defaults to the currently selected frame. */) #endif /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) + if (EQ (FVAR (XFRAME (frame), minibuffer_window), minibuf_window)) { struct frame *sf = XFRAME (selected_frame); - Fset_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->buffer, Qnil); - minibuf_window = sf->minibuffer_window; + Fset_window_buffer (FVAR (sf, minibuffer_window), + WVAR (XWINDOW (minibuf_window), buffer), Qnil); + minibuf_window = FVAR (sf, minibuffer_window); } /* I think this should be done with a hook. */ @@ -1829,7 +1776,7 @@ Return nil if FRAME was made invisible, via `make-frame-invisible'. On graphical displays, invisible frames are not updated and are usually not displayed at all, even in a window system's \"taskbar\". -If FRAME is a text-only terminal frame, this always returns t. +If FRAME is a text terminal frame, this always returns t. Such frames are always considered visible, whether or not they are currently being displayed on the terminal. */) (Lisp_Object frame) @@ -1885,7 +1832,7 @@ doesn't support multiple overlapping frames, this function selects FRAME. */) f = XFRAME (frame); if (FRAME_TERMCAP_P (f)) - /* On a text-only terminal select FRAME. */ + /* On a text terminal select FRAME. */ Fselect_frame (frame, Qnil); else /* Do like the documentation says. */ @@ -1928,8 +1875,8 @@ In other words, switch-frame events caused by events in FRAME will request a switch to FOCUS-FRAME, and `last-event-frame' will be FOCUS-FRAME after reading an event typed at FRAME. -If FOCUS-FRAME is omitted or nil, any existing redirection is -canceled, and the frame again receives its own keystrokes. +If FOCUS-FRAME is nil, any existing redirection is canceled, and the +frame again receives its own keystrokes. Focus redirection is useful for temporarily redirecting keystrokes to a surrogate minibuffer frame when a frame doesn't have its own @@ -1960,7 +1907,7 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */) f = XFRAME (frame); - f->focus_frame = focus_frame; + FVAR (f, focus_frame) = focus_frame; if (FRAME_TERMINAL (f)->frame_rehighlight_hook) (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f); @@ -1984,6 +1931,7 @@ See `redirect-frame-focus'. */) /* Return the value of frame parameter PROP in frame FRAME. */ +#ifdef HAVE_WINDOW_SYSTEM #if !HAVE_NS static #endif @@ -1992,18 +1940,19 @@ get_frame_param (register struct frame *frame, Lisp_Object prop) { register Lisp_Object tem; - tem = Fassq (prop, frame->param_alist); + tem = Fassq (prop, FVAR (frame, param_alist)); if (EQ (tem, Qnil)) return tem; return Fcdr (tem); } +#endif /* Return the buffer-predicate of the selected frame. */ Lisp_Object frame_buffer_predicate (Lisp_Object frame) { - return XFRAME (frame)->buffer_predicate; + return FVAR (XFRAME (frame), buffer_predicate); } /* Return the buffer-list of the selected frame. */ @@ -2011,7 +1960,7 @@ frame_buffer_predicate (Lisp_Object frame) static Lisp_Object frame_buffer_list (Lisp_Object frame) { - return XFRAME (frame)->buffer_list; + return FVAR (XFRAME (frame), buffer_list); } /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */ @@ -2023,10 +1972,10 @@ frames_discard_buffer (Lisp_Object buffer) FOR_EACH_FRAME (tail, frame) { - XFRAME (frame)->buffer_list - = Fdelq (buffer, XFRAME (frame)->buffer_list); - XFRAME (frame)->buried_buffer_list - = Fdelq (buffer, XFRAME (frame)->buried_buffer_list); + FVAR (XFRAME (frame), buffer_list) + = Fdelq (buffer, FVAR (XFRAME (frame), buffer_list)); + FVAR (XFRAME (frame), buried_buffer_list) + = Fdelq (buffer, FVAR (XFRAME (frame), buried_buffer_list)); } } @@ -2046,7 +1995,7 @@ store_in_alist (Lisp_Object *alistptr, Lisp_Object prop, Lisp_Object val) } static int -frame_name_fnn_p (char *str, EMACS_INT len) +frame_name_fnn_p (char *str, ptrdiff_t len) { if (len > 1 && str[0] == 'F' && '0' <= str[1] && str[1] <= '9') { @@ -2074,20 +2023,18 @@ set_term_frame_name (struct frame *f, Lisp_Object name) /* Check for no change needed in this very common case before we do any consing. */ - if (frame_name_fnn_p (SSDATA (f->name), - SBYTES (f->name))) + if (frame_name_fnn_p (SSDATA (FVAR (f, name)), + SBYTES (FVAR (f, name)))) return; - tty_frame_count++; - sprintf (namebuf, "F%"pMd, tty_frame_count); - name = build_string (namebuf); + name = make_formatted_string (namebuf, "F%"pMd, ++tty_frame_count); } else { CHECK_STRING (name); /* Don't change the name if it's already NAME. */ - if (! NILP (Fstring_equal (name, f->name))) + if (! NILP (Fstring_equal (name, FVAR (f, name)))) return; /* Don't allow the user to set the frame name to F, so it @@ -2096,7 +2043,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name) error ("Frame names of the form F are usurped by Emacs"); } - f->name = name; + FVAR (f, name) = name; update_mode_lines = 1; } @@ -2113,7 +2060,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) for (; CONSP (val); val = XCDR (val)) if (!NILP (Fbuffer_live_p (XCAR (val)))) list = Fcons (XCAR (val), list); - f->buffer_list = Fnreverse (list); + FVAR (f, buffer_list) = Fnreverse (list); return; } if (EQ (prop, Qburied_buffer_list)) @@ -2122,7 +2069,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) for (; CONSP (val); val = XCDR (val)) if (!NILP (Fbuffer_live_p (XCAR (val)))) list = Fcons (XCAR (val), list); - f->buried_buffer_list = Fnreverse (list); + FVAR (f, buried_buffer_list) = Fnreverse (list); return; } @@ -2157,9 +2104,9 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) FRAME_TTY (f)->previous_frame = NULL; /* Update the frame parameter alist. */ - old_alist_elt = Fassq (prop, f->param_alist); + old_alist_elt = Fassq (prop, FVAR (f, param_alist)); if (EQ (old_alist_elt, Qnil)) - f->param_alist = Fcons (Fcons (prop, val), f->param_alist); + FVAR (f, param_alist) = Fcons (Fcons (prop, val), FVAR (f, param_alist)); else Fsetcdr (old_alist_elt, val); @@ -2167,7 +2114,7 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) in addition to the alist. */ if (EQ (prop, Qbuffer_predicate)) - f->buffer_predicate = val; + FVAR (f, buffer_predicate) = val; if (! FRAME_WINDOW_P (f)) { @@ -2183,11 +2130,11 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) error ("Surrogate minibuffer windows must be minibuffer windows"); if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f)) - && !EQ (val, f->minibuffer_window)) + && !EQ (val, FVAR (f, minibuffer_window))) error ("Can't change the surrogate minibuffer of a frame with its own minibuffer"); /* Install the chosen minibuffer window, with proper buffer. */ - f->minibuffer_window = val; + FVAR (f, minibuffer_window) = val; } } @@ -2212,7 +2159,7 @@ If FRAME is omitted, return information on the currently selected frame. */) if (!FRAME_LIVE_P (f)) return Qnil; - alist = Fcopy_alist (f->param_alist); + alist = Fcopy_alist (FVAR (f, param_alist)); GCPRO1 (alist); if (!FRAME_WINDOW_P (f)) @@ -2258,7 +2205,7 @@ If FRAME is omitted, return information on the currently selected frame. */) : FRAME_W32_P (f) ? "w32term" :"tty")); } - store_in_alist (&alist, Qname, f->name); + store_in_alist (&alist, Qname, FVAR (f, name)); height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f)); store_in_alist (&alist, Qheight, make_number (height)); width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f)); @@ -2270,7 +2217,8 @@ If FRAME is omitted, return information on the currently selected frame. */) : FRAME_MINIBUF_WINDOW (f))); store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil)); store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame)); - store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list); + store_in_alist (&alist, Qburied_buffer_list, + FVAR (XFRAME (frame), buried_buffer_list)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -2311,7 +2259,7 @@ If FRAME is nil, describe the currently selected frame. */) { /* Avoid consing in frequent cases. */ if (EQ (parameter, Qname)) - value = f->name; + value = FVAR (f, name); #ifdef HAVE_X_WINDOWS else if (EQ (parameter, Qdisplay) && FRAME_X_P (f)) value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element); @@ -2319,7 +2267,7 @@ If FRAME is nil, describe the currently selected frame. */) else if (EQ (parameter, Qbackground_color) || EQ (parameter, Qforeground_color)) { - value = Fassq (parameter, f->param_alist); + value = Fassq (parameter, FVAR (f, param_alist)); if (CONSP (value)) { value = XCDR (value); @@ -2330,7 +2278,7 @@ If FRAME is nil, describe the currently selected frame. */) if (STRINGP (value) && !FRAME_WINDOW_P (f)) { const char *color_name; - EMACS_INT csz; + ptrdiff_t csz; if (EQ (parameter, Qbackground_color)) { @@ -2357,7 +2305,7 @@ If FRAME is nil, describe the currently selected frame. */) } else if (EQ (parameter, Qdisplay_type) || EQ (parameter, Qbackground_mode)) - value = Fcdr (Fassq (parameter, f->param_alist)); + value = Fcdr (Fassq (parameter, FVAR (f, param_alist))); else /* FIXME: Avoid this code path at all (as well as code duplication) by sharing more code with Fframe_parameters. */ @@ -2406,12 +2354,13 @@ use is not recommended. Explicitly check for a frame-parameter instead. */) #endif { - int length = XINT (Flength (alist)); - int i; - Lisp_Object *parms - = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); - Lisp_Object *values - = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); + EMACS_INT length = XFASTINT (Flength (alist)); + ptrdiff_t i; + Lisp_Object *parms; + Lisp_Object *values; + USE_SAFE_ALLOCA; + SAFE_ALLOCA_LISP (parms, 2 * length); + values = parms + length; /* Extract parm names and values into those vectors. */ @@ -2437,6 +2386,8 @@ use is not recommended. Explicitly check for a frame-parameter instead. */) || EQ (prop, Qbackground_color)) update_face_from_frame_parameter (f, prop, val); } + + SAFE_FREE (); } return Qnil; } @@ -2503,7 +2454,7 @@ not the menu bar). In a graphical version with no toolkit, it includes both the tool bar and menu bar. -For a text-only terminal, it includes the menu bar. In this case, the +For a text terminal, it includes the menu bar. In this case, the result is really in characters rather than pixels (i.e., is identical to `frame-height'). */) (Lisp_Object frame) @@ -2553,16 +2504,13 @@ or right side of FRAME. If FRAME is omitted, the selected frame is used. */) (Lisp_Object frame) { - struct frame *f; - if (NILP (frame)) frame = selected_frame; CHECK_FRAME (frame); - f = XFRAME (frame); #ifdef FRAME_TOOLBAR_WIDTH - if (FRAME_WINDOW_P (f)) - return make_number (FRAME_TOOLBAR_WIDTH (f)); + if (FRAME_WINDOW_P (XFRAME (frame))) + return make_number (FRAME_TOOLBAR_WIDTH (XFRAME (frame))); #endif return make_number (0); } @@ -2575,7 +2523,7 @@ but that the idea of the actual height of the frame should not be changed. */) { register struct frame *f; - CHECK_NUMBER (lines); + CHECK_TYPE_RANGED_INTEGER (int, lines); if (NILP (frame)) frame = selected_frame; CHECK_LIVE_FRAME (frame); @@ -2602,7 +2550,7 @@ but that the idea of the actual width of the frame should not be changed. */) (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend) { register struct frame *f; - CHECK_NUMBER (cols); + CHECK_TYPE_RANGED_INTEGER (int, cols); if (NILP (frame)) frame = selected_frame; CHECK_LIVE_FRAME (frame); @@ -2629,8 +2577,8 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, register struct frame *f; CHECK_LIVE_FRAME (frame); - CHECK_NUMBER (cols); - CHECK_NUMBER (rows); + CHECK_TYPE_RANGED_INTEGER (int, cols); + CHECK_TYPE_RANGED_INTEGER (int, rows); f = XFRAME (frame); /* I think this should be done with a hook. */ @@ -2661,8 +2609,8 @@ the rightmost or bottommost possible position (that stays within the screen). * register struct frame *f; CHECK_LIVE_FRAME (frame); - CHECK_NUMBER (xoffset); - CHECK_NUMBER (yoffset); + CHECK_TYPE_RANGED_INTEGER (int, xoffset); + CHECK_TYPE_RANGED_INTEGER (int, yoffset); f = XFRAME (frame); /* I think this should be done with a hook. */ @@ -2808,11 +2756,11 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) struct gcpro gcpro1, gcpro2; i = 0; - for (tail = alist; CONSP (tail); tail = Fcdr (tail)) + for (tail = alist; CONSP (tail); tail = XCDR (tail)) i++; - parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); - values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); + parms = alloca (i * sizeof *parms); + values = alloca (i * sizeof *values); /* Extract parm names and values into those vectors. */ @@ -2881,12 +2829,12 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) prop = parms[i]; val = values[i]; - if (EQ (prop, Qwidth) && NATNUMP (val)) + if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX)) { size_changed = 1; width = XFASTINT (val); } - else if (EQ (prop, Qheight) && NATNUMP (val)) + else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX)) { size_changed = 1; height = XFASTINT (val); @@ -2940,17 +2888,17 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) } /* If one of the icon positions was not set, preserve or default it. */ - if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left)) + if (! TYPE_RANGED_INTEGERP (int, icon_left)) { icon_left_no_change = 1; - icon_left = Fcdr (Fassq (Qicon_left, f->param_alist)); + icon_left = Fcdr (Fassq (Qicon_left, FVAR (f, param_alist))); if (NILP (icon_left)) XSETINT (icon_left, 0); } - if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top)) + if (! TYPE_RANGED_INTEGERP (int, icon_top)) { icon_top_no_change = 1; - icon_top = Fcdr (Fassq (Qicon_top, f->param_alist)); + icon_top = Fcdr (Fassq (Qicon_top, FVAR (f, param_alist))); if (NILP (icon_top)) XSETINT (icon_top, 0); } @@ -3099,22 +3047,18 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr) actually a pointer. Explicit casting avoids compiler warnings. */ w = (unsigned long) FRAME_X_WINDOW (f); - sprintf (buf, "%lu", w); store_in_alist (alistptr, Qwindow_id, - build_string (buf)); + make_formatted_string (buf, "%lu", w)); #ifdef HAVE_X_WINDOWS #ifdef USE_X_TOOLKIT /* Tooltip frame may not have this widget. */ if (FRAME_X_OUTPUT (f)->widget) #endif - { - w = (unsigned long) FRAME_OUTER_WINDOW (f); - sprintf (buf, "%lu", w); - } + w = (unsigned long) FRAME_OUTER_WINDOW (f); store_in_alist (alistptr, Qouter_window_id, - build_string (buf)); + make_formatted_string (buf, "%lu", w)); #endif - store_in_alist (alistptr, Qicon_name, f->icon_name); + store_in_alist (alistptr, Qicon_name, FVAR (f, icon_name)); FRAME_SAMPLE_VISIBILITY (f); store_in_alist (alistptr, Qvisibility, (FRAME_VISIBLE_P (f) ? Qt @@ -3128,7 +3072,7 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr) XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc); store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil)); store_in_alist (alistptr, Qparent_id, tem); - store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position); + store_in_alist (alistptr, Qtool_bar_position, FVAR (f, tool_bar_position)); } @@ -3162,7 +3106,7 @@ x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu { if (NILP (new_value)) f->extra_line_spacing = 0; - else if (NATNUMP (new_value)) + else if (RANGED_INTEGERP (0, new_value, INT_MAX)) f->extra_line_spacing = XFASTINT (new_value); else signal_error ("Invalid line-spacing", new_value); @@ -3188,7 +3132,7 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu signal_error ("Invalid screen-gamma", new_value); /* Apply the new gamma value to the frame background. */ - bgcolor = Fassq (Qbackground_color, f->param_alist); + bgcolor = Fassq (Qbackground_color, FVAR (f, param_alist)); if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor))) { Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter); @@ -3207,8 +3151,11 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu void x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { - Lisp_Object font_object, font_param = Qnil; + Lisp_Object font_object; int fontset = -1; +#ifdef HAVE_X_WINDOWS + Lisp_Object font_param = arg; +#endif /* Set the frame parameter back to the old value because we may fail to use ARG as the new parameter value. */ @@ -3219,20 +3166,17 @@ x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) never fail. */ if (STRINGP (arg)) { - font_param = arg; fontset = fs_query_fontset (arg, 0); if (fontset < 0) { - font_object = font_open_by_name (f, SSDATA (arg)); + font_object = font_open_by_name (f, arg); if (NILP (font_object)) error ("Font `%s' is not defined", SSDATA (arg)); arg = AREF (font_object, FONT_NAME_INDEX); } else if (fontset > 0) { - Lisp_Object ascii_font = fontset_ascii (fontset); - - font_object = font_open_by_name (f, SSDATA (ascii_font)); + font_object = font_open_by_name (f, fontset_ascii (fontset)); if (NILP (font_object)) error ("Font `%s' is not defined", SDATA (arg)); arg = AREF (font_object, FONT_NAME_INDEX); @@ -3250,12 +3194,16 @@ x_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) error ("Unknown fontset: %s", SDATA (XCAR (arg))); font_object = XCDR (arg); arg = AREF (font_object, FONT_NAME_INDEX); +#ifdef HAVE_X_WINDOWS font_param = Ffont_get (font_object, QCname); +#endif } else if (FONT_OBJECT_P (arg)) { font_object = arg; +#ifdef HAVE_X_WINDOWS font_param = Ffont_get (font_object, QCname); +#endif /* This is to store the XLFD font name in the frame parameter for backward compatibility. We should store the font-object itself in the future. */ @@ -3371,7 +3319,7 @@ x_set_fringe_width (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu void x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { - CHECK_NUMBER (arg); + CHECK_TYPE_RANGED_INTEGER (int, arg); if (XINT (arg) == f->border_width) return; @@ -3387,7 +3335,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva { int old = FRAME_INTERNAL_BORDER_WIDTH (f); - CHECK_NUMBER (arg); + CHECK_TYPE_RANGED_INTEGER (int, arg); FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg); if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0) FRAME_INTERNAL_BORDER_WIDTH (f) = 0; @@ -3513,7 +3461,7 @@ x_icon_type (FRAME_PTR f) { Lisp_Object tem; - tem = assq_no_quit (Qicon_type, f->param_alist); + tem = assq_no_quit (Qicon_type, FVAR (f, param_alist)); if (CONSP (tem)) return XCDR (tem); else @@ -3673,17 +3621,17 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li /* Allocate space for the components, the dots which separate them, and the final '\0'. Make them big enough for the worst case. */ - name_key = (char *) alloca (SBYTES (Vx_resource_name) - + (STRINGP (component) - ? SBYTES (component) : 0) - + SBYTES (attribute) - + 3); - - class_key = (char *) alloca (SBYTES (Vx_resource_class) - + SBYTES (class) - + (STRINGP (subclass) - ? SBYTES (subclass) : 0) - + 3); + name_key = alloca (SBYTES (Vx_resource_name) + + (STRINGP (component) + ? SBYTES (component) : 0) + + SBYTES (attribute) + + 3); + + class_key = alloca (SBYTES (Vx_resource_class) + + SBYTES (class) + + (STRINGP (subclass) + ? SBYTES (subclass) : 0) + + 3); /* Start with emacs.FRAMENAME for the name (the specific one) and with `Emacs' for the class key (the general one). */ @@ -3759,8 +3707,7 @@ x_get_resource_string (const char *attribute, const char *class) /* Allocate space for the components, the dots which separate them, and the final '\0'. */ SAFE_ALLOCA (name_key, char *, invocation_namelen + strlen (attribute) + 2); - class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) - + strlen (class) + 2); + class_key = alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2); esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); sprintf (class_key, "%s.%s", EMACS_CLASS, class); @@ -3952,7 +3899,7 @@ On Nextstep, this just calls `ns-parse-geometry'. */) (Lisp_Object string) { #ifdef HAVE_NS - call1 (Qns_parse_geometry, string); + return call1 (Qns_parse_geometry, string); #else int geometry, x, y; unsigned int width, height; @@ -4124,7 +4071,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p) f->top_pos = 0; else { - CHECK_NUMBER (tem0); + CHECK_TYPE_RANGED_INTEGER (int, tem0); f->top_pos = XINT (tem0); if (f->top_pos < 0) window_prompting |= YNegative; @@ -4152,7 +4099,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p) f->left_pos = 0; else { - CHECK_NUMBER (tem1); + CHECK_TYPE_RANGED_INTEGER (int, tem1); f->left_pos = XINT (tem1); if (f->left_pos < 0) window_prompting |= XNegative;