3
* Copyright © 2000 SuSE, Inc.
5
* Permission to use, copy, modify, distribute, and sell this software and its
6
* documentation for any purpose is hereby granted without fee, provided that
7
* the above copyright notice appear in all copies and that both that
8
* copyright notice and this permission notice appear in supporting
9
* documentation, and that the name of SuSE not be used in advertising or
10
* publicity pertaining to distribution of the software without specific,
11
* written prior permission. SuSE makes no representations about the
12
* suitability of this software for any purpose. It is provided "as is"
13
* without express or implied warranty.
15
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
* Author: Keith Packard, SuSE, Inc.
25
#ifdef HAVE_DIX_CONFIG_H
26
#include <dix-config.h>
32
#include "fboverlay.h"
35
static DevPrivateKeyRec fbOverlayScreenPrivateKeyRec;
37
#define fbOverlayScreenPrivateKey (&fbOverlayScreenPrivateKeyRec)
40
fbOverlayGetScreenPrivateKey(void)
42
return fbOverlayScreenPrivateKey;
46
* Replace this if you want something supporting
47
* multiple overlays with the same depth
50
fbOverlayCreateWindow(WindowPtr pWin)
52
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
56
if (pWin->drawable.class != InputOutput)
59
if (pWin->drawable.bitsPerPixel == 32)
60
pWin->drawable.bitsPerPixel =
61
fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
63
for (i = 0; i < pScrPriv->nlayers; i++) {
64
pPixmap = pScrPriv->layer[i].u.run.pixmap;
65
if (pWin->drawable.depth == pPixmap->drawable.depth) {
66
dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin), pPixmap);
68
* Make sure layer keys are written correctly by
69
* having non-root layers set to full while the
70
* root layer is set to empty. This will cause
71
* all of the layers to get painted when the root
75
RegionEmpty(&pScrPriv->layer[i].u.run.region);
84
fbOverlayCloseScreen(ScreenPtr pScreen)
86
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
89
for (i = 0; i < pScrPriv->nlayers; i++) {
90
(*pScreen->DestroyPixmap) (pScrPriv->layer[i].u.run.pixmap);
91
RegionUninit(&pScrPriv->layer[i].u.run.region);
97
* Return layer containing this window
100
fbOverlayWindowLayer(WindowPtr pWin)
102
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
105
for (i = 0; i < pScrPriv->nlayers; i++)
106
if (dixLookupPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin)) ==
107
(void *) pScrPriv->layer[i].u.run.pixmap)
113
fbOverlayCreateScreenResources(ScreenPtr pScreen)
116
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
123
if (!miCreateScreenResources(pScreen))
128
box.x2 = pScreen->width;
129
box.y2 = pScreen->height;
130
for (i = 0; i < pScrPriv->nlayers; i++) {
131
pbits = pScrPriv->layer[i].u.init.pbits;
132
width = pScrPriv->layer[i].u.init.width;
133
depth = pScrPriv->layer[i].u.init.depth;
134
pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, 0);
137
if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
138
pScreen->height, depth,
140
PixmapBytePad(width, depth),
143
pScrPriv->layer[i].u.run.pixmap = pPixmap;
144
RegionInit(&pScrPriv->layer[i].u.run.region, &box, 0);
146
pScreen->devPrivate = pScrPriv->layer[0].u.run.pixmap;
151
fbOverlayPaintKey(DrawablePtr pDrawable,
152
RegionPtr pRegion, CARD32 pixel, int layer)
154
fbFillRegionSolid(pDrawable, pRegion, 0,
155
fbReplicatePixel(pixel, pDrawable->bitsPerPixel));
159
* Track visible region for each layer
162
fbOverlayUpdateLayerRegion(ScreenPtr pScreen, int layer, RegionPtr prgn)
164
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
168
if (!prgn || !RegionNotEmpty(prgn))
170
for (i = 0; i < pScrPriv->nlayers; i++) {
172
/* add new piece to this fb */
173
RegionUnion(&pScrPriv->layer[i].u.run.region,
174
&pScrPriv->layer[i].u.run.region, prgn);
176
else if (RegionNotEmpty(&pScrPriv->layer[i].u.run.region)) {
177
/* paint new piece with chroma key */
179
RegionIntersect(&rgnNew, prgn, &pScrPriv->layer[i].u.run.region);
180
(*pScrPriv->PaintKey) (&pScrPriv->layer[i].u.run.pixmap->drawable,
181
&rgnNew, pScrPriv->layer[i].key, i);
182
RegionUninit(&rgnNew);
183
/* remove piece from other fbs */
184
RegionSubtract(&pScrPriv->layer[i].u.run.region,
185
&pScrPriv->layer[i].u.run.region, prgn);
191
* Copy only areas in each layer containing real bits
194
fbOverlayCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
196
ScreenPtr pScreen = pWin->drawable.pScreen;
197
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
201
RegionRec layerRgn[FB_OVERLAY_MAX];
204
dx = ptOldOrg.x - pWin->drawable.x;
205
dy = ptOldOrg.y - pWin->drawable.y;
208
* Clip to existing bits
210
RegionTranslate(prgnSrc, -dx, -dy);
212
RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
213
RegionTranslate(&rgnDst, dx, dy);
215
* Compute the portion of each fb affected by this copy
217
for (i = 0; i < pScrPriv->nlayers; i++) {
218
RegionNull(&layerRgn[i]);
219
RegionIntersect(&layerRgn[i], &rgnDst,
220
&pScrPriv->layer[i].u.run.region);
221
if (RegionNotEmpty(&layerRgn[i])) {
222
RegionTranslate(&layerRgn[i], -dx, -dy);
223
pPixmap = pScrPriv->layer[i].u.run.pixmap;
224
miCopyRegion(&pPixmap->drawable, &pPixmap->drawable,
226
&layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0,
233
for (i = 0; i < pScrPriv->nlayers; i++) {
234
if (RegionNotEmpty(&layerRgn[i]))
235
fbOverlayUpdateLayerRegion(pScreen, i, &layerRgn[i]);
237
RegionUninit(&layerRgn[i]);
239
RegionUninit(&rgnDst);
243
fbOverlayWindowExposures(WindowPtr pWin,
244
RegionPtr prgn, RegionPtr other_exposed)
246
fbOverlayUpdateLayerRegion(pWin->drawable.pScreen,
247
fbOverlayWindowLayer(pWin), prgn);
248
miWindowExposures(pWin, prgn, other_exposed);
252
fbOverlaySetupScreen(ScreenPtr pScreen,
258
int dpiy, int width1, int width2, int bpp1, int bpp2)
260
return fbSetupScreen(pScreen,
261
pbits1, xsize, ysize, dpix, dpiy, width1, bpp1);
265
fb24_32OverlayCreateScreenResources(ScreenPtr pScreen)
267
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
272
if ((retval = fbOverlayCreateScreenResources(pScreen))) {
273
for (i = 0; i < pScrPriv->nlayers; i++) {
274
/* fix the screen pixmap */
275
PixmapPtr pPix = (PixmapPtr) pScrPriv->layer[i].u.run.pixmap;
277
if (pPix->drawable.bitsPerPixel == 32) {
278
pPix->drawable.bitsPerPixel = 24;
279
pitch = BitmapBytePad(pPix->drawable.width * 24);
280
pPix->devKind = pitch;
289
fbOverlayFinishScreenInit(ScreenPtr pScreen,
298
int bpp1, int bpp2, int depth1, int depth2)
304
int bpp = 0, imagebpp = 32;
305
VisualID defaultVisual;
306
FbOverlayScrPrivPtr pScrPriv;
308
if (!dixRegisterPrivateKey
309
(&fbOverlayScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
312
pScrPriv = malloc(sizeof(FbOverlayScrPrivRec));
316
if (bpp1 == 32 || bpp2 == 32)
318
else if (bpp1 == 24 || bpp2 == 24)
326
* Check to see if we're advertising a 24bpp image format,
327
* in which case windows will use it in preference to a 32 bit
330
for (f = 0; f < screenInfo.numPixmapFormats; f++) {
331
if (screenInfo.formats[f].bitsPerPixel == 24) {
337
if (imagebpp == 32) {
338
fbGetScreenPrivate(pScreen)->win32bpp = bpp;
339
fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
342
fbGetScreenPrivate(pScreen)->win32bpp = 32;
343
fbGetScreenPrivate(pScreen)->pix32bpp = 32;
346
if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &depth1,
347
&defaultVisual, ((unsigned long) 1 << (bpp1 - 1)) |
348
((unsigned long) 1 << (bpp2 - 1)), 8)) {
352
if (!miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0,
353
depth1, ndepths, depths,
354
defaultVisual, nvisuals, visuals)) {
358
/* MI thinks there's no frame buffer */
360
ShmRegisterFbFuncs(pScreen);
362
pScreen->minInstalledCmaps = 1;
363
pScreen->maxInstalledCmaps = 2;
365
pScrPriv->nlayers = 2;
366
pScrPriv->PaintKey = fbOverlayPaintKey;
367
pScrPriv->CopyWindow = fbCopyWindowProc;
368
pScrPriv->layer[0].u.init.pbits = pbits1;
369
pScrPriv->layer[0].u.init.width = width1;
370
pScrPriv->layer[0].u.init.depth = depth1;
372
pScrPriv->layer[1].u.init.pbits = pbits2;
373
pScrPriv->layer[1].u.init.width = width2;
374
pScrPriv->layer[1].u.init.depth = depth2;
375
dixSetPrivate(&pScreen->devPrivates, fbOverlayScreenPrivateKey, pScrPriv);
377
/* overwrite miCloseScreen with our own */
378
pScreen->CloseScreen = fbOverlayCloseScreen;
379
pScreen->CreateScreenResources = fbOverlayCreateScreenResources;
380
pScreen->CreateWindow = fbOverlayCreateWindow;
381
pScreen->WindowExposures = fbOverlayWindowExposures;
382
pScreen->CopyWindow = fbOverlayCopyWindow;
383
if (bpp == 24 && imagebpp == 32) {
384
pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
385
pScreen->CreateScreenResources = fb24_32OverlayCreateScreenResources;