1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=8:
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "mozilla/ArrayUtils.h"
10 #include "nsXRemoteServer.h"
12 #include "nsICommandLine.h"
14 #include "nsIWidget.h"
15 #include "nsAppShellCID.h"
16 #include "nsPIDOMWindow.h"
17 #include "mozilla/X11Util.h"
24 #include "nsXULAppAPI.h"
27 #include <X11/Xatom.h>
29 using namespace mozilla
;
31 #define MOZILLA_VERSION_PROP "_MOZILLA_VERSION"
32 #define MOZILLA_LOCK_PROP "_MOZILLA_LOCK"
33 #define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE"
34 #define MOZILLA_USER_PROP "_MOZILLA_USER"
35 #define MOZILLA_PROFILE_PROP "_MOZILLA_PROFILE"
36 #define MOZILLA_PROGRAM_PROP "_MOZILLA_PROGRAM"
37 #define MOZILLA_COMMANDLINE_PROP "_MOZILLA_COMMANDLINE"
39 const unsigned char kRemoteVersion
[] = "5.1";
41 // Minimize the roundtrips to the X server by getting all the atoms at once
42 static const char* XAtomNames
[] = {
43 MOZILLA_VERSION_PROP
, MOZILLA_LOCK_PROP
, MOZILLA_RESPONSE_PROP
,
44 MOZILLA_USER_PROP
, MOZILLA_PROFILE_PROP
, MOZILLA_PROGRAM_PROP
,
45 MOZILLA_COMMANDLINE_PROP
};
46 static Atom XAtoms
[std::size(XAtomNames
)];
48 Atom
nsXRemoteServer::sMozVersionAtom
;
49 Atom
nsXRemoteServer::sMozLockAtom
;
50 Atom
nsXRemoteServer::sMozResponseAtom
;
51 Atom
nsXRemoteServer::sMozUserAtom
;
52 Atom
nsXRemoteServer::sMozProfileAtom
;
53 Atom
nsXRemoteServer::sMozProgramAtom
;
54 Atom
nsXRemoteServer::sMozCommandLineAtom
;
56 nsXRemoteServer::nsXRemoteServer() = default;
58 void nsXRemoteServer::XRemoteBaseStartup(const char* aAppName
,
59 const char* aProfileName
) {
63 ToLowerCase(mAppName
);
65 mProfileName
= aProfileName
;
68 void nsXRemoteServer::HandleCommandsFor(Window aWindowId
) {
70 XChangeProperty(mozilla::DefaultXDisplay(), aWindowId
, sMozVersionAtom
,
71 XA_STRING
, 8, PropModeReplace
, kRemoteVersion
,
72 sizeof(kRemoteVersion
) - 1);
75 unsigned char* logname
;
76 logname
= (unsigned char*)PR_GetEnv("LOGNAME");
78 // set the property on the window if it's available
79 XChangeProperty(mozilla::DefaultXDisplay(), aWindowId
, sMozUserAtom
,
80 XA_STRING
, 8, PropModeReplace
, logname
,
81 strlen((char*)logname
));
84 XChangeProperty(mozilla::DefaultXDisplay(), aWindowId
, sMozProgramAtom
,
85 XA_STRING
, 8, PropModeReplace
, (unsigned char*)mAppName
.get(),
88 XChangeProperty(mozilla::DefaultXDisplay(), aWindowId
, sMozProfileAtom
,
89 XA_STRING
, 8, PropModeReplace
,
90 (unsigned char*)mProfileName
.get(), mProfileName
.Length());
93 bool nsXRemoteServer::HandleNewProperty(XID aWindowId
, Display
* aDisplay
,
94 Time aEventTime
, Atom aChangedAtom
) {
95 if (aChangedAtom
== sMozCommandLineAtom
) {
96 // We got a new command atom.
100 unsigned long len
, bytes_after
;
103 result
= XGetWindowProperty(aDisplay
, aWindowId
, aChangedAtom
,
105 (65536 / sizeof(long)), /* long_length */
106 X11True
, /* atomic delete after */
107 XA_STRING
, /* req_type */
108 &actual_type
, /* actual_type return */
109 &actual_format
, /* actual_format_return */
110 &len
, /* nitems_return */
111 &bytes_after
, /* bytes_after_return */
112 (unsigned char**)&data
); /* prop_return
116 // Failed to get property off the window or
118 if (result
!= Success
|| bytes_after
!= 0) {
122 // Failed to get the data off the window or it was the wrong type?
123 if (!data
|| !TO_LITTLE_ENDIAN32(*reinterpret_cast<int32_t*>(data
))) {
127 // cool, we got the property data.
128 const char* response
= HandleCommandLine(Span(data
, len
), aEventTime
);
130 // put the property onto the window as the response
131 XChangeProperty(aDisplay
, aWindowId
, sMozResponseAtom
, XA_STRING
, 8,
132 PropModeReplace
, (const unsigned char*)response
,
138 if (aChangedAtom
== sMozResponseAtom
) {
139 // client accepted the response. party on wayne.
143 else if (aChangedAtom
== sMozLockAtom
) {
144 // someone locked the window
151 void nsXRemoteServer::EnsureAtoms(void) {
152 if (sMozVersionAtom
) return;
154 XInternAtoms(mozilla::DefaultXDisplay(), const_cast<char**>(XAtomNames
),
155 std::size(XAtomNames
), X11False
, XAtoms
);
158 sMozVersionAtom
= XAtoms
[i
++];
159 sMozLockAtom
= XAtoms
[i
++];
160 sMozResponseAtom
= XAtoms
[i
++];
161 sMozUserAtom
= XAtoms
[i
++];
162 sMozProfileAtom
= XAtoms
[i
++];
163 sMozProgramAtom
= XAtoms
[i
++];
164 sMozCommandLineAtom
= XAtoms
[i
];