2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Graphics hidd class implementation.
9 /****************************************************************************************/
11 #include <aros/atomic.h>
12 #include <aros/config.h>
13 #include <aros/symbolsets.h>
14 #include <cybergraphx/cgxvideo.h>
15 #include <exec/lists.h>
16 #include <oop/static_mid.h>
17 #include <graphics/displayinfo.h>
18 #include <graphics/view.h>
20 #include "graphics_intern.h"
25 #include <proto/exec.h>
26 #include <proto/utility.h>
27 #include <proto/oop.h>
28 #include <exec/libraries.h>
29 #include <exec/memory.h>
31 #include <utility/tagitem.h>
33 #include LC_LIBDEFS_FILE
39 #include <aros/debug.h>
44 #include <hidd/graphics.h>
46 /*****************************************************************************************
49 --background_graphics--
52 hidd.graphics.graphics
55 When working with graphics drivers this is the first object you get.
56 It allows you to create BitMap and GC (graphics context)
57 object. The class' methods must be overidden by hardware-specific
58 subclasses where documented to do so.
60 *****************************************************************************************/
62 /*****************************************************************************************
68 hidd.graphics.graphics
71 Each display driver object internally stores a database of supported display mode
72 IDs. This database is normally managed by base class, the driver does not need to
73 reimplement respective methods.
75 A display mode ID in AROS is a 32-bit integer value, the same as on AmigaOS(tm).
76 However mode ID layout introduced by Commodore does not fit well for RTG systems.
77 In order to overcome its limitations, display ID on AROS may have two forms:
79 1. A chipset mode ID. These are standard IDs defined by Commodore. You may find
80 their definitions in graphics/modeid.h.
84 An RTG mode ID is composed of three parts in the form:
88 nnnn - monitor ID. This number is maintained by system libraries. IDs are
89 assigned in the order in which drivers are loaded and display hardware is
90 found. Drivers do not have to care about this part, and should normally
91 mask it out if they for some reason look at mode ID. In order to
92 distinguish between chipset mode IDs and RTG mode IDs, order number starts
93 not from zero, reserving some space for C= chipset mode IDs (which appear
94 to have order numbers from 0x0000 to 0x000A). Currently RTG monitor IDs
95 start from 0x0010, however with time this value may change. So don't rely
96 on some particular values in RTG IDs. Use cybergraphics.library/IsCyberModeID()
97 function if you want to know for sure if the given mode ID belongs to an
100 xx - A sync object index in driver's mode database.
101 yy - A pixelformat object in driver's mode database.
103 Normally the driver does not have to care about mode ID decoding. The mode
104 database is maintained by base class. The only useful things for the driver are
105 sync and pixelformat objects, from which it's possible to get different
106 information about the mode. They can be obtained from the base class using
109 Note that the driver object by itself does not know its monitor ID. Different
110 displays are served by different objects, any of which may belong to any class.
111 So all driver methods which return mode IDs will set monitor ID to zero. All
112 methods that take mode ID as argument are expected to ignore the monitor ID part
113 and do not make any assumptions about its value.
115 *****************************************************************************************/
117 static BOOL
create_std_pixfmts(struct class_static_data
*_csd
);
118 static VOID
delete_pixfmts(struct class_static_data
*_csd
);
119 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
);
121 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
);
122 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
);
123 static OOP_Object
*create_and_init_object(OOP_Class
*cl
, UBYTE
*data
, ULONG datasize
,
124 struct class_static_data
*_csd
);
126 static struct pixfmt_data
*find_pixfmt(HIDDT_PixelFormat
*tofind
127 , struct class_static_data
*_csd
);
129 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
130 , OOP_Object
*dst_bm
, ULONG width
, ULONG height
);
132 BOOL
parse_pixfmt_tags(struct TagItem
*tags
, HIDDT_PixelFormat
*pf
, ULONG attrcheck
, struct class_static_data
*_csd
);
134 /****************************************************************************************/
136 #define COMPUTE_HIDD_MODEID(sync, pf) \
137 ( ((sync) << 8) | (pf) )
139 #define MODEID_TO_SYNCIDX(id) (((id) & 0X0000FF00) >> 8)
140 #define MODEID_TO_PFIDX(id) ( (id) & 0x000000FF)
142 /****************************************************************************************/
144 OOP_Object
*GFX__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
146 struct HIDDGraphicsData
*data
;
148 struct TagItem
*modetags
;
149 struct TagItem gctags
[] =
154 D(bug("Entering gfx.hidd::New\n"));
156 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
160 D(bug("Got object o=%x\n", o
));
162 data
= OOP_INST_DATA(cl
, o
);
164 InitSemaphore(&data
->mdb
.sema
);
165 /* data->curmode = vHidd_ModeID_Invalid; */
167 /* Get the mode tags */
168 modetags
= (struct TagItem
*)GetTagData(aHidd_Gfx_ModeTags
, 0, msg
->attrList
);
169 if (NULL
!= modetags
)
171 /* Parse it and register the gfxmodes */
172 if (register_modes(cl
, o
, modetags
))
177 D(bug("Could not register modes\n"));
180 D(bug("Could not get ModeTags\n"));
184 /* Create a gc that we can use for some rendering */
187 data
->gc
= OOP_NewObject(CSD(cl
)->gcclass
, NULL
, gctags
);
188 if (NULL
== data
->gc
)
190 D(bug("Could not get gc\n"));
198 OOP_MethodID dispose_mid
;
200 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
201 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
205 D(bug("Leaving gfx.hidd::New o=%x\n", o
));
210 /****************************************************************************************/
212 VOID
GFX__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
214 struct HIDDGraphicsData
*data
;
216 data
= OOP_INST_DATA(cl
, o
);
218 /* free the mode db stuff */
219 free_mode_db(&data
->mdb
, cl
);
221 /* Here we should unregister pixelformats registered in our New().
222 However gfx drivers aren't supposed to be removed, so it's okay
223 not to do it at all for now. */
225 if (NULL
!= data
->gc
)
226 OOP_DisposeObject(data
->gc
);
228 OOP_DoSuperMethod(cl
, o
, msg
);
231 /*****************************************************************************************
234 aoHidd_Gfx_IsWindowed
240 hidd.graphics.graphics
243 Tells if the display driver is using hosted display in host OS' window, and mouse
244 input is handled by host OS.
246 Windowed displays may send activation events to AROS. This is needed in order to
247 correctly handle display switch in a multi-display configuration (which means that
248 the user has multiple windows on host OS desktop and can freely switch between them).
251 Even in fullscreen mode drivers should still return TRUE if the host OS manages mouse
252 input (for example, X11 driver). If mouse input is not managed by the host OS
253 (for example, with Linux framebuffer driver), return FALSE.
260 aoHidd_Gfx_ActiveCallBack, aoHidd_Gfx_ActiveCallBackData
263 Base class always provides FALSE value
265 *****************************************************************************************/
267 /*****************************************************************************************
273 [ISG], HIDDT_DPMSLevel
276 hidd.graphics.graphics
279 Gets or sets current DPMS level for driver's display.
280 A value can be one of:
281 vHidd_Gfx_DPMSLevel_On,
282 vHidd_Gfx_DPMSLevel_Standby,
283 vHidd_Gfx_DPMSLevel_Suspend,
284 vHidd_Gfx_DPMSLevel_Off
286 If the driver does not support some state, it's up to the driver what to do.
287 Usually it is expected to ignore the request.
289 Getting this attribute should return real current state.
300 Base class always provides vHidd_Gfx_DPMSLevel_On value (comes from rootclass'
301 Get() which sets the value to 0).
303 *****************************************************************************************/
305 /*****************************************************************************************
311 [I..], struct TagItem *
314 hidd.graphics.graphics
317 Specify a pointer to a taglist which contains description of display modes
318 supported by the driver.
320 This attribute is usually appended in moRoot_New method of the display driver
323 This attribute is mandatory for the base class, otherwise driver object creation
326 Mode description taglist may contain the following tags:
327 - Any sync attributes - these attributes will specify values common for all sync
329 - Any pixelformat attributes - these attributes will specify values common for
330 all pixelformat modes
331 - aoHidd_Gfx_SyncTags - specifies a pointer to another separate taglist containing
332 attributes for one sync (display) mode. If this tag
333 is not supplied at all, a set of default modes will be
334 generated for the driver.
335 - aoHidd_Gfx_PixFmtTags - specifies a pointer to another separate taglist containing
336 attributes for one pixelformat. This tag must be supplied
337 at least once, otherwise driver object will fail to create.
339 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags can be specified multiple times in
340 order to associate more than one display mode with the driver. Note that common
341 values for sync and pixelformat objects need to be placed in the taglist before
342 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags. You may specify them again between
343 these tags in order to alter common values.
348 Partial example code of display driver supporting a truecolor display with three
351 // Our pixelformat (24-bit 0BGR)
352 struct TagItem pftags[] =
354 { aHidd_PixFmt_RedShift , 24 },
355 { aHidd_PixFmt_GreenShift , 16 },
356 { aHidd_PixFmt_BlueShift , 8 },
357 { aHidd_PixFmt_AlphaShift , 0 },
358 { aHidd_PixFmt_RedMask , 0x000000FF },
359 { aHidd_PixFmt_GreenMask , 0x0000FF00 },
360 { aHidd_PixFmt_BlueMask , 0x00FF0000 },
361 { aHidd_PixFmt_AlphaMask , 0x00000000 },
362 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_TrueColor },
363 { aHidd_PixFmt_Depth , 24 },
364 { aHidd_PixFmt_BytesPerPixel, 4 },
365 { aHidd_PixFmt_BitsPerPixel , 24 },
366 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Native },
367 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Chunky },
371 // 640x480 resolution
372 struct TagItem tags_800_600[] =
374 { aHidd_Sync_HDisp , 640 },
375 { aHidd_Sync_VDisp , 480 },
379 // 800x600 resolution
380 struct TagItem tags_800_600[] =
382 { aHidd_Sync_HDisp , 800 },
383 { aHidd_Sync_VDisp , 600 },
387 // 1024x768 resolution
388 struct TagItem tags_1024_768[] =
390 { aHidd_Sync_HDisp , 1024 },
391 { aHidd_Sync_VDisp , 768 },
395 // Mode description taglist itself
396 struct TagItem mode_tags[] =
398 // Our driver supports a single pixelformat
399 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
401 // Here go sync values common for all sync modes
402 { aHidd_Sync_HMin , 112 },
403 { aHidd_Sync_VMin , 112 },
404 { aHidd_Sync_HMax , 16384 },
405 { aHidd_Sync_VMax , 16384 },
406 { aHidd_Sync_Description, (IPTR)"Example: %hx%v" },
409 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
411 // Next two syncs will have HMax = 32768, as an example
412 { aHidd_Sync_HMax , 32768 },
414 // Two more resolutions
415 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
416 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
420 // This is the attribute list which is given to New method
422 struct TagItem mytags[] =
424 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
434 *****************************************************************************************/
436 /*****************************************************************************************
445 hidd.graphics.graphics
448 Gets total number of sync objects in the internal display mode database.
461 *****************************************************************************************/
463 /*****************************************************************************************
466 aoHidd_Gfx_SupportsHWCursor
472 hidd.graphics.graphics
475 Tells whether the driver supports hardware mouse pointer sprite.
477 If the driver provides TRUE value for this attribute, it is expected to implement
478 HIDD_Gfx_SetCursorPos(), HIDD_Gfx_SetCursorShape() and HIDD_Gfx_SetCursorVisible()
481 Mouse pointer counts for one hardware sprite, so if the driver implements also
482 HIDD_Gfx_ModeProperties(), it should set NumHWSprites to 1 in order to provide
483 valid information about display modes.
485 The driver must implement this attribute if it implements HIDD_Gfx_ModeProperties().
486 Otherwise it will provide false information in graphics.library/GetDisplayInfoData().
487 Base class can determine NumHWSprites based on this attribute value but not vice
491 Default implementation in the base class returns FALSE. This causes the system to
492 use software sprite emulation.
494 This attribute is obsolete and is used only by AROS graphics.library up to v41.2. In
495 new drivers consider implementing aoHidd_Gfx_HWSpriteTypes attribute.
502 aoHidd_Gfx_HWSpriteTypes, moHidd_Gfx_ModeProperties
506 *****************************************************************************************/
508 /*****************************************************************************************
511 aoHidd_Gfx_NoFrameBuffer
517 hidd.graphics.graphics
520 Tells whether the driver does not need a framebuffer.
522 A framebuffer is a special bitmap in a fixed area of video RAM. If the framebuffer
523 is used, the driver is expected to copy a new bitmap into it in HIDD_Gfx_Show()
524 and optionally copy old bitmap back.
526 A framebuffer is needed if the hardware does not have enough VRAM to store many
527 bitmaps or does not have capabilities to switch the display between various VRAM
530 An example of driver using a framebuffer is hosted SDL driver. By design SDL works
531 only with single display window, which is considered a framebuffer.
534 Provides FALSE if not implemented in the driver.
544 VGA and VESA do not use framebuffer, they use mirroring technique instead in order
545 to prevents VRAM reading which is slow.
547 *****************************************************************************************/
549 /*****************************************************************************************
552 aoHidd_Gfx_HWSpriteTypes
558 hidd.graphics.graphics
561 Return hardware sprite image types supported by the driver.
563 The returned value is a combination of the following bit flags:
564 vHidd_SpriteType_3Plus1 - color 0 is transparent, 1-3 visible
565 (Amiga(tm) chipset sprite format)
566 vHidd_SpriteType_2Plus1 - color 0 is transparent, color 1 is undefined
567 (can be whatever, for example clear or inverse),
569 vHidd_SpriteType_DirectColor - Hi- or truecolor image, or LUT image with own
570 palette, perhaps with alpha channel
573 This attribute should return 0 if the driver does not support hardware mouse sprite
574 at all. Software sprite emulation is done by graphics.library.
576 Default implementation in the base class is based on aoHidd_Gfx_SupportsHWCursor
577 value. This is done for backwards compatibility.
584 aoHidd_Gfx_SupportsHWCursor
587 Default implementation in the base class queries aoHidd_Gfx_SupportsHWCursor
588 and provides (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) in case
589 if it returns TRUE. Otherwise it returns zero. This is done for backwards
590 compatibility with old drivers.
592 *****************************************************************************************/
594 /*****************************************************************************************
597 aoHidd_Gfx_MemorySize
603 hidd.graphics.graphics
606 Query total size of video card memory in bytes.
615 aoHidd_Gfx_MemoryClock
619 *****************************************************************************************/
621 /*****************************************************************************************
624 aoHidd_Gfx_MemoryClock
630 hidd.graphics.graphics
633 Query video card's memory clock in Hz. 0 is a valid value meaning 'unknown'.
642 aoHidd_Gfx_MemorySize
646 *****************************************************************************************/
648 /*****************************************************************************************
651 aoHidd_Gfx_DriverName
657 hidd.graphics.graphics
660 Query CyberGraphX driver name. It is the same name which can be given to
661 cybergraphics.library/BestCModeIDTagList() as CYBRBIDTG_BoardName value.
664 By default base class returns class name as value of this attribute.
665 However this can (and must for some drivers listed in BestCModeIDTagList()
666 documentation) be overriden.
676 *****************************************************************************************/
678 /*****************************************************************************************
681 aoHidd_Gfx_ActiveCallBack
684 [.S.], void (*)(APTR userdata, OOP_Object *bitmap)
687 hidd.graphics.graphics
690 Set display activation interrupt handler.
692 This handler needs to be called by hosted display driver, if host OS
693 windowing system is used for the display and mouse input is handled by the
696 This way the driver can tell AROS when a display window has been activated so that
697 AROS will be able to switch current display correctly when working in a multi-display
700 The function uses C calling convention and needs to be declared as follows:
702 void ActivationHandler(APTR userdata, OOP_Object *bitmap);
704 Parameters of this function will be:
705 userdata - Whatever is specified by aoHidd_Gfx_ActiveCallBackData attribute.
706 bitmap - Currently reserved. Drivers need to set it to NULL.
708 The function can be called from within an interrupt, so usual restrictions apply
711 Set this attribute to NULL in order to disable activation handling.
714 When setting the activation callback function, be sure that you set correct
715 userdata before you actually set the callback pointer. Otherwise your callback
716 can be called with wrong data pointer.
718 Only one activation handler can be installed. Installing a new handler replaces
721 Native displays do not need to implement this attribute because there can be
722 no external activation events.
729 aoHidd_Gfx_ActiveCallBackData, aoHidd_Gfx_IsWindowed
732 This attribute needs to be implemented by the display driver. Base class contains
735 *****************************************************************************************/
737 /*****************************************************************************************
740 aoHidd_Gfx_ActiveCallBackData
746 hidd.graphics.graphics
749 Set user-defined data pointer for display activation handler.
758 aoHidd_Gfx_ActiveCallBack
761 This attribute needs to be implemented by the display driver. Base class contains
764 *****************************************************************************************/
766 VOID
GFX__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
768 struct HIDDGraphicsData
*data
;
771 data
= OOP_INST_DATA(cl
, o
);
773 if (IS_GFX_ATTR(msg
->attrID
, idx
))
777 case aoHidd_Gfx_NumSyncs
:
778 *msg
->storage
= data
->mdb
.num_syncs
;
781 case aoHidd_Gfx_IsWindowed
:
782 case aoHidd_Gfx_SupportsHWCursor
:
786 case aoHidd_Gfx_HWSpriteTypes
:
790 OOP_GetAttr(o
, aHidd_Gfx_SupportsHWCursor
, &hwc
);
791 *msg
->storage
= hwc
? (vHidd_SpriteType_3Plus1
|vHidd_SpriteType_DirectColor
) : 0;
795 case aoHidd_Gfx_DriverName
:
796 *msg
->storage
= (IPTR
)OOP_OCLASS(o
)->ClassNode
.ln_Name
;
799 default: /* Keep compiler happy */
804 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
809 /*****************************************************************************************
815 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewGC *msg);
817 OOP_Object *HIDD_Gfx_NewGC(OOP_Object *gfxHidd, struct TagItem *tagList);
820 hidd.graphics.graphics
823 Create a GC (gfx context) object that may be used for rendering
827 gfxHidd - A graphics driver object with which the GC will perform
828 the rendering operations.
829 tagList - A list of GC attributes. See hidd.graphics.gc class
830 documentation for their description.
833 gc - pointer to the newly created GC, ready for use for rendering
837 A GC object is just a data storage. You may create a subclass of GC if
838 you wish to, however there's usually no need to. Additionally, this may
839 be not future-proof (since GC subclasses can not be interchanged between
840 different drivers. Please avoid using custom GCs.
845 At the moment subclassing GCs is not supported because some parts of
846 the operating system create GC objects directly. It is unclear whether
847 subclassing GCs is actually needed.
854 *****************************************************************************************/
856 OOP_Object
*GFX__Hidd_Gfx__NewGC(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewGC
*msg
)
858 OOP_Object
*gc
= NULL
;
860 EnterFunc(bug("HIDDGfx::NewGC()\n"));
862 gc
= OOP_NewObject(NULL
, CLID_Hidd_GC
, msg
->attrList
);
864 ReturnPtr("HIDDGfx::NewGC", OOP_Object
*, gc
);
867 /*****************************************************************************************
873 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeGC *msg);
875 VOID HIDD_Gfx_DisposeGC(OOP_Object *gfxHidd, OOP_Object *gc)
878 hidd.graphics.graphics
881 Deletes a GC (Graphics Context) object previously created
884 Subclasses do not have to override this method
885 unless they allocate anything additional to a gc object in
886 their HIDD_Gfx_NewGC() implementation.
889 gfxHidd - A driver object which was used for creating a GC.
890 gc - Pointer to gc object to delete.
905 Basically just does OOP_DisposeObject(gc);
907 *****************************************************************************************/
909 VOID
GFX__Hidd_Gfx__DisposeGC(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_DisposeGC
*msg
)
911 EnterFunc(bug("HIDDGfx::DisposeGC()\n"));
913 if (NULL
!= msg
->gc
) OOP_DisposeObject(msg
->gc
);
915 ReturnVoid("HIDDGfx::DisposeGC");
918 /****************************************************************************************/
920 #define BMAO(x) aoHidd_BitMap_ ## x
921 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
923 #define BM_DIMS_AF (BMAF(Width) | BMAF(Height))
925 #define SET_TAG(tags, idx, tag, val) \
926 tags[idx].ti_Tag = tag ; tags[idx].ti_Data = (IPTR)val;
928 #define SET_BM_TAG(tags, idx, tag, val) \
929 SET_TAG(tags, idx, aHidd_BitMap_ ## tag, val)
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 TagItem bmtags
[8];
1031 IPTR attrs
[num_Total_BitMap_Attrs
];
1032 STRPTR classid
= NULL
;
1033 OOP_Class
*classptr
= NULL
;
1034 BOOL displayable
= FALSE
; /* Default attr value */
1035 BOOL framebuffer
= FALSE
;
1036 OOP_Object
*pf
= NULL
, *sync
;
1037 HIDDT_ModeID modeid
= 0;
1040 struct HIDDGraphicsData
*data
;
1042 DECLARE_ATTRCHECK(bitmap
);
1044 BOOL gotclass
= FALSE
;
1046 data
= OOP_INST_DATA(cl
, o
);
1048 if (0 != OOP_ParseAttrs(msg
->attrList
, attrs
, num_Total_BitMap_Attrs
,
1049 &ATTRCHECK(bitmap
), HiddBitMapAttrBase
))
1051 D(bug("!!! FAILED TO PARSE ATTRS IN Gfx::NewBitMap !!!\n"));
1055 if (GOT_BM_ATTR(PixFmt
))
1057 D(bug("!!! Gfx::NewBitMap: USER IS NOT ALLOWED TO PASS aHidd_BitMap_PixFmt !!!\n"));
1061 /* Get class supplied by superclass */
1062 if (GOT_BM_ATTR(ClassPtr
))
1064 classptr
= (OOP_Class
*)attrs
[BMAO(ClassPtr
)];
1069 if (GOT_BM_ATTR(ClassID
))
1071 classid
= (STRPTR
)attrs
[BMAO(ClassID
)];
1076 if (GOT_BM_ATTR(Displayable
))
1077 displayable
= (BOOL
)attrs
[BMAO(Displayable
)];
1079 if (GOT_BM_ATTR(FrameBuffer
))
1081 framebuffer
= (BOOL
)attrs
[BMAO(FrameBuffer
)];
1082 if (framebuffer
) displayable
= TRUE
;
1085 if (GOT_BM_ATTR(ModeID
))
1087 modeid
= attrs
[BMAO(ModeID
)];
1089 /* Check that it is a valid mode */
1090 if (!HIDD_Gfx_GetMode(o
, modeid
, &sync
, &pf
))
1092 D(bug("!!! Gfx::NewBitMap: USER PASSED INVALID MODEID !!!\n"));
1095 if (GOT_BM_ATTR(Depth
))
1096 depth
= attrs
[BMAO(Depth
)];
1098 /* First argument is gfxhidd */
1099 SET_BM_TAG(bmtags
, 0, GfxHidd
, o
);
1100 SET_BM_TAG(bmtags
, 1, Displayable
, displayable
);
1103 if (displayable
|| framebuffer
)
1105 /* The user has to supply a modeid */
1106 if (!GOT_BM_ATTR(ModeID
))
1108 D(bug("!!! Gfx::NewBitMap: USER HAS NOT PASSED MODEID FOR DISPLAYABLE BITMAP !!!\n"));
1114 D(bug("!!! Gfx::NewBitMap: SUBCLASS DID NOT PASS CLASS FOR DISPLAYABLE BITMAP !!!\n"));
1118 SET_BM_TAG(bmtags
, 2, ModeID
, modeid
);
1119 SET_BM_TAG(bmtags
, 3, PixFmt
, pf
);
1123 SET_BM_TAG(bmtags
, 4, FrameBuffer
, TRUE
);
1127 SET_TAG(bmtags
, 4, TAG_IGNORE
, 0UL);
1130 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
1131 SET_BM_TAG(bmtags
, 5, Depth
, depth
);
1132 SET_TAG(bmtags
, 6, TAG_MORE
, msg
->attrList
);
1136 { /* if (displayable) */
1139 /* To get a pixfmt for an offscreen bitmap we either need
1140 (ModeID || ( (Width && Height) && StdPixFmt) || ( (Width && Height) && Friend))
1143 if (GOT_BM_ATTR(ModeID
))
1145 /* We have allredy gotten pixelformat and sync for the modeid case */
1146 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &width
);
1147 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &height
);
1151 /* Next to look for is StdPixFmt */
1153 /* Check that we have width && height */
1154 if (BM_DIMS_AF
!= (BM_DIMS_AF
& ATTRCHECK(bitmap
)))
1156 D(bug("!!! Gfx::NewBitMap() MISSING WIDTH/HEIGHT TAGS !!!\n"));
1160 width
= attrs
[BMAO(Width
)];
1161 height
= attrs
[BMAO(Height
)];
1163 if (GOT_BM_ATTR(StdPixFmt
))
1165 pf
= HIDD_Gfx_GetPixFmt(o
, (HIDDT_StdPixFmt
)attrs
[BMAO(StdPixFmt
)]);
1168 D(bug("!!! Gfx::NewBitMap(): USER PASSED BOGUS StdPixFmt !!!\n"));
1174 /* Last alternative is that the user passed a friend bitmap */
1175 if (GOT_BM_ATTR(Friend
))
1177 OOP_Object
*friend_bm
= (OOP_Object
*)attrs
[BMAO(Friend
)];
1178 OOP_GetAttr(friend_bm
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1179 /* Try to grab the class from friend bitmap (if not already specified).
1180 We do it because friend bitmap may be a display HIDD bitmap */
1182 /* Another weirdness is that we have to use this attribute instead of
1183 simple getting OOP_OCLASS(friend_bm). We can't get class directly
1184 from the object, because the framebuffer bitmap object may be a
1185 fakegfx.hidd object, which is even not a bitmap at all. Attempt
1186 to create a bitmap of this class causes system-wide breakage.
1187 Perhaps fakegfx HIDD should be fixed in order to handle this correctly.
1189 OOP_GetAttr(friend_bm
, aHidd_BitMap_ClassPtr
, (IPTR
*)&classptr
);
1190 D(bug("[GFX] Friend bitmap is 0x%p has ClassPtr 0x%p\n", friend_bm
, classptr
));
1197 D(bug("!!! Gfx::NewBitMap: UNSIFFICIENT ATTRS TO CREATE OFFSCREEN BITMAP !!!\n"));
1203 /* Did the subclass provide an offbitmap class for us ? */
1206 /* Have to find a suitable class ourselves */
1207 HIDDT_BitMapType bmtype
;
1209 OOP_GetAttr(pf
, aHidd_PixFmt_BitMapType
, &bmtype
);
1212 case vHidd_BitMapType_Chunky
:
1213 classptr
= CSD(cl
)->chunkybmclass
;
1216 case vHidd_BitMapType_Planar
:
1217 classptr
= CSD(cl
)->planarbmclass
;
1221 D(bug("!!! Gfx::NewBitMap: UNKNOWN BITMAPTYPE %d !!!\n", bmtype
));
1225 D(bug("[GFX] Bitmap type is %u, using class 0x%p\n", bmtype
, classptr
));
1227 } /* if (!gotclass) */
1230 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
1232 /* Set the tags we want to pass to the selected bitmap class */
1233 SET_BM_TAG(bmtags
, 2, Width
, width
);
1234 SET_BM_TAG(bmtags
, 3, Height
, height
);
1235 SET_BM_TAG(bmtags
, 4, Depth
, depth
);
1236 SET_BM_TAG(bmtags
, 5, PixFmt
, pf
);
1238 if (GOT_BM_ATTR(Friend
))
1240 SET_BM_TAG(bmtags
, 6, Friend
, attrs
[BMAO(Friend
)]);
1244 SET_TAG(bmtags
, 6, TAG_IGNORE
, 0UL);
1246 SET_TAG(bmtags
, 7, TAG_MORE
, msg
->attrList
);
1248 } /* if (!displayable) */
1251 bm
= OOP_NewObject(classptr
, classid
, bmtags
);
1254 data
->framebuffer
= bm
;
1260 /*****************************************************************************************
1263 moHidd_Gfx_DisposeBitMap
1266 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeBitMap *msg);
1268 VOID HIDD_Gfx_DisposeBitMap(OOP_Object *gfxHidd, OOP_Object *bitMap);
1271 hidd.graphics.graphics
1274 Deletes a bitmap object previously created by HIDD_Gfx_NewBitMap().
1276 Subclasses do not have to override this method
1277 unless they allocate anything additional to a bitmap object in
1278 their HIDD_Gfx_NewBitMap() implementation.
1281 gfxHidd - A driver object which was used for creating a bitmap.
1282 bitMap - Pointer to a bitmap object to delete.
1294 moHidd_Gfx_NewBitMap
1297 Basically just does OOP_DisposeObject(bitMap);
1299 ******************************************************************************************/
1301 VOID
GFX__Hidd_Gfx__DisposeBitMap(OOP_Class
*cl
, OOP_Object
*o
,
1302 struct pHidd_Gfx_DisposeBitMap
*msg
)
1304 if (NULL
!= msg
->bitMap
)
1305 OOP_DisposeObject(msg
->bitMap
);
1308 /****************************************************************************************/
1310 #define SD(x) ((struct sync_data *)x)
1311 #define PF(x) ((HIDDT_PixelFormat *)x)
1313 #define XCOORD_TO_BYTEIDX(x) ( (x) >> 3)
1314 #define COORD_TO_BYTEIDX(x, y, bpr) ( ( (y) * bpr ) + XCOORD_TO_BYTEIDX(x) )
1315 #define XCOORD_TO_MASK(x) (1L << (7 - ((x) & 0x07) ))
1316 #define WIDTH_TO_BYTES(width) ( (( (width) - 1) >> 3) + 1)
1318 /****************************************************************************************/
1320 /* modebm functions pfidx is x and syncidx is y coord in the bitmap */
1322 /****************************************************************************************/
1324 static inline BOOL
alloc_mode_bm(struct mode_bm
*bm
, ULONG numsyncs
, ULONG numpfs
,
1327 bm
->bpr
= WIDTH_TO_BYTES(numpfs
);
1329 bm
->bm
= AllocVec(bm
->bpr
* numsyncs
, MEMF_CLEAR
);
1333 /* We initialize the mode bitmap to all modes valid */
1334 memset(bm
->bm
, 0xFF, bm
->bpr
* numsyncs
);
1339 /****************************************************************************************/
1341 static inline VOID
free_mode_bm(struct mode_bm
*bm
, OOP_Class
*cl
)
1348 /****************************************************************************************/
1350 static inline BOOL
is_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
)
1352 if (0 != (XCOORD_TO_MASK(pfidx
) & bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)]))
1358 /****************************************************************************************/
1360 static inline VOID
set_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
,
1364 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] |= XCOORD_TO_MASK(pfidx
);
1366 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] &= ~XCOORD_TO_MASK(pfidx
);
1371 /****************************************************************************************/
1373 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
)
1377 if (0 == numsyncs
|| 0 == numpfs
)
1380 ObtainSemaphore(&mdb
->sema
);
1381 /* free_mode_bm() needs this */
1382 mdb
->num_pixfmts
= numpfs
;
1383 mdb
->num_syncs
= numsyncs
;
1385 mdb
->syncs
= AllocMem(sizeof (OOP_Object
*) * numsyncs
, MEMF_CLEAR
);
1387 if (NULL
!= mdb
->syncs
)
1389 mdb
->pixfmts
= AllocMem(sizeof (OOP_Object
*) * numpfs
, MEMF_CLEAR
);
1391 if (NULL
!= mdb
->pixfmts
)
1393 if (alloc_mode_bm(&mdb
->orig_mode_bm
, numsyncs
, numpfs
, cl
))
1395 if (alloc_mode_bm(&mdb
->checked_mode_bm
, numsyncs
, numpfs
, cl
))
1404 free_mode_db(mdb
, cl
);
1406 ReleaseSemaphore(&mdb
->sema
);
1411 /****************************************************************************************/
1413 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
)
1417 ObtainSemaphore(&mdb
->sema
);
1419 if (NULL
!= mdb
->pixfmts
)
1422 /* Pixelformats are shared objects and never freed */
1423 FreeMem(mdb
->pixfmts
, sizeof (OOP_Object
*) * mdb
->num_pixfmts
);
1424 mdb
->pixfmts
= NULL
; mdb
->num_pixfmts
= 0;
1427 if (NULL
!= mdb
->syncs
)
1429 for (i
= 0; i
< mdb
->num_syncs
; i
++)
1431 if (NULL
!= mdb
->syncs
[i
])
1434 OOP_DisposeObject(mdb
->syncs
[i
]);
1435 mdb
->syncs
[i
] = NULL
;
1439 FreeMem(mdb
->syncs
, sizeof (OOP_Object
*) * mdb
->num_syncs
);
1440 mdb
->syncs
= NULL
; mdb
->num_syncs
= 0;
1443 if (NULL
!= mdb
->orig_mode_bm
.bm
)
1445 free_mode_bm(&mdb
->orig_mode_bm
, cl
);
1448 if (NULL
!= mdb
->checked_mode_bm
.bm
)
1450 free_mode_bm(&mdb
->checked_mode_bm
, cl
);
1453 ReleaseSemaphore(&mdb
->sema
);
1458 /****************************************************************************************/
1460 /* Initializes default tagarray. in numtags the TAG_MORE is not accounted for,
1461 so the array must be of size NUM_TAGS + 1
1464 /****************************************************************************************/
1466 static VOID
init_def_tags(struct TagItem
*tags
, ULONG numtags
)
1470 for (i
= 0; i
< numtags
; i
++)
1472 tags
[i
].ti_Tag
= TAG_IGNORE
;
1473 tags
[i
].ti_Data
= 0UL;
1476 tags
[i
].ti_Tag
= TAG_MORE
;
1477 tags
[i
].ti_Data
= 0UL;
1482 /****************************************************************************************/
1484 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
1485 struct TagItem sync_ ## name[]={ \
1486 { aHidd_Sync_PixelClock, clock*1000 }, \
1487 { aHidd_Sync_HDisp, hdisp }, \
1488 { aHidd_Sync_HSyncStart, hstart }, \
1489 { aHidd_Sync_HSyncEnd, hend }, \
1490 { aHidd_Sync_HTotal, htotal }, \
1491 { aHidd_Sync_VDisp, vdisp }, \
1492 { aHidd_Sync_VSyncStart, vstart }, \
1493 { aHidd_Sync_VSyncEnd, vend }, \
1494 { aHidd_Sync_VTotal, vtotal }, \
1495 { aHidd_Sync_Description, (IPTR)descr}, \
1498 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
)
1500 struct TagItem
*tag
, *tstate
;
1501 struct HIDDGraphicsData
*data
;
1503 MAKE_SYNC(640x480_60
, 25174,
1508 MAKE_SYNC(800x600_56
, 36000, // 36000
1509 800, 824, 896, 1024,
1513 MAKE_SYNC(1024x768_60
, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
1514 1024, 1048, 1184, 1344,
1516 "Default:1024x768");
1518 MAKE_SYNC(1152x864_60
, 80000,
1519 1152, 1216, 1328, 1456,
1521 "Default:1152x864");
1523 MAKE_SYNC(1280x1024_60
, 108880,
1524 1280, 1360, 1496, 1712,
1525 1024, 1025, 1028, 1060,
1526 "Default:1280x1024");
1528 MAKE_SYNC(1600x1200_60
, 155982,
1529 1600, 1632, 1792, 2048,
1530 1200, 1210, 1218, 1270,
1531 "Default:1600x1200");
1533 /* "new" 16:10 modes */
1535 MAKE_SYNC(1280x800_60
, 83530,
1536 1280, 1344, 1480, 1680,
1538 "Default:1280x800");
1540 MAKE_SYNC(1440x900_60
, 106470,
1541 1440, 1520, 1672, 1904,
1543 "Default:1440x900");
1545 MAKE_SYNC(1680x1050_60
, 147140,
1546 1680, 1784, 1968, 2256,
1547 1050, 1051, 1054, 1087,
1548 "Default:1680x1050");
1550 MAKE_SYNC(1920x1080_60
, 173000,
1551 1920, 2048, 2248, 2576,
1552 1080, 1083, 1088, 1120,
1553 "Default:1920x1080");
1555 MAKE_SYNC(1920x1200_60
, 154000,
1556 1920, 1968, 2000, 2080,
1557 1200, 1203, 1209, 1235,
1558 "Default:1920x1200");
1560 struct mode_db
*mdb
;
1562 HIDDT_PixelFormat pixfmt_data
;
1564 struct TagItem def_sync_tags
[num_Hidd_Sync_Attrs
+ 1];
1565 struct TagItem def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
+ 1];
1567 ULONG numpfs
= 0,numsyncs
= 0;
1568 ULONG pfidx
= 0, syncidx
= 0;
1570 struct TagItem temporary_tags
[] = {
1571 { aHidd_Gfx_SyncTags
, (IPTR
)sync_640x480_60
},
1572 { aHidd_Gfx_SyncTags
, (IPTR
)sync_800x600_56
},
1573 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1024x768_60
},
1574 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1152x864_60
},
1575 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x1024_60
},
1576 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1600x1200_60
},
1577 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x800_60
},
1578 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1440x900_60
},
1579 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1680x1050_60
},
1580 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1920x1080_60
},
1581 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1920x1200_60
},
1585 data
= OOP_INST_DATA(cl
, o
);
1587 InitSemaphore(&mdb
->sema
);
1589 memset(&pixfmt_data
, 0, sizeof (pixfmt_data
));
1591 init_def_tags(def_sync_tags
, num_Hidd_Sync_Attrs
);
1592 init_def_tags(def_pixfmt_tags
, num_Hidd_PixFmt_Attrs
);
1594 def_sync_tags
[aoHidd_Sync_GfxHidd
].ti_Tag
= aHidd_Sync_GfxHidd
;
1595 def_sync_tags
[aoHidd_Sync_GfxHidd
].ti_Data
= (IPTR
)o
;
1597 /* First we need to calculate how much memory we are to allocate by counting supplied
1598 pixel formats and syncs */
1600 for (tstate
= modetags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
));)
1604 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
1608 case aoHidd_Gfx_PixFmtTags
:
1612 case aoHidd_Gfx_SyncTags
:
1624 D(bug("!!! WE MUST AT LEAST HAVE ONE PIXFMT IN Gfx::RegisterModes() !!!\n"));
1629 D(bug("!!! NO SYNC IN Gfx::RegisterModes() !!!\n!!! USING DEFAULT MODES !!!\n"));
1630 temporary_tags
[11].ti_Tag
= TAG_MORE
;
1631 temporary_tags
[11].ti_Data
= (IPTR
)modetags
;
1632 modetags
= &temporary_tags
[0];
1636 ObtainSemaphore(&mdb
->sema
);
1638 /* Allocate memory for mode db */
1639 if (!alloc_mode_db(&data
->mdb
, numsyncs
, numpfs
, cl
))
1643 for (tstate
= modetags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
));)
1645 /* Look for Gfx, PixFmt and Sync tags */
1648 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
1652 case aoHidd_Gfx_PixFmtTags
:
1653 def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
].ti_Data
= tag
->ti_Data
;
1654 mdb
->pixfmts
[pfidx
] = HIDD_Gfx_RegisterPixFmt(o
, def_pixfmt_tags
);
1656 if (NULL
== mdb
->pixfmts
[pfidx
])
1658 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
1665 case aoHidd_Gfx_SyncTags
:
1666 def_sync_tags
[num_Hidd_Sync_Attrs
].ti_Data
= tag
->ti_Data
;
1668 mdb
->syncs
[syncidx
] = OOP_NewObject(CSD(cl
)->syncclass
, NULL
, def_sync_tags
);
1669 if (!mdb
->syncs
[syncidx
]) {
1670 D(bug("!!! UNABLE TO CREATE SYNC OBJECT IN Gfx::RegisterModes() !!!\n"));
1679 else if (IS_SYNC_ATTR(tag
->ti_Tag
, idx
))
1681 if (idx
>= num_Hidd_Sync_Attrs
)
1683 D(bug("!!! UNKNOWN SYNC ATTR IN Gfx::New(): %d !!!\n", idx
));
1687 def_sync_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
1688 def_sync_tags
[idx
].ti_Data
= tag
->ti_Data
;
1692 else if (IS_PIXFMT_ATTR(tag
->ti_Tag
, idx
))
1694 if (idx
>= num_Hidd_PixFmt_Attrs
)
1696 D(bug("!!! UNKNOWN PIXFMT ATTR IN Gfx::New(): %d !!!\n", idx
));
1700 def_pixfmt_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
1701 def_pixfmt_tags
[idx
].ti_Data
= tag
->ti_Data
;
1706 ReleaseSemaphore(&mdb
->sema
);
1712 /* mode db is freed in dispose */
1713 ReleaseSemaphore(&mdb
->sema
);
1718 /****************************************************************************************/
1722 struct mode_db
*mdb
;
1727 HIDDT_StdPixFmt
*stdpfs
;
1737 /****************************************************************************************/
1739 /* This is a recursive function that looks for valid modes */
1741 /****************************************************************************************/
1743 static HIDDT_ModeID
*querymode(struct modequery
*mq
)
1745 HIDDT_ModeID
*modeids
;
1746 register OOP_Object
*pf
;
1747 register OOP_Object
*sync
;
1748 BOOL mode_ok
= FALSE
;
1749 ULONG syncidx
, pfidx
;
1751 mq
->dims_ok
= FALSE
;
1752 mq
->stdpfs_ok
= FALSE
;
1753 mq
->check_ok
= FALSE
;
1755 /* Look at the supplied idx */
1756 if (mq
->pfidx
>= mq
->mdb
->num_pixfmts
)
1762 if (mq
->syncidx
>= mq
->mdb
->num_syncs
)
1764 /* We have reached the end of the recursion. Allocate memory and go back
1767 modeids
= AllocVec(sizeof (HIDDT_ModeID
) * (mq
->numfound
+ 1), MEMF_ANY
);
1768 /* Get the end of the array */
1769 modeids
+= mq
->numfound
;
1770 *modeids
= vHidd_ModeID_Invalid
;
1775 syncidx
= mq
->syncidx
;
1777 /* Get the pf and sync objects */
1778 pf
= mq
->mdb
->pixfmts
[syncidx
];
1779 sync
= mq
->mdb
->syncs
[pfidx
];
1782 /* Check that the mode is really usable */
1783 if (is_valid_mode(&mq
->mdb
->checked_mode_bm
, syncidx
, pfidx
))
1785 mq
->check_ok
= TRUE
;
1788 /* See if this mode matches the criterias set */
1790 if ( SD(sync
)->hdisp
>= mq
->minwidth
1791 && SD(sync
)->hdisp
<= mq
->maxwidth
1792 && SD(sync
)->vdisp
>= mq
->minheight
1793 && SD(sync
)->vdisp
<= mq
->maxheight
)
1799 if (NULL
!= mq
->stdpfs
)
1801 register HIDDT_StdPixFmt
*stdpf
= mq
->stdpfs
;
1804 if (*stdpf
== PF(pf
)->stdpixfmt
)
1806 mq
->stdpfs_ok
= TRUE
;
1813 mq
->stdpfs_ok
= TRUE
;
1819 if (mq
->dims_ok
&& mq
->stdpfs_ok
&& mq
->check_ok
)
1827 modeids
= querymode(mq
);
1829 if (NULL
== modeids
)
1834 /* The mode is OK. Add it to the list */
1836 *modeids
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
1843 /*****************************************************************************************
1846 moHidd_Gfx_QueryModeIDs
1849 HIDDT_ModeID *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryModeIDs *msg);
1851 HIDDT_ModeID *HIDD_Gfx_QueryModeIDs(OOP_Object *gfxHidd, struct TagItem *queryTags);
1854 hidd.graphics.graphics
1857 Obtain a table of all supported display mode IDs
1859 The returned address points to an array of HIDDT_ModeID containing all ModeIDs
1860 supported by this driver. The array is terminated with vHidd_ModeID_Invalid.
1863 gfxHidd - A driver object which to query.
1864 querytags - An optional taglist containing query options. Can be NULL.
1865 The following tags are supported:
1867 tHidd_GfxMode_MinWidth (ULONG) - A minimum width of modes you are
1869 tHidd_GfxMode_MaxWidth (ULONG) - A maximum width of modes you are
1871 tHidd_GfxMode_MinHeight (ULONG) - A minimum height of modes you are
1873 tHidd_GfxMode_MaxHeight (ULONG) - A maximum height of modes you are
1875 tHidd_GfxMode_PixFmts (HIDDT_StdPifXmt *) - A pointer to an array
1876 of standard pixelformat indexes. If supplied, only mode IDs whose
1877 pixelformat numbers match any of given ones will be returned.
1880 A pointer to an array of ModeIDs or NULL in case of failure
1889 moHidd_Gfx_ReleaseModeIDs, moHidd_Gfx_NextModeID
1893 *****************************************************************************************/
1895 HIDDT_ModeID
*GFX__Hidd_Gfx__QueryModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
1896 struct pHidd_Gfx_QueryModeIDs
*msg
)
1898 struct TagItem
*tag
, *tstate
;
1900 HIDDT_ModeID
*modeids
;
1901 struct HIDDGraphicsData
*data
;
1902 struct mode_db
*mdb
;
1904 struct modequery mq
=
1906 NULL
, /* mode db (set later) */
1907 0, 0xFFFFFFFF, /* minwidth, maxwidth */
1908 0, 0xFFFFFFFF, /* minheight, maxheight */
1911 0, 0, /* pfidx, syncidx */
1912 FALSE
, FALSE
, /* dims_ok, stdpfs_ok */
1913 FALSE
, /* check_ok */
1914 NULL
/* class (set later) */
1919 data
= OOP_INST_DATA(cl
, o
);
1924 for (tstate
= msg
->queryTags
; (tag
= NextTagItem((const struct TagItem
**)&tstate
)); )
1926 switch (tag
->ti_Tag
)
1928 case tHidd_GfxMode_MinWidth
:
1929 mq
.minwidth
= (ULONG
)tag
->ti_Tag
;
1932 case tHidd_GfxMode_MaxWidth
:
1933 mq
.maxwidth
= (ULONG
)tag
->ti_Tag
;
1936 case tHidd_GfxMode_MinHeight
:
1937 mq
.minheight
= (ULONG
)tag
->ti_Tag
;
1940 case tHidd_GfxMode_MaxHeight
:
1941 mq
.maxheight
= (ULONG
)tag
->ti_Tag
;
1944 case tHidd_GfxMode_PixFmts
:
1945 mq
.stdpfs
= (HIDDT_StdPixFmt
*)tag
->ti_Data
;
1951 ObtainSemaphoreShared(&mdb
->sema
);
1953 /* Recursively check all modes */
1954 modeids
= querymode(&mq
);
1956 ReleaseSemaphore(&mdb
->sema
);
1962 /*****************************************************************************************
1965 moHidd_Gfx_ReleaseModeIDs
1968 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ReleaseModeIDs *msg);
1970 VOID HIDD_Gfx_ReleaseModeIDs(OOP_Object *gfxHidd, HIDDT_ModeID *modeIDs);
1973 hidd.graphics.graphics
1976 Free array of display mode IDs returned by HIDD_Gfx_QueryModeIDs()
1979 gfxHidd - A driver object used to obtain the array
1980 modeIDs - A pointer to an array
1992 moHidd_Gfx_QueryModeIDs
1996 *****************************************************************************************/
1998 VOID
GFX__Hidd_Gfx__ReleaseModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
1999 struct pHidd_Gfx_ReleaseModeIDs
*msg
)
2001 FreeVec(msg
->modeIDs
);
2004 /*****************************************************************************************
2007 moHidd_Gfx_NextModeID
2010 HIDDT_ModeID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NextModeID *msg);
2012 HIDDT_ModeID HIDD_Gfx_NextModeID(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2013 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2016 hidd.graphics.graphics
2019 Iterate driver's internal display mode database.
2022 gfxHidd - A driver object to query
2023 modeID - A previous mode ID or vHidd_ModeID_Invalid for start of the iteration
2024 syncPtr - A pointer to a storage where pointer to sync object will be placed
2025 pixFmtPtr - A pointer to a storage where pointer to pixelformat object will be placed
2028 Next available mode ID or vHidd_ModeID_Invalid if there are no more display modes.
2029 If the function returns vHidd_ModeID_Invalid, sync and pixelformat pointers will
2043 *****************************************************************************************/
2045 HIDDT_ModeID
GFX__Hidd_Gfx__NextModeID(OOP_Class
*cl
, OOP_Object
*o
,
2046 struct pHidd_Gfx_NextModeID
*msg
)
2048 struct HIDDGraphicsData
*data
;
2049 struct mode_db
*mdb
;
2050 ULONG syncidx
, pfidx
;
2051 HIDDT_ModeID return_id
= vHidd_ModeID_Invalid
;
2054 data
= OOP_INST_DATA(cl
, o
);
2057 ObtainSemaphoreShared(&mdb
->sema
);
2058 if (vHidd_ModeID_Invalid
== msg
->modeID
)
2065 pfidx
= MODEID_TO_PFIDX( msg
->modeID
);
2066 syncidx
= MODEID_TO_SYNCIDX( msg
->modeID
);
2068 /* Increament one from the last call */
2070 if (pfidx
>= mdb
->num_pixfmts
)
2077 /* Search for a new mode. We only accept valid modes */
2078 for (; syncidx
< mdb
->num_syncs
; syncidx
++)
2080 /* We only return valid modes */
2081 for (; pfidx
< mdb
->num_pixfmts
; pfidx
++)
2083 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
2095 return_id
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
2096 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
2097 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
2101 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
2104 ReleaseSemaphore(&mdb
->sema
);
2109 /*****************************************************************************************
2115 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMode *msg);
2117 BOOL HIDD_Gfx_GetMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2118 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2121 hidd.graphics.graphics
2124 Get sync and pixelformat objects for a particular display ModeID.
2127 gfxHidd - pointer to a driver object which this ModeID belongs to
2128 syncPtr - pointer to a storage where sync object pointer will be placed
2129 pixFmtPtr - pointer to a storage where pixelformat object pointer will be placed
2132 TRUE upon success, FALSE in case of failure (e.g. given mode does not exist in
2133 driver's internal database). If the function returns FALSE, sync and pixelformat
2134 pointers will be set to NULL.
2137 Every display mode is associated with some sync and pixelformat object. If the
2138 method returns TRUE, object pointers are guaranteed to be valid.
2145 moHidd_Gfx_NextModeID
2149 *****************************************************************************************/
2151 BOOL
GFX__Hidd_Gfx__GetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMode
*msg
)
2153 ULONG pfidx
, syncidx
;
2154 struct HIDDGraphicsData
*data
;
2155 struct mode_db
*mdb
;
2158 data
= OOP_INST_DATA(cl
, o
);
2161 pfidx
= MODEID_TO_PFIDX(msg
->modeID
);
2162 syncidx
= MODEID_TO_SYNCIDX(msg
->modeID
);
2164 ObtainSemaphoreShared(&mdb
->sema
);
2166 if (! (pfidx
>= mdb
->num_pixfmts
|| syncidx
>= mdb
->num_syncs
) )
2168 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
2171 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
2172 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
2176 ReleaseSemaphore(&mdb
->sema
);
2180 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
2186 /*****************************************************************************************
2192 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetMode *msg);
2194 BOOL HIDD_Gfx_SetMode(OOP_Object *gfxHidd, OOP_Object *sync);
2197 hidd.graphics.graphics
2200 Update display mode according to changed sync object
2203 gfxHidd - A display driver to operate on
2204 sync - A modified sync object pointer
2207 TRUE if everything went OK and FALSE in case of some error
2210 This method is used to inform the driver that some external program has changed
2211 sync data and wants to update the display if needed. It's up to the implementation to
2212 check that current display is really using this sync (frontmost screen uses this mode).
2221 Base class implementation just returns FALSE indicating that this method is
2224 *****************************************************************************************/
2226 BOOL
GFX__Hidd_Gfx__SetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetMode
*msg
)
2231 /****************************************************************************************/
2233 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
,
2234 OOP_Object
*dst_bm
, ULONG width
, ULONG height
)
2236 struct HIDDGraphicsData
*data
;
2239 OOP_Object
*src_colmap
;
2240 APTR psrc_colmap
= &src_colmap
;
2242 data
= OOP_INST_DATA(cl
, o
);
2244 /* We have to copy the colormap into the framebuffer bitmap */
2245 OOP_GetAttr(src_bm
, aHidd_BitMap_ColorMap
, (IPTR
*)psrc_colmap
);
2246 OOP_GetAttr(src_colmap
, aHidd_ColorMap_NumEntries
, &numentries
);
2248 for (i
= 0; i
< numentries
; i
++)
2252 HIDD_CM_GetColor(src_colmap
, i
, &col
);
2253 HIDD_BM_SetColors(dst_bm
, &col
, i
, 1);
2266 /*****************************************************************************************
2272 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Show *msg);
2274 OOP_Object *HIDD_Gfx_Show(OOP_Object *gfxHidd, OOP_Object *bitMap, ULONG flags);
2277 hidd.graphics.graphics
2280 Change currently displayed bitmap on the screen.
2282 The bitmap object supplied must have been created with aHidd_BitMap_Displayable
2283 attribute set to TRUE.
2285 The function's behavior differs a lot depending on whether the driver uses a
2286 framebuffer or video hardware is able to switch screens itself.
2288 If the driver uses a framebuffer bitmap, it is supposed to copy the supplied bitmap
2289 into the framebuffer and return a framebuffer pointer. It also can be asked to
2290 copy back old framebuffer contents into previous bitmap object. It is driver's
2291 job to keep track of which bitmap object was displayed last time. This is what
2292 default implementation does. Note that it is very basic, and even does not support
2293 changing display resolution. It's not recommended to rely on it in production
2294 drivers (unless your video hardware supports only one mode).
2296 If the driver does not use a framebuffer, it is supposed to reprogram the hardware
2297 here to display an appropriate region of video RAM. Do not call the base class
2298 in this case, its implementation relies on framebuffer existance and will always
2299 return NULL which indicates an error.
2301 It is valid to get NULL value in bitMap parameter. This means that there is
2302 nothing to display and the screen needs to be blanked out. It is valid for
2303 non-framebuffer-based driver to return NULL as a reply then. In all other cases
2304 NULL return value means an error.
2306 Please avoid returning errors at all. graphics.library/LoadView() has no error
2307 indication. An error during showing a bitmap would leave the display in
2308 unpredictable state.
2310 If the driver does not use a framebuffer, consider using HIDD_Gfx_ShowViewPorts().
2311 It's more straightforward, flexible and offers support for screen composition.
2314 gfxHidd - a display driver object, whose display you wish to change.
2315 bitMap - a pointer to a bitmap object which needs to be shown or NULL.
2316 flags - currently only one flag is defined:
2318 fHidd_Gfx_Show_CopyBack - Copy back the image data from framebuffer bitmap
2319 to old displayed bitmap. Used only if the driver
2320 needs a framebuffer.
2323 A pointer to a currently displayed bitmap object or NULL (read FUNCTION paragraph for
2324 detailed description)
2327 Drivers which use mirrored video data buffer do not have to update the display
2328 immediately in this method. moHidd_BitMap_UpdateRect will be sent to the returned
2329 bitmap if it's not NULL. Of course display blanking (if NULL bitmap was received)
2330 needs to be performed immediately.
2337 moHidd_Gfx_ShowViewPorts, graphics.library/LoadView()
2341 *****************************************************************************************/
2343 OOP_Object
*GFX__Hidd_Gfx__Show(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Show
*msg
)
2345 struct HIDDGraphicsData
*data
;
2352 struct TagItem gctags
[] =
2354 { aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
2355 { aHidd_GC_Foreground
, 0 },
2359 data
= OOP_INST_DATA(cl
, o
);
2362 /* We have to do some consistency checking */
2365 OOP_GetAttr(bm
, aHidd_BitMap_Displayable
, &displayable
);
2368 if (bm
&& !displayable
)
2369 /* We cannot show a non-displayable bitmap */
2372 if (NULL
== data
->framebuffer
)
2375 OOP_SetAttrs(data
->gc
, gctags
);
2376 if (NULL
!= data
->shownbm
)
2378 OOP_GetAttr(data
->shownbm
, aHidd_BitMap_Width
, &oldwidth
);
2379 OOP_GetAttr(data
->shownbm
, aHidd_BitMap_Height
, &oldheight
);
2380 /* Copy the framebuffer data back into the old shown bitmap */
2381 if (msg
->flags
& fHidd_Gfx_Show_CopyBack
)
2382 copy_bm_and_colmap(cl
, o
, data
->framebuffer
, data
->shownbm
, oldwidth
, oldheight
);
2386 OOP_GetAttr(bm
, aHidd_BitMap_Width
, &newwidth
);
2387 OOP_GetAttr(bm
, aHidd_BitMap_Height
, &newheight
);
2388 copy_bm_and_colmap(cl
, o
, bm
, data
->framebuffer
, newwidth
, newheight
);
2390 /* Clear remaining parts of the framebuffer (if previous bitmap was larger than new one) */
2392 if (newwidth
< oldwidth
)
2393 HIDD_BM_FillRect(data
->framebuffer
, data
->gc
, newwidth
, 0, oldwidth
- 1, oldheight
- 1);
2394 if ((newheight
< oldheight
) && newwidth
)
2395 HIDD_BM_FillRect(data
->framebuffer
, data
->gc
, 0, newheight
, newwidth
- 1, oldheight
);
2400 return data
->framebuffer
;
2403 /*****************************************************************************************
2406 moHidd_Gfx_ShowViewPorts
2409 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ShowViewPorts *msg);
2411 ULONG HIDD_Gfx_ShowViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view);
2414 hidd.graphics.graphics
2417 Show one or more bitmaps on the screen.
2419 It is completely up to the driver how to implement this function. The driver may
2420 or may not support hardware-assisted screens composition. Bitmaps are sorted
2421 in the list in descending z-order. The driver is expected to put at least frontmost
2424 It is valid to get NULL pointer as data parameter. This means that there's
2425 nothing to show and the screen should go blank.
2427 Bitmaps display offsets are stored in their aHidd_BitMap_LeftEdge and
2428 aHidd_BitMap_TopEdge attributes. This function is not expected to modify their
2429 values somehow. They are assumed to be preserved between calls unless changed
2430 explicitly by the system.
2432 If you implement this method, you don't have to implement HIDD_Gfx_Show() because
2433 it will never be called.
2435 Note that there is no more error indication - the driver is expected to be
2439 gfxHidd - a display driver object, whose display you wish to change.
2440 data - a singly linked list of bitmap objects to show
2443 TRUE if this method is supported by the driver, FALSE otherwise
2455 Default base class implementation simply returns FALSE. This causes
2456 the system to use HIDD_Gfx_Show() instead.
2458 *****************************************************************************************/
2460 ULONG
GFX__Hidd_Gfx__ShowViewPorts(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ShowViewPorts
*msg
)
2462 /* By default we don't support screen composition (and this method too) */
2466 /*****************************************************************************************
2469 moHidd_Gfx_SetCursorShape
2472 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorShape *msg);
2474 BOOL HIDD_Gfx_SetCursorShape(OOP_Object *gfxHidd, OOP_Object *shape,
2475 LONG xoffset, LONG yoffset);
2478 hidd.graphics.graphics
2481 Set mouse pointer shape.
2483 A pointer image is contained in the specified bitmap object. The bitmap object
2484 may contain a colormap if the system wants to specify own colors for the pointer.
2485 The supplied colormap will also contain alpha channel values.
2487 It is up to driver what to do if, for example, alpha channel is not supported by
2488 the hardware. Or if given bitmap type is not supported (for example truecolor
2489 bitmap on LUT-only hardware). It is expected that the driver converts bitmap
2490 data to a more appropriate form in such a case.
2492 A hotspot is given as an offset from the actual hotspot to the top-left corner
2493 of the pointer image. It is generally needed only for hosted display drivers
2494 which utilize host's support for mouse pointer.
2496 The default implementation in the base class just does nothing. A software mouse
2497 pointer is implemented in a special layer called fakegfx.hidd inside
2498 graphics.library. If a software pointer emulation is used, this method will
2502 gfxHidd - a display driver object, for whose display you wish to change the pointer
2503 shape - a pointer to a bitmap object, containing pointer bitmap
2504 xoffset - a horizontal hotspot offset
2505 yoffset - a vertical hotspot offset
2508 TRUE on success, FALSE on failure
2517 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2521 *****************************************************************************************/
2523 BOOL
GFX__Hidd_Gfx__SetCursorShape(OOP_Class
*cl
, OOP_Object
*o
,
2524 struct pHidd_Gfx_SetCursorShape
*msg
)
2526 /* We have no clue how to render the cursor */
2530 /*****************************************************************************************
2533 moHidd_Gfx_SetCursorVisible
2536 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorVisible *msg);
2538 VOID HIDD_Gfx_SetCursorVisible(OOP_Object *gfxHidd, BOOL visible);
2541 hidd.graphics.graphics
2544 Control mouse pointer visiblity.
2546 The default implementation in the base class does nothing. If a software pointer
2547 emulation is used, this method will never be called.
2550 gfxHidd - a display driver object, on whose display you wish to turn
2552 visible - TRUE to enable pointer display, FALSE to disable it
2564 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2568 *****************************************************************************************/
2570 VOID
GFX__Hidd_Gfx__SetCursorVisible(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorVisible
*msg
)
2575 /*****************************************************************************************
2578 moHidd_Gfx_SetCursorPos
2581 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorPos *msg);
2583 BOOL HIDD_Gfx_SetCursorPos(OOP_Object *gfxHidd, LONG x, LONG y);
2586 hidd.graphics.graphics
2589 Set current mouse pointer position.
2591 This is a real position on top-left image corner relative to top-left corner of
2592 the physical display. Neither logical screen origin nor hotspot are taken into
2595 The default implementation in the base class does nothing and just returns TRUE.
2596 If a software pointer emulation is used, this method will never be called.
2599 gfxHidd - a display driver object, on whose display you wish to position the pointer
2600 x - An x coordinate of the pointer (relative to the physical screen origin)
2601 y - An y coordinate of the pointer (relative to the physical screen origin)
2604 Always TRUE. Reserved for future, do not use it.
2607 This method is called by graphics.library/MoveSprite() which has no return value.
2608 However, for historical reasons, this method has a return value. Drivers should
2609 always return TRUE in order to ensure future compatibility.
2616 moHidd_Gfx_SetCursorShape, moHidd_Gfx_SetCursorVisible, graphics.library/MoveSprite()
2620 *****************************************************************************************/
2622 BOOL
GFX__Hidd_Gfx__SetCursorPos(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorPos
*msg
)
2627 /*****************************************************************************************
2633 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg);
2635 VOID HIDD_Gfx_CopyBox(OOP_Object *gfxHidd, OOP_Object *src, WORD srcX, WORD srcY,
2636 OOP_Object *dest, WORD destX, WORD destY, UWORD width, UWORD height,
2640 hidd.graphics.graphics
2643 Perform rectangle copy (blit) operation from one bitmap to another.
2645 Given bitmaps may belong to different display drivers. The driver may attempt to
2646 use hardware for acceleration (if available), and if it's impossible, pass the
2647 operation on to the base class.
2649 Always check class of the supplied bitmap before attempting to look at its
2652 A GC is used in order to specify raster operation performed between the source
2653 and destination according to its aHidd_GC_DrawMode attribute value.
2656 gfxHidd - a display driver object that you are going to use for copying
2657 src - a pointer to source bitmap object
2658 srcX - an X coordinate of the source rectangle
2659 srcY - an Y coordinate of the source rectangle
2660 dest - a pointer to destination bitmap object
2661 destX - an X coordinate of the destination rectangle
2662 destY - an Y coordinate of the destination rectangle
2663 width - width of the rectangle to copy
2664 height - height of the rectangle to copy
2665 gc - graphics context holding draw mode on the destination
2671 You must specify valid coordinates (non-negative and inside the actual bitmap
2672 area), no checks are done.
2674 It is valid to specify two overlapped areas of the same bitmap as source
2685 *****************************************************************************************/
2687 VOID
GFX__Hidd_Gfx__CopyBox(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_Gfx_CopyBox
*msg
)
2690 WORD srcX
= msg
->srcX
, destX
= msg
->destX
;
2691 WORD srcY
= msg
->srcY
, destY
= msg
->destY
;
2692 WORD startX
, endX
, deltaX
, startY
, endY
, deltaY
;
2695 HIDDT_PixelFormat
*srcpf
, *dstpf
;
2696 OOP_Object
*dest
, *src
;
2699 #if USE_FAST_GETPIXEL
2700 struct pHidd_BitMap_GetPixel get_p
;
2703 #if USE_FAST_DRAWPIXEL
2704 struct pHidd_BitMap_DrawPixel draw_p
;
2706 draw_p
.mID
= CSD(cl
)->drawpixel_mid
;
2707 draw_p
.gc
= msg
->gc
;
2710 #if USE_FAST_GETPIXEL
2711 get_p
.mID
= CSD(cl
)->getpixel_mid
;
2717 /* If source/dest overlap, direction of operation is important */
2721 startX
= msg
->width
- 1; endX
= -1; deltaX
= -1;
2725 startX
= 0; endX
= msg
->width
; deltaX
= 1;
2730 startY
= msg
->height
- 1; endY
= -1; deltaY
= -1;
2734 startY
= 0; endY
= msg
->height
; deltaY
= 1;
2737 /* Get the source pixel format */
2738 srcpf
= (HIDDT_PixelFormat
*)HBM(src
)->prot
.pixfmt
;
2740 /* bug("COPYBOX: SRC PF: %p, obj=%p, cl=%s, OOP_OCLASS: %s\n", srcpf, obj
2741 , cl->ClassNode.ln_Name, OOP_OCLASS(obj)->ClassNode.ln_Name);
2746 IPTR sw
, sh
, dw
, dh
;
2747 D(bug("COPYBOX: src=%p, dst=%p, width=%d, height=%d\n"
2748 , obj
, msg
->dest
, msg
->width
, msg
->height
));
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
);
2754 D(bug("src dims: %d, %d dest dims: %d, %d\n", sw
, sh
, dw
, dh
));
2758 dstpf
= (HIDDT_PixelFormat
*)HBM(dest
)->prot
.pixfmt
;
2760 /* Compare graphtypes */
2761 if (HIDD_PF_COLMODEL(srcpf
) == HIDD_PF_COLMODEL(dstpf
))
2763 /* It is ok to do a direct copy */
2767 /* Find out the gfx formats */
2768 if ( IS_PALETTIZED(srcpf
) && IS_TRUECOLOR(dstpf
))
2772 else if (IS_TRUECOLOR(srcpf
) && IS_PALETTIZED(dstpf
))
2776 else if (IS_PALETTE(srcpf
) && IS_STATICPALETTE(dstpf
))
2780 else if (IS_STATICPALETTE(srcpf
) && IS_PALETTE(dstpf
))
2788 memFG
= GC_FG(msg
->gc
);
2790 /* All else have failed, copy pixel by pixel */
2793 if (HIDD_PF_COLMODEL(srcpf
) == HIDD_PF_COLMODEL(dstpf
))
2795 if (IS_TRUECOLOR(srcpf
))
2797 // bug("COPY FROM TRUECOLOR TO TRUECOLOR\n");
2798 for(y
= startY
; y
!= endY
; y
+= deltaY
)
2802 /* if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2803 bug("[%d,%d] ", memSrcX, memDestX);
2805 for(x
= startX
; x
!= endX
; x
+= deltaX
)
2809 #if USE_FAST_GETPIXEL
2812 pix
= GETPIXEL(src
, &get_p
);
2814 pix
= HIDD_BM_GetPixel(obj
, srcX
+ x
, srcY
+ y
);
2817 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2825 HIDD_BM_UnmapPixel(src
, pix
, &col
);
2826 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, &col
);
2827 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2833 #if USE_FAST_DRAWPIXEL
2834 draw_p
.x
= destX
+ x
;
2835 draw_p
.y
= destY
+ y
;
2836 DRAWPIXEL(dest
, &draw_p
);
2839 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
2844 /*if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2845 bug("[%d,%d] ", srcY, destY);
2849 } /* if (IS_TRUECOLOR(srcpf)) */
2852 /* Two palette bitmaps.
2853 For this case we do NOT convert through RGB,
2854 but copy the pixel indexes directly
2856 // bug("COPY FROM PALETTE TO PALETTE\n");
2858 /* FIXME: This might not work very well with two StaticPalette bitmaps */
2860 for(y
= startY
; y
!= endY
; y
+= deltaY
)
2862 for(x
= startX
; x
!= endX
; x
+= deltaX
)
2864 GC_FG(gc
) = HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
2866 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
2871 } /* if (IS_TRUECOLOR(srcpf)) else ... */
2873 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) */
2876 /* Two unlike bitmaps */
2877 if (IS_TRUECOLOR(srcpf
))
2879 /* FIXME: Implement this */
2880 D(bug("!! DEFAULT COPYING FROM TRUECOLOR TO PALETTIZED NOT IMPLEMENTED IN BitMap::CopyBox\n"));
2882 else if (IS_TRUECOLOR(dstpf
))
2884 /* Get the colortab */
2885 HIDDT_Color
*ctab
= ((HIDDT_ColorLUT
*)HBM(src
)->colmap
)->colors
;
2887 // bug("COPY FROM PALETTE TO TRUECOLOR, DRAWMODE %d, CTAB %p\n", GC_DRMD(gc), ctab);
2889 for(y
= startY
; y
!= endY
; y
+= deltaY
)
2891 for(x
= startX
; x
!= endX
; x
+= deltaX
)
2893 register HIDDT_Pixel pix
;
2894 register HIDDT_Color
*col
;
2896 pix
= HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
2899 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, col
);
2900 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
2906 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) else ... */
2911 /*****************************************************************************************
2914 moHidd_Gfx_ShowImminentReset
2917 VOID OOP_DoMethod(OOP_Object *obj, OOP_Msg msg);
2920 hidd.graphics.graphics
2923 Indicate upcoming machine reset. Obsolete.
2925 Since graphics.library v41.4 this method is not used any more. Considered
2926 reserved. Do not use it in any way.
2944 *****************************************************************************************/
2946 VOID
GFX__Hidd_Gfx__ShowImminentReset(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg msg
)
2950 /****************************************************************************************/
2952 OOP_Object
*GFX__Hidd_Gfx__RegisterPixFmt(OOP_Class
*cl
, OOP_Object
*o
,
2953 struct pHidd_Gfx_RegisterPixFmt
*msg
)
2955 HIDDT_PixelFormat cmp_pf
;
2956 struct class_static_data
*data
;
2957 struct pixfmt_data
*retpf
= NULL
;
2959 memset(&cmp_pf
, 0, sizeof(cmp_pf
));
2962 if (!parse_pixfmt_tags(msg
->pixFmtTags
, &cmp_pf
, 0, CSD(cl
)))
2964 D(bug("!!! FAILED PARSING TAGS IN Gfx::RegisterPixFmt() !!!\n"));
2968 DPF(bug("Gfx::RegisterPixFmt(): Registering pixelformat:\n"));
2969 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
2970 , PF(&cmp_pf
)->red_shift
2971 , PF(&cmp_pf
)->green_shift
2972 , PF(&cmp_pf
)->blue_shift
2973 , PF(&cmp_pf
)->alpha_shift
2974 , PF(&cmp_pf
)->red_mask
2975 , PF(&cmp_pf
)->green_mask
2976 , PF(&cmp_pf
)->blue_mask
2977 , PF(&cmp_pf
)->alpha_mask
2978 , PF(&cmp_pf
)->bytes_per_pixel
2980 , PF(&cmp_pf
)->depth
2981 , PF(&cmp_pf
)->stdpixfmt
));
2983 retpf
= find_pixfmt(&cmp_pf
, CSD(cl
));
2985 DPF(bug("Found matching pixelformat: 0x%p\n", retpf
));
2987 /* Increase pf refcount */
2988 AROS_ATOMIC_INC(retpf
->refcount
);
2990 /* Could not find an alike pf, Create a new pfdb node */
2991 /* Since we pass NULL as the taglist below, the PixFmt class will just create a dummy pixfmt */
2992 retpf
= OOP_NewObject(CSD(cl
)->pixfmtclass
, NULL
, NULL
);
2994 /* We have one user */
2995 retpf
->refcount
= 1;
2997 /* Initialize the pixfmt object the "ugly" way */
2998 memcpy(retpf
, &cmp_pf
, sizeof (HIDDT_PixelFormat
));
3000 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3001 , PF(&cmp_pf
)->red_shift
3002 , PF(&cmp_pf
)->green_shift
3003 , PF(&cmp_pf
)->blue_shift
3004 , PF(&cmp_pf
)->alpha_shift
3005 , PF(&cmp_pf
)->red_mask
3006 , PF(&cmp_pf
)->green_mask
3007 , PF(&cmp_pf
)->blue_mask
3008 , PF(&cmp_pf
)->alpha_mask
3009 , PF(&cmp_pf
)->bytes_per_pixel
3011 , PF(&cmp_pf
)->depth
3012 , PF(&cmp_pf
)->stdpixfmt
));
3014 ObtainSemaphore(&data
->pfsema
);
3015 AddTail((struct List
*)&data
->pflist
, (struct Node
*)&retpf
->node
);
3016 ReleaseSemaphore(&data
->pfsema
);
3020 DPF(bug("New refcount is %u\n", retpf
->refcount
));
3021 return (OOP_Object
*)retpf
;
3024 /****************************************************************************************/
3026 VOID
GFX__Hidd_Gfx__ReleasePixFmt(OOP_Class
*cl
, OOP_Object
*o
,
3027 struct pHidd_Gfx_ReleasePixFmt
*msg
)
3029 struct class_static_data
*data
;
3030 struct pixfmt_data
*pixfmt
= (struct pixfmt_data
*)msg
->pixFmt
;
3032 DPF(bug("release_pixfmt 0x%p\n", pixfmt
));
3036 ObtainSemaphore(&data
->pfsema
);
3038 /* If refcount is already 0, this object was never registered in the database,
3040 DPF(bug("Old reference count is %u\n", pixfmt
->refcount
));
3041 if (pixfmt
->refcount
) {
3042 if (--pixfmt
->refcount
== 0) {
3043 Remove((struct Node
*)&pixfmt
->node
);
3044 OOP_DisposeObject((OOP_Object
*)pixfmt
);
3048 ReleaseSemaphore(&data
->pfsema
);
3051 /*****************************************************************************************
3054 moHidd_Gfx_CheckMode
3057 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CheckMode *msg);
3059 BOOL HIDD_Gfx_CheckMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3060 OOP_Object *sync, OOP_Object *pixFmt);
3063 hidd.graphics.graphics
3066 Check if given display mode is supported by the driver.
3068 Normally any resolution (sync) can be used together with any pixelformat. However
3069 on some hardware there may be exceptions from this rule. In such a case this
3070 method should be implemented, and check should be performed.
3072 The information provided by this method is used in order to exclude unsupported
3073 modes from the database
3075 Default implementation in the base class just returns TRUE for all supplied values.
3077 Note that this method can not be used in order to chech that the given mode is
3078 really present in the database and it really refers to the given sync and
3079 pixelformat objects. Use HIDD_Gfx_GetMode() for mode ID validation.
3082 gfxHidd - A display driver object
3083 modeID - A display mode ID
3084 sync - A pointer to a sync object associated with this mode
3085 pixFmt - A pointer to a pixelformat object associated with this mode
3088 TRUE if this mode is supported and FALSE if it's not.
3095 Currently base class does not call this method after driver object creation.
3096 This needs to be fixed.
3103 *****************************************************************************************/
3105 BOOL
GFX__Hidd_Gfx__CheckMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CheckMode
*msg
)
3107 /* As a default we allways return TRUE, ie. the mode is OK */
3111 /*****************************************************************************************
3114 moHidd_Gfx_GetPixFmt
3117 OOP_Object *OOP_DoMethod(OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg);
3119 OOP_Object *HIDD_Gfx_GetPixFmt(OOP_Object *gfxHidd, HIDDT_StdPixFmt pixFmt);
3122 hidd.graphics.graphics
3125 Get a standard pixelformat descriptor from internal pixelformats database.
3128 gfxHidd - A display driver object
3129 pixFmt - An index of pixelformat (one of vHIDD_StdPixFmt_... values)
3132 A pointer to a pixelformat object or NULL if lookup failed
3135 Pixelformat objects are stored in a global system-wide database. They are not
3136 linked with a particular driver in any way and completely sharable between all
3146 This operation can never fail because all standard pixelformats are registered
3147 during early system initialization.
3149 *****************************************************************************************/
3151 OOP_Object
*GFX__Hidd_Gfx__GetPixFmt(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetPixFmt
*msg
)
3155 if (!IS_REAL_STDPIXFMT(msg
->stdPixFmt
))
3157 D(bug("!!! Illegal pixel format passed to Gfx::GetPixFmt(): %d\n", msg
->stdPixFmt
));
3162 fmt
= (OOP_Object
*)CSD(cl
)->std_pixfmts
[REAL_STDPIXFMT_IDX(msg
->stdPixFmt
)];
3168 /*****************************************************************************************
3174 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetSync *msg);
3176 OOP_Object *HIDD_Gfx_GetSync(OOP_Object *gfxHidd, ULONG num);
3179 hidd.graphics.graphics
3182 Get a sync object from internal display mode database by index
3185 gfxHidd - A display driver object to query
3186 num - An index of sync object starting from 0
3189 A pointer to a sync object or NULL if there's no sync with such index
3201 *****************************************************************************************/
3203 OOP_Object
*GFX__Hidd_Gfx__GetSync(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetSync
*msg
)
3205 struct HIDDGraphicsData
*data
= OOP_INST_DATA(cl
, o
);
3207 if (msg
->num
< data
->mdb
.num_syncs
)
3208 return data
->mdb
.syncs
[msg
->num
];
3210 D(bug("!!! Illegal sync index passed to Gfx::GetSync(): %d\n", msg
->num
));
3215 /*****************************************************************************************
3218 moHidd_Gfx_ModeProperties
3221 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ModeProperties *msg);
3223 ULONG HIDD_Gfx_ModeProperties(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3224 struct HIDD_ModeProperties *props, ULONG propsLen);
3227 hidd.graphics.graphics
3230 Obtain an information about the video mode.
3232 Video mode description structure may grow in future, so be careful and always check
3233 propsLen parameter value. A system may ask you for less data than you can provide.
3234 Always return an actual value. Do not just zero out fields you don't know about,
3235 this is not expected to be backwards compatible.
3238 gfxHidd - a pointer to a display driver object whose display mode you want to query
3239 modeID - a mode ID to query
3240 props - a pointer to a storage area where HIDD_ModeProperties structure will be put
3241 propsLen - length of the supplied buffer in bytes.
3244 Actual length of obtained structure
3247 Returned data must reflect only real hardware capabilities. For example, do not
3248 count emulated sprites. The system takes care about emulated features itself.
3255 aoHidd_Gfx_HWSpriteTypes, aoHidd_Gfx_SupportsHWCursor
3258 Default implementation in the base class relies on aHidd_Gfx_HWSpriteTypes attribute,
3259 not vice versa. If you override this method, do not forget to override this attribute too.
3261 *****************************************************************************************/
3263 ULONG
GFX__Hidd_Gfx__ModeProperties(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ModeProperties
*msg
)
3265 struct HIDD_ModeProperties props
= {0, 0, 0};
3266 IPTR has_hw_cursor
= 0;
3267 ULONG len
= msg
->propsLen
;
3269 D(bug("[GFXHIDD] Hidd::Gfx::ModeProperties(0x%08lX, 0x%p, %u)\n", msg
->modeID
, msg
->props
, msg
->propsLen
));
3270 OOP_GetAttr(o
, aHidd_Gfx_HWSpriteTypes
, &has_hw_cursor
);
3271 if (has_hw_cursor
) {
3272 D(bug("[GFXHIDD] Driver has hardware mouse cursor implementation\n"));
3273 props
.DisplayInfoFlags
= DIPF_IS_SPRITES
;
3274 props
.NumHWSprites
= 1;
3277 if (len
> sizeof(props
))
3278 len
= sizeof(props
);
3279 D(bug("[GFXHIDD] Copying %u bytes\n", len
));
3280 CopyMem(&props
, msg
->props
, len
);
3285 /*****************************************************************************************
3291 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3293 BOOL HIDD_Gfx_GetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3296 hidd.graphics.graphics
3299 Get current gamma table for the display.
3301 A gamma table consists of three 256-byte tables: one for red component, one for
3302 green and one for blue.
3304 A user should supply three pointers to preallocated 256-byte tables which will
3305 be filled in. Any ot these pointers may have NULL value, in this case the
3306 respective component will be ignored.
3309 gfxHidd - A display driver object
3310 Red - A pointer to a 256-byte array for red component or NULL
3311 Green - A pointer to a 256-byte array for green component or NULL
3312 Blue - A pointer to a 256-byte array for blue component or NULL
3315 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3318 This method can be used just to query if the driver supports gamma correction.
3319 Just set Red, Green and Blue to NULL for this.
3330 *****************************************************************************************/
3332 BOOL
GFX__Hidd_Gfx__GetGamma(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Gamma
*msg
)
3337 /*****************************************************************************************
3343 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3345 BOOL HIDD_Gfx_SetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3348 hidd.graphics.graphics
3351 Set current gamma table for the display.
3353 A gamma table consists of three 256-byte tables: one for red component, one for
3354 green and one for blue.
3356 A user should supply three pointers to 256-byte tables from which gamma values
3357 will be picked up. Any ot these pointers may have NULL value, in this case the
3358 respective component will be ignored.
3361 gfxHidd - A display driver object
3362 Red - A pointer to a 256-byte array for red component or NULL
3363 Green - A pointer to a 256-byte array for green component or NULL
3364 Blue - A pointer to a 256-byte array for blue component or NULL
3367 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3370 This method can be used just to query if the driver supports gamma correction.
3371 Just set Red, Green and Blue to NULL for this.
3382 *****************************************************************************************/
3384 BOOL
GFX__Hidd_Gfx__SetGamma(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Gamma
*msg
)
3389 /*****************************************************************************************
3392 moHidd_Gfx_QueryHardware3D
3395 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryHardware3D *msg);
3397 BOOL HIDD_Gfx_QueryHardware3D(OOP_Object *gfxHidd, OOP_Object *pixFmt);
3400 hidd.graphics.graphics
3403 Query if the driver supports hardware-accelerated 3D graphics for the given
3407 gfxHidd - A display driver object
3408 pixFmt - A pointer to a pixelformat descriptor object
3411 TRUE if the driver supports hardware-accelerated 3D for the given pixelformat,
3424 *****************************************************************************************/
3426 BOOL
GFX__Hidd_Gfx__QueryHardware3D(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_QueryHardware3D
*msg
)
3431 /*****************************************************************************************
3434 moHidd_Gfx_GetMaxSpriteSize
3437 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMaxSpriteSize *msg);
3439 BOOL HIDD_Gfx_GetMaxSpriteSize(OOP_Object *gfxHidd, ULONG Type, ULONG *Width, ULONG *Height);
3442 hidd.graphics.graphics
3445 Query maximum allowed size for the given sprite type.
3448 gfxHidd - A display driver object
3449 Type - Type of the sprite image (one of vHidd_SpriteType_... values)
3450 Width - A pointer to ULONG where width will be placed.
3451 Height - A pointer to ULONG where height will be placed.
3454 FALSE is the given sprite type is not supported, otherwise TRUE.
3457 Default implementation in the base class just return some small values
3458 which it hopes can be supported by every driver if the driver supports given
3459 sprite type. It is strongly suggested to reimplement this method in the display
3462 Width and Height are considered undefined if the method returns FALSE.
3472 *****************************************************************************************/
3474 BOOL
GFX__Hidd_Gfx__GetMaxSpriteSize(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMaxSpriteSize
*msg
)
3478 OOP_GetAttr(o
, aHidd_Gfx_HWSpriteTypes
, &types
);
3480 if (types
& msg
->Type
) {
3488 /*****************************************************************************************
3491 moHidd_Gfx_NewOverlay
3494 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewOverlay *msg);
3496 OOP_Object *HIDD_Gfx_NewOverlay(OOP_Object *gfxHidd, struct TagItem *tagList);
3499 hidd.graphics.graphics
3502 Create a video overlay object.
3505 gfxHidd - A graphics driver object on whose display you want to create an overlay.
3506 tagList - A list of overlay attributes. See overlay class documentation for
3510 Pointer to the newly created overlay object or NULL in case of failure.
3513 Default implementation in the base class always sets VOERR_INVSCRMODE error and
3514 returns NULL meaning that hardware overlays are not supported. There's no sense
3515 in software implementation because the software is supposed to handle software
3523 moHidd_Gfx_DisposeOverlay
3527 *****************************************************************************************/
3529 OOP_Object
*GFX__Hidd_Gfx__NewOverlay(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewOverlay
*msg
)
3531 ULONG
*err
= (ULONG
*)GetTagData(aHidd_Overlay_Error
, 0, msg
->attrList
);
3534 *err
= VOERR_INVSCRMODE
;
3539 /*****************************************************************************************
3542 moHidd_Gfx_DisposeOverlay
3545 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeOverlay *msg);
3547 VOID HIDD_Gfx_DisposeOverlay(OOP_Object *gfxHidd, OOP_Object *Overlay)
3550 hidd.graphics.graphics
3553 Deletes an overlay previously created by moHidd_Gfx_NewOverlay.
3555 Subclasses do not have to override this method
3556 unless they allocate anything additional to an overlay object in
3557 their HIDD_Gfx_NewOverlay() implementation.
3560 gfxHidd - A driver object which was used for creating a GC.
3561 Overlay - Pointer to an overlay object to delete.
3576 Basically just does OOP_DisposeObject(Overlay);
3578 *****************************************************************************************/
3580 VOID
GFX__Hidd_Gfx__DisposeOverlay(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_DisposeOverlay
*msg
)
3582 OOP_DisposeObject(msg
->Overlay
);
3585 /*****************************************************************************************
3588 moHidd_Gfx_MakeViewPort
3591 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_MakeViewPort *msg);
3593 ULONG HIDD_Gfx_MakeViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3596 hidd.graphics.graphics
3599 Performs driver-specific setup on a given ViewPort.
3602 gfxHidd - A display driver object.
3603 data - a pointer to a HIDD_ViewPortDats structure.
3606 The same code as used as return value for graphics.library/MakeVPort().
3609 When graphics.library calls this method, a complete view is not built yet.
3610 This means that data->Next pointer contains invalid data and needs to be
3613 It is valid to keep private data pointer in data->UserData accross calls.
3614 Newly created HIDD_ViewPortData is guraranteed to have NULL there.
3621 moHidd_Gfx_CleanViewPort
3624 Base class implementation just does nothing. This function is mainly intended
3625 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3627 *****************************************************************************************/
3629 ULONG
GFX__Hidd_Gfx__MakeViewPort(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_MakeViewPort
*msg
)
3631 D(bug("Gfx::MakeViewPort: object 0x%p, data 0x%p\n", o
, msg
->Data
));
3636 /*****************************************************************************************
3639 moHidd_Gfx_CleanViewPort
3642 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CleanViewPort *msg);
3644 ULONG HIDD_Gfx_CleanViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3647 hidd.graphics.graphics
3650 Performs driver-specific cleanup on a given ViewPort.
3653 gfxHidd - A display driver object.
3654 data - a pointer to a HIDD_ViewPortDats structure.
3657 The same code as used as return value for graphics.library/MakeVPort().
3660 When graphics.library calls this method, the ViewPort is already unlinked
3661 from its view, and the bitmap can already be deallocated.
3662 This means that both data->Next and data->Bitmap pointers can contain invalid
3670 moHidd_Gfx_MakeViewPort
3673 Base class implementation just does nothing. This function is mainly intended
3674 to provide support for copperlist disposal by Amiga(tm) chipset driver.
3676 *****************************************************************************************/
3678 void GFX__Hidd_Gfx__CleanViewPort(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CleanViewPort
*msg
)
3680 D(bug("Gfx::CleanViewPort: object 0x%p, data 0x%p\n", o
, msg
->Data
));
3683 /*****************************************************************************************
3686 moHidd_Gfx_PrepareViewPorts
3689 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_PrepareViewPorts *msg);
3691 ULONG HIDD_Gfx_PrepareViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view)
3694 hidd.graphics.graphics
3697 Performs driver-specific setup on a given view.
3700 gfxHidd - A display driver object.
3701 data - a pointer to a chain of HIDD_ViewPortData structures.
3702 view - A pointer to graphics.library View structure being prepared.
3705 MCOP_OK if there was no error or MCOP_NO_MEM otherwise.
3706 MCOP_NOP is not allowed as a return value of this method.
3709 graphics.library calls this method in MrgCop() after the complete view
3710 is built. data->Next pointer contains valid data.
3712 This function can be repeatedly called several times, and there is no
3713 cleanup counterpart for it. This should be taken into account in method
3723 Base class implementation just does nothing. This function is mainly intended
3724 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3726 *****************************************************************************************/
3728 ULONG
GFX__Hidd_Gfx__PrepareViewPorts(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ShowViewPorts
*msg
)
3735 /****************************************************************************************/
3737 static int GFX_ClassInit(LIBBASETYPEPTR LIBBASE
)
3739 struct class_static_data
*csd
= &LIBBASE
->hdg_csd
;
3741 __IHidd_PixFmt
= OOP_ObtainAttrBase(IID_Hidd_PixFmt
);
3742 __IHidd_BitMap
= OOP_ObtainAttrBase(IID_Hidd_BitMap
);
3743 __IHidd_Gfx
= OOP_ObtainAttrBase(IID_Hidd_Gfx
);
3744 __IHidd_Sync
= OOP_ObtainAttrBase(IID_Hidd_Sync
);
3745 __IHidd_GC
= OOP_ObtainAttrBase(IID_Hidd_GC
);
3746 __IHidd_Overlay
= OOP_ObtainAttrBase(IID_Hidd_Overlay
);
3747 __IHidd_ColorMap
= OOP_ObtainAttrBase(IID_Hidd_ColorMap
);
3748 __IHidd_PlanarBM
= OOP_ObtainAttrBase(IID_Hidd_PlanarBM
);
3749 __IHidd_ChunkyBM
= OOP_ObtainAttrBase(IID_Hidd_ChunkyBM
);
3751 if (!__IHidd_PixFmt
||
3756 !__IHidd_ColorMap
||
3757 !__IHidd_PlanarBM
||
3764 D(bug("Creating std pixelfmts\n"));
3765 if (!create_std_pixfmts(csd
))
3767 D(bug("Pixfmts created\n"));
3769 /* Get two methodis required for direct method execution */
3770 #if USE_FAST_PUTPIXEL
3771 csd
->putpixel_mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_PutPixel
);
3773 #if USE_FAST_GETPIXEL
3774 csd
->getpixel_mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_GetPixel
);
3776 #if USE_FAST_DRAWPIXEL
3777 csd
->drawpixel_mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_DrawPixel
);
3780 ReturnInt("init_gfxhiddclass", ULONG
, TRUE
);
3783 ReturnInt("init_gfxhiddclass", ULONG
, FALSE
);
3786 /****************************************************************************************/
3788 static int GFX_ClassFree(LIBBASETYPEPTR LIBBASE
)
3790 struct class_static_data
*csd
= &LIBBASE
->hdg_csd
;
3792 EnterFunc(bug("free_gfxhiddclass(csd=%p)\n", csd
));
3796 delete_pixfmts(csd
);
3798 OOP_ReleaseAttrBase(IID_Hidd_PixFmt
);
3799 OOP_ReleaseAttrBase(IID_Hidd_BitMap
);
3800 OOP_ReleaseAttrBase(IID_Hidd_Gfx
);
3801 OOP_ReleaseAttrBase(IID_Hidd_Sync
);
3802 OOP_ReleaseAttrBase(IID_Hidd_GC
);
3803 OOP_ReleaseAttrBase(IID_Hidd_Overlay
);
3804 OOP_ReleaseAttrBase(IID_Hidd_ColorMap
);
3805 OOP_ReleaseAttrBase(IID_Hidd_PlanarBM
);
3806 OOP_ReleaseAttrBase(IID_Hidd_ChunkyBM
);
3809 ReturnInt("free_gfxhiddclass", BOOL
, TRUE
);
3812 /****************************************************************************************/
3814 ADD2INITLIB(GFX_ClassInit
, 0)
3815 ADD2EXPUNGELIB(GFX_ClassFree
, 0)
3817 /****************************************************************************************/
3819 /* Since the shift/mask values of a pixel format are designed for pixel
3820 access, not byte access, they are endianess dependant */
3823 #include "stdpixfmts_be.h"
3825 #include "stdpixfmts_le.h"
3828 /****************************************************************************************/
3830 static BOOL
create_std_pixfmts(struct class_static_data
*csd
)
3833 struct pixfmt_data
*pf
;
3835 memset(csd
->std_pixfmts
, 0, sizeof (OOP_Object
*) * num_Hidd_StdPixFmt
);
3837 for (i
= 0; i
< num_Hidd_StdPixFmt
; i
++)
3839 pf
= (struct pixfmt_data
*)create_and_init_object(csd
->pixfmtclass
, (UBYTE
*)&stdpfs
[i
], sizeof (stdpfs
[i
]), csd
);
3843 D(bug("FAILED TO CREATE PIXEL FORMAT %d\n", i
));
3844 delete_pixfmts(csd
);
3845 ReturnBool("create_stdpixfmts", FALSE
);
3848 csd
->std_pixfmts
[i
] = &pf
->pf
;
3849 /* We don't use semaphore protection here because we do this only during class init stage */
3851 AddTail((struct List
*)&csd
->pflist
, (struct Node
*)&pf
->node
);
3853 ReturnBool("create_stdpixfmts", TRUE
);
3856 /****************************************************************************************/
3858 static VOID
delete_pixfmts(struct class_static_data
*csd
)
3860 struct Node
*n
, *safe
;
3862 ForeachNodeSafe(&csd
->pflist
, n
, safe
)
3863 OOP_DisposeObject((OOP_Object
*)PIXFMT_OBJ(n
));
3866 /****************************************************************************************/
3868 static inline BOOL
cmp_pfs(HIDDT_PixelFormat
*tmppf
, HIDDT_PixelFormat
*dbpf
)
3870 /* Just compare everything except stdpixfmt */
3871 /* Compare flags first (because it's a fast check) */
3872 if (tmppf
->flags
!= dbpf
->flags
)
3874 /* If they match, compare the rest of things */
3875 return !memcmp(tmppf
, dbpf
, offsetof(HIDDT_PixelFormat
, stdpixfmt
));
3878 /****************************************************************************************/
3881 Parses the tags supplied in 'tags' and puts the result into 'pf'.
3882 It also checks to see if all needed attrs are supplied.
3883 It uses 'attrcheck' for this, so you may find attrs outside
3884 of this function, and mark them as found before calling this function
3887 #define PFAF(x) (1L << aoHidd_PixFmt_ ## x)
3888 #define PF_COMMON_AF ( PFAF(Depth) | PFAF(BitsPerPixel) | PFAF(BytesPerPixel) \
3889 | PFAF(ColorModel) | PFAF(BitMapType) )
3891 #define PF_TRUECOLOR_AF ( PFAF(RedMask) | PFAF(GreenMask) | PFAF(BlueMask) | PFAF(AlphaMask) | \
3892 PFAF(RedShift) | PFAF(GreenShift) | PFAF(BlueShift) | PFAF(AlphaShift))
3894 #define PF_PALETTE_AF ( PFAF(CLUTMask) | PFAF(CLUTShift) | PFAF(RedMask) | PFAF(GreenMask) | \
3897 #define PFAO(x) (aoHidd_PixFmt_ ## x)
3899 /****************************************************************************************/
3901 BOOL
parse_pixfmt_tags(struct TagItem
*tags
, HIDDT_PixelFormat
*pf
,
3902 ULONG
ATTRCHECK(pixfmt
), struct class_static_data
*csd
)
3904 IPTR attrs
[num_Hidd_PixFmt_Attrs
] = {0};
3906 if (0 != OOP_ParseAttrs(tags
, attrs
, num_Hidd_PixFmt_Attrs
,
3907 &ATTRCHECK(pixfmt
), HiddPixFmtAttrBase
))
3909 D(bug("!!! parse_pixfmt_tags: ERROR PARSING TAGS THROUGH OOP_ParseAttrs !!!\n"));
3913 if (PF_COMMON_AF
!= (PF_COMMON_AF
& ATTRCHECK(pixfmt
)))
3915 D(bug("!!! parse_pixfmt_tags: Missing PixFmt attributes passed to parse_pixfmt_tags(): %x !!!\n", ATTRCHECK(pixfmt
)));
3919 /* Set the common attributes */
3920 pf
->depth
= attrs
[PFAO(Depth
)];
3921 pf
->size
= attrs
[PFAO(BitsPerPixel
)];
3922 pf
->bytes_per_pixel
= attrs
[PFAO(BytesPerPixel
)];
3923 /* Fill in only real StdPixFmt specification. Special values (Native and Native32)
3924 are not allowed here */
3925 if (attrs
[PFAO(StdPixFmt
)] >= num_Hidd_PseudoStdPixFmt
)
3926 pf
->stdpixfmt
= attrs
[PFAO(StdPixFmt
)];
3928 SET_PF_COLMODEL( pf
, attrs
[PFAO(ColorModel
)]);
3929 SET_PF_BITMAPTYPE(pf
, attrs
[PFAO(BitMapType
)]);
3931 if (ATTRCHECK(pixfmt
) & PFAF(SwapPixelBytes
))
3933 SET_PF_SWAPPIXELBYTES_FLAG(pf
, attrs
[PFAO(SwapPixelBytes
)]);
3936 /* Set the colormodel specific stuff */
3937 switch (HIDD_PF_COLMODEL(pf
))
3939 case vHidd_ColorModel_TrueColor
:
3940 /* Check that we got all the truecolor describing stuff */
3941 if (PF_TRUECOLOR_AF
!= (PF_TRUECOLOR_AF
& ATTRCHECK(pixfmt
)))
3943 D(bug("!!! Unsufficient true color format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
3947 /* Set the truecolor stuff */
3948 pf
->red_mask
= attrs
[PFAO(RedMask
)];
3949 pf
->green_mask
= attrs
[PFAO(GreenMask
)];
3950 pf
->blue_mask
= attrs
[PFAO(BlueMask
)];
3951 pf
->alpha_mask
= attrs
[PFAO(AlphaMask
)];
3953 pf
->red_shift
= attrs
[PFAO(RedShift
)];
3954 pf
->green_shift
= attrs
[PFAO(GreenShift
)];
3955 pf
->blue_shift
= attrs
[PFAO(BlueShift
)];
3956 pf
->alpha_shift
= attrs
[PFAO(AlphaShift
)];
3959 case vHidd_ColorModel_Palette
:
3960 case vHidd_ColorModel_StaticPalette
:
3961 if ( PF_PALETTE_AF
!= (PF_PALETTE_AF
& ATTRCHECK(pixfmt
)))
3963 D(bug("!!! Unsufficient palette format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
3967 /* set palette stuff */
3968 pf
->clut_mask
= attrs
[PFAO(CLUTMask
)];
3969 pf
->clut_shift
= attrs
[PFAO(CLUTShift
)];
3971 pf
->red_mask
= attrs
[PFAO(RedMask
)];
3972 pf
->green_mask
= attrs
[PFAO(GreenMask
)];
3973 pf
->blue_mask
= attrs
[PFAO(BlueMask
)];
3977 } /* shift (colormodel) */
3982 /****************************************************************************************/
3985 Create an empty object and initialize it the "ugly" way. This only works with
3986 CLID_Hidd_PixFmt and CLID_Hidd_Sync classes
3989 /****************************************************************************************/
3991 static OOP_Object
*create_and_init_object(OOP_Class
*cl
, UBYTE
*data
, ULONG datasize
,
3992 struct class_static_data
*csd
)
3996 o
= OOP_NewObject(cl
, NULL
, NULL
);
3999 D(bug("!!! UNABLE TO CREATE OBJECT IN create_and_init_object() !!!\n"));
4003 memcpy(o
, data
, datasize
);
4008 /****************************************************************************************/
4010 static struct pixfmt_data
*find_pixfmt(HIDDT_PixelFormat
*tofind
, struct class_static_data
*csd
)
4012 struct pixfmt_data
*retpf
= NULL
;
4013 HIDDT_PixelFormat
*db_pf
;
4016 /* Go through the pixel format list to see if a similar pf allready exists */
4017 ObtainSemaphoreShared(&csd
->pfsema
);
4019 ForeachNode(&csd
->pflist
, n
)
4021 db_pf
= PIXFMT_OBJ(n
);
4022 DPF(bug("find_pixfmt(): Trying pixelformat 0x%p\n", db_pf
));
4023 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n",
4024 db_pf
->red_shift
, db_pf
->green_shift
, db_pf
->blue_shift
, db_pf
->alpha_shift
,
4025 db_pf
->red_mask
, db_pf
->green_mask
, db_pf
->blue_mask
, db_pf
->alpha_mask
,
4026 db_pf
->bytes_per_pixel
, db_pf
->size
, db_pf
->depth
, db_pf
->stdpixfmt
));
4027 if (cmp_pfs(tofind
, db_pf
))
4029 DPF(bug("Match!\n"));
4030 retpf
= (struct pixfmt_data
*)db_pf
;
4035 ReleaseSemaphore(&csd
->pfsema
);
4039 /****************************************************************************************/
4041 /* Stubs for private methods */
4043 /****************************************************************************************/
4045 OOP_Object
*HIDD_Gfx_RegisterPixFmt(OOP_Object
*o
, struct TagItem
*pixFmtTags
)
4048 struct pHidd_Gfx_RegisterPixFmt p
, *msg
= &p
;
4050 if (!static_mid
) static_mid
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_RegisterPixFmt
);
4054 p
.pixFmtTags
= pixFmtTags
;
4056 return (OOP_Object
*)OOP_DoMethod(o
, (OOP_Msg
)msg
);
4060 /****************************************************************************************/
4062 VOID
HIDD_Gfx_ReleasePixFmt(OOP_Object
*o
, OOP_Object
*pixFmt
)
4065 struct pHidd_Gfx_ReleasePixFmt p
, *msg
= &p
;
4067 if (!static_mid
) static_mid
= OOP_GetMethodID(IID_Hidd_Gfx
, moHidd_Gfx_ReleasePixFmt
);
4073 OOP_DoMethod(o
, (OOP_Msg
)msg
);
4077 /****************************************************************************************/