-Use PCI hidd stubs for reading/writing config memory
[AROS.git] / rom / hidds / graphics / GraphicsClass.c
blob36b805d8a0df7f24bf6736f4bf82e4c974cbd603
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics hidd class implementation.
6 Lang: english
7 */
9 /****************************************************************************************/
11 #include <aros/atomic.h>
12 #include <aros/config.h>
13 #include <aros/symbolsets.h>
14 #include <cybergraphx/cgxvideo.h>
15 #include <exec/lists.h>
16 #include <oop/static_mid.h>
17 #include <graphics/displayinfo.h>
18 #include <graphics/view.h>
20 #include "graphics_intern.h"
22 #include <string.h>
23 #include <stddef.h>
25 #include <proto/exec.h>
26 #include <proto/utility.h>
27 #include <proto/oop.h>
28 #include <exec/libraries.h>
29 #include <exec/memory.h>
31 #include <utility/tagitem.h>
33 #include LC_LIBDEFS_FILE
35 #undef SDEBUG
36 #undef DEBUG
37 #define SDEBUG 0
38 #define DEBUG 0
39 #include <aros/debug.h>
41 #define DPF(x)
44 #include <hidd/graphics.h>
46 /*****************************************************************************************
48 NAME
49 --background_graphics--
51 LOCATION
52 hidd.graphics.graphics
54 NOTES
55 When working with graphics drivers this is the first object you get.
56 It allows you to create BitMap and GC (graphics context)
57 object. The class' methods must be overidden by hardware-specific
58 subclasses where documented to do so.
60 *****************************************************************************************/
62 /*****************************************************************************************
64 NAME
65 --display_modes--
67 LOCATION
68 hidd.graphics.graphics
70 NOTES
71 Each display driver object internally stores a database of supported display mode
72 IDs. This database is normally managed by base class, the driver does not need to
73 reimplement respective methods.
75 A display mode ID in AROS is a 32-bit integer value, the same as on AmigaOS(tm).
76 However mode ID layout introduced by Commodore does not fit well for RTG systems.
77 In order to overcome its limitations, display ID on AROS may have two forms:
79 1. A chipset mode ID. These are standard IDs defined by Commodore. You may find
80 their definitions in graphics/modeid.h.
82 2. AROS RTG mode ID.
84 An RTG mode ID is composed of three parts in the form:
86 nnnn xx yy
88 nnnn - monitor ID. This number is maintained by system libraries. IDs are
89 assigned in the order in which drivers are loaded and display hardware is
90 found. Drivers do not have to care about this part, and should normally
91 mask it out if they for some reason look at mode ID. In order to
92 distinguish between chipset mode IDs and RTG mode IDs, order number starts
93 not from zero, reserving some space for C= chipset mode IDs (which appear
94 to have order numbers from 0x0000 to 0x000A). Currently RTG monitor IDs
95 start from 0x0010, however with time this value may change. So don't rely
96 on some particular values in RTG IDs. Use cybergraphics.library/IsCyberModeID()
97 function if you want to know for sure if the given mode ID belongs to an
98 RTG driver.
100 xx - A sync object index in driver's mode database.
101 yy - A pixelformat object in driver's mode database.
103 Normally the driver does not have to care about mode ID decoding. The mode
104 database is maintained by base class. The only useful things for the driver are
105 sync and pixelformat objects, from which it's possible to get different
106 information about the mode. They can be obtained from the base class using
107 HIDD_Gfx_GetMode().
109 Note that the driver object by itself does not know its monitor ID. Different
110 displays are served by different objects, any of which may belong to any class.
111 So all driver methods which return mode IDs will set monitor ID to zero. All
112 methods that take mode ID as argument are expected to ignore the monitor ID part
113 and do not make any assumptions about its value.
115 *****************************************************************************************/
117 static BOOL create_std_pixfmts(struct class_static_data *_csd);
118 static VOID delete_pixfmts(struct class_static_data *_csd);
119 static BOOL register_modes(OOP_Class *cl, OOP_Object *o, struct TagItem *modetags);
121 static BOOL alloc_mode_db(struct mode_db *mdb, ULONG numsyncs, ULONG numpfs, OOP_Class *cl);
122 static VOID free_mode_db(struct mode_db *mdb, OOP_Class *cl);
123 static OOP_Object *create_and_init_object(OOP_Class *cl, UBYTE *data, ULONG datasize,
124 struct class_static_data *_csd);
126 static struct pixfmt_data *find_pixfmt(HIDDT_PixelFormat *tofind
127 , struct class_static_data *_csd);
129 static VOID copy_bm_and_colmap(OOP_Class *cl, OOP_Object *o, OOP_Object *src_bm
130 , OOP_Object *dst_bm, ULONG width, ULONG height);
132 BOOL parse_pixfmt_tags(struct TagItem *tags, HIDDT_PixelFormat *pf, ULONG attrcheck, struct class_static_data *_csd);
134 /****************************************************************************************/
136 #define COMPUTE_HIDD_MODEID(sync, pf) \
137 ( ((sync) << 8) | (pf) )
139 #define MODEID_TO_SYNCIDX(id) (((id) & 0X0000FF00) >> 8)
140 #define MODEID_TO_PFIDX(id) ( (id) & 0x000000FF)
142 /****************************************************************************************/
144 OOP_Object *GFX__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
146 struct HIDDGraphicsData *data;
147 BOOL ok = FALSE;
148 struct TagItem *modetags;
149 struct TagItem gctags[] =
151 {TAG_DONE, 0UL}
154 D(bug("Entering gfx.hidd::New\n"));
156 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
157 if (NULL == o)
158 return NULL;
160 D(bug("Got object o=%x\n", o));
162 data = OOP_INST_DATA(cl, o);
164 InitSemaphore(&data->mdb.sema);
165 /* data->curmode = vHidd_ModeID_Invalid; */
167 /* Get the mode tags */
168 modetags = (struct TagItem *)GetTagData(aHidd_Gfx_ModeTags, 0, msg->attrList);
169 if (NULL != modetags)
171 /* Parse it and register the gfxmodes */
172 if (register_modes(cl, o, modetags))
174 ok = TRUE;
176 else
177 D(bug("Could not register modes\n"));
179 else {
180 D(bug("Could not get ModeTags\n"));
181 ok = TRUE;
184 /* Create a gc that we can use for some rendering */
185 if (ok)
187 data->gc = OOP_NewObject(CSD(cl)->gcclass, NULL, gctags);
188 if (NULL == data->gc)
190 D(bug("Could not get gc\n"));
191 ok = FALSE;
195 if (!ok)
197 D(bug("Not OK\n"));
198 OOP_MethodID dispose_mid;
200 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
201 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
202 o = NULL;
205 D(bug("Leaving gfx.hidd::New o=%x\n", o));
207 return o;
210 /****************************************************************************************/
212 VOID GFX__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
214 struct HIDDGraphicsData *data;
216 data = OOP_INST_DATA(cl, o);
218 /* free the mode db stuff */
219 free_mode_db(&data->mdb, cl);
221 /* Here we should unregister pixelformats registered in our New().
222 However gfx drivers aren't supposed to be removed, so it's okay
223 not to do it at all for now. */
225 if (NULL != data->gc)
226 OOP_DisposeObject(data->gc);
228 OOP_DoSuperMethod(cl, o, msg);
231 /*****************************************************************************************
233 NAME
234 aoHidd_Gfx_IsWindowed
236 SYNOPSIS
237 [..G], BOOL
239 LOCATION
240 hidd.graphics.graphics
242 FUNCTION
243 Tells if the display driver is using hosted display in host OS' window, and mouse
244 input is handled by host OS.
246 Windowed displays may send activation events to AROS. This is needed in order to
247 correctly handle display switch in a multi-display configuration (which means that
248 the user has multiple windows on host OS desktop and can freely switch between them).
250 NOTES
251 Even in fullscreen mode drivers should still return TRUE if the host OS manages mouse
252 input (for example, X11 driver). If mouse input is not managed by the host OS
253 (for example, with Linux framebuffer driver), return FALSE.
255 EXAMPLE
257 BUGS
259 SEE ALSO
260 aoHidd_Gfx_ActiveCallBack, aoHidd_Gfx_ActiveCallBackData
262 INTERNALS
263 Base class always provides FALSE value
265 *****************************************************************************************/
267 /*****************************************************************************************
269 NAME
270 aoHidd_Gfx_DMPSLevel
272 SYNOPSIS
273 [ISG], HIDDT_DPMSLevel
275 LOCATION
276 hidd.graphics.graphics
278 FUNCTION
279 Gets or sets current DPMS level for driver's display.
280 A value can be one of:
281 vHidd_Gfx_DPMSLevel_On,
282 vHidd_Gfx_DPMSLevel_Standby,
283 vHidd_Gfx_DPMSLevel_Suspend,
284 vHidd_Gfx_DPMSLevel_Off
286 If the driver does not support some state, it's up to the driver what to do.
287 Usually it is expected to ignore the request.
289 Getting this attribute should return real current state.
291 NOTES
293 EXAMPLE
295 BUGS
297 SEE ALSO
299 INTERNALS
300 Base class always provides vHidd_Gfx_DPMSLevel_On value (comes from rootclass'
301 Get() which sets the value to 0).
303 *****************************************************************************************/
305 /*****************************************************************************************
307 NAME
308 aoHidd_Gfx_ModeTags
310 SYNOPSIS
311 [I..], struct TagItem *
313 LOCATION
314 hidd.graphics.graphics
316 FUNCTION
317 Specify a pointer to a taglist which contains description of display modes
318 supported by the driver.
320 This attribute is usually appended in moRoot_New method of the display driver
321 class.
323 This attribute is mandatory for the base class, otherwise driver object creation
324 fails.
326 Mode description taglist may contain the following tags:
327 - Any sync attributes - these attributes will specify values common for all sync
328 modes
329 - Any pixelformat attributes - these attributes will specify values common for
330 all pixelformat modes
331 - aoHidd_Gfx_SyncTags - specifies a pointer to another separate taglist containing
332 attributes for one sync (display) mode. If this tag
333 is not supplied at all, a set of default modes will be
334 generated for the driver.
335 - aoHidd_Gfx_PixFmtTags - specifies a pointer to another separate taglist containing
336 attributes for one pixelformat. This tag must be supplied
337 at least once, otherwise driver object will fail to create.
339 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags can be specified multiple times in
340 order to associate more than one display mode with the driver. Note that common
341 values for sync and pixelformat objects need to be placed in the taglist before
342 aoHidd_Gfx_SyncTags and aoHidd_Gfx_PixFmtTags. You may specify them again between
343 these tags in order to alter common values.
345 NOTES
347 EXAMPLE
348 Partial example code of display driver supporting a truecolor display with three
349 resolutions:
351 // Our pixelformat (24-bit 0BGR)
352 struct TagItem pftags[] =
354 { aHidd_PixFmt_RedShift , 24 },
355 { aHidd_PixFmt_GreenShift , 16 },
356 { aHidd_PixFmt_BlueShift , 8 },
357 { aHidd_PixFmt_AlphaShift , 0 },
358 { aHidd_PixFmt_RedMask , 0x000000FF },
359 { aHidd_PixFmt_GreenMask , 0x0000FF00 },
360 { aHidd_PixFmt_BlueMask , 0x00FF0000 },
361 { aHidd_PixFmt_AlphaMask , 0x00000000 },
362 { aHidd_PixFmt_ColorModel , vHidd_ColorModel_TrueColor },
363 { aHidd_PixFmt_Depth , 24 },
364 { aHidd_PixFmt_BytesPerPixel, 4 },
365 { aHidd_PixFmt_BitsPerPixel , 24 },
366 { aHidd_PixFmt_StdPixFmt , vHidd_StdPixFmt_Native },
367 { aHidd_PixFmt_BitMapType , vHidd_BitMapType_Chunky },
368 { TAG_DONE , 0UL }
371 // 640x480 resolution
372 struct TagItem tags_800_600[] =
374 { aHidd_Sync_HDisp , 640 },
375 { aHidd_Sync_VDisp , 480 },
376 { TAG_DONE , 0UL }
379 // 800x600 resolution
380 struct TagItem tags_800_600[] =
382 { aHidd_Sync_HDisp , 800 },
383 { aHidd_Sync_VDisp , 600 },
384 { TAG_DONE , 0UL }
387 // 1024x768 resolution
388 struct TagItem tags_1024_768[] =
390 { aHidd_Sync_HDisp , 1024 },
391 { aHidd_Sync_VDisp , 768 },
392 { TAG_DONE , 0UL }
395 // Mode description taglist itself
396 struct TagItem mode_tags[] =
398 // Our driver supports a single pixelformat
399 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
401 // Here go sync values common for all sync modes
402 { aHidd_Sync_HMin , 112 },
403 { aHidd_Sync_VMin , 112 },
404 { aHidd_Sync_HMax , 16384 },
405 { aHidd_Sync_VMax , 16384 },
406 { aHidd_Sync_Description, (IPTR)"Example: %hx%v" },
408 // First resolution
409 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
411 // Next two syncs will have HMax = 32768, as an example
412 { aHidd_Sync_HMax , 32768 },
414 // Two more resolutions
415 { aHidd_Gfx_SyncTags , (IPTR)tags_800_600 },
416 { aHidd_Gfx_SyncTags , (IPTR)tags_1024_768 },
417 { TAG_DONE , 0UL }
420 // This is the attribute list which is given to New method
421 // of the base class
422 struct TagItem mytags[] =
424 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
425 { TAG_DONE , NULL }
428 BUGS
430 SEE ALSO
432 INTERNALS
434 *****************************************************************************************/
436 /*****************************************************************************************
438 NAME
439 aoHidd_Gfx_NumSyncs
441 SYNOPSIS
442 [..G], ULONG
444 LOCATION
445 hidd.graphics.graphics
447 FUNCTION
448 Gets total number of sync objects in the internal display mode database.
450 NOTES
452 EXAMPLE
454 BUGS
456 SEE ALSO
457 moHidd_Gfx_GetSync
459 INTERNALS
461 *****************************************************************************************/
463 /*****************************************************************************************
465 NAME
466 aoHidd_Gfx_SupportsHWCursor
468 SYNOPSIS
469 [..G], BOOL
471 LOCATION
472 hidd.graphics.graphics
474 FUNCTION
475 Tells whether the driver supports hardware mouse pointer sprite.
477 If the driver provides TRUE value for this attribute, it is expected to implement
478 HIDD_Gfx_SetCursorPos(), HIDD_Gfx_SetCursorShape() and HIDD_Gfx_SetCursorVisible()
479 methods.
481 Mouse pointer counts for one hardware sprite, so if the driver implements also
482 HIDD_Gfx_ModeProperties(), it should set NumHWSprites to 1 in order to provide
483 valid information about display modes.
485 The driver must implement this attribute if it implements HIDD_Gfx_ModeProperties().
486 Otherwise it will provide false information in graphics.library/GetDisplayInfoData().
487 Base class can determine NumHWSprites based on this attribute value but not vice
488 versa.
490 NOTES
491 Default implementation in the base class returns FALSE. This causes the system to
492 use software sprite emulation.
494 This attribute is obsolete and is used only by AROS graphics.library up to v41.2. In
495 new drivers consider implementing aoHidd_Gfx_HWSpriteTypes attribute.
497 EXAMPLE
499 BUGS
501 SEE ALSO
502 aoHidd_Gfx_HWSpriteTypes, moHidd_Gfx_ModeProperties
504 INTERNALS
506 *****************************************************************************************/
508 /*****************************************************************************************
510 NAME
511 aoHidd_Gfx_NoFrameBuffer
513 SYNOPSIS
514 [..G], BOOL
516 LOCATION
517 hidd.graphics.graphics
519 FUNCTION
520 Tells whether the driver does not need a framebuffer.
522 A framebuffer is a special bitmap in a fixed area of video RAM. If the framebuffer
523 is used, the driver is expected to copy a new bitmap into it in HIDD_Gfx_Show()
524 and optionally copy old bitmap back.
526 A framebuffer is needed if the hardware does not have enough VRAM to store many
527 bitmaps or does not have capabilities to switch the display between various VRAM
528 regions.
530 An example of driver using a framebuffer is hosted SDL driver. By design SDL works
531 only with single display window, which is considered a framebuffer.
533 NOTES
534 Provides FALSE if not implemented in the driver.
536 EXAMPLE
538 BUGS
540 SEE ALSO
541 moHidd_Gfx_Show
543 INTERNALS
544 VGA and VESA do not use framebuffer, they use mirroring technique instead in order
545 to prevents VRAM reading which is slow.
547 *****************************************************************************************/
549 /*****************************************************************************************
551 NAME
552 aoHidd_Gfx_HWSpriteTypes
554 SYNOPSIS
555 [..G], BOOL
557 LOCATION
558 hidd.graphics.graphics
560 FUNCTION
561 Return hardware sprite image types supported by the driver.
563 The returned value is a combination of the following bit flags:
564 vHidd_SpriteType_3Plus1 - color 0 is transparent, 1-3 visible
565 (Amiga(tm) chipset sprite format)
566 vHidd_SpriteType_2Plus1 - color 0 is transparent, color 1 is undefined
567 (can be whatever, for example clear or inverse),
568 colors 2-3 visible.
569 vHidd_SpriteType_DirectColor - Hi- or truecolor image, or LUT image with own
570 palette, perhaps with alpha channel
572 NOTES
573 This attribute should return 0 if the driver does not support hardware mouse sprite
574 at all. Software sprite emulation is done by graphics.library.
576 Default implementation in the base class is based on aoHidd_Gfx_SupportsHWCursor
577 value. This is done for backwards compatibility.
579 EXAMPLE
581 BUGS
583 SEE ALSO
584 aoHidd_Gfx_SupportsHWCursor
586 INTERNALS
587 Default implementation in the base class queries aoHidd_Gfx_SupportsHWCursor
588 and provides (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) in case
589 if it returns TRUE. Otherwise it returns zero. This is done for backwards
590 compatibility with old drivers.
592 *****************************************************************************************/
594 /*****************************************************************************************
596 NAME
597 aoHidd_Gfx_MemorySize
599 SYNOPSIS
600 [..G], ULONG
602 LOCATION
603 hidd.graphics.graphics
605 FUNCTION
606 Query total size of video card memory in bytes.
608 NOTES
610 EXAMPLE
612 BUGS
614 SEE ALSO
615 aoHidd_Gfx_MemoryClock
617 INTERNALS
619 *****************************************************************************************/
621 /*****************************************************************************************
623 NAME
624 aoHidd_Gfx_MemoryClock
626 SYNOPSIS
627 [..G], ULONG
629 LOCATION
630 hidd.graphics.graphics
632 FUNCTION
633 Query video card's memory clock in Hz. 0 is a valid value meaning 'unknown'.
635 NOTES
637 EXAMPLE
639 BUGS
641 SEE ALSO
642 aoHidd_Gfx_MemorySize
644 INTERNALS
646 *****************************************************************************************/
648 /*****************************************************************************************
650 NAME
651 aoHidd_Gfx_DriverName
653 SYNOPSIS
654 [..G], STRPTR
656 LOCATION
657 hidd.graphics.graphics
659 FUNCTION
660 Query CyberGraphX driver name. It is the same name which can be given to
661 cybergraphics.library/BestCModeIDTagList() as CYBRBIDTG_BoardName value.
663 NOTES
664 By default base class returns class name as value of this attribute.
665 However this can (and must for some drivers listed in BestCModeIDTagList()
666 documentation) be overriden.
668 EXAMPLE
670 BUGS
672 SEE ALSO
674 INTERNALS
676 *****************************************************************************************/
678 /*****************************************************************************************
680 NAME
681 aoHidd_Gfx_ActiveCallBack
683 SYNOPSIS
684 [.S.], void (*)(APTR userdata, OOP_Object *bitmap)
686 LOCATION
687 hidd.graphics.graphics
689 FUNCTION
690 Set display activation interrupt handler.
692 This handler needs to be called by hosted display driver, if host OS
693 windowing system is used for the display and mouse input is handled by the
694 host OS.
696 This way the driver can tell AROS when a display window has been activated so that
697 AROS will be able to switch current display correctly when working in a multi-display
698 configuration.
700 The function uses C calling convention and needs to be declared as follows:
702 void ActivationHandler(APTR userdata, OOP_Object *bitmap);
704 Parameters of this function will be:
705 userdata - Whatever is specified by aoHidd_Gfx_ActiveCallBackData attribute.
706 bitmap - Currently reserved. Drivers need to set it to NULL.
708 The function can be called from within an interrupt, so usual restrictions apply
709 to it.
711 Set this attribute to NULL in order to disable activation handling.
713 NOTES
714 When setting the activation callback function, be sure that you set correct
715 userdata before you actually set the callback pointer. Otherwise your callback
716 can be called with wrong data pointer.
718 Only one activation handler can be installed. Installing a new handler replaces
719 the previous one.
721 Native displays do not need to implement this attribute because there can be
722 no external activation events.
724 EXAMPLE
726 BUGS
728 SEE ALSO
729 aoHidd_Gfx_ActiveCallBackData, aoHidd_Gfx_IsWindowed
731 INTERNALS
732 This attribute needs to be implemented by the display driver. Base class contains
733 no implementation.
735 *****************************************************************************************/
737 /*****************************************************************************************
739 NAME
740 aoHidd_Gfx_ActiveCallBackData
742 SYNOPSIS
743 [.S.], APTR
745 LOCATION
746 hidd.graphics.graphics
748 FUNCTION
749 Set user-defined data pointer for display activation handler.
751 NOTES
753 EXAMPLE
755 BUGS
757 SEE ALSO
758 aoHidd_Gfx_ActiveCallBack
760 INTERNALS
761 This attribute needs to be implemented by the display driver. Base class contains
762 no implementation.
764 *****************************************************************************************/
766 VOID GFX__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
768 struct HIDDGraphicsData *data;
769 ULONG idx;
771 data = OOP_INST_DATA(cl, o);
773 if (IS_GFX_ATTR(msg->attrID, idx))
775 switch (idx)
777 case aoHidd_Gfx_NumSyncs:
778 *msg->storage = data->mdb.num_syncs;
779 return;
781 case aoHidd_Gfx_IsWindowed:
782 case aoHidd_Gfx_SupportsHWCursor:
783 *msg->storage = 0;
784 return;
786 case aoHidd_Gfx_HWSpriteTypes:
788 IPTR hwc;
790 OOP_GetAttr(o, aHidd_Gfx_SupportsHWCursor, &hwc);
791 *msg->storage = hwc ? (vHidd_SpriteType_3Plus1|vHidd_SpriteType_DirectColor) : 0;
792 return;
795 case aoHidd_Gfx_DriverName:
796 *msg->storage = (IPTR)OOP_OCLASS(o)->ClassNode.ln_Name;
797 return;
799 default: /* Keep compiler happy */
800 break;
804 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
806 return;
809 /*****************************************************************************************
811 NAME
812 moHidd_Gfx_NewGC
814 SYNOPSIS
815 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewGC *msg);
817 OOP_Object *HIDD_Gfx_NewGC(OOP_Object *gfxHidd, struct TagItem *tagList);
819 LOCATION
820 hidd.graphics.graphics
822 FUNCTION
823 Create a GC (gfx context) object that may be used for rendering
824 into a bitmap.
826 INPUTS
827 gfxHidd - A graphics driver object with which the GC will perform
828 the rendering operations.
829 tagList - A list of GC attributes. See hidd.graphics.gc class
830 documentation for their description.
832 RESULT
833 gc - pointer to the newly created GC, ready for use for rendering
834 operations.
836 NOTES
837 A GC object is just a data storage. You may create a subclass of GC if
838 you wish to, however there's usually no need to. Additionally, this may
839 be not future-proof (since GC subclasses can not be interchanged between
840 different drivers. Please avoid using custom GCs.
842 EXAMPLE
844 BUGS
845 At the moment subclassing GCs is not supported because some parts of
846 the operating system create GC objects directly. It is unclear whether
847 subclassing GCs is actually needed.
849 SEE ALSO
850 moHidd_Gfx_DisposeGC
852 INTERNALS
854 *****************************************************************************************/
856 OOP_Object *GFX__Hidd_Gfx__NewGC(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewGC *msg)
858 OOP_Object *gc = NULL;
860 EnterFunc(bug("HIDDGfx::NewGC()\n"));
862 gc = OOP_NewObject(NULL, CLID_Hidd_GC, msg->attrList);
864 ReturnPtr("HIDDGfx::NewGC", OOP_Object *, gc);
867 /*****************************************************************************************
869 NAME
870 moHidd_Gfx_DisposeGC
872 SYNOPSIS
873 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeGC *msg);
875 VOID HIDD_Gfx_DisposeGC(OOP_Object *gfxHidd, OOP_Object *gc)
877 LOCATION
878 hidd.graphics.graphics
880 FUNCTION
881 Deletes a GC (Graphics Context) object previously created
882 by HIDD_Gfx_NewGC().
884 Subclasses do not have to override this method
885 unless they allocate anything additional to a gc object in
886 their HIDD_Gfx_NewGC() implementation.
888 INPUTS
889 gfxHidd - A driver object which was used for creating a GC.
890 gc - Pointer to gc object to delete.
892 RESULT
893 None.
895 NOTES
897 EXAMPLE
899 BUGS
901 SEE ALSO
902 moHidd_Gfx_NewGC
904 INTERNALS
905 Basically just does OOP_DisposeObject(gc);
907 *****************************************************************************************/
909 VOID GFX__Hidd_Gfx__DisposeGC(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_DisposeGC *msg)
911 EnterFunc(bug("HIDDGfx::DisposeGC()\n"));
913 if (NULL != msg->gc) OOP_DisposeObject(msg->gc);
915 ReturnVoid("HIDDGfx::DisposeGC");
918 /****************************************************************************************/
920 #define BMAO(x) aoHidd_BitMap_ ## x
921 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
923 #define BM_DIMS_AF (BMAF(Width) | BMAF(Height))
925 #define SET_TAG(tags, idx, tag, val) \
926 tags[idx].ti_Tag = tag ; tags[idx].ti_Data = (IPTR)val;
928 #define SET_BM_TAG(tags, idx, tag, val) \
929 SET_TAG(tags, idx, aHidd_BitMap_ ## tag, val)
931 /*****************************************************************************************
933 NAME
934 moHidd_Gfx_NewBitMap
936 SYNOPSIS
937 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewBitMap *msg);
939 OOP_Object *HIDD_Gfx_NewBitMap(OOP_Object *gfxHidd, struct TagItem *tagList);
941 LOCATION
942 hidd.graphics.graphics
944 FUNCTION
945 Create a bitmap object.
947 One graphics driver represents at least one displayable bitmap class.
948 Additionally it may represent more classes (for example some old drivers use
949 a separate class for nondisplayable bitmaps).
951 These classes are private to the driver. In order to be able to use them
952 bitmap objects are never created directly. Instead they are created using the
953 HIDD_Gfx_NewBitMap() call. An implementation of this method in the driver
954 should examine bitmap attributes supplied and make a decision if the bitmap
955 should be created using the driver's own class or one of the system classes.
957 A typical implementation should pay attention to the following bitmap attributes:
959 aHIDD_BitMap_ModeID - If this attribute is supplied, the bitmap needs to be
960 either displayable by this driver, or be a friend of a
961 displayable bitmap. A friend bitmap usually repeats the
962 internal layout of its friend so that the driver may
963 perform blitting operations quickly.
965 aHIDD_BitMap_Displayable - If this attribute is supplied, the bitmap NEEDS to be
966 displayable by this driver. Usually this means that
967 the bitmap object will contain video hardware state
968 information. This attribute will always be accompanied
969 by aHIDD_BitMap_ModeID.
971 aHIDD_BitMap_FrameBuffer - The bitmap needs to be a framebuffer bitmap. A
972 framebuffer bitmap is necessary for some kinds of
973 hardware which have a small fixed amount of video
974 RAM which can hold only one screen at a time. Setting
975 this attribute requires that a valid ModeID be also set.
977 aHIDD_BitMap_Friend - If there's no ModeID supplied, you may wish to check class
978 of friend bitmap. This can be useful if your driver uses
979 different classes for displayable and non-displayable bitmaps.
980 By default base class will pick up friend's class and use it
981 for new bitmap if nothing is specified, here you may override
982 this behavior.
984 If your driver wants to specify own class for the bitmap being created,
985 it should prepend an aHIDD_BitMap_ClassPtr attribute to the supplied taglist
986 and pass it to base class. It's not allowed to create bitmap objects directly
987 since they need some more extra information which is added by the base class!
989 This method must be implemented by your subclass. aHIDD_BitMap_ClassPtr or
990 aHIDD_BitMap_ClassID must be provided to the base class for a displayable bitmap!
992 INPUTS
993 gfxHidd - The graphics driver object that will provide the bitmap.
995 tagList - A list of bitmap attributes. See hidd.graphics.bitmap class
996 documentation for their descriptions.
998 RESULT
999 bm - pointer to the newly created bitmap.
1001 NOTES
1003 EXAMPLE
1005 BUGS
1007 SEE ALSO
1008 moHidd_Gfx_DisposeBitMap
1010 INTERNALS
1011 The base class implementation currently does the folliwing in order to determine
1012 a class for a nondisplayable bitmap (in the listed order):
1014 1. Check aHIDD_BitMap_ClassPtr and aHIDD_BitMap_ClassID. If one of them is supplied,
1015 the class is already set by a subclass.
1016 2. Check aHIDD_BitMap_StdPixFmt. If this attribute is supplied, figure out type of
1017 the pixelformat (chunky or planar), and use one of two system's default classes.
1018 3. Check aHIDD_BitMap_Friend. If friend bitmap is supplied, obtain its class from
1019 aHIDD_BitMap_ClassPtr value of friend bitmap.
1020 4. If everything fails, bitmap creation fails too.
1022 This behavior is subject to change, but will maintain backwards compatibility.
1024 *****************************************************************************************/
1026 OOP_Object * GFX__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o,
1027 struct pHidd_Gfx_NewBitMap *msg)
1029 struct TagItem bmtags[8];
1031 IPTR attrs[num_Total_BitMap_Attrs];
1032 STRPTR classid = NULL;
1033 OOP_Class *classptr = NULL;
1034 BOOL displayable = FALSE; /* Default attr value */
1035 BOOL framebuffer = FALSE;
1036 OOP_Object *pf = NULL, *sync;
1037 HIDDT_ModeID modeid = 0;
1038 OOP_Object *bm;
1039 IPTR depth = 0;
1040 struct HIDDGraphicsData *data;
1042 DECLARE_ATTRCHECK(bitmap);
1044 BOOL gotclass = FALSE;
1046 data = OOP_INST_DATA(cl, o);
1048 if (0 != OOP_ParseAttrs(msg->attrList, attrs, num_Total_BitMap_Attrs,
1049 &ATTRCHECK(bitmap), HiddBitMapAttrBase))
1051 D(bug("!!! FAILED TO PARSE ATTRS IN Gfx::NewBitMap !!!\n"));
1052 return NULL;
1055 if (GOT_BM_ATTR(PixFmt))
1057 D(bug("!!! Gfx::NewBitMap: USER IS NOT ALLOWED TO PASS aHidd_BitMap_PixFmt !!!\n"));
1058 return NULL;
1061 /* Get class supplied by superclass */
1062 if (GOT_BM_ATTR(ClassPtr))
1064 classptr = (OOP_Class *)attrs[BMAO(ClassPtr)];
1065 gotclass = TRUE;
1067 else
1069 if (GOT_BM_ATTR(ClassID))
1071 classid = (STRPTR)attrs[BMAO(ClassID)];
1072 gotclass = TRUE;
1076 if (GOT_BM_ATTR(Displayable))
1077 displayable = (BOOL)attrs[BMAO(Displayable)];
1079 if (GOT_BM_ATTR(FrameBuffer))
1081 framebuffer = (BOOL)attrs[BMAO(FrameBuffer)];
1082 if (framebuffer) displayable = TRUE;
1085 if (GOT_BM_ATTR(ModeID))
1087 modeid = attrs[BMAO(ModeID)];
1089 /* Check that it is a valid mode */
1090 if (!HIDD_Gfx_GetMode(o, modeid, &sync, &pf))
1092 D(bug("!!! Gfx::NewBitMap: USER PASSED INVALID MODEID !!!\n"));
1095 if (GOT_BM_ATTR(Depth))
1096 depth = attrs[BMAO(Depth)];
1098 /* First argument is gfxhidd */
1099 SET_BM_TAG(bmtags, 0, GfxHidd, o);
1100 SET_BM_TAG(bmtags, 1, Displayable, displayable);
1103 if (displayable || framebuffer)
1105 /* The user has to supply a modeid */
1106 if (!GOT_BM_ATTR(ModeID))
1108 D(bug("!!! Gfx::NewBitMap: USER HAS NOT PASSED MODEID FOR DISPLAYABLE BITMAP !!!\n"));
1109 return NULL;
1112 if (!gotclass)
1114 D(bug("!!! Gfx::NewBitMap: SUBCLASS DID NOT PASS CLASS FOR DISPLAYABLE BITMAP !!!\n"));
1115 return NULL;
1118 SET_BM_TAG(bmtags, 2, ModeID, modeid);
1119 SET_BM_TAG(bmtags, 3, PixFmt, pf);
1121 if (framebuffer)
1123 SET_BM_TAG(bmtags, 4, FrameBuffer, TRUE);
1125 else
1127 SET_TAG(bmtags, 4, TAG_IGNORE, 0UL);
1129 if (!depth)
1130 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
1131 SET_BM_TAG(bmtags, 5, Depth, depth);
1132 SET_TAG(bmtags, 6, TAG_MORE, msg->attrList);
1135 else
1136 { /* if (displayable) */
1137 IPTR width, height;
1139 /* To get a pixfmt for an offscreen bitmap we either need
1140 (ModeID || ( (Width && Height) && StdPixFmt) || ( (Width && Height) && Friend))
1143 if (GOT_BM_ATTR(ModeID))
1145 /* We have allredy gotten pixelformat and sync for the modeid case */
1146 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
1147 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
1149 else
1151 /* Next to look for is StdPixFmt */
1153 /* Check that we have width && height */
1154 if (BM_DIMS_AF != (BM_DIMS_AF & ATTRCHECK(bitmap)))
1156 D(bug("!!! Gfx::NewBitMap() MISSING WIDTH/HEIGHT TAGS !!!\n"));
1157 return NULL;
1160 width = attrs[BMAO(Width)];
1161 height = attrs[BMAO(Height)];
1163 if (GOT_BM_ATTR(StdPixFmt))
1165 pf = HIDD_Gfx_GetPixFmt(o, (HIDDT_StdPixFmt)attrs[BMAO(StdPixFmt)]);
1166 if (NULL == pf)
1168 D(bug("!!! Gfx::NewBitMap(): USER PASSED BOGUS StdPixFmt !!!\n"));
1169 return NULL;
1172 else
1174 /* Last alternative is that the user passed a friend bitmap */
1175 if (GOT_BM_ATTR(Friend))
1177 OOP_Object *friend_bm = (OOP_Object *)attrs[BMAO(Friend)];
1178 OOP_GetAttr(friend_bm, aHidd_BitMap_PixFmt, (IPTR *)&pf);
1179 /* Try to grab the class from friend bitmap (if not already specified).
1180 We do it because friend bitmap may be a display HIDD bitmap */
1181 if (!gotclass) {
1182 /* Another weirdness is that we have to use this attribute instead of
1183 simple getting OOP_OCLASS(friend_bm). We can't get class directly
1184 from the object, because the framebuffer bitmap object may be a
1185 fakegfx.hidd object, which is even not a bitmap at all. Attempt
1186 to create a bitmap of this class causes system-wide breakage.
1187 Perhaps fakegfx HIDD should be fixed in order to handle this correctly.
1189 OOP_GetAttr(friend_bm, aHidd_BitMap_ClassPtr, (IPTR *)&classptr);
1190 D(bug("[GFX] Friend bitmap is 0x%p has ClassPtr 0x%p\n", friend_bm, classptr));
1191 if (classptr)
1192 gotclass = TRUE;
1195 else
1197 D(bug("!!! Gfx::NewBitMap: UNSIFFICIENT ATTRS TO CREATE OFFSCREEN BITMAP !!!\n"));
1198 return NULL;
1203 /* Did the subclass provide an offbitmap class for us ? */
1204 if (!gotclass)
1206 /* Have to find a suitable class ourselves */
1207 HIDDT_BitMapType bmtype;
1209 OOP_GetAttr(pf, aHidd_PixFmt_BitMapType, &bmtype);
1210 switch (bmtype)
1212 case vHidd_BitMapType_Chunky:
1213 classptr = CSD(cl)->chunkybmclass;
1214 break;
1216 case vHidd_BitMapType_Planar:
1217 classptr = CSD(cl)->planarbmclass;
1218 break;
1220 default:
1221 D(bug("!!! Gfx::NewBitMap: UNKNOWN BITMAPTYPE %d !!!\n", bmtype));
1222 return NULL;
1225 D(bug("[GFX] Bitmap type is %u, using class 0x%p\n", bmtype, classptr));
1227 } /* if (!gotclass) */
1229 if (!depth)
1230 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
1232 /* Set the tags we want to pass to the selected bitmap class */
1233 SET_BM_TAG(bmtags, 2, Width, width);
1234 SET_BM_TAG(bmtags, 3, Height, height);
1235 SET_BM_TAG(bmtags, 4, Depth, depth);
1236 SET_BM_TAG(bmtags, 5, PixFmt, pf);
1238 if (GOT_BM_ATTR(Friend))
1240 SET_BM_TAG(bmtags, 6, Friend, attrs[BMAO(Friend)]);
1242 else
1244 SET_TAG(bmtags, 6, TAG_IGNORE, 0UL);
1246 SET_TAG(bmtags, 7, TAG_MORE, msg->attrList);
1248 } /* if (!displayable) */
1251 bm = OOP_NewObject(classptr, classid, bmtags);
1253 if (framebuffer)
1254 data->framebuffer = bm;
1256 return bm;
1260 /*****************************************************************************************
1262 NAME
1263 moHidd_Gfx_DisposeBitMap
1265 SYNOPSIS
1266 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeBitMap *msg);
1268 VOID HIDD_Gfx_DisposeBitMap(OOP_Object *gfxHidd, OOP_Object *bitMap);
1270 LOCATION
1271 hidd.graphics.graphics
1273 FUNCTION
1274 Deletes a bitmap object previously created by HIDD_Gfx_NewBitMap().
1276 Subclasses do not have to override this method
1277 unless they allocate anything additional to a bitmap object in
1278 their HIDD_Gfx_NewBitMap() implementation.
1280 INPUTS
1281 gfxHidd - A driver object which was used for creating a bitmap.
1282 bitMap - Pointer to a bitmap object to delete.
1284 RESULT
1285 None.
1287 NOTES
1289 EXAMPLE
1291 BUGS
1293 SEE ALSO
1294 moHidd_Gfx_NewBitMap
1296 INTERNALS
1297 Basically just does OOP_DisposeObject(bitMap);
1299 ******************************************************************************************/
1301 VOID GFX__Hidd_Gfx__DisposeBitMap(OOP_Class *cl, OOP_Object *o,
1302 struct pHidd_Gfx_DisposeBitMap *msg)
1304 if (NULL != msg->bitMap)
1305 OOP_DisposeObject(msg->bitMap);
1308 /****************************************************************************************/
1310 #define SD(x) ((struct sync_data *)x)
1311 #define PF(x) ((HIDDT_PixelFormat *)x)
1313 #define XCOORD_TO_BYTEIDX(x) ( (x) >> 3)
1314 #define COORD_TO_BYTEIDX(x, y, bpr) ( ( (y) * bpr ) + XCOORD_TO_BYTEIDX(x) )
1315 #define XCOORD_TO_MASK(x) (1L << (7 - ((x) & 0x07) ))
1316 #define WIDTH_TO_BYTES(width) ( (( (width) - 1) >> 3) + 1)
1318 /****************************************************************************************/
1320 /* modebm functions pfidx is x and syncidx is y coord in the bitmap */
1322 /****************************************************************************************/
1324 static inline BOOL alloc_mode_bm(struct mode_bm *bm, ULONG numsyncs, ULONG numpfs,
1325 OOP_Class *cl)
1327 bm->bpr = WIDTH_TO_BYTES(numpfs);
1329 bm->bm = AllocVec(bm->bpr * numsyncs, MEMF_CLEAR);
1330 if (NULL == bm->bm)
1331 return FALSE;
1333 /* We initialize the mode bitmap to all modes valid */
1334 memset(bm->bm, 0xFF, bm->bpr * numsyncs);
1336 return TRUE;
1339 /****************************************************************************************/
1341 static inline VOID free_mode_bm(struct mode_bm *bm, OOP_Class *cl)
1343 FreeVec(bm->bm);
1344 bm->bm = NULL;
1345 bm->bpr = 0;
1348 /****************************************************************************************/
1350 static inline BOOL is_valid_mode(struct mode_bm *bm, ULONG syncidx, ULONG pfidx)
1352 if (0 != (XCOORD_TO_MASK(pfidx) & bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)]))
1353 return TRUE;
1355 return FALSE;
1358 /****************************************************************************************/
1360 static inline VOID set_valid_mode(struct mode_bm *bm, ULONG syncidx, ULONG pfidx,
1361 BOOL valid)
1363 if (valid)
1364 bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)] |= XCOORD_TO_MASK(pfidx);
1365 else
1366 bm->bm[COORD_TO_BYTEIDX(pfidx, syncidx, bm->bpr)] &= ~XCOORD_TO_MASK(pfidx);
1368 return;
1371 /****************************************************************************************/
1373 static BOOL alloc_mode_db(struct mode_db *mdb, ULONG numsyncs, ULONG numpfs, OOP_Class *cl)
1375 BOOL ok = FALSE;
1377 if (0 == numsyncs || 0 == numpfs)
1378 return FALSE;
1380 ObtainSemaphore(&mdb->sema);
1381 /* free_mode_bm() needs this */
1382 mdb->num_pixfmts = numpfs;
1383 mdb->num_syncs = numsyncs;
1385 mdb->syncs = AllocMem(sizeof (OOP_Object *) * numsyncs, MEMF_CLEAR);
1387 if (NULL != mdb->syncs)
1389 mdb->pixfmts = AllocMem(sizeof (OOP_Object *) * numpfs, MEMF_CLEAR);
1391 if (NULL != mdb->pixfmts)
1393 if (alloc_mode_bm(&mdb->orig_mode_bm, numsyncs, numpfs, cl))
1395 if (alloc_mode_bm(&mdb->checked_mode_bm, numsyncs, numpfs, cl))
1397 ok = TRUE;
1403 if (!ok)
1404 free_mode_db(mdb, cl);
1406 ReleaseSemaphore(&mdb->sema);
1408 return ok;
1411 /****************************************************************************************/
1413 static VOID free_mode_db(struct mode_db *mdb, OOP_Class *cl)
1415 ULONG i;
1417 ObtainSemaphore(&mdb->sema);
1419 if (NULL != mdb->pixfmts)
1422 /* Pixelformats are shared objects and never freed */
1423 FreeMem(mdb->pixfmts, sizeof (OOP_Object *) * mdb->num_pixfmts);
1424 mdb->pixfmts = NULL; mdb->num_pixfmts = 0;
1427 if (NULL != mdb->syncs)
1429 for (i = 0; i < mdb->num_syncs; i ++)
1431 if (NULL != mdb->syncs[i])
1434 OOP_DisposeObject(mdb->syncs[i]);
1435 mdb->syncs[i] = NULL;
1439 FreeMem(mdb->syncs, sizeof (OOP_Object *) * mdb->num_syncs);
1440 mdb->syncs = NULL; mdb->num_syncs = 0;
1443 if (NULL != mdb->orig_mode_bm.bm)
1445 free_mode_bm(&mdb->orig_mode_bm, cl);
1448 if (NULL != mdb->checked_mode_bm.bm)
1450 free_mode_bm(&mdb->checked_mode_bm, cl);
1453 ReleaseSemaphore(&mdb->sema);
1455 return;
1458 /****************************************************************************************/
1460 /* Initializes default tagarray. in numtags the TAG_MORE is not accounted for,
1461 so the array must be of size NUM_TAGS + 1
1464 /****************************************************************************************/
1466 static VOID init_def_tags(struct TagItem *tags, ULONG numtags)
1468 ULONG i;
1470 for (i = 0; i < numtags; i ++)
1472 tags[i].ti_Tag = TAG_IGNORE;
1473 tags[i].ti_Data = 0UL;
1476 tags[i].ti_Tag = TAG_MORE;
1477 tags[i].ti_Data = 0UL;
1479 return;
1482 /****************************************************************************************/
1484 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
1485 struct TagItem sync_ ## name[]={ \
1486 { aHidd_Sync_PixelClock, clock*1000 }, \
1487 { aHidd_Sync_HDisp, hdisp }, \
1488 { aHidd_Sync_HSyncStart, hstart }, \
1489 { aHidd_Sync_HSyncEnd, hend }, \
1490 { aHidd_Sync_HTotal, htotal }, \
1491 { aHidd_Sync_VDisp, vdisp }, \
1492 { aHidd_Sync_VSyncStart, vstart }, \
1493 { aHidd_Sync_VSyncEnd, vend }, \
1494 { aHidd_Sync_VTotal, vtotal }, \
1495 { aHidd_Sync_Description, (IPTR)descr}, \
1496 { TAG_DONE, 0UL }}
1498 static BOOL register_modes(OOP_Class *cl, OOP_Object *o, struct TagItem *modetags)
1500 struct TagItem *tag, *tstate;
1501 struct HIDDGraphicsData *data;
1503 MAKE_SYNC(640x480_60, 25174,
1504 640, 656, 752, 800,
1505 480, 490, 492, 525,
1506 "Default:640x480");
1508 MAKE_SYNC(800x600_56, 36000, // 36000
1509 800, 824, 896, 1024,
1510 600, 601, 603, 625,
1511 "Default:800x600");
1513 MAKE_SYNC(1024x768_60, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
1514 1024, 1048, 1184, 1344,
1515 768, 771, 777, 806,
1516 "Default:1024x768");
1518 MAKE_SYNC(1152x864_60, 80000,
1519 1152, 1216, 1328, 1456,
1520 864, 870, 875, 916,
1521 "Default:1152x864");
1523 MAKE_SYNC(1280x1024_60, 108880,
1524 1280, 1360, 1496, 1712,
1525 1024, 1025, 1028, 1060,
1526 "Default:1280x1024");
1528 MAKE_SYNC(1600x1200_60, 155982,
1529 1600, 1632, 1792, 2048,
1530 1200, 1210, 1218, 1270,
1531 "Default:1600x1200");
1533 /* "new" 16:10 modes */
1535 MAKE_SYNC(1280x800_60, 83530,
1536 1280, 1344, 1480, 1680,
1537 800, 801, 804, 828,
1538 "Default:1280x800");
1540 MAKE_SYNC(1440x900_60, 106470,
1541 1440, 1520, 1672, 1904,
1542 900, 901, 904, 932,
1543 "Default:1440x900");
1545 MAKE_SYNC(1680x1050_60, 147140,
1546 1680, 1784, 1968, 2256,
1547 1050, 1051, 1054, 1087,
1548 "Default:1680x1050");
1550 MAKE_SYNC(1920x1080_60, 173000,
1551 1920, 2048, 2248, 2576,
1552 1080, 1083, 1088, 1120,
1553 "Default:1920x1080");
1555 MAKE_SYNC(1920x1200_60, 154000,
1556 1920, 1968, 2000, 2080,
1557 1200, 1203, 1209, 1235,
1558 "Default:1920x1200");
1560 struct mode_db *mdb;
1562 HIDDT_PixelFormat pixfmt_data;
1564 struct TagItem def_sync_tags[num_Hidd_Sync_Attrs + 1];
1565 struct TagItem def_pixfmt_tags[num_Hidd_PixFmt_Attrs + 1];
1567 ULONG numpfs = 0,numsyncs = 0;
1568 ULONG pfidx = 0, syncidx = 0;
1570 struct TagItem temporary_tags[] = {
1571 { aHidd_Gfx_SyncTags, (IPTR)sync_640x480_60 },
1572 { aHidd_Gfx_SyncTags, (IPTR)sync_800x600_56 },
1573 { aHidd_Gfx_SyncTags, (IPTR)sync_1024x768_60 },
1574 { aHidd_Gfx_SyncTags, (IPTR)sync_1152x864_60 },
1575 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x1024_60 },
1576 { aHidd_Gfx_SyncTags, (IPTR)sync_1600x1200_60 },
1577 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x800_60 },
1578 { aHidd_Gfx_SyncTags, (IPTR)sync_1440x900_60 },
1579 { aHidd_Gfx_SyncTags, (IPTR)sync_1680x1050_60 },
1580 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1080_60 },
1581 { aHidd_Gfx_SyncTags, (IPTR)sync_1920x1200_60 },
1582 { TAG_MORE, 0UL }
1585 data = OOP_INST_DATA(cl, o);
1586 mdb = &data->mdb;
1587 InitSemaphore(&mdb->sema);
1589 memset(&pixfmt_data, 0, sizeof (pixfmt_data));
1591 init_def_tags(def_sync_tags, num_Hidd_Sync_Attrs);
1592 init_def_tags(def_pixfmt_tags, num_Hidd_PixFmt_Attrs);
1594 def_sync_tags[aoHidd_Sync_GfxHidd].ti_Tag = aHidd_Sync_GfxHidd;
1595 def_sync_tags[aoHidd_Sync_GfxHidd].ti_Data = (IPTR)o;
1597 /* First we need to calculate how much memory we are to allocate by counting supplied
1598 pixel formats and syncs */
1600 for (tstate = modetags; (tag = NextTagItem((const struct TagItem **)&tstate));)
1602 ULONG idx;
1604 if (IS_GFX_ATTR(tag->ti_Tag, idx))
1606 switch (idx)
1608 case aoHidd_Gfx_PixFmtTags:
1609 numpfs++;
1610 break;
1612 case aoHidd_Gfx_SyncTags:
1613 numsyncs ++;
1614 break;
1616 default:
1617 break;
1622 if (0 == numpfs)
1624 D(bug("!!! WE MUST AT LEAST HAVE ONE PIXFMT IN Gfx::RegisterModes() !!!\n"));
1627 if (0 == numsyncs)
1629 D(bug("!!! NO SYNC IN Gfx::RegisterModes() !!!\n!!! USING DEFAULT MODES !!!\n"));
1630 temporary_tags[11].ti_Tag = TAG_MORE;
1631 temporary_tags[11].ti_Data = (IPTR)modetags;
1632 modetags = &temporary_tags[0];
1633 numsyncs = 11;
1636 ObtainSemaphore(&mdb->sema);
1638 /* Allocate memory for mode db */
1639 if (!alloc_mode_db(&data->mdb, numsyncs, numpfs, cl))
1640 goto failure;
1643 for (tstate = modetags; (tag = NextTagItem((const struct TagItem **)&tstate));)
1645 /* Look for Gfx, PixFmt and Sync tags */
1646 ULONG idx;
1648 if (IS_GFX_ATTR(tag->ti_Tag, idx))
1650 switch (idx)
1652 case aoHidd_Gfx_PixFmtTags:
1653 def_pixfmt_tags[num_Hidd_PixFmt_Attrs].ti_Data = tag->ti_Data;
1654 mdb->pixfmts[pfidx] = HIDD_Gfx_RegisterPixFmt(o, def_pixfmt_tags);
1656 if (NULL == mdb->pixfmts[pfidx])
1658 D(bug("!!! UNABLE TO CREATE PIXFMT OBJECT IN Gfx::RegisterModes() !!!\n"));
1659 goto failure;
1662 pfidx ++;
1663 break;
1665 case aoHidd_Gfx_SyncTags:
1666 def_sync_tags[num_Hidd_Sync_Attrs].ti_Data = tag->ti_Data;
1668 mdb->syncs[syncidx] = OOP_NewObject(CSD(cl)->syncclass, NULL, def_sync_tags);
1669 if (!mdb->syncs[syncidx]) {
1670 D(bug("!!! UNABLE TO CREATE SYNC OBJECT IN Gfx::RegisterModes() !!!\n"));
1671 goto failure;
1674 syncidx ++;
1675 break;
1679 else if (IS_SYNC_ATTR(tag->ti_Tag, idx))
1681 if (idx >= num_Hidd_Sync_Attrs)
1683 D(bug("!!! UNKNOWN SYNC ATTR IN Gfx::New(): %d !!!\n", idx));
1685 else
1687 def_sync_tags[idx].ti_Tag = tag->ti_Tag;
1688 def_sync_tags[idx].ti_Data = tag->ti_Data;
1692 else if (IS_PIXFMT_ATTR(tag->ti_Tag, idx))
1694 if (idx >= num_Hidd_PixFmt_Attrs)
1696 D(bug("!!! UNKNOWN PIXFMT ATTR IN Gfx::New(): %d !!!\n", idx));
1698 else
1700 def_pixfmt_tags[idx].ti_Tag = tag->ti_Tag;
1701 def_pixfmt_tags[idx].ti_Data = tag->ti_Data;
1706 ReleaseSemaphore(&mdb->sema);
1708 return TRUE;
1710 failure:
1712 /* mode db is freed in dispose */
1713 ReleaseSemaphore(&mdb->sema);
1715 return FALSE;
1718 /****************************************************************************************/
1720 struct modequery
1722 struct mode_db *mdb;
1723 ULONG minwidth;
1724 ULONG maxwidth;
1725 ULONG minheight;
1726 ULONG maxheight;
1727 HIDDT_StdPixFmt *stdpfs;
1728 ULONG numfound;
1729 ULONG pfidx;
1730 ULONG syncidx;
1731 BOOL dims_ok;
1732 BOOL stdpfs_ok;
1733 BOOL check_ok;
1734 OOP_Class *cl;
1737 /****************************************************************************************/
1739 /* This is a recursive function that looks for valid modes */
1741 /****************************************************************************************/
1743 static HIDDT_ModeID *querymode(struct modequery *mq)
1745 HIDDT_ModeID *modeids;
1746 register OOP_Object *pf;
1747 register OOP_Object *sync;
1748 BOOL mode_ok = FALSE;
1749 ULONG syncidx, pfidx;
1751 mq->dims_ok = FALSE;
1752 mq->stdpfs_ok = FALSE;
1753 mq->check_ok = FALSE;
1755 /* Look at the supplied idx */
1756 if (mq->pfidx >= mq->mdb->num_pixfmts)
1758 mq->pfidx = 0;
1759 mq->syncidx ++;
1762 if (mq->syncidx >= mq->mdb->num_syncs)
1764 /* We have reached the end of the recursion. Allocate memory and go back
1767 modeids = AllocVec(sizeof (HIDDT_ModeID) * (mq->numfound + 1), MEMF_ANY);
1768 /* Get the end of the array */
1769 modeids += mq->numfound;
1770 *modeids = vHidd_ModeID_Invalid;
1772 return modeids;
1775 syncidx = mq->syncidx;
1776 pfidx = mq->pfidx;
1777 /* Get the pf and sync objects */
1778 pf = mq->mdb->pixfmts[syncidx];
1779 sync = mq->mdb->syncs[pfidx];
1782 /* Check that the mode is really usable */
1783 if (is_valid_mode(&mq->mdb->checked_mode_bm, syncidx, pfidx))
1785 mq->check_ok = TRUE;
1788 /* See if this mode matches the criterias set */
1790 if ( SD(sync)->hdisp >= mq->minwidth
1791 && SD(sync)->hdisp <= mq->maxwidth
1792 && SD(sync)->vdisp >= mq->minheight
1793 && SD(sync)->vdisp <= mq->maxheight )
1797 mq->dims_ok = TRUE;
1799 if (NULL != mq->stdpfs)
1801 register HIDDT_StdPixFmt *stdpf = mq->stdpfs;
1802 while (*stdpf)
1804 if (*stdpf == PF(pf)->stdpixfmt)
1806 mq->stdpfs_ok = TRUE;
1808 stdpf ++;
1811 else
1813 mq->stdpfs_ok = TRUE;
1819 if (mq->dims_ok && mq->stdpfs_ok && mq->check_ok)
1821 mode_ok = TRUE;
1822 mq->numfound ++;
1825 mq->pfidx ++;
1827 modeids = querymode(mq);
1829 if (NULL == modeids)
1830 return NULL;
1832 if (mode_ok)
1834 /* The mode is OK. Add it to the list */
1835 modeids --;
1836 *modeids = COMPUTE_HIDD_MODEID(syncidx, pfidx);
1839 return modeids;
1843 /*****************************************************************************************
1845 NAME
1846 moHidd_Gfx_QueryModeIDs
1848 SYNOPSIS
1849 HIDDT_ModeID *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryModeIDs *msg);
1851 HIDDT_ModeID *HIDD_Gfx_QueryModeIDs(OOP_Object *gfxHidd, struct TagItem *queryTags);
1853 LOCATION
1854 hidd.graphics.graphics
1856 FUNCTION
1857 Obtain a table of all supported display mode IDs
1859 The returned address points to an array of HIDDT_ModeID containing all ModeIDs
1860 supported by this driver. The array is terminated with vHidd_ModeID_Invalid.
1862 INPUTS
1863 gfxHidd - A driver object which to query.
1864 querytags - An optional taglist containing query options. Can be NULL.
1865 The following tags are supported:
1867 tHidd_GfxMode_MinWidth (ULONG) - A minimum width of modes you are
1868 interested in
1869 tHidd_GfxMode_MaxWidth (ULONG) - A maximum width of modes you are
1870 interested in
1871 tHidd_GfxMode_MinHeight (ULONG) - A minimum height of modes you are
1872 interested in
1873 tHidd_GfxMode_MaxHeight (ULONG) - A maximum height of modes you are
1874 interested in
1875 tHidd_GfxMode_PixFmts (HIDDT_StdPifXmt *) - A pointer to an array
1876 of standard pixelformat indexes. If supplied, only mode IDs whose
1877 pixelformat numbers match any of given ones will be returned.
1879 RESULT
1880 A pointer to an array of ModeIDs or NULL in case of failure
1882 NOTES
1884 EXAMPLE
1886 BUGS
1888 SEE ALSO
1889 moHidd_Gfx_ReleaseModeIDs, moHidd_Gfx_NextModeID
1891 INTERNALS
1893 *****************************************************************************************/
1895 HIDDT_ModeID *GFX__Hidd_Gfx__QueryModeIDs(OOP_Class *cl, OOP_Object *o,
1896 struct pHidd_Gfx_QueryModeIDs *msg)
1898 struct TagItem *tag, *tstate;
1900 HIDDT_ModeID *modeids;
1901 struct HIDDGraphicsData *data;
1902 struct mode_db *mdb;
1904 struct modequery mq =
1906 NULL, /* mode db (set later) */
1907 0, 0xFFFFFFFF, /* minwidth, maxwidth */
1908 0, 0xFFFFFFFF, /* minheight, maxheight */
1909 NULL, /* stdpfs */
1910 0, /* numfound */
1911 0, 0, /* pfidx, syncidx */
1912 FALSE, FALSE, /* dims_ok, stdpfs_ok */
1913 FALSE, /* check_ok */
1914 NULL /* class (set later) */
1919 data = OOP_INST_DATA(cl, o);
1920 mdb = &data->mdb;
1921 mq.mdb = mdb;
1922 mq.cl = cl;
1924 for (tstate = msg->queryTags; (tag = NextTagItem((const struct TagItem **)&tstate)); )
1926 switch (tag->ti_Tag)
1928 case tHidd_GfxMode_MinWidth:
1929 mq.minwidth = (ULONG)tag->ti_Tag;
1930 break;
1932 case tHidd_GfxMode_MaxWidth:
1933 mq.maxwidth = (ULONG)tag->ti_Tag;
1934 break;
1936 case tHidd_GfxMode_MinHeight:
1937 mq.minheight = (ULONG)tag->ti_Tag;
1938 break;
1940 case tHidd_GfxMode_MaxHeight:
1941 mq.maxheight = (ULONG)tag->ti_Tag;
1942 break;
1944 case tHidd_GfxMode_PixFmts:
1945 mq.stdpfs = (HIDDT_StdPixFmt *)tag->ti_Data;
1946 break;
1951 ObtainSemaphoreShared(&mdb->sema);
1953 /* Recursively check all modes */
1954 modeids = querymode(&mq);
1956 ReleaseSemaphore(&mdb->sema);
1958 return modeids;
1962 /*****************************************************************************************
1964 NAME
1965 moHidd_Gfx_ReleaseModeIDs
1967 SYNOPSIS
1968 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ReleaseModeIDs *msg);
1970 VOID HIDD_Gfx_ReleaseModeIDs(OOP_Object *gfxHidd, HIDDT_ModeID *modeIDs);
1972 LOCATION
1973 hidd.graphics.graphics
1975 FUNCTION
1976 Free array of display mode IDs returned by HIDD_Gfx_QueryModeIDs()
1978 INPUTS
1979 gfxHidd - A driver object used to obtain the array
1980 modeIDs - A pointer to an array
1982 RESULT
1983 None.
1985 NOTES
1987 EXAMPLE
1989 BUGS
1991 SEE ALSO
1992 moHidd_Gfx_QueryModeIDs
1994 INTERNALS
1996 *****************************************************************************************/
1998 VOID GFX__Hidd_Gfx__ReleaseModeIDs(OOP_Class *cl, OOP_Object *o,
1999 struct pHidd_Gfx_ReleaseModeIDs *msg)
2001 FreeVec(msg->modeIDs);
2004 /*****************************************************************************************
2006 NAME
2007 moHidd_Gfx_NextModeID
2009 SYNOPSIS
2010 HIDDT_ModeID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NextModeID *msg);
2012 HIDDT_ModeID HIDD_Gfx_NextModeID(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2013 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2015 LOCATION
2016 hidd.graphics.graphics
2018 FUNCTION
2019 Iterate driver's internal display mode database.
2021 INPUTS
2022 gfxHidd - A driver object to query
2023 modeID - A previous mode ID or vHidd_ModeID_Invalid for start of the iteration
2024 syncPtr - A pointer to a storage where pointer to sync object will be placed
2025 pixFmtPtr - A pointer to a storage where pointer to pixelformat object will be placed
2027 RESULT
2028 Next available mode ID or vHidd_ModeID_Invalid if there are no more display modes.
2029 If the function returns vHidd_ModeID_Invalid, sync and pixelformat pointers will
2030 be set to NULL.
2032 NOTES
2034 EXAMPLE
2036 BUGS
2038 SEE ALSO
2039 moHidd_Gfx_GetMode
2041 INTERNALS
2043 *****************************************************************************************/
2045 HIDDT_ModeID GFX__Hidd_Gfx__NextModeID(OOP_Class *cl, OOP_Object *o,
2046 struct pHidd_Gfx_NextModeID *msg)
2048 struct HIDDGraphicsData *data;
2049 struct mode_db *mdb;
2050 ULONG syncidx, pfidx;
2051 HIDDT_ModeID return_id = vHidd_ModeID_Invalid;
2052 BOOL found = FALSE;
2054 data = OOP_INST_DATA(cl, o);
2055 mdb = &data->mdb;
2057 ObtainSemaphoreShared(&mdb->sema);
2058 if (vHidd_ModeID_Invalid == msg->modeID)
2060 pfidx = 0;
2061 syncidx = 0;
2063 else
2065 pfidx = MODEID_TO_PFIDX( msg->modeID );
2066 syncidx = MODEID_TO_SYNCIDX( msg->modeID );
2068 /* Increament one from the last call */
2069 pfidx ++;
2070 if (pfidx >= mdb->num_pixfmts)
2072 pfidx = 0;
2073 syncidx ++;
2077 /* Search for a new mode. We only accept valid modes */
2078 for (; syncidx < mdb->num_syncs; syncidx ++)
2080 /* We only return valid modes */
2081 for (; pfidx < mdb->num_pixfmts; pfidx ++)
2083 if (is_valid_mode(&mdb->checked_mode_bm, syncidx, pfidx))
2085 found = TRUE;
2086 break;
2089 if (found)
2090 break;
2093 if (found)
2095 return_id = COMPUTE_HIDD_MODEID(syncidx, pfidx);
2096 *msg->syncPtr = mdb->syncs[syncidx];
2097 *msg->pixFmtPtr = mdb->pixfmts[pfidx];
2099 else
2101 *msg->syncPtr = *msg->pixFmtPtr = NULL;
2104 ReleaseSemaphore(&mdb->sema);
2106 return return_id;
2109 /*****************************************************************************************
2111 NAME
2112 moHidd_Gfx_GetMode
2114 SYNOPSIS
2115 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMode *msg);
2117 BOOL HIDD_Gfx_GetMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
2118 OOP_Object **syncPtr, OOP_Object **pixFmtPtr);
2120 LOCATION
2121 hidd.graphics.graphics
2123 FUNCTION
2124 Get sync and pixelformat objects for a particular display ModeID.
2126 INPUTS
2127 gfxHidd - pointer to a driver object which this ModeID belongs to
2128 syncPtr - pointer to a storage where sync object pointer will be placed
2129 pixFmtPtr - pointer to a storage where pixelformat object pointer will be placed
2131 RESULT
2132 TRUE upon success, FALSE in case of failure (e.g. given mode does not exist in
2133 driver's internal database). If the function returns FALSE, sync and pixelformat
2134 pointers will be set to NULL.
2136 NOTES
2137 Every display mode is associated with some sync and pixelformat object. If the
2138 method returns TRUE, object pointers are guaranteed to be valid.
2140 EXAMPLE
2142 BUGS
2144 SEE ALSO
2145 moHidd_Gfx_NextModeID
2147 INTERNALS
2149 *****************************************************************************************/
2151 BOOL GFX__Hidd_Gfx__GetMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetMode *msg)
2153 ULONG pfidx, syncidx;
2154 struct HIDDGraphicsData *data;
2155 struct mode_db *mdb;
2156 BOOL ok = FALSE;
2158 data = OOP_INST_DATA(cl, o);
2159 mdb = &data->mdb;
2161 pfidx = MODEID_TO_PFIDX(msg->modeID);
2162 syncidx = MODEID_TO_SYNCIDX(msg->modeID);
2164 ObtainSemaphoreShared(&mdb->sema);
2166 if (! (pfidx >= mdb->num_pixfmts || syncidx >= mdb->num_syncs) )
2168 if (is_valid_mode(&mdb->checked_mode_bm, syncidx, pfidx))
2170 ok = TRUE;
2171 *msg->syncPtr = mdb->syncs[syncidx];
2172 *msg->pixFmtPtr = mdb->pixfmts[pfidx];
2176 ReleaseSemaphore(&mdb->sema);
2178 if (!ok)
2180 *msg->syncPtr = *msg->pixFmtPtr = NULL;
2183 return ok;
2186 /*****************************************************************************************
2188 NAME
2189 moHidd_Gfx_SetMode
2191 SYNOPSIS
2192 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetMode *msg);
2194 BOOL HIDD_Gfx_SetMode(OOP_Object *gfxHidd, OOP_Object *sync);
2196 LOCATION
2197 hidd.graphics.graphics
2199 FUNCTION
2200 Update display mode according to changed sync object
2202 INPUTS
2203 gfxHidd - A display driver to operate on
2204 sync - A modified sync object pointer
2206 RESULT
2207 TRUE if everything went OK and FALSE in case of some error
2209 NOTES
2210 This method is used to inform the driver that some external program has changed
2211 sync data and wants to update the display if needed. It's up to the implementation to
2212 check that current display is really using this sync (frontmost screen uses this mode).
2214 EXAMPLE
2216 BUGS
2218 SEE ALSO
2220 INTERNALS
2221 Base class implementation just returns FALSE indicating that this method is
2222 not supported.
2224 *****************************************************************************************/
2226 BOOL GFX__Hidd_Gfx__SetMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetMode *msg)
2228 return FALSE;
2231 /****************************************************************************************/
2233 static VOID copy_bm_and_colmap(OOP_Class *cl, OOP_Object *o, OOP_Object *src_bm,
2234 OOP_Object *dst_bm, ULONG width, ULONG height)
2236 struct HIDDGraphicsData *data;
2237 ULONG i;
2238 IPTR numentries;
2239 OOP_Object *src_colmap;
2240 APTR psrc_colmap = &src_colmap;
2242 data = OOP_INST_DATA(cl, o);
2244 /* We have to copy the colormap into the framebuffer bitmap */
2245 OOP_GetAttr(src_bm, aHidd_BitMap_ColorMap, (IPTR *)psrc_colmap);
2246 OOP_GetAttr(src_colmap, aHidd_ColorMap_NumEntries, &numentries);
2248 for (i = 0; i < numentries; i ++)
2250 HIDDT_Color col;
2252 HIDD_CM_GetColor(src_colmap, i, &col);
2253 HIDD_BM_SetColors(dst_bm, &col, i, 1);
2256 HIDD_Gfx_CopyBox(o
2257 , src_bm
2258 , 0, 0
2259 , dst_bm
2260 , 0, 0
2261 , width, height
2262 , data->gc
2266 /*****************************************************************************************
2268 NAME
2269 moHidd_Gfx_Show
2271 SYNOPSIS
2272 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Show *msg);
2274 OOP_Object *HIDD_Gfx_Show(OOP_Object *gfxHidd, OOP_Object *bitMap, ULONG flags);
2276 LOCATION
2277 hidd.graphics.graphics
2279 FUNCTION
2280 Change currently displayed bitmap on the screen.
2282 The bitmap object supplied must have been created with aHidd_BitMap_Displayable
2283 attribute set to TRUE.
2285 The function's behavior differs a lot depending on whether the driver uses a
2286 framebuffer or video hardware is able to switch screens itself.
2288 If the driver uses a framebuffer bitmap, it is supposed to copy the supplied bitmap
2289 into the framebuffer and return a framebuffer pointer. It also can be asked to
2290 copy back old framebuffer contents into previous bitmap object. It is driver's
2291 job to keep track of which bitmap object was displayed last time. This is what
2292 default implementation does. Note that it is very basic, and even does not support
2293 changing display resolution. It's not recommended to rely on it in production
2294 drivers (unless your video hardware supports only one mode).
2296 If the driver does not use a framebuffer, it is supposed to reprogram the hardware
2297 here to display an appropriate region of video RAM. Do not call the base class
2298 in this case, its implementation relies on framebuffer existance and will always
2299 return NULL which indicates an error.
2301 It is valid to get NULL value in bitMap parameter. This means that there is
2302 nothing to display and the screen needs to be blanked out. It is valid for
2303 non-framebuffer-based driver to return NULL as a reply then. In all other cases
2304 NULL return value means an error.
2306 Please avoid returning errors at all. graphics.library/LoadView() has no error
2307 indication. An error during showing a bitmap would leave the display in
2308 unpredictable state.
2310 If the driver does not use a framebuffer, consider using HIDD_Gfx_ShowViewPorts().
2311 It's more straightforward, flexible and offers support for screen composition.
2313 INPUTS
2314 gfxHidd - a display driver object, whose display you wish to change.
2315 bitMap - a pointer to a bitmap object which needs to be shown or NULL.
2316 flags - currently only one flag is defined:
2318 fHidd_Gfx_Show_CopyBack - Copy back the image data from framebuffer bitmap
2319 to old displayed bitmap. Used only if the driver
2320 needs a framebuffer.
2322 RESULT
2323 A pointer to a currently displayed bitmap object or NULL (read FUNCTION paragraph for
2324 detailed description)
2326 NOTES
2327 Drivers which use mirrored video data buffer do not have to update the display
2328 immediately in this method. moHidd_BitMap_UpdateRect will be sent to the returned
2329 bitmap if it's not NULL. Of course display blanking (if NULL bitmap was received)
2330 needs to be performed immediately.
2332 EXAMPLE
2334 BUGS
2336 SEE ALSO
2337 moHidd_Gfx_ShowViewPorts, graphics.library/LoadView()
2339 INTERNALS
2341 *****************************************************************************************/
2343 OOP_Object *GFX__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Show *msg)
2345 struct HIDDGraphicsData *data;
2346 OOP_Object *bm;
2347 IPTR displayable;
2348 IPTR oldwidth = 0;
2349 IPTR oldheight = 0;
2350 IPTR newwidth = 0;
2351 IPTR newheight = 0;
2352 struct TagItem gctags[] =
2354 { aHidd_GC_DrawMode , vHidd_GC_DrawMode_Copy},
2355 { aHidd_GC_Foreground, 0 },
2356 { TAG_DONE , 0UL }
2359 data = OOP_INST_DATA(cl, o);
2360 bm = msg->bitMap;
2362 /* We have to do some consistency checking */
2363 if (bm)
2365 OOP_GetAttr(bm, aHidd_BitMap_Displayable, &displayable);
2368 if (bm && !displayable)
2369 /* We cannot show a non-displayable bitmap */
2370 return NULL;
2372 if (NULL == data->framebuffer)
2373 return NULL;
2375 OOP_SetAttrs(data->gc, gctags);
2376 if (NULL != data->shownbm)
2378 OOP_GetAttr(data->shownbm, aHidd_BitMap_Width, &oldwidth);
2379 OOP_GetAttr(data->shownbm, aHidd_BitMap_Height, &oldheight);
2380 /* Copy the framebuffer data back into the old shown bitmap */
2381 if (msg->flags & fHidd_Gfx_Show_CopyBack)
2382 copy_bm_and_colmap(cl, o, data->framebuffer, data->shownbm, oldwidth, oldheight);
2385 if (bm) {
2386 OOP_GetAttr(bm, aHidd_BitMap_Width, &newwidth);
2387 OOP_GetAttr(bm, aHidd_BitMap_Height, &newheight);
2388 copy_bm_and_colmap(cl, o, bm, data->framebuffer, newwidth, newheight);
2390 /* Clear remaining parts of the framebuffer (if previous bitmap was larger than new one) */
2391 if (oldheight) {
2392 if (newwidth < oldwidth)
2393 HIDD_BM_FillRect(data->framebuffer, data->gc, newwidth, 0, oldwidth - 1, oldheight - 1);
2394 if ((newheight < oldheight) && newwidth)
2395 HIDD_BM_FillRect(data->framebuffer, data->gc, 0, newheight, newwidth - 1, oldheight);
2398 data->shownbm = bm;
2400 return data->framebuffer;
2403 /*****************************************************************************************
2405 NAME
2406 moHidd_Gfx_ShowViewPorts
2408 SYNOPSIS
2409 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ShowViewPorts *msg);
2411 ULONG HIDD_Gfx_ShowViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view);
2413 LOCATION
2414 hidd.graphics.graphics
2416 FUNCTION
2417 Show one or more bitmaps on the screen.
2419 It is completely up to the driver how to implement this function. The driver may
2420 or may not support hardware-assisted screens composition. Bitmaps are sorted
2421 in the list in descending z-order. The driver is expected to put at least frontmost
2422 bitmap on display.
2424 It is valid to get NULL pointer as data parameter. This means that there's
2425 nothing to show and the screen should go blank.
2427 Bitmaps display offsets are stored in their aHidd_BitMap_LeftEdge and
2428 aHidd_BitMap_TopEdge attributes. This function is not expected to modify their
2429 values somehow. They are assumed to be preserved between calls unless changed
2430 explicitly by the system.
2432 If you implement this method, you don't have to implement HIDD_Gfx_Show() because
2433 it will never be called.
2435 Note that there is no more error indication - the driver is expected to be
2436 error-free here.
2438 INPUTS
2439 gfxHidd - a display driver object, whose display you wish to change.
2440 data - a singly linked list of bitmap objects to show
2442 RESULT
2443 TRUE if this method is supported by the driver, FALSE otherwise
2445 NOTES
2447 EXAMPLE
2449 BUGS
2451 SEE ALSO
2452 moHidd_Gfx_Show
2454 INTERNALS
2455 Default base class implementation simply returns FALSE. This causes
2456 the system to use HIDD_Gfx_Show() instead.
2458 *****************************************************************************************/
2460 ULONG GFX__Hidd_Gfx__ShowViewPorts(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ShowViewPorts *msg)
2462 /* By default we don't support screen composition (and this method too) */
2463 return FALSE;
2466 /*****************************************************************************************
2468 NAME
2469 moHidd_Gfx_SetCursorShape
2471 SYNOPSIS
2472 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorShape *msg);
2474 BOOL HIDD_Gfx_SetCursorShape(OOP_Object *gfxHidd, OOP_Object *shape,
2475 LONG xoffset, LONG yoffset);
2477 LOCATION
2478 hidd.graphics.graphics
2480 FUNCTION
2481 Set mouse pointer shape.
2483 A pointer image is contained in the specified bitmap object. The bitmap object
2484 may contain a colormap if the system wants to specify own colors for the pointer.
2485 The supplied colormap will also contain alpha channel values.
2487 It is up to driver what to do if, for example, alpha channel is not supported by
2488 the hardware. Or if given bitmap type is not supported (for example truecolor
2489 bitmap on LUT-only hardware). It is expected that the driver converts bitmap
2490 data to a more appropriate form in such a case.
2492 A hotspot is given as an offset from the actual hotspot to the top-left corner
2493 of the pointer image. It is generally needed only for hosted display drivers
2494 which utilize host's support for mouse pointer.
2496 The default implementation in the base class just does nothing. A software mouse
2497 pointer is implemented in a special layer called fakegfx.hidd inside
2498 graphics.library. If a software pointer emulation is used, this method will
2499 never be called.
2501 INPUTS
2502 gfxHidd - a display driver object, for whose display you wish to change the pointer
2503 shape - a pointer to a bitmap object, containing pointer bitmap
2504 xoffset - a horizontal hotspot offset
2505 yoffset - a vertical hotspot offset
2507 RESULT
2508 TRUE on success, FALSE on failure
2510 NOTES
2512 EXAMPLE
2514 BUGS
2516 SEE ALSO
2517 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2519 INTERNALS
2521 *****************************************************************************************/
2523 BOOL GFX__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o,
2524 struct pHidd_Gfx_SetCursorShape *msg)
2526 /* We have no clue how to render the cursor */
2527 return TRUE;
2530 /*****************************************************************************************
2532 NAME
2533 moHidd_Gfx_SetCursorVisible
2535 SYNOPSIS
2536 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorVisible *msg);
2538 VOID HIDD_Gfx_SetCursorVisible(OOP_Object *gfxHidd, BOOL visible);
2540 LOCATION
2541 hidd.graphics.graphics
2543 FUNCTION
2544 Control mouse pointer visiblity.
2546 The default implementation in the base class does nothing. If a software pointer
2547 emulation is used, this method will never be called.
2549 INPUTS
2550 gfxHidd - a display driver object, on whose display you wish to turn
2551 pointer on or off
2552 visible - TRUE to enable pointer display, FALSE to disable it
2554 RESULT
2555 None.
2557 NOTES
2559 EXAMPLE
2561 BUGS
2563 SEE ALSO
2564 moHidd_Gfx_SetCursorPos, moHidd_Gfx_SetCursorVisible
2566 INTERNALS
2568 *****************************************************************************************/
2570 VOID GFX__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorVisible *msg)
2575 /*****************************************************************************************
2577 NAME
2578 moHidd_Gfx_SetCursorPos
2580 SYNOPSIS
2581 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_SetCursorPos *msg);
2583 BOOL HIDD_Gfx_SetCursorPos(OOP_Object *gfxHidd, LONG x, LONG y);
2585 LOCATION
2586 hidd.graphics.graphics
2588 FUNCTION
2589 Set current mouse pointer position.
2591 This is a real position on top-left image corner relative to top-left corner of
2592 the physical display. Neither logical screen origin nor hotspot are taken into
2593 account here.
2595 The default implementation in the base class does nothing and just returns TRUE.
2596 If a software pointer emulation is used, this method will never be called.
2598 INPUTS
2599 gfxHidd - a display driver object, on whose display you wish to position the pointer
2600 x - An x coordinate of the pointer (relative to the physical screen origin)
2601 y - An y coordinate of the pointer (relative to the physical screen origin)
2603 RESULT
2604 Always TRUE. Reserved for future, do not use it.
2606 NOTES
2607 This method is called by graphics.library/MoveSprite() which has no return value.
2608 However, for historical reasons, this method has a return value. Drivers should
2609 always return TRUE in order to ensure future compatibility.
2611 EXAMPLE
2613 BUGS
2615 SEE ALSO
2616 moHidd_Gfx_SetCursorShape, moHidd_Gfx_SetCursorVisible, graphics.library/MoveSprite()
2618 INTERNALS
2620 *****************************************************************************************/
2622 BOOL GFX__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorPos *msg)
2624 return TRUE;
2627 /*****************************************************************************************
2629 NAME
2630 moHidd_Gfx_CopyBox
2632 SYNOPSIS
2633 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg);
2635 VOID HIDD_Gfx_CopyBox(OOP_Object *gfxHidd, OOP_Object *src, WORD srcX, WORD srcY,
2636 OOP_Object *dest, WORD destX, WORD destY, UWORD width, UWORD height,
2637 OOP_Object *gc);
2639 LOCATION
2640 hidd.graphics.graphics
2642 FUNCTION
2643 Perform rectangle copy (blit) operation from one bitmap to another.
2645 Given bitmaps may belong to different display drivers. The driver may attempt to
2646 use hardware for acceleration (if available), and if it's impossible, pass the
2647 operation on to the base class.
2649 Always check class of the supplied bitmap before attempting to look at its
2650 private data.
2652 A GC is used in order to specify raster operation performed between the source
2653 and destination according to its aHidd_GC_DrawMode attribute value.
2655 INPUTS
2656 gfxHidd - a display driver object that you are going to use for copying
2657 src - a pointer to source bitmap object
2658 srcX - an X coordinate of the source rectangle
2659 srcY - an Y coordinate of the source rectangle
2660 dest - a pointer to destination bitmap object
2661 destX - an X coordinate of the destination rectangle
2662 destY - an Y coordinate of the destination rectangle
2663 width - width of the rectangle to copy
2664 height - height of the rectangle to copy
2665 gc - graphics context holding draw mode on the destination
2667 RESULT
2668 None.
2670 NOTES
2671 You must specify valid coordinates (non-negative and inside the actual bitmap
2672 area), no checks are done.
2674 It is valid to specify two overlapped areas of the same bitmap as source
2675 and destination.
2677 EXAMPLE
2679 BUGS
2681 SEE ALSO
2683 INTERNALS
2685 *****************************************************************************************/
2687 VOID GFX__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *obj, struct pHidd_Gfx_CopyBox *msg)
2689 WORD x, y;
2690 WORD srcX = msg->srcX, destX = msg->destX;
2691 WORD srcY = msg->srcY, destY = msg->destY;
2692 WORD startX, endX, deltaX, startY, endY, deltaY;
2693 ULONG memFG;
2695 HIDDT_PixelFormat *srcpf, *dstpf;
2696 OOP_Object *dest, *src;
2698 OOP_Object *gc;
2699 #if USE_FAST_GETPIXEL
2700 struct pHidd_BitMap_GetPixel get_p;
2701 #endif
2703 #if USE_FAST_DRAWPIXEL
2704 struct pHidd_BitMap_DrawPixel draw_p;
2706 draw_p.mID = CSD(cl)->drawpixel_mid;
2707 draw_p.gc = msg->gc;
2708 #endif
2710 #if USE_FAST_GETPIXEL
2711 get_p.mID = CSD(cl)->getpixel_mid;
2712 #endif
2714 dest = msg->dest;
2715 src = msg->src;
2717 /* If source/dest overlap, direction of operation is important */
2719 if (srcX < destX)
2721 startX = msg->width - 1; endX = -1; deltaX = -1;
2723 else
2725 startX = 0; endX = msg->width; deltaX = 1;
2728 if (srcY < destY)
2730 startY = msg->height - 1; endY = -1; deltaY = -1;
2732 else
2734 startY = 0; endY = msg->height; deltaY = 1;
2737 /* Get the source pixel format */
2738 srcpf = (HIDDT_PixelFormat *)HBM(src)->prot.pixfmt;
2740 /* bug("COPYBOX: SRC PF: %p, obj=%p, cl=%s, OOP_OCLASS: %s\n", srcpf, obj
2741 , cl->ClassNode.ln_Name, OOP_OCLASS(obj)->ClassNode.ln_Name);
2744 #if 0
2746 IPTR sw, sh, dw, dh;
2747 D(bug("COPYBOX: src=%p, dst=%p, width=%d, height=%d\n"
2748 , obj, msg->dest, msg->width, msg->height));
2750 OOP_GetAttr(obj, aHidd_BitMap_Width, &sw);
2751 OOP_GetAttr(obj, aHidd_BitMap_Height, &sh);
2752 OOP_GetAttr(msg->dest, aHidd_BitMap_Width, &dw);
2753 OOP_GetAttr(msg->dest, aHidd_BitMap_Height, &dh);
2754 D(bug("src dims: %d, %d dest dims: %d, %d\n", sw, sh, dw, dh));
2756 #endif
2758 dstpf = (HIDDT_PixelFormat *)HBM(dest)->prot.pixfmt;
2760 /* Compare graphtypes */
2761 if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf))
2763 /* It is ok to do a direct copy */
2765 else
2767 /* Find out the gfx formats */
2768 if ( IS_PALETTIZED(srcpf) && IS_TRUECOLOR(dstpf))
2772 else if (IS_TRUECOLOR(srcpf) && IS_PALETTIZED(dstpf))
2776 else if (IS_PALETTE(srcpf) && IS_STATICPALETTE(dstpf))
2780 else if (IS_STATICPALETTE(srcpf) && IS_PALETTE(dstpf))
2786 gc = msg->gc;
2788 memFG = GC_FG(msg->gc);
2790 /* All else have failed, copy pixel by pixel */
2793 if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf))
2795 if (IS_TRUECOLOR(srcpf))
2797 // bug("COPY FROM TRUECOLOR TO TRUECOLOR\n");
2798 for(y = startY; y != endY; y += deltaY)
2800 HIDDT_Color col;
2802 /* if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2803 bug("[%d,%d] ", memSrcX, memDestX);
2805 for(x = startX; x != endX; x += deltaX)
2807 HIDDT_Pixel pix;
2809 #if USE_FAST_GETPIXEL
2810 get_p.x = srcX + x;
2811 get_p.y = srcY + y;
2812 pix = GETPIXEL(src, &get_p);
2813 #else
2814 pix = HIDD_BM_GetPixel(obj, srcX + x, srcY + y);
2815 #endif
2817 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2818 if (srcpf == dstpf)
2820 GC_FG(gc) = pix;
2822 else
2824 #endif
2825 HIDD_BM_UnmapPixel(src, pix, &col);
2826 GC_FG(gc) = HIDD_BM_MapColor(msg->dest, &col);
2827 #if COPYBOX_CHECK_FOR_ALIKE_PIXFMT
2829 #endif
2831 // #if 0
2833 #if USE_FAST_DRAWPIXEL
2834 draw_p.x = destX + x;
2835 draw_p.y = destY + y;
2836 DRAWPIXEL(dest, &draw_p);
2837 #else
2839 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2840 #endif
2842 // #endif
2844 /*if (0 == strcmp("CON: Window", FindTask(NULL)->tc_Node.ln_Name))
2845 bug("[%d,%d] ", srcY, destY);
2849 } /* if (IS_TRUECOLOR(srcpf)) */
2850 else
2852 /* Two palette bitmaps.
2853 For this case we do NOT convert through RGB,
2854 but copy the pixel indexes directly
2856 // bug("COPY FROM PALETTE TO PALETTE\n");
2858 /* FIXME: This might not work very well with two StaticPalette bitmaps */
2860 for(y = startY; y != endY; y += deltaY)
2862 for(x = startX; x != endX; x += deltaX)
2864 GC_FG(gc) = HIDD_BM_GetPixel(src, srcX + x, srcY + y);
2866 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2871 } /* if (IS_TRUECOLOR(srcpf)) else ... */
2873 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) */
2874 else
2876 /* Two unlike bitmaps */
2877 if (IS_TRUECOLOR(srcpf))
2879 /* FIXME: Implement this */
2880 D(bug("!! DEFAULT COPYING FROM TRUECOLOR TO PALETTIZED NOT IMPLEMENTED IN BitMap::CopyBox\n"));
2882 else if (IS_TRUECOLOR(dstpf))
2884 /* Get the colortab */
2885 HIDDT_Color *ctab = ((HIDDT_ColorLUT *)HBM(src)->colmap)->colors;
2887 // bug("COPY FROM PALETTE TO TRUECOLOR, DRAWMODE %d, CTAB %p\n", GC_DRMD(gc), ctab);
2889 for(y = startY; y != endY; y += deltaY)
2891 for(x = startX; x != endX; x += deltaX)
2893 register HIDDT_Pixel pix;
2894 register HIDDT_Color *col;
2896 pix = HIDD_BM_GetPixel(src, srcX + x, srcY + y);
2897 col = &ctab[pix];
2899 GC_FG(gc) = HIDD_BM_MapColor(msg->dest, col);
2900 HIDD_BM_DrawPixel(msg->dest, gc, destX + x, destY + y);
2906 } /* if (HIDD_PF_COLMODEL(srcpf) == HIDD_PF_COLMODEL(dstpf)) else ... */
2908 GC_FG(gc) = memFG;
2911 /*****************************************************************************************
2913 NAME
2914 moHidd_Gfx_ShowImminentReset
2916 SYNOPSIS
2917 VOID OOP_DoMethod(OOP_Object *obj, OOP_Msg msg);
2919 LOCATION
2920 hidd.graphics.graphics
2922 FUNCTION
2923 Indicate upcoming machine reset. Obsolete.
2925 Since graphics.library v41.4 this method is not used any more. Considered
2926 reserved. Do not use it in any way.
2928 INPUTS
2929 None.
2931 RESULT
2932 None.
2934 NOTES
2936 EXAMPLE
2938 BUGS
2940 SEE ALSO
2942 INTERNALS
2944 *****************************************************************************************/
2946 VOID GFX__Hidd_Gfx__ShowImminentReset(OOP_Class *cl, OOP_Object *obj, OOP_Msg msg)
2950 /****************************************************************************************/
2952 OOP_Object *GFX__Hidd_Gfx__RegisterPixFmt(OOP_Class *cl, OOP_Object *o,
2953 struct pHidd_Gfx_RegisterPixFmt *msg)
2955 HIDDT_PixelFormat cmp_pf;
2956 struct class_static_data *data;
2957 struct pixfmt_data *retpf = NULL;
2959 memset(&cmp_pf, 0, sizeof(cmp_pf));
2961 data = CSD(cl);
2962 if (!parse_pixfmt_tags(msg->pixFmtTags, &cmp_pf, 0, CSD(cl)))
2964 D(bug("!!! FAILED PARSING TAGS IN Gfx::RegisterPixFmt() !!!\n"));
2965 return FALSE;
2968 DPF(bug("Gfx::RegisterPixFmt(): Registering pixelformat:\n"));
2969 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
2970 , PF(&cmp_pf)->red_shift
2971 , PF(&cmp_pf)->green_shift
2972 , PF(&cmp_pf)->blue_shift
2973 , PF(&cmp_pf)->alpha_shift
2974 , PF(&cmp_pf)->red_mask
2975 , PF(&cmp_pf)->green_mask
2976 , PF(&cmp_pf)->blue_mask
2977 , PF(&cmp_pf)->alpha_mask
2978 , PF(&cmp_pf)->bytes_per_pixel
2979 , PF(&cmp_pf)->size
2980 , PF(&cmp_pf)->depth
2981 , PF(&cmp_pf)->stdpixfmt));
2983 retpf = find_pixfmt(&cmp_pf, CSD(cl));
2985 DPF(bug("Found matching pixelformat: 0x%p\n", retpf));
2986 if (retpf)
2987 /* Increase pf refcount */
2988 AROS_ATOMIC_INC(retpf->refcount);
2989 else {
2990 /* Could not find an alike pf, Create a new pfdb node */
2991 /* Since we pass NULL as the taglist below, the PixFmt class will just create a dummy pixfmt */
2992 retpf = OOP_NewObject(CSD(cl)->pixfmtclass, NULL, NULL);
2993 if (retpf) {
2994 /* We have one user */
2995 retpf->refcount = 1;
2997 /* Initialize the pixfmt object the "ugly" way */
2998 memcpy(retpf, &cmp_pf, sizeof (HIDDT_PixelFormat));
3000 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n"
3001 , PF(&cmp_pf)->red_shift
3002 , PF(&cmp_pf)->green_shift
3003 , PF(&cmp_pf)->blue_shift
3004 , PF(&cmp_pf)->alpha_shift
3005 , PF(&cmp_pf)->red_mask
3006 , PF(&cmp_pf)->green_mask
3007 , PF(&cmp_pf)->blue_mask
3008 , PF(&cmp_pf)->alpha_mask
3009 , PF(&cmp_pf)->bytes_per_pixel
3010 , PF(&cmp_pf)->size
3011 , PF(&cmp_pf)->depth
3012 , PF(&cmp_pf)->stdpixfmt));
3014 ObtainSemaphore(&data->pfsema);
3015 AddTail((struct List *)&data->pflist, (struct Node *)&retpf->node);
3016 ReleaseSemaphore(&data->pfsema);
3020 DPF(bug("New refcount is %u\n", retpf->refcount));
3021 return (OOP_Object *)retpf;
3024 /****************************************************************************************/
3026 VOID GFX__Hidd_Gfx__ReleasePixFmt(OOP_Class *cl, OOP_Object *o,
3027 struct pHidd_Gfx_ReleasePixFmt *msg)
3029 struct class_static_data *data;
3030 struct pixfmt_data *pixfmt = (struct pixfmt_data *)msg->pixFmt;
3032 DPF(bug("release_pixfmt 0x%p\n", pixfmt));
3034 data = CSD(cl);
3036 ObtainSemaphore(&data->pfsema);
3038 /* If refcount is already 0, this object was never registered in the database,
3039 don't touch it */
3040 DPF(bug("Old reference count is %u\n", pixfmt->refcount));
3041 if (pixfmt->refcount) {
3042 if (--pixfmt->refcount == 0) {
3043 Remove((struct Node *)&pixfmt->node);
3044 OOP_DisposeObject((OOP_Object *)pixfmt);
3048 ReleaseSemaphore(&data->pfsema);
3051 /*****************************************************************************************
3053 NAME
3054 moHidd_Gfx_CheckMode
3056 SYNOPSIS
3057 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CheckMode *msg);
3059 BOOL HIDD_Gfx_CheckMode(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3060 OOP_Object *sync, OOP_Object *pixFmt);
3062 LOCATION
3063 hidd.graphics.graphics
3065 FUNCTION
3066 Check if given display mode is supported by the driver.
3068 Normally any resolution (sync) can be used together with any pixelformat. However
3069 on some hardware there may be exceptions from this rule. In such a case this
3070 method should be implemented, and check should be performed.
3072 The information provided by this method is used in order to exclude unsupported
3073 modes from the database
3075 Default implementation in the base class just returns TRUE for all supplied values.
3077 Note that this method can not be used in order to chech that the given mode is
3078 really present in the database and it really refers to the given sync and
3079 pixelformat objects. Use HIDD_Gfx_GetMode() for mode ID validation.
3081 INPUTS
3082 gfxHidd - A display driver object
3083 modeID - A display mode ID
3084 sync - A pointer to a sync object associated with this mode
3085 pixFmt - A pointer to a pixelformat object associated with this mode
3087 RESULT
3088 TRUE if this mode is supported and FALSE if it's not.
3090 NOTES
3092 EXAMPLE
3094 BUGS
3095 Currently base class does not call this method after driver object creation.
3096 This needs to be fixed.
3098 SEE ALSO
3099 moHidd_Gfx_GetMode
3101 INTERNALS
3103 *****************************************************************************************/
3105 BOOL GFX__Hidd_Gfx__CheckMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CheckMode *msg)
3107 /* As a default we allways return TRUE, ie. the mode is OK */
3108 return TRUE;
3111 /*****************************************************************************************
3113 NAME
3114 moHidd_Gfx_GetPixFmt
3116 SYNOPSIS
3117 OOP_Object *OOP_DoMethod(OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg);
3119 OOP_Object *HIDD_Gfx_GetPixFmt(OOP_Object *gfxHidd, HIDDT_StdPixFmt pixFmt);
3121 LOCATION
3122 hidd.graphics.graphics
3124 FUNCTION
3125 Get a standard pixelformat descriptor from internal pixelformats database.
3127 INPUTS
3128 gfxHidd - A display driver object
3129 pixFmt - An index of pixelformat (one of vHIDD_StdPixFmt_... values)
3131 RESULT
3132 A pointer to a pixelformat object or NULL if lookup failed
3134 NOTES
3135 Pixelformat objects are stored in a global system-wide database. They are not
3136 linked with a particular driver in any way and completely sharable between all
3137 drivers.
3139 EXAMPLE
3141 BUGS
3143 SEE ALSO
3145 INTERNALS
3146 This operation can never fail because all standard pixelformats are registered
3147 during early system initialization.
3149 *****************************************************************************************/
3151 OOP_Object *GFX__Hidd_Gfx__GetPixFmt(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetPixFmt *msg)
3153 OOP_Object *fmt;
3155 if (!IS_REAL_STDPIXFMT(msg->stdPixFmt))
3157 D(bug("!!! Illegal pixel format passed to Gfx::GetPixFmt(): %d\n", msg->stdPixFmt));
3158 return NULL;
3160 else
3162 fmt = (OOP_Object *)CSD(cl)->std_pixfmts[REAL_STDPIXFMT_IDX(msg->stdPixFmt)];
3165 return fmt;
3168 /*****************************************************************************************
3170 NAME
3171 moHidd_Gfx_GetSync
3173 SYNOPSIS
3174 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetSync *msg);
3176 OOP_Object *HIDD_Gfx_GetSync(OOP_Object *gfxHidd, ULONG num);
3178 LOCATION
3179 hidd.graphics.graphics
3181 FUNCTION
3182 Get a sync object from internal display mode database by index
3184 INPUTS
3185 gfxHidd - A display driver object to query
3186 num - An index of sync object starting from 0
3188 RESULT
3189 A pointer to a sync object or NULL if there's no sync with such index
3191 NOTES
3193 EXAMPLE
3195 BUGS
3197 SEE ALSO
3199 INTERNALS
3201 *****************************************************************************************/
3203 OOP_Object *GFX__Hidd_Gfx__GetSync(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetSync *msg)
3205 struct HIDDGraphicsData *data = OOP_INST_DATA(cl, o);
3207 if (msg->num < data->mdb.num_syncs)
3208 return data->mdb.syncs[msg->num];
3209 else {
3210 D(bug("!!! Illegal sync index passed to Gfx::GetSync(): %d\n", msg->num));
3211 return NULL;
3215 /*****************************************************************************************
3217 NAME
3218 moHidd_Gfx_ModeProperties
3220 SYNOPSIS
3221 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_ModeProperties *msg);
3223 ULONG HIDD_Gfx_ModeProperties(OOP_Object *gfxHidd, HIDDT_ModeID modeID,
3224 struct HIDD_ModeProperties *props, ULONG propsLen);
3226 LOCATION
3227 hidd.graphics.graphics
3229 FUNCTION
3230 Obtain an information about the video mode.
3232 Video mode description structure may grow in future, so be careful and always check
3233 propsLen parameter value. A system may ask you for less data than you can provide.
3234 Always return an actual value. Do not just zero out fields you don't know about,
3235 this is not expected to be backwards compatible.
3237 INPUTS
3238 gfxHidd - a pointer to a display driver object whose display mode you want to query
3239 modeID - a mode ID to query
3240 props - a pointer to a storage area where HIDD_ModeProperties structure will be put
3241 propsLen - length of the supplied buffer in bytes.
3243 RESULT
3244 Actual length of obtained structure
3246 NOTES
3247 Returned data must reflect only real hardware capabilities. For example, do not
3248 count emulated sprites. The system takes care about emulated features itself.
3250 EXAMPLE
3252 BUGS
3254 SEE ALSO
3255 aoHidd_Gfx_HWSpriteTypes, aoHidd_Gfx_SupportsHWCursor
3257 INTERNALS
3258 Default implementation in the base class relies on aHidd_Gfx_HWSpriteTypes attribute,
3259 not vice versa. If you override this method, do not forget to override this attribute too.
3261 *****************************************************************************************/
3263 ULONG GFX__Hidd_Gfx__ModeProperties(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ModeProperties *msg)
3265 struct HIDD_ModeProperties props = {0, 0, 0};
3266 IPTR has_hw_cursor = 0;
3267 ULONG len = msg->propsLen;
3269 D(bug("[GFXHIDD] Hidd::Gfx::ModeProperties(0x%08lX, 0x%p, %u)\n", msg->modeID, msg->props, msg->propsLen));
3270 OOP_GetAttr(o, aHidd_Gfx_HWSpriteTypes, &has_hw_cursor);
3271 if (has_hw_cursor) {
3272 D(bug("[GFXHIDD] Driver has hardware mouse cursor implementation\n"));
3273 props.DisplayInfoFlags = DIPF_IS_SPRITES;
3274 props.NumHWSprites = 1;
3277 if (len > sizeof(props))
3278 len = sizeof(props);
3279 D(bug("[GFXHIDD] Copying %u bytes\n", len));
3280 CopyMem(&props, msg->props, len);
3282 return len;
3285 /*****************************************************************************************
3287 NAME
3288 moHidd_Gfx_GetGamma
3290 SYNOPSIS
3291 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3293 BOOL HIDD_Gfx_GetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3295 LOCATION
3296 hidd.graphics.graphics
3298 FUNCTION
3299 Get current gamma table for the display.
3301 A gamma table consists of three 256-byte tables: one for red component, one for
3302 green and one for blue.
3304 A user should supply three pointers to preallocated 256-byte tables which will
3305 be filled in. Any ot these pointers may have NULL value, in this case the
3306 respective component will be ignored.
3308 INPUTS
3309 gfxHidd - A display driver object
3310 Red - A pointer to a 256-byte array for red component or NULL
3311 Green - A pointer to a 256-byte array for green component or NULL
3312 Blue - A pointer to a 256-byte array for blue component or NULL
3314 RESULT
3315 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3317 NOTES
3318 This method can be used just to query if the driver supports gamma correction.
3319 Just set Red, Green and Blue to NULL for this.
3321 EXAMPLE
3323 BUGS
3325 SEE ALSO
3326 moHidd_Gfx_SetGamma
3328 INTERNALS
3330 *****************************************************************************************/
3332 BOOL GFX__Hidd_Gfx__GetGamma(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Gamma *msg)
3334 return FALSE;
3337 /*****************************************************************************************
3339 NAME
3340 moHidd_Gfx_SetGamma
3342 SYNOPSIS
3343 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_Gamma *msg);
3345 BOOL HIDD_Gfx_SetGamma(OOP_Object *gfxHidd, UBYTE *Red, UBYTE *Green, UBYTE *Blue);
3347 LOCATION
3348 hidd.graphics.graphics
3350 FUNCTION
3351 Set current gamma table for the display.
3353 A gamma table consists of three 256-byte tables: one for red component, one for
3354 green and one for blue.
3356 A user should supply three pointers to 256-byte tables from which gamma values
3357 will be picked up. Any ot these pointers may have NULL value, in this case the
3358 respective component will be ignored.
3360 INPUTS
3361 gfxHidd - A display driver object
3362 Red - A pointer to a 256-byte array for red component or NULL
3363 Green - A pointer to a 256-byte array for green component or NULL
3364 Blue - A pointer to a 256-byte array for blue component or NULL
3366 RESULT
3367 FALSE if the driver doesn't support gamma correction, otherwise TRUE
3369 NOTES
3370 This method can be used just to query if the driver supports gamma correction.
3371 Just set Red, Green and Blue to NULL for this.
3373 EXAMPLE
3375 BUGS
3377 SEE ALSO
3378 moHidd_Gfx_GetGamma
3380 INTERNALS
3382 *****************************************************************************************/
3384 BOOL GFX__Hidd_Gfx__SetGamma(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_Gamma *msg)
3386 return FALSE;
3389 /*****************************************************************************************
3391 NAME
3392 moHidd_Gfx_QueryHardware3D
3394 SYNOPSIS
3395 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_QueryHardware3D *msg);
3397 BOOL HIDD_Gfx_QueryHardware3D(OOP_Object *gfxHidd, OOP_Object *pixFmt);
3399 LOCATION
3400 hidd.graphics.graphics
3402 FUNCTION
3403 Query if the driver supports hardware-accelerated 3D graphics for the given
3404 pixelformat.
3406 INPUTS
3407 gfxHidd - A display driver object
3408 pixFmt - A pointer to a pixelformat descriptor object
3410 RESULT
3411 TRUE if the driver supports hardware-accelerated 3D for the given pixelformat,
3412 FALSE otherwise.
3414 NOTES
3416 EXAMPLE
3418 BUGS
3420 SEE ALSO
3422 INTERNALS
3424 *****************************************************************************************/
3426 BOOL GFX__Hidd_Gfx__QueryHardware3D(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_QueryHardware3D *msg)
3428 return FALSE;
3431 /*****************************************************************************************
3433 NAME
3434 moHidd_Gfx_GetMaxSpriteSize
3436 SYNOPSIS
3437 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_GetMaxSpriteSize *msg);
3439 BOOL HIDD_Gfx_GetMaxSpriteSize(OOP_Object *gfxHidd, ULONG Type, ULONG *Width, ULONG *Height);
3441 LOCATION
3442 hidd.graphics.graphics
3444 FUNCTION
3445 Query maximum allowed size for the given sprite type.
3447 INPUTS
3448 gfxHidd - A display driver object
3449 Type - Type of the sprite image (one of vHidd_SpriteType_... values)
3450 Width - A pointer to ULONG where width will be placed.
3451 Height - A pointer to ULONG where height will be placed.
3453 RESULT
3454 FALSE is the given sprite type is not supported, otherwise TRUE.
3456 NOTES
3457 Default implementation in the base class just return some small values
3458 which it hopes can be supported by every driver if the driver supports given
3459 sprite type. It is strongly suggested to reimplement this method in the display
3460 driver.
3462 Width and Height are considered undefined if the method returns FALSE.
3464 EXAMPLE
3466 BUGS
3468 SEE ALSO
3470 INTERNALS
3472 *****************************************************************************************/
3474 BOOL GFX__Hidd_Gfx__GetMaxSpriteSize(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetMaxSpriteSize *msg)
3476 IPTR types;
3478 OOP_GetAttr(o, aHidd_Gfx_HWSpriteTypes, &types);
3480 if (types & msg->Type) {
3481 *msg->Width = 16;
3482 *msg->Height = 32;
3483 return TRUE;
3484 } else
3485 return FALSE;
3488 /*****************************************************************************************
3490 NAME
3491 moHidd_Gfx_NewOverlay
3493 SYNOPSIS
3494 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_NewOverlay *msg);
3496 OOP_Object *HIDD_Gfx_NewOverlay(OOP_Object *gfxHidd, struct TagItem *tagList);
3498 LOCATION
3499 hidd.graphics.graphics
3501 FUNCTION
3502 Create a video overlay object.
3504 INPUTS
3505 gfxHidd - A graphics driver object on whose display you want to create an overlay.
3506 tagList - A list of overlay attributes. See overlay class documentation for
3507 their description.
3509 RESULT
3510 Pointer to the newly created overlay object or NULL in case of failure.
3512 NOTES
3513 Default implementation in the base class always sets VOERR_INVSCRMODE error and
3514 returns NULL meaning that hardware overlays are not supported. There's no sense
3515 in software implementation because the software is supposed to handle software
3516 rendering itself.
3518 EXAMPLE
3520 BUGS
3522 SEE ALSO
3523 moHidd_Gfx_DisposeOverlay
3525 INTERNALS
3527 *****************************************************************************************/
3529 OOP_Object *GFX__Hidd_Gfx__NewOverlay(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewOverlay *msg)
3531 ULONG *err = (ULONG *)GetTagData(aHidd_Overlay_Error, 0, msg->attrList);
3533 if (err)
3534 *err = VOERR_INVSCRMODE;
3536 return NULL;
3539 /*****************************************************************************************
3541 NAME
3542 moHidd_Gfx_DisposeOverlay
3544 SYNOPSIS
3545 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_DisposeOverlay *msg);
3547 VOID HIDD_Gfx_DisposeOverlay(OOP_Object *gfxHidd, OOP_Object *Overlay)
3549 LOCATION
3550 hidd.graphics.graphics
3552 FUNCTION
3553 Deletes an overlay previously created by moHidd_Gfx_NewOverlay.
3555 Subclasses do not have to override this method
3556 unless they allocate anything additional to an overlay object in
3557 their HIDD_Gfx_NewOverlay() implementation.
3559 INPUTS
3560 gfxHidd - A driver object which was used for creating a GC.
3561 Overlay - Pointer to an overlay object to delete.
3563 RESULT
3564 None.
3566 NOTES
3568 EXAMPLE
3570 BUGS
3572 SEE ALSO
3573 moHidd_Gfx_NewGC
3575 INTERNALS
3576 Basically just does OOP_DisposeObject(Overlay);
3578 *****************************************************************************************/
3580 VOID GFX__Hidd_Gfx__DisposeOverlay(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_DisposeOverlay *msg)
3582 OOP_DisposeObject(msg->Overlay);
3585 /*****************************************************************************************
3587 NAME
3588 moHidd_Gfx_MakeViewPort
3590 SYNOPSIS
3591 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_MakeViewPort *msg);
3593 ULONG HIDD_Gfx_MakeViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3595 LOCATION
3596 hidd.graphics.graphics
3598 FUNCTION
3599 Performs driver-specific setup on a given ViewPort.
3601 INPUTS
3602 gfxHidd - A display driver object.
3603 data - a pointer to a HIDD_ViewPortDats structure.
3605 RESULT
3606 The same code as used as return value for graphics.library/MakeVPort().
3608 NOTES
3609 When graphics.library calls this method, a complete view is not built yet.
3610 This means that data->Next pointer contains invalid data and needs to be
3611 ignored.
3613 It is valid to keep private data pointer in data->UserData accross calls.
3614 Newly created HIDD_ViewPortData is guraranteed to have NULL there.
3616 EXAMPLE
3618 BUGS
3620 SEE ALSO
3621 moHidd_Gfx_CleanViewPort
3623 INTERNALS
3624 Base class implementation just does nothing. This function is mainly intended
3625 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3627 *****************************************************************************************/
3629 ULONG GFX__Hidd_Gfx__MakeViewPort(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_MakeViewPort *msg)
3631 D(bug("Gfx::MakeViewPort: object 0x%p, data 0x%p\n", o, msg->Data));
3633 return MVP_OK;
3636 /*****************************************************************************************
3638 NAME
3639 moHidd_Gfx_CleanViewPort
3641 SYNOPSIS
3642 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_CleanViewPort *msg);
3644 ULONG HIDD_Gfx_CleanViewPort(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data)
3646 LOCATION
3647 hidd.graphics.graphics
3649 FUNCTION
3650 Performs driver-specific cleanup on a given ViewPort.
3652 INPUTS
3653 gfxHidd - A display driver object.
3654 data - a pointer to a HIDD_ViewPortDats structure.
3656 RESULT
3657 The same code as used as return value for graphics.library/MakeVPort().
3659 NOTES
3660 When graphics.library calls this method, the ViewPort is already unlinked
3661 from its view, and the bitmap can already be deallocated.
3662 This means that both data->Next and data->Bitmap pointers can contain invalid
3663 values.
3665 EXAMPLE
3667 BUGS
3669 SEE ALSO
3670 moHidd_Gfx_MakeViewPort
3672 INTERNALS
3673 Base class implementation just does nothing. This function is mainly intended
3674 to provide support for copperlist disposal by Amiga(tm) chipset driver.
3676 *****************************************************************************************/
3678 void GFX__Hidd_Gfx__CleanViewPort(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CleanViewPort *msg)
3680 D(bug("Gfx::CleanViewPort: object 0x%p, data 0x%p\n", o, msg->Data));
3683 /*****************************************************************************************
3685 NAME
3686 moHidd_Gfx_PrepareViewPorts
3688 SYNOPSIS
3689 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_Gfx_PrepareViewPorts *msg);
3691 ULONG HIDD_Gfx_PrepareViewPorts(OOP_Object *gfxHidd, struct HIDD_ViewPortData *data, struct View *view)
3693 LOCATION
3694 hidd.graphics.graphics
3696 FUNCTION
3697 Performs driver-specific setup on a given view.
3699 INPUTS
3700 gfxHidd - A display driver object.
3701 data - a pointer to a chain of HIDD_ViewPortData structures.
3702 view - A pointer to graphics.library View structure being prepared.
3704 RESULT
3705 MCOP_OK if there was no error or MCOP_NO_MEM otherwise.
3706 MCOP_NOP is not allowed as a return value of this method.
3708 NOTES
3709 graphics.library calls this method in MrgCop() after the complete view
3710 is built. data->Next pointer contains valid data.
3712 This function can be repeatedly called several times, and there is no
3713 cleanup counterpart for it. This should be taken into account in method
3714 implementation.
3716 EXAMPLE
3718 BUGS
3720 SEE ALSO
3722 INTERNALS
3723 Base class implementation just does nothing. This function is mainly intended
3724 to provide support for copperlist maintenance by Amiga(tm) chipset driver.
3726 *****************************************************************************************/
3728 ULONG GFX__Hidd_Gfx__PrepareViewPorts(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ShowViewPorts *msg)
3730 return MCOP_OK;
3733 #undef csd
3735 /****************************************************************************************/
3737 static int GFX_ClassInit(LIBBASETYPEPTR LIBBASE)
3739 struct class_static_data *csd = &LIBBASE->hdg_csd;
3741 __IHidd_PixFmt = OOP_ObtainAttrBase(IID_Hidd_PixFmt);
3742 __IHidd_BitMap = OOP_ObtainAttrBase(IID_Hidd_BitMap);
3743 __IHidd_Gfx = OOP_ObtainAttrBase(IID_Hidd_Gfx);
3744 __IHidd_Sync = OOP_ObtainAttrBase(IID_Hidd_Sync);
3745 __IHidd_GC = OOP_ObtainAttrBase(IID_Hidd_GC);
3746 __IHidd_Overlay = OOP_ObtainAttrBase(IID_Hidd_Overlay);
3747 __IHidd_ColorMap = OOP_ObtainAttrBase(IID_Hidd_ColorMap);
3748 __IHidd_PlanarBM = OOP_ObtainAttrBase(IID_Hidd_PlanarBM);
3749 __IHidd_ChunkyBM = OOP_ObtainAttrBase(IID_Hidd_ChunkyBM);
3751 if (!__IHidd_PixFmt ||
3752 !__IHidd_BitMap ||
3753 !__IHidd_Gfx ||
3754 !__IHidd_Sync ||
3755 !__IHidd_GC ||
3756 !__IHidd_ColorMap ||
3757 !__IHidd_PlanarBM ||
3758 !__IHidd_ChunkyBM
3761 goto failexit;
3764 D(bug("Creating std pixelfmts\n"));
3765 if (!create_std_pixfmts(csd))
3766 goto failexit;
3767 D(bug("Pixfmts created\n"));
3769 /* Get two methodis required for direct method execution */
3770 #if USE_FAST_PUTPIXEL
3771 csd->putpixel_mid = OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_PutPixel);
3772 #endif
3773 #if USE_FAST_GETPIXEL
3774 csd->getpixel_mid = OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_GetPixel);
3775 #endif
3776 #if USE_FAST_DRAWPIXEL
3777 csd->drawpixel_mid = OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_DrawPixel);
3778 #endif
3780 ReturnInt("init_gfxhiddclass", ULONG, TRUE);
3782 failexit:
3783 ReturnInt("init_gfxhiddclass", ULONG, FALSE);
3786 /****************************************************************************************/
3788 static int GFX_ClassFree(LIBBASETYPEPTR LIBBASE)
3790 struct class_static_data *csd = &LIBBASE->hdg_csd;
3792 EnterFunc(bug("free_gfxhiddclass(csd=%p)\n", csd));
3794 if(NULL != csd)
3796 delete_pixfmts(csd);
3798 OOP_ReleaseAttrBase(IID_Hidd_PixFmt);
3799 OOP_ReleaseAttrBase(IID_Hidd_BitMap);
3800 OOP_ReleaseAttrBase(IID_Hidd_Gfx);
3801 OOP_ReleaseAttrBase(IID_Hidd_Sync);
3802 OOP_ReleaseAttrBase(IID_Hidd_GC);
3803 OOP_ReleaseAttrBase(IID_Hidd_Overlay);
3804 OOP_ReleaseAttrBase(IID_Hidd_ColorMap);
3805 OOP_ReleaseAttrBase(IID_Hidd_PlanarBM);
3806 OOP_ReleaseAttrBase(IID_Hidd_ChunkyBM);
3809 ReturnInt("free_gfxhiddclass", BOOL, TRUE);
3812 /****************************************************************************************/
3814 ADD2INITLIB(GFX_ClassInit, 0)
3815 ADD2EXPUNGELIB(GFX_ClassFree, 0)
3817 /****************************************************************************************/
3819 /* Since the shift/mask values of a pixel format are designed for pixel
3820 access, not byte access, they are endianess dependant */
3822 #if AROS_BIG_ENDIAN
3823 #include "stdpixfmts_be.h"
3824 #else
3825 #include "stdpixfmts_le.h"
3826 #endif
3828 /****************************************************************************************/
3830 static BOOL create_std_pixfmts(struct class_static_data *csd)
3832 ULONG i;
3833 struct pixfmt_data *pf;
3835 memset(csd->std_pixfmts, 0, sizeof (OOP_Object *) * num_Hidd_StdPixFmt);
3837 for (i = 0; i < num_Hidd_StdPixFmt; i ++)
3839 pf = (struct pixfmt_data *)create_and_init_object(csd->pixfmtclass, (UBYTE *)&stdpfs[i], sizeof (stdpfs[i]), csd);
3841 if (!pf)
3843 D(bug("FAILED TO CREATE PIXEL FORMAT %d\n", i));
3844 delete_pixfmts(csd);
3845 ReturnBool("create_stdpixfmts", FALSE);
3848 csd->std_pixfmts[i] = &pf->pf;
3849 /* We don't use semaphore protection here because we do this only during class init stage */
3850 pf->refcount = 1;
3851 AddTail((struct List *)&csd->pflist, (struct Node *)&pf->node);
3853 ReturnBool("create_stdpixfmts", TRUE);
3856 /****************************************************************************************/
3858 static VOID delete_pixfmts(struct class_static_data *csd)
3860 struct Node *n, *safe;
3862 ForeachNodeSafe(&csd->pflist, n, safe)
3863 OOP_DisposeObject((OOP_Object *)PIXFMT_OBJ(n));
3866 /****************************************************************************************/
3868 static inline BOOL cmp_pfs(HIDDT_PixelFormat *tmppf, HIDDT_PixelFormat *dbpf)
3870 /* Just compare everything except stdpixfmt */
3871 /* Compare flags first (because it's a fast check) */
3872 if (tmppf->flags != dbpf->flags)
3873 return FALSE;
3874 /* If they match, compare the rest of things */
3875 return !memcmp(tmppf, dbpf, offsetof(HIDDT_PixelFormat, stdpixfmt));
3878 /****************************************************************************************/
3881 Parses the tags supplied in 'tags' and puts the result into 'pf'.
3882 It also checks to see if all needed attrs are supplied.
3883 It uses 'attrcheck' for this, so you may find attrs outside
3884 of this function, and mark them as found before calling this function
3887 #define PFAF(x) (1L << aoHidd_PixFmt_ ## x)
3888 #define PF_COMMON_AF ( PFAF(Depth) | PFAF(BitsPerPixel) | PFAF(BytesPerPixel) \
3889 | PFAF(ColorModel) | PFAF(BitMapType) )
3891 #define PF_TRUECOLOR_AF ( PFAF(RedMask) | PFAF(GreenMask) | PFAF(BlueMask) | PFAF(AlphaMask) | \
3892 PFAF(RedShift) | PFAF(GreenShift) | PFAF(BlueShift) | PFAF(AlphaShift))
3894 #define PF_PALETTE_AF ( PFAF(CLUTMask) | PFAF(CLUTShift) | PFAF(RedMask) | PFAF(GreenMask) | \
3895 PFAF(BlueMask) )
3897 #define PFAO(x) (aoHidd_PixFmt_ ## x)
3899 /****************************************************************************************/
3901 BOOL parse_pixfmt_tags(struct TagItem *tags, HIDDT_PixelFormat *pf,
3902 ULONG ATTRCHECK(pixfmt), struct class_static_data *csd)
3904 IPTR attrs[num_Hidd_PixFmt_Attrs] = {0};
3906 if (0 != OOP_ParseAttrs(tags, attrs, num_Hidd_PixFmt_Attrs,
3907 &ATTRCHECK(pixfmt), HiddPixFmtAttrBase))
3909 D(bug("!!! parse_pixfmt_tags: ERROR PARSING TAGS THROUGH OOP_ParseAttrs !!!\n"));
3910 return FALSE;
3913 if (PF_COMMON_AF != (PF_COMMON_AF & ATTRCHECK(pixfmt)))
3915 D(bug("!!! parse_pixfmt_tags: Missing PixFmt attributes passed to parse_pixfmt_tags(): %x !!!\n", ATTRCHECK(pixfmt)));
3916 return FALSE;
3919 /* Set the common attributes */
3920 pf->depth = attrs[PFAO(Depth)];
3921 pf->size = attrs[PFAO(BitsPerPixel)];
3922 pf->bytes_per_pixel = attrs[PFAO(BytesPerPixel)];
3923 /* Fill in only real StdPixFmt specification. Special values (Native and Native32)
3924 are not allowed here */
3925 if (attrs[PFAO(StdPixFmt)] >= num_Hidd_PseudoStdPixFmt)
3926 pf->stdpixfmt = attrs[PFAO(StdPixFmt)];
3928 SET_PF_COLMODEL( pf, attrs[PFAO(ColorModel)]);
3929 SET_PF_BITMAPTYPE(pf, attrs[PFAO(BitMapType)]);
3931 if (ATTRCHECK(pixfmt) & PFAF(SwapPixelBytes))
3933 SET_PF_SWAPPIXELBYTES_FLAG(pf, attrs[PFAO(SwapPixelBytes)]);
3936 /* Set the colormodel specific stuff */
3937 switch (HIDD_PF_COLMODEL(pf))
3939 case vHidd_ColorModel_TrueColor:
3940 /* Check that we got all the truecolor describing stuff */
3941 if (PF_TRUECOLOR_AF != (PF_TRUECOLOR_AF & ATTRCHECK(pixfmt)))
3943 D(bug("!!! Unsufficient true color format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
3944 return FALSE;
3947 /* Set the truecolor stuff */
3948 pf->red_mask = attrs[PFAO(RedMask)];
3949 pf->green_mask = attrs[PFAO(GreenMask)];
3950 pf->blue_mask = attrs[PFAO(BlueMask)];
3951 pf->alpha_mask = attrs[PFAO(AlphaMask)];
3953 pf->red_shift = attrs[PFAO(RedShift)];
3954 pf->green_shift = attrs[PFAO(GreenShift)];
3955 pf->blue_shift = attrs[PFAO(BlueShift)];
3956 pf->alpha_shift = attrs[PFAO(AlphaShift)];
3957 break;
3959 case vHidd_ColorModel_Palette:
3960 case vHidd_ColorModel_StaticPalette:
3961 if ( PF_PALETTE_AF != (PF_PALETTE_AF & ATTRCHECK(pixfmt)))
3963 D(bug("!!! Unsufficient palette format describing attrs to pixfmt in parse_pixfmt_tags() !!!\n"));
3964 return FALSE;
3967 /* set palette stuff */
3968 pf->clut_mask = attrs[PFAO(CLUTMask)];
3969 pf->clut_shift = attrs[PFAO(CLUTShift)];
3971 pf->red_mask = attrs[PFAO(RedMask)];
3972 pf->green_mask = attrs[PFAO(GreenMask)];
3973 pf->blue_mask = attrs[PFAO(BlueMask)];
3975 break;
3977 } /* shift (colormodel) */
3979 return TRUE;
3982 /****************************************************************************************/
3985 Create an empty object and initialize it the "ugly" way. This only works with
3986 CLID_Hidd_PixFmt and CLID_Hidd_Sync classes
3989 /****************************************************************************************/
3991 static OOP_Object *create_and_init_object(OOP_Class *cl, UBYTE *data, ULONG datasize,
3992 struct class_static_data *csd)
3994 OOP_Object *o;
3996 o = OOP_NewObject(cl, NULL, NULL);
3997 if (NULL == o)
3999 D(bug("!!! UNABLE TO CREATE OBJECT IN create_and_init_object() !!!\n"));
4000 return NULL;
4003 memcpy(o, data, datasize);
4005 return o;
4008 /****************************************************************************************/
4010 static struct pixfmt_data *find_pixfmt(HIDDT_PixelFormat *tofind, struct class_static_data *csd)
4012 struct pixfmt_data *retpf = NULL;
4013 HIDDT_PixelFormat *db_pf;
4014 struct Node *n;
4016 /* Go through the pixel format list to see if a similar pf allready exists */
4017 ObtainSemaphoreShared(&csd->pfsema);
4019 ForeachNode(&csd->pflist, n)
4021 db_pf = PIXFMT_OBJ(n);
4022 DPF(bug("find_pixfmt(): Trying pixelformat 0x%p\n", db_pf));
4023 DPF(bug("(%d, %d, %d, %d), (%x, %x, %x, %x), %d, %d, %d, %d\n",
4024 db_pf->red_shift, db_pf->green_shift, db_pf->blue_shift, db_pf->alpha_shift,
4025 db_pf->red_mask, db_pf->green_mask, db_pf->blue_mask, db_pf->alpha_mask,
4026 db_pf->bytes_per_pixel, db_pf->size, db_pf->depth, db_pf->stdpixfmt));
4027 if (cmp_pfs(tofind, db_pf))
4029 DPF(bug("Match!\n"));
4030 retpf = (struct pixfmt_data *)db_pf;
4031 break;
4035 ReleaseSemaphore(&csd->pfsema);
4036 return retpf;
4039 /****************************************************************************************/
4041 /* Stubs for private methods */
4043 /****************************************************************************************/
4045 OOP_Object *HIDD_Gfx_RegisterPixFmt(OOP_Object *o, struct TagItem *pixFmtTags)
4047 STATIC_MID;
4048 struct pHidd_Gfx_RegisterPixFmt p, *msg = &p;
4050 if (!static_mid) static_mid = OOP_GetMethodID(IID_Hidd_Gfx, moHidd_Gfx_RegisterPixFmt);
4052 p.mID = static_mid;
4054 p.pixFmtTags = pixFmtTags;
4056 return (OOP_Object *)OOP_DoMethod(o, (OOP_Msg)msg);
4060 /****************************************************************************************/
4062 VOID HIDD_Gfx_ReleasePixFmt(OOP_Object *o, OOP_Object *pixFmt)
4064 STATIC_MID;
4065 struct pHidd_Gfx_ReleasePixFmt p, *msg = &p;
4067 if (!static_mid) static_mid = OOP_GetMethodID(IID_Hidd_Gfx, moHidd_Gfx_ReleasePixFmt);
4069 p.mID = static_mid;
4071 p.pixFmt = pixFmt;
4073 OOP_DoMethod(o, (OOP_Msg)msg);
4077 /****************************************************************************************/