forked from mirrors/gecko-dev
		
	 e0e5aaf219
			
		
	
	
		e0e5aaf219
		
	
	
	
	
		
			
			MozReview-Commit-ID: 6tvC4VWcUiC --HG-- extra : rebase_source : b40fe3e8cd827f15a947a889b154fd1ba0ffca75
		
			
				
	
	
		
			196 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim:expandtab:shiftwidth=2:tabstop=8:
 | |
|  */
 | |
| /* 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/. */
 | |
| 
 | |
| #include "mozilla/ArrayUtils.h"
 | |
| 
 | |
| #include "nsXRemoteService.h"
 | |
| #include "nsRemoteService.h"
 | |
| #include "nsIObserverService.h"
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsIServiceManager.h"
 | |
| #include "nsICommandLineRunner.h"
 | |
| #include "nsICommandLine.h"
 | |
| 
 | |
| #include "nsIBaseWindow.h"
 | |
| #include "nsIDocShell.h"
 | |
| #include "nsIFile.h"
 | |
| #include "nsIServiceManager.h"
 | |
| #include "nsIWeakReference.h"
 | |
| #include "nsIWidget.h"
 | |
| #include "nsIAppShellService.h"
 | |
| #include "nsAppShellCID.h"
 | |
| #include "nsPIDOMWindow.h"
 | |
| #include "mozilla/X11Util.h"
 | |
| 
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsString.h"
 | |
| #include "prenv.h"
 | |
| #include "nsCRT.h"
 | |
| 
 | |
| #include "nsXULAppAPI.h"
 | |
| 
 | |
| #include <X11/Xlib.h>
 | |
| #include <X11/Xatom.h>
 | |
| 
 | |
| using namespace mozilla;
 | |
| 
 | |
| #define MOZILLA_VERSION_PROP   "_MOZILLA_VERSION"
 | |
| #define MOZILLA_LOCK_PROP      "_MOZILLA_LOCK"
 | |
| #define MOZILLA_RESPONSE_PROP  "_MOZILLA_RESPONSE"
 | |
| #define MOZILLA_USER_PROP      "_MOZILLA_USER"
 | |
| #define MOZILLA_PROFILE_PROP   "_MOZILLA_PROFILE"
 | |
| #define MOZILLA_PROGRAM_PROP   "_MOZILLA_PROGRAM"
 | |
| #define MOZILLA_COMMANDLINE_PROP "_MOZILLA_COMMANDLINE"
 | |
| 
 | |
| const unsigned char kRemoteVersion[] = "5.1";
 | |
| 
 | |
| // Minimize the roundtrips to the X server by getting all the atoms at once
 | |
| static const char *XAtomNames[] = {
 | |
|   MOZILLA_VERSION_PROP,
 | |
|   MOZILLA_LOCK_PROP,
 | |
|   MOZILLA_RESPONSE_PROP,
 | |
|   MOZILLA_USER_PROP,
 | |
|   MOZILLA_PROFILE_PROP,
 | |
|   MOZILLA_PROGRAM_PROP,
 | |
|   MOZILLA_COMMANDLINE_PROP
 | |
| };
 | |
| static Atom XAtoms[MOZ_ARRAY_LENGTH(XAtomNames)];
 | |
| 
 | |
| Atom nsXRemoteService::sMozVersionAtom;
 | |
| Atom nsXRemoteService::sMozLockAtom;
 | |
| Atom nsXRemoteService::sMozResponseAtom;
 | |
| Atom nsXRemoteService::sMozUserAtom;
 | |
| Atom nsXRemoteService::sMozProfileAtom;
 | |
| Atom nsXRemoteService::sMozProgramAtom;
 | |
| Atom nsXRemoteService::sMozCommandLineAtom;
 | |
| 
 | |
| nsXRemoteService::nsXRemoteService() = default;
 | |
| 
 | |
| void
 | |
| nsXRemoteService::XRemoteBaseStartup(const char *aAppName, const char *aProfileName)
 | |
| {
 | |
|     EnsureAtoms();
 | |
| 
 | |
|     mAppName = aAppName;
 | |
|     ToLowerCase(mAppName);
 | |
| 
 | |
|     mProfileName = aProfileName;
 | |
| }
 | |
| 
 | |
| void
 | |
| nsXRemoteService::HandleCommandsFor(Window aWindowId)
 | |
| {
 | |
|   // set our version
 | |
|   XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozVersionAtom, XA_STRING,
 | |
|                   8, PropModeReplace, kRemoteVersion, sizeof(kRemoteVersion) - 1);
 | |
| 
 | |
|   // get our username
 | |
|   unsigned char *logname;
 | |
|   logname = (unsigned char*) PR_GetEnv("LOGNAME");
 | |
|   if (logname) {
 | |
|     // set the property on the window if it's available
 | |
|     XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozUserAtom, XA_STRING,
 | |
|                     8, PropModeReplace, logname, strlen((char*) logname));
 | |
|   }
 | |
| 
 | |
|   XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozProgramAtom, XA_STRING,
 | |
|                   8, PropModeReplace, (unsigned char*) mAppName.get(), mAppName.Length());
 | |
| 
 | |
|   if (!mProfileName.IsEmpty()) {
 | |
|     XChangeProperty(mozilla::DefaultXDisplay(),
 | |
|                     aWindowId, sMozProfileAtom, XA_STRING,
 | |
|                     8, PropModeReplace,
 | |
|                     (unsigned char*) mProfileName.get(), mProfileName.Length());
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| bool
 | |
| nsXRemoteService::HandleNewProperty(XID aWindowId, Display* aDisplay,
 | |
|                                     Time aEventTime,
 | |
|                                     Atom aChangedAtom,
 | |
|                                     nsIWeakReference* aDomWindow)
 | |
| {
 | |
| 
 | |
|   nsCOMPtr<nsIDOMWindow> window (do_QueryReferent(aDomWindow));
 | |
| 
 | |
|   if (aChangedAtom == sMozCommandLineAtom) {
 | |
|     // We got a new command atom.
 | |
|     int result;
 | |
|     Atom actual_type;
 | |
|     int actual_format;
 | |
|     unsigned long nitems, bytes_after;
 | |
|     char *data = 0;
 | |
| 
 | |
|     result = XGetWindowProperty (aDisplay,
 | |
|                                  aWindowId,
 | |
|                                  aChangedAtom,
 | |
|                                  0,                        /* long_offset */
 | |
|                                  (65536 / sizeof (long)),  /* long_length */
 | |
|                                  True,                     /* atomic delete after */
 | |
|                                  XA_STRING,                /* req_type */
 | |
|                                  &actual_type,             /* actual_type return */
 | |
|                                  &actual_format,           /* actual_format_return */
 | |
|                                  &nitems,                  /* nitems_return */
 | |
|                                  &bytes_after,             /* bytes_after_return */
 | |
|                                  (unsigned char **)&data); /* prop_return
 | |
|                                                               (we only care
 | |
|                                                               about the first ) */
 | |
| 
 | |
|     // Failed to get property off the window?
 | |
|     if (result != Success)
 | |
|       return false;
 | |
| 
 | |
|     // Failed to get the data off the window or it was the wrong type?
 | |
|     if (!data || !TO_LITTLE_ENDIAN32(*reinterpret_cast<int32_t*>(data)))
 | |
|       return false;
 | |
| 
 | |
|     // cool, we got the property data.
 | |
|     const char *response =
 | |
|       nsRemoteService::HandleCommandLine(data, window, aEventTime);
 | |
| 
 | |
|     // put the property onto the window as the response
 | |
|     XChangeProperty (aDisplay, aWindowId,
 | |
|                      sMozResponseAtom, XA_STRING,
 | |
|                      8, PropModeReplace,
 | |
|                      (const unsigned char *)response,
 | |
|                      strlen (response));
 | |
|     XFree(data);
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   if (aChangedAtom == sMozResponseAtom) {
 | |
|     // client accepted the response.  party on wayne.
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   else if (aChangedAtom == sMozLockAtom) {
 | |
|     // someone locked the window
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| void
 | |
| nsXRemoteService::EnsureAtoms(void)
 | |
| {
 | |
|   if (sMozVersionAtom)
 | |
|     return;
 | |
| 
 | |
|   XInternAtoms(mozilla::DefaultXDisplay(), const_cast<char**>(XAtomNames),
 | |
|                ArrayLength(XAtomNames), False, XAtoms);
 | |
| 
 | |
|   int i = 0;
 | |
|   sMozVersionAtom     = XAtoms[i++];
 | |
|   sMozLockAtom        = XAtoms[i++];
 | |
|   sMozResponseAtom    = XAtoms[i++];
 | |
|   sMozUserAtom        = XAtoms[i++];
 | |
|   sMozProfileAtom     = XAtoms[i++];
 | |
|   sMozProgramAtom     = XAtoms[i++];
 | |
|   sMozCommandLineAtom = XAtoms[i];
 | |
| }
 |