+/* Width of a scroll bar in frame F, measured in columns (characters),
+ but only if scroll bars are on the left. If scroll bars are on
+ the right in this frame, or there are no scroll bars, value is 0. */
+
+#define FRAME_LEFT_SCROLL_BAR_COLS(f) \
+ (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \
+ ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
+ : 0)
+
+/* Width of a left scroll bar in frame F, measured in pixels */
+
+#define FRAME_LEFT_SCROLL_BAR_AREA_WIDTH(f) \
+ (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \
+ ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \
+ : 0)
+
+/* Width of a scroll bar in frame F, measured in columns (characters),
+ but only if scroll bars are on the right. If scroll bars are on
+ the left in this frame, or there are no scroll bars, value is 0. */
+
+#define FRAME_RIGHT_SCROLL_BAR_COLS(f) \
+ (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \
+ ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
+ : 0)
+
+/* Width of a right scroll bar area in frame F, measured in pixels */
+
+#define FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH(f) \
+ (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \
+ ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \
+ : 0)
+
+/* Actual width of a scroll bar in frame F, measured in columns. */
+
+#define FRAME_SCROLL_BAR_COLS(f) \
+ (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
+ ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
+ : 0)
+
+/* Actual width of a scroll bar area in frame F, measured in pixels. */
+
+#define FRAME_SCROLL_BAR_AREA_WIDTH(f) \
+ (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
+ ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \
+ : 0)
+
+/* Total width of frame F, in columns (characters),
+ including the width used by scroll bars if any. */
+
+#define FRAME_TOTAL_COLS(f) ((f)->total_cols)
+
+/* Set the width of frame F to VAL.
+ VAL is the width of a full-frame window,
+ not including scroll bars and fringes. */
+
+#define SET_FRAME_COLS(f, val) \
+ (FRAME_COLS (f) = (val), \
+ (f)->total_cols = FRAME_TOTAL_COLS_ARG (f, FRAME_COLS (f)))
+
+/* Given a value WIDTH for frame F's nominal width,
+ return the value that FRAME_TOTAL_COLS should have. */
+
+#define FRAME_TOTAL_COLS_ARG(f, width) \
+ ((width) \
+ + FRAME_SCROLL_BAR_COLS (f) \
+ + FRAME_FRINGE_COLS (f))
+
+/* Maximum + 1 legitimate value for FRAME_CURSOR_X. */
+
+#define FRAME_CURSOR_X_LIMIT(f) \
+ (FRAME_COLS (f) + FRAME_LEFT_SCROLL_BAR_COLS (f))
+
+/* Nonzero if frame F has scroll bars. */
+
+#define FRAME_SCROLL_BARS(f) ((f)->scroll_bars)
+
+#define FRAME_CONDEMNED_SCROLL_BARS(f) ((f)->condemned_scroll_bars)
+#define FRAME_MENU_BAR_ITEMS(f) ((f)->menu_bar_items)
+#define FRAME_COST_BAUD_RATE(f) ((f)->cost_calculation_baud_rate)
+
+#define FRAME_DESIRED_CURSOR(f) ((f)->desired_cursor)
+#define FRAME_BLINK_OFF_CURSOR(f) ((f)->blink_off_cursor)
+#define FRAME_CURSOR_WIDTH(f) ((f)->cursor_width)
+#define FRAME_BLINK_OFF_CURSOR_WIDTH(f) ((f)->blink_off_cursor_width)
+
+/* Return a pointer to the face cache of frame F. */
+
+#define FRAME_FACE_CACHE(F) (F)->face_cache
+
+/* Return the size of message_buf of the frame F. We multiply the
+ width of the frame by 4 because multi-byte form may require at most
+ 4-byte for a character. */
+
+#define FRAME_MESSAGE_BUF_SIZE(f) (((int) FRAME_COLS (f)) * 4)
+
+/* Emacs's redisplay code could become confused if a frame's
+ visibility changes at arbitrary times. For example, if a frame is
+ visible while the desired glyphs are being built, but becomes
+ invisible before they are updated, then some rows of the
+ desired_glyphs will be left marked as enabled after redisplay is
+ complete, which should never happen. The next time the frame
+ becomes visible, redisplay will probably barf.
+
+ Currently, there are no similar situations involving iconified, but
+ the principle is the same.
+
+ So instead of having asynchronous input handlers directly set and
+ clear the frame's visibility and iconification flags, they just set
+ the async_visible and async_iconified flags; the redisplay code
+ calls the FRAME_SAMPLE_VISIBILITY macro before doing any redisplay,
+ which sets visible and iconified from their asynchronous
+ counterparts.
+
+ Synchronous code must use the FRAME_SET_VISIBLE macro.
+
+ Also, if a frame used to be invisible, but has just become visible,
+ it must be marked as garbaged, since redisplay hasn't been keeping
+ up its contents. */
+
+#define FRAME_SAMPLE_VISIBILITY(f) \
+ (((f)->async_visible && (f)->visible != (f)->async_visible) ? \
+ SET_FRAME_GARBAGED (f) : 0, \
+ (f)->visible = (f)->async_visible, \
+ (f)->iconified = (f)->async_iconified)
+
+#define CHECK_FRAME(x) \
+ do { \
+ if (! FRAMEP (x)) \
+ x = wrong_type_argument (Qframep, (x)); \
+ } while (0)
+
+#define CHECK_LIVE_FRAME(x) \
+ do { \
+ if (! FRAMEP (x) \
+ || ! FRAME_LIVE_P (XFRAME (x))) \
+ x = wrong_type_argument (Qframe_live_p, (x)); \
+ } while (0)
+
+/* FOR_EACH_FRAME (LIST_VAR, FRAME_VAR) followed by a statement is a
+ `for' loop which iterates over the elements of Vframe_list. The
+ loop will set FRAME_VAR, a Lisp_Object, to each frame in
+ Vframe_list in succession and execute the statement. LIST_VAR
+ should be a Lisp_Object too; it is used to iterate through the
+ Vframe_list.
+
+ This macro is a holdover from a time when multiple frames weren't always
+ supported. An alternate definition of the macro would expand to
+ something which executes the statement once. */
+
+#define FOR_EACH_FRAME(list_var, frame_var) \
+ for ((list_var) = Vframe_list; \
+ (CONSP (list_var) \
+ && (frame_var = XCAR (list_var), 1)); \
+ list_var = XCDR (list_var))
+
+
+extern Lisp_Object Qframep, Qframe_live_p;
+
+extern struct frame *last_nonminibuf_frame;
+
+extern struct frame *make_terminal_frame P_ ((void));
+extern struct frame *make_frame P_ ((int));
+#ifdef HAVE_WINDOW_SYSTEM
+extern struct frame *make_minibuffer_frame P_ ((void));
+extern struct frame *make_frame_without_minibuffer P_ ((Lisp_Object,
+ struct kboard *,
+ Lisp_Object));
+#endif /* HAVE_WINDOW_SYSTEM */
+extern int other_visible_frames P_ ((struct frame *));
+
+extern Lisp_Object Vframe_list;
+extern Lisp_Object Vdefault_frame_alist;
+
+extern Lisp_Object Vterminal_frame;
+
+extern Lisp_Object Vmouse_highlight;
+
+enum text_cursor_kinds get_specified_cursor_type P_ ((Lisp_Object, int *));
+enum text_cursor_kinds get_window_cursor_type P_ ((struct window *, int *, int *));
+\f
+/* The currently selected frame. */
+
+extern Lisp_Object selected_frame;
+
+/* Value is a pointer to the selected frame. If the selected frame
+ isn't live, abort. */
+
+#define SELECTED_FRAME() \
+ ((FRAMEP (selected_frame) \
+ && FRAME_LIVE_P (XFRAME (selected_frame))) \
+ ? XFRAME (selected_frame) \
+ : (abort (), (struct frame *) 0))
+
+\f
+/***********************************************************************
+ Display-related Macros
+ ***********************************************************************/
+
+/* Canonical y-unit on frame F.
+ This value currently equals the line height of the frame (which is
+ the height of the default font of F). */
+
+#define FRAME_LINE_HEIGHT(F) ((F)->line_height)
+
+/* Canonical x-unit on frame F.
+ This value currently equals the width of the default font of F. */
+
+#define FRAME_COLUMN_WIDTH(F) ((F)->column_width)
+
+
+/* Pixel width of areas used to display truncation marks, continuation
+ marks, overlay arrows. This is 0 for terminal frames. */
+
+#ifdef HAVE_WINDOW_SYSTEM
+
+/* Total width of fringes reserved for drawing truncation bitmaps,
+ continuation bitmaps and alike. The width is in canonical char
+ units of the frame. This must currently be the case because window
+ sizes aren't pixel values. If it weren't the case, we wouldn't be
+ able to split windows horizontally nicely. */
+
+#define FRAME_FRINGE_COLS(F) ((F)->fringe_cols)
+
+/* Pixel-width of the left and right fringe. */
+
+#define FRAME_LEFT_FRINGE_WIDTH(F) ((F)->left_fringe_width)
+#define FRAME_RIGHT_FRINGE_WIDTH(F) ((F)->right_fringe_width)
+
+/* Total width of fringes in pixels. */
+
+#define FRAME_TOTAL_FRINGE_WIDTH(F) \
+ (FRAME_LEFT_FRINGE_WIDTH (F) + FRAME_RIGHT_FRINGE_WIDTH (F))
+
+
+/* Pixel-width of internal border lines */
+
+#define FRAME_INTERNAL_BORDER_WIDTH(F) ((F)->internal_border_width)
+
+#else /* not HAVE_WINDOW_SYSTEM */
+
+#define FRAME_FRINGE_COLS(F) 0
+#define FRAME_TOTAL_FRINGE_WIDTH(F) 0
+#define FRAME_LEFT_FRINGE_WIDTH(F) 0
+#define FRAME_RIGHT_FRINGE_WIDTH(F) 0
+#define FRAME_INTERNAL_BORDER_WIDTH(F) 0
+
+#endif /* not HAVE_WINDOW_SYSTEM */
+
+
+
+\f
+/***********************************************************************
+ Conversion between canonical units and pixels
+ ***********************************************************************/
+
+/* Canonical x-values are fractions of FRAME_COLUMN_WIDTH, canonical
+ y-unit are fractions of FRAME_LINE_HEIGHT of a frame. Both are
+ represented as Lisp numbers, i.e. integers or floats. */
+
+/* Convert canonical value X to pixels. F is the frame whose
+ canonical char width is to be used. X must be a Lisp integer or
+ float. Value is a C integer. */
+
+#define FRAME_PIXEL_X_FROM_CANON_X(F, X) \
+ (INTEGERP (X) \
+ ? XINT (X) * FRAME_COLUMN_WIDTH (F) \
+ : (int) (XFLOAT_DATA (X) * FRAME_COLUMN_WIDTH (F)))
+
+/* Convert canonical value Y to pixels. F is the frame whose
+ canonical character height is to be used. X must be a Lisp integer
+ or float. Value is a C integer. */
+
+#define FRAME_PIXEL_Y_FROM_CANON_Y(F, Y) \
+ (INTEGERP (Y) \
+ ? XINT (Y) * FRAME_LINE_HEIGHT (F) \
+ : (int) (XFLOAT_DATA (Y) * FRAME_LINE_HEIGHT (F)))
+
+/* Convert pixel-value X to canonical units. F is the frame whose
+ canonical character width is to be used. X is a C integer. Result
+ is a Lisp float if X is not a multiple of the canon width,
+ otherwise it's a Lisp integer. */
+
+#define FRAME_CANON_X_FROM_PIXEL_X(F, X) \
+ ((X) % FRAME_COLUMN_WIDTH (F) != 0 \
+ ? make_float ((double) (X) / FRAME_COLUMN_WIDTH (F)) \
+ : make_number ((X) / FRAME_COLUMN_WIDTH (F)))
+
+/* Convert pixel-value Y to canonical units. F is the frame whose
+ canonical character height is to be used. Y is a C integer.
+ Result is a Lisp float if Y is not a multiple of the canon width,
+ otherwise it's a Lisp integer. */
+
+#define FRAME_CANON_Y_FROM_PIXEL_Y(F, Y) \
+ ((Y) % FRAME_LINE_HEIGHT (F) \
+ ? make_float ((double) (Y) / FRAME_LINE_HEIGHT (F)) \
+ : make_number ((Y) / FRAME_LINE_HEIGHT (F)))