2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Gfx Hidd driver class implementation.
9 /****************************************************************************************/
11 #include "gfx_debug.h"
13 #include <aros/atomic.h>
14 #include <aros/debug.h>
15 #include <aros/symbolsets.h>
16 #include <aros/config.h>
17 #include <cybergraphx/cgxvideo.h>
18 #include <exec/lists.h>
19 #include <oop/static_mid.h>
20 #include <graphics/displayinfo.h>
21 #include <graphics/view.h>
23 #include "gfx_intern.h"
28 #include <proto/exec.h>
29 #include <proto/utility.h>
30 #include <proto/oop.h>
31 #include <exec/libraries.h>
32 #include <exec/memory.h>
34 #include <utility/tagitem.h>
36 #include LC_LIBDEFS_FILE
40 /*****************************************************************************************
43 --background_graphics--
49 When working with graphics drivers this is the first object you get.
50 It allows you to create BitMap and GC (graphics context)
51 object. The class' methods must be overidden by hardware-specific
52 subclasses where documented to do so.
54 *****************************************************************************************/
56 /*****************************************************************************************
65 Each display driver object internally stores a database of supported display mode
66 IDs. This database is normally managed by base class, the driver does not need to
67 reimplement respective methods.
69 A display mode ID in AROS is a 32-bit integer value, the same as on AmigaOS(tm).
70 However mode ID layout introduced by Commodore does not fit well for RTG systems.
71 In order to overcome its limitations, display ID on AROS may have two forms:
73 1. A chipset mode ID. These are standard IDs defined by Commodore. You may find
74 their definitions in graphics/modeid.h.
78 An RTG mode ID is composed of three parts in the form:
82 nnnn - monitor ID. This number is maintained by system libraries. IDs are
83 assigned in the order in which drivers are loaded and display hardware is
84 found. Drivers do not have to care about this part, and should normally
85 mask it out if they for some reason look at mode ID. In order to
86 distinguish between chipset mode IDs and RTG mode IDs, order number starts
87 not from zero, reserving some space for C= chipset mode IDs (which appear
88 to have order numbers from 0x0000 to 0x000A). Currently RTG monitor IDs
89 start from 0x0010, however with time this value may change. So don't rely
90 on some particular values in RTG IDs. Use cybergraphics.library/IsCyberModeID()
91 function if you want to know for sure if the given mode ID belongs to an
94 xx - A sync object index in driver's mode database.
95 yy - A pixelformat object in driver's mode database.
97 Normally the driver does not have to care about mode ID decoding. The mode
98 database is maintained by base class. The only useful things for the driver are
99 sync and pixelformat objects, from which it's possible to get different
100 information about the mode. They can be obtained from the base class using
103 Note that the driver object by itself does not know its monitor ID. Different
104 displays are served by different objects, any of which may belong to any class.
105 So all driver methods which return mode IDs will set monitor ID to zero. All
106 methods that take mode ID as argument are expected to ignore the monitor ID part
107 and do not make any assumptions about its value.
109 *****************************************************************************************/
111 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
);
113 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
);
114 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
);
116 static struct pixfmt_data
*find_pixfmt(HIDDT_PixelFormat
*tofind
117 , struct class_static_data
*_csd
);
119 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
120 , OOP_Object
*dst_bm
, UWORD width
, UWORD height
);
122 BOOL
parse_pixfmt_tags(struct TagItem
*tags
, HIDDT_PixelFormat
*pf
, ULONG attrcheck
, struct class_static_data
*_csd
);
124 /****************************************************************************************/
126 #define COMPUTE_HIDD_MODEID(sync, pf) \
127 ( ((sync) << 8) | (pf) )
129 #define MODEID_TO_SYNCIDX(id) (((id) & 0X0000FF00) >> 8)
130 #define MODEID_TO_PFIDX(id) ( (id) & 0x000000FF)
132 /****************************************************************************************/
134 OOP_Object
*GFXHIDD__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
136 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
137 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
138 struct TagItem gctags
[] =
140 {aHidd_GC_Foreground
, 0},
143 struct TagItem new_tags
[] =
146 {aHidd_HardwareName
, 0 },
147 {aHidd_ProducerName
, 0 },
148 {TAG_MORE
, (IPTR
)msg
->attrList
}
150 struct pRoot_New new_msg
=
156 D(bug("Entering gfx.hidd::New\n"));
158 new_tags
[0].ti_Data
= GetTagData(aHidd_Name
, (IPTR
)"gfx.hidd", msg
->attrList
);
159 new_tags
[1].ti_Data
= GetTagData(aHidd_HardwareName
, (IPTR
)"Software Rasterizer", msg
->attrList
);
160 new_tags
[2].ti_Data
= GetTagData(aHidd_ProducerName
, (IPTR
)"The AROS development team", msg
->attrList
);
162 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)&new_msg
);
164 D(bug("Got object o=%x\n", o
));
168 struct HiddGfxData
*data
= OOP_INST_DATA(cl
, o
);
169 struct TagItem
*tstate
= msg
->attrList
;
170 struct TagItem
*modetags
= NULL
;
174 InitSemaphore(&data
->mdb
.sema
);
175 InitSemaphore(&data
->fbsem
);
178 D(bug("[GFX] attrList 0x%p\n", msg
->attrList
));
180 while ((tag
= NextTagItem(&tstate
)))
184 Hidd_Gfx_Switch(tag
->ti_Tag
, idx
)
186 case aoHidd_Gfx_ModeTags
:
187 modetags
= (struct TagItem
*)tag
->ti_Data
;
190 case aoHidd_Gfx_FrameBufferType
:
191 data
->fbmode
= tag
->ti_Data
;
196 /* Register modes only after other attributes are initialized */
197 ok
= modetags
? register_modes(cl
, o
, modetags
) : TRUE
;
199 /* Create a gc that we can use for some rendering */
202 data
->gc
= OOP_NewObject(CSD(cl
)->gcclass
, NULL
, gctags
);
203 if (NULL
== data
->gc
)
205 D(bug("Could not get gc\n"));
212 OOP_MethodID dispose_mid
= msg
->mID
- moRoot_New
+ moRoot_Dispose
;
215 OOP_CoerceMethod(cl
, o
, &dispose_mid
);
220 D(bug("Leaving gfx.hidd::New o=%x\n", o
));
224 /****************************************************************************************/
226 VOID
GFXHIDD__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
228 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
229 struct HiddGfxData
*data
;
231 data
= OOP_INST_DATA(cl
, o
);
233 /* free the mode db stuff */
234 free_mode_db(&data
->mdb
, cl
);
236 /* Here we should unregister pixelformats registered in our New().
237 However gfx drivers aren't supposed to be removed, so it's okay
238 not to do it at all for now. */
240 if (NULL
!= data
->gc
)
241 OOP_DisposeObject(data
->gc
);
243 OOP_DoSuperMethod(cl
, o
, msg
);
246 /*****************************************************************************************
249 aoHidd_Gfx_IsWindowed
258 Tells if the display driver is using hosted display in host OS' window, and mouse
259 input is handled by host OS.
261 Windowed displays may send activation events to AROS. This is needed in order to
262 correctly handle display switch in a multi-display configuration (which means that
263 the user has multiple windows on host OS desktop and can freely switch between them).
266 Even in fullscreen mode drivers should still return TRUE if the host OS manages mouse
267 input (for example, X11 driver). If mouse input is not managed by the host OS
268 (for example, with Linux framebuffer driver), return FALSE.
275 aoHidd_Gfx_ActiveCallBack, aoHidd_Gfx_ActiveCallBackData
278 Base class always provides FALSE value
280 *****************************************************************************************/
282 /*****************************************************************************************
288 [ISG], HIDDT_DPMSLevel
294 Gets or sets current DPMS level for driver's display.
295 A value can be one of:
296 vHidd_Gfx_DPMSLevel_On,
297 vHidd_Gfx_DPMSLevel_Standby,
298 vHidd_Gfx_DPMSLevel_Suspend,
299 vHidd_Gfx_DPMSLevel_Off
301 If the driver does not support some state, it's up to the driver what to do.
302 Usually it is expected to ignore the request.
304 Getting this attribute should return real current state.
315 Base class always provides vHidd_Gfx_DPMSLevel_On value (comes from rootclass'
316 Get() which sets the value to 0).
318 *****************************************************************************************/
320 /*****************************************************************************************
326 [I..], struct TagItem *
332 Specify a pointer to a taglist which contains description of display modes
333 supported by the driver.
335 This attribute is usually appended in moRoot_New method of the display driver
338 This attribute is mandatory for the base class, otherwise driver object creation
341 Mode description taglist may contain the following tags:
342 - Any sync attributes - these attributes will specify values common for all sync
344 - Any pixelformat attributes - these attributes will specify values common for
345 all pixelformat modes
346 - aoHidd_Gfx_SyncTags - specifies a pointer to another separate taglist containing
347 attributes for one sync (display) mode. If this tag
348 is not supplied at all, a set of default modes will be
349 generated for the driver.
350 - aoHidd_Gfx_PixFmtTags - specifies a pointer to another separate taglist containing
351 attributes for one pixelformat. This tag must be supplied
352 at least once, otherwise driver object will fail to create.
354 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags can be specified multiple times in
355 order to associate more than one display mode with the driver. Note that common
356 values for sync and pixelformat objects need to be placed in the taglist before
357 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags. You may specify them again between
358 these tags in order to alter common values.
363 Partial example code of display driver supporting a truecolor display with three
366 // Our pixelformat (24-bit 0BGR)
367 struct TagItem pftags[] =
369 { aHidd_PixFmt_RedShift , 24 },
370 { aHidd_PixFmt_GreenShift , 16 },
371 { aHidd_PixFmt_BlueShift , 8 },
372 { aHidd_PixFmt_AlphaShift , 0 },
373 { aHidd_PixFmt_RedMask , 0x000000FF },
374 { aHidd_PixFmt_GreenMask , 0x0000FF00 },
375 { aHidd_PixFmt_BlueMask , 0x00FF0000 },
376 { aHidd_PixFmt_AlphaMask , 0x00000000 },
377 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_TrueColor },
378 { aHidd_PixFmt_Depth , 24 },
379 { aHidd_PixFmt_BytesPerPixel, 4 },
380 { aHidd_PixFmt_BitsPerPixel , 24 },
381 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Native },
382 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Chunky },
386 // 640x480 resolution
387 struct TagItem tags_800_600[] =
389 { aHidd_Sync_HDisp , 640 },
390 { aHidd_Sync_VDisp , 480 },
394 // 800x600 resolution
395 struct TagItem tags_800_600[] =
397 { aHidd_Sync_HDisp , 800 },
398 { aHidd_Sync_VDisp , 600 },
402 // 1024x768 resolution
403 struct TagItem tags_1024_768[] =
405 { aHidd_Sync_HDisp , 1024 },
406 { aHidd_Sync_VDisp , 768 },
410 // Mode description taglist itself
411 struct TagItem mode_tags[] =
413 // Our driver supports a single pixelformat
414 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
416 // Here go sync values common for all sync modes
417 { aHidd_Sync_HMin , 112 },
418 { aHidd_Sync_VMin , 112 },
419 { aHidd_Sync_HMax , 16384 },
420 { aHidd_Sync_VMax , 16384 },
421 { aHidd_Sync_Description, (IPTR)"Example: %hx%v" },
424 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
426 // Next two syncs will have HMax = 32768, as an example
427 { aHidd_Sync_HMax , 32768 },
429 // Two more resolutions
430 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
431 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
435 // This is the attribute list which is given to New method
437 struct TagItem mytags[] =
439 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
449 *****************************************************************************************/
451 /*****************************************************************************************
463 Gets total number of sync objects in the internal display mode database.
476 *****************************************************************************************/
478 /*****************************************************************************************
481 aoHidd_Gfx_SupportsHWCursor
490 Tells whether the driver supports hardware mouse pointer sprite.
492 If the driver provides TRUE value for this attribute, it is expected to implement
493 HIDD_Gfx_SetCursorPos(), HIDD_Gfx_SetCursorShape() and HIDD_Gfx_SetCursorVisible()
496 Mouse pointer counts for one hardware sprite, so if the driver implements also
497 HIDD_Gfx_ModeProperties(), it should set NumHWSprites to 1 in order to provide
498 valid information about display modes.
500 The driver must implement this attribute if it implements HIDD_Gfx_ModeProperties().
501 Otherwise it will provide false information in graphics.library/GetDisplayInfoData().
502 Base class can determine NumHWSprites based on this attribute value but not vice
506 Default implementation in the base class returns FALSE. This causes the system to
507 use software sprite emulation.
509 This attribute is obsolete and is used only by AROS graphics.library up to v41.2. In
510 new drivers consider implementing aoHidd_Gfx_HWSpriteTypes attribute.
517 aoHidd_Gfx_HWSpriteTypes, moHidd_Gfx_ModeProperties
521 *****************************************************************************************/
523 /*****************************************************************************************
526 aoHidd_Gfx_NoFrameBuffer
535 Tells whether the driver does not need a framebuffer.
537 Since v1.2 this attribute is obsolete. Please use aoHidd_Gfx_FrameBufferType
541 Provides FALSE if not implemented in the driver.
548 aoHidd_Gfx_FrameBufferType, moHidd_Gfx_Show
552 *****************************************************************************************/
554 /*****************************************************************************************
557 aoHidd_Gfx_HWSpriteTypes
566 Return hardware sprite image types supported by the driver.
568 The returned value is a combination of the following bit flags:
569 vHidd_SpriteType_3Plus1 - color 0 is transparent, 1-3 visible
570 (Amiga(tm) chipset sprite format)
571 vHidd_SpriteType_2Plus1 - color 0 is transparent, color 1 is undefined
572 (can be whatever, for example clear or inverse),
574 vHidd_SpriteType_DirectColor - Hi- or truecolor image, or LUT image with own
575 palette, perhaps with alpha channel
578 This attribute should return 0 if the driver does not support hardware mouse sprite
579 at all. Software sprite emulation is done by graphics.library.
581 Default implementation in the base class is based on aoHidd_Gfx_SupportsHWCursor
582 value. This is done for backwards compatibility.
589 aoHidd_Gfx_SupportsHWCursor
592 Default implementation in the base class queries aoHidd_Gfx_SupportsHWCursor
593 and provides (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) in case
594 if it returns TRUE. Otherwise it returns zero. This is done for backwards
595 compatibility with old drivers.
597 *****************************************************************************************/
599 /*****************************************************************************************
602 aoHidd_Gfx_MemorySize
611 Query total size of video card memory in bytes.
620 aoHidd_Gfx_MemoryClock
624 *****************************************************************************************/
626 /*****************************************************************************************
629 aoHidd_Gfx_MemoryClock
638 Query video card's memory clock in Hz. 0 is a valid value meaning 'unknown'.
647 aoHidd_Gfx_MemorySize
651 *****************************************************************************************/
653 /*****************************************************************************************
656 aoHidd_Gfx_DriverName
665 Query CyberGraphX driver name. It is the same name which can be given to
666 cybergraphics.library/BestCModeIDTagList() as CYBRBIDTG_BoardName value.
669 By default base class returns class name as value of this attribute.
670 However this can (and must for some drivers listed in BestCModeIDTagList()
671 documentation) be overriden.
681 *****************************************************************************************/
683 /*****************************************************************************************
686 aoHidd_Gfx_ActiveCallBack
689 [.S.], void (*)(APTR userdata, OOP_Object *bitmap)
695 Set display activation interrupt handler.
697 This handler needs to be called by hosted display driver, if host OS
698 windowing system is used for the display and mouse input is handled by the
701 This way the driver can tell AROS when a display window has been activated so that
702 AROS will be able to switch current display correctly when working in a multi-display
705 The function uses C calling convention and needs to be declared as follows:
707 void ActivationHandler(APTR userdata, OOP_Object *bitmap);
709 Parameters of this function will be:
710 userdata - Whatever is specified by aoHidd_Gfx_ActiveCallBackData attribute.
711 bitmap - Currently reserved. Drivers need to set it to NULL.
713 The function can be called from within an interrupt, so usual restrictions apply
716 Set this attribute to NULL in order to disable activation handling.
719 When setting the activation callback function, be sure that you set correct
720 userdata before you actually set the callback pointer. Otherwise your callback
721 can be called with wrong data pointer.
723 Only one activation handler can be installed. Installing a new handler replaces
726 Native displays do not need to implement this attribute because there can be
727 no external activation events.
734 aoHidd_Gfx_ActiveCallBackData, aoHidd_Gfx_IsWindowed
737 This attribute needs to be implemented by the display driver. Base class contains
740 *****************************************************************************************/
742 /*****************************************************************************************
745 aoHidd_Gfx_ActiveCallBackData
754 Set user-defined data pointer for display activation handler.
763 aoHidd_Gfx_ActiveCallBack
766 This attribute needs to be implemented by the display driver. Base class contains
769 *****************************************************************************************/
771 /*****************************************************************************************
783 Get a pointer to shared default GC object.
786 The returned GC is preset to the following:
794 You must not alter these settings even temporarily, because this GC is shared between
795 bitmaps and between different tasks which may perform the rendering into different
796 regions of the same bitmap (two windows on one screen, for example). This GC is intended
797 to be used for internal copying operations.
804 aoHidd_Gfx_ActiveCallBack
807 This attribute needs to be implemented by the display driver. Base class contains
810 *****************************************************************************************/
812 static UBYTE
get_fbmode(OOP_Class
*cl
, OOP_Object
*o
)
814 struct HiddGfxData
*data
= OOP_INST_DATA(cl
, o
);
816 if (data
->fbmode
== -1)
818 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
821 * This attribute has never been set.
822 * Fall back to obsolete NoFrameBuffer.
824 data
->fbmode
= OOP_GET(o
, aHidd_Gfx_NoFrameBuffer
) ? vHidd_FrameBuffer_None
: vHidd_FrameBuffer_Direct
;
830 /*****************************************************************************************
833 aoHidd_Gfx_FrameBufferType
842 Specifies fixed framebuffer type used by the driver. The value can be one of the following:
844 vHidd_FrameBuffer_None - the driver does not use framebuffer.
845 vHidd_FrameBuffer_Direct - the driver uses framefuffer which can be accessed
846 directly for both reads and writes.
847 vHidd_FrameBuffer_Mirrored - the driver uses write-only framebuffer.
849 This attribute has to be specified during driver object creation. If this is not done,
850 the OS will use value of old aoHidd_Gfx_NoFrameBuffer attribute in order to distinguish
851 between vHidd_FrameBuffer_Direct (for FALSE) and vHidd_FrameBuffer_None (for TRUE).
854 A fixed framebuffer is a special bitmap in a fixed area of video RAM. If the
855 framebuffer is used, the driver is expected to copy a new bitmap into it in
856 HIDD_Gfx_Show() and optionally copy old bitmap back.
858 A framebuffer is needed if the hardware does not have enough VRAM to store many
859 bitmaps or does not have capabilities to switch the display between various VRAM
862 Some hardware suffers from slow VRAM reading. In this case you should use mirrored
863 mode. If you use it, the system will hold a bitmap in the memory buffer, and
864 update VRAM on demand (hence the name).
866 An example of driver using a framebuffer is hosted SDL driver. By design SDL works
867 only with single display window, which is considered a framebuffer.
874 aoHidd_Gfx_NoFrameBuffer
878 *****************************************************************************************/
880 /*****************************************************************************************
883 aoHidd_Gfx_SupportsGamma
892 Specifies if the driver supports gamma correction tables. Default implementation
893 in base class returns FALSE.
906 *****************************************************************************************/
908 VOID
GFXHIDD__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
910 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
911 struct HiddGfxData
*data
= OOP_INST_DATA(cl
, o
);
914 Hidd_Gfx_Switch (msg
->attrID
, idx
)
916 case aoHidd_Gfx_NumSyncs
:
917 *msg
->storage
= data
->mdb
.num_syncs
;
920 case aoHidd_Gfx_IsWindowed
:
921 case aoHidd_Gfx_SupportsHWCursor
:
922 case aoHidd_Gfx_SupportsGamma
:
926 case aoHidd_Gfx_HWSpriteTypes
:
927 /* Fall back to obsolete SupportsHWCursor */
928 *msg
->storage
= OOP_GET(o
, aHidd_Gfx_SupportsHWCursor
) ? (vHidd_SpriteType_3Plus1
|vHidd_SpriteType_DirectColor
) : 0;
931 case aoHidd_Gfx_DriverName
:
932 *msg
->storage
= (IPTR
)OOP_OCLASS(o
)->ClassNode
.ln_Name
;
935 case aoHidd_Gfx_DefaultGC
:
936 *msg
->storage
= (IPTR
)data
->gc
;
939 case aoHidd_Gfx_FrameBufferType
:
940 *msg
->storage
= get_fbmode(cl
, o
);
944 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
947 /*****************************************************************************************
950 moHidd_Gfx_NominalDimensions
953 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NominalDimensions *msg);
955 OOP_Object *HIDD_Gfx_NominalDimensions(OOP_Object *gfxHidd, UWORD *width, UWORD *height, UBYTE *depth);
963 gfxHidd - The graphics driver used to create the object.
977 *****************************************************************************************/
978 VOID
GFXHIDD__Hidd_Gfx__NominalDimensions(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NominalDimensions
*msg
)
980 EnterFunc(bug("HIDDGfx::NominalDimensions()\n"));
983 *(msg
->width
) = AROS_NOMINAL_WIDTH
;
985 *(msg
->height
) = AROS_NOMINAL_HEIGHT
;
987 *(msg
->depth
) = AROS_NOMINAL_DEPTH
;
990 /*****************************************************************************************
993 moHidd_Gfx_CreateObject
996 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CreateObject *msg);
998 OOP_Object *HIDD_Gfx_CreateObject(OOP_Object *gfxHidd, OOP_Class *cl, struct TagItem *tagList);
1004 Create a driver specific Gfx Object of the type "classID"
1007 gfxHidd - The graphics driver used to create the object.
1008 cl - The base OOP_Class of the object to be created.
1009 tagList - Object specific attributes.
1012 pointer to the newly created OOP_Object, or NULL on failure.
1015 Drivers should query the gfx.hidd, or support class for the base class Ptr that
1016 the driver objects should use. The gfx hidd itself defines the following -:
1019 A GC object is just used for data storage. It is possible to subclass, however
1020 it is not recommended since it may not be future-proof due to the fact
1021 GC subclasses can not be interchanged between different drivers.
1022 Avoid using custom GCs.
1026 Each graphics driver exposes at least one displayable bitmap class.
1027 More may be exposed at the drivers discretion to represent nondisplayable bitmaps
1028 or other driver specific bitmap types.
1030 Generally bitmap objects are never created directly. Instead they are created
1031 using the HIDD_Gfx_CreateObject() call. An implementation of this method in the
1032 driver should examine bitmap attributes supplied and make a decision if the bitmap
1033 should be created using the driver's own class or one of the system classes.
1035 A typical implementation should pay attention to the following bitmap attributes:
1037 aHIDD_BitMap_ModeID - If this attribute is supplied, the bitmap needs to be
1038 either displayable by this driver, or be a friend of a
1039 displayable bitmap. A friend bitmap usually repeats the
1040 internal layout of its friend so that the driver may
1041 perform blitting operations quickly.
1043 aHIDD_BitMap_Displayable - If this attribute is supplied, the bitmap NEEDS to be
1044 displayable by this driver. Usually this means that
1045 the bitmap object will contain video hardware state
1046 information. This attribute will always be accompanied
1047 by aHIDD_BitMap_ModeID.
1049 aHIDD_BitMap_FrameBuffer - The bitmap needs to be a framebuffer bitmap. A
1050 framebuffer bitmap is necessary for some kinds of
1051 hardware which have a small fixed amount of video
1052 RAM which can hold only one screen at a time. Setting
1053 this attribute requires that a valid ModeID be also set.
1055 aHIDD_BitMap_Friend - If there's no ModeID supplied, you may wish to check class
1056 of friend bitmap. This can be useful if your driver uses
1057 different classes for displayable and non-displayable bitmaps.
1058 By default base class will pick up friend's class and use it
1059 for new bitmap if nothing is specified, here you may override
1062 If a driver wants to specify a custom class for the bitmap being created,
1063 it should pass the aoHidd_BitMap_ClassPtr attribute to the base class.
1064 Bitmap objects should not be directly created, otherwise necessary information
1065 provided by the base class will be missing.
1067 This method must be implemented by the subclass. aHIDD_BitMap_ClassPtr or
1068 aHIDD_BitMap_ClassID must be provided to the base class for a displayable bitmap.
1077 The base class implementation currently does the folliwing in order to determine
1078 a class for a nondisplayable bitmap (in the listed order):
1080 1. Check aHIDD_BitMap_ClassPtr and aHIDD_BitMap_ClassID. If one of them is supplied,
1081 the class is already set by a subclass.
1082 2. Check aHIDD_BitMap_StdPixFmt. If this attribute is supplied, figure out type of
1083 the pixelformat (chunky or planar), and use one of two system's default classes.
1084 3. Check aHIDD_BitMap_Friend. If friend bitmap is supplied, obtain its class from
1085 aHIDD_BitMap_ClassPtr value of friend bitmap.
1086 4. If everything fails, bitmap creation fails too.
1088 This behavior is subject to change, but will maintain backwards compatibility.
1090 *****************************************************************************************/
1091 OOP_Object
*GFXHIDD__Hidd_Gfx__CreateObject(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CreateObject
*msg
)
1093 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1094 struct HiddGfxData
*data
= OOP_INST_DATA(cl
, o
);
1095 OOP_Object
*object
= NULL
;
1097 EnterFunc(bug("HIDDGfx::CreateObject()\n"));
1099 if (msg
->cl
== CSD(cl
)->gcclass
)
1101 object
= OOP_NewObject(NULL
, CLID_Hidd_GC
, msg
->attrList
);
1103 else if (msg
->cl
== CSD(cl
)->bitmapclass
)
1105 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
1107 struct TagItem bmtags
[] =
1109 {aHidd_BitMap_GfxHidd
, 0}, /* 0 */
1110 {aHidd_BitMap_PixFmt
, 0}, /* 1 */
1111 {TAG_IGNORE
, 0}, /* 2 */
1112 {TAG_IGNORE
, 0}, /* 3 */
1113 {TAG_IGNORE
, 0}, /* 4 */
1114 {TAG_IGNORE
, 0}, /* 5 */
1115 {TAG_MORE
, 0}, /* 6 */
1117 struct TagItem
*tag
, *tstate
= msg
->attrList
;
1120 STRPTR classid
= NULL
;
1121 OOP_Class
*classptr
= NULL
;
1122 BOOL displayable
= FALSE
;
1123 BOOL framebuffer
= FALSE
;
1124 HIDDT_StdPixFmt pixfmt
= vHidd_StdPixFmt_Unknown
;
1125 OOP_Object
*friend_bm
= NULL
;
1126 OOP_Object
*sync
= NULL
;
1127 OOP_Object
*pf
= NULL
;
1129 BOOL gotclass
= FALSE
;
1130 BOOL got_width
= FALSE
;
1131 BOOL got_height
= FALSE
;
1132 BOOL got_depth
= FALSE
;
1134 #define BMAO(x) aoHidd_BitMap_ ## x
1135 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
1137 #define BM_DIMS_AF (BMAF(Width) | BMAF(Height))
1139 #define SET_TAG(tags, idx, tag, val) \
1140 tags[idx].ti_Tag = tag ; tags[idx].ti_Data = (IPTR)val;
1142 #define SET_BM_TAG(tags, idx, tag, val) \
1143 SET_TAG(tags, idx, aHidd_BitMap_ ## tag, val)
1145 #define COPY_BM_TAG(tags, idx, tag, obj) \
1146 tags[idx].ti_Tag = aHidd_BitMap_ ## tag; \
1147 OOP_GetAttr(obj, aHidd_BitMap_ ## tag , &tags[idx].ti_Data)
1149 while ((tag
= NextTagItem(&tstate
)))
1151 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
1155 case aoHidd_BitMap_Displayable
:
1156 displayable
= tag
->ti_Data
;
1159 case aoHidd_BitMap_FrameBuffer
:
1160 framebuffer
= tag
->ti_Data
;
1163 case aoHidd_BitMap_Width
:
1167 case aoHidd_BitMap_Height
:
1171 case aoHidd_BitMap_Depth
:
1175 case aoHidd_BitMap_ModeID
:
1176 /* Make sure it is a valid mode, and retrieve sync/pixelformat data */
1177 if (!HIDD_Gfx_GetMode(o
, tag
->ti_Data
, &sync
, &pf
))
1179 D(bug("!!! Gfx::CreateObject: USER PASSED INVALID MODEID !!!\n"));
1184 case aoHidd_BitMap_Friend
:
1185 friend_bm
= (OOP_Object
*)tag
->ti_Data
;
1188 case aoHidd_BitMap_PixFmt
:
1189 D(bug("!!! Gfx::CreateObject: USER IS NOT ALLOWED TO PASS aHidd_BitMap_PixFmt !!!\n"));
1192 case aoHidd_BitMap_StdPixFmt
:
1193 pixfmt
= tag
->ti_Data
;
1196 case aoHidd_BitMap_ClassPtr
:
1197 classptr
= (OOP_Class
*)tag
->ti_Data
;
1201 case aoHidd_BitMap_ClassID
:
1202 classid
= (STRPTR
)tag
->ti_Data
;
1209 /* If we have a friend bitmap, we can inherit some attributes from it */
1214 COPY_BM_TAG(bmtags
, 2, Width
, friend_bm
);
1220 COPY_BM_TAG(bmtags
, 3, Height
, friend_bm
);
1226 COPY_BM_TAG(bmtags
, 4, Depth
, friend_bm
);
1232 /* FrameBuffer implies Displayable */
1233 SET_BM_TAG(bmtags
, 5, Displayable
, TRUE
);
1236 else if (displayable
)
1239 * Displayable, but not framebuffer (user's screen).
1240 * If we are working in framebuffer mode, we treat all such
1241 * bitmaps as framebuffer's friends and can inherit its class.
1243 if ((!gotclass
) && data
->framebuffer
&& (get_fbmode(cl
, o
) != vHidd_FrameBuffer_None
))
1245 classptr
= OOP_OCLASS(data
->framebuffer
);
1248 D(bug("[GFX] Using class 0x%p (%s) for displayable bitmap\n", classptr
, classptr
->ClassNode
.ln_Name
));
1254 /* Displayable bitmap. Here we must have ModeID and class. */
1257 D(bug("!!! Gfx::CreateObject: USER HAS NOT PASSED MODEID FOR DISPLAYABLE BITMAP !!!\n"));
1263 D(bug("!!! Gfx::CreateObject: SUBCLASS DID NOT PASS CLASS FOR DISPLAYABLE BITMAP !!!\n"));
1267 else /* if (!displayable) */
1270 * This is an offscreen bitmap and we need to guess its pixelformat.
1271 * In order to do this we need one of (in the order of preference):
1280 * We have alredy got sync for the modeid case.
1281 * Obtain missing size information from it.
1285 bmtags
[2].ti_Tag
= aHidd_BitMap_Width
;
1286 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &bmtags
[2].ti_Data
);
1291 bmtags
[3].ti_Tag
= aHidd_BitMap_Height
;
1292 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &bmtags
[3].ti_Data
);
1295 else if (pixfmt
!= vHidd_StdPixFmt_Unknown
)
1297 /* Next to look for is StdPixFmt */
1298 pf
= HIDD_Gfx_GetPixFmt(o
, pixfmt
);
1301 D(bug("!!! Gfx::CreateObject(): USER PASSED BOGUS StdPixFmt !!!\n"));
1307 /* Last alternative is that the user passed a friend bitmap */
1309 OOP_GetAttr(friend_bm
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1312 * Inherit the class from friend bitmap (if not already specified).
1313 * We do it because friend bitmap may be a display HIDD bitmap
1317 classptr
= OOP_OCLASS(friend_bm
);
1320 D(bug("[GFX] Friend bitmap is 0x%p has class 0x%p (%s)\n", friend_bm
, classptr
, classptr
->ClassNode
.ln_Name
));
1325 D(bug("!!! Gfx::CreateObject: INSUFFICIENT ATTRS TO CREATE OFFSCREEN BITMAP !!!\n"));
1329 /* Did the subclass provide an offbitmap class for us? */
1332 /* Have to find a suitable class ourselves from the pixelformat */
1333 HIDDT_BitMapType bmtype
;
1335 OOP_GetAttr(pf
, aHidd_PixFmt_BitMapType
, &bmtype
);
1338 case vHidd_BitMapType_Chunky
:
1339 classptr
= CSD(cl
)->chunkybmclass
;
1342 case vHidd_BitMapType_Planar
:
1343 classptr
= CSD(cl
)->planarbmclass
;
1347 D(bug("!!! Gfx::CreateObject: UNKNOWN BITMAPTYPE %d !!!\n", bmtype
));
1350 D(bug("[GFX] Bitmap type is %u, using class 0x%p\n", bmtype
, classptr
));
1352 } /* if (!gotclass) */
1354 } /* if (!displayable) */
1356 /* Set the tags we want to pass to the selected bitmap class */
1357 bmtags
[0].ti_Data
= (IPTR
)o
;
1358 bmtags
[1].ti_Data
= (IPTR
)pf
;
1359 bmtags
[6].ti_Data
= (IPTR
)msg
->attrList
;
1361 object
= OOP_NewObject(classptr
, classid
, bmtags
);
1363 /* Remember the framebuffer. It can be needed for default Show() implementation. */
1365 data
->framebuffer
= object
;
1368 ReturnPtr("HIDDGfx::CreateObject", OOP_Object
*, object
);
1371 /****************************************************************************************/
1373 #define SD(x) ((struct sync_data *)x)
1374 #define PF(x) ((HIDDT_PixelFormat *)x)
1376 #define XCOORD_TO_BYTEIDX(x) ( (x) >> 3)
1377 #define COORD_TO_BYTEIDX(x, y, bpr) ( ( (y) * bpr ) + XCOORD_TO_BYTEIDX(x) )
1378 #define XCOORD_TO_MASK(x) (1L << (7 - ((x) & 0x07) ))
1379 #define WIDTH_TO_BYTES(width) ( (( (width) - 1) >> 3) + 1)
1381 /****************************************************************************************/
1383 /* modebm functions pfidx is x and syncidx is y coord in the bitmap */
1385 /****************************************************************************************/
1387 static inline BOOL
alloc_mode_bm(struct mode_bm
*bm
, ULONG numsyncs
, ULONG numpfs
,
1390 bm
->bpr
= WIDTH_TO_BYTES(numpfs
);
1392 bm
->bm
= AllocVec(bm
->bpr
* numsyncs
, MEMF_CLEAR
);
1396 /* We initialize the mode bitmap to all modes valid */
1397 memset(bm
->bm
, 0xFF, bm
->bpr
* numsyncs
);
1402 /****************************************************************************************/
1404 static inline VOID
free_mode_bm(struct mode_bm
*bm
, OOP_Class
*cl
)
1411 /****************************************************************************************/
1413 static inline BOOL
is_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
)
1415 if (0 != (XCOORD_TO_MASK(pfidx
) & bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)]))
1421 /****************************************************************************************/
1423 static inline VOID
set_valid_mode(struct mode_bm
*bm
, ULONG syncidx
, ULONG pfidx
,
1427 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] |= XCOORD_TO_MASK(pfidx
);
1429 bm
->bm
[COORD_TO_BYTEIDX(pfidx
, syncidx
, bm
->bpr
)] &= ~XCOORD_TO_MASK(pfidx
);
1434 /****************************************************************************************/
1436 static BOOL
alloc_mode_db(struct mode_db
*mdb
, ULONG numsyncs
, ULONG numpfs
, OOP_Class
*cl
)
1440 if (0 == numsyncs
|| 0 == numpfs
)
1443 ObtainSemaphore(&mdb
->sema
);
1444 /* free_mode_bm() needs this */
1445 mdb
->num_pixfmts
= numpfs
;
1446 mdb
->num_syncs
= numsyncs
;
1448 mdb
->syncs
= AllocMem(sizeof (OOP_Object
*) * numsyncs
, MEMF_CLEAR
);
1450 if (NULL
!= mdb
->syncs
)
1452 mdb
->pixfmts
= AllocMem(sizeof (OOP_Object
*) * numpfs
, MEMF_CLEAR
);
1454 if (NULL
!= mdb
->pixfmts
)
1456 if (alloc_mode_bm(&mdb
->orig_mode_bm
, numsyncs
, numpfs
, cl
))
1458 if (alloc_mode_bm(&mdb
->checked_mode_bm
, numsyncs
, numpfs
, cl
))
1467 free_mode_db(mdb
, cl
);
1469 ReleaseSemaphore(&mdb
->sema
);
1474 /****************************************************************************************/
1476 static VOID
free_mode_db(struct mode_db
*mdb
, OOP_Class
*cl
)
1478 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1481 ObtainSemaphore(&mdb
->sema
);
1483 if (NULL
!= mdb
->pixfmts
)
1486 /* Pixelformats are shared objects and never freed */
1487 FreeMem(mdb
->pixfmts
, sizeof (OOP_Object
*) * mdb
->num_pixfmts
);
1488 mdb
->pixfmts
= NULL
; mdb
->num_pixfmts
= 0;
1491 if (NULL
!= mdb
->syncs
)
1493 for (i
= 0; i
< mdb
->num_syncs
; i
++)
1495 if (NULL
!= mdb
->syncs
[i
])
1498 OOP_DisposeObject(mdb
->syncs
[i
]);
1499 mdb
->syncs
[i
] = NULL
;
1503 FreeMem(mdb
->syncs
, sizeof (OOP_Object
*) * mdb
->num_syncs
);
1504 mdb
->syncs
= NULL
; mdb
->num_syncs
= 0;
1507 if (NULL
!= mdb
->orig_mode_bm
.bm
)
1509 free_mode_bm(&mdb
->orig_mode_bm
, cl
);
1512 if (NULL
!= mdb
->checked_mode_bm
.bm
)
1514 free_mode_bm(&mdb
->checked_mode_bm
, cl
);
1517 ReleaseSemaphore(&mdb
->sema
);
1522 /****************************************************************************************/
1524 /* Initializes default tagarray. in numtags the TAG_MORE is not accounted for,
1525 so the array must be of size NUM_TAGS + 1
1528 /****************************************************************************************/
1530 static VOID
init_def_tags(struct TagItem
*tags
, ULONG numtags
)
1534 for (i
= 0; i
< numtags
; i
++)
1536 tags
[i
].ti_Tag
= TAG_IGNORE
;
1537 tags
[i
].ti_Data
= 0UL;
1540 tags
[i
].ti_Tag
= TAG_MORE
;
1541 tags
[i
].ti_Data
= 0UL;
1546 /****************************************************************************************/
1548 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
1549 struct TagItem sync_ ## name[]={ \
1550 { aHidd_Sync_PixelClock, clock*1000 }, \
1551 { aHidd_Sync_HDisp, hdisp }, \
1552 { aHidd_Sync_HSyncStart, hstart }, \
1553 { aHidd_Sync_HSyncEnd, hend }, \
1554 { aHidd_Sync_HTotal, htotal }, \
1555 { aHidd_Sync_VDisp, vdisp }, \
1556 { aHidd_Sync_VSyncStart, vstart }, \
1557 { aHidd_Sync_VSyncEnd, vend }, \
1558 { aHidd_Sync_VTotal, vtotal }, \
1559 { aHidd_Sync_Description, (IPTR)descr}, \
1562 static BOOL
register_modes(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*modetags
)
1564 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
1565 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1566 struct TagItem
*tag
, *tstate
;
1567 struct HiddGfxData
*data
;
1569 MAKE_SYNC(640x480_60
, 25174,
1574 MAKE_SYNC(800x600_56
, 36000, // 36000
1575 800, 824, 896, 1024,
1579 MAKE_SYNC(1024x768_60
, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
1580 1024, 1048, 1184, 1344,
1582 "Default:1024x768");
1584 MAKE_SYNC(1152x864_60
, 80000,
1585 1152, 1216, 1328, 1456,
1587 "Default:1152x864");
1589 MAKE_SYNC(1280x1024_60
, 108880,
1590 1280, 1360, 1496, 1712,
1591 1024, 1025, 1028, 1060,
1592 "Default:1280x1024");
1594 MAKE_SYNC(1600x1200_60
, 155982,
1595 1600, 1632, 1792, 2048,
1596 1200, 1210, 1218, 1270,
1597 "Default:1600x1200");
1599 /* "new" 16:10 modes */
1601 MAKE_SYNC(1280x800_60
, 83530,
1602 1280, 1344, 1480, 1680,
1604 "Default:1280x800");
1606 MAKE_SYNC(1440x900_60
, 106470,
1607 1440, 1520, 1672, 1904,
1609 "Default:1440x900");
1611 MAKE_SYNC(1680x1050_60
, 147140,
1612 1680, 1784, 1968, 2256,
1613 1050, 1051, 1054, 1087,
1614 "Default:1680x1050");
1616 MAKE_SYNC(1920x1080_60
, 173000,
1617 1920, 2048, 2248, 2576,
1618 1080, 1083, 1088, 1120,
1619 "Default:1920x1080");
1621 MAKE_SYNC(1920x1200_60
, 154000,
1622 1920, 1968, 2000, 2080,
1623 1200, 1203, 1209, 1235,
1624 "Default:1920x1200");
1626 struct mode_db
*mdb
;
1628 HIDDT_PixelFormat pixfmt_data
;
1630 struct TagItem def_sync_tags
[num_Hidd_Sync_Attrs
+ 1];
1631 struct TagItem def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
+ 1];
1633 ULONG numpfs
= 0,numsyncs
= 0;
1634 ULONG pfidx
= 0, syncidx
= 0;
1636 struct TagItem temporary_tags
[] = {
1637 { aHidd_Gfx_SyncTags
, (IPTR
)sync_640x480_60
},
1638 { aHidd_Gfx_SyncTags
, (IPTR
)sync_800x600_56
},
1639 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1024x768_60
},
1640 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1152x864_60
},
1641 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x1024_60
},
1642 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1600x1200_60
},
1643 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1280x800_60
},
1644 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1440x900_60
},
1645 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1680x1050_60
},
1646 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1920x1080_60
},
1647 { aHidd_Gfx_SyncTags
, (IPTR
)sync_1920x1200_60
},
1651 data
= OOP_INST_DATA(cl
, o
);
1653 InitSemaphore(&mdb
->sema
);
1655 memset(&pixfmt_data
, 0, sizeof (pixfmt_data
));
1657 init_def_tags(def_sync_tags
, num_Hidd_Sync_Attrs
);
1658 init_def_tags(def_pixfmt_tags
, num_Hidd_PixFmt_Attrs
);
1660 def_sync_tags
[aoHidd_Sync_GfxHidd
].ti_Tag
= aHidd_Sync_GfxHidd
;
1661 def_sync_tags
[aoHidd_Sync_GfxHidd
].ti_Data
= (IPTR
)o
;
1663 /* First we need to calculate how much memory we are to allocate by counting supplied
1664 pixel formats and syncs */
1666 for (tstate
= modetags
; (tag
= NextTagItem(&tstate
));)
1670 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
1674 case aoHidd_Gfx_PixFmtTags
:
1678 case aoHidd_Gfx_SyncTags
:
1690 D(bug("!!! WE MUST AT LEAST HAVE ONE PIXFMT IN Gfx::RegisterModes() !!!\n"));
1695 D(bug("!!! NO SYNC IN Gfx::RegisterModes() !!!\n!!! USING DEFAULT MODES !!!\n"));
1696 temporary_tags
[11].ti_Tag
= TAG_MORE
;
1697 temporary_tags
[11].ti_Data
= (IPTR
)modetags
;
1698 modetags
= &temporary_tags
[0];
1702 ObtainSemaphore(&mdb
->sema
);
1704 /* Allocate memory for mode db */
1705 if (!alloc_mode_db(&data
->mdb
, numsyncs
, numpfs
, cl
))
1709 for (tstate
= modetags
; (tag
= NextTagItem(&tstate
));)
1711 /* Look for Gfx, PixFmt and Sync tags */
1714 if (IS_GFX_ATTR(tag
->ti_Tag
, idx
))
1718 case aoHidd_Gfx_PixFmtTags
:
1719 def_pixfmt_tags
[num_Hidd_PixFmt_Attrs
].ti_Data
= tag
->ti_Data
;
1720 mdb
->pixfmts
[pfidx
] = GFXHIDD__Hidd_Gfx__RegisterPixFmt(cl
, def_pixfmt_tags
);
1722 if (NULL
== mdb
->pixfmts
[pfidx
])
1724 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
1731 case aoHidd_Gfx_SyncTags
:
1732 def_sync_tags
[num_Hidd_Sync_Attrs
].ti_Data
= tag
->ti_Data
;
1734 mdb
->syncs
[syncidx
] = OOP_NewObject(CSD(cl
)->syncclass
, NULL
, def_sync_tags
);
1735 if (!mdb
->syncs
[syncidx
]) {
1736 D(bug("!!! UNABLE TO CREATE SYNC OBJECT IN Gfx::RegisterModes() !!!\n"));
1745 else if (IS_SYNC_ATTR(tag
->ti_Tag
, idx
))
1747 if (idx
>= num_Hidd_Sync_Attrs
)
1749 D(bug("!!! UNKNOWN SYNC ATTR IN Gfx::New(): %d !!!\n", idx
));
1753 def_sync_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
1754 def_sync_tags
[idx
].ti_Data
= tag
->ti_Data
;
1758 else if (IS_PIXFMT_ATTR(tag
->ti_Tag
, idx
))
1760 if (idx
>= num_Hidd_PixFmt_Attrs
)
1762 D(bug("!!! UNKNOWN PIXFMT ATTR IN Gfx::New(): %d !!!\n", idx
));
1766 def_pixfmt_tags
[idx
].ti_Tag
= tag
->ti_Tag
;
1767 def_pixfmt_tags
[idx
].ti_Data
= tag
->ti_Data
;
1772 ReleaseSemaphore(&mdb
->sema
);
1778 /* mode db is freed in dispose */
1779 ReleaseSemaphore(&mdb
->sema
);
1784 /****************************************************************************************/
1788 struct mode_db
*mdb
;
1793 HIDDT_StdPixFmt
*stdpfs
;
1803 /****************************************************************************************/
1805 /* This is a recursive function that looks for valid modes */
1807 /****************************************************************************************/
1809 static HIDDT_ModeID
*querymode(struct modequery
*mq
)
1811 HIDDT_ModeID
*modeids
;
1812 register OOP_Object
*pf
;
1813 register OOP_Object
*sync
;
1814 BOOL mode_ok
= FALSE
;
1815 ULONG syncidx
, pfidx
;
1817 mq
->dims_ok
= FALSE
;
1818 mq
->stdpfs_ok
= FALSE
;
1819 mq
->check_ok
= FALSE
;
1821 /* Look at the supplied idx */
1822 if (mq
->pfidx
>= mq
->mdb
->num_pixfmts
)
1828 if (mq
->syncidx
>= mq
->mdb
->num_syncs
)
1830 /* We have reached the end of the recursion. Allocate memory and go back
1833 modeids
= AllocVec(sizeof (HIDDT_ModeID
) * (mq
->numfound
+ 1), MEMF_ANY
);
1834 /* Get the end of the array */
1835 modeids
+= mq
->numfound
;
1836 *modeids
= vHidd_ModeID_Invalid
;
1841 syncidx
= mq
->syncidx
;
1843 /* Get the pf and sync objects */
1844 pf
= mq
->mdb
->pixfmts
[syncidx
];
1845 sync
= mq
->mdb
->syncs
[pfidx
];
1848 /* Check that the mode is really usable */
1849 if (is_valid_mode(&mq
->mdb
->checked_mode_bm
, syncidx
, pfidx
))
1851 mq
->check_ok
= TRUE
;
1854 /* See if this mode matches the criterias set */
1856 if ( SD(sync
)->hdisp
>= mq
->minwidth
1857 && SD(sync
)->hdisp
<= mq
->maxwidth
1858 && SD(sync
)->vdisp
>= mq
->minheight
1859 && SD(sync
)->vdisp
<= mq
->maxheight
)
1865 if (NULL
!= mq
->stdpfs
)
1867 register HIDDT_StdPixFmt
*stdpf
= mq
->stdpfs
;
1870 if (*stdpf
== PF(pf
)->stdpixfmt
)
1872 mq
->stdpfs_ok
= TRUE
;
1879 mq
->stdpfs_ok
= TRUE
;
1885 if (mq
->dims_ok
&& mq
->stdpfs_ok
&& mq
->check_ok
)
1893 modeids
= querymode(mq
);
1895 if (NULL
== modeids
)
1900 /* The mode is OK. Add it to the list */
1902 *modeids
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
1909 /*****************************************************************************************
1912 moHidd_Gfx_QueryModeIDs
1915 HIDDT_ModeID *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryModeIDs *msg);
1917 HIDDT_ModeID *HIDD_Gfx_QueryModeIDs(OOP_Object *gfxHidd, struct TagItem *queryTags);
1923 Obtain a table of all supported display mode IDs
1925 The returned address points to an array of HIDDT_ModeID containing all ModeIDs
1926 supported by this driver. The array is terminated with vHidd_ModeID_Invalid.
1929 gfxHidd - A driver object which to query.
1930 querytags - An optional taglist containing query options. Can be NULL.
1931 The following tags are supported:
1933 tHidd_GfxMode_MinWidth (ULONG) - A minimum width of modes you are
1935 tHidd_GfxMode_MaxWidth (ULONG) - A maximum width of modes you are
1937 tHidd_GfxMode_MinHeight (ULONG) - A minimum height of modes you are
1939 tHidd_GfxMode_MaxHeight (ULONG) - A maximum height of modes you are
1941 tHidd_GfxMode_PixFmts (HIDDT_StdPifXmt *) - A pointer to an array
1942 of standard pixelformat indexes. If supplied, only mode IDs whose
1943 pixelformat numbers match any of given ones will be returned.
1946 A pointer to an array of ModeIDs or NULL in case of failure
1955 moHidd_Gfx_ReleaseModeIDs, moHidd_Gfx_NextModeID
1959 *****************************************************************************************/
1961 HIDDT_ModeID
*GFXHIDD__Hidd_Gfx__QueryModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
1962 struct pHidd_Gfx_QueryModeIDs
*msg
)
1964 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
1965 struct TagItem
*tag
, *tstate
;
1967 HIDDT_ModeID
*modeids
;
1968 struct HiddGfxData
*data
;
1969 struct mode_db
*mdb
;
1971 struct modequery mq
=
1973 NULL
, /* mode db (set later) */
1974 0, 0xFFFFFFFF, /* minwidth, maxwidth */
1975 0, 0xFFFFFFFF, /* minheight, maxheight */
1978 0, 0, /* pfidx, syncidx */
1979 FALSE
, FALSE
, /* dims_ok, stdpfs_ok */
1980 FALSE
, /* check_ok */
1981 NULL
/* class (set later) */
1986 data
= OOP_INST_DATA(cl
, o
);
1991 for (tstate
= msg
->queryTags
; (tag
= NextTagItem(&tstate
)); )
1993 switch (tag
->ti_Tag
)
1995 case tHidd_GfxMode_MinWidth
:
1996 mq
.minwidth
= (ULONG
)tag
->ti_Tag
;
1999 case tHidd_GfxMode_MaxWidth
:
2000 mq
.maxwidth
= (ULONG
)tag
->ti_Tag
;
2003 case tHidd_GfxMode_MinHeight
:
2004 mq
.minheight
= (ULONG
)tag
->ti_Tag
;
2007 case tHidd_GfxMode_MaxHeight
:
2008 mq
.maxheight
= (ULONG
)tag
->ti_Tag
;
2011 case tHidd_GfxMode_PixFmts
:
2012 mq
.stdpfs
= (HIDDT_StdPixFmt
*)tag
->ti_Data
;
2018 ObtainSemaphoreShared(&mdb
->sema
);
2020 /* Recursively check all modes */
2021 modeids
= querymode(&mq
);
2023 ReleaseSemaphore(&mdb
->sema
);
2029 /*****************************************************************************************
2032 moHidd_Gfx_ReleaseModeIDs
2035 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ReleaseModeIDs *msg);
2037 VOID HIDD_Gfx_ReleaseModeIDs(OOP_Object *gfxHidd, HIDDT_ModeID *modeIDs);
2043 Free array of display mode IDs returned by HIDD_Gfx_QueryModeIDs()
2046 gfxHidd - A driver object used to obtain the array
2047 modeIDs - A pointer to an array
2059 moHidd_Gfx_QueryModeIDs
2063 *****************************************************************************************/
2065 VOID
GFXHIDD__Hidd_Gfx__ReleaseModeIDs(OOP_Class
*cl
, OOP_Object
*o
,
2066 struct pHidd_Gfx_ReleaseModeIDs
*msg
)
2068 FreeVec(msg
->modeIDs
);
2071 /*****************************************************************************************
2074 moHidd_Gfx_NextModeID
2077 HIDDT_ModeID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NextModeID *msg);
2079 HIDDT_ModeID HIDD_Gfx_NextModeID(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2080 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2086 Iterate driver's internal display mode database.
2089 gfxHidd - A driver object to query
2090 modeID - A previous mode ID or vHidd_ModeID_Invalid for start of the iteration
2091 syncPtr - A pointer to a storage where pointer to sync object will be placed
2092 pixFmtPtr - A pointer to a storage where pointer to pixelformat object will be placed
2095 Next available mode ID or vHidd_ModeID_Invalid if there are no more display modes.
2096 If the function returns vHidd_ModeID_Invalid, sync and pixelformat pointers will
2110 *****************************************************************************************/
2112 HIDDT_ModeID
GFXHIDD__Hidd_Gfx__NextModeID(OOP_Class
*cl
, OOP_Object
*o
,
2113 struct pHidd_Gfx_NextModeID
*msg
)
2115 struct HiddGfxData
*data
;
2116 struct mode_db
*mdb
;
2117 ULONG syncidx
, pfidx
;
2118 HIDDT_ModeID return_id
= vHidd_ModeID_Invalid
;
2121 data
= OOP_INST_DATA(cl
, o
);
2124 ObtainSemaphoreShared(&mdb
->sema
);
2125 if (vHidd_ModeID_Invalid
== msg
->modeID
)
2132 pfidx
= MODEID_TO_PFIDX( msg
->modeID
);
2133 syncidx
= MODEID_TO_SYNCIDX( msg
->modeID
);
2135 /* Increament one from the last call */
2137 if (pfidx
>= mdb
->num_pixfmts
)
2144 /* Search for a new mode. We only accept valid modes */
2145 for (; syncidx
< mdb
->num_syncs
; syncidx
++)
2147 /* We only return valid modes */
2148 for (; pfidx
< mdb
->num_pixfmts
; pfidx
++)
2150 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
2162 return_id
= COMPUTE_HIDD_MODEID(syncidx
, pfidx
);
2163 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
2164 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
2168 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
2171 ReleaseSemaphore(&mdb
->sema
);
2176 /*****************************************************************************************
2182 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMode *msg);
2184 BOOL HIDD_Gfx_GetMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2185 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2191 Get sync and pixelformat objects for a particular display ModeID.
2194 gfxHidd - pointer to a driver object which this ModeID belongs to
2195 syncPtr - pointer to a storage where sync object pointer will be placed
2196 pixFmtPtr - pointer to a storage where pixelformat object pointer will be placed
2199 TRUE upon success, FALSE in case of failure (e.g. given mode does not exist in
2200 driver's internal database). If the function returns FALSE, sync and pixelformat
2201 pointers will be set to NULL.
2204 Every display mode is associated with some sync and pixelformat object. If the
2205 method returns TRUE, object pointers are guaranteed to be valid.
2212 moHidd_Gfx_NextModeID
2216 *****************************************************************************************/
2218 BOOL
GFXHIDD__Hidd_Gfx__GetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMode
*msg
)
2220 ULONG pfidx
, syncidx
;
2221 struct HiddGfxData
*data
;
2222 struct mode_db
*mdb
;
2225 data
= OOP_INST_DATA(cl
, o
);
2228 pfidx
= MODEID_TO_PFIDX(msg
->modeID
);
2229 syncidx
= MODEID_TO_SYNCIDX(msg
->modeID
);
2231 ObtainSemaphoreShared(&mdb
->sema
);
2233 if (! (pfidx
>= mdb
->num_pixfmts
|| syncidx
>= mdb
->num_syncs
) )
2235 if (is_valid_mode(&mdb
->checked_mode_bm
, syncidx
, pfidx
))
2238 *msg
->syncPtr
= mdb
->syncs
[syncidx
];
2239 *msg
->pixFmtPtr
= mdb
->pixfmts
[pfidx
];
2243 ReleaseSemaphore(&mdb
->sema
);
2247 *msg
->syncPtr
= *msg
->pixFmtPtr
= NULL
;
2253 /*****************************************************************************************
2259 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetMode *msg);
2261 BOOL HIDD_Gfx_SetMode(OOP_Object *gfxHidd, OOP_Object *sync);
2267 Update display mode according to changed sync object
2270 gfxHidd - A display driver to operate on
2271 sync - A modified sync object pointer
2274 TRUE if everything went OK and FALSE in case of some error
2277 This method is used to inform the driver that some external program has changed
2278 sync data and wants to update the display if needed. It's up to the implementation to
2279 check that current display is really using this sync (frontmost screen uses this mode).
2288 Base class implementation just returns FALSE indicating that this method is
2291 *****************************************************************************************/
2293 BOOL
GFXHIDD__Hidd_Gfx__SetMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetMode
*msg
)
2298 /****************************************************************************************/
2300 static VOID
copy_bm_and_colmap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*src_bm
,
2301 OOP_Object
*dst_bm
, UWORD width
, UWORD height
)
2303 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2304 struct HiddGfxData
*data
;
2307 OOP_Object
*src_colmap
;
2308 APTR psrc_colmap
= &src_colmap
;
2310 data
= OOP_INST_DATA(cl
, o
);
2312 /* We have to copy the colormap into the framebuffer bitmap */
2313 OOP_GetAttr(src_bm
, aHidd_BitMap_ColorMap
, (IPTR
*)psrc_colmap
);
2314 OOP_GetAttr(src_colmap
, aHidd_ColorMap_NumEntries
, &numentries
);
2316 for (i
= 0; i
< numentries
; i
++)
2320 HIDD_CM_GetColor(src_colmap
, i
, &col
);
2321 HIDD_BM_SetColors(dst_bm
, &col
, i
, 1);
2324 if (data
->fbmode
== vHidd_FrameBuffer_Mirrored
)
2327 * Mirror mode, just turn on visibility.
2328 * The data will be copied to the framebuffer later,
2329 * when graphics.library calls UpdateRect() after Show().
2331 BM__Hidd_BitMap__SetVisible(CSD(cl
)->bitmapclass
, src_bm
, TRUE
);
2336 * Direct framebuffer mode.
2337 * graphics.library will call UpdateRect() on the framebuffer object.
2338 * So we need to copy the data now.
2339 * We don't support scrolling for this mode, so we simply do the
2340 * bulk copy and ignore all offsets.
2342 HIDD_Gfx_CopyBox(o
, src_bm
, 0, 0,
2343 dst_bm
, 0, 0, width
, height
, data
->gc
);
2347 /*****************************************************************************************
2353 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Show *msg);
2355 OOP_Object *HIDD_Gfx_Show(OOP_Object *gfxHidd, OOP_Object *bitMap, ULONG flags);
2361 Change currently displayed bitmap on the screen.
2363 The bitmap object supplied must have been created with aHidd_BitMap_Displayable
2364 attribute set to TRUE.
2366 The function's behavior differs a lot depending on whether the driver uses a
2367 framebuffer or video hardware is able to switch screens itself.
2369 If the driver uses a framebuffer bitmap, it is supposed to copy the supplied bitmap
2370 into the framebuffer and return a framebuffer pointer. It also can be asked to
2371 copy back old framebuffer contents into previous bitmap object. It is driver's
2372 job to keep track of which bitmap object was displayed last time. This is what
2373 default implementation does. Note that it is very basic, and even does not support
2374 changing display resolution. It's not recommended to rely on it in production
2375 drivers (unless your video hardware supports only one mode).
2377 If the driver does not use a framebuffer, it is supposed to reprogram the hardware
2378 here to display an appropriate region of video RAM. Do not call the base class
2379 in this case, its implementation relies on framebuffer existance and will always
2380 return NULL which indicates an error.
2382 It is valid to get NULL value in bitMap parameter. This means that there is
2383 nothing to display and the screen needs to be blanked out. It is valid for
2384 non-framebuffer-based driver to return NULL as a reply then. In all other cases
2385 NULL return value means an error.
2387 Please avoid returning errors at all. graphics.library/LoadView() has no error
2388 indication. An error during showing a bitmap would leave the display in
2389 unpredictable state.
2391 If the driver does not use a framebuffer, consider using HIDD_Gfx_ShowViewPorts().
2392 It's more straightforward, flexible and offers support for screen composition.
2395 gfxHidd - a display driver object, whose display you wish to change.
2396 bitMap - a pointer to a bitmap object which needs to be shown or NULL.
2397 flags - currently only one flag is defined:
2399 fHidd_Gfx_Show_CopyBack - Copy back the image data from framebuffer bitmap
2400 to old displayed bitmap. Used only if the driver
2401 needs a framebuffer.
2404 A pointer to a currently displayed bitmap object or NULL (read FUNCTION paragraph for
2405 detailed description)
2408 Drivers which use mirrored video data buffer do not have to update the display
2409 immediately in this method. moHidd_BitMap_UpdateRect will be sent to the returned
2410 bitmap if it's not NULL. Of course display blanking (if NULL bitmap was received)
2411 needs to be performed immediately.
2418 moHidd_Gfx_ShowViewPorts, graphics.library/LoadView()
2422 *****************************************************************************************/
2424 OOP_Object
*GFXHIDD__Hidd_Gfx__Show(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Show
*msg
)
2426 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2427 struct HiddGfxData
*data
= OOP_INST_DATA(cl
, o
);
2428 OOP_Object
*bm
= msg
->bitMap
;
2434 if (NULL
== data
->framebuffer
)
2436 /* We require framebuffer. Don't call us otherwise. */
2440 ObtainSemaphore(&data
->fbsem
);
2444 /* Get size of old bitmap */
2445 OOP_GetAttr(data
->shownbm
, aHidd_BitMap_Width
, &oldwidth
);
2446 OOP_GetAttr(data
->shownbm
, aHidd_BitMap_Height
, &oldheight
);
2448 if (data
->fbmode
== vHidd_FrameBuffer_Mirrored
)
2450 BM__Hidd_BitMap__SetVisible(CSD(cl
)->bitmapclass
, data
->shownbm
, FALSE
);
2452 else if (msg
->flags
& fHidd_Gfx_Show_CopyBack
)
2454 /* Copy the framebuffer data back into the old shown bitmap */
2455 copy_bm_and_colmap(cl
, o
, data
->framebuffer
, data
->shownbm
, oldwidth
, oldheight
);
2459 if (bm
== data
->framebuffer
)
2461 /* If showing the framebuffer itself, just detach from old bitmap and that's all. */
2462 data
->shownbm
= NULL
;
2463 ReleaseSemaphore(&data
->fbsem
);
2465 return data
->framebuffer
;
2473 * Switch framebuffer display mode.
2474 * This operation can fail if the bitmap has inappropriate mode.
2476 OOP_GetAttr(bm
, aHidd_BitMap_ModeID
, &modeid
);
2477 if (!OOP_SetAttrsTags(data
->framebuffer
, aHidd_BitMap_ModeID
, modeid
, TAG_DONE
))
2480 /* Get size of new bitmap */
2481 OOP_GetAttr(bm
, aHidd_BitMap_Width
, &newwidth
);
2482 OOP_GetAttr(bm
, aHidd_BitMap_Height
, &newheight
);
2484 /* Copy it into the framebuffer */
2485 copy_bm_and_colmap(cl
, o
, bm
, data
->framebuffer
, newwidth
, newheight
);
2489 * Clear remaining parts of the framebuffer (if previous bitmap was larger than new one)
2490 * Note that if the new bitmap is NULL, newwidth and newheight will both be zero.
2491 * This will cause clearing the whole display.
2493 if (oldheight
) /* width and height can be zero only together, check one of them */
2495 if (newwidth
< oldwidth
)
2496 HIDD_BM_FillRect(data
->framebuffer
, data
->gc
, newwidth
, 0, oldwidth
- 1, oldheight
- 1);
2497 if ((newheight
< oldheight
) && newwidth
)
2498 HIDD_BM_FillRect(data
->framebuffer
, data
->gc
, 0, newheight
, newwidth
- 1, oldheight
);
2501 /* Remember new displayed bitmap */
2504 ReleaseSemaphore(&data
->fbsem
);
2506 /* Return the actual bitmap to perform further operations on */
2507 return (data
->fbmode
== vHidd_FrameBuffer_Mirrored
) ? bm
: data
->framebuffer
;
2510 /*****************************************************************************************
2513 moHidd_Gfx_ShowViewPorts
2516 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ShowViewPorts *msg);
2518 ULONG HIDD_Gfx_ShowViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view);
2524 Show one or more bitmaps on the screen.
2526 It is completely up to the driver how to implement this function. The driver may
2527 or may not support hardware-assisted screens composition. Bitmaps are sorted
2528 in the list in descending z-order. The driver is expected to put at least frontmost
2531 It is valid to get NULL pointer as data parameter. This means that there's
2532 nothing to show and the screen should go blank.
2534 Bitmaps display offsets are stored in their aHidd_BitMap_LeftEdge and
2535 aHidd_BitMap_TopEdge attributes. This function is not expected to modify their
2536 values somehow. They are assumed to be preserved between calls unless changed
2537 explicitly by the system.
2539 If you implement this method, you don't have to implement HIDD_Gfx_Show() because
2540 it will never be called.
2542 Note that there is no more error indication - the driver is expected to be
2546 gfxHidd - a display driver object, whose display you wish to change.
2547 data - a singly linked list of bitmap objects to show
2550 TRUE if this method is supported by the driver, FALSE otherwise
2562 Default base class implementation simply returns FALSE. This causes
2563 the system to use HIDD_Gfx_Show() instead.
2565 *****************************************************************************************/
2567 ULONG
GFXHIDD__Hidd_Gfx__ShowViewPorts(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ShowViewPorts
*msg
)
2569 /* By default we don't support screen composition (and this method too) */
2573 /*****************************************************************************************
2576 moHidd_Gfx_SetCursorShape
2579 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorShape *msg);
2581 BOOL HIDD_Gfx_SetCursorShape(OOP_Object *gfxHidd, OOP_Object *shape,
2582 WORD xoffset, WORD yoffset);
2588 Set mouse pointer shape.
2590 A pointer image is contained in the specified bitmap object. The bitmap object
2591 may contain a colormap if the system wants to specify own colors for the pointer.
2592 The supplied colormap will also contain alpha channel values.
2594 It is up to driver what to do if, for example, alpha channel is not supported by
2595 the hardware. Or if given bitmap type is not supported (for example truecolor
2596 bitmap on LUT-only hardware). It is expected that the driver converts bitmap
2597 data to a more appropriate form in such a case.
2599 A hotspot is given as an offset from the actual hotspot to the top-left corner
2600 of the pointer image. It is generally needed only for hosted display drivers
2601 which utilize host's support for mouse pointer.
2603 The default implementation in the base class just does nothing. A software mouse
2604 pointer is implemented in a special layer called fakegfx.hidd inside
2605 graphics.library. If a software pointer emulation is used, this method will
2609 gfxHidd - a display driver object, for whose display you wish to change the pointer
2610 shape - a pointer to a bitmap object, containing pointer bitmap
2611 xoffset - a horizontal hotspot offset
2612 yoffset - a vertical hotspot offset
2615 TRUE on success, FALSE on failure
2624 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2628 *****************************************************************************************/
2630 BOOL
GFXHIDD__Hidd_Gfx__SetCursorShape(OOP_Class
*cl
, OOP_Object
*o
,
2631 struct pHidd_Gfx_SetCursorShape
*msg
)
2633 /* We have no clue how to render the cursor */
2637 /*****************************************************************************************
2640 moHidd_Gfx_SetCursorVisible
2643 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorVisible *msg);
2645 VOID HIDD_Gfx_SetCursorVisible(OOP_Object *gfxHidd, BOOL visible);
2651 Control mouse pointer visiblity.
2653 The default implementation in the base class does nothing. If a software pointer
2654 emulation is used, this method will never be called.
2657 gfxHidd - a display driver object, on whose display you wish to turn
2659 visible - TRUE to enable pointer display, FALSE to disable it
2671 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2675 *****************************************************************************************/
2677 VOID
GFXHIDD__Hidd_Gfx__SetCursorVisible(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorVisible
*msg
)
2682 /*****************************************************************************************
2685 moHidd_Gfx_SetCursorPos
2688 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorPos *msg);
2690 BOOL HIDD_Gfx_SetCursorPos(OOP_Object *gfxHidd, WORD x, WORD y);
2696 Set current mouse pointer position.
2698 This is a real position on top-left image corner relative to top-left corner of
2699 the physical display. Neither logical screen origin nor hotspot are taken into
2702 The default implementation in the base class does nothing and just returns TRUE.
2703 If a software pointer emulation is used, this method will never be called.
2706 gfxHidd - a display driver object, on whose display you wish to position the pointer
2707 x - An x coordinate of the pointer (relative to the physical screen origin)
2708 y - A y coordinate of the pointer (relative to the physical screen origin)
2711 Always TRUE. Reserved for future, do not use it.
2714 This method is called by graphics.library/MoveSprite() which has no return value.
2715 However, for historical reasons, this method has a return value. Drivers should
2716 always return TRUE in order to ensure future compatibility.
2723 moHidd_Gfx_SetCursorShape, moHidd_Gfx_SetCursorVisible, graphics.library/MoveSprite()
2727 *****************************************************************************************/
2729 BOOL
GFXHIDD__Hidd_Gfx__SetCursorPos(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_SetCursorPos
*msg
)
2734 /*****************************************************************************************
2740 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg);
2742 VOID HIDD_Gfx_CopyBox(OOP_Object *gfxHidd, OOP_Object *src, WORD srcX, WORD srcY,
2743 OOP_Object *dest, WORD destX, WORD destY, UWORD width, UWORD height,
2750 Perform rectangle copy (blit) operation from one bitmap to another.
2752 Given bitmaps may belong to different display drivers. The driver may attempt to
2753 use hardware for acceleration (if available), and if it's impossible, pass the
2754 operation on to the base class.
2756 Always check class of the supplied bitmap before attempting to look at its
2759 A GC is used in order to specify raster operation performed between the source
2760 and destination according to its aHidd_GC_DrawMode attribute value.
2763 gfxHidd - a display driver object that you are going to use for copying
2764 src - a pointer to source bitmap object
2765 srcX - an X coordinate of the source rectangle
2766 srcY - a Y coordinate of the source rectangle
2767 dest - a pointer to destination bitmap object
2768 destX - an X coordinate of the destination rectangle
2769 destY - a Y coordinate of the destination rectangle
2770 width - width of the rectangle to copy
2771 height - height of the rectangle to copy
2772 gc - graphics context holding draw mode on the destination
2778 You must specify valid coordinates (non-negative and inside the actual bitmap
2779 area), no checks are done.
2781 It is valid to specify two overlapped areas of the same bitmap as source
2792 *****************************************************************************************/
2794 VOID
GFXHIDD__Hidd_Gfx__CopyBox(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_Gfx_CopyBox
*msg
)
2796 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2798 WORD srcX
= msg
->srcX
, destX
= msg
->destX
;
2799 WORD srcY
= msg
->srcY
, destY
= msg
->destY
;
2800 WORD startX
, endX
, deltaX
, startY
, endY
, deltaY
;
2802 HIDDT_PixelFormat
*srcpf
, *dstpf
;
2803 OOP_Object
*dest
, *src
;
2805 APTR srcPixels
= NULL
;
2806 APTR destPixels
= NULL
;
2811 /* If source/dest overlap, direction of operation is important */
2815 startX
= msg
->width
- 1; endX
= -1; deltaX
= -1;
2819 startX
= 0; endX
= msg
->width
; deltaX
= 1;
2824 startY
= msg
->height
- 1; endY
= -1; deltaY
= -1;
2828 startY
= 0; endY
= msg
->height
; deltaY
= 1;
2831 /* Get the source pixel format */
2832 srcpf
= (HIDDT_PixelFormat
*)HBM(src
)->prot
.pixfmt
;
2834 DCOPYBOX(bug("COPYBOX: obj=0x%p (%s), src=0x%p at (%d, %d), dst=0x%p at (%d, %d), size=%dx%d\n", obj
, OOP_OCLASS(obj
)->ClassNode
.ln_Name
,
2835 msg
->src
, srcX
, srcY
, msg
->dest
, destX
, destY
, msg
->width
, msg
->height
));
2836 DCOPYBOX(bug("COPYBOX: GC=0x%p, DrawMode %ld, ColMask 0x%08X\n", msg
->gc
, GC_DRMD(msg
->gc
), GC_COLMASK(msg
->gc
)));
2838 #ifdef COPYBOX_DUMP_DIMS
2840 IPTR sw
, sh
, dw
, dh
;
2842 OOP_GetAttr(obj
, aHidd_BitMap_Width
, &sw
);
2843 OOP_GetAttr(obj
, aHidd_BitMap_Height
, &sh
);
2844 OOP_GetAttr(msg
->dest
, aHidd_BitMap_Width
, &dw
);
2845 OOP_GetAttr(msg
->dest
, aHidd_BitMap_Height
, &dh
);
2847 bug("src dims: %dx%d dest dims: %dx%d\n", sw
, sh
, dw
, dh
);
2851 dstpf
= (HIDDT_PixelFormat
*)HBM(dest
)->prot
.pixfmt
;
2853 OOP_GetAttr(msg
->src
, aHidd_ChunkyBM_Buffer
, (APTR
)&srcPixels
);
2854 OOP_GetAttr(msg
->dest
, aHidd_ChunkyBM_Buffer
, (APTR
)&destPixels
);
2856 if (srcPixels
&& destPixels
)
2859 * Both bitmaps are chunky ones and they have directly accessible buffer.
2860 * We can use optimized routines to do the copy.
2862 IPTR src_bytesperline
, dest_bytesperline
;
2864 OOP_GetAttr(msg
->src
, aHidd_BitMap_BytesPerRow
, &src_bytesperline
);
2865 OOP_GetAttr(msg
->dest
, aHidd_BitMap_BytesPerRow
, &dest_bytesperline
);
2867 switch(GC_DRMD(msg
->gc
))
2869 case vHidd_GC_DrawMode_Copy
:
2870 /* At the moment we optimize only bulk copy */
2875 * The same pixelformat. Extremely great!
2877 * FIXME: Bulk copy to the same pixelformat is also handled in ConvertPixels very well
2878 * (optimized to either per-line or bulk memcpy()). But it can't handle
2879 * overlapping regions (which seems to be a requirement for CopyBox).
2880 * If this is fixed, we can even throw away HIDD_BM_CopyMemBoxXX at all, reducing
2883 switch(srcpf
->bytes_per_pixel
)
2887 * In fact all these methods are static, they ignore object pointer, and it's
2888 * needed only for OOP_DoMethod() to fetch class information.
2889 * We use destination bitmap pointer, we can also source one.
2891 HIDD_BM_CopyMemBox8(msg
->dest
,
2892 srcPixels
, msg
->srcX
, msg
->srcY
,
2893 destPixels
, msg
->destX
, msg
->destY
,
2894 msg
->width
, msg
->height
,
2895 src_bytesperline
, dest_bytesperline
);
2899 HIDD_BM_CopyMemBox16(msg
->dest
,
2900 srcPixels
, msg
->srcX
, msg
->srcY
,
2901 destPixels
, msg
->destX
, msg
->destY
,
2902 msg
->width
, msg
->height
,
2903 src_bytesperline
, dest_bytesperline
);
2907 HIDD_BM_CopyMemBox24(msg
->dest
,
2908 srcPixels
, msg
->srcX
, msg
->srcY
,
2909 destPixels
, msg
->destX
, msg
->destY
,
2910 msg
->width
, msg
->height
,
2911 src_bytesperline
, dest_bytesperline
);
2915 HIDD_BM_CopyMemBox32(msg
->dest
,
2916 srcPixels
, msg
->srcX
, msg
->srcY
,
2917 destPixels
, msg
->destX
, msg
->destY
,
2918 msg
->width
, msg
->height
,
2919 src_bytesperline
, dest_bytesperline
);
2922 } /* switch(srcpf->bytes_per_pixel) */
2923 } /* srcpf == dstpf */
2927 * Pixelformats are different. This can't be the same bitmap,
2928 * and it's safe to use ConvertPixels method (see FIXME above).
2930 srcPixels
+= (msg
->srcY
* src_bytesperline
) + (msg
->srcX
* srcpf
->bytes_per_pixel
);
2931 destPixels
+= (msg
->destY
* dest_bytesperline
) + (msg
->destX
* dstpf
->bytes_per_pixel
);
2934 * Supply NULL pixlut. In this case bitmap's own colormap will be used
2935 * for color lookup (if needed).
2937 HIDD_BM_ConvertPixels(msg
->dest
,
2938 &srcPixels
, srcpf
, src_bytesperline
,
2939 &destPixels
, dstpf
, dest_bytesperline
,
2940 msg
->width
, msg
->height
, NULL
);
2947 /* TODO: Optimize other DrawModes here */
2949 } /* switch(mode) */
2951 } /* srcPixels && destPixels */
2955 memFG
= GC_FG(msg
->gc
);
2957 /* All else have failed, copy pixel by pixel */
2958 if (HIDD_PF_COLMODEL(srcpf
) == HIDD_PF_COLMODEL(dstpf
))
2960 if (IS_TRUECOLOR(srcpf
))
2962 DCOPYBOX(bug("COPY FROM TRUECOLOR TO TRUECOLOR\n"));
2964 for(y
= startY
; y
!= endY
; y
+= deltaY
)
2968 /* if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2969 bug("[%d,%d] ", memSrcX, memDestX);
2971 for(x
= startX
; x
!= endX
; x
+= deltaX
)
2973 HIDDT_Pixel pix
= GETPIXEL(cl
, src
, srcX
+ x
, srcY
+ y
);
2975 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2983 HIDD_BM_UnmapPixel(src
, pix
, &col
);
2984 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, &col
);
2987 DRAWPIXEL(cl
, dest
, gc
, destX
+ x
, destY
+ y
);
2989 /*if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2990 bug("[%d,%d] ", srcY, destY);
2994 } /* if (IS_TRUECOLOR(srcpf)) */
2997 /* Two palette bitmaps.
2998 For this case we do NOT convert through RGB,
2999 but copy the pixel indexes directly
3001 DCOPYBOX(bug("COPY FROM PALETTE TO PALETTE\n"));
3003 /* FIXME: This might not work very well with two StaticPalette bitmaps */
3005 for(y
= startY
; y
!= endY
; y
+= deltaY
)
3007 for(x
= startX
; x
!= endX
; x
+= deltaX
)
3009 GC_FG(gc
) = HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
3011 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
3016 } /* if (IS_TRUECOLOR(srcpf)) else ... */
3018 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) */
3021 /* Two unlike bitmaps */
3022 if (IS_TRUECOLOR(srcpf
))
3024 for(y
= startY
; y
!= endY
; y
+= deltaY
)
3026 for(x
= startX
; x
!= endX
; x
+= deltaX
)
3031 pix
= HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
3032 HIDD_BM_UnmapPixel(src
, pix
, &col
);
3034 HIDD_BM_PutPixel(dest
, destX
+ x
, destY
+ y
,
3035 HIDD_BM_MapColor(dest
, &col
));
3039 else if (IS_TRUECOLOR(dstpf
))
3041 /* Get the colortab */
3042 HIDDT_Color
*ctab
= ((HIDDT_ColorLUT
*)HBM(src
)->colmap
)->colors
;
3044 DCOPYBOX(bug("COPY FROM PALETTE TO TRUECOLOR, DRAWMODE %d, CTAB %p\n", GC_DRMD(gc
), ctab
));
3046 for(y
= startY
; y
!= endY
; y
+= deltaY
)
3048 for(x
= startX
; x
!= endX
; x
+= deltaX
)
3050 register HIDDT_Pixel pix
;
3053 pix
= HIDD_BM_GetPixel(src
, srcX
+ x
, srcY
+ y
);
3057 * !!!! HIDD_BM_MapColor() pokes pixval of the passed HIDDT_Color,
3058 * so if the address of the entry in the colormap is passed, the colormap
3059 * itself will be modified, if we pass "&ctab[pix]" to HIDD_BM_MapColor() !!!!
3062 GC_FG(gc
) = HIDD_BM_MapColor(msg
->dest
, &col
);
3063 HIDD_BM_DrawPixel(msg
->dest
, gc
, destX
+ x
, destY
+ y
);
3069 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) else ... */
3074 /*****************************************************************************************
3077 moHidd_Gfx_CopyBoxMasked
3080 IPTR OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CopyBoxMasked *msg);
3082 IPTR HIDD_Gfx_CopyBoxMasked(OOP_Object *gfxHidd, OOP_Object *src, WORD srcX, WORD srcY,
3083 OOP_Object *dest, WORD destX, WORD destY, UWORD width, UWORD height,
3084 PLANEPTR mask, OOP_Object *gc);
3090 Perform rectangle copy (blit) operation from one bitmap to another,
3091 using a cookie cutter mask.
3093 Given bitmaps must be on the same display driver.
3095 A GC is used in order to specify raster operation performed between the source
3096 and destination according to its aHidd_GC_DrawMode attribute value.
3099 gfxHidd - a display driver object that you are going to use for copying
3100 src - a pointer to source bitmap object
3101 srcX - an X coordinate of the source rectangle
3102 srcY - a Y coordinate of the source rectangle
3103 dest - a pointer to destination bitmap object
3104 destX - an X coordinate of the destination rectangle
3105 destY - a Y coordinate of the destination rectangle
3106 width - width of the rectangle to copy
3107 height - height of the rectangle to copy
3108 mask - single bitplane mask
3109 gc - graphics context holding draw mode on the destination
3112 TRUE is the operation succeeded and FALSE in case of some error, for example
3113 if the system was too low on memory.
3116 You must specify valid coordinates (non-negative and inside the actual bitmap
3117 area), no checks are done.
3119 It is valid to specify two overlapped areas of the same bitmap as source
3122 Mask size must correspond to full source bitmap size (including alignment).
3132 *****************************************************************************************/
3134 /* Nominal size of the pixel conversion buffer */
3136 #define NUMPIX 4096 /* Not that much room to spare */
3138 #define NUMPIX 100000
3141 IPTR
GFXHIDD__Hidd_Gfx__CopyBoxMasked(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_Gfx_CopyBoxMasked
*msg
)
3143 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
3144 ULONG pixfmt
= vHidd_StdPixFmt_Native32
;
3145 OOP_Object
*src_pf
, *dest_pf
;
3146 HIDDT_ColorModel src_colmod
, dest_colmod
;
3147 HIDDT_Color
*ctab
= NULL
;
3148 ULONG bytes_per_line
, lines_per_step
, doing_lines
, lines_done
;
3149 IPTR mask_align
, mask_bpr
;
3152 OOP_GetAttr(msg
->src
, aHidd_BitMap_PixFmt
, (IPTR
*)&src_pf
);
3153 OOP_GetAttr(msg
->dest
, aHidd_BitMap_PixFmt
, (IPTR
*)&dest_pf
);
3155 OOP_GetAttr(src_pf
, aHidd_PixFmt_ColorModel
, &src_colmod
);
3156 OOP_GetAttr(dest_pf
, aHidd_PixFmt_ColorModel
, &dest_colmod
);
3158 if ((src_colmod
== vHidd_ColorModel_Palette
) && (dest_colmod
== vHidd_ColorModel_TrueColor
))
3161 * LUT->truecolor conversion. We need a colormap (palette).
3162 * If the source is displayable (screen) bitmap, it will have own palette. In this case
3164 * If it's just a bitmap in memory, it won't have a palette (colmap will be NULL). In this
3165 * case destination bitmap needs to have a palette. This will happen if it's either a displayable
3166 * bitmap, or is a friend of displayable bitmap (will share friend's palette then).
3168 HIDDT_ColorLUT
*colmap
= (HIDDT_ColorLUT
*)HBM(msg
->src
)->colmap
;
3171 colmap
= (HIDDT_ColorLUT
*)HBM(msg
->dest
)->colmap
;
3175 D(bug("BltMaskBitMapRastPort could not retrieve pixel table for blit from palette to truecolor bitmap"));
3179 ctab
= colmap
->colors
;
3181 else if ((src_colmod
== vHidd_ColorModel_TrueColor
) && (dest_colmod
== vHidd_ColorModel_TrueColor
))
3183 if (src_pf
!= dest_pf
)
3186 * Pixelformats are different, conversion needed.
3187 * First, we use two operations on destination bitmap (get and put), and only one
3188 * operation on source bitmap (get).
3189 * Second, we map LUT source pixels on destination bitmap's pixelformat.
3190 * Resume: we use destination's pixelformat for the whole operation. Conversion
3191 * happens during GetImage on the source bitmap.
3193 OOP_GetAttr(dest_pf
, aHidd_PixFmt_StdPixFmt
, (IPTR
*)&pixfmt
);
3196 else if ((src_colmod
== vHidd_ColorModel_TrueColor
) && (dest_colmod
== vHidd_ColorModel_Palette
))
3198 D(bug("BltMaskBitMapRastPort from truecolor bitmap to palette bitmap not supported!"));
3202 /* Mask width in pixels corresponds to full bitmap width (including alignment) */
3203 OOP_GetAttr(msg
->src
, aHidd_BitMap_Width
, &mask_bpr
);
3204 OOP_GetAttr(msg
->src
, aHidd_BitMap_Align
, &mask_align
);
3207 mask_bpr
= ((mask_bpr
+ mask_align
) & ~mask_align
) >> 3;
3210 * TODO: Here we use a temporary buffer to perform the operation. This is slow and
3211 * actually unnecessary is many cases. If one of source or destination bitmaps is
3212 * directly accessible, we should use their own buffers. This will increase the speed
3213 * and decrease memory usage, because of omitted copy operations.
3216 /* Based on the NUMPIX advice, figure out how many
3217 * lines per step we can allocate
3219 bytes_per_line
= msg
->width
* sizeof(HIDDT_Pixel
);
3220 lines_per_step
= NUMPIX
/ bytes_per_line
;
3221 if (lines_per_step
== 0)
3224 /* Allocate a temporary buffer */
3225 srcbuf
= AllocMem(2 * lines_per_step
* bytes_per_line
, MEMF_ANY
);
3227 /* Try line-at-a-time if we can't allocate a big buffer */
3228 if (!srcbuf
&& lines_per_step
> 1)
3231 srcbuf
= AllocMem(2 * lines_per_step
* bytes_per_line
, MEMF_ANY
);
3236 UBYTE
*destbuf
= srcbuf
+ lines_per_step
* bytes_per_line
;
3237 HIDDT_DrawMode drawmode
= GC_DRMD(msg
->gc
);
3239 /* PutImage needs to be called in Copy mode for proper operation */
3240 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
3242 for (lines_done
= 0; lines_done
!= msg
->height
; lines_done
+= doing_lines
)
3244 HIDDT_Pixel
*srcpixelbuf
;
3245 HIDDT_Pixel
*destpixelbuf
;
3249 doing_lines
= lines_per_step
;
3250 if (lines_done
+ doing_lines
> msg
->height
)
3251 doing_lines
= msg
->height
- lines_done
;
3253 HIDD_BM_GetImage(msg
->src
, srcbuf
, bytes_per_line
,
3254 msg
->srcX
, msg
->srcY
+ lines_done
,
3255 msg
->width
, doing_lines
, pixfmt
);
3257 HIDD_BM_GetImage(msg
->dest
, destbuf
, bytes_per_line
,
3258 msg
->destX
, msg
->destY
+ lines_done
,
3259 msg
->width
, doing_lines
, pixfmt
);
3261 mask
= &msg
->mask
[COORD_TO_BYTEIDX(0, msg
->srcY
+ lines_done
, mask_bpr
)];
3263 srcpixelbuf
= (HIDDT_Pixel
*)srcbuf
;
3264 destpixelbuf
= (HIDDT_Pixel
*)destbuf
;
3268 case vHidd_GC_DrawMode_Or
: /* (ABC|ABNC|ANBC) if copy source and blit thru mask */
3269 case vHidd_GC_DrawMode_Copy
: /* (ABC|ABNC = 0xC0) - compatibility with AOS3 */
3270 for (y
= 0; y
< doing_lines
; y
++)
3272 for (x
= 0; x
< msg
->width
; x
++)
3274 if (mask
[XCOORD_TO_BYTEIDX(msg
->srcX
+ x
)] & XCOORD_TO_MASK(msg
->srcX
+ x
))
3276 HIDDT_Pixel pix
= *srcpixelbuf
;
3282 * Here and in several other places we use colormap data for palette->truecolor conversion.
3283 * The algorithm is as follows: take LUT pixel value (which is effectively color index), find RGB
3284 * entry in the LUT, then compose a pixel from RGB triplet using MapColor method on the destination
3286 * This two-step operation is slow. graphics.library internally uses cached version of the palette
3287 * (HIDDT_PixLut), where all colors are already decoded into pixel values.
3288 * Since HIDD subsystem also needs this, this pixlut (called pixtab - pixel table in graphics.library),
3289 * should be moved here. In fact a good place for it is a bitmap object (since pixlut = colormap + pixfmt,
3290 * and pixfmt is a bitmap's property.
3291 * graphics.library has pixlut attached to a BitMap structure (using HIDD_BM_PIXTAB() macro).
3295 * !!!! HIDD_BM_MapColor() pokes pixval of the passed HIDDT_Color,
3296 * so if the address of the entry in the colormap is passed, the colormap
3297 * itself will be modified, if we pass "&ctab[pix]" to HIDD_BM_MapColor() !!!!
3300 HIDDT_Color col
= ctab
[pix
];
3302 pix
= HIDD_BM_MapColor(msg
->dest
, &col
);
3305 *destpixelbuf
= pix
;
3314 case vHidd_GC_DrawMode_AndInverted
: /* (ANBC) if invert source and blit thru mask */
3315 D(bug("CopyBoxMasked does not support ANBC minterm yet"));
3319 D(bug("CopyBoxMasked: DrawMode 0x%x not handled.\n", drawmode
));
3323 HIDD_BM_PutImage(msg
->dest
, msg
->gc
, destbuf
, bytes_per_line
,
3324 msg
->destX
, msg
->destY
+ lines_done
,
3325 msg
->width
, doing_lines
, pixfmt
);
3327 } /* for(lines_done = 0; lines_done != height; lines_done += doing_lines) */
3329 /* Restore GC state */
3330 GC_DRMD(msg
->gc
) = drawmode
;
3332 /* Free our temporary buffer */
3333 FreeMem(srcbuf
, 2 * lines_per_step
* bytes_per_line
);
3336 } /* if (lines_per_step) */
3339 /* urk :-( pixelbuffer too small to hold two lines) */
3340 D(bug("BltMaskBitMapRastPort found pixelbuffer to be too small"));
3346 /*****************************************************************************************
3349 moHidd_Gfx_ShowImminentReset
3352 VOID OOP_DoMethod(OOP_Object *obj, OOP_Msg msg);
3358 Indicate upcoming machine reset. Obsolete.
3360 Since graphics.library v41.4 this method is not used any more. Considered
3361 reserved. Do not use it in any way.
3379 *****************************************************************************************/
3381 VOID
GFXHIDD__Hidd_Gfx__ShowImminentReset(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg msg
)
3385 /****************************************************************************************/
3388 * The following two methods are private, static, and not virtual.
3389 * They operate only on static data and don't need object pointer.
3392 OOP_Object
*GFXHIDD__Hidd_Gfx__RegisterPixFmt(OOP_Class
*cl
, struct TagItem
*pixFmtTags
)
3394 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
3395 HIDDT_PixelFormat cmp_pf
;
3396 struct class_static_data
*data
;
3397 struct pixfmt_data
*retpf
= NULL
;
3399 memset(&cmp_pf
, 0, sizeof(cmp_pf
));
3402 if (!parse_pixfmt_tags(pixFmtTags
, &cmp_pf
, 0, CSD(cl
)))
3404 D(bug("!!! FAILED PARSING TAGS IN Gfx::RegisterPixFmt() !!!\n"));
3409 * Our alpha-less R8G8B8 pixelformats are defined as having depth
3410 * and size = 24, not 32 bits. Nevertheless, many hardware reports
3411 * 32 bits in such cases.
3412 * In order to avoid confusion we attempt to detect this situation and
3413 * fix up pixelformat definition. If we don't do it, we get nonstandard
3414 * pixelformat with no corresponding CGX code, which can misbehave.
3416 if ((cmp_pf
.flags
== PF_GRAPHTYPE(TrueColor
, Chunky
)) &&
3417 (cmp_pf
.bytes_per_pixel
== 4) && (cmp_pf
.alpha_mask
== 0) &&
3418 (cmp_pf
.red_mask
<< cmp_pf
.red_shift
== 0xFF000000) &&
3419 (cmp_pf
.green_mask
<< cmp_pf
.green_shift
== 0xFF000000) &&
3420 (cmp_pf
.blue_mask
<< cmp_pf
.blue_shift
== 0xFF000000))
3422 DPF(bug("Gfx::RegisterPixFmt(): 4-byte R8G8B8 detected\n"));
3424 if (cmp_pf
.depth
> 24)
3426 DPF(bug("Gfx::RegisterPixFmt(): Fixing up depth %d > 24\n", cmp_pf
.depth
));
3430 if (cmp_pf
.size
> 24)
3432 DPF(bug("Gfx::RegisterPixFmt(): Fixing up size %d > 24\n", cmp_pf
.size
));
3437 DPF(bug("Gfx::RegisterPixFmt(): Registering pixelformat:\n"));
3438 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3439 , PF(&cmp_pf
)->red_shift
3440 , PF(&cmp_pf
)->green_shift
3441 , PF(&cmp_pf
)->blue_shift
3442 , PF(&cmp_pf
)->alpha_shift
3443 , PF(&cmp_pf
)->red_mask
3444 , PF(&cmp_pf
)->green_mask
3445 , PF(&cmp_pf
)->blue_mask
3446 , PF(&cmp_pf
)->alpha_mask
3447 , PF(&cmp_pf
)->bytes_per_pixel
3449 , PF(&cmp_pf
)->depth
3450 , PF(&cmp_pf
)->stdpixfmt
));
3452 retpf
= find_pixfmt(&cmp_pf
, CSD(cl
));
3454 DPF(bug("Found matching pixelformat: 0x%p\n", retpf
));
3456 /* Increase pf refcount */
3457 AROS_ATOMIC_INC(retpf
->refcount
);
3460 /* Could not find an alike pf, Create a new pfdb node */
3461 /* Since we pass NULL as the taglist below, the PixFmt class will just create a dummy pixfmt */
3462 retpf
= OOP_NewObject(CSD(cl
)->pixfmtclass
, NULL
, NULL
);
3464 /* We have one user */
3465 retpf
->refcount
= 1;
3467 /* Initialize the pixfmt object the "ugly" way */
3468 memcpy(retpf
, &cmp_pf
, sizeof (HIDDT_PixelFormat
));
3470 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3471 , PF(&cmp_pf
)->red_shift
3472 , PF(&cmp_pf
)->green_shift
3473 , PF(&cmp_pf
)->blue_shift
3474 , PF(&cmp_pf
)->alpha_shift
3475 , PF(&cmp_pf
)->red_mask
3476 , PF(&cmp_pf
)->green_mask
3477 , PF(&cmp_pf
)->blue_mask
3478 , PF(&cmp_pf
)->alpha_mask
3479 , PF(&cmp_pf
)->bytes_per_pixel
3481 , PF(&cmp_pf
)->depth
3482 , PF(&cmp_pf
)->stdpixfmt
));
3484 ObtainSemaphore(&data
->pfsema
);
3485 AddTail((struct List
*)&data
->pflist
, (struct Node
*)&retpf
->node
);
3486 ReleaseSemaphore(&data
->pfsema
);
3490 DPF(bug("New refcount is %u\n", retpf
->refcount
));
3491 return (OOP_Object
*)retpf
;
3494 /****************************************************************************************/
3496 /* This method doesn't need object pointer, it's static. */
3498 VOID
GFXHIDD__Hidd_Gfx__ReleasePixFmt(OOP_Class
*cl
, OOP_Object
*pf
)
3500 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
3501 struct class_static_data
*data
;
3502 struct pixfmt_data
*pixfmt
= (struct pixfmt_data
*)pf
;
3504 DPF(bug("release_pixfmt 0x%p\n", pixfmt
));
3508 ObtainSemaphore(&data
->pfsema
);
3510 /* If refcount is already 0, this object was never registered in the database,
3512 DPF(bug("Old reference count is %u\n", pixfmt
->refcount
));
3513 if (pixfmt
->refcount
) {
3514 if (--pixfmt
->refcount
== 0) {
3515 Remove((struct Node
*)&pixfmt
->node
);
3516 OOP_DisposeObject((OOP_Object
*)pixfmt
);
3520 ReleaseSemaphore(&data
->pfsema
);
3523 /*****************************************************************************************
3526 moHidd_Gfx_CheckMode
3529 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CheckMode *msg);
3531 BOOL HIDD_Gfx_CheckMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3532 OOP_Object *sync, OOP_Object *pixFmt);
3538 Check if given display mode is supported by the driver.
3540 Normally any resolution (sync) can be used together with any pixelformat. However
3541 on some hardware there may be exceptions from this rule. In such a case this
3542 method should be implemented, and check should be performed.
3544 The information provided by this method is used in order to exclude unsupported
3545 modes from the database
3547 Default implementation in the base class just returns TRUE for all supplied values.
3549 Note that this method can not be used in order to chech that the given mode is
3550 really present in the database and it really refers to the given sync and
3551 pixelformat objects. Use HIDD_Gfx_GetMode() for mode ID validation.
3554 gfxHidd - A display driver object
3555 modeID - A display mode ID
3556 sync - A pointer to a sync object associated with this mode
3557 pixFmt - A pointer to a pixelformat object associated with this mode
3560 TRUE if this mode is supported and FALSE if it's not.
3567 Currently base class does not call this method after driver object creation.
3568 This needs to be fixed.
3575 *****************************************************************************************/
3577 BOOL
GFXHIDD__Hidd_Gfx__CheckMode(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CheckMode
*msg
)
3579 /* As a default we allways return TRUE, ie. the mode is OK */
3583 /*****************************************************************************************
3586 moHidd_Gfx_GetPixFmt
3589 OOP_Object *OOP_DoMethod(OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg);
3591 OOP_Object *HIDD_Gfx_GetPixFmt(OOP_Object *gfxHidd, HIDDT_StdPixFmt pixFmt);
3597 Get a standard pixelformat descriptor from internal pixelformats database.
3600 gfxHidd - A display driver object
3601 pixFmt - An index of pixelformat (one of vHIDD_StdPixFmt_... values)
3604 A pointer to a pixelformat object or NULL if lookup failed
3607 Pixelformat objects are stored in a global system-wide database. They are not
3608 linked with a particular driver in any way and completely sharable between all
3618 This operation can never fail because all standard pixelformats are registered
3619 during early system initialization.
3621 *****************************************************************************************/
3623 OOP_Object
*GFXHIDD__Hidd_Gfx__GetPixFmt(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetPixFmt
*msg
)
3627 if (!IS_REAL_STDPIXFMT(msg
->stdPixFmt
))
3629 D(bug("!!! Illegal pixel format passed to Gfx::GetPixFmt(): %d\n", msg
->stdPixFmt
));
3634 fmt
= (OOP_Object
*)CSD(cl
)->std_pixfmts
[REAL_STDPIXFMT_IDX(msg
->stdPixFmt
)];
3640 /*****************************************************************************************
3646 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetSync *msg);
3648 OOP_Object *HIDD_Gfx_GetSync(OOP_Object *gfxHidd, ULONG num);
3654 Get a sync object from internal display mode database by index
3657 gfxHidd - A display driver object to query
3658 num - An index of sync object starting from 0
3661 A pointer to a sync object or NULL if there's no sync with such index
3673 *****************************************************************************************/
3675 OOP_Object
*GFXHIDD__Hidd_Gfx__GetSync(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetSync
*msg
)
3677 struct HiddGfxData
*data
= OOP_INST_DATA(cl
, o
);
3679 if (msg
->num
< data
->mdb
.num_syncs
)
3680 return data
->mdb
.syncs
[msg
->num
];
3682 D(bug("!!! Illegal sync index passed to Gfx::GetSync(): %d\n", msg
->num
));
3687 /*****************************************************************************************
3690 moHidd_Gfx_ModeProperties
3693 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ModeProperties *msg);
3695 ULONG HIDD_Gfx_ModeProperties(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3696 struct HIDD_ModeProperties *props, ULONG propsLen);
3702 Obtain an information about the video mode.
3704 Video mode description structure may grow in future, so be careful and always check
3705 propsLen parameter value. A system may ask you for less data than you can provide.
3706 Always return an actual value. Do not just zero out fields you don't know about,
3707 this is not expected to be backwards compatible.
3710 gfxHidd - a pointer to a display driver object whose display mode you want to query
3711 modeID - a mode ID to query
3712 props - a pointer to a storage area where HIDD_ModeProperties structure will be put
3713 propsLen - length of the supplied buffer in bytes.
3716 Actual length of obtained structure
3719 Returned data must reflect only real hardware capabilities. For example, do not
3720 count emulated sprites. The system takes care about emulated features itself.
3727 aoHidd_Gfx_HWSpriteTypes, aoHidd_Gfx_SupportsHWCursor
3730 Default implementation in the base class relies on aHidd_Gfx_HWSpriteTypes attribute,
3731 not vice versa. If you override this method, do not forget to override this attribute too.
3733 *****************************************************************************************/
3735 ULONG
GFXHIDD__Hidd_Gfx__ModeProperties(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ModeProperties
*msg
)
3737 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
3738 struct HIDD_ModeProperties props
= {0, 0, 0};
3739 IPTR has_hw_cursor
= 0;
3740 ULONG len
= msg
->propsLen
;
3742 D(bug("[GFXHIDD] Hidd::Gfx::ModeProperties(0x%08lX, 0x%p, %u)\n", msg
->modeID
, msg
->props
, msg
->propsLen
));
3743 OOP_GetAttr(o
, aHidd_Gfx_HWSpriteTypes
, &has_hw_cursor
);
3744 if (has_hw_cursor
) {
3745 D(bug("[GFXHIDD] Driver has hardware mouse cursor implementation\n"));
3746 props
.DisplayInfoFlags
= DIPF_IS_SPRITES
;
3747 props
.NumHWSprites
= 1;
3750 if (len
> sizeof(props
))
3751 len
= sizeof(props
);
3752 D(bug("[GFXHIDD] Copying %u bytes\n", len
));
3753 CopyMem(&props
, msg
->props
, len
);
3758 /*****************************************************************************************
3764 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3766 BOOL HIDD_Gfx_GetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3772 Get current gamma table for the display.
3774 This method was neither ever implemented nor used. Currently obsolete and
3775 considered reserved.
3792 *****************************************************************************************/
3794 BOOL
GFXHIDD__Hidd_Gfx__GetGamma(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Gamma
*msg
)
3799 /*****************************************************************************************
3805 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3807 BOOL HIDD_Gfx_SetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3813 Set current gamma table for the display.
3815 A gamma table consists of three 256-byte tables: one for red component, one for
3816 green and one for blue.
3819 gfxHidd - A display driver object
3820 Red - A pointer to a 256-byte array for red component
3821 Green - A pointer to a 256-byte array for green component
3822 Blue - A pointer to a 256-byte array for blue component
3825 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3837 *****************************************************************************************/
3839 BOOL
GFXHIDD__Hidd_Gfx__SetGamma(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Gamma
*msg
)
3844 /*****************************************************************************************
3847 moHidd_Gfx_QueryHardware3D
3850 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryHardware3D *msg);
3852 BOOL HIDD_Gfx_QueryHardware3D(OOP_Object *gfxHidd, OOP_Object *pixFmt);
3858 Query if the driver supports hardware-accelerated 3D graphics for the given
3862 gfxHidd - A display driver object
3863 pixFmt - A pointer to a pixelformat descriptor object
3866 TRUE if the driver supports hardware-accelerated 3D for the given pixelformat,
3879 *****************************************************************************************/
3881 BOOL
GFXHIDD__Hidd_Gfx__QueryHardware3D(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_QueryHardware3D
*msg
)
3886 /*****************************************************************************************
3889 moHidd_Gfx_GetMaxSpriteSize
3892 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMaxSpriteSize *msg);
3894 BOOL HIDD_Gfx_GetMaxSpriteSize(OOP_Object *gfxHidd, ULONG Type, UWORD *Width, UWORD *Height);
3900 Query maximum allowed size for the given sprite type.
3903 gfxHidd - A display driver object
3904 Type - Type of the sprite image (one of vHidd_SpriteType_... values)
3905 Width - A pointer to UWORD where width will be placed.
3906 Height - A pointer to UWORD where height will be placed.
3909 FALSE is the given sprite type is not supported, otherwise TRUE.
3912 Default implementation in the base class just return some small values
3913 which it hopes can be supported by every driver if the driver supports given
3914 sprite type. It is strongly suggested to reimplement this method in the display
3917 Width and Height are considered undefined if the method returns FALSE.
3927 *****************************************************************************************/
3929 BOOL
GFXHIDD__Hidd_Gfx__GetMaxSpriteSize(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_GetMaxSpriteSize
*msg
)
3932 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
3934 OOP_GetAttr(o
, aHidd_Gfx_HWSpriteTypes
, &types
);
3936 if (types
& msg
->Type
) {
3944 /*****************************************************************************************
3947 moHidd_Gfx_NewOverlay
3950 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewOverlay *msg);
3952 OOP_Object *HIDD_Gfx_NewOverlay(OOP_Object *gfxHidd, struct TagItem *tagList);
3958 Create a video overlay object.
3961 gfxHidd - A graphics driver object on whose display you want to create an overlay.
3962 tagList - A list of overlay attributes. See overlay class documentation for
3966 Pointer to the newly created overlay object or NULL in case of failure.
3969 Default implementation in the base class always sets VOERR_INVSCRMODE error and
3970 returns NULL meaning that hardware overlays are not supported. There's no sense
3971 in software implementation because the software is supposed to handle software
3979 moHidd_Gfx_DisposeOverlay
3983 *****************************************************************************************/
3985 OOP_Object
*GFXHIDD__Hidd_Gfx__NewOverlay(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_NewOverlay
*msg
)
3987 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
3988 ULONG
*err
= (ULONG
*)GetTagData(aHidd_Overlay_Error
, 0, msg
->attrList
);
3991 *err
= VOERR_INVSCRMODE
;
3996 /*****************************************************************************************
3999 moHidd_Gfx_DisposeOverlay
4002 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeOverlay *msg);
4004 VOID HIDD_Gfx_DisposeOverlay(OOP_Object *gfxHidd, OOP_Object *Overlay)
4010 Deletes an overlay previously created by moHidd_Gfx_NewOverlay.
4012 Subclasses do not have to override this method
4013 unless they allocate anything additional to an overlay object in
4014 their HIDD_Gfx_NewOverlay() implementation.
4017 gfxHidd - A driver object which was used for creating a GC.
4018 Overlay - Pointer to an overlay object to delete.
4033 Basically just does OOP_DisposeObject(Overlay);
4035 *****************************************************************************************/
4037 VOID
GFXHIDD__Hidd_Gfx__DisposeOverlay(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_DisposeOverlay
*msg
)
4039 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
4040 OOP_DisposeObject(msg
->Overlay
);
4043 /*****************************************************************************************
4046 moHidd_Gfx_MakeViewPort
4049 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_MakeViewPort *msg);
4051 ULONG HIDD_Gfx_MakeViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
4057 Performs driver-specific setup on a given ViewPort.
4060 gfxHidd - A display driver object.
4061 data - a pointer to a HIDD_ViewPortData structure.
4064 The same code as used as return value for graphics.library/MakeVPort().
4067 When graphics.library calls this method, a complete view is not built yet.
4068 This means that data->Next pointer contains invalid data and needs to be
4071 It is valid to keep private data pointer in data->UserData accross calls.
4072 Newly created HIDD_ViewPortData is guraranteed to have NULL there.
4079 moHidd_Gfx_CleanViewPort
4082 Base class implementation just does nothing. This function is mainly intended
4083 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
4085 *****************************************************************************************/
4087 ULONG
GFXHIDD__Hidd_Gfx__MakeViewPort(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_MakeViewPort
*msg
)
4089 D(bug("Gfx::MakeViewPort: object 0x%p, data 0x%p\n", o
, msg
->Data
));
4094 /*****************************************************************************************
4097 moHidd_Gfx_CleanViewPort
4100 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CleanViewPort *msg);
4102 ULONG HIDD_Gfx_CleanViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
4108 Performs driver-specific cleanup on a given ViewPort.
4111 gfxHidd - A display driver object.
4112 data - a pointer to a HIDD_ViewPortDats structure.
4115 The same code as used as return value for graphics.library/MakeVPort().
4118 When graphics.library calls this method, the ViewPort is already unlinked
4119 from its view, and the bitmap can already be deallocated.
4120 This means that both data->Next and data->Bitmap pointers can contain invalid
4128 moHidd_Gfx_MakeViewPort
4131 Base class implementation just does nothing. This function is mainly intended
4132 to provide support for copperlist disposal by Amiga(tm) chipset driver.
4134 *****************************************************************************************/
4136 void GFXHIDD__Hidd_Gfx__CleanViewPort(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CleanViewPort
*msg
)
4138 D(bug("Gfx::CleanViewPort: object 0x%p, data 0x%p\n", o
, msg
->Data
));
4141 /*****************************************************************************************
4144 moHidd_Gfx_PrepareViewPorts
4147 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_PrepareViewPorts *msg);
4149 ULONG HIDD_Gfx_PrepareViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view)
4155 Performs driver-specific setup on a given view.
4158 gfxHidd - A display driver object.
4159 data - a pointer to a chain of HIDD_ViewPortData structures.
4160 view - A pointer to graphics.library View structure being prepared.
4163 MCOP_OK if there was no error or MCOP_NO_MEM otherwise.
4164 MCOP_NOP is not allowed as a return value of this method.
4167 graphics.library calls this method in MrgCop() after the complete view
4168 is built. data->Next pointer contains valid data.
4170 This function can be repeatedly called several times, and there is no
4171 cleanup counterpart for it. This should be taken into account in method
4181 Base class implementation just does nothing. This function is mainly intended
4182 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
4184 *****************************************************************************************/
4186 ULONG
GFXHIDD__Hidd_Gfx__PrepareViewPorts(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_ShowViewPorts
*msg
)
4191 /****************************************************************************************/
4193 /* This is a private nonvirtual method */
4194 void GFXHIDD__Hidd_Gfx__UpdateBitMap(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*bm
,
4195 struct pHidd_BitMap_UpdateRect
*msg
, struct Rectangle
*display
)
4197 struct HiddGfxData
*data
= OOP_INST_DATA(cl
, o
);
4200 * We check data->shownbm twice in order to avoid unnecessary locking
4201 * when our bitmap is not on display (it may be not displayable at all).
4202 * However the second check is still needed in order to make sure that
4203 * this bitmap is still on display, because we could be preempted between
4204 * the test and ObtainSemaphore() by concurrently running Show() call.
4205 * We use shared lock because it's safe to have two concurrently running
4206 * updates even on the same region.
4208 if ((data
->fbmode
== vHidd_FrameBuffer_Mirrored
) && (bm
== data
->shownbm
))
4210 ObtainSemaphoreShared(&data
->fbsem
);
4212 if (bm
== data
->shownbm
)
4215 * Complete update rectangle.
4216 * Display rectangle is already in bitmap's coordinates.
4218 UWORD srcX
= msg
->x
;
4219 UWORD srcY
= msg
->y
;
4220 UWORD xLimit
= srcX
+ msg
->width
;
4221 UWORD yLimit
= srcY
+ msg
->height
;
4223 /* Intersect rectangles */
4224 if (display
->MinX
> srcX
)
4225 srcX
= display
->MinX
;
4226 if (display
->MinY
> srcY
)
4227 srcY
= display
->MinY
;
4228 if (display
->MaxX
< xLimit
)
4229 xLimit
= display
->MaxX
;
4230 if (display
->MaxY
< yLimit
)
4231 yLimit
= display
->MaxY
;
4233 if ((xLimit
> srcX
) && (yLimit
> srcY
))
4235 HIDD_Gfx_CopyBox(o
, bm
, srcX
, srcY
,
4236 data
->framebuffer
, srcX
- display
->MinX
, srcY
- display
->MinY
,
4237 xLimit
- srcX
, yLimit
- srcY
, data
->gc
);
4241 ReleaseSemaphore(&data
->fbsem
);
4245 /****************************************************************************************/
4249 static inline BOOL
cmp_pfs(HIDDT_PixelFormat
*tmppf
, HIDDT_PixelFormat
*dbpf
)
4251 /* Just compare everything except stdpixfmt */
4252 /* Compare flags first (because it's a fast check) */
4253 if (tmppf
->flags
!= dbpf
->flags
)
4255 /* If they match, compare the rest of things */
4256 return !memcmp(tmppf
, dbpf
, offsetof(HIDDT_PixelFormat
, stdpixfmt
));
4259 static struct pixfmt_data
*find_pixfmt(HIDDT_PixelFormat
*tofind
, struct class_static_data
*csd
)
4261 struct pixfmt_data
*retpf
= NULL
;
4262 HIDDT_PixelFormat
*db_pf
;
4265 /* Go through the pixel format list to see if a similar pf allready exists */
4266 ObtainSemaphoreShared(&csd
->pfsema
);
4268 ForeachNode(&csd
->pflist
, n
)
4270 db_pf
= PIXFMT_OBJ(n
);
4271 DPF(bug("find_pixfmt(): Trying pixelformat 0x%p\n", db_pf
));
4272 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n",
4273 db_pf
->red_shift
, db_pf
->green_shift
, db_pf
->blue_shift
, db_pf
->alpha_shift
,
4274 db_pf
->red_mask
, db_pf
->green_mask
, db_pf
->blue_mask
, db_pf
->alpha_mask
,
4275 db_pf
->bytes_per_pixel
, db_pf
->size
, db_pf
->depth
, db_pf
->stdpixfmt
));
4276 if (cmp_pfs(tofind
, db_pf
))
4278 DPF(bug("Match!\n"));
4279 retpf
= (struct pixfmt_data
*)db_pf
;
4284 ReleaseSemaphore(&csd
->pfsema
);