2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
5 Desc: Graphics hidd class implementation.
9 /****************************************************************************************/
11 #include <aros/config.h>
12 #include <aros/symbolsets.h>
13 #include <exec/lists.h>
15 #include "graphics_intern.h"
19 #include <proto/exec.h>
20 #include <proto/utility.h>
21 #include <proto/oop.h>
22 #include <exec/libraries.h>
23 #include <exec/memory.h>
25 #include <utility/tagitem.h>
26 #include <hidd/graphics.h>
28 #include LC_LIBDEFS_FILE
34 #include <aros/debug.h>
36 /****************************************************************************************/
38 static BOOL
create_std_pixfmts(struct class_static_data
*_csd
);
39 static VOID
delete_std_pixfmts(struct class_static_data
*_csd
);
40 static VOID
free_objectlist(struct List
*list
, BOOL OOP_DisposeObjects
,
41 struct class_static_data
*_csd
);
42 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
);
44 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
);
45 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
);
46 static OOP_Object
*create_and_init_object(OOP_Class
*cl
, UBYTE
*data
, ULONG datasize
,
47 struct class_static_data
*_csd
);
49 static struct pfnode
*find_pixfmt(struct MinList
*pflist
50 , HIDDT_PixelFormat
*tofind
51 , struct class_static_data
*_csd
);
53 static OOP_Object
*find_stdpixfmt(HIDDT_PixelFormat
*tofind
54 , struct class_static_data
*_csd
);
55 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
56 , OOP_Object
*dst_bm
, OOP_Object
*dims_bm
);
58 BOOL
parse_pixfmt_tags(struct TagItem
*tags
, HIDDT_PixelFormat
*pf
, ULONG attrcheck
, struct class_static_data
*_csd
);
59 BOOL
parse_sync_tags(struct TagItem
*tags
, struct sync_data
*data
, ULONG attrcheck
, struct class_static_data
*_csd
);
61 /****************************************************************************************/
63 #define COMPUTE_HIDD_MODEID(sync, pf) \
64 ( ((sync) << 16) | (pf) )
66 #define MODEID_TO_SYNCIDX(id) ( (id) >> 16 )
67 #define MODEID_TO_PFIDX(id) ( (id) & 0x0000FFFF )
69 /****************************************************************************************/
71 OOP_Object
*GFX__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
73 struct HIDDGraphicsData
*data
;
75 struct TagItem
*modetags
;
76 struct TagItem gctags
[] =
81 D(bug("Entering gfx.hidd::New\n"));
83 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
87 D(bug("Got object o=%x\n", o
));
89 data
= OOP_INST_DATA(cl
, o
);
91 NEWLIST(&data
->pflist
);
93 InitSemaphore(&data
->mdb
.sema
);
94 InitSemaphore(&data
->pfsema
);
95 data
->curmode
= vHidd_ModeID_Invalid
;
97 /* Get the mode tags */
98 modetags
= (struct TagItem
*)GetTagData(aHidd_Gfx_ModeTags
, NULL
, msg
->attrList
);
101 /* Parse it and register the gfxmodes */
102 if (register_modes(cl
, o
, modetags
))
107 D(bug("Could not register modes\n"));
110 D(bug("Could not get ModeTags\n"));
112 /* Create a gc that we can use for some rendering */
115 data
->gc
= OOP_NewObject(CSD(cl
)->gcclass
, NULL
, gctags
);
116 if (NULL
== data
->gc
)
118 D(bug("Could not get gc\n"));
126 OOP_MethodID dispose_mid
;
128 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
129 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
133 D(bug("Leaving gfx.hidd::New o=%x\n", o
));
138 /****************************************************************************************/
140 VOID
GFX__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
142 struct HIDDGraphicsData
*data
;
144 data
= OOP_INST_DATA(cl
, o
);
146 /* free the mode db stuff */
147 free_mode_db(&data
->mdb
, cl
);
149 ObtainSemaphore(&data
->pfsema
);
150 free_objectlist((struct List
*)&data
->pflist
, TRUE
, CSD(cl
));
151 ReleaseSemaphore(&data
->pfsema
);
153 if (NULL
!= data
->gc
)
154 OOP_DisposeObject(data
->gc
);
156 OOP_DoSuperMethod(cl
, o
, msg
);
159 /****************************************************************************************/
161 VOID
GFX__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
163 struct HIDDGraphicsData
*data
;
167 data
= OOP_INST_DATA(cl
, o
);
169 if (IS_GFX_ATTR(msg
->attrID
, idx
))
173 case aoHidd_Gfx_NumSyncs
:
176 *msg
->storage
= data
->mdb
.num_syncs
;
180 case aoHidd_Gfx_SupportsHWCursor
:
182 *msg
->storage
= FALSE
;
185 case aoHidd_Gfx_IsWindowed
:
187 *msg
->storage
= FALSE
;
190 default: /* Keep compiler happy */
196 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
201 /****************************************************************************************/
203 OOP_Object
*GFX__Hidd_Gfx__NewGC(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewGC
*msg
)
205 OOP_Object
*gc
= NULL
;
207 EnterFunc(bug("HIDDGfx::NewGC()\n"));
209 gc
= OOP_NewObject(NULL
, CLID_Hidd_GC
, msg
->attrList
);
211 ReturnPtr("HIDDGfx::NewGC", OOP_Object
*, gc
);
214 /****************************************************************************************/
216 VOID
GFX__Hidd_Gfx__DisposeGC(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_DisposeGC
*msg
)
218 EnterFunc(bug("HIDDGfx::DisposeGC()\n"));
220 if (NULL
!= msg
->gc
) OOP_DisposeObject(msg
->gc
);
222 ReturnVoid("HIDDGfx::DisposeGC");
225 /****************************************************************************************/
227 #define BMAO(x) aoHidd_BitMap_ ## x
228 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
230 #define BM_DIMS_AF (BMAF(Width) | BMAF(Height))
232 #define SET_TAG(tags, idx, tag, val) \
233 tags[idx].ti_Tag = tag ; tags[idx].ti_Data = (IPTR)val;
235 #define SET_BM_TAG(tags, idx, tag, val) \
236 SET_TAG(tags, idx, aHidd_BitMap_ ## tag, val)
238 /****************************************************************************************/
240 OOP_Object
* GFX__Hidd_Gfx__NewBitMap(OOP_Class
*cl
, OOP_Object
*o
,
241 struct pHidd_Gfx_NewBitMap
*msg
)
243 struct TagItem bmtags
[7];
245 IPTR attrs
[num_Total_BitMap_Attrs
];
246 STRPTR classid
= NULL
;
247 OOP_Class
*classptr
= NULL
;
248 BOOL displayable
= FALSE
; /* Default attr value */
249 BOOL framebuffer
= FALSE
;
250 OOP_Object
*pf
= NULL
, *sync
;
252 HIDDT_ModeID modeid
= 0;
254 struct HIDDGraphicsData
*data
;
256 DECLARE_ATTRCHECK(bitmap
);
258 BOOL gotclass
= FALSE
;
260 data
= OOP_INST_DATA(cl
, o
);
262 if (0 != OOP_ParseAttrs(msg
->attrList
, attrs
, num_Total_BitMap_Attrs
,
263 &ATTRCHECK(bitmap
), HiddBitMapAttrBase
))
265 D(bug("!!! FAILED TO PARSE ATTRS IN Gfx::NewBitMap !!!\n"));
269 if (GOT_BM_ATTR(PixFmt
))
271 D(bug("!!! Gfx::NewBitMap: USER IS NOT ALLOWED TO PASS aHidd_BitMap_PixFmt !!!\n"));
275 /* Get class supplied by superclass */
276 if (GOT_BM_ATTR(ClassPtr
))
278 classptr
= (OOP_Class
*)attrs
[BMAO(ClassPtr
)];
283 if (GOT_BM_ATTR(ClassID
))
285 classid
= (STRPTR
)attrs
[BMAO(ClassID
)];
290 if (GOT_BM_ATTR(Displayable
))
291 displayable
= (BOOL
)attrs
[BMAO(Displayable
)];
293 if (GOT_BM_ATTR(FrameBuffer
))
295 framebuffer
= (BOOL
)attrs
[BMAO(FrameBuffer
)];
296 if (framebuffer
) displayable
= TRUE
;
299 if (GOT_BM_ATTR(ModeID
))
301 modeid
= attrs
[BMAO(ModeID
)];
303 /* Check that it is a valid mode */
304 if (!HIDD_Gfx_GetMode(o
, modeid
, &sync
, &pf
))
306 D(bug("!!! Gfx::NewBitMap: USER PASSED INVALID MODEID !!!\n"));
310 /* First argument is gfxhidd */
311 SET_BM_TAG(bmtags
, 0, GfxHidd
, o
);
312 SET_BM_TAG(bmtags
, 1, Displayable
, displayable
);
315 if (displayable
|| framebuffer
)
317 /* The user has to supply a modeid */
318 if (!GOT_BM_ATTR(ModeID
))
320 D(bug("!!! Gfx::NewBitMap: USER HAS NOT PASSED MODEID FOR DISPLAYABLE BITMAP !!!\n"));
326 D(bug("!!! Gfx::NewBitMap: SUBCLASS DID NOT PASS CLASS FOR DISPLAYABLE BITMAP !!!\n"));
330 SET_BM_TAG(bmtags
, 2, ModeID
, modeid
);
331 SET_BM_TAG(bmtags
, 3, PixFmt
, pf
);
335 SET_BM_TAG(bmtags
, 4, FrameBuffer
, TRUE
);
339 SET_TAG(bmtags
, 4, TAG_IGNORE
, 0UL);
341 SET_TAG(bmtags
, 5, TAG_MORE
, msg
->attrList
);
345 { /* if (displayable) */
348 /* To get a pixfmt for an offscreen bitmap we either need
349 (ModeID || ( (Width && Height) && StdPixFmt) || ( (Width && Height) && Friend))
352 if (GOT_BM_ATTR(ModeID
))
354 /* We have allredy gotten pixelformat and sync for the modeid case */
355 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &width
);
356 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &height
);
360 /* Next to look for is StdPixFmt */
362 /* Check that we have width && height */
363 if (BM_DIMS_AF
!= (BM_DIMS_AF
& ATTRCHECK(bitmap
)))
365 D(bug("!!! Gfx::NewBitMap() MISSING WIDTH/HEIGHT TAGS !!!\n"));
369 width
= attrs
[BMAO(Width
)];
370 height
= attrs
[BMAO(Height
)];
372 if (GOT_BM_ATTR(StdPixFmt
))
374 pf
= HIDD_Gfx_GetPixFmt(o
, (HIDDT_StdPixFmt
)attrs
[BMAO(StdPixFmt
)]);
377 D(bug("!!! Gfx::NewBitMap(): USER PASSED BOGUS StdPixFmt !!!\n"));
383 /* Last alternative is that the user passed a friend bitmap */
384 if (GOT_BM_ATTR(Friend
))
386 OOP_GetAttr((OOP_Object
*)attrs
[BMAO(Friend
)], aHidd_BitMap_PixFmt
, (IPTR
*)ptr_pf
);
390 D(bug("!!! Gfx::NewBitMap: UNSIFFICIENT ATTRS TO CREATE OFFSCREEN BITMAP !!!\n"));
396 /* Did the subclass provide an offbitmap class for us ? */
399 /* Have to find a suitable class ourselves */
400 HIDDT_BitMapType bmtype
;
402 OOP_GetAttr(pf
, aHidd_PixFmt_BitMapType
, &bmtype
);
405 case vHidd_BitMapType_Chunky
:
406 classptr
= CSD(cl
)->chunkybmclass
;
409 case vHidd_BitMapType_Planar
:
410 classptr
= CSD(cl
)->planarbmclass
;
414 D(bug("!!! Gfx::NewBitMap: UNKNOWN BITMAPTYPE %d !!!\n", bmtype
));
419 } /* if (!gotclass) */
421 /* Set the tags we want to pass to the selected bitmap class */
422 SET_BM_TAG(bmtags
, 2, Width
, width
);
423 SET_BM_TAG(bmtags
, 3, Height
, height
);
424 SET_BM_TAG(bmtags
, 4, PixFmt
, pf
);
426 if (GOT_BM_ATTR(Friend
))
428 SET_BM_TAG(bmtags
, 5, Friend
, attrs
[BMAO(Friend
)]);
432 SET_TAG(bmtags
, 5, TAG_IGNORE
, 0UL);
434 SET_TAG(bmtags
, 6, TAG_MORE
, msg
->attrList
);
436 } /* if (!displayable) */
439 bm
= OOP_NewObject(classptr
, classid
, bmtags
);
442 data
->framebuffer
= bm
;
448 /****************************************************************************************/
450 VOID
GFX__Hidd_Gfx__DisposeBitMap(OOP_Class
*cl
, OOP_Object
*o
,
451 struct pHidd_Gfx_DisposeBitMap
*msg
)
453 if (NULL
!= msg
->bitMap
)
454 OOP_DisposeObject(msg
->bitMap
);
457 /****************************************************************************************/
459 #define SD(x) ((struct sync_data *)x)
460 #define PF(x) ((HIDDT_PixelFormat *)x)
462 #define XCOORD_TO_BYTEIDX(x) ( (x) >> 3)
463 #define COORD_TO_BYTEIDX(x, y, bpr) ( ( (y) * bpr ) + XCOORD_TO_BYTEIDX(x) )
464 #define XCOORD_TO_MASK(x) (1L << (7 - ((x) & 0x07) ))
465 #define WIDTH_TO_BYTES(width) ( (( (width) - 1) >> 3) + 1)
467 /****************************************************************************************/
469 /* modebm functions pfidx is x and syncidx is y coord in the bitmap */
471 /****************************************************************************************/
473 static inline BOOL
alloc_mode_bm(struct mode_bm
*bm
, ULONG numsyncs
, ULONG numpfs
,
476 bm
->bpr
= WIDTH_TO_BYTES(numpfs
);
478 bm
->bm
= AllocVec(bm
->bpr
* numsyncs
, MEMF_CLEAR
);
482 /* We initialize the mode bitmap to all modes valid */
483 memset(bm
->bm
, 0xFF, bm
->bpr
* numsyncs
);
488 /****************************************************************************************/
490 static inline VOID
free_mode_bm(struct mode_bm
*bm
, OOP_Class
*cl
)
497 /****************************************************************************************/
499 static inline BOOL
is_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
)
501 if (0 != (XCOORD_TO_MASK(pfidx
) & bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)]))
507 /****************************************************************************************/
509 static inline VOID
set_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
,
513 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] |= XCOORD_TO_MASK(pfidx
);
515 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] &= ~XCOORD_TO_MASK(pfidx
);
520 /****************************************************************************************/
522 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
)
526 if (0 == numsyncs
|| 0 == numpfs
)
529 ObtainSemaphore(&mdb
->sema
);
530 /* free_mode_bm() needs this */
531 mdb
->num_pixfmts
= numpfs
;
532 mdb
->num_syncs
= numsyncs
;
534 mdb
->syncs
= AllocMem(sizeof (OOP_Object
*) * numsyncs
, MEMF_CLEAR
);
536 if (NULL
!= mdb
->syncs
)
538 mdb
->pixfmts
= AllocMem(sizeof (OOP_Object
*) * numpfs
, MEMF_CLEAR
);
540 if (NULL
!= mdb
->pixfmts
)
542 if (alloc_mode_bm(&mdb
->orig_mode_bm
, numsyncs
, numpfs
, cl
))
544 if (alloc_mode_bm(&mdb
->checked_mode_bm
, numsyncs
, numpfs
, cl
))
553 free_mode_db(mdb
, cl
);
555 ReleaseSemaphore(&mdb
->sema
);
560 /****************************************************************************************/
562 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
)
566 ObtainSemaphore(&mdb
->sema
);
568 if (NULL
!= mdb
->pixfmts
)
571 /****** !!! NB !!! The Pixel formats are registerd in the
572 GfxMode Database and is freed in the
573 free_object_list functions
575 for (i = 0; i < mdb->num_pixfmts; i ++)
577 if (NULL != mdb->pixfmts[i])
579 OOP_DisposeObject(mdb->pixfmts[i]);
580 mdb->pixfmts[i] = NULL;
585 FreeMem(mdb
->pixfmts
, sizeof (OOP_Object
*) * mdb
->num_pixfmts
);
586 mdb
->pixfmts
= NULL
; mdb
->num_pixfmts
= 0;
589 if (NULL
!= mdb
->syncs
)
591 for (i
= 0; i
< mdb
->num_syncs
; i
++)
593 if (NULL
!= mdb
->syncs
[i
])
596 OOP_DisposeObject(mdb
->syncs
[i
]);
597 mdb
->syncs
[i
] = NULL
;
601 FreeMem(mdb
->syncs
, sizeof (OOP_Object
*) * mdb
->num_syncs
);
602 mdb
->syncs
= NULL
; mdb
->num_syncs
= 0;
605 if (NULL
!= mdb
->orig_mode_bm
.bm
)
607 free_mode_bm(&mdb
->orig_mode_bm
, cl
);
610 if (NULL
!= mdb
->checked_mode_bm
.bm
)
612 free_mode_bm(&mdb
->checked_mode_bm
, cl
);
615 ReleaseSemaphore(&mdb
->sema
);
620 /****************************************************************************************/
622 /* Initializes default tagarray. in numtags the TAG_MORE is not accounted for,
623 so the array must be of size NUM_TAGS + 1
626 /****************************************************************************************/
628 static VOID
init_def_tags(struct TagItem
*tags
, ULONG numtags
)
632 for (i
= 0; i
< numtags
; i
++)
634 tags
[i
].ti_Tag
= TAG_IGNORE
;
635 tags
[i
].ti_Data
= 0UL;
638 tags
[i
].ti_Tag
= TAG_MORE
;
639 tags
[i
].ti_Data
= 0UL;
644 /****************************************************************************************/
646 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
)
648 struct TagItem
*tag
, *tstate
;
649 struct HIDDGraphicsData
*data
;
651 DECLARE_ATTRCHECK(sync
);
655 HIDDT_PixelFormat pixfmt_data
;
656 struct sync_data sync_data
;
658 struct TagItem def_sync_tags
[num_Hidd_Sync_Attrs
+ 1];
659 struct TagItem def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
+ 1];
661 ULONG numpfs
= 0,numsyncs
= 0;
662 ULONG pfidx
= 0, syncidx
= 0;
664 data
= OOP_INST_DATA(cl
, o
);
666 InitSemaphore(&mdb
->sema
);
668 memset(&pixfmt_data
, 0, sizeof (pixfmt_data
));
669 memset(&sync_data
, 0, sizeof (sync_data
));
671 init_def_tags(def_sync_tags
, num_Hidd_Sync_Attrs
);
672 init_def_tags(def_pixfmt_tags
, num_Hidd_PixFmt_Attrs
);
674 /* First we need to calculate how much memory we are to allocate by counting supplied
675 pixel formats and syncs */
677 for (tstate
= modetags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
));)
681 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
685 case aoHidd_Gfx_PixFmtTags
:
689 case aoHidd_Gfx_SyncTags
:
699 if (0 == numpfs
|| 0 == numsyncs
)
701 D(bug("!!! WE MUST AT LEAST HAVE ONE PIXFMT AND ONE SYNC IN Gfx::RegisterModes() !!!\n"));
704 ObtainSemaphore(&mdb
->sema
);
706 /* Allocate memory for mode db */
707 if (!alloc_mode_db(&data
->mdb
, numsyncs
, numpfs
, cl
))
711 for (tstate
= modetags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
));)
713 /* Look for Gfx, PixFmt and Sync tags */
716 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
720 case aoHidd_Gfx_PixFmtTags
:
721 def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
].ti_Data
= tag
->ti_Data
;
722 mdb
->pixfmts
[pfidx
] = HIDD_Gfx_RegisterPixFmt(o
, def_pixfmt_tags
);
724 if (NULL
== mdb
->pixfmts
[pfidx
])
726 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
733 case aoHidd_Gfx_SyncTags
:
734 def_sync_tags
[num_Hidd_Sync_Attrs
].ti_Data
= tag
->ti_Data
;
735 if (!parse_sync_tags(def_sync_tags
740 D(bug("!!! ERROR PARSING SYNC TAGS IN Gfx::RegisterModes() !!!\n"));
745 mdb
->syncs
[syncidx
] = create_and_init_object(CSD(cl
)->syncclass
746 , (UBYTE
*)&sync_data
750 if (NULL
== mdb
->syncs
[syncidx
])
752 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
761 else if (IS_SYNC_ATTR(tag
->ti_Tag
, idx
))
763 if (idx
>= num_Hidd_Sync_Attrs
)
765 D(bug("!!! UNKNOWN SYNC ATTR IN Gfx::New(): %d !!!\n", idx
));
769 def_sync_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
770 def_sync_tags
[idx
].ti_Data
= tag
->ti_Data
;
774 else if (IS_PIXFMT_ATTR(tag
->ti_Tag
, idx
))
776 if (idx
>= num_Hidd_PixFmt_Attrs
)
778 D(bug("!!! UNKNOWN PIXFMT ATTR IN Gfx::New(): %d !!!\n", idx
));
782 def_pixfmt_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
783 def_pixfmt_tags
[idx
].ti_Data
= tag
->ti_Data
;
788 ReleaseSemaphore(&mdb
->sema
);
794 /* mode db is freed in dispose */
795 ReleaseSemaphore(&mdb
->sema
);
800 /****************************************************************************************/
809 HIDDT_StdPixFmt
*stdpfs
;
819 /****************************************************************************************/
821 /* This is a recursive function that looks for valid modes */
823 /****************************************************************************************/
825 static HIDDT_ModeID
*querymode(struct modequery
*mq
)
827 HIDDT_ModeID
*modeids
;
828 register OOP_Object
*pf
;
829 register OOP_Object
*sync
;
830 BOOL mode_ok
= FALSE
;
831 OOP_Class
*cl
= mq
->cl
;
832 ULONG syncidx
, pfidx
;
835 mq
->stdpfs_ok
= FALSE
;
836 mq
->check_ok
= FALSE
;
838 /* Look at the supplied idx */
839 if (mq
->pfidx
>= mq
->mdb
->num_pixfmts
)
845 if (mq
->syncidx
>= mq
->mdb
->num_syncs
)
847 /* We have reached the end of the recursion. Allocate memory and go back
850 modeids
= AllocVec(sizeof (HIDDT_ModeID
) * (mq
->numfound
+ 1), MEMF_ANY
);
851 /* Get the end of the array */
852 modeids
+= mq
->numfound
;
853 *modeids
= vHidd_ModeID_Invalid
;
858 syncidx
= mq
->syncidx
;
860 /* Get the pf and sync objects */
861 pf
= mq
->mdb
->pixfmts
[syncidx
];
862 sync
= mq
->mdb
->syncs
[pfidx
];
865 /* Check that the mode is really usable */
866 if (is_valid_mode(&mq
->mdb
->checked_mode_bm
, syncidx
, pfidx
))
871 /* See if this mode matches the criterias set */
873 if ( SD(sync
)->hdisp
>= mq
->minwidth
874 && SD(sync
)->hdisp
<= mq
->maxwidth
875 && SD(sync
)->vdisp
>= mq
->minheight
876 && SD(sync
)->vdisp
<= mq
->maxheight
)
882 if (NULL
!= mq
->stdpfs
)
884 register HIDDT_StdPixFmt
*stdpf
= mq
->stdpfs
;
887 if (*stdpf
== PF(pf
)->stdpixfmt
)
889 mq
->stdpfs_ok
= TRUE
;
896 mq
->stdpfs_ok
= TRUE
;
902 if (mq
->dims_ok
&& mq
->stdpfs_ok
&& mq
->check_ok
)
910 modeids
= querymode(mq
);
917 /* The mode is OK. Add it to the list */
919 *modeids
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
926 /****************************************************************************************/
928 HIDDT_ModeID
*GFX__Hidd_Gfx__QueryModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
929 struct pHidd_Gfx_QueryModeIDs
*msg
)
931 struct TagItem
*tag
, *tstate
;
933 HIDDT_ModeID
*modeids
;
934 struct HIDDGraphicsData
*data
;
937 struct modequery mq
=
939 NULL
, /* mode db (set later) */
940 0, 0xFFFFFFFF, /* minwidth, maxwidth */
941 0, 0xFFFFFFFF, /* minheight, maxheight */
944 0, 0, /* pfidx, syncidx */
945 FALSE
, FALSE
, /* dims_ok, stdpfs_ok */
946 FALSE
, /* check_ok */
947 NULL
/* class (set later) */
952 data
= OOP_INST_DATA(cl
, o
);
957 for (tstate
= msg
->queryTags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
)); )
961 case tHidd_GfxMode_MinWidth
:
962 mq
.minwidth
= (ULONG
)tag
->ti_Tag
;
965 case tHidd_GfxMode_MaxWidth
:
966 mq
.maxwidth
= (ULONG
)tag
->ti_Tag
;
969 case tHidd_GfxMode_MinHeight
:
970 mq
.minheight
= (ULONG
)tag
->ti_Tag
;
973 case tHidd_GfxMode_MaxHeight
:
974 mq
.maxheight
= (ULONG
)tag
->ti_Tag
;
977 case tHidd_GfxMode_PixFmts
:
978 mq
.stdpfs
= (HIDDT_StdPixFmt
*)tag
->ti_Data
;
984 ObtainSemaphoreShared(&mdb
->sema
);
986 /* Recursively check all modes */
987 modeids
= querymode(&mq
);
989 ReleaseSemaphore(&mdb
->sema
);
995 /****************************************************************************************/
997 VOID
GFX__Hidd_Gfx__ReleaseModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
998 struct pHidd_Gfx_ReleaseModeIDs
*msg
)
1000 FreeVec(msg
->modeIDs
);
1003 /****************************************************************************************/
1005 HIDDT_ModeID
GFX__Hidd_Gfx__NextModeID(OOP_Class
*cl
, OOP_Object
*o
,
1006 struct pHidd_Gfx_NextModeID
*msg
)
1008 struct HIDDGraphicsData
*data
;
1009 struct mode_db
*mdb
;
1010 ULONG syncidx
, pfidx
;
1011 HIDDT_ModeID return_id
= vHidd_ModeID_Invalid
;
1014 data
= OOP_INST_DATA(cl
, o
);
1017 ObtainSemaphoreShared(&mdb
->sema
);
1018 if (vHidd_ModeID_Invalid
== msg
->modeID
)
1025 pfidx
= MODEID_TO_PFIDX( msg
->modeID
);
1026 syncidx
= MODEID_TO_SYNCIDX( msg
->modeID
);
1028 /* Increament one from the last call */
1030 if (pfidx
>= mdb
->num_pixfmts
)
1037 /* Search for a new mode. We only accept valid modes */
1038 for (; syncidx
< mdb
->num_syncs
; syncidx
++)
1040 /* We only return valid modes */
1041 for (; pfidx
< mdb
->num_pixfmts
; pfidx
++)
1043 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
1055 return_id
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
1056 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
1057 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
1061 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
1064 ReleaseSemaphore(&mdb
->sema
);
1069 /****************************************************************************************/
1071 BOOL
GFX__Hidd_Gfx__GetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMode
*msg
)
1073 ULONG pfidx
, syncidx
;
1074 struct HIDDGraphicsData
*data
;
1075 struct mode_db
*mdb
;
1078 data
= OOP_INST_DATA(cl
, o
);
1081 pfidx
= MODEID_TO_PFIDX(msg
->modeID
);
1082 syncidx
= MODEID_TO_SYNCIDX(msg
->modeID
);
1084 ObtainSemaphoreShared(&mdb
->sema
);
1086 if (! (pfidx
>= mdb
->num_pixfmts
|| syncidx
>= mdb
->num_syncs
) )
1088 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
1091 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
1092 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
1096 ReleaseSemaphore(&mdb
->sema
);
1100 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
1106 /****************************************************************************************/
1108 BOOL
GFX__Hidd_Gfx__SetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetMode
*msg
)
1111 struct HIDDGraphicsData
*data
;
1112 OOP_Object
*sync
, *pf
;
1114 data
= OOP_INST_DATA(cl
, o
);
1116 /* Check if we have a valid modeid */
1117 if (HIDD_Gfx_GetMode(o
, msg
->modeID
, &sync
, &pf
))
1121 curmode
= msg
->modeID
;
1123 /* Do we have a framebuffer yet ? */
1124 if (NULL
== data
->framebuffer
)
1126 /* No framebuffer. We should init one. */
1130 /* Framebuffer created. Check if framebuffer is large enough
1141 /****************************************************************************************/
1143 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
,
1144 OOP_Object
*dst_bm
, OOP_Object
*dims_bm
)
1146 struct TagItem gctags
[] =
1148 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
1151 struct HIDDGraphicsData
*data
;
1155 OOP_Object
*src_colmap
;
1156 APTR psrc_colmap
= &src_colmap
;
1158 data
= OOP_INST_DATA(cl
, o
);
1160 /* Copy the displayable bitmap into the framebuffer */
1161 OOP_GetAttr(dims_bm
, aHidd_BitMap_Width
, &width
);
1162 OOP_GetAttr(dims_bm
, aHidd_BitMap_Height
, &height
);
1164 /* We have to copy the colormap into the framebuffer bitmap */
1165 OOP_GetAttr(src_bm
, aHidd_BitMap_ColorMap
, (IPTR
*)psrc_colmap
);
1166 OOP_GetAttr(src_colmap
, aHidd_ColorMap_NumEntries
, &numentries
);
1168 for (i
= 0; i
< numentries
; i
++)
1172 HIDD_CM_GetColor(src_colmap
, i
, &col
);
1173 HIDD_BM_SetColors(dst_bm
, &col
, i
, 1);
1177 OOP_SetAttrs(data
->gc
, gctags
);
1188 /****************************************************************************************/
1190 OOP_Object
*GFX__Hidd_Gfx__Show(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Show
*msg
)
1192 struct HIDDGraphicsData
*data
;
1196 data
= OOP_INST_DATA(cl
, o
);
1199 /* We have to do some consistency checking */
1202 OOP_GetAttr(bm
, aHidd_BitMap_Displayable
, &displayable
);
1205 if (bm
&& !displayable
)
1206 /* We cannot show a non-displayable bitmap */
1209 if (NULL
== data
->framebuffer
)
1212 if (NULL
!= data
->shownbm
&& (msg
->flags
& fHidd_Gfx_Show_CopyBack
))
1214 /* Copy the framebuffer data back into the old shown bitmap */
1215 copy_bm_and_colmap(cl
, o
, data
->framebuffer
, data
->shownbm
, data
->shownbm
);
1220 copy_bm_and_colmap(cl
, o
, bm
, data
->framebuffer
, bm
);
1224 #warning should clear framebuffer to black
1228 return data
->framebuffer
;
1231 /****************************************************************************************/
1233 BOOL
GFX__Hidd_Gfx__SetCursorShape(OOP_Class
*cl
, OOP_Object
*o
,
1234 struct pHidd_Gfx_SetCursorShape
*msg
)
1236 /* We have no clue how to render the cursor */
1240 /****************************************************************************************/
1242 BOOL
GFX__Hidd_Gfx__SetCursorVisible(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorVisible
*msg
)
1247 /****************************************************************************************/
1249 BOOL
GFX__Hidd_Gfx__SetCursorPos(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorPos
*msg
)
1254 /*****************************************************************************************
1262 OOP_DoMethod(src, WORD srcX, WORD srcY,
1263 OOP_Object *dest, WORD destX, WORD destY,
1264 UWORD sizeX, UWORD sizeY);
1267 Copy a rectangular area from the drawing area src to the drawing
1268 area stored in dest (which may be src). The source area is not
1269 changed (except when both rectangles overlap). The mode of the GC
1270 dest determines how the copy takes place.
1272 In quick mode, the following restrictions are not checked: It's not
1273 checked whether the source or destination rectangle is completely
1274 inside the valid area or whether the areas overlap. If they
1275 overlap, the results are unpredictable. Also drawing modes are
1276 ignored. If the two bitmaps in the GCs have a different depth,
1277 copying might be slow.
1279 When copying bitmaps between two different HIDDs, the following
1280 pseudo algorithm is executed: First the destination HIDD is queried
1281 whether it does understand the format of the source HIDD. If it
1282 does, then the destination HIDD does the copying. If it doesn't,
1283 then the source is asked whether it understands the destination
1284 HIDDs' format. If it does, then the source HIDD will do the
1285 copying. If it doesn't, then the default CopyArea of the graphics
1286 HIDD base class will be invoked which copies the bitmaps pixel by
1287 pixel with BitMap::GetPixel() and BitMap::DrawPixel().
1290 src - source bitmap object
1291 srcX, srcY - upper, left corner of the area to copy in the source
1292 dest - destination bitmap object
1293 destX, destY - upper, left corner in the destination to copy the area
1294 width, height - width and height of the area in hidd units
1305 GROUP=HIDD_BltBitMap
1313 *****************************************************************************************/
1315 VOID
GFX__Hidd_Gfx__CopyBox(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_Gfx_CopyBox
*msg
)
1318 WORD srcX
= msg
->srcX
, destX
= msg
->destX
;
1319 WORD srcY
= msg
->srcY
, destY
= msg
->destY
;
1320 WORD startX
, endX
, deltaX
, startY
, endY
, deltaY
;
1323 HIDDT_PixelFormat
*srcpf
, *dstpf
;
1324 OOP_Object
*dest
, *src
;
1327 #if USE_FAST_GETPIXEL
1328 struct pHidd_BitMap_GetPixel get_p
;
1331 #if USE_FAST_DRAWPIXEL
1332 struct pHidd_BitMap_DrawPixel draw_p
;
1334 draw_p
.mID
= CSD(cl
)->drawpixel_mid
;
1335 draw_p
.gc
= msg
->gc
;
1338 #if USE_FAST_GETPIXEL
1339 get_p
.mID
= CSD(cl
)->getpixel_mid
;
1345 /* If source/dest overlap, direction of operation is important */
1349 startX
= msg
->width
- 1; endX
= -1; deltaX
= -1;
1353 startX
= 0; endX
= msg
->width
; deltaX
= 1;
1358 startY
= msg
->height
- 1; endY
= -1; deltaY
= -1;
1362 startY
= 0; endY
= msg
->height
; deltaY
= 1;
1365 /* Get the source pixel format */
1366 srcpf
= (HIDDT_PixelFormat
*)HBM(src
)->prot
.pixfmt
;
1368 /* bug("COPYBOX: SRC PF: %p, obj=%p, cl=%s, OOP_OCLASS: %s\n", srcpf, obj
1369 , cl->ClassNode.ln_Name, OOP_OCLASS(obj)->ClassNode.ln_Name);
1374 IPTR sw
, sh
, dw
, dh
;
1375 D(bug("COPYBOX: src=%p, dst=%p, width=%d, height=%d\n"
1376 , obj
, msg
->dest
, msg
->width
, msg
->height
));
1378 OOP_GetAttr(obj
, aHidd_BitMap_Width
, &sw
);
1379 OOP_GetAttr(obj
, aHidd_BitMap_Height
, &sh
);
1380 OOP_GetAttr(msg
->dest
, aHidd_BitMap_Width
, &dw
);
1381 OOP_GetAttr(msg
->dest
, aHidd_BitMap_Height
, &dh
);
1382 D(bug("src dims: %d, %d dest dims: %d, %d\n", sw
, sh
, dw
, dh
));
1386 dstpf
= (HIDDT_PixelFormat
*)HBM(dest
)->prot
.pixfmt
;
1388 /* Compare graphtypes */
1389 if (HIDD_PF_COLMODEL(srcpf
) == HIDD_PF_COLMODEL(dstpf
))
1391 /* It is ok to do a direct copy */
1395 /* Find out the gfx formats */
1396 if ( IS_PALETTIZED(srcpf
) && IS_TRUECOLOR(dstpf
))
1400 else if (IS_TRUECOLOR(srcpf
) && IS_PALETTIZED(dstpf
))
1404 else if (IS_PALETTE(srcpf
) && IS_STATICPALETTE(dstpf
))
1408 else if (IS_STATICPALETTE(srcpf
) && IS_PALETTE(dstpf
))
1416 memFG
= GC_FG(msg
->gc
);
1418 /* All else have failed, copy pixel by pixel */
1421 if (HIDD_PF_COLMODEL(srcpf
) == HIDD_PF_COLMODEL(dstpf
))
1423 if (IS_TRUECOLOR(srcpf
))
1425 // bug("COPY FROM TRUECOLOR TO TRUECOLOR\n");
1426 for(y
= startY
; y
!= endY
; y
+= deltaY
)
1430 /* if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
1431 bug("[%d,%d] ", memSrcX, memDestX);
1433 for(x
= startX
; x
!= endX
; x
+= deltaX
)
1437 #if USE_FAST_GETPIXEL
1440 pix
= GETPIXEL(src
, &get_p
);
1442 pix
= HIDD_BM_GetPixel(obj
, srcX
+ x
, srcY
+ y
);
1445 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
1453 HIDD_BM_UnmapPixel(src
, pix
, &col
);
1454 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, &col
);
1455 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
1461 #if USE_FAST_DRAWPIXEL
1462 draw_p
.x
= destX
+ x
;
1463 draw_p
.y
= destY
+ y
;
1464 DRAWPIXEL(dest
, &draw_p
);
1467 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
1472 /*if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
1473 bug("[%d,%d] ", srcY, destY);
1477 } /* if (IS_TRUECOLOR(srcpf)) */
1480 /* Two palette bitmaps.
1481 For this case we do NOT convert through RGB,
1482 but copy the pixel indexes directly
1484 // bug("COPY FROM PALETTE TO PALETTE\n");
1486 #warning This might not work very well with two StaticPalette bitmaps
1488 for(y
= startY
; y
!= endY
; y
+= deltaY
)
1490 for(x
= startX
; x
!= endX
; x
+= deltaX
)
1492 GC_FG(gc
) = HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
1494 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
1499 } /* if (IS_TRUECOLOR(srcpf)) else ... */
1501 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) */
1504 /* Two unlike bitmaps */
1505 if (IS_TRUECOLOR(srcpf
))
1507 #warning Implement this
1508 D(bug("!! DEFAULT COPYING FROM TRUECOLOR TO PALETTIZED NOT IMPLEMENTED IN BitMap::CopyBox\n"));
1510 else if (IS_TRUECOLOR(dstpf
))
1512 /* Get the colortab */
1513 HIDDT_Color
*ctab
= ((HIDDT_ColorLUT
*)HBM(src
)->colmap
)->colors
;
1515 // bug("COPY FROM PALETTE TO TRUECOLOR, DRAWMODE %d, CTAB %p\n", GC_DRMD(gc), ctab);
1517 for(y
= startY
; y
!= endY
; y
+= deltaY
)
1519 for(x
= startX
; x
!= endX
; x
+= deltaX
)
1521 register HIDDT_Pixel pix
;
1522 register HIDDT_Color
*col
;
1524 pix
= HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
1527 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, col
);
1528 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
1534 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) else ... */
1539 /****************************************************************************************/
1541 VOID
GFX__Hidd_Gfx__ShowImminentReset(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg msg
)
1545 /****************************************************************************************/
1547 OOP_Object
*GFX__Hidd_Gfx__RegisterPixFmt(OOP_Class
*cl
, OOP_Object
*o
,
1548 struct pHidd_Gfx_RegisterPixFmt
*msg
)
1550 HIDDT_PixelFormat cmp_pf
;
1551 struct HIDDGraphicsData
*data
;
1553 struct pfnode
*pfnode
;
1555 OOP_Object
*retpf
= NULL
;
1557 memset(&cmp_pf
, 0, sizeof(cmp_pf
));
1559 data
= OOP_INST_DATA(cl
, o
);
1560 if (!parse_pixfmt_tags(msg
->pixFmtTags
, &cmp_pf
, 0, CSD(cl
)))
1562 D(bug("!!! FAILED PARSING TAGS IN Gfx::RegisterPixFmt() !!!\n"));
1566 ObtainSemaphoreShared(&data
->pfsema
);
1567 pfnode
= find_pixfmt(&data
->pflist
, &cmp_pf
, CSD(cl
));
1568 ReleaseSemaphore(&data
->pfsema
);
1572 retpf
= find_stdpixfmt(&cmp_pf
, CSD(cl
));
1576 retpf
= pfnode
->pixfmt
;
1577 /* Increase pf refcount */
1578 pfnode
->refcount
++;
1584 struct pfnode
*newnode
;
1585 /* Could not find an alike pf, Create a new pfdb node */
1587 newnode
= AllocMem(sizeof (struct pfnode
), MEMF_ANY
);
1588 if (NULL
!= newnode
)
1591 /* Since we pass NULL as the taglist below, the PixFmt class will just create a dummy pixfmt */
1592 retpf
= OOP_NewObject(CSD(cl
)->pixfmtclass
, NULL
, NULL
);
1595 newnode
->pixfmt
= retpf
;
1597 /* We have one user */
1598 newnode
->refcount
= 1;
1600 /* Initialize the pixfmt object the "ugly" way */
1601 cmp_pf
.stdpixfmt
= vHidd_StdPixFmt_Unknown
;
1602 memcpy(retpf
, &cmp_pf
, sizeof (HIDDT_PixelFormat
));
1604 #define PF(x) ((HIDDT_PixelFormat *)x)
1606 bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
1607 , PF(&cmp_pf)->red_shift
1608 , PF(&cmp_pf)->green_shift
1609 , PF(&cmp_pf)->blue_shift
1610 , PF(&cmp_pf)->alpha_shift
1611 , PF(&cmp_pf)->red_mask
1612 , PF(&cmp_pf)->green_mask
1613 , PF(&cmp_pf)->blue_mask
1614 , PF(&cmp_pf)->alpha_mask
1615 , PF(&cmp_pf)->bytes_per_pixel
1617 , PF(&cmp_pf)->depth
1618 , PF(&cmp_pf)->stdpixfmt
1619 , HIDD_BP_BITMAPTYPE(&cmp_pf));
1623 ObtainSemaphore(&data
->pfsema
);
1624 AddTail((struct List
*)&data
->pflist
, (struct Node
*)newnode
);
1625 ReleaseSemaphore(&data
->pfsema
);
1630 FreeMem(newnode
, sizeof (struct pfnode
));
1640 /****************************************************************************************/
1642 VOID
GFX__Hidd_Gfx__ReleasePixFmt(OOP_Class
*cl
, OOP_Object
*o
,
1643 struct pHidd_Gfx_ReleasePixFmt
*msg
)
1645 struct HIDDGraphicsData
*data
;
1647 struct objectnode
*n
, *safe
;
1650 /* bug("release_pixfmt\n");
1653 data
= OOP_INST_DATA(cl
, o
);
1655 /* Go through the pixfmt list trying to find the object */
1656 ObtainSemaphore(&data
->pfsema
);
1658 ForeachNodeSafe(&data
->pflist
, n
, safe
)
1660 if (msg
->pixFmt
== n
->object
)
1663 if (0 == n
->refcount
)
1665 /* Remove the node */
1666 Remove((struct Node
*)n
);
1668 /* Dispose the pixel format */
1669 OOP_DisposeObject(n
->object
);
1672 FreeMem(n
, sizeof (struct objectnode
));
1679 ReleaseSemaphore(&data
->pfsema
);
1682 /*****************************************************************************************
1686 This is a method which should be implemented by the subclasses.
1687 It should look at the supplied pixfmt and sync and see if it is valid.
1688 This will handle any special cases that are not covered by the
1689 pixfmts/syncs supplied in HIDD_Gfx_RegisterModes().
1690 For example some advanced modes, like 1024x768x24 @ 90 might not be available
1691 because of lack of bandwidth in the gfx hw.
1693 *****************************************************************************************/
1695 BOOL
GFX__Hidd_Gfx__CheckMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CheckMode
*msg
)
1697 /* As a default we allways return TRUE, ie. the mode is OK */
1701 /****************************************************************************************/
1703 OOP_Object
*GFX__Hidd_Gfx__GetPixFmt(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetPixFmt
*msg
)
1707 if (!IS_REAL_STDPIXFMT(msg
->stdPixFmt
))
1709 D(bug("!!! Illegal pixel format passed to Gfx::GetPixFmt(): %d\n", msg
->stdPixFmt
));
1714 fmt
= CSD(cl
)->std_pixfmts
[REAL_STDPIXFMT_IDX(msg
->stdPixFmt
)];
1720 /****************************************************************************************/
1724 /****************************************************************************************/
1726 static int GFX_ClassInit(LIBBASETYPEPTR LIBBASE
)
1728 struct class_static_data
*csd
= &LIBBASE
->hdg_csd
;
1730 __IHidd_PixFmt
= OOP_ObtainAttrBase(IID_Hidd_PixFmt
);
1731 __IHidd_BitMap
= OOP_ObtainAttrBase(IID_Hidd_BitMap
);
1732 __IHidd_Gfx
= OOP_ObtainAttrBase(IID_Hidd_Gfx
);
1733 __IHidd_Sync
= OOP_ObtainAttrBase(IID_Hidd_Sync
);
1734 __IHidd_GC
= OOP_ObtainAttrBase(IID_Hidd_GC
);
1735 __IHidd_ColorMap
= OOP_ObtainAttrBase(IID_Hidd_ColorMap
);
1736 __IHidd_PlanarBM
= OOP_ObtainAttrBase(IID_Hidd_PlanarBM
);
1738 if (!__IHidd_PixFmt
||
1743 !__IHidd_ColorMap
||
1750 D(bug("Creating std pixelfmts\n"));
1751 if (!create_std_pixfmts(csd
))
1753 D(bug("Pixfmts created\n"));
1755 /* Get two methodis required for direct method execution */
1756 #if USE_FAST_PUTPIXEL
1757 csd
->putpixel_mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_PutPixel
);
1759 #if USE_FAST_GETPIXEL
1760 csd
->getpixel_mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_GetPixel
);
1762 #if USE_FAST_DRAWPIXEL
1763 csd
->drawpixel_mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_DrawPixel
);
1766 ReturnInt("init_gfxhiddclass", ULONG
, TRUE
);
1769 ReturnPtr("init_gfxhiddclass", ULONG
, FALSE
);
1772 /****************************************************************************************/
1774 static int GFX_ClassFree(LIBBASETYPEPTR LIBBASE
)
1776 struct class_static_data
*csd
= &LIBBASE
->hdg_csd
;
1778 EnterFunc(bug("free_gfxhiddclass(csd=%p)\n", csd
));
1782 delete_std_pixfmts(csd
);
1784 OOP_ReleaseAttrBase(IID_Hidd_PixFmt
);
1785 OOP_ReleaseAttrBase(IID_Hidd_BitMap
);
1786 OOP_ReleaseAttrBase(IID_Hidd_Gfx
);
1787 OOP_ReleaseAttrBase(IID_Hidd_Sync
);
1788 OOP_ReleaseAttrBase(IID_Hidd_GC
);
1789 OOP_ReleaseAttrBase(IID_Hidd_ColorMap
);
1790 OOP_ReleaseAttrBase(IID_Hidd_PlanarBM
);
1794 ReturnInt("free_gfxhiddclass", BOOL
, TRUE
);
1797 /****************************************************************************************/
1799 ADD2INITLIB(GFX_ClassInit
, 0)
1800 ADD2EXPUNGELIB(GFX_ClassFree
, 0)
1802 /****************************************************************************************/
1804 /* Since the shift/mask values of a pixel format are designed for pixel
1805 access, not byte access, they are endianess dependant */
1808 #include "stdpixfmts_be.h"
1810 #include "stdpixfmts_le.h"
1813 /****************************************************************************************/
1815 static BOOL
create_std_pixfmts(struct class_static_data
*csd
)
1819 memset(csd
->std_pixfmts
, 0, sizeof (OOP_Object
*) * num_Hidd_StdPixFmt
);
1821 for (i
= 0; i
< num_Hidd_StdPixFmt
; i
++)
1823 csd
->std_pixfmts
[i
] = create_and_init_object(csd
->pixfmtclass
1824 , (UBYTE
*)&stdpfs
[i
], sizeof (stdpfs
[i
]), csd
);
1826 if (NULL
== csd
->std_pixfmts
[i
])
1828 D(bug("FAILED TO CREATE PIXEL FORMAT %d\n", i
));
1829 delete_std_pixfmts(csd
);
1830 ReturnBool("create_stdpixfmts", FALSE
);
1833 ReturnBool("create_stdpixfmts", TRUE
);
1837 /****************************************************************************************/
1839 static VOID
delete_std_pixfmts(struct class_static_data
*csd
)
1843 for (i
= 0; i
< num_Hidd_StdPixFmt
; i
++)
1846 if (NULL
!= csd
->std_pixfmts
[i
])
1848 OOP_DisposeObject(csd
->std_pixfmts
[i
]);
1849 csd
->std_pixfmts
[i
] = NULL
;
1854 /****************************************************************************************/
1856 static VOID
free_objectlist(struct List
*list
, BOOL OOP_DisposeObjects
,
1857 struct class_static_data
*csd
)
1859 struct objectnode
*n
, *safe
;
1861 ForeachNodeSafe(list
, n
, safe
)
1863 Remove(( struct Node
*)n
);
1865 if (NULL
!= n
->object
&& OOP_DisposeObjects
)
1867 OOP_DisposeObject(n
->object
);
1870 FreeMem(n
, sizeof (struct objectnode
));
1875 /****************************************************************************************/
1877 static inline BOOL
cmp_pfs(HIDDT_PixelFormat
*tmppf
, HIDDT_PixelFormat
*dbpf
)
1879 if ( dbpf
->depth
== tmppf
->depth
1880 && HIDD_PF_COLMODEL(dbpf
) == HIDD_PF_COLMODEL(tmppf
))
1882 /* The pixfmts are very alike, check all attrs */
1884 HIDDT_PixelFormat
*old
;
1886 old
= (HIDDT_PixelFormat
*)tmppf
->stdpixfmt
;
1888 tmppf
->stdpixfmt
= ((HIDDT_PixelFormat
*)dbpf
)->stdpixfmt
;
1890 if (0 == memcmp(tmppf
, dbpf
, sizeof (HIDDT_PixelFormat
)))
1895 tmppf
->stdpixfmt
= old
;
1901 /****************************************************************************************/
1904 Matches the supplied pixelformat against all standard pixelformats
1905 to see if there allready exsts a pixelformat object for this pixelformat
1908 /****************************************************************************************/
1910 static OOP_Object
*find_stdpixfmt(HIDDT_PixelFormat
*tofind
,
1911 struct class_static_data
*csd
)
1913 OOP_Object
*retpf
= NULL
;
1917 for (i
= 0; i
< num_Hidd_StdPixFmt
; i
++)
1919 stdpf
= csd
->std_pixfmts
[i
];
1921 if (cmp_pfs(tofind
, (HIDDT_PixelFormat
*)stdpf
))
1932 /****************************************************************************************/
1935 Parses the tags supplied in 'tags' and puts the result into 'sync'.
1936 It also checks to see if all needed attrs are supplied.
1937 It uses 'attrcheck' for this, so you may find attrs outside
1938 of this function, and mark them as found before calling this function
1941 #define SYNC_AF(code) (1L << aoHidd_Sync_ ## code)
1942 #define SYAO(x) (aoHidd_Sync_ ## x)
1944 #define X11_SYNC_AF ( \
1945 SYNC_AF(HSyncStart) | SYNC_AF(HSyncEnd) | SYNC_AF(HTotal) \
1946 | SYNC_AF(VSyncStart) | SYNC_AF(VSyncEnd) | SYNC_AF(VTotal) )
1948 #define LINUXFB_SYNC_AF ( \
1949 SYNC_AF(LeftMargin) | SYNC_AF(RightMargin) | SYNC_AF(HSyncLength) \
1950 | SYNC_AF(UpperMargin) | SYNC_AF(LowerMargin) | SYNC_AF(VSyncLength) )
1952 #define SYNC_DISP_AF ( \
1953 SYNC_AF(HDisp) | SYNC_AF(VDisp) )
1955 /****************************************************************************************/
1957 BOOL
parse_sync_tags(struct TagItem
*tags
, struct sync_data
*data
, ULONG
ATTRCHECK(sync
),
1958 struct class_static_data
*csd
)
1960 IPTR attrs
[num_Hidd_Sync_Attrs
];
1963 if (0 != OOP_ParseAttrs(tags
, attrs
, num_Hidd_Sync_Attrs
, &ATTRCHECK(sync
), HiddSyncAttrBase
))
1965 D(bug("!!! parse_sync_tags: ERROR PARSING ATTRS !!!\n"));
1969 /* Check that we have all attrs */
1970 if (GOT_SYNC_ATTR(PixelTime
))
1972 data
->pixtime
= attrs
[SYAO(PixelTime
)];
1974 else if (GOT_SYNC_ATTR(PixelClock
))
1976 #if !AROS_BOCHS_HACK
1978 #warning Write code for non-FPU!
1979 data
->pixtime
= 0x12345678;
1981 /* Something in there makes Bochs freeze */
1982 DOUBLE pixclock
, pixtime
;
1984 /* Compute the pixtime */
1985 pixclock
=(DOUBLE
)attrs
[SYAO(PixelClock
)];
1986 pixtime
= 1 / pixclock
;
1987 pixtime
*= 1000000000000;
1988 data
->pixtime
= (ULONG
)pixtime
;
1991 data
->pixtime
= 0x12345678;
1996 D(bug("!!! MISSING PIXELTIME/CLOCK ATTR !!!\n"));
2000 if (GOT_SYNC_ATTR(Description
))
2002 strlcpy(data
->description
,
2003 (STRPTR
)attrs
[SYAO(Description
)],
2004 sizeof(data
->description
));
2007 /* Check that we have HDisp and VDisp */
2008 if (SYNC_DISP_AF
!= (SYNC_DISP_AF
& ATTRCHECK(sync
)))
2010 D(bug("!!! MISSING HDISP OR VDISP ATTR !!!\n"));
2014 data
->hdisp
= attrs
[SYAO(HDisp
)];
2015 data
->vdisp
= attrs
[SYAO(VDisp
)];
2017 /* Test that the user has not supplied both X11 style and fbdev style attrs */
2018 if ( (LINUXFB_SYNC_AF
& ATTRCHECK(sync
)) != 0 && (X11_SYNC_AF
& ATTRCHECK(sync
)) != 0 )
2020 D(bug("!!! BOTH LINUXFB-STYLE AND X11-STYLE ATTRS WERE SUPPLIED !!!\n"));
2021 D(bug("!!! YOU MAY ONLY SUPPLY ONE OF THEM !!!\n"));
2026 /* Test that we have all attrs of either the X11 style or the Linux FB style */
2027 if ((LINUXFB_SYNC_AF
& ATTRCHECK(sync
)) == LINUXFB_SYNC_AF
)
2029 /* Set the data struct */
2030 data
->left_margin
= attrs
[SYAO(LeftMargin
)];
2031 data
->right_margin
= attrs
[SYAO(RightMargin
)];
2032 data
->hsync_length
= attrs
[SYAO(HSyncLength
)];
2034 data
->upper_margin
= attrs
[SYAO(UpperMargin
)];
2035 data
->lower_margin
= attrs
[SYAO(LowerMargin
)];
2036 data
->vsync_length
= attrs
[SYAO(VSyncLength
)];
2040 else if ((X11_SYNC_AF
& ATTRCHECK(sync
)) == X11_SYNC_AF
)
2042 ULONG hsync_start
, hsync_end
, htotal
;
2043 ULONG vsync_start
, vsync_end
, vtotal
;
2045 hsync_start
= attrs
[SYAO(HSyncStart
)];
2046 hsync_end
= attrs
[SYAO(HSyncEnd
)];
2047 htotal
= attrs
[SYAO(HTotal
)];
2049 vsync_start
= attrs
[SYAO(VSyncStart
)];
2050 vsync_end
= attrs
[SYAO(VSyncEnd
)];
2051 vtotal
= attrs
[SYAO(VTotal
)];
2053 data
->left_margin
= htotal
- hsync_end
;
2054 data
->right_margin
= hsync_start
- data
->hdisp
;
2055 data
->hsync_length
= hsync_end
- hsync_start
;
2057 data
->upper_margin
= vtotal
- vsync_end
;
2058 data
->lower_margin
= vsync_start
- data
->vdisp
;
2059 data
->vsync_length
= vsync_end
- vsync_start
;
2064 D(bug("!!! UNSUFFICIENT ATTRS PASSED TO parse_sync_tags: %x !!!\n", ATTRCHECK(sync
)));
2072 /****************************************************************************************/
2075 Parses the tags supplied in 'tags' and puts the result into 'pf'.
2076 It also checks to see if all needed attrs are supplied.
2077 It uses 'attrcheck' for this, so you may find attrs outside
2078 of this function, and mark them as found before calling this function
2081 #define PFAF(x) (1L << aoHidd_PixFmt_ ## x)
2082 #define PF_COMMON_AF ( PFAF(Depth) | PFAF(BitsPerPixel) | PFAF(BytesPerPixel) \
2083 | PFAF(ColorModel) | PFAF(BitMapType) )
2085 #define PF_TRUECOLOR_AF ( PFAF(RedMask) | PFAF(GreenMask) | PFAF(BlueMask) | PFAF(AlphaMask) | \
2086 PFAF(RedShift) | PFAF(GreenShift) | PFAF(BlueShift) | PFAF(AlphaShift))
2088 #define PF_PALETTE_AF ( PFAF(CLUTMask) | PFAF(CLUTShift) | PFAF(RedMask) | PFAF(GreenMask) | \
2091 #define PFAO(x) (aoHidd_PixFmt_ ## x)
2093 /****************************************************************************************/
2095 BOOL
parse_pixfmt_tags(struct TagItem
*tags
, HIDDT_PixelFormat
*pf
,
2096 ULONG
ATTRCHECK(pixfmt
), struct class_static_data
*csd
)
2098 IPTR attrs
[num_Hidd_PixFmt_Attrs
];
2100 if (0 != OOP_ParseAttrs(tags
, attrs
, num_Hidd_PixFmt_Attrs
,
2101 &ATTRCHECK(pixfmt
), HiddPixFmtAttrBase
))
2103 D(bug("!!! parse_pixfmt_tags: ERROR PARSING TAGS THROUGH OOP_ParseAttrs !!!\n"));
2107 if (PF_COMMON_AF
!= (PF_COMMON_AF
& ATTRCHECK(pixfmt
)))
2109 D(bug("!!! parse_pixfmt_tags: Missing PixFmt attributes passed to parse_pixfmt_tags(): %x !!!\n", ATTRCHECK(pixfmt
)));
2113 /* Set the common attributes */
2114 pf
->depth
= attrs
[PFAO(Depth
)];
2115 pf
->size
= attrs
[PFAO(BitsPerPixel
)];
2116 pf
->bytes_per_pixel
= attrs
[PFAO(BytesPerPixel
)];
2118 SET_PF_COLMODEL( pf
, attrs
[PFAO(ColorModel
)]);
2119 SET_PF_BITMAPTYPE(pf
, attrs
[PFAO(BitMapType
)]);
2121 if (ATTRCHECK(pixfmt
) & PFAF(SwapPixelBytes
))
2123 SET_PF_SWAPPIXELBYTES_FLAG(pf
, attrs
[PFAO(SwapPixelBytes
)]);
2126 /* Set the colormodel specific stuff */
2127 switch (HIDD_PF_COLMODEL(pf
))
2129 case vHidd_ColorModel_TrueColor
:
2130 /* Check that we got all the truecolor describing stuff */
2131 if (PF_TRUECOLOR_AF
!= (PF_TRUECOLOR_AF
& ATTRCHECK(pixfmt
)))
2133 D(bug("!!! Unsufficient true color format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
2137 /* Set the truecolor stuff */
2138 pf
->red_mask
= attrs
[PFAO(RedMask
)];
2139 pf
->green_mask
= attrs
[PFAO(GreenMask
)];
2140 pf
->blue_mask
= attrs
[PFAO(BlueMask
)];
2141 pf
->alpha_mask
= attrs
[PFAO(AlphaMask
)];
2143 pf
->red_shift
= attrs
[PFAO(RedShift
)];
2144 pf
->green_shift
= attrs
[PFAO(GreenShift
)];
2145 pf
->blue_shift
= attrs
[PFAO(BlueShift
)];
2146 pf
->alpha_shift
= attrs
[PFAO(AlphaShift
)];
2149 case vHidd_ColorModel_Palette
:
2150 case vHidd_ColorModel_StaticPalette
:
2151 if ( PF_PALETTE_AF
!= (PF_PALETTE_AF
& ATTRCHECK(pixfmt
)))
2153 D(bug("!!! Unsufficient palette format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
2157 /* set palette stuff */
2158 pf
->clut_mask
= attrs
[PFAO(CLUTMask
)];
2159 pf
->clut_shift
= attrs
[PFAO(CLUTShift
)];
2161 pf
->red_mask
= attrs
[PFAO(RedMask
)];
2162 pf
->green_mask
= attrs
[PFAO(GreenMask
)];
2163 pf
->blue_mask
= attrs
[PFAO(BlueMask
)];
2167 } /* shift (colormodel) */
2172 /****************************************************************************************/
2175 Create an empty object and initialize it the "ugly" way. This only works with
2176 CLID_Hidd_PixFmt and CLID_Hidd_Sync classes
2179 /****************************************************************************************/
2181 static OOP_Object
*create_and_init_object(OOP_Class
*cl
, UBYTE
*data
, ULONG datasize
,
2182 struct class_static_data
*csd
)
2186 o
= OOP_NewObject(cl
, NULL
, NULL
);
2189 D(bug("!!! UNABLE TO CREATE OBJECT IN create_and_init_object() !!!\n"));
2193 memcpy(o
, data
, datasize
);
2198 /****************************************************************************************/
2200 static struct pfnode
*find_pixfmt(struct MinList
*pflist
, HIDDT_PixelFormat
*tofind
,
2201 struct class_static_data
*csd
)
2203 OOP_Object
*retpf
= NULL
;
2204 HIDDT_PixelFormat
*db_pf
;
2207 /* Go through the pixel format list to see if a similar pf allready exists */
2208 ForeachNode(pflist
, n
)
2210 db_pf
= (HIDDT_PixelFormat
*)n
->pixfmt
;
2211 if (cmp_pfs(tofind
, db_pf
))
2213 retpf
= (OOP_Object
*)db_pf
;
2224 /****************************************************************************************/
2226 /* Stubs for private methods */
2228 #ifndef AROS_CREATE_ROM
2229 # define STATIC_MID static OOP_MethodID mid
2231 # define STATIC_MID OOP_MethodID mid = 0
2234 /****************************************************************************************/
2236 OOP_Object
*HIDD_Gfx_RegisterPixFmt(OOP_Object
*o
, struct TagItem
*pixFmtTags
)
2239 struct pHidd_Gfx_RegisterPixFmt p
, *msg
= &p
;
2241 if (!mid
) mid
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_RegisterPixFmt
);
2245 p
.pixFmtTags
= pixFmtTags
;
2247 return (OOP_Object
*)OOP_DoMethod(o
, (OOP_Msg
)msg
);
2251 /****************************************************************************************/
2253 VOID
HIDD_Gfx_ReleasePixFmt(OOP_Object
*o
, OOP_Object
*pixFmt
)
2256 struct pHidd_Gfx_ReleasePixFmt p
, *msg
= &p
;
2258 if (!mid
) mid
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_ReleasePixFmt
);
2264 OOP_DoMethod(o
, (OOP_Msg
)msg
);
2268 /****************************************************************************************/