1 /*
2 *
3 * Compiz title bar information extension plugin
4 *
5 * titleinfo.cpp
6 *
7 * Copyright : (C) 2009 by Danny Baumann
8 * E-mail : maniac@compiz.org
9 *
10 * Ported to Compiz 0.9 by:
11 * Copyright : (C) 2009 Sam Spilsbury
12 * E-mail : smspillaz@gmail.com
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 */
25
26 #include "titleinfo.h"
27
28
29 COMPIZ_PLUGIN_20090315 (titleinfo, TitleinfoPluginVTable);
30
31 void
32 TitleinfoWindow::updateVisibleName ()
33 {
34 CompString text, f_machine;
35 CompString root, f_title;
36
37 TITLEINFO_SCREEN (screen);
38
39 f_title = title.size () ? title : "";
40
41 if (ts->optionGetShowRoot () && owner == 0)
42 root = "ROOT: ";
43
44 if (ts->optionGetShowRemoteMachine () && remoteMachine.size ())
45 {
46 char hostname[256];
47
48 if (gethostname (hostname, 256) || strcmp (hostname, remoteMachine.c_str ()))
49 f_machine = remoteMachine;
50 }
51
52 if (f_machine.size ())
53 text = root + f_title + "(@" + f_machine + ")";
54 else if (root.size ())
55 text = root + f_title;
56
57 if (text.size ())
58 {
59 XChangeProperty (screen->dpy (), window->id (), ts->visibleNameAtom,
60 Atoms::utf8String, 8, PropModeReplace,
61 (unsigned char *) text.c_str (), text.size ());
62 text.clear ();
63 }
64 else
65 {
66 XDeleteProperty (screen->dpy (), window->id (), ts->visibleNameAtom);
67 }
68 }
69
70 void
71 TitleinfoWindow::updatePid ()
72 {
73 int pid = -1;
74 Atom type;
75 int result, format;
76 unsigned long nItems, bytesAfter;
77 unsigned char *propVal;
78
79 TITLEINFO_SCREEN (screen);
80
81 owner = -1;
82
83 result = XGetWindowProperty (screen->dpy (), window->id (), ts->wmPidAtom,
84 0L, 1L, False, XA_CARDINAL, &type,
85 &format, &nItems, &bytesAfter, &propVal);
86
87 if (result == Success && propVal)
88 {
89 if (nItems)
90 {
91 unsigned long value;
92
93 memcpy (&value, propVal, sizeof (unsigned long));
94 pid = value;
95 }
96
97 XFree (propVal);
98 }
99
100 if (pid >= 0)
101 {
102 char path[512];
103 struct stat fileStat;
104
105 snprintf (path, 512, "/proc/%d", pid);
106 if (!lstat (path, &fileStat))
107 owner = fileStat.st_uid;
108 }
109
110 if (ts->optionGetShowRoot ())
111 updateVisibleName ();
112 }
113
114 CompString
115 TitleinfoScreen::getUtf8Property (Window id,
116 Atom atom)
117 {
118 Atom type;
119 int result, format;
120 unsigned long nItems, bytesAfter;
121 char *val = NULL, *retval_c = NULL;
122 CompString retval;
123
124 result = XGetWindowProperty (screen->dpy (), id, atom, 0L, 65536, False,
125 Atoms::utf8String, &type, &format, &nItems,
126 &bytesAfter, (unsigned char **) &val);
127
128 if (result != Success)
129 return retval;
130
131 if (type == Atoms::utf8String && format == 8 && val && nItems > 0)
132 {
133 retval_c = (char *) malloc (sizeof (char) * (nItems + 1));
134 if (retval_c)
135 {
136 strncpy (retval_c, val, nItems);
137 retval_c[nItems] = 0;
138 }
139 }
140
141 if (retval_c)
142 retval = CompString (retval_c);
143
144 if (val)
145 XFree (val);
146
147 return retval;
148 }
149
150 CompString
151 TitleinfoScreen::getTextProperty (Window id,
152 Atom atom)
153 {
154 XTextProperty text;
155 char *retval_c = NULL;
156 CompString retval;
157
158 text.nitems = 0;
Condition "XGetTextProperty(screen->dpy(), id, &text, atom)", taking true branch
159 if (XGetTextProperty (screen->dpy (), id, &text, atom))
160 {
Condition "text.value", taking true branch
161 if (text.value)
162 {
CID 12499 - RESOURCE_LEAK
Storage is returned from allocation function "malloc(size_t)".
Assigning: "retval_c" = storage returned from "malloc(1UL * (text.nitems + 1UL))".
163 retval_c = (char *) malloc (sizeof (char) * (text.nitems + 1));
Condition "retval_c", taking true branch
164 if (retval_c)
165 {
CID 12499 - RESOURCE_LEAK
Resource "retval_c" is not freed or pointed-to in function "strncpy(char *, char const *, size_t)".
166 strncpy (retval_c, (char *) text.value, text.nitems);
167 retval_c[text.nitems] = 0;
168 }
169
170 XFree (text.value);
171 }
172 }
173
Condition "retval_c", taking true branch
174 if (retval_c)
CID 12499 - RESOURCE_LEAK
Resource "retval_c" is not freed or pointed-to in function "std::basic_string, std::allocator >::basic_string(char const *, std::allocator const &)".
175 retval = CompString (retval_c);
176
CID 12499 - RESOURCE_LEAK
Variable "retval_c" going out of scope leaks the storage it points to.
177 return retval;
178 }
179
180 void
181 TitleinfoWindow::updateTitle ()
182 {
183 CompString f_title;
184
185 TITLEINFO_SCREEN (screen);
186
187 f_title = ts->getUtf8Property (window->id (), Atoms::wmName);
188
189 if (f_title.empty ())
190 title = ts->getTextProperty (window->id (), XA_WM_NAME);\
191
192 title = f_title;
193 updateVisibleName ();
194 }
195
196
197 void
198 TitleinfoWindow::updateMachine ()
199 {
200 TITLEINFO_SCREEN (screen);
201
202 if (remoteMachine.size ())
203 remoteMachine.clear ();
204
205 remoteMachine = ts->getTextProperty (window->id (),
206 XA_WM_CLIENT_MACHINE);
207
208 if (ts->optionGetShowRemoteMachine ())
209 updateVisibleName ();
210 }
211
212 void
213 TitleinfoScreen::addSupportedAtoms (std::vector<Atom> &atoms)
214 {
215 screen->addSupportedAtoms (atoms);
216
217 atoms.push_back (visibleNameAtom);
218 atoms.push_back (wmPidAtom);
219 }
220
221 void
222 TitleinfoScreen::handleEvent (XEvent *event)
223 {
224
225 screen->handleEvent (event);
226
227 if (event->type == PropertyNotify)
228 {
229 CompWindow *w;
230
231 if (event->xproperty.atom == XA_WM_CLIENT_MACHINE)
232 {
233 w = screen->findWindow (event->xproperty.window);
234 if (w)
235 {
236 TITLEINFO_WINDOW (w);
237 tw->updateMachine ();
238 }
239 }
240 else if (event->xproperty.atom == wmPidAtom)
241 {
242 w = screen->findWindow (event->xproperty.window);
243 if (w)
244 {
245 TITLEINFO_WINDOW (w);
246 tw->updatePid ();
247 }
248 }
249 else if (event->xproperty.atom == Atoms::wmName ||
250 event->xproperty.atom == XA_WM_NAME)
251 {
252 w = screen->findWindow (event->xproperty.window);
253 if (w)
254 {
255 TITLEINFO_WINDOW (w);
256 tw->updateTitle ();
257 }
258 }
259 }
260 }
261
262 TitleinfoScreen::TitleinfoScreen (CompScreen *screen) :
263 PluginClassHandler <TitleinfoScreen, CompScreen> (screen),
264 visibleNameAtom (XInternAtom (screen->dpy (), "_NET_WM_VISIBLE_NAME", 0)),
265 wmPidAtom (XInternAtom (screen->dpy (), "_NET_WM_PID", 0))
266 {
267 ScreenInterface::setHandler (screen);
268
269 screen->updateSupportedWmHints ();
270 };
271
272 TitleinfoScreen::~TitleinfoScreen ()
273 {
274 screen->addSupportedAtomsSetEnabled (this, false);
275
276 screen->updateSupportedWmHints ();
277 }
278
279 TitleinfoWindow::TitleinfoWindow (CompWindow *window) :
280 PluginClassHandler <TitleinfoWindow, CompWindow> (window),
281 window (window),
282 owner (-1)
283 {
284 updateTitle ();
285 updateMachine ();
286 updatePid ();
287 updateVisibleName ();
288 }
289
290 bool
291 TitleinfoPluginVTable::init ()
292 {
293 if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
294 return false;
295
296 return true;
297 };