Fixed warning.
[AROS.git] / rom / hidds / graphics / GraphicsClass.c
blob6281b664619169139805578f4408bca718d4901f
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics hidd class implementation.
6 Lang: english
7 */
9 /****************************************************************************************/
11 #include <aros/atomic.h>
12 #include <aros/config.h>
13 #include <aros/symbolsets.h>
14 #include <cybergraphx/cgxvideo.h>
15 #include <exec/lists.h>
16 #include <graphics/displayinfo.h>
18 #include "graphics_intern.h"
20 #include <string.h>
22 #include <proto/exec.h>
23 #include <proto/utility.h>
24 #include <proto/oop.h>
25 #include <exec/libraries.h>
26 #include <exec/memory.h>
28 #include <utility/tagitem.h>
30 #include LC_LIBDEFS_FILE
32 #undef SDEBUG
33 #undef DEBUG
34 #define SDEBUG 0
35 #define DEBUG 0
36 #include <aros/debug.h>
38 #define DPF(x)
41 #include <hidd/graphics.h>
43 /*****************************************************************************************
45 NAME
46 --background_graphics--
48 LOCATION
49 hidd.graphics.graphics
51 NOTES
52 When working with graphics drivers this is the first object you get.
53 It allows you to create BitMap and GC (graphics context)
54 object. The class' methods must be overidden by hardware-specific
55 subclasses where documented to do so.
57 *****************************************************************************************/
59 /*****************************************************************************************
61 NAME
62 --display_modes--
64 LOCATION
65 hidd.graphics.graphics
67 NOTES
68 Each display driver object internally stores a database of supported display mode
69 IDs. This database is normally managed by base class, the driver does not need to
70 reimplement respective methods.
72 A display mode ID in AROS is a 32-bit integer value, the same as on AmigaOS(tm).
73 However mode ID layout introduced by Commodore does not fit well for RTG systems.
74 In order to overcome its limitations, display ID on AROS may have two forms:
76 1. A chipset mode ID. These are standard IDs defined by Commodore. You may find
77 their definitions in graphics/modeid.h.
79 2. AROS RTG mode ID.
81 An RTG mode ID is composed of three parts in the form:
83 nnnn xx yy
85 nnnn - monitor ID. This number is maintained by system libraries. IDs are
86 assigned in the order in which drivers are loaded and display hardware is
87 found. Drivers do not have to care about this part, and should normally
88 mask it out if they for some reason look at mode ID. In order to
89 distinguish between chipset mode IDs and RTG mode IDs, order number starts
90 not from zero, reserving some space for C= chipset mode IDs (which appear
91 to have order numbers from 0x0000 to 0x000A). Currently RTG monitor IDs
92 start from 0x0010, however with time this value may change. So don't rely
93 on some particular values in RTG IDs. Use cybergraphics.library/IsCyberModeID()
94 function if you want to know for sure if the given mode ID belongs to an
95 RTG driver.
97 xx - A sync object index in driver's mode database.
98 yy - A pixelformat object in driver's mode database.
100 Normally the driver does not have to care about mode ID decoding. The mode
101 database is maintained by base class. The only useful things for the driver are
102 sync and pixelformat objects, from which it's possible to get different
103 information about the mode. They can be obtained from the base class using
104 HIDD_Gfx_GetMode().
106 Note that the driver object by itself does not know its monitor ID. Different
107 displays are served by different objects, any of which may belong to any class.
108 So all driver methods which return mode IDs will set monitor ID to zero. All
109 methods that take mode ID as argument are expected to ignore the monitor ID part
110 and do not make any assumptions about its value.
112 *****************************************************************************************/
114 static BOOL create_std_pixfmts(struct class_static_data *_csd);
115 static VOID delete_pixfmts(struct class_static_data *_csd);
116 static BOOL register_modes(OOP_Class *cl, OOP_Object *o, struct TagItem *modetags);
118 static BOOL alloc_mode_db(struct mode_db *mdb, ULONG numsyncs, ULONG numpfs, OOP_Class *cl);
119 static VOID free_mode_db(struct mode_db *mdb, OOP_Class *cl);
120 static OOP_Object *create_and_init_object(OOP_Class *cl, UBYTE *data, ULONG datasize,
121 struct class_static_data *_csd);
123 static struct pixfmt_data *find_pixfmt(HIDDT_PixelFormat *tofind
124 , struct class_static_data *_csd);
126 static VOID copy_bm_and_colmap(OOP_Class *cl, OOP_Object *o, OOP_Object *src_bm
127 , OOP_Object *dst_bm, ULONG width, ULONG height);
129 BOOL parse_pixfmt_tags(struct TagItem *tags, HIDDT_PixelFormat *pf, ULONG attrcheck, struct class_static_data *_csd);
131 /****************************************************************************************/
133 #define COMPUTE_HIDD_MODEID(sync, pf) \
134 ( ((sync) << 8) | (pf) )
136 #define MODEID_TO_SYNCIDX(id) (((id) & 0X0000FF00) >> 8)
137 #define MODEID_TO_PFIDX(id) ( (id) & 0x000000FF)
139 /****************************************************************************************/
141 OOP_Object *GFX__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
143 struct HIDDGraphicsData *data;
144 BOOL ok = FALSE;
145 struct TagItem *modetags;
146 struct TagItem gctags[] =
148 {TAG_DONE, 0UL}
151 D(bug("Entering gfx.hidd::New\n"));
153 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
154 if (NULL == o)
155 return NULL;
157 D(bug("Got object o=%x\n", o));
159 data = OOP_INST_DATA(cl, o);
161 InitSemaphore(&data->mdb.sema);
162 /* data->curmode = vHidd_ModeID_Invalid; */
164 /* Get the mode tags */
165 modetags = (struct TagItem *)GetTagData(aHidd_Gfx_ModeTags, 0, msg->attrList);
166 if (NULL != modetags)
168 /* Parse it and register the gfxmodes */
169 if (register_modes(cl, o, modetags))
171 ok = TRUE;
173 else
174 D(bug("Could not register modes\n"));
176 else {
177 D(bug("Could not get ModeTags\n"));
178 ok = TRUE;
181 /* Create a gc that we can use for some rendering */
182 if (ok)
184 data->gc = OOP_NewObject(CSD(cl)->gcclass, NULL, gctags);
185 if (NULL == data->gc)
187 D(bug("Could not get gc\n"));
188 ok = FALSE;
192 if (!ok)
194 D(bug("Not OK\n"));
195 OOP_MethodID dispose_mid;
197 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
198 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
199 o = NULL;
202 D(bug("Leaving gfx.hidd::New o=%x\n", o));
204 return o;
207 /****************************************************************************************/
209 VOID GFX__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
211 struct HIDDGraphicsData *data;
213 data = OOP_INST_DATA(cl, o);
215 /* free the mode db stuff */
216 free_mode_db(&data->mdb, cl);
218 /* Here we should unregister pixelformats registered in our New().
219 However gfx drivers aren't supposed to be removed, so it's okay
220 not to do it at all for now. */
222 if (NULL != data->gc)
223 OOP_DisposeObject(data->gc);
225 OOP_DoSuperMethod(cl, o, msg);
228 /*****************************************************************************************
230 NAME
231 aoHidd_Gfx_IsWindowed
233 SYNOPSIS
234 [..G], BOOL
236 LOCATION
237 hidd.graphics.graphics
239 FUNCTION
240 Tells if the display driver is using hosted display in host OS' window, and mouse
241 input is handled by host OS.
243 Windowed displays may send activation events to AROS. This is needed in order to
244 correctly handle display switch in a multi-display configuration (which means that
245 the user has multiple windows on host OS desktop and can freely switch between them).
247 NOTES
248 Even in fullscreen mode drivers should still return TRUE if the host OS manages mouse
249 input (for example, X11 driver). If mouse input is not managed by the host OS
250 (for example, with Linux framebuffer driver), return FALSE.
252 EXAMPLE
254 BUGS
256 SEE ALSO
257 aoHidd_Gfx_ActiveCallBack, aoHidd_Gfx_ActiveCallBackData
259 INTERNALS
260 Base class always provides FALSE value
262 *****************************************************************************************/
264 /*****************************************************************************************
266 NAME
267 aoHidd_Gfx_DMPSLevel
269 SYNOPSIS
270 [ISG], HIDDT_DPMSLevel
272 LOCATION
273 hidd.graphics.graphics
275 FUNCTION
276 Gets or sets current DPMS level for driver's display.
277 A value can be one of:
278 vHidd_Gfx_DPMSLevel_On,
279 vHidd_Gfx_DPMSLevel_Standby,
280 vHidd_Gfx_DPMSLevel_Suspend,
281 vHidd_Gfx_DPMSLevel_Off
283 If the driver does not support some state, it's up to the driver what to do.
284 Usually it is expected to ignore the request.
286 Getting this attribute should return real current state.
288 NOTES
290 EXAMPLE
292 BUGS
294 SEE ALSO
296 INTERNALS
297 Base class always provides vHidd_Gfx_DPMSLevel_On value (comes from rootclass'
298 Get() which sets the value to 0).
300 *****************************************************************************************/
302 /*****************************************************************************************
304 NAME
305 aoHidd_Gfx_ModeTags
307 SYNOPSIS
308 [I..], struct TagItem *
310 LOCATION
311 hidd.graphics.graphics
313 FUNCTION
314 Specify a pointer to a taglist which contains description of display modes
315 supported by the driver.
317 This attribute is usually appended in moRoot_New method of the display driver
318 class.
320 This attribute is mandatory for the base class, otherwise driver object creation
321 fails.
323 Mode description taglist may contain the following tags:
324 - Any sync attributes - these attributes will specify values common for all sync
325 modes
326 - Any pixelformat attributes - these attributes will specify values common for
327 all pixelformat modes
328 - aoHidd_Gfx_SyncTags - specifies a pointer to another separate taglist containing
329 attributes for one sync (display) mode. If this tag
330 is not supplied at all, a set of default modes will be
331 generated for the driver.
332 - aoHidd_Gfx_PixFmtTags - specifies a pointer to another separate taglist containing
333 attributes for one pixelformat. This tag must be supplied
334 at least once, otherwise driver object will fail to create.
336 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags can be specified multiple times in
337 order to associate more than one display mode with the driver. Note that common
338 values for sync and pixelformat objects need to be placed in the taglist before
339 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags. You may specify them again between
340 these tags in order to alter common values.
342 NOTES
344 EXAMPLE
345 Partial example code of display driver supporting a truecolor display with three
346 resolutions:
348 // Our pixelformat (24-bit 0BGR)
349 struct TagItem pftags[] =
351 { aHidd_PixFmt_RedShift , 24 },
352 { aHidd_PixFmt_GreenShift , 16 },
353 { aHidd_PixFmt_BlueShift , 8 },
354 { aHidd_PixFmt_AlphaShift , 0 },
355 { aHidd_PixFmt_RedMask , 0x000000FF },
356 { aHidd_PixFmt_GreenMask , 0x0000FF00 },
357 { aHidd_PixFmt_BlueMask , 0x00FF0000 },
358 { aHidd_PixFmt_AlphaMask , 0x00000000 },
359 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_TrueColor },
360 { aHidd_PixFmt_Depth , 24 },
361 { aHidd_PixFmt_BytesPerPixel, 4 },
362 { aHidd_PixFmt_BitsPerPixel , 24 },
363 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Native },
364 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Chunky },
365 { TAG_DONE , 0UL }
368 // 640x480 resolution
369 struct TagItem tags_800_600[] =
371 { aHidd_Sync_HDisp , 640 },
372 { aHidd_Sync_VDisp , 480 },
373 { TAG_DONE , 0UL }
376 // 800x600 resolution
377 struct TagItem tags_800_600[] =
379 { aHidd_Sync_HDisp , 800 },
380 { aHidd_Sync_VDisp , 600 },
381 { TAG_DONE , 0UL }
384 // 1024x768 resolution
385 struct TagItem tags_1024_768[] =
387 { aHidd_Sync_HDisp , 1024 },
388 { aHidd_Sync_VDisp , 768 },
389 { TAG_DONE , 0UL }
392 // Mode description taglist itself
393 struct TagItem mode_tags[] =
395 // Our driver supports a single pixelformat
396 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
398 // Here go sync values common for all sync modes
399 { aHidd_Sync_HMin , 112 },
400 { aHidd_Sync_VMin , 112 },
401 { aHidd_Sync_HMax , 16384 },
402 { aHidd_Sync_VMax , 16384 },
403 { aHidd_Sync_Description, (IPTR)"Example: %hx%v" },
405 // First resolution
406 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
408 // Next two syncs will have HMax = 32768, as an example
409 { aHidd_Sync_HMax , 32768 },
411 // Two more resolutions
412 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
413 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
414 { TAG_DONE , 0UL }
417 // This is the attribute list which is given to New method
418 // of the base class
419 struct TagItem mytags[] =
421 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
422 { TAG_DONE , NULL }
425 BUGS
427 SEE ALSO
429 INTERNALS
431 *****************************************************************************************/
433 /*****************************************************************************************
435 NAME
436 aoHidd_Gfx_NumSyncs
438 SYNOPSIS
439 [..G], ULONG
441 LOCATION
442 hidd.graphics.graphics
444 FUNCTION
445 Gets total number of sync objects in the internal display mode database.
447 NOTES
449 EXAMPLE
451 BUGS
453 SEE ALSO
454 moHidd_Gfx_GetSync
456 INTERNALS
458 *****************************************************************************************/
460 /*****************************************************************************************
462 NAME
463 aoHidd_Gfx_SupportsHWCursor
465 SYNOPSIS
466 [..G], BOOL
468 LOCATION
469 hidd.graphics.graphics
471 FUNCTION
472 Tells whether the driver supports hardware mouse pointer sprite.
474 If the driver provides TRUE value for this attribute, it is expected to implement
475 HIDD_Gfx_SetCursorPos(), HIDD_Gfx_SetCursorShape() and HIDD_Gfx_SetCursorVisible()
476 methods.
478 Mouse pointer counts for one hardware sprite, so if the driver implements also
479 HIDD_Gfx_ModeProperties(), it should set NumHWSprites to 1 in order to provide
480 valid information about display modes.
482 The driver must implement this attribute if it implements HIDD_Gfx_ModeProperties().
483 Otherwise it will provide false information in graphics.library/GetDisplayInfoData().
484 Base class can determine NumHWSprites based on this attribute value but not vice
485 versa.
487 NOTES
488 Default implementation in the base class returns FALSE. This causes the system to
489 use software sprite emulation.
491 This attribute is obsolete and is used only by AROS graphics.library up to v41.2. In
492 new drivers consider implementing aoHidd_Gfx_HWSpriteTypes attribute.
494 EXAMPLE
496 BUGS
498 SEE ALSO
499 aoHidd_Gfx_HWSpriteTypes, moHidd_Gfx_ModeProperties
501 INTERNALS
503 *****************************************************************************************/
505 /*****************************************************************************************
507 NAME
508 aoHidd_Gfx_NoFrameBuffer
510 SYNOPSIS
511 [..G], BOOL
513 LOCATION
514 hidd.graphics.graphics
516 FUNCTION
517 Tells whether the driver does not need a framebuffer.
519 A framebuffer is a special bitmap in a fixed area of video RAM. If the framebuffer
520 is used, the driver is expected to copy a new bitmap into it in HIDD_Gfx_Show()
521 and optionally copy old bitmap back.
523 A framebuffer is needed if the hardware does not have enough VRAM to store many
524 bitmaps or does not have capabilities to switch the display between various VRAM
525 regions.
527 An example of driver using a framebuffer is hosted SDL driver. By design SDL works
528 only with single display window, which is considered a framebuffer.
530 NOTES
531 Provides FALSE if not implemented in the driver.
533 EXAMPLE
535 BUGS
537 SEE ALSO
538 moHidd_Gfx_Show
540 INTERNALS
541 VGA and VESA do not use framebuffer, they use mirroring technique instead in order
542 to prevents VRAM reading which is slow.
544 *****************************************************************************************/
546 /*****************************************************************************************
548 NAME
549 aoHidd_Gfx_HWSpriteTypes
551 SYNOPSIS
552 [..G], BOOL
554 LOCATION
555 hidd.graphics.graphics
557 FUNCTION
558 Return hardware sprite image types supported by the driver.
560 The returned value is a combination of the following bit flags:
561 vHidd_SpriteType_3Plus1 - color 0 is transparent, 1-3 visible
562 (Amiga(tm) chipset sprite format)
563 vHidd_SpriteType_2Plus1 - color 0 is transparent, color 1 is undefined
564 (can be whatever, for example clear or inverse),
565 colors 2-3 visible.
566 vHidd_SpriteType_DirectColor - Hi- or truecolor image, or LUT image with own
567 palette, perhaps with alpha channel
569 NOTES
570 This attribute should return 0 if the driver does not support hardware mouse sprite
571 at all. Software sprite emulation is done by graphics.library.
573 Default implementation in the base class is based on aoHidd_Gfx_SupportsHWCursor
574 value. This is done for backwards compatibility.
576 EXAMPLE
578 BUGS
580 SEE ALSO
581 aoHidd_Gfx_SupportsHWCursor
583 INTERNALS
584 Default implementation in the base class queries aoHidd_Gfx_SupportsHWCursor
585 and provides (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) in case
586 if it returns TRUE. Otherwise it returns zero. This is done for backwards
587 compatibility with old drivers.
589 *****************************************************************************************/
591 /*****************************************************************************************
593 NAME
594 aoHidd_Gfx_MemorySize
596 SYNOPSIS
597 [..G], ULONG
599 LOCATION
600 hidd.graphics.graphics
602 FUNCTION
603 Query total size of video card memory in bytes.
605 NOTES
607 EXAMPLE
609 BUGS
611 SEE ALSO
612 aoHidd_Gfx_MemoryClock
614 INTERNALS
616 *****************************************************************************************/
618 /*****************************************************************************************
620 NAME
621 aoHidd_Gfx_MemoryClock
623 SYNOPSIS
624 [..G], ULONG
626 LOCATION
627 hidd.graphics.graphics
629 FUNCTION
630 Query video card's memory clock in Hz. 0 is a valid value meaning 'unknown'.
632 NOTES
634 EXAMPLE
636 BUGS
638 SEE ALSO
639 aoHidd_Gfx_MemorySize
641 INTERNALS
643 *****************************************************************************************/
645 /*****************************************************************************************
647 NAME
648 aoHidd_Gfx_DriverName
650 SYNOPSIS
651 [..G], STRPTR
653 LOCATION
654 hidd.graphics.graphics
656 FUNCTION
657 Query CyberGraphX driver name. It is the same name which can be given to
658 cybergraphics.library/BestCModeIDTagList() as CYBRBIDTG_BoardName value.
660 NOTES
661 By default base class returns class name as value of this attribute.
662 However this can (and must for some drivers listed in BestCModeIDTagList()
663 documentation) be overriden.
665 EXAMPLE
667 BUGS
669 SEE ALSO
671 INTERNALS
673 *****************************************************************************************/
675 /*****************************************************************************************
677 NAME
678 aoHidd_Gfx_ActiveCallBack
680 SYNOPSIS
681 [.S.], void (*)(APTR userdata, OOP_Object *bitmap)
683 LOCATION
684 hidd.graphics.graphics
686 FUNCTION
687 Set display activation interrupt handler.
689 This handler needs to be called by hosted display driver, if host OS
690 windowing system is used for the display and mouse input is handled by the
691 host OS.
693 This way the driver can tell AROS when a display window has been activated so that
694 AROS will be able to switch current display correctly when working in a multi-display
695 configuration.
697 The function uses C calling convention and needs to be declared as follows:
699 void ActivationHandler(APTR userdata, OOP_Object *bitmap);
701 Parameters of this function will be:
702 userdata - Whatever is specified by aoHidd_Gfx_ActiveCallBackData attribute.
703 bitmap - Currently reserved. Drivers need to set it to NULL.
705 The function can be called from within an interrupt, so usual restrictions apply
706 to it.
708 Set this attribute to NULL in order to disable activation handling.
710 NOTES
711 When setting the activation callback function, be sure that you set correct
712 userdata before you actually set the callback pointer. Otherwise your callback
713 can be called with wrong data pointer.
715 Only one activation handler can be installed. Installing a new handler replaces
716 the previous one.
718 Native displays do not need to implement this attribute because there can be
719 no external activation events.
721 EXAMPLE
723 BUGS
725 SEE ALSO
726 aoHidd_Gfx_ActiveCallBackData, aoHidd_Gfx_IsWindowed
728 INTERNALS
729 This attribute needs to be implemented by the display driver. Base class contains
730 no implementation.
732 *****************************************************************************************/
734 /*****************************************************************************************
736 NAME
737 aoHidd_Gfx_ActiveCallBackData
739 SYNOPSIS
740 [.S.], APTR
742 LOCATION
743 hidd.graphics.graphics
745 FUNCTION
746 Set user-defined data pointer for display activation handler.
748 NOTES
750 EXAMPLE
752 BUGS
754 SEE ALSO
755 aoHidd_Gfx_ActiveCallBack
757 INTERNALS
758 This attribute needs to be implemented by the display driver. Base class contains
759 no implementation.
761 *****************************************************************************************/
763 VOID GFX__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
765 struct HIDDGraphicsData *data;
766 ULONG idx;
768 data = OOP_INST_DATA(cl, o);
770 if (IS_GFX_ATTR(msg->attrID, idx))
772 switch (idx)
774 case aoHidd_Gfx_NumSyncs:
775 *msg->storage = data->mdb.num_syncs;
776 return;
778 case aoHidd_Gfx_IsWindowed:
779 case aoHidd_Gfx_SupportsHWCursor:
780 *msg->storage = 0;
781 return;
783 case aoHidd_Gfx_HWSpriteTypes:
785 IPTR hwc;
787 OOP_GetAttr(o, aHidd_Gfx_SupportsHWCursor, &hwc);
788 *msg->storage = hwc ? (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) : 0;
789 return;
792 case aoHidd_Gfx_DriverName:
793 *msg->storage = (IPTR)OOP_OCLASS(o)->ClassNode.ln_Name;
794 return;
796 default: /* Keep compiler happy */
797 break;
801 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
803 return;
806 /*****************************************************************************************
808 NAME
809 moHidd_Gfx_NewGC
811 SYNOPSIS
812 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewGC *msg);
814 OOP_Object *HIDD_Gfx_NewGC(OOP_Object *gfxHidd, struct TagItem *tagList);
816 LOCATION
817 hidd.graphics.graphics
819 FUNCTION
820 Create a GC (gfx context) object that may be used for rendering
821 into a bitmap.
823 INPUTS
824 gfxHidd - A graphics driver object with which the GC will perform
825 the rendering operations.
826 tagList - A list of GC attributes. See hidd.graphics.gc class
827 documentation for their description.
829 RESULT
830 gc - pointer to the newly created GC, ready for use for rendering
831 operations.
833 NOTES
834 A GC object is just a data storage. You may create a subclass of GC if
835 you wish to, however there's usually no need to. Additionally, this may
836 be not future-proof (since GC subclasses can not be interchanged between
837 different drivers. Please avoid using custom GCs.
839 EXAMPLE
841 BUGS
842 At the moment subclassing GCs is not supported because some parts of
843 the operating system create GC objects directly. It is unclear whether
844 subclassing GCs is actually needed.
846 SEE ALSO
847 moHidd_Gfx_DisposeGC
849 INTERNALS
851 *****************************************************************************************/
853 OOP_Object *GFX__Hidd_Gfx__NewGC(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewGC *msg)
855 OOP_Object *gc = NULL;
857 EnterFunc(bug("HIDDGfx::NewGC()\n"));
859 gc = OOP_NewObject(NULL, CLID_Hidd_GC, msg->attrList);
861 ReturnPtr("HIDDGfx::NewGC", OOP_Object *, gc);
864 /*****************************************************************************************
866 NAME
867 moHidd_Gfx_DisposeGC
869 SYNOPSIS
870 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeGC *msg);
872 VOID HIDD_Gfx_DisposeGC(OOP_Object *gfxHidd, OOP_Object *gc)
874 LOCATION
875 hidd.graphics.graphics
877 FUNCTION
878 Deletes a GC (Graphics Context) object previously created
879 by HIDD_Gfx_NewGC().
881 Subclasses do not have to override this method
882 unless they allocate anything additional to a gc object in
883 their HIDD_Gfx_NewGC() implementation.
885 INPUTS
886 gfxHidd - A driver object which was used for creating a GC.
887 gc - Pointer to gc object to delete.
889 RESULT
890 None.
892 NOTES
894 EXAMPLE
896 BUGS
898 SEE ALSO
899 moHidd_Gfx_NewGC
901 INTERNALS
902 Basically just does OOP_DisposeObject(gc);
904 *****************************************************************************************/
906 VOID GFX__Hidd_Gfx__DisposeGC(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_DisposeGC *msg)
908 EnterFunc(bug("HIDDGfx::DisposeGC()\n"));
910 if (NULL != msg->gc) OOP_DisposeObject(msg->gc);
912 ReturnVoid("HIDDGfx::DisposeGC");
915 /****************************************************************************************/
917 #define BMAO(x) aoHidd_BitMap_ ## x
918 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
920 #define BM_DIMS_AF (BMAF(Width) | BMAF(Height))
922 #define SET_TAG(tags, idx, tag, val) \
923 tags[idx].ti_Tag = tag ; tags[idx].ti_Data = (IPTR)val;
925 #define SET_BM_TAG(tags, idx, tag, val) \
926 SET_TAG(tags, idx, aHidd_BitMap_ ## tag, val)
928 /*****************************************************************************************
930 NAME
931 moHidd_Gfx_NewBitMap
933 SYNOPSIS
934 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewBitMap *msg);
936 OOP_Object *HIDD_Gfx_NewBitMap(OOP_Object *gfxHidd, struct TagItem *tagList);
938 LOCATION
939 hidd.graphics.graphics
941 FUNCTION
942 Create a bitmap object.
944 One graphics driver represents at least one displayable bitmap class.
945 Additionally it may represent more classes (for example some old drivers use
946 separate class for nondisplayable bitmaps).
948 These classes are private to the driver. In order to be able to use them
949 bitmap objects are never created directly. Instead they are created using
950 HIDD_Gfx_NewBitMap() call. An implementation of this method in the driver
951 should examine bitmap attributes supplied and make a decision if the bitmap
952 should be created using driver's own class or one of system classes.
954 A typical implementation should pay attention to the following bitmap attributes:
956 aHIDD_BitMap_ModeID - If this attribute is supplied, the bitmap needs to be
957 either displayable by this driver, or be a friend of
958 displayable bitmap. A friend bitmap usually repeats the
959 internal layout of its friend so that the driver may
960 perform blitting operations quickly.
962 aHIDD_BitMap_Displayable - If this attribute is supplied, the bitmap NEEDS to be
963 displayable by this driver. Usually this means that
964 bitmap object will contain video hardware state
965 information. This attribute will always be accompanied
966 by aHIDD_BitMap_ModeID.
968 aHIDD_BitMap_FrameBuffer - The bitmap needs to be a framebuffer bitmap. A
969 framebuffer bitmap is necessary for some kinds of
970 hardware which have a small fixed amount of video
971 RAM which can hold only one screen at a time. Setting
972 this attribute also requires to set also a valid ModeID.
974 aHIDD_BitMap_Friend - If there's no ModeID supplied, you may wish to check class
975 of friend bitmap. This can be useful if your driver uses
976 different classes for displayable and non-displayable bitmaps.
977 By default base class will pick up friend's class and use it
978 for new bitmap if nothing is specified, here you may override
979 this behavior.
981 If your driver wants to specify own class for the bitmap being created,
982 it should prepend an aHIDD_BitMap_ClassPtr attribute to the supplied taglist
983 and pass it to base class. It's not allowed to create bitmap objects directly
984 since they need some more extra information which is added by the base class!
986 This method must be implemented by your subclass. aHIDD_BitMap_ClassPtr or
987 aHIDD_BitMap_ClassID must be provided to the base class for a displayable bitmap!
989 INPUTS
990 gfxHidd - A graphics driver object with which the GC will perform
991 the rendering operations.
993 tagList - A list of bitmap attributes. See hidd.graphics.bitmap class
994 documentation for their description.
996 RESULT
997 gc - pointer to the newly created GC, ready for use for rendering
998 operations.
1000 NOTES
1002 EXAMPLE
1004 BUGS
1006 SEE ALSO
1007 moHidd_Gfx_DisposeBitMap
1009 INTERNALS
1010 The base class implementation currently does the folliwing in order to determine
1011 a class for a nondisplayable bitmap (in the listed order):
1013 1. Check aHIDD_BitMap_ClassPtr and aHIDD_BitMap_ClassID. If one of them is supplied,
1014 the class is already set by a subclass.
1015 2. Check aHIDD_BitMap_StdPixFmt. If this attribute is supplied, figure out type of
1016 the pixelformat (chunky or planar), and use one of two system's default classes.
1017 3. Check aHIDD_BitMap_Friend. If friend bitmap is supplied, obtain its class from
1018 aHIDD_BitMap_ClassPtr value of friend bitmap.
1019 4. If everything fails, bitmap creation fails too.
1021 This behavior is subject to change, but will maintain backwards compatibility.
1023 *****************************************************************************************/
1025 OOP_Object * GFX__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o,
1026 struct pHidd_Gfx_NewBitMap *msg)
1028 struct TagItem bmtags[7];
1030 IPTR attrs[num_Total_BitMap_Attrs];
1031 STRPTR classid = NULL;
1032 OOP_Class *classptr = NULL;
1033 BOOL displayable = FALSE; /* Default attr value */
1034 BOOL framebuffer = FALSE;
1035 OOP_Object *pf = NULL, *sync;
1036 HIDDT_ModeID modeid = 0;
1037 OOP_Object *bm;
1038 struct HIDDGraphicsData *data;
1040 DECLARE_ATTRCHECK(bitmap);
1042 BOOL gotclass = FALSE;
1044 data = OOP_INST_DATA(cl, o);
1046 if (0 != OOP_ParseAttrs(msg->attrList, attrs, num_Total_BitMap_Attrs,
1047 &ATTRCHECK(bitmap), HiddBitMapAttrBase))
1049 D(bug("!!! FAILED TO PARSE ATTRS IN Gfx::NewBitMap !!!\n"));
1050 return NULL;
1053 if (GOT_BM_ATTR(PixFmt))
1055 D(bug("!!! Gfx::NewBitMap: USER IS NOT ALLOWED TO PASS aHidd_BitMap_PixFmt !!!\n"));
1056 return NULL;
1059 /* Get class supplied by superclass */
1060 if (GOT_BM_ATTR(ClassPtr))
1062 classptr = (OOP_Class *)attrs[BMAO(ClassPtr)];
1063 gotclass = TRUE;
1065 else
1067 if (GOT_BM_ATTR(ClassID))
1069 classid = (STRPTR)attrs[BMAO(ClassID)];
1070 gotclass = TRUE;
1074 if (GOT_BM_ATTR(Displayable))
1075 displayable = (BOOL)attrs[BMAO(Displayable)];
1077 if (GOT_BM_ATTR(FrameBuffer))
1079 framebuffer = (BOOL)attrs[BMAO(FrameBuffer)];
1080 if (framebuffer) displayable = TRUE;
1083 if (GOT_BM_ATTR(ModeID))
1085 modeid = attrs[BMAO(ModeID)];
1087 /* Check that it is a valid mode */
1088 if (!HIDD_Gfx_GetMode(o, modeid, &sync, &pf))
1090 D(bug("!!! Gfx::NewBitMap: USER PASSED INVALID MODEID !!!\n"));
1094 /* First argument is gfxhidd */
1095 SET_BM_TAG(bmtags, 0, GfxHidd, o);
1096 SET_BM_TAG(bmtags, 1, Displayable, displayable);
1099 if (displayable || framebuffer)
1101 /* The user has to supply a modeid */
1102 if (!GOT_BM_ATTR(ModeID))
1104 D(bug("!!! Gfx::NewBitMap: USER HAS NOT PASSED MODEID FOR DISPLAYABLE BITMAP !!!\n"));
1105 return NULL;
1108 if (!gotclass)
1110 D(bug("!!! Gfx::NewBitMap: SUBCLASS DID NOT PASS CLASS FOR DISPLAYABLE BITMAP !!!\n"));
1111 return NULL;
1114 SET_BM_TAG(bmtags, 2, ModeID, modeid);
1115 SET_BM_TAG(bmtags, 3, PixFmt, pf);
1117 if (framebuffer)
1119 SET_BM_TAG(bmtags, 4, FrameBuffer, TRUE);
1121 else
1123 SET_TAG(bmtags, 4, TAG_IGNORE, 0UL);
1125 SET_TAG(bmtags, 5, TAG_MORE, msg->attrList);
1128 else
1129 { /* if (displayable) */
1130 IPTR width, height;
1132 /* To get a pixfmt for an offscreen bitmap we either need
1133 (ModeID || ( (Width && Height) && StdPixFmt) || ( (Width && Height) && Friend))
1136 if (GOT_BM_ATTR(ModeID))
1138 /* We have allredy gotten pixelformat and sync for the modeid case */
1139 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
1140 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
1142 else
1144 /* Next to look for is StdPixFmt */
1146 /* Check that we have width && height */
1147 if (BM_DIMS_AF != (BM_DIMS_AF & ATTRCHECK(bitmap)))
1149 D(bug("!!! Gfx::NewBitMap() MISSING WIDTH/HEIGHT TAGS !!!\n"));
1150 return NULL;
1153 width = attrs[BMAO(Width)];
1154 height = attrs[BMAO(Height)];
1156 if (GOT_BM_ATTR(StdPixFmt))
1158 pf = HIDD_Gfx_GetPixFmt(o, (HIDDT_StdPixFmt)attrs[BMAO(StdPixFmt)]);
1159 if (NULL == pf)
1161 D(bug("!!! Gfx::NewBitMap(): USER PASSED BOGUS StdPixFmt !!!\n"));
1162 return NULL;
1165 else
1167 /* Last alternative is that the user passed a friend bitmap */
1168 if (GOT_BM_ATTR(Friend))
1170 OOP_Object *friend_bm = (OOP_Object *)attrs[BMAO(Friend)];
1171 OOP_GetAttr(friend_bm, aHidd_BitMap_PixFmt, (IPTR *)&pf);
1172 /* Try to grab the class from friend bitmap (if not already specified).
1173 We do it because friend bitmap may be a display HIDD bitmap */
1174 if (!gotclass) {
1175 /* Another weirdness is that we have to use this attribute instead of
1176 simple getting OOP_OCLASS(friend_bm). We can't get class directly
1177 from the object, because the framebuffer bitmap object may be a
1178 fakegfx.hidd object, which is even not a bitmap at all. Attempt
1179 to create a bitmap of this class causes system-wide breakage.
1180 Perhaps fakegfx HIDD should be fixed in order to handle this correctly.
1182 OOP_GetAttr(friend_bm, aHidd_BitMap_ClassPtr, (IPTR *)&classptr);
1183 D(bug("[GFX] Friend bitmap is 0x%p has ClassPtr 0x%p\n", friend_bm, classptr));
1184 if (classptr)
1185 gotclass = TRUE;
1188 else
1190 D(bug("!!! Gfx::NewBitMap: UNSIFFICIENT ATTRS TO CREATE OFFSCREEN BITMAP !!!\n"));
1191 return NULL;
1196 /* Did the subclass provide an offbitmap class for us ? */
1197 if (!gotclass)
1199 /* Have to find a suitable class ourselves */
1200 HIDDT_BitMapType bmtype;
1202 OOP_GetAttr(pf, aHidd_PixFmt_BitMapType, &bmtype);
1203 switch (bmtype)
1205 case vHidd_BitMapType_Chunky:
1206 classptr = CSD(cl)->chunkybmclass;
1207 break;
1209 case vHidd_BitMapType_Planar:
1210 classptr = CSD(cl)->planarbmclass;
1211 break;
1213 default:
1214 D(bug("!!! Gfx::NewBitMap: UNKNOWN BITMAPTYPE %d !!!\n", bmtype));
1215 return NULL;
1218 D(bug("[GFX] Bitmap type is %u, using class 0x%p\n", bmtype, classptr));
1220 } /* if (!gotclass) */
1222 /* Set the tags we want to pass to the selected bitmap class */
1223 SET_BM_TAG(bmtags, 2, Width, width);
1224 SET_BM_TAG(bmtags, 3, Height, height);
1225 SET_BM_TAG(bmtags, 4, PixFmt, pf);
1227 if (GOT_BM_ATTR(Friend))
1229 SET_BM_TAG(bmtags, 5, Friend, attrs[BMAO(Friend)]);
1231 else
1233 SET_TAG(bmtags, 5, TAG_IGNORE, 0UL);
1235 SET_TAG(bmtags, 6, TAG_MORE, msg->attrList);
1237 } /* if (!displayable) */
1240 bm = OOP_NewObject(classptr, classid, bmtags);
1242 if (framebuffer)
1243 data->framebuffer = bm;
1245 return bm;
1249 /*****************************************************************************************
1251 NAME
1252 moHidd_Gfx_DisposeBitMap
1254 SYNOPSIS
1255 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeBitMap *msg);
1257 VOID HIDD_Gfx_DisposeBitMap(OOP_Object *gfxHidd, OOP_Object *bitMap);
1259 LOCATION
1260 hidd.graphics.graphics
1262 FUNCTION
1263 Deletes a bitmap object previously created by HIDD_Gfx_NewBitMap().
1265 Subclasses do not have to override this method
1266 unless they allocate anything additional to a bitmap object in
1267 their HIDD_Gfx_NewBitMap() implementation.
1269 INPUTS
1270 gfxHidd - A driver object which was used for creating a bitmap.
1271 bitMap - Pointer to a bitmap object to delete.
1273 RESULT
1274 None.
1276 NOTES
1278 EXAMPLE
1280 BUGS
1282 SEE ALSO
1283 moHidd_Gfx_NewBitMap
1285 INTERNALS
1286 Basically just does OOP_DisposeObject(bitMap);
1288 ******************************************************************************************/
1290 VOID GFX__Hidd_Gfx__DisposeBitMap(OOP_Class *cl, OOP_Object *o,
1291 struct pHidd_Gfx_DisposeBitMap *msg)
1293 if (NULL != msg->bitMap)
1294 OOP_DisposeObject(msg->bitMap);
1297 /****************************************************************************************/
1299 #define SD(x) ((struct sync_data *)x)
1300 #define PF(x) ((HIDDT_PixelFormat *)x)
1302 #define XCOORD_TO_BYTEIDX(x) ( (x) >> 3)
1303 #define COORD_TO_BYTEIDX(x, y, bpr) ( ( (y) * bpr ) + XCOORD_TO_BYTEIDX(x) )
1304 #define XCOORD_TO_MASK(x) (1L << (7 - ((x) & 0x07) ))
1305 #define WIDTH_TO_BYTES(width) ( (( (width) - 1) >> 3) + 1)
1307 /****************************************************************************************/
1309 /* modebm functions pfidx is x and syncidx is y coord in the bitmap */
1311 /****************************************************************************************/
1313 static inline BOOL alloc_mode_bm(struct mode_bm *bm, ULONG numsyncs, ULONG numpfs,
1314 OOP_Class *cl)
1316 bm->bpr = WIDTH_TO_BYTES(numpfs);
1318 bm->bm = AllocVec(bm->bpr * numsyncs, MEMF_CLEAR);
1319 if (NULL == bm->bm)
1320 return FALSE;
1322 /* We initialize the mode bitmap to all modes valid */
1323 memset(bm->bm, 0xFF, bm->bpr * numsyncs);
1325 return TRUE;
1328 /****************************************************************************************/
1330 static inline VOID free_mode_bm(struct mode_bm *bm, OOP_Class *cl)
1332 FreeVec(bm->bm);
1333 bm->bm = NULL;
1334 bm->bpr = 0;
1337 /****************************************************************************************/
1339 static inline BOOL is_valid_mode(struct mode_bm *bm, ULONG syncidx, ULONG pfidx)
1341 if (0 != (XCOORD_TO_MASK(pfidx) & bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)]))
1342 return TRUE;
1344 return FALSE;
1347 /****************************************************************************************/
1349 static inline VOID set_valid_mode(struct mode_bm *bm, ULONG syncidx, ULONG pfidx,
1350 BOOL valid)
1352 if (valid)
1353 bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)] |= XCOORD_TO_MASK(pfidx);
1354 else
1355 bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)] &= ~XCOORD_TO_MASK(pfidx);
1357 return;
1360 /****************************************************************************************/
1362 static BOOL alloc_mode_db(struct mode_db *mdb, ULONG numsyncs, ULONG numpfs, OOP_Class *cl)
1364 BOOL ok = FALSE;
1366 if (0 == numsyncs || 0 == numpfs)
1367 return FALSE;
1369 ObtainSemaphore(&mdb->sema);
1370 /* free_mode_bm() needs this */
1371 mdb->num_pixfmts = numpfs;
1372 mdb->num_syncs = numsyncs;
1374 mdb->syncs = AllocMem(sizeof (OOP_Object *) * numsyncs, MEMF_CLEAR);
1376 if (NULL != mdb->syncs)
1378 mdb->pixfmts = AllocMem(sizeof (OOP_Object *) * numpfs, MEMF_CLEAR);
1380 if (NULL != mdb->pixfmts)
1382 if (alloc_mode_bm(&mdb->orig_mode_bm, numsyncs, numpfs, cl))
1384 if (alloc_mode_bm(&mdb->checked_mode_bm, numsyncs, numpfs, cl))
1386 ok = TRUE;
1392 if (!ok)
1393 free_mode_db(mdb, cl);
1395 ReleaseSemaphore(&mdb->sema);
1397 return ok;
1400 /****************************************************************************************/
1402 static VOID free_mode_db(struct mode_db *mdb, OOP_Class *cl)
1404 ULONG i;
1406 ObtainSemaphore(&mdb->sema);
1408 if (NULL != mdb->pixfmts)
1411 /* Pixelformats are shared objects and never freed */
1412 FreeMem(mdb->pixfmts, sizeof (OOP_Object *) * mdb->num_pixfmts);
1413 mdb->pixfmts = NULL; mdb->num_pixfmts = 0;
1416 if (NULL != mdb->syncs)
1418 for (i = 0; i < mdb->num_syncs; i ++)
1420 if (NULL != mdb->syncs[i])
1423 OOP_DisposeObject(mdb->syncs[i]);
1424 mdb->syncs[i] = NULL;
1428 FreeMem(mdb->syncs, sizeof (OOP_Object *) * mdb->num_syncs);
1429 mdb->syncs = NULL; mdb->num_syncs = 0;
1432 if (NULL != mdb->orig_mode_bm.bm)
1434 free_mode_bm(&mdb->orig_mode_bm, cl);
1437 if (NULL != mdb->checked_mode_bm.bm)
1439 free_mode_bm(&mdb->checked_mode_bm, cl);
1442 ReleaseSemaphore(&mdb->sema);
1444 return;
1447 /****************************************************************************************/
1449 /* Initializes default tagarray. in numtags the TAG_MORE is not accounted for,
1450 so the array must be of size NUM_TAGS + 1
1453 /****************************************************************************************/
1455 static VOID init_def_tags(struct TagItem *tags, ULONG numtags)
1457 ULONG i;
1459 for (i = 0; i < numtags; i ++)
1461 tags[i].ti_Tag = TAG_IGNORE;
1462 tags[i].ti_Data = 0UL;
1465 tags[i].ti_Tag = TAG_MORE;
1466 tags[i].ti_Data = 0UL;
1468 return;
1471 /****************************************************************************************/
1473 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
1474 struct TagItem sync_ ## name[]={ \
1475 { aHidd_Sync_PixelClock, clock*1000 }, \
1476 { aHidd_Sync_HDisp, hdisp }, \
1477 { aHidd_Sync_HSyncStart, hstart }, \
1478 { aHidd_Sync_HSyncEnd, hend }, \
1479 { aHidd_Sync_HTotal, htotal }, \
1480 { aHidd_Sync_VDisp, vdisp }, \
1481 { aHidd_Sync_VSyncStart, vstart }, \
1482 { aHidd_Sync_VSyncEnd, vend }, \
1483 { aHidd_Sync_VTotal, vtotal }, \
1484 { aHidd_Sync_Description, (IPTR)descr}, \
1485 { TAG_DONE, 0UL }}
1487 static BOOL register_modes(OOP_Class *cl, OOP_Object *o, struct TagItem *modetags)
1489 struct TagItem *tag, *tstate;
1490 struct HIDDGraphicsData *data;
1492 MAKE_SYNC(640x480_60, 25174,
1493 640, 656, 752, 800,
1494 480, 490, 492, 525,
1495 "Default:640x480");
1497 MAKE_SYNC(800x600_56, 36000, // 36000
1498 800, 824, 896, 1024,
1499 600, 601, 603, 625,
1500 "Default:800x600");
1502 MAKE_SYNC(1024x768_60, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
1503 1024, 1048, 1184, 1344,
1504 768, 771, 777, 806,
1505 "Default:1024x768");
1507 MAKE_SYNC(1152x864_60, 80000,
1508 1152, 1216, 1328, 1456,
1509 864, 870, 875, 916,
1510 "Default:1152x864");
1512 MAKE_SYNC(1280x1024_60, 108880,
1513 1280, 1360, 1496, 1712,
1514 1024, 1025, 1028, 1060,
1515 "Default:1280x1024");
1517 MAKE_SYNC(1600x1200_60, 155982,
1518 1600, 1632, 1792, 2048,
1519 1200, 1210, 1218, 1270,
1520 "Default:1600x1200");
1522 /* "new" 16:10 modes */
1524 MAKE_SYNC(1280x800_60, 83530,
1525 1280, 1344, 1480, 1680,
1526 800, 801, 804, 828,
1527 "Default:1280x800");
1529 MAKE_SYNC(1440x900_60, 106470,
1530 1440, 1520, 1672, 1904,
1531 900, 901, 904, 932,
1532 "Default:1440x900");
1534 MAKE_SYNC(1680x1050_60, 147140,
1535 1680, 1784, 1968, 2256,
1536 1050, 1051, 1054, 1087,
1537 "Default:1680x1050");
1539 MAKE_SYNC(1920x1080_60, 173000,
1540 1920, 2048, 2248, 2576,
1541 1080, 1083, 1088, 1120,
1542 "Default:1920x1080");
1544 MAKE_SYNC(1920x1200_60, 154000,
1545 1920, 1968, 2000, 2080,
1546 1200, 1203, 1209, 1235,
1547 "Default:1920x1200");
1549 struct mode_db *mdb;
1551 HIDDT_PixelFormat pixfmt_data;
1553 struct TagItem def_sync_tags[num_Hidd_Sync_Attrs + 1];
1554 struct TagItem def_pixfmt_tags[num_Hidd_PixFmt_Attrs + 1];
1556 ULONG numpfs = 0,numsyncs = 0;
1557 ULONG pfidx = 0, syncidx = 0;
1559 struct TagItem temporary_tags[] = {
1560 { aHidd_Gfx_SyncTags, (IPTR)sync_640x480_60 },
1561 { aHidd_Gfx_SyncTags, (IPTR)sync_800x600_56 },
1562 { aHidd_Gfx_SyncTags, (IPTR)sync_1024x768_60 },
1563 { aHidd_Gfx_SyncTags, (IPTR)sync_1152x864_60 },
1564 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x1024_60 },
1565 { aHidd_Gfx_SyncTags, (IPTR)sync_1600x1200_60 },
1566 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x800_60 },
1567 { aHidd_Gfx_SyncTags, (IPTR)sync_1440x900_60 },
1568 { aHidd_Gfx_SyncTags, (IPTR)sync_1680x1050_60 },
1569 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1080_60 },
1570 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1200_60 },
1571 { TAG_MORE, 0UL }
1574 data = OOP_INST_DATA(cl, o);
1575 mdb = &data->mdb;
1576 InitSemaphore(&mdb->sema);
1578 memset(&pixfmt_data, 0, sizeof (pixfmt_data));
1580 init_def_tags(def_sync_tags, num_Hidd_Sync_Attrs);
1581 init_def_tags(def_pixfmt_tags, num_Hidd_PixFmt_Attrs);
1583 def_sync_tags[aoHidd_Sync_GfxHidd].ti_Tag = aHidd_Sync_GfxHidd;
1584 def_sync_tags[aoHidd_Sync_GfxHidd].ti_Data = (IPTR)o;
1586 /* First we need to calculate how much memory we are to allocate by counting supplied
1587 pixel formats and syncs */
1589 for (tstate = modetags; (tag = NextTagItem((const struct TagItem **)&tstate));)
1591 ULONG idx;
1593 if (IS_GFX_ATTR(tag->ti_Tag, idx))
1595 switch (idx)
1597 case aoHidd_Gfx_PixFmtTags:
1598 numpfs++;
1599 break;
1601 case aoHidd_Gfx_SyncTags:
1602 numsyncs ++;
1603 break;
1605 default:
1606 break;
1611 if (0 == numpfs)
1613 D(bug("!!! WE MUST AT LEAST HAVE ONE PIXFMT IN Gfx::RegisterModes() !!!\n"));
1616 if (0 == numsyncs)
1618 D(bug("!!! NO SYNC IN Gfx::RegisterModes() !!!\n!!! USING DEFAULT MODES !!!\n"));
1619 temporary_tags[11].ti_Tag = TAG_MORE;
1620 temporary_tags[11].ti_Data = (IPTR)modetags;
1621 modetags = &temporary_tags[0];
1622 numsyncs = 11;
1625 ObtainSemaphore(&mdb->sema);
1627 /* Allocate memory for mode db */
1628 if (!alloc_mode_db(&data->mdb, numsyncs, numpfs, cl))
1629 goto failure;
1632 for (tstate = modetags; (tag = NextTagItem((const struct TagItem **)&tstate));)
1634 /* Look for Gfx, PixFmt and Sync tags */
1635 ULONG idx;
1637 if (IS_GFX_ATTR(tag->ti_Tag, idx))
1639 switch (idx)
1641 case aoHidd_Gfx_PixFmtTags:
1642 def_pixfmt_tags[num_Hidd_PixFmt_Attrs].ti_Data = tag->ti_Data;
1643 mdb->pixfmts[pfidx] = HIDD_Gfx_RegisterPixFmt(o, def_pixfmt_tags);
1645 if (NULL == mdb->pixfmts[pfidx])
1647 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
1648 goto failure;
1651 pfidx ++;
1652 break;
1654 case aoHidd_Gfx_SyncTags:
1655 def_sync_tags[num_Hidd_Sync_Attrs].ti_Data = tag->ti_Data;
1657 mdb->syncs[syncidx] = OOP_NewObject(CSD(cl)->syncclass, NULL, def_sync_tags);
1658 if (!mdb->syncs[syncidx]) {
1659 D(bug("!!! UNABLE TO CREATE SYNC OBJECT IN Gfx::RegisterModes() !!!\n"));
1660 goto failure;
1663 syncidx ++;
1664 break;
1668 else if (IS_SYNC_ATTR(tag->ti_Tag, idx))
1670 if (idx >= num_Hidd_Sync_Attrs)
1672 D(bug("!!! UNKNOWN SYNC ATTR IN Gfx::New(): %d !!!\n", idx));
1674 else
1676 def_sync_tags[idx].ti_Tag = tag->ti_Tag;
1677 def_sync_tags[idx].ti_Data = tag->ti_Data;
1681 else if (IS_PIXFMT_ATTR(tag->ti_Tag, idx))
1683 if (idx >= num_Hidd_PixFmt_Attrs)
1685 D(bug("!!! UNKNOWN PIXFMT ATTR IN Gfx::New(): %d !!!\n", idx));
1687 else
1689 def_pixfmt_tags[idx].ti_Tag = tag->ti_Tag;
1690 def_pixfmt_tags[idx].ti_Data = tag->ti_Data;
1695 ReleaseSemaphore(&mdb->sema);
1697 return TRUE;
1699 failure:
1701 /* mode db is freed in dispose */
1702 ReleaseSemaphore(&mdb->sema);
1704 return FALSE;
1707 /****************************************************************************************/
1709 struct modequery
1711 struct mode_db *mdb;
1712 ULONG minwidth;
1713 ULONG maxwidth;
1714 ULONG minheight;
1715 ULONG maxheight;
1716 HIDDT_StdPixFmt *stdpfs;
1717 ULONG numfound;
1718 ULONG pfidx;
1719 ULONG syncidx;
1720 BOOL dims_ok;
1721 BOOL stdpfs_ok;
1722 BOOL check_ok;
1723 OOP_Class *cl;
1726 /****************************************************************************************/
1728 /* This is a recursive function that looks for valid modes */
1730 /****************************************************************************************/
1732 static HIDDT_ModeID *querymode(struct modequery *mq)
1734 HIDDT_ModeID *modeids;
1735 register OOP_Object *pf;
1736 register OOP_Object *sync;
1737 BOOL mode_ok = FALSE;
1738 ULONG syncidx, pfidx;
1740 mq->dims_ok = FALSE;
1741 mq->stdpfs_ok = FALSE;
1742 mq->check_ok = FALSE;
1744 /* Look at the supplied idx */
1745 if (mq->pfidx >= mq->mdb->num_pixfmts)
1747 mq->pfidx = 0;
1748 mq->syncidx ++;
1751 if (mq->syncidx >= mq->mdb->num_syncs)
1753 /* We have reached the end of the recursion. Allocate memory and go back
1756 modeids = AllocVec(sizeof (HIDDT_ModeID) * (mq->numfound + 1), MEMF_ANY);
1757 /* Get the end of the array */
1758 modeids += mq->numfound;
1759 *modeids = vHidd_ModeID_Invalid;
1761 return modeids;
1764 syncidx = mq->syncidx;
1765 pfidx = mq->pfidx;
1766 /* Get the pf and sync objects */
1767 pf = mq->mdb->pixfmts[syncidx];
1768 sync = mq->mdb->syncs[pfidx];
1771 /* Check that the mode is really usable */
1772 if (is_valid_mode(&mq->mdb->checked_mode_bm, syncidx, pfidx))
1774 mq->check_ok = TRUE;
1777 /* See if this mode matches the criterias set */
1779 if ( SD(sync)->hdisp >= mq->minwidth
1780 && SD(sync)->hdisp <= mq->maxwidth
1781 && SD(sync)->vdisp >= mq->minheight
1782 && SD(sync)->vdisp <= mq->maxheight )
1786 mq->dims_ok = TRUE;
1788 if (NULL != mq->stdpfs)
1790 register HIDDT_StdPixFmt *stdpf = mq->stdpfs;
1791 while (*stdpf)
1793 if (*stdpf == PF(pf)->stdpixfmt)
1795 mq->stdpfs_ok = TRUE;
1797 stdpf ++;
1800 else
1802 mq->stdpfs_ok = TRUE;
1808 if (mq->dims_ok && mq->stdpfs_ok && mq->check_ok)
1810 mode_ok = TRUE;
1811 mq->numfound ++;
1814 mq->pfidx ++;
1816 modeids = querymode(mq);
1818 if (NULL == modeids)
1819 return NULL;
1821 if (mode_ok)
1823 /* The mode is OK. Add it to the list */
1824 modeids --;
1825 *modeids = COMPUTE_HIDD_MODEID(syncidx, pfidx);
1828 return modeids;
1832 /*****************************************************************************************
1834 NAME
1835 moHidd_Gfx_QueryModeIDs
1837 SYNOPSIS
1838 HIDDT_ModeID *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryModeIDs *msg);
1840 HIDDT_ModeID *HIDD_Gfx_QueryModeIDs(OOP_Object *gfxHidd, struct TagItem *queryTags);
1842 LOCATION
1843 hidd.graphics.graphics
1845 FUNCTION
1846 Obtain a table of all supported display mode IDs
1848 The returned address points to an array of HIDDT_ModeID containing all ModeIDs
1849 supported by this driver. The array is terminated with vHidd_ModeID_Invalid.
1851 INPUTS
1852 gfxHidd - A driver object which to query.
1853 querytags - An optional taglist containing query options. Can be NULL.
1854 The following tags are supported:
1856 tHidd_GfxMode_MinWidth (ULONG) - A minimum width of modes you are
1857 interested in
1858 tHidd_GfxMode_MaxWidth (ULONG) - A maximum width of modes you are
1859 interested in
1860 tHidd_GfxMode_MinHeight (ULONG) - A minimum height of modes you are
1861 interested in
1862 tHidd_GfxMode_MaxHeight (ULONG) - A maximum height of modes you are
1863 interested in
1864 tHidd_GfxMode_PixFmts (HIDDT_StdPifXmt *) - A pointer to an array
1865 of standard pixelformat indexes. If supplied, only mode IDs whose
1866 pixelformat numbers match any of given ones will be returned.
1868 RESULT
1869 A pointer to an array of ModeIDs or NULL in case of failure
1871 NOTES
1873 EXAMPLE
1875 BUGS
1877 SEE ALSO
1878 moHidd_Gfx_ReleaseModeIDs, moHidd_Gfx_NextModeID
1880 INTERNALS
1882 *****************************************************************************************/
1884 HIDDT_ModeID *GFX__Hidd_Gfx__QueryModeIDs(OOP_Class *cl, OOP_Object *o,
1885 struct pHidd_Gfx_QueryModeIDs *msg)
1887 struct TagItem *tag, *tstate;
1889 HIDDT_ModeID *modeids;
1890 struct HIDDGraphicsData *data;
1891 struct mode_db *mdb;
1893 struct modequery mq =
1895 NULL, /* mode db (set later) */
1896 0, 0xFFFFFFFF, /* minwidth, maxwidth */
1897 0, 0xFFFFFFFF, /* minheight, maxheight */
1898 NULL, /* stdpfs */
1899 0, /* numfound */
1900 0, 0, /* pfidx, syncidx */
1901 FALSE, FALSE, /* dims_ok, stdpfs_ok */
1902 FALSE, /* check_ok */
1903 NULL /* class (set later) */
1908 data = OOP_INST_DATA(cl, o);
1909 mdb = &data->mdb;
1910 mq.mdb = mdb;
1911 mq.cl = cl;
1913 for (tstate = msg->queryTags; (tag = NextTagItem((const struct TagItem **)&tstate)); )
1915 switch (tag->ti_Tag)
1917 case tHidd_GfxMode_MinWidth:
1918 mq.minwidth = (ULONG)tag->ti_Tag;
1919 break;
1921 case tHidd_GfxMode_MaxWidth:
1922 mq.maxwidth = (ULONG)tag->ti_Tag;
1923 break;
1925 case tHidd_GfxMode_MinHeight:
1926 mq.minheight = (ULONG)tag->ti_Tag;
1927 break;
1929 case tHidd_GfxMode_MaxHeight:
1930 mq.maxheight = (ULONG)tag->ti_Tag;
1931 break;
1933 case tHidd_GfxMode_PixFmts:
1934 mq.stdpfs = (HIDDT_StdPixFmt *)tag->ti_Data;
1935 break;
1940 ObtainSemaphoreShared(&mdb->sema);
1942 /* Recursively check all modes */
1943 modeids = querymode(&mq);
1945 ReleaseSemaphore(&mdb->sema);
1947 return modeids;
1951 /*****************************************************************************************
1953 NAME
1954 moHidd_Gfx_ReleaseModeIDs
1956 SYNOPSIS
1957 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ReleaseModeIDs *msg);
1959 VOID HIDD_Gfx_ReleaseModeIDs(OOP_Object *gfxHidd, HIDDT_ModeID *modeIDs);
1961 LOCATION
1962 hidd.graphics.graphics
1964 FUNCTION
1965 Free array of display mode IDs returned by HIDD_Gfx_QueryModeIDs()
1967 INPUTS
1968 gfxHidd - A driver object used to obtain the array
1969 modeIDs - A pointer to an array
1971 RESULT
1972 None.
1974 NOTES
1976 EXAMPLE
1978 BUGS
1980 SEE ALSO
1981 moHidd_Gfx_QueryModeIDs
1983 INTERNALS
1985 *****************************************************************************************/
1987 VOID GFX__Hidd_Gfx__ReleaseModeIDs(OOP_Class *cl, OOP_Object *o,
1988 struct pHidd_Gfx_ReleaseModeIDs *msg)
1990 FreeVec(msg->modeIDs);
1993 /*****************************************************************************************
1995 NAME
1996 moHidd_Gfx_NextModeID
1998 SYNOPSIS
1999 HIDDT_ModeID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NextModeID *msg);
2001 HIDDT_ModeID HIDD_Gfx_NextModeID(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2002 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2004 LOCATION
2005 hidd.graphics.graphics
2007 FUNCTION
2008 Iterate driver's internal display mode database.
2010 INPUTS
2011 gfxHidd - A driver object to query
2012 modeID - A previous mode ID or vHidd_ModeID_Invalid for start of the iteration
2013 syncPtr - A pointer to a storage where pointer to sync object will be placed
2014 pixFmtPtr - A pointer to a storage where pointer to pixelformat object will be placed
2016 RESULT
2017 Next available mode ID or vHidd_ModeID_Invalid if there are no more display modes.
2018 If the function returns vHidd_ModeID_Invalid, sync and pixelformat pointers will
2019 be set to NULL.
2021 NOTES
2023 EXAMPLE
2025 BUGS
2027 SEE ALSO
2028 moHidd_Gfx_GetMode
2030 INTERNALS
2032 *****************************************************************************************/
2034 HIDDT_ModeID GFX__Hidd_Gfx__NextModeID(OOP_Class *cl, OOP_Object *o,
2035 struct pHidd_Gfx_NextModeID *msg)
2037 struct HIDDGraphicsData *data;
2038 struct mode_db *mdb;
2039 ULONG syncidx, pfidx;
2040 HIDDT_ModeID return_id = vHidd_ModeID_Invalid;
2041 BOOL found = FALSE;
2043 data = OOP_INST_DATA(cl, o);
2044 mdb = &data->mdb;
2046 ObtainSemaphoreShared(&mdb->sema);
2047 if (vHidd_ModeID_Invalid == msg->modeID)
2049 pfidx = 0;
2050 syncidx = 0;
2052 else
2054 pfidx = MODEID_TO_PFIDX( msg->modeID );
2055 syncidx = MODEID_TO_SYNCIDX( msg->modeID );
2057 /* Increament one from the last call */
2058 pfidx ++;
2059 if (pfidx >= mdb->num_pixfmts)
2061 pfidx = 0;
2062 syncidx ++;
2066 /* Search for a new mode. We only accept valid modes */
2067 for (; syncidx < mdb->num_syncs; syncidx ++)
2069 /* We only return valid modes */
2070 for (; pfidx < mdb->num_pixfmts; pfidx ++)
2072 if (is_valid_mode(&mdb->checked_mode_bm, syncidx, pfidx))
2074 found = TRUE;
2075 break;
2078 if (found)
2079 break;
2082 if (found)
2084 return_id = COMPUTE_HIDD_MODEID(syncidx, pfidx);
2085 *msg->syncPtr = mdb->syncs[syncidx];
2086 *msg->pixFmtPtr = mdb->pixfmts[pfidx];
2088 else
2090 *msg->syncPtr = *msg->pixFmtPtr = NULL;
2093 ReleaseSemaphore(&mdb->sema);
2095 return return_id;
2098 /*****************************************************************************************
2100 NAME
2101 moHidd_Gfx_GetMode
2103 SYNOPSIS
2104 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMode *msg);
2106 BOOL HIDD_Gfx_GetMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2107 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2109 LOCATION
2110 hidd.graphics.graphics
2112 FUNCTION
2113 Get sync and pixelformat objects for a particular display ModeID.
2115 INPUTS
2116 gfxHidd - pointer to a driver object which this ModeID belongs to
2117 syncPtr - pointer to a storage where sync object pointer will be placed
2118 pixFmtPtr - pointer to a storage where pixelformat object pointer will be placed
2120 RESULT
2121 TRUE upon success, FALSE in case of failure (e.g. given mode does not exist in
2122 driver's internal database). If the function returns FALSE, sync and pixelformat
2123 pointers will be set to NULL.
2125 NOTES
2126 Every display mode is associated with some sync and pixelformat object. If the
2127 method returns TRUE, object pointers are guaranteed to be valid.
2129 EXAMPLE
2131 BUGS
2133 SEE ALSO
2134 moHidd_Gfx_NextModeID
2136 INTERNALS
2138 *****************************************************************************************/
2140 BOOL GFX__Hidd_Gfx__GetMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetMode *msg)
2142 ULONG pfidx, syncidx;
2143 struct HIDDGraphicsData *data;
2144 struct mode_db *mdb;
2145 BOOL ok = FALSE;
2147 data = OOP_INST_DATA(cl, o);
2148 mdb = &data->mdb;
2150 pfidx = MODEID_TO_PFIDX(msg->modeID);
2151 syncidx = MODEID_TO_SYNCIDX(msg->modeID);
2153 ObtainSemaphoreShared(&mdb->sema);
2155 if (! (pfidx >= mdb->num_pixfmts || syncidx >= mdb->num_syncs) )
2157 if (is_valid_mode(&mdb->checked_mode_bm, syncidx, pfidx))
2159 ok = TRUE;
2160 *msg->syncPtr = mdb->syncs[syncidx];
2161 *msg->pixFmtPtr = mdb->pixfmts[pfidx];
2165 ReleaseSemaphore(&mdb->sema);
2167 if (!ok)
2169 *msg->syncPtr = *msg->pixFmtPtr = NULL;
2172 return ok;
2175 /*****************************************************************************************
2177 NAME
2178 moHidd_Gfx_SetMode
2180 SYNOPSIS
2181 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetMode *msg);
2183 BOOL HIDD_Gfx_SetMode(OOP_Object *gfxHidd, OOP_Object *sync);
2185 LOCATION
2186 hidd.graphics.graphics
2188 FUNCTION
2189 Update display mode according to changed sync object
2191 INPUTS
2192 gfxHidd - A display driver to operate on
2193 sync - A modified sync object pointer
2195 RESULT
2196 TRUE if everything went OK and FALSE in case of some error
2198 NOTES
2199 This method is used to inform the driver that some external program has changed
2200 sync data and wants to update the display if needed. It's up to the implementation to
2201 check that current display is really using this sync (frontmost screen uses this mode).
2203 EXAMPLE
2205 BUGS
2207 SEE ALSO
2209 INTERNALS
2210 Base class implementation just returns FALSE indicating that this method is
2211 not supported.
2213 *****************************************************************************************/
2215 BOOL GFX__Hidd_Gfx__SetMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetMode *msg)
2217 return FALSE;
2220 /****************************************************************************************/
2222 static VOID copy_bm_and_colmap(OOP_Class *cl, OOP_Object *o, OOP_Object *src_bm,
2223 OOP_Object *dst_bm, ULONG width, ULONG height)
2225 struct HIDDGraphicsData *data;
2226 ULONG i;
2227 IPTR numentries;
2228 OOP_Object *src_colmap;
2229 APTR psrc_colmap = &src_colmap;
2231 data = OOP_INST_DATA(cl, o);
2233 /* We have to copy the colormap into the framebuffer bitmap */
2234 OOP_GetAttr(src_bm, aHidd_BitMap_ColorMap, (IPTR *)psrc_colmap);
2235 OOP_GetAttr(src_colmap, aHidd_ColorMap_NumEntries, &numentries);
2237 for (i = 0; i < numentries; i ++)
2239 HIDDT_Color col;
2241 HIDD_CM_GetColor(src_colmap, i, &col);
2242 HIDD_BM_SetColors(dst_bm, &col, i, 1);
2245 HIDD_Gfx_CopyBox(o
2246 , src_bm
2247 , 0, 0
2248 , dst_bm
2249 , 0, 0
2250 , width, height
2251 , data->gc
2255 /*****************************************************************************************
2257 NAME
2258 moHidd_Gfx_Show
2260 SYNOPSIS
2261 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Show *msg);
2263 OOP_Object *HIDD_Gfx_Show(OOP_Object *gfxHidd, OOP_Object *bitMap, ULONG flags);
2265 LOCATION
2266 hidd.graphics.graphics
2268 FUNCTION
2269 Change currently displayed bitmap on the screen.
2271 The bitmap object supplied must have been created with aHidd_BitMap_Displayable
2272 attribute set to TRUE.
2274 The function's behavior differs a lot depending on whether the driver uses a
2275 framebuffer or video hardware is able to switch screens itself.
2277 If the driver uses framebuffer bitmap, it is supposed to copy the supplied bitmap
2278 into the framebuffer and return a framebuffer pointer. It also can be asked to
2279 copy back old framebuffer contents into previous bitmap object. It is driver's
2280 job to keep track of which bitmap object was displayed last time. This is what
2281 default implementation does. Note that it is very basic, and even does not support
2282 changing display resolution. It's not recommended to rely on it in production
2283 drivers (unless your video hardware supports only one mode).
2285 If the driver does not use a framebuffer, it is supposed to reprogram the hardware
2286 here to display an appropriate region of video RAM. Do not call the base class
2287 in this case, its implementation relies on framebuffer existance and will always
2288 return NULL which indicates an error.
2290 It is valid to get NULL value in bitMap parameter. This means that there is
2291 nothing to display and the screen needs to be blanked out. It is valid for
2292 non-framebuffer-based driver to return NULL as a reply then. In all other cases
2293 NULL return value means an error.
2295 Please avoid returning errors at all. graphics.library/LoadView() has no error
2296 indication. An error during showing a bitmap would leave the display in
2297 unpredictable state.
2299 If the driver does not use a framebuffer, consider using HIDD_Gfx_ShowViewPorts().
2300 It's more straightforward, flexible and offers support for screen composition.
2302 INPUTS
2303 gfxHidd - a display driver object, whose display you wish to change.
2304 bitMap - a pointer to a bitmap object which needs to be shown or NULL.
2305 flags - currently only one flag is defined:
2307 fHidd_Gfx_Show_CopyBack - Copy back the image data from framebuffer bitmap
2308 to old displayed bitmap. Used only if the driver
2309 needs a framebuffer.
2311 RESULT
2312 A pointer to a currently displayed bitmap object or NULL (read FUNCTION paragraph for
2313 detailed description)
2315 NOTES
2316 Drivers which use mirrored video data buffer do not have to update the display
2317 immediately in this method. moHidd_BitMap_UpdateRect will be sent to the returned
2318 bitmap if it's not NULL. Of course display blanking (if NULL bitmap was received)
2319 needs to be performed immediately.
2321 EXAMPLE
2323 BUGS
2325 SEE ALSO
2326 moHidd_Gfx_ShowViewPorts, graphics.library/LoadView()
2328 INTERNALS
2330 *****************************************************************************************/
2332 OOP_Object *GFX__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Show *msg)
2334 struct HIDDGraphicsData *data;
2335 OOP_Object *bm;
2336 IPTR displayable;
2337 IPTR oldwidth = 0;
2338 IPTR oldheight = 0;
2339 IPTR newwidth = 0;
2340 IPTR newheight = 0;
2341 struct TagItem gctags[] =
2343 { aHidd_GC_DrawMode , vHidd_GC_DrawMode_Copy},
2344 { aHidd_GC_Foreground, 0 },
2345 { TAG_DONE , 0UL }
2348 data = OOP_INST_DATA(cl, o);
2349 bm = msg->bitMap;
2351 /* We have to do some consistency checking */
2352 if (bm)
2354 OOP_GetAttr(bm, aHidd_BitMap_Displayable, &displayable);
2357 if (bm && !displayable)
2358 /* We cannot show a non-displayable bitmap */
2359 return NULL;
2361 if (NULL == data->framebuffer)
2362 return NULL;
2364 OOP_SetAttrs(data->gc, gctags);
2365 if (NULL != data->shownbm)
2367 OOP_GetAttr(data->shownbm, aHidd_BitMap_Width, &oldwidth);
2368 OOP_GetAttr(data->shownbm, aHidd_BitMap_Height, &oldheight);
2369 /* Copy the framebuffer data back into the old shown bitmap */
2370 if (msg->flags & fHidd_Gfx_Show_CopyBack)
2371 copy_bm_and_colmap(cl, o, data->framebuffer, data->shownbm, oldwidth, oldheight);
2374 if (bm) {
2375 OOP_GetAttr(bm, aHidd_BitMap_Width, &newwidth);
2376 OOP_GetAttr(bm, aHidd_BitMap_Height, &newheight);
2377 copy_bm_and_colmap(cl, o, bm, data->framebuffer, newwidth, newheight);
2379 /* Clear remaining parts of the framebuffer (if previous bitmap was larger than new one) */
2380 if (oldheight) {
2381 if (newwidth < oldwidth)
2382 HIDD_BM_FillRect(data->framebuffer, data->gc, newwidth, 0, oldwidth - 1, oldheight - 1);
2383 if ((newheight < oldheight) && newwidth)
2384 HIDD_BM_FillRect(data->framebuffer, data->gc, 0, newheight, newwidth - 1, oldheight);
2387 data->shownbm = bm;
2389 return data->framebuffer;
2392 /*****************************************************************************************
2394 NAME
2395 moHidd_Gfx_ShowViewPorts
2397 SYNOPSIS
2398 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ShowViewPorts *msg);
2400 ULONG HIDD_Gfx_ShowViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data);
2402 LOCATION
2403 hidd.graphics.graphics
2405 FUNCTION
2406 Show one or more bitmaps on the screen.
2408 It is completely up to the driver how to implement this function. The driver may
2409 or may not support hardware-assisted screens composition. Bitmaps are sorted
2410 in the list in descending z-order. The driver is expected to put at least frontmost
2411 bitmap on display.
2413 It is valid to get NULL pointer as data parameter. This means that there's
2414 nothing to show and the screen should go blank.
2416 Bitmaps display offsets are stored in their aHidd_BitMap_LeftEdge and
2417 aHidd_BitMap_TopEdge attributes. This function is not expected to modify their
2418 values somehow. They are assumed to be preserved between calls unless changed
2419 explicitly by the system.
2421 If you implement this method, you don't have to implement HIDD_Gfx_Show() because
2422 it will never be called.
2424 Note that there is no more error indication - the driver is expected to be
2425 error-free here.
2427 INPUTS
2428 gfxHidd - a display driver object, whose display you wish to change.
2429 data - a singly linked list of bitmap objects to show
2431 RESULT
2432 TRUE if this method is supported by the driver, FALSE otherwise
2434 NOTES
2436 EXAMPLE
2438 BUGS
2440 SEE ALSO
2441 moHidd_Gfx_Show
2443 INTERNALS
2444 Default base class implementation simply returns FALSE. This causes
2445 the system to use HIDD_Gfx_Show() instead.
2447 *****************************************************************************************/
2449 ULONG GFX__Hidd_Gfx__ShowViewPorts(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ShowViewPorts *msg)
2451 /* By default we don't support screen composition (and this method too) */
2452 return FALSE;
2455 /*****************************************************************************************
2457 NAME
2458 moHidd_Gfx_SetCursorShape
2460 SYNOPSIS
2461 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorShape *msg);
2463 BOOL HIDD_Gfx_SetCursorShape(OOP_Object *gfxHidd, OOP_Object *shape,
2464 LONG xoffset, LONG yoffset);
2466 LOCATION
2467 hidd.graphics.graphics
2469 FUNCTION
2470 Set mouse pointer shape.
2472 A pointer image is contained in the specified bitmap object. The bitmap object
2473 may contain a colormap if the system wants to specify own colors for the pointer.
2474 The supplied colormap will also contain alpha channel values.
2476 It is up to driver what to do if, for example, alpha channel is not supported by
2477 the hardware. Or if given bitmap type is not supported (for example truecolor
2478 bitmap on LUT-only hardware). It is expected that the driver converts bitmap
2479 data to a more appropriate form in such a case.
2481 A hotspot is given as an offset from the actual hotspot to the top-left corner
2482 of the pointer image. It is generally needed only for hosted display drivers
2483 which utilize host's support for mouse pointer.
2485 The default implementation in the base class just does nothing. A software mouse
2486 pointer is implemented in a special layer calles fakegfx.hidd inside
2487 graphics.library. If a software pointer emulation is used, this method will
2488 never be called.
2490 INPUTS
2491 gfxHidd - a display driver object, for whose display you wish to change the pointer
2492 shape - a pointer to a bitmap object, containing pointer bitmap
2493 xoffset - a horizontal hotspot offset
2494 yoffset - a vertical hotspot offset
2496 RESULT
2497 TRUE on success, FALSE on failure
2499 NOTES
2501 EXAMPLE
2503 BUGS
2505 SEE ALSO
2506 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2508 INTERNALS
2510 *****************************************************************************************/
2512 BOOL GFX__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o,
2513 struct pHidd_Gfx_SetCursorShape *msg)
2515 /* We have no clue how to render the cursor */
2516 return TRUE;
2519 /*****************************************************************************************
2521 NAME
2522 moHidd_Gfx_SetCursorVisible
2524 SYNOPSIS
2525 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorVisible *msg);
2527 VOID HIDD_Gfx_SetCursorVisible(OOP_Object *gfxHidd, BOOL visible);
2529 LOCATION
2530 hidd.graphics.graphics
2532 FUNCTION
2533 Control mouse pointer visiblity.
2535 The default implementation in the base class does nothing. If a software pointer
2536 emulation is used, this method will never be called.
2538 INPUTS
2539 gfxHidd - a display driver object, on whose display you wish to turn pointer or on off
2540 visible - TRUE to enable pointer display, FALSE to disable it
2542 RESULT
2543 None.
2545 NOTES
2547 EXAMPLE
2549 BUGS
2551 SEE ALSO
2552 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2554 INTERNALS
2556 *****************************************************************************************/
2558 VOID GFX__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorVisible *msg)
2563 /*****************************************************************************************
2565 NAME
2566 moHidd_Gfx_SetCursorPos
2568 SYNOPSIS
2569 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorPos *msg);
2571 BOOL HIDD_Gfx_SetCursorPos(OOP_Object *gfxHidd, LONG x, LONG y);
2573 LOCATION
2574 hidd.graphics.graphics
2576 FUNCTION
2577 Set current mouse pointer position.
2579 This is a real position on top-left image corner relative to top-left corner of
2580 the physical display. Neither logical screen origin nor hotspot are taken into
2581 account here.
2583 The default implementation in the base class does nothing and just returns TRUE.
2584 If a software pointer emulation is used, this method will never be called.
2586 INPUTS
2587 gfxHidd - a display driver object, on whose display you wish to position the pointer
2588 x - An x coordinate of the pointer (relative to the physical screen origin)
2589 y - An y coordinate of the pointer (relative to the physical screen origin)
2591 RESULT
2592 Always TRUE. Reserved for future, do not use it.
2594 NOTES
2595 This method is called by graphics.library/MoveSprite() which has no return value.
2596 However, for historical reasons, this method has a return value. Drivers should
2597 always return TRUE in order to ensure future compatibility.
2599 EXAMPLE
2601 BUGS
2603 SEE ALSO
2604 moHidd_Gfx_SetCursorShape, moHidd_Gfx_SetCursorVisible, graphics.library/MoveSprite()
2606 INTERNALS
2608 *****************************************************************************************/
2610 BOOL GFX__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorPos *msg)
2612 return TRUE;
2615 /*****************************************************************************************
2617 NAME
2618 moHidd_Gfx_CopyBox
2620 SYNOPSIS
2621 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg);
2623 VOID HIDD_Gfx_CopyBox(OOP_Object *gfxHidd, OOP_Object *src, WORD srcX, WORD srcY,
2624 OOP_Object *dest, WORD destX, WORD destY, UWORD width, UWORD height,
2625 OOP_Object *gc);
2627 LOCATION
2628 hidd.graphics.graphics
2630 FUNCTION
2631 Perform rectangle copy (blit) operation from one bitmap to another.
2633 Given bitmaps may belong to different display drivers. The driver may attempt to
2634 use hardware for acceleration (if availible), and if it's impossible, pass the
2635 operation on to the base class.
2637 Always check class of the supplied bitmap before attempting to look at its
2638 private data.
2640 A GC is used in order to specify raster operation performed between the source
2641 and destination according to its aHidd_GC_DrawMode attribute value.
2643 INPUTS
2644 gfxHidd - a display driver object that you are going to use for copying
2645 src - a pointer to source bitmap object
2646 srcX - an X coordinate of the source rectangle
2647 srcY - an Y coordinate of the source rectangle
2648 dest - a pointer to destination bitmap object
2649 destX - an X coordinate of the destination rectangle
2650 destY - an Y coordinate of the destination rectangle
2651 width - width of the rectangle to copy
2652 height - height of the rectangle to copy
2653 gc - graphics context holding draw mode on the destination
2655 RESULT
2656 None.
2658 NOTES
2659 You must specify valid coordinates (non-negative and inside the actual bitmap
2660 area), no checks are done.
2662 It is valid to specify two overlapped areas of the same bitmap as source
2663 and destination.
2665 EXAMPLE
2667 BUGS
2669 SEE ALSO
2671 INTERNALS
2673 *****************************************************************************************/
2675 VOID GFX__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg)
2677 WORD x, y;
2678 WORD srcX = msg->srcX, destX = msg->destX;
2679 WORD srcY = msg->srcY, destY = msg->destY;
2680 WORD startX, endX, deltaX, startY, endY, deltaY;
2681 ULONG memFG;
2683 HIDDT_PixelFormat *srcpf, *dstpf;
2684 OOP_Object *dest, *src;
2686 OOP_Object *gc;
2687 #if USE_FAST_GETPIXEL
2688 struct pHidd_BitMap_GetPixel get_p;
2689 #endif
2691 #if USE_FAST_DRAWPIXEL
2692 struct pHidd_BitMap_DrawPixel draw_p;
2694 draw_p.mID = CSD(cl)->drawpixel_mid;
2695 draw_p.gc = msg->gc;
2696 #endif
2698 #if USE_FAST_GETPIXEL
2699 get_p.mID = CSD(cl)->getpixel_mid;
2700 #endif
2702 dest = msg->dest;
2703 src = msg->src;
2705 /* If source/dest overlap, direction of operation is important */
2707 if (srcX < destX)
2709 startX = msg->width - 1; endX = -1; deltaX = -1;
2711 else
2713 startX = 0; endX = msg->width; deltaX = 1;
2716 if (srcY < destY)
2718 startY = msg->height - 1; endY = -1; deltaY = -1;
2720 else
2722 startY = 0; endY = msg->height; deltaY = 1;
2725 /* Get the source pixel format */
2726 srcpf = (HIDDT_PixelFormat *)HBM(src)->prot.pixfmt;
2728 /* bug("COPYBOX: SRC PF: %p, obj=%p, cl=%s, OOP_OCLASS: %s\n", srcpf, obj
2729 , cl->ClassNode.ln_Name, OOP_OCLASS(obj)->ClassNode.ln_Name);
2732 #if 0
2734 IPTR sw, sh, dw, dh;
2735 D(bug("COPYBOX: src=%p, dst=%p, width=%d, height=%d\n"
2736 , obj, msg->dest, msg->width, msg->height));
2738 OOP_GetAttr(obj, aHidd_BitMap_Width, &sw);
2739 OOP_GetAttr(obj, aHidd_BitMap_Height, &sh);
2740 OOP_GetAttr(msg->dest, aHidd_BitMap_Width, &dw);
2741 OOP_GetAttr(msg->dest, aHidd_BitMap_Height, &dh);
2742 D(bug("src dims: %d, %d dest dims: %d, %d\n", sw, sh, dw, dh));
2744 #endif
2746 dstpf = (HIDDT_PixelFormat *)HBM(dest)->prot.pixfmt;
2748 /* Compare graphtypes */
2749 if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf))
2751 /* It is ok to do a direct copy */
2753 else
2755 /* Find out the gfx formats */
2756 if ( IS_PALETTIZED(srcpf) && IS_TRUECOLOR(dstpf))
2760 else if (IS_TRUECOLOR(srcpf) && IS_PALETTIZED(dstpf))
2764 else if (IS_PALETTE(srcpf) && IS_STATICPALETTE(dstpf))
2768 else if (IS_STATICPALETTE(srcpf) && IS_PALETTE(dstpf))
2774 gc = msg->gc;
2776 memFG = GC_FG(msg->gc);
2778 /* All else have failed, copy pixel by pixel */
2781 if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf))
2783 if (IS_TRUECOLOR(srcpf))
2785 // bug("COPY FROM TRUECOLOR TO TRUECOLOR\n");
2786 for(y = startY; y != endY; y += deltaY)
2788 HIDDT_Color col;
2790 /* if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2791 bug("[%d,%d] ", memSrcX, memDestX);
2793 for(x = startX; x != endX; x += deltaX)
2795 HIDDT_Pixel pix;
2797 #if USE_FAST_GETPIXEL
2798 get_p.x = srcX + x;
2799 get_p.y = srcY + y;
2800 pix = GETPIXEL(src, &get_p);
2801 #else
2802 pix = HIDD_BM_GetPixel(obj, srcX + x, srcY + y);
2803 #endif
2805 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2806 if (srcpf == dstpf)
2808 GC_FG(gc) = pix;
2810 else
2812 #endif
2813 HIDD_BM_UnmapPixel(src, pix, &col);
2814 GC_FG(gc) = HIDD_BM_MapColor(msg->dest, &col);
2815 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2817 #endif
2819 // #if 0
2821 #if USE_FAST_DRAWPIXEL
2822 draw_p.x = destX + x;
2823 draw_p.y = destY + y;
2824 DRAWPIXEL(dest, &draw_p);
2825 #else
2827 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2828 #endif
2830 // #endif
2832 /*if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2833 bug("[%d,%d] ", srcY, destY);
2837 } /* if (IS_TRUECOLOR(srcpf)) */
2838 else
2840 /* Two palette bitmaps.
2841 For this case we do NOT convert through RGB,
2842 but copy the pixel indexes directly
2844 // bug("COPY FROM PALETTE TO PALETTE\n");
2846 /* FIXME: This might not work very well with two StaticPalette bitmaps */
2848 for(y = startY; y != endY; y += deltaY)
2850 for(x = startX; x != endX; x += deltaX)
2852 GC_FG(gc) = HIDD_BM_GetPixel(src, srcX + x, srcY + y);
2854 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2859 } /* if (IS_TRUECOLOR(srcpf)) else ... */
2861 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) */
2862 else
2864 /* Two unlike bitmaps */
2865 if (IS_TRUECOLOR(srcpf))
2867 /* FIXME: Implement this */
2868 D(bug("!! DEFAULT COPYING FROM TRUECOLOR TO PALETTIZED NOT IMPLEMENTED IN BitMap::CopyBox\n"));
2870 else if (IS_TRUECOLOR(dstpf))
2872 /* Get the colortab */
2873 HIDDT_Color *ctab = ((HIDDT_ColorLUT *)HBM(src)->colmap)->colors;
2875 // bug("COPY FROM PALETTE TO TRUECOLOR, DRAWMODE %d, CTAB %p\n", GC_DRMD(gc), ctab);
2877 for(y = startY; y != endY; y += deltaY)
2879 for(x = startX; x != endX; x += deltaX)
2881 register HIDDT_Pixel pix;
2882 register HIDDT_Color *col;
2884 pix = HIDD_BM_GetPixel(src, srcX + x, srcY + y);
2885 col = &ctab[pix];
2887 GC_FG(gc) = HIDD_BM_MapColor(msg->dest, col);
2888 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2894 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) else ... */
2896 GC_FG(gc) = memFG;
2899 /*****************************************************************************************
2901 NAME
2902 moHidd_Gfx_ShowImminentReset
2904 SYNOPSIS
2905 VOID OOP_DoMethod(OOP_Object *obj, OOP_Msg msg);
2907 LOCATION
2908 hidd.graphics.graphics
2910 FUNCTION
2911 Indicate upcoming machine reset. Obsolete.
2913 Since graphics.library v41.4 this method is not used any more. Considered
2914 reserved. Do not use it in any way.
2916 INPUTS
2917 None.
2919 RESULT
2920 None.
2922 NOTES
2924 EXAMPLE
2926 BUGS
2928 SEE ALSO
2930 INTERNALS
2932 *****************************************************************************************/
2934 VOID GFX__Hidd_Gfx__ShowImminentReset(OOP_Class *cl, OOP_Object *obj, OOP_Msg msg)
2938 /****************************************************************************************/
2940 OOP_Object *GFX__Hidd_Gfx__RegisterPixFmt(OOP_Class *cl, OOP_Object *o,
2941 struct pHidd_Gfx_RegisterPixFmt *msg)
2943 HIDDT_PixelFormat cmp_pf;
2944 struct class_static_data *data;
2945 struct pixfmt_data *retpf = NULL;
2947 memset(&cmp_pf, 0, sizeof(cmp_pf));
2949 data = CSD(cl);
2950 if (!parse_pixfmt_tags(msg->pixFmtTags, &cmp_pf, 0, CSD(cl)))
2952 D(bug("!!! FAILED PARSING TAGS IN Gfx::RegisterPixFmt() !!!\n"));
2953 return FALSE;
2956 DPF(bug("Gfx::RegisterPixFmt(): Registering pixelformat:\n"));
2957 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
2958 , PF(&cmp_pf)->red_shift
2959 , PF(&cmp_pf)->green_shift
2960 , PF(&cmp_pf)->blue_shift
2961 , PF(&cmp_pf)->alpha_shift
2962 , PF(&cmp_pf)->red_mask
2963 , PF(&cmp_pf)->green_mask
2964 , PF(&cmp_pf)->blue_mask
2965 , PF(&cmp_pf)->alpha_mask
2966 , PF(&cmp_pf)->bytes_per_pixel
2967 , PF(&cmp_pf)->size
2968 , PF(&cmp_pf)->depth
2969 , PF(&cmp_pf)->stdpixfmt));
2971 retpf = find_pixfmt(&cmp_pf, CSD(cl));
2973 DPF(bug("Found matching pixelformat: 0x%p\n", retpf));
2974 if (retpf)
2975 /* Increase pf refcount */
2976 AROS_ATOMIC_INC(retpf->refcount);
2977 else {
2978 /* Could not find an alike pf, Create a new pfdb node */
2979 /* Since we pass NULL as the taglist below, the PixFmt class will just create a dummy pixfmt */
2980 retpf = OOP_NewObject(CSD(cl)->pixfmtclass, NULL, NULL);
2981 if (retpf) {
2982 /* We have one user */
2983 retpf->refcount = 1;
2985 /* Initialize the pixfmt object the "ugly" way */
2986 memcpy(retpf, &cmp_pf, sizeof (HIDDT_PixelFormat));
2988 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
2989 , PF(&cmp_pf)->red_shift
2990 , PF(&cmp_pf)->green_shift
2991 , PF(&cmp_pf)->blue_shift
2992 , PF(&cmp_pf)->alpha_shift
2993 , PF(&cmp_pf)->red_mask
2994 , PF(&cmp_pf)->green_mask
2995 , PF(&cmp_pf)->blue_mask
2996 , PF(&cmp_pf)->alpha_mask
2997 , PF(&cmp_pf)->bytes_per_pixel
2998 , PF(&cmp_pf)->size
2999 , PF(&cmp_pf)->depth
3000 , PF(&cmp_pf)->stdpixfmt));
3002 ObtainSemaphore(&data->pfsema);
3003 AddTail((struct List *)&data->pflist, (struct Node *)&retpf->node);
3004 ReleaseSemaphore(&data->pfsema);
3008 DPF(bug("New refcount is %u\n", retpf->refcount));
3009 return (OOP_Object *)retpf;
3012 /****************************************************************************************/
3014 VOID GFX__Hidd_Gfx__ReleasePixFmt(OOP_Class *cl, OOP_Object *o,
3015 struct pHidd_Gfx_ReleasePixFmt *msg)
3017 struct class_static_data *data;
3018 struct pixfmt_data *pixfmt = (struct pixfmt_data *)msg->pixFmt;
3020 DPF(bug("release_pixfmt 0x%p\n", pixfmt));
3022 data = CSD(cl);
3024 ObtainSemaphore(&data->pfsema);
3026 /* If refcount is already 0, this object was never registered in the database,
3027 don't touch it */
3028 DPF(bug("Old reference count is %u\n", pixfmt->refcount));
3029 if (pixfmt->refcount) {
3030 if (--pixfmt->refcount == 0) {
3031 Remove((struct Node *)&pixfmt->node);
3032 OOP_DisposeObject((OOP_Object *)pixfmt);
3036 ReleaseSemaphore(&data->pfsema);
3039 /*****************************************************************************************
3041 NAME
3042 moHidd_Gfx_CheckMode
3044 SYNOPSIS
3045 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CheckMode *msg);
3047 BOOL HIDD_Gfx_CheckMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3048 OOP_Object *sync, OOP_Object *pixFmt);
3050 LOCATION
3051 hidd.graphics.graphics
3053 FUNCTION
3054 Check if given display mode is supported by the driver.
3056 Normally any resolution (sync) can be used together with any pixelformat. However
3057 on some hardware there may be exceptions from this rule. In such a case this
3058 method should be implemented, and check should be performed.
3060 The information provided by this method is used in order to exclude unsupported
3061 modes from the database
3063 Default implementation in the base class just returns TRUE for all supplied values.
3065 Note that this method can not be used in order to chech that the given mode is
3066 really present in the database and it really refers to the given sync and
3067 pixelformat objects. Use HIDD_Gfx_GetMode() for mode ID validation.
3069 INPUTS
3070 gfxHidd - A display driver object
3071 modeID - A display mode ID
3072 sync - A pointer to a sync object associated with this mode
3073 pixFmt - A pointer to a pixelformat object associated with this mode
3075 RESULT
3076 TRUE if this mode is supported and FALSE if it's not.
3078 NOTES
3080 EXAMPLE
3082 BUGS
3083 Currently base class does not call this method after driver object creation.
3084 This needs to be fixed.
3086 SEE ALSO
3087 moHidd_Gfx_GetMode
3089 INTERNALS
3091 *****************************************************************************************/
3093 BOOL GFX__Hidd_Gfx__CheckMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CheckMode *msg)
3095 /* As a default we allways return TRUE, ie. the mode is OK */
3096 return TRUE;
3099 /*****************************************************************************************
3101 NAME
3102 moHidd_Gfx_GetPixFmt
3104 SYNOPSIS
3105 OOP_Object *OOP_DoMethod(OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg);
3107 OOP_Object *HIDD_Gfx_GetPixFmt(OOP_Object *gfxHidd, HIDDT_StdPixFmt pixFmt);
3109 LOCATION
3110 hidd.graphics.graphics
3112 FUNCTION
3113 Get a standard pixelformat descriptor from internal pixelformats database.
3115 INPUTS
3116 gfxHidd - A display driver object
3117 pixFmt - An index of pixelformat (one of vHIDD_StdPixFmt_... values)
3119 RESULT
3120 A pointer to a pixelformat object or NULL if lookup failed
3122 NOTES
3123 Pixelformat objects are stored in a global system-wide database. They are not
3124 linked with a particular driver in any way and completely sharable between all
3125 drivers.
3127 EXAMPLE
3129 BUGS
3131 SEE ALSO
3133 INTERNALS
3134 This operation can never fail because all standard pixelformats are registered
3135 during early system initialization.
3137 *****************************************************************************************/
3139 OOP_Object *GFX__Hidd_Gfx__GetPixFmt(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg)
3141 OOP_Object *fmt;
3143 if (!IS_REAL_STDPIXFMT(msg->stdPixFmt))
3145 D(bug("!!! Illegal pixel format passed to Gfx::GetPixFmt(): %d\n", msg->stdPixFmt));
3146 return NULL;
3148 else
3150 fmt = (OOP_Object *)CSD(cl)->std_pixfmts[REAL_STDPIXFMT_IDX(msg->stdPixFmt)];
3153 return fmt;
3156 /*****************************************************************************************
3158 NAME
3159 moHidd_Gfx_GetSync
3161 SYNOPSIS
3162 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetSync *msg);
3164 OOP_Object *HIDD_Gfx_GetSync(OOP_Object *gfxHidd, ULONG num);
3166 LOCATION
3167 hidd.graphics.graphics
3169 FUNCTION
3170 Get a sync object from internal display mode database by index
3172 INPUTS
3173 gfxHidd - A display driver object to query
3174 num - An index of pixelformat starting from 0
3176 RESULT
3177 A pointer to a sync object or NULL if there's no sync with such index
3179 NOTES
3181 EXAMPLE
3183 BUGS
3185 SEE ALSO
3187 INTERNALS
3189 *****************************************************************************************/
3191 OOP_Object *GFX__Hidd_Gfx__GetSync(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetSync *msg)
3193 struct HIDDGraphicsData *data = OOP_INST_DATA(cl, o);
3195 if (msg->num < data->mdb.num_syncs)
3196 return data->mdb.syncs[msg->num];
3197 else {
3198 D(bug("!!! Illegal sync index passed to Gfx::GetSync(): %d\n", msg->num));
3199 return NULL;
3203 /*****************************************************************************************
3205 NAME
3206 moHidd_Gfx_ModeProperties
3208 SYNOPSIS
3209 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ModeProperties *msg);
3211 ULONG HIDD_Gfx_ModeProperties(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3212 struct HIDD_ModeProperties *props, ULONG propsLen);
3214 LOCATION
3215 hidd.graphics.graphics
3217 FUNCTION
3218 Obtain an information about the video mode.
3220 Video mode description structure may grow in future, so be careful and always check
3221 propsLen parameter value. A system may ask you for less data than you can provide.
3222 Always return an actual value. Do not just zero out fields you don't know about,
3223 this is not expected to be backwards compatible.
3225 INPUTS
3226 gfxHidd - a pointer to a display driver object whose display mode you want to query
3227 modeID - a mode ID to query
3228 props - a pointer to a storage area where HIDD_ModeProperties structure will be put
3229 propsLen - A length of the supplied buffer in bytes.
3231 RESULT
3232 An actual length of obtained structure
3234 NOTES
3235 Returned data must reflect only real hardware capabilities. For example, do not
3236 count emulated sprites. The system takes care about emulated features itself.
3238 EXAMPLE
3240 BUGS
3242 SEE ALSO
3243 aoHidd_Gfx_HWSpriteTypes, aoHidd_Gfx_SupportsHWCursor
3245 INTERNALS
3246 Default implementation in the base class relies on aHidd_Gfx_HWSpriteTypes attribute,
3247 not vice versa. If you override this method, do not forget to override this attribute too.
3249 *****************************************************************************************/
3251 ULONG GFX__Hidd_Gfx__ModeProperties(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ModeProperties *msg)
3253 struct HIDD_ModeProperties props = {0, 0, 0};
3254 IPTR has_hw_cursor = 0;
3255 ULONG len = msg->propsLen;
3257 D(bug("[GFXHIDD] Hidd::Gfx::ModeProperties(0x%08lX, 0x%p, %u)\n", msg->modeID, msg->props, msg->propsLen));
3258 OOP_GetAttr(o, aHidd_Gfx_HWSpriteTypes, &has_hw_cursor);
3259 if (has_hw_cursor) {
3260 D(bug("[GFXHIDD] Driver has hardware mouse cursor implementation\n"));
3261 props.DisplayInfoFlags = DIPF_IS_SPRITES;
3262 props.NumHWSprites = 1;
3265 if (len > sizeof(props))
3266 len = sizeof(props);
3267 D(bug("[GFXHIDD] Copying %u bytes\n", len));
3268 CopyMem(&props, msg->props, len);
3270 return len;
3273 /*****************************************************************************************
3275 NAME
3276 moHidd_Gfx_GetGamma
3278 SYNOPSIS
3279 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3281 BOOL HIDD_Gfx_GetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3283 LOCATION
3284 hidd.graphics.graphics
3286 FUNCTION
3287 Get current gamma table for the display.
3289 A gamma table consists of three 256-byte tables: one for red component, one for
3290 green and one for blue.
3292 A user should supply three pointers to preallocated 256-byte tables which will
3293 be filled in. Any ot these pointers may have NULL value, in this case the
3294 respective component will be ignored.
3296 INPUTS
3297 gfxHidd - A display driver object
3298 Red - A pointer to a 256-byte array for red component or NULL
3299 Green - A pointer to a 256-byte array for green component or NULL
3300 Blue - A pointer to a 256-byte array for blue component or NULL
3302 RESULT
3303 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3305 NOTES
3306 This method can be used just to query if the driver supports gamma correction.
3307 Just set Red, Green and Blue to NULL for this.
3309 EXAMPLE
3311 BUGS
3313 SEE ALSO
3314 moHidd_Gfx_SetGamma
3316 INTERNALS
3318 *****************************************************************************************/
3320 BOOL GFX__Hidd_Gfx__GetGamma(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Gamma *msg)
3322 return FALSE;
3325 /*****************************************************************************************
3327 NAME
3328 moHidd_Gfx_SetGamma
3330 SYNOPSIS
3331 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3333 BOOL HIDD_Gfx_SetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3335 LOCATION
3336 hidd.graphics.graphics
3338 FUNCTION
3339 Set current gamma table for the display.
3341 A gamma table consists of three 256-byte tables: one for red component, one for
3342 green and one for blue.
3344 A user should supply three pointers to 256-byte tables from which gamma values
3345 will be picked up. Any ot these pointers may have NULL value, in this case the
3346 respective component will be ignored.
3348 INPUTS
3349 gfxHidd - A display driver object
3350 Red - A pointer to a 256-byte array for red component or NULL
3351 Green - A pointer to a 256-byte array for green component or NULL
3352 Blue - A pointer to a 256-byte array for blue component or NULL
3354 RESULT
3355 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3357 NOTES
3358 This method can be used just to query if the driver supports gamma correction.
3359 Just set Red, Green and Blue to NULL for this.
3361 EXAMPLE
3363 BUGS
3365 SEE ALSO
3366 moHidd_Gfx_GetGamma
3368 INTERNALS
3370 *****************************************************************************************/
3372 BOOL GFX__Hidd_Gfx__SetGamma(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Gamma *msg)
3374 return FALSE;
3377 /*****************************************************************************************
3379 NAME
3380 moHidd_Gfx_QueryHardware3D
3382 SYNOPSIS
3383 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryHardware3D *msg);
3385 BOOL HIDD_Gfx_QueryHardware3D(OOP_Object *gfxHidd, OOP_Object *pixFmt);
3387 LOCATION
3388 hidd.graphics.graphics
3390 FUNCTION
3391 Query if the driver supports hardware-accelerated 3D graphics for the given
3392 pixelformat.
3394 INPUTS
3395 gfxHidd - A display driver object
3396 pixFmt - A pointer to a pixelformat descriptor object
3398 RESULT
3399 TRUE if the driver supports hardware-accelerated 3D for the given pixelformat,
3400 FALSE otherwise.
3402 NOTES
3404 EXAMPLE
3406 BUGS
3408 SEE ALSO
3410 INTERNALS
3412 *****************************************************************************************/
3414 BOOL GFX__Hidd_Gfx__QueryHardware3D(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_QueryHardware3D *msg)
3416 return FALSE;
3419 /*****************************************************************************************
3421 NAME
3422 moHidd_Gfx_GetMaxSpriteSize
3424 SYNOPSIS
3425 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMaxSpriteSize *msg);
3427 BOOL HIDD_Gfx_GetMaxSpriteSize(OOP_Object *gfxHidd, ULONG Type, ULONG *Width, ULONG *Height);
3429 LOCATION
3430 hidd.graphics.graphics
3432 FUNCTION
3433 Query maximum allowed size for the given sprite type.
3435 INPUTS
3436 gfxHidd - A display driver object
3437 Type - Type of the sprite image (one of vHidd_SpriteType_... values)
3438 Width - A pointer to ULONG where width will be placed.
3439 Height - A pointer to ULONG where height will be placed.
3441 RESULT
3442 FALSE is the given sprite type is not supported, otherwise TRUE.
3444 NOTES
3445 Default implementation in the base class just return some small values
3446 which it hopes can be supported by every driver if the driver supports given
3447 sprite type. It is strongly suggested to reimplement this method in the display
3448 driver.
3450 Width and Height are considered undefined if the method returns FALSE.
3452 EXAMPLE
3454 BUGS
3456 SEE ALSO
3458 INTERNALS
3460 *****************************************************************************************/
3462 BOOL GFX__Hidd_Gfx__GetMaxSpriteSize(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetMaxSpriteSize *msg)
3464 IPTR types;
3466 OOP_GetAttr(o, aHidd_Gfx_HWSpriteTypes, &types);
3468 if (types & msg->Type) {
3469 *msg->Width = 16;
3470 *msg->Height = 32;
3471 return TRUE;
3472 } else
3473 return FALSE;
3476 /*****************************************************************************************
3478 NAME
3479 moHidd_Gfx_NewOverlay
3481 SYNOPSIS
3482 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewOverlay *msg);
3484 OOP_Object *HIDD_Gfx_NewOverlay(OOP_Object *gfxHidd, struct TagItem *tagList);
3486 LOCATION
3487 hidd.graphics.graphics
3489 FUNCTION
3490 Create a video overlay object.
3492 INPUTS
3493 gfxHidd - A graphics driver object on whose display you want to create an overlay.
3494 tagList - A list of overlay attributes. See overlay class documentation for
3495 their description.
3497 RESULT
3498 Pointer to the newly created overlay object or NULL in case of failure.
3500 NOTES
3501 Default implementation in the base class always sets VOERR_INVSCRMODE error and
3502 returns NULL meaning that hardware overlays are not supported. There's no sense
3503 in software implementation because the software is supposed to handle software
3504 rendering itself.
3506 EXAMPLE
3508 BUGS
3510 SEE ALSO
3511 moHidd_Gfx_DisposeOverlay
3513 INTERNALS
3515 *****************************************************************************************/
3517 OOP_Object *GFX__Hidd_Gfx__NewOverlay(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewOverlay *msg)
3519 ULONG *err = (ULONG *)GetTagData(aHidd_Overlay_Error, 0, msg->attrList);
3521 if (err)
3522 *err = VOERR_INVSCRMODE;
3524 return NULL;
3527 /*****************************************************************************************
3529 NAME
3530 moHidd_Gfx_DisposeOverlay
3532 SYNOPSIS
3533 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeOverlay *msg);
3535 VOID HIDD_Gfx_DisposeOverlay(OOP_Object *gfxHidd, OOP_Object *Overlay)
3537 LOCATION
3538 hidd.graphics.graphics
3540 FUNCTION
3541 Deletes an overlay previously created by moHidd_Gfx_NewOverlay.
3543 Subclasses do not have to override this method
3544 unless they allocate anything additional to an overlay object in
3545 their HIDD_Gfx_NewOverlay() implementation.
3547 INPUTS
3548 gfxHidd - A driver object which was used for creating a GC.
3549 Overlay - Pointer to an overlay object to delete.
3551 RESULT
3552 None.
3554 NOTES
3556 EXAMPLE
3558 BUGS
3560 SEE ALSO
3561 moHidd_Gfx_NewGC
3563 INTERNALS
3564 Basically just does OOP_DisposeObject(Overlay);
3566 *****************************************************************************************/
3568 VOID GFX__Hidd_Gfx__DisposeOverlay(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_DisposeOverlay *msg)
3570 OOP_DisposeObject(msg->Overlay);
3573 /****************************************************************************************/
3575 #undef csd
3577 /****************************************************************************************/
3579 static int GFX_ClassInit(LIBBASETYPEPTR LIBBASE)
3581 struct class_static_data *csd = &LIBBASE->hdg_csd;
3583 __IHidd_PixFmt = OOP_ObtainAttrBase(IID_Hidd_PixFmt);
3584 __IHidd_BitMap = OOP_ObtainAttrBase(IID_Hidd_BitMap);
3585 __IHidd_Gfx = OOP_ObtainAttrBase(IID_Hidd_Gfx);
3586 __IHidd_Sync = OOP_ObtainAttrBase(IID_Hidd_Sync);
3587 __IHidd_GC = OOP_ObtainAttrBase(IID_Hidd_GC);
3588 __IHidd_Overlay = OOP_ObtainAttrBase(IID_Hidd_Overlay);
3589 __IHidd_ColorMap = OOP_ObtainAttrBase(IID_Hidd_ColorMap);
3590 __IHidd_PlanarBM = OOP_ObtainAttrBase(IID_Hidd_PlanarBM);
3592 if (!__IHidd_PixFmt ||
3593 !__IHidd_BitMap ||
3594 !__IHidd_Gfx ||
3595 !__IHidd_Sync ||
3596 !__IHidd_GC ||
3597 !__IHidd_ColorMap ||
3598 !__IHidd_PlanarBM
3601 goto failexit;
3604 D(bug("Creating std pixelfmts\n"));
3605 if (!create_std_pixfmts(csd))
3606 goto failexit;
3607 D(bug("Pixfmts created\n"));
3609 /* Get two methodis required for direct method execution */
3610 #if USE_FAST_PUTPIXEL
3611 csd->putpixel_mid = OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_PutPixel);
3612 #endif
3613 #if USE_FAST_GETPIXEL
3614 csd->getpixel_mid = OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_GetPixel);
3615 #endif
3616 #if USE_FAST_DRAWPIXEL
3617 csd->drawpixel_mid = OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_DrawPixel);
3618 #endif
3620 ReturnInt("init_gfxhiddclass", ULONG, TRUE);
3622 failexit:
3623 ReturnInt("init_gfxhiddclass", ULONG, FALSE);
3626 /****************************************************************************************/
3628 static int GFX_ClassFree(LIBBASETYPEPTR LIBBASE)
3630 struct class_static_data *csd = &LIBBASE->hdg_csd;
3632 EnterFunc(bug("free_gfxhiddclass(csd=%p)\n", csd));
3634 if(NULL != csd)
3636 delete_pixfmts(csd);
3638 OOP_ReleaseAttrBase(IID_Hidd_PixFmt);
3639 OOP_ReleaseAttrBase(IID_Hidd_BitMap);
3640 OOP_ReleaseAttrBase(IID_Hidd_Gfx);
3641 OOP_ReleaseAttrBase(IID_Hidd_Sync);
3642 OOP_ReleaseAttrBase(IID_Hidd_GC);
3643 OOP_ReleaseAttrBase(IID_Hidd_Overlay);
3644 OOP_ReleaseAttrBase(IID_Hidd_ColorMap);
3645 OOP_ReleaseAttrBase(IID_Hidd_PlanarBM);
3648 ReturnInt("free_gfxhiddclass", BOOL, TRUE);
3651 /****************************************************************************************/
3653 ADD2INITLIB(GFX_ClassInit, 0)
3654 ADD2EXPUNGELIB(GFX_ClassFree, 0)
3656 /****************************************************************************************/
3658 /* Since the shift/mask values of a pixel format are designed for pixel
3659 access, not byte access, they are endianess dependant */
3661 #if AROS_BIG_ENDIAN
3662 #include "stdpixfmts_be.h"
3663 #else
3664 #include "stdpixfmts_le.h"
3665 #endif
3667 /****************************************************************************************/
3669 static BOOL create_std_pixfmts(struct class_static_data *csd)
3671 ULONG i;
3672 struct pixfmt_data *pf;
3674 memset(csd->std_pixfmts, 0, sizeof (OOP_Object *) * num_Hidd_StdPixFmt);
3676 for (i = 0; i < num_Hidd_StdPixFmt; i ++)
3678 pf = (struct pixfmt_data *)create_and_init_object(csd->pixfmtclass, (UBYTE *)&stdpfs[i], sizeof (stdpfs[i]), csd);
3680 if (!pf)
3682 D(bug("FAILED TO CREATE PIXEL FORMAT %d\n", i));
3683 delete_pixfmts(csd);
3684 ReturnBool("create_stdpixfmts", FALSE);
3687 csd->std_pixfmts[i] = &pf->pf;
3688 /* We don't use semaphore protection here because we do this only during class init stage */
3689 pf->refcount = 1;
3690 AddTail((struct List *)&csd->pflist, (struct Node *)&pf->node);
3692 ReturnBool("create_stdpixfmts", TRUE);
3695 /****************************************************************************************/
3697 static VOID delete_pixfmts(struct class_static_data *csd)
3699 struct Node *n, *safe;
3701 ForeachNodeSafe(&csd->pflist, n, safe)
3702 OOP_DisposeObject((OOP_Object *)PIXFMT_OBJ(n));
3705 /****************************************************************************************/
3707 static inline BOOL cmp_pfs(HIDDT_PixelFormat *tmppf, HIDDT_PixelFormat *dbpf)
3709 /* Just compare everything except stdpixfmt */
3710 /* Compare flags first (because it's a fast check) */
3711 if (tmppf->flags != dbpf->flags)
3712 return FALSE;
3713 /* If they match, compare the rest of things */
3714 return !memcmp(tmppf, dbpf, offsetof(HIDDT_PixelFormat, stdpixfmt));
3717 /****************************************************************************************/
3720 Parses the tags supplied in 'tags' and puts the result into 'pf'.
3721 It also checks to see if all needed attrs are supplied.
3722 It uses 'attrcheck' for this, so you may find attrs outside
3723 of this function, and mark them as found before calling this function
3726 #define PFAF(x) (1L << aoHidd_PixFmt_ ## x)
3727 #define PF_COMMON_AF ( PFAF(Depth) | PFAF(BitsPerPixel) | PFAF(BytesPerPixel) \
3728 | PFAF(ColorModel) | PFAF(BitMapType) )
3730 #define PF_TRUECOLOR_AF ( PFAF(RedMask) | PFAF(GreenMask) | PFAF(BlueMask) | PFAF(AlphaMask) | \
3731 PFAF(RedShift) | PFAF(GreenShift) | PFAF(BlueShift) | PFAF(AlphaShift))
3733 #define PF_PALETTE_AF ( PFAF(CLUTMask) | PFAF(CLUTShift) | PFAF(RedMask) | PFAF(GreenMask) | \
3734 PFAF(BlueMask) )
3736 #define PFAO(x) (aoHidd_PixFmt_ ## x)
3738 /****************************************************************************************/
3740 BOOL parse_pixfmt_tags(struct TagItem *tags, HIDDT_PixelFormat *pf,
3741 ULONG ATTRCHECK(pixfmt), struct class_static_data *csd)
3743 IPTR attrs[num_Hidd_PixFmt_Attrs] = {0};
3745 if (0 != OOP_ParseAttrs(tags, attrs, num_Hidd_PixFmt_Attrs,
3746 &ATTRCHECK(pixfmt), HiddPixFmtAttrBase))
3748 D(bug("!!! parse_pixfmt_tags: ERROR PARSING TAGS THROUGH OOP_ParseAttrs !!!\n"));
3749 return FALSE;
3752 if (PF_COMMON_AF != (PF_COMMON_AF & ATTRCHECK(pixfmt)))
3754 D(bug("!!! parse_pixfmt_tags: Missing PixFmt attributes passed to parse_pixfmt_tags(): %x !!!\n", ATTRCHECK(pixfmt)));
3755 return FALSE;
3758 /* Set the common attributes */
3759 pf->depth = attrs[PFAO(Depth)];
3760 pf->size = attrs[PFAO(BitsPerPixel)];
3761 pf->bytes_per_pixel = attrs[PFAO(BytesPerPixel)];
3762 /* Fill in only real StdPixFmt specification. Special values (Native and Native32)
3763 are not allowed here */
3764 if (attrs[PFAO(StdPixFmt)] >= num_Hidd_PseudoStdPixFmt)
3765 pf->stdpixfmt = attrs[PFAO(StdPixFmt)];
3767 SET_PF_COLMODEL( pf, attrs[PFAO(ColorModel)]);
3768 SET_PF_BITMAPTYPE(pf, attrs[PFAO(BitMapType)]);
3770 if (ATTRCHECK(pixfmt) & PFAF(SwapPixelBytes))
3772 SET_PF_SWAPPIXELBYTES_FLAG(pf, attrs[PFAO(SwapPixelBytes)]);
3775 /* Set the colormodel specific stuff */
3776 switch (HIDD_PF_COLMODEL(pf))
3778 case vHidd_ColorModel_TrueColor:
3779 /* Check that we got all the truecolor describing stuff */
3780 if (PF_TRUECOLOR_AF != (PF_TRUECOLOR_AF & ATTRCHECK(pixfmt)))
3782 D(bug("!!! Unsufficient true color format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
3783 return FALSE;
3786 /* Set the truecolor stuff */
3787 pf->red_mask = attrs[PFAO(RedMask)];
3788 pf->green_mask = attrs[PFAO(GreenMask)];
3789 pf->blue_mask = attrs[PFAO(BlueMask)];
3790 pf->alpha_mask = attrs[PFAO(AlphaMask)];
3792 pf->red_shift = attrs[PFAO(RedShift)];
3793 pf->green_shift = attrs[PFAO(GreenShift)];
3794 pf->blue_shift = attrs[PFAO(BlueShift)];
3795 pf->alpha_shift = attrs[PFAO(AlphaShift)];
3796 break;
3798 case vHidd_ColorModel_Palette:
3799 case vHidd_ColorModel_StaticPalette:
3800 if ( PF_PALETTE_AF != (PF_PALETTE_AF & ATTRCHECK(pixfmt)))
3802 D(bug("!!! Unsufficient palette format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
3803 return FALSE;
3806 /* set palette stuff */
3807 pf->clut_mask = attrs[PFAO(CLUTMask)];
3808 pf->clut_shift = attrs[PFAO(CLUTShift)];
3810 pf->red_mask = attrs[PFAO(RedMask)];
3811 pf->green_mask = attrs[PFAO(GreenMask)];
3812 pf->blue_mask = attrs[PFAO(BlueMask)];
3814 break;
3816 } /* shift (colormodel) */
3818 return TRUE;
3821 /****************************************************************************************/
3824 Create an empty object and initialize it the "ugly" way. This only works with
3825 CLID_Hidd_PixFmt and CLID_Hidd_Sync classes
3828 /****************************************************************************************/
3830 static OOP_Object *create_and_init_object(OOP_Class *cl, UBYTE *data, ULONG datasize,
3831 struct class_static_data *csd)
3833 OOP_Object *o;
3835 o = OOP_NewObject(cl, NULL, NULL);
3836 if (NULL == o)
3838 D(bug("!!! UNABLE TO CREATE OBJECT IN create_and_init_object() !!!\n"));
3839 return NULL;
3842 memcpy(o, data, datasize);
3844 return o;
3847 /****************************************************************************************/
3849 static struct pixfmt_data *find_pixfmt(HIDDT_PixelFormat *tofind, struct class_static_data *csd)
3851 struct pixfmt_data *retpf = NULL;
3852 HIDDT_PixelFormat *db_pf;
3853 struct Node *n;
3855 /* Go through the pixel format list to see if a similar pf allready exists */
3856 ObtainSemaphoreShared(&csd->pfsema);
3858 ForeachNode(&csd->pflist, n)
3860 db_pf = PIXFMT_OBJ(n);
3861 DPF(bug("find_pixfmt(): Trying pixelformat 0x%p\n", db_pf));
3862 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n",
3863 db_pf->red_shift, db_pf->green_shift, db_pf->blue_shift, db_pf->alpha_shift,
3864 db_pf->red_mask, db_pf->green_mask, db_pf->blue_mask, db_pf->alpha_mask,
3865 db_pf->bytes_per_pixel, db_pf->size, db_pf->depth, db_pf->stdpixfmt));
3866 if (cmp_pfs(tofind, db_pf))
3868 DPF(bug("Match!\n"));
3869 retpf = (struct pixfmt_data *)db_pf;
3870 break;
3874 ReleaseSemaphore(&csd->pfsema);
3875 return retpf;
3878 /****************************************************************************************/
3880 /* Stubs for private methods */
3882 #ifndef AROS_CREATE_ROM
3883 # define STATIC_MID static OOP_MethodID mid
3884 #else
3885 # define STATIC_MID OOP_MethodID mid = 0
3886 #endif
3888 /****************************************************************************************/
3890 OOP_Object *HIDD_Gfx_RegisterPixFmt(OOP_Object *o, struct TagItem *pixFmtTags)
3892 STATIC_MID;
3893 struct pHidd_Gfx_RegisterPixFmt p, *msg = &p;
3895 if (!mid) mid = OOP_GetMethodID(IID_Hidd_Gfx, moHidd_Gfx_RegisterPixFmt);
3897 p.mID = mid;
3899 p.pixFmtTags = pixFmtTags;
3901 return (OOP_Object *)OOP_DoMethod(o, (OOP_Msg)msg);
3905 /****************************************************************************************/
3907 VOID HIDD_Gfx_ReleasePixFmt(OOP_Object *o, OOP_Object *pixFmt)
3909 STATIC_MID;
3910 struct pHidd_Gfx_ReleasePixFmt p, *msg = &p;
3912 if (!mid) mid = OOP_GetMethodID(IID_Hidd_Gfx, moHidd_Gfx_ReleasePixFmt);
3914 p.mID = mid;
3916 p.pixFmt = pixFmt;
3918 OOP_DoMethod(o, (OOP_Msg)msg);
3922 /****************************************************************************************/