diff -u ../old/emacs.orig/src/macfns.c src/macfns.c
--- ../old/emacs.orig/src/macfns.c	2008-06-02 16:25:51.000000000 -0400
+++ src/macfns.c	2008-06-03 08:12:55.000000000 -0400
@@ -57,8 +57,6 @@
 
 static Lisp_Object Vmac_carbon_version_string;
 
-static int mac_autohide_menubar_on_maximize;
-
 #endif	/* TARGET_API_MAC_CARBON */
 
 /* Non-zero means we're allowed to display an hourglass cursor.  */
@@ -4310,459 +4308,6 @@
 
 #if TARGET_API_MAC_CARBON
 
-/* === Begin support for maximizing frames to the full display. === */
-
-#define MAC_EMACS_WINDOW_PROPTAG_MAXWIN               ('cmwt')
-#define MAC_EMACS_WINDOW_PROPTAG_CLOSE_HANDLER_STATUS ('cchi')
-
-OSStatus MacGetDisplayIdForWindow(
-    WindowRef          wnd,
-    CGDirectDisplayID* outInDispId)
-{
-    OSStatus s;
-    
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
-    s = HIWindowGetGreatestAreaDisplay(
-        wnd,
-        kWindowContentRgn,
-        kHICoordSpaceScreenPixel,
-        outInDispId,
-        NULL);
-    if (s != noErr)
-        error ("Error while attempting to determine display id.");
-    return s;
-#else
-    GDHandle devh;
-    DisplayIDType id;
-
-    /*
-      NB: HIWindowGetGreatestAreaDisplay() isn't available before 10.5,
-      so if we want this to build in Tiger we need to use
-      GetWindowGreatestAreaDevice() and obtain the display ID via
-      DMGetDisplayIDByGDevice().
-    */
-
-    s = GetWindowGreatestAreaDevice(
-        wnd,
-        kWindowContentRgn,
-        &devh,
-        NULL);
-    
-    if (s != noErr) {
-       error ("Error while attempting to determine GDHandle.");
-       return s;
-     }
-
-    OSErr e = DMGetDisplayIDByGDevice(
-        devh,
-        &id,
-        true);
-    if (e != noErr)
-    {
-        error ("Error while attempting to map GDevice to DisplayID");
-        return s;
-    }
-    
-    *outInDispId = (CGDirectDisplayID) id;
-    return s;
-#endif
-}
-
-Rect MacConvertCGRectToRect(
-    CGRect r)
-{
-    Rect rslt;
-    rslt.top    = (short) r.origin.y;
-    rslt.left   = (short) r.origin.x;
-    rslt.right  = rslt.left + ((short) r.size.width);
-    rslt.bottom = rslt.top  + ((short) r.size.height);
-    return rslt;
-}
-
-CGRect MacConvertRectToCGRect(
-    Rect r)
-{
-    CGRect rslt;
-    rslt.origin.x    = r.left;
-    rslt.origin.y    = r.top;
-    rslt.size.width  = r.right - r.left;
-    rslt.size.height = r.bottom - r.top;
-    return rslt;
-}
-
-typedef struct 
-{
-    Rect bounds;
-} MacWindowCustomState, **MacWindowCustomStateH;
-
-#define MAC_WINSTATE_HANDLE_FIELD_PTR(handle, fld) (&((**handle).fld))
-
-void MacReleaseWindowCustomState(
-    MacWindowCustomStateH h)
-{
-    free(*h);
-    free(h);
-}
-
-void MacToggleFullFrame(WindowRef frame);
-static pascal void MacOnReconfigMaximizedWindow(
-    CGDirectDisplayID           dispID,
-    CGDisplayChangeSummaryFlags flags,
-    void*                       userInfo)
-{
-    if (flags & kCGDisplayRemoveFlag)
-    {
-        /*
-          NB: We choose to un-maximize any full-screen frame during a
-          display reconfiguration involving the removal of a display.
-        */
-
-        CGDirectDisplayID inDispID;
-        WindowRef         frame = (WindowRef) userInfo;
-        MacToggleFullFrame(frame);
-    }
-}
-
-Boolean MacGetWindowCustomState(
-    WindowRef              wnd,
-    MacWindowCustomStateH* outStateHandle)
-{
-    OSStatus s = GetWindowProperty(
-        wnd,
-        MAC_EMACS_CREATOR_CODE,
-        MAC_EMACS_WINDOW_PROPTAG_MAXWIN,
-        sizeof(MacWindowCustomStateH),
-        NULL,
-        outStateHandle);
-    return s == noErr;
-}
-
-static int mac_maximized_frame_count = 0;
-int MacHandleMenuBarBehavior(bool isMaximizing, WindowRef frame)
-{
-    OSStatus st;
-    GDHandle device_handle = NULL;
-
-    st = GetWindowGreatestAreaDevice (frame, kWindowContentRgn, &device_handle, NULL);
-
-    if (st != noErr || device_handle != LMGetMainDevice())
-      {
-	return 0; /* no menu bar on secondary display. */
-      }
-    if (isMaximizing)
-      {
-	++mac_maximized_frame_count;
-	if (mac_autohide_menubar_on_maximize)
-	  {
-	    st = SetSystemUIMode(kUIModeAllHidden,
-				 kUIOptionAutoShowMenuBar);
-	    if (st != noErr)
-	      error("Error while handling menubar behavior.");
-	  }
-	else
-	  {
-	    st = SetSystemUIMode(kUIModeNormal, 0);
-	    if (st != noErr)
-	      error("Error while handling menubar behavior.");
-	  }
-      }
-    else
-      {
-	if (0 == --mac_maximized_frame_count)
-	  {
-	    st = SetSystemUIMode(kUIModeNormal, 0);
-	    if (st != noErr)
-	      error("Error while handling menubar behavior.");
-	  }
-      }
-    return GetMBarHeight(); /* return resulting height of menu bar */
-}
-
-static pascal OSStatus MacHandleMaxWndClose(
-    EventHandlerCallRef inHandlerCallRef,
-    EventRef            inEvent,
-    void*               inUserData)
-{
-    WindowRef             wnd = (WindowRef) inUserData;
-    MacWindowCustomStateH h;
-
-    BLOCK_INPUT;
-
-    if (MacGetWindowCustomState(wnd, &h))
-    {
-        MacReleaseWindowCustomState(h);
-        MacHandleMenuBarBehavior(false, wnd);
-    }
-
-    UNBLOCK_INPUT;
-    return noErr;
-}
-
-void MacRegisterMaxWinCloseHandler(
-    WindowRef wnd)
-{
-    /* Register the window close handler for this window if we haven't
-       already done so. We use the property with tag
-       MAC_EMACS_WINDOW_PROPTAG_CLOSE_HANDLER_STATUS to denote whether
-       or not the handler has been already been registered. */
-
-    int alreadyRegisteredHandler = 0;
-
-    OSStatus s = GetWindowProperty(
-        wnd,
-        MAC_EMACS_CREATOR_CODE,
-        MAC_EMACS_WINDOW_PROPTAG_CLOSE_HANDLER_STATUS,
-        sizeof(int),
-        NULL,
-        &alreadyRegisteredHandler);
-
-    if (s != noErr)
-    {
-        /* No such property, so we haven't registered the event handler
-           for this window yet. Do so and record the fact that we
-           did. */
-
-        EventTypeSpec etWC = { kEventClassWindow, kEventWindowClosed };
-
-        /* Register a handler to do cleanup when this window closes */
-        s = InstallWindowEventHandler(
-            wnd,
-            MacHandleMaxWndClose,
-            1,
-            &etWC,
-            (void*)wnd,
-            NULL);
-
-        if (s != noErr) {
-            error("Error while installing window handler");
-            return;
-        }
-
-        alreadyRegisteredHandler = 1;
-        s = SetWindowProperty(
-            wnd,
-            MAC_EMACS_CREATOR_CODE,
-            MAC_EMACS_WINDOW_PROPTAG_CLOSE_HANDLER_STATUS,
-            sizeof(int),
-            &alreadyRegisteredHandler);
-        if (s != noErr) {
-            error("Error while saving window handler status.");
-        }
-    }
-}
-
-MacWindowCustomStateH MacSaveWindowCustomState(
-    WindowRef wnd)
-{
-    OSStatus              s;
-    MacWindowCustomState* state = malloc(sizeof(MacWindowCustomState));
-    MacWindowCustomStateH h     = malloc(sizeof(MacWindowCustomStateH));
-    *h                          = state;
-
-    MacRegisterMaxWinCloseHandler(wnd);
-
-    if (noErr != GetWindowBounds(wnd, kWindowStructureRgn, &state->bounds))
-    {
-        error("Error while obtaining window bounds.");
-        MacReleaseWindowCustomState(h);
-        return NULL;
-    }
-    else {
-        s = SetWindowProperty(
-            wnd,
-            MAC_EMACS_CREATOR_CODE,
-            MAC_EMACS_WINDOW_PROPTAG_MAXWIN,
-            sizeof(MacWindowCustomStateH),
-            &h);
-
-        if (s != noErr)
-        {
-            error("Error while saving window bounds.");
-            MacReleaseWindowCustomState(h);
-            return NULL;
-        }
-    }
-    return h;
-}
-
-/* This function is the workhorse routine for the toggle max-size frame
-   behavior. */
-
-/* workaround for compiling on pre-10.4 systems */ 
-#define FNS_kWindowNoTitleBarAttribute 512
-
-void MacToggleFullFrame(
-    WindowRef frame)
-{
-    OSStatus              st;
-    CGError               e;
-    CGDirectDisplayID     inDispID;
-    MacWindowCustomStateH savedState_h;
-    
-    if (MacGetWindowCustomState(frame, &savedState_h))
-    {
-        /* We're un-maximizing the current frame. */
-
-        Rect* bounds_p =
-            MAC_WINSTATE_HANDLE_FIELD_PTR(savedState_h, bounds);
-
-        /*
-           Saved window state only exists when frame has already been
-           maximized, so we need to restore the window to its initial,
-           pre-maximized state and then remove the saved window state
-           from the window.
-        */
-
-        /* Enable title bar and resizability */
-        st = ChangeWindowAttributes(
-            frame,
-            kWindowResizableAttribute,
-            FNS_kWindowNoTitleBarAttribute);
-        if (st != noErr)
-        {
-            error ("Error during unmaximize: couldn't change window attributes.");
-            goto unmax_cleanup;
-        }
-
-        /* Reset window size */
-        st = SetWindowBounds(frame, kWindowStructureRgn, bounds_p);
-        if (st != noErr)
-        {
-            error ("Error during unmaximize: couldn't reset window bounds.");
-            goto unmax_cleanup;
-        }
-
-        MacHandleMenuBarBehavior(false,frame);
-
-        /* Resize and/or move the frame as needed in case the saved
-           bounds aren't acceptable for the current display */
-
-        st = ConstrainWindowToScreen(
-            frame,
-            kWindowStructureRgn,
-            kWindowConstrainStandardOptions,
-            NULL,
-            NULL);
-
-        if (st != noErr)
-        {
-            error("Error during unmaximize: couldn't constrain window.");
-            goto unmax_cleanup;
-        }
-
-        /* Toss the saved data */
-        st = RemoveWindowProperty(
-            frame,
-            MAC_EMACS_CREATOR_CODE,
-            MAC_EMACS_WINDOW_PROPTAG_MAXWIN);
-        if (st != noErr)
-        {
-            error ("Error during unmaximize: couldn't remove window state.");
-            goto unmax_cleanup;
-        }
-        
-    unmax_cleanup:
-        MacReleaseWindowCustomState(savedState_h);
-        
-        /* Unregister the display reconfiguration cb */
-        e = CGDisplayRemoveReconfigurationCallback(
-            MacOnReconfigMaximizedWindow,
-            frame);
-        if (e != noErr)
-            error ("Error during unmaximize: couldn't unregister cb");
-    }
-    else
-    {
-        /* We're maximizing the current frame. */
-
-        Rect                  screenBnds;
-        CGDirectDisplayID     inDispID;
-        short                 mbarHeight;
-
-        savedState_h = MacSaveWindowCustomState(frame);
-        if (savedState_h == NULL)
-            return;
-
-        mbarHeight = MacHandleMenuBarBehavior(true, frame);
-        
-        /* Remove title bar & resizability from the window */
-        st = ChangeWindowAttributes(
-            frame,
-            FNS_kWindowNoTitleBarAttribute,
-            kWindowResizableAttribute);
-        if (st != noErr)
-        {
-            error("Error during maximize: couldn't set window attributes.");
-            goto max_cleanup;
-        }
-
-        st = MacGetDisplayIdForWindow(frame, &inDispID);
-        if (st != noErr)
-        {
-            error ("Error during maximize: couldn't get display id");
-            goto max_cleanup;
-        }
-
-        /* Maximize the window to the screen bounds, , leaving room
-           for the menubar to if it is visible (this can be
-           controlled by the user via mac-autohide-menubar-on-maximize */
-
-        screenBnds      = MacConvertCGRectToRect(CGDisplayBounds(inDispID));
-        screenBnds.top += mbarHeight;
-
-        st = SetWindowBounds(frame, kWindowStructureRgn, &screenBnds);
-        if (st != noErr)
-        {
-            error ("Error during maximize: couldn't set window bounds.");
-            goto max_cleanup;
-        }
-        
-        /*
-          Register a callback to restore the window to its old size when
-          the displays are reconfigured; if we don't do this, we can end
-          up with a maximized window that is larger than the current
-          display.  The cb is unregistered on un-maximize.
-        */
-
-        e = CGDisplayRegisterReconfigurationCallback(
-            MacOnReconfigMaximizedWindow,
-            frame);
-        if (e != noErr)
-        {
-            error ("Error during maximize: couldn't register reconfig cb");
-            goto max_cleanup;
-        }
-
-        goto max_done;
-        
-    max_cleanup:
-        MacReleaseWindowCustomState(savedState_h);
-
-    max_done:
-        return;
-    }
-}
-
-DEFUN ("mac-toggle-full-frame", Fmac_toggle_full_frame, Smac_toggle_full_frame, 0, 0, "",
-       doc: /* Makes the current frame use as much of the display as
-possible, or reverts it to its previous size and position if already
-maximized.  If mac-autohide-menubar-on-maximize is non-nil, maximized
-frames auto-hide the menubar.*/)
-    ()
-{
-    if (!EQ (Vwindow_system, intern ("mac")))
-        return Qnil;
-
-    BLOCK_INPUT;
-    
-    WindowRef frame = GetUserFocusWindow();
-    MacToggleFullFrame(frame);
-
-    UNBLOCK_INPUT;
-    return Qnil;
-}
-/* === End support for maximizing frames to the full display. === */
-
 #endif /* MAC_OSX && TARGET_API_MAC_CARBON */
 
 DEFUN ("mac-show-menu-bar", Fmac_show_menu_bar, Smac_show_menu_bar, 0, 0, "",
@@ -5097,11 +4642,6 @@
     Vmac_carbon_version_string = build_string (carbon_version);
   }
 
-  DEFVAR_BOOL ("mac-autohide-menubar-on-maximize", &mac_autohide_menubar_on_maximize,
-	       doc: /* Non-nil means auto-hide the menubar when a frame is maximized
-                     with mac-toggle-full-frame */);
-  mac_autohide_menubar_on_maximize = 1;
-
 #endif	/* TARGET_API_MAC_CARBON */
 
   /* X window properties.  */
@@ -5163,7 +4703,6 @@
 #if TARGET_API_MAC_CARBON
   defsubr (&Sx_file_dialog);
 #if MAC_OSX
-  defsubr (&Smac_toggle_full_frame);
   defsubr (&Smac_show_menu_bar);
   defsubr (&Smac_hide_menu_bar);
   defsubr (&Smac_dialog);
diff -u ../old/emacs.orig/src/macterm.c src/macterm.c
--- ../old/emacs.orig/src/macterm.c	2008-06-02 16:25:51.000000000 -0400
+++ src/macterm.c	2008-06-03 10:13:27.000000000 -0400
@@ -83,6 +83,8 @@
 
 
 
+int mac_autohide_menubar_on_fullscreen;
+
 /* Non-nil means Emacs uses toolkit scroll bars.  */
 
 Lisp_Object Vx_toolkit_scroll_bars;
@@ -242,6 +244,7 @@
 static void x_update_window_begin P_ ((struct window *));
 static void x_after_update_window_line P_ ((struct glyph_row *));
 
+static CGDirectDisplayID mac_display_id P_ ((WindowRef));
 static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
 static void XSetFont P_ ((Display *, GC, XFontStruct *));
 
@@ -4361,6 +4364,19 @@
     }
 
   x_frame_rehighlight (dpyinfo);
+
+  if (frame)
+    {
+      CGDirectDisplayID display = mac_display_id (FRAME_MAC_WINDOW(frame));
+      CGDirectDisplayID main_display = CGMainDisplayID ();
+      if (display == main_display)
+        {
+          if (frame->want_fullscreen == FULLSCREEN_BOTH)
+            SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+          else
+            SetSystemUIMode(kUIModeNormal, 0);
+        }
+    }
 }
 
 /* Handle FocusIn and FocusOut state changes for FRAME.
@@ -5654,6 +5670,12 @@
      register int xoff, yoff;
      int change_gravity;
 {
+  /* Refuse to change one or both offsets if in full-screen mode. */
+  if (f->want_fullscreen & FULLSCREEN_HEIGHT)
+    yoff = f->top_pos;
+  if (f->want_fullscreen & FULLSCREEN_WIDTH)
+    xoff = f->left_pos;
+
   if (change_gravity > 0)
     {
       f->top_pos = yoff;
@@ -5740,6 +5762,13 @@
   BLOCK_INPUT;
 
   check_frame_size (f, &rows, &cols);
+
+  /* Refuse to set cols, rows, or both if in full-screen mode. */
+  if (f->want_fullscreen & FULLSCREEN_HEIGHT)
+    rows = FRAME_LINES (f);
+  if (f->want_fullscreen & FULLSCREEN_WIDTH)
+    cols = FRAME_COLS (f);
+
   f->scroll_bar_actual_width
     = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
 
@@ -8247,6 +8276,8 @@
 /* Contains the string "reverse", which is a constant for mouse button emu.*/
 Lisp_Object Qreverse;
 
+Lisp_Object Qfullscreen_saved_state;
+
 
 /* Modifier associated with the control key, or nil to ignore. */
 Lisp_Object Vmac_control_modifier;
@@ -9494,6 +9525,225 @@
       bzero (dpyinfo, sizeof (*dpyinfo));
     }
 }
+
+/* Full-screen mode */
+
+static CGDirectDisplayID mac_display_id (wnd)
+     WindowRef wnd;
+{
+  OSStatus s;
+  CGDirectDisplayID display_id;
+    
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+  s = HIWindowGetGreatestAreaDisplay (wnd, kWindowContentRgn,
+                                      kHICoordSpaceScreenPixel, &display_id, 
+                                      NULL);
+  if (s != noErr)
+    return NULL;
+#else
+  GDHandle devh;
+  DisplayIDType id;
+
+  s = GetWindowGreatestAreaDevice (wnd, kWindowContentRgn, &devh, NULL);
+  if (s != noErr)
+    return NULL;
+  OSErr e = DMGetDisplayIDByGDevice (devh, &id, true);
+  if (e != noErr)
+    return NULL;
+  display_id = (CGDirectDisplayID)id;
+#endif
+  return display_id;
+}
+
+#define FNS_kWindowNoTitleBarAttribute 512
+
+extern Lisp_Object Qfullwidth, Qfullheight, Qfullboth;
+
+struct fullscreen_state {
+  int mode, top, bottom, left, right;
+};
+
+static int fullscreen_mode_as_int (symbol)
+     Lisp_Object symbol;
+{
+  CHECK_SYMBOL (symbol);
+  if (EQ (symbol, Qfullwidth))
+    return FULLSCREEN_WIDTH;
+  if (EQ (symbol, Qfullheight))
+    return FULLSCREEN_HEIGHT;
+  if (EQ (symbol, Qfullboth))
+    return FULLSCREEN_BOTH;
+  return FULLSCREEN_NONE;
+}
+
+static Lisp_Object fullscreen_mode_as_symbol (i)
+     int i;
+{
+  Lisp_Object mode = Qnil;
+  switch (i) {
+  case FULLSCREEN_WIDTH: mode = Qfullwidth; break;
+  case FULLSCREEN_HEIGHT: mode = Qfullheight; break;
+  case FULLSCREEN_BOTH: mode = Qfullboth; break;
+  }
+  return mode;
+}
+
+static struct fullscreen_state *
+get_fullscreen_state (f)
+     FRAME_PTR f;
+{
+  struct fullscreen_state *s = xmalloc (sizeof (struct fullscreen_state));
+  s->mode = FULLSCREEN_NONE;
+  s->top = s->left = s->bottom = s->right = INT_MAX;
+  Lisp_Object frame;
+  XSETFRAME (frame, f);
+  Lisp_Object list = Fframe_parameter (frame, Qfullscreen_saved_state);
+  if (Qnil != list)
+    {
+      CHECK_CONS (list);
+      s->mode = fullscreen_mode_as_int (Fcar (list)); 
+      list = Fcdr (list);
+#define POP_NUMBER_OR_NIL(dest, list) do { CHECK_CONS (list); if (Qnil == Fcar (list)) dest = INT_MAX; else { CHECK_NUMBER (Fcar (list)); dest = XINT (Fcar (list)); } list = Fcdr (list); } while (0)
+      POP_NUMBER_OR_NIL (s->top, list);
+      POP_NUMBER_OR_NIL (s->left, list);
+      POP_NUMBER_OR_NIL (s->bottom, list);
+      POP_NUMBER_OR_NIL (s->right, list);
+#undef POP_NUMBER
+    }
+  return s;
+}
+
+static void
+save_fullscreen_state (f, s)
+     FRAME_PTR f;
+     const struct fullscreen_state *s;
+{
+  if (s->mode == FULLSCREEN_NONE)
+    store_frame_param (f, Qfullscreen_saved_state, Qnil);
+  else
+#define NUM(n) n == INT_MAX ? Qnil : make_number (n)
+      store_frame_param (f, Qfullscreen_saved_state, 
+                         list5 (fullscreen_mode_as_symbol (s->mode), 
+                                NUM (s->top), NUM (s->left), NUM (s->bottom),
+                                NUM (s->right)));
+#undef NUM
+}
+
+static pascal void mac_handle_display_reconfiguration (dispID, flags, userInfo)
+     CGDirectDisplayID dispID;
+     CGDisplayChangeSummaryFlags flags;
+     void* userInfo;
+{
+  /* Leave full-screen mode when the display is reconfigured (e.g., a
+     display is added or removed, or the resolution is changed)
+     because it is not obvious whether resizing the window is always
+     the right thing to do. */
+  Lisp_Object frame;
+  XSETFRAME (frame, (FRAME_PTR)userInfo);
+  Fmodify_frame_parameters (frame, list1 (Fcons (Qfullscreen, Qnil)));
+}
+
+static void
+mac_fullscreen_hook (f)
+     FRAME_PTR f;
+{
+  Rect b;
+  OSStatus st;
+     
+  if (f->async_visible)
+    {
+      /* May signal errors, so do before blocking input. */
+      struct fullscreen_state *s = get_fullscreen_state (f);
+
+      BLOCK_INPUT;
+
+      /* Must get the current bounds before removing the title bar,
+         otherwise the window will be too short when restored. */
+      st = GetWindowBounds (FRAME_MAC_WINDOW (f), kWindowStructureRgn, &b);
+      if (st != noErr)
+        {
+          UNBLOCK_INPUT;
+          error("Failed to get current window bounds.");
+        }
+
+      CGDirectDisplayID display = mac_display_id (FRAME_MAC_WINDOW(f));
+      if (!display)
+        {
+          UNBLOCK_INPUT;
+          error("Failed to get display ID.");
+        }
+      CGDirectDisplayID main_display = CGMainDisplayID ();
+      if ((f->want_fullscreen & FULLSCREEN_BOTH) == FULLSCREEN_BOTH)
+        {
+          ChangeWindowAttributes (FRAME_MAC_WINDOW (f), 
+                                  FNS_kWindowNoTitleBarAttribute,
+                                  kWindowResizableAttribute);
+          if (mac_autohide_menubar_on_fullscreen && display == main_display)
+            SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+        }
+      else
+        {
+          ChangeWindowAttributes (FRAME_MAC_WINDOW (f), 
+                                  kWindowResizableAttribute, 
+                                  FNS_kWindowNoTitleBarAttribute);
+          if (f->want_fullscreen & FULLSCREEN_BOTH)
+            ChangeWindowAttributes (FRAME_MAC_WINDOW (f),
+                                    0, kWindowResizableAttribute);
+          SetSystemUIMode (kUIModeNormal, 0);
+        }
+
+      /* Update the saved state. */
+      int tmp;
+#define SWAP(a, b) tmp = a, a = b, b = tmp
+      if ((f->want_fullscreen ^ s->mode) & FULLSCREEN_WIDTH)
+        SWAP (b.left, s->left), SWAP (b.right, s->right);
+      if ((f->want_fullscreen ^ s->mode) & FULLSCREEN_HEIGHT)
+        SWAP (b.top, s->top), SWAP (b.bottom, s->bottom);
+#undef SWAP
+      s->mode = f->want_fullscreen;
+      save_fullscreen_state (f, s);
+      xfree (s);
+
+      CGRect screen_bounds = CGDisplayBounds (display);
+      if (f->want_fullscreen & FULLSCREEN_HEIGHT)
+      {
+           b.top = (short)screen_bounds.origin.y;
+           b.bottom = b.top + (short)screen_bounds.size.height;
+           b.top += GetMBarHeight();
+      }
+      if (f->want_fullscreen & FULLSCREEN_WIDTH)
+      {
+           b.left = (short)screen_bounds.origin.x;
+           b.right = b.left + (short)screen_bounds.size.width;
+      }
+
+      SetWindowBounds(FRAME_MAC_WINDOW (f), kWindowStructureRgn, &b);
+
+      /* Resize and/or move the frame as needed in case the saved
+         bounds aren't acceptable for the current display. */
+      ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowStructureRgn, 
+                               kWindowConstrainStandardOptions, NULL, NULL);
+
+      /* Necessary because x_set_offset and x_set_window_size refuse
+         to change the offset and size of a full-screen frame. */
+      st = GetWindowBounds(FRAME_MAC_WINDOW (f), kWindowContentRgn, &b);
+      if (st == noErr)
+        {
+          mac_handle_size_change (f, b.right - b.left, b.bottom - b.top);
+          mac_handle_origin_change (f);
+        }
+
+      if (f->want_fullscreen & FULLSCREEN_BOTH)
+           CGDisplayRegisterReconfigurationCallback 
+                (mac_handle_display_reconfiguration, f);
+      else
+           CGDisplayRemoveReconfigurationCallback
+                (mac_handle_display_reconfiguration, f);
+
+      UNBLOCK_INPUT;
+      do_pending_window_change(0);
+    }
+}
 
 
 /* Set up use of X before we make the first connection.  */
@@ -9564,6 +9814,7 @@
   condemn_scroll_bars_hook = XTcondemn_scroll_bars;
   redeem_scroll_bar_hook = XTredeem_scroll_bar;
   judge_scroll_bars_hook = XTjudge_scroll_bars;
+  fullscreen_hook = mac_fullscreen_hook;
 
   scroll_region_ok = 1;         /* we'll scroll partial frames */
   char_ins_del_ok = 1;
@@ -9666,6 +9917,9 @@
   staticpro (&Qreverse);
   Qreverse = intern ("reverse");
 
+  staticpro (&Qfullscreen_saved_state);
+  Qfullscreen_saved_state = intern ("fullscreen-saved-state");
+
   staticpro (&x_display_name_list);
   x_display_name_list = Qnil;
 
@@ -9813,6 +10067,11 @@
     Fcons (list3 (build_string ("mac-roman"),
 		  make_number (smRoman), Qnil), Qnil);
 
+  DEFVAR_BOOL ("mac-autohide-menubar-on-fullscreen", &mac_autohide_menubar_on_fullscreen,
+	       doc: /* Non-nil means auto-hide the menubar when a frame's fullscreen parameter is 'fullboth. */);
+  mac_autohide_menubar_on_fullscreen = 1;
+
+
 #if USE_MAC_TSM
   DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
     doc: /* Overlay used to display Mac TSM active input area.  */);
