1 /*
2  * Copyright © 2007 Novell, Inc.
3  *
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
13  * implied warranty.
14  *
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.
22  *
23  * Author: David Reveman <davidr@novell.com>
24  */
25 
26 #include <string.h>
27 
28 #include <compiz-core.h>
29 
30 CompCore core;
31 
32 static char *corePrivateIndices = 0;
33 static int  corePrivateLen = 0;
34 
35 static int
reallocCorePrivate(int size,void * closure)36 reallocCorePrivate (int  size,
37 		    void *closure)
38 {
39     void *privates;
40 
41     privates = realloc (core.base.privates, size * sizeof (CompPrivate));
42     if (!privates)
43 	return FALSE;
44 
45     core.base.privates = (CompPrivate *) privates;
46 
47     return TRUE;
48 }
49 
50 int
allocCoreObjectPrivateIndex(CompObject * parent)51 allocCoreObjectPrivateIndex (CompObject *parent)
52 {
53     return allocatePrivateIndex (&corePrivateLen,
54 				 &corePrivateIndices,
55 				 reallocCorePrivate,
56 				 0);
57 }
58 
59 void
freeCoreObjectPrivateIndex(CompObject * parent,int index)60 freeCoreObjectPrivateIndex (CompObject *parent,
61 			    int	       index)
62 {
63     freePrivateIndex (corePrivateLen, corePrivateIndices, index);
64 }
65 
66 CompBool
forEachCoreObject(CompObject * parent,ObjectCallBackProc proc,void * closure)67 forEachCoreObject (CompObject         *parent,
68 		   ObjectCallBackProc proc,
69 		   void		      *closure)
70 {
71     return TRUE;
72 }
73 
74 char *
nameCoreObject(CompObject * object)75 nameCoreObject (CompObject *object)
76 {
77     return NULL;
78 }
79 
80 CompObject *
findCoreObject(CompObject * parent,const char * name)81 findCoreObject (CompObject *parent,
82 		const char *name)
83 {
84     return NULL;
85 }
86 
87 int
allocateCorePrivateIndex(void)88 allocateCorePrivateIndex (void)
89 {
90     return compObjectAllocatePrivateIndex (NULL, COMP_OBJECT_TYPE_CORE);
91 }
92 
93 void
freeCorePrivateIndex(int index)94 freeCorePrivateIndex (int index)
95 {
96     compObjectFreePrivateIndex (NULL, COMP_OBJECT_TYPE_CORE, index);
97 }
98 
99 static CompBool
initCorePluginForObject(CompPlugin * p,CompObject * o)100 initCorePluginForObject (CompPlugin *p,
101 			 CompObject *o)
102 {
103     return TRUE;
104 }
105 
106 static void
finiCorePluginForObject(CompPlugin * p,CompObject * o)107 finiCorePluginForObject (CompPlugin *p,
108 			 CompObject *o)
109 {
110 }
111 
112 static CompBool
setOptionForPlugin(CompObject * object,const char * plugin,const char * name,CompOptionValue * value)113 setOptionForPlugin (CompObject      *object,
114 		    const char	    *plugin,
115 		    const char	    *name,
116 		    CompOptionValue *value)
117 {
118     CompPlugin *p;
119 
120     p = findActivePlugin (plugin);
121     if (p && p->vTable->setObjectOption)
122 	return (*p->vTable->setObjectOption) (p, object, name, value);
123 
124     return FALSE;
125 }
126 
127 static void
coreObjectAdd(CompObject * parent,CompObject * object)128 coreObjectAdd (CompObject *parent,
129 	       CompObject *object)
130 {
131     object->parent = parent;
132 }
133 
134 static void
coreObjectRemove(CompObject * parent,CompObject * object)135 coreObjectRemove (CompObject *parent,
136 		  CompObject *object)
137 {
138     object->parent = NULL;
139 }
140 
141 static void
fileWatchAdded(CompCore * core,CompFileWatch * fileWatch)142 fileWatchAdded (CompCore      *core,
143 		CompFileWatch *fileWatch)
144 {
145 }
146 
147 static void
fileWatchRemoved(CompCore * core,CompFileWatch * fileWatch)148 fileWatchRemoved (CompCore      *core,
149 		  CompFileWatch *fileWatch)
150 {
151 }
152 
153 CompBool
initCore(void)154 initCore (void)
155 {
156     CompPlugin *corePlugin;
157 
158     compObjectInit (&core.base, 0, COMP_OBJECT_TYPE_CORE);
159 
160     core.displays = NULL;
161 
162     core.tmpRegion = XCreateRegion ();
163     if (!core.tmpRegion)
164 	return FALSE;
165 
166     core.outputRegion = XCreateRegion ();
167     if (!core.outputRegion)
168     {
169 	XDestroyRegion (core.tmpRegion);
170 	return FALSE;
171     }
172 
173     core.fileWatch	     = NULL;
174     core.lastFileWatchHandle = 1;
175 
176     core.timeouts	   = NULL;
177     core.lastTimeoutHandle = 1;
178 
179     core.watchFds	   = NULL;
180     core.lastWatchFdHandle = 1;
181     core.watchPollFds	   = NULL;
182     core.nWatchFds	   = 0;
183 
184     gettimeofday (&core.lastTimeout, 0);
185 
186     core.initPluginForObject = initCorePluginForObject;
187     core.finiPluginForObject = finiCorePluginForObject;
188 
189     core.setOptionForPlugin = setOptionForPlugin;
190 
191     core.objectAdd    = coreObjectAdd;
192     core.objectRemove = coreObjectRemove;
193 
194     core.fileWatchAdded   = fileWatchAdded;
195     core.fileWatchRemoved = fileWatchRemoved;
196 
197     core.sessionEvent = sessionEvent;
198     core.logMessage   = logMessage;
199 
200     corePlugin = loadPlugin ("core");
201     if (!corePlugin)
202     {
203 	compLogMessage ("core", CompLogLevelFatal,
204 			"Couldn't load core plugin");
205 	return FALSE;
206     }
207 
208     if (!pushPlugin (corePlugin))
209     {
210 	compLogMessage ("core", CompLogLevelFatal,
211 			"Couldn't activate core plugin");
212 	return FALSE;
213     }
214 
215     return TRUE;
216 }
217 
218 void
finiCore(void)219 finiCore (void)
220 {
221     CompPlugin *p;
222 
223     while (core.displays)
224 	removeDisplay (core.displays);
225 
226     if (core.watchPollFds)
227 	free (core.watchPollFds);
228 
229     while ((p = popPlugin ()))
230 	unloadPlugin (p);
231 
232     XDestroyRegion (core.outputRegion);
233     XDestroyRegion (core.tmpRegion);
234 }
235 
236 void
addDisplayToCore(CompDisplay * d)237 addDisplayToCore (CompDisplay *d)
238 {
239     CompDisplay *prev;
240 
241     for (prev = core.displays; prev && prev->next; prev = prev->next);
242 
243     if (prev)
244 	prev->next = d;
245     else
246 	core.displays = d;
247 }
248 
249 CompFileWatchHandle
addFileWatch(const char * path,int mask,FileWatchCallBackProc callBack,void * closure)250 addFileWatch (const char	    *path,
251 	      int		    mask,
252 	      FileWatchCallBackProc callBack,
253 	      void		    *closure)
254 {
255     CompFileWatch *fileWatch;
256 
257     fileWatch = malloc (sizeof (CompFileWatch));
258     if (!fileWatch)
259 	return 0;
260 
261     fileWatch->path	= strdup (path);
262     fileWatch->mask	= mask;
263     fileWatch->callBack = callBack;
264     fileWatch->closure  = closure;
265     fileWatch->handle   = core.lastFileWatchHandle++;
266 
267     if (core.lastFileWatchHandle == MAXSHORT)
268 	core.lastFileWatchHandle = 1;
269 
270     fileWatch->next = core.fileWatch;
271     core.fileWatch = fileWatch;
272 
273     (*core.fileWatchAdded) (&core, fileWatch);
274 
275     return fileWatch->handle;
276 }
277 
278 void
removeFileWatch(CompFileWatchHandle handle)279 removeFileWatch (CompFileWatchHandle handle)
280 {
281     CompFileWatch *p = 0, *w;
282 
283     for (w = core.fileWatch; w; w = w->next)
284     {
285 	if (w->handle == handle)
286 	    break;
287 
288 	p = w;
289     }
290 
291     if (w)
292     {
293 	if (p)
294 	    p->next = w->next;
295 	else
296 	    core.fileWatch = w->next;
297 
298 	(*core.fileWatchRemoved) (&core, w);
299 
300 	if (w->path)
301 	    free (w->path);
302 
303 	free (w);
304     }
305 }
306