2 Copyright © 1995-2011, 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
;
291 IPTR noframebuffer
= FALSE
;
293 realgfxhidd
= (OOP_Object
*)GetTagData(aHidd_FakeGfxHidd_RealGfxHidd
, (IPTR
)NULL
, msg
->attrList
);
294 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
298 data
= OOP_INST_DATA(cl
, o
);
299 memset(data
, 0, sizeof (*data
));
300 InitSemaphore(&data
->fbsema
);
302 OOP_GetAttr(realgfxhidd
, aHidd_Gfx_NoFrameBuffer
, &noframebuffer
);
303 data
->fakefb_attr
= noframebuffer
? aHidd_BitMap_Displayable
: aHidd_BitMap_FrameBuffer
;
305 data
->gfxhidd
= realgfxhidd
;
307 if (NULL
!= data
->gfxhidd
)
309 struct TagItem gctags
[] =
314 data
->gc
= HIDD_Gfx_NewGC(data
->gfxhidd
, gctags
);
315 if (NULL
!= data
->gc
)
325 mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
326 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&mid
);
332 static VOID
gfx_dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
334 struct gfx_data
*data
;
336 data
= OOP_INST_DATA(cl
, o
);
337 if (NULL
!= data
->curs_backup
)
339 OOP_DisposeObject(data
->curs_backup
);
340 data
->curs_backup
= NULL
;
343 if (data
->curs_pixels
)
344 FreeMem(data
->curs_pixels
, data
->curs_width
* data
->curs_height
* 4);
346 if (NULL
!= data
->gc
)
348 OOP_DisposeObject(data
->gc
);
353 static void gfx_get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
355 struct gfx_data
*data
= OOP_INST_DATA(cl
, o
);
357 if (msg
->attrID
== aHidd_Gfx_HWSpriteTypes
) {
358 *msg
->storage
= vHidd_SpriteType_3Plus1
|vHidd_SpriteType_DirectColor
;
362 OOP_DoMethod(data
->gfxhidd
, (OOP_Msg
)msg
);
365 static OOP_Object
*gfx_newbitmap(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewBitMap
*msg
)
367 /* Is the user about to create a framebuffer ? */
369 struct gfx_data
*data
;
371 OOP_Object
*ret
= NULL
;
373 data
= OOP_INST_DATA(cl
, o
);
374 create_fb
= (BOOL
)GetTagData(data
->fakefb_attr
, FALSE
, msg
->attrList
);
376 realfb
= HIDD_Gfx_NewBitMap(data
->gfxhidd
, msg
->attrList
);
378 if (realfb
&& create_fb
)
380 ret
= create_fake_fb(realfb
, data
, GfxBase
);
382 OOP_DisposeObject(realfb
);
390 static BOOL
gfx_setcursorshape(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorShape
*msg
)
392 struct gfx_data
*data
;
396 data
= OOP_INST_DATA(cl
, o
);
398 D(bug("[FakeGfx] SetCursorShape(0x%p)\n", shape
));
403 /* Erase the old cursor */
404 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
405 data
->curs_on
= FALSE
;
406 data
->curs_bm
= NULL
;
407 data
->curs_x
= data
->curs_y
= 0;
408 data
->curs_maxx
= data
->curs_maxy
= 0;
409 data
->curs_width
= data
->curs_height
= 0;
410 data
->curs_xoffset
= 0;
411 data
->curs_yoffset
= 0;
413 if (NULL
!= data
->curs_backup
)
415 OOP_DisposeObject(data
->curs_backup
);
416 data
->curs_backup
= NULL
;
418 if (data
->curs_pixels
) {
419 FreeMem(data
->curs_pixels
, data
->curs_width
* data
->curs_height
* 4);
420 data
->curs_pixels
= NULL
;
425 IPTR curs_width
, curs_height
;
426 APTR new_curs_pixels
;
427 ULONG curs_pixels_len
;
429 OOP_GetAttr(shape
, aHidd_BitMap_Width
, &curs_width
);
430 OOP_GetAttr(shape
, aHidd_BitMap_Height
, &curs_height
);
432 DCURS(bug("[FakeGfx] New cursor size: %lu x %lu, framebuffer 0x%p\n", curs_width
, curs_height
, data
->framebuffer
));
434 /* Create new cursor pixelbuffer. We multiply size by 4 because we want ARGB data
436 curs_pixels_len
= curs_width
* curs_height
* 4;
437 new_curs_pixels
= AllocMem(curs_pixels_len
, MEMF_ANY
|MEMF_CLEAR
);
438 if (!new_curs_pixels
)
443 /* Erase the old cursor */
444 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
446 /* Now that we have disposed the old image using the old
447 backup bm, we can install the new image and backup bm before
448 rendering the new cursor.
449 Backup bitmap is recreated in rethink_cursor()
452 if (data
->curs_pixels
)
453 FreeMem(data
->curs_pixels
, data
->curs_width
* data
->curs_height
* 4);
455 data
->curs_bm
= shape
;
456 data
->curs_width
= curs_width
;
457 data
->curs_height
= curs_height
;
458 data
->curs_maxx
= data
->curs_x
+ curs_width
- 1;
459 data
->curs_maxy
= data
->curs_y
+ curs_height
- 1;
460 data
->curs_pixels
= new_curs_pixels
;
461 data
->curs_xoffset
= msg
->xoffset
;
462 data
->curs_yoffset
= msg
->yoffset
;
464 ok
= rethink_cursor(data
, GfxBase
);
467 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
473 static BOOL
gfx_setcursorpos(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorPos
*msg
)
475 struct gfx_data
*data
;
479 data
= OOP_INST_DATA(cl
, o
);
480 DPOS(bug("[FakeGfx] SetCursorPos(%d, %d)\n", msg
->x
, msg
->y
));
482 if (!data
->framebuffer
)
485 /* We draw our cursor on the bitmap, so we have to convert back
486 from physical to logical coordinates */
487 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_LeftEdge
, &xoffset
);
488 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_TopEdge
, &yoffset
);
491 /* erase the old cursor */
492 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
494 data
->curs_x
= msg
->x
- xoffset
;
495 data
->curs_y
= msg
->y
- yoffset
;
496 /* Shift to the hotspot location */
497 data
->curs_x
+= data
->curs_xoffset
;
498 data
->curs_y
+= data
->curs_yoffset
;
499 data
->curs_maxx
= data
->curs_x
+ data
->curs_width
- 1;
500 data
->curs_maxy
= data
->curs_y
+ data
->curs_height
- 1;
502 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
507 static VOID
gfx_setcursorvisible(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorVisible
*msg
)
509 struct gfx_data
*data
;
511 data
= OOP_INST_DATA(cl
, o
);
519 data
->curs_on
= TRUE
;
520 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
527 draw_cursor(data
, FALSE
, TRUE
, GfxBase
);
528 data
->curs_on
= FALSE
;
536 #define PIXEL_INSIDE(fgh, x, y) \
537 ( ( (x) >= (fgh)->curs_x ) \
538 && ( (y) >= (fgh)->curs_y ) \
539 && ( (x) <= (fgh)->curs_maxx ) \
540 && ( (y) <= (fgh)->curs_maxy ) )
542 /* NOTE: x1, y1, x2, y2 MUST be sorted */
543 #define RECT_INSIDE(fgh, x1, y1, x2, y2) \
544 ( ( (x1) <= fgh->curs_maxx ) \
545 && ( (x2) >= fgh->curs_x ) \
546 && ( (y1) <= fgh->curs_maxy ) \
547 && ( (y2) >= fgh->curs_y ) )
549 #define WRECT_INSIDE(fgh, x1, y1, width, height) \
550 RECT_INSIDE(fgh, x1, y1, (x1) + (width) - 1, (y1) + (height) - 1)
552 static void gfx_copybox(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CopyBox
*msg
)
554 struct gfx_data
*data
;
555 OOP_Object
*src
= NULL
;
556 OOP_Object
*dest
= NULL
;
559 data
= OOP_INST_DATA(cl
, o
);
562 /* De-masquerade bitmap objects, every of which can be fakefb object */
563 OOP_GetAttr(msg
->src
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&src
);
564 OOP_GetAttr(msg
->dest
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&dest
);
570 /* FIXME: other bitmap may belong to another instance of fakegfx which can be on
571 display on another monitor. In this case mouse cursor should be handled also
572 there. Needs further reengineering. */
573 if ((msg
->src
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->srcX
, msg
->srcY
, msg
->width
, msg
->height
))
576 if ((msg
->dest
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
580 draw_cursor(data
, FALSE
, FALSE
, GfxBase
);
582 HIDD_Gfx_CopyBox(data
->gfxhidd
, src
, msg
->srcX
, msg
->srcY
,
583 dest
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
, msg
->gc
);
586 draw_cursor(data
, TRUE
, FALSE
, GfxBase
);
591 static IPTR
gfx_copyboxmasked(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CopyBoxMasked
*msg
)
593 struct gfx_data
*data
;
594 OOP_Object
*src
= NULL
;
595 OOP_Object
*dest
= NULL
;
599 data
= OOP_INST_DATA(cl
, o
);
602 /* De-masquerade bitmap objects, every of which can be fakefb object */
603 OOP_GetAttr(msg
->src
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&src
);
604 OOP_GetAttr(msg
->dest
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&dest
);
611 * FIXME: other bitmap may belong to another instance of fakegfx which can be on
612 * display on another monitor. In this case mouse cursor should be handled also
613 * there. Needs further reengineering.
615 if ((msg
->src
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->srcX
, msg
->srcY
, msg
->width
, msg
->height
))
618 if ((msg
->dest
== data
->fakefb
) && WRECT_INSIDE(data
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
622 draw_cursor(data
, FALSE
, FALSE
, GfxBase
);
624 ret
= HIDD_Gfx_CopyBoxMasked(data
->gfxhidd
, src
, msg
->srcX
, msg
->srcY
,
625 dest
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
, msg
->mask
, msg
->gc
);
628 draw_cursor(data
, TRUE
, FALSE
, GfxBase
);
635 static OOP_Object
*gfx_show(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Show
*msg
)
638 struct gfx_data
*data
;
640 data
= OOP_INST_DATA(cl
, o
);
643 D(bug("[FakeGfx] Show(0x%p)\n", ret
));
646 * If we are attempting to show a fake bitmap, we are working
647 * in NoFrameBuffer mode where each displayable bitmap is
650 if (ret
&& (OOP_OCLASS(ret
) == CDD(GfxBase
)->fakefbclass
))
653 OOP_GetAttr(msg
->bitMap
, aHidd_FakeFB_RealBitMap
, (IPTR
*)&ret
);
654 D(bug("[FakeGfx] Bitmap is a fakefb object, real bitmap is 0x%p\n", ret
));
658 draw_cursor(data
, FALSE
, FALSE
, GfxBase
);
660 ret
= HIDD_Gfx_Show(data
->gfxhidd
, ret
, msg
->flags
);
661 D(bug("[FakeGfx] Real framebuffer object 0x%p\n", ret
));
662 gfx_setFrameBuffer(GfxBase
, data
, ret
);
665 /* FIXME: temporary workaround: at this point Intuition has already destroyed
666 the sprite image (since the last screen was closed) but we have no information
667 about it. Perhaps FreeSpriteData() should track this down somehow and inform
668 drivers about destroyed sprites.
670 data->curs_bm = NULL;*/
671 rethink_cursor(data
, GfxBase
);
672 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
676 D(bug("[FakeGfx] Returning 0x%p\n", ret
));
680 static ULONG
gfx_showviewports(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
682 /* Composition is not supported here */
686 static BOOL
gfx_getmaxspritesize(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMaxSpriteSize
*msg
)
688 if (msg
->Type
& (vHidd_SpriteType_3Plus1
|vHidd_SpriteType_DirectColor
)) {
689 /* I hope these values are enough for everyone :) */
691 *msg
->Height
= 65535;
698 static IPTR
gfx_fwd(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
700 struct gfx_data
*data
;
702 data
= OOP_INST_DATA(cl
, o
);
704 return OOP_DoMethod(data
->gfxhidd
, msg
);
707 /* Private non-virtual method */
708 static BOOL
FakeGfx_UpdateFrameBuffer(OOP_Object
*o
)
710 OOP_Class
*cl
= OOP_OCLASS(o
);
711 struct gfx_data
*data
= OOP_INST_DATA(cl
, o
);
716 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_Width
, &data
->fb_width
);
717 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_Height
, &data
->fb_height
);
719 DCURS(bug("[FakeGfx] Changed framebuffer size: %u x %u\n", data
->fb_width
, data
->fb_height
));
721 ok
= rethink_cursor(data
, GfxBase
);
724 draw_cursor(data
, TRUE
, TRUE
, GfxBase
);
730 OOP_Object
*framebuffer
;
731 OOP_Object
*fakegfxhidd
;
734 #define FGH(data) ((struct gfx_data *)data->fakegfxhidd)
735 #define REMOVE_CURSOR(data) \
736 draw_cursor(FGH(data), FALSE, FALSE, GfxBase)
738 #define RENDER_CURSOR(data) \
739 draw_cursor(FGH(data), TRUE, FALSE, GfxBase)
742 #define BITMAP_METHOD_INIT \
743 struct fakefb_data *data; \
744 BOOL inside = FALSE; \
746 struct gfx_data *fgh; \
747 data = OOP_INST_DATA(cl, o); \
751 #define FORWARD_METHOD \
752 retval = OOP_DoMethod(data->framebuffer, (OOP_Msg)msg);
754 #define BITMAP_METHOD_EXIT \
756 RENDER_CURSOR(data); \
761 static OOP_Object
*fakefb_new(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
763 OOP_Object
*framebuffer
;
764 OOP_Object
*fakegfxhidd
;
766 framebuffer
= (OOP_Object
*)GetTagData(aHidd_FakeFB_RealBitMap
, 0, msg
->attrList
);
767 fakegfxhidd
= (OOP_Object
*)GetTagData(aHidd_FakeFB_FakeGfxHidd
, 0, msg
->attrList
);
769 if (NULL
== framebuffer
|| NULL
== fakegfxhidd
)
771 D(bug("!!! FakeBM::New(): MISSING FRAMEBUFFER OR FAKE GFX HIDD !!!\n"));
775 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
778 struct fakefb_data
*data
;
779 data
= OOP_INST_DATA(cl
, o
);
780 data
->framebuffer
= framebuffer
;
781 data
->fakegfxhidd
= fakegfxhidd
;
786 static VOID
fakefb_dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
788 struct fakefb_data
*data
;
789 data
= OOP_INST_DATA(cl
, o
);
790 if (NULL
!= data
->framebuffer
)
792 OOP_DisposeObject(data
->framebuffer
);
793 data
->framebuffer
= NULL
;
797 static void fakefb_get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
799 struct fakefb_data
*data
= OOP_INST_DATA(cl
, o
);
801 if (msg
->attrID
== aHidd_FakeFB_RealBitMap
)
803 *msg
->storage
= (IPTR
)data
->framebuffer
;
806 else if (msg
->attrID
== aHidd_BitMap_GfxHidd
)
808 *msg
->storage
= (IPTR
)data
->fakegfxhidd
;
812 OOP_DoMethod(data
->framebuffer
, (OOP_Msg
)msg
);
815 /* Intercept framebuffer mode change */
816 static IPTR
fakefb_set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
818 struct fakefb_data
*data
= OOP_INST_DATA(cl
, o
);
819 IPTR ret
= OOP_DoMethod(data
->framebuffer
, &msg
->mID
);
820 struct TagItem
*modeid
= FindTagItem(aHidd_BitMap_ModeID
, msg
->attrList
);
824 /* Framebuffer mode change succeeded. Update fakegfx' information */
825 ret
= FakeGfx_UpdateFrameBuffer(data
->fakegfxhidd
);
831 static IPTR
fakefb_getpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetPixel
*msg
)
835 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
846 static IPTR
fakefb_putpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPixel
*msg
)
850 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
861 static IPTR
fakefb_drawpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPixel
*msg
)
865 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
876 static IPTR
fakefb_drawline(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawLine
*msg
)
878 register LONG x1
, y1
, x2
, y2
;
881 if (msg
->x1
< msg
->x2
)
883 x1
= msg
->x1
; x2
= msg
->x2
;
887 x2
= msg
->x1
; x1
= msg
->x2
;
890 if (msg
->y1
< msg
->y2
)
892 y1
= msg
->y1
; y2
= msg
->y2
;
896 y2
= msg
->y1
; y1
= msg
->y2
;
899 /* FIXME: Maybe do some more intelligent checking for DrawLine */
900 if (RECT_INSIDE(fgh
, x1
, y1
, x2
, y2
))
911 static IPTR
fakefb_getimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImage
*msg
)
915 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
926 static IPTR
fakefb_putimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImage
*msg
)
930 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
941 static IPTR
fakefb_putalphaimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutAlphaImage
*msg
)
945 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
956 static IPTR
fakefb_puttemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
960 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
971 static IPTR
fakefb_putalphatemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutAlphaTemplate
*msg
)
975 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
986 static IPTR
fakefb_putpattern(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPattern
*msg
)
990 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1001 static IPTR
fakefb_getimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImageLUT
*msg
)
1005 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1007 REMOVE_CURSOR(data
);
1016 static IPTR
fakefb_putimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImageLUT
*msg
)
1020 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1022 REMOVE_CURSOR(data
);
1031 static IPTR
fakefb_puttranspimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTranspImageLUT
*msg
)
1035 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
1037 REMOVE_CURSOR(data
);
1046 static IPTR
fakefb_drawrect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
1050 /* FIXME: Maybe do something clever here to see if the rectangle is drawn around the cursor */
1051 if (RECT_INSIDE(fgh
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
))
1053 REMOVE_CURSOR(data
);
1062 static IPTR
fakefb_fillrect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
1066 /* bug("BITMAP FILLRECT(%d, %d, %d, %d), (%d, %d, %d, %d, %d, %d)\n"
1067 , msg->minX, msg->minY, msg->maxX, msg->maxY
1068 , fgh->curs_x, fgh->curs_y, fgh->curs_maxx, fgh->curs_maxy
1069 , fgh->curs_width, fgh->curs_height);
1071 if (RECT_INSIDE(fgh
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
))
1073 /* bug("FILLRECT: REMOVING CURSOR\n");
1075 REMOVE_CURSOR(data
);
1085 static IPTR
fakefb_drawellipse(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawEllipse
*msg
)
1087 register LONG x1
, y1
, x2
, y2
;
1090 x1
= msg
->x
- msg
->rx
;
1091 y1
= msg
->y
- msg
->ry
;
1092 x2
= msg
->x
+ msg
->rx
;
1093 y2
= msg
->y
+ msg
->ry
;
1094 /* FIXME: Maybe do something clever here to see if the rectangle is drawn around the cursor */
1096 if (RECT_INSIDE(fgh
, x1
, y1
, x2
, y2
))
1098 REMOVE_CURSOR(data
);
1107 static IPTR
fakefb_fillellipse(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawEllipse
*msg
)
1109 register LONG x1
, y1
, x2
, y2
;
1112 x1
= msg
->x
- msg
->rx
;
1113 y1
= msg
->y
- msg
->ry
;
1114 x2
= msg
->x
+ msg
->rx
;
1115 y2
= msg
->y
+ msg
->ry
;
1117 if (RECT_INSIDE(fgh
, x1
, y1
, x2
, y2
))
1119 REMOVE_CURSOR(data
);
1128 static IPTR
fakefb_drawpolygon(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPolygon
*msg
)
1131 /* FIXME: Maybe do checking here, but it probably is not worth it */
1132 REMOVE_CURSOR(data
);
1140 static IPTR
fakefb_fillpolygon(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPolygon
*msg
)
1143 /* FIXME: Maybe do checking here, but it probably is not worth it */
1144 REMOVE_CURSOR(data
);
1153 static IPTR
fakefb_drawtext(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawText
*msg
)
1157 /* FIXME: Maybe do testing here, but probably not wirth it */
1158 REMOVE_CURSOR(data
);
1165 static IPTR
fakefb_drawfilltext(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawText
*msg
)
1169 /* FIXME: Maybe do testing here, but probably not worth it */
1170 REMOVE_CURSOR(data
);
1177 static IPTR
fakefb_blitcolexp(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BlitColorExpansion
*msg
)
1181 if (WRECT_INSIDE(fgh
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
1183 REMOVE_CURSOR(data
);
1192 static IPTR
fakefb_clear(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_Clear
*msg
)
1204 static IPTR
fakefb_fillspan(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
1208 REMOVE_CURSOR(data
);
1216 static IPTR
fakefb_scale(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BitMapScale
*msg
)
1218 /* FIXME: should check both source and destination, similar to gfx_copybox() */
1221 if (WRECT_INSIDE(fgh
, msg
->bsa
->bsa_SrcX
, msg
->bsa
->bsa_SrcY
, msg
->bsa
->bsa_SrcWidth
, msg
->bsa
->bsa_SrcHeight
))
1223 REMOVE_CURSOR(data
);
1232 static IPTR
fakefb_fwd(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
1234 struct fakefb_data
*data
;
1235 data
= OOP_INST_DATA(cl
, o
);
1236 // kill(getpid(), 19);
1237 // bug("BITMAP_FWD\n");
1238 return OOP_DoMethod(data
->framebuffer
, msg
);
1243 static BOOL
rethink_cursor(struct gfx_data
*data
, struct GfxBase
*GfxBase
)
1245 OOP_Object
*pf
, *cmap
;
1246 IPTR fbdepth
, curdepth
, i
;
1247 UWORD curs_base
= 16;
1249 struct TagItem bmtags
[] = {
1250 { aHidd_BitMap_Width
, data
->curs_width
},
1251 { aHidd_BitMap_Height
, data
->curs_height
},
1252 { aHidd_BitMap_Friend
, (IPTR
)data
->framebuffer
},
1256 D(bug("rethink_cursor(), curs_bm is 0x%p, framebuffer is 0x%p\n", data
->curs_bm
, data
->framebuffer
));
1258 /* The first thing we do is recreating a backup bitmap. We do it every time when either
1259 cursor shape changes (because new shape may have different size) or shown bitmap
1260 changes (because new bitmap may have different depth). Note that even real framebuffer
1261 object may dynamically change its characteristics.
1263 Delete the old backup bitmap first */
1264 if (NULL
!= data
->curs_backup
) {
1265 OOP_DisposeObject(data
->curs_backup
);
1266 D(bug("[FakeGfx] Disposed old backup bitmap\n"));
1267 data
->curs_backup
= NULL
;
1270 /* If we have no cursor, we have nothing more to do.
1271 We also don't need new backup bitmap */
1275 /* We may also have no framebuffer (empty display on
1276 non-framebuffer driver). Also NOP in this case */
1277 if (!data
->framebuffer
)
1280 /* Create new backup bitmap */
1281 data
->curs_backup
= HIDD_Gfx_NewBitMap(data
->gfxhidd
, bmtags
);
1282 D(bug("[FakeGfx] New backup bitmap is 0x%p\n", data
->curs_backup
));
1283 if (!data
->curs_backup
)
1286 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1287 D(bug("[FakeGfx] Framebuffer pixelformat 0x%p\n", pf
));
1288 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &fbdepth
);
1289 D(bug("[FakeGfx] Framebuffer depth %u\n", fbdepth
));
1290 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_ColorMap
, (IPTR
*)&cmap
);
1291 D(bug("[FakeGfx] Cursor colormap 0x%p\n", cmap
));
1292 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1293 D(bug("[FakeGfx] Cursor pixelformat 0x%p\n", pf
));
1294 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &curdepth
);
1295 D(bug("[FakeGfx] Cursor depth %u\n", curdepth
));
1297 #ifndef DISABLE_ARGB_POINTER
1298 /* We can get ARGB data from the pointer bitmap only
1299 on one of two cases:
1300 1) Pointer bitmap has more than 256 colors, in this case it
1301 stores ARGB data in itself.
1302 2) Pointer bitmap is a LUT bitmap with a colormap attached.
1303 In this case colormap should contain ARGB values for actual
1305 Of course having ARGB data makes sense only on truecolor screens. */
1306 if ((fbdepth
> 8) && ((curdepth
> 8) || cmap
)) {
1307 data
->curs_pixfmt
= vHidd_StdPixFmt_ARGB32
;
1312 data
->curs_pixfmt
= vHidd_StdPixFmt_LUT8
;
1314 /* TODO: curs_base should be somehow synchronised with SpriteBase field of ColorMap */
1315 curs_base
= (fbdepth
> 4) ? 16 : (1 << fbdepth
) - 8;
1317 /* If we have some good bitmap->bitmap blitting function with alpha channel support,
1318 we would not need this extra buffer and conversion for truecolor screens. */
1319 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
);
1320 D(bug("[FakeGfx] Obtained cursor sprite data @ 0x%p\n", data
->curs_pixels
));
1322 if (data
->curs_pixfmt
== vHidd_StdPixFmt_LUT8
)
1324 for (i
= 0; i
< data
->curs_width
* data
->curs_height
; i
++)
1326 if (data
->curs_pixels
[i
])
1327 data
->curs_pixels
[i
] += curs_base
;
1333 static VOID
draw_cursor(struct gfx_data
*data
, BOOL draw
, BOOL updaterect
, struct GfxBase
*GfxBase
)
1336 LONG fbwidth
, fbheight
;
1342 struct TagItem gctags
[] =
1344 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
1351 if (NULL
== data
->curs_bm
|| NULL
== data
->framebuffer
)
1353 DB2(bug("!!! draw_cursor: FAKE GFX HIDD NOT PROPERLY INITIALIZED !!!\n"));
1354 DB2(bug("CURS BM: 0x%p, FB: 0x%p\n", data
->curs_bm
, data
->framebuffer
));
1358 fbwidth
= data
->fb_width
;
1359 fbheight
= data
->fb_height
;
1360 width
= data
->curs_width
;
1361 height
= data
->curs_height
;
1365 /* Do nothing if sprite went outside of bitmap */
1366 if ((x
< -width
) || (y
< -height
)) {
1367 DCURS(bug("[FakeGfx] Cursor is beyond left or top edge\n"));
1370 if ((x
>= fbwidth
) || (y
>= fbheight
)) {
1371 DCURS(bug("[FakeGfx] Cursor is beyond right or bottom edge\n"));
1375 /* Do some clipping */
1388 w2end
= data
->fb_width
- width
;
1389 h2end
= data
->fb_height
- width
;
1393 width
-= (x
- w2end
);
1394 DCLIP(bug("[FakeGfx] Clipped sprite width to %d\n", width
));
1399 height
-= (y
- h2end
);
1400 DCLIP(bug("[FakeGfx] Clipped sprite height to %d\n", height
));
1403 /* FIXME: clip negative coordinates */
1405 OOP_SetAttrs(data
->gc
, gctags
);
1409 /* Calculate origin of sprite image according to offsets */
1410 ULONG modulo
= data
->curs_width
* data
->curs_bpp
;
1411 UBYTE
*pixels
= data
->curs_pixels
+ yoffset
* modulo
+ xoffset
* data
->curs_bpp
;
1413 /* Backup under the new cursor image */
1414 // bug("BACKING UP RENDERED AREA\n");
1415 HIDD_Gfx_CopyBox(data
->gfxhidd
1424 data
->backup_done
= TRUE
;
1426 DB2(bug("[FakeGfx] Rendering cursor, framebuffer 0x%p\n", data
->framebuffer
));
1427 /* Render the cursor image */
1428 if (data
->curs_pixfmt
== vHidd_StdPixFmt_ARGB32
)
1429 HIDD_BM_PutAlphaImage(data
->framebuffer
, data
->gc
, pixels
, modulo
, x
, y
, width
, height
);
1431 /* data->curs_bpp is always 1 here so we safely ignore it */
1432 HIDD_BM_PutTranspImageLUT(data
->framebuffer
, data
->gc
, pixels
, modulo
, x
, y
, width
, height
, NULL
, 0);
1435 HIDD_BM_UpdateRect(data
->framebuffer
, x
, y
, width
, height
);
1440 /* Erase the old cursor image */
1441 if (data
->backup_done
)
1443 DB2(bug("[FakeGfx] Restoring cursor area, framebuffer 0x%p\n", data
->framebuffer
));
1444 HIDD_Gfx_CopyBox(data
->gfxhidd
1453 if (updaterect
) HIDD_BM_UpdateRect(data
->framebuffer
, data
->curs_x
, data
->curs_y
, width
, height
);
1459 static void gfx_setFrameBuffer(struct GfxBase
*GfxBase
, struct gfx_data
*data
, OOP_Object
*fb
)
1461 data
->framebuffer
= fb
;
1465 /* Cache framebuffer size, needed by sprite rendering routine */
1466 OOP_GetAttr(fb
, aHidd_BitMap_Width
, &data
->fb_width
);
1467 OOP_GetAttr(fb
, aHidd_BitMap_Height
, &data
->fb_height
);
1469 DCURS(bug("[FakeGfx] Framebuffer size: %u x %u\n", data
->fb_width
, data
->fb_height
));
1473 static OOP_Object
*create_fake_fb(OOP_Object
*framebuffer
, struct gfx_data
*data
, struct GfxBase
*GfxBase
)
1476 struct TagItem fakebmtags
[] =
1478 { aHidd_FakeFB_RealBitMap
, (IPTR
)framebuffer
},
1479 { aHidd_FakeFB_FakeGfxHidd
, (IPTR
)data
},
1483 /* If we work with framebuffer-based driver, Show() will never be called on
1484 a fakefb object so we remember it right now */
1485 fakebm
= OOP_NewObject(CDD(GfxBase
)->fakefbclass
, NULL
, fakebmtags
);
1487 if (data
->fakefb_attr
== aHidd_BitMap_FrameBuffer
)
1489 data
->fakefb
= fakebm
;
1490 gfx_setFrameBuffer(GfxBase
, data
, framebuffer
);
1496 static OOP_Class
*init_fakegfxhiddclass (struct GfxBase
*GfxBase
)
1498 OOP_Class
*cl
= NULL
;
1500 struct OOP_MethodDescr root_descr
[num_Root_Methods
+ 1] =
1502 {(IPTR (*)())gfx_new
, moRoot_New
},
1503 {(IPTR (*)())gfx_dispose
, moRoot_Dispose
},
1504 {(IPTR (*)())gfx_get
, moRoot_Get
},
1505 {(IPTR (*)())gfx_fwd
, moRoot_Set
},
1509 struct OOP_MethodDescr gfxhidd_descr
[num_Hidd_Gfx_Methods
+ 1] =
1511 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_NewGC
},
1512 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_DisposeGC
},
1513 {(IPTR (*)())gfx_newbitmap
, moHidd_Gfx_NewBitMap
},
1514 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_DisposeBitMap
},
1515 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_QueryModeIDs
},
1516 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_ReleaseModeIDs
},
1517 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_CheckMode
},
1518 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_NextModeID
},
1519 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetMode
},
1520 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetPixFmt
},
1521 {(IPTR (*)())gfx_setcursorshape
, moHidd_Gfx_SetCursorShape
},
1522 {(IPTR (*)())gfx_setcursorpos
, moHidd_Gfx_SetCursorPos
},
1523 {(IPTR (*)())gfx_setcursorvisible
, moHidd_Gfx_SetCursorVisible
},
1524 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_SetMode
},
1525 {(IPTR (*)())gfx_show
, moHidd_Gfx_Show
},
1526 {(IPTR (*)())gfx_copybox
, moHidd_Gfx_CopyBox
},
1527 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_ModeProperties
},
1528 {(IPTR (*)())gfx_showviewports
, moHidd_Gfx_ShowViewPorts
},
1529 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetSync
},
1530 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_GetGamma
},
1531 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_SetGamma
},
1532 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_QueryHardware3D
},
1533 {(IPTR (*)())gfx_getmaxspritesize
, moHidd_Gfx_GetMaxSpriteSize
},
1534 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_NewOverlay
},
1535 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_DisposeOverlay
},
1536 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_MakeViewPort
},
1537 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_CleanViewPort
},
1538 {(IPTR (*)())gfx_fwd
, moHidd_Gfx_PrepareViewPorts
},
1539 {(IPTR (*)())gfx_copyboxmasked
, moHidd_Gfx_CopyBoxMasked
},
1543 struct OOP_InterfaceDescr ifdescr
[] =
1545 {root_descr
, IID_Root
, num_Root_Methods
},
1546 {gfxhidd_descr
, IID_Hidd_Gfx
, num_Hidd_Gfx_Methods
},
1550 OOP_AttrBase MetaAttrBase
= OOP_GetAttrBase(IID_Meta
);
1552 struct TagItem tags
[] =
1554 { aMeta_SuperID
, (IPTR
)CLID_Root
},
1555 { aMeta_InterfaceDescr
, (IPTR
)ifdescr
},
1556 { aMeta_InstSize
, (IPTR
)sizeof (struct gfx_data
) },
1561 D(bug("INIT FAKEGFXCLASS\n"));
1563 if ((__IHidd_FakeFB
= OOP_ObtainAttrBase(IID_Hidd_FakeFB
)))
1565 cl
= OOP_NewObject(NULL
, CLID_HiddMeta
, tags
);
1568 D(bug("FAKE GFX CLASS INITED\n"));
1569 cl
->UserData
= GfxBase
;
1574 OOP_ReleaseAttrBase(IID_Hidd_FakeFB
);
1580 static OOP_Class
*init_fakefbclass(struct GfxBase
*GfxBase
)
1582 struct OOP_MethodDescr root_descr
[num_Root_Methods
+ 1] =
1584 {(IPTR (*)())fakefb_new
, moRoot_New
},
1585 {(IPTR (*)())fakefb_dispose
, moRoot_Dispose
},
1586 {(IPTR (*)())fakefb_get
, moRoot_Get
},
1587 {(IPTR (*)())fakefb_set
, moRoot_Set
},
1591 struct OOP_MethodDescr bitmap_descr
[num_Hidd_BitMap_Methods
+ 1] =
1593 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_SetColors
},
1594 {(IPTR (*)())fakefb_putpixel
, moHidd_BitMap_PutPixel
},
1595 {(IPTR (*)())fakefb_drawpixel
, moHidd_BitMap_DrawPixel
},
1596 {(IPTR (*)())fakefb_putimage
, moHidd_BitMap_PutImage
},
1597 {(IPTR (*)())fakefb_putalphaimage
, moHidd_BitMap_PutAlphaImage
},
1598 {(IPTR (*)())fakefb_puttemplate
, moHidd_BitMap_PutTemplate
},
1599 {(IPTR (*)())fakefb_putalphatemplate
, moHidd_BitMap_PutAlphaTemplate
},
1600 {(IPTR (*)())fakefb_putpattern
, moHidd_BitMap_PutPattern
},
1601 {(IPTR (*)())fakefb_getimage
, moHidd_BitMap_GetImage
},
1602 {(IPTR (*)())fakefb_getpixel
, moHidd_BitMap_GetPixel
},
1603 {(IPTR (*)())fakefb_drawline
, moHidd_BitMap_DrawLine
},
1604 {(IPTR (*)())fakefb_drawrect
, moHidd_BitMap_DrawRect
},
1605 {(IPTR (*)())fakefb_fillrect
, moHidd_BitMap_FillRect
},
1606 {(IPTR (*)())fakefb_drawellipse
, moHidd_BitMap_DrawEllipse
},
1607 {(IPTR (*)())fakefb_fillellipse
, moHidd_BitMap_FillEllipse
},
1608 {(IPTR (*)())fakefb_drawpolygon
, moHidd_BitMap_DrawPolygon
},
1609 {(IPTR (*)())fakefb_fillpolygon
, moHidd_BitMap_FillPolygon
},
1610 {(IPTR (*)())fakefb_drawtext
, moHidd_BitMap_DrawText
},
1611 {(IPTR (*)())fakefb_drawfilltext
, moHidd_BitMap_FillText
},
1612 {(IPTR (*)())fakefb_fillspan
, moHidd_BitMap_FillSpan
},
1613 {(IPTR (*)())fakefb_clear
, moHidd_BitMap_Clear
},
1614 {(IPTR (*)())fakefb_blitcolexp
, moHidd_BitMap_BlitColorExpansion
},
1615 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_MapColor
},
1616 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_UnmapPixel
},
1617 {(IPTR (*)())fakefb_putimagelut
, moHidd_BitMap_PutImageLUT
},
1618 {(IPTR (*)())fakefb_puttranspimagelut
, moHidd_BitMap_PutTranspImageLUT
},
1619 {(IPTR (*)())fakefb_getimagelut
, moHidd_BitMap_GetImageLUT
},
1620 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_BytesPerLine
},
1621 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_ConvertPixels
},
1622 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect8
},
1623 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect16
},
1624 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect24
},
1625 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_FillMemRect32
},
1626 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_InvertMemRect
},
1627 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox8
},
1628 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox16
},
1629 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox24
},
1630 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyMemBox32
},
1631 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyLUTMemBox16
},
1632 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyLUTMemBox24
},
1633 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_CopyLUTMemBox32
},
1634 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMem32Image8
},
1635 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMem32Image16
},
1636 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMem32Image24
},
1637 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_GetMem32Image8
},
1638 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_GetMem32Image16
},
1639 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_GetMem32Image24
},
1640 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate8
},
1641 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate16
},
1642 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate24
},
1643 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemTemplate32
},
1644 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern8
},
1645 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern16
},
1646 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern24
},
1647 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PutMemPattern32
},
1648 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_SetColorMap
},
1649 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_ObtainDirectAccess
},
1650 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_ReleaseDirectAccess
},
1651 {(IPTR (*)())fakefb_scale
, moHidd_BitMap_BitMapScale
},
1652 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_PrivateSet
},
1653 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_SetRGBConversionFunction
},
1654 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_UpdateRect
},
1658 struct OOP_InterfaceDescr ifdescr
[] =
1660 {root_descr
, IID_Root
, num_Root_Methods
},
1661 {bitmap_descr
, IID_Hidd_BitMap
, num_Hidd_BitMap_Methods
},
1665 OOP_AttrBase MetaAttrBase
= OOP_GetAttrBase(IID_Meta
);
1667 struct TagItem tags
[] =
1669 {aMeta_SuperID
, (IPTR
) CLID_Root
},
1670 {aMeta_InterfaceDescr
, (IPTR
) ifdescr
},
1671 {aMeta_InstSize
, (IPTR
) sizeof(struct fakefb_data
) },
1675 OOP_Class
*cl
= NULL
;
1679 cl
= OOP_NewObject(NULL
, CLID_HiddMeta
, tags
);
1681 cl
->UserData
= GfxBase
;
1682 } /* if(MetaAttrBase) */
1687 OOP_Object
*init_fakegfxhidd(OOP_Object
*gfxhidd
, struct GfxBase
*GfxBase
)
1689 struct common_driverdata
*csd
= CDD(GfxBase
);
1691 if (!csd
->fakegfxclass
)
1693 /* Lazy class initialization */
1694 csd
->fakegfxclass
= init_fakegfxhiddclass(GfxBase
);
1695 csd
->fakefbclass
= init_fakefbclass(GfxBase
);
1697 if (!csd
->fakegfxclass
|| !csd
->fakefbclass
)
1699 cleanup_fakegfxhidd(GfxBase
);
1705 return OOP_NewObjectTags(csd
->fakegfxclass
, NULL
, aHidd_FakeGfxHidd_RealGfxHidd
, gfxhidd
, TAG_DONE
);
1708 VOID
cleanup_fakegfxhidd(struct GfxBase
*GfxBase
)
1710 struct common_driverdata
*csd
= CDD(GfxBase
);
1712 if (NULL
!= csd
->fakefbclass
)
1714 OOP_DisposeObject((OOP_Object
*)csd
->fakefbclass
);
1715 csd
->fakefbclass
= NULL
;
1718 if (NULL
!= csd
->fakegfxclass
)
1720 OOP_DisposeObject((OOP_Object
*)csd
->fakegfxclass
);
1721 OOP_ReleaseAttrBase(IID_Hidd_FakeFB
);
1722 csd
->fakegfxclass
= NULL
;