added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / rom / graphics / fakegfxhidd.c
blob1afb23b7f0bfd54ac6d426148aafa1c40816f6eb
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <string.h>
8 #include <proto/exec.h>
9 #include <proto/oop.h>
10 #include <proto/utility.h>
11 #include <oop/oop.h>
12 #include <hidd/graphics.h>
13 #include <aros/atomic.h>
14 #include <proto/arossupport.h>
16 #include "graphics_intern.h"
17 #include "graphics_internal.h"
18 #include "fakegfxhidd.h"
20 #define DEBUG 1
21 #include <aros/debug.h>
23 /******************************************************************************/
25 #define SPECIAL_LOCKING 1 /* When activated mouse cursor relevant locks are
26 treated in some kind of privileged way, by
27 inserting wait-for-sem-requests at head of
28 wait queue, instead of at tail */
30 /******************************************************************************/
32 static OOP_Class *init_fakefbclass(struct class_static_data *csd);
33 static VOID free_fakefbclass(OOP_Class *cl, struct class_static_data *csd);
35 static OOP_Class *init_fakegfxhiddclass (struct class_static_data *csd);
36 static VOID free_fakegfxhiddclass(OOP_Class *cl, struct class_static_data *csd);
38 /******************************************************************************/
40 struct gfx_data
42 OOP_Object *gfxhidd;
43 OOP_Object *framebuffer;
44 OOP_Object *fakefb;
45 OOP_Object *gc;
47 OOP_Object *curs_bm;
48 OOP_Object *curs_backup;
49 HIDDT_Pixel curs_pixels[256];
50 BOOL curs_on;
51 LONG curs_x;
52 LONG curs_y;
53 ULONG curs_width;
54 ULONG curs_height;
55 LONG curs_maxx;
56 LONG curs_maxy;
57 struct SignalSemaphore fbsema;
58 BOOL backup_done;
61 /******************************************************************************/
63 static VOID draw_cursor(struct gfx_data *data, BOOL draw, struct class_static_data *csd);
64 static VOID rethink_cursor(struct gfx_data *data, struct class_static_data *csd);
65 static OOP_Object *create_fake_fb(OOP_Object *framebuffer, struct gfx_data *data, struct class_static_data *csd);
67 /******************************************************************************/
69 #define LFB(data) ObtainSemaphore(&(data)->fbsema)
70 #define UFB(data) ReleaseSemaphore(&(data)->fbsema)
71 #define LFB_QUICK(data) ObtainSemaphore(&(data)->fbsema)
72 #define UFB_QUICK(data) ReleaseSemaphore(&(data)->fbsema)
74 #define CSD(cl) ((struct class_static_data *)cl->UserData)
76 #define __IHidd_FakeFB (CSD(cl)->hiddFakeFBAttrBase)
78 /******************************************************************************/
80 #if SPECIAL_LOCKING
82 /******************************************************************************/
84 #undef SysBase
86 static void FakeGfxHidd_ObtainSemaphore(struct SignalSemaphore *sigSem, BOOL urgent,
87 struct ExecBase *SysBase)
89 struct Task *me;
91 /* Get pointer to current task */
92 me=SysBase->ThisTask;
94 /* Arbitrate for the semaphore structure */
95 Forbid();
98 ss_QueueCount == -1 indicates that the semaphore is
99 free, so we increment this straight away. If it then
100 equals 0, then we are the first to allocate this semaphore.
102 Note: This will need protection for SMP machines.
104 sigSem->ss_QueueCount++;
105 if( sigSem->ss_QueueCount == 0 )
107 /* We now own the semaphore. This is quick. */
108 sigSem->ss_Owner = me;
109 sigSem->ss_NestCount++;
112 /* The semaphore was in use, but was it by us? */
113 else if( sigSem->ss_Owner == me )
115 /* Yes, just increase the nesting count */
116 sigSem->ss_NestCount++;
120 Else, some other task must own it. We have
121 to set a waiting request here.
123 else
126 We need a node to mark our semaphore request. Lets use some
127 stack memory.
129 struct SemaphoreRequest sr;
130 sr.sr_Waiter = me;
133 Have to clear the signal to make sure that we don't
134 return immediately. We then add the SemReq to the
135 waiters list of the semaphore. We were the last to
136 request, so we must be the last to get the semaphore.
139 #warning This must be atomic!
140 AROS_ATOMIC_AND(me->tc_SigRecvd, ~SIGF_SINGLE);
142 if (urgent)
144 AddHead((struct List *)&sigSem->ss_WaitQueue, (struct Node *)&sr);
146 else
148 AddTail((struct List *)&sigSem->ss_WaitQueue, (struct Node *)&sr);
152 Finally, we simply wait, ReleaseSemaphore() will fill in
153 who owns the semaphore.
155 Wait(SIGF_SINGLE);
158 /* All Done! */
159 Permit();
163 /******************************************************************************/
165 static void FakeGfxHidd_ReleaseSemaphore(struct SignalSemaphore *sigSem,
166 struct ExecBase *SysBase)
168 /* Protect the semaphore structure from multiple access. */
169 Forbid();
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
197 is shared or not.
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 */
233 else
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. */
245 else
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 );
260 /* All done. */
261 Permit();
265 /******************************************************************************/
267 #undef LFB
268 #undef UFB
269 #undef LFB_QUICK
270 #undef UFB_QUICK
272 #define LFB(data) FakeGfxHidd_ObtainSemaphore(&(data)->fbsema, FALSE, SysBase)
273 #define UFB(data) FakeGfxHidd_ReleaseSemaphore(&(data)->fbsema, SysBase)
275 #define LFB_QUICK(data) FakeGfxHidd_ObtainSemaphore(&(data)->fbsema, TRUE, SysBase)
276 #define UFB_QUICK(data) FakeGfxHidd_ReleaseSemaphore(&(data)->fbsema, SysBase)
279 /******************************************************************************/
281 #endif /* SPECIAL_LOCKING */
283 /******************************************************************************/
285 #undef GfxBase
286 #define GfxBase (CSD(cl)->gfxbase)
288 static OOP_Object *gfx_new(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
290 /* Create a new gfxhid object */
291 OOP_Object *realgfxhidd;
292 struct gfx_data *data;
293 BOOL ok = FALSE;
295 realgfxhidd = (OOP_Object *)GetTagData(aHidd_FakeGfxHidd_RealGfxHidd, (IPTR)NULL, msg->attrList);
296 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
297 if (NULL == o)
298 return NULL;
300 data = OOP_INST_DATA(cl, o);
301 memset(data, 0, sizeof (*data));
302 InitSemaphore(&data->fbsema);
304 data->gfxhidd = realgfxhidd;
306 if (NULL != data->gfxhidd)
308 struct TagItem gctags[] =
310 { TAG_DONE, 0UL }
313 data->gc = HIDD_Gfx_NewGC(data->gfxhidd, gctags);
314 if (NULL != data->gc)
316 ok = TRUE;
320 if (!ok)
322 OOP_MethodID mid;
324 mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
325 OOP_CoerceMethod(cl, o, (OOP_Msg)&mid);
328 return o;
331 static VOID gfx_dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
333 struct gfx_data *data;
335 data = OOP_INST_DATA(cl, o);
336 if (NULL != data->curs_backup)
338 OOP_DisposeObject(data->curs_backup);
339 data->curs_backup = NULL;
342 if (NULL != data->gc)
344 OOP_DisposeObject(data->gc);
345 data->gc = NULL;
348 #if 0
349 if (NULL != data->gfxhidd)
351 OOP_DisposeObject(data->gfxhidd);
352 data->gfxhidd = NULL;
354 #endif
357 static OOP_Object *gfx_newbitmap(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewBitMap *msg)
359 /* Is the user about to create a framebuffer ? */
360 BOOL create_fb;
361 struct gfx_data *data;
362 OOP_Object *realfb;
363 OOP_Object *ret = NULL;
364 BOOL ok = TRUE;
366 data = OOP_INST_DATA(cl, o);
367 create_fb = (BOOL)GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
369 realfb = HIDD_Gfx_NewBitMap(data->gfxhidd, msg->attrList);
371 if (NULL != realfb && create_fb)
373 OOP_Object *fakefb;
374 fakefb = create_fake_fb(realfb, data, CSD(cl));
375 if (NULL != fakefb)
377 ret = fakefb;
378 data->framebuffer = realfb;
380 else
382 ok = FALSE;
385 else
387 ret = realfb;
390 if (!ok)
392 OOP_DisposeObject(realfb);
393 ret = NULL;
396 return ret;
399 static BOOL gfx_setcursorshape(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorShape *msg)
401 struct gfx_data *data;
402 OOP_Object *shape;
404 data = OOP_INST_DATA(cl, o);
405 shape = msg->shape;
407 /* Bitmap changed */
408 if (NULL == shape)
410 /* Erase the old cursor */
411 draw_cursor(data, FALSE, CSD(cl));
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;
418 if (NULL != data->curs_backup)
420 OOP_DisposeObject(data->curs_backup);
421 data->curs_backup = NULL;
425 else
428 IPTR curs_width, curs_height, curs_depth;
429 IPTR mode_width, mode_height, mode_depth;
430 OOP_Object *curs_pf, *mode_sync,* mode_pf;
431 IPTR fbmode;
432 OOP_Object *new_backup;
434 struct TagItem bmtags[] =
436 { aHidd_BitMap_Displayable , FALSE },
437 { aHidd_BitMap_Width , 0 },
438 { aHidd_BitMap_Height , 0 },
439 { aHidd_BitMap_Friend , 0 },
440 { TAG_DONE , 0UL }
443 OOP_GetAttr(shape, aHidd_BitMap_Width, &curs_width);
444 OOP_GetAttr(shape, aHidd_BitMap_Height, &curs_height);
446 OOP_GetAttr(shape, aHidd_BitMap_PixFmt, (IPTR *)&curs_pf);
448 OOP_GetAttr(curs_pf, aHidd_PixFmt_Depth, &curs_depth);
449 OOP_GetAttr(data->framebuffer, aHidd_BitMap_ModeID, &fbmode);
450 HIDD_Gfx_GetMode(o, (HIDDT_ModeID)fbmode, &mode_sync, &mode_pf);
452 OOP_GetAttr(mode_sync, aHidd_Sync_HDisp, &mode_width);
453 OOP_GetAttr(mode_sync, aHidd_Sync_VDisp, &mode_height);
454 OOP_GetAttr(mode_pf, aHidd_PixFmt_Depth, &mode_depth);
456 /* Disallow very large cursors, and cursors with higher
457 depth than the framebuffer bitmap */
458 if ( ( curs_width > (mode_width / 2) )
459 || ( curs_height > (mode_height / 2) )
460 || ( curs_depth > mode_depth) )
462 D(bug("!!! FakeGfx::SetCursorShape: CURSOR BM HAS INVALID ATTRS !!!\n"));
463 return FALSE;
466 /* Create new backup bitmap */
467 bmtags[1].ti_Data = curs_width;
468 bmtags[2].ti_Data = curs_height;
469 bmtags[3].ti_Data = (IPTR)data->framebuffer;
471 new_backup = HIDD_Gfx_NewBitMap(data->gfxhidd, bmtags);
473 if (NULL == new_backup)
475 D(bug("!!! FakeGfx::SetCursorShape: COULD NOT CREATE BACKUP BM !!!\n"));
476 return FALSE;
479 data->curs_bm = shape;
481 if (data->curs_on)
483 /* Erase the old cursor */
484 draw_cursor(data, FALSE, CSD(cl));
486 /* Now that we have disposed the old image using the old
487 backup bm, we can install the new backup bm before
488 rendering the new curso
491 if (NULL != data->curs_backup)
492 OOP_DisposeObject(data->curs_backup);
494 data->curs_width = curs_width;
495 data->curs_height = curs_height;
497 data->curs_maxx = data->curs_x + curs_width - 1;
498 data->curs_maxy = data->curs_y + curs_height - 1;
499 data->curs_backup = new_backup;
501 rethink_cursor(data, CSD(cl));
503 draw_cursor(data, TRUE, CSD(cl));
506 else
509 if (NULL != data->curs_backup)
510 OOP_DisposeObject(data->curs_backup);
512 data->curs_width = curs_width;
513 data->curs_height = curs_height;
515 data->curs_maxx = data->curs_x + curs_width - 1;
516 data->curs_maxy = data->curs_y + curs_height - 1;
517 data->curs_backup = new_backup;
519 rethink_cursor(data, CSD(cl));
525 return TRUE;
528 static BOOL gfx_setcursorpos(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorPos *msg)
530 struct gfx_data *data;
532 data = OOP_INST_DATA(cl, o);
533 LFB_QUICK(data);
534 /* erase the old cursor */
535 if (data->curs_on)
536 draw_cursor(data, FALSE, CSD(cl));
538 data->curs_x = msg->x;
539 data->curs_y = msg->y;
540 data->curs_maxx = data->curs_x + data->curs_width - 1;
541 data->curs_maxy = data->curs_y + data->curs_height - 1;
543 if (data->curs_on)
544 draw_cursor(data, TRUE, CSD(cl));
545 UFB_QUICK(data);
546 return TRUE;
549 static VOID gfx_setcursorvisible(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorVisible *msg)
551 struct gfx_data *data;
553 data = OOP_INST_DATA(cl, o);
555 LFB_QUICK(data);
557 if (msg->visible)
559 if (!data->curs_on)
561 data->curs_on = TRUE;
562 draw_cursor(data, TRUE, CSD(cl));
565 else
567 if (data->curs_on)
569 data->curs_on = FALSE;
570 draw_cursor(data, FALSE, CSD(cl));
574 UFB_QUICK(data);
578 #define PIXEL_INSIDE(fgh, x, y) \
579 ( ( (x) >= (fgh)->curs_x ) \
580 && ( (y) >= (fgh)->curs_y ) \
581 && ( (x) <= (fgh)->curs_maxx ) \
582 && ( (y) <= (fgh)->curs_maxy ) )
584 /* NOTE: x1, y1, x2, y2 MUST be sorted */
585 #define RECT_INSIDE(fgh, x1, y1, x2, y2) \
586 ( ( (x1) <= fgh->curs_maxx ) \
587 && ( (x2) >= fgh->curs_x ) \
588 && ( (y1) <= fgh->curs_maxy ) \
589 && ( (y2) >= fgh->curs_y ) )
591 #define WRECT_INSIDE(fgh, x1, y1, width, height) \
592 RECT_INSIDE(fgh, x1, y1, (x1) + (width) - 1, (y1) + (height) - 1)
594 static IPTR gfx_copybox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
596 struct gfx_data *data;
597 BOOL inside = FALSE;
598 IPTR retval;
599 struct pHidd_Gfx_CopyBox p;
601 data = OOP_INST_DATA(cl, o);
602 LFB(data);
603 p = *msg;
605 if (msg->src == data->fakefb)
607 if (WRECT_INSIDE(data, msg->srcX, msg->srcY, msg->width, msg->height))
609 inside = TRUE;
611 p.src = data->framebuffer;
614 if (msg->dest == data->fakefb)
616 if (WRECT_INSIDE(data, msg->destX, msg->destY, msg->width, msg->height))
618 inside = TRUE;
620 p.dest = data->framebuffer;
623 if (inside)
625 draw_cursor(data, FALSE, CSD(cl));
627 msg = &p;
629 retval = OOP_DoMethod(data->gfxhidd, (OOP_Msg)msg);
631 if (inside)
632 draw_cursor(data, TRUE, CSD(cl));
633 UFB(data);
635 return retval;
638 static OOP_Object *gfx_show(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
640 OOP_Object *ret;
641 struct gfx_data *data;
643 data = OOP_INST_DATA(cl, o);
645 LFB(data);
646 draw_cursor(data, FALSE, CSD(cl));
648 ret = (OOP_Object *)OOP_DoMethod(data->gfxhidd, msg);
649 if (NULL != ret)
651 data->framebuffer = ret;
652 ret = data->fakefb;
654 rethink_cursor(data, CSD(cl));
655 draw_cursor(data, TRUE, CSD(cl));
657 UFB(data);
659 return ret;
661 static IPTR gfx_fwd(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
663 struct gfx_data *data;
665 data = OOP_INST_DATA(cl, o);
667 return OOP_DoMethod(data->gfxhidd, msg);
670 struct fakefb_data
672 OOP_Object *framebuffer;
673 OOP_Object *fakegfxhidd;
676 #define FGH(data) ((struct gfx_data *)data->fakegfxhidd)
677 #define REMOVE_CURSOR(data) \
678 draw_cursor(FGH(data), FALSE, CSD(cl))
680 #define RENDER_CURSOR(data) \
681 draw_cursor(FGH(data), TRUE, CSD(cl))
684 #define BITMAP_METHOD_INIT \
685 struct fakefb_data *data; \
686 BOOL inside = FALSE; \
687 IPTR retval; \
688 struct gfx_data *fgh; \
689 data = OOP_INST_DATA(cl, o); \
690 fgh = FGH(data); \
691 LFB(fgh);
693 #define FORWARD_METHOD \
694 retval = OOP_DoMethod(data->framebuffer, (OOP_Msg)msg);
696 #define BITMAP_METHOD_EXIT \
697 if (inside) { \
698 RENDER_CURSOR(data); \
700 UFB(fgh); \
701 return retval;
703 static OOP_Object *fakefb_new(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
705 OOP_Object *framebuffer;
706 OOP_Object *fakegfxhidd;
708 framebuffer = (OOP_Object *)GetTagData(aHidd_FakeFB_RealBitMap, NULL, msg->attrList);
709 fakegfxhidd = (OOP_Object *)GetTagData(aHidd_FakeFB_FakeGfxHidd, NULL, msg->attrList);
711 if (NULL == framebuffer || NULL == fakegfxhidd)
713 D(bug("!!! FakeBM::New(): MISSING FRAMEBUFFER OR FAKE GFX HIDD !!!\n"));
714 return NULL;
717 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
718 if (NULL != o)
720 struct fakefb_data *data;
721 data = OOP_INST_DATA(cl, o);
722 data->framebuffer = framebuffer;
723 data->fakegfxhidd = fakegfxhidd;
725 return o;
728 static VOID fakefb_dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
730 struct fakefb_data *data;
731 data = OOP_INST_DATA(cl, o);
732 if (NULL != data->framebuffer)
734 OOP_DisposeObject(data->framebuffer);
735 data->framebuffer = NULL;
739 static IPTR fakefb_getpixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetPixel *msg)
741 BITMAP_METHOD_INIT
743 if (PIXEL_INSIDE(fgh, msg->x, msg->y))
745 REMOVE_CURSOR(data);
746 inside = TRUE;
749 FORWARD_METHOD
751 BITMAP_METHOD_EXIT
754 static IPTR fakefb_putpixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg)
756 BITMAP_METHOD_INIT
758 if (PIXEL_INSIDE(fgh, msg->x, msg->y))
760 REMOVE_CURSOR(data);
761 inside = TRUE;
764 FORWARD_METHOD
766 BITMAP_METHOD_EXIT
769 static IPTR fakefb_drawpixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawPixel *msg)
771 BITMAP_METHOD_INIT
773 if (PIXEL_INSIDE(fgh, msg->x, msg->y))
775 REMOVE_CURSOR(data);
776 inside = TRUE;
779 FORWARD_METHOD
781 BITMAP_METHOD_EXIT
784 static IPTR fakefb_drawline(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawLine *msg)
786 register LONG x1, y1, x2, y2;
787 BITMAP_METHOD_INIT
789 if (msg->x1 < msg->x2)
791 x1 = msg->x1; x2 = msg->x2;
793 else
795 x2 = msg->x1; x1 = msg->x2;
798 if (msg->y1 < msg->y2)
800 y1 = msg->y1; y2 = msg->y2;
802 else
804 y2 = msg->y1; y1 = msg->y2;
807 #warning Maybe do some more intelligent checking for DrawLine
808 if (RECT_INSIDE(fgh, x1, y1, x2, y2))
810 REMOVE_CURSOR(data);
811 inside = TRUE;
814 FORWARD_METHOD
816 BITMAP_METHOD_EXIT
819 static IPTR fakefb_getimage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImage *msg)
821 BITMAP_METHOD_INIT
823 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
825 REMOVE_CURSOR(data);
826 inside = TRUE;
829 FORWARD_METHOD
831 BITMAP_METHOD_EXIT
834 static IPTR fakefb_putimage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImage *msg)
836 BITMAP_METHOD_INIT
838 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
840 REMOVE_CURSOR(data);
841 inside = TRUE;
844 FORWARD_METHOD
846 BITMAP_METHOD_EXIT
849 static IPTR fakefb_putalphaimage(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutAlphaImage *msg)
851 BITMAP_METHOD_INIT
853 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
855 REMOVE_CURSOR(data);
856 inside = TRUE;
859 FORWARD_METHOD
861 BITMAP_METHOD_EXIT
864 static IPTR fakefb_puttemplate(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutTemplate *msg)
866 BITMAP_METHOD_INIT
868 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
870 REMOVE_CURSOR(data);
871 inside = TRUE;
874 FORWARD_METHOD
876 BITMAP_METHOD_EXIT
879 static IPTR fakefb_putalphatemplate(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutAlphaTemplate *msg)
881 BITMAP_METHOD_INIT
883 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
885 REMOVE_CURSOR(data);
886 inside = TRUE;
889 FORWARD_METHOD
891 BITMAP_METHOD_EXIT
894 static IPTR fakefb_putpattern(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPattern *msg)
896 BITMAP_METHOD_INIT
898 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
900 REMOVE_CURSOR(data);
901 inside = TRUE;
904 FORWARD_METHOD
906 BITMAP_METHOD_EXIT
909 static IPTR fakefb_getimagelut(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImageLUT *msg)
911 BITMAP_METHOD_INIT
913 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
915 REMOVE_CURSOR(data);
916 inside = TRUE;
919 FORWARD_METHOD
921 BITMAP_METHOD_EXIT
924 static IPTR fakefb_putimagelut(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg)
926 BITMAP_METHOD_INIT
928 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
930 REMOVE_CURSOR(data);
931 inside = TRUE;
934 FORWARD_METHOD
936 BITMAP_METHOD_EXIT
939 static IPTR fakefb_puttranspimagelut(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutTranspImageLUT *msg)
941 BITMAP_METHOD_INIT
943 if (WRECT_INSIDE(fgh, msg->x, msg->y, msg->width, msg->height))
945 REMOVE_CURSOR(data);
946 inside = TRUE;
949 FORWARD_METHOD
951 BITMAP_METHOD_EXIT
954 static IPTR fakefb_drawrect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg)
956 BITMAP_METHOD_INIT
958 #warning Maybe do something clever here to see if the rectangle is drawn around the cursor
959 if (RECT_INSIDE(fgh, msg->minX, msg->minY, msg->maxX, msg->maxY))
961 REMOVE_CURSOR(data);
962 inside = TRUE;
965 FORWARD_METHOD
967 BITMAP_METHOD_EXIT
970 static IPTR fakefb_fillrect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg)
972 BITMAP_METHOD_INIT
974 /* bug("BITMAP FILLRECT(%d, %d, %d, %d), (%d, %d, %d, %d, %d, %d)\n"
975 , msg->minX, msg->minY, msg->maxX, msg->maxY
976 , fgh->curs_x, fgh->curs_y, fgh->curs_maxx, fgh->curs_maxy
977 , fgh->curs_width, fgh->curs_height);
979 if (RECT_INSIDE(fgh, msg->minX, msg->minY, msg->maxX, msg->maxY))
981 /* bug("FILLRECT: REMOVING CURSOR\n");
983 REMOVE_CURSOR(data);
985 inside = TRUE;
988 FORWARD_METHOD
990 BITMAP_METHOD_EXIT
993 static IPTR fakefb_drawellipse(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawEllipse *msg)
995 register LONG x1, y1, x2, y2;
996 BITMAP_METHOD_INIT
998 x1 = msg->x - msg->rx;
999 y1 = msg->y - msg->ry;
1000 x2 = msg->x + msg->rx;
1001 y2 = msg->y + msg->ry;
1002 #warning Maybe do something clever here to see if the rectangle is drawn around the cursor
1004 if (RECT_INSIDE(fgh, x1, y1, x2, y2))
1006 REMOVE_CURSOR(data);
1007 inside = TRUE;
1010 FORWARD_METHOD
1012 BITMAP_METHOD_EXIT
1015 static IPTR fakefb_fillellipse(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawEllipse *msg)
1017 register LONG x1, y1, x2, y2;
1018 BITMAP_METHOD_INIT
1020 x1 = msg->x - msg->rx;
1021 y1 = msg->y - msg->ry;
1022 x2 = msg->x + msg->rx;
1023 y2 = msg->y + msg->ry;
1025 if (RECT_INSIDE(fgh, x1, y1, x2, y2))
1027 REMOVE_CURSOR(data);
1028 inside = TRUE;
1031 FORWARD_METHOD
1033 BITMAP_METHOD_EXIT
1036 static IPTR fakefb_drawpolygon(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawPolygon *msg)
1038 BITMAP_METHOD_INIT
1039 #warning Maybe do checking here, but it probably is not worth it
1040 REMOVE_CURSOR(data);
1041 inside = TRUE;
1043 FORWARD_METHOD
1045 BITMAP_METHOD_EXIT
1048 static IPTR fakefb_fillpolygon(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawPolygon *msg)
1050 BITMAP_METHOD_INIT
1051 #warning Maybe do checking here, but it probably is not worth it
1052 REMOVE_CURSOR(data);
1053 inside = TRUE;
1055 FORWARD_METHOD
1057 BITMAP_METHOD_EXIT
1061 static IPTR fakefb_drawtext(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawText *msg)
1063 BITMAP_METHOD_INIT
1065 #warning Maybe do testing here, but probably not wirth it
1066 REMOVE_CURSOR(data);
1068 FORWARD_METHOD
1070 BITMAP_METHOD_EXIT
1073 static IPTR fakefb_drawfilltext(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawText *msg)
1075 BITMAP_METHOD_INIT
1077 #warning Maybe do testing here, but probably not worth it
1078 REMOVE_CURSOR(data);
1080 FORWARD_METHOD
1082 BITMAP_METHOD_EXIT
1085 static IPTR fakefb_blitcolexp(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_BlitColorExpansion *msg)
1087 BITMAP_METHOD_INIT
1089 if (WRECT_INSIDE(fgh, msg->destX, msg->destY, msg->width, msg->height))
1091 REMOVE_CURSOR(data);
1092 inside = TRUE;
1095 FORWARD_METHOD
1097 BITMAP_METHOD_EXIT
1100 static IPTR fakefb_clear(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_Clear *msg)
1102 BITMAP_METHOD_INIT
1104 inside = TRUE;
1106 FORWARD_METHOD
1108 BITMAP_METHOD_EXIT
1112 static IPTR fakefb_fillspan(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
1114 BITMAP_METHOD_INIT
1116 REMOVE_CURSOR(data);
1117 inside = TRUE;
1119 FORWARD_METHOD
1121 BITMAP_METHOD_EXIT
1126 static IPTR fakefb_fwd(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
1128 struct fakefb_data *data;
1129 data = OOP_INST_DATA(cl, o);
1130 // kill(getpid(), 19);
1131 // bug("BITMAP_FWD\n");
1132 return OOP_DoMethod(data->framebuffer, msg);
1137 #undef CSD
1138 #define CSD(cl) csd
1141 static OOP_Class *init_fakegfxhiddclass (struct class_static_data *csd)
1143 OOP_Class *cl = NULL;
1145 struct OOP_MethodDescr root_descr[num_Root_Methods + 1] =
1147 {(IPTR (*)())gfx_new , moRoot_New },
1148 {(IPTR (*)())gfx_dispose, moRoot_Dispose },
1149 {(IPTR (*)())gfx_fwd , moRoot_Get },
1150 {(IPTR (*)())gfx_fwd , moRoot_Set },
1151 { NULL , 0UL }
1154 struct OOP_MethodDescr gfxhidd_descr[num_Hidd_Gfx_Methods + 1] =
1156 {(IPTR (*)())gfx_fwd , moHidd_Gfx_NewGC },
1157 {(IPTR (*)())gfx_fwd , moHidd_Gfx_DisposeGC },
1158 {(IPTR (*)())gfx_newbitmap , moHidd_Gfx_NewBitMap },
1159 {(IPTR (*)())gfx_fwd , moHidd_Gfx_DisposeBitMap },
1160 {(IPTR (*)())gfx_fwd , moHidd_Gfx_QueryModeIDs },
1161 {(IPTR (*)())gfx_fwd , moHidd_Gfx_ReleaseModeIDs },
1162 {(IPTR (*)())gfx_fwd , moHidd_Gfx_CheckMode },
1163 {(IPTR (*)())gfx_fwd , moHidd_Gfx_NextModeID },
1164 {(IPTR (*)())gfx_fwd , moHidd_Gfx_GetMode },
1166 #if 0
1167 /* These are private to the gfxhidd, and we should not be called with these */
1168 {(IPTR (*)())gfx_fwd , moHidd_Gfx_RegisterPixFmt },
1169 {(IPTR (*)())gfx_fwd , moHidd_Gfx_ReleasePixFmt },
1170 #endif
1171 {(IPTR (*)())gfx_fwd , moHidd_Gfx_GetPixFmt },
1172 {(IPTR (*)())gfx_setcursorshape , moHidd_Gfx_SetCursorShape },
1173 {(IPTR (*)())gfx_setcursorpos , moHidd_Gfx_SetCursorPos },
1174 {(IPTR (*)())gfx_setcursorvisible , moHidd_Gfx_SetCursorVisible },
1175 {(IPTR (*)())gfx_fwd , moHidd_Gfx_SetMode },
1176 {(IPTR (*)())gfx_show , moHidd_Gfx_Show },
1177 {(IPTR (*)())gfx_copybox , moHidd_Gfx_CopyBox },
1178 {NULL , 0UL }
1181 struct OOP_InterfaceDescr ifdescr[] =
1183 {root_descr , IID_Root , num_Root_Methods },
1184 {gfxhidd_descr , IID_Hidd_Gfx , num_Hidd_Gfx_Methods },
1185 {NULL , NULL , 0 }
1188 OOP_AttrBase MetaAttrBase = OOP_GetAttrBase(IID_Meta);
1190 struct TagItem tags[] =
1192 /* { aMeta_SuperID , (IPTR)CLID_Hidd },*/
1193 { aMeta_SuperID , (IPTR)CLID_Root },
1194 { aMeta_InterfaceDescr , (IPTR)ifdescr },
1195 { aMeta_ID , (IPTR)CLID_Hidd_FakeGfxHidd },
1196 { aMeta_InstSize , (IPTR)sizeof (struct gfx_data) },
1197 {TAG_DONE , 0UL }
1201 D(bug("INIT FAKEGFXCLASS\n"));
1202 if ((__IHidd_FakeFB = OOP_ObtainAttrBase(IID_Hidd_FakeFB)))
1204 cl = OOP_NewObject(NULL, CLID_HiddMeta, tags);
1205 if(NULL != cl)
1207 D(bug("FAKE GFX CLASS INITED\n"));
1208 cl->UserData = csd;
1209 OOP_AddClass(cl);
1211 return cl;
1215 if (NULL == cl)
1216 free_fakegfxhiddclass(cl, csd);
1218 return cl;
1221 static void free_fakegfxhiddclass(OOP_Class *cl, struct class_static_data *csd)
1223 if (NULL != cl)
1225 OOP_RemoveClass(cl);
1226 OOP_DisposeObject((OOP_Object *) cl);
1227 OOP_ReleaseAttrBase(IID_Hidd_FakeFB);
1231 static OOP_Class *init_fakefbclass(struct class_static_data *csd)
1233 struct OOP_MethodDescr root_descr[num_Root_Methods + 1] =
1235 {(IPTR (*)())fakefb_new , moRoot_New },
1236 {(IPTR (*)())fakefb_dispose, moRoot_Dispose },
1237 {(IPTR (*)())fakefb_fwd , moRoot_Get },
1238 {(IPTR (*)())fakefb_fwd , moRoot_Set },
1239 {NULL , 0UL }
1242 struct OOP_MethodDescr bitmap_descr[num_Hidd_BitMap_Methods + 1] =
1244 {(IPTR (*)())fakefb_putpixel , moHidd_BitMap_PutPixel },
1245 {(IPTR (*)())fakefb_getpixel , moHidd_BitMap_GetPixel },
1246 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_SetColors },
1247 {(IPTR (*)())fakefb_drawpixel , moHidd_BitMap_DrawPixel },
1248 {(IPTR (*)())fakefb_drawline , moHidd_BitMap_DrawLine },
1249 {(IPTR (*)())fakefb_drawrect , moHidd_BitMap_DrawRect },
1250 {(IPTR (*)())fakefb_fillrect , moHidd_BitMap_FillRect },
1251 {(IPTR (*)())fakefb_drawellipse , moHidd_BitMap_DrawEllipse },
1252 {(IPTR (*)())fakefb_fillellipse , moHidd_BitMap_FillEllipse },
1253 {(IPTR (*)())fakefb_drawpolygon , moHidd_BitMap_DrawPolygon },
1254 {(IPTR (*)())fakefb_fillpolygon , moHidd_BitMap_FillPolygon },
1255 {(IPTR (*)())fakefb_drawtext , moHidd_BitMap_DrawText },
1256 {(IPTR (*)())fakefb_drawfilltext , moHidd_BitMap_FillText },
1257 {(IPTR (*)())fakefb_fillspan , moHidd_BitMap_FillSpan },
1258 {(IPTR (*)())fakefb_clear , moHidd_BitMap_Clear },
1259 {(IPTR (*)())fakefb_putimage , moHidd_BitMap_PutImage },
1260 {(IPTR (*)())fakefb_putalphaimage , moHidd_BitMap_PutAlphaImage },
1261 {(IPTR (*)())fakefb_puttemplate , moHidd_BitMap_PutTemplate },
1262 {(IPTR (*)())fakefb_putalphatemplate , moHidd_BitMap_PutAlphaTemplate },
1263 {(IPTR (*)())fakefb_putpattern , moHidd_BitMap_PutPattern },
1264 {(IPTR (*)())fakefb_putimagelut , moHidd_BitMap_PutImageLUT },
1265 {(IPTR (*)())fakefb_puttranspimagelut , moHidd_BitMap_PutTranspImageLUT },
1266 {(IPTR (*)())fakefb_getimage , moHidd_BitMap_GetImage },
1267 {(IPTR (*)())fakefb_getimagelut , moHidd_BitMap_GetImageLUT },
1268 {(IPTR (*)())fakefb_blitcolexp , moHidd_BitMap_BlitColorExpansion },
1269 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_BytesPerLine },
1270 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_ConvertPixels },
1271 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_SetColorMap },
1272 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_MapColor },
1273 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_UnmapPixel },
1274 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_ObtainDirectAccess },
1275 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_ReleaseDirectAccess },
1276 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_SetRGBConversionFunction },
1278 /* PRIVATE METHODS */
1279 #if 0
1280 /* This is private to the gfxhidd, and we should not be called with this */
1281 {(IPTR (*)())fakefb_fwd , moHidd_BitMap_SetBitMapTags },
1282 #endif
1283 {NULL, 0UL}
1286 struct OOP_InterfaceDescr ifdescr[] =
1288 {root_descr , IID_Root , num_Root_Methods },
1289 {bitmap_descr , IID_Hidd_BitMap, num_Hidd_BitMap_Methods },
1290 {NULL , NULL , 0 }
1293 OOP_AttrBase MetaAttrBase = OOP_GetAttrBase(IID_Meta);
1295 struct TagItem tags[] =
1297 {aMeta_SuperID , (IPTR) CLID_Root },
1298 {aMeta_InterfaceDescr , (IPTR) ifdescr },
1299 {aMeta_ID , (IPTR) CLID_Hidd_FakeFB },
1300 {aMeta_InstSize , (IPTR) sizeof(struct fakefb_data) },
1301 {TAG_DONE , 0UL }
1304 OOP_Class *cl = NULL;
1306 if(MetaAttrBase)
1308 cl = OOP_NewObject(NULL, CLID_HiddMeta, tags);
1309 if(NULL != cl)
1311 cl->UserData = csd;
1312 OOP_AddClass(cl);
1314 } /* if(MetaAttrBase) */
1316 if (NULL == cl)
1317 free_fakefbclass(cl, csd);
1319 return cl;
1322 static void free_fakefbclass(OOP_Class *cl, struct class_static_data *csd)
1324 if (NULL != cl)
1326 OOP_RemoveClass(cl);
1327 OOP_DisposeObject((OOP_Object *) cl);
1332 static VOID rethink_cursor(struct gfx_data *data, struct class_static_data *csd)
1334 OOP_Object *pf, *colmap;
1335 IPTR depth, fbdepth, i;
1337 D(bug("rethink_cursor()\n"));
1338 OOP_GetAttr(data->curs_backup, aHidd_BitMap_PixFmt, (IPTR *)&pf);
1339 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &fbdepth);
1341 OOP_GetAttr(data->curs_bm, aHidd_BitMap_PixFmt, (IPTR *)&pf);
1342 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
1343 OOP_GetAttr(data->curs_bm, aHidd_BitMap_ColorMap, (IPTR *)&colmap);
1345 if (depth > 8) depth = 8;
1347 for(i = 0; i < (1L << depth); i++)
1349 if (fbdepth > 8)
1351 HIDDT_Color col;
1353 HIDD_CM_GetColor(colmap, i, &col);
1354 data->curs_pixels[i] = HIDD_BM_MapColor(data->curs_backup, &col);
1356 else
1358 /* FIXME: this assumes fbdepth > 3 */
1359 if (fbdepth > 4)
1360 data->curs_pixels[i] = i + 16;
1361 else
1362 data->curs_pixels[i] = i + (1 << fbdepth) - 8;
1368 static VOID draw_cursor(struct gfx_data *data, BOOL draw, struct class_static_data *csd)
1370 IPTR width, height;
1371 IPTR fb_width, fb_height;
1372 ULONG x, y;
1373 LONG w2end;
1374 LONG h2end;
1376 struct TagItem gctags[] =
1378 { aHidd_GC_DrawMode , vHidd_GC_DrawMode_Copy },
1379 { TAG_DONE , 0UL }
1382 if (NULL == data->curs_bm || NULL == data->framebuffer || !data->curs_on)
1384 D(bug("!!! draw_cursor: FAKE GFX HIDD NOT PROPERLY INITIALIZED !!!\n"));
1385 D(bug("CURS BM: %p, FB: %p, ON: %d\n"
1386 , data->curs_bm, data->framebuffer, data->curs_on));
1387 return;
1390 OOP_GetAttr(data->curs_bm, aHidd_BitMap_Width, &width);
1391 OOP_GetAttr(data->curs_bm, aHidd_BitMap_Height, &height);
1393 OOP_GetAttr(data->framebuffer, aHidd_BitMap_Width, &fb_width);
1394 OOP_GetAttr(data->framebuffer, aHidd_BitMap_Height, &fb_height);
1396 /* Do some clipping */
1397 x = data->curs_x;
1398 y = data->curs_y;
1400 w2end = fb_width - 1 - data->curs_x;
1401 h2end = fb_height - 1 - data->curs_y;
1403 if (w2end <= 0 || h2end <= 0) /* Cursor outside framebuffer */
1404 return;
1406 if (w2end < width)
1407 width -= (width - w2end);
1409 if (h2end < height)
1410 height -= (height - h2end);
1412 OOP_SetAttrs(data->gc, gctags);
1414 if (draw)
1416 /* Backup under the new cursor image */
1417 // bug("BACKING UP RENDERED AREA\n");
1418 HIDD_Gfx_CopyBox(data->gfxhidd
1419 , data->framebuffer
1420 , data->curs_x
1421 , data->curs_y
1422 , data->curs_backup
1423 , 0, 0
1424 , width, height
1425 , data->gc
1428 data->backup_done = TRUE;
1430 // bug("RENDERING CURSOR IMAGE\n");
1431 /* Render the cursor image */
1433 #if 0
1434 HIDD_Gfx_CopyBox(data->gfxhidd
1435 , data->curs_bm
1436 , 0, 0
1437 , data->framebuffer
1438 , data->curs_x, data->curs_y
1439 , width, height
1440 , data->gc
1442 #else
1443 for(y = 0; y < height; y++)
1445 for(x = 0; x < width; x++)
1447 HIDDT_Pixel pix;
1449 pix = HIDD_BM_GetPixel(data->curs_bm, x, y);
1450 if (pix)
1452 HIDD_BM_PutPixel(data->framebuffer, data->curs_x + x, data->curs_y + y, data->curs_pixels[pix]);
1457 #endif
1460 else
1462 /* Erase the old cursor image */
1463 if (data->backup_done)
1465 // bug("PUTTING BACK BACKED UP AREA\n");
1466 HIDD_Gfx_CopyBox(data->gfxhidd
1467 , data->curs_backup
1468 , 0, 0
1469 , data->framebuffer
1470 , data->curs_x
1471 , data->curs_y
1472 , width, height
1473 , data->gc
1477 return;
1480 static OOP_Object *create_fake_fb(OOP_Object *framebuffer, struct gfx_data *data, struct class_static_data *csd)
1482 OOP_Object *fakebm;
1483 struct TagItem fakebmtags[] =
1485 { aHidd_FakeFB_RealBitMap , (IPTR)framebuffer },
1486 { aHidd_FakeFB_FakeGfxHidd , (IPTR)data },
1487 { TAG_DONE , 0UL }
1490 fakebm = OOP_NewObject(NULL, CLID_Hidd_FakeFB, fakebmtags);
1491 if (NULL != fakebm)
1493 data->framebuffer = framebuffer;
1494 data->fakefb = fakebm;
1498 return fakebm;
1501 #undef GfxBase
1503 OOP_Object *init_fakegfxhidd(OOP_Object *gfxhidd, struct class_static_data *csd, struct GfxBase *GfxBase)
1505 OOP_Object *fgo = NULL;
1507 csd->gfxbase = GfxBase;
1509 csd->fakegfxclass = init_fakegfxhiddclass(csd);
1510 csd->fakefbclass = init_fakefbclass(csd);
1512 if (NULL != csd->fakegfxclass && NULL != csd->fakefbclass)
1514 struct TagItem fgh_tags[] =
1516 { aHidd_FakeGfxHidd_RealGfxHidd , (IPTR)gfxhidd },
1517 { TAG_DONE , 0UL }
1520 fgo = OOP_NewObject(NULL, CLID_Hidd_FakeGfxHidd, fgh_tags);
1522 if (NULL != fgo)
1524 csd->fakegfxobj = fgo;
1528 if (NULL == fgo)
1529 cleanup_fakegfxhidd(csd, GfxBase);
1531 return fgo;
1534 VOID cleanup_fakegfxhidd(struct class_static_data *csd, struct GfxBase *GfxBase)
1536 if (NULL != csd->fakegfxobj)
1538 OOP_DisposeObject(csd->fakegfxobj);
1539 csd->fakegfxobj = NULL;
1542 if (NULL != csd->fakefbclass)
1544 free_fakefbclass(csd->fakefbclass, csd);
1545 csd->fakefbclass = NULL;
1548 if (NULL != csd->fakegfxclass)
1550 free_fakegfxhiddclass(csd->fakegfxclass, csd);
1551 csd->fakegfxclass = NULL;
1554 return;