Imported Upstream version 1.11.4
[ubuntu-omap:xserver.git] / fb / fbwindow.c
1 /*
2  * Copyright © 1998 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Keith Packard not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Keith Packard makes no
11  * representations about the suitability of this software for any purpose.  It
12  * is provided "as is" without express or implied warranty.
13  *
14  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #ifdef HAVE_DIX_CONFIG_H
24 #include <dix-config.h>
25 #endif
26
27 #include <stdlib.h>
28
29 #include "fb.h"
30
31 Bool
32 fbCreateWindow(WindowPtr pWin)
33 {
34     dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(),
35                   fbGetScreenPixmap(pWin->drawable.pScreen));
36     if (pWin->drawable.bitsPerPixel == 32)
37         pWin->drawable.bitsPerPixel = fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
38     return TRUE;
39 }
40
41 Bool
42 fbDestroyWindow(WindowPtr pWin)
43 {
44     return TRUE;
45 }
46
47 Bool
48 fbMapWindow(WindowPtr pWindow)
49 {
50     return TRUE;
51 }
52
53 Bool
54 fbPositionWindow(WindowPtr pWin, int x, int y)
55 {
56     return TRUE;
57 }
58
59 Bool
60 fbUnmapWindow(WindowPtr pWindow)
61 {
62     return TRUE;
63 }
64
65 void
66 fbCopyWindowProc (DrawablePtr   pSrcDrawable,
67                   DrawablePtr   pDstDrawable,
68                   GCPtr         pGC,
69                   BoxPtr        pbox,
70                   int           nbox,
71                   int           dx,
72                   int           dy,
73                   Bool          reverse,
74                   Bool          upsidedown,
75                   Pixel         bitplane,
76                   void          *closure)
77 {
78     FbBits      *src;
79     FbStride    srcStride;
80     int         srcBpp;
81     int         srcXoff, srcYoff;
82     FbBits      *dst;
83     FbStride    dstStride;
84     int         dstBpp;
85     int         dstXoff, dstYoff;
86     
87     fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
88     fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
89     
90     while (nbox--)
91     {
92         fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
93                srcStride,
94                (pbox->x1 + dx + srcXoff) * srcBpp,
95     
96                dst + (pbox->y1 + dstYoff) * dstStride,
97                dstStride,
98                (pbox->x1 + dstXoff) * dstBpp,
99     
100                (pbox->x2 - pbox->x1) * dstBpp,
101                (pbox->y2 - pbox->y1),
102     
103                GXcopy,
104                FB_ALLONES,
105                dstBpp,
106     
107                reverse,
108                upsidedown);
109         pbox++;
110     }
111
112     fbFinishAccess (pDstDrawable);
113     fbFinishAccess (pSrcDrawable);
114 }
115
116 void
117 fbCopyWindow(WindowPtr      pWin, 
118              DDXPointRec    ptOldOrg, 
119              RegionPtr      prgnSrc)
120 {
121     RegionRec   rgnDst;
122     int         dx, dy;
123
124     PixmapPtr   pPixmap = fbGetWindowPixmap (pWin);
125     DrawablePtr pDrawable = &pPixmap->drawable;
126
127     dx = ptOldOrg.x - pWin->drawable.x;
128     dy = ptOldOrg.y - pWin->drawable.y;
129     RegionTranslate(prgnSrc, -dx, -dy);
130
131     RegionNull(&rgnDst);
132     
133     RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
134
135 #ifdef COMPOSITE
136     if (pPixmap->screen_x || pPixmap->screen_y)
137         RegionTranslate(&rgnDst,
138                           -pPixmap->screen_x, -pPixmap->screen_y);
139 #endif
140
141     miCopyRegion (pDrawable, pDrawable,
142                   0,
143                   &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
144     
145     RegionUninit(&rgnDst);
146     fbValidateDrawable (&pWin->drawable);
147 }
148
149 static void
150 fbFixupWindowPixmap(DrawablePtr pDrawable, PixmapPtr *ppPixmap)
151 {
152     PixmapPtr pPixmap = *ppPixmap;
153
154     if (pPixmap->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
155     {
156         pPixmap = fb24_32ReformatTile (pPixmap, pDrawable->bitsPerPixel);
157         if (!pPixmap)
158             return;
159         (*pDrawable->pScreen->DestroyPixmap) (*ppPixmap);
160         *ppPixmap = pPixmap;
161     }
162     if (FbEvenTile (pPixmap->drawable.width *
163                     pPixmap->drawable.bitsPerPixel))
164         fbPadPixmap (pPixmap);
165 }
166
167 Bool
168 fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
169 {
170     if (mask & CWBackPixmap)
171     {
172         if (pWin->backgroundState == BackgroundPixmap)
173             fbFixupWindowPixmap(&pWin->drawable, &pWin->background.pixmap);
174     }
175     if (mask & CWBorderPixmap)
176     {
177         if (pWin->borderIsPixel == FALSE)
178             fbFixupWindowPixmap(&pWin->drawable, &pWin->border.pixmap);
179     }
180     return TRUE;
181 }
182
183 void
184 fbFillRegionSolid (DrawablePtr  pDrawable,
185                    RegionPtr    pRegion,
186                    FbBits       and,
187                    FbBits       xor)
188 {
189     FbBits      *dst;
190     FbStride    dstStride;
191     int         dstBpp;
192     int         dstXoff, dstYoff;
193     int         n = RegionNumRects(pRegion);
194     BoxPtr      pbox = RegionRects(pRegion);
195
196 #ifndef FB_ACCESS_WRAPPER
197     int try_mmx = 0;
198     if (!and)
199         try_mmx = 1;
200 #endif
201
202     fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
203     
204     while (n--)
205     {
206 #ifndef FB_ACCESS_WRAPPER
207         if (!try_mmx || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
208                                       pbox->x1 + dstXoff, pbox->y1 + dstYoff,
209                                       (pbox->x2 - pbox->x1),
210                                       (pbox->y2 - pbox->y1),
211                                       xor))
212         {
213 #endif
214             fbSolid (dst + (pbox->y1 + dstYoff) * dstStride,
215                      dstStride,
216                      (pbox->x1 + dstXoff) * dstBpp,
217                      dstBpp,
218                      (pbox->x2 - pbox->x1) * dstBpp,
219                      pbox->y2 - pbox->y1,
220                      and, xor);
221 #ifndef FB_ACCESS_WRAPPER
222         }
223 #endif
224         fbValidateDrawable (pDrawable);
225         pbox++;
226     }
227     
228     fbFinishAccess (pDrawable);
229 }