Change /opt/etc/X11/xkb to /etc/X11/xkb
[profile/ivi/xorg-x11-server.git] / composite / compinit.c
1 /*
2  * Copyright © 2006 Sun Microsystems, Inc.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Copyright © 2003 Keith Packard
24  *
25  * Permission to use, copy, modify, distribute, and sell this software and its
26  * documentation for any purpose is hereby granted without fee, provided that
27  * the above copyright notice appear in all copies and that both that
28  * copyright notice and this permission notice appear in supporting
29  * documentation, and that the name of Keith Packard not be used in
30  * advertising or publicity pertaining to distribution of the software without
31  * specific, written prior permission.  Keith Packard makes no
32  * representations about the suitability of this software for any purpose.  It
33  * is provided "as is" without express or implied warranty.
34  *
35  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
36  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
37  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
38  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
39  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
40  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
41  * PERFORMANCE OF THIS SOFTWARE.
42  */
43
44 #ifdef HAVE_DIX_CONFIG_H
45 #include <dix-config.h>
46 #endif
47
48 #include "compint.h"
49 #include "compositeext.h"
50
51 DevPrivateKeyRec CompScreenPrivateKeyRec;
52 DevPrivateKeyRec CompWindowPrivateKeyRec;
53 DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
54
55 static Bool
56 compCloseScreen (int index, ScreenPtr pScreen)
57 {
58     CompScreenPtr   cs = GetCompScreen (pScreen);
59     Bool            ret;
60
61     free(cs->alternateVisuals);
62
63     pScreen->CloseScreen = cs->CloseScreen;
64     pScreen->BlockHandler = cs->BlockHandler;
65     pScreen->InstallColormap = cs->InstallColormap;
66     pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
67     pScreen->ReparentWindow = cs->ReparentWindow;
68     pScreen->ConfigNotify = cs->ConfigNotify;
69     pScreen->MoveWindow = cs->MoveWindow;
70     pScreen->ResizeWindow = cs->ResizeWindow;
71     pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
72     
73     pScreen->ClipNotify = cs->ClipNotify;
74     pScreen->UnrealizeWindow = cs->UnrealizeWindow;
75     pScreen->RealizeWindow = cs->RealizeWindow;
76     pScreen->DestroyWindow = cs->DestroyWindow;
77     pScreen->CreateWindow = cs->CreateWindow;
78     pScreen->CopyWindow = cs->CopyWindow;
79     pScreen->PositionWindow = cs->PositionWindow;
80
81     free(cs);
82     dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL);
83     ret = (*pScreen->CloseScreen) (index, pScreen);
84
85     return ret;
86 }
87
88 static void
89 compInstallColormap (ColormapPtr pColormap)
90 {
91     VisualPtr       pVisual = pColormap->pVisual;
92     ScreenPtr       pScreen = pColormap->pScreen;
93     CompScreenPtr   cs = GetCompScreen (pScreen);
94     int             a;
95
96     for (a = 0; a < cs->numAlternateVisuals; a++)
97         if (pVisual->vid == cs->alternateVisuals[a])
98             return;
99     pScreen->InstallColormap = cs->InstallColormap;
100     (*pScreen->InstallColormap) (pColormap);
101     cs->InstallColormap = pScreen->InstallColormap;
102     pScreen->InstallColormap = compInstallColormap;
103 }
104
105 /* Fake backing store via automatic redirection */
106 static Bool
107 compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
108 {
109     ScreenPtr pScreen = pWin->drawable.pScreen;
110     CompScreenPtr cs = GetCompScreen (pScreen);
111     Bool ret;
112
113     pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
114     ret = pScreen->ChangeWindowAttributes(pWin, mask);
115
116     if (ret && (mask & CWBackingStore) &&
117             pScreen->backingStoreSupport != NotUseful) {
118         if (pWin->backingStore != NotUseful) {
119             compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
120             pWin->backStorage = (pointer) (intptr_t) 1;
121         } else {
122             compUnredirectWindow(serverClient, pWin,
123                                  CompositeRedirectAutomatic);
124             pWin->backStorage = NULL;
125         }
126     }
127
128     pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
129
130     return ret;
131 }
132
133 static void
134 compScreenUpdate (ScreenPtr pScreen)
135 {
136     CompScreenPtr   cs = GetCompScreen (pScreen);
137
138     compCheckTree (pScreen);
139     if (cs->damaged)
140     {
141         compWindowUpdate (pScreen->root);
142         cs->damaged = FALSE;
143     }
144 }
145
146 static void
147 compBlockHandler (int       i,
148                   pointer   blockData,
149                   pointer   pTimeout,
150                   pointer   pReadmask)
151 {
152     ScreenPtr       pScreen = screenInfo.screens[i];
153     CompScreenPtr   cs = GetCompScreen (pScreen);
154
155     pScreen->BlockHandler = cs->BlockHandler;
156     compScreenUpdate (pScreen);
157     (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
158     cs->BlockHandler = pScreen->BlockHandler;
159     pScreen->BlockHandler = compBlockHandler;
160 }
161
162 /*
163  * Add alternate visuals -- always expose an ARGB32 and RGB24 visual
164  */
165
166 static DepthPtr
167 compFindVisuallessDepth (ScreenPtr pScreen, int d)
168 {
169     int         i;
170
171     for (i = 0; i < pScreen->numDepths; i++)
172     {
173         DepthPtr    depth = &pScreen->allowedDepths[i];
174         if (depth->depth == d)
175         {
176             /*
177              * Make sure it doesn't have visuals already
178              */
179             if (depth->numVids)
180                 return 0;
181             /*
182              * looks fine
183              */
184             return depth;
185         }
186     }
187     /*
188      * If there isn't one, then it's gonna be hard to have 
189      * an associated visual
190      */
191     return 0;
192 }
193
194 /*
195  * Add a list of visual IDs to the list of visuals to implicitly redirect.
196  */
197 static Bool
198 compRegisterAlternateVisuals (CompScreenPtr cs, VisualID *vids, int nVisuals)
199 {
200     VisualID *p;
201
202     p = realloc(cs->alternateVisuals,
203                  sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals));
204     if(p == NULL)
205         return FALSE;
206
207     memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals);
208
209     cs->alternateVisuals = p;
210     cs->numAlternateVisuals += nVisuals;
211
212     return TRUE;
213 }
214
215 Bool CompositeRegisterAlternateVisuals (ScreenPtr pScreen, VisualID *vids,
216                                         int nVisuals)
217 {
218     CompScreenPtr cs = GetCompScreen (pScreen);
219     return compRegisterAlternateVisuals(cs, vids, nVisuals);
220 }
221
222 typedef struct _alternateVisual {
223     int         depth;
224     CARD32      format;
225 } CompAlternateVisual;
226
227 static CompAlternateVisual  altVisuals[] = {
228 #if COMP_INCLUDE_RGB24_VISUAL
229     {   24,     PICT_r8g8b8 },
230 #endif
231     {   32,     PICT_a8r8g8b8 },
232 };
233
234 static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) /
235                                               sizeof(CompAlternateVisual);
236
237 static Bool
238 compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs,
239                        CompAlternateVisual *alt)
240 {
241     VisualPtr       visual;
242     DepthPtr        depth;
243     PictFormatPtr   pPictFormat;
244     unsigned long   alphaMask;
245
246     /*
247      * The ARGB32 visual is always available.  Other alternate depth visuals
248      * are only provided if their depth is less than the root window depth.
249      * There's no deep reason for this.
250      */
251     if (alt->depth >= pScreen->rootDepth && alt->depth != 32)
252         return FALSE;
253
254     depth = compFindVisuallessDepth (pScreen, alt->depth);
255     if (!depth)
256         /* alt->depth doesn't exist or already has alternate visuals. */
257         return TRUE;
258
259     pPictFormat = PictureMatchFormat (pScreen, alt->depth, alt->format);
260     if (!pPictFormat)
261         return FALSE;
262
263     if (ResizeVisualArray(pScreen, 1, depth) == FALSE) {
264         return FALSE;
265     }
266
267     visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */
268
269     /* Initialize the visual */
270     visual->bitsPerRGBValue = 8;
271     if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) {
272         visual->class = PseudoColor;
273         visual->nplanes = PICT_FORMAT_BPP(alt->format);
274         visual->ColormapEntries = 1 << visual->nplanes;
275     } else {
276         DirectFormatRec *direct = &pPictFormat->direct;
277         visual->class = TrueColor;
278         visual->redMask   = ((unsigned long)direct->redMask) << direct->red;
279         visual->greenMask = ((unsigned long)direct->greenMask) << direct->green;
280         visual->blueMask  = ((unsigned long)direct->blueMask) << direct->blue;
281         alphaMask = ((unsigned long)direct->alphaMask) << direct->alpha;
282         visual->offsetRed   = direct->red;
283         visual->offsetGreen = direct->green;
284         visual->offsetBlue  = direct->blue;
285         /*
286          * Include A bits in this (unlike GLX which includes only RGB)
287          * This lets DIX compute suitable masks for colormap allocations
288          */
289         visual->nplanes = Ones (visual->redMask |
290                 visual->greenMask |
291                 visual->blueMask |
292                 alphaMask);
293         /* find widest component */
294         visual->ColormapEntries = (1 << max (Ones (visual->redMask),
295                     max (Ones (visual->greenMask),
296                         Ones (visual->blueMask))));
297     }
298
299     /* remember the visual ID to detect auto-update windows */
300     compRegisterAlternateVisuals(cs, &visual->vid, 1);
301
302     return TRUE;
303 }
304
305 static Bool
306 compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs)
307 {
308     int alt, ret = 0;
309
310     for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
311         ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt);
312
313     return !!ret;
314 }
315
316 Bool
317 compScreenInit (ScreenPtr pScreen)
318 {
319     CompScreenPtr   cs;
320
321     if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
322         return FALSE;
323     if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
324         return FALSE;
325     if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0))
326         return FALSE;
327
328     if (GetCompScreen (pScreen))
329         return TRUE;
330     cs = (CompScreenPtr) malloc(sizeof (CompScreenRec));
331     if (!cs)
332         return FALSE;
333
334     cs->damaged = FALSE;
335     cs->overlayWid = FakeClientID(0);
336     cs->pOverlayWin = NULL;
337     cs->pOverlayClients = NULL;
338
339     cs->numAlternateVisuals = 0;
340     cs->alternateVisuals = NULL;
341
342     if (!compAddAlternateVisuals (pScreen, cs))
343     {
344         free(cs);
345         return FALSE;
346     }
347
348     cs->PositionWindow = pScreen->PositionWindow;
349     pScreen->PositionWindow = compPositionWindow;
350
351     cs->CopyWindow = pScreen->CopyWindow;
352     pScreen->CopyWindow = compCopyWindow;
353
354     cs->CreateWindow = pScreen->CreateWindow;
355     pScreen->CreateWindow = compCreateWindow;
356
357     cs->DestroyWindow = pScreen->DestroyWindow;
358     pScreen->DestroyWindow = compDestroyWindow;
359
360     cs->RealizeWindow = pScreen->RealizeWindow;
361     pScreen->RealizeWindow = compRealizeWindow;
362
363     cs->UnrealizeWindow = pScreen->UnrealizeWindow;
364     pScreen->UnrealizeWindow = compUnrealizeWindow;
365
366     cs->ClipNotify = pScreen->ClipNotify;
367     pScreen->ClipNotify = compClipNotify;
368
369     cs->ConfigNotify = pScreen->ConfigNotify;
370     pScreen->ConfigNotify = compConfigNotify;
371
372     cs->MoveWindow = pScreen->MoveWindow;
373     pScreen->MoveWindow = compMoveWindow;
374
375     cs->ResizeWindow = pScreen->ResizeWindow;
376     pScreen->ResizeWindow = compResizeWindow;
377
378     cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
379     pScreen->ChangeBorderWidth = compChangeBorderWidth;
380
381     cs->ReparentWindow = pScreen->ReparentWindow;
382     pScreen->ReparentWindow = compReparentWindow;
383
384     cs->InstallColormap = pScreen->InstallColormap;
385     pScreen->InstallColormap = compInstallColormap;
386
387     cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
388     pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
389
390     cs->BlockHandler = pScreen->BlockHandler;
391     pScreen->BlockHandler = compBlockHandler;
392
393     cs->CloseScreen = pScreen->CloseScreen;
394     pScreen->CloseScreen = compCloseScreen;
395
396     dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs);
397
398     RegisterRealChildHeadProc(CompositeRealChildHead);
399
400     return TRUE;
401 }