2
* Copyright © 2007 Novell, Inc.
4
* Permission to use, copy, modify, distribute, and sell this software
5
* and its documentation for any purpose is hereby granted without
6
* fee, provided that the above copyright notice appear in all copies
7
* and that both that copyright notice and this permission notice
8
* appear in supporting documentation, and that the name of
9
* Novell, Inc. not be used in advertising or publicity pertaining to
10
* distribution of the software without specific, written prior permission.
11
* Novell, Inc. makes no representations about the suitability of this
12
* software for any purpose. It is provided "as is" without express or
15
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
* Author: David Reveman <davidr@novell.com>
26
#include "regexplugin.h"
29
COMPIZ_PLUGIN_20081216 (regex, RegexPluginVTable);
31
class RegexExp : public CompMatch::Expression
41
RegexExp (const CompString& str, int item);
44
bool evaluate (CompWindow *w);
45
static int matches (const CompString& str);
55
static const Prefix prefix[];
61
const RegexExp::Prefix RegexExp::prefix[] = {
62
{ "title=", 6, TypeTitle, 0 },
63
{ "role=", 5, TypeRole, 0 },
64
{ "class=", 6, TypeClass, 0 },
65
{ "name=", 5, TypeName, 0 },
66
{ "ititle=", 7, TypeTitle, REG_ICASE },
67
{ "irole=", 6, TypeRole, REG_ICASE },
68
{ "iclass=", 7, TypeClass, REG_ICASE },
69
{ "iname=", 6, TypeName, REG_ICASE }
72
RegexExp::RegexExp (const CompString& str, int item) :
75
if (item < sizeof (prefix) / sizeof (prefix[0]))
80
value = str.substr (prefix[item].length);
82
status = regcomp (mRegex, value.c_str (),
83
REG_NOSUB | prefix[item].flags);
89
regerror (status, mRegex, errMsg, sizeof (errMsg));
91
compLogMessage ("regex", CompLogLevelWarn,
92
"%s = %s", errMsg, value.c_str ());
99
mType = prefix[item].type;
103
RegexExp::~RegexExp ()
113
RegexExp::evaluate (CompWindow *w)
115
CompString *string = NULL;
116
RegexWindow *rw = RegexWindow::get (w);
127
string = &rw->resClass;
130
string = &rw->resName;
134
if (!mRegex || !string)
137
if (regexec (mRegex, string->c_str (), 0, NULL, 0))
144
RegexExp::matches (const CompString& str)
148
for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
149
if (str.compare (0, prefix[i].length, prefix[i].name) == 0)
155
CompMatch::Expression *
156
RegexScreen::matchInitExp (const CompString& str)
158
int item = RegexExp::matches (str);
161
return new RegexExp (str, item);
163
return screen->matchInitExp (str);
167
RegexWindow::getStringProperty (Atom nameAtom,
172
unsigned long nItems;
173
unsigned long bytesAfter;
174
unsigned char *str = NULL;
178
result = XGetWindowProperty (screen->dpy (), window->id (), nameAtom, 0,
179
LONG_MAX, FALSE, typeAtom, &type, &format,
180
&nItems, &bytesAfter, (unsigned char **) &str);
182
if (result != Success)
185
if (type != typeAtom)
191
string = (char *) str;
199
RegexWindow::updateRole ()
201
RegexScreen *rs = RegexScreen::get (screen);
204
getStringProperty (rs->roleAtom, XA_STRING, role);
208
RegexWindow::updateTitle ()
210
RegexScreen *rs = RegexScreen::get (screen);
214
if (getStringProperty (rs->visibleNameAtom, Atoms::utf8String, title))
217
if (getStringProperty (Atoms::wmName, Atoms::utf8String, title))
220
getStringProperty (XA_WM_NAME, XA_STRING, title);
223
void RegexWindow::updateClass ()
225
XClassHint classHint;
230
if (!XGetClassHint (screen->dpy (), window->id (), &classHint) != Success)
233
if (classHint.res_name)
235
resName = classHint.res_name;
236
XFree (classHint.res_name);
239
if (classHint.res_class)
241
resClass = classHint.res_class;
242
XFree (classHint.res_class);
247
RegexScreen::handleEvent (XEvent *event)
251
screen->handleEvent (event);
253
if (event->type != PropertyNotify)
256
w = screen->findWindow (event->xproperty.window);
260
if (event->xproperty.atom == XA_WM_NAME)
262
RegexWindow::get (w)->updateTitle ();
263
screen->matchPropertyChanged (w);
265
else if (event->xproperty.atom == roleAtom)
267
RegexWindow::get (w)->updateRole ();
268
screen->matchPropertyChanged (w);
270
else if (event->xproperty.atom == XA_WM_CLASS)
272
RegexWindow::get (w)->updateClass ();
273
screen->matchPropertyChanged (w);
277
RegexScreen::RegexScreen (CompScreen *s) :
278
PrivateHandler<RegexScreen, CompScreen> (s)
280
ScreenInterface::setHandler (s);
282
roleAtom = XInternAtom (s->dpy (), "WM_WINDOW_ROLE", 0);
283
visibleNameAtom = XInternAtom (s->dpy (), "_NET_WM_VISIBLE_NAME", 0);
285
s->matchExpHandlerChanged ();
288
RegexScreen::~RegexScreen ()
290
screen->matchInitExpSetEnabled (this, false);
291
screen->matchExpHandlerChanged ();
294
RegexWindow::RegexWindow (CompWindow *w) :
295
PrivateHandler<RegexWindow, CompWindow> (w),
304
RegexPluginVTable::init ()
306
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
309
getMetadata ()->addFromFile (name ());