2 Copyright © 2010-2017, The AROS Development Team. All rights reserved.
7 This is ment to be (in future) a generic class that will be capable of
8 compositor bitmaps on screen to get effects like screen dragging.
9 The code is generic where possible, using abstract OOP_Objects instead of
10 concrete driver structures. There are places where nouveau specific calls
11 are performed, however there are only few and can be generilized to
12 (private) methods that should be reimplemented by child classes in each of
16 /* Non generic part */
17 #include "nouveau_intern.h"
18 /* Non generic part */
20 #include "nouveau_compositor.h"
22 #include <proto/exec.h>
23 #include <aros/debug.h>
24 #include <proto/oop.h>
25 #include <proto/utility.h>
28 #undef HiddPixFmtAttrBase
29 #undef HiddSyncAttrBase
30 #undef HiddBitMapAttrBase
32 #undef HiddCompositorAttrBase
34 #define HiddPixFmtAttrBase (compdata->pixFmtAttrBase)
35 #define HiddSyncAttrBase (compdata->syncAttrBase)
36 #define HiddBitMapAttrBase (compdata->bitMapAttrBase)
37 #define HiddGCAttrBase (compdata->gcAttrBase)
38 #define HiddCompositorAttrBase (compdata->compositorAttrBase)
40 #define MAX(a,b) a > b ? a : b
41 #define MIN(a,b) a < b ? a : b
43 static BOOL
AndRectRect(struct _Rectangle
* rect1
, struct _Rectangle
* rect2
,
44 struct _Rectangle
* intersect
)
46 intersect
->MinX
= MAX(rect1
->MinX
, rect2
->MinX
);
47 intersect
->MinY
= MAX(rect1
->MinY
, rect2
->MinY
);
48 intersect
->MaxX
= MIN(rect1
->MaxX
, rect2
->MaxX
);
49 intersect
->MaxY
= MIN(rect1
->MaxY
, rect2
->MaxY
);
51 if ((intersect
->MinX
> intersect
->MaxX
) ||
52 (intersect
->MinY
> intersect
->MaxY
))
58 static struct StackBitMapNode
* HIDDCompositorIsBitMapOnStack(struct HIDDCompositorData
* compdata
, OOP_Object
* bm
)
60 struct StackBitMapNode
* n
= NULL
;
62 ForeachNode(&compdata
->bitmapstack
, n
)
71 static VOID
HIDDCompositorValidateBitMapPositionChange(struct HIDDCompositorData
* compdata
, OOP_Object
* bm
,
72 LONG
* newxoffset
, LONG
* newyoffset
)
74 struct StackBitMapNode
* n
= NULL
;
76 /* Check if passed bitmap is in stack, ignore if not */
77 if ((n
= HIDDCompositorIsBitMapOnStack(compdata
, bm
)) != NULL
)
82 OOP_GetAttr(bm
, aHidd_BitMap_Width
, &width
);
83 OOP_GetAttr(bm
, aHidd_BitMap_Height
, &height
);
85 /* Check x position */
86 limit
= n
->displayedwidth
- width
;
87 if (*(newxoffset
) > 0)
90 if (*(newxoffset
) < limit
)
91 *(newxoffset
) = limit
;
93 /* Check y position */
94 limit
= n
->displayedheight
- height
;
95 if (*(newyoffset
) > n
->displayedheight
- 15) /* Limit for drag */
96 *(newyoffset
) = n
->displayedheight
- 15;
98 if (*(newyoffset
) < limit
) /* Limit for scroll */
99 *(newyoffset
) = limit
;
104 static VOID
HIDDCompositorRecalculateVisibleRects(struct HIDDCompositorData
* compdata
)
106 ULONG lastscreenvisibleline
= compdata
->screenrect
.MaxY
;
107 struct StackBitMapNode
* n
= NULL
;
109 /* This function assumes bitmapstack is in correct Z order:
110 from top most to bottom most */
112 ForeachNode(&compdata
->bitmapstack
, n
)
114 /* Stack bitmap bounding boxes equal screen bounding box taking into
117 struct _Rectangle tmprect
;
119 OOP_GetAttr(n
->bm
, aHidd_BitMap_TopEdge
, &topedge
);
120 /* Copy screen rect */
121 tmprect
= compdata
->screenrect
;
122 /* Set bottom and top values */
123 tmprect
.MinY
= topedge
;
124 tmprect
.MaxY
= lastscreenvisibleline
;
125 /* Intersect both to make sure values are withint screen limit */
126 if (AndRectRect(&tmprect
, &compdata
->screenrect
, &n
->screenvisiblerect
))
128 lastscreenvisibleline
= n
->screenvisiblerect
.MinY
- 1;
129 n
->isscreenvisible
= TRUE
;
132 n
->isscreenvisible
= FALSE
;
134 D(bug("[Compositor] Bitmap 0x%x, visible %d, (%d, %d) , (%d, %d)\n",
135 n
->bm
, n
->isscreenvisible
,
136 n
->screenvisiblerect
.MinX
, n
->screenvisiblerect
.MinY
,
137 n
->screenvisiblerect
.MaxX
, n
->screenvisiblerect
.MaxY
));
141 static BOOL
HIDDCompositorTopBitMapChanged(struct HIDDCompositorData
* compdata
, OOP_Object
* bm
)
143 OOP_Object
* sync
= NULL
;
144 OOP_Object
* pf
= NULL
;
145 IPTR modeid
, hdisp
, vdisp
, e
, depth
;
147 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, &e
);
150 if (compdata
->gfx
!= (OOP_Object
*)e
)
152 /* Provided top bitmap is not using the same driver as compositor. Fail. */
153 D(bug("[Compositor] GfxHidd different than one used by compositor\n"));
157 /* Read display mode properties */
158 OOP_GetAttr(bm
, aHidd_BitMap_ModeID
, &modeid
);
159 if (modeid
== vHidd_ModeID_Invalid
)
161 D(bug("[Compositor] Invalid ModeID\n"));
165 /* Invalidate screen bitmap if it is set to "previous" top bitmap, since this
166 "previous" top bitmap is already gone at this point */
167 if (compdata
->screenbitmap
== compdata
->topbitmap
)
168 compdata
->screenbitmap
= NULL
;
170 /* Set the pointer to top bitmap */
171 compdata
->topbitmap
= bm
;
173 /* If the mode is already visible do nothing */
174 if (modeid
== compdata
->screenmodeid
)
177 /* The mode is different. Need to prepare information needed for compositor */
179 /* Get width and height of mode */
180 struct pHidd_Gfx_GetMode __getmodemsg
=
185 }, *getmodemsg
= &__getmodemsg
;
186 struct TagItem gctags
[] =
188 { aHidd_GC_Foreground
, (HIDDT_Pixel
)0x99999999 },
189 { TAG_DONE
, TAG_DONE
}
193 getmodemsg
->mID
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_GetMode
);
194 OOP_DoMethod(compdata
->gfx
, (OOP_Msg
)getmodemsg
);
196 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &hdisp
);
197 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &vdisp
);
198 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
200 /* Store mode information */
201 compdata
->screenmodeid
= modeid
;
202 compdata
->screenrect
.MinX
= 0;
203 compdata
->screenrect
.MinY
= 0;
204 compdata
->screenrect
.MaxX
= hdisp
- 1;
205 compdata
->screenrect
.MaxY
= vdisp
- 1;
206 compdata
->modeschanged
= TRUE
;
208 /* Get gray foregound */
209 if (depth
< 24) gctags
[0].ti_Data
= (HIDDT_Pixel
)0x9492;
211 OOP_SetAttrs(compdata
->gc
, gctags
);
217 static BOOL
HIDDCompositorCanCompositeWithScreenBitMap(struct HIDDCompositorData
* compdata
, OOP_Object
* bm
)
219 OOP_Object
* screenbm
= compdata
->topbitmap
; /* Tread top bitmap as screen bitmap */
220 IPTR screenbmwidth
, screenbmheight
, screenbmstdpixfmt
;
221 IPTR bmgfx
, bmmodeid
, bmwidth
, bmheight
, bmstdpixfmt
;
225 /* These two values cannot be obtained from topbitmap width/height, because
226 those can be larger than screen mode values and we are interested exaclty
227 in screen mode height/width */
228 screenbmwidth
= compdata
->screenrect
.MaxX
+ 1;
229 screenbmheight
= compdata
->screenrect
.MaxY
+ 1;
230 OOP_GetAttr(screenbm
, aHidd_BitMap_PixFmt
, &pf
);
231 OOP_GetAttr((OOP_Object
*)pf
, aHidd_PixFmt_StdPixFmt
, &screenbmstdpixfmt
);
236 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, &bmgfx
);
237 OOP_GetAttr(bm
, aHidd_BitMap_ModeID
, &bmmodeid
);
238 OOP_GetAttr(bm
, aHidd_BitMap_Width
, &bmwidth
);
239 OOP_GetAttr(bm
, aHidd_BitMap_Height
, &bmheight
);
240 OOP_GetAttr(bm
, aHidd_BitMap_PixFmt
, &pf
);
241 OOP_GetAttr((OOP_Object
*)pf
, aHidd_PixFmt_StdPixFmt
, &bmstdpixfmt
);
244 /* If bm uses different instances of gfx hidd than screenbm(=composing), they cannot be composited */
245 if (compdata
->gfx
!= (OOP_Object
*)bmgfx
)
248 /* If bitmaps have the same modeid, they can be composited */
249 if (compdata
->screenmodeid
== bmmodeid
)
252 /* If bitmaps have different pixel formats, they cannot be composited */
253 /* FIXME: actually they can, but CopyBox for different formats is not
254 optimized so let's not make user experience worse */
255 if (screenbmstdpixfmt
!= bmstdpixfmt
)
258 /* If screenbm is not bigger than bm, bitmaps can be composited, because
259 bm will start scrolling on smaller resolution of screenbm */
260 /* FIXME: the opposite situation might also work - smaller bitmap on bigger
261 resolution. In such case, left out areas need to be cleared up. Also it
262 needs to be checked if mouse clicks outside of bitmap will not cause
264 if ((screenbmwidth
<= bmwidth
) && (screenbmheight
<= bmheight
))
267 /* Last decision, bitmaps cannot be composited */
271 static VOID
HIDDCompositorRedrawBitmap(struct HIDDCompositorData
* compdata
,
272 OOP_Object
* bm
, WORD x
, WORD y
, WORD width
, WORD height
)
274 struct StackBitMapNode
* n
= NULL
;
276 /* Check if compositedbitmap is being displayed right now */
277 if (compdata
->screenbitmap
!= compdata
->compositedbitmap
)
280 /* Check if passed bitmap is in stack, ignore if not */
281 if ((n
= HIDDCompositorIsBitMapOnStack(compdata
, bm
)) == NULL
)
284 if (!n
->isscreenvisible
)
287 if (compdata
->compositedbitmap
)
289 IPTR leftedge
, topedge
;
290 struct _Rectangle srcrect
;
291 struct _Rectangle srcindstrect
;
292 struct _Rectangle dstandvisrect
;
294 OOP_GetAttr(bm
, aHidd_BitMap_LeftEdge
, &leftedge
);
295 OOP_GetAttr(bm
, aHidd_BitMap_TopEdge
, &topedge
);
297 /* Rectangle in source bitmap coord system */
300 srcrect
.MaxX
= x
+ width
- 1;
301 srcrect
.MaxY
= y
+ height
- 1;
303 /* Source bitmap rectangle in destination (screen) coord system */
304 srcindstrect
.MinX
= srcrect
.MinX
+ leftedge
;
305 srcindstrect
.MaxX
= srcrect
.MaxX
+ leftedge
;
306 srcindstrect
.MinY
= srcrect
.MinY
+ topedge
;
307 srcindstrect
.MaxY
= srcrect
.MaxY
+ topedge
;
309 /* Find intersection of bitmap visible screen rect and srcindst rect */
310 if (AndRectRect(&srcindstrect
, &n
->screenvisiblerect
, &dstandvisrect
))
312 /* Intersection is valid. Blit. */
317 /* Transform back to source bitmap coord system */
318 dstandvisrect
.MinX
- leftedge
, dstandvisrect
.MinY
- topedge
,
319 compdata
->compositedbitmap
,
320 dstandvisrect
.MinX
, dstandvisrect
.MinY
,
321 dstandvisrect
.MaxX
- dstandvisrect
.MinX
+ 1,
322 dstandvisrect
.MaxY
- dstandvisrect
.MinY
+ 1,
328 static VOID
HIDDCompositorRedrawVisibleScreen(struct HIDDCompositorData
* compdata
)
330 struct StackBitMapNode
* n
= NULL
;
331 ULONG lastscreenvisibleline
= compdata
->screenrect
.MaxY
;
333 /* Calculations are performed regardless if compositedbitmap is beeing show.
334 Gfx operations are only performed if compositedbitmap is beeing show */
336 /* Recalculate visible rects per screen */
337 HIDDCompositorRecalculateVisibleRects(compdata
);
339 /* Refresh all bitmaps on stack */
340 ForeachNode(&compdata
->bitmapstack
, n
)
342 if (n
->isscreenvisible
)
345 OOP_GetAttr(n
->bm
, aHidd_BitMap_Width
, &width
);
346 OOP_GetAttr(n
->bm
, aHidd_BitMap_Height
, &height
);
348 HIDDCompositorRedrawBitmap(compdata
, n
->bm
, 0, 0, width
, height
);
349 if (lastscreenvisibleline
> n
->screenvisiblerect
.MinY
)
350 lastscreenvisibleline
= n
->screenvisiblerect
.MinY
;
354 /* Clean up area revealed by drag */
355 /* TODO: Find all areas which might have been releaved, not only top -
356 This will happen when there are bitmaps of different sizes composited */
357 if ((compdata
->screenbitmap
== compdata
->compositedbitmap
) && (lastscreenvisibleline
> 1))
359 HIDD_BM_FillRect(compdata
->compositedbitmap
,
360 compdata
->gc
, 0, 0, compdata
->screenrect
.MaxX
, lastscreenvisibleline
- 1);
366 There are several cases that needs to be handled in this code. They are documented
367 below. Please read it before making changes.
368 etb = existing topbitmap
371 cb = composited bitmap
372 fs = covers full screen
373 nfs = not covers full screen
379 The resulting mode is always that of screen bitmap as set in "effect" column.
380 The composited bitmap always matches the resulting screen mode or is NULL.
382 | exiting screen situation | change | effect |
383 | USE CASE: SWITCHING BETWEEN FULL SCREEN SCREENS - SAME MODE |
384 | etb->fs, mA, sb==etb, cb==NULL | ntb->fs, mA | sb==ntb, cb==NULL |
385 | etb->fs, mA, sb==etb, cb!=NULL | ntb->fs, mA | sb==ntb, cb!=NULL |
386 | USE CASE: SWITCHING BETWEEN FULL SCREEN AND NOT FULL SCREEN SCREENS - SAME MODE |
387 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mA | new(cb), sb==cb, cb!=NULL |
388 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mA | sb==cb, cb!=NULL |
389 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND FULL SCREEN SCREENS - SAME MODE |
390 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
391 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mA | sb==ntb, cb!=NULL |
392 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND NOT FULL SCREEN SCREENS - SAME MODE |
393 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
394 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->nfs, mA | sb==cb, cb!=NULL |
397 | USE CASE: SWITCHING BETWEEN FULL SCREEN SCREENS - DIFFERENT MODES |
398 | etb->fs, mA, sb==etb, cb==NULL | ntb->fs, mB | sb==ntb, cb==NULL |
399 | etb->fs, mA, sb==etb, cb!=NULL | ntb->fs, mB | disp(cb), sb==ntb, cb==NULL |
400 | USE CASE: SWITCHING BETWEEN FULL SCREEN AND NOT FULL SCREEN SCREENS - DIFFERENT MODES |
401 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mB | new(cb), sb==cb, cb!=NULL |
402 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mB | disp(cb), new(cb), sb==cb, cb!=NULL |
403 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND FULL SCREEN SCREENS - DIFFERENT MODES |
404 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
405 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mB | disp(cb), sb==ntb, cb==NULL |
406 | USE CASE: SWITCHING BETWEEN NOT FULL SCREEN AND NOT FULL SCREEN SCREENS - DIFFERENT MODES |
407 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
408 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->nfs, mB | disp(cb), new(cb), sb==cb, cb!=NULL |
411 | USE CASE: DRAGGING SCREEN DOWN |
412 | etb->fs, mA, sb==etb, cb==NULL | ntb->nfs, mA | new(cb), sb==cb |
413 | etb->fs, mA, sb==etb, cb!=NULL | ntb->nfs, mA | sb==cb |
414 | USE CASE: DRAGGING SCREEN UP |
415 | etb->nfs, mA, sb==cb, cb!=NULL | ntb->fs, mA | sb==etb |
416 | etb->nfs, mA, sb==cb, cb==NULL | NOT POSSIBLE |
418 Resulting rules (order matters):
420 (a) if ((cb!=NULL) && (etb->mode!=ntb->mode)) {dispose(cb), cb=NULL}
421 (b) if ((ntb->nfs) && (cb==NULL)) new(cb)
422 (c) if (ntb->nsf) sb=cb
423 (d) if (ntb->fs) sb=ntb
426 (e) if (oldsb!=sb) modeswitch(sb)
429 static VOID
HIDDCompositorToggleCompositing(struct HIDDCompositorData
* compdata
)
431 /* If the topbitmap covers the complete screen, show it instead of
432 compositedbitmap. This removes the need for copying
433 screen bitmap -> composited bitmap. Not copying improves performance */
435 OOP_Object
* oldscreenbitmap
= compdata
->screenbitmap
;
436 OOP_Object
* oldcompositedbitmap
= NULL
;
438 OOP_GetAttr(compdata
->topbitmap
, aHidd_BitMap_TopEdge
, &topedge
);
441 if ((compdata
->compositedbitmap
) && (compdata
->modeschanged
))
443 oldcompositedbitmap
= compdata
->compositedbitmap
;
444 compdata
->compositedbitmap
= NULL
;
448 /* This condition is enough as compositor allows only dragging screen down
449 and not up/left/right */
450 if ((LONG
)topedge
> (LONG
)0) /* Explicitly cast to get signed comparison */
453 if (compdata
->compositedbitmap
== NULL
)
455 struct TagItem bmtags
[5];
457 /* Create a new bitmap that will be used for compositor */
458 bmtags
[0].ti_Tag
= aHidd_BitMap_Width
; bmtags
[0].ti_Data
= compdata
->screenrect
.MaxX
+ 1;
459 bmtags
[1].ti_Tag
= aHidd_BitMap_Height
; bmtags
[1].ti_Data
= compdata
->screenrect
.MaxY
+ 1;
460 bmtags
[2].ti_Tag
= aHidd_BitMap_Displayable
; bmtags
[2].ti_Data
= TRUE
;
461 bmtags
[3].ti_Tag
= aHidd_BitMap_ModeID
; bmtags
[3].ti_Data
= compdata
->screenmodeid
;
462 bmtags
[4].ti_Tag
= TAG_DONE
; bmtags
[4].ti_Data
= TAG_DONE
;
464 compdata
->compositedbitmap
= HIDD_Gfx_CreateObject(compdata
->gfx
, SD(OOP_OCLASS(compdata
->gfx
))->basebm
, bmtags
);
468 if (oldscreenbitmap
!= compdata
->compositedbitmap
)
470 compdata
->screenbitmap
= compdata
->compositedbitmap
;
472 /* Redraw bitmap stack - compensate for changes that happened while
473 compositor was not active */
474 HIDDCompositorRedrawVisibleScreen(compdata
);
480 compdata
->screenbitmap
= compdata
->topbitmap
;
483 D(bug("[Compositor] Toggle te %d, oldscr 0x%x, top 0x%x, comp 0x%x, scr 0x%x\n",
484 topedge
, oldscreenbitmap
, compdata
->topbitmap
, compdata
->compositedbitmap
,
485 compdata
->screenbitmap
));
487 /* If the screenbitmap changed, show the new screenbitmap */
489 if (oldscreenbitmap
!= compdata
->screenbitmap
)
490 HIDDNouveauSwitchToVideoMode(compdata
->screenbitmap
);
492 /* (a) - disposing of oldcompositorbitmap needs to happen after mode switch
493 since it could have been the current screenbitmap */
494 if (oldcompositedbitmap
)
495 OOP_DisposeObject(oldcompositedbitmap
);
498 compdata
->modeschanged
= FALSE
;
501 static VOID
HIDDCompositorPurgeBitMapStack(struct HIDDCompositorData
* compdata
)
503 struct StackBitMapNode
* curr
, * next
;
505 ForeachNodeSafe(&compdata
->bitmapstack
, curr
, next
)
507 Remove((struct Node
*)curr
);
508 FreeMem(curr
, sizeof(struct StackBitMapNode
));
511 NEWLIST(&compdata
->bitmapstack
);
518 OOP_Object
*METHOD(Compositor
, Root
, New
)
520 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
524 struct HIDDCompositorData
* compdata
= OOP_INST_DATA(cl
, o
);
526 struct OOP_ABDescr attrbases
[] =
528 { IID_Hidd_PixFmt
, &compdata
->pixFmtAttrBase
},
529 { IID_Hidd_Sync
, &compdata
->syncAttrBase
},
530 { IID_Hidd_BitMap
, &compdata
->bitMapAttrBase
},
531 { IID_Hidd_GC
, &compdata
->gcAttrBase
},
532 { IID_Hidd_Compositor
, &compdata
->compositorAttrBase
},
536 NEWLIST(&compdata
->bitmapstack
);
537 compdata
->compositedbitmap
= NULL
;
538 compdata
->topbitmap
= NULL
;
539 compdata
->screenbitmap
= NULL
;
540 compdata
->screenmodeid
= vHidd_ModeID_Invalid
;
541 compdata
->modeschanged
= FALSE
;
542 InitSemaphore(&compdata
->semaphore
);
544 /* Obtain Attr bases - make this class self-contained */
545 if (OOP_ObtainAttrBases(attrbases
))
547 compdata
->gfx
= (OOP_Object
*)GetTagData(aHidd_Compositor_GfxHidd
, 0, msg
->attrList
);
549 if (compdata
->gfx
!= NULL
)
551 /* Create GC object that will be used for drawing operations */
552 compdata
->gc
= HIDD_Gfx_CreateObject(compdata
->gfx
, SD(cl
)->basegc
, NULL
);
556 if ((compdata
->gfx
== NULL
) || (compdata
->gc
== NULL
))
558 /* Creation failed */
559 OOP_MethodID disposemid
;
560 disposemid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
561 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&disposemid
);
569 VOID
METHOD(Compositor
, Hidd_Compositor
, BitMapStackChanged
)
571 struct HIDD_ViewPortData
* vpdata
;
572 struct HIDDCompositorData
* compdata
= OOP_INST_DATA(cl
, o
);
573 struct StackBitMapNode
* n
= NULL
;
575 D(bug("[Compositor] BitMapStackChanged, topbitmap: 0x%x\n",
578 LOCK_COMPOSITOR_WRITE
580 /* Free all items which are already on the list */
581 HIDDCompositorPurgeBitMapStack(compdata
);
587 return; /* TODO: BLANK SCREEN */
590 /* Switch mode if needed */
591 if (!HIDDCompositorTopBitMapChanged(compdata
, msg
->data
->Bitmap
))
593 /* Something bad happened. Yes, bitmap stack is already erased - that's ok */
594 D(bug("[Compositor] Failed to change top bitmap\n"));
599 /* Copy bitmaps pointers to our stack */
600 for (vpdata
= msg
->data
; vpdata
; vpdata
= vpdata
->Next
)
602 D(bug("Compositor] Testing bitmap: %x\n", vpdata
->Bitmap
));
603 /* Check if the passed bitmap can be composited together with screen
605 if (HIDDCompositorCanCompositeWithScreenBitMap(compdata
, vpdata
->Bitmap
))
607 n
= AllocMem(sizeof(struct StackBitMapNode
), MEMF_ANY
| MEMF_CLEAR
);
609 n
->bm
= vpdata
->Bitmap
;
610 n
->isscreenvisible
= FALSE
;
611 n
->displayedwidth
= compdata
->screenrect
.MaxX
+ 1;
612 n
->displayedheight
= compdata
->screenrect
.MaxY
+ 1;
613 AddTail(&compdata
->bitmapstack
, (struct Node
*)n
);
617 /* Validate bitmap offsets - they might not match the compositor rules taking
618 new displayedwidth/displayedheight values */
619 ForeachNode(&compdata
->bitmapstack
, n
)
621 LONG newxoffset
, newyoffset
;
623 OOP_GetAttr(n
->bm
, aHidd_BitMap_TopEdge
, &val
);newyoffset
= (LONG
)val
;
624 OOP_GetAttr(n
->bm
, aHidd_BitMap_LeftEdge
, &val
);newxoffset
= (LONG
)val
;
626 HIDDCompositorValidateBitMapPositionChange(compdata
, n
->bm
,
627 &newxoffset
, &newyoffset
);
629 /* Override offsets without checks present in bitmap Set method */
630 HIDDNouveauSetOffsets(n
->bm
, newxoffset
, newyoffset
);
633 /* Toogle compositor based on screen positions */
634 HIDDCompositorToggleCompositing(compdata
);
636 /* Redraw bitmap stack - compensate for change of visible rects
637 resulting from new top bitmap */
638 HIDDCompositorRedrawVisibleScreen(compdata
);
643 VOID
METHOD(Compositor
, Hidd_Compositor
, BitMapRectChanged
)
645 struct HIDDCompositorData
* compdata
= OOP_INST_DATA(cl
, o
);
649 HIDDCompositorRedrawBitmap(compdata
, msg
->bm
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
654 VOID
METHOD(Compositor
, Hidd_Compositor
, BitMapPositionChanged
)
656 struct HIDDCompositorData
* compdata
= OOP_INST_DATA(cl
, o
);
658 LOCK_COMPOSITOR_WRITE
660 /* Check is passed bitmap is in stack, ignore if not */
661 if (HIDDCompositorIsBitMapOnStack(compdata
, msg
->bm
) != NULL
)
663 /* If top bitmap position has changed, possibly toggle compositor */
664 if (compdata
->topbitmap
== msg
->bm
)
665 HIDDCompositorToggleCompositing(compdata
);
667 /* If compositor is not active and top bitmap has changed, execute scroll */
668 if ((compdata
->screenbitmap
== compdata
->topbitmap
)
669 && (compdata
->topbitmap
== msg
->bm
))
672 HIDDNouveauSwitchToVideoMode(compdata
->screenbitmap
);
676 /* Redraw bitmap stack - compensate change of visible rects resulting
677 from move of bitmap */
678 HIDDCompositorRedrawVisibleScreen(compdata
);
685 VOID
METHOD(Compositor
, Hidd_Compositor
, ValidateBitMapPositionChange
)
687 struct HIDDCompositorData
* compdata
= OOP_INST_DATA(cl
, o
);
691 HIDDCompositorValidateBitMapPositionChange(compdata
, msg
->bm
,
692 msg
->newxoffset
, msg
->newyoffset
);