Index: /trunk/include/VBox/pdmifs.h
===================================================================
--- /trunk/include/VBox/pdmifs.h	(revision 6851)
+++ /trunk/include/VBox/pdmifs.h	(revision 6852)
@@ -1677,4 +1677,13 @@
      */
     DECLR3CALLBACKMEMBER(int, pfnSleepButtonPress,(PPDMIACPIPORT pInterface));
+
+    /**
+     * Check if the last power button event was handled by the guest.
+     *
+     * @returns VBox status code
+     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
+     * @param   pfHandled       Is set to true if the last power button event was handled, false otherwise.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnGetPowerButtonHandled,(PPDMIACPIPORT pInterface, bool *pfHandled));
 } PDMIACPIPORT;
 
Index: /trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 6851)
+++ /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 6852)
@@ -181,4 +181,5 @@
     uint8_t             u8IndexShift;
     uint8_t             u8UseIOApic;
+    bool                fPowerButtonHandled;
 
     /** ACPI port base interface. */
@@ -741,5 +742,13 @@
 {
     ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
+    s->fPowerButtonHandled = false;
     update_pm1a (s, s->pm1a_sts | PWRBTN_STS, s->pm1a_en);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) acpiGetPowerButtonHandled(PPDMIACPIPORT pInterface, bool *pfHandled)
+{
+    ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
+    *pfHandled = s->fPowerButtonHandled;
     return VINF_SUCCESS;
 }
@@ -784,4 +793,6 @@
 {
     Log (("acpi: acpiPM1aStsWritew <- %#x (%#x)\n", val, val & ~(RSR_STS | IGN_STS)));
+    if (val & PWRBTN_STS)
+        s->fPowerButtonHandled = true; /* Remember that the guest handled the last power button event */
     val = s->pm1a_sts & ~(val & ~(RSR_STS | IGN_STS));
     update_pm1a (s, val, s->pm1a_en);
@@ -1063,5 +1074,4 @@
             return VERR_IOM_IOPORT_UNUSED;
     }
-//    LogRel(("Query %04x => %08x\n", s->uBatteryIndex, *pu32));
     return VINF_SUCCESS;
 }
@@ -1676,8 +1686,9 @@
      */
     /* IBase */
-    s->IBase.pfnQueryInterface         = acpiQueryInterface;
+    s->IBase.pfnQueryInterface            = acpiQueryInterface;
     /* IACPIPort */
-    s->IACPIPort.pfnSleepButtonPress   = acpiSleepButtonPress;
-    s->IACPIPort.pfnPowerButtonPress   = acpiPowerButtonPress;
+    s->IACPIPort.pfnSleepButtonPress      = acpiSleepButtonPress;
+    s->IACPIPort.pfnPowerButtonPress      = acpiPowerButtonPress;
+    s->IACPIPort.pfnGetPowerButtonHandled = acpiGetPowerButtonHandled;
 
    /*
Index: /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 6851)
+++ /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 6852)
@@ -140,4 +140,5 @@
 static Uint32  StartupTimer(Uint32 interval, void *param);
 static Uint32  ResizeTimer(Uint32 interval, void *param);
+static Uint32  QuitTimer(Uint32 interval, void *param);
 static int     WaitSDLEvent(SDL_Event *event);
 
@@ -191,4 +192,5 @@
 static SDL_Cursor *gpOffCursor = NULL;
 static SDL_TimerID gSdlResizeTimer = NULL;
+static SDL_TimerID gSdlQuitTimer = NULL;
 
 #ifdef VBOXSDL_WITH_X11
@@ -2210,9 +2212,9 @@
             case SDL_QUIT:
             {
-                if (!gfACPITerm)
+                if (!gfACPITerm || gSdlQuitTimer)
                     goto leave;
                 if (gConsole)
                     gConsole->PowerButton();
-                gfACPITerm = false; /* don't try a second time */
+                gSdlQuitTimer = SDL_AddTimer(1000, QuitTimer, NULL);
                 break;
             }
@@ -4371,4 +4373,29 @@
 
 /**
+ * Timer callback function to check if an ACPI power button event was handled by the guest.
+ */
+static Uint32 QuitTimer(Uint32 interval, void *param)
+{
+    PRBool fHandled = FALSE;
+
+    gSdlQuitTimer = NULL;
+    if (gConsole)
+    {
+        int rc = gConsole->GetPowerButtonHandled(&fHandled);
+        LogRel(("QuitTimer: rc=%d handled=%d\n", rc, fHandled));
+        if (VBOX_FAILURE(rc) || !fHandled)
+        {
+            /* event was not handled, power down the guest */
+            gfACPITerm = FALSE;
+            SDL_Event event = {0};
+            event.type = SDL_QUIT;
+            PushSDLEventForSure(&event);
+        }
+    }
+    /* one-shot */
+    return 0;
+}
+
+/**
  * Wait for the next SDL event. Don't use SDL_WaitEvent since this function
  * calls SDL_Delay(10) if the event queue is empty.
Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 6851)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 6852)
@@ -1554,4 +1554,41 @@
         setError (E_FAIL,
             tr ("Controlled power off failed (%Vrc)"), vrc);
+
+    LogFlowThisFunc (("rc=%08X\n", rc));
+    LogFlowThisFuncLeave();
+    return rc;
+}
+
+STDMETHODIMP Console::GetPowerButtonHandled(PRBool *aHandled)
+{
+    LogFlowThisFuncEnter();
+
+    AutoCaller autoCaller (this);
+
+    AutoLock lock (this);
+
+    if (mMachineState != MachineState_Running)
+        return E_FAIL;
+
+    /* protect mpVM */
+    AutoVMCaller autoVMCaller (this);
+    CheckComRCReturnRC (autoVMCaller.rc());
+
+    PPDMIBASE pBase;
+    int vrc = PDMR3QueryDeviceLun (mpVM, "acpi", 0, 0, &pBase);
+    bool handled = false;
+    if (VBOX_SUCCESS (vrc))
+    {
+        Assert (pBase);
+        PPDMIACPIPORT pPort =
+            (PPDMIACPIPORT) pBase->pfnQueryInterface(pBase, PDMINTERFACE_ACPI_PORT);
+        vrc = pPort ? pPort->pfnGetPowerButtonHandled(pPort, &handled) : VERR_INVALID_POINTER;
+    }
+
+    HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK :
+        setError (E_FAIL,
+            tr ("Checking if poweroff was handled failed (%Vrc)"), vrc);
+
+    *aHandled = handled;
 
     LogFlowThisFunc (("rc=%08X\n", rc));
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 6851)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 6852)
@@ -3768,4 +3768,9 @@
     </method>
 
+    <method name="getPowerButtonHandled">
+      <desc>Check if the last power button event was handled by guest.</desc>
+      <param name="handled" type="boolean" dir="return"/>
+    </method>
+
     <method name="saveState">
       <desc>
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 6851)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 6852)
@@ -127,4 +127,5 @@
     STDMETHOD(PowerButton)();
     STDMETHOD(SleepButton)();
+    STDMETHOD(GetPowerButtonHandled)(PRBool *aHandled);
     STDMETHOD(SaveState) (IProgress **aProgress);
     STDMETHOD(AdoptSavedState) (INPTR BSTR aSavedStateFile);
