1: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2: /* ***** BEGIN LICENSE BLOCK *****
3: * Version: NPL 1.1/GPL 2.0/LGPL 2.1
4: *
5: * The contents of this file are subject to the Netscape Public License
6: * Version 1.1 (the "License"); you may not use this file except in
7: * compliance with the License. You may obtain a copy of the License at
8: * http://www.mozilla.org/NPL/
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.org 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: *
24: * Alternatively, the contents of this file may be used under the terms of
25: * either the GNU General Public License Version 2 or later (the "GPL"), or
26: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27: * in which case the provisions of the GPL or the LGPL are applicable instead
28: * of those above. If you wish to allow use of your version of this file only
29: * under the terms of either the GPL or the LGPL, and not to allow others to
30: * use your version of this file under the terms of the NPL, indicate your
31: * decision by deleting the provisions above and replace them with the notice
32: * and other provisions required by the GPL or the LGPL. If you do not delete
33: * the provisions above, a recipient may use your version of this file under
34: * the terms of any one of the NPL, the GPL or the LGPL.
35: *
36: * ***** END LICENSE BLOCK ***** */
37:
38: #include "nsCocoaBrowserService.h"
39:
40: #include "nsIWindowWatcher.h"
41: #include "nsIWebBrowserChrome.h"
42: #include "nsIEmbeddingSiteWindow.h"
43: #include "nsIProfile.h"
44: #include "NSBrowserView.h"
45: #include "nsCRT.h"
46: #include "nsString.h"
47:
48: nsAlertController* nsCocoaBrowserService::sController = nsnull;
49: nsCocoaBrowserService* nsCocoaBrowserService::sSingleton = nsnull;
50: PRUint32 nsCocoaBrowserService::sNumBrowsers = 0;
51:
52: // nsCocoaBrowserService implementation
53: nsCocoaBrowserService::nsCocoaBrowserService()
54: {
55: NS_INIT_ISUPPORTS();
56: }
57:
58: nsCocoaBrowserService::~nsCocoaBrowserService()
59: {
60: }
61:
62: NS_IMPL_ISUPPORTS3(nsCocoaBrowserService,
63: nsIWindowCreator,
64: nsIPromptService,
65: nsIFactory)
66:
67: nsresult
68: nsCocoaBrowserService::InitEmbedding()
69: {
70: sNumBrowsers++;
71:
72: if (sSingleton)
73: return NS_OK;
74:
75: // XXX Temporary hack to make sure we find the
76: // right executable directory
77: NSBundle* mainBundle = [NSBundle mainBundle];
78: NSString* path = [mainBundle bundlePath];
79: NSMutableString* mutablePath = [NSMutableString stringWithString:path];
80: [mutablePath appendString:@"/Contents/MacOS/"];
81: const char* cstr = [mutablePath cString];
82: setenv("MOZILLA_FIVE_HOME", cstr, 1);
83:
84: sSingleton = new nsCocoaBrowserService();
85: if (!sSingleton) {
86: return NS_ERROR_OUT_OF_MEMORY;
87: }
88: NS_ADDREF(sSingleton);
89:
90: nsresult rv = NS_InitEmbedding(nsnull, nsnull);
91: if (NS_FAILED(rv)) {
92: return rv;
93: }
94:
95: // Register as the prompt service
96: #define NS_PROMPTSERVICE_CID \
97: {0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}
98: static NS_DEFINE_CID(kPromptServiceCID, NS_PROMPTSERVICE_CID);
99:
100: rv = nsComponentManager::RegisterFactory(kPromptServiceCID,
101: "Prompt Service",
102: "@mozilla.org/embedcomp/prompt-service;1",
103: sSingleton,
104: PR_TRUE); // replace existing
105: if (NS_FAILED(rv)) {
106: return rv;
107: }
108:
109: // Register as the window creator
110: nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
111: if (!watcher) {
112: return NS_ERROR_FAILURE;
113: }
114:
115: watcher->SetWindowCreator(sSingleton);
116:
117: // Set the profile which the control will use
118: nsCOMPtr<nsIProfile> profileService(do_GetService(NS_PROFILE_CONTRACTID, &rv));
119: if (NS_FAILED(rv))
120: return rv;
121:
122: // Make a new default profile for the control if none exists.
123: nsAutoString newProfileName(NS_LITERAL_STRING("Chimera"));
124: PRBool profileExists = PR_FALSE;
125: rv = profileService->ProfileExists(newProfileName.get(), &profileExists);
126: if (NS_FAILED(rv))
127: return rv;
128:
129: if (!profileExists) {
130: rv = profileService->CreateNewProfile(newProfileName.get(), nsnull, nsnull, PR_FALSE);
131: if (NS_FAILED(rv))
132: return rv;
133: }
134:
135: rv = profileService->SetCurrentProfile(newProfileName.get());
136: if (NS_FAILED(rv))
137: return rv;
138:
139: return NS_OK;
140: }
141:
142: void
143: nsCocoaBrowserService::BrowserClosed()
144: {
145: sNumBrowsers--;
146: if (!sSingleton && sNumBrowsers == 0) {
147: // The app is terminating *and* our count dropped to 0.
148: NS_TermEmbedding();
149: printf("Shutting down embedding!\n");
150: }
151: }
152:
153: void
154: nsCocoaBrowserService::TermEmbedding()
155: {
156: NS_RELEASE(sSingleton);
157:
158: if (sNumBrowsers == 0) {
159: NS_TermEmbedding(); // Safe to terminate now.
160: printf("Shutting down embedding.\n");
161: }
162:
163: // Otherwise we cannot yet terminate. We have to let the death of the browser windows
164: // induce termination.
165: }
166:
167: #define NS_ALERT_NIB_NAME "alert"
168:
169: nsAlertController*
170: nsCocoaBrowserService::GetAlertController()
171: {
172: if (!sController) {
173: NSBundle* bundle = [NSBundle bundleForClass:[NSBrowserView class]];
174: [bundle loadNibFile:@NS_ALERT_NIB_NAME externalNameTable:nsnull withZone:[NSApp zone]];
175: }
176: return sController;
177: }
178:
179: void
180: nsCocoaBrowserService::SetAlertController(nsAlertController* aController)
181: {
182: // XXX When should the controller be released?
183: sController = aController;
184: [sController retain];
185: }
186:
187: // nsIFactory implementation
188: NS_IMETHODIMP
189: nsCocoaBrowserService::CreateInstance(nsISupports *aOuter,
190: const nsIID & aIID,
191: void **aResult)
192: {
193: NS_ENSURE_ARG_POINTER(aResult);
194:
195: return sSingleton->QueryInterface(aIID, aResult);
196: }
197:
198: NS_IMETHODIMP
199: nsCocoaBrowserService::LockFactory(PRBool lock)
200: {
201: return NS_OK;
202: }
203:
204: // nsIPromptService implementation
205: static NSWindow*
206: GetNSWindowForDOMWindow(nsIDOMWindow* window)
207: {
208: nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
209: if (!watcher) {
210: return nsnull;
211: }
212:
213: nsCOMPtr<nsIWebBrowserChrome> chrome;
214: watcher->GetChromeForWindow(window, getter_AddRefs(chrome));
215: if (!chrome) {
216: return nsnull;
217: }
218:
219: nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow(do_QueryInterface(chrome));
220: if (!siteWindow) {
221: return nsnull;
222: }
223:
224: NSWindow* nswin;
225: siteWindow->GetSiteWindow((void**)&nswin);
226:
227: return nswin;
228: }
229:
230: // Implementation of nsIPromptService
231: NS_IMETHODIMP
232: nsCocoaBrowserService::Alert(nsIDOMWindow *parent,
233: const PRUnichar *dialogTitle,
234: const PRUnichar *text)
235: {
236: nsAlertController* controller = GetAlertController();
237: if (!controller) {
238: return NS_ERROR_FAILURE;
239: }
240:
241: NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
242: NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
243: NSWindow* window = GetNSWindowForDOMWindow(parent);
244:
245: [controller alert:window title:titleStr text:textStr];
246:
247: return NS_OK;
248: }
249:
250: /* void alertCheck (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue); */
251: NS_IMETHODIMP
252: nsCocoaBrowserService::AlertCheck(nsIDOMWindow *parent,
253: const PRUnichar *dialogTitle,
254: const PRUnichar *text,
255: const PRUnichar *checkMsg,
256: PRBool *checkValue)
257: {
258: nsAlertController* controller = GetAlertController();
259: if (!controller) {
260: return NS_ERROR_FAILURE;
261: }
262:
263: NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
264: NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
265: NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
266: NSWindow* window = GetNSWindowForDOMWindow(parent);
267:
268: if (checkValue) {
269: BOOL valueBool = *checkValue ? YES : NO;
270:
271: [controller alertCheck:window title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
272:
273: *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
274: }
275: else {
276: [controller alert:window title:titleStr text:textStr];
277: }
278:
279: return NS_OK;
280: }
281:
282: /* boolean confirm (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text); */
283: NS_IMETHODIMP
284: nsCocoaBrowserService::Confirm(nsIDOMWindow *parent,
285: const PRUnichar *dialogTitle,
286: const PRUnichar *text,
287: PRBool *_retval)
288: {
289: nsAlertController* controller = GetAlertController();
290: if (!controller) {
291: return NS_ERROR_FAILURE;
292: }
293:
294: NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
295: NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
296: NSWindow* window = GetNSWindowForDOMWindow(parent);
297:
298: *_retval = (PRBool)[controller confirm:window title:titleStr text:textStr];
299:
300: return NS_OK;
301: }
302:
303: /* boolean confirmCheck (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue); */
304: NS_IMETHODIMP
305: nsCocoaBrowserService::ConfirmCheck(nsIDOMWindow *parent,
306: const PRUnichar *dialogTitle,
307: const PRUnichar *text,
308: const PRUnichar *checkMsg,
309: PRBool *checkValue, PRBool *_retval)
310: {
311: nsAlertController* controller = GetAlertController();
312: if (!controller) {
313: return NS_ERROR_FAILURE;
314: }
315:
316: NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
317: NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
318: NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
319: NSWindow* window = GetNSWindowForDOMWindow(parent);
320:
321: if (checkValue) {
322: BOOL valueBool = *checkValue ? YES : NO;
323:
324: *_retval = (PRBool)[controller confirmCheck:window title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
325:
326: *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
327: }
328: else {
329: *_retval = (PRBool)[controller confirm:window title:titleStr text:textStr];
330: }
331:
332: return NS_OK;
333: }
334:
335: /* void confirmEx (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in unsigned long buttonFlags, in wstring button0Title, in wstring button1Title, in wstring button2Title, in wstring checkMsg, inout boolean checkValue, out PRInt32 buttonPressed); */
336: NS_IMETHODIMP
337: nsCocoaBrowserService::ConfirmEx(nsIDOMWindow *parent,
338: const PRUnichar *dialogTitle,
339: const PRUnichar *text,
340: PRUint32 buttonFlags,
341: const PRUnichar *button0Title,
342: const PRUnichar *button1Title,
343: const PRUnichar *button2Title,
344: const PRUnichar *checkMsg,
345: PRBool *checkValue, PRInt32 *buttonPressed)
346: {
347: return NS_ERROR_NOT_IMPLEMENTED;
348: }
349:
350: /* boolean prompt (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, inout wstring value, in wstring checkMsg, inout boolean checkValue); */
351: NS_IMETHODIMP
352: nsCocoaBrowserService::Prompt(nsIDOMWindow *parent,
353: const PRUnichar *dialogTitle,
354: const PRUnichar *text,
355: PRUnichar **value,
356: const PRUnichar *checkMsg,
357: PRBool *checkValue,
358: PRBool *_retval)
359: {
360: nsAlertController* controller = GetAlertController();
361: if (!controller) {
362: return NS_ERROR_FAILURE;
363: }
364:
365: NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
366: NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
367: NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
368: NSMutableString* valueStr = [NSMutableString stringWithCharacters:*value length:(*value ? nsCRT::strlen(*value) : 0)];
369:
370: BOOL valueBool;
371: if (checkValue) {
372: valueBool = *checkValue ? YES : NO;
373: }
374: NSWindow* window = GetNSWindowForDOMWindow(parent);
375:
376: *_retval = (PRBool)[controller prompt:window title:titleStr text:textStr promptText:valueStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
377:
378: if (checkValue) {
379: *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
380: }
381: PRUint32 length = [valueStr length];
382: PRUnichar* retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
383: [valueStr getCharacters:retStr];
384: retStr[length] = PRUnichar(0);
385: *value = retStr;
386:
387: return NS_OK;
388: }
389:
390: /* boolean promptUsernameAndPassword (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, inout wstring username, inout wstring password, in wstring checkMsg, inout boolean checkValue); */
391: NS_IMETHODIMP
392: nsCocoaBrowserService::PromptUsernameAndPassword(nsIDOMWindow *parent,
393: const PRUnichar *dialogTitle,
394: const PRUnichar *text,
395: PRUnichar **username,
396: PRUnichar **password,
397: const PRUnichar *checkMsg,
398: PRBool *checkValue,
399: PRBool *_retval)
400: {
401: nsAlertController* controller = GetAlertController();
402: if (!controller) {
403: return NS_ERROR_FAILURE;
404: }
405:
406: NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
407: NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
408: NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
409: NSMutableString* userNameStr = [NSMutableString stringWithCharacters:*username length:(*username ? nsCRT::strlen(*username) : 0)];
410: NSMutableString* passwordStr = [NSMutableString stringWithCharacters:*password length:(*password ? nsCRT::strlen(*password) : 0)];
411:
412: BOOL valueBool;
413: if (checkValue) {
414: valueBool = *checkValue ? YES : NO;
415: }
416: NSWindow* window = GetNSWindowForDOMWindow(parent);
417:
418: *_retval = (PRBool)[controller promptUserNameAndPassword:window title:titleStr text:textStr userNameText:userNameStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
419:
420: if (checkValue) {
421: *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
422: }
423:
424: PRUint32 length = [userNameStr length];
425: PRUnichar* retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
426: [userNameStr getCharacters:retStr];
427: retStr[length] = PRUnichar(0);
428: *username = retStr;
429:
430: length = [passwordStr length];
431: retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
432: [passwordStr getCharacters:retStr];
433: retStr[length] = PRUnichar(0);
434: *password = retStr;
435:
436: return NS_OK;
437: }
438:
439: /* boolean promptPassword (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, inout wstring password, in wstring checkMsg, inout boolean checkValue); */
440: NS_IMETHODIMP
441: nsCocoaBrowserService::PromptPassword(nsIDOMWindow *parent,
442: const PRUnichar *dialogTitle,
443: const PRUnichar *text,
444: PRUnichar **password,
445: const PRUnichar *checkMsg,
446: PRBool *checkValue,
447: PRBool *_retval)
448: {
449: nsAlertController* controller = GetAlertController();
450: if (!controller) {
451: return NS_ERROR_FAILURE;
452: }
453:
454: NSString* titleStr = [NSString stringWithCharacters:dialogTitle length:(dialogTitle ? nsCRT::strlen(dialogTitle) : 0)];
455: NSString* textStr = [NSString stringWithCharacters:text length:(text ? nsCRT::strlen(text) : 0)];
456: NSString* msgStr = [NSString stringWithCharacters:checkMsg length:(checkMsg ? nsCRT::strlen(checkMsg) : 0)];
457: NSMutableString* passwordStr = [NSMutableString stringWithCharacters:*password length:(*password ? nsCRT::strlen(*password) : 0)];
458:
459: BOOL valueBool;
460: if (checkValue) {
461: valueBool = *checkValue ? YES : NO;
462: }
463: NSWindow* window = GetNSWindowForDOMWindow(parent);
464:
465: *_retval = (PRBool)[controller promptPassword:window title:titleStr text:textStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
466:
467: if (checkValue) {
468: *checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
469: }
470:
471: PRUint32 length = [passwordStr length];
472: PRUnichar* retStr = (PRUnichar*)nsMemory::Alloc((length + 1) * sizeof(PRUnichar));
473: [passwordStr getCharacters:retStr];
474: retStr[length] = PRUnichar(0);
475: *password = retStr;
476:
477: return NS_OK;
478: }
479:
480: /* boolean select (in nsIDOMWindow parent, in wstring dialogTitle, in wstring text, in PRUint32 count, [array, size_is (count)] in wstring selectList, out long outSelection); */
481: NS_IMETHODIMP
482: nsCocoaBrowserService::Select(nsIDOMWindow *parent,
483: const PRUnichar *dialogTitle,
484: const PRUnichar *text,
485: PRUint32 count,
486: const PRUnichar **selectList,
487: PRInt32 *outSelection,
488: PRBool *_retval)
489: {
490: return NS_ERROR_NOT_IMPLEMENTED;
491: }
492:
493: // Implementation of nsIWindowCreator
494: /* nsIWebBrowserChrome createChromeWindow (in nsIWebBrowserChrome parent, in PRUint32 chromeFlags); */
495: NS_IMETHODIMP
496: nsCocoaBrowserService::CreateChromeWindow(nsIWebBrowserChrome *parent,
497: PRUint32 chromeFlags,
498: nsIWebBrowserChrome **_retval)
499: {
500: return NS_ERROR_NOT_IMPLEMENTED;
501: }
502:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>