source: trunk/third/mozilla/xpfe/bootstrap/nsNativeAppSupportForCocoa.mm @ 19518

Revision 19518, 8.0 KB checked in by rbasch, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19517, which included commits to RCS files with non-trunk default branches.
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Netscape Public License
5 * Version 1.1 (the "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/NPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is Mozilla Communicator client code.
15 *
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1998
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 *
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the NPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the NPL, the GPL or the LGPL.
34 *
35 * ***** END LICENSE BLOCK ***** */
36
37#import <Cocoa/Cocoa.h>
38
39#include "nsNativeAppSupport.h"
40#include "nsString.h"
41
42#include <Gestalt.h>
43#include <Dialogs.h>
44#include <Resources.h>
45#include <TextUtils.h>
46
47#include "nsIObserver.h"
48
49#define rSplashDialog 512
50
51const OSType kNSCreator = 'MOSS';
52const OSType kMozCreator = 'MOZZ';
53const SInt16 kNSCanRunStrArrayID = 1000;
54const SInt16 kAnotherVersionStrIndex = 1;
55
56class nsSplashScreenCocoa : public nsISplashScreen,
57                          public nsIObserver
58{
59public:
60
61    // dialog itemse
62    enum {
63      eSplashPictureItem = 1,
64      eSplashStatusTextItem   
65    };
66   
67            nsSplashScreenCocoa();   
68    virtual ~nsSplashScreenCocoa();
69
70    NS_DECL_ISUPPORTS
71
72    NS_IMETHOD Show();
73    NS_IMETHOD Hide();
74
75    NS_DECL_NSIOBSERVER
76
77protected:
78
79    DialogPtr mDialog;
80
81}; // class nsSplashScreenCocoa
82
83
84nsSplashScreenCocoa::nsSplashScreenCocoa()
85: mDialog(nsnull)
86{
87}
88
89
90nsSplashScreenCocoa::~nsSplashScreenCocoa()
91{
92  Hide();
93}
94
95
96NS_IMPL_ISUPPORTS2(nsSplashScreenCocoa, nsISplashScreen, nsIObserver);
97
98NS_IMETHODIMP
99nsSplashScreenCocoa::Show()
100{
101printf("-- nsSplashScreenCocoa::Show()\n");
102#if 0
103  mDialog = ::GetNewDialog(rSplashDialog, nil, (WindowPtr)-1L);
104  if (!mDialog) return NS_ERROR_FAILURE;
105
106  ::ShowWindow(GetDialogWindow(mDialog));
107  ::SetPortDialogPort(mDialog);
108
109  ::DrawDialog(mDialog);    // we don't handle events for this dialog, so we
110                            // need to draw explicitly. Yuck.
111#endif
112  return NS_OK;
113}
114
115NS_IMETHODIMP
116nsSplashScreenCocoa::Hide()
117{
118printf("-- nsSplashScreenCocoa::Hide()\n");
119#if 0
120  if (mDialog)
121  {
122    ::DisposeDialog( mDialog );
123    mDialog = nsnull;
124  }
125#endif
126  return NS_OK;
127}
128
129
130NS_IMETHODIMP
131nsSplashScreenCocoa::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
132{
133  // update a string in the dialog
134 
135  nsCAutoString statusString;
136  statusString.AssignWithConversion(someData);
137printf("\n[[[ Splash Screen -- %s ]]]\n\n", (const char *)statusString.get());
138
139#if 0
140  Handle    item = nsnull;
141  Rect      itemRect;
142  short     itemType;
143  ::GetDialogItem(mDialog, eSplashStatusTextItem, &itemType, &item, &itemRect);
144  if (!item) return NS_OK;
145 
146  // convert string to Pascal string
147  Str255    statusPStr;
148  PRInt32   maxLen = statusString.Length();
149  if (maxLen > 254)
150    maxLen = 254;
151  strncpy((char *)&statusPStr[1], (const char *)statusString, maxLen);
152  statusPStr[0] = maxLen;
153 
154  ::SetDialogItemText(item, statusPStr);
155  ::DrawDialog(mDialog);
156#endif
157  return NS_OK;
158}
159
160
161#pragma mark -
162
163nsresult NS_CreateSplashScreen(nsISplashScreen**aResult)
164{
165  if ( aResult ) { 
166      *aResult = new nsSplashScreenCocoa;
167      if ( *aResult ) {
168          NS_ADDREF( *aResult );
169          return NS_OK;
170      } else {
171          return NS_ERROR_OUT_OF_MEMORY;
172      }
173  } else {
174      return NS_ERROR_NULL_POINTER;
175  }
176}
177
178// Snagged from mozilla/xpinstall/wizrd/mac/src/SetupTypeWin.c
179// VersGreaterThan4 - utility function to test if it's >4.x running
180static Boolean VersGreaterThan4(FSSpec *fSpec)
181{
182  Boolean result = false;
183  short fRefNum = 0;
184 
185  ::SetResLoad(false);
186  fRefNum = ::FSpOpenResFile(fSpec, fsRdPerm);
187  ::SetResLoad(true);
188  if (fRefNum != -1)
189  {
190    Handle  h;
191    h = ::Get1Resource('vers', 2);
192    if (h && **(unsigned short**)h >= 0x0500)
193      result = true;
194    ::CloseResFile(fRefNum);
195  }
196   
197  return result;
198}
199
200PRBool NS_CanRun()
201{
202  // init Cocoa before anything else happens, like showing the
203  // splash screen.
204  // XXX We leak the pool, but that's ok, it'll go away when the app quits
205  [NSApplication sharedApplication];
206  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
207 
208  return PR_TRUE;
209#if 0
210  // Check for running instances of Mozilla or Netscape. The real issue
211  // is having more than one app use the same profile directory. That would
212  // be REAL BAD!!!!!!!!
213
214  // The code below is a copy of nsLocalFile::FindRunningAppBySignature which is
215  // a non-static method. Sounds silly that I have to create an nsILocalFile
216  // just to call that method. At any rate, don't think we want to go through
217  // all that rigmarole during startup anyway.
218
219  ProcessInfoRec  info;
220  FSSpec          tempFSSpec;
221  ProcessSerialNumber psn, nextProcessPsn;
222
223  nextProcessPsn.highLongOfPSN = 0;
224  nextProcessPsn.lowLongOfPSN  = kNoProcess;
225
226  // first, get our psn so that we can exclude ourselves when searching
227  err = ::GetCurrentProcess(&psn);
228
229  if (err != noErr)
230    return PR_FALSE;
231
232  // We loop while err == noErr, which should mean all our calls are OK
233  // The ways of 'break'-ing out of the loop are:
234  //   GetNextProcess() fails (this includes getting procNotFound, meaning we're at the end of the process list),
235  //   GetProcessInformation() fails
236  // The ways we should fall out of the while loop are:
237  //   GetIndString() fails, err == resNotFound,
238  //   we found a running mozilla process or running Netscape > 4.x process, err == fnfErr
239  while (err == noErr)
240  {
241    err = ::GetNextProcess(&nextProcessPsn);
242    if (err != noErr)
243      break; // most likely, end of process list
244    info.processInfoLength = sizeof(ProcessInfoRec);
245    info.processName = nil;
246    info.processAppSpec = &tempFSSpec;
247    err = ::GetProcessInformation(&nextProcessPsn, &info);
248    if (err != noErr)
249      break; // aww crap, GetProcessInfo() failed, we're outta here
250
251    if (info.processSignature == kNSCreator || info.processSignature == kMozCreator)
252    {
253      // if the found process is us, obviously, it's okay if WE'RE running,
254      if (!(info.processNumber.lowLongOfPSN == psn.lowLongOfPSN &&
255            info.processNumber.highLongOfPSN == psn.highLongOfPSN))
256      {
257        // check to see if Netscape process is greater than Netscape 4.x or
258        // if process is Mozilla
259        if ((info.processSignature == kNSCreator && VersGreaterThan4(&tempFSSpec)) ||
260             info.processSignature == kMozCreator)
261        {
262          // put up error dialog
263          Str255 str;
264          ::GetIndString(str, kNSCanRunStrArrayID, kAnotherVersionStrIndex);
265          if (StrLength(str) == 0)
266            err = resNotFound; // set err to something so that we return false
267          else
268          {
269            SInt16 outItemHit;
270            if (str)
271              ::StandardAlert(kAlertStopAlert, str, nil, nil, &outItemHit);
272            err = fnfErr; // set err to something so that we return false
273          }
274        }
275      }
276    }
277  }
278
279  if (err == noErr || err == procNotFound)
280    return PR_TRUE;
281
282  return PR_FALSE;
283#endif
284}
Note: See TracBrowser for help on using the repository browser.