Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / toolkit / xre / nsNativeAppSupportCocoa.mm
blobcbc2bce8680efeed76374ad761d0d88333c1d609
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  * http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * The Original Code is Mozilla Communicator client code.
16  *
17  * The Initial Developer of the Original Code is
18  * Netscape Communications Corporation.
19  * Portions created by the Initial Developer are Copyright (C) 1998
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *   Steven Michaud <smichaud@pobox.com>
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either the GNU General Public License Version 2 or later (the "GPL"), or
27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the MPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the MPL, the GPL or the LGPL.
36  *
37  * ***** END LICENSE BLOCK ***** */
39 #include "nsString.h"
41 #import <Carbon/Carbon.h>
42 #import <Cocoa/Cocoa.h>
44 #include "nsCOMPtr.h"
45 #include "nsObjCExceptions.h"
46 #include "nsNativeAppSupportBase.h"
48 #include "nsIAppShellService.h"
49 #include "nsIAppStartup.h"
50 #include "nsIBaseWindow.h"
51 #include "nsICommandLineRunner.h"
52 #include "nsIDOMWindowInternal.h"
53 #include "nsIDocShellTreeItem.h"
54 #include "nsIDocShellTreeOwner.h"
55 #include "nsIInterfaceRequestorUtils.h"
56 #include "nsIObserver.h"
57 #include "nsIServiceManager.h"
58 #include "nsIWebNavigation.h"
59 #include "nsIWidget.h"
60 #include "nsIWindowMediator.h"
62 #include "nsXPFEComponentsCID.h"
64 const OSType kNSCreator = 'MOSS';
65 const OSType kMozCreator = 'MOZZ';
66 const SInt16 kNSCanRunStrArrayID = 1000;
67 const SInt16 kAnotherVersionStrIndex = 1;
69 nsresult
70 GetNativeWindowPointerFromDOMWindow(nsIDOMWindowInternal *window, NSWindow **nativeWindow);
72 const SInt16 kNSOSVersErrsStrArrayID = 1001;
74 enum {
75         eOSXVersTooOldErrIndex = 1,
76         eOSXVersTooOldExplanationIndex,
77         eContinueButtonTextIndex,
78         eQuitButtonTextIndex,
79         eCarbonLibVersTooOldIndex,
80         eCarbonLibVersTooOldExplanationIndex
81      };
83 class nsNativeAppSupportCocoa : public nsNativeAppSupportBase
85 public:
86   nsNativeAppSupportCocoa() :
87     mCanShowUI(PR_FALSE) { }
89   NS_IMETHOD Start(PRBool* aRetVal);
90   NS_IMETHOD ReOpen();
91   NS_IMETHOD Enable();
93 private:
94   PRBool mCanShowUI;
98 NS_IMETHODIMP
99 nsNativeAppSupportCocoa::Enable()
101   mCanShowUI = PR_TRUE;
102   return NS_OK;
105 /* boolean start (); */
106 NS_IMETHODIMP nsNativeAppSupportCocoa::Start(PRBool *_retval)
108   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
110   long response = 0;
111   OSErr err = ::Gestalt (gestaltSystemVersion, &response);
112   response &= 0xFFFF; // The system version is in the low order word
114   // Check for at least Mac OS X 10.4, and if that fails return PR_FALSE,
115   // which will make the browser quit.  In principle we could display an
116   // alert here.  But the alert's message and buttons would require custom
117   // localization.  So (for now at least) we just log an English message
118   // to the console before quitting.
119   if ((err != noErr) || response < 0x00001040)
120   {
121     NSLog(@"Requires Mac OS X version 10.4 or newer");
122     return PR_FALSE;
123   }
125   *_retval = PR_TRUE;
126   return NS_OK;
128   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
131 NS_IMETHODIMP
132 nsNativeAppSupportCocoa::ReOpen()
134   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
136   if (!mCanShowUI)
137     return NS_ERROR_FAILURE;
139   PRBool haveNonMiniaturized = PR_FALSE;
140   PRBool haveOpenWindows = PR_FALSE;
141   PRBool done = PR_FALSE;
142   
143   nsCOMPtr<nsIWindowMediator> 
144     wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
145   if (!wm)
146   {
147     return NS_ERROR_FAILURE;
148   } 
149   else
150   {
151     nsCOMPtr<nsISimpleEnumerator> windowList;
152     wm->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowList));
153     PRBool more;
154     windowList->HasMoreElements(&more);
155     while (more)
156     {
157       nsCOMPtr<nsISupports> nextWindow = nsnull;
158       windowList->GetNext(getter_AddRefs(nextWindow));
159       nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(nextWindow));
160       if (!baseWindow)
161       {
162         windowList->HasMoreElements(&more);
163         continue;
164       }
165       else
166       {
167         haveOpenWindows = PR_TRUE;
168       }
170       nsCOMPtr<nsIWidget> widget = nsnull;
171       baseWindow->GetMainWidget(getter_AddRefs(widget));
172       if (!widget)
173       {
174         windowList->HasMoreElements(&more);
175         continue;
176       }
177       NSWindow *cocoaWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
178       if (![cocoaWindow isMiniaturized]) {
179         haveNonMiniaturized = PR_TRUE;
180         break;  //have un-minimized windows, nothing to do
181       } 
182       windowList->HasMoreElements(&more);
183     } // end while
184         
185     if (!haveNonMiniaturized)
186     {
187       // Deminiaturize the most recenty used window
188       nsCOMPtr<nsIDOMWindowInternal> mru = nsnull;
189       wm->GetMostRecentWindow(nsnull, getter_AddRefs(mru));
190             
191       if (mru) 
192       {        
193         NSWindow *cocoaMru = nil;
194         GetNativeWindowPointerFromDOMWindow(mru, &cocoaMru);
195         if (cocoaMru) {
196           [cocoaMru deminiaturize:nil];
197           done = PR_TRUE;
198         }
199       }
200       
201     } // end if have non miniaturized
202     
203     if (!haveOpenWindows && !done)
204     {
205       char* argv[] = { nsnull };
206     
207       // use an empty command line to make the right kind(s) of window open
208       nsCOMPtr<nsICommandLineRunner> cmdLine
209         (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
210       NS_ENSURE_TRUE(cmdLine, NS_ERROR_FAILURE);
212       nsresult rv;
213       rv = cmdLine->Init(0, argv, nsnull,
214                          nsICommandLine::STATE_REMOTE_EXPLICIT);
215       NS_ENSURE_SUCCESS(rv, rv);
217       return cmdLine->Run();
218     }
219     
220   } // got window mediator
221   return NS_OK;
223   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
226 nsresult
227 GetNativeWindowPointerFromDOMWindow(nsIDOMWindowInternal *a_window, NSWindow **a_nativeWindow)
229     *a_nativeWindow = nil;
230     if (!a_window) return NS_ERROR_INVALID_ARG;
231     
232     nsCOMPtr<nsIWebNavigation> mruWebNav(do_GetInterface(a_window));
233     if (mruWebNav)
234     {
235       nsCOMPtr<nsIDocShellTreeItem> mruTreeItem(do_QueryInterface(mruWebNav));
236       nsCOMPtr<nsIDocShellTreeOwner> mruTreeOwner = nsnull;
237       mruTreeItem->GetTreeOwner(getter_AddRefs(mruTreeOwner));
238       if(mruTreeOwner)
239       {
240         nsCOMPtr<nsIBaseWindow> mruBaseWindow(do_QueryInterface(mruTreeOwner));
241         if (mruBaseWindow)
242         {
243           nsCOMPtr<nsIWidget> mruWidget = nsnull;
244           mruBaseWindow->GetMainWidget(getter_AddRefs(mruWidget));
245           if (mruWidget)
246           {
247             *a_nativeWindow = (NSWindow*)mruWidget->GetNativeData(NS_NATIVE_WINDOW);
248           }
249         }
250       }
251     }
252     return NS_OK;
255 #pragma mark -
257 // Create and return an instance of class nsNativeAppSupportCocoa.
258 nsresult NS_CreateNativeAppSupport(nsINativeAppSupport**aResult)
260   *aResult = new nsNativeAppSupportCocoa;
261   if (!*aResult) return NS_ERROR_OUT_OF_MEMORY;
263   NS_ADDREF(*aResult);
264   return NS_OK;