Compositor: Compiler delint
[AROS.git] / workbench / devs / monitors / Compositor / compositorclass.c
blob404bef188d98a56c6fbcd75ba38ab29ad53d6078
1 /*
2 Copyright © 2010-2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #if (DEBUG)
8 #define DTOGGLE(x) x
9 #define DMODE(x) x
10 #define DMOVE(x) x
11 #define DRECALC(x) x
12 #define DREDRAWBM(x) x
13 #define DREDRAWSCR(x) x
14 #define DSTACK(x) x
15 #define DUPDATE(x) x
16 #else
17 #define DTOGGLE(x)
18 #define DMODE(x)
19 #define DMOVE(x)
20 #define DRECALC(x)
21 #define DREDRAWBM(x)
22 #define DREDRAWSCR(x)
23 #define DSTACK(x)
24 #define DUPDATE(x)
25 #endif
27 #include <aros/debug.h>
29 #include <proto/exec.h>
30 #include <proto/dos.h>
31 #include <proto/graphics.h>
32 #include <proto/oop.h>
33 #include <proto/utility.h>
35 #include <graphics/view.h>
36 #include <hidd/graphics.h>
38 #include "compositor_intern.h"
40 #define COMPOSITE_PREFS "SYS/compositor.prefs"
41 #define COMPOSITE_PEFSTEMPLATE "ABOVE/S,BELOW/S,LEFT/S,RIGHT/S,ALPHA/S"
43 enum
45 ARG_ABOVE = 0,
46 ARG_BELOW,
47 ARG_LEFT,
48 ARG_RIGHT,
49 ARG_ALPHA,
50 NOOFARGS
54 #ifdef GfxBase
55 #undef GfxBase
56 #endif
57 #define GfxBase compdata->GraphicsBase
59 #define _RECT(x) x.MinX, x.MinY, x.MaxX, x.MaxY
61 #define MAX(a,b) a > b ? a : b
62 #define MIN(a,b) a < b ? a : b
64 static BOOL AndRectRect(struct Rectangle * rect1, struct Rectangle * rect2,
65 struct Rectangle * intersect)
67 intersect->MinX = MAX(rect1->MinX, rect2->MinX);
68 intersect->MinY = MAX(rect1->MinY, rect2->MinY);
69 intersect->MaxX = MIN(rect1->MaxX, rect2->MaxX);
70 intersect->MaxY = MIN(rect1->MaxY, rect2->MaxY);
72 if ((intersect->MinX > intersect->MaxX) ||
73 (intersect->MinY > intersect->MaxY))
74 return FALSE;
75 else
76 return TRUE;
79 static struct StackBitMapNode * HIDDCompositorIsBitMapOnStack(struct HIDDCompositorData * compdata, OOP_Object * bm)
81 struct StackBitMapNode * n = NULL;
83 ForeachNode(&compdata->bitmapstack, n)
85 if (n->bm == bm)
86 return n;
89 return NULL;
92 static VOID HIDDCompositorValidateBitMapPositionChange(OOP_Object * bm, SIPTR *newxoffset, SIPTR *newyoffset, LONG displayedwidth, LONG displayedheight)
94 IPTR width, height;
95 LONG neglimit, poslimit;
97 OOP_GetAttr(bm, aHidd_BitMap_Width, &width);
98 OOP_GetAttr(bm, aHidd_BitMap_Height, &height);
100 /* Check x position */
101 if (width > displayedwidth)
103 neglimit = displayedwidth - width;
104 poslimit = 0;
106 else
108 neglimit = 0;
109 poslimit = displayedwidth - width;
112 if (*(newxoffset) > poslimit)
113 *(newxoffset) = poslimit;
114 if (*(newxoffset) < neglimit)
115 *(newxoffset) = neglimit;
117 /* Check y position */
118 if (height > displayedheight)
119 neglimit = displayedheight - height; /* Limit for scroll */
120 else
121 neglimit = 0;
122 poslimit = displayedheight - 15; /* Limit for drag */
124 if (*(newyoffset) > poslimit)
125 *(newyoffset) = poslimit;
126 if (*(newyoffset) < neglimit)
127 *(newyoffset) = neglimit;
130 static VOID HIDDCompositorRecalculateVisibleRegions(struct HIDDCompositorData *compdata)
132 struct StackBitMapNode *n = NULL, *tmpn;
133 struct Region *dispvisregion = NULL;
134 OOP_Object *bmpxfmt;
136 DRECALC(bug("[Compositor:%s] Display rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, _RECT(compdata->screenrect)));
139 * This function assumes bitmapstack is in correct Z order:
140 * from topmost to bottom most
142 if ((dispvisregion = NewRegion()) != NULL)
144 OrRectRegion(dispvisregion, &compdata->screenrect);
146 DRECALC(bug("[Compositor:%s] DisplayRegion @ 0x%p\n", __PRETTY_FUNCTION__, dispvisregion));
148 ForeachNodeSafe(&compdata->bitmapstack, n, tmpn)
150 /* Get bitmap bounding box in screen coordinates */
151 struct Rectangle tmprect;
153 n->sbmflags &= ~STACKNODE_VISIBLE;
155 if (n->screenregion)
156 DisposeRegion(n->screenregion);
158 if ((n->screenregion = NewRegion()) != NULL)
160 tmprect.MinX = n->leftedge;
161 tmprect.MaxX = n->leftedge + OOP_GET(n->bm, aHidd_BitMap_Width) - 1;
162 tmprect.MinY = n->topedge;
163 tmprect.MaxY = n->topedge + OOP_GET(n->bm, aHidd_BitMap_Height) - 1;
165 DRECALC(bug("[Compositor:%s] Screen Rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, _RECT(&tmprect)));
167 OrRectRegion(n->screenregion, &tmprect); // Start with the Screen's dimensions ..
168 AndRegionRegion(dispvisregion, n->screenregion); // And adjust for the "Display"
170 if (n->screenregion->RegionRectangle)
172 int bmpstdfmt;
173 bmpxfmt = (OOP_Object *)OOP_GET(n->bm, aHidd_BitMap_PixFmt);
174 bmpstdfmt = (int)OOP_GET(bmpxfmt, aHidd_PixFmt_StdPixFmt);
175 DRECALC(bug("[Compositor:%s] Screen BitMap PixFmt %lx @ 0x%p\n", __PRETTY_FUNCTION__, bmpstdfmt, bmpxfmt));
177 switch (bmpstdfmt)
179 case vHidd_StdPixFmt_ARGB32:
180 case vHidd_StdPixFmt_BGRA32:
181 case vHidd_StdPixFmt_RGBA32:
182 case vHidd_StdPixFmt_ABGR32:
184 DRECALC(bug("[Compositor:%s] BitMap has ALPHA\n", __PRETTY_FUNCTION__));
186 n->sbmflags |= STACKNODE_ALPHA;
188 if (!(compdata->alpharegion))
190 compdata->alpharegion = NewRegion();
191 DRECALC(bug("[Compositor:%s] AlphaRegion Allocated @ 0x%p\n", __PRETTY_FUNCTION__, compdata->alpharegion));
194 OrRegionRegion(compdata->alpharegion, n->screenregion);
195 break;
197 default:
199 n->sbmflags &= ~STACKNODE_ALPHA;
201 AndRectRect(&n->screenregion->bounds, &compdata->screenrect, &n->screenvisiblerect);
202 ClearRegionRegion(n->screenregion, dispvisregion);
204 if (!(compdata->capabilities & COMPF_ABOVE))
206 tmprect.MinX = compdata->screenrect.MinX;
207 tmprect.MaxX = compdata->screenrect.MaxX;
208 tmprect.MinY = compdata->screenrect.MinY;
209 tmprect.MaxY = n->topedge - 1;
210 ClearRectRegion(dispvisregion, &tmprect);
212 if (!(compdata->capabilities & COMPF_BELOW))
214 tmprect.MinX = compdata->screenrect.MinX;
215 tmprect.MaxX = compdata->screenrect.MaxX;
216 tmprect.MinY = n->topedge + OOP_GET(n->bm, aHidd_BitMap_Height);
217 tmprect.MaxY = compdata->screenrect.MaxY;
218 ClearRectRegion(dispvisregion, &tmprect);
220 if (!(compdata->capabilities & COMPF_LEFT))
222 tmprect.MinX = compdata->screenrect.MinX;
223 tmprect.MaxX = n->leftedge - 1;
224 tmprect.MinY = n->topedge;
225 tmprect.MaxY = n->topedge + OOP_GET(n->bm, aHidd_BitMap_Height) - 1;
226 ClearRectRegion(dispvisregion, &tmprect);
228 if (!(compdata->capabilities & COMPF_RIGHT))
230 tmprect.MinX = n->leftedge + OOP_GET(n->bm, aHidd_BitMap_Width);
231 tmprect.MaxX = compdata->screenrect.MaxX;
232 tmprect.MinY = n->topedge;
233 tmprect.MaxY = n->topedge + OOP_GET(n->bm, aHidd_BitMap_Height) - 1;
234 ClearRectRegion(dispvisregion, &tmprect);
238 n->sbmflags |= STACKNODE_VISIBLE;
241 DRECALC(bug("[Compositor:%s] Bitmap 0x%x, topedge %d, visible %d, [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__,
242 n->bm, n->topedge, (n->sbmflags & STACKNODE_VISIBLE), _RECT(n->screenvisiblerect)));
244 else
246 DRECALC(bug("[Compositor:%s] Failed to create Screen Region\n", __PRETTY_FUNCTION__));
249 DisposeRegion(dispvisregion);
251 else
253 DRECALC(bug("[Compositor:%s] Failed to create Display Region\n", __PRETTY_FUNCTION__));
257 static HIDDT_ModeID FindBestHiddMode(struct HIDDCompositorData *compdata, ULONG width, ULONG height, ULONG depth, ULONG *res_depth)
259 HIDDT_ModeID mode = vHidd_ModeID_Invalid;
260 OOP_Object *sync, *pf;
261 IPTR w, h, d;
262 ULONG dw, dh, delta;
263 ULONG found_delta = -1;
264 ULONG found_width = 0;
265 ULONG found_height = 0;
266 ULONG found_depth = 0;
267 HIDDT_ModeID found_mode = vHidd_ModeID_Invalid;
269 DMODE(bug("[%s] Finding best match for mode %ux%ux%u\n", __PRETTY_FUNCTION__, width, height, depth));
271 while ((mode = HIDD_Gfx_NextModeID(compdata->gfx, mode, &sync, &pf)) != vHidd_ModeID_Invalid)
273 BOOL match;
275 DMODE(bug("[%s] Checking mode 0x%08X... ", __PRETTY_FUNCTION__, mode));
276 if (OOP_GET(pf, aHidd_PixFmt_ColorModel) != vHidd_ColorModel_TrueColor)
278 DMODE(bug("Skipped (not truecolor)\n"));
279 continue;
282 OOP_GetAttr(sync, aHidd_Sync_HDisp, &w);
283 OOP_GetAttr(sync, aHidd_Sync_VDisp, &h);
284 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &d);
286 dw = w > width ? w - width : w < width ? width - w : 1;
287 dh = h > height ? h - height : h < height ? height - h : 1;
288 delta = dw * dh;
290 match = FALSE;
291 if (delta < found_delta)
293 /* If mode resolution is closer to the needed one, we've got a better match */
294 found_delta = delta;
295 found_width = w;
296 found_height = h;
298 match = TRUE;
300 else if (delta == found_delta)
302 /* If resolution is the same as that of current candidate mode, we can look at depth. */
303 if (found_depth > depth)
306 * Candidate mode if deeper than requested. We can supersede it with another mode
307 * of smaller depth, but which still matches our request.
309 if ((d < found_depth) && (d >= depth))
310 match = TRUE;
312 else if (found_depth < depth)
315 * We want better depth than current candidate.
316 * In this case anything deeper will do.
318 if (d > found_depth)
319 match = TRUE;
323 if (match)
326 * Mode with the same delta, but larger depth, may supersede
327 * previous mode, if we prefer deeper ones.
329 DMODE(bug("Selected (%ldx%ldx%ld, delta = %u)", w, h, d, delta));
330 found_depth = d;
331 found_mode = mode;
333 DMODE(bug("\n"));
336 /* Store mode information */
337 compdata->screenrect.MinX = 0;
338 compdata->screenrect.MinY = 0;
339 compdata->screenrect.MaxX = found_width - 1;
340 compdata->screenrect.MaxY = found_height - 1;
341 *res_depth = found_depth;
343 return found_mode;
346 static void UpdateDisplayMode(struct HIDDCompositorData *compdata)
348 struct StackBitMapNode *n;
349 IPTR modeid, width, height, depth;
350 OOP_Object *sync, *pf;
351 UBYTE comp_depth = 16;
352 ULONG found_depth;
355 * Examine all bitmaps in the stack to figure out the needed depth.
356 * We need a maximum depth of all depths in order to keep correct colors.
357 * But not less than 16 bits, because we can't compose on a LUT screen.
359 * If a LUT bitmap is present in the stack (depth < 9), we request truecolor
360 * screen for better color presentation.
362 * We examine bitmaps in reverse order, in this case 'sync' will hold
363 * information about the top bitmap when we exit the loop.
364 * Size of our composited mode needs to be as close as possible to that one.
366 for (n = (struct StackBitMapNode *)compdata->bitmapstack.mlh_TailPred;
367 n->n.mln_Pred; n = (struct StackBitMapNode *)n->n.mln_Pred)
369 OOP_GetAttr(n->bm, aHidd_BitMap_ModeID, &modeid);
370 HIDD_Gfx_GetMode(compdata->gfx, modeid, &sync, &pf);
372 if (OOP_GET(pf, aHidd_PixFmt_ColorModel) == vHidd_ColorModel_TrueColor)
374 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
375 if (depth > comp_depth)
376 comp_depth = depth;
378 else
381 * If we have a LUT bitmap on stack, we request 24-bit screen
382 * for better color transfer.
384 comp_depth = 24;
388 /* Get the needed size */
389 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
390 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
392 DSTACK(bug("[%s] Requested mode %ldx%ldx%d\n", __PRETTY_FUNCTION__, width, height, comp_depth));
394 modeid = FindBestHiddMode(compdata, width, height, depth, &found_depth);
395 DSTACK(bug("[%s] Composition Display Mode 0x%08X [current 0x%08X]\n", __PRETTY_FUNCTION__, modeid, compdata->screenmodeid));
397 if (modeid != compdata->screenmodeid)
399 /* The mode is different. Need to prepare information needed for compositing */
400 struct TagItem gctags[] =
402 { aHidd_GC_Foreground, 0x99999999 },
403 { TAG_DONE , 0 }
406 /* Signal mode change */
407 compdata->screenmodeid = modeid;
408 compdata->modeschanged = TRUE;
410 /* Get gray foregound */
411 if (found_depth < 24)
412 gctags[0].ti_Data = 0x9492;
414 OOP_SetAttrs(compdata->gc, gctags);
418 static inline void HIDDCompositorRedrawBitmap(struct HIDDCompositorData *compdata, struct StackBitMapNode *n, struct Rectangle *rect)
420 /* The given rectangle is already in screen coordinate system here */
421 ULONG blitwidth = rect->MaxX - rect->MinX + 1;
422 ULONG blitheight = rect->MaxY - rect->MinY + 1;
424 DREDRAWBM(bug("[Compositor:%s] Redraw BitMap 0x%p, Rect[%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, n->bm,
425 rect->MinX, rect->MinY, rect->MaxX, rect->MaxY));
426 DREDRAWBM(bug("[Compositor:%s] Blitting %dx%d [from %d, %d]\n", __PRETTY_FUNCTION__, blitwidth, blitheight,
427 rect->MinX - n->leftedge, rect->MinY - n->topedge));
429 HIDD_Gfx_CopyBox(compdata->gfx, n->bm,
430 /* Transform to source bitmap coord system */
431 rect->MinX - n->leftedge, rect->MinY - n->topedge,
432 compdata->compositedbitmap,
433 rect->MinX, rect->MinY, blitwidth, blitheight,
434 compdata->gc);
437 static inline void ClearRect(struct HIDDCompositorData *compdata, ULONG MinX, ULONG MinY, ULONG MaxX, ULONG MaxY)
439 DREDRAWSCR(bug("[Compositor:%s] Clearing [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__,
440 MinX, MinY, MaxX, MaxY));
442 HIDD_BM_FillRect(compdata->compositedbitmap, compdata->gc,
443 MinX, MinY, MaxX, MaxY);
446 static VOID HIDDCompositorRedrawVisibleDisplay(struct HIDDCompositorData *compdata)
448 struct Region *dispvisregion = NULL;
449 struct Rectangle tmprect;
451 struct StackBitMapNode *n;
453 DREDRAWSCR(bug("[Compositor:%s] Redrawing screen (GfxBase @ 0x%p)\n", __PRETTY_FUNCTION__, GfxBase));
455 /* Recalculate visible regions */
456 HIDDCompositorRecalculateVisibleRegions(compdata);
458 if ((dispvisregion = NewRegion()) != NULL)
460 OrRectRegion(dispvisregion, &compdata->screenrect);
461 DRECALC(bug("[Compositor:%s] Display rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, _RECT(compdata->screenrect)));
463 ForeachNode(&compdata->bitmapstack, n)
465 if ((n->sbmflags & STACKNODE_VISIBLE) &&
466 (!(n->sbmflags & STACKNODE_ALPHA)) &&
467 (n->screenregion))
469 DREDRAWSCR(bug("[Compositor:%s] ScreenRegion @ 0x%p ScreenBitMap @ 0x%p [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__,
470 n->screenregion, n->bm, _RECT(n->screenvisiblerect)));
472 DREDRAWSCR(bug("[Compositor:%s] Redrawing Visible Screen Regions..\n", __PRETTY_FUNCTION__));
473 // Render the visable regions ..
474 struct RegionRectangle * srrect = n->screenregion->RegionRectangle;
475 while (srrect)
477 tmprect.MinX = srrect->bounds.MinX + n->screenregion->bounds.MinX;
478 tmprect.MinY = srrect->bounds.MinY + n->screenregion->bounds.MinY;
479 tmprect.MaxX = srrect->bounds.MaxX + n->screenregion->bounds.MinX;
480 tmprect.MaxY = srrect->bounds.MaxY + n->screenregion->bounds.MinY;
482 DREDRAWSCR(bug("[Compositor:%s] Region [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, _RECT(&tmprect)));
484 HIDDCompositorRedrawBitmap(compdata, n, &tmprect);
485 HIDD_BM_UpdateRect(compdata->compositedbitmap,
486 tmprect.MinX, tmprect.MinY,
487 tmprect.MaxX - tmprect.MinX + 1,
488 tmprect.MaxY - tmprect.MinY + 1);
490 srrect = srrect->Next;
492 ClearRegionRegion(n->screenregion, dispvisregion);
495 struct RegionRectangle * dispclrrect = dispvisregion->RegionRectangle;
496 while (dispclrrect)
498 struct HIDD_BackFillHookMsg clearmsg;
500 tmprect.MinX = dispclrrect->bounds.MinX + dispvisregion->bounds.MinX;
501 tmprect.MinY = dispclrrect->bounds.MinY + dispvisregion->bounds.MinY;
502 tmprect.MaxX = dispclrrect->bounds.MaxX + dispvisregion->bounds.MinX;
503 tmprect.MaxY = dispclrrect->bounds.MaxY + dispvisregion->bounds.MinY;
505 DREDRAWSCR(bug("[Compositor:%s] Render Display Void Region [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, _RECT(&tmprect)));
507 clearmsg.bounds = &tmprect;
508 clearmsg.offsetx = 0;
509 clearmsg.offsety = 0;
510 CallHookPkt(compdata->backfillhook, compdata->compositedbitmap, &clearmsg);
511 HIDD_BM_UpdateRect(compdata->compositedbitmap,
512 tmprect.MinX, tmprect.MinY,
513 tmprect.MaxX - tmprect.MinX + 1,
514 tmprect.MaxY - tmprect.MinY + 1);
516 dispclrrect = dispclrrect->Next;
518 ForeachNode(&compdata->bitmapstack, n)
520 if ((n->sbmflags & STACKNODE_VISIBLE) &&
521 (n->sbmflags & STACKNODE_ALPHA) &&
522 (n->screenregion))
524 DREDRAWSCR(bug("[Compositor:%s] ALPHAScreenRegion @ 0x%p ScreenBitMap @ 0x%p [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__,
525 n->screenregion, n->bm, _RECT(n->screenvisiblerect)));
528 DisposeRegion(dispvisregion);
534 There are several cases that needs to be handled in this code. They are documented
535 below. Please read it before making changes.
536 etb = existing topbitmap
537 ntb = new top bitmap
538 sb = screen bitmap
539 cb = composited bitmap
540 fs = covers full screen
541 nfs = not covers full screen
542 mA = mode "A"
543 mB = mode "B"
544 disp() = dispose
545 new() = new
547 The resulting mode is always that of screen bitmap as set in "effect" column.
548 The composited bitmap always matches the resulting screen mode or is NULL.
550 | exiting screen situation | change | effect |
551 | USE CASE: SWITCHING BETWEEN FULL SCREEN SCREENS - SAME MODE |
552 | etb->fs, mA, sb==etb, cb==NULL | ntb->fs, mA | sb==ntb, cb==NULL |
553 | etb->fs, mA, sb==etb, cb!=NULL | ntb->fs, mA | sb==ntb, cb!=NULL |
554 | USE CASE: SWITCHING BETWEEN FULL SCREEN AND NOT FULL SCREEN SCREENS - SAME MODE |
555 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mA | new(cb), sb==cb, cb!=NULL |
556 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mA | sb==cb, cb!=NULL |
557 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND FULL SCREEN SCREENS - SAME MODE |
558 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
559 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mA | sb==ntb, cb!=NULL |
560 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND NOT FULL SCREEN SCREENS - SAME MODE |
561 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
562 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->nfs, mA | sb==cb, cb!=NULL |
565 | USE CASE: SWITCHING BETWEEN FULL SCREEN SCREENS - DIFFERENT MODES |
566 | etb->fs, mA, sb==etb, cb==NULL | ntb->fs, mB | sb==ntb, cb==NULL |
567 | etb->fs, mA, sb==etb, cb!=NULL | ntb->fs, mB | disp(cb), sb==ntb, cb==NULL |
568 | USE CASE: SWITCHING BETWEEN FULL SCREEN AND NOT FULL SCREEN SCREENS - DIFFERENT MODES |
569 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mB | new(cb), sb==cb, cb!=NULL |
570 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mB | disp(cb), new(cb), sb==cb, cb!=NULL |
571 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND FULL SCREEN SCREENS - DIFFERENT MODES |
572 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
573 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mB | disp(cb), sb==ntb, cb==NULL |
574 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND NOT FULL SCREEN SCREENS - DIFFERENT MODES |
575 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
576 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->nfs, mB | disp(cb), new(cb), sb==cb, cb!=NULL |
579 | USE CASE: DRAGGING SCREEN DOWN |
580 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mA | new(cb), sb==cb |
581 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mA | sb==cb |
582 | USE CASE: DRAGGING SCREEN UP |
583 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mA | sb==etb |
584 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
586 Resulting rules (order matters):
588 (a) if ((cb!=NULL) && (etb->mode!=ntb->mode)) {dispose(cb), cb=NULL}
589 (b) if ((ntb->nfs) && (cb==NULL)) new(cb)
590 (c) if (ntb->nfs) sb=cb
591 (d) if (ntb->fs) sb=ntb
593 Additional rule:
594 (e) if (oldsb!=sb) modeswitch(sb)
596 02.09.2011: we don't remember sb any more because we don't handle it in any way. Instead
597 we either have or don't have compositedbitmap. If we have it, composition
598 is on (sb = cb). If we don't have it, composition is off (sb = ntb).
600 static BOOL HIDDCompositorToggleCompositing(struct HIDDCompositorData *compdata, BOOL newtop)
603 * If the topbitmap covers the complete screen, show it instead of
604 * compositedbitmap. Remember that screen bitmap -> composited bitmap
605 * mirroring has a negative impact on performance.
607 OOP_Object *oldcompositedbitmap = compdata->compositedbitmap;
608 OOP_Object *newscreenbitmap = NULL;
609 BOOL ok = TRUE;
611 /* (a) If mode change is needed, enforce opening a new screen */
612 if (compdata->modeschanged)
614 D(bug("[Compositor:%s] Display Mode changed\n", __PRETTY_FUNCTION__));
615 compdata->compositedbitmap = NULL;
618 #if (0)
620 * This condition is enough as compositing allows only dragging screen down
621 * and not up/left/right at the moment.
623 if (topedge > 0)
625 #endif
626 /* (b) */
627 if (compdata->compositedbitmap == NULL)
630 * compositedbitmap == NULL means we were in passthrough mode before,
631 * or have just changed display mode - set up screen for composition.
633 D(bug("[Compositor:%s] Initialising Display-Compositor..\n", __PRETTY_FUNCTION__));
635 if (compdata->fb)
638 * If our display driver uses a framebuffer, we can reuse it.
639 * Copy its original contents back into the bitmap which it replaced,
640 * then change framebuffer's video mode.
641 * Framebuffer is the only bitmap which can change its ModeID on the fly.
643 D(bug("[Compositor:%s] Using Display Famebuffer BitMap @ 0x%p\n", __PRETTY_FUNCTION__, compdata->fb));
645 /* Do this comparison in order not to show the framebuffer twice */
646 if (oldcompositedbitmap != compdata->fb)
649 * 1. It's legal to show the framebuffer itself. This causes copying
650 * back old bitmap contents and detaching from it.
651 * 2. The result of this will always match compdata->fb.
652 * 3. Internally this is a simple blit operation, it can't fail.
654 D(bug("[Compositor:%s] Copying old Famebuffer BitMap\n", __PRETTY_FUNCTION__));
655 compdata->screenbitmap = HIDD_Gfx_Show(compdata->gfx, compdata->fb, fHidd_Gfx_Show_CopyBack);
658 /* Switch display mode on the framebuffer. */
659 OOP_SetAttrsTags(compdata->fb, aHidd_BitMap_ModeID, compdata->screenmodeid, TAG_DONE);
660 /* We are now compositing on the framebuffer */
661 compdata->compositedbitmap = compdata->fb;
663 else
666 * There's no framebuffer.
667 * Create a new bitmap that will be used for compositing.
669 struct TagItem bmtags[5];
671 bmtags[0].ti_Tag = aHidd_BitMap_Width; bmtags[0].ti_Data = compdata->screenrect.MaxX + 1;
672 bmtags[1].ti_Tag = aHidd_BitMap_Height; bmtags[1].ti_Data = compdata->screenrect.MaxY + 1;
673 bmtags[2].ti_Tag = aHidd_BitMap_Displayable; bmtags[2].ti_Data = TRUE;
674 bmtags[3].ti_Tag = aHidd_BitMap_ModeID; bmtags[3].ti_Data = compdata->screenmodeid;
675 bmtags[4].ti_Tag = TAG_DONE; bmtags[4].ti_Data = TAG_DONE;
677 compdata->compositedbitmap = HIDD_Gfx_NewBitMap(compdata->gfx, bmtags);
678 D(bug("[Compositor:%s] Created Compositor Display BitMap @ 0x%p\n", __PRETTY_FUNCTION__, compdata->compositedbitmap));
680 /* Mode changed, this bitmap will be shown later */
681 newscreenbitmap = compdata->compositedbitmap;
683 /* NewBitMap can fail, handle this */
684 if (!newscreenbitmap)
685 ok = FALSE;
688 else /* if (compdata->compositedbitmap == NULL) */
691 * We are already in compositing mode and will stay in it.
692 * Do not destroy our working bitmap.
694 oldcompositedbitmap = NULL;
698 * (c) Here composition is turned on (compositedbitmap != NULL).
699 * Redraw bitmap stack - compensate possible changes
701 if (ok)
702 HIDDCompositorRedrawVisibleDisplay(compdata);
703 #if(0)
705 else if (oldcompositedbitmap || newtop)
708 * (d) Set passthrough mode and display the frontmost bitmap.
709 * This is also triggered by 'newtop' parameter, which tells us
710 * that frontmost bitmap has been changed, and we need to display a new one.
711 * Old compositedbitmap has been remembered in the beginning. If it's not
712 * NULL, it will be destroyed in the end.
714 newscreenbitmap = compdata->topbitmap;
715 compdata->compositedbitmap = NULL;
717 #endif
719 DTOGGLE(bug("[Compositor:%s] oldcompbmp 0x%p, topbmp 0x%p, compbmp 0x%p, newscreenbmp 0x%p\n", __PRETTY_FUNCTION__,
720 oldcompositedbitmap, compdata->topbitmap, compdata->compositedbitmap, newscreenbitmap));
723 * (e) If the screenbitmap changed, show the new screenbitmap.
724 * We do it after refreshing, for better visual appearance.
726 if (newscreenbitmap)
728 IPTR w, h;
730 compdata->screenbitmap = HIDD_Gfx_Show(compdata->gfx, newscreenbitmap, fHidd_Gfx_Show_CopyBack);
731 D(bug("[Compositor:%s] Displayed bitmap 0x%p, Show returned 0x%p\n", __PRETTY_FUNCTION__, newscreenbitmap, compdata->screenbitmap));
733 /* After Show we need Update for mirroring drivers */
734 if (compdata->screenbitmap)
736 OOP_GetAttr(compdata->screenbitmap, aHidd_BitMap_Width, &w);
737 OOP_GetAttr(compdata->screenbitmap, aHidd_BitMap_Height, &h);
738 HIDD_BM_UpdateRect(compdata->screenbitmap, 0, 0, w, h);
743 * (a) - disposing of oldcompositingbitmap needs to happen after mode switch
744 * since it could have been the current screenbitmap
746 if (oldcompositedbitmap && (oldcompositedbitmap != compdata->fb))
748 D(bug("[Compositor:%s] Disposing old working bitmap 0x%p\n", __PRETTY_FUNCTION__, oldcompositedbitmap));
749 HIDD_Gfx_DisposeBitMap(compdata->gfx, oldcompositedbitmap);
752 /* Handled */
753 compdata->modeschanged = FALSE;
755 return ok;
758 static VOID HIDDCompositorPurgeBitMapStack(struct HIDDCompositorData * compdata)
760 struct StackBitMapNode * curr, * next;
762 ForeachNodeSafe(&compdata->bitmapstack, curr, next)
764 if (curr->screenregion)
765 DisposeRegion(curr->screenregion);
767 FreeMem(curr, sizeof(struct StackBitMapNode));
770 NEWLIST(&compdata->bitmapstack);
773 static void HIDDCompositorShowSingle(struct HIDDCompositorData *compdata, OOP_Object *bm)
775 /* Show the single top bitmap */
776 compdata->topbitmap = bm;
777 compdata->screenbitmap = HIDD_Gfx_Show(compdata->gfx, bm, fHidd_Gfx_Show_CopyBack);
779 /* Dispose working bitmap (if any) */
780 if (compdata->compositedbitmap)
782 /* Be careful with the framebuffer */
783 if (compdata->compositedbitmap != compdata->fb)
784 HIDD_Gfx_DisposeBitMap(compdata->gfx, compdata->compositedbitmap);
786 /* This will deactivate us */
787 compdata->compositedbitmap = NULL;
791 /* Emergency error recovery function */
792 static void HIDDCompositorReset(struct HIDDCompositorData *compdata)
794 /* Purge bitmap stack */
795 HIDDCompositorPurgeBitMapStack(compdata);
798 * Reset our internal state so that next BitMapStackChanged
799 * causes complete reinitialization.
801 compdata->screenmodeid = vHidd_ModeID_Invalid;
802 compdata->screenbitmap = NULL;
805 VOID CompositorParseConfig(struct HIDDCompositorData *compdata)
807 struct RDArgs *rdargs;
808 IPTR CompArgs[NOOFARGS] = { 0 };
809 TEXT CompConfig[1024];
811 /* use default amiga-like capabailities */
812 compdata->capabilities = COMPF_ABOVE;
814 rdargs = AllocDosObjectTags(DOS_RDARGS, TAG_END);
815 if (rdargs != NULL)
817 if (GetVar(COMPOSITE_PREFS, CompConfig, 1024, GVF_GLOBAL_ONLY) != -1)
819 rdargs->RDA_Source.CS_Buffer = CompConfig;
820 rdargs->RDA_Source.CS_Length = strlen(rdargs->RDA_Source.CS_Buffer);
821 rdargs->RDA_DAList = (IPTR)NULL;
822 rdargs->RDA_Buffer = NULL;
823 rdargs->RDA_BufSiz = 0;
824 rdargs->RDA_ExtHelp = NULL;
825 rdargs->RDA_Flags = 0;
827 if (ReadArgs(COMPOSITE_PEFSTEMPLATE, CompArgs, rdargs) != NULL)
829 if (CompArgs[ARG_ABOVE])
830 compdata->capabilities |= COMPF_ABOVE;
831 else
832 compdata->capabilities &= ~COMPF_ABOVE;
834 if (CompArgs[ARG_BELOW])
835 compdata->capabilities |= COMPF_BELOW;
836 else
837 compdata->capabilities &= ~COMPF_BELOW;
839 if (CompArgs[ARG_LEFT])
840 compdata->capabilities |= COMPF_LEFT;
841 else
842 compdata->capabilities &= ~COMPF_LEFT;
844 if (CompArgs[ARG_RIGHT])
845 compdata->capabilities |= COMPF_RIGHT;
846 else
847 compdata->capabilities &= ~COMPF_RIGHT;
849 if (CompArgs[ARG_ALPHA])
850 compdata->capabilities |= COMPF_ALPHA;
851 else
852 compdata->capabilities &= ~COMPF_ALPHA;
854 FreeArgs(rdargs);
857 FreeDosObject(DOS_RDARGS, rdargs);
861 AROS_UFH3(void, CompositorDefaultBackFillFunc,
862 AROS_UFHA(struct Hook * , h, A0),
863 AROS_UFHA(OOP_Object * , bm, A2),
864 AROS_UFHA(struct HIDD_BackFillHookMsg * , msg, A1))
866 AROS_USERFUNC_INIT
868 struct HIDDCompositorData *compdata = h->h_Data;
870 D(bug("[%s] HIDDCompositorData @ 0x%p\n", __PRETTY_FUNCTION__, compdata));
872 ClearRect(compdata, msg->bounds->MinX, msg->bounds->MinY, msg->bounds->MaxX, msg->bounds->MaxY);
874 AROS_USERFUNC_EXIT
877 /* PUBLIC METHODS */
878 OOP_Object *METHOD(Compositor, Root, New)
880 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
882 if (o)
884 OOP_MethodID disposemid;
885 struct HIDDCompositorData *compdata = OOP_INST_DATA(cl, o);
887 D(bug("[%s] Compositor @ 0x%p, data @ 0x%p\n", __PRETTY_FUNCTION__, o, compdata));
889 CompositorParseConfig(compdata);
891 D(bug("[%s] Composite Capabilities: %08lx\n", __PRETTY_FUNCTION__, compdata->capabilities));
893 compdata->screenmodeid = vHidd_ModeID_Invalid;
895 NEWLIST(&compdata->bitmapstack);
897 compdata->defaultbackfill.h_Entry = (HOOKFUNC)AROS_ASMSYMNAME(CompositorDefaultBackFillFunc);
898 compdata->defaultbackfill.h_Data = compdata;
899 compdata->backfillhook = &compdata->defaultbackfill;
901 InitSemaphore(&compdata->semaphore);
903 compdata->gfx = (OOP_Object *)GetTagData(aHidd_Compositor_GfxHidd, 0, msg->attrList);
904 compdata->fb = (OOP_Object *)GetTagData(aHidd_Compositor_FrameBuffer, 0, msg->attrList);
906 compdata->GraphicsBase = (APTR)OpenLibrary("graphics.library", 41);
908 /* GfxHidd is mandatory */
909 if ((compdata->GraphicsBase) && (compdata->gfx != NULL))
911 /* Create GC object that will be used for drawing operations */
912 compdata->gc = HIDD_Gfx_NewGC(compdata->gfx, NULL);
914 D(bug("[%s] Compositor GC @ %p\n", __PRETTY_FUNCTION__, compdata->gc));
916 if ((compdata->gfx) && (compdata->gc))
917 return o;
920 /* Creation failed */
921 disposemid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
922 OOP_CoerceMethod(cl, o, &disposemid);
925 return NULL;
928 void METHOD(Compositor, Root, Dispose)
932 struct HIDDCompositorData *compdata = OOP_INST_DATA(cl, o);
933 bug("[%s] HIDDCompositorData @ 0x%p\n", __PRETTY_FUNCTION__, compdata);
936 OOP_DoSuperMethod(cl, o, &msg->mID);
939 VOID METHOD(Compositor, Root, Get)
941 ULONG idx;
943 struct HIDDCompositorData *compdata = OOP_INST_DATA(cl, o);
945 if (IS_COMPOSITOR_ATTR(msg->attrID, idx))
947 switch (idx)
949 case aoHidd_Compositor_Capabilities:
951 D(bug("[%s] Composite Capabilities: %lx\n", __PRETTY_FUNCTION__, compdata->capabilities));
952 *msg->storage = (IPTR)COMPF_ABOVE|COMPF_BELOW|COMPF_LEFT|COMPF_RIGHT;
953 return;
955 case aoHidd_Compositor_BackFillHook:
957 D(bug("[%s] BackFillHook: 0x%p\n", __PRETTY_FUNCTION__, compdata->backfillhook));
958 *msg->storage = (IPTR)compdata->backfillhook;
959 return;
963 OOP_DoSuperMethod(cl, o, &msg->mID);
966 VOID METHOD(Compositor, Root, Set)
968 ULONG idx;
970 struct HIDDCompositorData *compdata = OOP_INST_DATA(cl, o);
971 struct TagItem *tag, *tstate = msg->attrList;
973 while ((tag = NextTagItem(&tstate)))
975 if (IS_COMPOSITOR_ATTR(tag->ti_Tag, idx))
977 switch (idx)
979 case aoHidd_Compositor_Capabilities:
981 D(bug("[%s] Composite Capabilities: %lx -> %lx\n", __PRETTY_FUNCTION__, compdata->capabilities, tag->ti_Data));
982 compdata->capabilities = (ULONG)tag->ti_Data;
983 break;
985 case aoHidd_Compositor_BackFillHook:
987 if (tag->ti_Data)
989 D(bug("[%s] BackFillHook: 0x%p -> 0x%p\n", __PRETTY_FUNCTION__, compdata->backfillhook, tag->ti_Data));
990 compdata->backfillhook = (struct Hook *)tag->ti_Data;
992 else
994 D(bug("[%s] Default BackFillHook\n", __PRETTY_FUNCTION__));
995 compdata->backfillhook = &compdata->defaultbackfill;
997 break;
1003 OOP_DoSuperMethod(cl, o, &msg->mID);
1006 OOP_Object *METHOD(Compositor, Hidd_Compositor, BitMapStackChanged)
1008 struct HIDD_ViewPortData *vpdata;
1009 struct HIDDCompositorData *compdata = OOP_INST_DATA(cl, o);
1010 struct StackBitMapNode *n;
1011 BOOL newtop = FALSE;
1012 BOOL ok = TRUE;
1014 DSTACK(bug("[%s] Top bitmap: 0x%lx\n", __PRETTY_FUNCTION__, msg->data->Bitmap));
1016 LOCK_COMPOSITOR_WRITE
1018 /* Free all items which are already on the list */
1019 HIDDCompositorPurgeBitMapStack(compdata);
1021 if (!msg->data)
1023 UNLOCK_COMPOSITOR
1025 /* Blank screen */
1026 HIDDCompositorShowSingle(compdata, NULL);
1028 /* We know we are inactive after this */
1029 *msg->active = FALSE;
1030 /* This can return NULL, it's okay */
1031 return compdata->screenbitmap;
1034 /* Copy bitmaps pointers to our stack */
1035 for (vpdata = msg->data; vpdata; vpdata = vpdata->Next)
1037 n = AllocMem(sizeof(struct StackBitMapNode), MEMF_ANY | MEMF_CLEAR);
1038 if (!n)
1041 * Error happened.
1042 * We need to reset own state and return NULL. graphics.library
1043 * falls back to no composition in this case.
1045 DSTACK(bug("[%s] Error allocating StackBitMapNode!!!\n", __PRETTY_FUNCTION__));
1047 ok = FALSE;
1048 break;
1051 DSTACK(bug("[%s] ViewPort 0x%p, offset (%d, %d)\n", __PRETTY_FUNCTION__, vpdata->vpe->ViewPort, vpdata->vpe->ViewPort->DxOffset, vpdata->vpe->ViewPort->DyOffset));
1053 n->bm = vpdata->Bitmap;
1054 n->sbmflags = 0;
1055 n->leftedge = vpdata->vpe->ViewPort->DxOffset;
1056 n->topedge = vpdata->vpe->ViewPort->DyOffset;
1058 AddTail((struct List *)&compdata->bitmapstack, (struct Node *)n);
1061 /* Switch mode if needed */
1062 UpdateDisplayMode(compdata);
1064 if (msg->data->Bitmap != compdata->topbitmap)
1066 /* Set the new pointer to top bitmap */
1067 compdata->topbitmap = msg->data->Bitmap;
1068 newtop = TRUE;
1071 if (ok)
1074 * Validate bitmap offsets - they might not match the compositing rules taking
1075 * new displayedwidth/displayedheight values
1077 ForeachNode(&compdata->bitmapstack, n)
1079 HIDDCompositorValidateBitMapPositionChange(n->bm, &n->leftedge, &n->topedge,
1080 compdata->screenrect.MaxX + 1, compdata->screenrect.MaxY + 1);
1081 DSTACK(bug("[%s] Bitmap 0x%p, display size %d x %d, validated position (%ld, %ld)\n", __PRETTY_FUNCTION__,
1082 n->bm, compdata->screenrect.MaxX + 1, compdata->screenrect.MaxY + 1,
1083 n->leftedge, n->topedge));
1086 /* Toogle compositing based on screen positions */
1087 ok = HIDDCompositorToggleCompositing(compdata, newtop);
1090 /* Handle error */
1091 if (!ok)
1093 HIDDCompositorReset(compdata);
1094 HIDDCompositorShowSingle(compdata, msg->data->Bitmap);
1097 UNLOCK_COMPOSITOR
1099 DSTACK(bug("[%s] Done, composited bitmap 0x%p\n", __PRETTY_FUNCTION__, compdata->compositedbitmap));
1101 /* Tell if the composition is active */
1102 *msg->active = compdata->compositedbitmap ? TRUE : FALSE;
1103 /* Return actually displayed bitmap */
1104 return compdata->screenbitmap;
1107 VOID METHOD(Compositor, Hidd_Compositor, BitMapRectChanged)
1109 struct HIDDCompositorData * compdata = OOP_INST_DATA(cl, o);
1111 if (compdata->compositedbitmap)
1113 /* Composition is active, handle redraw if the bitmap is on screen */
1114 struct StackBitMapNode *n;
1116 DUPDATE(bug("[%s] Bitmap 0x%p\n", __PRETTY_FUNCTION__, msg->bm));
1118 LOCK_COMPOSITOR_READ
1120 n = HIDDCompositorIsBitMapOnStack(compdata, msg->bm);
1121 if (n && (n->sbmflags & STACKNODE_VISIBLE))
1123 struct Rectangle srcrect, dstandvisrect;
1125 srcrect.MinX = n->leftedge + msg->x;
1126 srcrect.MinY = n->topedge + msg->y;
1127 srcrect.MaxX = n->leftedge + msg->x + msg->width - 1;
1128 srcrect.MaxY = n->topedge + msg->y + msg->height - 1;
1129 DUPDATE(bug("[%s] Bitmap rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, msg->x, msg->y, msg->x + msg->width - 1, msg->y + msg->height - 1));
1131 DUPDATE(bug("[%s] Screen-relative rect [%d, %d - %d, %d]\n", __PRETTY_FUNCTION__, _RECT(srcrect)));
1133 struct RegionRectangle * srrect = n->screenregion->RegionRectangle;
1134 while (srrect)
1136 dstandvisrect.MinX = srrect->bounds.MinX + n->screenregion->bounds.MinX;
1137 dstandvisrect.MinY = srrect->bounds.MinY + n->screenregion->bounds.MinY;
1138 dstandvisrect.MaxX = srrect->bounds.MaxX + n->screenregion->bounds.MinX;
1139 dstandvisrect.MaxY = srrect->bounds.MaxY + n->screenregion->bounds.MinY;
1141 if (AndRectRect(&srcrect, &dstandvisrect, &dstandvisrect))
1143 /* Intersection is valid. Blit. */
1144 DUPDATE(bug("[%s] Clipped rect (%d, %d) - (%d, %d)\n", __PRETTY_FUNCTION__, _RECT(dstandvisrect)));
1146 HIDDCompositorRedrawBitmap(compdata, n, &dstandvisrect);
1148 HIDD_BM_UpdateRect(compdata->compositedbitmap,
1149 dstandvisrect.MinX, dstandvisrect.MinY,
1150 dstandvisrect.MaxX - dstandvisrect.MinX + 1,
1151 dstandvisrect.MaxY - dstandvisrect.MinY + 1);
1153 srrect = srrect->Next;
1157 UNLOCK_COMPOSITOR
1159 DUPDATE(bug("[%s] Done\n", __PRETTY_FUNCTION__));
1161 else
1164 * In order to speed things up, we handle passthrough ourselves here.
1165 * It's not difficult.
1167 HIDD_BM_UpdateRect(msg->bm, msg->x, msg->y, msg->width, msg->height);
1171 IPTR METHOD(Compositor, Hidd_Compositor, BitMapPositionChange)
1173 struct HIDDCompositorData *compdata = OOP_INST_DATA(cl, o);
1174 struct StackBitMapNode *n;
1175 IPTR disp_width, disp_height;
1177 LOCK_COMPOSITOR_READ
1179 n = HIDDCompositorIsBitMapOnStack(compdata, msg->bm);
1180 if (n)
1182 /* The bitmap is on display. Validate against screen size */
1183 disp_width = compdata->screenrect.MaxX + 1;
1184 disp_height = compdata->screenrect.MaxY + 1;
1186 else
1188 /* The bitmap is not displayed yet. Validate against its own ModeID size. */
1189 HIDDT_ModeID modeid = vHidd_ModeID_Invalid;
1190 OOP_Object *sync, *pf;
1192 OOP_GetAttr(msg->bm, aHidd_BitMap_ModeID, &modeid);
1194 if (modeid == vHidd_ModeID_Invalid)
1197 * Nondisplayable bitmaps don't scroll.
1198 * In fact they simply can't get in here because MakeVPort() performs the validation.
1199 * But who knows what bug can slip into someone's software...
1201 UNLOCK_COMPOSITOR
1202 return FALSE;
1205 HIDD_Gfx_GetMode(compdata->gfx, modeid, &sync, &pf);
1206 OOP_GetAttr(sync, aHidd_Sync_HDisp, &disp_width);
1207 OOP_GetAttr(sync, aHidd_Sync_VDisp, &disp_height);
1210 DMOVE(bug("[%s] Validating bitmap 0x%p, position (%ld, %ld), limits %ld x %ld\n", __PRETTY_FUNCTION__,
1211 msg->bm, *msg->newxoffset, *msg->newyoffset, disp_width, disp_height));
1213 HIDDCompositorValidateBitMapPositionChange(msg->bm, msg->newxoffset, msg->newyoffset,
1214 disp_width, disp_height);
1216 DMOVE(bug("[%s] Validated position (%ld, %ld)\n", __PRETTY_FUNCTION__, *msg->newxoffset, *msg->newyoffset));
1218 if (n && ((*msg->newxoffset != n->leftedge) || (*msg->newyoffset != n->topedge)))
1220 DMOVE(bug("[%s] Old position (%ld, %ld)\n", __PRETTY_FUNCTION__, n->leftedge, n->topedge));
1222 /* Reflect the change if it happened */
1223 n->leftedge = *msg->newxoffset;
1224 n->topedge = *msg->newyoffset;
1226 if (compdata->topbitmap == msg->bm)
1229 * If this is the frontmost bitmap, we may want to toggle compositing,
1230 * if it starts/stops covering the whole screen at one point.
1231 * We don't need to call HIDDCompositorRedrawVisibleDisplay() here because
1232 * HIDDCompositorToggleCompositing() does this itself, for improved
1233 * visual appearance.
1235 HIDDCompositorToggleCompositing(compdata, FALSE);
1237 else
1238 HIDDCompositorRedrawVisibleDisplay(compdata);
1241 UNLOCK_COMPOSITOR
1243 /* Return active state */
1244 return compdata->compositedbitmap ? TRUE : FALSE;
1247 #define NUM_Compositor_Root_METHODS 4
1249 static const struct OOP_MethodDescr Compositor_Root_descr[] =
1251 {(OOP_MethodFunc)Compositor__Root__New, moRoot_New},
1252 {(OOP_MethodFunc)Compositor__Root__Dispose, moRoot_Dispose},
1253 {(OOP_MethodFunc)Compositor__Root__Get, moRoot_Get},
1254 {(OOP_MethodFunc)Compositor__Root__Set, moRoot_Set},
1255 {NULL, 0}
1258 #define NUM_Compositor_Hidd_Compositor_METHODS 3
1260 static const struct OOP_MethodDescr Compositor_Hidd_Compositor_descr[] =
1262 {(OOP_MethodFunc)Compositor__Hidd_Compositor__BitMapStackChanged, moHidd_Compositor_BitMapStackChanged},
1263 {(OOP_MethodFunc)Compositor__Hidd_Compositor__BitMapRectChanged, moHidd_Compositor_BitMapRectChanged},
1264 {(OOP_MethodFunc)Compositor__Hidd_Compositor__BitMapPositionChange, moHidd_Compositor_BitMapPositionChange},
1265 {NULL, 0}
1268 const struct OOP_InterfaceDescr Compositor_ifdescr[] =
1270 {Compositor_Root_descr, IID_Root, NUM_Compositor_Root_METHODS},
1271 {Compositor_Hidd_Compositor_descr, IID_Hidd_Compositor, NUM_Compositor_Hidd_Compositor_METHODS},
1272 {NULL, NULL}