Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /****************************************************************************** |
2 | * | |
3 | * Copyright (c) 1994, 1995 Hewlett-Packard Company | |
4 | * | |
5 | * Permission is hereby granted, free of charge, to any person obtaining | |
6 | * a copy of this software and associated documentation files (the | |
7 | * "Software"), to deal in the Software without restriction, including | |
8 | * without limitation the rights to use, copy, modify, merge, publish, | |
9 | * distribute, sublicense, and/or sell copies of the Software, and to | |
10 | * permit persons to whom the Software is furnished to do so, subject to | |
11 | * the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included | |
14 | * in all copies or substantial portions of the Software. | |
15 | * | |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
19 | * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, | |
20 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
21 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR | |
22 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
23 | * | |
24 | * Except as contained in this notice, the name of the Hewlett-Packard | |
25 | * Company shall not be used in advertising or otherwise to promote the | |
26 | * sale, use or other dealings in this Software without prior written | |
27 | * authorization from the Hewlett-Packard Company. | |
28 | * | |
29 | * Machine-independent DBE code | |
30 | * | |
31 | *****************************************************************************/ | |
32 | ||
33 | /* INCLUDES */ | |
34 | ||
35 | #ifdef HAVE_DIX_CONFIG_H | |
36 | #include <dix-config.h> | |
37 | #endif | |
38 | ||
39 | #include <X11/X.h> | |
40 | #include <X11/Xproto.h> | |
41 | #include "misc.h" | |
42 | #include "os.h" | |
43 | #include "windowstr.h" | |
44 | #include "scrnintstr.h" | |
45 | #include "pixmapstr.h" | |
46 | #include "extnsionst.h" | |
47 | #include "dixstruct.h" | |
48 | #include "resource.h" | |
49 | #include "opaque.h" | |
50 | #include "dbestruct.h" | |
51 | #include "regionstr.h" | |
52 | #include "gcstruct.h" | |
53 | #include "inputstr.h" | |
54 | #include "midbe.h" | |
55 | #include "xace.h" | |
56 | ||
57 | #include <stdio.h> | |
58 | ||
59 | \f | |
60 | /****************************************************************************** | |
61 | * | |
62 | * DBE MI Procedure: miDbeGetVisualInfo | |
63 | * | |
64 | * Description: | |
65 | * | |
66 | * This is the MI function for the DbeGetVisualInfo request. This function | |
67 | * is called through pDbeScreenPriv->GetVisualInfo. This function is also | |
68 | * called for the DbeAllocateBackBufferName request at the extension level; | |
69 | * it is called by ProcDbeAllocateBackBufferName() in dbe.c. | |
70 | * | |
71 | * If memory allocation fails or we can not get the visual info, this | |
72 | * function returns FALSE. Otherwise, it returns TRUE for success. | |
73 | * | |
74 | *****************************************************************************/ | |
75 | ||
76 | static Bool | |
77 | miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo) | |
78 | { | |
79 | register int i, j, k; | |
80 | register int count; | |
81 | DepthPtr pDepth; | |
82 | XdbeVisualInfo *visInfo; | |
83 | ||
84 | /* Determine number of visuals for this screen. */ | |
85 | for (i = 0, count = 0; i < pScreen->numDepths; i++) { | |
86 | count += pScreen->allowedDepths[i].numVids; | |
87 | } | |
88 | ||
89 | /* Allocate an array of XdbeVisualInfo items. */ | |
90 | if (!(visInfo = (XdbeVisualInfo *) malloc(count * sizeof(XdbeVisualInfo)))) { | |
91 | return FALSE; /* memory alloc failure */ | |
92 | } | |
93 | ||
94 | for (i = 0, k = 0; i < pScreen->numDepths; i++) { | |
95 | /* For each depth of this screen, get visual information. */ | |
96 | ||
97 | pDepth = &pScreen->allowedDepths[i]; | |
98 | ||
99 | for (j = 0; j < pDepth->numVids; j++) { | |
100 | /* For each visual for this depth of this screen, get visual ID | |
101 | * and visual depth. Since this is MI code, we will always return | |
102 | * the same performance level for all visuals (0). A higher | |
103 | * performance level value indicates higher performance. | |
104 | */ | |
105 | visInfo[k].visual = pDepth->vids[j]; | |
106 | visInfo[k].depth = pDepth->depth; | |
107 | visInfo[k].perflevel = 0; | |
108 | k++; | |
109 | } | |
110 | } | |
111 | ||
112 | /* Record the number of visuals and point visual_depth to | |
113 | * the array of visual info. | |
114 | */ | |
115 | pScrVisInfo->count = count; | |
116 | pScrVisInfo->visinfo = visInfo; | |
117 | ||
118 | return TRUE; /* success */ | |
119 | ||
120 | } /* miDbeGetVisualInfo() */ | |
121 | \f | |
122 | /****************************************************************************** | |
123 | * | |
124 | * DBE MI Procedure: miAllocBackBufferName | |
125 | * | |
126 | * Description: | |
127 | * | |
128 | * This is the MI function for the DbeAllocateBackBufferName request. | |
129 | * | |
130 | *****************************************************************************/ | |
131 | ||
132 | static int | |
133 | miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction) | |
134 | { | |
135 | ScreenPtr pScreen; | |
136 | DbeWindowPrivPtr pDbeWindowPriv; | |
137 | DbeScreenPrivPtr pDbeScreenPriv; | |
138 | GCPtr pGC; | |
139 | xRectangle clearRect; | |
140 | int rc; | |
141 | ||
142 | pScreen = pWin->drawable.pScreen; | |
143 | pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); | |
144 | ||
145 | if (pDbeWindowPriv->nBufferIDs == 0) { | |
146 | /* There is no buffer associated with the window. | |
147 | * We have to create the window priv priv. Remember, the window | |
148 | * priv was created at the DIX level, so all we need to do is | |
149 | * create the priv priv and attach it to the priv. | |
150 | */ | |
151 | ||
152 | pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); | |
153 | ||
154 | /* Get a front pixmap. */ | |
155 | if (!(pDbeWindowPriv->pFrontBuffer = | |
156 | (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, | |
157 | pDbeWindowPriv->height, | |
158 | pWin->drawable.depth, 0))) { | |
159 | return BadAlloc; | |
160 | } | |
161 | ||
162 | /* Get a back pixmap. */ | |
163 | if (!(pDbeWindowPriv->pBackBuffer = | |
164 | (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width, | |
165 | pDbeWindowPriv->height, | |
166 | pWin->drawable.depth, 0))) { | |
167 | (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); | |
168 | return BadAlloc; | |
169 | } | |
170 | ||
171 | /* Security creation/labeling check. */ | |
172 | rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId, | |
173 | dbeDrawableResType, pDbeWindowPriv->pBackBuffer, | |
174 | RT_WINDOW, pWin, DixCreateAccess); | |
175 | ||
176 | /* Make the back pixmap a DBE drawable resource. */ | |
177 | if (rc != Success || !AddResource(bufId, dbeDrawableResType, | |
178 | pDbeWindowPriv->pBackBuffer)) { | |
179 | /* free the buffer and the drawable resource */ | |
180 | FreeResource(bufId, RT_NONE); | |
181 | return (rc == Success) ? BadAlloc : rc; | |
182 | } | |
183 | ||
184 | /* Clear the back buffer. */ | |
185 | pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); | |
186 | if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { | |
187 | ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); | |
188 | clearRect.x = clearRect.y = 0; | |
189 | clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; | |
190 | clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; | |
191 | (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> | |
192 | pBackBuffer, pGC, 1, &clearRect); | |
193 | } | |
194 | FreeScratchGC(pGC); | |
195 | ||
196 | } /* if no buffer associated with the window */ | |
197 | ||
198 | else { | |
199 | /* A buffer is already associated with the window. | |
200 | * Place the new buffer ID information at the head of the ID list. | |
201 | */ | |
202 | ||
203 | /* Associate the new ID with an existing pixmap. */ | |
204 | if (!AddResource(bufId, dbeDrawableResType, | |
205 | (pointer) pDbeWindowPriv->pBackBuffer)) { | |
206 | return BadAlloc; | |
207 | } | |
208 | ||
209 | } | |
210 | ||
211 | return Success; | |
212 | ||
213 | } /* miDbeAllocBackBufferName() */ | |
214 | \f | |
215 | /****************************************************************************** | |
216 | * | |
217 | * DBE MI Procedure: miDbeAliasBuffers | |
218 | * | |
219 | * Description: | |
220 | * | |
221 | * This function associates all XIDs of a buffer with the back pixmap | |
222 | * stored in the window priv. | |
223 | * | |
224 | *****************************************************************************/ | |
225 | ||
226 | static void | |
227 | miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv) | |
228 | { | |
229 | int i; | |
230 | ||
231 | for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) { | |
232 | ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, | |
233 | (pointer) pDbeWindowPriv->pBackBuffer); | |
234 | } | |
235 | ||
236 | } /* miDbeAliasBuffers() */ | |
237 | \f | |
238 | /****************************************************************************** | |
239 | * | |
240 | * DBE MI Procedure: miDbeSwapBuffers | |
241 | * | |
242 | * Description: | |
243 | * | |
244 | * This is the MI function for the DbeSwapBuffers request. | |
245 | * | |
246 | *****************************************************************************/ | |
247 | ||
248 | static int | |
249 | miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo) | |
250 | { | |
251 | DbeScreenPrivPtr pDbeScreenPriv; | |
252 | DbeWindowPrivPtr pDbeWindowPriv; | |
253 | GCPtr pGC; | |
254 | WindowPtr pWin; | |
255 | PixmapPtr pTmpBuffer; | |
256 | xRectangle clearRect; | |
257 | ||
258 | pWin = swapInfo[0].pWindow; | |
259 | pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); | |
260 | pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); | |
261 | pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); | |
262 | ||
263 | /* | |
264 | ********************************************************************** | |
265 | ** Setup before swap. | |
266 | ********************************************************************** | |
267 | */ | |
268 | ||
269 | switch (swapInfo[0].swapAction) { | |
270 | case XdbeUndefined: | |
271 | break; | |
272 | ||
273 | case XdbeBackground: | |
274 | break; | |
275 | ||
276 | case XdbeUntouched: | |
277 | ValidateGC((DrawablePtr) pDbeWindowPriv->pFrontBuffer, pGC); | |
278 | (*pGC->ops->CopyArea) ((DrawablePtr) pWin, | |
279 | (DrawablePtr) pDbeWindowPriv->pFrontBuffer, | |
280 | pGC, 0, 0, pWin->drawable.width, | |
281 | pWin->drawable.height, 0, 0); | |
282 | break; | |
283 | ||
284 | case XdbeCopied: | |
285 | break; | |
286 | ||
287 | } | |
288 | ||
289 | /* | |
290 | ********************************************************************** | |
291 | ** Swap. | |
292 | ********************************************************************** | |
293 | */ | |
294 | ||
295 | ValidateGC((DrawablePtr) pWin, pGC); | |
296 | (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, | |
297 | (DrawablePtr) pWin, pGC, 0, 0, | |
298 | pWin->drawable.width, pWin->drawable.height, 0, 0); | |
299 | ||
300 | /* | |
301 | ********************************************************************** | |
302 | ** Tasks after swap. | |
303 | ********************************************************************** | |
304 | */ | |
305 | ||
306 | switch (swapInfo[0].swapAction) { | |
307 | case XdbeUndefined: | |
308 | break; | |
309 | ||
310 | case XdbeBackground: | |
311 | if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { | |
312 | ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC); | |
313 | clearRect.x = 0; | |
314 | clearRect.y = 0; | |
315 | clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width; | |
316 | clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height; | |
317 | (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv-> | |
318 | pBackBuffer, pGC, 1, &clearRect); | |
319 | } | |
320 | break; | |
321 | ||
322 | case XdbeUntouched: | |
323 | /* Swap pixmap pointers. */ | |
324 | pTmpBuffer = pDbeWindowPriv->pBackBuffer; | |
325 | pDbeWindowPriv->pBackBuffer = pDbeWindowPriv->pFrontBuffer; | |
326 | pDbeWindowPriv->pFrontBuffer = pTmpBuffer; | |
327 | ||
328 | miDbeAliasBuffers(pDbeWindowPriv); | |
329 | ||
330 | break; | |
331 | ||
332 | case XdbeCopied: | |
333 | break; | |
334 | ||
335 | } | |
336 | ||
337 | /* Remove the swapped window from the swap information array and decrement | |
338 | * pNumWindows to indicate to the DIX level how many windows were actually | |
339 | * swapped. | |
340 | */ | |
341 | ||
342 | if (*pNumWindows > 1) { | |
343 | /* We were told to swap more than one window, but we only swapped the | |
344 | * first one. Remove the first window in the list by moving the last | |
345 | * window to the beginning. | |
346 | */ | |
347 | swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow; | |
348 | swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction; | |
349 | ||
350 | /* Clear the last window information just to be safe. */ | |
351 | swapInfo[*pNumWindows - 1].pWindow = (WindowPtr) NULL; | |
352 | swapInfo[*pNumWindows - 1].swapAction = 0; | |
353 | } | |
354 | else { | |
355 | /* Clear the window information just to be safe. */ | |
356 | swapInfo[0].pWindow = (WindowPtr) NULL; | |
357 | swapInfo[0].swapAction = 0; | |
358 | } | |
359 | ||
360 | (*pNumWindows)--; | |
361 | ||
362 | FreeScratchGC(pGC); | |
363 | ||
364 | return Success; | |
365 | ||
366 | } /* miSwapBuffers() */ | |
367 | \f | |
368 | /****************************************************************************** | |
369 | * | |
370 | * DBE MI Procedure: miDbeWinPrivDelete | |
371 | * | |
372 | * Description: | |
373 | * | |
374 | * This is the MI function for deleting the dbeWindowPrivResType resource. | |
375 | * This function is invoked indirectly by calling FreeResource() to free | |
376 | * the resources associated with a DBE buffer ID. There are 5 ways that | |
377 | * miDbeWinPrivDelete() can be called by FreeResource(). They are: | |
378 | * | |
379 | * - A DBE window is destroyed, in which case the DbeDestroyWindow() | |
380 | * wrapper is invoked. The wrapper calls FreeResource() for all DBE | |
381 | * buffer IDs. | |
382 | * | |
383 | * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources | |
384 | * after a buffer allocation failure. | |
385 | * | |
386 | * - The PositionWindow wrapper, miDbePositionWindow(), calls | |
387 | * FreeResource() when it fails to create buffers of the new size. | |
388 | * FreeResource() is called for all DBE buffer IDs. | |
389 | * | |
390 | * - FreeClientResources() calls FreeResource() when a client dies or the | |
391 | * the server resets. | |
392 | * | |
393 | * When FreeResource() is called for a DBE buffer ID, the delete function | |
394 | * for the only other type of DBE resource, dbeDrawableResType, is also | |
395 | * invoked. This delete function (DbeDrawableDelete) is a NOOP to make | |
396 | * resource deletion easier. It is not guaranteed which delete function is | |
397 | * called first. Hence, we will let miDbeWinPrivDelete() free all DBE | |
398 | * resources. | |
399 | * | |
400 | * This function deletes/frees the following stuff associated with | |
401 | * the window private: | |
402 | * | |
403 | * - the ID node in the ID list representing the passed in ID. | |
404 | * | |
405 | * In addition, pDbeWindowPriv->nBufferIDs is decremented. | |
406 | * | |
407 | * If this function is called for the last/only buffer ID for a window, | |
408 | * these are additionally deleted/freed: | |
409 | * | |
410 | * - the front and back pixmaps | |
411 | * - the window priv itself | |
412 | * | |
413 | *****************************************************************************/ | |
414 | ||
415 | static void | |
416 | miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId) | |
417 | { | |
418 | if (pDbeWindowPriv->nBufferIDs != 0) { | |
419 | /* We still have at least one more buffer ID associated with this | |
420 | * window. | |
421 | */ | |
422 | return; | |
423 | } | |
424 | ||
425 | /* We have no more buffer IDs associated with this window. We need to | |
426 | * free some stuff. | |
427 | */ | |
428 | ||
429 | /* Destroy the front and back pixmaps. */ | |
430 | if (pDbeWindowPriv->pFrontBuffer) { | |
431 | (*pDbeWindowPriv->pWindow->drawable.pScreen-> | |
432 | DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); | |
433 | } | |
434 | if (pDbeWindowPriv->pBackBuffer) { | |
435 | (*pDbeWindowPriv->pWindow->drawable.pScreen-> | |
436 | DestroyPixmap) (pDbeWindowPriv->pBackBuffer); | |
437 | } | |
438 | } /* miDbeWinPrivDelete() */ | |
439 | \f | |
440 | /****************************************************************************** | |
441 | * | |
442 | * DBE MI Procedure: miDbePositionWindow | |
443 | * | |
444 | * Description: | |
445 | * | |
446 | * This function was cloned from miMbxPositionWindow() in mimultibuf.c. | |
447 | * This function resizes the buffer when the window is resized. | |
448 | * | |
449 | *****************************************************************************/ | |
450 | ||
451 | static Bool | |
452 | miDbePositionWindow(WindowPtr pWin, int x, int y) | |
453 | { | |
454 | ScreenPtr pScreen; | |
455 | DbeScreenPrivPtr pDbeScreenPriv; | |
456 | DbeWindowPrivPtr pDbeWindowPriv; | |
457 | int width, height; | |
458 | int dx, dy, dw, dh; | |
459 | int sourcex, sourcey; | |
460 | int destx, desty; | |
461 | int savewidth, saveheight; | |
462 | PixmapPtr pFrontBuffer; | |
463 | PixmapPtr pBackBuffer; | |
464 | Bool clear; | |
465 | GCPtr pGC; | |
466 | xRectangle clearRect; | |
467 | Bool ret; | |
468 | ||
469 | /* | |
470 | ************************************************************************** | |
471 | ** 1. Unwrap the member routine. | |
472 | ************************************************************************** | |
473 | */ | |
474 | ||
475 | pScreen = pWin->drawable.pScreen; | |
476 | pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); | |
477 | pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; | |
478 | ||
479 | /* | |
480 | ************************************************************************** | |
481 | ** 2. Do any work necessary before the member routine is called. | |
482 | ** | |
483 | ** In this case we do not need to do anything. | |
484 | ************************************************************************** | |
485 | */ | |
486 | ||
487 | /* | |
488 | ************************************************************************** | |
489 | ** 3. Call the member routine, saving its result if necessary. | |
490 | ************************************************************************** | |
491 | */ | |
492 | ||
493 | ret = (*pScreen->PositionWindow) (pWin, x, y); | |
494 | ||
495 | /* | |
496 | ************************************************************************** | |
497 | ** 4. Rewrap the member routine, restoring the wrapper value first in case | |
498 | ** the wrapper (or something that it wrapped) change this value. | |
499 | ************************************************************************** | |
500 | */ | |
501 | ||
502 | pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; | |
503 | pScreen->PositionWindow = miDbePositionWindow; | |
504 | ||
505 | /* | |
506 | ************************************************************************** | |
507 | ** 5. Do any work necessary after the member routine has been called. | |
508 | ************************************************************************** | |
509 | */ | |
510 | ||
511 | if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) { | |
512 | return ret; | |
513 | } | |
514 | ||
515 | if (pDbeWindowPriv->width == pWin->drawable.width && | |
516 | pDbeWindowPriv->height == pWin->drawable.height) { | |
517 | return ret; | |
518 | } | |
519 | ||
520 | width = pWin->drawable.width; | |
521 | height = pWin->drawable.height; | |
522 | ||
523 | dx = pWin->drawable.x - pDbeWindowPriv->x; | |
524 | dy = pWin->drawable.y - pDbeWindowPriv->y; | |
525 | dw = width - pDbeWindowPriv->width; | |
526 | dh = height - pDbeWindowPriv->height; | |
527 | ||
528 | GravityTranslate(0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); | |
529 | ||
530 | clear = ((pDbeWindowPriv->width < (unsigned short) width) || | |
531 | (pDbeWindowPriv->height < (unsigned short) height) || | |
532 | (pWin->bitGravity == ForgetGravity)); | |
533 | ||
534 | sourcex = 0; | |
535 | sourcey = 0; | |
536 | savewidth = pDbeWindowPriv->width; | |
537 | saveheight = pDbeWindowPriv->height; | |
538 | ||
539 | /* Clip rectangle to source and destination. */ | |
540 | if (destx < 0) { | |
541 | savewidth += destx; | |
542 | sourcex -= destx; | |
543 | destx = 0; | |
544 | } | |
545 | ||
546 | if (destx + savewidth > width) { | |
547 | savewidth = width - destx; | |
548 | } | |
549 | ||
550 | if (desty < 0) { | |
551 | saveheight += desty; | |
552 | sourcey -= desty; | |
553 | desty = 0; | |
554 | } | |
555 | ||
556 | if (desty + saveheight > height) { | |
557 | saveheight = height - desty; | |
558 | } | |
559 | ||
560 | pDbeWindowPriv->width = width; | |
561 | pDbeWindowPriv->height = height; | |
562 | pDbeWindowPriv->x = pWin->drawable.x; | |
563 | pDbeWindowPriv->y = pWin->drawable.y; | |
564 | ||
565 | pGC = GetScratchGC(pWin->drawable.depth, pScreen); | |
566 | ||
567 | if (clear) { | |
568 | if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) { | |
569 | clearRect.x = 0; | |
570 | clearRect.y = 0; | |
571 | clearRect.width = width; | |
572 | clearRect.height = height; | |
573 | } | |
574 | else { | |
575 | clear = FALSE; | |
576 | } | |
577 | } | |
578 | ||
579 | /* Create DBE buffer pixmaps equal to size of resized window. */ | |
580 | pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, | |
581 | pWin->drawable.depth, 0); | |
582 | ||
583 | pBackBuffer = (*pScreen->CreatePixmap) (pScreen, width, height, | |
584 | pWin->drawable.depth, 0); | |
585 | ||
586 | if (!pFrontBuffer || !pBackBuffer) { | |
587 | /* We failed at creating 1 or 2 of the pixmaps. */ | |
588 | ||
589 | if (pFrontBuffer) { | |
590 | (*pScreen->DestroyPixmap) (pFrontBuffer); | |
591 | } | |
592 | ||
593 | if (pBackBuffer) { | |
594 | (*pScreen->DestroyPixmap) (pBackBuffer); | |
595 | } | |
596 | ||
597 | /* Destroy all buffers for this window. */ | |
598 | while (pDbeWindowPriv) { | |
599 | /* DbeWindowPrivDelete() will free the window private if there no | |
600 | * more buffer IDs associated with this window. | |
601 | */ | |
602 | FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); | |
603 | pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); | |
604 | } | |
605 | ||
606 | FreeScratchGC(pGC); | |
607 | return FALSE; | |
608 | } | |
609 | ||
610 | else { | |
611 | /* Clear out the new DBE buffer pixmaps. */ | |
612 | ||
613 | /* I suppose this could avoid quite a bit of work if | |
614 | * it computed the minimal area required. | |
615 | */ | |
616 | ValidateGC(&pFrontBuffer->drawable, pGC); | |
617 | if (clear) { | |
618 | (*pGC->ops->PolyFillRect) ((DrawablePtr) pFrontBuffer, pGC, 1, | |
619 | &clearRect); | |
620 | } | |
621 | /* Copy the contents of the old front pixmap to the new one. */ | |
622 | if (pWin->bitGravity != ForgetGravity) { | |
623 | (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pFrontBuffer, | |
624 | (DrawablePtr) pFrontBuffer, pGC, | |
625 | sourcex, sourcey, savewidth, saveheight, | |
626 | destx, desty); | |
627 | } | |
628 | ||
629 | ValidateGC(&pBackBuffer->drawable, pGC); | |
630 | if (clear) { | |
631 | (*pGC->ops->PolyFillRect) ((DrawablePtr) pBackBuffer, pGC, 1, | |
632 | &clearRect); | |
633 | } | |
634 | /* Copy the contents of the old back pixmap to the new one. */ | |
635 | if (pWin->bitGravity != ForgetGravity) { | |
636 | (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer, | |
637 | (DrawablePtr) pBackBuffer, pGC, | |
638 | sourcex, sourcey, savewidth, saveheight, | |
639 | destx, desty); | |
640 | } | |
641 | ||
642 | /* Destroy the old pixmaps, and point the DBE window priv to the new | |
643 | * pixmaps. | |
644 | */ | |
645 | ||
646 | (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer); | |
647 | (*pScreen->DestroyPixmap) (pDbeWindowPriv->pBackBuffer); | |
648 | ||
649 | pDbeWindowPriv->pFrontBuffer = pFrontBuffer; | |
650 | pDbeWindowPriv->pBackBuffer = pBackBuffer; | |
651 | ||
652 | /* Make sure all XID are associated with the new back pixmap. */ | |
653 | miDbeAliasBuffers(pDbeWindowPriv); | |
654 | ||
655 | FreeScratchGC(pGC); | |
656 | } | |
657 | ||
658 | return ret; | |
659 | ||
660 | } /* miDbePositionWindow() */ | |
661 | \f | |
662 | /****************************************************************************** | |
663 | * | |
664 | * DBE MI Procedure: miDbeInit | |
665 | * | |
666 | * Description: | |
667 | * | |
668 | * This is the MI initialization function called by DbeExtensionInit(). | |
669 | * | |
670 | *****************************************************************************/ | |
671 | ||
672 | Bool | |
673 | miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv) | |
674 | { | |
675 | /* Wrap functions. */ | |
676 | pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; | |
677 | pScreen->PositionWindow = miDbePositionWindow; | |
678 | ||
679 | /* Initialize the per-screen DBE function pointers. */ | |
680 | pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo; | |
681 | pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName; | |
682 | pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers; | |
683 | pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete; | |
684 | ||
685 | return TRUE; | |
686 | ||
687 | } /* miDbeInit() */ |