Merge from emacs-24; up to 2012-12-27T08:21:08Z!rgm@gnu.org
[bpt/emacs.git] / src / nsfns.m
index fac61d2..a483f84 100644 (file)
@@ -107,43 +107,6 @@ static ptrdiff_t image_cache_refcount;
 
    ========================================================================== */
 
-
-void
-check_ns (void)
-{
- if (NSApp == nil)
-   error ("OpenStep is not in use or not initialized");
-}
-
-
-/* Nonzero if we can use mouse menus. */
-int
-have_menus_p (void)
-{
-  return NSApp != nil;
-}
-
-
-/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
-   and checking validity for NS.  */
-static FRAME_PTR
-check_ns_frame (Lisp_Object frame)
-{
-  FRAME_PTR f;
-
-  if (NILP (frame))
-      f = SELECTED_FRAME ();
-  else
-    {
-      CHECK_LIVE_FRAME (frame);
-      f = XFRAME (frame);
-    }
-  if (! FRAME_NS_P (f))
-    error ("non-Nextstep frame used");
-  return f;
-}
-
-
 /* Let the user specify an Nextstep display with a frame.
    nil stands for the selected frame--or, if that is not an Nextstep frame,
    the first Nextstep display on the list.  */
@@ -261,6 +224,29 @@ ns_display_info_for_name (Lisp_Object name)
   return dpyinfo;
 }
 
+static NSString *
+ns_filename_from_panel (NSSavePanel *panel)
+{
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+  NSURL *url = [panel URL];
+  NSString *str = [url path];
+  return str;
+#else
+  return [panel filename];
+#endif
+}
+
+static NSString *
+ns_directory_from_panel (NSSavePanel *panel)
+{
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+  NSURL *url = [panel directoryURL];
+  NSString *str = [url path];
+  return str;
+#else
+  return [panel directory];
+#endif
+}
 
 static Lisp_Object
 interpret_services_menu (NSMenu *menu, Lisp_Object prefix, Lisp_Object old)
@@ -596,7 +582,7 @@ ns_set_name_as_filename (struct frame *f)
 {
   NSView *view;
   Lisp_Object name, filename;
-  Lisp_Object buf = XWINDOW (f->selected_window)->buffer;
+  Lisp_Object buf = XWINDOW (f->selected_window)->contents;
   const char *title;
   NSAutoreleasePool *pool;
   struct gcpro gcpro1;
@@ -1122,8 +1108,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
   Lisp_Object tfont, tfontsize;
   static int desc_ctr = 1;
 
-  check_ns ();
-
   /* x_get_arg modifies parms.  */
   parms = Fcopy_alist (parms);
 
@@ -1220,9 +1204,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
       specbind (Qx_resource_name, name);
     }
 
-  f->resx = dpyinfo->resx;
-  f->resy = dpyinfo->resy;
-
   block_input ();
   register_font_driver (&nsfont_driver, f);
   x_default_parameter (f, parms, Qfont_backend, Qnil,
@@ -1398,7 +1379,7 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
 FRAME nil means use the selected frame.  */)
      (Lisp_Object frame)
 {
-  struct frame *f = check_ns_frame (frame);
+  struct frame *f = decode_window_system_frame (frame);
   struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
 
   if (dpyinfo->x_focus_frame != f)
@@ -1419,18 +1400,8 @@ DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
        doc: /* Pop up the font panel. */)
      (Lisp_Object frame)
 {
-  id fm;
-  struct frame *f;
-
-  check_ns ();
-  fm = [NSFontManager sharedFontManager];
-  if (NILP (frame))
-    f = SELECTED_FRAME ();
-  else
-    {
-      CHECK_FRAME (frame);
-      f = XFRAME (frame);
-    }
+  struct frame *f = decode_window_system_frame (frame);
+  id fm = [NSFontManager sharedFontManager];
 
   [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont
            isMultiple: NO];
@@ -1444,17 +1415,7 @@ DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel,
        doc: /* Pop up the color panel.  */)
      (Lisp_Object frame)
 {
-  struct frame *f;
-
-  check_ns ();
-  if (NILP (frame))
-    f = SELECTED_FRAME ();
-  else
-    {
-      CHECK_FRAME (frame);
-      f = XFRAME (frame);
-    }
-
+  check_window_system (NULL);
   [NSApp orderFrontColorPanel: NSApp];
   return Qnil;
 }
@@ -1471,7 +1432,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories.  */)
    Lisp_Object init, Lisp_Object dir_only_p)
 {
   static id fileDelegate = nil;
-  int ret;
+  BOOL ret;
   id panel;
   Lisp_Object fname;
 
@@ -1483,7 +1444,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories.  */)
   NSString *initS = NILP (init) || !STRINGP (init) ? nil :
     [NSString stringWithUTF8String: SSDATA (init)];
 
-  check_ns ();
+  check_window_system (NULL);
 
   if (fileDelegate == nil)
     fileDelegate = [EmacsFileDelegate new];
@@ -1508,6 +1469,13 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories.  */)
       [panel setCanChooseDirectories: YES];
       [panel setCanChooseFiles: NO];
     }
+  else
+    {
+      /* This is not quite what the documentation says, but it is compatible
+         with the Gtk+ code.  Also, the menu entry says "Open File...".  */
+      [panel setCanChooseDirectories: NO];
+      [panel setCanChooseFiles: YES];
+    }
 
   block_input ();
 #if defined (NS_IMPL_COCOA) && \
@@ -1528,15 +1496,19 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories.  */)
     }
   else
     {
-      [panel setCanChooseDirectories: YES];
       ret = [panel runModalForDirectory: dirS file: initS types: nil];
     }
 #endif
 
   ret = (ret == NSOKButton) || panelOK;
 
-  if (ret)
-    fname = build_string ([[panel filename] UTF8String]);
+  if (ret) 
+    {
+      NSString *str = [panel getFilename];
+      if (! str) str = [panel getDirectory];
+      if (! str) ret = NO;
+      else fname = build_string ([str UTF8String]);
+    }
 
   [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
   unblock_input ();
@@ -1563,11 +1535,10 @@ If OWNER is nil, Emacs is assumed.  */)
 {
   const char *value;
 
-  check_ns ();
+  check_window_system (NULL);
   if (NILP (owner))
     owner = build_string([ns_app_name UTF8String]);
   CHECK_STRING (name);
-/*fprintf (stderr, "ns-get-resource checking resource '%s'\n", SSDATA (name)); */
 
   value = ns_get_defaults_value (SSDATA (name));
 
@@ -1583,7 +1554,7 @@ If OWNER is nil, Emacs is assumed.
 If VALUE is nil, the default is removed.  */)
      (Lisp_Object owner, Lisp_Object name, Lisp_Object value)
 {
-  check_ns ();
+  check_window_system (NULL);
   if (NILP (owner))
     owner = build_string ([ns_app_name UTF8String]);
   CHECK_STRING (name);
@@ -1611,7 +1582,7 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
        doc: /* This function is a no-op.  It is only present for completeness.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   /* This function has no real equivalent under NeXTstep.  Return nil to
      indicate this. */
   return Qnil;
@@ -1649,9 +1620,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
           The last number is where we distinguish between the Apple
           and GNUstep implementations ("distributor-specific release
           number") and give int'ized versions of major.minor. */
-  return Fcons (make_number (10),
-               Fcons (make_number (3),
-                      Fcons (make_number (ns_appkit_version_int()), Qnil)));
+  return list3i (10, 3, ns_appkit_version_int ());
 }
 
 
@@ -1663,7 +1632,7 @@ If omitted or nil, the selected frame's display is used.  */)
 {
   int num;
 
-  check_ns ();
+  check_ns_display_info (display);
   num = [[NSScreen screens] count];
 
   return (num != 0) ? make_number (num) : Qnil;
@@ -1677,7 +1646,7 @@ DISPLAY should be a frame, the display name as a string, or a terminal ID.
 If omitted or nil, the selected frame's display is used.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   return make_number ((int)
                      ([ns_get_screen (display) frame].size.height/(92.0/25.4)));
 }
@@ -1690,7 +1659,7 @@ DISPLAY should be a frame, the display name as a string, or a terminal ID.
 If omitted or nil, the selected frame's display is used.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   return make_number ((int)
                      ([ns_get_screen (display) frame].size.width/(92.0/25.4)));
 }
@@ -1704,7 +1673,7 @@ DISPLAY should be a frame, the display name as a string, or a terminal ID.
 If omitted or nil, the selected frame's display is used.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   switch ([ns_get_window (display) backingType])
     {
     case NSBackingStoreBuffered:
@@ -1730,7 +1699,8 @@ If omitted or nil, the selected frame's display is used.  */)
      (Lisp_Object display)
 {
   NSWindowDepth depth;
-  check_ns ();
+  
+  check_ns_display_info (display);
   depth = [ns_get_screen (display) depth];
 
   if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
@@ -1757,7 +1727,7 @@ DISPLAY should be a frame, the display name as a string, or a terminal ID.
 If omitted or nil, the selected frame's display is used.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   switch ([ns_get_window (display) backingType])
     {
     case NSBackingStoreBuffered:
@@ -1807,11 +1777,10 @@ terminate Emacs if we can't open the connection.
 DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
        1, 1, 0,
        doc: /* Close the connection to the current Nextstep display server.
-The argument DISPLAY is currently ignored.  */)
+DISPLAY should be a frame, the display name as a string, or a terminal ID.  */)
      (Lisp_Object display)
 {
-  check_ns ();
-  /*ns_delete_terminal (dpyinfo->terminal); */
+  check_ns_display_info (display);
   [NSApp terminate: NSApp];
   return Qnil;
 }
@@ -1836,7 +1805,7 @@ DEFUN ("ns-hide-others", Fns_hide_others, Sns_hide_others,
        doc: /* Hides all applications other than Emacs.  */)
      (void)
 {
-  check_ns ();
+  check_window_system (NULL);
   [NSApp hideOtherApplications: NSApp];
   return Qnil;
 }
@@ -1849,7 +1818,7 @@ If ON is equal to `activate', Emacs is unhidden and becomes
 the active application.  */)
      (Lisp_Object on)
 {
-  check_ns ();
+  check_window_system (NULL);
   if (EQ (on, intern ("activate")))
     {
       [NSApp unhide: NSApp];
@@ -1868,7 +1837,7 @@ DEFUN ("ns-emacs-info-panel", Fns_emacs_info_panel, Sns_emacs_info_panel,
        doc: /* Shows the 'Info' or 'About' panel for Emacs.  */)
      (void)
 {
-  check_ns ();
+  check_window_system (NULL);
   [NSApp orderFrontStandardAboutPanel: nil];
   return Qnil;
 }
@@ -1946,7 +1915,7 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
   NSMenu *svcs;
   id delegate;
 
-  check_ns ();
+  check_window_system (NULL);
   svcs = [[NSMenu alloc] initWithTitle: @"Services"];
   [NSApp setServicesMenu: svcs];
   [NSApp registerServicesMenuSendTypes: ns_send_types
@@ -1999,7 +1968,7 @@ there was no result.  */)
   char *utfStr;
 
   CHECK_STRING (service);
-  check_ns ();
+  check_window_system (NULL);
 
   utfStr = SSDATA (service);
   svcName = [NSString stringWithUTF8String: utfStr];
@@ -2123,7 +2092,7 @@ In case the execution fails, an error is signaled. */)
   NSEvent *nxev;
 
   CHECK_STRING (script);
-  check_ns ();
+  check_window_system (NULL);
 
   block_input ();
 
@@ -2172,15 +2141,6 @@ In case the execution fails, an error is signaled. */)
 
    ========================================================================== */
 
-
-/* called from image.c */
-FRAME_PTR
-check_x_frame (Lisp_Object frame)
-{
-  return check_ns_frame (frame);
-}
-
-
 /* called from frame.c */
 struct ns_display_info *
 check_x_display_info (Lisp_Object frame)
@@ -2206,7 +2166,7 @@ x_get_string_resource (XrmDatabase rdb, char *name, char *class)
   /* remove appname prefix; TODO: allow for !="Emacs" */
   char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
   const char *res;
-  check_ns ();
+  check_window_system (NULL);
 
   if (inhibit_x_resources)
     /* --quick was passed, so this is a no-op.  */
@@ -2276,7 +2236,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
      (Lisp_Object color, Lisp_Object frame)
 {
   NSColor * col;
-  check_ns ();
+  check_window_system (NULL);
   return ns_lisp_to_color (color, &col) ? Qnil : Qt;
 }
 
@@ -2288,7 +2248,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
   NSColor * col;
   CGFloat red, green, blue, alpha;
 
-  check_ns ();
+  check_window_system (NULL);
   CHECK_STRING (color);
 
   if (ns_lisp_to_color (color, &col))
@@ -2296,9 +2256,8 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
 
   [[col colorUsingColorSpaceName: NSCalibratedRGBColorSpace]
         getRed: &red green: &green blue: &blue alpha: &alpha];
-  return list3 (make_number (lrint (red*65280)),
-               make_number (lrint (green*65280)),
-               make_number (lrint (blue*65280)));
+  return list3i (lrint (red * 65280), lrint (green * 65280),
+                lrint (blue * 65280));
 }
 
 
@@ -2308,7 +2267,8 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
 {
   NSWindowDepth depth;
   NSString *colorSpace;
-  check_ns ();
+  
+  check_ns_display_info (display);
   depth = [ns_get_screen (display) depth];
   colorSpace = NSColorSpaceFromDepth (depth);
 
@@ -2328,7 +2288,8 @@ If omitted or nil, that stands for the selected frame's display. */)
      (Lisp_Object display)
 {
   NSWindowDepth depth;
-  check_ns ();
+
+  check_ns_display_info (display);
   depth = [ns_get_screen (display) depth];
 
   return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
@@ -2343,7 +2304,7 @@ DISPLAY should be either a frame, a display name (a string), or terminal ID.
 If omitted or nil, that stands for the selected frame's display.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   return make_number ((int) [ns_get_screen (display) frame].size.width);
 }
 
@@ -2356,7 +2317,7 @@ DISPLAY should be either a frame, a display name (a string), or terminal ID.
 If omitted or nil, that stands for the selected frame's display.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   return make_number ((int) [ns_get_screen (display) frame].size.height);
 }
 
@@ -2376,7 +2337,7 @@ that stands for the selected frame's display. */)
   NSScreen *screen;
   NSRect vScreen;
 
-  check_ns ();
+  check_ns_display_info (display);
   screen = ns_get_screen (display);
   if (!screen)
     return Qnil;
@@ -2385,11 +2346,10 @@ that stands for the selected frame's display. */)
 
   /* NS coordinate system is upside-down.
      Transform to screen-specific coordinates. */
-  return list4 (make_number ((int) vScreen.origin.x),
-               make_number ((int) [screen frame].size.height
-                            - vScreen.size.height - vScreen.origin.y),
-                make_number ((int) vScreen.size.width),
-                make_number ((int) vScreen.size.height));
+  return list4i (vScreen.origin.x,
+                [screen frame].size.height
+                - vScreen.size.height - vScreen.origin.y,
+                vScreen.size.width, vScreen.size.height);
 }
 
 
@@ -2401,7 +2361,7 @@ DISPLAY should be either a frame, a display name (a string), or terminal ID.
 If omitted or nil, that stands for the selected frame's display.  */)
      (Lisp_Object display)
 {
-  check_ns ();
+  check_ns_display_info (display);
   return make_number
     (NSBitsPerPixelFromDepth ([ns_get_screen (display) depth]));
 }
@@ -2415,10 +2375,7 @@ DISPLAY should be either a frame, a display name (a string), or terminal ID.
 If omitted or nil, that stands for the selected frame's display.  */)
      (Lisp_Object display)
 {
-  struct ns_display_info *dpyinfo;
-  check_ns ();
-
-  dpyinfo = check_ns_display_info (display);
+  struct ns_display_info *dpyinfo = check_ns_display_info (display);
   /* We force 24+ bit depths to 24-bit to prevent an overflow.  */
   return make_number (1 << min (dpyinfo->n_planes, 24));
 }
@@ -2531,7 +2488,7 @@ Text larger than the specified size is clipped.  */)
 
   CHECK_STRING (string);
   str = SSDATA (string);
-  f = check_x_frame (frame);
+  f = decode_window_system_frame (frame);
   if (NILP (timeout))
     timeout = make_number (5);
   else
@@ -2607,6 +2564,14 @@ Value is t if tooltip was open, nil otherwise.  */)
   [NSApp stop: self];
 }
 #endif
+- (NSString *) getFilename
+{
+  return ns_filename_from_panel (self);
+}
+- (NSString *) getDirectory
+{
+  return ns_directory_from_panel (self);
+}
 @end
 
 
@@ -2620,6 +2585,12 @@ Value is t if tooltip was open, nil otherwise.  */)
 - (void) ok: (id)sender
 {
   [super ok: sender];
+
+  // If not choosing directories, and Open is pressed on a directory, return.
+  if (! [self canChooseDirectories] && [self getDirectory] &&
+      ! [self getFilename])
+    return;
+
   panelOK = 1;
   [NSApp stop: self];
 }
@@ -2628,7 +2599,17 @@ Value is t if tooltip was open, nil otherwise.  */)
   [super cancel: sender];
   [NSApp stop: self];
 }
+
 #endif
+- (NSString *) getFilename
+{
+  return ns_filename_from_panel (self);
+}
+- (NSString *) getDirectory
+{
+  return ns_directory_from_panel (self);
+}
+
 @end
 
 
@@ -2736,9 +2717,6 @@ be used as the image of the icon representing the frame.  */);
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
 
-  /* used only in fontset.c */
-  check_window_system_func = check_ns;
-
   as_status = 0;
   as_script = Qnil;
   as_result = 0;