2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Graphics hidd class implementation.
9 /****************************************************************************************/
16 #include <aros/atomic.h>
17 #include <aros/debug.h>
18 #include <aros/symbolsets.h>
19 #include <cybergraphx/cgxvideo.h>
20 #include <exec/lists.h>
21 #include <oop/static_mid.h>
22 #include <graphics/displayinfo.h>
23 #include <graphics/view.h>
25 #include "graphics_intern.h"
30 #include <proto/exec.h>
31 #include <proto/utility.h>
32 #include <proto/oop.h>
33 #include <exec/libraries.h>
34 #include <exec/memory.h>
36 #include <utility/tagitem.h>
38 #include LC_LIBDEFS_FILE
40 #include <hidd/graphics.h>
42 /*****************************************************************************************
45 --background_graphics--
48 hidd.graphics.graphics
51 When working with graphics drivers this is the first object you get.
52 It allows you to create BitMap and GC (graphics context)
53 object. The class' methods must be overidden by hardware-specific
54 subclasses where documented to do so.
56 *****************************************************************************************/
58 /*****************************************************************************************
64 hidd.graphics.graphics
67 Each display driver object internally stores a database of supported display mode
68 IDs. This database is normally managed by base class, the driver does not need to
69 reimplement respective methods.
71 A display mode ID in AROS is a 32-bit integer value, the same as on AmigaOS(tm).
72 However mode ID layout introduced by Commodore does not fit well for RTG systems.
73 In order to overcome its limitations, display ID on AROS may have two forms:
75 1. A chipset mode ID. These are standard IDs defined by Commodore. You may find
76 their definitions in graphics/modeid.h.
80 An RTG mode ID is composed of three parts in the form:
84 nnnn - monitor ID. This number is maintained by system libraries. IDs are
85 assigned in the order in which drivers are loaded and display hardware is
86 found. Drivers do not have to care about this part, and should normally
87 mask it out if they for some reason look at mode ID. In order to
88 distinguish between chipset mode IDs and RTG mode IDs, order number starts
89 not from zero, reserving some space for C= chipset mode IDs (which appear
90 to have order numbers from 0x0000 to 0x000A). Currently RTG monitor IDs
91 start from 0x0010, however with time this value may change. So don't rely
92 on some particular values in RTG IDs. Use cybergraphics.library/IsCyberModeID()
93 function if you want to know for sure if the given mode ID belongs to an
96 xx - A sync object index in driver's mode database.
97 yy - A pixelformat object in driver's mode database.
99 Normally the driver does not have to care about mode ID decoding. The mode
100 database is maintained by base class. The only useful things for the driver are
101 sync and pixelformat objects, from which it's possible to get different
102 information about the mode. They can be obtained from the base class using
105 Note that the driver object by itself does not know its monitor ID. Different
106 displays are served by different objects, any of which may belong to any class.
107 So all driver methods which return mode IDs will set monitor ID to zero. All
108 methods that take mode ID as argument are expected to ignore the monitor ID part
109 and do not make any assumptions about its value.
111 *****************************************************************************************/
113 static BOOL
create_std_pixfmts(struct class_static_data
*_csd
);
114 static VOID
delete_pixfmts(struct class_static_data
*_csd
);
115 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
);
117 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
);
118 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
);
119 static OOP_Object
*create_and_init_object(OOP_Class
*cl
, UBYTE
*data
, ULONG datasize
,
120 struct class_static_data
*_csd
);
122 static struct pixfmt_data
*find_pixfmt(HIDDT_PixelFormat
*tofind
123 , struct class_static_data
*_csd
);
125 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
126 , OOP_Object
*dst_bm
, ULONG width
, ULONG height
);
128 BOOL
parse_pixfmt_tags(struct TagItem
*tags
, HIDDT_PixelFormat
*pf
, ULONG attrcheck
, struct class_static_data
*_csd
);
130 /****************************************************************************************/
132 #define COMPUTE_HIDD_MODEID(sync, pf) \
133 ( ((sync) << 8) | (pf) )
135 #define MODEID_TO_SYNCIDX(id) (((id) & 0X0000FF00) >> 8)
136 #define MODEID_TO_PFIDX(id) ( (id) & 0x000000FF)
138 /****************************************************************************************/
140 OOP_Object
*GFX__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
142 struct HIDDGraphicsData
*data
;
144 struct TagItem
*modetags
;
145 struct TagItem gctags
[] =
150 D(bug("Entering gfx.hidd::New\n"));
152 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
156 D(bug("Got object o=%x\n", o
));
158 data
= OOP_INST_DATA(cl
, o
);
160 InitSemaphore(&data
->mdb
.sema
);
161 /* data->curmode = vHidd_ModeID_Invalid; */
163 /* Get the mode tags */
164 modetags
= (struct TagItem
*)GetTagData(aHidd_Gfx_ModeTags
, 0, msg
->attrList
);
165 if (NULL
!= modetags
)
167 /* Parse it and register the gfxmodes */
168 if (register_modes(cl
, o
, modetags
))
173 D(bug("Could not register modes\n"));
176 D(bug("Could not get ModeTags\n"));
180 /* Create a gc that we can use for some rendering */
183 data
->gc
= OOP_NewObject(CSD(cl
)->gcclass
, NULL
, gctags
);
184 if (NULL
== data
->gc
)
186 D(bug("Could not get gc\n"));
194 OOP_MethodID dispose_mid
;
196 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
197 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
201 D(bug("Leaving gfx.hidd::New o=%x\n", o
));
206 /****************************************************************************************/
208 VOID
GFX__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
210 struct HIDDGraphicsData
*data
;
212 data
= OOP_INST_DATA(cl
, o
);
214 /* free the mode db stuff */
215 free_mode_db(&data
->mdb
, cl
);
217 /* Here we should unregister pixelformats registered in our New().
218 However gfx drivers aren't supposed to be removed, so it's okay
219 not to do it at all for now. */
221 if (NULL
!= data
->gc
)
222 OOP_DisposeObject(data
->gc
);
224 OOP_DoSuperMethod(cl
, o
, msg
);
227 /*****************************************************************************************
230 aoHidd_Gfx_IsWindowed
236 hidd.graphics.graphics
239 Tells if the display driver is using hosted display in host OS' window, and mouse
240 input is handled by host OS.
242 Windowed displays may send activation events to AROS. This is needed in order to
243 correctly handle display switch in a multi-display configuration (which means that
244 the user has multiple windows on host OS desktop and can freely switch between them).
247 Even in fullscreen mode drivers should still return TRUE if the host OS manages mouse
248 input (for example, X11 driver). If mouse input is not managed by the host OS
249 (for example, with Linux framebuffer driver), return FALSE.
256 aoHidd_Gfx_ActiveCallBack, aoHidd_Gfx_ActiveCallBackData
259 Base class always provides FALSE value
261 *****************************************************************************************/
263 /*****************************************************************************************
269 [ISG], HIDDT_DPMSLevel
272 hidd.graphics.graphics
275 Gets or sets current DPMS level for driver's display.
276 A value can be one of:
277 vHidd_Gfx_DPMSLevel_On,
278 vHidd_Gfx_DPMSLevel_Standby,
279 vHidd_Gfx_DPMSLevel_Suspend,
280 vHidd_Gfx_DPMSLevel_Off
282 If the driver does not support some state, it's up to the driver what to do.
283 Usually it is expected to ignore the request.
285 Getting this attribute should return real current state.
296 Base class always provides vHidd_Gfx_DPMSLevel_On value (comes from rootclass'
297 Get() which sets the value to 0).
299 *****************************************************************************************/
301 /*****************************************************************************************
307 [I..], struct TagItem *
310 hidd.graphics.graphics
313 Specify a pointer to a taglist which contains description of display modes
314 supported by the driver.
316 This attribute is usually appended in moRoot_New method of the display driver
319 This attribute is mandatory for the base class, otherwise driver object creation
322 Mode description taglist may contain the following tags:
323 - Any sync attributes - these attributes will specify values common for all sync
325 - Any pixelformat attributes - these attributes will specify values common for
326 all pixelformat modes
327 - aoHidd_Gfx_SyncTags - specifies a pointer to another separate taglist containing
328 attributes for one sync (display) mode. If this tag
329 is not supplied at all, a set of default modes will be
330 generated for the driver.
331 - aoHidd_Gfx_PixFmtTags - specifies a pointer to another separate taglist containing
332 attributes for one pixelformat. This tag must be supplied
333 at least once, otherwise driver object will fail to create.
335 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags can be specified multiple times in
336 order to associate more than one display mode with the driver. Note that common
337 values for sync and pixelformat objects need to be placed in the taglist before
338 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags. You may specify them again between
339 these tags in order to alter common values.
344 Partial example code of display driver supporting a truecolor display with three
347 // Our pixelformat (24-bit 0BGR)
348 struct TagItem pftags[] =
350 { aHidd_PixFmt_RedShift , 24 },
351 { aHidd_PixFmt_GreenShift , 16 },
352 { aHidd_PixFmt_BlueShift , 8 },
353 { aHidd_PixFmt_AlphaShift , 0 },
354 { aHidd_PixFmt_RedMask , 0x000000FF },
355 { aHidd_PixFmt_GreenMask , 0x0000FF00 },
356 { aHidd_PixFmt_BlueMask , 0x00FF0000 },
357 { aHidd_PixFmt_AlphaMask , 0x00000000 },
358 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_TrueColor },
359 { aHidd_PixFmt_Depth , 24 },
360 { aHidd_PixFmt_BytesPerPixel, 4 },
361 { aHidd_PixFmt_BitsPerPixel , 24 },
362 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Native },
363 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Chunky },
367 // 640x480 resolution
368 struct TagItem tags_800_600[] =
370 { aHidd_Sync_HDisp , 640 },
371 { aHidd_Sync_VDisp , 480 },
375 // 800x600 resolution
376 struct TagItem tags_800_600[] =
378 { aHidd_Sync_HDisp , 800 },
379 { aHidd_Sync_VDisp , 600 },
383 // 1024x768 resolution
384 struct TagItem tags_1024_768[] =
386 { aHidd_Sync_HDisp , 1024 },
387 { aHidd_Sync_VDisp , 768 },
391 // Mode description taglist itself
392 struct TagItem mode_tags[] =
394 // Our driver supports a single pixelformat
395 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
397 // Here go sync values common for all sync modes
398 { aHidd_Sync_HMin , 112 },
399 { aHidd_Sync_VMin , 112 },
400 { aHidd_Sync_HMax , 16384 },
401 { aHidd_Sync_VMax , 16384 },
402 { aHidd_Sync_Description, (IPTR)"Example: %hx%v" },
405 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
407 // Next two syncs will have HMax = 32768, as an example
408 { aHidd_Sync_HMax , 32768 },
410 // Two more resolutions
411 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
412 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
416 // This is the attribute list which is given to New method
418 struct TagItem mytags[] =
420 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
430 *****************************************************************************************/
432 /*****************************************************************************************
441 hidd.graphics.graphics
444 Gets total number of sync objects in the internal display mode database.
457 *****************************************************************************************/
459 /*****************************************************************************************
462 aoHidd_Gfx_SupportsHWCursor
468 hidd.graphics.graphics
471 Tells whether the driver supports hardware mouse pointer sprite.
473 If the driver provides TRUE value for this attribute, it is expected to implement
474 HIDD_Gfx_SetCursorPos(), HIDD_Gfx_SetCursorShape() and HIDD_Gfx_SetCursorVisible()
477 Mouse pointer counts for one hardware sprite, so if the driver implements also
478 HIDD_Gfx_ModeProperties(), it should set NumHWSprites to 1 in order to provide
479 valid information about display modes.
481 The driver must implement this attribute if it implements HIDD_Gfx_ModeProperties().
482 Otherwise it will provide false information in graphics.library/GetDisplayInfoData().
483 Base class can determine NumHWSprites based on this attribute value but not vice
487 Default implementation in the base class returns FALSE. This causes the system to
488 use software sprite emulation.
490 This attribute is obsolete and is used only by AROS graphics.library up to v41.2. In
491 new drivers consider implementing aoHidd_Gfx_HWSpriteTypes attribute.
498 aoHidd_Gfx_HWSpriteTypes, moHidd_Gfx_ModeProperties
502 *****************************************************************************************/
504 /*****************************************************************************************
507 aoHidd_Gfx_NoFrameBuffer
513 hidd.graphics.graphics
516 Tells whether the driver does not need a framebuffer.
518 A framebuffer is a special bitmap in a fixed area of video RAM. If the framebuffer
519 is used, the driver is expected to copy a new bitmap into it in HIDD_Gfx_Show()
520 and optionally copy old bitmap back.
522 A framebuffer is needed if the hardware does not have enough VRAM to store many
523 bitmaps or does not have capabilities to switch the display between various VRAM
526 An example of driver using a framebuffer is hosted SDL driver. By design SDL works
527 only with single display window, which is considered a framebuffer.
530 Provides FALSE if not implemented in the driver.
540 VGA and VESA do not use framebuffer, they use mirroring technique instead in order
541 to prevents VRAM reading which is slow.
543 *****************************************************************************************/
545 /*****************************************************************************************
548 aoHidd_Gfx_HWSpriteTypes
554 hidd.graphics.graphics
557 Return hardware sprite image types supported by the driver.
559 The returned value is a combination of the following bit flags:
560 vHidd_SpriteType_3Plus1 - color 0 is transparent, 1-3 visible
561 (Amiga(tm) chipset sprite format)
562 vHidd_SpriteType_2Plus1 - color 0 is transparent, color 1 is undefined
563 (can be whatever, for example clear or inverse),
565 vHidd_SpriteType_DirectColor - Hi- or truecolor image, or LUT image with own
566 palette, perhaps with alpha channel
569 This attribute should return 0 if the driver does not support hardware mouse sprite
570 at all. Software sprite emulation is done by graphics.library.
572 Default implementation in the base class is based on aoHidd_Gfx_SupportsHWCursor
573 value. This is done for backwards compatibility.
580 aoHidd_Gfx_SupportsHWCursor
583 Default implementation in the base class queries aoHidd_Gfx_SupportsHWCursor
584 and provides (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) in case
585 if it returns TRUE. Otherwise it returns zero. This is done for backwards
586 compatibility with old drivers.
588 *****************************************************************************************/
590 /*****************************************************************************************
593 aoHidd_Gfx_MemorySize
599 hidd.graphics.graphics
602 Query total size of video card memory in bytes.
611 aoHidd_Gfx_MemoryClock
615 *****************************************************************************************/
617 /*****************************************************************************************
620 aoHidd_Gfx_MemoryClock
626 hidd.graphics.graphics
629 Query video card's memory clock in Hz. 0 is a valid value meaning 'unknown'.
638 aoHidd_Gfx_MemorySize
642 *****************************************************************************************/
644 /*****************************************************************************************
647 aoHidd_Gfx_DriverName
653 hidd.graphics.graphics
656 Query CyberGraphX driver name. It is the same name which can be given to
657 cybergraphics.library/BestCModeIDTagList() as CYBRBIDTG_BoardName value.
660 By default base class returns class name as value of this attribute.
661 However this can (and must for some drivers listed in BestCModeIDTagList()
662 documentation) be overriden.
672 *****************************************************************************************/
674 /*****************************************************************************************
677 aoHidd_Gfx_ActiveCallBack
680 [.S.], void (*)(APTR userdata, OOP_Object *bitmap)
683 hidd.graphics.graphics
686 Set display activation interrupt handler.
688 This handler needs to be called by hosted display driver, if host OS
689 windowing system is used for the display and mouse input is handled by the
692 This way the driver can tell AROS when a display window has been activated so that
693 AROS will be able to switch current display correctly when working in a multi-display
696 The function uses C calling convention and needs to be declared as follows:
698 void ActivationHandler(APTR userdata, OOP_Object *bitmap);
700 Parameters of this function will be:
701 userdata - Whatever is specified by aoHidd_Gfx_ActiveCallBackData attribute.
702 bitmap - Currently reserved. Drivers need to set it to NULL.
704 The function can be called from within an interrupt, so usual restrictions apply
707 Set this attribute to NULL in order to disable activation handling.
710 When setting the activation callback function, be sure that you set correct
711 userdata before you actually set the callback pointer. Otherwise your callback
712 can be called with wrong data pointer.
714 Only one activation handler can be installed. Installing a new handler replaces
717 Native displays do not need to implement this attribute because there can be
718 no external activation events.
725 aoHidd_Gfx_ActiveCallBackData, aoHidd_Gfx_IsWindowed
728 This attribute needs to be implemented by the display driver. Base class contains
731 *****************************************************************************************/
733 /*****************************************************************************************
736 aoHidd_Gfx_ActiveCallBackData
742 hidd.graphics.graphics
745 Set user-defined data pointer for display activation handler.
754 aoHidd_Gfx_ActiveCallBack
757 This attribute needs to be implemented by the display driver. Base class contains
760 *****************************************************************************************/
762 VOID
GFX__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
764 struct HIDDGraphicsData
*data
;
767 data
= OOP_INST_DATA(cl
, o
);
769 if (IS_GFX_ATTR(msg
->attrID
, idx
))
773 case aoHidd_Gfx_NumSyncs
:
774 *msg
->storage
= data
->mdb
.num_syncs
;
777 case aoHidd_Gfx_IsWindowed
:
778 case aoHidd_Gfx_SupportsHWCursor
:
782 case aoHidd_Gfx_HWSpriteTypes
:
786 OOP_GetAttr(o
, aHidd_Gfx_SupportsHWCursor
, &hwc
);
787 *msg
->storage
= hwc
? (vHidd_SpriteType_3Plus1
|vHidd_SpriteType_DirectColor
) : 0;
791 case aoHidd_Gfx_DriverName
:
792 *msg
->storage
= (IPTR
)OOP_OCLASS(o
)->ClassNode
.ln_Name
;
795 default: /* Keep compiler happy */
800 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
805 /*****************************************************************************************
811 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewGC *msg);
813 OOP_Object *HIDD_Gfx_NewGC(OOP_Object *gfxHidd, struct TagItem *tagList);
816 hidd.graphics.graphics
819 Create a GC (gfx context) object that may be used for rendering
823 gfxHidd - A graphics driver object with which the GC will perform
824 the rendering operations.
825 tagList - A list of GC attributes. See hidd.graphics.gc class
826 documentation for their description.
829 gc - pointer to the newly created GC, ready for use for rendering
833 A GC object is just a data storage. You may create a subclass of GC if
834 you wish to, however there's usually no need to. Additionally, this may
835 be not future-proof (since GC subclasses can not be interchanged between
836 different drivers. Please avoid using custom GCs.
841 At the moment subclassing GCs is not supported because some parts of
842 the operating system create GC objects directly. It is unclear whether
843 subclassing GCs is actually needed.
850 *****************************************************************************************/
852 OOP_Object
*GFX__Hidd_Gfx__NewGC(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewGC
*msg
)
854 OOP_Object
*gc
= NULL
;
856 EnterFunc(bug("HIDDGfx::NewGC()\n"));
858 gc
= OOP_NewObject(NULL
, CLID_Hidd_GC
, msg
->attrList
);
860 ReturnPtr("HIDDGfx::NewGC", OOP_Object
*, gc
);
863 /*****************************************************************************************
869 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeGC *msg);
871 VOID HIDD_Gfx_DisposeGC(OOP_Object *gfxHidd, OOP_Object *gc)
874 hidd.graphics.graphics
877 Deletes a GC (Graphics Context) object previously created
880 Subclasses do not have to override this method
881 unless they allocate anything additional to a gc object in
882 their HIDD_Gfx_NewGC() implementation.
885 gfxHidd - A driver object which was used for creating a GC.
886 gc - Pointer to gc object to delete.
901 Basically just does OOP_DisposeObject(gc);
903 *****************************************************************************************/
905 VOID
GFX__Hidd_Gfx__DisposeGC(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_DisposeGC
*msg
)
907 EnterFunc(bug("HIDDGfx::DisposeGC()\n"));
909 if (NULL
!= msg
->gc
) OOP_DisposeObject(msg
->gc
);
911 ReturnVoid("HIDDGfx::DisposeGC");
914 /****************************************************************************************/
916 #define BMAO(x) aoHidd_BitMap_ ## x
917 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
919 #define BM_DIMS_AF (BMAF(Width) | BMAF(Height))
921 #define SET_TAG(tags, idx, tag, val) \
922 tags[idx].ti_Tag = tag ; tags[idx].ti_Data = (IPTR)val;
924 #define SET_BM_TAG(tags, idx, tag, val) \
925 SET_TAG(tags, idx, aHidd_BitMap_ ## tag, val)
927 #define COPY_BM_TAG(tags, idx, tag, obj) \
928 tags[idx].ti_Tag = aHidd_BitMap_ ## tag; \
929 OOP_GetAttr(obj, aHidd_BitMap_ ## tag , &tags[idx].ti_Data)
931 /*****************************************************************************************
937 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewBitMap *msg);
939 OOP_Object *HIDD_Gfx_NewBitMap(OOP_Object *gfxHidd, struct TagItem *tagList);
942 hidd.graphics.graphics
945 Create a bitmap object.
947 One graphics driver represents at least one displayable bitmap class.
948 Additionally it may represent more classes (for example some old drivers use
949 a separate class for nondisplayable bitmaps).
951 These classes are private to the driver. In order to be able to use them
952 bitmap objects are never created directly. Instead they are created using the
953 HIDD_Gfx_NewBitMap() call. An implementation of this method in the driver
954 should examine bitmap attributes supplied and make a decision if the bitmap
955 should be created using the driver's own class or one of the system classes.
957 A typical implementation should pay attention to the following bitmap attributes:
959 aHIDD_BitMap_ModeID - If this attribute is supplied, the bitmap needs to be
960 either displayable by this driver, or be a friend of a
961 displayable bitmap. A friend bitmap usually repeats the
962 internal layout of its friend so that the driver may
963 perform blitting operations quickly.
965 aHIDD_BitMap_Displayable - If this attribute is supplied, the bitmap NEEDS to be
966 displayable by this driver. Usually this means that
967 the bitmap object will contain video hardware state
968 information. This attribute will always be accompanied
969 by aHIDD_BitMap_ModeID.
971 aHIDD_BitMap_FrameBuffer - The bitmap needs to be a framebuffer bitmap. A
972 framebuffer bitmap is necessary for some kinds of
973 hardware which have a small fixed amount of video
974 RAM which can hold only one screen at a time. Setting
975 this attribute requires that a valid ModeID be also set.
977 aHIDD_BitMap_Friend - If there's no ModeID supplied, you may wish to check class
978 of friend bitmap. This can be useful if your driver uses
979 different classes for displayable and non-displayable bitmaps.
980 By default base class will pick up friend's class and use it
981 for new bitmap if nothing is specified, here you may override
984 If your driver wants to specify own class for the bitmap being created,
985 it should prepend an aHIDD_BitMap_ClassPtr attribute to the supplied taglist
986 and pass it to base class. It's not allowed to create bitmap objects directly
987 since they need some more extra information which is added by the base class!
989 This method must be implemented by your subclass. aHIDD_BitMap_ClassPtr or
990 aHIDD_BitMap_ClassID must be provided to the base class for a displayable bitmap!
993 gfxHidd - The graphics driver object that will provide the bitmap.
995 tagList - A list of bitmap attributes. See hidd.graphics.bitmap class
996 documentation for their descriptions.
999 bm - pointer to the newly created bitmap.
1008 moHidd_Gfx_DisposeBitMap
1011 The base class implementation currently does the folliwing in order to determine
1012 a class for a nondisplayable bitmap (in the listed order):
1014 1. Check aHIDD_BitMap_ClassPtr and aHIDD_BitMap_ClassID. If one of them is supplied,
1015 the class is already set by a subclass.
1016 2. Check aHIDD_BitMap_StdPixFmt. If this attribute is supplied, figure out type of
1017 the pixelformat (chunky or planar), and use one of two system's default classes.
1018 3. Check aHIDD_BitMap_Friend. If friend bitmap is supplied, obtain its class from
1019 aHIDD_BitMap_ClassPtr value of friend bitmap.
1020 4. If everything fails, bitmap creation fails too.
1022 This behavior is subject to change, but will maintain backwards compatibility.
1024 *****************************************************************************************/
1026 OOP_Object
* GFX__Hidd_Gfx__NewBitMap(OOP_Class
*cl
, OOP_Object
*o
,
1027 struct pHidd_Gfx_NewBitMap
*msg
)
1029 struct HIDDGraphicsData
*data
= OOP_INST_DATA(cl
, o
);
1031 struct TagItem bmtags
[] =
1033 {aHidd_BitMap_GfxHidd
, 0}, /* 0 */
1034 {aHidd_BitMap_PixFmt
, 0}, /* 1 */
1035 {TAG_IGNORE
, 0}, /* 2 */
1036 {TAG_IGNORE
, 0}, /* 3 */
1037 {TAG_IGNORE
, 0}, /* 4 */
1038 {TAG_IGNORE
, 0}, /* 5 */
1039 {TAG_MORE
, 0}, /* 6 */
1043 const struct TagItem
*tstate
= msg
->attrList
;
1044 struct TagItem
*tag
;
1047 STRPTR classid
= NULL
;
1048 OOP_Class
*classptr
= NULL
;
1049 BOOL displayable
= FALSE
;
1050 BOOL framebuffer
= FALSE
;
1051 HIDDT_StdPixFmt pixfmt
= vHidd_StdPixFmt_Unknown
;
1052 OOP_Object
*friend_bm
= NULL
;
1053 OOP_Object
*sync
= NULL
;
1054 OOP_Object
*pf
= NULL
;
1056 BOOL gotclass
= FALSE
;
1057 BOOL got_width
= FALSE
;
1058 BOOL got_height
= FALSE
;
1059 BOOL got_depth
= FALSE
;
1061 while ((tag
= NextTagItem(&tstate
)))
1063 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
1067 case aoHidd_BitMap_Displayable
:
1068 displayable
= tag
->ti_Data
;
1071 case aoHidd_BitMap_FrameBuffer
:
1072 framebuffer
= tag
->ti_Data
;
1075 case aoHidd_BitMap_Width
:
1079 case aoHidd_BitMap_Height
:
1083 case aoHidd_BitMap_Depth
:
1087 case aoHidd_BitMap_ModeID
:
1088 /* Make sure it is a valid mode, and retrieve sync/pixelformat data */
1089 if (!HIDD_Gfx_GetMode(o
, tag
->ti_Data
, &sync
, &pf
))
1091 D(bug("!!! Gfx::NewBitMap: USER PASSED INVALID MODEID !!!\n"));
1096 case aoHidd_BitMap_Friend
:
1097 friend_bm
= (OOP_Object
*)tag
->ti_Data
;
1100 case aoHidd_BitMap_PixFmt
:
1101 D(bug("!!! Gfx::NewBitMap: USER IS NOT ALLOWED TO PASS aHidd_BitMap_PixFmt !!!\n"));
1104 case aoHidd_BitMap_StdPixFmt
:
1105 pixfmt
= tag
->ti_Data
;
1108 case aoHidd_BitMap_ClassPtr
:
1109 classptr
= (OOP_Class
*)tag
->ti_Data
;
1113 case aoHidd_BitMap_ClassID
:
1114 classid
= (STRPTR
)tag
->ti_Data
;
1123 /* If we have a friend bitmap, we can inherit some attributes from it */
1126 COPY_BM_TAG(bmtags
, 2, Width
, friend_bm
);
1132 COPY_BM_TAG(bmtags
, 3, Height
, friend_bm
);
1138 COPY_BM_TAG(bmtags
, 4, Depth
, friend_bm
);
1142 /* FrameBuffer implies Displayable */
1145 SET_BM_TAG(bmtags
, 5, Displayable
, TRUE
);
1151 /* Displayable bitmap. Our subclass has to supply a ModeID and class. */
1154 D(bug("!!! Gfx::NewBitMap: USER HAS NOT PASSED MODEID FOR DISPLAYABLE BITMAP !!!\n"));
1160 D(bug("!!! Gfx::NewBitMap: SUBCLASS DID NOT PASS CLASS FOR DISPLAYABLE BITMAP !!!\n"));
1164 else /* if (!displayable) */
1167 * This is an offscreen bitmap and we need to guess its pixelformat.
1168 * In order to do this we need one of (in the order of preference):
1177 * We have alredy got sync for the modeid case.
1178 * Obtain missing size information from it.
1182 bmtags
[2].ti_Tag
= aHidd_BitMap_Width
;
1183 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &bmtags
[2].ti_Data
);
1188 bmtags
[3].ti_Tag
= aHidd_BitMap_Height
;
1189 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &bmtags
[3].ti_Data
);
1192 else if (pixfmt
!= vHidd_StdPixFmt_Unknown
)
1194 /* Next to look for is StdPixFmt */
1195 pf
= HIDD_Gfx_GetPixFmt(o
, pixfmt
);
1198 D(bug("!!! Gfx::NewBitMap(): USER PASSED BOGUS StdPixFmt !!!\n"));
1204 /* Last alternative is that the user passed a friend bitmap */
1206 OOP_GetAttr(friend_bm
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1208 /* Try to grab the class from friend bitmap (if not already specified).
1209 We do it because friend bitmap may be a display HIDD bitmap */
1212 /* Another weirdness is that we have to use this attribute instead of
1213 simple getting OOP_OCLASS(friend_bm). We can't get class directly
1214 from the object, because the framebuffer bitmap object may be a
1215 fakegfx.hidd object, which is even not a bitmap at all. Attempt
1216 to create a bitmap of this class causes system-wide breakage.
1217 Perhaps fakegfx HIDD should be fixed in order to handle this correctly.
1219 OOP_GetAttr(friend_bm
, aHidd_BitMap_ClassPtr
, (IPTR
*)&classptr
);
1220 D(bug("[GFX] Friend bitmap is 0x%p has ClassPtr 0x%p\n", friend_bm
, classptr
));
1228 D(bug("!!! Gfx::NewBitMap: UNSIFFICIENT ATTRS TO CREATE OFFSCREEN BITMAP !!!\n"));
1232 /* Did the subclass provide an offbitmap class for us ? */
1235 /* Have to find a suitable class ourselves from the pixelformat */
1236 HIDDT_BitMapType bmtype
;
1238 OOP_GetAttr(pf
, aHidd_PixFmt_BitMapType
, &bmtype
);
1241 case vHidd_BitMapType_Chunky
:
1242 classptr
= CSD(cl
)->chunkybmclass
;
1245 case vHidd_BitMapType_Planar
:
1246 classptr
= CSD(cl
)->planarbmclass
;
1250 D(bug("!!! Gfx::NewBitMap: UNKNOWN BITMAPTYPE %d !!!\n", bmtype
));
1253 D(bug("[GFX] Bitmap type is %u, using class 0x%p\n", bmtype
, classptr
));
1255 } /* if (!gotclass) */
1257 } /* if (!displayable) */
1259 /* Set the tags we want to pass to the selected bitmap class */
1260 bmtags
[0].ti_Data
= (IPTR
)o
;
1261 bmtags
[1].ti_Data
= (IPTR
)pf
;
1262 bmtags
[6].ti_Data
= (IPTR
)msg
->attrList
;
1264 bm
= OOP_NewObject(classptr
, classid
, bmtags
);
1268 /* Remember the framebuffer. It can be needed for default Show() implementation. */
1269 data
->framebuffer
= bm
;
1276 /*****************************************************************************************
1279 moHidd_Gfx_DisposeBitMap
1282 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeBitMap *msg);
1284 VOID HIDD_Gfx_DisposeBitMap(OOP_Object *gfxHidd, OOP_Object *bitMap);
1287 hidd.graphics.graphics
1290 Deletes a bitmap object previously created by HIDD_Gfx_NewBitMap().
1292 Subclasses do not have to override this method
1293 unless they allocate anything additional to a bitmap object in
1294 their HIDD_Gfx_NewBitMap() implementation.
1297 gfxHidd - A driver object which was used for creating a bitmap.
1298 bitMap - Pointer to a bitmap object to delete.
1310 moHidd_Gfx_NewBitMap
1313 Basically just does OOP_DisposeObject(bitMap);
1315 ******************************************************************************************/
1317 VOID
GFX__Hidd_Gfx__DisposeBitMap(OOP_Class
*cl
, OOP_Object
*o
,
1318 struct pHidd_Gfx_DisposeBitMap
*msg
)
1320 if (NULL
!= msg
->bitMap
)
1321 OOP_DisposeObject(msg
->bitMap
);
1324 /****************************************************************************************/
1326 #define SD(x) ((struct sync_data *)x)
1327 #define PF(x) ((HIDDT_PixelFormat *)x)
1329 #define XCOORD_TO_BYTEIDX(x) ( (x) >> 3)
1330 #define COORD_TO_BYTEIDX(x, y, bpr) ( ( (y) * bpr ) + XCOORD_TO_BYTEIDX(x) )
1331 #define XCOORD_TO_MASK(x) (1L << (7 - ((x) & 0x07) ))
1332 #define WIDTH_TO_BYTES(width) ( (( (width) - 1) >> 3) + 1)
1334 /****************************************************************************************/
1336 /* modebm functions pfidx is x and syncidx is y coord in the bitmap */
1338 /****************************************************************************************/
1340 static inline BOOL
alloc_mode_bm(struct mode_bm
*bm
, ULONG numsyncs
, ULONG numpfs
,
1343 bm
->bpr
= WIDTH_TO_BYTES(numpfs
);
1345 bm
->bm
= AllocVec(bm
->bpr
* numsyncs
, MEMF_CLEAR
);
1349 /* We initialize the mode bitmap to all modes valid */
1350 memset(bm
->bm
, 0xFF, bm
->bpr
* numsyncs
);
1355 /****************************************************************************************/
1357 static inline VOID
free_mode_bm(struct mode_bm
*bm
, OOP_Class
*cl
)
1364 /****************************************************************************************/
1366 static inline BOOL
is_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
)
1368 if (0 != (XCOORD_TO_MASK(pfidx
) & bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)]))
1374 /****************************************************************************************/
1376 static inline VOID
set_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
,
1380 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] |= XCOORD_TO_MASK(pfidx
);
1382 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] &= ~XCOORD_TO_MASK(pfidx
);
1387 /****************************************************************************************/
1389 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
)
1393 if (0 == numsyncs
|| 0 == numpfs
)
1396 ObtainSemaphore(&mdb
->sema
);
1397 /* free_mode_bm() needs this */
1398 mdb
->num_pixfmts
= numpfs
;
1399 mdb
->num_syncs
= numsyncs
;
1401 mdb
->syncs
= AllocMem(sizeof (OOP_Object
*) * numsyncs
, MEMF_CLEAR
);
1403 if (NULL
!= mdb
->syncs
)
1405 mdb
->pixfmts
= AllocMem(sizeof (OOP_Object
*) * numpfs
, MEMF_CLEAR
);
1407 if (NULL
!= mdb
->pixfmts
)
1409 if (alloc_mode_bm(&mdb
->orig_mode_bm
, numsyncs
, numpfs
, cl
))
1411 if (alloc_mode_bm(&mdb
->checked_mode_bm
, numsyncs
, numpfs
, cl
))
1420 free_mode_db(mdb
, cl
);
1422 ReleaseSemaphore(&mdb
->sema
);
1427 /****************************************************************************************/
1429 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
)
1433 ObtainSemaphore(&mdb
->sema
);
1435 if (NULL
!= mdb
->pixfmts
)
1438 /* Pixelformats are shared objects and never freed */
1439 FreeMem(mdb
->pixfmts
, sizeof (OOP_Object
*) * mdb
->num_pixfmts
);
1440 mdb
->pixfmts
= NULL
; mdb
->num_pixfmts
= 0;
1443 if (NULL
!= mdb
->syncs
)
1445 for (i
= 0; i
< mdb
->num_syncs
; i
++)
1447 if (NULL
!= mdb
->syncs
[i
])
1450 OOP_DisposeObject(mdb
->syncs
[i
]);
1451 mdb
->syncs
[i
] = NULL
;
1455 FreeMem(mdb
->syncs
, sizeof (OOP_Object
*) * mdb
->num_syncs
);
1456 mdb
->syncs
= NULL
; mdb
->num_syncs
= 0;
1459 if (NULL
!= mdb
->orig_mode_bm
.bm
)
1461 free_mode_bm(&mdb
->orig_mode_bm
, cl
);
1464 if (NULL
!= mdb
->checked_mode_bm
.bm
)
1466 free_mode_bm(&mdb
->checked_mode_bm
, cl
);
1469 ReleaseSemaphore(&mdb
->sema
);
1474 /****************************************************************************************/
1476 /* Initializes default tagarray. in numtags the TAG_MORE is not accounted for,
1477 so the array must be of size NUM_TAGS + 1
1480 /****************************************************************************************/
1482 static VOID
init_def_tags(struct TagItem
*tags
, ULONG numtags
)
1486 for (i
= 0; i
< numtags
; i
++)
1488 tags
[i
].ti_Tag
= TAG_IGNORE
;
1489 tags
[i
].ti_Data
= 0UL;
1492 tags
[i
].ti_Tag
= TAG_MORE
;
1493 tags
[i
].ti_Data
= 0UL;
1498 /****************************************************************************************/
1500 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
1501 struct TagItem sync_ ## name[]={ \
1502 { aHidd_Sync_PixelClock, clock*1000 }, \
1503 { aHidd_Sync_HDisp, hdisp }, \
1504 { aHidd_Sync_HSyncStart, hstart }, \
1505 { aHidd_Sync_HSyncEnd, hend }, \
1506 { aHidd_Sync_HTotal, htotal }, \
1507 { aHidd_Sync_VDisp, vdisp }, \
1508 { aHidd_Sync_VSyncStart, vstart }, \
1509 { aHidd_Sync_VSyncEnd, vend }, \
1510 { aHidd_Sync_VTotal, vtotal }, \
1511 { aHidd_Sync_Description, (IPTR)descr}, \
1514 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
)
1516 struct TagItem
*tag
, *tstate
;
1517 struct HIDDGraphicsData
*data
;
1519 MAKE_SYNC(640x480_60
, 25174,
1524 MAKE_SYNC(800x600_56
, 36000, // 36000
1525 800, 824, 896, 1024,
1529 MAKE_SYNC(1024x768_60
, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
1530 1024, 1048, 1184, 1344,
1532 "Default:1024x768");
1534 MAKE_SYNC(1152x864_60
, 80000,
1535 1152, 1216, 1328, 1456,
1537 "Default:1152x864");
1539 MAKE_SYNC(1280x1024_60
, 108880,
1540 1280, 1360, 1496, 1712,
1541 1024, 1025, 1028, 1060,
1542 "Default:1280x1024");
1544 MAKE_SYNC(1600x1200_60
, 155982,
1545 1600, 1632, 1792, 2048,
1546 1200, 1210, 1218, 1270,
1547 "Default:1600x1200");
1549 /* "new" 16:10 modes */
1551 MAKE_SYNC(1280x800_60
, 83530,
1552 1280, 1344, 1480, 1680,
1554 "Default:1280x800");
1556 MAKE_SYNC(1440x900_60
, 106470,
1557 1440, 1520, 1672, 1904,
1559 "Default:1440x900");
1561 MAKE_SYNC(1680x1050_60
, 147140,
1562 1680, 1784, 1968, 2256,
1563 1050, 1051, 1054, 1087,
1564 "Default:1680x1050");
1566 MAKE_SYNC(1920x1080_60
, 173000,
1567 1920, 2048, 2248, 2576,
1568 1080, 1083, 1088, 1120,
1569 "Default:1920x1080");
1571 MAKE_SYNC(1920x1200_60
, 154000,
1572 1920, 1968, 2000, 2080,
1573 1200, 1203, 1209, 1235,
1574 "Default:1920x1200");
1576 struct mode_db
*mdb
;
1578 HIDDT_PixelFormat pixfmt_data
;
1580 struct TagItem def_sync_tags
[num_Hidd_Sync_Attrs
+ 1];
1581 struct TagItem def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
+ 1];
1583 ULONG numpfs
= 0,numsyncs
= 0;
1584 ULONG pfidx
= 0, syncidx
= 0;
1586 struct TagItem temporary_tags
[] = {
1587 { aHidd_Gfx_SyncTags
, (IPTR
)sync_640x480_60
},
1588 { aHidd_Gfx_SyncTags
, (IPTR
)sync_800x600_56
},
1589 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1024x768_60
},
1590 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1152x864_60
},
1591 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x1024_60
},
1592 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1600x1200_60
},
1593 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x800_60
},
1594 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1440x900_60
},
1595 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1680x1050_60
},
1596 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1920x1080_60
},
1597 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1920x1200_60
},
1601 data
= OOP_INST_DATA(cl
, o
);
1603 InitSemaphore(&mdb
->sema
);
1605 memset(&pixfmt_data
, 0, sizeof (pixfmt_data
));
1607 init_def_tags(def_sync_tags
, num_Hidd_Sync_Attrs
);
1608 init_def_tags(def_pixfmt_tags
, num_Hidd_PixFmt_Attrs
);
1610 def_sync_tags
[aoHidd_Sync_GfxHidd
].ti_Tag
= aHidd_Sync_GfxHidd
;
1611 def_sync_tags
[aoHidd_Sync_GfxHidd
].ti_Data
= (IPTR
)o
;
1613 /* First we need to calculate how much memory we are to allocate by counting supplied
1614 pixel formats and syncs */
1616 for (tstate
= modetags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
));)
1620 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
1624 case aoHidd_Gfx_PixFmtTags
:
1628 case aoHidd_Gfx_SyncTags
:
1640 D(bug("!!! WE MUST AT LEAST HAVE ONE PIXFMT IN Gfx::RegisterModes() !!!\n"));
1645 D(bug("!!! NO SYNC IN Gfx::RegisterModes() !!!\n!!! USING DEFAULT MODES !!!\n"));
1646 temporary_tags
[11].ti_Tag
= TAG_MORE
;
1647 temporary_tags
[11].ti_Data
= (IPTR
)modetags
;
1648 modetags
= &temporary_tags
[0];
1652 ObtainSemaphore(&mdb
->sema
);
1654 /* Allocate memory for mode db */
1655 if (!alloc_mode_db(&data
->mdb
, numsyncs
, numpfs
, cl
))
1659 for (tstate
= modetags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
));)
1661 /* Look for Gfx, PixFmt and Sync tags */
1664 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
1668 case aoHidd_Gfx_PixFmtTags
:
1669 def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
].ti_Data
= tag
->ti_Data
;
1670 mdb
->pixfmts
[pfidx
] = GFX__Hidd_Gfx__RegisterPixFmt(cl
, o
, def_pixfmt_tags
);
1672 if (NULL
== mdb
->pixfmts
[pfidx
])
1674 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
1681 case aoHidd_Gfx_SyncTags
:
1682 def_sync_tags
[num_Hidd_Sync_Attrs
].ti_Data
= tag
->ti_Data
;
1684 mdb
->syncs
[syncidx
] = OOP_NewObject(CSD(cl
)->syncclass
, NULL
, def_sync_tags
);
1685 if (!mdb
->syncs
[syncidx
]) {
1686 D(bug("!!! UNABLE TO CREATE SYNC OBJECT IN Gfx::RegisterModes() !!!\n"));
1695 else if (IS_SYNC_ATTR(tag
->ti_Tag
, idx
))
1697 if (idx
>= num_Hidd_Sync_Attrs
)
1699 D(bug("!!! UNKNOWN SYNC ATTR IN Gfx::New(): %d !!!\n", idx
));
1703 def_sync_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
1704 def_sync_tags
[idx
].ti_Data
= tag
->ti_Data
;
1708 else if (IS_PIXFMT_ATTR(tag
->ti_Tag
, idx
))
1710 if (idx
>= num_Hidd_PixFmt_Attrs
)
1712 D(bug("!!! UNKNOWN PIXFMT ATTR IN Gfx::New(): %d !!!\n", idx
));
1716 def_pixfmt_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
1717 def_pixfmt_tags
[idx
].ti_Data
= tag
->ti_Data
;
1722 ReleaseSemaphore(&mdb
->sema
);
1728 /* mode db is freed in dispose */
1729 ReleaseSemaphore(&mdb
->sema
);
1734 /****************************************************************************************/
1738 struct mode_db
*mdb
;
1743 HIDDT_StdPixFmt
*stdpfs
;
1753 /****************************************************************************************/
1755 /* This is a recursive function that looks for valid modes */
1757 /****************************************************************************************/
1759 static HIDDT_ModeID
*querymode(struct modequery
*mq
)
1761 HIDDT_ModeID
*modeids
;
1762 register OOP_Object
*pf
;
1763 register OOP_Object
*sync
;
1764 BOOL mode_ok
= FALSE
;
1765 ULONG syncidx
, pfidx
;
1767 mq
->dims_ok
= FALSE
;
1768 mq
->stdpfs_ok
= FALSE
;
1769 mq
->check_ok
= FALSE
;
1771 /* Look at the supplied idx */
1772 if (mq
->pfidx
>= mq
->mdb
->num_pixfmts
)
1778 if (mq
->syncidx
>= mq
->mdb
->num_syncs
)
1780 /* We have reached the end of the recursion. Allocate memory and go back
1783 modeids
= AllocVec(sizeof (HIDDT_ModeID
) * (mq
->numfound
+ 1), MEMF_ANY
);
1784 /* Get the end of the array */
1785 modeids
+= mq
->numfound
;
1786 *modeids
= vHidd_ModeID_Invalid
;
1791 syncidx
= mq
->syncidx
;
1793 /* Get the pf and sync objects */
1794 pf
= mq
->mdb
->pixfmts
[syncidx
];
1795 sync
= mq
->mdb
->syncs
[pfidx
];
1798 /* Check that the mode is really usable */
1799 if (is_valid_mode(&mq
->mdb
->checked_mode_bm
, syncidx
, pfidx
))
1801 mq
->check_ok
= TRUE
;
1804 /* See if this mode matches the criterias set */
1806 if ( SD(sync
)->hdisp
>= mq
->minwidth
1807 && SD(sync
)->hdisp
<= mq
->maxwidth
1808 && SD(sync
)->vdisp
>= mq
->minheight
1809 && SD(sync
)->vdisp
<= mq
->maxheight
)
1815 if (NULL
!= mq
->stdpfs
)
1817 register HIDDT_StdPixFmt
*stdpf
= mq
->stdpfs
;
1820 if (*stdpf
== PF(pf
)->stdpixfmt
)
1822 mq
->stdpfs_ok
= TRUE
;
1829 mq
->stdpfs_ok
= TRUE
;
1835 if (mq
->dims_ok
&& mq
->stdpfs_ok
&& mq
->check_ok
)
1843 modeids
= querymode(mq
);
1845 if (NULL
== modeids
)
1850 /* The mode is OK. Add it to the list */
1852 *modeids
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
1859 /*****************************************************************************************
1862 moHidd_Gfx_QueryModeIDs
1865 HIDDT_ModeID *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryModeIDs *msg);
1867 HIDDT_ModeID *HIDD_Gfx_QueryModeIDs(OOP_Object *gfxHidd, struct TagItem *queryTags);
1870 hidd.graphics.graphics
1873 Obtain a table of all supported display mode IDs
1875 The returned address points to an array of HIDDT_ModeID containing all ModeIDs
1876 supported by this driver. The array is terminated with vHidd_ModeID_Invalid.
1879 gfxHidd - A driver object which to query.
1880 querytags - An optional taglist containing query options. Can be NULL.
1881 The following tags are supported:
1883 tHidd_GfxMode_MinWidth (ULONG) - A minimum width of modes you are
1885 tHidd_GfxMode_MaxWidth (ULONG) - A maximum width of modes you are
1887 tHidd_GfxMode_MinHeight (ULONG) - A minimum height of modes you are
1889 tHidd_GfxMode_MaxHeight (ULONG) - A maximum height of modes you are
1891 tHidd_GfxMode_PixFmts (HIDDT_StdPifXmt *) - A pointer to an array
1892 of standard pixelformat indexes. If supplied, only mode IDs whose
1893 pixelformat numbers match any of given ones will be returned.
1896 A pointer to an array of ModeIDs or NULL in case of failure
1905 moHidd_Gfx_ReleaseModeIDs, moHidd_Gfx_NextModeID
1909 *****************************************************************************************/
1911 HIDDT_ModeID
*GFX__Hidd_Gfx__QueryModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
1912 struct pHidd_Gfx_QueryModeIDs
*msg
)
1914 struct TagItem
*tag
, *tstate
;
1916 HIDDT_ModeID
*modeids
;
1917 struct HIDDGraphicsData
*data
;
1918 struct mode_db
*mdb
;
1920 struct modequery mq
=
1922 NULL
, /* mode db (set later) */
1923 0, 0xFFFFFFFF, /* minwidth, maxwidth */
1924 0, 0xFFFFFFFF, /* minheight, maxheight */
1927 0, 0, /* pfidx, syncidx */
1928 FALSE
, FALSE
, /* dims_ok, stdpfs_ok */
1929 FALSE
, /* check_ok */
1930 NULL
/* class (set later) */
1935 data
= OOP_INST_DATA(cl
, o
);
1940 for (tstate
= msg
->queryTags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
)); )
1942 switch (tag
->ti_Tag
)
1944 case tHidd_GfxMode_MinWidth
:
1945 mq
.minwidth
= (ULONG
)tag
->ti_Tag
;
1948 case tHidd_GfxMode_MaxWidth
:
1949 mq
.maxwidth
= (ULONG
)tag
->ti_Tag
;
1952 case tHidd_GfxMode_MinHeight
:
1953 mq
.minheight
= (ULONG
)tag
->ti_Tag
;
1956 case tHidd_GfxMode_MaxHeight
:
1957 mq
.maxheight
= (ULONG
)tag
->ti_Tag
;
1960 case tHidd_GfxMode_PixFmts
:
1961 mq
.stdpfs
= (HIDDT_StdPixFmt
*)tag
->ti_Data
;
1967 ObtainSemaphoreShared(&mdb
->sema
);
1969 /* Recursively check all modes */
1970 modeids
= querymode(&mq
);
1972 ReleaseSemaphore(&mdb
->sema
);
1978 /*****************************************************************************************
1981 moHidd_Gfx_ReleaseModeIDs
1984 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ReleaseModeIDs *msg);
1986 VOID HIDD_Gfx_ReleaseModeIDs(OOP_Object *gfxHidd, HIDDT_ModeID *modeIDs);
1989 hidd.graphics.graphics
1992 Free array of display mode IDs returned by HIDD_Gfx_QueryModeIDs()
1995 gfxHidd - A driver object used to obtain the array
1996 modeIDs - A pointer to an array
2008 moHidd_Gfx_QueryModeIDs
2012 *****************************************************************************************/
2014 VOID
GFX__Hidd_Gfx__ReleaseModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
2015 struct pHidd_Gfx_ReleaseModeIDs
*msg
)
2017 FreeVec(msg
->modeIDs
);
2020 /*****************************************************************************************
2023 moHidd_Gfx_NextModeID
2026 HIDDT_ModeID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NextModeID *msg);
2028 HIDDT_ModeID HIDD_Gfx_NextModeID(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2029 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2032 hidd.graphics.graphics
2035 Iterate driver's internal display mode database.
2038 gfxHidd - A driver object to query
2039 modeID - A previous mode ID or vHidd_ModeID_Invalid for start of the iteration
2040 syncPtr - A pointer to a storage where pointer to sync object will be placed
2041 pixFmtPtr - A pointer to a storage where pointer to pixelformat object will be placed
2044 Next available mode ID or vHidd_ModeID_Invalid if there are no more display modes.
2045 If the function returns vHidd_ModeID_Invalid, sync and pixelformat pointers will
2059 *****************************************************************************************/
2061 HIDDT_ModeID
GFX__Hidd_Gfx__NextModeID(OOP_Class
*cl
, OOP_Object
*o
,
2062 struct pHidd_Gfx_NextModeID
*msg
)
2064 struct HIDDGraphicsData
*data
;
2065 struct mode_db
*mdb
;
2066 ULONG syncidx
, pfidx
;
2067 HIDDT_ModeID return_id
= vHidd_ModeID_Invalid
;
2070 data
= OOP_INST_DATA(cl
, o
);
2073 ObtainSemaphoreShared(&mdb
->sema
);
2074 if (vHidd_ModeID_Invalid
== msg
->modeID
)
2081 pfidx
= MODEID_TO_PFIDX( msg
->modeID
);
2082 syncidx
= MODEID_TO_SYNCIDX( msg
->modeID
);
2084 /* Increament one from the last call */
2086 if (pfidx
>= mdb
->num_pixfmts
)
2093 /* Search for a new mode. We only accept valid modes */
2094 for (; syncidx
< mdb
->num_syncs
; syncidx
++)
2096 /* We only return valid modes */
2097 for (; pfidx
< mdb
->num_pixfmts
; pfidx
++)
2099 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
2111 return_id
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
2112 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
2113 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
2117 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
2120 ReleaseSemaphore(&mdb
->sema
);
2125 /*****************************************************************************************
2131 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMode *msg);
2133 BOOL HIDD_Gfx_GetMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2134 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2137 hidd.graphics.graphics
2140 Get sync and pixelformat objects for a particular display ModeID.
2143 gfxHidd - pointer to a driver object which this ModeID belongs to
2144 syncPtr - pointer to a storage where sync object pointer will be placed
2145 pixFmtPtr - pointer to a storage where pixelformat object pointer will be placed
2148 TRUE upon success, FALSE in case of failure (e.g. given mode does not exist in
2149 driver's internal database). If the function returns FALSE, sync and pixelformat
2150 pointers will be set to NULL.
2153 Every display mode is associated with some sync and pixelformat object. If the
2154 method returns TRUE, object pointers are guaranteed to be valid.
2161 moHidd_Gfx_NextModeID
2165 *****************************************************************************************/
2167 BOOL
GFX__Hidd_Gfx__GetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMode
*msg
)
2169 ULONG pfidx
, syncidx
;
2170 struct HIDDGraphicsData
*data
;
2171 struct mode_db
*mdb
;
2174 data
= OOP_INST_DATA(cl
, o
);
2177 pfidx
= MODEID_TO_PFIDX(msg
->modeID
);
2178 syncidx
= MODEID_TO_SYNCIDX(msg
->modeID
);
2180 ObtainSemaphoreShared(&mdb
->sema
);
2182 if (! (pfidx
>= mdb
->num_pixfmts
|| syncidx
>= mdb
->num_syncs
) )
2184 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
2187 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
2188 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
2192 ReleaseSemaphore(&mdb
->sema
);
2196 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
2202 /*****************************************************************************************
2208 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetMode *msg);
2210 BOOL HIDD_Gfx_SetMode(OOP_Object *gfxHidd, OOP_Object *sync);
2213 hidd.graphics.graphics
2216 Update display mode according to changed sync object
2219 gfxHidd - A display driver to operate on
2220 sync - A modified sync object pointer
2223 TRUE if everything went OK and FALSE in case of some error
2226 This method is used to inform the driver that some external program has changed
2227 sync data and wants to update the display if needed. It's up to the implementation to
2228 check that current display is really using this sync (frontmost screen uses this mode).
2237 Base class implementation just returns FALSE indicating that this method is
2240 *****************************************************************************************/
2242 BOOL
GFX__Hidd_Gfx__SetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetMode
*msg
)
2247 /****************************************************************************************/
2249 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
,
2250 OOP_Object
*dst_bm
, ULONG width
, ULONG height
)
2252 struct HIDDGraphicsData
*data
;
2255 OOP_Object
*src_colmap
;
2256 APTR psrc_colmap
= &src_colmap
;
2258 data
= OOP_INST_DATA(cl
, o
);
2260 /* We have to copy the colormap into the framebuffer bitmap */
2261 OOP_GetAttr(src_bm
, aHidd_BitMap_ColorMap
, (IPTR
*)psrc_colmap
);
2262 OOP_GetAttr(src_colmap
, aHidd_ColorMap_NumEntries
, &numentries
);
2264 for (i
= 0; i
< numentries
; i
++)
2268 HIDD_CM_GetColor(src_colmap
, i
, &col
);
2269 HIDD_BM_SetColors(dst_bm
, &col
, i
, 1);
2282 /*****************************************************************************************
2288 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Show *msg);
2290 OOP_Object *HIDD_Gfx_Show(OOP_Object *gfxHidd, OOP_Object *bitMap, ULONG flags);
2293 hidd.graphics.graphics
2296 Change currently displayed bitmap on the screen.
2298 The bitmap object supplied must have been created with aHidd_BitMap_Displayable
2299 attribute set to TRUE.
2301 The function's behavior differs a lot depending on whether the driver uses a
2302 framebuffer or video hardware is able to switch screens itself.
2304 If the driver uses a framebuffer bitmap, it is supposed to copy the supplied bitmap
2305 into the framebuffer and return a framebuffer pointer. It also can be asked to
2306 copy back old framebuffer contents into previous bitmap object. It is driver's
2307 job to keep track of which bitmap object was displayed last time. This is what
2308 default implementation does. Note that it is very basic, and even does not support
2309 changing display resolution. It's not recommended to rely on it in production
2310 drivers (unless your video hardware supports only one mode).
2312 If the driver does not use a framebuffer, it is supposed to reprogram the hardware
2313 here to display an appropriate region of video RAM. Do not call the base class
2314 in this case, its implementation relies on framebuffer existance and will always
2315 return NULL which indicates an error.
2317 It is valid to get NULL value in bitMap parameter. This means that there is
2318 nothing to display and the screen needs to be blanked out. It is valid for
2319 non-framebuffer-based driver to return NULL as a reply then. In all other cases
2320 NULL return value means an error.
2322 Please avoid returning errors at all. graphics.library/LoadView() has no error
2323 indication. An error during showing a bitmap would leave the display in
2324 unpredictable state.
2326 If the driver does not use a framebuffer, consider using HIDD_Gfx_ShowViewPorts().
2327 It's more straightforward, flexible and offers support for screen composition.
2330 gfxHidd - a display driver object, whose display you wish to change.
2331 bitMap - a pointer to a bitmap object which needs to be shown or NULL.
2332 flags - currently only one flag is defined:
2334 fHidd_Gfx_Show_CopyBack - Copy back the image data from framebuffer bitmap
2335 to old displayed bitmap. Used only if the driver
2336 needs a framebuffer.
2339 A pointer to a currently displayed bitmap object or NULL (read FUNCTION paragraph for
2340 detailed description)
2343 Drivers which use mirrored video data buffer do not have to update the display
2344 immediately in this method. moHidd_BitMap_UpdateRect will be sent to the returned
2345 bitmap if it's not NULL. Of course display blanking (if NULL bitmap was received)
2346 needs to be performed immediately.
2353 moHidd_Gfx_ShowViewPorts, graphics.library/LoadView()
2357 *****************************************************************************************/
2359 OOP_Object
*GFX__Hidd_Gfx__Show(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Show
*msg
)
2361 struct HIDDGraphicsData
*data
;
2368 struct TagItem gctags
[] =
2370 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
2371 { aHidd_GC_Foreground
, 0 },
2375 data
= OOP_INST_DATA(cl
, o
);
2378 /* We have to do some consistency checking */
2381 OOP_GetAttr(bm
, aHidd_BitMap_Displayable
, &displayable
);
2384 if (bm
&& !displayable
)
2385 /* We cannot show a non-displayable bitmap */
2388 if (NULL
== data
->framebuffer
)
2391 OOP_SetAttrs(data
->gc
, gctags
);
2392 if (NULL
!= data
->shownbm
)
2394 OOP_GetAttr(data
->shownbm
, aHidd_BitMap_Width
, &oldwidth
);
2395 OOP_GetAttr(data
->shownbm
, aHidd_BitMap_Height
, &oldheight
);
2396 /* Copy the framebuffer data back into the old shown bitmap */
2397 if (msg
->flags
& fHidd_Gfx_Show_CopyBack
)
2398 copy_bm_and_colmap(cl
, o
, data
->framebuffer
, data
->shownbm
, oldwidth
, oldheight
);
2402 OOP_GetAttr(bm
, aHidd_BitMap_Width
, &newwidth
);
2403 OOP_GetAttr(bm
, aHidd_BitMap_Height
, &newheight
);
2404 copy_bm_and_colmap(cl
, o
, bm
, data
->framebuffer
, newwidth
, newheight
);
2406 /* Clear remaining parts of the framebuffer (if previous bitmap was larger than new one) */
2408 if (newwidth
< oldwidth
)
2409 HIDD_BM_FillRect(data
->framebuffer
, data
->gc
, newwidth
, 0, oldwidth
- 1, oldheight
- 1);
2410 if ((newheight
< oldheight
) && newwidth
)
2411 HIDD_BM_FillRect(data
->framebuffer
, data
->gc
, 0, newheight
, newwidth
- 1, oldheight
);
2416 return data
->framebuffer
;
2419 /*****************************************************************************************
2422 moHidd_Gfx_ShowViewPorts
2425 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ShowViewPorts *msg);
2427 ULONG HIDD_Gfx_ShowViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view);
2430 hidd.graphics.graphics
2433 Show one or more bitmaps on the screen.
2435 It is completely up to the driver how to implement this function. The driver may
2436 or may not support hardware-assisted screens composition. Bitmaps are sorted
2437 in the list in descending z-order. The driver is expected to put at least frontmost
2440 It is valid to get NULL pointer as data parameter. This means that there's
2441 nothing to show and the screen should go blank.
2443 Bitmaps display offsets are stored in their aHidd_BitMap_LeftEdge and
2444 aHidd_BitMap_TopEdge attributes. This function is not expected to modify their
2445 values somehow. They are assumed to be preserved between calls unless changed
2446 explicitly by the system.
2448 If you implement this method, you don't have to implement HIDD_Gfx_Show() because
2449 it will never be called.
2451 Note that there is no more error indication - the driver is expected to be
2455 gfxHidd - a display driver object, whose display you wish to change.
2456 data - a singly linked list of bitmap objects to show
2459 TRUE if this method is supported by the driver, FALSE otherwise
2471 Default base class implementation simply returns FALSE. This causes
2472 the system to use HIDD_Gfx_Show() instead.
2474 *****************************************************************************************/
2476 ULONG
GFX__Hidd_Gfx__ShowViewPorts(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ShowViewPorts
*msg
)
2478 /* By default we don't support screen composition (and this method too) */
2482 /*****************************************************************************************
2485 moHidd_Gfx_SetCursorShape
2488 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorShape *msg);
2490 BOOL HIDD_Gfx_SetCursorShape(OOP_Object *gfxHidd, OOP_Object *shape,
2491 LONG xoffset, LONG yoffset);
2494 hidd.graphics.graphics
2497 Set mouse pointer shape.
2499 A pointer image is contained in the specified bitmap object. The bitmap object
2500 may contain a colormap if the system wants to specify own colors for the pointer.
2501 The supplied colormap will also contain alpha channel values.
2503 It is up to driver what to do if, for example, alpha channel is not supported by
2504 the hardware. Or if given bitmap type is not supported (for example truecolor
2505 bitmap on LUT-only hardware). It is expected that the driver converts bitmap
2506 data to a more appropriate form in such a case.
2508 A hotspot is given as an offset from the actual hotspot to the top-left corner
2509 of the pointer image. It is generally needed only for hosted display drivers
2510 which utilize host's support for mouse pointer.
2512 The default implementation in the base class just does nothing. A software mouse
2513 pointer is implemented in a special layer called fakegfx.hidd inside
2514 graphics.library. If a software pointer emulation is used, this method will
2518 gfxHidd - a display driver object, for whose display you wish to change the pointer
2519 shape - a pointer to a bitmap object, containing pointer bitmap
2520 xoffset - a horizontal hotspot offset
2521 yoffset - a vertical hotspot offset
2524 TRUE on success, FALSE on failure
2533 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2537 *****************************************************************************************/
2539 BOOL
GFX__Hidd_Gfx__SetCursorShape(OOP_Class
*cl
, OOP_Object
*o
,
2540 struct pHidd_Gfx_SetCursorShape
*msg
)
2542 /* We have no clue how to render the cursor */
2546 /*****************************************************************************************
2549 moHidd_Gfx_SetCursorVisible
2552 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorVisible *msg);
2554 VOID HIDD_Gfx_SetCursorVisible(OOP_Object *gfxHidd, BOOL visible);
2557 hidd.graphics.graphics
2560 Control mouse pointer visiblity.
2562 The default implementation in the base class does nothing. If a software pointer
2563 emulation is used, this method will never be called.
2566 gfxHidd - a display driver object, on whose display you wish to turn
2568 visible - TRUE to enable pointer display, FALSE to disable it
2580 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2584 *****************************************************************************************/
2586 VOID
GFX__Hidd_Gfx__SetCursorVisible(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorVisible
*msg
)
2591 /*****************************************************************************************
2594 moHidd_Gfx_SetCursorPos
2597 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorPos *msg);
2599 BOOL HIDD_Gfx_SetCursorPos(OOP_Object *gfxHidd, LONG x, LONG y);
2602 hidd.graphics.graphics
2605 Set current mouse pointer position.
2607 This is a real position on top-left image corner relative to top-left corner of
2608 the physical display. Neither logical screen origin nor hotspot are taken into
2611 The default implementation in the base class does nothing and just returns TRUE.
2612 If a software pointer emulation is used, this method will never be called.
2615 gfxHidd - a display driver object, on whose display you wish to position the pointer
2616 x - An x coordinate of the pointer (relative to the physical screen origin)
2617 y - An y coordinate of the pointer (relative to the physical screen origin)
2620 Always TRUE. Reserved for future, do not use it.
2623 This method is called by graphics.library/MoveSprite() which has no return value.
2624 However, for historical reasons, this method has a return value. Drivers should
2625 always return TRUE in order to ensure future compatibility.
2632 moHidd_Gfx_SetCursorShape, moHidd_Gfx_SetCursorVisible, graphics.library/MoveSprite()
2636 *****************************************************************************************/
2638 BOOL
GFX__Hidd_Gfx__SetCursorPos(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorPos
*msg
)
2643 /*****************************************************************************************
2649 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg);
2651 VOID HIDD_Gfx_CopyBox(OOP_Object *gfxHidd, OOP_Object *src, WORD srcX, WORD srcY,
2652 OOP_Object *dest, WORD destX, WORD destY, UWORD width, UWORD height,
2656 hidd.graphics.graphics
2659 Perform rectangle copy (blit) operation from one bitmap to another.
2661 Given bitmaps may belong to different display drivers. The driver may attempt to
2662 use hardware for acceleration (if available), and if it's impossible, pass the
2663 operation on to the base class.
2665 Always check class of the supplied bitmap before attempting to look at its
2668 A GC is used in order to specify raster operation performed between the source
2669 and destination according to its aHidd_GC_DrawMode attribute value.
2672 gfxHidd - a display driver object that you are going to use for copying
2673 src - a pointer to source bitmap object
2674 srcX - an X coordinate of the source rectangle
2675 srcY - an Y coordinate of the source rectangle
2676 dest - a pointer to destination bitmap object
2677 destX - an X coordinate of the destination rectangle
2678 destY - an Y coordinate of the destination rectangle
2679 width - width of the rectangle to copy
2680 height - height of the rectangle to copy
2681 gc - graphics context holding draw mode on the destination
2687 You must specify valid coordinates (non-negative and inside the actual bitmap
2688 area), no checks are done.
2690 It is valid to specify two overlapped areas of the same bitmap as source
2701 *****************************************************************************************/
2703 VOID
GFX__Hidd_Gfx__CopyBox(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_Gfx_CopyBox
*msg
)
2706 WORD srcX
= msg
->srcX
, destX
= msg
->destX
;
2707 WORD srcY
= msg
->srcY
, destY
= msg
->destY
;
2708 WORD startX
, endX
, deltaX
, startY
, endY
, deltaY
;
2710 HIDDT_PixelFormat
*srcpf
, *dstpf
;
2711 OOP_Object
*dest
, *src
;
2713 APTR srcPixels
= NULL
;
2714 APTR destPixels
= NULL
;
2719 /* If source/dest overlap, direction of operation is important */
2723 startX
= msg
->width
- 1; endX
= -1; deltaX
= -1;
2727 startX
= 0; endX
= msg
->width
; deltaX
= 1;
2732 startY
= msg
->height
- 1; endY
= -1; deltaY
= -1;
2736 startY
= 0; endY
= msg
->height
; deltaY
= 1;
2739 /* Get the source pixel format */
2740 srcpf
= (HIDDT_PixelFormat
*)HBM(src
)->prot
.pixfmt
;
2742 DCOPYBOX(bug("COPYBOX: obj=0x%p (%s), src=0x%p at (%d, %d), dst=0x%p at (%d, %d), size=%dx%d\n", obj
, OOP_OCLASS(obj
)->ClassNode
.ln_Name
,
2743 msg
->src
, srcX
, srcY
, msg
->dest
, destX
, destY
, msg
->width
, msg
->height
));
2744 DCOPYBOX(bug("COPYBOX: GC=0x%p, DrawMode %ld, ColMask 0x%08X\n", msg
->gc
, GC_DRMD(msg
->gc
), GC_COLMASK(msg
->gc
)));
2746 #ifdef COPYBOX_DUMP_DIMS
2748 IPTR sw
, sh
, dw
, dh
;
2750 OOP_GetAttr(obj
, aHidd_BitMap_Width
, &sw
);
2751 OOP_GetAttr(obj
, aHidd_BitMap_Height
, &sh
);
2752 OOP_GetAttr(msg
->dest
, aHidd_BitMap_Width
, &dw
);
2753 OOP_GetAttr(msg
->dest
, aHidd_BitMap_Height
, &dh
);
2755 bug("src dims: %dx%d dest dims: %dx%d\n", sw
, sh
, dw
, dh
);
2759 dstpf
= (HIDDT_PixelFormat
*)HBM(dest
)->prot
.pixfmt
;
2761 OOP_GetAttr(msg
->src
, aHidd_ChunkyBM_Buffer
, (APTR
)&srcPixels
);
2762 OOP_GetAttr(msg
->dest
, aHidd_ChunkyBM_Buffer
, (APTR
)&destPixels
);
2764 if (srcPixels
&& destPixels
)
2767 * Both bitmaps are chunky ones and they have directly accessible buffer.
2768 * We can use optimized routines to do the copy.
2770 IPTR src_bytesperline
, dest_bytesperline
;
2772 OOP_GetAttr(msg
->src
, aHidd_BitMap_BytesPerRow
, &src_bytesperline
);
2773 OOP_GetAttr(msg
->dest
, aHidd_BitMap_BytesPerRow
, &dest_bytesperline
);
2775 switch(GC_DRMD(msg
->gc
))
2777 case vHidd_GC_DrawMode_Copy
:
2778 /* At the moment we optimize only bulk copy */
2783 * The same pixelformat. Extremely great!
2785 * FIXME: Bulk copy to the same pixelformat is also handled in ConvertPixels very well
2786 * (optimized to either per-line or bulk memcpy()). But it can't handle
2787 * overlapping regions (which seems to be a requirement for CopyBox).
2788 * If this is fixed, we can even throw away HIDD_BM_CopyMemBoxXX at all, reducing
2791 switch(srcpf
->bytes_per_pixel
)
2795 * In fact all these methods are static, they ignore object pointer, and it's
2796 * needed only for OOP_DoMethod() to fetch class information.
2797 * We use destination bitmap pointer, we can also source one.
2799 HIDD_BM_CopyMemBox8(msg
->dest
,
2800 srcPixels
, msg
->srcX
, msg
->srcY
,
2801 destPixels
, msg
->destX
, msg
->destY
,
2802 msg
->width
, msg
->height
,
2803 src_bytesperline
, dest_bytesperline
);
2807 HIDD_BM_CopyMemBox16(msg
->dest
,
2808 srcPixels
, msg
->srcX
, msg
->srcY
,
2809 destPixels
, msg
->destX
, msg
->destY
,
2810 msg
->width
, msg
->height
,
2811 src_bytesperline
, dest_bytesperline
);
2815 HIDD_BM_CopyMemBox24(msg
->dest
,
2816 srcPixels
, msg
->srcX
, msg
->srcY
,
2817 destPixels
, msg
->destX
, msg
->destY
,
2818 msg
->width
, msg
->height
,
2819 src_bytesperline
, dest_bytesperline
);
2823 HIDD_BM_CopyMemBox32(msg
->dest
,
2824 srcPixels
, msg
->srcX
, msg
->srcY
,
2825 destPixels
, msg
->destX
, msg
->destY
,
2826 msg
->width
, msg
->height
,
2827 src_bytesperline
, dest_bytesperline
);
2830 } /* switch(srcpf->bytes_per_pixel) */
2831 } /* srcpf == dstpf */
2835 * Pixelformats are different. This can't be the same bitmap,
2836 * and it's safe to use ConvertPixels method (see FIXME above).
2838 srcPixels
+= (msg
->srcY
* src_bytesperline
) + (msg
->srcX
* srcpf
->bytes_per_pixel
);
2839 destPixels
+= (msg
->destY
* dest_bytesperline
) + (msg
->destX
* dstpf
->bytes_per_pixel
);
2842 * Supply NULL pixlut. In this case bitmap's own colormap will be used
2843 * for color lookup (if needed).
2845 HIDD_BM_ConvertPixels(msg
->dest
,
2846 &srcPixels
, srcpf
, src_bytesperline
,
2847 &destPixels
, dstpf
, dest_bytesperline
,
2848 msg
->width
, msg
->height
, NULL
);
2855 /* TODO: Optimize other DrawModes here */
2857 } /* switch(mode) */
2859 } /* srcPixels && destPixels */
2863 memFG
= GC_FG(msg
->gc
);
2865 /* All else have failed, copy pixel by pixel */
2866 if (HIDD_PF_COLMODEL(srcpf
) == HIDD_PF_COLMODEL(dstpf
))
2868 if (IS_TRUECOLOR(srcpf
))
2870 DCOPYBOX(bug("COPY FROM TRUECOLOR TO TRUECOLOR\n"));
2872 for(y
= startY
; y
!= endY
; y
+= deltaY
)
2876 /* if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2877 bug("[%d,%d] ", memSrcX, memDestX);
2879 for(x
= startX
; x
!= endX
; x
+= deltaX
)
2881 HIDDT_Pixel pix
= GETPIXEL(cl
, src
, srcX
+ x
, srcY
+ y
);
2883 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2891 HIDD_BM_UnmapPixel(src
, pix
, &col
);
2892 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, &col
);
2895 DRAWPIXEL(cl
, dest
, gc
, destX
+ x
, destY
+ y
);
2897 /*if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2898 bug("[%d,%d] ", srcY, destY);
2902 } /* if (IS_TRUECOLOR(srcpf)) */
2905 /* Two palette bitmaps.
2906 For this case we do NOT convert through RGB,
2907 but copy the pixel indexes directly
2909 DCOPYBOX(bug("COPY FROM PALETTE TO PALETTE\n"));
2911 /* FIXME: This might not work very well with two StaticPalette bitmaps */
2913 for(y
= startY
; y
!= endY
; y
+= deltaY
)
2915 for(x
= startX
; x
!= endX
; x
+= deltaX
)
2917 GC_FG(gc
) = HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
2919 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
2924 } /* if (IS_TRUECOLOR(srcpf)) else ... */
2926 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) */
2929 /* Two unlike bitmaps */
2930 if (IS_TRUECOLOR(srcpf
))
2932 /* FIXME: Implement this */
2933 DCOPYBOX(bug("!! DEFAULT COPYING FROM TRUECOLOR TO PALETTIZED NOT IMPLEMENTED IN BitMap::CopyBox\n"));
2935 else if (IS_TRUECOLOR(dstpf
))
2937 /* Get the colortab */
2938 HIDDT_Color
*ctab
= ((HIDDT_ColorLUT
*)HBM(src
)->colmap
)->colors
;
2940 DCOPYBOX(bug("COPY FROM PALETTE TO TRUECOLOR, DRAWMODE %d, CTAB %p\n", GC_DRMD(gc
), ctab
));
2942 for(y
= startY
; y
!= endY
; y
+= deltaY
)
2944 for(x
= startX
; x
!= endX
; x
+= deltaX
)
2946 register HIDDT_Pixel pix
;
2947 register HIDDT_Color
*col
;
2949 pix
= HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
2952 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, col
);
2953 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
2959 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) else ... */
2964 /*****************************************************************************************
2967 moHidd_Gfx_ShowImminentReset
2970 VOID OOP_DoMethod(OOP_Object *obj, OOP_Msg msg);
2973 hidd.graphics.graphics
2976 Indicate upcoming machine reset. Obsolete.
2978 Since graphics.library v41.4 this method is not used any more. Considered
2979 reserved. Do not use it in any way.
2997 *****************************************************************************************/
2999 VOID
GFX__Hidd_Gfx__ShowImminentReset(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg msg
)
3003 /****************************************************************************************/
3005 /* The following two methods are private and not virtual */
3007 OOP_Object
*GFX__Hidd_Gfx__RegisterPixFmt(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*pixFmtTags
)
3009 HIDDT_PixelFormat cmp_pf
;
3010 struct class_static_data
*data
;
3011 struct pixfmt_data
*retpf
= NULL
;
3013 memset(&cmp_pf
, 0, sizeof(cmp_pf
));
3016 if (!parse_pixfmt_tags(pixFmtTags
, &cmp_pf
, 0, CSD(cl
)))
3018 D(bug("!!! FAILED PARSING TAGS IN Gfx::RegisterPixFmt() !!!\n"));
3022 DPF(bug("Gfx::RegisterPixFmt(): Registering pixelformat:\n"));
3023 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3024 , PF(&cmp_pf
)->red_shift
3025 , PF(&cmp_pf
)->green_shift
3026 , PF(&cmp_pf
)->blue_shift
3027 , PF(&cmp_pf
)->alpha_shift
3028 , PF(&cmp_pf
)->red_mask
3029 , PF(&cmp_pf
)->green_mask
3030 , PF(&cmp_pf
)->blue_mask
3031 , PF(&cmp_pf
)->alpha_mask
3032 , PF(&cmp_pf
)->bytes_per_pixel
3034 , PF(&cmp_pf
)->depth
3035 , PF(&cmp_pf
)->stdpixfmt
));
3037 retpf
= find_pixfmt(&cmp_pf
, CSD(cl
));
3039 DPF(bug("Found matching pixelformat: 0x%p\n", retpf
));
3041 /* Increase pf refcount */
3042 AROS_ATOMIC_INC(retpf
->refcount
);
3045 /* Could not find an alike pf, Create a new pfdb node */
3046 /* Since we pass NULL as the taglist below, the PixFmt class will just create a dummy pixfmt */
3047 retpf
= OOP_NewObject(CSD(cl
)->pixfmtclass
, NULL
, NULL
);
3049 /* We have one user */
3050 retpf
->refcount
= 1;
3052 /* Initialize the pixfmt object the "ugly" way */
3053 memcpy(retpf
, &cmp_pf
, sizeof (HIDDT_PixelFormat
));
3055 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3056 , PF(&cmp_pf
)->red_shift
3057 , PF(&cmp_pf
)->green_shift
3058 , PF(&cmp_pf
)->blue_shift
3059 , PF(&cmp_pf
)->alpha_shift
3060 , PF(&cmp_pf
)->red_mask
3061 , PF(&cmp_pf
)->green_mask
3062 , PF(&cmp_pf
)->blue_mask
3063 , PF(&cmp_pf
)->alpha_mask
3064 , PF(&cmp_pf
)->bytes_per_pixel
3066 , PF(&cmp_pf
)->depth
3067 , PF(&cmp_pf
)->stdpixfmt
));
3069 ObtainSemaphore(&data
->pfsema
);
3070 AddTail((struct List
*)&data
->pflist
, (struct Node
*)&retpf
->node
);
3071 ReleaseSemaphore(&data
->pfsema
);
3075 DPF(bug("New refcount is %u\n", retpf
->refcount
));
3076 return (OOP_Object
*)retpf
;
3079 /****************************************************************************************/
3081 /* This method doesn't need object pointer, it's static. */
3083 VOID
GFX__Hidd_Gfx__ReleasePixFmt(OOP_Class
*cl
, OOP_Object
*pf
)
3085 struct class_static_data
*data
;
3086 struct pixfmt_data
*pixfmt
= (struct pixfmt_data
*)pf
;
3088 DPF(bug("release_pixfmt 0x%p\n", pixfmt
));
3092 ObtainSemaphore(&data
->pfsema
);
3094 /* If refcount is already 0, this object was never registered in the database,
3096 DPF(bug("Old reference count is %u\n", pixfmt
->refcount
));
3097 if (pixfmt
->refcount
) {
3098 if (--pixfmt
->refcount
== 0) {
3099 Remove((struct Node
*)&pixfmt
->node
);
3100 OOP_DisposeObject((OOP_Object
*)pixfmt
);
3104 ReleaseSemaphore(&data
->pfsema
);
3107 /*****************************************************************************************
3110 moHidd_Gfx_CheckMode
3113 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CheckMode *msg);
3115 BOOL HIDD_Gfx_CheckMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3116 OOP_Object *sync, OOP_Object *pixFmt);
3119 hidd.graphics.graphics
3122 Check if given display mode is supported by the driver.
3124 Normally any resolution (sync) can be used together with any pixelformat. However
3125 on some hardware there may be exceptions from this rule. In such a case this
3126 method should be implemented, and check should be performed.
3128 The information provided by this method is used in order to exclude unsupported
3129 modes from the database
3131 Default implementation in the base class just returns TRUE for all supplied values.
3133 Note that this method can not be used in order to chech that the given mode is
3134 really present in the database and it really refers to the given sync and
3135 pixelformat objects. Use HIDD_Gfx_GetMode() for mode ID validation.
3138 gfxHidd - A display driver object
3139 modeID - A display mode ID
3140 sync - A pointer to a sync object associated with this mode
3141 pixFmt - A pointer to a pixelformat object associated with this mode
3144 TRUE if this mode is supported and FALSE if it's not.
3151 Currently base class does not call this method after driver object creation.
3152 This needs to be fixed.
3159 *****************************************************************************************/
3161 BOOL
GFX__Hidd_Gfx__CheckMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CheckMode
*msg
)
3163 /* As a default we allways return TRUE, ie. the mode is OK */
3167 /*****************************************************************************************
3170 moHidd_Gfx_GetPixFmt
3173 OOP_Object *OOP_DoMethod(OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg);
3175 OOP_Object *HIDD_Gfx_GetPixFmt(OOP_Object *gfxHidd, HIDDT_StdPixFmt pixFmt);
3178 hidd.graphics.graphics
3181 Get a standard pixelformat descriptor from internal pixelformats database.
3184 gfxHidd - A display driver object
3185 pixFmt - An index of pixelformat (one of vHIDD_StdPixFmt_... values)
3188 A pointer to a pixelformat object or NULL if lookup failed
3191 Pixelformat objects are stored in a global system-wide database. They are not
3192 linked with a particular driver in any way and completely sharable between all
3202 This operation can never fail because all standard pixelformats are registered
3203 during early system initialization.
3205 *****************************************************************************************/
3207 OOP_Object
*GFX__Hidd_Gfx__GetPixFmt(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetPixFmt
*msg
)
3211 if (!IS_REAL_STDPIXFMT(msg
->stdPixFmt
))
3213 D(bug("!!! Illegal pixel format passed to Gfx::GetPixFmt(): %d\n", msg
->stdPixFmt
));
3218 fmt
= (OOP_Object
*)CSD(cl
)->std_pixfmts
[REAL_STDPIXFMT_IDX(msg
->stdPixFmt
)];
3224 /*****************************************************************************************
3230 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetSync *msg);
3232 OOP_Object *HIDD_Gfx_GetSync(OOP_Object *gfxHidd, ULONG num);
3235 hidd.graphics.graphics
3238 Get a sync object from internal display mode database by index
3241 gfxHidd - A display driver object to query
3242 num - An index of sync object starting from 0
3245 A pointer to a sync object or NULL if there's no sync with such index
3257 *****************************************************************************************/
3259 OOP_Object
*GFX__Hidd_Gfx__GetSync(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetSync
*msg
)
3261 struct HIDDGraphicsData
*data
= OOP_INST_DATA(cl
, o
);
3263 if (msg
->num
< data
->mdb
.num_syncs
)
3264 return data
->mdb
.syncs
[msg
->num
];
3266 D(bug("!!! Illegal sync index passed to Gfx::GetSync(): %d\n", msg
->num
));
3271 /*****************************************************************************************
3274 moHidd_Gfx_ModeProperties
3277 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ModeProperties *msg);
3279 ULONG HIDD_Gfx_ModeProperties(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3280 struct HIDD_ModeProperties *props, ULONG propsLen);
3283 hidd.graphics.graphics
3286 Obtain an information about the video mode.
3288 Video mode description structure may grow in future, so be careful and always check
3289 propsLen parameter value. A system may ask you for less data than you can provide.
3290 Always return an actual value. Do not just zero out fields you don't know about,
3291 this is not expected to be backwards compatible.
3294 gfxHidd - a pointer to a display driver object whose display mode you want to query
3295 modeID - a mode ID to query
3296 props - a pointer to a storage area where HIDD_ModeProperties structure will be put
3297 propsLen - length of the supplied buffer in bytes.
3300 Actual length of obtained structure
3303 Returned data must reflect only real hardware capabilities. For example, do not
3304 count emulated sprites. The system takes care about emulated features itself.
3311 aoHidd_Gfx_HWSpriteTypes, aoHidd_Gfx_SupportsHWCursor
3314 Default implementation in the base class relies on aHidd_Gfx_HWSpriteTypes attribute,
3315 not vice versa. If you override this method, do not forget to override this attribute too.
3317 *****************************************************************************************/
3319 ULONG
GFX__Hidd_Gfx__ModeProperties(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ModeProperties
*msg
)
3321 struct HIDD_ModeProperties props
= {0, 0, 0};
3322 IPTR has_hw_cursor
= 0;
3323 ULONG len
= msg
->propsLen
;
3325 D(bug("[GFXHIDD] Hidd::Gfx::ModeProperties(0x%08lX, 0x%p, %u)\n", msg
->modeID
, msg
->props
, msg
->propsLen
));
3326 OOP_GetAttr(o
, aHidd_Gfx_HWSpriteTypes
, &has_hw_cursor
);
3327 if (has_hw_cursor
) {
3328 D(bug("[GFXHIDD] Driver has hardware mouse cursor implementation\n"));
3329 props
.DisplayInfoFlags
= DIPF_IS_SPRITES
;
3330 props
.NumHWSprites
= 1;
3333 if (len
> sizeof(props
))
3334 len
= sizeof(props
);
3335 D(bug("[GFXHIDD] Copying %u bytes\n", len
));
3336 CopyMem(&props
, msg
->props
, len
);
3341 /*****************************************************************************************
3347 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3349 BOOL HIDD_Gfx_GetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3352 hidd.graphics.graphics
3355 Get current gamma table for the display.
3357 A gamma table consists of three 256-byte tables: one for red component, one for
3358 green and one for blue.
3360 A user should supply three pointers to preallocated 256-byte tables which will
3361 be filled in. Any ot these pointers may have NULL value, in this case the
3362 respective component will be ignored.
3365 gfxHidd - A display driver object
3366 Red - A pointer to a 256-byte array for red component or NULL
3367 Green - A pointer to a 256-byte array for green component or NULL
3368 Blue - A pointer to a 256-byte array for blue component or NULL
3371 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3374 This method can be used just to query if the driver supports gamma correction.
3375 Just set Red, Green and Blue to NULL for this.
3386 *****************************************************************************************/
3388 BOOL
GFX__Hidd_Gfx__GetGamma(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Gamma
*msg
)
3393 /*****************************************************************************************
3399 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3401 BOOL HIDD_Gfx_SetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3404 hidd.graphics.graphics
3407 Set current gamma table for the display.
3409 A gamma table consists of three 256-byte tables: one for red component, one for
3410 green and one for blue.
3412 A user should supply three pointers to 256-byte tables from which gamma values
3413 will be picked up. Any ot these pointers may have NULL value, in this case the
3414 respective component will be ignored.
3417 gfxHidd - A display driver object
3418 Red - A pointer to a 256-byte array for red component or NULL
3419 Green - A pointer to a 256-byte array for green component or NULL
3420 Blue - A pointer to a 256-byte array for blue component or NULL
3423 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3426 This method can be used just to query if the driver supports gamma correction.
3427 Just set Red, Green and Blue to NULL for this.
3438 *****************************************************************************************/
3440 BOOL
GFX__Hidd_Gfx__SetGamma(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Gamma
*msg
)
3445 /*****************************************************************************************
3448 moHidd_Gfx_QueryHardware3D
3451 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryHardware3D *msg);
3453 BOOL HIDD_Gfx_QueryHardware3D(OOP_Object *gfxHidd, OOP_Object *pixFmt);
3456 hidd.graphics.graphics
3459 Query if the driver supports hardware-accelerated 3D graphics for the given
3463 gfxHidd - A display driver object
3464 pixFmt - A pointer to a pixelformat descriptor object
3467 TRUE if the driver supports hardware-accelerated 3D for the given pixelformat,
3480 *****************************************************************************************/
3482 BOOL
GFX__Hidd_Gfx__QueryHardware3D(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_QueryHardware3D
*msg
)
3487 /*****************************************************************************************
3490 moHidd_Gfx_GetMaxSpriteSize
3493 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMaxSpriteSize *msg);
3495 BOOL HIDD_Gfx_GetMaxSpriteSize(OOP_Object *gfxHidd, ULONG Type, ULONG *Width, ULONG *Height);
3498 hidd.graphics.graphics
3501 Query maximum allowed size for the given sprite type.
3504 gfxHidd - A display driver object
3505 Type - Type of the sprite image (one of vHidd_SpriteType_... values)
3506 Width - A pointer to ULONG where width will be placed.
3507 Height - A pointer to ULONG where height will be placed.
3510 FALSE is the given sprite type is not supported, otherwise TRUE.
3513 Default implementation in the base class just return some small values
3514 which it hopes can be supported by every driver if the driver supports given
3515 sprite type. It is strongly suggested to reimplement this method in the display
3518 Width and Height are considered undefined if the method returns FALSE.
3528 *****************************************************************************************/
3530 BOOL
GFX__Hidd_Gfx__GetMaxSpriteSize(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMaxSpriteSize
*msg
)
3534 OOP_GetAttr(o
, aHidd_Gfx_HWSpriteTypes
, &types
);
3536 if (types
& msg
->Type
) {
3544 /*****************************************************************************************
3547 moHidd_Gfx_NewOverlay
3550 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewOverlay *msg);
3552 OOP_Object *HIDD_Gfx_NewOverlay(OOP_Object *gfxHidd, struct TagItem *tagList);
3555 hidd.graphics.graphics
3558 Create a video overlay object.
3561 gfxHidd - A graphics driver object on whose display you want to create an overlay.
3562 tagList - A list of overlay attributes. See overlay class documentation for
3566 Pointer to the newly created overlay object or NULL in case of failure.
3569 Default implementation in the base class always sets VOERR_INVSCRMODE error and
3570 returns NULL meaning that hardware overlays are not supported. There's no sense
3571 in software implementation because the software is supposed to handle software
3579 moHidd_Gfx_DisposeOverlay
3583 *****************************************************************************************/
3585 OOP_Object
*GFX__Hidd_Gfx__NewOverlay(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewOverlay
*msg
)
3587 ULONG
*err
= (ULONG
*)GetTagData(aHidd_Overlay_Error
, 0, msg
->attrList
);
3590 *err
= VOERR_INVSCRMODE
;
3595 /*****************************************************************************************
3598 moHidd_Gfx_DisposeOverlay
3601 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeOverlay *msg);
3603 VOID HIDD_Gfx_DisposeOverlay(OOP_Object *gfxHidd, OOP_Object *Overlay)
3606 hidd.graphics.graphics
3609 Deletes an overlay previously created by moHidd_Gfx_NewOverlay.
3611 Subclasses do not have to override this method
3612 unless they allocate anything additional to an overlay object in
3613 their HIDD_Gfx_NewOverlay() implementation.
3616 gfxHidd - A driver object which was used for creating a GC.
3617 Overlay - Pointer to an overlay object to delete.
3632 Basically just does OOP_DisposeObject(Overlay);
3634 *****************************************************************************************/
3636 VOID
GFX__Hidd_Gfx__DisposeOverlay(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_DisposeOverlay
*msg
)
3638 OOP_DisposeObject(msg
->Overlay
);
3641 /*****************************************************************************************
3644 moHidd_Gfx_MakeViewPort
3647 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_MakeViewPort *msg);
3649 ULONG HIDD_Gfx_MakeViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3652 hidd.graphics.graphics
3655 Performs driver-specific setup on a given ViewPort.
3658 gfxHidd - A display driver object.
3659 data - a pointer to a HIDD_ViewPortDats structure.
3662 The same code as used as return value for graphics.library/MakeVPort().
3665 When graphics.library calls this method, a complete view is not built yet.
3666 This means that data->Next pointer contains invalid data and needs to be
3669 It is valid to keep private data pointer in data->UserData accross calls.
3670 Newly created HIDD_ViewPortData is guraranteed to have NULL there.
3677 moHidd_Gfx_CleanViewPort
3680 Base class implementation just does nothing. This function is mainly intended
3681 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3683 *****************************************************************************************/
3685 ULONG
GFX__Hidd_Gfx__MakeViewPort(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_MakeViewPort
*msg
)
3687 D(bug("Gfx::MakeViewPort: object 0x%p, data 0x%p\n", o
, msg
->Data
));
3692 /*****************************************************************************************
3695 moHidd_Gfx_CleanViewPort
3698 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CleanViewPort *msg);
3700 ULONG HIDD_Gfx_CleanViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3703 hidd.graphics.graphics
3706 Performs driver-specific cleanup on a given ViewPort.
3709 gfxHidd - A display driver object.
3710 data - a pointer to a HIDD_ViewPortDats structure.
3713 The same code as used as return value for graphics.library/MakeVPort().
3716 When graphics.library calls this method, the ViewPort is already unlinked
3717 from its view, and the bitmap can already be deallocated.
3718 This means that both data->Next and data->Bitmap pointers can contain invalid
3726 moHidd_Gfx_MakeViewPort
3729 Base class implementation just does nothing. This function is mainly intended
3730 to provide support for copperlist disposal by Amiga(tm) chipset driver.
3732 *****************************************************************************************/
3734 void GFX__Hidd_Gfx__CleanViewPort(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CleanViewPort
*msg
)
3736 D(bug("Gfx::CleanViewPort: object 0x%p, data 0x%p\n", o
, msg
->Data
));
3739 /*****************************************************************************************
3742 moHidd_Gfx_PrepareViewPorts
3745 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_PrepareViewPorts *msg);
3747 ULONG HIDD_Gfx_PrepareViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view)
3750 hidd.graphics.graphics
3753 Performs driver-specific setup on a given view.
3756 gfxHidd - A display driver object.
3757 data - a pointer to a chain of HIDD_ViewPortData structures.
3758 view - A pointer to graphics.library View structure being prepared.
3761 MCOP_OK if there was no error or MCOP_NO_MEM otherwise.
3762 MCOP_NOP is not allowed as a return value of this method.
3765 graphics.library calls this method in MrgCop() after the complete view
3766 is built. data->Next pointer contains valid data.
3768 This function can be repeatedly called several times, and there is no
3769 cleanup counterpart for it. This should be taken into account in method
3779 Base class implementation just does nothing. This function is mainly intended
3780 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3782 *****************************************************************************************/
3784 ULONG
GFX__Hidd_Gfx__PrepareViewPorts(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ShowViewPorts
*msg
)
3791 /****************************************************************************************/
3793 static ULONG
ObtainAttrBases(OOP_AttrBase
*bases
, CONST_STRPTR
*interfaces
, ULONG count
)
3798 for (i
= 0; i
< count
; i
++)
3800 bases
[i
] = OOP_ObtainAttrBase(interfaces
[i
]);
3808 static void ReleaseAttrBases(OOP_AttrBase
*bases
, CONST_STRPTR
*interfaces
, ULONG count
)
3812 for (i
= 0; i
< count
; i
++)
3815 OOP_ReleaseAttrBase(interfaces
[i
]);
3819 static ULONG
GetMethodBases(OOP_MethodID
*bases
, CONST_STRPTR
*interfaces
, ULONG count
)
3824 for (i
= 0; i
< count
; i
++)
3826 bases
[i
] = OOP_GetMethodID(interfaces
[i
], 0);
3834 static CONST_STRPTR interfaces
[NUM_ATTRBASES
] =
3847 static int GFX_ClassInit(LIBBASETYPEPTR LIBBASE
)
3849 struct class_static_data
*csd
= &LIBBASE
->hdg_csd
;
3851 if (ObtainAttrBases(csd
->attrBases
, interfaces
, NUM_ATTRBASES
))
3853 ReturnInt("init_gfxhiddclass", ULONG
, FALSE
);
3856 if (GetMethodBases(csd
->methodBases
, interfaces
, NUM_METHODBASES
))
3858 ReturnInt("init_gfxhiddclass", ULONG
, FALSE
);
3861 D(bug("Creating std pixelfmts\n"));
3862 ReturnInt("init_gfxhiddclass", ULONG
, create_std_pixfmts(csd
));
3865 /****************************************************************************************/
3867 static int GFX_ClassFree(LIBBASETYPEPTR LIBBASE
)
3869 struct class_static_data
*csd
= &LIBBASE
->hdg_csd
;
3871 EnterFunc(bug("free_gfxhiddclass(csd=%p)\n", csd
));
3873 delete_pixfmts(csd
);
3874 ReleaseAttrBases(csd
->attrBases
, interfaces
, NUM_ATTRBASES
);
3876 ReturnInt("free_gfxhiddclass", BOOL
, TRUE
);
3879 /****************************************************************************************/
3881 ADD2INITLIB(GFX_ClassInit
, 0)
3882 ADD2EXPUNGELIB(GFX_ClassFree
, 0)
3884 /****************************************************************************************/
3886 /* Since the shift/mask values of a pixel format are designed for pixel
3887 access, not byte access, they are endianess dependant */
3890 #include "stdpixfmts_be.h"
3892 #include "stdpixfmts_le.h"
3895 /****************************************************************************************/
3897 static BOOL
create_std_pixfmts(struct class_static_data
*csd
)
3900 struct pixfmt_data
*pf
;
3902 memset(csd
->std_pixfmts
, 0, sizeof (OOP_Object
*) * num_Hidd_StdPixFmt
);
3904 for (i
= 0; i
< num_Hidd_StdPixFmt
; i
++)
3906 pf
= (struct pixfmt_data
*)create_and_init_object(csd
->pixfmtclass
, (UBYTE
*)&stdpfs
[i
], sizeof (stdpfs
[i
]), csd
);
3910 D(bug("FAILED TO CREATE PIXEL FORMAT %d\n", i
));
3911 delete_pixfmts(csd
);
3912 ReturnBool("create_stdpixfmts", FALSE
);
3915 csd
->std_pixfmts
[i
] = &pf
->pf
;
3916 /* We don't use semaphore protection here because we do this only during class init stage */
3918 AddTail((struct List
*)&csd
->pflist
, (struct Node
*)&pf
->node
);
3920 ReturnBool("create_stdpixfmts", TRUE
);
3923 /****************************************************************************************/
3925 static VOID
delete_pixfmts(struct class_static_data
*csd
)
3927 struct Node
*n
, *safe
;
3929 ForeachNodeSafe(&csd
->pflist
, n
, safe
)
3930 OOP_DisposeObject((OOP_Object
*)PIXFMT_OBJ(n
));
3933 /****************************************************************************************/
3935 static inline BOOL
cmp_pfs(HIDDT_PixelFormat
*tmppf
, HIDDT_PixelFormat
*dbpf
)
3937 /* Just compare everything except stdpixfmt */
3938 /* Compare flags first (because it's a fast check) */
3939 if (tmppf
->flags
!= dbpf
->flags
)
3941 /* If they match, compare the rest of things */
3942 return !memcmp(tmppf
, dbpf
, offsetof(HIDDT_PixelFormat
, stdpixfmt
));
3945 /****************************************************************************************/
3948 Parses the tags supplied in 'tags' and puts the result into 'pf'.
3949 It also checks to see if all needed attrs are supplied.
3950 It uses 'attrcheck' for this, so you may find attrs outside
3951 of this function, and mark them as found before calling this function
3954 #define PFAF(x) (1L << aoHidd_PixFmt_ ## x)
3955 #define PF_COMMON_AF ( PFAF(Depth) | PFAF(BitsPerPixel) | PFAF(BytesPerPixel) \
3956 | PFAF(ColorModel) | PFAF(BitMapType) )
3958 #define PF_TRUECOLOR_AF ( PFAF(RedMask) | PFAF(GreenMask) | PFAF(BlueMask) | PFAF(AlphaMask) | \
3959 PFAF(RedShift) | PFAF(GreenShift) | PFAF(BlueShift) | PFAF(AlphaShift))
3961 #define PF_PALETTE_AF ( PFAF(CLUTMask) | PFAF(CLUTShift) | PFAF(RedMask) | PFAF(GreenMask) | \
3964 #define PFAO(x) (aoHidd_PixFmt_ ## x)
3966 /****************************************************************************************/
3968 BOOL
parse_pixfmt_tags(struct TagItem
*tags
, HIDDT_PixelFormat
*pf
,
3969 ULONG
ATTRCHECK(pixfmt
), struct class_static_data
*csd
)
3971 IPTR attrs
[num_Hidd_PixFmt_Attrs
] = {0};
3973 if (0 != OOP_ParseAttrs(tags
, attrs
, num_Hidd_PixFmt_Attrs
,
3974 &ATTRCHECK(pixfmt
), HiddPixFmtAttrBase
))
3976 D(bug("!!! parse_pixfmt_tags: ERROR PARSING TAGS THROUGH OOP_ParseAttrs !!!\n"));
3980 if (PF_COMMON_AF
!= (PF_COMMON_AF
& ATTRCHECK(pixfmt
)))
3982 D(bug("!!! parse_pixfmt_tags: Missing PixFmt attributes passed to parse_pixfmt_tags(): %x !!!\n", ATTRCHECK(pixfmt
)));
3986 /* Set the common attributes */
3987 pf
->depth
= attrs
[PFAO(Depth
)];
3988 pf
->size
= attrs
[PFAO(BitsPerPixel
)];
3989 pf
->bytes_per_pixel
= attrs
[PFAO(BytesPerPixel
)];
3990 /* Fill in only real StdPixFmt specification. Special values (Native and Native32)
3991 are not allowed here */
3992 if (attrs
[PFAO(StdPixFmt
)] >= num_Hidd_PseudoStdPixFmt
)
3993 pf
->stdpixfmt
= attrs
[PFAO(StdPixFmt
)];
3995 SET_PF_COLMODEL( pf
, attrs
[PFAO(ColorModel
)]);
3996 SET_PF_BITMAPTYPE(pf
, attrs
[PFAO(BitMapType
)]);
3998 if (ATTRCHECK(pixfmt
) & PFAF(SwapPixelBytes
))
4000 SET_PF_SWAPPIXELBYTES_FLAG(pf
, attrs
[PFAO(SwapPixelBytes
)]);
4003 /* Set the colormodel specific stuff */
4004 switch (HIDD_PF_COLMODEL(pf
))
4006 case vHidd_ColorModel_TrueColor
:
4007 /* Check that we got all the truecolor describing stuff */
4008 if (PF_TRUECOLOR_AF
!= (PF_TRUECOLOR_AF
& ATTRCHECK(pixfmt
)))
4010 D(bug("!!! Unsufficient true color format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
4014 /* Set the truecolor stuff */
4015 pf
->red_mask
= attrs
[PFAO(RedMask
)];
4016 pf
->green_mask
= attrs
[PFAO(GreenMask
)];
4017 pf
->blue_mask
= attrs
[PFAO(BlueMask
)];
4018 pf
->alpha_mask
= attrs
[PFAO(AlphaMask
)];
4020 pf
->red_shift
= attrs
[PFAO(RedShift
)];
4021 pf
->green_shift
= attrs
[PFAO(GreenShift
)];
4022 pf
->blue_shift
= attrs
[PFAO(BlueShift
)];
4023 pf
->alpha_shift
= attrs
[PFAO(AlphaShift
)];
4026 case vHidd_ColorModel_Palette
:
4027 case vHidd_ColorModel_StaticPalette
:
4028 if ( PF_PALETTE_AF
!= (PF_PALETTE_AF
& ATTRCHECK(pixfmt
)))
4030 D(bug("!!! Unsufficient palette format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
4034 /* set palette stuff */
4035 pf
->clut_mask
= attrs
[PFAO(CLUTMask
)];
4036 pf
->clut_shift
= attrs
[PFAO(CLUTShift
)];
4038 pf
->red_mask
= attrs
[PFAO(RedMask
)];
4039 pf
->green_mask
= attrs
[PFAO(GreenMask
)];
4040 pf
->blue_mask
= attrs
[PFAO(BlueMask
)];
4044 } /* shift (colormodel) */
4049 /****************************************************************************************/
4052 Create an empty object and initialize it the "ugly" way. This only works with
4053 CLID_Hidd_PixFmt and CLID_Hidd_Sync classes
4056 /****************************************************************************************/
4058 static OOP_Object
*create_and_init_object(OOP_Class
*cl
, UBYTE
*data
, ULONG datasize
,
4059 struct class_static_data
*csd
)
4063 o
= OOP_NewObject(cl
, NULL
, NULL
);
4066 D(bug("!!! UNABLE TO CREATE OBJECT IN create_and_init_object() !!!\n"));
4070 memcpy(o
, data
, datasize
);
4075 /****************************************************************************************/
4077 static struct pixfmt_data
*find_pixfmt(HIDDT_PixelFormat
*tofind
, struct class_static_data
*csd
)
4079 struct pixfmt_data
*retpf
= NULL
;
4080 HIDDT_PixelFormat
*db_pf
;
4083 /* Go through the pixel format list to see if a similar pf allready exists */
4084 ObtainSemaphoreShared(&csd
->pfsema
);
4086 ForeachNode(&csd
->pflist
, n
)
4088 db_pf
= PIXFMT_OBJ(n
);
4089 DPF(bug("find_pixfmt(): Trying pixelformat 0x%p\n", db_pf
));
4090 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n",
4091 db_pf
->red_shift
, db_pf
->green_shift
, db_pf
->blue_shift
, db_pf
->alpha_shift
,
4092 db_pf
->red_mask
, db_pf
->green_mask
, db_pf
->blue_mask
, db_pf
->alpha_mask
,
4093 db_pf
->bytes_per_pixel
, db_pf
->size
, db_pf
->depth
, db_pf
->stdpixfmt
));
4094 if (cmp_pfs(tofind
, db_pf
))
4096 DPF(bug("Match!\n"));
4097 retpf
= (struct pixfmt_data
*)db_pf
;
4102 ReleaseSemaphore(&csd
->pfsema
);