First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xgl / xglwindow.c
blob967d10f77880338c6dc5e689e430509afaf1196b
1 /*
2 * Copyright © 2004 David Reveman
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 * David Reveman not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * David Reveman makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
15 * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL DAVID REVEMAN 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.
23 * Author: David Reveman <davidr@novell.com>
26 #include "xgl.h"
27 #include "fb.h"
29 #define XGL_WINDOW_FALLBACK_PROLOGUE(pWin, func) \
30 if (!xglMapPixmapBits (XGL_GET_DRAWABLE_PIXMAP (&pWin->drawable))) \
31 FatalError (XGL_SW_FAILURE_STRING); \
32 XGL_SCREEN_UNWRAP (func)
34 #define XGL_WINDOW_FALLBACK_EPILOGUE(pWin, pRegion, func, xglfunc) \
35 XGL_SCREEN_WRAP (func, xglfunc); \
36 xglAddSurfaceDamage (&pWin->drawable, pRegion)
38 Bool
39 xglCreateWindow (WindowPtr pWin)
41 ScreenPtr pScreen = pWin->drawable.pScreen;
42 Bool ret;
44 XGL_SCREEN_PRIV (pScreen);
45 XGL_WINDOW_PRIV (pWin);
47 XGL_SCREEN_UNWRAP (CreateWindow);
48 ret = (*pScreen->CreateWindow) (pWin);
49 XGL_SCREEN_WRAP (CreateWindow, xglCreateWindow);
51 pWinPriv->pPixmap = pWin->drawable.pScreen->devPrivate;
53 return ret;
56 Bool
57 xglDestroyWindow (WindowPtr pWin)
59 ScreenPtr pScreen = pWin->drawable.pScreen;
60 Bool ret;
62 XGL_SCREEN_PRIV (pScreen);
64 XGL_SCREEN_UNWRAP (DestroyWindow);
65 ret = (*pScreen->DestroyWindow) (pWin);
66 XGL_SCREEN_WRAP (DestroyWindow, xglDestroyWindow);
68 return ret;
71 Bool
72 xglChangeWindowAttributes (WindowPtr pWin,
73 unsigned long mask)
75 ScreenPtr pScreen = pWin->drawable.pScreen;
76 PixmapPtr pPixmap;
77 Bool ret;
79 XGL_SCREEN_PRIV (pScreen);
81 if (mask & CWBackPixmap)
83 if (pWin->backgroundState == BackgroundPixmap)
85 pPixmap = pWin->background.pixmap;
87 if (FbEvenTile (pPixmap->drawable.width *
88 pPixmap->drawable.bitsPerPixel))
89 xglSyncBits (&pPixmap->drawable, NULL);
93 if (mask & CWBorderPixmap)
95 if (pWin->borderIsPixel == FALSE)
97 pPixmap = pWin->border.pixmap;
99 if (FbEvenTile (pPixmap->drawable.width *
100 pPixmap->drawable.bitsPerPixel))
101 xglSyncBits (&pPixmap->drawable, NULL);
105 XGL_SCREEN_UNWRAP (ChangeWindowAttributes);
106 ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
107 XGL_SCREEN_WRAP (ChangeWindowAttributes, xglChangeWindowAttributes);
109 return ret;
112 void
113 xglCopyWindow (WindowPtr pWin,
114 DDXPointRec ptOldOrg,
115 RegionPtr prgnSrc)
117 PixmapPtr pPixmap;
118 RegionRec rgnDst;
119 int dx, dy;
120 BoxPtr pExtent = REGION_EXTENTS (pWin->drawable.pScreen, prgnSrc);
121 BoxRec box;
123 pPixmap = XGL_GET_WINDOW_PIXMAP (pWin);
125 box.x1 = pExtent->x1;
126 box.y1 = pExtent->y1;
127 box.x2 = pExtent->x2;
128 box.y2 = pExtent->y2;
130 dx = ptOldOrg.x - pWin->drawable.x;
131 dy = ptOldOrg.y - pWin->drawable.y;
133 REGION_TRANSLATE (pWin->drawable.pScreen, prgnSrc, -dx, -dy);
134 REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
135 REGION_INTERSECT (pWin->drawable.pScreen,
136 &rgnDst, &pWin->borderClip, prgnSrc);
138 fbCopyRegion (&pWin->drawable, &pWin->drawable,
139 0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &box);
141 REGION_UNINIT (pWin->drawable.pScreen, &rgnDst);
144 static Bool
145 xglFillRegionSolid (DrawablePtr pDrawable,
146 RegionPtr pRegion,
147 Pixel pixel)
149 glitz_pixel_format_t format;
150 glitz_surface_t *solid;
151 glitz_buffer_t *buffer;
152 BoxPtr pExtent;
153 Bool ret;
155 XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
156 XGL_SCREEN_PRIV (pDrawable->pScreen);
158 if (!xglPrepareTarget (pDrawable))
159 return FALSE;
161 solid = glitz_surface_create (pScreenPriv->drawable,
162 pPixmapPriv->pVisual->format.surface,
163 1, 1, 0, NULL);
164 if (!solid)
165 return FALSE;
167 glitz_surface_set_fill (solid, GLITZ_FILL_REPEAT);
169 format.fourcc = GLITZ_FOURCC_RGB;
170 format.masks = pPixmapPriv->pVisual->pPixel->masks;
171 format.xoffset = 0;
172 format.skip_lines = 0;
173 format.bytes_per_line = sizeof (CARD32);
174 format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
176 buffer = glitz_buffer_create_for_data (&pixel);
178 glitz_set_pixels (solid, 0, 0, 1, 1, &format, buffer);
180 glitz_buffer_destroy (buffer);
182 pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
184 ret = xglSolid (pDrawable,
185 GLITZ_OPERATOR_SRC,
186 solid,
187 NULL,
188 pExtent->x1, pExtent->y1,
189 pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
190 REGION_RECTS (pRegion),
191 REGION_NUM_RECTS (pRegion));
193 glitz_surface_destroy (solid);
195 return ret;
198 static Bool
199 xglFillRegionTiled (DrawablePtr pDrawable,
200 RegionPtr pRegion,
201 PixmapPtr pTile,
202 int tileX,
203 int tileY)
205 BoxPtr pExtent;
207 pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
209 if (xglTile (pDrawable,
210 GLITZ_OPERATOR_SRC,
211 pTile,
212 tileX, tileY,
213 NULL,
214 pExtent->x1, pExtent->y1,
215 pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
216 REGION_RECTS (pRegion),
217 REGION_NUM_RECTS (pRegion)))
218 return TRUE;
220 return FALSE;
223 void
224 xglPaintWindowBackground (WindowPtr pWin,
225 RegionPtr pRegion,
226 int what)
228 ScreenPtr pScreen = pWin->drawable.pScreen;
230 XGL_SCREEN_PRIV (pScreen);
232 switch (pWin->backgroundState) {
233 case None:
234 return;
235 case ParentRelative:
236 do {
237 pWin = pWin->parent;
238 } while (pWin->backgroundState == ParentRelative);
240 (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
241 return;
242 case BackgroundPixmap:
243 if (xglFillRegionTiled (&pWin->drawable,
244 pRegion,
245 pWin->background.pixmap,
246 -pWin->drawable.x,
247 -pWin->drawable.y))
249 xglAddCurrentBitDamage (&pWin->drawable);
250 return;
253 if (!xglSyncBits (&pWin->background.pixmap->drawable, NullBox))
254 FatalError (XGL_SW_FAILURE_STRING);
255 break;
256 case BackgroundPixel:
257 if (xglFillRegionSolid (&pWin->drawable,
258 pRegion,
259 pWin->background.pixel))
261 xglAddCurrentBitDamage (&pWin->drawable);
262 return;
264 break;
267 XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBackground);
268 (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
269 XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBackground,
270 xglPaintWindowBackground);
273 void
274 xglPaintWindowBorder (WindowPtr pWin,
275 RegionPtr pRegion,
276 int what)
278 ScreenPtr pScreen = pWin->drawable.pScreen;
280 XGL_SCREEN_PRIV (pScreen);
282 if (pWin->borderIsPixel)
284 if (xglFillRegionSolid (&pWin->drawable,
285 pRegion,
286 pWin->border.pixel))
288 xglAddCurrentBitDamage (&pWin->drawable);
289 return;
292 else
294 WindowPtr pBgWin = pWin;
296 while (pBgWin->backgroundState == ParentRelative)
297 pBgWin = pBgWin->parent;
299 if (xglFillRegionTiled (&pBgWin->drawable,
300 pRegion,
301 pWin->border.pixmap,
302 -pBgWin->drawable.x,
303 -pBgWin->drawable.y))
305 xglAddCurrentBitDamage (&pWin->drawable);
306 return;
309 if (!xglSyncBits (&pWin->border.pixmap->drawable, NullBox))
310 FatalError (XGL_SW_FAILURE_STRING);
313 XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBorder);
314 (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
315 XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBorder,
316 xglPaintWindowBorder);
319 PixmapPtr
320 xglGetWindowPixmap (WindowPtr pWin)
322 return XGL_GET_WINDOW_PIXMAP (pWin);
325 void
326 xglSetWindowPixmap (WindowPtr pWin,
327 PixmapPtr pPixmap)
329 ScreenPtr pScreen = pWin->drawable.pScreen;
331 XGL_SCREEN_PRIV (pScreen);
333 XGL_SCREEN_UNWRAP (SetWindowPixmap);
334 (*pScreen->SetWindowPixmap) (pWin, pPixmap);
335 XGL_SCREEN_WRAP (SetWindowPixmap, xglSetWindowPixmap);
337 XGL_GET_WINDOW_PRIV (pWin)->pPixmap = pPixmap;
339 if (pPixmap != pScreenPriv->pScreenPixmap)
340 xglEnablePixmapAccel (pPixmap, &pScreenPriv->accel.window);