]> code.delx.au - gnu-emacs/blobdiff - src/nsterm.m
Bump version to 24.1.
[gnu-emacs] / src / nsterm.m
index ac9c44a57a95b49996b3f62315b34ce07e533b04..7cbaf9913111c40d77da7ec43b771ea14414e36f 100644 (file)
@@ -1,6 +1,7 @@
 /* NeXT/Open/GNUstep / MacOSX communication module.
-   Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2011
-     Free Software Foundation, Inc.
+
+Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2012
+  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -64,6 +65,7 @@ int term_trace_num = 0;
 #define NSTRACE(x)
 #endif
 
+extern NSString *NSMenuDidBeginTrackingNotification;
 
 /* ==========================================================================
 
@@ -134,11 +136,12 @@ static unsigned convert_ns_to_X_keysym[] =
   0x1B,                                0x1B   /* escape */
 };
 
-
 static Lisp_Object Qmodifier_value;
 Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone;
 extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft;
 
+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
    no way to control this behavior. */
@@ -163,7 +166,7 @@ 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;
@@ -262,8 +265,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);
 
-/* FIXME: figure out what to do with underline_minimum_offset. */
-
 
 /* ==========================================================================
 
@@ -560,7 +561,7 @@ ns_constrain_all_frames (void)
         {
           NSView *view = FRAME_NS_VIEW (f);
           /* This no-op will trigger the default window placing
-           * constriant system. */
+           * constraint system. */
           f->output_data.ns->dont_constrain = 0;
           [[view window] setFrameOrigin:[[view window] frame].origin];
         }
@@ -1124,12 +1125,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);
@@ -1161,13 +1160,27 @@ x_destroy_window (struct frame *f)
 
   xfree (f->output_data.ns);
 
+  if (f->output_data.ns->miniimage != nil)
+    [f->output_data.ns->miniimage release];
+
   [[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)
@@ -1342,8 +1355,8 @@ 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;
-  NSNumber *index;
+  ptrdiff_t idx;
+  ptrdiff_t i;
 
   if (!color_table->colors)
     {
@@ -1356,33 +1369,22 @@ ns_index_color (NSColor *color, struct frame *f)
     }
 
   /* do we already have this color ? */
-  {
-    int i;
-    for (i = 1; i < color_table->avail; i++)
-      {
-        if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
-          {
-            [color_table->colors[i] retain];
-            return i;
-          }
-      }
-  }
+  for (i = 1; i < color_table->avail; i++)
+    if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
+      return i;
 
   if ([color_table->empty_indices count] > 0)
     {
-      index = [color_table->empty_indices anyObject];
+      NSNumber *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++;
     }
 
@@ -1406,20 +1408,20 @@ ns_free_indexed_color (unsigned long idx, struct frame *f)
   color_table = FRAME_NS_DISPLAY_INFO (f)->color_table;
 
   if (idx <= 0 || idx >= color_table->size) {
-    message1("ns_free_indexed_color: Color index out of range.\n");
+    message1 ("ns_free_indexed_color: Color index out of range.\n");
     return;
   }
 
   index = [NSNumber numberWithUnsignedInt: idx];
   if ([color_table->empty_indices containsObject: index]) {
-    message1("ns_free_indexed_color: attempt to free already freed color.\n");
+    message1 ("ns_free_indexed_color: attempt to free already freed color.\n");
     return;
   }
 
   color = color_table->colors[idx];
   [color release];
   color_table->colors[idx] = nil;
-  [color_table->empty_indices addObject: [NSNumber numberWithUnsignedInt: idx]];
+  [color_table->empty_indices addObject: index];
 /*fprintf(stderr, "color_table: FREED %d\n",idx);*/
 }
 
@@ -2103,7 +2105,7 @@ ns_scroll_run (struct window *w, struct run *run)
     }
   else
     {
-      /* Scolling down.  Make sure we don't copy over the mode line.
+      /* Scrolling down.  Make sure we don't copy over the mode line.
         at the bottom.  */
       if (to_y + run->height > bottom_y)
        height = bottom_y - to_y;
@@ -2322,7 +2324,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);
 
@@ -2596,6 +2598,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)
@@ -2853,6 +2956,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
   char raised_p;
   NSRect br;
   struct face *face;
+  NSColor *tdCol;
 
   NSTRACE (ns_dumpglyphs_image);
 
@@ -2881,10 +2985,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)
@@ -2922,6 +3023,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 anticipation 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)
     {
@@ -2950,7 +3072,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
 
   /* If there is no mask, the background won't be seen,
      so draw a rectangle on the image for the cursor.
-     Do this for all images, getting trancparency right is not reliable.  */
+     Do this for all images, getting transparency right is not reliable.  */
   if (s->hl == DRAW_CURSOR)
     {
       int thickness = abs (s->img->relief);
@@ -2966,22 +3088,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
@@ -2997,30 +3146,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;
     }
@@ -3665,11 +3821,9 @@ ns_default (const char *parameter, Lisp_Object *result,
       Check a parameter value in user's preferences
    -------------------------------------------------------------------------- */
 {
-  const char *value;
+  const char *value = ns_get_defaults_value (parameter);
 
-  if ( (value =[[[NSUserDefaults standardUserDefaults]
-                   stringForKey: [NSString stringWithUTF8String: parameter]]
-                UTF8String]) )
+  if (value)
     {
       double f;
       char *pos;
@@ -4046,6 +4200,15 @@ ns_term_init (Lisp_Object display_name)
     [NSApp setServicesMenu: svcsMenu];
     /* Needed at least on Cocoa, to get dock menu to show windows */
     [NSApp setWindowsMenu: [[NSMenu alloc] init]];
+
+    [[NSNotificationCenter defaultCenter]
+      addObserver: mainMenu
+         selector: @selector (trackingNotification:)
+             name: NSMenuDidBeginTrackingNotification object: mainMenu];
+    [[NSNotificationCenter defaultCenter]
+      addObserver: mainMenu
+         selector: @selector (trackingNotification:)
+             name: NSMenuDidEndTrackingNotification object: mainMenu];
   }
 #endif /* MAC OS X menu setup */
 
@@ -4058,6 +4221,8 @@ ns_term_init (Lisp_Object display_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));
@@ -4102,6 +4267,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");
@@ -4332,7 +4507,7 @@ ns_term_shutdown (int sig)
   //ns_app_active=YES;
 
   ns_update_auto_hide_menu_bar ();
-  // No constrining takes place when the application is not active.
+  // No constraining takes place when the application is not active.
   ns_constrain_all_frames ();
 }
 - (void)applicationDidResignActive: (NSNotification *)notification
@@ -4512,7 +4687,9 @@ 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);
@@ -4700,13 +4877,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");
 
@@ -5150,7 +5329,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);
@@ -5191,7 +5370,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);
@@ -5297,6 +5492,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
@@ -5362,6 +5560,9 @@ ns_term_shutdown (int sig)
 
   [self allocateGState];
 
+  [NSApp registerServicesMenuSendTypes: ns_send_types
+                           returnTypes: nil];
+
   ns_window_num++;
   return self;
 }
@@ -5733,13 +5934,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];
@@ -5763,8 +5967,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;
 }
 
 
@@ -5814,11 +6038,15 @@ ns_term_shutdown (int sig)
    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.  */
+  /* When making the frame visible for the first time or if there is just
+     one screen, we want to constrain.  Other times not.  */
+  NSUInteger nr_screens = [[NSScreen screens] count];
   struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
   NSTRACE (constrainFrameRect);
 
+  if (nr_screens == 1)
+    return [super constrainFrameRect:frameRect toScreen:screen];
+  
   if (f->output_data.ns->dont_constrain
       || ns_menu_bar_should_be_hidden ())
     return frameRect;
@@ -6036,14 +6264,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;
 }
@@ -6388,6 +6628,8 @@ 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));
@@ -6499,30 +6741,24 @@ Only works on OSX 10.6 or later.  */);
 
   /* TODO: move to common code */
   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
-              doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
-#ifdef USE_TOOLKIT_SCROLL_BARS
+              doc: /* Which toolkit scroll bars Emacs uses, if any.
+A value of nil means Emacs doesn't use toolkit scroll bars.
+With the X Window system, the value is a symbol describing the
+X toolkit.  Possible values are: gtk, motif, xaw, or xaw3d.
+With MS Windows or Nextstep, the value is t.  */);
   Vx_toolkit_scroll_bars = Qt;
-#else
-  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.
+     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.
+     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.  */);