]> code.delx.au - gnu-emacs/blobdiff - src/macfns.c
*** empty log message ***
[gnu-emacs] / src / macfns.c
index de6a055fce62171408cd32eb20f9f5f85d77c2e8..f9a5f051eb4667b975763707fe1f96bfe879ff63 100644 (file)
@@ -1,6 +1,6 @@
 /* Graphical user interface functions for Mac OS.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-                 2005 Free Software Foundation, Inc.
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -210,15 +210,6 @@ void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
-void x_set_scroll_bar_foreground P_ ((struct frame *, Lisp_Object,
-                                     Lisp_Object));
-void x_set_scroll_bar_background P_ ((struct frame *, Lisp_Object,
-                                     Lisp_Object));
-static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
-                                                            Lisp_Object,
-                                                            Lisp_Object,
-                                                            char *, char *,
-                                                            int));
 
 extern void mac_get_window_bounds P_ ((struct frame *, Rect *, Rect *));
 
@@ -1033,7 +1024,7 @@ Lisp_Object
 x_to_mac_color (colorname)
      char * colorname;
 {
-  register Lisp_Object tail, ret = Qnil;
+  register Lisp_Object ret = Qnil;
 
   BLOCK_INPUT;
 
@@ -1368,7 +1359,6 @@ x_set_mouse_color (f, arg, oldval)
      Lisp_Object arg, oldval;
 {
   struct x_output *x = f->output_data.x;
-  Display *dpy = FRAME_MAC_DISPLAY (f);
   Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
   Cursor hourglass_cursor, horizontal_drag_cursor;
   unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
@@ -1448,7 +1438,8 @@ x_set_mouse_color (f, arg, oldval)
 
   BLOCK_INPUT;
 
-  rif->define_frame_cursor (f, cursor);
+  if (FRAME_MAC_WINDOW (f) != 0)
+    rif->define_frame_cursor (f, cursor);
 
   f->output_data.mac->text_cursor = cursor;
   f->output_data.mac->nontext_cursor = nontext_cursor;
@@ -1646,36 +1637,15 @@ x_set_menu_bar_lines (f, value, oldval)
      struct frame *f;
      Lisp_Object value, oldval;
 {
-  int nlines;
-  int olines = FRAME_MENU_BAR_LINES (f);
-
-  /* Right now, menu bars don't work properly in minibuf-only frames;
-     most of the commands try to apply themselves to the minibuffer
-     frame itself, and get an error because you can't switch buffers
-     in or split the minibuffer window.  */
-  if (FRAME_MINIBUF_ONLY_P (f))
-    return;
-
-  if (INTEGERP (value))
-    nlines = XINT (value);
-  else
-    nlines = 0;
+  /* Make sure we redisplay all windows in this frame.  */
+  windows_or_buffers_changed++;
 
   FRAME_MENU_BAR_LINES (f) = 0;
-  if (nlines)
-    FRAME_EXTERNAL_MENU_BAR (f) = 1;
-  else
-    {
-      if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
-       free_frame_menubar (f);
-      FRAME_EXTERNAL_MENU_BAR (f) = 0;
-
-      /* Adjust the frame size so that the client (text) dimensions
-        remain the same.  This depends on FRAME_EXTERNAL_MENU_BAR being
-        set correctly.  */
-      x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
-      do_pending_window_change (0);
-    }
+  /* The menu bar is always shown.  */
+  FRAME_EXTERNAL_MENU_BAR (f) = 1;
+  if (FRAME_MAC_P (f) && f->output_data.mac->menubar_widget == 0)
+    /* Make sure next redisplay shows the menu bar.  */
+    XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = Qt;
   adjust_glyphs (f);
 }
 
@@ -1917,7 +1887,7 @@ x_set_scroll_bar_default_width (f)
   int wid = FRAME_COLUMN_WIDTH (f);
 
 #ifdef MAC_OSX
-  FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 16;  /* Aqua scroll bars.  */
+  FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH;
   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
                                      wid - 1) / wid;
 #else /* not MAC_OSX */
@@ -1931,6 +1901,24 @@ x_set_scroll_bar_default_width (f)
 #endif /* not MAC_OSX */
 }
 
+void
+mac_set_scroll_bar_width (f, arg, oldval)
+     struct frame *f;
+     Lisp_Object arg, oldval;
+{
+#ifdef MAC_OSX
+  if (INTEGERP (arg) && XINT (arg) > 0)
+    {
+      if (XINT (arg) < (MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH
+                       + MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH) / 2)
+       XSETINT (arg, MAC_AQUA_SMALL_VERTICAL_SCROLL_BAR_WIDTH);
+      else
+       XSETINT (arg, MAC_AQUA_VERTICAL_SCROLL_BAR_WIDTH);
+    }
+#endif
+  x_set_scroll_bar_width (f, arg, oldval);
+}
+
 \f
 /* Subroutines of creating a frame.  */
 
@@ -2398,11 +2386,11 @@ This function is an internal primitive--use `make-frame' instead.  */)
   struct mac_display_info *dpyinfo = NULL;
   Lisp_Object parent;
   struct kboard *kb;
-  char x_frame_name[10];
-  static int x_frame_count = 2;  /* begins at 2 because terminal frame is F1 */
 
   check_mac ();
 
+  parms = Fcopy_alist (parms);
+
   /* Use this general default value to start with
      until we know if this frame has a specified name.  */
   Vx_resource_name = Vinvocation_name;
@@ -2452,18 +2440,6 @@ This function is an internal primitive--use `make-frame' instead.  */)
   else
     f = make_frame (1);
 
-  if (EQ (name, Qunbound) || NILP (name))
-    {
-      sprintf (x_frame_name, "F%d", x_frame_count++);
-      f->name = build_string (x_frame_name);
-      f->explicit_name = 0;
-    }
-  else
-    {
-      f->name = name;
-      f->explicit_name = 1;
-    }
-
   XSETFRAME (frame, f);
 
   /* Note that X Windows does support scroll bars.  */
@@ -2544,7 +2520,7 @@ This function is an internal primitive--use `make-frame' instead.  */)
       font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
     /* If those didn't work, look for something which will at least work.  */
     if (! STRINGP (font))
-      font = x_new_fontset (f, "fontset-mac");
+      font = x_new_fontset (f, "fontset-standard");
     if (! STRINGP (font))
       font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
     if (! STRINGP (font))
@@ -2679,17 +2655,28 @@ This function is an internal primitive--use `make-frame' instead.  */)
       if (EQ (visibility, Qunbound))
        visibility = Qt;
 
-#if 0 /* MAC_TODO: really no iconify on Mac */
       if (EQ (visibility, Qicon))
        x_iconify_frame (f);
-      else
-#endif
-      if (! NILP (visibility))
+      else if (! NILP (visibility))
        x_make_frame_visible (f);
       else
        /* Must have been Qnil.  */
        ;
     }
+
+  /* Initialize `default-minibuffer-frame' in case this is the first
+     frame on this display device.  */
+  if (FRAME_HAS_MINIBUF_P (f)
+      && (!FRAMEP (kb->Vdefault_minibuffer_frame)
+          || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
+    kb->Vdefault_minibuffer_frame = frame;
+
+  /* All remaining specified parameters, which have not been "used"
+     by x_get_arg and friends, now go in the misc. alist of the frame.  */
+  for (tem = parms; !NILP (tem); tem = XCDR (tem))
+    if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+      f->param_alist = Fcons (XCAR (tem), f->param_alist);
+
   UNGCPRO;
 
   /* Make sure windows on this frame appear in calls to next-window
@@ -2699,9 +2686,11 @@ This function is an internal primitive--use `make-frame' instead.  */)
   return unbind_to (count, frame);
 }
 
+
 /* FRAME is used only to get a handle on the X display.  We don't pass the
    display info directly because we're called from frame.c, which doesn't
    know about that structure.  */
+
 Lisp_Object
 x_get_focus_frame (frame)
      struct frame *frame;
@@ -2714,6 +2703,39 @@ x_get_focus_frame (frame)
   XSETFRAME (xfocus, dpyinfo->x_focus_frame);
   return xfocus;
 }
+
+
+DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
+       doc: /* Set the input focus to FRAME.
+FRAME nil means use the selected frame.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  struct frame *f = check_x_frame (frame);
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+  if (dpyinfo->x_focus_frame != f)
+    {
+      BLOCK_INPUT;
+#ifdef MAC_OSX
+      ActivateWindow (ActiveNonFloatingWindow (), false);
+      ActivateWindow (FRAME_MAC_WINDOW (f), true);
+#else
+#if !TARGET_API_MAC_CARBON
+      /* SelectWindow (Non-Carbon) does not issue deactivate events if
+        the possibly inactive window that is to be selected is
+        already the frontmost one.  */
+      SendBehind (FRAME_MAC_WINDOW (f), NULL);
+#endif
+      /* This brings the window to the front.  */
+      SelectWindow (FRAME_MAC_WINDOW (f));
+#endif
+      UNBLOCK_INPUT;
+    }
+
+  return Qnil;
+}
+
 \f
 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
        doc: /* Internal function called by `color-defined-p', which see.  */)
@@ -2880,24 +2902,39 @@ If omitted or nil, that stands for the selected frame's display.  */)
      (display)
      Lisp_Object display;
 {
-  int mac_major_version;
-  SInt32 response;
+  UInt32 response, major, minor, bugfix;
   OSErr err;
 
   BLOCK_INPUT;
   err = Gestalt (gestaltSystemVersion, &response);
+  if (err == noErr)
+    {
+      if (response >= 0x00001040)
+       {
+         err = Gestalt ('sys1', &major); /* gestaltSystemVersionMajor */
+         if (err == noErr)
+           err = Gestalt ('sys2', &minor); /* gestaltSystemVersionMinor */
+         if (err == noErr)
+           err = Gestalt ('sys3', &bugfix); /* gestaltSystemVersionBugFix */
+       }
+      else
+       {
+         bugfix = response & 0xf;
+         response >>= 4;
+         minor = response & 0xf;
+         response >>= 4;
+         /* convert BCD to int */
+         major = response - (response >> 4) * 6;
+       }
+    }
   UNBLOCK_INPUT;
 
   if (err != noErr)
     error ("Cannot get Mac OS version");
 
-  mac_major_version = (response >> 8) & 0xff;
-  /* convert BCD to int */
-  mac_major_version -= (mac_major_version >> 4) * 6;
-
-  return Fcons (make_number (mac_major_version),
-               Fcons (make_number ((response >> 4) & 0xf),
-                      Fcons (make_number (response & 0xf),
+  return Fcons (make_number (major),
+               Fcons (make_number (minor),
+                      Fcons (make_number (bugfix),
                              Qnil)));
 }
 
@@ -3173,6 +3210,14 @@ DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
   return Qnil;
 }
 
+/* x_sync is a no-op on Mac.  */
+
+void
+x_sync (f)
+     FRAME_PTR f;
+{
+}
+
 \f
 /***********************************************************************
                            Window properties
@@ -3554,6 +3599,7 @@ x_create_tip_frame (dpyinfo, parms, text)
 
   check_mac ();
 
+  parms = Fcopy_alist (parms);
 
 #ifdef MULTI_KBOARD
   kb = dpyinfo->kboard;
@@ -3651,7 +3697,7 @@ x_create_tip_frame (dpyinfo, parms, text)
       font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
     /* If those didn't work, look for something which will at least work.  */
     if (! STRINGP (font))
-      font = x_new_fontset (f, "fontset-mac");
+      font = x_new_fontset (f, "fontset-standard");
     if (! STRINGP (font))
       font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
     if (! STRINGP (font))
@@ -3840,9 +3886,11 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
 
   if (INTEGERP (top))
     *root_y = XINT (top);
+  else if (*root_y + XINT (dy) <= 0)
+    *root_y = 0; /* Can happen for negative dy */
   else if (*root_y + XINT (dy) + height <= FRAME_MAC_DISPLAY_INFO (f)->height)
     /* It fits below the pointer */
-      *root_y += XINT (dy);
+    *root_y += XINT (dy);
   else if (height + XINT (dy) <= *root_y)
     /* It fits above the pointer.  */
     *root_y -= height + XINT (dy);
@@ -3852,6 +3900,8 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
 
   if (INTEGERP (left))
     *root_x = XINT (left);
+  else if (*root_x + XINT (dx) <= 0)
+    *root_x = 0; /* Can happen for negative dx */
   else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
     /* It fits to the right of the pointer.  */
     *root_x += XINT (dx);
@@ -4145,7 +4195,6 @@ If ONLY-DIR-P is non-nil, the user can only select directories.  */)
   int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
   char filename[MAXPATHLEN];
-  int default_filter_index = 1; /* 1: All Files, 2: Directories only  */
   static NavEventUPP mac_nav_event_callbackUPP = NULL;
 
   GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
@@ -4222,21 +4271,13 @@ If ONLY-DIR-P is non-nil, the user can only select directories.  */)
     /* Set the default location and continue*/
     if (status == noErr)
       {
+       Lisp_Object encoded_dir = ENCODE_FILE (dir);
        AEDesc defLocAed;
-#ifdef MAC_OSX
-       FSRef defLoc;
-       status = FSPathMakeRef(SDATA(ENCODE_FILE(dir)), &defLoc, NULL);
-#else
-       FSSpec defLoc;
-       status = posix_pathname_to_fsspec (SDATA (ENCODE_FILE (dir)), &defLoc);
-#endif
+
+       status = AECreateDesc (TYPE_FILE_NAME, SDATA (encoded_dir),
+                              SBYTES (encoded_dir), &defLocAed);
        if (status == noErr)
          {
-#ifdef MAC_OSX
-           AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed);
-#else
-           AECreateDesc(typeFSS, &defLoc, sizeof(FSSpec), &defLocAed);
-#endif
            NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed);
            AEDisposeDesc(&defLocAed);
          }
@@ -4258,41 +4299,36 @@ If ONLY-DIR-P is non-nil, the user can only select directories.  */)
        case kNavUserActionSaveAs:
          {
            NavReplyRecord reply;
-           AEDesc aed;
-#ifdef MAC_OSX
-           FSRef fsRef;
-#else
-           FSSpec fs;
-#endif
-           status = NavDialogGetReply(dialogRef, &reply);
+           Size len;
 
-#ifdef MAC_OSX
-           AECoerceDesc(&reply.selection, typeFSRef, &aed);
-           AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef));
-           FSRefMakePath(&fsRef, (UInt8 *) filename, sizeof (filename));
-#else
-           AECoerceDesc (&reply.selection, typeFSS, &aed);
-           AEGetDescData (&aed, (void *) &fs, sizeof (FSSpec));
-           fsspec_to_posix_pathname (&fs, filename, sizeof (filename) - 1);
-#endif
-           AEDisposeDesc(&aed);
-           if (reply.saveFileName)
+           status = NavDialogGetReply(dialogRef, &reply);
+           if (status != noErr)
+             break;
+           status = AEGetNthPtr (&reply.selection, 1, TYPE_FILE_NAME,
+                                 NULL, NULL, filename,
+                                 sizeof (filename) - 1, &len);
+           if (status == noErr)
              {
-               /* If it was a saved file, we need to add the file name */
-               int len = strlen(filename);
-               if (len && filename[len-1] != '/')
-                 filename[len++] = '/';
-               CFStringGetCString(reply.saveFileName, filename+len,
-                                  sizeof (filename) - len,
+               len = min (len, sizeof (filename) - 1);
+               filename[len] = '\0';
+               if (reply.saveFileName)
+                 {
+                   /* If it was a saved file, we need to add the file name */
+                   if (len && len < sizeof (filename) - 1
+                       && filename[len-1] != '/')
+                     filename[len++] = '/';
+                   CFStringGetCString(reply.saveFileName, filename+len,
+                                      sizeof (filename) - len,
 #if MAC_OSX
-                                  kCFStringEncodingUTF8
+                                      kCFStringEncodingUTF8
 #else
-                                  CFStringGetSystemEncoding ()
+                                      CFStringGetSystemEncoding ()
 #endif
-                                  );
+                                      );
+                 }
+               file = DECODE_FILE (make_unibyte_string (filename,
+                                                        strlen (filename)));
              }
-           file = DECODE_FILE (make_unibyte_string (filename,
-                                                    strlen (filename)));
            NavDisposeReply(&reply);
          }
          break;
@@ -4354,7 +4390,7 @@ frame_parm_handler mac_frame_parm_handlers[] =
   x_set_menu_bar_lines,
   x_set_mouse_color,
   x_explicitly_set_name,
-  x_set_scroll_bar_width,
+  mac_set_scroll_bar_width,
   x_set_title,
   x_set_unsplittable,
   x_set_vertical_scroll_bars,
@@ -4509,6 +4545,7 @@ Chinese, Japanese, and Korean.  */);
   defsubr (&Sx_close_connection);
   defsubr (&Sx_display_list);
   defsubr (&Sx_synchronize);
+  defsubr (&Sx_focus_frame);
 
   /* Setting callback functions for fontset handler.  */
   get_font_info_func = x_get_font_info;