2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
8 #include <proto/exec.h>
10 #include <proto/utility.h>
12 #include <hidd/graphics.h>
13 #include <aros/atomic.h>
14 #include <proto/arossupport.h>
16 #include "graphics_intern.h"
17 #include "fakegfxhidd.h"
23 * DISABLE_ARGB_POINTER actually makes the software mouse pointer code to always
24 * behave like if a LUT framebuffer is used.
25 * Useful for debugging if you have only truecolor display modes.
26 * If you define this, make sure that ALWAYS_ALLOCATE_SPRITE_COLORS in
27 * intuition/intuition_intern.h is also defined.
29 #define DISABLE_ARGB_POINTER */
31 #include <aros/debug.h>
33 /******************************************************************************/
35 #define SPECIAL_LOCKING 1 /* When activated mouse cursor relevant locks are
36 treated in some kind of privileged way, by
37 inserting wait-for-sem-requests at head of
38 wait queue, instead of at tail */
40 /******************************************************************************/
42 static OOP_Class
*init_fakefbclass(struct GfxBase
*GfxBase
);
43 static OOP_Class
*init_fakegfxhiddclass (struct GfxBase
*GfxBase
);
45 /******************************************************************************/
50 OOP_Object
*framebuffer
;
59 OOP_Object
*curs_backup
;
61 HIDDT_StdPixFmt curs_pixfmt
;
72 struct SignalSemaphore fbsema
;
76 /******************************************************************************/
78 static void gfx_setFrameBuffer(struct GfxBase
*GfxBase
, struct gfx_data
*data
, OOP_Object
*fb
);
79 static VOID
draw_cursor(struct gfx_data
*data
, BOOL draw
, BOOL updaterect
, struct GfxBase
*GfxBase
);
80 static BOOL
rethink_cursor(struct gfx_data
*data
, struct GfxBase
*GfxBase
);
81 static OOP_Object
*create_fake_fb(OOP_Object
*framebuffer
, struct gfx_data
*data
, struct GfxBase
*GfxBase
);
83 /******************************************************************************/
87 static void FakeGfxHidd_ObtainSemaphore(struct SignalSemaphore
*sigSem
, BOOL urgent
,
88 struct GfxBase
*GfxBase
)
92 /* Get pointer to current task */
95 /* Arbitrate for the semaphore structure */
99 ss_QueueCount == -1 indicates that the semaphore is
100 free, so we increment this straight away. If it then
101 equals 0, then we are the first to allocate this semaphore.
103 Note: This will need protection for SMP machines.
105 sigSem
->ss_QueueCount
++;
106 if( sigSem
->ss_QueueCount
== 0 )
108 /* We now own the semaphore. This is quick. */
109 sigSem
->ss_Owner
= me
;
110 sigSem
->ss_NestCount
++;
113 /* The semaphore was in use, but was it by us? */
114 else if( sigSem
->ss_Owner
== me
)
116 /* Yes, just increase the nesting count */
117 sigSem
->ss_NestCount
++;
121 Else, some other task must own it. We have
122 to set a waiting request here.
127 We need a node to mark our semaphore request. Lets use some
130 struct SemaphoreRequest sr
;
134 Have to clear the signal to make sure that we don't
135 return immediately. We then add the SemReq to the
136 waiters list of the semaphore. We were the last to
137 request, so we must be the last to get the semaphore.
140 AROS_ATOMIC_AND(me
->tc_SigRecvd
, ~SIGF_SINGLE
);
144 AddHead((struct List
*)&sigSem
->ss_WaitQueue
, (struct Node
*)&sr
);
148 AddTail((struct List
*)&sigSem
->ss_WaitQueue
, (struct Node
*)&sr
);
152 Finally, we simply wait, ReleaseSemaphore() will fill in
153 who owns the semaphore.
163 /******************************************************************************/
165 static void FakeGfxHidd_ReleaseSemaphore(struct SignalSemaphore
*sigSem
,
166 struct GfxBase
*GfxBase
)
168 /* Protect the semaphore structure from multiple access. */
171 /* Release one on the nest count */
172 sigSem
->ss_NestCount
--;
173 sigSem
->ss_QueueCount
--;
175 if(sigSem
->ss_NestCount
== 0)
178 There are two cases here. Either we are a shared
179 semaphore, or not. If we are not, make sure that the
180 correct Task is calling ReleaseSemaphore()
184 Do not try and wake anything unless there are a number
185 of tasks waiting. We do both the tests, this is another
186 opportunity to throw an alert if there is an error.
189 sigSem
->ss_QueueCount
>= 0
190 && sigSem
->ss_WaitQueue
.mlh_Head
->mln_Succ
!= NULL
193 struct SemaphoreRequest
*sr
, *srn
;
196 Look at the first node, but only to see whether it
199 sr
= (struct SemaphoreRequest
*)sigSem
->ss_WaitQueue
.mlh_Head
;
202 A node is shared if the ln_Name/sr_Waiter field is
203 odd (ie it has bit 1 set).
205 If the sr_Waiter field is != NULL, then this is a
206 task waiting, otherwise it is a message.
208 if( ((IPTR
)sr
->sr_Waiter
& SM_SHARED
) == SM_SHARED
)
210 /* This is a shared lock, so ss_Owner == NULL */
211 sigSem
->ss_Owner
= NULL
;
213 /* Go through all the nodes to find the shared ones */
214 ForeachNodeSafe(&sigSem
->ss_WaitQueue
, sr
, srn
)
216 srn
= (struct SemaphoreRequest
*)sr
->sr_Link
.mln_Succ
;
218 if( ((IPTR
)sr
->sr_Waiter
& SM_SHARED
) == SM_SHARED
)
220 Remove((struct Node
*)sr
);
222 /* Clear the bit, and update the owner count */
223 sr
->sr_Waiter
= (APTR
)((IPTR
)sr
->sr_Waiter
& ~1);
224 sigSem
->ss_NestCount
++;
226 /* This is a task, signal it */
227 Signal(sr
->sr_Waiter
, SIGF_SINGLE
);
232 /* This is an exclusive lock - awaken first node */
235 /* Only awaken the first of the nodes */
236 Remove((struct Node
*)sr
);
237 sigSem
->ss_NestCount
++;
239 sigSem
->ss_Owner
= sr
->sr_Waiter
;
240 Signal(sr
->sr_Waiter
, SIGF_SINGLE
);
243 } /* there are waiters */
244 /* Otherwise, there are not tasks waiting. */
247 sigSem
->ss_Owner
= NULL
;
248 sigSem
->ss_QueueCount
= -1;
251 else if(sigSem
->ss_NestCount
< 0)
254 This can't happen. It means that somebody has released
255 more times than they have obtained.
257 Alert( AN_SemCorrupt
);
265 /******************************************************************************/
267 #define LFB(data) FakeGfxHidd_ObtainSemaphore(&(data)->fbsema, FALSE, GfxBase)
268 #define UFB(data) FakeGfxHidd_ReleaseSemaphore(&(data)->fbsema, GfxBase)
269 #define LFB_QUICK(data) FakeGfxHidd_ObtainSemaphore(&(data)->fbsema, TRUE, GfxBase)
270 #define UFB_QUICK(data) FakeGfxHidd_ReleaseSemaphore(&(data)->fbsema, GfxBase)
272 #else /* !SPECIAL_LOCKING */
274 #define LFB(data) ObtainSemaphore(&(data)->fbsema)
275 #define UFB(data) ReleaseSemaphore(&(data)->fbsema)
276 #define LFB_QUICK(data) ObtainSemaphore(&(data)->fbsema)
277 #define UFB_QUICK(data) ReleaseSemaphore(&(data)->fbsema)
279 #endif /* SPECIAL_LOCKING */
281 /******************************************************************************/
283 #define GfxBase ((struct GfxBase *)cl->UserData)
285 static OOP_Object
*gfx_new(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
287 /* Create a new gfxhid object */
288 OOP_Object
*realgfxhidd
;
289 struct gfx_data
*data
;
292 realgfxhidd
= (OOP_Object
*)GetTagData(aHidd_FakeGfxHidd_RealGfxHidd
, (IPTR
)NULL
, msg
->attrList
);
293 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
297 data
= OOP_INST_DATA(cl
, o
);
298 memset(data
, 0, sizeof (*data
));
299 InitSemaphore(&data
->fbsema
);
302 * If this is direct framebuffer driver, we draw our
303 * cursor on framebuffer bitmap.
304 * Otherwise we draw cursor on displayable bitmaps.
305 * TODO: Implement separate handling for mirrored framebuffers.
306 * In this case we actually don't need to backup pixels
307 * behind the sprite, because we can use mirror for this.
309 data
->fakefb_attr
= (OOP_GET(realgfxhidd
, aHidd_Gfx_FrameBufferType
) == vHidd_FrameBuffer_Direct
) ?
310 aHidd_BitMap_FrameBuffer
: aHidd_BitMap_Displayable
;
312 data
->gfxhidd
= realgfxhidd
;
314 if (NULL
!= data
->gfxhidd
)
316 struct TagItem gctags
[] =
321 data
->gc
= HIDD_Gfx_NewGC(data
->gfxhidd
, gctags
);
322 if (NULL
!= data
->gc
)
332 mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
333 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&mid
);
339 static VOID
gfx_dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
341 struct gfx_data
*data
;
343 data
= OOP_INST_DATA(cl
, o
);
344 if (NULL
!= data
->curs_backup
)
346 OOP_DisposeObject(data
->curs_backup
);
347 data
->curs_backup
= NULL
;
350 if (data
->curs_pixels
)
351 FreeMem(data
->curs_pixels
, data
->curs_width
* data
->curs_height
* 4);
353 if (NULL
!= data
->gc
)
355 OOP_DisposeObject(data
->gc
);
360 static void gfx_get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
362 struct gfx_data
*data
= OOP_INST_DATA(cl
, o
);
364 if (msg
->attrID
== aHidd_Gfx_HWSpriteTypes
) {
365 *msg
->storage
= vHidd_SpriteType_3Plus1
|vHidd_SpriteType_DirectColor
;
369 OOP_DoMethod(data
->gfxhidd
, (OOP_Msg
)msg
);
372 static OOP_Object
*gfx_newbitmap(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewBitMap
*msg
)
374 /* Is the user about to create a framebuffer ? */
376 struct gfx_data
*data
;
378 OOP_Object
*ret
= NULL
;
380 data
= OOP_INST_DATA(cl
, o
);
381 create_fb
= (BOOL
)GetTagData(data
->fakefb_attr
, FALSE
, msg
->attrList
);
383 realfb
= HIDD_Gfx_NewBitMap(data
->gfxhidd
, msg
->attrList
);
385 if (realfb
&& create_fb
)
387 ret
= create_fake_fb(realfb
, data
, GfxBase
);
389 OOP_DisposeObject(realfb
);
397 static BOOL
gfx_setcursorshape(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorShape
*msg
)
399 struct gfx_data
*data
;
403 data
= OOP_INST_DATA(cl
, o
);
405 D(bug("[FakeGfx] SetCursorShape(0x%p)\n", shape
));
410 /* Erase the old cursor */
411 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
412 data
->curs_on
= FALSE
;
413 data
->curs_bm
= NULL
;
414 data
->curs_x
= data
->curs_y
= 0;
415 data
->curs_maxx
= data
->curs_maxy
= 0;
416 data
->curs_width
= data
->curs_height
= 0;
417 data
->curs_xoffset
= 0;
418 data
->curs_yoffset
= 0;
420 if (NULL
!= data
->curs_backup
)
422 OOP_DisposeObject(data
->curs_backup
);
423 data
->curs_backup
= NULL
;
425 if (data
->curs_pixels
) {
426 FreeMem(data
->curs_pixels
, data
->curs_width
* data
->curs_height
* 4);
427 data
->curs_pixels
= NULL
;
432 IPTR curs_width
, curs_height
;
433 APTR new_curs_pixels
;
434 ULONG curs_pixels_len
;
436 OOP_GetAttr(shape
, aHidd_BitMap_Width
, &curs_width
);
437 OOP_GetAttr(shape
, aHidd_BitMap_Height
, &curs_height
);
439 DCURS(bug("[FakeGfx] New cursor size: %lu x %lu, framebuffer 0x%p\n", curs_width
, curs_height
, data
->framebuffer
));
441 /* Create new cursor pixelbuffer. We multiply size by 4 because we want ARGB data
443 curs_pixels_len
= curs_width
* curs_height
* 4;
444 new_curs_pixels
= AllocMem(curs_pixels_len
, MEMF_ANY
|MEMF_CLEAR
);
445 if (!new_curs_pixels
)
450 /* Erase the old cursor */
451 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
453 /* Now that we have disposed the old image using the old
454 backup bm, we can install the new image and backup bm before
455 rendering the new cursor.
456 Backup bitmap is recreated in rethink_cursor()
459 if (data
->curs_pixels
)
460 FreeMem(data
->curs_pixels
, data
->curs_width
* data
->curs_height
* 4);
462 data
->curs_bm
= shape
;
463 data
->curs_width
= curs_width
;
464 data
->curs_height
= curs_height
;
465 data
->curs_maxx
= data
->curs_x
+ curs_width
- 1;
466 data
->curs_maxy
= data
->curs_y
+ curs_height
- 1;
467 data
->curs_pixels
= new_curs_pixels
;
468 data
->curs_xoffset
= msg
->xoffset
;
469 data
->curs_yoffset
= msg
->yoffset
;
471 ok
= rethink_cursor(data
, GfxBase
);
474 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
480 static BOOL
gfx_setcursorpos(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorPos
*msg
)
482 struct gfx_data
*data
;
486 data
= OOP_INST_DATA(cl
, o
);
487 DPOS(bug("[FakeGfx] SetCursorPos(%d, %d)\n", msg
->x
, msg
->y
));
489 if (!data
->framebuffer
)
492 /* We draw our cursor on the bitmap, so we have to convert back
493 from physical to logical coordinates */
494 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_LeftEdge
, &xoffset
);
495 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_TopEdge
, &yoffset
);
498 /* erase the old cursor */
499 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
501 data
->curs_x
= msg
->x
- xoffset
;
502 data
->curs_y
= msg
->y
- yoffset
;
503 /* Shift to the hotspot location */
504 data
->curs_x
+= data
->curs_xoffset
;
505 data
->curs_y
+= data
->curs_yoffset
;
506 data
->curs_maxx
= data
->curs_x
+ data
->curs_width
- 1;
507 data
->curs_maxy
= data
->curs_y
+ data
->curs_height
- 1;
509 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
514 static VOID
gfx_setcursorvisible(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorVisible
*msg
)
516 struct gfx_data
*data
;
518 data
= OOP_INST_DATA(cl
, o
);
526 data
->curs_on
= TRUE
;
527 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
534 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
535 data
->curs_on
= FALSE
;
543 #define PIXEL_INSIDE(fgh, x, y) \
544 ( ( (x) >= (fgh)->curs_x ) \
545 && ( (y) >= (fgh)->curs_y ) \
546 && ( (x) <= (fgh)->curs_maxx ) \
547 && ( (y) <= (fgh)->curs_maxy ) )
549 /* NOTE: x1, y1, x2, y2 MUST be sorted */
550 #define RECT_INSIDE(fgh, x1, y1, x2, y2) \
551 ( ( (x1) <= fgh->curs_maxx ) \
552 && ( (x2) >= fgh->curs_x ) \
553 && ( (y1) <= fgh->curs_maxy ) \
554 && ( (y2) >= fgh->curs_y ) )
556 #define WRECT_INSIDE(fgh, x1, y1, width, height) \
557 RECT_INSIDE(fgh, x1, y1, (x1) + (width) - 1, (y1) + (height) - 1)
559 static void gfx_copybox(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CopyBox
*msg
)
561 struct gfx_data
*data
;
562 OOP_Object
*src
= NULL
;
563 OOP_Object
*dest
= NULL
;
566 data
= OOP_INST_DATA(cl
, o
);
569 /* De-masquerade bitmap objects, every of which can be fakefb object */
570 OOP_GetAttr(msg
->src
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&src
);
571 OOP_GetAttr(msg
->dest
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&dest
);
577 /* FIXME: other bitmap may belong to another instance of fakegfx which can be on
578 display on another monitor. In this case mouse cursor should be handled also
579 there. Needs further reengineering. */
580 if ((msg
->src
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->srcX
, msg
->srcY
, msg
->width
, msg
->height
))
583 if ((msg
->dest
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
587 draw_cursor(data
, FALSE
, FALSE
, GfxBase
);
589 HIDD_Gfx_CopyBox(data
->gfxhidd
, src
, msg
->srcX
, msg
->srcY
,
590 dest
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
, msg
->gc
);
593 draw_cursor(data
, TRUE
, FALSE
, GfxBase
);
598 static IPTR
gfx_copyboxmasked(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CopyBoxMasked
*msg
)
600 struct gfx_data
*data
;
601 OOP_Object
*src
= NULL
;
602 OOP_Object
*dest
= NULL
;
606 data
= OOP_INST_DATA(cl
, o
);
609 /* De-masquerade bitmap objects, every of which can be fakefb object */
610 OOP_GetAttr(msg
->src
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&src
);
611 OOP_GetAttr(msg
->dest
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&dest
);
618 * FIXME: other bitmap may belong to another instance of fakegfx which can be on
619 * display on another monitor. In this case mouse cursor should be handled also
620 * there. Needs further reengineering.
622 if ((msg
->src
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->srcX
, msg
->srcY
, msg
->width
, msg
->height
))
625 if ((msg
->dest
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
629 draw_cursor(data
, FALSE
, FALSE
, GfxBase
);
631 ret
= HIDD_Gfx_CopyBoxMasked(data
->gfxhidd
, src
, msg
->srcX
, msg
->srcY
,
632 dest
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
, msg
->mask
, msg
->gc
);
635 draw_cursor(data
, TRUE
, FALSE
, GfxBase
);
642 static OOP_Object
*gfx_show(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Show
*msg
)
645 struct gfx_data
*data
;
647 data
= OOP_INST_DATA(cl
, o
);
650 D(bug("[FakeGfx] Show(0x%p)\n", ret
));
653 * If we are attempting to show a fake bitmap, we are working
654 * in NoFrameBuffer mode where each displayable bitmap is
657 if (ret
&& (OOP_OCLASS(ret
) == CDD(GfxBase
)->fakefbclass
))
660 OOP_GetAttr(msg
->bitMap
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&ret
);
661 D(bug("[FakeGfx] Bitmap is a fakefb object, real bitmap is 0x%p\n", ret
));
665 draw_cursor(data
, FALSE
, FALSE
, GfxBase
);
667 ret
= HIDD_Gfx_Show(data
->gfxhidd
, ret
, msg
->flags
);
668 D(bug("[FakeGfx] Real framebuffer object 0x%p\n", ret
));
669 gfx_setFrameBuffer(GfxBase
, data
, ret
);
672 /* FIXME: temporary workaround: at this point Intuition has already destroyed
673 the sprite image (since the last screen was closed) but we have no information
674 about it. Perhaps FreeSpriteData() should track this down somehow and inform
675 drivers about destroyed sprites.
677 data->curs_bm = NULL;*/
678 rethink_cursor(data
, GfxBase
);
679 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
683 D(bug("[FakeGfx] Returning 0x%p\n", ret
));
687 static ULONG
gfx_showviewports(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
689 /* Composition is not supported here */
693 static BOOL
gfx_getmaxspritesize(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMaxSpriteSize
*msg
)
695 if (msg
->Type
& (vHidd_SpriteType_3Plus1
|vHidd_SpriteType_DirectColor
)) {
696 /* I hope these values are enough for everyone :) */
698 *msg
->Height
= 65535;
705 static IPTR
gfx_fwd(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
707 struct gfx_data
*data
;
709 data
= OOP_INST_DATA(cl
, o
);
711 return OOP_DoMethod(data
->gfxhidd
, msg
);
714 /* Private non-virtual method */
715 static BOOL
FakeGfx_UpdateFrameBuffer(OOP_Object
*o
)
717 OOP_Class
*cl
= OOP_OCLASS(o
);
718 struct gfx_data
*data
= OOP_INST_DATA(cl
, o
);
723 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_Width
, &data
->fb_width
);
724 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_Height
, &data
->fb_height
);
726 DCURS(bug("[FakeGfx] Changed framebuffer size: %u x %u\n", data
->fb_width
, data
->fb_height
));
728 ok
= rethink_cursor(data
, GfxBase
);
731 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
737 OOP_Object
*framebuffer
;
738 OOP_Object
*fakegfxhidd
;
741 #define FGH(data) ((struct gfx_data *)data->fakegfxhidd)
742 #define REMOVE_CURSOR(data) \
743 draw_cursor(FGH(data), FALSE, FALSE, GfxBase)
745 #define RENDER_CURSOR(data) \
746 draw_cursor(FGH(data), TRUE, FALSE, GfxBase)
749 #define BITMAP_METHOD_INIT \
750 struct fakefb_data *data; \
751 BOOL inside = FALSE; \
753 struct gfx_data *fgh; \
754 data = OOP_INST_DATA(cl, o); \
758 #define FORWARD_METHOD \
759 retval = OOP_DoMethod(data->framebuffer, (OOP_Msg)msg);
761 #define BITMAP_METHOD_EXIT \
763 RENDER_CURSOR(data); \
768 static OOP_Object
*fakefb_new(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
770 OOP_Object
*framebuffer
;
771 OOP_Object
*fakegfxhidd
;
773 framebuffer
= (OOP_Object
*)GetTagData(aHidd_FakeFB_RealBitMap
, 0, msg
->attrList
);
774 fakegfxhidd
= (OOP_Object
*)GetTagData(aHidd_FakeFB_FakeGfxHidd
, 0, msg
->attrList
);
776 if (NULL
== framebuffer
|| NULL
== fakegfxhidd
)
778 D(bug("!!! FakeBM::New(): MISSING FRAMEBUFFER OR FAKE GFX HIDD !!!\n"));
782 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
785 struct fakefb_data
*data
;
786 data
= OOP_INST_DATA(cl
, o
);
787 data
->framebuffer
= framebuffer
;
788 data
->fakegfxhidd
= fakegfxhidd
;
793 static VOID
fakefb_dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
795 struct fakefb_data
*data
;
796 data
= OOP_INST_DATA(cl
, o
);
797 if (NULL
!= data
->framebuffer
)
799 OOP_DisposeObject(data
->framebuffer
);
800 data
->framebuffer
= NULL
;
804 static void fakefb_get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
806 struct fakefb_data
*data
= OOP_INST_DATA(cl
, o
);
808 if (msg
->attrID
== aHidd_FakeFB_RealBitMap
)
810 *msg
->storage
= (IPTR
)data
->framebuffer
;
813 else if (msg
->attrID
== aHidd_BitMap_GfxHidd
)
815 *msg
->storage
= (IPTR
)data
->fakegfxhidd
;
819 OOP_DoMethod(data
->framebuffer
, (OOP_Msg
)msg
);
822 /* Intercept framebuffer mode change */
823 static IPTR
fakefb_set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
825 struct fakefb_data
*data
= OOP_INST_DATA(cl
, o
);
826 IPTR ret
= OOP_DoMethod(data
->framebuffer
, &msg
->mID
);
827 struct TagItem
*modeid
= FindTagItem(aHidd_BitMap_ModeID
, msg
->attrList
);
831 /* Framebuffer mode change succeeded. Update fakegfx' information */
832 ret
= FakeGfx_UpdateFrameBuffer(data
->fakegfxhidd
);
838 static IPTR
fakefb_getpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetPixel
*msg
)
842 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
853 static IPTR
fakefb_putpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPixel
*msg
)
857 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
868 static IPTR
fakefb_drawpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPixel
*msg
)
872 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
883 static IPTR
fakefb_drawline(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawLine
*msg
)
885 register LONG x1
, y1
, x2
, y2
;
888 if (msg
->x1
< msg
->x2
)
890 x1
= msg
->x1
; x2
= msg
->x2
;
894 x2
= msg
->x1
; x1
= msg
->x2
;
897 if (msg
->y1
< msg
->y2
)
899 y1
= msg
->y1
; y2
= msg
->y2
;
903 y2
= msg
->y1
; y1
= msg
->y2
;
906 /* FIXME: Maybe do some more intelligent checking for DrawLine */
907 if (RECT_INSIDE(fgh
, x1
, y1
, x2
, y2
))
918 static IPTR
fakefb_getimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImage
*msg
)
922 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
933 static IPTR
fakefb_putimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImage
*msg
)
937 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
948 static IPTR
fakefb_putalphaimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutAlphaImage
*msg
)
952 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
963 static IPTR
fakefb_puttemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
967 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
978 static IPTR
fakefb_putalphatemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutAlphaTemplate
*msg
)
982 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
993 static IPTR
fakefb_putpattern(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPattern
*msg
)
997 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1008 static IPTR
fakefb_getimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImageLUT
*msg
)
1012 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1014 REMOVE_CURSOR(data
);
1023 static IPTR
fakefb_putimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImageLUT
*msg
)
1027 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1029 REMOVE_CURSOR(data
);
1038 static IPTR
fakefb_puttranspimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTranspImageLUT
*msg
)
1042 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1044 REMOVE_CURSOR(data
);
1053 static IPTR
fakefb_drawrect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
1057 /* FIXME: Maybe do something clever here to see if the rectangle is drawn around the cursor */
1058 if (RECT_INSIDE(fgh
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
))
1060 REMOVE_CURSOR(data
);
1069 static IPTR
fakefb_fillrect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
1073 /* bug("BITMAP FILLRECT(%d, %d, %d, %d), (%d, %d, %d, %d, %d, %d)\n"
1074 , msg->minX, msg->minY, msg->maxX, msg->maxY
1075 , fgh->curs_x, fgh->curs_y, fgh->curs_maxx, fgh->curs_maxy
1076 , fgh->curs_width, fgh->curs_height);
1078 if (RECT_INSIDE(fgh
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
))
1080 /* bug("FILLRECT: REMOVING CURSOR\n");
1082 REMOVE_CURSOR(data
);
1092 static IPTR
fakefb_drawellipse(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawEllipse
*msg
)
1094 register LONG x1
, y1
, x2
, y2
;
1097 x1
= msg
->x
- msg
->rx
;
1098 y1
= msg
->y
- msg
->ry
;
1099 x2
= msg
->x
+ msg
->rx
;
1100 y2
= msg
->y
+ msg
->ry
;
1101 /* FIXME: Maybe do something clever here to see if the rectangle is drawn around the cursor */
1103 if (RECT_INSIDE(fgh
, x1
, y1
, x2
, y2
))
1105 REMOVE_CURSOR(data
);
1114 static IPTR
fakefb_fillellipse(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawEllipse
*msg
)
1116 register LONG x1
, y1
, x2
, y2
;
1119 x1
= msg
->x
- msg
->rx
;
1120 y1
= msg
->y
- msg
->ry
;
1121 x2
= msg
->x
+ msg
->rx
;
1122 y2
= msg
->y
+ msg
->ry
;
1124 if (RECT_INSIDE(fgh
, x1
, y1
, x2
, y2
))
1126 REMOVE_CURSOR(data
);
1135 static IPTR
fakefb_drawpolygon(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPolygon
*msg
)
1138 /* FIXME: Maybe do checking here, but it probably is not worth it */
1139 REMOVE_CURSOR(data
);
1147 static IPTR
fakefb_fillpolygon(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPolygon
*msg
)
1150 /* FIXME: Maybe do checking here, but it probably is not worth it */
1151 REMOVE_CURSOR(data
);
1160 static IPTR
fakefb_drawtext(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawText
*msg
)
1164 /* FIXME: Maybe do testing here, but probably not wirth it */
1165 REMOVE_CURSOR(data
);
1172 static IPTR
fakefb_drawfilltext(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawText
*msg
)
1176 /* FIXME: Maybe do testing here, but probably not worth it */
1177 REMOVE_CURSOR(data
);
1184 static IPTR
fakefb_blitcolexp(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BlitColorExpansion
*msg
)
1188 if (WRECT_INSIDE(fgh
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
1190 REMOVE_CURSOR(data
);
1199 static IPTR
fakefb_clear(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_Clear
*msg
)
1211 static IPTR
fakefb_fillspan(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
1215 REMOVE_CURSOR(data
);
1223 static IPTR
fakefb_scale(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BitMapScale
*msg
)
1225 /* FIXME: should check both source and destination, similar to gfx_copybox() */
1228 if (WRECT_INSIDE(fgh
, msg
->bsa
->bsa_SrcX
, msg
->bsa
->bsa_SrcY
, msg
->bsa
->bsa_SrcWidth
, msg
->bsa
->bsa_SrcHeight
))
1230 REMOVE_CURSOR(data
);
1239 static IPTR
fakefb_fwd(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
1241 struct fakefb_data
*data
;
1242 data
= OOP_INST_DATA(cl
, o
);
1243 // kill(getpid(), 19);
1244 // bug("BITMAP_FWD\n");
1245 return OOP_DoMethod(data
->framebuffer
, msg
);
1250 static BOOL
rethink_cursor(struct gfx_data
*data
, struct GfxBase
*GfxBase
)
1252 OOP_Object
*pf
, *cmap
;
1253 IPTR fbdepth
, curdepth
, i
;
1254 UWORD curs_base
= 16;
1256 struct TagItem bmtags
[] = {
1257 { aHidd_BitMap_Width
, data
->curs_width
},
1258 { aHidd_BitMap_Height
, data
->curs_height
},
1259 { aHidd_BitMap_Friend
, (IPTR
)data
->framebuffer
},
1263 D(bug("rethink_cursor(), curs_bm is 0x%p, framebuffer is 0x%p\n", data
->curs_bm
, data
->framebuffer
));
1265 /* The first thing we do is recreating a backup bitmap. We do it every time when either
1266 cursor shape changes (because new shape may have different size) or shown bitmap
1267 changes (because new bitmap may have different depth). Note that even real framebuffer
1268 object may dynamically change its characteristics.
1270 Delete the old backup bitmap first */
1271 if (NULL
!= data
->curs_backup
) {
1272 OOP_DisposeObject(data
->curs_backup
);
1273 D(bug("[FakeGfx] Disposed old backup bitmap\n"));
1274 data
->curs_backup
= NULL
;
1277 /* If we have no cursor, we have nothing more to do.
1278 We also don't need new backup bitmap */
1282 /* We may also have no framebuffer (empty display on
1283 non-framebuffer driver). Also NOP in this case */
1284 if (!data
->framebuffer
)
1287 /* Create new backup bitmap */
1288 data
->curs_backup
= HIDD_Gfx_NewBitMap(data
->gfxhidd
, bmtags
);
1289 D(bug("[FakeGfx] New backup bitmap is 0x%p\n", data
->curs_backup
));
1290 if (!data
->curs_backup
)
1293 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1294 D(bug("[FakeGfx] Framebuffer pixelformat 0x%p\n", pf
));
1295 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &fbdepth
);
1296 D(bug("[FakeGfx] Framebuffer depth %u\n", fbdepth
));
1297 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_ColorMap
, (IPTR
*)&cmap
);
1298 D(bug("[FakeGfx] Cursor colormap 0x%p\n", cmap
));
1299 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1300 D(bug("[FakeGfx] Cursor pixelformat 0x%p\n", pf
));
1301 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &curdepth
);
1302 D(bug("[FakeGfx] Cursor depth %u\n", curdepth
));
1304 #ifndef DISABLE_ARGB_POINTER
1305 /* We can get ARGB data from the pointer bitmap only
1306 on one of two cases:
1307 1) Pointer bitmap has more than 256 colors, in this case it
1308 stores ARGB data in itself.
1309 2) Pointer bitmap is a LUT bitmap with a colormap attached.
1310 In this case colormap should contain ARGB values for actual
1312 Of course having ARGB data makes sense only on truecolor screens. */
1313 if ((fbdepth
> 8) && ((curdepth
> 8) || cmap
)) {
1314 data
->curs_pixfmt
= vHidd_StdPixFmt_ARGB32
;
1319 data
->curs_pixfmt
= vHidd_StdPixFmt_LUT8
;
1321 /* TODO: curs_base should be somehow synchronised with SpriteBase field of ColorMap */
1322 curs_base
= (fbdepth
> 4) ? 16 : (1 << fbdepth
) - 8;
1324 /* If we have some good bitmap->bitmap blitting function with alpha channel support,
1325 we would not need this extra buffer and conversion for truecolor screens. */
1326 HIDD_BM_GetImage(data
->curs_bm
, data
->curs_pixels
, data
->curs_width
* data
->curs_bpp
, 0, 0, data
->curs_width
, data
->curs_height
, data
->curs_pixfmt
);
1327 D(bug("[FakeGfx] Obtained cursor sprite data @ 0x%p\n", data
->curs_pixels
));
1329 if (data
->curs_pixfmt
== vHidd_StdPixFmt_LUT8
)
1331 for (i
= 0; i
< data
->curs_width
* data
->curs_height
; i
++)
1333 if (data
->curs_pixels
[i
])
1334 data
->curs_pixels
[i
] += curs_base
;
1340 static VOID
draw_cursor(struct gfx_data
*data
, BOOL draw
, BOOL updaterect
, struct GfxBase
*GfxBase
)
1343 LONG fbwidth
, fbheight
;
1349 struct TagItem gctags
[] =
1351 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
1358 if (NULL
== data
->curs_bm
|| NULL
== data
->framebuffer
)
1360 DB2(bug("!!! draw_cursor: FAKE GFX HIDD NOT PROPERLY INITIALIZED !!!\n"));
1361 DB2(bug("CURS BM: 0x%p, FB: 0x%p\n", data
->curs_bm
, data
->framebuffer
));
1365 fbwidth
= data
->fb_width
;
1366 fbheight
= data
->fb_height
;
1367 width
= data
->curs_width
;
1368 height
= data
->curs_height
;
1372 /* Do nothing if sprite went outside of bitmap */
1373 if ((x
< -width
) || (y
< -height
)) {
1374 DCURS(bug("[FakeGfx] Cursor is beyond left or top edge\n"));
1377 if ((x
>= fbwidth
) || (y
>= fbheight
)) {
1378 DCURS(bug("[FakeGfx] Cursor is beyond right or bottom edge\n"));
1382 /* Do some clipping */
1395 w2end
= data
->fb_width
- width
;
1396 h2end
= data
->fb_height
- height
;
1400 width
-= (x
- w2end
);
1401 DCLIP(bug("[FakeGfx] Clipped sprite width to %d\n", width
));
1406 height
-= (y
- h2end
);
1407 DCLIP(bug("[FakeGfx] Clipped sprite height to %d\n", height
));
1410 /* FIXME: clip negative coordinates */
1412 OOP_SetAttrs(data
->gc
, gctags
);
1416 /* Calculate origin of sprite image according to offsets */
1417 ULONG modulo
= data
->curs_width
* data
->curs_bpp
;
1418 UBYTE
*pixels
= data
->curs_pixels
+ yoffset
* modulo
+ xoffset
* data
->curs_bpp
;
1420 /* Backup under the new cursor image */
1421 // bug("BACKING UP RENDERED AREA\n");
1422 HIDD_Gfx_CopyBox(data
->gfxhidd
1431 data
->backup_done
= TRUE
;
1433 DB2(bug("[FakeGfx] Rendering cursor, framebuffer 0x%p\n", data
->framebuffer
));
1434 /* Render the cursor image */
1435 if (data
->curs_pixfmt
== vHidd_StdPixFmt_ARGB32
)
1436 HIDD_BM_PutAlphaImage(data
->framebuffer
, data
->gc
, pixels
, modulo
, x
, y
, width
, height
);
1438 /* data->curs_bpp is always 1 here so we safely ignore it */
1439 HIDD_BM_PutTranspImageLUT(data
->framebuffer
, data
->gc
, pixels
, modulo
, x
, y
, width
, height
, NULL
, 0);
1442 HIDD_BM_UpdateRect(data
->framebuffer
, x
, y
, width
, height
);
1447 /* Erase the old cursor image */
1448 if (data
->backup_done
)
1450 DB2(bug("[FakeGfx] Restoring cursor area, framebuffer 0x%p\n", data
->framebuffer
));
1451 HIDD_Gfx_CopyBox(data
->gfxhidd
1461 HIDD_BM_UpdateRect(data
->framebuffer
, x
, y
, width
, height
);
1467 static void gfx_setFrameBuffer(struct GfxBase
*GfxBase
, struct gfx_data
*data
, OOP_Object
*fb
)
1469 data
->framebuffer
= fb
;
1473 /* Cache framebuffer size, needed by sprite rendering routine */
1474 OOP_GetAttr(fb
, aHidd_BitMap_Width
, &data
->fb_width
);
1475 OOP_GetAttr(fb
, aHidd_BitMap_Height
, &data
->fb_height
);
1477 DCURS(bug("[FakeGfx] Framebuffer size: %u x %u\n", data
->fb_width
, data
->fb_height
));
1481 static OOP_Object
*create_fake_fb(OOP_Object
*framebuffer
, struct gfx_data
*data
, struct GfxBase
*GfxBase
)
1484 struct TagItem fakebmtags
[] =
1486 { aHidd_FakeFB_RealBitMap
, (IPTR
)framebuffer
},
1487 { aHidd_FakeFB_FakeGfxHidd
, (IPTR
)data
},
1491 /* If we work with framebuffer-based driver, Show() will never be called on
1492 a fakefb object so we remember it right now */
1493 fakebm
= OOP_NewObject(CDD(GfxBase
)->fakefbclass
, NULL
, fakebmtags
);
1495 if (data
->fakefb_attr
== aHidd_BitMap_FrameBuffer
)
1497 data
->fakefb
= fakebm
;
1498 gfx_setFrameBuffer(GfxBase
, data
, framebuffer
);
1504 static OOP_Class
*init_fakegfxhiddclass (struct GfxBase
*GfxBase
)
1506 OOP_Class
*cl
= NULL
;
1508 struct OOP_MethodDescr root_descr
[num_Root_Methods
+ 1] =
1510 {(IPTR (*)())gfx_new
, moRoot_New
},
1511 {(IPTR (*)())gfx_dispose
, moRoot_Dispose
},
1512 {(IPTR (*)())gfx_get
, moRoot_Get
},
1513 {(IPTR (*)())gfx_fwd
, moRoot_Set
},
1517 struct OOP_MethodDescr gfxhidd_descr
[num_Hidd_Gfx_Methods
+ 1] =
1519 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_NewGC
},
1520 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_DisposeGC
},
1521 {(IPTR (*)())gfx_newbitmap
, moHidd_Gfx_NewBitMap
},
1522 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_DisposeBitMap
},
1523 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_QueryModeIDs
},
1524 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_ReleaseModeIDs
},
1525 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_CheckMode
},
1526 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_NextModeID
},
1527 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetMode
},
1528 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetPixFmt
},
1529 {(IPTR (*)())gfx_setcursorshape
, moHidd_Gfx_SetCursorShape
},
1530 {(IPTR (*)())gfx_setcursorpos
, moHidd_Gfx_SetCursorPos
},
1531 {(IPTR (*)())gfx_setcursorvisible
, moHidd_Gfx_SetCursorVisible
},
1532 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_SetMode
},
1533 {(IPTR (*)())gfx_show
, moHidd_Gfx_Show
},
1534 {(IPTR (*)())gfx_copybox
, moHidd_Gfx_CopyBox
},
1535 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_ModeProperties
},
1536 {(IPTR (*)())gfx_showviewports
, moHidd_Gfx_ShowViewPorts
},
1537 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetSync
},
1538 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetGamma
},
1539 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_SetGamma
},
1540 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_QueryHardware3D
},
1541 {(IPTR (*)())gfx_getmaxspritesize
, moHidd_Gfx_GetMaxSpriteSize
},
1542 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_NewOverlay
},
1543 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_DisposeOverlay
},
1544 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_MakeViewPort
},
1545 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_CleanViewPort
},
1546 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_PrepareViewPorts
},
1547 {(IPTR (*)())gfx_copyboxmasked
, moHidd_Gfx_CopyBoxMasked
},
1551 struct OOP_InterfaceDescr ifdescr
[] =
1553 {root_descr
, IID_Root
, num_Root_Methods
},
1554 {gfxhidd_descr
, IID_Hidd_Gfx
, num_Hidd_Gfx_Methods
},
1558 OOP_AttrBase MetaAttrBase
= OOP_GetAttrBase(IID_Meta
);
1560 struct TagItem tags
[] =
1562 { aMeta_SuperID
, (IPTR
)CLID_Root
},
1563 { aMeta_InterfaceDescr
, (IPTR
)ifdescr
},
1564 { aMeta_InstSize
, (IPTR
)sizeof (struct gfx_data
) },
1569 D(bug("INIT FAKEGFXCLASS\n"));
1571 if ((__IHidd_FakeFB
= OOP_ObtainAttrBase(IID_Hidd_FakeFB
)))
1573 cl
= OOP_NewObject(NULL
, CLID_HiddMeta
, tags
);
1576 D(bug("FAKE GFX CLASS INITED\n"));
1577 cl
->UserData
= GfxBase
;
1582 OOP_ReleaseAttrBase(IID_Hidd_FakeFB
);
1588 static OOP_Class
*init_fakefbclass(struct GfxBase
*GfxBase
)
1590 struct OOP_MethodDescr root_descr
[num_Root_Methods
+ 1] =
1592 {(IPTR (*)())fakefb_new
, moRoot_New
},
1593 {(IPTR (*)())fakefb_dispose
, moRoot_Dispose
},
1594 {(IPTR (*)())fakefb_get
, moRoot_Get
},
1595 {(IPTR (*)())fakefb_set
, moRoot_Set
},
1599 struct OOP_MethodDescr bitmap_descr
[num_Hidd_BitMap_Methods
+ 1] =
1601 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_SetColors
},
1602 {(IPTR (*)())fakefb_putpixel
, moHidd_BitMap_PutPixel
},
1603 {(IPTR (*)())fakefb_drawpixel
, moHidd_BitMap_DrawPixel
},
1604 {(IPTR (*)())fakefb_putimage
, moHidd_BitMap_PutImage
},
1605 {(IPTR (*)())fakefb_putalphaimage
, moHidd_BitMap_PutAlphaImage
},
1606 {(IPTR (*)())fakefb_puttemplate
, moHidd_BitMap_PutTemplate
},
1607 {(IPTR (*)())fakefb_putalphatemplate
, moHidd_BitMap_PutAlphaTemplate
},
1608 {(IPTR (*)())fakefb_putpattern
, moHidd_BitMap_PutPattern
},
1609 {(IPTR (*)())fakefb_getimage
, moHidd_BitMap_GetImage
},
1610 {(IPTR (*)())fakefb_getpixel
, moHidd_BitMap_GetPixel
},
1611 {(IPTR (*)())fakefb_drawline
, moHidd_BitMap_DrawLine
},
1612 {(IPTR (*)())fakefb_drawrect
, moHidd_BitMap_DrawRect
},
1613 {(IPTR (*)())fakefb_fillrect
, moHidd_BitMap_FillRect
},
1614 {(IPTR (*)())fakefb_drawellipse
, moHidd_BitMap_DrawEllipse
},
1615 {(IPTR (*)())fakefb_fillellipse
, moHidd_BitMap_FillEllipse
},
1616 {(IPTR (*)())fakefb_drawpolygon
, moHidd_BitMap_DrawPolygon
},
1617 {(IPTR (*)())fakefb_fillpolygon
, moHidd_BitMap_FillPolygon
},
1618 {(IPTR (*)())fakefb_drawtext
, moHidd_BitMap_DrawText
},
1619 {(IPTR (*)())fakefb_drawfilltext
, moHidd_BitMap_FillText
},
1620 {(IPTR (*)())fakefb_fillspan
, moHidd_BitMap_FillSpan
},
1621 {(IPTR (*)())fakefb_clear
, moHidd_BitMap_Clear
},
1622 {(IPTR (*)())fakefb_blitcolexp
, moHidd_BitMap_BlitColorExpansion
},
1623 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_MapColor
},
1624 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_UnmapPixel
},
1625 {(IPTR (*)())fakefb_putimagelut
, moHidd_BitMap_PutImageLUT
},
1626 {(IPTR (*)())fakefb_puttranspimagelut
, moHidd_BitMap_PutTranspImageLUT
},
1627 {(IPTR (*)())fakefb_getimagelut
, moHidd_BitMap_GetImageLUT
},
1628 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_BytesPerLine
},
1629 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_ConvertPixels
},
1630 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect8
},
1631 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect16
},
1632 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect24
},
1633 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect32
},
1634 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_InvertMemRect
},
1635 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox8
},
1636 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox16
},
1637 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox24
},
1638 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox32
},
1639 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyLUTMemBox16
},
1640 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyLUTMemBox24
},
1641 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyLUTMemBox32
},
1642 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMem32Image8
},
1643 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMem32Image16
},
1644 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMem32Image24
},
1645 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_GetMem32Image8
},
1646 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_GetMem32Image16
},
1647 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_GetMem32Image24
},
1648 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate8
},
1649 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate16
},
1650 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate24
},
1651 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate32
},
1652 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern8
},
1653 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern16
},
1654 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern24
},
1655 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern32
},
1656 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_SetColorMap
},
1657 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_ObtainDirectAccess
},
1658 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_ReleaseDirectAccess
},
1659 {(IPTR (*)())fakefb_scale
, moHidd_BitMap_BitMapScale
},
1660 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PrivateSet
},
1661 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_SetRGBConversionFunction
},
1662 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_UpdateRect
},
1666 struct OOP_InterfaceDescr ifdescr
[] =
1668 {root_descr
, IID_Root
, num_Root_Methods
},
1669 {bitmap_descr
, IID_Hidd_BitMap
, num_Hidd_BitMap_Methods
},
1673 OOP_AttrBase MetaAttrBase
= OOP_GetAttrBase(IID_Meta
);
1675 struct TagItem tags
[] =
1677 {aMeta_SuperID
, (IPTR
) CLID_Root
},
1678 {aMeta_InterfaceDescr
, (IPTR
) ifdescr
},
1679 {aMeta_InstSize
, (IPTR
) sizeof(struct fakefb_data
) },
1683 OOP_Class
*cl
= NULL
;
1687 cl
= OOP_NewObject(NULL
, CLID_HiddMeta
, tags
);
1689 cl
->UserData
= GfxBase
;
1690 } /* if(MetaAttrBase) */
1695 OOP_Object
*init_fakegfxhidd(OOP_Object
*gfxhidd
, struct GfxBase
*GfxBase
)
1697 struct common_driverdata
*csd
= CDD(GfxBase
);
1699 if (!csd
->fakegfxclass
)
1701 /* Lazy class initialization */
1702 csd
->fakegfxclass
= init_fakegfxhiddclass(GfxBase
);
1703 csd
->fakefbclass
= init_fakefbclass(GfxBase
);
1705 if (!csd
->fakegfxclass
|| !csd
->fakefbclass
)
1707 cleanup_fakegfxhidd(GfxBase
);
1713 return OOP_NewObjectTags(csd
->fakegfxclass
, NULL
, aHidd_FakeGfxHidd_RealGfxHidd
, gfxhidd
, TAG_DONE
);
1716 VOID
cleanup_fakegfxhidd(struct GfxBase
*GfxBase
)
1718 struct common_driverdata
*csd
= CDD(GfxBase
);
1720 if (NULL
!= csd
->fakefbclass
)
1722 OOP_DisposeObject((OOP_Object
*)csd
->fakefbclass
);
1723 csd
->fakefbclass
= NULL
;
1726 if (NULL
!= csd
->fakegfxclass
)
1728 OOP_DisposeObject((OOP_Object
*)csd
->fakegfxclass
);
1729 OOP_ReleaseAttrBase(IID_Hidd_FakeFB
);
1730 csd
->fakegfxclass
= NULL
;