* nsfns.m: Declare image_cache_refcount if GLYPH_DEBUG.
[bpt/emacs.git] / src / nsterm.m
index 714b8a0..3d3723f 100644 (file)
@@ -1,5 +1,5 @@
 /* NeXT/Open/GNUstep / MacOSX communication module.
-   Copyright (C) 1989, 1993, 1994, 2005, 2006, 2008, 2009, 2010, 2011
+   Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2011
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -134,49 +134,11 @@ static unsigned convert_ns_to_X_keysym[] =
   0x1B,                                0x1B   /* escape */
 };
 
-
-/* Lisp communications */
-Lisp_Object ns_input_file, ns_input_font, ns_input_fontsize, ns_input_line;
-Lisp_Object ns_input_color, ns_input_text, ns_working_text;
-Lisp_Object ns_input_spi_name, ns_input_spi_arg;
-Lisp_Object Vx_toolkit_scroll_bars;
 static Lisp_Object Qmodifier_value;
 Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone;
 extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft;
 
-/* Specifies which emacs modifier should be generated when NS receives
-   the Alternate modifier.  May be Qnone or any of the modifier lisp symbols. */
-Lisp_Object ns_alternate_modifier;
-
-/* Specifies which emacs modifier should be generated when NS receives
-   the right Alternate modifier.  Has same values as ns_alternate_modifier plus
-   the value Qleft which means whatever value ns_alternate_modifier has.  */
-Lisp_Object ns_right_alternate_modifier;
-
-/* Specifies which emacs modifier should be generated when NS receives
-   the Command modifier.  May be any of the modifier lisp symbols. */
-Lisp_Object ns_command_modifier;
-
-/* Specifies which emacs modifier should be generated when NS receives
-   the right Command modifier.  Has same values as ns_command_modifier plus
-   the value Qleft which means whatever value ns_command_modifier has.  */
-Lisp_Object ns_right_command_modifier;
-
-/* Specifies which emacs modifier should be generated when NS receives
-   the Control modifier.  May be any of the modifier lisp symbols. */
-Lisp_Object ns_control_modifier;
-
-/* Specifies which emacs modifier should be generated when NS receives
-   the right Control modifier.  Has same values as ns_control_modifier plus
-   the value Qleft which means whatever value ns_control_modifier has.  */
-Lisp_Object ns_right_control_modifier;
-
-/* Specifies which emacs modifier should be generated when NS receives
-   the Function modifier (laptops).  May be any of the modifier lisp symbols. */
-Lisp_Object ns_function_modifier;
-
-/* Control via default 'GSFontAntiAlias' on OS X and GNUstep. */
-Lisp_Object ns_antialias_text;
+static Lisp_Object QUTF8_STRING;
 
 /* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold,
    the maximum font size to NOT antialias.  On GNUstep there is currently
@@ -186,9 +148,6 @@ float ns_antialias_threshold;
 /* Used to pick up AppleHighlightColor on OS X */
 NSString *ns_selection_color;
 
-/* Confirm on exit. */
-Lisp_Object ns_confirm_quit;
-
 NSArray *ns_send_types =0, *ns_return_types =0, *ns_drag_types =0;
 NSString *ns_app_name = @"Emacs";  /* default changed later */
 
@@ -200,18 +159,19 @@ long context_menu_value = 0;
 /* display update */
 NSPoint last_mouse_motion_position;
 static NSRect last_mouse_glyph;
-static unsigned long last_mouse_movement_time = 0;
+static Time last_mouse_movement_time = 0;
 static Lisp_Object last_mouse_motion_frame;
 static EmacsScroller *last_mouse_scroll_bar = nil;
 static struct frame *ns_updating_frame;
 static NSView *focus_view = NULL;
-static int ns_window_num =0;
+static int ns_window_num = 0;
 static NSRect uRect;
 static BOOL gsaved = NO;
 BOOL ns_in_resize = NO;
 static BOOL ns_fake_keydown = NO;
 int ns_tmp_flags; /* FIXME */
 struct nsfont_info *ns_tmp_font; /* FIXME */
+static BOOL ns_menu_bar_is_hidden = NO;
 /*static int debug_lock = 0; */
 
 /* event loop */
@@ -231,7 +191,7 @@ static NSMutableArray *ns_pending_files, *ns_pending_service_names,
   *ns_pending_service_args;
 static BOOL inNsSelect = 0;
 
-/* Convert modifiers in a NeXTSTEP event to emacs style modifiers.  */
+/* Convert modifiers in a NeXTstep event to emacs style modifiers.  */
 #define NS_FUNCTION_KEY_MASK 0x800000
 #define NSLeftControlKeyMask    (0x000001 | NSControlKeyMask)
 #define NSRightControlKeyMask   (0x002000 | NSControlKeyMask)
@@ -303,10 +263,6 @@ static void ns_condemn_scroll_bars (struct frame *f);
 static void ns_judge_scroll_bars (struct frame *f);
 void x_set_frame_alpha (struct frame *f);
 
-/* unused variables needed for compatibility reasons */
-int x_use_underline_position_properties, x_underline_at_descent_line;
-/* FIXME: figure out what to do with underline_minimum_offset. */
-
 
 /* ==========================================================================
 
@@ -549,6 +505,125 @@ ns_resize_handle_rect (NSWindow *window)
 }
 
 
+//
+// Window constraining
+// -------------------
+//
+// To ensure that the windows are not placed under the menu bar, they
+// are typically moved by the call-back constrainFrameRect. However,
+// by overriding it, it's possible to inhibit this, leaving the window
+// in it's original position.
+//
+// It's possible to hide the menu bar. However, technically, it's only
+// possible to hide it when the application is active. To ensure that
+// this work properly, the menu bar and window constraining are
+// deferred until the application becomes active.
+//
+// Even though it's not possible to manually move a window above the
+// top of the screen, it is allowed if it's done programmatically,
+// when the menu is hidden. This allows the editable area to cover the
+// full screen height.
+//
+// Test cases
+// ----------
+//
+// Use the following extra files:
+//
+//    init.el:
+//       ;; Hide menu and place frame slightly above the top of the screen.
+//       (setq ns-auto-hide-menu-bar t)
+//       (set-frame-position (selected-frame) 0 -20)
+//
+// Test 1:
+//
+//    emacs -Q -l init.el
+//
+//    Result: No menu bar, and the title bar should be above the screen.
+//
+// Test 2:
+//
+//    emacs -Q
+//
+//    Result: Menu bar visible, frame placed immediately below the menu.
+//
+
+static void
+ns_constrain_all_frames (void)
+{
+  Lisp_Object tail, frame;
+
+  FOR_EACH_FRAME (tail, frame)
+    {
+      struct frame *f = XFRAME (frame);
+      if (FRAME_NS_P (f))
+        {
+          NSView *view = FRAME_NS_VIEW (f);
+          /* This no-op will trigger the default window placing
+           * constriant system. */
+          f->output_data.ns->dont_constrain = 0;
+          [[view window] setFrameOrigin:[[view window] frame].origin];
+        }
+    }
+}
+
+
+/* True, if the menu bar should be hidden.  */
+
+static BOOL
+ns_menu_bar_should_be_hidden (void)
+{
+  return !NILP (ns_auto_hide_menu_bar)
+    && [NSApp respondsToSelector:@selector(setPresentationOptions:)];
+}
+
+
+/* Show or hide the menu bar, based on user setting.  */
+
+static void
+ns_update_auto_hide_menu_bar (void)
+{
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+  BLOCK_INPUT;
+
+  NSTRACE (ns_update_auto_hide_menu_bar);
+
+  if (NSApp != nil
+      && [NSApp isActive]
+      && [NSApp respondsToSelector:@selector(setPresentationOptions:)])
+    {
+      // Note, "setPresentationOptions" triggers an error unless the
+      // application is active.
+      BOOL menu_bar_should_be_hidden = ns_menu_bar_should_be_hidden ();
+
+      if (menu_bar_should_be_hidden != ns_menu_bar_is_hidden)
+        {
+          NSApplicationPresentationOptions options
+            = NSApplicationPresentationAutoHideDock;
+
+          if (menu_bar_should_be_hidden)
+            options |= NSApplicationPresentationAutoHideMenuBar;
+
+          [NSApp setPresentationOptions: options];
+
+          ns_menu_bar_is_hidden = menu_bar_should_be_hidden;
+
+          if (!ns_menu_bar_is_hidden)
+            {
+              ns_constrain_all_frames ();
+            }
+        }
+    }
+
+  UNBLOCK_INPUT;
+#endif
+#endif
+}
+
+
 static void
 ns_update_begin (struct frame *f)
 /* --------------------------------------------------------------------------
@@ -559,6 +634,8 @@ ns_update_begin (struct frame *f)
   NSView *view = FRAME_NS_VIEW (f);
   NSTRACE (ns_update_begin);
 
+  ns_update_auto_hide_menu_bar ();
+
   ns_updating_frame = f;
   [view lockFocus];
 
@@ -1046,12 +1123,10 @@ x_iconify_frame (struct frame *f)
   [[view window] miniaturize: NSApp];
 }
 
+/* Free X resources of frame F.  */
 
 void
-x_destroy_window (struct frame *f)
-/* --------------------------------------------------------------------------
-     External: Delete the window
-   -------------------------------------------------------------------------- */
+x_free_frame_resources (struct frame *f)
 {
   NSView *view = FRAME_NS_VIEW (f);
   struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
@@ -1086,10 +1161,21 @@ x_destroy_window (struct frame *f)
   [[view window] close];
   [view release];
 
-  ns_window_num--;
   UNBLOCK_INPUT;
 }
 
+void
+x_destroy_window (struct frame *f)
+/* --------------------------------------------------------------------------
+     External: Delete the window
+   -------------------------------------------------------------------------- */
+{
+  NSTRACE (x_destroy_window);
+  check_ns ();
+  x_free_frame_resources (f);
+  ns_window_num--;
+}
+
 
 void
 x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
@@ -1097,8 +1183,10 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
      External: Position the window
    -------------------------------------------------------------------------- */
 {
-  NSScreen *screen;
   NSView *view = FRAME_NS_VIEW (f);
+  NSArray *screens = [NSScreen screens];
+  NSScreen *fscreen = [screens objectAtIndex: 0];
+  NSScreen *screen = [[view window] screen];
 
   NSTRACE (x_set_offset);
 
@@ -1107,14 +1195,14 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
   f->left_pos = xoff;
   f->top_pos = yoff;
 
-  if (view != nil && (screen = [[view window] screen]))
+  if (view != nil && screen && fscreen)
     {
       f->left_pos = f->size_hint_flags & XNegative
         ? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f)
         : f->left_pos;
       /* We use visibleFrame here to take menu bar into account.
-        Ideally we should also adjust left/top with visibleFrame.offset.  */
-        
+        Ideally we should also adjust left/top with visibleFrame.origin.  */
+
       f->top_pos = f->size_hint_flags & YNegative
         ? ([screen visibleFrame].size.height + f->top_pos
            - FRAME_PIXEL_HEIGHT (f) - FRAME_NS_TITLEBAR_HEIGHT (f)
@@ -1124,9 +1212,12 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
       if (f->left_pos < 100)
         f->left_pos = 100;  /* don't overlap menu */
 #endif
+      /* Constrain the setFrameTopLeftPoint so we don't move behind the
+         menu bar.  */
+      f->output_data.ns->dont_constrain = 0;
       [[view window] setFrameTopLeftPoint:
                        NSMakePoint (SCREENMAXBOUND (f->left_pos),
-                                    SCREENMAXBOUND ([screen frame].size.height
+                                    SCREENMAXBOUND ([fscreen frame].size.height
                                                     - NS_TOP_POS (f)))];
       f->size_hint_flags &= ~(XNegative|YNegative);
     }
@@ -1140,13 +1231,12 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
 /* --------------------------------------------------------------------------
      Adjust window pixel size based on given character grid size
      Impl is a bit more complex than other terms, need to do some
-     internal clipping and also pay attention to screen constraints.
+     internal clipping.
    -------------------------------------------------------------------------- */
 {
   EmacsView *view = FRAME_NS_VIEW (f);
   EmacsToolbar *toolbar = [view toolbar];
   NSWindow *window = [view window];
-  NSScreen *screen = [window screen];
   NSRect wr = [window frame];
   int tb = FRAME_EXTERNAL_TOOL_BAR (f);
   int pixelwidth, pixelheight;
@@ -1194,34 +1284,16 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
     FRAME_TOOLBAR_HEIGHT (f) = 0;
 
   wr.size.width = pixelwidth + f->border_width;
-  wr.size.height = pixelheight + FRAME_NS_TITLEBAR_HEIGHT (f) 
+  wr.size.height = pixelheight + FRAME_NS_TITLEBAR_HEIGHT (f)
                   + FRAME_TOOLBAR_HEIGHT (f);
 
-  /* constrain to screen if we can */
-  if (screen)
-    {
-      NSSize sz = [screen visibleFrame].size;
-      NSSize ez = { wr.size.width - sz.width, wr.size.height - sz.height };
-      if (ez.width > 0)
-        {
-          int cr = ez.width / FRAME_COLUMN_WIDTH (f) + 1;
-          cols -= cr;
-          oldCols = cols;
-          wr.size.width -= cr * FRAME_COLUMN_WIDTH (f);
-          pixelwidth -= cr * FRAME_COLUMN_WIDTH (f);
-        }
-      if (ez.height > 0)
-        {
-          int rr = ez.height / FRAME_LINE_HEIGHT (f) + 1;
-          rows -= rr;
-          oldRows = rows;
-          wr.size.height -= rr * FRAME_LINE_HEIGHT (f);
-          pixelheight -= rr * FRAME_LINE_HEIGHT (f);
-        }
-      wr.origin.x = f->left_pos;
-      wr.origin.y = [screen frame].size.height - NS_TOP_POS (f)
-        - wr.size.height;
-    }
+  /* Do not try to constrain to this screen.  We may have multiple
+     screens, and want Emacs to span those.  Constraining to screen
+     prevents that, and that is not nice to the user.  */
+ if (f->output_data.ns->zooming)
+   f->output_data.ns->zooming = 0;
+ else
+   wr.origin.y += FRAME_PIXEL_HEIGHT (f) - pixelheight;
 
   [view setRows: rows andColumns: cols];
   [window setFrame: wr display: YES];
@@ -1278,7 +1350,7 @@ unsigned long
 ns_index_color (NSColor *color, struct frame *f)
 {
   struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table;
-  int idx;
+  ptrdiff_t idx;
   NSNumber *index;
 
   if (!color_table->colors)
@@ -1293,7 +1365,7 @@ ns_index_color (NSColor *color, struct frame *f)
 
   /* do we already have this color ? */
   {
-    int i;
+    ptrdiff_t i;
     for (i = 1; i < color_table->avail; i++)
       {
         if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
@@ -1308,17 +1380,14 @@ ns_index_color (NSColor *color, struct frame *f)
     {
       index = [color_table->empty_indices anyObject];
       [color_table->empty_indices removeObject: index];
-      idx = [index unsignedIntValue];
+      idx = [index unsignedLongValue];
     }
   else
     {
       if (color_table->avail == color_table->size)
-        {
-          color_table->size += NS_COLOR_CAPACITY;
-          color_table->colors
-           = (NSColor **)xrealloc (color_table->colors,
-                                   color_table->size * sizeof (NSColor *));
-        }
+       color_table->colors =
+         xpalloc (color_table->colors, &color_table->size, 1,
+                  min (ULONG_MAX, PTRDIFF_MAX), sizeof *color_table->colors);
       idx = color_table->avail++;
     }
 
@@ -1725,7 +1794,7 @@ note_mouse_movement (struct frame *frame, float x, float y)
 static void
 ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
                    enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
-                   unsigned long *time)
+                   Time *time)
 /* --------------------------------------------------------------------------
     External (hook): inform emacs about mouse position and hit parts.
     If a scrollbar is being dragged, set bar_window, part, x, y, time.
@@ -2258,7 +2327,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
       if (!img)
         {
           unsigned short *bits = p->bits + p->dh;
-          int len = 8 * p->h/8;
+          int len = p->h;
           int i;
           unsigned char *cbits = xmalloc (len);
 
@@ -2288,15 +2357,12 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
                        int x, int y, int cursor_type, int cursor_width,
                        int on_p, int active_p)
 /* --------------------------------------------------------------------------
-     External call (RIF): draw cursor
-     (modeled after x_draw_window_cursor
-     FIXME: cursor_width is effectively bogus -- it sometimes gets set
-     in xdisp.c set_frame_cursor_types, sometimes left uninitialized;
-     DON'T USE IT (no other terms do)
+     External call (RIF): draw cursor.
+     Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
    -------------------------------------------------------------------------- */
 {
   NSRect r, s;
-  int fx, fy, h;
+  int fx, fy, h, cursor_height;
   struct frame *f = WINDOW_XFRAME (w);
   struct glyph *phys_cursor_glyph;
   int overspill;
@@ -2309,7 +2375,6 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
      and mini-buffer.  */
 
   NSTRACE (dumpcursor);
-//fprintf(stderr, "drawcursor (%d,%d) activep = %d\tonp = %d\tc_type = %d\twidth = %d\n",x,y, active_p,on_p,cursor_type,cursor_width);
 
   if (!on_p)
     return;
@@ -2334,8 +2399,28 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
       return;
     }
 
+  /* We draw the cursor (with NSRectFill), then draw the glyph on top
+     (other terminals do it the other way round).  We must set
+     w->phys_cursor_width to the cursor width.  For bar cursors, that
+     is CURSOR_WIDTH; for box cursors, it is the glyph width.  */
   get_phys_cursor_geometry (w, glyph_row, phys_cursor_glyph, &fx, &fy, &h);
 
+  /* The above get_phys_cursor_geometry call set w->phys_cursor_width
+     to the glyph width; replace with CURSOR_WIDTH for (V)BAR cursors. */
+  if (cursor_type == BAR_CURSOR)
+    {
+      if (cursor_width < 1)
+       cursor_width = max (FRAME_CURSOR_WIDTH (f), 1);
+      w->phys_cursor_width = cursor_width;
+    }
+  /* If we have an HBAR, "cursor_width" MAY specify height. */
+  else if (cursor_type == HBAR_CURSOR)
+    {
+      cursor_height = (cursor_width < 1) ? lrint (0.25 * h) : cursor_width;
+      fy += h - cursor_height;
+      h = cursor_height;
+    }
+
   r.origin.x = fx, r.origin.y = fy;
   r.size.height = h;
   r.size.width = w->phys_cursor_width;
@@ -2343,7 +2428,7 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
   /* FIXME: if we overwrite the internal border area, it does not get erased;
      fix by truncating cursor, but better would be to erase properly */
   overspill = r.origin.x + r.size.width -
-    WINDOW_TEXT_TO_FRAME_PIXEL_X (w, WINDOW_BOX_RIGHT_EDGE_X (w) 
+    WINDOW_TEXT_TO_FRAME_PIXEL_X (w, WINDOW_BOX_RIGHT_EDGE_X (w)
       - WINDOW_TOTAL_FRINGE_WIDTH (w) - FRAME_INTERNAL_BORDER_WIDTH (f));
   if (overspill > 0)
     r.size.width -= overspill;
@@ -2386,15 +2471,10 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
       [FRAME_CURSOR_COLOR (f) set];
       break;
     case HBAR_CURSOR:
-      s = r;
-      s.origin.y += lrint (0.75 * s.size.height);
-      s.size.height = lrint (s.size.height * 0.25);
-      NSRectFill (s);
+      NSRectFill (r);
       break;
     case BAR_CURSOR:
       s = r;
-      s.size.width = min (cursor_width, 2); //FIXME(see above)
-
       /* If the character under cursor is R2L, draw the bar cursor
          on the right of its glyph, rather than on the left.  */
       cursor_glyph = get_phys_cursor_glyph (w);
@@ -2521,6 +2601,107 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
   return n;
 }
 
+void
+ns_draw_text_decoration (struct glyph_string *s, struct face *face,
+                         NSColor *defaultCol, CGFloat width, CGFloat x)
+/* --------------------------------------------------------------------------
+   Draw underline, overline, and strike-through on glyph string s.
+   -------------------------------------------------------------------------- */
+{
+  if (s->for_overlaps)
+    return;
+
+  /* Do underline. */
+  if (face->underline_p)
+    {
+      NSRect r;
+      unsigned long thickness, position;
+
+      /* If the prev was underlined, match its appearance. */
+      if (s->prev && s->prev->face->underline_p
+          && s->prev->underline_thickness > 0)
+        {
+          thickness = s->prev->underline_thickness;
+          position = s->prev->underline_position;
+        }
+      else
+        {
+          struct font *font;
+          unsigned long descent;
+
+          font=s->font;
+          descent = s->y + s->height - s->ybase;
+
+          /* Use underline thickness of font, defaulting to 1. */
+          thickness = (font && font->underline_thickness > 0)
+            ? font->underline_thickness : 1;
+
+          /* Determine the offset of underlining from the baseline. */
+          if (x_underline_at_descent_line)
+            position = descent - thickness;
+          else if (x_use_underline_position_properties
+                   && font && font->underline_position >= 0)
+            position = font->underline_position;
+          else if (font)
+            position = lround (font->descent / 2);
+          else
+            position = underline_minimum_offset;
+
+          position = max (position, underline_minimum_offset);
+
+          /* Ensure underlining is not cropped. */
+          if (descent <= position)
+            {
+              position = descent - 1;
+              thickness = 1;
+            }
+          else if (descent < position + thickness)
+            thickness = 1;
+        }
+
+      s->underline_thickness = thickness;
+      s->underline_position = position;
+
+      r = NSMakeRect (x, s->ybase + position, width, thickness);
+
+      if (face->underline_defaulted_p)
+        [defaultCol set];
+      else
+        [ns_lookup_indexed_color (face->underline_color, s->f) set];
+      NSRectFill (r);
+    }
+
+  /* Do overline. We follow other terms in using a thickness of 1
+     and ignoring overline_margin. */
+  if (face->overline_p)
+    {
+      NSRect r;
+      r = NSMakeRect (x, s->y, width, 1);
+
+      if (face->overline_color_defaulted_p)
+        [defaultCol set];
+      else
+        [ns_lookup_indexed_color (face->overline_color, s->f) set];
+      NSRectFill (r);
+    }
+
+  /* Do strike-through.  We follow other terms for thickness and
+     vertical position.*/
+  if (face->strike_through_p)
+    {
+      NSRect r;
+      unsigned long dy;
+
+      dy = lrint ((s->height - 1) / 2);
+      r = NSMakeRect (x, s->y + dy, width, 1);
+
+      if (face->strike_through_color_defaulted_p)
+        [defaultCol set];
+      else
+        [ns_lookup_indexed_color (face->strike_through_color, s->f) set];
+      NSRectFill (r);
+    }
+}
 
 static void
 ns_draw_box (NSRect r, float thickness, NSColor *col, char left_p, char right_p)
@@ -2778,6 +2959,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
   char raised_p;
   NSRect br;
   struct face *face;
+  NSColor *tdCol;
 
   NSTRACE (ns_dumpglyphs_image);
 
@@ -2806,10 +2988,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
   else
     face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
 
-  if (s->hl == DRAW_CURSOR)
-      [FRAME_CURSOR_COLOR (s->f) set];
-  else
-    [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
+  [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
 
   if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
       || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
@@ -2847,6 +3026,27 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
     [img compositeToPoint: NSMakePoint (x, y + s->slice.height)
                 operation: NSCompositeSourceOver];
 
+  if (s->hl == DRAW_CURSOR)
+    {
+    [FRAME_CURSOR_COLOR (s->f) set];
+    if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
+      tdCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
+    else
+      /* Currently on NS img->mask is always 0. Since
+         get_window_cursor_type specifies a hollow box cursor when on
+         a non-masked image we never reach this clause. But we put it
+         in in antipication of better support for image masks on
+         NS. */
+      tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
+    }
+  else
+    {
+      tdCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
+    }
+
+  /* Draw underline, overline, strike-through. */
+  ns_draw_text_decoration (s, face, tdCol, br.size.width, br.origin.x);
+
   /* Draw relief, if requested */
   if (s->img->relief || s->hl ==DRAW_IMAGE_RAISED || s->hl ==DRAW_IMAGE_SUNKEN)
     {
@@ -2891,22 +3091,49 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
   NSRect r[2];
   int n, i;
   struct face *face;
+  NSColor *fgCol, *bgCol;
 
   if (!s->background_filled_p)
     {
       n = ns_get_glyph_string_clip_rect (s, r);
       *r = NSMakeRect (s->x, s->y, s->background_width, s->height);
 
+      ns_focus (s->f, r, n);
+
+      if (s->hl == DRAW_MOUSE_FACE)
+       {
+         face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
+         if (!face)
+           face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+       }
+      else
+       face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+
+      bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
+      fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
+
       for (i=0; i<n; i++)
         {
           if (!s->row->full_width_p)
             {
+             int overrun, leftoverrun;
+
               /* truncate to avoid overwriting fringe and/or scrollbar */
-              int overrun = max (0, (s->x + s->background_width)
-                                  - (WINDOW_BOX_RIGHT_EDGE_X (s->w)
-                                    - WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
+             overrun = max (0, (s->x + s->background_width)
+                            - (WINDOW_BOX_RIGHT_EDGE_X (s->w)
+                               - WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
               r[i].size.width -= overrun;
 
+             /* truncate to avoid overwriting to left of the window box */
+             leftoverrun = (WINDOW_BOX_LEFT_EDGE_X (s->w)
+                            + WINDOW_LEFT_FRINGE_WIDTH (s->w)) - s->x;
+
+             if (leftoverrun > 0)
+               {
+                 r[i].origin.x += leftoverrun;
+                 r[i].size.width -= leftoverrun;
+               }
+
               /* XXX: Try to work between problem where a stretch glyph on
                  a partially-visible bottom row will clear part of the
                  modeline, and another where list-buffers headers and similar
@@ -2922,30 +3149,37 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
                                       FRAME_PIXEL_WIDTH (s->f));
             }
 
+          [bgCol set];
+
           /* NOTE: under NS this is NOT used to draw cursors, but we must avoid
              overwriting cursor (usually when cursor on a tab) */
           if (s->hl == DRAW_CURSOR)
             {
-              r[i].origin.x += s->width;
-              r[i].size.width -= s->width;
-            }
-        }
+              CGFloat x, width;
 
-      ns_focus (s->f, r, n);
+              x = r[i].origin.x;
+              width = s->w->phys_cursor_width;
+              r[i].size.width -= width;
+              r[i].origin.x += width;
 
-      if (s->hl == DRAW_MOUSE_FACE)
-       {
-         face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
-         if (!face)
-           face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
-       }
-      else
-       face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+              NSRectFill (r[i]);
 
-      [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
+              /* Draw overlining, etc. on the cursor. */
+              if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
+                ns_draw_text_decoration (s, face, bgCol, width, x);
+              else
+                ns_draw_text_decoration (s, face, fgCol, width, x);
+            }
+          else
+            {
+              NSRectFill (r[i]);
+            }
 
-      NSRectFill (r[0]);
-      NSRectFill (r[1]);
+          /* Draw overlining, etc. on the stretch glyph (or the part
+             of the stretch glyph after the cursor). */
+          ns_draw_text_decoration (s, face, fgCol, r[i].size.width,
+                                   r[i].origin.x);
+        }
       ns_unfocus (s->f);
       s->background_filled_p = 1;
     }
@@ -3042,7 +3276,7 @@ ns_draw_glyph_string (struct glyph_string *s)
           NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
           NS_FACE_FOREGROUND (s->face) = tmp;
         }
-                    
+
       ns_tmp_font->font.driver->draw
         (s, 0, s->nchars, s->x, s->y,
          (ns_tmp_flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p)
@@ -3068,9 +3302,9 @@ ns_draw_glyph_string (struct glyph_string *s)
       else
         ns_maybe_dumpglyphs_background
           (s, s->first_glyph->type == COMPOSITE_GLYPH);
-      /* ... */ 
+      /* ... */
       /* Not yet implemented.  */
-      /* ... */ 
+      /* ... */
       ns_unfocus (s->f);
       break;
 
@@ -3820,7 +4054,7 @@ ns_term_init (Lisp_Object display_name)
 
   terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
   init_kboard (terminal->kboard);
-  terminal->kboard->Vwindow_system = Qns;
+  KVAR (terminal->kboard, Vwindow_system) = Qns;
   terminal->kboard->next_kboard = all_kboards;
   all_kboards = terminal->kboard;
   /* Don't let the initial kboard remain current longer than necessary.
@@ -3843,7 +4077,7 @@ ns_term_init (Lisp_Object display_name)
   strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
   terminal->name[SBYTES (display_name)] = 0;
 
-  UNBLOCK_INPUT; 
+  UNBLOCK_INPUT;
 
   if (!inhibit_x_resources)
     {
@@ -3860,7 +4094,7 @@ ns_term_init (Lisp_Object display_name)
                         stringForKey: @"AppleHighlightColor"];
   if (ns_selection_color == nil)
     ns_selection_color = NS_SELECTION_COLOR_DEFAULT;
-  
+
   {
     NSColorList *cl = [NSColorList colorListNamed: @"Emacs"];
 
@@ -3956,7 +4190,7 @@ ns_term_init (Lisp_Object display_name)
                    keyEquivalent: @"q"
                          atIndex: 9];
 
-    item = [mainMenu insertItemWithTitle: ns_app_name                       
+    item = [mainMenu insertItemWithTitle: ns_app_name
                                   action: @selector (menuDown:)
                            keyEquivalent: @""
                                  atIndex: 0];
@@ -3980,10 +4214,11 @@ ns_term_init (Lisp_Object display_name)
 }
 
 
-extern Lisp_Object Vauto_save_list_file_name;
 void
 ns_term_shutdown (int sig)
 {
+  [[NSUserDefaults standardUserDefaults] synchronize];
+
   /* code not reached in emacs.c after this is called by shut_down_emacs: */
   if (STRINGP (Vauto_save_list_file_name))
     unlink (SDATA (Vauto_save_list_file_name));
@@ -4028,6 +4263,16 @@ ns_term_shutdown (int sig)
 /*  NSTRACE (sendEvent); */
 /*fprintf (stderr, "received event of type %d\t%d\n", type);*/
 
+#ifdef NS_IMPL_COCOA
+  if (type == NSApplicationDefined
+      && [theEvent data2] == NSAPP_DATA2_RUNASSCRIPT)
+    {
+      ns_run_ascript ();
+      [self stop: self];
+      return;
+    }
+#endif
+
   if (type == NSCursorUpdate && window == nil)
     {
       fprintf (stderr, "Dropping external cursor update event.\n");
@@ -4162,7 +4407,7 @@ ns_term_shutdown (int sig)
         -appShouldTerminate
           Cancel -> Nothing else
           Accept ->
-         
+
          -terminate
          KEY_NS_POWER_OFF, (save-buffers-kill-emacs)
          ns_term_shutdown()
@@ -4172,10 +4417,10 @@ ns_term_shutdown (int sig)
 - (void) terminate: (id)sender
 {
   struct frame *emacsframe = SELECTED_FRAME ();
-  
+
   if (!emacs_event)
     return;
-  
+
   emacs_event->kind = NS_NONKEY_EVENT;
   emacs_event->code = KEY_NS_POWER_OFF;
   emacs_event->arg = Qt; /* mark as non-key event */
@@ -4253,7 +4498,13 @@ ns_term_shutdown (int sig)
 }
 - (void)applicationDidBecomeActive: (NSNotification *)notification
 {
+  NSTRACE (applicationDidBecomeActive);
+
   //ns_app_active=YES;
+
+  ns_update_auto_hide_menu_bar ();
+  // No constrining takes place when the application is not active.
+  ns_constrain_all_frames ();
 }
 - (void)applicationDidResignActive: (NSNotification *)notification
 {
@@ -4432,7 +4683,10 @@ ns_term_shutdown (int sig)
   unsigned fnKeysym = 0;
   int flags;
   static NSMutableArray *nsEvArray;
+#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
   static BOOL firstTime = YES;
+#endif
+  int left_is_none;
 
   NSTRACE (keyDown);
 
@@ -4476,7 +4730,7 @@ ns_term_shutdown (int sig)
       code = ([[theEvent charactersIgnoringModifiers] length] == 0) ?
         0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
       /* (Carbon way: [theEvent keyCode]) */
-      
+
       /* is it a "function key"? */
       fnKeysym = ns_convert_key (code);
       if (fnKeysym)
@@ -4556,10 +4810,14 @@ ns_term_shutdown (int sig)
           emacs_event->modifiers |=
             parse_solitary_modifier (ns_function_modifier);
 
+      left_is_none = NILP (ns_alternate_modifier)
+        || EQ (ns_alternate_modifier, Qnone);
+
       if ((flags & NSRightAlternateKeyMask) == NSRightAlternateKeyMask)
         {
           if ((NILP (ns_right_alternate_modifier)
-               || EQ (ns_right_alternate_modifier, Qnone))
+               || EQ (ns_right_alternate_modifier, Qnone)
+               || (EQ (ns_right_alternate_modifier, Qleft) && left_is_none))
               && !fnKeysym)
             {   /* accept pre-interp alt comb */
               if ([[theEvent characters] length] > 0)
@@ -4577,9 +4835,7 @@ ns_term_shutdown (int sig)
 
       if ((flags & NSLeftAlternateKeyMask) == NSLeftAlternateKeyMask) /* default = meta */
         {
-          if ((NILP (ns_alternate_modifier)
-               || EQ (ns_alternate_modifier, Qnone))
-              && !fnKeysym)
+          if (left_is_none && !fnKeysym)
             {   /* accept pre-interp alt comb */
               if ([[theEvent characters] length] > 0)
                 code = [[theEvent characters] characterAtIndex: 0];
@@ -4598,6 +4854,7 @@ ns_term_shutdown (int sig)
 
       /* if it was a function key or had modifiers, pass it directly to emacs */
       if (fnKeysym || (emacs_event->modifiers
+                       && (emacs_event->modifiers != shift_modifier)
                        && [[theEvent charactersIgnoringModifiers] length] > 0))
 /*[[theEvent characters] length] */
         {
@@ -4616,13 +4873,15 @@ ns_term_shutdown (int sig)
         }
     }
 
+
+#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
   /* if we get here we should send the key for input manager processing */
   if (firstTime && [[NSInputManager currentInputManager]
                      wantsToDelayTextChangeNotifications] == NO)
     fprintf (stderr,
           "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n");
   firstTime = NO;
-
+#endif
   if (NS_KEYLOG && !processingCompose)
     fprintf (stderr, "keyDown: Begin compose sequence.\n");
 
@@ -5029,7 +5288,6 @@ ns_term_shutdown (int sig)
 #endif
   if (cols < MINWIDTH)
     cols = MINWIDTH;
-  frameSize.width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (emacsframe, cols);
 
   rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, frameSize.height
 #ifdef NS_IMPL_GNUSTEP
@@ -5041,9 +5299,6 @@ ns_term_shutdown (int sig)
 #endif
   if (rows < MINHEIGHT)
     rows = MINHEIGHT;
-  frameSize.height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (emacsframe, rows)
-                       + FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
-                       + FRAME_TOOLBAR_HEIGHT (emacsframe);
 #ifdef NS_IMPL_COCOA
   {
     /* this sets window title to have size in it; the wm does this under GS */
@@ -5070,7 +5325,7 @@ ns_term_shutdown (int sig)
             strcpy (old_title, t);
           }
         size_title = xmalloc (strlen (old_title) + 40);
-        sprintf (size_title, "%s  —  (%d x %d)", old_title, cols, rows);
+       esprintf (size_title, "%s  —  (%d x %d)", old_title, cols, rows);
         [window setTitle: [NSString stringWithUTF8String: size_title]];
         [window display];
         xfree (size_title);
@@ -5111,7 +5366,23 @@ ns_term_shutdown (int sig)
      a "windowDidResize" which calls x_set_window_size).  */
 #ifndef NS_IMPL_GNUSTEP
   if (cols > 0 && rows > 0)
-     x_set_window_size (emacsframe, 0, cols, rows);
+    {
+      if (ns_in_resize)
+        x_set_window_size (emacsframe, 0, cols, rows);
+      else
+        {
+          NSWindow *window = [self window];
+          NSRect wr = [window frame];
+          FRAME_PIXEL_WIDTH (emacsframe) = (int)wr.size.width
+            - emacsframe->border_width;
+          FRAME_PIXEL_HEIGHT (emacsframe) = (int)wr.size.height
+            - FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
+            - FRAME_TOOLBAR_HEIGHT (emacsframe);
+          change_frame_size (emacsframe, rows, cols, 0, 0, 1);
+          SET_FRAME_GARBAGED (emacsframe);
+          cancel_mouse_face (emacsframe);
+        }
+    }
 #endif
 
   ns_send_appdefined (-1);
@@ -5204,6 +5475,7 @@ ns_term_shutdown (int sig)
 
 /*fprintf (stderr,"init with %d, %d\n",f->text_cols, f->text_lines); */
 
+  ns_userRect = NSMakeRect (0, 0, 0, 0);
   r = NSMakeRect (0, 0, FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols),
                  FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, f->text_lines));
   [self initWithFrame: r];
@@ -5216,6 +5488,9 @@ ns_term_shutdown (int sig)
   win = [[EmacsWindow alloc]
             initWithContentRect: r
                       styleMask: (NSResizableWindowMask |
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+                                  NSTitledWindowMask |
+#endif
                                   NSMiniaturizableWindowMask |
                                   NSClosableWindowMask)
                         backing: NSBackingStoreBuffered
@@ -5281,6 +5556,9 @@ ns_term_shutdown (int sig)
 
   [self allocateGState];
 
+  [NSApp registerServicesMenuSendTypes: ns_send_types
+                           returnTypes: nil];
+
   ns_window_num++;
   return self;
 }
@@ -5290,7 +5568,8 @@ ns_term_shutdown (int sig)
 {
   NSWindow *win = [self window];
   NSRect r = [win frame];
-  NSScreen *screen = [win screen];
+  NSArray *screens = [NSScreen screens];
+  NSScreen *screen = [screens objectAtIndex: 0];
 
   NSTRACE (windowDidMove);
 
@@ -5310,10 +5589,7 @@ ns_term_shutdown (int sig)
    location so set_window_size moves the frame. */
 - (BOOL)windowShouldZoom: (NSWindow *)sender toFrame: (NSRect)newFrame
 {
-  NSTRACE (windowShouldZoom);
-  emacsframe->left_pos = (int)newFrame.origin.x;
-  emacsframe->top_pos = [[sender screen] frame].size.height
-                            - (newFrame.origin.y+newFrame.size.height);
+  emacsframe->output_data.ns->zooming = 1;
   return YES;
 }
 
@@ -5325,7 +5601,6 @@ ns_term_shutdown (int sig)
                         defaultFrame:(NSRect)defaultFrame
 {
   NSRect result = [sender frame];
-  static NSRect ns_userRect = { 0, 0, 0, 0 };
 
   NSTRACE (windowWillUseStandardFrame);
 
@@ -5343,7 +5618,11 @@ ns_term_shutdown (int sig)
           > FRAME_COLUMN_WIDTH (emacsframe))
         result = defaultFrame;  /* second click */
       else
-        result = ns_userRect.size.height ? ns_userRect : result;  /* restore */
+        {
+          /* restore */
+          result = ns_userRect.size.height ? ns_userRect : result;
+          ns_userRect = NSMakeRect (0, 0, 0, 0);
+        }
     }
 
   [self windowWillResize: sender toSize: result.size];
@@ -5503,7 +5782,7 @@ ns_term_shutdown (int sig)
 
   /*
     drawRect: may be called (at least in OS X 10.5) for invisible
-    views as well for some reason.  Thus, do not infer visibility 
+    views as well for some reason.  Thus, do not infer visibility
     here.
 
     emacsframe->async_visible = 1;
@@ -5651,13 +5930,16 @@ ns_term_shutdown (int sig)
 }
 
 
-- validRequestorForSendType: (NSString *)typeSent
-                 returnType: (NSString *)typeReturned
+- (id) validRequestorForSendType: (NSString *)typeSent
+                      returnType: (NSString *)typeReturned
 {
   NSTRACE (validRequestorForSendType);
-  if ([ns_send_types indexOfObjectIdenticalTo: typeSent] != NSNotFound &&
-      [ns_return_types indexOfObjectIdenticalTo: typeSent] != NSNotFound)
-    return self;
+  if (typeSent != nil && [ns_send_types indexOfObject: typeSent] != NSNotFound
+      && typeReturned == nil)
+    {
+      if (! NILP (ns_get_local_selection (QPRIMARY, QUTF8_STRING)))
+        return self;
+    }
 
   return [super validRequestorForSendType: typeSent
                                returnType: typeReturned];
@@ -5681,8 +5963,28 @@ ns_term_shutdown (int sig)
 
 - (BOOL) writeSelectionToPasteboard: (NSPasteboard *)pb types: (NSArray *)types
 {
-  /* supposed to write for as many of types as we are able */
-  return NO;
+  NSArray *typesDeclared;
+  Lisp_Object val;
+
+  /* We only support NSStringPboardType */
+  if ([types containsObject:NSStringPboardType] == NO) {
+    return NO;
+  }
+
+  val = ns_get_local_selection (QPRIMARY, QUTF8_STRING);
+  if (CONSP (val) && SYMBOLP (XCAR (val)))
+    {
+      val = XCDR (val);
+      if (CONSP (val) && NILP (XCDR (val)))
+        val = XCAR (val);
+    }
+  if (! STRINGP (val))
+    return NO;
+
+  typesDeclared = [NSArray arrayWithObject:NSStringPboardType];
+  [pb declareTypes:typesDeclared owner:nil];
+  ns_string_to_pasteboard (pb, val);
+  return YES;
 }
 
 
@@ -5728,6 +6030,24 @@ ns_term_shutdown (int sig)
 
 @implementation EmacsWindow
 
+/* If we have multiple monitors, one above the other, we don't want to
+   restrict the height to just one monitor.  So we override this.  */
+- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
+{
+  /* When making the frame visible for the first time, we want to
+     constrain.  Other times not.  */
+  struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
+  NSTRACE (constrainFrameRect);
+
+  if (f->output_data.ns->dont_constrain
+      || ns_menu_bar_should_be_hidden ())
+    return frameRect;
+
+  f->output_data.ns->dont_constrain = 1;
+  return [super constrainFrameRect:frameRect toScreen:screen];
+}
+
+
 /* called only on resize clicks by special case in EmacsApp-sendEvent */
 - (void)mouseDown: (NSEvent *)theEvent
 {
@@ -5773,12 +6093,9 @@ ns_term_shutdown (int sig)
         return;
 
       vettedSize = [[self delegate] windowWillResize: self toSize: size];
-      if (vettedSize.width != size.width || vettedSize.height != size.height)
-        {
-          [[NSNotificationCenter defaultCenter]
+      [[NSNotificationCenter defaultCenter]
             postNotificationName: NSWindowDidResizeNotification
                           object: self];
-        }
     }
   else
     [super mouseDragged: theEvent];
@@ -5829,6 +6146,7 @@ ns_term_shutdown (int sig)
   win = nwin;
   condemned = NO;
   pixel_height = NSHeight (r);
+  if (pixel_height == 0) pixel_height = 1;
   min_portion = 20 / pixel_height;
 
   frame = XFRAME (XWINDOW (win)->frame);
@@ -5858,6 +6176,7 @@ ns_term_shutdown (int sig)
   NSTRACE (EmacsScroller_setFrame);
 /*  BLOCK_INPUT; */
   pixel_height = NSHeight (newRect);
+  if (pixel_height == 0) pixel_height = 1;
   min_portion = 20 / pixel_height;
   [super setFrame: newRect];
   [self display];
@@ -5937,14 +6256,26 @@ ns_term_shutdown (int sig)
   em_whole = whole;
 
   if (portion >= whole)
-    [self setFloatValue: 0.0 knobProportion: 1.0];
+    {
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
+      [self setKnobProportion: 1.0];
+      [self setDoubleValue: 1.0];
+#else
+      [self setFloatValue: 0.0 knobProportion: 1.0];
+#endif
+    }
   else
     {
       float pos, por;
       portion = max ((float)whole*min_portion/pixel_height, portion);
       pos = (float)position / (whole - portion);
       por = (float)portion/whole;
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
+      [self setKnobProportion: por];
+      [self setDoubleValue: pos];
+#else
       [self setFloatValue: pos knobProportion: por];
+#endif
     }
   return self;
 }
@@ -6289,56 +6620,58 @@ syms_of_nsterm (void)
   DEFSYM (Qsuper, "super");
   DEFSYM (Qcontrol, "control");
   DEFSYM (Qnone, "none");
+  DEFSYM (QUTF8_STRING, "UTF8_STRING");
+
   Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
   Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
   Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
   Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
   Fput (Qcontrol, Qmodifier_value, make_number (ctrl_modifier));
 
-  DEFVAR_LISP ("ns-input-file", &ns_input_file,
+  DEFVAR_LISP ("ns-input-file", ns_input_file,
               "The file specified in the last NS event.");
   ns_input_file =Qnil;
 
-  DEFVAR_LISP ("ns-input-text", &ns_input_text,
+  DEFVAR_LISP ("ns-input-text", ns_input_text,
               "The data received in the last NS text drag event.");
   ns_input_text =Qnil;
 
-  DEFVAR_LISP ("ns-working-text", &ns_working_text,
+  DEFVAR_LISP ("ns-working-text", ns_working_text,
               "String for visualizing working composition sequence.");
   ns_working_text =Qnil;
 
-  DEFVAR_LISP ("ns-input-font", &ns_input_font,
+  DEFVAR_LISP ("ns-input-font", ns_input_font,
               "The font specified in the last NS event.");
   ns_input_font =Qnil;
 
-  DEFVAR_LISP ("ns-input-fontsize", &ns_input_fontsize,
+  DEFVAR_LISP ("ns-input-fontsize", ns_input_fontsize,
               "The fontsize specified in the last NS event.");
   ns_input_fontsize =Qnil;
 
-  DEFVAR_LISP ("ns-input-line", &ns_input_line,
+  DEFVAR_LISP ("ns-input-line", ns_input_line,
                "The line specified in the last NS event.");
   ns_input_line =Qnil;
 
-  DEFVAR_LISP ("ns-input-color", &ns_input_color,
+  DEFVAR_LISP ("ns-input-color", ns_input_color,
                "The color specified in the last NS event.");
   ns_input_color =Qnil;
 
-  DEFVAR_LISP ("ns-input-spi-name", &ns_input_spi_name,
+  DEFVAR_LISP ("ns-input-spi-name", ns_input_spi_name,
                "The service name specified in the last NS event.");
   ns_input_spi_name =Qnil;
 
-  DEFVAR_LISP ("ns-input-spi-arg", &ns_input_spi_arg,
+  DEFVAR_LISP ("ns-input-spi-arg", ns_input_spi_arg,
                "The service argument specified in the last NS event.");
   ns_input_spi_arg =Qnil;
 
-  DEFVAR_LISP ("ns-alternate-modifier", &ns_alternate_modifier,
+  DEFVAR_LISP ("ns-alternate-modifier", ns_alternate_modifier,
                "This variable describes the behavior of the alternate or option key.\n\
 Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
 Set to none means that the alternate / option key is not interpreted by Emacs\n\
 at all, allowing it to be used at a lower level for accented character entry.");
   ns_alternate_modifier = Qmeta;
 
-  DEFVAR_LISP ("ns-right-alternate-modifier", &ns_right_alternate_modifier,
+  DEFVAR_LISP ("ns-right-alternate-modifier", ns_right_alternate_modifier,
                "This variable describes the behavior of the right alternate or option key.\n\
 Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
 Set to left means be the same key as `ns-alternate-modifier'.\n\
@@ -6346,12 +6679,12 @@ Set to none means that the alternate / option key is not interpreted by Emacs\n\
 at all, allowing it to be used at a lower level for accented character entry.");
   ns_right_alternate_modifier = Qleft;
 
-  DEFVAR_LISP ("ns-command-modifier", &ns_command_modifier,
+  DEFVAR_LISP ("ns-command-modifier", ns_command_modifier,
                "This variable describes the behavior of the command key.\n\
 Set to control, meta, alt, super, or hyper means it is taken to be that key.");
   ns_command_modifier = Qsuper;
 
-  DEFVAR_LISP ("ns-right-command-modifier", &ns_right_command_modifier,
+  DEFVAR_LISP ("ns-right-command-modifier", ns_right_command_modifier,
                "This variable describes the behavior of the right command key.\n\
 Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
 Set to left means be the same key as `ns-command-modifier'.\n\
@@ -6359,12 +6692,12 @@ Set to none means that the command / option key is not interpreted by Emacs\n\
 at all, allowing it to be used at a lower level for accented character entry.");
   ns_right_command_modifier = Qleft;
 
-  DEFVAR_LISP ("ns-control-modifier", &ns_control_modifier,
+  DEFVAR_LISP ("ns-control-modifier", ns_control_modifier,
                "This variable describes the behavior of the control key.\n\
 Set to control, meta, alt, super, or hyper means it is taken to be that key.");
   ns_control_modifier = Qcontrol;
 
-  DEFVAR_LISP ("ns-right-control-modifier", &ns_right_control_modifier,
+  DEFVAR_LISP ("ns-right-control-modifier", ns_right_control_modifier,
                "This variable describes the behavior of the right control key.\n\
 Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
 Set to left means be the same key as `ns-control-modifier'.\n\
@@ -6372,18 +6705,18 @@ Set to none means that the control / option key is not interpreted by Emacs\n\
 at all, allowing it to be used at a lower level for accented character entry.");
   ns_right_control_modifier = Qleft;
 
-  DEFVAR_LISP ("ns-function-modifier", &ns_function_modifier,
+  DEFVAR_LISP ("ns-function-modifier", ns_function_modifier,
                "This variable describes the behavior of the function key (on laptops).\n\
 Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
 Set to none means that the function key is not interpreted by Emacs at all,\n\
 allowing it to be used at a lower level for accented character entry.");
   ns_function_modifier = Qnone;
 
-  DEFVAR_LISP ("ns-antialias-text", &ns_antialias_text,
+  DEFVAR_LISP ("ns-antialias-text", ns_antialias_text,
                "Non-nil (the default) means to render text antialiased. Only has an effect on OS X Panther and above.");
   ns_antialias_text = Qt;
 
-  DEFVAR_LISP ("ns-confirm-quit", &ns_confirm_quit,
+  DEFVAR_LISP ("ns-confirm-quit", ns_confirm_quit,
                "Whether to confirm application quit using dialog.");
   ns_confirm_quit = Qnil;
 
@@ -6393,8 +6726,13 @@ allowing it to be used at a lower level for accented character entry.");
   staticpro (&last_mouse_motion_frame);
   last_mouse_motion_frame = Qnil;
 
+  DEFVAR_LISP ("ns-auto-hide-menu-bar", ns_auto_hide_menu_bar,
+               doc: /* Non-nil means that the menu bar is hidden, but appears when the mouse is near.
+Only works on OSX 10.6 or later.  */);
+  ns_auto_hide_menu_bar = Qnil;
+
   /* TODO: move to common code */
-  DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
+  DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
               doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
 #ifdef USE_TOOLKIT_SCROLL_BARS
   Vx_toolkit_scroll_bars = Qt;
@@ -6402,23 +6740,17 @@ allowing it to be used at a lower level for accented character entry.");
   Vx_toolkit_scroll_bars = Qnil;
 #endif
 
-  /* these are unsupported but we need the declarations to avoid whining
-     messages from cus-start.el */
   DEFVAR_BOOL ("x-use-underline-position-properties",
-              &x_use_underline_position_properties,
-     doc: /* NOT SUPPORTED UNDER NS.
-*Non-nil means make use of UNDERLINE_POSITION font properties.
+              x_use_underline_position_properties,
+     doc: /*Non-nil means make use of UNDERLINE_POSITION font properties.
 A value of nil means ignore them.  If you encounter fonts with bogus
 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
-to 4.1, set this to nil.
-
-NOTE: Not supported on Mac yet.  */);
+to 4.1, set this to nil. */);
   x_use_underline_position_properties = 0;
 
   DEFVAR_BOOL ("x-underline-at-descent-line",
-              &x_underline_at_descent_line,
-     doc: /* NOT SUPPORTED UNDER NS.
-*Non-nil means to draw the underline at the same place as the descent line.
+              x_underline_at_descent_line,
+     doc: /* Non-nil means to draw the underline at the same place as the descent line.
 A value of nil means to draw the underline according to the value of the
 variable `x-use-underline-position-properties', which is usually at the
 baseline level.  The default value is nil.  */);
@@ -6427,5 +6759,3 @@ baseline level.  The default value is nil.  */);
   /* Tell emacs about this window system. */
   Fprovide (intern ("ns"), Qnil);
 }
-
-