lisp/emacs-lisp/tabulated-list.el: Use defvar-local, setq-local.
[bpt/emacs.git] / src / frame.h
index 35cbc44..31d3e73 100644 (file)
@@ -1,5 +1,5 @@
 /* Define frame-object for GNU Emacs.
 /* Define frame-object for GNU Emacs.
-   Copyright (C) 1993-1994, 1999-2012 Free Software Foundation, Inc.
+   Copyright (C) 1993-1994, 1999-2013 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -18,7 +18,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Don't multiply include: dispextern.h includes macterm.h which
    includes frame.h some emacs source includes both dispextern.h and
 
 /* Don't multiply include: dispextern.h includes macterm.h which
    includes frame.h some emacs source includes both dispextern.h and
-   frame.h */
+   frame.h */
 
 #ifndef EMACS_FRAME_H
 #define EMACS_FRAME_H
 
 #ifndef EMACS_FRAME_H
 #define EMACS_FRAME_H
@@ -33,7 +33,7 @@ INLINE_HEADER_BEGIN
 \f
 /* Miscellanea.  */
 
 \f
 /* Miscellanea.  */
 
-/* Nonzero means there is at least one garbaged frame. */
+/* Nonzero means there is at least one garbaged frame.  */
 extern bool frame_garbaged;
 
 \f
 extern bool frame_garbaged;
 
 \f
@@ -46,7 +46,6 @@ enum output_method
   output_x_window,
   output_msdos_raw,
   output_w32,
   output_x_window,
   output_msdos_raw,
   output_w32,
-  output_mac,
   output_ns
 };
 
   output_ns
 };
 
@@ -171,9 +170,11 @@ struct frame
      most recently buried buffer is first.  For last-buffer.  */
   Lisp_Object buried_buffer_list;
 
      most recently buried buffer is first.  For last-buffer.  */
   Lisp_Object buried_buffer_list;
 
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
   /* A dummy window used to display menu bars under X when no X
      toolkit support is available.  */
   Lisp_Object menu_bar_window;
   /* A dummy window used to display menu bars under X when no X
      toolkit support is available.  */
   Lisp_Object menu_bar_window;
+#endif
 
   /* A window used to display the tool-bar of a frame.  */
   Lisp_Object tool_bar_window;
 
   /* A window used to display the tool-bar of a frame.  */
   Lisp_Object tool_bar_window;
@@ -201,7 +202,7 @@ struct frame
      string's pointer (`name', above) because it might get relocated.  */
   char *namebuf;
 
      string's pointer (`name', above) because it might get relocated.  */
   char *namebuf;
 
-  /* Glyph pool and matrix. */
+  /* Glyph pool and matrix.  */
   struct glyph_pool *current_pool;
   struct glyph_pool *desired_pool;
   struct glyph_matrix *desired_matrix;
   struct glyph_pool *current_pool;
   struct glyph_pool *desired_pool;
   struct glyph_matrix *desired_matrix;
@@ -277,9 +278,6 @@ struct frame
   /* Size of the frame window in pixels.  */
   int pixel_height, pixel_width;
 
   /* Size of the frame window in pixels.  */
   int pixel_height, pixel_width;
 
-  /* Dots per inch of the screen the frame is on.  */
-  double resx, resy;
-
   /* These many pixels are the difference between the outer window (i.e. the
      left and top of the window manager decoration) and FRAME_X_WINDOW. */
   int x_pixels_diff, y_pixels_diff;
   /* These many pixels are the difference between the outer window (i.e. the
      left and top of the window manager decoration) and FRAME_X_WINDOW. */
   int x_pixels_diff, y_pixels_diff;
@@ -301,9 +299,6 @@ struct frame
   /* Canonical X unit.  Width of default font, in pixels.  */
   int column_width;
 
   /* Canonical X unit.  Width of default font, in pixels.  */
   int column_width;
 
-  /* Width of space glyph of default font, in pixels.  */
-  int space_width;
-
   /* Canonical Y unit.  Height of a line, in pixels.  */
   int line_height;
 
   /* Canonical Y unit.  Height of a line, in pixels.  */
   int line_height;
 
@@ -357,49 +352,30 @@ struct frame
   unsigned int external_menu_bar : 1;
 #endif
 
   unsigned int external_menu_bar : 1;
 #endif
 
-  /* Nonzero if last attempt at redisplay on this frame was preempted.  */
-  unsigned display_preempted : 1;
+  /* Next two bitfields are mutually exclusive.  They might both be
+     zero if the frame has been made invisible without an icon.  */
 
 
-  /* visible is nonzero if the frame is currently displayed; we check
+  /* Nonzero if the frame is currently displayed; we check
      it to see if we should bother updating the frame's contents.
      it to see if we should bother updating the frame's contents.
-     DON'T SET IT DIRECTLY; instead, use FRAME_SET_VISIBLE.
 
      Note that, since invisible frames aren't updated, whenever a
 
      Note that, since invisible frames aren't updated, whenever a
-     frame becomes visible again, it must be marked as garbaged.  The
-     FRAME_SAMPLE_VISIBILITY macro takes care of this.
+     frame becomes visible again, it must be marked as garbaged.
 
      On ttys and on Windows NT/9X, to avoid wasting effort updating
      visible frames that are actually completely obscured by other
      windows on the display, we bend the meaning of visible slightly:
 
      On ttys and on Windows NT/9X, to avoid wasting effort updating
      visible frames that are actually completely obscured by other
      windows on the display, we bend the meaning of visible slightly:
-     if greater than 1, then the frame is obscured - we still consider
+     if equal to 2, then the frame is obscured - we still consider
      it to be "visible" as seen from lisp, but we don't bother
      updating it.  We must take care to garbage the frame when it
      it to be "visible" as seen from lisp, but we don't bother
      updating it.  We must take care to garbage the frame when it
-     ceases to be obscured though.
-
-     iconified is nonzero if the frame is currently iconified.
-
-     Asynchronous input handlers should NOT change these directly;
-     instead, they should change async_visible or async_iconified, and
-     let the FRAME_SAMPLE_VISIBILITY macro set visible and iconified
-     at the next redisplay.
-
-     These should probably be considered read-only by everyone except
-     FRAME_SAMPLE_VISIBILITY.
-
-     These two are mutually exclusive.  They might both be zero, if the
-     frame has been made invisible without an icon.  */
+     ceases to be obscured though.  See SET_FRAME_VISIBLE below.  */
   unsigned visible : 2;
   unsigned visible : 2;
-  unsigned iconified : 1;
 
 
-  /* Let's not use bitfields for volatile variables.  */
-
-  /* Asynchronous input handlers change these, and
-     FRAME_SAMPLE_VISIBILITY copies them into visible and iconified.
-     See FRAME_SAMPLE_VISIBILITY, below.  */
-  volatile char async_visible, async_iconified;
+  /* Nonzero if the frame is currently iconified.  Do not
+     set this directly, use SET_FRAME_ICONIFIED instead.  */
+  unsigned iconified : 1;
 
   /* Nonzero if this frame should be redrawn.  */
 
   /* Nonzero if this frame should be redrawn.  */
-  volatile char garbaged;
+  unsigned garbaged : 1;
 
   /* True if frame actually has a minibuffer window on it.
      0 if using a minibuffer window that isn't on this frame.  */
 
   /* True if frame actually has a minibuffer window on it.
      0 if using a minibuffer window that isn't on this frame.  */
@@ -451,13 +427,6 @@ struct frame
   /* Width of bar cursor (if we are using that) for blink-off state.  */
   int blink_off_cursor_width;
 
   /* Width of bar cursor (if we are using that) for blink-off state.  */
   int blink_off_cursor_width;
 
-  /* Storage for messages to this frame. */
-  char *message_buf;
-
-  /* Nonnegative if current redisplay should not do scroll computation
-     for lines beyond a certain vpos.  This is the vpos.  */
-  int scroll_bottom_vpos;
-
   /* Configured width of the scroll bar, in pixels and in characters.
      config_scroll_bar_cols tracks config_scroll_bar_width if the
      latter is positive; a zero value in config_scroll_bar_width means
   /* Configured width of the scroll bar, in pixels and in characters.
      config_scroll_bar_cols tracks config_scroll_bar_width if the
      latter is positive; a zero value in config_scroll_bar_width means
@@ -544,11 +513,13 @@ fset_menu_bar_vector (struct frame *f, Lisp_Object val)
 {
   f->menu_bar_vector = val;
 }
 {
   f->menu_bar_vector = val;
 }
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
 FRAME_INLINE void
 fset_menu_bar_window (struct frame *f, Lisp_Object val)
 {
   f->menu_bar_window = val;
 }
 FRAME_INLINE void
 fset_menu_bar_window (struct frame *f, Lisp_Object val)
 {
   f->menu_bar_window = val;
 }
+#endif
 FRAME_INLINE void
 fset_name (struct frame *f, Lisp_Object val)
 {
 FRAME_INLINE void
 fset_name (struct frame *f, Lisp_Object val)
 {
@@ -595,6 +566,26 @@ fset_tool_bar_window (struct frame *f, Lisp_Object val)
   f->tool_bar_window = val;
 }
 
   f->tool_bar_window = val;
 }
 
+#define NUMVAL(X) ((INTEGERP (X) || FLOATP (X)) ? XFLOATINT (X) : -1)
+
+FRAME_INLINE double
+default_pixels_per_inch_x (void)
+{
+  Lisp_Object v = (CONSP (Vdisplay_pixels_per_inch)
+                  ? XCAR (Vdisplay_pixels_per_inch)
+                  : Vdisplay_pixels_per_inch);
+  return NUMVAL (v) > 0 ? NUMVAL (v) : 72.0;
+}
+
+FRAME_INLINE double
+default_pixels_per_inch_y (void)
+{
+  Lisp_Object v = (CONSP (Vdisplay_pixels_per_inch)
+                  ? XCDR (Vdisplay_pixels_per_inch)
+                  : Vdisplay_pixels_per_inch);
+  return NUMVAL (v) > 0 ? NUMVAL (v) : 72.0;
+}
+
 #define FRAME_KBOARD(f) ((f)->terminal->kboard)
 
 /* Return a pointer to the image cache of frame F.  */
 #define FRAME_KBOARD(f) ((f)->terminal->kboard)
 
 /* Return a pointer to the image cache of frame F.  */
@@ -607,7 +598,7 @@ typedef struct frame *FRAME_PTR;
 #define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME))
 
 /* Given a window, return its frame as a Lisp_Object.  */
 #define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME))
 
 /* Given a window, return its frame as a Lisp_Object.  */
-#define WINDOW_FRAME(w) w->frame
+#define WINDOW_FRAME(w) ((w)->frame)
 
 /* Test a frame for particular kinds of display methods.  */
 #define FRAME_INITIAL_P(f) ((f)->output_method == output_initial)
 
 /* Test a frame for particular kinds of display methods.  */
 #define FRAME_INITIAL_P(f) ((f)->output_method == output_initial)
@@ -628,6 +619,37 @@ typedef struct frame *FRAME_PTR;
 #else
 #define FRAME_NS_P(f) ((f)->output_method == output_ns)
 #endif
 #else
 #define FRAME_NS_P(f) ((f)->output_method == output_ns)
 #endif
+
+/* Dots per inch of the screen the frame F is on.  */
+
+#ifdef HAVE_X_WINDOWS
+#define FRAME_RES_X(f)                                         \
+  (eassert (FRAME_X_P (f)), FRAME_X_DISPLAY_INFO (f)->resx)
+#define FRAME_RES_Y(f)                                         \
+  (eassert (FRAME_X_P (f)), FRAME_X_DISPLAY_INFO (f)->resy)
+#endif
+
+#ifdef HAVE_NTGUI
+#define FRAME_RES_X(f)                                         \
+  (eassert (FRAME_W32_P (f)), FRAME_W32_DISPLAY_INFO (f)->resx)
+#define FRAME_RES_Y(f)                                         \
+  (eassert (FRAME_W32_P (f)), FRAME_W32_DISPLAY_INFO (f)->resy)
+#endif
+
+#ifdef HAVE_NS
+#define FRAME_RES_X(f)                                         \
+  (eassert (FRAME_NS_P (f)), FRAME_NS_DISPLAY_INFO (f)->resx)
+#define FRAME_RES_Y(f)                                         \
+  (eassert (FRAME_NS_P (f)), FRAME_NS_DISPLAY_INFO (f)->resy)
+#endif
+
+/* Defaults when no window system available.  */
+
+#ifndef FRAME_RES_X
+#define FRAME_RES_X(f) default_pixels_per_inch_x ()
+#define FRAME_RES_Y(f) default_pixels_per_inch_y ()
+#endif
+
 /* FRAME_WINDOW_P tests whether the frame is a window, and is
    defined to be the predicate for the window system being used.  */
 
 /* FRAME_WINDOW_P tests whether the frame is a window, and is
    defined to be the predicate for the window system being used.  */
 
@@ -721,7 +743,7 @@ typedef struct frame *FRAME_PTR;
 #else
 #define FRAME_EXTERNAL_MENU_BAR(f) 0
 #endif
 #else
 #define FRAME_EXTERNAL_MENU_BAR(f) 0
 #endif
-#define FRAME_VISIBLE_P(f) ((f)->visible != 0)
+#define FRAME_VISIBLE_P(f) (f)->visible
 
 /* Nonzero if frame F is currently visible but hidden.  */
 #define FRAME_OBSCURED_P(f) ((f)->visible > 1)
 
 /* Nonzero if frame F is currently visible but hidden.  */
 #define FRAME_OBSCURED_P(f) ((f)->visible > 1)
@@ -729,9 +751,10 @@ typedef struct frame *FRAME_PTR;
 /* Nonzero if frame F is currently iconified.  */
 #define FRAME_ICONIFIED_P(f) (f)->iconified
 
 /* Nonzero if frame F is currently iconified.  */
 #define FRAME_ICONIFIED_P(f) (f)->iconified
 
-#define FRAME_SET_VISIBLE(f,p) \
-  ((f)->async_visible = (p), FRAME_SAMPLE_VISIBILITY (f))
+/* Mark frame F as currently garbaged.  */
 #define SET_FRAME_GARBAGED(f) (frame_garbaged = 1, f->garbaged = 1)
 #define SET_FRAME_GARBAGED(f) (frame_garbaged = 1, f->garbaged = 1)
+
+/* Nonzero if frame F is currently garbaged.  */
 #define FRAME_GARBAGED_P(f) (f)->garbaged
 
 /* Nonzero means do not allow splitting this frame's window.  */
 #define FRAME_GARBAGED_P(f) (f)->garbaged
 
 /* Nonzero means do not allow splitting this frame's window.  */
@@ -758,8 +781,6 @@ typedef struct frame *FRAME_PTR;
 #define FRAME_DELETE_COST(f) (f)->delete_line_cost
 #define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost
 #define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost
 #define FRAME_DELETE_COST(f) (f)->delete_line_cost
 #define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost
 #define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost
-#define FRAME_MESSAGE_BUF(f) (f)->message_buf
-#define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos
 #define FRAME_FOCUS_FRAME(f) f->focus_frame
 
 /* This frame slot says whether scroll bars are currently enabled for frame F,
 #define FRAME_FOCUS_FRAME(f) f->focus_frame
 
 /* This frame slot says whether scroll bars are currently enabled for frame F,
@@ -877,39 +898,6 @@ typedef struct frame *FRAME_PTR;
 
 #define FRAME_MESSAGE_BUF_SIZE(f) (((int) FRAME_COLS (f)) * 4)
 
 
 #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.
-
-   Note that a tty frame is visible if and only if it is the topmost
-   frame. */
-
-#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) \
   CHECK_TYPE (FRAMEP (x), Qframep, x)
 
 #define CHECK_FRAME(x) \
   CHECK_TYPE (FRAMEP (x), Qframep, x)
 
@@ -933,6 +921,33 @@ typedef struct frame *FRAME_PTR;
        && (frame_var = XCAR (list_var), 1));   \
        list_var = XCDR (list_var))
 
        && (frame_var = XCAR (list_var), 1));   \
        list_var = XCDR (list_var))
 
+/* Reflect mouse movement when a complete frame update is performed.  */
+
+#define FRAME_MOUSE_UPDATE(frame)                              \
+  do {                                                         \
+    Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (frame);              \
+    if (frame == hlinfo->mouse_face_mouse_frame)               \
+      {                                                                \
+       block_input ();                                         \
+       if (hlinfo->mouse_face_mouse_frame)                     \
+         note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \
+                               hlinfo->mouse_face_mouse_x,     \
+                               hlinfo->mouse_face_mouse_y);    \
+       unblock_input ();                                       \
+      }                                                                \
+  } while (0)
+
+/* Set visibility of frame F, marking F as garbaged if needed.  */
+
+#define SET_FRAME_VISIBLE(f, v)                                \
+  (((f)->visible == 0 || ((f)->visible == 2))          \
+   && ((v) == 1) ? SET_FRAME_GARBAGED (f) : 0,         \
+   (f)->visible = (eassert (0 <= (v) && (v) <= 2), (v)))
+
+/* Set iconify of frame F.  */
+
+#define SET_FRAME_ICONIFIED(f, i)                      \
+  (f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i))
 
 extern Lisp_Object Qframep, Qframe_live_p;
 extern Lisp_Object Qtty, Qtty_type;
 
 extern Lisp_Object Qframep, Qframe_live_p;
 extern Lisp_Object Qtty, Qtty_type;
@@ -943,6 +958,7 @@ extern Lisp_Object Qnoelisp;
 extern struct frame *last_nonminibuf_frame;
 
 extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
 extern struct frame *last_nonminibuf_frame;
 
 extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
+extern struct frame *decode_window_system_frame (Lisp_Object);
 extern struct frame *decode_live_frame (Lisp_Object);
 extern struct frame *decode_any_frame (Lisp_Object);
 extern struct frame *make_initial_frame (void);
 extern struct frame *decode_live_frame (Lisp_Object);
 extern struct frame *decode_any_frame (Lisp_Object);
 extern struct frame *make_initial_frame (void);
@@ -953,6 +969,8 @@ extern struct frame *make_frame_without_minibuffer (Lisp_Object,
                                                     struct kboard *,
                                                     Lisp_Object);
 #endif /* HAVE_WINDOW_SYSTEM */
                                                     struct kboard *,
                                                     Lisp_Object);
 #endif /* HAVE_WINDOW_SYSTEM */
+extern bool window_system_available (struct frame *);
+extern void check_window_system (struct frame *);
 extern void frame_make_pointer_invisible (void);
 extern void frame_make_pointer_visible (void);
 extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
 extern void frame_make_pointer_invisible (void);
 extern void frame_make_pointer_visible (void);
 extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
@@ -988,11 +1006,6 @@ extern Lisp_Object selected_frame;
 
 #define FRAME_COLUMN_WIDTH(F) ((F)->column_width)
 
 
 #define FRAME_COLUMN_WIDTH(F) ((F)->column_width)
 
-/* Space glyph width of the default font of frame F.  */
-
-#define FRAME_SPACE_WIDTH(F) ((F)->space_width)
-
-
 /* Pixel width of areas used to display truncation marks, continuation
    marks, overlay arrows.  This is 0 for terminal frames.  */
 
 /* Pixel width of areas used to display truncation marks, continuation
    marks, overlay arrows.  This is 0 for terminal frames.  */
 
@@ -1174,7 +1187,7 @@ extern Lisp_Object Qalpha;
 extern Lisp_Object Qleft_fringe, Qright_fringe;
 extern Lisp_Object Qheight, Qwidth;
 extern Lisp_Object Qminibuffer, Qmodeline;
 extern Lisp_Object Qleft_fringe, Qright_fringe;
 extern Lisp_Object Qheight, Qwidth;
 extern Lisp_Object Qminibuffer, Qmodeline;
-extern Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
+extern Lisp_Object Qx, Qw32, Qpc, Qns;
 extern Lisp_Object Qvisible;
 extern Lisp_Object Qdisplay_type;
 
 extern Lisp_Object Qvisible;
 extern Lisp_Object Qdisplay_type;
 
@@ -1251,8 +1264,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
 extern void x_make_frame_visible (struct frame *f);
 extern void x_make_frame_invisible (struct frame *f);
 extern void x_iconify_frame (struct frame *f);
 extern void x_make_frame_visible (struct frame *f);
 extern void x_make_frame_invisible (struct frame *f);
 extern void x_iconify_frame (struct frame *f);
-extern int x_char_width (struct frame *f);
-extern int x_char_height (struct frame *f);
 extern int x_pixel_width (struct frame *f);
 extern int x_pixel_height (struct frame *f);
 extern void x_set_frame_alpha (struct frame *f);
 extern int x_pixel_width (struct frame *f);
 extern int x_pixel_height (struct frame *f);
 extern void x_set_frame_alpha (struct frame *f);
@@ -1277,6 +1288,28 @@ extern void x_query_colors (struct frame *f, XColor *, int);
 extern void x_query_color (struct frame *f, XColor *);
 
 #endif /* HAVE_WINDOW_SYSTEM */
 extern void x_query_color (struct frame *f, XColor *);
 
 #endif /* HAVE_WINDOW_SYSTEM */
+\f
+/***********************************************************************
+                       Multimonitor data
+ ***********************************************************************/
+
+#ifdef HAVE_WINDOW_SYSTEM
+
+struct MonitorInfo {
+  XRectangle geom, work;
+  int mm_width, mm_height;
+  char *name;
+};
+
+extern void free_monitors (struct MonitorInfo *monitors, int n_monitors);
+extern Lisp_Object make_monitor_attribute_list (struct MonitorInfo *monitors,
+                                                int n_monitors,
+                                                int primary_monitor,
+                                                Lisp_Object monitor_frames,
+                                                const char *source);
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
 
 INLINE_HEADER_END
 
 
 INLINE_HEADER_END