This file is indexed.

/usr/include/compiz/core/pluginclasshandler.h is in compiz-dev 1:0.9.13.1+18.04.20180302-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
/*
 * Copyright © 2008 Dennis Kasprzyk
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that the above copyright notice appear in all copies
 * and that both that copyright notice and this permission notice
 * appear in supporting documentation, and that the name of
 * Dennis Kasprzyk not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 * Dennis Kasprzyk makes no representations about the suitability of this
 * software for any purpose. It is provided "as is" without express or
 * implied warranty.
 *
 * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
 */

#ifndef _COMPPLUGINCLASSHANDLER_H
#define _COMPPLUGINCLASSHANDLER_H

#include <typeinfo>
#include <boost/preprocessor/cat.hpp>

#include <core/string.h>
#include <core/valueholder.h>
#include <core/pluginclasses.h>

/* Continuously increments every time a new
 * plugin class is added, guaranteed to be
 * the same as the pcIndex of the most up-to-date
 * PluginClassHandler index. Any index that
 * hold the same value this value is safe to
 * use to retreive the plugin class for a base
 * class (and as such we don't need to constantly
 * re-query ValueHolder for the index of this plugin
 * on the base class)
 */
extern unsigned int pluginClassHandlerIndex;

namespace compiz
{
namespace plugin
{
namespace internal
{
class PluginKey;
/**
 * LoadedPluginClassBridge
 *
 * This template essentially exists so that we can reduce the
 * scope of functions which are allowed to mark plugin classes
 * as instantiatable as we can't really inject the interface
 * from PluginClassHandler to do that anywhere. We also can't
 * forward declare a nested class declaration, but we can forward
 * declare PluginKey, which users should inherit from and take
 * it by reference. If the class we're depending on can only be
 * defined in one other place along with a private constructor
 * accessible only to a friend it means that we've effectively
 * limited the scope of users of this class.
 */
template <class Tp, class Tb, int ABI = 0>
class LoadedPluginClassBridge
{
    public:

	static void
	allowInstantiations (const PluginKey &);

	static void
	disallowInstantiations (const PluginKey &);
};
}
}
}

template<class Tp, class Tb, int ABI = 0>
class PluginClassHandler
{
    public:

	typedef Tp ClassPluginType;
	typedef Tb ClassPluginBaseType;

	PluginClassHandler (Tb *);
	~PluginClassHandler ();

	/**
	 * Changes this PluginClassHandler's state to "failed"
	 */ 
	void setFailed () { mFailed = true; };

	/**
	 * Checks to see if this plugin class failed to load for
	 * whatever reason, so that instantiation of the class
	 * can be aborted
	 */
	bool loadFailed () { return mFailed; };

	/**
	 * Returns the unique instance of the plugin class
	 * for this base class
	 */
	Tb * get () { return mBase; };
	static Tp * get (Tb *);
	static const Tp * get (const Tb *);

    private:
	/**
	 * Returns the unique string identifying this plugin type with it's
	 * ABI
	 */
	static CompString keyName ()
	{
	    return compPrintf ("%s_index_%lu", typeid (Tp).name (), ABI);
	}

	/**
	 * Actually initializes the index of this plugin class
	 * by allocating a new index for plugin class storage
	 * on this base class if there wasn't one already and then
	 * storing that index inside of ValueHolder
	 */
	static bool initializeIndex (Tb *base);
	static inline Tp * getInstance (Tb *base);

	static void allowInstantiations ();
	static void disallowInstantiations ();

	template <class Plugin, class Base, int PluginABI>
	friend class compiz::plugin::internal::LoadedPluginClassBridge;

    private:
	bool mFailed;
	Tb   *mBase;

	static PluginClassIndex mIndex;
	static bool             mPluginLoaded;
};

namespace compiz
{
namespace plugin
{
namespace internal
{
template <class Tp, class Tb, int ABI>
void
LoadedPluginClassBridge <Tp, Tb, ABI>::allowInstantiations (const PluginKey &)
{
    PluginClassHandler <Tp, Tb, ABI>::allowInstantiations ();
}

template <class Tp, class Tb, int ABI>
void
LoadedPluginClassBridge <Tp, Tb, ABI>::disallowInstantiations (const PluginKey &)
{
    PluginClassHandler <Tp, Tb, ABI>::disallowInstantiations ();
}
}
}
}

template<class Tp, class Tb, int ABI>
PluginClassIndex PluginClassHandler<Tp,Tb,ABI>::mIndex;

template<class Tp, class Tb, int ABI>
bool PluginClassHandler<Tp,Tb,ABI>::mPluginLoaded = false;

/**
 * Attaches a unique instance of the specified plugin class to a
 * unique instance of a specified base class
 */
template<class Tp, class Tb, int ABI>
PluginClassHandler<Tp,Tb,ABI>::PluginClassHandler (Tb *base) :
    mFailed (false),
    mBase (base)
{
    /* If allocating plugin class indices for this base has
     * already failed once don't bother to allocate more for
     * this plugin class, just instantly fail */
    if (mIndex.pcFailed)
    {
	mFailed = true;
    }
    else
    {
	/* The index for this plugin class hasn't been initiated
	 * so do that (done once per plugin) */
	if (!mIndex.initiated)
	    mFailed = !initializeIndex (base);

	/* Increase the reference count of this plugin class index
	 * for this plugin on this base object for each attached
	 * plugin class and set the index pointer */
	if (!mIndex.failed)
	{
	    mIndex.refCount++;
	    mBase->pluginClasses[mIndex.index] = static_cast<Tp *> (this);
	}
    }
}

template<class Tp, class Tb, int ABI>
bool
PluginClassHandler<Tp,Tb,ABI>::initializeIndex (Tb *base)
{
    /* Allocate a new storage space index in the array of CompPrivate's
     * specified in the base class */
    mIndex.index = base->allocPluginClassIndex ();
    if (mIndex.index != (unsigned)~0)
    {
	/* Allocation was successful, this is the most recently allocated
	 * plugin class index so it is fresh to use */
	mIndex.initiated = true;
	mIndex.failed    = false;
	mIndex.pcIndex = pluginClassHandlerIndex;

	CompPrivate p;
	p.uval = mIndex.index;

	/* Also store the index value inside of ValueHolder for this plugin-base
	 * combination so that we can fetch it later should the index location
	 * change */
	if (!ValueHolder::Default ()->hasValue (keyName ()))
	{
	    ValueHolder::Default ()->storeValue (keyName (), p);
	    pluginClassHandlerIndex++;
	}
	else
	{
	    compLogMessage ("core", CompLogLevelFatal,
		"Private index value \"%s\" already stored in screen.",
		keyName ().c_str ());
	}
	return true;
    }
    else
    {
	mIndex.index = 0;
	mIndex.failed = true;
	mIndex.initiated = false;
	mIndex.pcFailed = true;
	mIndex.pcIndex = pluginClassHandlerIndex;
	return false;
    }
}

template<class Tp, class Tb, int ABI>
PluginClassHandler<Tp,Tb,ABI>::~PluginClassHandler ()
{
    /* Only bother to destroy the static mIndex if plugin
     * class allocation was actually successful */
    if (!mIndex.pcFailed)
    {
	mIndex.refCount--;

	/* Once this index's reference count hits zero it
	 * means that there are no more plugin classes attached
	 * to the base class, so other plugins are free to use our
	 * index and we can erase our data from ValueHolder
	 * (also increment pluginClassHandlerIndex since after doing
	 *  this operation, all the other indexes with the same pcIndex
	 *  won't be fresh) */
	if (mIndex.refCount == 0)
	{
	    mBase->freePluginClassIndex (mIndex.index);
	    mIndex.initiated = false;
	    mIndex.failed = false;
	    mIndex.pcIndex = pluginClassHandlerIndex;
	    ValueHolder::Default ()->eraseValue (keyName ());
	    pluginClassHandlerIndex++;
	}
    }
}

template<class Tp, class Tb, int ABI>
Tp *
PluginClassHandler<Tp,Tb,ABI>::getInstance (Tb *base)
{
    /* Return the plugin class found at index if it exists
     * otherwise spawn a new one implicitly (objects should
     * never expect ::get () to fail, unless the plugin class
     * fails to instantiate or the underlying base object
     * does not take plugin classes of this type)
     */
    if (base->pluginClasses[mIndex.index])
	return static_cast<Tp *> (base->pluginClasses[mIndex.index]);
    else
    {
	/* mIndex.index will be implicitly set by
	 * the constructor */
	Tp *pc = new Tp (base);

	if (!pc)
	    return NULL;

	/* FIXME: If a plugin class fails to load for
	 * whatever reason, then ::get is going to return
	 * NULL, which is unsafe in cases that aren't
	 * initScreen and initWindow */
	if (pc->loadFailed ())
	{
	    delete pc;
	    return NULL;
	}

	return static_cast<Tp *> (base->pluginClasses[mIndex.index]);
    }
}

template<class Tp, class Tb, int ABI>
const Tp *
PluginClassHandler<Tp,Tb,ABI>::get (const Tb *base)
{
    return get (const_cast<Tb *> (base));
}

template<class Tp, class Tb, int ABI>
Tp *
PluginClassHandler<Tp,Tb,ABI>::get (Tb *base)
{
    /* Never instantiate an instance of this class
     * if the relevant plugin has not been loaded
     */
    if (!mPluginLoaded)
	return NULL;

    /* Always ensure that the index is initialized before
     * calls to ::get */
    if (!mIndex.initiated)
	initializeIndex (base);

    /* If pluginClassHandlerIndex == mIndex.pcIndex it means that our
     * mIndex.index is fresh and can be used directly without needing
     * to fetch it from ValueHolder */
    if (mIndex.initiated && pluginClassHandlerIndex == mIndex.pcIndex)
	return getInstance (base);

    /* If allocating or getting the updated index failed at any point
     * then just return NULL we don't know where our private data is stored */
    if (mIndex.failed && pluginClassHandlerIndex == mIndex.pcIndex)
	return NULL;

    if (ValueHolder::Default ()->hasValue (keyName ()))
    {
	mIndex.index     = ValueHolder::Default ()->getValue (keyName ()).uval;
	mIndex.initiated = true;
	mIndex.failed    = false;
	mIndex.pcIndex = pluginClassHandlerIndex;

	return getInstance (base);
    }
    else
    {
	mIndex.initiated = false;
	mIndex.failed    = true;
	mIndex.pcIndex = pluginClassHandlerIndex;
	return NULL;
    }
}

template<class Tp, class Tb, int ABI>
void
PluginClassHandler<Tp, Tb, ABI>::allowInstantiations ()
{
    mPluginLoaded = true;
}

template<class Tp, class Tb, int ABI>
void
PluginClassHandler<Tp, Tb, ABI>::disallowInstantiations ()
{
    mPluginLoaded = false;
}

#endif