Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / rom / hidds / graphics / GraphicsClass.c
blob91579939002423db9cec028d4f6e6c0f4859217c
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics hidd class implementation.
6 Lang: english
7 */
9 /****************************************************************************************/
11 #define DEBUG 0
12 #define SDEBUG 0
13 #define DPF(x)
14 #define DCOPYBOX(x)
16 #include <aros/atomic.h>
17 #include <aros/debug.h>
18 #include <aros/symbolsets.h>
19 #include <cybergraphx/cgxvideo.h>
20 #include <exec/lists.h>
21 #include <oop/static_mid.h>
22 #include <graphics/displayinfo.h>
23 #include <graphics/view.h>
25 #include "graphics_intern.h"
27 #include <string.h>
28 #include <stddef.h>
30 #include <proto/exec.h>
31 #include <proto/utility.h>
32 #include <proto/oop.h>
33 #include <exec/libraries.h>
34 #include <exec/memory.h>
36 #include <utility/tagitem.h>
38 #include LC_LIBDEFS_FILE
40 #include <hidd/graphics.h>
42 /*****************************************************************************************
44 NAME
45 --background_graphics--
47 LOCATION
48 hidd.graphics.graphics
50 NOTES
51 When working with graphics drivers this is the first object you get.
52 It allows you to create BitMap and GC (graphics context)
53 object. The class' methods must be overidden by hardware-specific
54 subclasses where documented to do so.
56 *****************************************************************************************/
58 /*****************************************************************************************
60 NAME
61 --display_modes--
63 LOCATION
64 hidd.graphics.graphics
66 NOTES
67 Each display driver object internally stores a database of supported display mode
68 IDs. This database is normally managed by base class, the driver does not need to
69 reimplement respective methods.
71 A display mode ID in AROS is a 32-bit integer value, the same as on AmigaOS(tm).
72 However mode ID layout introduced by Commodore does not fit well for RTG systems.
73 In order to overcome its limitations, display ID on AROS may have two forms:
75 1. A chipset mode ID. These are standard IDs defined by Commodore. You may find
76 their definitions in graphics/modeid.h.
78 2. AROS RTG mode ID.
80 An RTG mode ID is composed of three parts in the form:
82 nnnn xx yy
84 nnnn - monitor ID. This number is maintained by system libraries. IDs are
85 assigned in the order in which drivers are loaded and display hardware is
86 found. Drivers do not have to care about this part, and should normally
87 mask it out if they for some reason look at mode ID. In order to
88 distinguish between chipset mode IDs and RTG mode IDs, order number starts
89 not from zero, reserving some space for C= chipset mode IDs (which appear
90 to have order numbers from 0x0000 to 0x000A). Currently RTG monitor IDs
91 start from 0x0010, however with time this value may change. So don't rely
92 on some particular values in RTG IDs. Use cybergraphics.library/IsCyberModeID()
93 function if you want to know for sure if the given mode ID belongs to an
94 RTG driver.
96 xx - A sync object index in driver's mode database.
97 yy - A pixelformat object in driver's mode database.
99 Normally the driver does not have to care about mode ID decoding. The mode
100 database is maintained by base class. The only useful things for the driver are
101 sync and pixelformat objects, from which it's possible to get different
102 information about the mode. They can be obtained from the base class using
103 HIDD_Gfx_GetMode().
105 Note that the driver object by itself does not know its monitor ID. Different
106 displays are served by different objects, any of which may belong to any class.
107 So all driver methods which return mode IDs will set monitor ID to zero. All
108 methods that take mode ID as argument are expected to ignore the monitor ID part
109 and do not make any assumptions about its value.
111 *****************************************************************************************/
113 static BOOL create_std_pixfmts(struct class_static_data *_csd);
114 static VOID delete_pixfmts(struct class_static_data *_csd);
115 static BOOL register_modes(OOP_Class *cl, OOP_Object *o, struct TagItem *modetags);
117 static BOOL alloc_mode_db(struct mode_db *mdb, ULONG numsyncs, ULONG numpfs, OOP_Class *cl);
118 static VOID free_mode_db(struct mode_db *mdb, OOP_Class *cl);
119 static OOP_Object *create_and_init_object(OOP_Class *cl, UBYTE *data, ULONG datasize,
120 struct class_static_data *_csd);
122 static struct pixfmt_data *find_pixfmt(HIDDT_PixelFormat *tofind
123 , struct class_static_data *_csd);
125 static VOID copy_bm_and_colmap(OOP_Class *cl, OOP_Object *o, OOP_Object *src_bm
126 , OOP_Object *dst_bm, ULONG width, ULONG height);
128 BOOL parse_pixfmt_tags(struct TagItem *tags, HIDDT_PixelFormat *pf, ULONG attrcheck, struct class_static_data *_csd);
130 /****************************************************************************************/
132 #define COMPUTE_HIDD_MODEID(sync, pf) \
133 ( ((sync) << 8) | (pf) )
135 #define MODEID_TO_SYNCIDX(id) (((id) & 0X0000FF00) >> 8)
136 #define MODEID_TO_PFIDX(id) ( (id) & 0x000000FF)
138 /****************************************************************************************/
140 OOP_Object *GFX__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
142 struct HIDDGraphicsData *data;
143 BOOL ok = FALSE;
144 struct TagItem *modetags;
145 struct TagItem gctags[] =
147 {TAG_DONE, 0UL}
150 D(bug("Entering gfx.hidd::New\n"));
152 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
153 if (NULL == o)
154 return NULL;
156 D(bug("Got object o=%x\n", o));
158 data = OOP_INST_DATA(cl, o);
160 InitSemaphore(&data->mdb.sema);
161 /* data->curmode = vHidd_ModeID_Invalid; */
163 /* Get the mode tags */
164 modetags = (struct TagItem *)GetTagData(aHidd_Gfx_ModeTags, 0, msg->attrList);
165 if (NULL != modetags)
167 /* Parse it and register the gfxmodes */
168 if (register_modes(cl, o, modetags))
170 ok = TRUE;
172 else
173 D(bug("Could not register modes\n"));
175 else {
176 D(bug("Could not get ModeTags\n"));
177 ok = TRUE;
180 /* Create a gc that we can use for some rendering */
181 if (ok)
183 data->gc = OOP_NewObject(CSD(cl)->gcclass, NULL, gctags);
184 if (NULL == data->gc)
186 D(bug("Could not get gc\n"));
187 ok = FALSE;
191 if (!ok)
193 D(bug("Not OK\n"));
194 OOP_MethodID dispose_mid;
196 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
197 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
198 o = NULL;
201 D(bug("Leaving gfx.hidd::New o=%x\n", o));
203 return o;
206 /****************************************************************************************/
208 VOID GFX__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
210 struct HIDDGraphicsData *data;
212 data = OOP_INST_DATA(cl, o);
214 /* free the mode db stuff */
215 free_mode_db(&data->mdb, cl);
217 /* Here we should unregister pixelformats registered in our New().
218 However gfx drivers aren't supposed to be removed, so it's okay
219 not to do it at all for now. */
221 if (NULL != data->gc)
222 OOP_DisposeObject(data->gc);
224 OOP_DoSuperMethod(cl, o, msg);
227 /*****************************************************************************************
229 NAME
230 aoHidd_Gfx_IsWindowed
232 SYNOPSIS
233 [..G], BOOL
235 LOCATION
236 hidd.graphics.graphics
238 FUNCTION
239 Tells if the display driver is using hosted display in host OS' window, and mouse
240 input is handled by host OS.
242 Windowed displays may send activation events to AROS. This is needed in order to
243 correctly handle display switch in a multi-display configuration (which means that
244 the user has multiple windows on host OS desktop and can freely switch between them).
246 NOTES
247 Even in fullscreen mode drivers should still return TRUE if the host OS manages mouse
248 input (for example, X11 driver). If mouse input is not managed by the host OS
249 (for example, with Linux framebuffer driver), return FALSE.
251 EXAMPLE
253 BUGS
255 SEE ALSO
256 aoHidd_Gfx_ActiveCallBack, aoHidd_Gfx_ActiveCallBackData
258 INTERNALS
259 Base class always provides FALSE value
261 *****************************************************************************************/
263 /*****************************************************************************************
265 NAME
266 aoHidd_Gfx_DMPSLevel
268 SYNOPSIS
269 [ISG], HIDDT_DPMSLevel
271 LOCATION
272 hidd.graphics.graphics
274 FUNCTION
275 Gets or sets current DPMS level for driver's display.
276 A value can be one of:
277 vHidd_Gfx_DPMSLevel_On,
278 vHidd_Gfx_DPMSLevel_Standby,
279 vHidd_Gfx_DPMSLevel_Suspend,
280 vHidd_Gfx_DPMSLevel_Off
282 If the driver does not support some state, it's up to the driver what to do.
283 Usually it is expected to ignore the request.
285 Getting this attribute should return real current state.
287 NOTES
289 EXAMPLE
291 BUGS
293 SEE ALSO
295 INTERNALS
296 Base class always provides vHidd_Gfx_DPMSLevel_On value (comes from rootclass'
297 Get() which sets the value to 0).
299 *****************************************************************************************/
301 /*****************************************************************************************
303 NAME
304 aoHidd_Gfx_ModeTags
306 SYNOPSIS
307 [I..], struct TagItem *
309 LOCATION
310 hidd.graphics.graphics
312 FUNCTION
313 Specify a pointer to a taglist which contains description of display modes
314 supported by the driver.
316 This attribute is usually appended in moRoot_New method of the display driver
317 class.
319 This attribute is mandatory for the base class, otherwise driver object creation
320 fails.
322 Mode description taglist may contain the following tags:
323 - Any sync attributes - these attributes will specify values common for all sync
324 modes
325 - Any pixelformat attributes - these attributes will specify values common for
326 all pixelformat modes
327 - aoHidd_Gfx_SyncTags - specifies a pointer to another separate taglist containing
328 attributes for one sync (display) mode. If this tag
329 is not supplied at all, a set of default modes will be
330 generated for the driver.
331 - aoHidd_Gfx_PixFmtTags - specifies a pointer to another separate taglist containing
332 attributes for one pixelformat. This tag must be supplied
333 at least once, otherwise driver object will fail to create.
335 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags can be specified multiple times in
336 order to associate more than one display mode with the driver. Note that common
337 values for sync and pixelformat objects need to be placed in the taglist before
338 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags. You may specify them again between
339 these tags in order to alter common values.
341 NOTES
343 EXAMPLE
344 Partial example code of display driver supporting a truecolor display with three
345 resolutions:
347 // Our pixelformat (24-bit 0BGR)
348 struct TagItem pftags[] =
350 { aHidd_PixFmt_RedShift , 24 },
351 { aHidd_PixFmt_GreenShift , 16 },
352 { aHidd_PixFmt_BlueShift , 8 },
353 { aHidd_PixFmt_AlphaShift , 0 },
354 { aHidd_PixFmt_RedMask , 0x000000FF },
355 { aHidd_PixFmt_GreenMask , 0x0000FF00 },
356 { aHidd_PixFmt_BlueMask , 0x00FF0000 },
357 { aHidd_PixFmt_AlphaMask , 0x00000000 },
358 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_TrueColor },
359 { aHidd_PixFmt_Depth , 24 },
360 { aHidd_PixFmt_BytesPerPixel, 4 },
361 { aHidd_PixFmt_BitsPerPixel , 24 },
362 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Native },
363 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Chunky },
364 { TAG_DONE , 0UL }
367 // 640x480 resolution
368 struct TagItem tags_800_600[] =
370 { aHidd_Sync_HDisp , 640 },
371 { aHidd_Sync_VDisp , 480 },
372 { TAG_DONE , 0UL }
375 // 800x600 resolution
376 struct TagItem tags_800_600[] =
378 { aHidd_Sync_HDisp , 800 },
379 { aHidd_Sync_VDisp , 600 },
380 { TAG_DONE , 0UL }
383 // 1024x768 resolution
384 struct TagItem tags_1024_768[] =
386 { aHidd_Sync_HDisp , 1024 },
387 { aHidd_Sync_VDisp , 768 },
388 { TAG_DONE , 0UL }
391 // Mode description taglist itself
392 struct TagItem mode_tags[] =
394 // Our driver supports a single pixelformat
395 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
397 // Here go sync values common for all sync modes
398 { aHidd_Sync_HMin , 112 },
399 { aHidd_Sync_VMin , 112 },
400 { aHidd_Sync_HMax , 16384 },
401 { aHidd_Sync_VMax , 16384 },
402 { aHidd_Sync_Description, (IPTR)"Example: %hx%v" },
404 // First resolution
405 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
407 // Next two syncs will have HMax = 32768, as an example
408 { aHidd_Sync_HMax , 32768 },
410 // Two more resolutions
411 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
412 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
413 { TAG_DONE , 0UL }
416 // This is the attribute list which is given to New method
417 // of the base class
418 struct TagItem mytags[] =
420 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
421 { TAG_DONE , NULL }
424 BUGS
426 SEE ALSO
428 INTERNALS
430 *****************************************************************************************/
432 /*****************************************************************************************
434 NAME
435 aoHidd_Gfx_NumSyncs
437 SYNOPSIS
438 [..G], ULONG
440 LOCATION
441 hidd.graphics.graphics
443 FUNCTION
444 Gets total number of sync objects in the internal display mode database.
446 NOTES
448 EXAMPLE
450 BUGS
452 SEE ALSO
453 moHidd_Gfx_GetSync
455 INTERNALS
457 *****************************************************************************************/
459 /*****************************************************************************************
461 NAME
462 aoHidd_Gfx_SupportsHWCursor
464 SYNOPSIS
465 [..G], BOOL
467 LOCATION
468 hidd.graphics.graphics
470 FUNCTION
471 Tells whether the driver supports hardware mouse pointer sprite.
473 If the driver provides TRUE value for this attribute, it is expected to implement
474 HIDD_Gfx_SetCursorPos(), HIDD_Gfx_SetCursorShape() and HIDD_Gfx_SetCursorVisible()
475 methods.
477 Mouse pointer counts for one hardware sprite, so if the driver implements also
478 HIDD_Gfx_ModeProperties(), it should set NumHWSprites to 1 in order to provide
479 valid information about display modes.
481 The driver must implement this attribute if it implements HIDD_Gfx_ModeProperties().
482 Otherwise it will provide false information in graphics.library/GetDisplayInfoData().
483 Base class can determine NumHWSprites based on this attribute value but not vice
484 versa.
486 NOTES
487 Default implementation in the base class returns FALSE. This causes the system to
488 use software sprite emulation.
490 This attribute is obsolete and is used only by AROS graphics.library up to v41.2. In
491 new drivers consider implementing aoHidd_Gfx_HWSpriteTypes attribute.
493 EXAMPLE
495 BUGS
497 SEE ALSO
498 aoHidd_Gfx_HWSpriteTypes, moHidd_Gfx_ModeProperties
500 INTERNALS
502 *****************************************************************************************/
504 /*****************************************************************************************
506 NAME
507 aoHidd_Gfx_NoFrameBuffer
509 SYNOPSIS
510 [..G], BOOL
512 LOCATION
513 hidd.graphics.graphics
515 FUNCTION
516 Tells whether the driver does not need a framebuffer.
518 A framebuffer is a special bitmap in a fixed area of video RAM. If the framebuffer
519 is used, the driver is expected to copy a new bitmap into it in HIDD_Gfx_Show()
520 and optionally copy old bitmap back.
522 A framebuffer is needed if the hardware does not have enough VRAM to store many
523 bitmaps or does not have capabilities to switch the display between various VRAM
524 regions.
526 An example of driver using a framebuffer is hosted SDL driver. By design SDL works
527 only with single display window, which is considered a framebuffer.
529 NOTES
530 Provides FALSE if not implemented in the driver.
532 EXAMPLE
534 BUGS
536 SEE ALSO
537 moHidd_Gfx_Show
539 INTERNALS
540 VGA and VESA do not use framebuffer, they use mirroring technique instead in order
541 to prevents VRAM reading which is slow.
543 *****************************************************************************************/
545 /*****************************************************************************************
547 NAME
548 aoHidd_Gfx_HWSpriteTypes
550 SYNOPSIS
551 [..G], BOOL
553 LOCATION
554 hidd.graphics.graphics
556 FUNCTION
557 Return hardware sprite image types supported by the driver.
559 The returned value is a combination of the following bit flags:
560 vHidd_SpriteType_3Plus1 - color 0 is transparent, 1-3 visible
561 (Amiga(tm) chipset sprite format)
562 vHidd_SpriteType_2Plus1 - color 0 is transparent, color 1 is undefined
563 (can be whatever, for example clear or inverse),
564 colors 2-3 visible.
565 vHidd_SpriteType_DirectColor - Hi- or truecolor image, or LUT image with own
566 palette, perhaps with alpha channel
568 NOTES
569 This attribute should return 0 if the driver does not support hardware mouse sprite
570 at all. Software sprite emulation is done by graphics.library.
572 Default implementation in the base class is based on aoHidd_Gfx_SupportsHWCursor
573 value. This is done for backwards compatibility.
575 EXAMPLE
577 BUGS
579 SEE ALSO
580 aoHidd_Gfx_SupportsHWCursor
582 INTERNALS
583 Default implementation in the base class queries aoHidd_Gfx_SupportsHWCursor
584 and provides (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) in case
585 if it returns TRUE. Otherwise it returns zero. This is done for backwards
586 compatibility with old drivers.
588 *****************************************************************************************/
590 /*****************************************************************************************
592 NAME
593 aoHidd_Gfx_MemorySize
595 SYNOPSIS
596 [..G], ULONG
598 LOCATION
599 hidd.graphics.graphics
601 FUNCTION
602 Query total size of video card memory in bytes.
604 NOTES
606 EXAMPLE
608 BUGS
610 SEE ALSO
611 aoHidd_Gfx_MemoryClock
613 INTERNALS
615 *****************************************************************************************/
617 /*****************************************************************************************
619 NAME
620 aoHidd_Gfx_MemoryClock
622 SYNOPSIS
623 [..G], ULONG
625 LOCATION
626 hidd.graphics.graphics
628 FUNCTION
629 Query video card's memory clock in Hz. 0 is a valid value meaning 'unknown'.
631 NOTES
633 EXAMPLE
635 BUGS
637 SEE ALSO
638 aoHidd_Gfx_MemorySize
640 INTERNALS
642 *****************************************************************************************/
644 /*****************************************************************************************
646 NAME
647 aoHidd_Gfx_DriverName
649 SYNOPSIS
650 [..G], STRPTR
652 LOCATION
653 hidd.graphics.graphics
655 FUNCTION
656 Query CyberGraphX driver name. It is the same name which can be given to
657 cybergraphics.library/BestCModeIDTagList() as CYBRBIDTG_BoardName value.
659 NOTES
660 By default base class returns class name as value of this attribute.
661 However this can (and must for some drivers listed in BestCModeIDTagList()
662 documentation) be overriden.
664 EXAMPLE
666 BUGS
668 SEE ALSO
670 INTERNALS
672 *****************************************************************************************/
674 /*****************************************************************************************
676 NAME
677 aoHidd_Gfx_ActiveCallBack
679 SYNOPSIS
680 [.S.], void (*)(APTR userdata, OOP_Object *bitmap)
682 LOCATION
683 hidd.graphics.graphics
685 FUNCTION
686 Set display activation interrupt handler.
688 This handler needs to be called by hosted display driver, if host OS
689 windowing system is used for the display and mouse input is handled by the
690 host OS.
692 This way the driver can tell AROS when a display window has been activated so that
693 AROS will be able to switch current display correctly when working in a multi-display
694 configuration.
696 The function uses C calling convention and needs to be declared as follows:
698 void ActivationHandler(APTR userdata, OOP_Object *bitmap);
700 Parameters of this function will be:
701 userdata - Whatever is specified by aoHidd_Gfx_ActiveCallBackData attribute.
702 bitmap - Currently reserved. Drivers need to set it to NULL.
704 The function can be called from within an interrupt, so usual restrictions apply
705 to it.
707 Set this attribute to NULL in order to disable activation handling.
709 NOTES
710 When setting the activation callback function, be sure that you set correct
711 userdata before you actually set the callback pointer. Otherwise your callback
712 can be called with wrong data pointer.
714 Only one activation handler can be installed. Installing a new handler replaces
715 the previous one.
717 Native displays do not need to implement this attribute because there can be
718 no external activation events.
720 EXAMPLE
722 BUGS
724 SEE ALSO
725 aoHidd_Gfx_ActiveCallBackData, aoHidd_Gfx_IsWindowed
727 INTERNALS
728 This attribute needs to be implemented by the display driver. Base class contains
729 no implementation.
731 *****************************************************************************************/
733 /*****************************************************************************************
735 NAME
736 aoHidd_Gfx_ActiveCallBackData
738 SYNOPSIS
739 [.S.], APTR
741 LOCATION
742 hidd.graphics.graphics
744 FUNCTION
745 Set user-defined data pointer for display activation handler.
747 NOTES
749 EXAMPLE
751 BUGS
753 SEE ALSO
754 aoHidd_Gfx_ActiveCallBack
756 INTERNALS
757 This attribute needs to be implemented by the display driver. Base class contains
758 no implementation.
760 *****************************************************************************************/
762 VOID GFX__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
764 struct HIDDGraphicsData *data;
765 ULONG idx;
767 data = OOP_INST_DATA(cl, o);
769 if (IS_GFX_ATTR(msg->attrID, idx))
771 switch (idx)
773 case aoHidd_Gfx_NumSyncs:
774 *msg->storage = data->mdb.num_syncs;
775 return;
777 case aoHidd_Gfx_IsWindowed:
778 case aoHidd_Gfx_SupportsHWCursor:
779 *msg->storage = 0;
780 return;
782 case aoHidd_Gfx_HWSpriteTypes:
784 IPTR hwc;
786 OOP_GetAttr(o, aHidd_Gfx_SupportsHWCursor, &hwc);
787 *msg->storage = hwc ? (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) : 0;
788 return;
791 case aoHidd_Gfx_DriverName:
792 *msg->storage = (IPTR)OOP_OCLASS(o)->ClassNode.ln_Name;
793 return;
795 default: /* Keep compiler happy */
796 break;
800 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
802 return;
805 /*****************************************************************************************
807 NAME
808 moHidd_Gfx_NewGC
810 SYNOPSIS
811 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewGC *msg);
813 OOP_Object *HIDD_Gfx_NewGC(OOP_Object *gfxHidd, struct TagItem *tagList);
815 LOCATION
816 hidd.graphics.graphics
818 FUNCTION
819 Create a GC (gfx context) object that may be used for rendering
820 into a bitmap.
822 INPUTS
823 gfxHidd - A graphics driver object with which the GC will perform
824 the rendering operations.
825 tagList - A list of GC attributes. See hidd.graphics.gc class
826 documentation for their description.
828 RESULT
829 gc - pointer to the newly created GC, ready for use for rendering
830 operations.
832 NOTES
833 A GC object is just a data storage. You may create a subclass of GC if
834 you wish to, however there's usually no need to. Additionally, this may
835 be not future-proof (since GC subclasses can not be interchanged between
836 different drivers. Please avoid using custom GCs.
838 EXAMPLE
840 BUGS
841 At the moment subclassing GCs is not supported because some parts of
842 the operating system create GC objects directly. It is unclear whether
843 subclassing GCs is actually needed.
845 SEE ALSO
846 moHidd_Gfx_DisposeGC
848 INTERNALS
850 *****************************************************************************************/
852 OOP_Object *GFX__Hidd_Gfx__NewGC(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewGC *msg)
854 OOP_Object *gc = NULL;
856 EnterFunc(bug("HIDDGfx::NewGC()\n"));
858 gc = OOP_NewObject(NULL, CLID_Hidd_GC, msg->attrList);
860 ReturnPtr("HIDDGfx::NewGC", OOP_Object *, gc);
863 /*****************************************************************************************
865 NAME
866 moHidd_Gfx_DisposeGC
868 SYNOPSIS
869 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeGC *msg);
871 VOID HIDD_Gfx_DisposeGC(OOP_Object *gfxHidd, OOP_Object *gc)
873 LOCATION
874 hidd.graphics.graphics
876 FUNCTION
877 Deletes a GC (Graphics Context) object previously created
878 by HIDD_Gfx_NewGC().
880 Subclasses do not have to override this method
881 unless they allocate anything additional to a gc object in
882 their HIDD_Gfx_NewGC() implementation.
884 INPUTS
885 gfxHidd - A driver object which was used for creating a GC.
886 gc - Pointer to gc object to delete.
888 RESULT
889 None.
891 NOTES
893 EXAMPLE
895 BUGS
897 SEE ALSO
898 moHidd_Gfx_NewGC
900 INTERNALS
901 Basically just does OOP_DisposeObject(gc);
903 *****************************************************************************************/
905 VOID GFX__Hidd_Gfx__DisposeGC(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_DisposeGC *msg)
907 EnterFunc(bug("HIDDGfx::DisposeGC()\n"));
909 if (NULL != msg->gc) OOP_DisposeObject(msg->gc);
911 ReturnVoid("HIDDGfx::DisposeGC");
914 /****************************************************************************************/
916 #define BMAO(x) aoHidd_BitMap_ ## x
917 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
919 #define BM_DIMS_AF (BMAF(Width) | BMAF(Height))
921 #define SET_TAG(tags, idx, tag, val) \
922 tags[idx].ti_Tag = tag ; tags[idx].ti_Data = (IPTR)val;
924 #define SET_BM_TAG(tags, idx, tag, val) \
925 SET_TAG(tags, idx, aHidd_BitMap_ ## tag, val)
927 #define COPY_BM_TAG(tags, idx, tag, obj) \
928 tags[idx].ti_Tag = aHidd_BitMap_ ## tag; \
929 OOP_GetAttr(obj, aHidd_BitMap_ ## tag , &tags[idx].ti_Data)
931 /*****************************************************************************************
933 NAME
934 moHidd_Gfx_NewBitMap
936 SYNOPSIS
937 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewBitMap *msg);
939 OOP_Object *HIDD_Gfx_NewBitMap(OOP_Object *gfxHidd, struct TagItem *tagList);
941 LOCATION
942 hidd.graphics.graphics
944 FUNCTION
945 Create a bitmap object.
947 One graphics driver represents at least one displayable bitmap class.
948 Additionally it may represent more classes (for example some old drivers use
949 a separate class for nondisplayable bitmaps).
951 These classes are private to the driver. In order to be able to use them
952 bitmap objects are never created directly. Instead they are created using the
953 HIDD_Gfx_NewBitMap() call. An implementation of this method in the driver
954 should examine bitmap attributes supplied and make a decision if the bitmap
955 should be created using the driver's own class or one of the system classes.
957 A typical implementation should pay attention to the following bitmap attributes:
959 aHIDD_BitMap_ModeID - If this attribute is supplied, the bitmap needs to be
960 either displayable by this driver, or be a friend of a
961 displayable bitmap. A friend bitmap usually repeats the
962 internal layout of its friend so that the driver may
963 perform blitting operations quickly.
965 aHIDD_BitMap_Displayable - If this attribute is supplied, the bitmap NEEDS to be
966 displayable by this driver. Usually this means that
967 the bitmap object will contain video hardware state
968 information. This attribute will always be accompanied
969 by aHIDD_BitMap_ModeID.
971 aHIDD_BitMap_FrameBuffer - The bitmap needs to be a framebuffer bitmap. A
972 framebuffer bitmap is necessary for some kinds of
973 hardware which have a small fixed amount of video
974 RAM which can hold only one screen at a time. Setting
975 this attribute requires that a valid ModeID be also set.
977 aHIDD_BitMap_Friend - If there's no ModeID supplied, you may wish to check class
978 of friend bitmap. This can be useful if your driver uses
979 different classes for displayable and non-displayable bitmaps.
980 By default base class will pick up friend's class and use it
981 for new bitmap if nothing is specified, here you may override
982 this behavior.
984 If your driver wants to specify own class for the bitmap being created,
985 it should prepend an aHIDD_BitMap_ClassPtr attribute to the supplied taglist
986 and pass it to base class. It's not allowed to create bitmap objects directly
987 since they need some more extra information which is added by the base class!
989 This method must be implemented by your subclass. aHIDD_BitMap_ClassPtr or
990 aHIDD_BitMap_ClassID must be provided to the base class for a displayable bitmap!
992 INPUTS
993 gfxHidd - The graphics driver object that will provide the bitmap.
995 tagList - A list of bitmap attributes. See hidd.graphics.bitmap class
996 documentation for their descriptions.
998 RESULT
999 bm - pointer to the newly created bitmap.
1001 NOTES
1003 EXAMPLE
1005 BUGS
1007 SEE ALSO
1008 moHidd_Gfx_DisposeBitMap
1010 INTERNALS
1011 The base class implementation currently does the folliwing in order to determine
1012 a class for a nondisplayable bitmap (in the listed order):
1014 1. Check aHIDD_BitMap_ClassPtr and aHIDD_BitMap_ClassID. If one of them is supplied,
1015 the class is already set by a subclass.
1016 2. Check aHIDD_BitMap_StdPixFmt. If this attribute is supplied, figure out type of
1017 the pixelformat (chunky or planar), and use one of two system's default classes.
1018 3. Check aHIDD_BitMap_Friend. If friend bitmap is supplied, obtain its class from
1019 aHIDD_BitMap_ClassPtr value of friend bitmap.
1020 4. If everything fails, bitmap creation fails too.
1022 This behavior is subject to change, but will maintain backwards compatibility.
1024 *****************************************************************************************/
1026 OOP_Object * GFX__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o,
1027 struct pHidd_Gfx_NewBitMap *msg)
1029 struct HIDDGraphicsData *data = OOP_INST_DATA(cl, o);
1031 struct TagItem bmtags[] =
1033 {aHidd_BitMap_GfxHidd, 0}, /* 0 */
1034 {aHidd_BitMap_PixFmt , 0}, /* 1 */
1035 {TAG_IGNORE , 0}, /* 2 */
1036 {TAG_IGNORE , 0}, /* 3 */
1037 {TAG_IGNORE , 0}, /* 4 */
1038 {TAG_IGNORE , 0}, /* 5 */
1039 {TAG_MORE , 0}, /* 6 */
1041 OOP_Object *bm;
1043 const struct TagItem *tstate = msg->attrList;
1044 struct TagItem *tag;
1045 ULONG idx;
1047 STRPTR classid = NULL;
1048 OOP_Class *classptr = NULL;
1049 BOOL displayable = FALSE;
1050 BOOL framebuffer = FALSE;
1051 HIDDT_StdPixFmt pixfmt = vHidd_StdPixFmt_Unknown;
1052 OOP_Object *friend_bm = NULL;
1053 OOP_Object *sync = NULL;
1054 OOP_Object *pf = NULL;
1056 BOOL gotclass = FALSE;
1057 BOOL got_width = FALSE;
1058 BOOL got_height = FALSE;
1059 BOOL got_depth = FALSE;
1061 while ((tag = NextTagItem(&tstate)))
1063 if (IS_BITMAP_ATTR(tag->ti_Tag, idx))
1065 switch (idx)
1067 case aoHidd_BitMap_Displayable:
1068 displayable = tag->ti_Data;
1069 break;
1071 case aoHidd_BitMap_FrameBuffer:
1072 framebuffer = tag->ti_Data;
1073 break;
1075 case aoHidd_BitMap_Width:
1076 got_width = TRUE;
1077 break;
1079 case aoHidd_BitMap_Height:
1080 got_height = TRUE;
1081 break;
1083 case aoHidd_BitMap_Depth:
1084 got_depth = TRUE;
1085 break;
1087 case aoHidd_BitMap_ModeID:
1088 /* Make sure it is a valid mode, and retrieve sync/pixelformat data */
1089 if (!HIDD_Gfx_GetMode(o, tag->ti_Data, &sync, &pf))
1091 D(bug("!!! Gfx::NewBitMap: USER PASSED INVALID MODEID !!!\n"));
1092 return NULL;
1094 break;
1096 case aoHidd_BitMap_Friend:
1097 friend_bm = (OOP_Object *)tag->ti_Data;
1098 break;
1100 case aoHidd_BitMap_PixFmt:
1101 D(bug("!!! Gfx::NewBitMap: USER IS NOT ALLOWED TO PASS aHidd_BitMap_PixFmt !!!\n"));
1102 return NULL;
1104 case aoHidd_BitMap_StdPixFmt:
1105 pixfmt = tag->ti_Data;
1106 break;
1108 case aoHidd_BitMap_ClassPtr:
1109 classptr = (OOP_Class *)tag->ti_Data;
1110 gotclass = TRUE;
1111 break;
1113 case aoHidd_BitMap_ClassID:
1114 classid = (STRPTR)tag->ti_Data;
1115 gotclass = TRUE;
1116 break;
1121 if (friend_bm)
1123 /* If we have a friend bitmap, we can inherit some attributes from it */
1124 if (!got_width)
1126 COPY_BM_TAG(bmtags, 2, Width, friend_bm);
1127 got_width = TRUE;
1130 if (!got_height)
1132 COPY_BM_TAG(bmtags, 3, Height, friend_bm);
1133 got_height = TRUE;
1136 if (!got_depth)
1138 COPY_BM_TAG(bmtags, 4, Depth, friend_bm);
1142 /* FrameBuffer implies Displayable */
1143 if (framebuffer)
1145 SET_BM_TAG(bmtags, 5, Displayable, TRUE);
1146 displayable = TRUE;
1149 if (displayable)
1151 /* Displayable bitmap. Our subclass has to supply a ModeID and class. */
1152 if (!sync)
1154 D(bug("!!! Gfx::NewBitMap: USER HAS NOT PASSED MODEID FOR DISPLAYABLE BITMAP !!!\n"));
1155 return NULL;
1158 if (!gotclass)
1160 D(bug("!!! Gfx::NewBitMap: SUBCLASS DID NOT PASS CLASS FOR DISPLAYABLE BITMAP !!!\n"));
1161 return NULL;
1164 else /* if (!displayable) */
1167 * This is an offscreen bitmap and we need to guess its pixelformat.
1168 * In order to do this we need one of (in the order of preference):
1169 * - ModeID
1170 * - StdPixFmt
1171 * - Friend
1174 if (sync)
1177 * We have alredy got sync for the modeid case.
1178 * Obtain missing size information from it.
1180 if (!got_width)
1182 bmtags[2].ti_Tag = aHidd_BitMap_Width;
1183 OOP_GetAttr(sync, aHidd_Sync_HDisp, &bmtags[2].ti_Data);
1186 if (!got_height)
1188 bmtags[3].ti_Tag = aHidd_BitMap_Height;
1189 OOP_GetAttr(sync, aHidd_Sync_VDisp, &bmtags[3].ti_Data);
1192 else if (pixfmt != vHidd_StdPixFmt_Unknown)
1194 /* Next to look for is StdPixFmt */
1195 pf = HIDD_Gfx_GetPixFmt(o, pixfmt);
1196 if (NULL == pf)
1198 D(bug("!!! Gfx::NewBitMap(): USER PASSED BOGUS StdPixFmt !!!\n"));
1199 return NULL;
1202 else if (friend_bm)
1204 /* Last alternative is that the user passed a friend bitmap */
1206 OOP_GetAttr(friend_bm, aHidd_BitMap_PixFmt, (IPTR *)&pf);
1208 /* Try to grab the class from friend bitmap (if not already specified).
1209 We do it because friend bitmap may be a display HIDD bitmap */
1210 if (!gotclass)
1212 /* Another weirdness is that we have to use this attribute instead of
1213 simple getting OOP_OCLASS(friend_bm). We can't get class directly
1214 from the object, because the framebuffer bitmap object may be a
1215 fakegfx.hidd object, which is even not a bitmap at all. Attempt
1216 to create a bitmap of this class causes system-wide breakage.
1217 Perhaps fakegfx HIDD should be fixed in order to handle this correctly.
1219 OOP_GetAttr(friend_bm, aHidd_BitMap_ClassPtr, (IPTR *)&classptr);
1220 D(bug("[GFX] Friend bitmap is 0x%p has ClassPtr 0x%p\n", friend_bm, classptr));
1222 if (classptr)
1223 gotclass = TRUE;
1226 else
1228 D(bug("!!! Gfx::NewBitMap: UNSIFFICIENT ATTRS TO CREATE OFFSCREEN BITMAP !!!\n"));
1229 return NULL;
1232 /* Did the subclass provide an offbitmap class for us ? */
1233 if (!gotclass)
1235 /* Have to find a suitable class ourselves from the pixelformat */
1236 HIDDT_BitMapType bmtype;
1238 OOP_GetAttr(pf, aHidd_PixFmt_BitMapType, &bmtype);
1239 switch (bmtype)
1241 case vHidd_BitMapType_Chunky:
1242 classptr = CSD(cl)->chunkybmclass;
1243 break;
1245 case vHidd_BitMapType_Planar:
1246 classptr = CSD(cl)->planarbmclass;
1247 break;
1249 default:
1250 D(bug("!!! Gfx::NewBitMap: UNKNOWN BITMAPTYPE %d !!!\n", bmtype));
1251 return NULL;
1253 D(bug("[GFX] Bitmap type is %u, using class 0x%p\n", bmtype, classptr));
1255 } /* if (!gotclass) */
1257 } /* if (!displayable) */
1259 /* Set the tags we want to pass to the selected bitmap class */
1260 bmtags[0].ti_Data = (IPTR)o;
1261 bmtags[1].ti_Data = (IPTR)pf;
1262 bmtags[6].ti_Data = (IPTR)msg->attrList;
1264 bm = OOP_NewObject(classptr, classid, bmtags);
1266 if (framebuffer)
1268 /* Remember the framebuffer. It can be needed for default Show() implementation. */
1269 data->framebuffer = bm;
1272 return bm;
1276 /*****************************************************************************************
1278 NAME
1279 moHidd_Gfx_DisposeBitMap
1281 SYNOPSIS
1282 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeBitMap *msg);
1284 VOID HIDD_Gfx_DisposeBitMap(OOP_Object *gfxHidd, OOP_Object *bitMap);
1286 LOCATION
1287 hidd.graphics.graphics
1289 FUNCTION
1290 Deletes a bitmap object previously created by HIDD_Gfx_NewBitMap().
1292 Subclasses do not have to override this method
1293 unless they allocate anything additional to a bitmap object in
1294 their HIDD_Gfx_NewBitMap() implementation.
1296 INPUTS
1297 gfxHidd - A driver object which was used for creating a bitmap.
1298 bitMap - Pointer to a bitmap object to delete.
1300 RESULT
1301 None.
1303 NOTES
1305 EXAMPLE
1307 BUGS
1309 SEE ALSO
1310 moHidd_Gfx_NewBitMap
1312 INTERNALS
1313 Basically just does OOP_DisposeObject(bitMap);
1315 ******************************************************************************************/
1317 VOID GFX__Hidd_Gfx__DisposeBitMap(OOP_Class *cl, OOP_Object *o,
1318 struct pHidd_Gfx_DisposeBitMap *msg)
1320 if (NULL != msg->bitMap)
1321 OOP_DisposeObject(msg->bitMap);
1324 /****************************************************************************************/
1326 #define SD(x) ((struct sync_data *)x)
1327 #define PF(x) ((HIDDT_PixelFormat *)x)
1329 #define XCOORD_TO_BYTEIDX(x) ( (x) >> 3)
1330 #define COORD_TO_BYTEIDX(x, y, bpr) ( ( (y) * bpr ) + XCOORD_TO_BYTEIDX(x) )
1331 #define XCOORD_TO_MASK(x) (1L << (7 - ((x) & 0x07) ))
1332 #define WIDTH_TO_BYTES(width) ( (( (width) - 1) >> 3) + 1)
1334 /****************************************************************************************/
1336 /* modebm functions pfidx is x and syncidx is y coord in the bitmap */
1338 /****************************************************************************************/
1340 static inline BOOL alloc_mode_bm(struct mode_bm *bm, ULONG numsyncs, ULONG numpfs,
1341 OOP_Class *cl)
1343 bm->bpr = WIDTH_TO_BYTES(numpfs);
1345 bm->bm = AllocVec(bm->bpr * numsyncs, MEMF_CLEAR);
1346 if (NULL == bm->bm)
1347 return FALSE;
1349 /* We initialize the mode bitmap to all modes valid */
1350 memset(bm->bm, 0xFF, bm->bpr * numsyncs);
1352 return TRUE;
1355 /****************************************************************************************/
1357 static inline VOID free_mode_bm(struct mode_bm *bm, OOP_Class *cl)
1359 FreeVec(bm->bm);
1360 bm->bm = NULL;
1361 bm->bpr = 0;
1364 /****************************************************************************************/
1366 static inline BOOL is_valid_mode(struct mode_bm *bm, ULONG syncidx, ULONG pfidx)
1368 if (0 != (XCOORD_TO_MASK(pfidx) & bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)]))
1369 return TRUE;
1371 return FALSE;
1374 /****************************************************************************************/
1376 static inline VOID set_valid_mode(struct mode_bm *bm, ULONG syncidx, ULONG pfidx,
1377 BOOL valid)
1379 if (valid)
1380 bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)] |= XCOORD_TO_MASK(pfidx);
1381 else
1382 bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)] &= ~XCOORD_TO_MASK(pfidx);
1384 return;
1387 /****************************************************************************************/
1389 static BOOL alloc_mode_db(struct mode_db *mdb, ULONG numsyncs, ULONG numpfs, OOP_Class *cl)
1391 BOOL ok = FALSE;
1393 if (0 == numsyncs || 0 == numpfs)
1394 return FALSE;
1396 ObtainSemaphore(&mdb->sema);
1397 /* free_mode_bm() needs this */
1398 mdb->num_pixfmts = numpfs;
1399 mdb->num_syncs = numsyncs;
1401 mdb->syncs = AllocMem(sizeof (OOP_Object *) * numsyncs, MEMF_CLEAR);
1403 if (NULL != mdb->syncs)
1405 mdb->pixfmts = AllocMem(sizeof (OOP_Object *) * numpfs, MEMF_CLEAR);
1407 if (NULL != mdb->pixfmts)
1409 if (alloc_mode_bm(&mdb->orig_mode_bm, numsyncs, numpfs, cl))
1411 if (alloc_mode_bm(&mdb->checked_mode_bm, numsyncs, numpfs, cl))
1413 ok = TRUE;
1419 if (!ok)
1420 free_mode_db(mdb, cl);
1422 ReleaseSemaphore(&mdb->sema);
1424 return ok;
1427 /****************************************************************************************/
1429 static VOID free_mode_db(struct mode_db *mdb, OOP_Class *cl)
1431 ULONG i;
1433 ObtainSemaphore(&mdb->sema);
1435 if (NULL != mdb->pixfmts)
1438 /* Pixelformats are shared objects and never freed */
1439 FreeMem(mdb->pixfmts, sizeof (OOP_Object *) * mdb->num_pixfmts);
1440 mdb->pixfmts = NULL; mdb->num_pixfmts = 0;
1443 if (NULL != mdb->syncs)
1445 for (i = 0; i < mdb->num_syncs; i ++)
1447 if (NULL != mdb->syncs[i])
1450 OOP_DisposeObject(mdb->syncs[i]);
1451 mdb->syncs[i] = NULL;
1455 FreeMem(mdb->syncs, sizeof (OOP_Object *) * mdb->num_syncs);
1456 mdb->syncs = NULL; mdb->num_syncs = 0;
1459 if (NULL != mdb->orig_mode_bm.bm)
1461 free_mode_bm(&mdb->orig_mode_bm, cl);
1464 if (NULL != mdb->checked_mode_bm.bm)
1466 free_mode_bm(&mdb->checked_mode_bm, cl);
1469 ReleaseSemaphore(&mdb->sema);
1471 return;
1474 /****************************************************************************************/
1476 /* Initializes default tagarray. in numtags the TAG_MORE is not accounted for,
1477 so the array must be of size NUM_TAGS + 1
1480 /****************************************************************************************/
1482 static VOID init_def_tags(struct TagItem *tags, ULONG numtags)
1484 ULONG i;
1486 for (i = 0; i < numtags; i ++)
1488 tags[i].ti_Tag = TAG_IGNORE;
1489 tags[i].ti_Data = 0UL;
1492 tags[i].ti_Tag = TAG_MORE;
1493 tags[i].ti_Data = 0UL;
1495 return;
1498 /****************************************************************************************/
1500 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
1501 struct TagItem sync_ ## name[]={ \
1502 { aHidd_Sync_PixelClock, clock*1000 }, \
1503 { aHidd_Sync_HDisp, hdisp }, \
1504 { aHidd_Sync_HSyncStart, hstart }, \
1505 { aHidd_Sync_HSyncEnd, hend }, \
1506 { aHidd_Sync_HTotal, htotal }, \
1507 { aHidd_Sync_VDisp, vdisp }, \
1508 { aHidd_Sync_VSyncStart, vstart }, \
1509 { aHidd_Sync_VSyncEnd, vend }, \
1510 { aHidd_Sync_VTotal, vtotal }, \
1511 { aHidd_Sync_Description, (IPTR)descr}, \
1512 { TAG_DONE, 0UL }}
1514 static BOOL register_modes(OOP_Class *cl, OOP_Object *o, struct TagItem *modetags)
1516 struct TagItem *tag, *tstate;
1517 struct HIDDGraphicsData *data;
1519 MAKE_SYNC(640x480_60, 25174,
1520 640, 656, 752, 800,
1521 480, 490, 492, 525,
1522 "Default:640x480");
1524 MAKE_SYNC(800x600_56, 36000, // 36000
1525 800, 824, 896, 1024,
1526 600, 601, 603, 625,
1527 "Default:800x600");
1529 MAKE_SYNC(1024x768_60, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
1530 1024, 1048, 1184, 1344,
1531 768, 771, 777, 806,
1532 "Default:1024x768");
1534 MAKE_SYNC(1152x864_60, 80000,
1535 1152, 1216, 1328, 1456,
1536 864, 870, 875, 916,
1537 "Default:1152x864");
1539 MAKE_SYNC(1280x1024_60, 108880,
1540 1280, 1360, 1496, 1712,
1541 1024, 1025, 1028, 1060,
1542 "Default:1280x1024");
1544 MAKE_SYNC(1600x1200_60, 155982,
1545 1600, 1632, 1792, 2048,
1546 1200, 1210, 1218, 1270,
1547 "Default:1600x1200");
1549 /* "new" 16:10 modes */
1551 MAKE_SYNC(1280x800_60, 83530,
1552 1280, 1344, 1480, 1680,
1553 800, 801, 804, 828,
1554 "Default:1280x800");
1556 MAKE_SYNC(1440x900_60, 106470,
1557 1440, 1520, 1672, 1904,
1558 900, 901, 904, 932,
1559 "Default:1440x900");
1561 MAKE_SYNC(1680x1050_60, 147140,
1562 1680, 1784, 1968, 2256,
1563 1050, 1051, 1054, 1087,
1564 "Default:1680x1050");
1566 MAKE_SYNC(1920x1080_60, 173000,
1567 1920, 2048, 2248, 2576,
1568 1080, 1083, 1088, 1120,
1569 "Default:1920x1080");
1571 MAKE_SYNC(1920x1200_60, 154000,
1572 1920, 1968, 2000, 2080,
1573 1200, 1203, 1209, 1235,
1574 "Default:1920x1200");
1576 struct mode_db *mdb;
1578 HIDDT_PixelFormat pixfmt_data;
1580 struct TagItem def_sync_tags[num_Hidd_Sync_Attrs + 1];
1581 struct TagItem def_pixfmt_tags[num_Hidd_PixFmt_Attrs + 1];
1583 ULONG numpfs = 0,numsyncs = 0;
1584 ULONG pfidx = 0, syncidx = 0;
1586 struct TagItem temporary_tags[] = {
1587 { aHidd_Gfx_SyncTags, (IPTR)sync_640x480_60 },
1588 { aHidd_Gfx_SyncTags, (IPTR)sync_800x600_56 },
1589 { aHidd_Gfx_SyncTags, (IPTR)sync_1024x768_60 },
1590 { aHidd_Gfx_SyncTags, (IPTR)sync_1152x864_60 },
1591 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x1024_60 },
1592 { aHidd_Gfx_SyncTags, (IPTR)sync_1600x1200_60 },
1593 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x800_60 },
1594 { aHidd_Gfx_SyncTags, (IPTR)sync_1440x900_60 },
1595 { aHidd_Gfx_SyncTags, (IPTR)sync_1680x1050_60 },
1596 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1080_60 },
1597 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1200_60 },
1598 { TAG_MORE, 0UL }
1601 data = OOP_INST_DATA(cl, o);
1602 mdb = &data->mdb;
1603 InitSemaphore(&mdb->sema);
1605 memset(&pixfmt_data, 0, sizeof (pixfmt_data));
1607 init_def_tags(def_sync_tags, num_Hidd_Sync_Attrs);
1608 init_def_tags(def_pixfmt_tags, num_Hidd_PixFmt_Attrs);
1610 def_sync_tags[aoHidd_Sync_GfxHidd].ti_Tag = aHidd_Sync_GfxHidd;
1611 def_sync_tags[aoHidd_Sync_GfxHidd].ti_Data = (IPTR)o;
1613 /* First we need to calculate how much memory we are to allocate by counting supplied
1614 pixel formats and syncs */
1616 for (tstate = modetags; (tag = NextTagItem((const struct TagItem **)&tstate));)
1618 ULONG idx;
1620 if (IS_GFX_ATTR(tag->ti_Tag, idx))
1622 switch (idx)
1624 case aoHidd_Gfx_PixFmtTags:
1625 numpfs++;
1626 break;
1628 case aoHidd_Gfx_SyncTags:
1629 numsyncs ++;
1630 break;
1632 default:
1633 break;
1638 if (0 == numpfs)
1640 D(bug("!!! WE MUST AT LEAST HAVE ONE PIXFMT IN Gfx::RegisterModes() !!!\n"));
1643 if (0 == numsyncs)
1645 D(bug("!!! NO SYNC IN Gfx::RegisterModes() !!!\n!!! USING DEFAULT MODES !!!\n"));
1646 temporary_tags[11].ti_Tag = TAG_MORE;
1647 temporary_tags[11].ti_Data = (IPTR)modetags;
1648 modetags = &temporary_tags[0];
1649 numsyncs = 11;
1652 ObtainSemaphore(&mdb->sema);
1654 /* Allocate memory for mode db */
1655 if (!alloc_mode_db(&data->mdb, numsyncs, numpfs, cl))
1656 goto failure;
1659 for (tstate = modetags; (tag = NextTagItem((const struct TagItem **)&tstate));)
1661 /* Look for Gfx, PixFmt and Sync tags */
1662 ULONG idx;
1664 if (IS_GFX_ATTR(tag->ti_Tag, idx))
1666 switch (idx)
1668 case aoHidd_Gfx_PixFmtTags:
1669 def_pixfmt_tags[num_Hidd_PixFmt_Attrs].ti_Data = tag->ti_Data;
1670 mdb->pixfmts[pfidx] = GFX__Hidd_Gfx__RegisterPixFmt(cl, o, def_pixfmt_tags);
1672 if (NULL == mdb->pixfmts[pfidx])
1674 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
1675 goto failure;
1678 pfidx ++;
1679 break;
1681 case aoHidd_Gfx_SyncTags:
1682 def_sync_tags[num_Hidd_Sync_Attrs].ti_Data = tag->ti_Data;
1684 mdb->syncs[syncidx] = OOP_NewObject(CSD(cl)->syncclass, NULL, def_sync_tags);
1685 if (!mdb->syncs[syncidx]) {
1686 D(bug("!!! UNABLE TO CREATE SYNC OBJECT IN Gfx::RegisterModes() !!!\n"));
1687 goto failure;
1690 syncidx ++;
1691 break;
1695 else if (IS_SYNC_ATTR(tag->ti_Tag, idx))
1697 if (idx >= num_Hidd_Sync_Attrs)
1699 D(bug("!!! UNKNOWN SYNC ATTR IN Gfx::New(): %d !!!\n", idx));
1701 else
1703 def_sync_tags[idx].ti_Tag = tag->ti_Tag;
1704 def_sync_tags[idx].ti_Data = tag->ti_Data;
1708 else if (IS_PIXFMT_ATTR(tag->ti_Tag, idx))
1710 if (idx >= num_Hidd_PixFmt_Attrs)
1712 D(bug("!!! UNKNOWN PIXFMT ATTR IN Gfx::New(): %d !!!\n", idx));
1714 else
1716 def_pixfmt_tags[idx].ti_Tag = tag->ti_Tag;
1717 def_pixfmt_tags[idx].ti_Data = tag->ti_Data;
1722 ReleaseSemaphore(&mdb->sema);
1724 return TRUE;
1726 failure:
1728 /* mode db is freed in dispose */
1729 ReleaseSemaphore(&mdb->sema);
1731 return FALSE;
1734 /****************************************************************************************/
1736 struct modequery
1738 struct mode_db *mdb;
1739 ULONG minwidth;
1740 ULONG maxwidth;
1741 ULONG minheight;
1742 ULONG maxheight;
1743 HIDDT_StdPixFmt *stdpfs;
1744 ULONG numfound;
1745 ULONG pfidx;
1746 ULONG syncidx;
1747 BOOL dims_ok;
1748 BOOL stdpfs_ok;
1749 BOOL check_ok;
1750 OOP_Class *cl;
1753 /****************************************************************************************/
1755 /* This is a recursive function that looks for valid modes */
1757 /****************************************************************************************/
1759 static HIDDT_ModeID *querymode(struct modequery *mq)
1761 HIDDT_ModeID *modeids;
1762 register OOP_Object *pf;
1763 register OOP_Object *sync;
1764 BOOL mode_ok = FALSE;
1765 ULONG syncidx, pfidx;
1767 mq->dims_ok = FALSE;
1768 mq->stdpfs_ok = FALSE;
1769 mq->check_ok = FALSE;
1771 /* Look at the supplied idx */
1772 if (mq->pfidx >= mq->mdb->num_pixfmts)
1774 mq->pfidx = 0;
1775 mq->syncidx ++;
1778 if (mq->syncidx >= mq->mdb->num_syncs)
1780 /* We have reached the end of the recursion. Allocate memory and go back
1783 modeids = AllocVec(sizeof (HIDDT_ModeID) * (mq->numfound + 1), MEMF_ANY);
1784 /* Get the end of the array */
1785 modeids += mq->numfound;
1786 *modeids = vHidd_ModeID_Invalid;
1788 return modeids;
1791 syncidx = mq->syncidx;
1792 pfidx = mq->pfidx;
1793 /* Get the pf and sync objects */
1794 pf = mq->mdb->pixfmts[syncidx];
1795 sync = mq->mdb->syncs[pfidx];
1798 /* Check that the mode is really usable */
1799 if (is_valid_mode(&mq->mdb->checked_mode_bm, syncidx, pfidx))
1801 mq->check_ok = TRUE;
1804 /* See if this mode matches the criterias set */
1806 if ( SD(sync)->hdisp >= mq->minwidth
1807 && SD(sync)->hdisp <= mq->maxwidth
1808 && SD(sync)->vdisp >= mq->minheight
1809 && SD(sync)->vdisp <= mq->maxheight )
1813 mq->dims_ok = TRUE;
1815 if (NULL != mq->stdpfs)
1817 register HIDDT_StdPixFmt *stdpf = mq->stdpfs;
1818 while (*stdpf)
1820 if (*stdpf == PF(pf)->stdpixfmt)
1822 mq->stdpfs_ok = TRUE;
1824 stdpf ++;
1827 else
1829 mq->stdpfs_ok = TRUE;
1835 if (mq->dims_ok && mq->stdpfs_ok && mq->check_ok)
1837 mode_ok = TRUE;
1838 mq->numfound ++;
1841 mq->pfidx ++;
1843 modeids = querymode(mq);
1845 if (NULL == modeids)
1846 return NULL;
1848 if (mode_ok)
1850 /* The mode is OK. Add it to the list */
1851 modeids --;
1852 *modeids = COMPUTE_HIDD_MODEID(syncidx, pfidx);
1855 return modeids;
1859 /*****************************************************************************************
1861 NAME
1862 moHidd_Gfx_QueryModeIDs
1864 SYNOPSIS
1865 HIDDT_ModeID *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryModeIDs *msg);
1867 HIDDT_ModeID *HIDD_Gfx_QueryModeIDs(OOP_Object *gfxHidd, struct TagItem *queryTags);
1869 LOCATION
1870 hidd.graphics.graphics
1872 FUNCTION
1873 Obtain a table of all supported display mode IDs
1875 The returned address points to an array of HIDDT_ModeID containing all ModeIDs
1876 supported by this driver. The array is terminated with vHidd_ModeID_Invalid.
1878 INPUTS
1879 gfxHidd - A driver object which to query.
1880 querytags - An optional taglist containing query options. Can be NULL.
1881 The following tags are supported:
1883 tHidd_GfxMode_MinWidth (ULONG) - A minimum width of modes you are
1884 interested in
1885 tHidd_GfxMode_MaxWidth (ULONG) - A maximum width of modes you are
1886 interested in
1887 tHidd_GfxMode_MinHeight (ULONG) - A minimum height of modes you are
1888 interested in
1889 tHidd_GfxMode_MaxHeight (ULONG) - A maximum height of modes you are
1890 interested in
1891 tHidd_GfxMode_PixFmts (HIDDT_StdPifXmt *) - A pointer to an array
1892 of standard pixelformat indexes. If supplied, only mode IDs whose
1893 pixelformat numbers match any of given ones will be returned.
1895 RESULT
1896 A pointer to an array of ModeIDs or NULL in case of failure
1898 NOTES
1900 EXAMPLE
1902 BUGS
1904 SEE ALSO
1905 moHidd_Gfx_ReleaseModeIDs, moHidd_Gfx_NextModeID
1907 INTERNALS
1909 *****************************************************************************************/
1911 HIDDT_ModeID *GFX__Hidd_Gfx__QueryModeIDs(OOP_Class *cl, OOP_Object *o,
1912 struct pHidd_Gfx_QueryModeIDs *msg)
1914 struct TagItem *tag, *tstate;
1916 HIDDT_ModeID *modeids;
1917 struct HIDDGraphicsData *data;
1918 struct mode_db *mdb;
1920 struct modequery mq =
1922 NULL, /* mode db (set later) */
1923 0, 0xFFFFFFFF, /* minwidth, maxwidth */
1924 0, 0xFFFFFFFF, /* minheight, maxheight */
1925 NULL, /* stdpfs */
1926 0, /* numfound */
1927 0, 0, /* pfidx, syncidx */
1928 FALSE, FALSE, /* dims_ok, stdpfs_ok */
1929 FALSE, /* check_ok */
1930 NULL /* class (set later) */
1935 data = OOP_INST_DATA(cl, o);
1936 mdb = &data->mdb;
1937 mq.mdb = mdb;
1938 mq.cl = cl;
1940 for (tstate = msg->queryTags; (tag = NextTagItem((const struct TagItem **)&tstate)); )
1942 switch (tag->ti_Tag)
1944 case tHidd_GfxMode_MinWidth:
1945 mq.minwidth = (ULONG)tag->ti_Tag;
1946 break;
1948 case tHidd_GfxMode_MaxWidth:
1949 mq.maxwidth = (ULONG)tag->ti_Tag;
1950 break;
1952 case tHidd_GfxMode_MinHeight:
1953 mq.minheight = (ULONG)tag->ti_Tag;
1954 break;
1956 case tHidd_GfxMode_MaxHeight:
1957 mq.maxheight = (ULONG)tag->ti_Tag;
1958 break;
1960 case tHidd_GfxMode_PixFmts:
1961 mq.stdpfs = (HIDDT_StdPixFmt *)tag->ti_Data;
1962 break;
1967 ObtainSemaphoreShared(&mdb->sema);
1969 /* Recursively check all modes */
1970 modeids = querymode(&mq);
1972 ReleaseSemaphore(&mdb->sema);
1974 return modeids;
1978 /*****************************************************************************************
1980 NAME
1981 moHidd_Gfx_ReleaseModeIDs
1983 SYNOPSIS
1984 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ReleaseModeIDs *msg);
1986 VOID HIDD_Gfx_ReleaseModeIDs(OOP_Object *gfxHidd, HIDDT_ModeID *modeIDs);
1988 LOCATION
1989 hidd.graphics.graphics
1991 FUNCTION
1992 Free array of display mode IDs returned by HIDD_Gfx_QueryModeIDs()
1994 INPUTS
1995 gfxHidd - A driver object used to obtain the array
1996 modeIDs - A pointer to an array
1998 RESULT
1999 None.
2001 NOTES
2003 EXAMPLE
2005 BUGS
2007 SEE ALSO
2008 moHidd_Gfx_QueryModeIDs
2010 INTERNALS
2012 *****************************************************************************************/
2014 VOID GFX__Hidd_Gfx__ReleaseModeIDs(OOP_Class *cl, OOP_Object *o,
2015 struct pHidd_Gfx_ReleaseModeIDs *msg)
2017 FreeVec(msg->modeIDs);
2020 /*****************************************************************************************
2022 NAME
2023 moHidd_Gfx_NextModeID
2025 SYNOPSIS
2026 HIDDT_ModeID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NextModeID *msg);
2028 HIDDT_ModeID HIDD_Gfx_NextModeID(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2029 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2031 LOCATION
2032 hidd.graphics.graphics
2034 FUNCTION
2035 Iterate driver's internal display mode database.
2037 INPUTS
2038 gfxHidd - A driver object to query
2039 modeID - A previous mode ID or vHidd_ModeID_Invalid for start of the iteration
2040 syncPtr - A pointer to a storage where pointer to sync object will be placed
2041 pixFmtPtr - A pointer to a storage where pointer to pixelformat object will be placed
2043 RESULT
2044 Next available mode ID or vHidd_ModeID_Invalid if there are no more display modes.
2045 If the function returns vHidd_ModeID_Invalid, sync and pixelformat pointers will
2046 be set to NULL.
2048 NOTES
2050 EXAMPLE
2052 BUGS
2054 SEE ALSO
2055 moHidd_Gfx_GetMode
2057 INTERNALS
2059 *****************************************************************************************/
2061 HIDDT_ModeID GFX__Hidd_Gfx__NextModeID(OOP_Class *cl, OOP_Object *o,
2062 struct pHidd_Gfx_NextModeID *msg)
2064 struct HIDDGraphicsData *data;
2065 struct mode_db *mdb;
2066 ULONG syncidx, pfidx;
2067 HIDDT_ModeID return_id = vHidd_ModeID_Invalid;
2068 BOOL found = FALSE;
2070 data = OOP_INST_DATA(cl, o);
2071 mdb = &data->mdb;
2073 ObtainSemaphoreShared(&mdb->sema);
2074 if (vHidd_ModeID_Invalid == msg->modeID)
2076 pfidx = 0;
2077 syncidx = 0;
2079 else
2081 pfidx = MODEID_TO_PFIDX( msg->modeID );
2082 syncidx = MODEID_TO_SYNCIDX( msg->modeID );
2084 /* Increament one from the last call */
2085 pfidx ++;
2086 if (pfidx >= mdb->num_pixfmts)
2088 pfidx = 0;
2089 syncidx ++;
2093 /* Search for a new mode. We only accept valid modes */
2094 for (; syncidx < mdb->num_syncs; syncidx ++)
2096 /* We only return valid modes */
2097 for (; pfidx < mdb->num_pixfmts; pfidx ++)
2099 if (is_valid_mode(&mdb->checked_mode_bm, syncidx, pfidx))
2101 found = TRUE;
2102 break;
2105 if (found)
2106 break;
2109 if (found)
2111 return_id = COMPUTE_HIDD_MODEID(syncidx, pfidx);
2112 *msg->syncPtr = mdb->syncs[syncidx];
2113 *msg->pixFmtPtr = mdb->pixfmts[pfidx];
2115 else
2117 *msg->syncPtr = *msg->pixFmtPtr = NULL;
2120 ReleaseSemaphore(&mdb->sema);
2122 return return_id;
2125 /*****************************************************************************************
2127 NAME
2128 moHidd_Gfx_GetMode
2130 SYNOPSIS
2131 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMode *msg);
2133 BOOL HIDD_Gfx_GetMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2134 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2136 LOCATION
2137 hidd.graphics.graphics
2139 FUNCTION
2140 Get sync and pixelformat objects for a particular display ModeID.
2142 INPUTS
2143 gfxHidd - pointer to a driver object which this ModeID belongs to
2144 syncPtr - pointer to a storage where sync object pointer will be placed
2145 pixFmtPtr - pointer to a storage where pixelformat object pointer will be placed
2147 RESULT
2148 TRUE upon success, FALSE in case of failure (e.g. given mode does not exist in
2149 driver's internal database). If the function returns FALSE, sync and pixelformat
2150 pointers will be set to NULL.
2152 NOTES
2153 Every display mode is associated with some sync and pixelformat object. If the
2154 method returns TRUE, object pointers are guaranteed to be valid.
2156 EXAMPLE
2158 BUGS
2160 SEE ALSO
2161 moHidd_Gfx_NextModeID
2163 INTERNALS
2165 *****************************************************************************************/
2167 BOOL GFX__Hidd_Gfx__GetMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetMode *msg)
2169 ULONG pfidx, syncidx;
2170 struct HIDDGraphicsData *data;
2171 struct mode_db *mdb;
2172 BOOL ok = FALSE;
2174 data = OOP_INST_DATA(cl, o);
2175 mdb = &data->mdb;
2177 pfidx = MODEID_TO_PFIDX(msg->modeID);
2178 syncidx = MODEID_TO_SYNCIDX(msg->modeID);
2180 ObtainSemaphoreShared(&mdb->sema);
2182 if (! (pfidx >= mdb->num_pixfmts || syncidx >= mdb->num_syncs) )
2184 if (is_valid_mode(&mdb->checked_mode_bm, syncidx, pfidx))
2186 ok = TRUE;
2187 *msg->syncPtr = mdb->syncs[syncidx];
2188 *msg->pixFmtPtr = mdb->pixfmts[pfidx];
2192 ReleaseSemaphore(&mdb->sema);
2194 if (!ok)
2196 *msg->syncPtr = *msg->pixFmtPtr = NULL;
2199 return ok;
2202 /*****************************************************************************************
2204 NAME
2205 moHidd_Gfx_SetMode
2207 SYNOPSIS
2208 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetMode *msg);
2210 BOOL HIDD_Gfx_SetMode(OOP_Object *gfxHidd, OOP_Object *sync);
2212 LOCATION
2213 hidd.graphics.graphics
2215 FUNCTION
2216 Update display mode according to changed sync object
2218 INPUTS
2219 gfxHidd - A display driver to operate on
2220 sync - A modified sync object pointer
2222 RESULT
2223 TRUE if everything went OK and FALSE in case of some error
2225 NOTES
2226 This method is used to inform the driver that some external program has changed
2227 sync data and wants to update the display if needed. It's up to the implementation to
2228 check that current display is really using this sync (frontmost screen uses this mode).
2230 EXAMPLE
2232 BUGS
2234 SEE ALSO
2236 INTERNALS
2237 Base class implementation just returns FALSE indicating that this method is
2238 not supported.
2240 *****************************************************************************************/
2242 BOOL GFX__Hidd_Gfx__SetMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetMode *msg)
2244 return FALSE;
2247 /****************************************************************************************/
2249 static VOID copy_bm_and_colmap(OOP_Class *cl, OOP_Object *o, OOP_Object *src_bm,
2250 OOP_Object *dst_bm, ULONG width, ULONG height)
2252 struct HIDDGraphicsData *data;
2253 ULONG i;
2254 IPTR numentries;
2255 OOP_Object *src_colmap;
2256 APTR psrc_colmap = &src_colmap;
2258 data = OOP_INST_DATA(cl, o);
2260 /* We have to copy the colormap into the framebuffer bitmap */
2261 OOP_GetAttr(src_bm, aHidd_BitMap_ColorMap, (IPTR *)psrc_colmap);
2262 OOP_GetAttr(src_colmap, aHidd_ColorMap_NumEntries, &numentries);
2264 for (i = 0; i < numentries; i ++)
2266 HIDDT_Color col;
2268 HIDD_CM_GetColor(src_colmap, i, &col);
2269 HIDD_BM_SetColors(dst_bm, &col, i, 1);
2272 HIDD_Gfx_CopyBox(o
2273 , src_bm
2274 , 0, 0
2275 , dst_bm
2276 , 0, 0
2277 , width, height
2278 , data->gc
2282 /*****************************************************************************************
2284 NAME
2285 moHidd_Gfx_Show
2287 SYNOPSIS
2288 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Show *msg);
2290 OOP_Object *HIDD_Gfx_Show(OOP_Object *gfxHidd, OOP_Object *bitMap, ULONG flags);
2292 LOCATION
2293 hidd.graphics.graphics
2295 FUNCTION
2296 Change currently displayed bitmap on the screen.
2298 The bitmap object supplied must have been created with aHidd_BitMap_Displayable
2299 attribute set to TRUE.
2301 The function's behavior differs a lot depending on whether the driver uses a
2302 framebuffer or video hardware is able to switch screens itself.
2304 If the driver uses a framebuffer bitmap, it is supposed to copy the supplied bitmap
2305 into the framebuffer and return a framebuffer pointer. It also can be asked to
2306 copy back old framebuffer contents into previous bitmap object. It is driver's
2307 job to keep track of which bitmap object was displayed last time. This is what
2308 default implementation does. Note that it is very basic, and even does not support
2309 changing display resolution. It's not recommended to rely on it in production
2310 drivers (unless your video hardware supports only one mode).
2312 If the driver does not use a framebuffer, it is supposed to reprogram the hardware
2313 here to display an appropriate region of video RAM. Do not call the base class
2314 in this case, its implementation relies on framebuffer existance and will always
2315 return NULL which indicates an error.
2317 It is valid to get NULL value in bitMap parameter. This means that there is
2318 nothing to display and the screen needs to be blanked out. It is valid for
2319 non-framebuffer-based driver to return NULL as a reply then. In all other cases
2320 NULL return value means an error.
2322 Please avoid returning errors at all. graphics.library/LoadView() has no error
2323 indication. An error during showing a bitmap would leave the display in
2324 unpredictable state.
2326 If the driver does not use a framebuffer, consider using HIDD_Gfx_ShowViewPorts().
2327 It's more straightforward, flexible and offers support for screen composition.
2329 INPUTS
2330 gfxHidd - a display driver object, whose display you wish to change.
2331 bitMap - a pointer to a bitmap object which needs to be shown or NULL.
2332 flags - currently only one flag is defined:
2334 fHidd_Gfx_Show_CopyBack - Copy back the image data from framebuffer bitmap
2335 to old displayed bitmap. Used only if the driver
2336 needs a framebuffer.
2338 RESULT
2339 A pointer to a currently displayed bitmap object or NULL (read FUNCTION paragraph for
2340 detailed description)
2342 NOTES
2343 Drivers which use mirrored video data buffer do not have to update the display
2344 immediately in this method. moHidd_BitMap_UpdateRect will be sent to the returned
2345 bitmap if it's not NULL. Of course display blanking (if NULL bitmap was received)
2346 needs to be performed immediately.
2348 EXAMPLE
2350 BUGS
2352 SEE ALSO
2353 moHidd_Gfx_ShowViewPorts, graphics.library/LoadView()
2355 INTERNALS
2357 *****************************************************************************************/
2359 OOP_Object *GFX__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Show *msg)
2361 struct HIDDGraphicsData *data;
2362 OOP_Object *bm;
2363 IPTR displayable;
2364 IPTR oldwidth = 0;
2365 IPTR oldheight = 0;
2366 IPTR newwidth = 0;
2367 IPTR newheight = 0;
2368 struct TagItem gctags[] =
2370 { aHidd_GC_DrawMode , vHidd_GC_DrawMode_Copy},
2371 { aHidd_GC_Foreground, 0 },
2372 { TAG_DONE , 0UL }
2375 data = OOP_INST_DATA(cl, o);
2376 bm = msg->bitMap;
2378 /* We have to do some consistency checking */
2379 if (bm)
2381 OOP_GetAttr(bm, aHidd_BitMap_Displayable, &displayable);
2384 if (bm && !displayable)
2385 /* We cannot show a non-displayable bitmap */
2386 return NULL;
2388 if (NULL == data->framebuffer)
2389 return NULL;
2391 OOP_SetAttrs(data->gc, gctags);
2392 if (NULL != data->shownbm)
2394 OOP_GetAttr(data->shownbm, aHidd_BitMap_Width, &oldwidth);
2395 OOP_GetAttr(data->shownbm, aHidd_BitMap_Height, &oldheight);
2396 /* Copy the framebuffer data back into the old shown bitmap */
2397 if (msg->flags & fHidd_Gfx_Show_CopyBack)
2398 copy_bm_and_colmap(cl, o, data->framebuffer, data->shownbm, oldwidth, oldheight);
2401 if (bm) {
2402 OOP_GetAttr(bm, aHidd_BitMap_Width, &newwidth);
2403 OOP_GetAttr(bm, aHidd_BitMap_Height, &newheight);
2404 copy_bm_and_colmap(cl, o, bm, data->framebuffer, newwidth, newheight);
2406 /* Clear remaining parts of the framebuffer (if previous bitmap was larger than new one) */
2407 if (oldheight) {
2408 if (newwidth < oldwidth)
2409 HIDD_BM_FillRect(data->framebuffer, data->gc, newwidth, 0, oldwidth - 1, oldheight - 1);
2410 if ((newheight < oldheight) && newwidth)
2411 HIDD_BM_FillRect(data->framebuffer, data->gc, 0, newheight, newwidth - 1, oldheight);
2414 data->shownbm = bm;
2416 return data->framebuffer;
2419 /*****************************************************************************************
2421 NAME
2422 moHidd_Gfx_ShowViewPorts
2424 SYNOPSIS
2425 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ShowViewPorts *msg);
2427 ULONG HIDD_Gfx_ShowViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view);
2429 LOCATION
2430 hidd.graphics.graphics
2432 FUNCTION
2433 Show one or more bitmaps on the screen.
2435 It is completely up to the driver how to implement this function. The driver may
2436 or may not support hardware-assisted screens composition. Bitmaps are sorted
2437 in the list in descending z-order. The driver is expected to put at least frontmost
2438 bitmap on display.
2440 It is valid to get NULL pointer as data parameter. This means that there's
2441 nothing to show and the screen should go blank.
2443 Bitmaps display offsets are stored in their aHidd_BitMap_LeftEdge and
2444 aHidd_BitMap_TopEdge attributes. This function is not expected to modify their
2445 values somehow. They are assumed to be preserved between calls unless changed
2446 explicitly by the system.
2448 If you implement this method, you don't have to implement HIDD_Gfx_Show() because
2449 it will never be called.
2451 Note that there is no more error indication - the driver is expected to be
2452 error-free here.
2454 INPUTS
2455 gfxHidd - a display driver object, whose display you wish to change.
2456 data - a singly linked list of bitmap objects to show
2458 RESULT
2459 TRUE if this method is supported by the driver, FALSE otherwise
2461 NOTES
2463 EXAMPLE
2465 BUGS
2467 SEE ALSO
2468 moHidd_Gfx_Show
2470 INTERNALS
2471 Default base class implementation simply returns FALSE. This causes
2472 the system to use HIDD_Gfx_Show() instead.
2474 *****************************************************************************************/
2476 ULONG GFX__Hidd_Gfx__ShowViewPorts(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ShowViewPorts *msg)
2478 /* By default we don't support screen composition (and this method too) */
2479 return FALSE;
2482 /*****************************************************************************************
2484 NAME
2485 moHidd_Gfx_SetCursorShape
2487 SYNOPSIS
2488 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorShape *msg);
2490 BOOL HIDD_Gfx_SetCursorShape(OOP_Object *gfxHidd, OOP_Object *shape,
2491 LONG xoffset, LONG yoffset);
2493 LOCATION
2494 hidd.graphics.graphics
2496 FUNCTION
2497 Set mouse pointer shape.
2499 A pointer image is contained in the specified bitmap object. The bitmap object
2500 may contain a colormap if the system wants to specify own colors for the pointer.
2501 The supplied colormap will also contain alpha channel values.
2503 It is up to driver what to do if, for example, alpha channel is not supported by
2504 the hardware. Or if given bitmap type is not supported (for example truecolor
2505 bitmap on LUT-only hardware). It is expected that the driver converts bitmap
2506 data to a more appropriate form in such a case.
2508 A hotspot is given as an offset from the actual hotspot to the top-left corner
2509 of the pointer image. It is generally needed only for hosted display drivers
2510 which utilize host's support for mouse pointer.
2512 The default implementation in the base class just does nothing. A software mouse
2513 pointer is implemented in a special layer called fakegfx.hidd inside
2514 graphics.library. If a software pointer emulation is used, this method will
2515 never be called.
2517 INPUTS
2518 gfxHidd - a display driver object, for whose display you wish to change the pointer
2519 shape - a pointer to a bitmap object, containing pointer bitmap
2520 xoffset - a horizontal hotspot offset
2521 yoffset - a vertical hotspot offset
2523 RESULT
2524 TRUE on success, FALSE on failure
2526 NOTES
2528 EXAMPLE
2530 BUGS
2532 SEE ALSO
2533 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2535 INTERNALS
2537 *****************************************************************************************/
2539 BOOL GFX__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o,
2540 struct pHidd_Gfx_SetCursorShape *msg)
2542 /* We have no clue how to render the cursor */
2543 return TRUE;
2546 /*****************************************************************************************
2548 NAME
2549 moHidd_Gfx_SetCursorVisible
2551 SYNOPSIS
2552 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorVisible *msg);
2554 VOID HIDD_Gfx_SetCursorVisible(OOP_Object *gfxHidd, BOOL visible);
2556 LOCATION
2557 hidd.graphics.graphics
2559 FUNCTION
2560 Control mouse pointer visiblity.
2562 The default implementation in the base class does nothing. If a software pointer
2563 emulation is used, this method will never be called.
2565 INPUTS
2566 gfxHidd - a display driver object, on whose display you wish to turn
2567 pointer on or off
2568 visible - TRUE to enable pointer display, FALSE to disable it
2570 RESULT
2571 None.
2573 NOTES
2575 EXAMPLE
2577 BUGS
2579 SEE ALSO
2580 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2582 INTERNALS
2584 *****************************************************************************************/
2586 VOID GFX__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorVisible *msg)
2591 /*****************************************************************************************
2593 NAME
2594 moHidd_Gfx_SetCursorPos
2596 SYNOPSIS
2597 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorPos *msg);
2599 BOOL HIDD_Gfx_SetCursorPos(OOP_Object *gfxHidd, LONG x, LONG y);
2601 LOCATION
2602 hidd.graphics.graphics
2604 FUNCTION
2605 Set current mouse pointer position.
2607 This is a real position on top-left image corner relative to top-left corner of
2608 the physical display. Neither logical screen origin nor hotspot are taken into
2609 account here.
2611 The default implementation in the base class does nothing and just returns TRUE.
2612 If a software pointer emulation is used, this method will never be called.
2614 INPUTS
2615 gfxHidd - a display driver object, on whose display you wish to position the pointer
2616 x - An x coordinate of the pointer (relative to the physical screen origin)
2617 y - An y coordinate of the pointer (relative to the physical screen origin)
2619 RESULT
2620 Always TRUE. Reserved for future, do not use it.
2622 NOTES
2623 This method is called by graphics.library/MoveSprite() which has no return value.
2624 However, for historical reasons, this method has a return value. Drivers should
2625 always return TRUE in order to ensure future compatibility.
2627 EXAMPLE
2629 BUGS
2631 SEE ALSO
2632 moHidd_Gfx_SetCursorShape, moHidd_Gfx_SetCursorVisible, graphics.library/MoveSprite()
2634 INTERNALS
2636 *****************************************************************************************/
2638 BOOL GFX__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorPos *msg)
2640 return TRUE;
2643 /*****************************************************************************************
2645 NAME
2646 moHidd_Gfx_CopyBox
2648 SYNOPSIS
2649 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg);
2651 VOID HIDD_Gfx_CopyBox(OOP_Object *gfxHidd, OOP_Object *src, WORD srcX, WORD srcY,
2652 OOP_Object *dest, WORD destX, WORD destY, UWORD width, UWORD height,
2653 OOP_Object *gc);
2655 LOCATION
2656 hidd.graphics.graphics
2658 FUNCTION
2659 Perform rectangle copy (blit) operation from one bitmap to another.
2661 Given bitmaps may belong to different display drivers. The driver may attempt to
2662 use hardware for acceleration (if available), and if it's impossible, pass the
2663 operation on to the base class.
2665 Always check class of the supplied bitmap before attempting to look at its
2666 private data.
2668 A GC is used in order to specify raster operation performed between the source
2669 and destination according to its aHidd_GC_DrawMode attribute value.
2671 INPUTS
2672 gfxHidd - a display driver object that you are going to use for copying
2673 src - a pointer to source bitmap object
2674 srcX - an X coordinate of the source rectangle
2675 srcY - an Y coordinate of the source rectangle
2676 dest - a pointer to destination bitmap object
2677 destX - an X coordinate of the destination rectangle
2678 destY - an Y coordinate of the destination rectangle
2679 width - width of the rectangle to copy
2680 height - height of the rectangle to copy
2681 gc - graphics context holding draw mode on the destination
2683 RESULT
2684 None.
2686 NOTES
2687 You must specify valid coordinates (non-negative and inside the actual bitmap
2688 area), no checks are done.
2690 It is valid to specify two overlapped areas of the same bitmap as source
2691 and destination.
2693 EXAMPLE
2695 BUGS
2697 SEE ALSO
2699 INTERNALS
2701 *****************************************************************************************/
2703 VOID GFX__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg)
2705 WORD x, y;
2706 WORD srcX = msg->srcX, destX = msg->destX;
2707 WORD srcY = msg->srcY, destY = msg->destY;
2708 WORD startX, endX, deltaX, startY, endY, deltaY;
2709 ULONG memFG;
2710 HIDDT_PixelFormat *srcpf, *dstpf;
2711 OOP_Object *dest, *src;
2712 OOP_Object *gc;
2713 APTR srcPixels = NULL;
2714 APTR destPixels = NULL;
2716 dest = msg->dest;
2717 src = msg->src;
2719 /* If source/dest overlap, direction of operation is important */
2721 if (srcX < destX)
2723 startX = msg->width - 1; endX = -1; deltaX = -1;
2725 else
2727 startX = 0; endX = msg->width; deltaX = 1;
2730 if (srcY < destY)
2732 startY = msg->height - 1; endY = -1; deltaY = -1;
2734 else
2736 startY = 0; endY = msg->height; deltaY = 1;
2739 /* Get the source pixel format */
2740 srcpf = (HIDDT_PixelFormat *)HBM(src)->prot.pixfmt;
2742 DCOPYBOX(bug("COPYBOX: obj=0x%p (%s), src=0x%p at (%d, %d), dst=0x%p at (%d, %d), size=%dx%d\n", obj, OOP_OCLASS(obj)->ClassNode.ln_Name,
2743 msg->src, srcX, srcY, msg->dest, destX, destY, msg->width, msg->height));
2744 DCOPYBOX(bug("COPYBOX: GC=0x%p, DrawMode %ld, ColMask 0x%08X\n", msg->gc, GC_DRMD(msg->gc), GC_COLMASK(msg->gc)));
2746 #ifdef COPYBOX_DUMP_DIMS
2748 IPTR sw, sh, dw, dh;
2750 OOP_GetAttr(obj, aHidd_BitMap_Width, &sw);
2751 OOP_GetAttr(obj, aHidd_BitMap_Height, &sh);
2752 OOP_GetAttr(msg->dest, aHidd_BitMap_Width, &dw);
2753 OOP_GetAttr(msg->dest, aHidd_BitMap_Height, &dh);
2755 bug("src dims: %dx%d dest dims: %dx%d\n", sw, sh, dw, dh);
2757 #endif
2759 dstpf = (HIDDT_PixelFormat *)HBM(dest)->prot.pixfmt;
2761 OOP_GetAttr(msg->src, aHidd_ChunkyBM_Buffer, (APTR)&srcPixels);
2762 OOP_GetAttr(msg->dest, aHidd_ChunkyBM_Buffer, (APTR)&destPixels);
2764 if (srcPixels && destPixels)
2767 * Both bitmaps are chunky ones and they have directly accessible buffer.
2768 * We can use optimized routines to do the copy.
2770 IPTR src_bytesperline, dest_bytesperline;
2772 OOP_GetAttr(msg->src, aHidd_BitMap_BytesPerRow, &src_bytesperline);
2773 OOP_GetAttr(msg->dest, aHidd_BitMap_BytesPerRow, &dest_bytesperline);
2775 switch(GC_DRMD(msg->gc))
2777 case vHidd_GC_DrawMode_Copy:
2778 /* At the moment we optimize only bulk copy */
2780 if (srcpf == dstpf)
2783 * The same pixelformat. Extremely great!
2785 * FIXME: Bulk copy to the same pixelformat is also handled in ConvertPixels very well
2786 * (optimized to either per-line or bulk memcpy()). But it can't handle
2787 * overlapping regions (which seems to be a requirement for CopyBox).
2788 * If this is fixed, we can even throw away HIDD_BM_CopyMemBoxXX at all, reducing
2789 * kickstart size.
2791 switch(srcpf->bytes_per_pixel)
2793 case 1:
2795 * In fact all these methods are static, they ignore object pointer, and it's
2796 * needed only for OOP_DoMethod() to fetch class information.
2797 * We use destination bitmap pointer, we can also source one.
2799 HIDD_BM_CopyMemBox8(msg->dest,
2800 srcPixels, msg->srcX, msg->srcY,
2801 destPixels, msg->destX, msg->destY,
2802 msg->width, msg->height,
2803 src_bytesperline, dest_bytesperline);
2804 return;
2806 case 2:
2807 HIDD_BM_CopyMemBox16(msg->dest,
2808 srcPixels, msg->srcX, msg->srcY,
2809 destPixels, msg->destX, msg->destY,
2810 msg->width, msg->height,
2811 src_bytesperline, dest_bytesperline);
2812 return;
2814 case 3:
2815 HIDD_BM_CopyMemBox24(msg->dest,
2816 srcPixels, msg->srcX, msg->srcY,
2817 destPixels, msg->destX, msg->destY,
2818 msg->width, msg->height,
2819 src_bytesperline, dest_bytesperline);
2820 return;
2822 case 4:
2823 HIDD_BM_CopyMemBox32(msg->dest,
2824 srcPixels, msg->srcX, msg->srcY,
2825 destPixels, msg->destX, msg->destY,
2826 msg->width, msg->height,
2827 src_bytesperline, dest_bytesperline);
2828 return;
2830 } /* switch(srcpf->bytes_per_pixel) */
2831 } /* srcpf == dstpf */
2832 else
2835 * Pixelformats are different. This can't be the same bitmap,
2836 * and it's safe to use ConvertPixels method (see FIXME above).
2838 srcPixels += (msg->srcY * src_bytesperline ) + (msg->srcX * srcpf->bytes_per_pixel);
2839 destPixels += (msg->destY * dest_bytesperline) + (msg->destX * dstpf->bytes_per_pixel);
2842 * Supply NULL pixlut. In this case bitmap's own colormap will be used
2843 * for color lookup (if needed).
2845 HIDD_BM_ConvertPixels(msg->dest,
2846 &srcPixels, srcpf, src_bytesperline,
2847 &destPixels, dstpf, dest_bytesperline,
2848 msg->width, msg->height, NULL);
2850 return;
2853 break;
2855 /* TODO: Optimize other DrawModes here */
2857 } /* switch(mode) */
2859 } /* srcPixels && destPixels */
2861 gc = msg->gc;
2863 memFG = GC_FG(msg->gc);
2865 /* All else have failed, copy pixel by pixel */
2866 if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf))
2868 if (IS_TRUECOLOR(srcpf))
2870 DCOPYBOX(bug("COPY FROM TRUECOLOR TO TRUECOLOR\n"));
2872 for(y = startY; y != endY; y += deltaY)
2874 HIDDT_Color col;
2876 /* if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2877 bug("[%d,%d] ", memSrcX, memDestX);
2879 for(x = startX; x != endX; x += deltaX)
2881 HIDDT_Pixel pix = GETPIXEL(cl, src, srcX + x, srcY + y);
2883 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2884 if (srcpf == dstpf)
2886 GC_FG(gc) = pix;
2888 else
2889 #endif
2891 HIDD_BM_UnmapPixel(src, pix, &col);
2892 GC_FG(gc) = HIDD_BM_MapColor(msg->dest, &col);
2895 DRAWPIXEL(cl, dest, gc, destX + x, destY + y);
2897 /*if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2898 bug("[%d,%d] ", srcY, destY);
2902 } /* if (IS_TRUECOLOR(srcpf)) */
2903 else
2905 /* Two palette bitmaps.
2906 For this case we do NOT convert through RGB,
2907 but copy the pixel indexes directly
2909 DCOPYBOX(bug("COPY FROM PALETTE TO PALETTE\n"));
2911 /* FIXME: This might not work very well with two StaticPalette bitmaps */
2913 for(y = startY; y != endY; y += deltaY)
2915 for(x = startX; x != endX; x += deltaX)
2917 GC_FG(gc) = HIDD_BM_GetPixel(src, srcX + x, srcY + y);
2919 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2924 } /* if (IS_TRUECOLOR(srcpf)) else ... */
2926 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) */
2927 else
2929 /* Two unlike bitmaps */
2930 if (IS_TRUECOLOR(srcpf))
2932 /* FIXME: Implement this */
2933 DCOPYBOX(bug("!! DEFAULT COPYING FROM TRUECOLOR TO PALETTIZED NOT IMPLEMENTED IN BitMap::CopyBox\n"));
2935 else if (IS_TRUECOLOR(dstpf))
2937 /* Get the colortab */
2938 HIDDT_Color *ctab = ((HIDDT_ColorLUT *)HBM(src)->colmap)->colors;
2940 DCOPYBOX(bug("COPY FROM PALETTE TO TRUECOLOR, DRAWMODE %d, CTAB %p\n", GC_DRMD(gc), ctab));
2942 for(y = startY; y != endY; y += deltaY)
2944 for(x = startX; x != endX; x += deltaX)
2946 register HIDDT_Pixel pix;
2947 register HIDDT_Color *col;
2949 pix = HIDD_BM_GetPixel(src, srcX + x, srcY + y);
2950 col = &ctab[pix];
2952 GC_FG(gc) = HIDD_BM_MapColor(msg->dest, col);
2953 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2959 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) else ... */
2961 GC_FG(gc) = memFG;
2964 /*****************************************************************************************
2966 NAME
2967 moHidd_Gfx_ShowImminentReset
2969 SYNOPSIS
2970 VOID OOP_DoMethod(OOP_Object *obj, OOP_Msg msg);
2972 LOCATION
2973 hidd.graphics.graphics
2975 FUNCTION
2976 Indicate upcoming machine reset. Obsolete.
2978 Since graphics.library v41.4 this method is not used any more. Considered
2979 reserved. Do not use it in any way.
2981 INPUTS
2982 None.
2984 RESULT
2985 None.
2987 NOTES
2989 EXAMPLE
2991 BUGS
2993 SEE ALSO
2995 INTERNALS
2997 *****************************************************************************************/
2999 VOID GFX__Hidd_Gfx__ShowImminentReset(OOP_Class *cl, OOP_Object *obj, OOP_Msg msg)
3003 /****************************************************************************************/
3005 /* The following two methods are private and not virtual */
3007 OOP_Object *GFX__Hidd_Gfx__RegisterPixFmt(OOP_Class *cl, OOP_Object *o, struct TagItem *pixFmtTags)
3009 HIDDT_PixelFormat cmp_pf;
3010 struct class_static_data *data;
3011 struct pixfmt_data *retpf = NULL;
3013 memset(&cmp_pf, 0, sizeof(cmp_pf));
3015 data = CSD(cl);
3016 if (!parse_pixfmt_tags(pixFmtTags, &cmp_pf, 0, CSD(cl)))
3018 D(bug("!!! FAILED PARSING TAGS IN Gfx::RegisterPixFmt() !!!\n"));
3019 return FALSE;
3022 DPF(bug("Gfx::RegisterPixFmt(): Registering pixelformat:\n"));
3023 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3024 , PF(&cmp_pf)->red_shift
3025 , PF(&cmp_pf)->green_shift
3026 , PF(&cmp_pf)->blue_shift
3027 , PF(&cmp_pf)->alpha_shift
3028 , PF(&cmp_pf)->red_mask
3029 , PF(&cmp_pf)->green_mask
3030 , PF(&cmp_pf)->blue_mask
3031 , PF(&cmp_pf)->alpha_mask
3032 , PF(&cmp_pf)->bytes_per_pixel
3033 , PF(&cmp_pf)->size
3034 , PF(&cmp_pf)->depth
3035 , PF(&cmp_pf)->stdpixfmt));
3037 retpf = find_pixfmt(&cmp_pf, CSD(cl));
3039 DPF(bug("Found matching pixelformat: 0x%p\n", retpf));
3040 if (retpf)
3041 /* Increase pf refcount */
3042 AROS_ATOMIC_INC(retpf->refcount);
3043 else
3045 /* Could not find an alike pf, Create a new pfdb node */
3046 /* Since we pass NULL as the taglist below, the PixFmt class will just create a dummy pixfmt */
3047 retpf = OOP_NewObject(CSD(cl)->pixfmtclass, NULL, NULL);
3048 if (retpf) {
3049 /* We have one user */
3050 retpf->refcount = 1;
3052 /* Initialize the pixfmt object the "ugly" way */
3053 memcpy(retpf, &cmp_pf, sizeof (HIDDT_PixelFormat));
3055 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3056 , PF(&cmp_pf)->red_shift
3057 , PF(&cmp_pf)->green_shift
3058 , PF(&cmp_pf)->blue_shift
3059 , PF(&cmp_pf)->alpha_shift
3060 , PF(&cmp_pf)->red_mask
3061 , PF(&cmp_pf)->green_mask
3062 , PF(&cmp_pf)->blue_mask
3063 , PF(&cmp_pf)->alpha_mask
3064 , PF(&cmp_pf)->bytes_per_pixel
3065 , PF(&cmp_pf)->size
3066 , PF(&cmp_pf)->depth
3067 , PF(&cmp_pf)->stdpixfmt));
3069 ObtainSemaphore(&data->pfsema);
3070 AddTail((struct List *)&data->pflist, (struct Node *)&retpf->node);
3071 ReleaseSemaphore(&data->pfsema);
3075 DPF(bug("New refcount is %u\n", retpf->refcount));
3076 return (OOP_Object *)retpf;
3079 /****************************************************************************************/
3081 /* This method doesn't need object pointer, it's static. */
3083 VOID GFX__Hidd_Gfx__ReleasePixFmt(OOP_Class *cl, OOP_Object *pf)
3085 struct class_static_data *data;
3086 struct pixfmt_data *pixfmt = (struct pixfmt_data *)pf;
3088 DPF(bug("release_pixfmt 0x%p\n", pixfmt));
3090 data = CSD(cl);
3092 ObtainSemaphore(&data->pfsema);
3094 /* If refcount is already 0, this object was never registered in the database,
3095 don't touch it */
3096 DPF(bug("Old reference count is %u\n", pixfmt->refcount));
3097 if (pixfmt->refcount) {
3098 if (--pixfmt->refcount == 0) {
3099 Remove((struct Node *)&pixfmt->node);
3100 OOP_DisposeObject((OOP_Object *)pixfmt);
3104 ReleaseSemaphore(&data->pfsema);
3107 /*****************************************************************************************
3109 NAME
3110 moHidd_Gfx_CheckMode
3112 SYNOPSIS
3113 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CheckMode *msg);
3115 BOOL HIDD_Gfx_CheckMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3116 OOP_Object *sync, OOP_Object *pixFmt);
3118 LOCATION
3119 hidd.graphics.graphics
3121 FUNCTION
3122 Check if given display mode is supported by the driver.
3124 Normally any resolution (sync) can be used together with any pixelformat. However
3125 on some hardware there may be exceptions from this rule. In such a case this
3126 method should be implemented, and check should be performed.
3128 The information provided by this method is used in order to exclude unsupported
3129 modes from the database
3131 Default implementation in the base class just returns TRUE for all supplied values.
3133 Note that this method can not be used in order to chech that the given mode is
3134 really present in the database and it really refers to the given sync and
3135 pixelformat objects. Use HIDD_Gfx_GetMode() for mode ID validation.
3137 INPUTS
3138 gfxHidd - A display driver object
3139 modeID - A display mode ID
3140 sync - A pointer to a sync object associated with this mode
3141 pixFmt - A pointer to a pixelformat object associated with this mode
3143 RESULT
3144 TRUE if this mode is supported and FALSE if it's not.
3146 NOTES
3148 EXAMPLE
3150 BUGS
3151 Currently base class does not call this method after driver object creation.
3152 This needs to be fixed.
3154 SEE ALSO
3155 moHidd_Gfx_GetMode
3157 INTERNALS
3159 *****************************************************************************************/
3161 BOOL GFX__Hidd_Gfx__CheckMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CheckMode *msg)
3163 /* As a default we allways return TRUE, ie. the mode is OK */
3164 return TRUE;
3167 /*****************************************************************************************
3169 NAME
3170 moHidd_Gfx_GetPixFmt
3172 SYNOPSIS
3173 OOP_Object *OOP_DoMethod(OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg);
3175 OOP_Object *HIDD_Gfx_GetPixFmt(OOP_Object *gfxHidd, HIDDT_StdPixFmt pixFmt);
3177 LOCATION
3178 hidd.graphics.graphics
3180 FUNCTION
3181 Get a standard pixelformat descriptor from internal pixelformats database.
3183 INPUTS
3184 gfxHidd - A display driver object
3185 pixFmt - An index of pixelformat (one of vHIDD_StdPixFmt_... values)
3187 RESULT
3188 A pointer to a pixelformat object or NULL if lookup failed
3190 NOTES
3191 Pixelformat objects are stored in a global system-wide database. They are not
3192 linked with a particular driver in any way and completely sharable between all
3193 drivers.
3195 EXAMPLE
3197 BUGS
3199 SEE ALSO
3201 INTERNALS
3202 This operation can never fail because all standard pixelformats are registered
3203 during early system initialization.
3205 *****************************************************************************************/
3207 OOP_Object *GFX__Hidd_Gfx__GetPixFmt(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg)
3209 OOP_Object *fmt;
3211 if (!IS_REAL_STDPIXFMT(msg->stdPixFmt))
3213 D(bug("!!! Illegal pixel format passed to Gfx::GetPixFmt(): %d\n", msg->stdPixFmt));
3214 return NULL;
3216 else
3218 fmt = (OOP_Object *)CSD(cl)->std_pixfmts[REAL_STDPIXFMT_IDX(msg->stdPixFmt)];
3221 return fmt;
3224 /*****************************************************************************************
3226 NAME
3227 moHidd_Gfx_GetSync
3229 SYNOPSIS
3230 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetSync *msg);
3232 OOP_Object *HIDD_Gfx_GetSync(OOP_Object *gfxHidd, ULONG num);
3234 LOCATION
3235 hidd.graphics.graphics
3237 FUNCTION
3238 Get a sync object from internal display mode database by index
3240 INPUTS
3241 gfxHidd - A display driver object to query
3242 num - An index of sync object starting from 0
3244 RESULT
3245 A pointer to a sync object or NULL if there's no sync with such index
3247 NOTES
3249 EXAMPLE
3251 BUGS
3253 SEE ALSO
3255 INTERNALS
3257 *****************************************************************************************/
3259 OOP_Object *GFX__Hidd_Gfx__GetSync(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetSync *msg)
3261 struct HIDDGraphicsData *data = OOP_INST_DATA(cl, o);
3263 if (msg->num < data->mdb.num_syncs)
3264 return data->mdb.syncs[msg->num];
3265 else {
3266 D(bug("!!! Illegal sync index passed to Gfx::GetSync(): %d\n", msg->num));
3267 return NULL;
3271 /*****************************************************************************************
3273 NAME
3274 moHidd_Gfx_ModeProperties
3276 SYNOPSIS
3277 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ModeProperties *msg);
3279 ULONG HIDD_Gfx_ModeProperties(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3280 struct HIDD_ModeProperties *props, ULONG propsLen);
3282 LOCATION
3283 hidd.graphics.graphics
3285 FUNCTION
3286 Obtain an information about the video mode.
3288 Video mode description structure may grow in future, so be careful and always check
3289 propsLen parameter value. A system may ask you for less data than you can provide.
3290 Always return an actual value. Do not just zero out fields you don't know about,
3291 this is not expected to be backwards compatible.
3293 INPUTS
3294 gfxHidd - a pointer to a display driver object whose display mode you want to query
3295 modeID - a mode ID to query
3296 props - a pointer to a storage area where HIDD_ModeProperties structure will be put
3297 propsLen - length of the supplied buffer in bytes.
3299 RESULT
3300 Actual length of obtained structure
3302 NOTES
3303 Returned data must reflect only real hardware capabilities. For example, do not
3304 count emulated sprites. The system takes care about emulated features itself.
3306 EXAMPLE
3308 BUGS
3310 SEE ALSO
3311 aoHidd_Gfx_HWSpriteTypes, aoHidd_Gfx_SupportsHWCursor
3313 INTERNALS
3314 Default implementation in the base class relies on aHidd_Gfx_HWSpriteTypes attribute,
3315 not vice versa. If you override this method, do not forget to override this attribute too.
3317 *****************************************************************************************/
3319 ULONG GFX__Hidd_Gfx__ModeProperties(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ModeProperties *msg)
3321 struct HIDD_ModeProperties props = {0, 0, 0};
3322 IPTR has_hw_cursor = 0;
3323 ULONG len = msg->propsLen;
3325 D(bug("[GFXHIDD] Hidd::Gfx::ModeProperties(0x%08lX, 0x%p, %u)\n", msg->modeID, msg->props, msg->propsLen));
3326 OOP_GetAttr(o, aHidd_Gfx_HWSpriteTypes, &has_hw_cursor);
3327 if (has_hw_cursor) {
3328 D(bug("[GFXHIDD] Driver has hardware mouse cursor implementation\n"));
3329 props.DisplayInfoFlags = DIPF_IS_SPRITES;
3330 props.NumHWSprites = 1;
3333 if (len > sizeof(props))
3334 len = sizeof(props);
3335 D(bug("[GFXHIDD] Copying %u bytes\n", len));
3336 CopyMem(&props, msg->props, len);
3338 return len;
3341 /*****************************************************************************************
3343 NAME
3344 moHidd_Gfx_GetGamma
3346 SYNOPSIS
3347 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3349 BOOL HIDD_Gfx_GetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3351 LOCATION
3352 hidd.graphics.graphics
3354 FUNCTION
3355 Get current gamma table for the display.
3357 A gamma table consists of three 256-byte tables: one for red component, one for
3358 green and one for blue.
3360 A user should supply three pointers to preallocated 256-byte tables which will
3361 be filled in. Any ot these pointers may have NULL value, in this case the
3362 respective component will be ignored.
3364 INPUTS
3365 gfxHidd - A display driver object
3366 Red - A pointer to a 256-byte array for red component or NULL
3367 Green - A pointer to a 256-byte array for green component or NULL
3368 Blue - A pointer to a 256-byte array for blue component or NULL
3370 RESULT
3371 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3373 NOTES
3374 This method can be used just to query if the driver supports gamma correction.
3375 Just set Red, Green and Blue to NULL for this.
3377 EXAMPLE
3379 BUGS
3381 SEE ALSO
3382 moHidd_Gfx_SetGamma
3384 INTERNALS
3386 *****************************************************************************************/
3388 BOOL GFX__Hidd_Gfx__GetGamma(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Gamma *msg)
3390 return FALSE;
3393 /*****************************************************************************************
3395 NAME
3396 moHidd_Gfx_SetGamma
3398 SYNOPSIS
3399 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3401 BOOL HIDD_Gfx_SetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3403 LOCATION
3404 hidd.graphics.graphics
3406 FUNCTION
3407 Set current gamma table for the display.
3409 A gamma table consists of three 256-byte tables: one for red component, one for
3410 green and one for blue.
3412 A user should supply three pointers to 256-byte tables from which gamma values
3413 will be picked up. Any ot these pointers may have NULL value, in this case the
3414 respective component will be ignored.
3416 INPUTS
3417 gfxHidd - A display driver object
3418 Red - A pointer to a 256-byte array for red component or NULL
3419 Green - A pointer to a 256-byte array for green component or NULL
3420 Blue - A pointer to a 256-byte array for blue component or NULL
3422 RESULT
3423 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3425 NOTES
3426 This method can be used just to query if the driver supports gamma correction.
3427 Just set Red, Green and Blue to NULL for this.
3429 EXAMPLE
3431 BUGS
3433 SEE ALSO
3434 moHidd_Gfx_GetGamma
3436 INTERNALS
3438 *****************************************************************************************/
3440 BOOL GFX__Hidd_Gfx__SetGamma(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Gamma *msg)
3442 return FALSE;
3445 /*****************************************************************************************
3447 NAME
3448 moHidd_Gfx_QueryHardware3D
3450 SYNOPSIS
3451 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryHardware3D *msg);
3453 BOOL HIDD_Gfx_QueryHardware3D(OOP_Object *gfxHidd, OOP_Object *pixFmt);
3455 LOCATION
3456 hidd.graphics.graphics
3458 FUNCTION
3459 Query if the driver supports hardware-accelerated 3D graphics for the given
3460 pixelformat.
3462 INPUTS
3463 gfxHidd - A display driver object
3464 pixFmt - A pointer to a pixelformat descriptor object
3466 RESULT
3467 TRUE if the driver supports hardware-accelerated 3D for the given pixelformat,
3468 FALSE otherwise.
3470 NOTES
3472 EXAMPLE
3474 BUGS
3476 SEE ALSO
3478 INTERNALS
3480 *****************************************************************************************/
3482 BOOL GFX__Hidd_Gfx__QueryHardware3D(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_QueryHardware3D *msg)
3484 return FALSE;
3487 /*****************************************************************************************
3489 NAME
3490 moHidd_Gfx_GetMaxSpriteSize
3492 SYNOPSIS
3493 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMaxSpriteSize *msg);
3495 BOOL HIDD_Gfx_GetMaxSpriteSize(OOP_Object *gfxHidd, ULONG Type, ULONG *Width, ULONG *Height);
3497 LOCATION
3498 hidd.graphics.graphics
3500 FUNCTION
3501 Query maximum allowed size for the given sprite type.
3503 INPUTS
3504 gfxHidd - A display driver object
3505 Type - Type of the sprite image (one of vHidd_SpriteType_... values)
3506 Width - A pointer to ULONG where width will be placed.
3507 Height - A pointer to ULONG where height will be placed.
3509 RESULT
3510 FALSE is the given sprite type is not supported, otherwise TRUE.
3512 NOTES
3513 Default implementation in the base class just return some small values
3514 which it hopes can be supported by every driver if the driver supports given
3515 sprite type. It is strongly suggested to reimplement this method in the display
3516 driver.
3518 Width and Height are considered undefined if the method returns FALSE.
3520 EXAMPLE
3522 BUGS
3524 SEE ALSO
3526 INTERNALS
3528 *****************************************************************************************/
3530 BOOL GFX__Hidd_Gfx__GetMaxSpriteSize(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetMaxSpriteSize *msg)
3532 IPTR types;
3534 OOP_GetAttr(o, aHidd_Gfx_HWSpriteTypes, &types);
3536 if (types & msg->Type) {
3537 *msg->Width = 16;
3538 *msg->Height = 32;
3539 return TRUE;
3540 } else
3541 return FALSE;
3544 /*****************************************************************************************
3546 NAME
3547 moHidd_Gfx_NewOverlay
3549 SYNOPSIS
3550 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewOverlay *msg);
3552 OOP_Object *HIDD_Gfx_NewOverlay(OOP_Object *gfxHidd, struct TagItem *tagList);
3554 LOCATION
3555 hidd.graphics.graphics
3557 FUNCTION
3558 Create a video overlay object.
3560 INPUTS
3561 gfxHidd - A graphics driver object on whose display you want to create an overlay.
3562 tagList - A list of overlay attributes. See overlay class documentation for
3563 their description.
3565 RESULT
3566 Pointer to the newly created overlay object or NULL in case of failure.
3568 NOTES
3569 Default implementation in the base class always sets VOERR_INVSCRMODE error and
3570 returns NULL meaning that hardware overlays are not supported. There's no sense
3571 in software implementation because the software is supposed to handle software
3572 rendering itself.
3574 EXAMPLE
3576 BUGS
3578 SEE ALSO
3579 moHidd_Gfx_DisposeOverlay
3581 INTERNALS
3583 *****************************************************************************************/
3585 OOP_Object *GFX__Hidd_Gfx__NewOverlay(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewOverlay *msg)
3587 ULONG *err = (ULONG *)GetTagData(aHidd_Overlay_Error, 0, msg->attrList);
3589 if (err)
3590 *err = VOERR_INVSCRMODE;
3592 return NULL;
3595 /*****************************************************************************************
3597 NAME
3598 moHidd_Gfx_DisposeOverlay
3600 SYNOPSIS
3601 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeOverlay *msg);
3603 VOID HIDD_Gfx_DisposeOverlay(OOP_Object *gfxHidd, OOP_Object *Overlay)
3605 LOCATION
3606 hidd.graphics.graphics
3608 FUNCTION
3609 Deletes an overlay previously created by moHidd_Gfx_NewOverlay.
3611 Subclasses do not have to override this method
3612 unless they allocate anything additional to an overlay object in
3613 their HIDD_Gfx_NewOverlay() implementation.
3615 INPUTS
3616 gfxHidd - A driver object which was used for creating a GC.
3617 Overlay - Pointer to an overlay object to delete.
3619 RESULT
3620 None.
3622 NOTES
3624 EXAMPLE
3626 BUGS
3628 SEE ALSO
3629 moHidd_Gfx_NewGC
3631 INTERNALS
3632 Basically just does OOP_DisposeObject(Overlay);
3634 *****************************************************************************************/
3636 VOID GFX__Hidd_Gfx__DisposeOverlay(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_DisposeOverlay *msg)
3638 OOP_DisposeObject(msg->Overlay);
3641 /*****************************************************************************************
3643 NAME
3644 moHidd_Gfx_MakeViewPort
3646 SYNOPSIS
3647 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_MakeViewPort *msg);
3649 ULONG HIDD_Gfx_MakeViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3651 LOCATION
3652 hidd.graphics.graphics
3654 FUNCTION
3655 Performs driver-specific setup on a given ViewPort.
3657 INPUTS
3658 gfxHidd - A display driver object.
3659 data - a pointer to a HIDD_ViewPortDats structure.
3661 RESULT
3662 The same code as used as return value for graphics.library/MakeVPort().
3664 NOTES
3665 When graphics.library calls this method, a complete view is not built yet.
3666 This means that data->Next pointer contains invalid data and needs to be
3667 ignored.
3669 It is valid to keep private data pointer in data->UserData accross calls.
3670 Newly created HIDD_ViewPortData is guraranteed to have NULL there.
3672 EXAMPLE
3674 BUGS
3676 SEE ALSO
3677 moHidd_Gfx_CleanViewPort
3679 INTERNALS
3680 Base class implementation just does nothing. This function is mainly intended
3681 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3683 *****************************************************************************************/
3685 ULONG GFX__Hidd_Gfx__MakeViewPort(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_MakeViewPort *msg)
3687 D(bug("Gfx::MakeViewPort: object 0x%p, data 0x%p\n", o, msg->Data));
3689 return MVP_OK;
3692 /*****************************************************************************************
3694 NAME
3695 moHidd_Gfx_CleanViewPort
3697 SYNOPSIS
3698 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CleanViewPort *msg);
3700 ULONG HIDD_Gfx_CleanViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3702 LOCATION
3703 hidd.graphics.graphics
3705 FUNCTION
3706 Performs driver-specific cleanup on a given ViewPort.
3708 INPUTS
3709 gfxHidd - A display driver object.
3710 data - a pointer to a HIDD_ViewPortDats structure.
3712 RESULT
3713 The same code as used as return value for graphics.library/MakeVPort().
3715 NOTES
3716 When graphics.library calls this method, the ViewPort is already unlinked
3717 from its view, and the bitmap can already be deallocated.
3718 This means that both data->Next and data->Bitmap pointers can contain invalid
3719 values.
3721 EXAMPLE
3723 BUGS
3725 SEE ALSO
3726 moHidd_Gfx_MakeViewPort
3728 INTERNALS
3729 Base class implementation just does nothing. This function is mainly intended
3730 to provide support for copperlist disposal by Amiga(tm) chipset driver.
3732 *****************************************************************************************/
3734 void GFX__Hidd_Gfx__CleanViewPort(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CleanViewPort *msg)
3736 D(bug("Gfx::CleanViewPort: object 0x%p, data 0x%p\n", o, msg->Data));
3739 /*****************************************************************************************
3741 NAME
3742 moHidd_Gfx_PrepareViewPorts
3744 SYNOPSIS
3745 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_PrepareViewPorts *msg);
3747 ULONG HIDD_Gfx_PrepareViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view)
3749 LOCATION
3750 hidd.graphics.graphics
3752 FUNCTION
3753 Performs driver-specific setup on a given view.
3755 INPUTS
3756 gfxHidd - A display driver object.
3757 data - a pointer to a chain of HIDD_ViewPortData structures.
3758 view - A pointer to graphics.library View structure being prepared.
3760 RESULT
3761 MCOP_OK if there was no error or MCOP_NO_MEM otherwise.
3762 MCOP_NOP is not allowed as a return value of this method.
3764 NOTES
3765 graphics.library calls this method in MrgCop() after the complete view
3766 is built. data->Next pointer contains valid data.
3768 This function can be repeatedly called several times, and there is no
3769 cleanup counterpart for it. This should be taken into account in method
3770 implementation.
3772 EXAMPLE
3774 BUGS
3776 SEE ALSO
3778 INTERNALS
3779 Base class implementation just does nothing. This function is mainly intended
3780 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3782 *****************************************************************************************/
3784 ULONG GFX__Hidd_Gfx__PrepareViewPorts(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ShowViewPorts *msg)
3786 return MCOP_OK;
3789 #undef csd
3791 /****************************************************************************************/
3793 static ULONG ObtainAttrBases(OOP_AttrBase *bases, CONST_STRPTR *interfaces, ULONG count)
3795 ULONG i;
3796 ULONG failed = 0;
3798 for (i = 0; i < count; i++)
3800 bases[i] = OOP_ObtainAttrBase(interfaces[i]);
3801 if (!bases[i])
3802 failed++;
3805 return failed;
3808 static void ReleaseAttrBases(OOP_AttrBase *bases, CONST_STRPTR *interfaces, ULONG count)
3810 ULONG i;
3812 for (i = 0; i < count; i++)
3814 if (bases[i])
3815 OOP_ReleaseAttrBase(interfaces[i]);
3819 static ULONG GetMethodBases(OOP_MethodID *bases, CONST_STRPTR *interfaces, ULONG count)
3821 ULONG i;
3822 ULONG failed = 0;
3824 for (i = 0; i < count; i++)
3826 bases[i] = OOP_GetMethodID(interfaces[i], 0);
3827 if (bases[i] == -1)
3828 failed++;
3831 return failed;
3834 static CONST_STRPTR interfaces[NUM_ATTRBASES] =
3836 IID_Hidd_BitMap,
3837 IID_Hidd_Gfx,
3838 IID_Hidd_GC,
3839 IID_Hidd_ColorMap,
3840 IID_Hidd_Overlay,
3841 IID_Hidd_Sync,
3842 IID_Hidd_PixFmt,
3843 IID_Hidd_PlanarBM,
3844 IID_Hidd_ChunkyBM,
3847 static int GFX_ClassInit(LIBBASETYPEPTR LIBBASE)
3849 struct class_static_data *csd = &LIBBASE->hdg_csd;
3851 if (ObtainAttrBases(csd->attrBases, interfaces, NUM_ATTRBASES))
3853 ReturnInt("init_gfxhiddclass", ULONG, FALSE);
3856 if (GetMethodBases(csd->methodBases, interfaces, NUM_METHODBASES))
3858 ReturnInt("init_gfxhiddclass", ULONG, FALSE);
3861 D(bug("Creating std pixelfmts\n"));
3862 ReturnInt("init_gfxhiddclass", ULONG, create_std_pixfmts(csd));
3865 /****************************************************************************************/
3867 static int GFX_ClassFree(LIBBASETYPEPTR LIBBASE)
3869 struct class_static_data *csd = &LIBBASE->hdg_csd;
3871 EnterFunc(bug("free_gfxhiddclass(csd=%p)\n", csd));
3873 delete_pixfmts(csd);
3874 ReleaseAttrBases(csd->attrBases, interfaces, NUM_ATTRBASES);
3876 ReturnInt("free_gfxhiddclass", BOOL, TRUE);
3879 /****************************************************************************************/
3881 ADD2INITLIB(GFX_ClassInit, 0)
3882 ADD2EXPUNGELIB(GFX_ClassFree, 0)
3884 /****************************************************************************************/
3886 /* Since the shift/mask values of a pixel format are designed for pixel
3887 access, not byte access, they are endianess dependant */
3889 #if AROS_BIG_ENDIAN
3890 #include "stdpixfmts_be.h"
3891 #else
3892 #include "stdpixfmts_le.h"
3893 #endif
3895 /****************************************************************************************/
3897 static BOOL create_std_pixfmts(struct class_static_data *csd)
3899 ULONG i;
3900 struct pixfmt_data *pf;
3902 memset(csd->std_pixfmts, 0, sizeof (OOP_Object *) * num_Hidd_StdPixFmt);
3904 for (i = 0; i < num_Hidd_StdPixFmt; i ++)
3906 pf = (struct pixfmt_data *)create_and_init_object(csd->pixfmtclass, (UBYTE *)&stdpfs[i], sizeof (stdpfs[i]), csd);
3908 if (!pf)
3910 D(bug("FAILED TO CREATE PIXEL FORMAT %d\n", i));
3911 delete_pixfmts(csd);
3912 ReturnBool("create_stdpixfmts", FALSE);
3915 csd->std_pixfmts[i] = &pf->pf;
3916 /* We don't use semaphore protection here because we do this only during class init stage */
3917 pf->refcount = 1;
3918 AddTail((struct List *)&csd->pflist, (struct Node *)&pf->node);
3920 ReturnBool("create_stdpixfmts", TRUE);
3923 /****************************************************************************************/
3925 static VOID delete_pixfmts(struct class_static_data *csd)
3927 struct Node *n, *safe;
3929 ForeachNodeSafe(&csd->pflist, n, safe)
3930 OOP_DisposeObject((OOP_Object *)PIXFMT_OBJ(n));
3933 /****************************************************************************************/
3935 static inline BOOL cmp_pfs(HIDDT_PixelFormat *tmppf, HIDDT_PixelFormat *dbpf)
3937 /* Just compare everything except stdpixfmt */
3938 /* Compare flags first (because it's a fast check) */
3939 if (tmppf->flags != dbpf->flags)
3940 return FALSE;
3941 /* If they match, compare the rest of things */
3942 return !memcmp(tmppf, dbpf, offsetof(HIDDT_PixelFormat, stdpixfmt));
3945 /****************************************************************************************/
3948 Parses the tags supplied in 'tags' and puts the result into 'pf'.
3949 It also checks to see if all needed attrs are supplied.
3950 It uses 'attrcheck' for this, so you may find attrs outside
3951 of this function, and mark them as found before calling this function
3954 #define PFAF(x) (1L << aoHidd_PixFmt_ ## x)
3955 #define PF_COMMON_AF ( PFAF(Depth) | PFAF(BitsPerPixel) | PFAF(BytesPerPixel) \
3956 | PFAF(ColorModel) | PFAF(BitMapType) )
3958 #define PF_TRUECOLOR_AF ( PFAF(RedMask) | PFAF(GreenMask) | PFAF(BlueMask) | PFAF(AlphaMask) | \
3959 PFAF(RedShift) | PFAF(GreenShift) | PFAF(BlueShift) | PFAF(AlphaShift))
3961 #define PF_PALETTE_AF ( PFAF(CLUTMask) | PFAF(CLUTShift) | PFAF(RedMask) | PFAF(GreenMask) | \
3962 PFAF(BlueMask) )
3964 #define PFAO(x) (aoHidd_PixFmt_ ## x)
3966 /****************************************************************************************/
3968 BOOL parse_pixfmt_tags(struct TagItem *tags, HIDDT_PixelFormat *pf,
3969 ULONG ATTRCHECK(pixfmt), struct class_static_data *csd)
3971 IPTR attrs[num_Hidd_PixFmt_Attrs] = {0};
3973 if (0 != OOP_ParseAttrs(tags, attrs, num_Hidd_PixFmt_Attrs,
3974 &ATTRCHECK(pixfmt), HiddPixFmtAttrBase))
3976 D(bug("!!! parse_pixfmt_tags: ERROR PARSING TAGS THROUGH OOP_ParseAttrs !!!\n"));
3977 return FALSE;
3980 if (PF_COMMON_AF != (PF_COMMON_AF & ATTRCHECK(pixfmt)))
3982 D(bug("!!! parse_pixfmt_tags: Missing PixFmt attributes passed to parse_pixfmt_tags(): %x !!!\n", ATTRCHECK(pixfmt)));
3983 return FALSE;
3986 /* Set the common attributes */
3987 pf->depth = attrs[PFAO(Depth)];
3988 pf->size = attrs[PFAO(BitsPerPixel)];
3989 pf->bytes_per_pixel = attrs[PFAO(BytesPerPixel)];
3990 /* Fill in only real StdPixFmt specification. Special values (Native and Native32)
3991 are not allowed here */
3992 if (attrs[PFAO(StdPixFmt)] >= num_Hidd_PseudoStdPixFmt)
3993 pf->stdpixfmt = attrs[PFAO(StdPixFmt)];
3995 SET_PF_COLMODEL( pf, attrs[PFAO(ColorModel)]);
3996 SET_PF_BITMAPTYPE(pf, attrs[PFAO(BitMapType)]);
3998 if (ATTRCHECK(pixfmt) & PFAF(SwapPixelBytes))
4000 SET_PF_SWAPPIXELBYTES_FLAG(pf, attrs[PFAO(SwapPixelBytes)]);
4003 /* Set the colormodel specific stuff */
4004 switch (HIDD_PF_COLMODEL(pf))
4006 case vHidd_ColorModel_TrueColor:
4007 /* Check that we got all the truecolor describing stuff */
4008 if (PF_TRUECOLOR_AF != (PF_TRUECOLOR_AF & ATTRCHECK(pixfmt)))
4010 D(bug("!!! Unsufficient true color format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
4011 return FALSE;
4014 /* Set the truecolor stuff */
4015 pf->red_mask = attrs[PFAO(RedMask)];
4016 pf->green_mask = attrs[PFAO(GreenMask)];
4017 pf->blue_mask = attrs[PFAO(BlueMask)];
4018 pf->alpha_mask = attrs[PFAO(AlphaMask)];
4020 pf->red_shift = attrs[PFAO(RedShift)];
4021 pf->green_shift = attrs[PFAO(GreenShift)];
4022 pf->blue_shift = attrs[PFAO(BlueShift)];
4023 pf->alpha_shift = attrs[PFAO(AlphaShift)];
4024 break;
4026 case vHidd_ColorModel_Palette:
4027 case vHidd_ColorModel_StaticPalette:
4028 if ( PF_PALETTE_AF != (PF_PALETTE_AF & ATTRCHECK(pixfmt)))
4030 D(bug("!!! Unsufficient palette format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
4031 return FALSE;
4034 /* set palette stuff */
4035 pf->clut_mask = attrs[PFAO(CLUTMask)];
4036 pf->clut_shift = attrs[PFAO(CLUTShift)];
4038 pf->red_mask = attrs[PFAO(RedMask)];
4039 pf->green_mask = attrs[PFAO(GreenMask)];
4040 pf->blue_mask = attrs[PFAO(BlueMask)];
4042 break;
4044 } /* shift (colormodel) */
4046 return TRUE;
4049 /****************************************************************************************/
4052 Create an empty object and initialize it the "ugly" way. This only works with
4053 CLID_Hidd_PixFmt and CLID_Hidd_Sync classes
4056 /****************************************************************************************/
4058 static OOP_Object *create_and_init_object(OOP_Class *cl, UBYTE *data, ULONG datasize,
4059 struct class_static_data *csd)
4061 OOP_Object *o;
4063 o = OOP_NewObject(cl, NULL, NULL);
4064 if (NULL == o)
4066 D(bug("!!! UNABLE TO CREATE OBJECT IN create_and_init_object() !!!\n"));
4067 return NULL;
4070 memcpy(o, data, datasize);
4072 return o;
4075 /****************************************************************************************/
4077 static struct pixfmt_data *find_pixfmt(HIDDT_PixelFormat *tofind, struct class_static_data *csd)
4079 struct pixfmt_data *retpf = NULL;
4080 HIDDT_PixelFormat *db_pf;
4081 struct Node *n;
4083 /* Go through the pixel format list to see if a similar pf allready exists */
4084 ObtainSemaphoreShared(&csd->pfsema);
4086 ForeachNode(&csd->pflist, n)
4088 db_pf = PIXFMT_OBJ(n);
4089 DPF(bug("find_pixfmt(): Trying pixelformat 0x%p\n", db_pf));
4090 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n",
4091 db_pf->red_shift, db_pf->green_shift, db_pf->blue_shift, db_pf->alpha_shift,
4092 db_pf->red_mask, db_pf->green_mask, db_pf->blue_mask, db_pf->alpha_mask,
4093 db_pf->bytes_per_pixel, db_pf->size, db_pf->depth, db_pf->stdpixfmt));
4094 if (cmp_pfs(tofind, db_pf))
4096 DPF(bug("Match!\n"));
4097 retpf = (struct pixfmt_data *)db_pf;
4098 break;
4102 ReleaseSemaphore(&csd->pfsema);
4103 return retpf;