/src/mozilla-central/toolkit/components/remote/nsXRemoteService.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim:expandtab:shiftwidth=2:tabstop=8: |
3 | | */ |
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/. */ |
7 | | |
8 | | #include "mozilla/ArrayUtils.h" |
9 | | |
10 | | #include "nsXRemoteService.h" |
11 | | #include "nsRemoteService.h" |
12 | | #include "nsIObserverService.h" |
13 | | #include "nsCOMPtr.h" |
14 | | #include "nsIServiceManager.h" |
15 | | #include "nsICommandLineRunner.h" |
16 | | #include "nsICommandLine.h" |
17 | | |
18 | | #include "nsIBaseWindow.h" |
19 | | #include "nsIDocShell.h" |
20 | | #include "nsIFile.h" |
21 | | #include "nsIServiceManager.h" |
22 | | #include "nsIWeakReference.h" |
23 | | #include "nsIWidget.h" |
24 | | #include "nsIAppShellService.h" |
25 | | #include "nsAppShellCID.h" |
26 | | #include "nsPIDOMWindow.h" |
27 | | #include "mozilla/X11Util.h" |
28 | | |
29 | | #include "nsCOMPtr.h" |
30 | | #include "nsString.h" |
31 | | #include "prenv.h" |
32 | | #include "nsCRT.h" |
33 | | |
34 | | #include "nsXULAppAPI.h" |
35 | | |
36 | | #include <X11/Xlib.h> |
37 | | #include <X11/Xatom.h> |
38 | | |
39 | | using namespace mozilla; |
40 | | |
41 | | #define MOZILLA_VERSION_PROP "_MOZILLA_VERSION" |
42 | | #define MOZILLA_LOCK_PROP "_MOZILLA_LOCK" |
43 | | #define MOZILLA_RESPONSE_PROP "_MOZILLA_RESPONSE" |
44 | | #define MOZILLA_USER_PROP "_MOZILLA_USER" |
45 | | #define MOZILLA_PROFILE_PROP "_MOZILLA_PROFILE" |
46 | | #define MOZILLA_PROGRAM_PROP "_MOZILLA_PROGRAM" |
47 | | #define MOZILLA_COMMANDLINE_PROP "_MOZILLA_COMMANDLINE" |
48 | | |
49 | | const unsigned char kRemoteVersion[] = "5.1"; |
50 | | |
51 | | // Minimize the roundtrips to the X server by getting all the atoms at once |
52 | | static const char *XAtomNames[] = { |
53 | | MOZILLA_VERSION_PROP, |
54 | | MOZILLA_LOCK_PROP, |
55 | | MOZILLA_RESPONSE_PROP, |
56 | | MOZILLA_USER_PROP, |
57 | | MOZILLA_PROFILE_PROP, |
58 | | MOZILLA_PROGRAM_PROP, |
59 | | MOZILLA_COMMANDLINE_PROP |
60 | | }; |
61 | | static Atom XAtoms[MOZ_ARRAY_LENGTH(XAtomNames)]; |
62 | | |
63 | | Atom nsXRemoteService::sMozVersionAtom; |
64 | | Atom nsXRemoteService::sMozLockAtom; |
65 | | Atom nsXRemoteService::sMozResponseAtom; |
66 | | Atom nsXRemoteService::sMozUserAtom; |
67 | | Atom nsXRemoteService::sMozProfileAtom; |
68 | | Atom nsXRemoteService::sMozProgramAtom; |
69 | | Atom nsXRemoteService::sMozCommandLineAtom; |
70 | | |
71 | 0 | nsXRemoteService::nsXRemoteService() = default; |
72 | | |
73 | | void |
74 | | nsXRemoteService::XRemoteBaseStartup(const char *aAppName, const char *aProfileName) |
75 | 0 | { |
76 | 0 | EnsureAtoms(); |
77 | 0 |
|
78 | 0 | mAppName = aAppName; |
79 | 0 | ToLowerCase(mAppName); |
80 | 0 |
|
81 | 0 | mProfileName = aProfileName; |
82 | 0 | } |
83 | | |
84 | | void |
85 | | nsXRemoteService::HandleCommandsFor(Window aWindowId) |
86 | 0 | { |
87 | 0 | // set our version |
88 | 0 | XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozVersionAtom, XA_STRING, |
89 | 0 | 8, PropModeReplace, kRemoteVersion, sizeof(kRemoteVersion) - 1); |
90 | 0 |
|
91 | 0 | // get our username |
92 | 0 | unsigned char *logname; |
93 | 0 | logname = (unsigned char*) PR_GetEnv("LOGNAME"); |
94 | 0 | if (logname) { |
95 | 0 | // set the property on the window if it's available |
96 | 0 | XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozUserAtom, XA_STRING, |
97 | 0 | 8, PropModeReplace, logname, strlen((char*) logname)); |
98 | 0 | } |
99 | 0 |
|
100 | 0 | XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozProgramAtom, XA_STRING, |
101 | 0 | 8, PropModeReplace, (unsigned char*) mAppName.get(), mAppName.Length()); |
102 | 0 |
|
103 | 0 | if (!mProfileName.IsEmpty()) { |
104 | 0 | XChangeProperty(mozilla::DefaultXDisplay(), |
105 | 0 | aWindowId, sMozProfileAtom, XA_STRING, |
106 | 0 | 8, PropModeReplace, |
107 | 0 | (unsigned char*) mProfileName.get(), mProfileName.Length()); |
108 | 0 | } |
109 | 0 |
|
110 | 0 | } |
111 | | |
112 | | bool |
113 | | nsXRemoteService::HandleNewProperty(XID aWindowId, Display* aDisplay, |
114 | | Time aEventTime, |
115 | | Atom aChangedAtom, |
116 | | nsIWeakReference* aDomWindow) |
117 | 0 | { |
118 | 0 |
|
119 | 0 | nsCOMPtr<nsIDOMWindow> window (do_QueryReferent(aDomWindow)); |
120 | 0 |
|
121 | 0 | if (aChangedAtom == sMozCommandLineAtom) { |
122 | 0 | // We got a new command atom. |
123 | 0 | int result; |
124 | 0 | Atom actual_type; |
125 | 0 | int actual_format; |
126 | 0 | unsigned long nitems, bytes_after; |
127 | 0 | char *data = 0; |
128 | 0 |
|
129 | 0 | result = XGetWindowProperty (aDisplay, |
130 | 0 | aWindowId, |
131 | 0 | aChangedAtom, |
132 | 0 | 0, /* long_offset */ |
133 | 0 | (65536 / sizeof (long)), /* long_length */ |
134 | 0 | True, /* atomic delete after */ |
135 | 0 | XA_STRING, /* req_type */ |
136 | 0 | &actual_type, /* actual_type return */ |
137 | 0 | &actual_format, /* actual_format_return */ |
138 | 0 | &nitems, /* nitems_return */ |
139 | 0 | &bytes_after, /* bytes_after_return */ |
140 | 0 | (unsigned char **)&data); /* prop_return |
141 | 0 | (we only care |
142 | 0 | about the first ) */ |
143 | 0 |
|
144 | 0 | // Failed to get property off the window? |
145 | 0 | if (result != Success) |
146 | 0 | return false; |
147 | 0 | |
148 | 0 | // Failed to get the data off the window or it was the wrong type? |
149 | 0 | if (!data || !TO_LITTLE_ENDIAN32(*reinterpret_cast<int32_t*>(data))) |
150 | 0 | return false; |
151 | 0 | |
152 | 0 | // cool, we got the property data. |
153 | 0 | const char *response = |
154 | 0 | nsRemoteService::HandleCommandLine(data, window, aEventTime); |
155 | 0 |
|
156 | 0 | // put the property onto the window as the response |
157 | 0 | XChangeProperty (aDisplay, aWindowId, |
158 | 0 | sMozResponseAtom, XA_STRING, |
159 | 0 | 8, PropModeReplace, |
160 | 0 | (const unsigned char *)response, |
161 | 0 | strlen (response)); |
162 | 0 | XFree(data); |
163 | 0 | return true; |
164 | 0 | } |
165 | 0 | |
166 | 0 | if (aChangedAtom == sMozResponseAtom) { |
167 | 0 | // client accepted the response. party on wayne. |
168 | 0 | return true; |
169 | 0 | } |
170 | 0 | |
171 | 0 | else if (aChangedAtom == sMozLockAtom) { |
172 | 0 | // someone locked the window |
173 | 0 | return true; |
174 | 0 | } |
175 | 0 | |
176 | 0 | return false; |
177 | 0 | } |
178 | | |
179 | | void |
180 | | nsXRemoteService::EnsureAtoms(void) |
181 | 0 | { |
182 | 0 | if (sMozVersionAtom) |
183 | 0 | return; |
184 | 0 | |
185 | 0 | XInternAtoms(mozilla::DefaultXDisplay(), const_cast<char**>(XAtomNames), |
186 | 0 | ArrayLength(XAtomNames), False, XAtoms); |
187 | 0 |
|
188 | 0 | int i = 0; |
189 | 0 | sMozVersionAtom = XAtoms[i++]; |
190 | 0 | sMozLockAtom = XAtoms[i++]; |
191 | 0 | sMozResponseAtom = XAtoms[i++]; |
192 | 0 | sMozUserAtom = XAtoms[i++]; |
193 | 0 | sMozProfileAtom = XAtoms[i++]; |
194 | 0 | sMozProgramAtom = XAtoms[i++]; |
195 | 0 | sMozCommandLineAtom = XAtoms[i]; |
196 | 0 | } |