1
/* $XFree86: xc/programs/Xserver/afb/afbwindow.c,v 3.0 1996/08/18 01:45:58 dawes Exp $ */
2
/* $XConsortium: afbwindow.c,v 5.14 94/04/17 20:28:36 dpw Exp $ */
3
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
4
/***********************************************************
6
Copyright (c) 1987 X Consortium
8
Permission is hereby granted, free of charge, to any person obtaining a copy
9
of this software and associated documentation files (the "Software"), to deal
10
in the Software without restriction, including without limitation the rights
11
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
copies of the Software, and to permit persons to whom the Software is
13
furnished to do so, subject to the following conditions:
15
The above copyright notice and this permission notice shall be included in
16
all copies or substantial portions of the Software.
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
Except as contained in this notice, the name of the X Consortium shall not be
26
used in advertising or otherwise to promote the sale, use or other dealings
27
in this Software without prior written authorization from the X Consortium.
30
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
34
Permission to use, copy, modify, and distribute this software and its
35
documentation for any purpose and without fee is hereby granted,
36
provided that the above copyright notice appear in all copies and that
37
both that copyright notice and this permission notice appear in
38
supporting documentation, and that the name of Digital not be
39
used in advertising or publicity pertaining to distribution of the
40
software without specific, written prior permission.
42
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
43
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
44
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
45
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
46
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
47
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
50
******************************************************************/
52
#ifdef HAVE_DIX_CONFIG_H
53
#include <dix-config.h>
57
#include "scrnintstr.h"
58
#include "windowstr.h"
61
#include "regionstr.h"
66
register WindowPtr pWin;
68
register afbPrivWin *pPrivWin;
70
pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr);
71
pPrivWin->pRotatedBorder = NullPixmap;
72
pPrivWin->pRotatedBackground = NullPixmap;
73
pPrivWin->fastBackground = FALSE;
74
pPrivWin->fastBorder = FALSE;
75
#ifdef PIXMAP_PER_WINDOW
76
pWin->devPrivates[frameWindowPrivateIndex].ptr =
77
pWin->pDrawable.pScreen->devPrivates[afbScreenPrivateIndex].ptr;
83
/* This always returns true, because Xfree can't fail. It might be possible
84
* on some devices for Destroy to fail */
86
afbDestroyWindow(pWin)
89
register afbPrivWin *pPrivWin;
91
pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr);
93
if (pPrivWin->pRotatedBorder)
94
(*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBorder);
95
if (pPrivWin->pRotatedBackground)
96
(*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBackground);
103
afbMapWindow(pWindow)
109
/* (x, y) is the upper left corner of the window on the screen
110
do we really need to pass this? (is it a;ready in pWin->absCorner?)
111
we only do the rotation for pixmaps that are 32 bits wide (padded
113
afbChangeWindowAttributes() has already put a copy of the pixmap
114
in pPrivWin->pRotated*
119
afbPositionWindow(pWin, x, y)
123
register afbPrivWin *pPrivWin;
126
pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr);
127
if (pWin->backgroundState == BackgroundPixmap && pPrivWin->fastBackground) {
128
afbXRotatePixmap(pPrivWin->pRotatedBackground,
129
pWin->drawable.x - pPrivWin->oldRotate.x);
130
afbYRotatePixmap(pPrivWin->pRotatedBackground,
131
pWin->drawable.y - pPrivWin->oldRotate.y);
135
if (!pWin->borderIsPixel && pPrivWin->fastBorder) {
136
while (pWin->backgroundState == ParentRelative)
138
afbXRotatePixmap(pPrivWin->pRotatedBorder,
139
pWin->drawable.x - pPrivWin->oldRotate.x);
140
afbYRotatePixmap(pPrivWin->pRotatedBorder,
141
pWin->drawable.y - pPrivWin->oldRotate.y);
145
pPrivWin->oldRotate.x = pWin->drawable.x;
146
pPrivWin->oldRotate.y = pWin->drawable.y;
149
/* This is the "wrong" fix to the right problem, but it doesn't really
150
* cost very much. When the window is moved, we need to invalidate any
151
* RotatedPixmap that exists in any GC currently validated against this
154
pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
156
/* Again, we have no failure modes indicated by any of the routines
157
* we've called, so we have to assume it worked */
163
afbUnmapWindow(pWindow)
170
this code calls the bitblt helper code directly.
172
afbCopyWindow copies only the parts of the destination that are
173
visible in the source.
178
afbCopyWindow(pWin, ptOldOrg, prgnSrc)
180
DDXPointRec ptOldOrg;
184
register DDXPointPtr ppt;
186
register BoxPtr pbox;
188
register int i, nbox;
191
pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
193
prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
195
dx = ptOldOrg.x - pWin->drawable.x;
196
dy = ptOldOrg.y - pWin->drawable.y;
197
REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
198
REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
201
pbox = REGION_RECTS(prgnDst);
202
nbox = REGION_NUM_RECTS(prgnDst);
203
if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
207
for (i=nbox; --i >= 0; ppt++, pbox++) {
208
ppt->x = pbox->x1 + dx;
209
ppt->y = pbox->y1 + dy;
212
afbDoBitblt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, GXcopy, prgnDst,
214
DEALLOCATE_LOCAL(pptSrc);
215
REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
220
/* swap in correct PaintWindow* routine. If we can use a fast output
221
routine (i.e. the pixmap is paddable to 32 bits), also pre-rotate a copy
225
afbChangeWindowAttributes(pWin, mask)
226
register WindowPtr pWin;
227
register unsigned long mask;
229
register unsigned long index;
230
register afbPrivWin *pPrivWin;
233
pPrivWin = (afbPrivWin *)(pWin->devPrivates[afbWindowPrivateIndex].ptr);
235
* When background state changes from ParentRelative and
236
* we had previously rotated the fast border pixmap to match
237
* the parent relative origin, rerotate to match window
239
if (mask & (CWBackPixmap | CWBackPixel) &&
240
pWin->backgroundState != ParentRelative && pPrivWin->fastBorder &&
241
(pPrivWin->oldRotate.x != pWin->drawable.x ||
242
pPrivWin->oldRotate.y != pWin->drawable.y)) {
243
afbXRotatePixmap(pPrivWin->pRotatedBorder,
244
pWin->drawable.x - pPrivWin->oldRotate.x);
245
afbYRotatePixmap(pPrivWin->pRotatedBorder,
246
pWin->drawable.y - pPrivWin->oldRotate.y);
247
pPrivWin->oldRotate.x = pWin->drawable.x;
248
pPrivWin->oldRotate.y = pWin->drawable.y;
251
index = lowbit (mask);
255
if (pWin->backgroundState == None)
256
pPrivWin->fastBackground = FALSE;
257
else if (pWin->backgroundState == ParentRelative) {
258
pPrivWin->fastBackground = FALSE;
259
/* Rotate border to match parent origin */
260
if (pPrivWin->pRotatedBorder) {
261
for (pBgWin = pWin->parent;
262
pBgWin->backgroundState == ParentRelative;
263
pBgWin = pBgWin->parent);
264
afbXRotatePixmap(pPrivWin->pRotatedBorder,
265
pBgWin->drawable.x - pPrivWin->oldRotate.x);
266
afbYRotatePixmap(pPrivWin->pRotatedBorder,
267
pBgWin->drawable.y - pPrivWin->oldRotate.y);
268
pPrivWin->oldRotate.x = pBgWin->drawable.x;
269
pPrivWin->oldRotate.y = pBgWin->drawable.y;
271
} else if ((pWin->background.pixmap->drawable.width <= PPW) &&
272
!(pWin->background.pixmap->drawable.width &
273
(pWin->background.pixmap->drawable.width - 1))) {
274
afbCopyRotatePixmap(pWin->background.pixmap,
275
&pPrivWin->pRotatedBackground,
276
pWin->drawable.x, pWin->drawable.y);
277
if (pPrivWin->pRotatedBackground) {
278
pPrivWin->fastBackground = TRUE;
279
pPrivWin->oldRotate.x = pWin->drawable.x;
280
pPrivWin->oldRotate.y = pWin->drawable.y;
282
pPrivWin->fastBackground = FALSE;
284
pPrivWin->fastBackground = FALSE;
288
pPrivWin->fastBackground = FALSE;
292
if ((pWin->border.pixmap->drawable.width <= PPW) &&
293
!(pWin->border.pixmap->drawable.width &
294
(pWin->border.pixmap->drawable.width - 1))) {
296
pBgWin->backgroundState == ParentRelative;
297
pBgWin = pBgWin->parent);
298
afbCopyRotatePixmap(pWin->border.pixmap,
299
&pPrivWin->pRotatedBorder,
300
pBgWin->drawable.x, pBgWin->drawable.y);
301
if (pPrivWin->pRotatedBorder) {
302
pPrivWin->fastBorder = TRUE;
303
pPrivWin->oldRotate.x = pBgWin->drawable.x;
304
pPrivWin->oldRotate.y = pBgWin->drawable.y;
306
pPrivWin->fastBorder = FALSE;
308
pPrivWin->fastBorder = FALSE;
311
pPrivWin->fastBorder = FALSE;
315
/* Again, we have no failure modes indicated by any of the routines
316
* we've called, so we have to assume it worked */