2 Copyright © 1995-2006, 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 "graphics_internal.h"
18 #include "fakegfxhidd.h"
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 /******************************************************************************/
43 OOP_Object
*framebuffer
;
48 OOP_Object
*curs_backup
;
49 HIDDT_Pixel curs_pixels
[256];
57 struct SignalSemaphore fbsema
;
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 /******************************************************************************/
82 /******************************************************************************/
86 static void FakeGfxHidd_ObtainSemaphore(struct SignalSemaphore
*sigSem
, BOOL urgent
,
87 struct ExecBase
*SysBase
)
91 /* Get pointer to current task */
94 /* Arbitrate for the semaphore structure */
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.
126 We need a node to mark our semaphore request. Lets use some
129 struct SemaphoreRequest sr
;
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
);
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 ExecBase
*SysBase
)
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 /******************************************************************************/
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 /******************************************************************************/
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
;
295 realgfxhidd
= (OOP_Object
*)GetTagData(aHidd_FakeGfxHidd_RealGfxHidd
, (IPTR
)NULL
, msg
->attrList
);
296 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
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
[] =
313 data
->gc
= HIDD_Gfx_NewGC(data
->gfxhidd
, gctags
);
314 if (NULL
!= data
->gc
)
324 mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
325 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&mid
);
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
);
349 if (NULL
!= data
->gfxhidd
)
351 OOP_DisposeObject(data
->gfxhidd
);
352 data
->gfxhidd
= NULL
;
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 ? */
361 struct gfx_data
*data
;
363 OOP_Object
*ret
= NULL
;
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
)
374 fakefb
= create_fake_fb(realfb
, data
, CSD(cl
));
378 data
->framebuffer
= realfb
;
392 OOP_DisposeObject(realfb
);
399 static BOOL
gfx_setcursorshape(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorShape
*msg
)
401 struct gfx_data
*data
;
404 data
= OOP_INST_DATA(cl
, o
);
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
;
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
;
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 },
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"));
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"));
479 data
->curs_bm
= shape
;
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
));
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
));
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
);
534 /* erase the old cursor */
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;
544 draw_cursor(data
, TRUE
, CSD(cl
));
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
);
561 data
->curs_on
= TRUE
;
562 draw_cursor(data
, TRUE
, CSD(cl
));
569 data
->curs_on
= FALSE
;
570 draw_cursor(data
, FALSE
, CSD(cl
));
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
;
599 struct pHidd_Gfx_CopyBox p
;
601 data
= OOP_INST_DATA(cl
, o
);
605 if (msg
->src
== data
->fakefb
)
607 if (WRECT_INSIDE(data
, msg
->srcX
, msg
->srcY
, msg
->width
, msg
->height
))
611 p
.src
= data
->framebuffer
;
614 if (msg
->dest
== data
->fakefb
)
616 if (WRECT_INSIDE(data
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
620 p
.dest
= data
->framebuffer
;
625 draw_cursor(data
, FALSE
, CSD(cl
));
629 retval
= OOP_DoMethod(data
->gfxhidd
, (OOP_Msg
)msg
);
632 draw_cursor(data
, TRUE
, CSD(cl
));
638 static OOP_Object
*gfx_show(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
641 struct gfx_data
*data
;
643 data
= OOP_INST_DATA(cl
, o
);
646 draw_cursor(data
, FALSE
, CSD(cl
));
648 ret
= (OOP_Object
*)OOP_DoMethod(data
->gfxhidd
, msg
);
651 data
->framebuffer
= ret
;
654 rethink_cursor(data
, CSD(cl
));
655 draw_cursor(data
, TRUE
, CSD(cl
));
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
);
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; \
688 struct gfx_data *fgh; \
689 data = OOP_INST_DATA(cl, o); \
693 #define FORWARD_METHOD \
694 retval = OOP_DoMethod(data->framebuffer, (OOP_Msg)msg);
696 #define BITMAP_METHOD_EXIT \
698 RENDER_CURSOR(data); \
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"));
717 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
720 struct fakefb_data
*data
;
721 data
= OOP_INST_DATA(cl
, o
);
722 data
->framebuffer
= framebuffer
;
723 data
->fakegfxhidd
= fakegfxhidd
;
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
)
743 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
754 static IPTR
fakefb_putpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPixel
*msg
)
758 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
769 static IPTR
fakefb_drawpixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPixel
*msg
)
773 if (PIXEL_INSIDE(fgh
, msg
->x
, msg
->y
))
784 static IPTR
fakefb_drawline(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawLine
*msg
)
786 register LONG x1
, y1
, x2
, y2
;
789 if (msg
->x1
< msg
->x2
)
791 x1
= msg
->x1
; x2
= msg
->x2
;
795 x2
= msg
->x1
; x1
= msg
->x2
;
798 if (msg
->y1
< msg
->y2
)
800 y1
= msg
->y1
; y2
= msg
->y2
;
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
))
819 static IPTR
fakefb_getimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImage
*msg
)
823 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
834 static IPTR
fakefb_putimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImage
*msg
)
838 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
849 static IPTR
fakefb_putalphaimage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutAlphaImage
*msg
)
853 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
864 static IPTR
fakefb_puttemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
868 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
879 static IPTR
fakefb_putalphatemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutAlphaTemplate
*msg
)
883 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
894 static IPTR
fakefb_putpattern(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPattern
*msg
)
898 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
909 static IPTR
fakefb_getimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImageLUT
*msg
)
913 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
924 static IPTR
fakefb_putimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImageLUT
*msg
)
928 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
939 static IPTR
fakefb_puttranspimagelut(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTranspImageLUT
*msg
)
943 if (WRECT_INSIDE(fgh
, msg
->x
, msg
->y
, msg
->width
, msg
->height
))
954 static IPTR
fakefb_drawrect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
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
))
970 static IPTR
fakefb_fillrect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
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");
993 static IPTR
fakefb_drawellipse(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawEllipse
*msg
)
995 register LONG x1
, y1
, x2
, y2
;
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
);
1015 static IPTR
fakefb_fillellipse(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawEllipse
*msg
)
1017 register LONG x1
, y1
, x2
, y2
;
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
);
1036 static IPTR
fakefb_drawpolygon(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPolygon
*msg
)
1039 #warning Maybe do checking here, but it probably is not worth it
1040 REMOVE_CURSOR(data
);
1048 static IPTR
fakefb_fillpolygon(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPolygon
*msg
)
1051 #warning Maybe do checking here, but it probably is not worth it
1052 REMOVE_CURSOR(data
);
1061 static IPTR
fakefb_drawtext(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawText
*msg
)
1065 #warning Maybe do testing here, but probably not wirth it
1066 REMOVE_CURSOR(data
);
1073 static IPTR
fakefb_drawfilltext(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawText
*msg
)
1077 #warning Maybe do testing here, but probably not worth it
1078 REMOVE_CURSOR(data
);
1085 static IPTR
fakefb_blitcolexp(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BlitColorExpansion
*msg
)
1089 if (WRECT_INSIDE(fgh
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
))
1091 REMOVE_CURSOR(data
);
1100 static IPTR
fakefb_clear(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_Clear
*msg
)
1112 static IPTR
fakefb_fillspan(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
1116 REMOVE_CURSOR(data
);
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
);
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
},
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
},
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
},
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
},
1181 struct OOP_InterfaceDescr ifdescr
[] =
1183 {root_descr
, IID_Root
, num_Root_Methods
},
1184 {gfxhidd_descr
, IID_Hidd_Gfx
, num_Hidd_Gfx_Methods
},
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
) },
1201 D(bug("INIT FAKEGFXCLASS\n"));
1202 if ((__IHidd_FakeFB
= OOP_ObtainAttrBase(IID_Hidd_FakeFB
)))
1204 cl
= OOP_NewObject(NULL
, CLID_HiddMeta
, tags
);
1207 D(bug("FAKE GFX CLASS INITED\n"));
1216 free_fakegfxhiddclass(cl
, csd
);
1221 static void free_fakegfxhiddclass(OOP_Class
*cl
, struct class_static_data
*csd
)
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
},
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
},
1277 /* PRIVATE METHODS */
1279 /* This is private to the gfxhidd, and we should not be called with this */
1280 {(IPTR (*)())fakefb_fwd
, moHidd_BitMap_SetBitMapTags
},
1285 struct OOP_InterfaceDescr ifdescr
[] =
1287 {root_descr
, IID_Root
, num_Root_Methods
},
1288 {bitmap_descr
, IID_Hidd_BitMap
, num_Hidd_BitMap_Methods
},
1292 OOP_AttrBase MetaAttrBase
= OOP_GetAttrBase(IID_Meta
);
1294 struct TagItem tags
[] =
1296 {aMeta_SuperID
, (IPTR
) CLID_Root
},
1297 {aMeta_InterfaceDescr
, (IPTR
) ifdescr
},
1298 {aMeta_ID
, (IPTR
) CLID_Hidd_FakeFB
},
1299 {aMeta_InstSize
, (IPTR
) sizeof(struct fakefb_data
) },
1303 OOP_Class
*cl
= NULL
;
1307 cl
= OOP_NewObject(NULL
, CLID_HiddMeta
, tags
);
1313 } /* if(MetaAttrBase) */
1316 free_fakefbclass(cl
, csd
);
1321 static void free_fakefbclass(OOP_Class
*cl
, struct class_static_data
*csd
)
1325 OOP_RemoveClass(cl
);
1326 OOP_DisposeObject((OOP_Object
*) cl
);
1331 static VOID
rethink_cursor(struct gfx_data
*data
, struct class_static_data
*csd
)
1333 OOP_Object
*pf
, *colmap
;
1334 IPTR depth
, fbdepth
, i
;
1336 OOP_GetAttr(data
->curs_backup
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1337 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &fbdepth
);
1339 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1340 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
1341 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_ColorMap
, (IPTR
*)&colmap
);
1343 if (depth
> 8) depth
= 8;
1345 for(i
= 0; i
< (1L << depth
); i
++)
1351 HIDD_CM_GetColor(colmap
, i
, &col
);
1352 data
->curs_pixels
[i
] = HIDD_BM_MapColor(data
->curs_backup
, &col
);
1356 data
->curs_pixels
[i
] = i
;
1362 static VOID
draw_cursor(struct gfx_data
*data
, BOOL draw
, struct class_static_data
*csd
)
1365 IPTR fb_width
, fb_height
;
1370 struct TagItem gctags
[] =
1372 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
1376 if (NULL
== data
->curs_bm
|| NULL
== data
->framebuffer
|| !data
->curs_on
)
1378 D(bug("!!! draw_cursor: FAKE GFX HIDD NOT PROPERLY INITIALIZED !!!\n"));
1379 D(bug("CURS BM: %p, FB: %p, ON: %d\n"
1380 , data
->curs_bm
, data
->framebuffer
, data
->curs_on
));
1384 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_Width
, &width
);
1385 OOP_GetAttr(data
->curs_bm
, aHidd_BitMap_Height
, &height
);
1387 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_Width
, &fb_width
);
1388 OOP_GetAttr(data
->framebuffer
, aHidd_BitMap_Height
, &fb_height
);
1390 /* Do some clipping */
1394 w2end
= fb_width
- 1 - data
->curs_x
;
1395 h2end
= fb_height
- 1 - data
->curs_y
;
1397 if (w2end
<= 0 || h2end
<= 0) /* Cursor outside framebuffer */
1401 width
-= (width
- w2end
);
1404 height
-= (height
- h2end
);
1406 OOP_SetAttrs(data
->gc
, gctags
);
1410 /* Backup under the new cursor image */
1411 // bug("BACKING UP RENDERED AREA\n");
1412 HIDD_Gfx_CopyBox(data
->gfxhidd
1422 data
->backup_done
= TRUE
;
1424 // bug("RENDERING CURSOR IMAGE\n");
1425 /* Render the cursor image */
1428 HIDD_Gfx_CopyBox(data
->gfxhidd
1432 , data
->curs_x
, data
->curs_y
1437 for(y
= 0; y
< height
; y
++)
1439 for(x
= 0; x
< width
; x
++)
1443 pix
= HIDD_BM_GetPixel(data
->curs_bm
, x
, y
);
1446 HIDD_BM_PutPixel(data
->framebuffer
, data
->curs_x
+ x
, data
->curs_y
+ y
, data
->curs_pixels
[pix
]);
1456 /* Erase the old cursor image */
1457 if (data
->backup_done
)
1459 // bug("PUTTING BACK BACKED UP AREA\n");
1460 HIDD_Gfx_CopyBox(data
->gfxhidd
1474 static OOP_Object
*create_fake_fb(OOP_Object
*framebuffer
, struct gfx_data
*data
, struct class_static_data
*csd
)
1477 struct TagItem fakebmtags
[] =
1479 { aHidd_FakeFB_RealBitMap
, (IPTR
)framebuffer
},
1480 { aHidd_FakeFB_FakeGfxHidd
, (IPTR
)data
},
1484 fakebm
= OOP_NewObject(NULL
, CLID_Hidd_FakeFB
, fakebmtags
);
1487 data
->framebuffer
= framebuffer
;
1488 data
->fakefb
= fakebm
;
1497 OOP_Object
*init_fakegfxhidd(OOP_Object
*gfxhidd
, struct class_static_data
*csd
, struct GfxBase
*GfxBase
)
1499 OOP_Object
*fgo
= NULL
;
1501 csd
->gfxbase
= GfxBase
;
1503 csd
->fakegfxclass
= init_fakegfxhiddclass(csd
);
1504 csd
->fakefbclass
= init_fakefbclass(csd
);
1506 if (NULL
!= csd
->fakegfxclass
&& NULL
!= csd
->fakefbclass
)
1508 struct TagItem fgh_tags
[] =
1510 { aHidd_FakeGfxHidd_RealGfxHidd
, (IPTR
)gfxhidd
},
1514 fgo
= OOP_NewObject(NULL
, CLID_Hidd_FakeGfxHidd
, fgh_tags
);
1518 csd
->fakegfxobj
= fgo
;
1523 cleanup_fakegfxhidd(csd
, GfxBase
);
1528 VOID
cleanup_fakegfxhidd(struct class_static_data
*csd
, struct GfxBase
*GfxBase
)
1530 if (NULL
!= csd
->fakegfxobj
)
1532 OOP_DisposeObject(csd
->fakegfxobj
);
1533 csd
->fakegfxobj
= NULL
;
1536 if (NULL
!= csd
->fakefbclass
)
1538 free_fakefbclass(csd
->fakefbclass
, csd
);
1539 csd
->fakefbclass
= NULL
;
1542 if (NULL
!= csd
->fakegfxclass
)
1544 free_fakegfxhiddclass(csd
->fakegfxclass
, csd
);
1545 csd
->fakegfxclass
= NULL
;