forked from mirrors/gecko-dev
		
	 9331b9fb07
			
		
	
	
		9331b9fb07
		
	
	
	
	
		
			
			For some reason, its value in the Google style we use is 80... except for Objective-C, where it's 100, which led to things like: https://hg.mozilla.org/mozilla-central/rev/31bf68247e6e https://hg.mozilla.org/mozilla-central/rev/64ceb33533a4. There's probably a discussion to have about whether 80 is the right limit, but since it's what's used for everything except ObjC, let's roll with it. # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D187409
		
			
				
	
	
		
			139 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim:expandtab:shiftwidth=2:tabstop=2:
 | |
|  */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #import <Cocoa/Cocoa.h>
 | |
| #import <CoreServices/CoreServices.h>
 | |
| 
 | |
| #include "MacAutoreleasePool.h"
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsIComponentManager.h"
 | |
| #include "nsIServiceManager.h"
 | |
| #include "nsIWindowMediator.h"
 | |
| #include "nsIWidget.h"
 | |
| #include "nsICommandLineRunner.h"
 | |
| #include "nsICommandLine.h"
 | |
| #include "nsCommandLine.h"
 | |
| #include "nsIDocShell.h"
 | |
| #include "nsMacRemoteServer.h"
 | |
| #include "nsXPCOM.h"
 | |
| #include "RemoteUtils.h"
 | |
| 
 | |
| CFDataRef messageServerCallback(CFMessagePortRef aLocal, int32_t aMsgid,
 | |
|                                 CFDataRef aData, void* aInfo) {
 | |
|   // One of the clients submitted a structure.
 | |
|   static_cast<nsMacRemoteServer*>(aInfo)->HandleCommandLine(aData);
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| // aData contains serialized Dictionary, which in turn contains command line
 | |
| // arguments
 | |
| void nsMacRemoteServer::HandleCommandLine(CFDataRef aData) {
 | |
|   mozilla::MacAutoreleasePool pool;
 | |
| 
 | |
|   if (aData) {
 | |
|     NSDictionary* dict =
 | |
|         [NSKeyedUnarchiver unarchiveObjectWithData:(NSData*)aData];
 | |
|     if (dict && [dict isKindOfClass:[NSDictionary class]]) {
 | |
|       NSArray* args = dict[@"args"];
 | |
|       if (!args) {
 | |
|         NS_ERROR("Wrong parameters passed to the Remote Server");
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       nsCOMPtr<nsICommandLineRunner> cmdLine(new nsCommandLine());
 | |
| 
 | |
|       // Converting Objective-C array into a C array,
 | |
|       // which nsICommandLineRunner understands.
 | |
|       int argc = [args count];
 | |
|       const char** argv = new const char*[argc];
 | |
|       for (int i = 0; i < argc; i++) {
 | |
|         const char* arg = [[args objectAtIndex:i] UTF8String];
 | |
|         argv[i] = arg;
 | |
|       }
 | |
| 
 | |
|       nsresult rv =
 | |
|           cmdLine->Init(argc, argv, nullptr, nsICommandLine::STATE_REMOTE_AUTO);
 | |
| 
 | |
|       // Cleaning up C array.
 | |
|       delete[] argv;
 | |
| 
 | |
|       if (NS_FAILED(rv)) {
 | |
|         NS_ERROR("Error initializing command line.");
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       // Processing the command line, passed from a remote instance
 | |
|       // in the current instance.
 | |
|       cmdLine->Run();
 | |
| 
 | |
|       // And bring the app's window to front.
 | |
|       [[NSRunningApplication currentApplication]
 | |
|           activateWithOptions:NSApplicationActivateIgnoringOtherApps];
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| nsresult nsMacRemoteServer::Startup(const char* aAppName,
 | |
|                                     const char* aProfileName) {
 | |
|   // This is the first instance ever.
 | |
|   // Let's register a notification listener here,
 | |
|   // In case future instances would want to notify us about command line
 | |
|   // arguments passed to them. Note, that if mozilla process is restarting, we
 | |
|   // still need to register for notifications.
 | |
| 
 | |
|   mozilla::MacAutoreleasePool pool;
 | |
| 
 | |
|   nsString className;
 | |
|   BuildClassName(aAppName, aProfileName, className);
 | |
| 
 | |
|   NSString* serverNameString = [NSString
 | |
|       stringWithCharacters:reinterpret_cast<const unichar*>(className.get())
 | |
|                     length:className.Length()];
 | |
| 
 | |
|   CFMessagePortContext context;
 | |
|   context.copyDescription = NULL;
 | |
|   context.info = this;
 | |
|   context.release = NULL;
 | |
|   context.retain = NULL;
 | |
|   context.version = NULL;
 | |
|   mMessageServer =
 | |
|       CFMessagePortCreateLocal(NULL, (CFStringRef)serverNameString,
 | |
|                                messageServerCallback, &context, NULL);
 | |
|   if (!mMessageServer) {
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
|   mRunLoopSource = CFMessagePortCreateRunLoopSource(NULL, mMessageServer, 0);
 | |
|   if (!mRunLoopSource) {
 | |
|     CFRelease(mMessageServer);
 | |
|     mMessageServer = NULL;
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
|   CFRunLoopRef runLoop = CFRunLoopGetMain();
 | |
|   CFRunLoopAddSource(runLoop, mRunLoopSource, kCFRunLoopDefaultMode);
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| void nsMacRemoteServer::Shutdown() {
 | |
|   // 1) Invalidate server connection
 | |
|   if (mMessageServer) {
 | |
|     CFMessagePortInvalidate(mMessageServer);
 | |
|   }
 | |
| 
 | |
|   // 2) Release run loop source
 | |
|   if (mRunLoopSource) {
 | |
|     CFRelease(mRunLoopSource);
 | |
|     mRunLoopSource = NULL;
 | |
|   }
 | |
| 
 | |
|   // 3) Release server connection
 | |
|   if (mMessageServer) {
 | |
|     CFRelease(mMessageServer);
 | |
|     mMessageServer = NULL;
 | |
|   }
 | |
| }
 |