Intuition 3.0 (c) Copyright 1991-93 Commodore-Amiga, Inc. All Rights Reserved Graphics and AA-Chipset Issues Support for New Modes Intuition now has direct support for the AA display modes, through extensions to old mechanisms and through new tags. This includes the ability to select higher resolutions and to set colors in better than 4 bits-per-gun. The graphics database and the ASL screen-mode requester are the definitive places to get information about what modes and depths are available or desired. You can specify higher depths using SA_Depth, and new display modes with SA_DisplayID. SA_Colors32 supplants SA_Colors for specifying colors with a higher precision than 4 bits-per-gun. For full details, see the section on new screen features. Mode Promotion The AA chipset provides some flicker-free display modes that are roughly equivalent to NTSC or PAL when output through a display-enhancer or flicker-fixing product. While the AA chipset provides these modes without the significant extra expense of a display-enhancer, some software help is required. Conversely, the display-enhancer lives on the video output, and is completely transparent to software. To use promotion, the user needs to have a multiscan monitor. He needs to install the DblNTSC or DblPAL monitor into his devs:monitors drawer, and ensure that the "Mode Promotion" option in IControl Prefs is on (starting with 3.1, this setting will be on by default, eliminating this last step). When this is done, the graphics database entries for the "default" monitor will map to the most appropriate modes from the DblNTSC (or DblPAL) monitor, in place of the NTSC (or PAL) monitor. Interlaced screens that are promoted are displayed using double-height non-interlaced modes. For example, 640x400 NTSC interlaced appears as 640x400 double-NTSC non-interlaced. Non-interlaced 15 kHz screens are promoted using a chipset feature called "scan-doubling," in which each scan-line is output twice, because the 200 or 256 lines of the original screen only fill half the screen when in 31 kHz modes. Most applications which use the default monitor (either by explicitly using mode-IDs such as HIRES_KEY or by using V34-style 16-bit mode descriptions) and which go through Intuition and have relatively ordinary display requirements will be successfully and transparently promoted, and their screen will be displayed flicker-free. Applications which refer to modes of explicit monitors (e.g., SA_DisplayID of NTSC_MONITOR_ID|HIRES_KEY) are never promoted. The preferred method for an application is to use the ASL screen-mode requester, which normally presents all explicit modes (including the modes of DblNTSC and DblPAL) and omits the modes of the "default" monitor. Promotion and Compatibility De-interlacing in hardware is expensive but transparent, since the Amiga chipset's operation is unchanged by the presence of such hardware. However, promotion can change the behavior of the system in a manner which may be incompatible with certain applications. These are: o The overscan limits of DblNTSC (DblPAL) are a little less than the overscan limits of NTSC (PAL). (For 3.1, the DblNTSC (DblPAL) limits have been extended and are now comparable to NTSC (PAL)). o It may be harder to center a DblNTSC (DblPAL) screen on certain multiscan monitors than it was to center a de-interlaced NTSC (PAL) screen. (3.1 provides additional centering flexibility which basically solves this problem). o An interlaced screen is promoted to a non-interlaced screen, which has obvious implications on custom copper-lists. o The higher resolutions/depths of the AA chipset require higher alignment restrictions on bitplanes. Fortunately, most applications either let Intuition allocate their screen's BitMap or else they have a custom BitMap whose width is a multiple of 64 pixels (the highest alignment currently required by AA). However, if the custom BitMap is an unusual width, it may not be sufficiently aligned for the hardware. Such a screen can come up skewed when promoted. "1x" modes require 16-pixel (word boundary) alignment of each scan-line. "2x" modes require 32-pixel (longword boundary) alignment, while "4x" modes require 64-pixel (double-longword boundary) alignment. Here is a short reference: o 140 ns pixels (lores in 15 kHz modes, extra-lores in 31 kHz modes) 1-8 planes require 1X o 70 ns pixels (hires in 15 kHz modes, lores in 31 kHz modes) 1-4 planes require 1X 5-8 planes require 2X o 35 ns pixels (super-hires in 15 kHz modes, hires in 31 kHz modes) 1-2 planes require 1X 2-4 planes require 2X 5-8 planes require 4X As the graphics.library AllocBitMap() function takes care of allocating suitably-aligned BitMaps for you, you do not need to worry about alignment when using modern system calls. o The AA hardware does not allow dual-playfield non-interlaced screens to be scan-doubled, so they will appear half as tall as their non-promoted counterparts. o Like earlier chipsets, the AA chipset still supports eight sprites. In much the same way as ECS and original chipsets lose sprites when overscan is increased, many of the new modes have insufficient spare cycles to fetch data for these sprites. A promoted screen may have fewer sprites left than the corresponding 15 kHz mode, meaning that some sprites other than the pointer sprite may vanish. o There is no 31 kHz mode having 1280 pixels per line. That would require 17.5 ns pixel speeds, which is twice what the AA chipset is capable of. Therefore, SuperHires screens are promoted to 640 pixel-per-line screens, which generally can scroll. o Custom ViewPorts are not promoted, but a graphics-database aware application could open a ViewPort in DblNTSC or DblPAL. Pointer Sprite Features New Pointer Features Intuition's handling of the pointer sprite has undergone significant rework for V39, partly to add support for AA sprites (35/70/140 ns sprite pixels, 16/32/64 pixels per sprite, scan-doubling of sprites), and partly to make some general improvement to Intuition. The Intuition pointer now supports the various new sprite modes of the AA chipset. This includes 16, 32, and 64-bit wide sprites, as well as the sprite-pixel resolution control. Intuition automatically positions the pointer sprite on screen pixel resolution boundaries, even if the pointer is in a lower resolution, with the exception that graphics.library only allows positioning the pointer on every second line of an interlaced screen. For applications, there is a new boopsi class called "pointerclass," which is used to create Intuition pointer objects. The new include file contains definitions for the attributes that pointerclass supports, including: o POINTERA_BitMap - BitMap to use for sprite imagery o POINTERA_XOffset, POINTERA_YOffset - sprite hot-spot o POINTERA_WordWidth - intended width in words of this pointer o POINTERA_XResolution, POINTERA_YResolution - intended resolution of this pointer The resolution can be any of the hardware resolutions (ECS-compatible, 140 ns, 70 ns, or 35 ns), but Intuition also adds software-managed choices for o sprite resolution to match screen pixel resolution o sprite resolution to be "always lores" (~320 pixels per line) o sprite resolution to be "always hires" (~640 pixels per line) See for full details. There is a new pointer-control function called SetWindowPointerA(), which takes a window and a taglist. The tag values are as follows: o WA_Pointer (APTR) - used to specify an application custom pointer, ti_Data points to an instance of "pointerclass" you typically obtain using NewObject(). If NULL, you are requesting the Preferences default pointer. o WA_BusyPointer (BOOL) - if ti_Data is TRUE, this tag requests the Preferences default busy pointer. o WA_PointerDelay (BOOL) - if ti_Data is TRUE, this tag requests that the change of pointer imagery be deferred for a short duration. This is very useful for an application which is about to be busy for an unknown but possibly very short duration. Such an application should request both the Preferences default busy pointer and the pointer-delay feature. If the application clears the pointer or sets another pointer before the delay expires, the pending pointer change is cancelled. This reduces short flashes of the busy pointer caused by the application having brief intervals of busy-ness. The same three tags are now recognized by OpenWindowTagList(), so you can now arrange for a window to open with a custom pointer (or standard busy pointer) already in place, and never see a brief flash of the default pointer. The user can can now specify 32 pixel wide pointers in hires or lores using Pointer Preferences. Pointer Preferences supports a user-defined default pointer image as well as a user-defined busy pointer image. Intuition blanks the pointer around size or imagery changes, to reduce ugly flashing that might otherwise result. On an upbeat note, the notorious off-by-one error in sprite hot-spot position was eliminated from all new Intuition and Graphics calls. When using the new mechanisms, always specify the correct hot-spot offset. (The truth is, we tried to leave the error in, but couldn't agree whether the error should be one lores pixel or one sprite-resolution pixel.) Sprite Compatibility The old SetPointer() and ClearPointer() functions still work, giving compatible Intuition pointers. Likewise, the pointer imagery in devs:system-configuration will be used until a pointer.prefs file is received. However, due to growing complexity in the pointer subsystem, calling SetPointer() or ClearPointer() from within an input handler or inside Begin/EndRefresh() runs a risk of deadlocking. This has been kludged around, however: THIS IS WHY WE WARN PEOPLE TO STICK TO SIMPLE RENDERING FUNCTIONS ONLY! While inside LockLayerInfo(), LockLayer(), BeginRefresh(), BeginUpdate(), etc., and to not call Intuition or other high-level system functions inside of LockIBase(). As well, great care should be taken inside an input handler (it's generally best for the handler to signal a high-priority task which actually does the work). Don't be the application that dies under the next release when an inappropriate function that happened to work now deadlocks because its handling has become more sophisticated. See the Autodocs for these functions for more information on what other system calls are okay to use with these functions. Intuition and Graphics are involved in a scheme to maximize compatibility with older sprite-using applications. The AA chipset supports variable sprite resolution and width, but the setting affects all sprites. If an application requests a specific sprite width (through the old graphics.library/GetSprite() call or the new graphics.library calls (GetExtSpriteA() and ChangeExtSpriteA()), and Intuition's sprite is not compatible with that request, then graphics.library will blank Intuition's sprite and notify Intuition. Intuition will rebound by generating the most suitable pointer sprite which is compatible. Using an attached sprite for the Intuition pointer was quasi-supported under 2.0. It no longer works. The pointer information returned by GetPrefs() is no longer kept up-to-date, since the pointer data can exceed the storage space available in struct Preferences. (The ROM default pointer will be returned in all cases). (Like V37, V39 ignores the pointer data in calls to SetPointer() after the first one, for reasons such as this). Pen-Sharing Support Under V39, graphics.library has functions that let multiple applications share the pens in a palette (ObtainBestPen(), etc.). Palette sharing allows an application to gain exclusive access to some palette entries, which that application may then use or change as it sees fit. As well, an application may access a pen as shareable, meaning that other applications in need of a similar color may also be granted that pen value. Because these pens are shared among several clients, applications may not alter their color. Intuition now uses and supports this pen-sharing scheme. For all types of screen, the sprite pens and pens found in the DrawInfo->dri_Pens are obtained as shareable. By default, all other pens are allocated as exclusive on behalf of the screen opener (this provides compatibility when visitor windows aware of the pen-sharing functions open on unaware public screens). Exclusive pens are for the screen owner's use only, and may be changed at the owner's will. Screens that are aware of pen-sharing issues should set the {SA_SharePens,TRUE} tag, which instructs Intuition to leave all other pens unallocated. The Workbench screen is so marked, but pens 0 to 3 and ~0 to ~3 are also made shareable, for compatibility. Screens with SA_SharePens set to TRUE will have the new PENSHARED bit set in the screen->Flags field. The application may then allocate pens as needed. A paint package, for example, would allocate all colors it uses as exclusive. Other applications might allocate several colors as shared or exclusive. Since Intuition opens all public screens in private state, the application has a chance to allocate its colors before making the screen available to visitors (see SetPubScreenModes()). Preferences now listens to only 8 colors for the BitMap, which Intuition will set as the first four and the last four colors of the Workbench or any "Workbench-like" screen (those having the SA_FullPalette or SA_LikeWorkbench attributes). When the SA_Pens pen-array is evaluated, pens are masked to the number of available colors. As well, special definitions of pen-number (PEN_C3, PEN_C2, PEN_C1, and PEN_C0) mean the complementary pen numbers of pens 0 to 3, regardless of depth. The way the DrawInfo pens are determined is Intuition picks a default pen-array. Then, any pens you supply with SA_Pens override the defaults, up until the ~0 in your array. If the screen is monochrome or old-look, the default will be the standard two-color pens. If the screen is two or more planes deep, the default will be the standard four-color pens. If any explicit pens are specified, the default colors for NewLook menus and the titlebar match the V37 colors. If the SA_Pens tag points at ~0, the NewLook menu colors will be used. If the screen has the SA_LikeWorkbench property, the default will be the user's preferred pen-array, now changeable through Preferences. There is a preferred pen-array for four colors, and one for eight or more colors. Miscellaneous Graphics-Level Changes Intuition places a blanking gap between sliding screens. The time spent in this gap is used to load the hardware color registers, display-mode registers, and bitplane-pointers in a clean way. Under ECS and prior, three non-interlaced lines were sufficient, and this amount was hard-coded. Under AA, this amount may increase, so logic was added to graphics.library (CalcIVG()) to determine this amount. Intuition now bases its inter-screen gap on the result of this call. Under 2.0, when a screen was coerced, Intuition determined what display mode to use based on tables built into Intuition. This was too limiting, so graphics.library now has a CoerceMode() function to fulfill this responsibility. Intuition now uses this function. (Interested persons should see graphics.library/BestModeIDA(), which has wider application than CoerceMode()). Enhancements to Screens Attached Screens It is becoming increasingly popular for an application to have multiple screens open simultaneously. A typical use is an application that has a full-sized screen (perhaps in HAM mode) as a canvas, and a short screen as a control panel or palette. Since it is desirable that these screens slide and depth-arrange together, Intuition now provides the ability to attach screens together. OpenScreenTagList() now supports the SA_Parent tag to attach a new child to an existing parent. The SA_FrontChild and SA_BackChild tags can be used to attach an existing child in front of or behind a new parent. When opening a parent screen you can specify multiple SA_xxxChild tags, in order to attach multiple children. Draggable child screens can be dragged independently of each other and their parent, except that they can never go above their parent. Pulling down the parent below its natural top causes the child screens to move as well. Attached screens always remain adjacent to each other in the screen depth-ordering. It is not possible to interpose some other screen between screens of the same family. User depth-arrangement (via Amiga-M/N or the screen depth-gadget), as well as old programmatic depth-arrangement (ScreenToFront() and ScreenToBack()), depth-arrange a screen's family as a single unit, moving them to the front or to the back of the list of screens without altering the ordering of screens within the family. The new ScreenDepth() function has an SDEPTH_INFAMILY option which allows the programmer to depth-arrange screens within their family. There are times when it would be useful for a parent and child screen to masquerade as a single screen. This can allow independent setting of screen mode, depth, resolution, etc. Set the new SA_Draggable tag to FALSE to get a child screen which is non-draggable with respect to its parent. Trying to drag a child screen (through MoveScreen(), its drag-bar, or mouse-screen-drag) is equivalent to dragging the parent. The new ScreenPosition() function has an SPOS_FORCEDRAG option which allows the application to independently move such a child screen. To complement attached screens, a feature called "menu lending" has been implemented. This allows menu button presses in one window to activate the menus of a different window, and have the menus appear in the screen of that other window. The idea is to allow unification of the menu strips of attached screens. The LendMenus() function is used for this. If OpenScreen() is unable to attach screens (due to illegal hierarchies, etc.), the screen will fail to open, with a secondary error of OSERR_ATTACHFAIL. A parent screen may not itself have a parent, nor may a child screen have a child. Also, a child screen may not be the child of more than one screen. One parent may legally have several child screens. Aside from the SA_Parent, SA_FrontChild, or SA_BackChild tags, and the drag and depth arrangement behavior described, attached screens are just like other screens, that is to say they live on the regular screen list (IntuitionBase->FirstScreen-> ...), and child screens don't inherit any properties from their parent. In particular this means you can run the same code under Release 2 and all you will lose are the depth arrangement and dragging relationships. That would yield the best situation under those versions, and no conditional code is required on your part. Various combinations of DClips and over-sized scrolling screens are supported by attached screens, and they work in much the manner you would expect. Note that there are problems when non-draggable child screens are attached to parent screens and their DClips or dimensions are not equivalent. These problems are fixed in 3.1. The attachdemo.c example on the DevCon disks shows usage of attached screens. Double-Buffering Support for Screens Intuition now supports double (or multiple) buffering inside an Intuition screen, with full support for menus, and support for certain kinds of gadget. The AllocScreenBuffer() call allows you to create other BitMap buffers for your screen. the SB_SCREEN_BITMAP flag is used to get a buffer handle for the BitMap currently in use in the screen. Subsequent buffers are allocated with the SB_COPY_BITMAP flag instead, which instructs Intuition to copy the current imagery (e.g., the screen title-bar and any of your rendering) into the alternate BitMap. Normally you let Intuition allocate these alternate BitMaps, but if your screen is CUSTOMBITMAP, you should allocate the alternate BitMaps yourself. To swap buffers, call the ChangeScreenBuffer() function, which attempts to install the new buffer. ChangeScreenBuffer() will fail if Intuition is temporarily unable to make the change (say while gadgets or menus are active). Intuition builds these functions on top of the new graphics.library ChangeVPBitMap() function, so the signalling information that graphics provides is also available to the Intuition user. To clean up, call FreeScreenBuffer() for each screen buffer. It is not necessary to restore the original buffer before freeing things. Consult the autodocs for full details. When the user accesses the screen's menus, buffer-swapping will stop. The ChangeScreenBuffer() call will return failure during this time. When the user finishes his menu selection, buffer-swapping will be possible again. Only a small subset of gadgets are supportable in double-buffered screens. These gadgets are those whose imagery returns to the initial state when you release them (e.g., action buttons or the screen's depth gadget). To use other kinds of gadgets (such as sliders or string gadgets) you need to put them on a separate screen, which can be an attached screen. Windows with borders are not supportable on double-buffered screens. Double-buffered screens are expected to consist nearly entirely of custom rendering. An example program illustrating double-buffering under Intuition, with menu-lending and an attached screen to hold two slider gadgets is provided. Miscellaneous Screen Features The new {SA_Interleaved,TRUE} tag allows applications to request that their custom or public screen have an "interleaved" BitMap. Interleaved BitMaps are built out of a single allocation, instead of one per bitplane. Further, the data is laid out as follows: bitplane 0, scan-line 0 bitplane 1, scan-line 0 ... bitplane n, scan-line 0 bitplane 0, scan-line 1 ... (Contrast this to regular BitMaps, where each bitplane is contiguous.) The primary advantage of interleaved BitMaps is that blitting between them is cleaner, because color artifacting is eliminated. As well, multiple small blits are replaced by fewer large blits, saving on blitter setup time and improving blitter/processor overlap. The primary disadvantage of interleaved BitMaps is that BitMap->BytesPerRow no longer means "how many bytes are in one row of one bitplane." This field continues to mean "how many bytes must be added to the current address to arrive at the same pixel one row down." See the notes for the compatibility talk for further details. (Screen grabbers and screen printers seem to be the primary victims of this change.) For compatibility, the Workbench screen is non-interleaved if it opens before IPrefs has run. If opened or reset after IPrefs has run, the Workbench screen will be interleaved. The new SA_LikeWorkbench tag gives you a screen having the same attributes as the Workbench screen, including depth, colors, pen-array, screen mode, etc. Individual attributes can be overridden by using tags. (SA_Workbench itself overrides things specified in the NewScreen structure). Attention should be paid to hidden assumptions when doing this. For example, setting the depth to two makes assumptions about the pen values in the DrawInfo pens. Note that this tag requests that Intuition attempt to open the screen to match the Workbench. There are fallbacks in case that fails, so it is not correct to make enquiries about the Workbench screen then make strong assumptions about what you're going to get. OpenScreen() now allocates an appropriate-sized ColorMap for new modes. You can override this with the SA_ColorMapEntries tag to let the application increase the ColorMap size if needed. The SA_Draggable and SA_Exclusive tags are designed to help implement "game screens" that coexist with Intuition. {SA_Draggable,FALSE} allows the caller to make a screen non-draggable. {SA_Exclusive,TRUE} allows the caller to make a screen exclusive, meaning it will never share the display with another screen. Dragging down a screen that's in front of an exclusive screen won't reveal the exclusive screen. Although exclusive screens can autoscroll, but they can't be pulled down below their natural top (since nothing should be visible behind). Starting with 3.1, you can attach one or more exclusive screens with the SA_Parent and SA_xxxChild tags already described. Such screens form an exclusive family, and only coexist on the display with each other, not with other screens (exclusive or not). Intuition and graphics.library now support over-sized scrollable A2024/Moniterm screens. While such screens can autoscroll and be dragged around, they can't be pulled down, since other screens would not be visible behind them (similar to the SA_Exclusive property, but dictated by the graphics database MonitorInfo.Compatibility field). The new ScreenPosition() function extends the functionality of MoveScreen() to also include absolute screen positioning and optional movement of {SA_Draggable,FALSE} screens. The hope is that only the screen's opener (and not any commodity-type programs) would forcibly move a non-draggable screen. As well, ScreenPosition() allows you to specify a rectangle in screen coordinates which you wish to be made visible. Over-sized screens will be scrolled such that the rectangle you supply will be on the visible part of the display. The new ScreenDepth() function unifies ScreenToFront() and ScreenToBack() while adding a flag allowing optional in-family depth-arrangement of attached screens. ScreenToFront(), ScreenToBack(), Amiga-M/N, screen depth-gadget action, and EasyRequest screen-popping all go through the ScreenDepth() LVO. Due to a bug, WBenchToFront() and WBenchToBack() do not yet do so, but this is expected to be fixed for 3.1. OpenScreen() and the routines which open the Workbench now call OpenScreenTagList() through the LVO, which will allow some useful SetFunction()ing. OpenScreen() now supports the new SA_BackFill tag, to install a LayerInfo backfill hook for the screen. Intuition now ensures that the Workbench screen is at least 640x200. This is needed in order to safely allow lores (and other odd resolution) Workbench screens. The original Screen structure has an embedded instance of a BitMap structure, which is unfortunate. When Intuition allocates a screen's BitMap (i.e., a non-CUSTOMBITMAP screen), it now uses AllocBitMap(), and copies the struct BitMap into &screen->BitMap. This is the direction to head for RTG, and it is needed now for double-buffering. Intuition internally now references the real BitMap (obtainable as screen->RastPort.BitMap) instead of &screen->BitMap. It is recommended that applications do the same. The new SA_Colors32 tag can be used to provide 32-bit color information at OpenScreen() time. ti_Data points to a longword-array that Intuition will pass to LoadRGB32(). See the autodoc for LoadRGB32() for details on how to format the data. The new SA_VideoControl tag allows an application to provide a taglist which Intuition will pass to VideoControl() after opening the screen. This can be useful to turn on border-sprites, for example. The requested screen depth is now validated. Making a request for a screen too deep causes failure with a secondary error of OSERR_TOODEEP. Enhancements to Windows The window depth-gadget now determines whether a click should send the window to front or to back based on whether the window is obscured or not, rather than on whether it's the top layer. The new ScrollWindowRaster() function implements ScrollRasterBF() at the Intuition level. You will receive an IDCMP_REFRESHWINDOW event if there is damage to your window. Damage will appear if obscured parts of a simple refresh window are scrolled into view. Note: this area is not cleared! When you supply the "alternate-size" rectangle for zooming using the WA_Zoom tag, you can now specify (-1,-1) for the upper-left corner. This instructs Intuition to perform size-only zooming. Wherever the window is placed, zooming will toggle size but not affect position (unless moving the window would be required to keep it on-screen). Using (-1,-1) under V37 is safe, and equivalent to using (0,0). The Window->WindowPort is now allocated at OpenWindow() time, even if IDCMPFlags of zero are requested. This simplifies ModifyIDCMP() failure handling because failure can no longer happen when you set the window->UserPort to your shared port, then call ModifyIDCMP() to turn on messaging. ModifyIDCMP() can now only fail if you ask it to create the UserPort. The new OpenWindow() tag WA_NotifyDepth allows a window to request IDCMP_CHANGEWINDOW messages when that window is depth-arranged. These messages arrive with an IntuiMessage->Code value of CWCODE_DEPTH to distinguish them from V37-style IDCMP_CHANGEWINDOW messages (sent in response to window movement or resizing), which have a Code value of CW_MOVESIZE. When inactive, window borders are filled with BACKGROUNDPEN instead of pen zero. There are presumably a few more places when pen zero is being used incorrectly, but they are hard to track down (ever try to search 1.5 megabytes of source code for all references to "0"?) The WA_HelpGroup and WA_HelpGroupWindow tags allow the programmer to identify multiple windows of the same application, for purposes of gadget help processing. See the section on gadget help for details. Enhancements to Gadgets and Imagery Extended Gadget Structure V39 introduces the ExtGadget structure as a compatible substitute that can be used wherever old Gadget structures can be found. An arbitrary gadget can be identified as an ExtGadget if the GFLG_EXTENDED bit in its Flags field is set. Never attempt to read any of the extended fields of a gadget if this flag is not set. Starting with V39, all instances of gadgetclass or its subclasses are ExtGadgets. The extended fields include a new longword worth of flags, and a bounding box. Gadget Bounding Box and GM_LAYOUT Until now, the only area that was defined for gadgets was the select box area. However, the imagery of a gadget often extends outside its select box. For example, the border of a string gadget is often outside, as is its label. ExtGadgets have four new fields that describe the "bounding box." The bounding box can be used to allow relative size or position gadgets to work even if they have imagery outside the select box. The BoundsLeftEdge, BoundsTopEdge, BoundsWidth, and BoundsHeight fields of an ExtGadget are assumed valid if the GMORE_BOUNDS flag in the ExtGadget->MoreFlags field is set. Where Intuition wants to use a bounding box, but the gadget is not extended or does not have GMORE_BOUNDS set, the gadget select box will be used instead, which matches the V37 behavior. The routine that manages erasing and redrawing GRELxxx gadgets during window resizing now bases its work on the gadget bounding box (if one is specified), instead of the gadget select box. This means that you can finally have GREL gadgets which have imagery (e.g., a gadget label) extending outside of the select box, and Intuition will correctly move or resize such a gadget. As well, there is a new boopsi method for gadgets called GM_LAYOUT. If your gadget has any of the GREL properties, it will receive a GM_LAYOUT message when the gadget is first added (or the window containing the gadget is first opened), as well as whenever the window size changes. At GM_LAYOUT time, the gadget can change its gadget select box and/or bounding box. It can re-allocate or change its image dimensions if it likes. If it is a group-gadget, it can move its members around. To round this all out, there is a new "special relativity" property, GFLG_RELSPECIAL or GA_RelSpecial. Unlike the older GREL properties, this property doesn't affect the interpretation of the gadget box. It does allow your gadget to receive GM_LAYOUT messages, hence have arbitrary layout power. The DevCon disks include a sample program called relspecial.c that implements a boopsi gadget whose size is kept at half the current size of the window, and which is centered in that window. The example makes use of GFLG_RELSPECIAL and GM_LAYOUT. Gadget Help Intuition now supports "gadget help". If a window enables this feature and the user passes the mouse over the bounding box of a gadget which has the GMORE_GADGETHELP property, then an IDCMP_GADGETHELP event will be sent. There is a corresponding boopsi GM_HELPTEST method which boopsi gadgets can use to refine their help-sensitivity areas or to delegate help-testing to member gadgets. Boopsi gadgets can also return values for the IntuiMessage Code field of the IDCMP_GADGETHELP message. The gadget help feature may be turned on or off through the HelpControl() function. The gadget help checking is optimized for performance. If the mouse is moving quickly, Intuition skips the check for gadget help. If Intuition discovers that the mouse is still over the same gadget as the last one that sent gadget help, no new IntuiMessage is sent unless the gadget wants to report a different IntuiMessage->Code value. When the mouse is over a GMORE_GADGETHELP gadget, the IDCMP_GADGETHELP message has an IntuiMessage->IAddress which points to the gadget. When the mouse is over the window but not over any help-aware gadget, the IAddress points to the window itself. When the mouse is not over the window, the IntuiMessage IAddress will be zero. Intuition will look "through" gadgets that do not have the GMORE_GADGETHELP property to see if some other gadget lies underneath. Ordinarily, gadget help only applies to the active window. However, a multi-window application can mark all its windows as being in a group (using the WA_HelpGroup or WA_HelpGroupWindow tags), which makes Intuition test gadget help in all windows of the group when any one of them is the active one. There is a new utility.library function called GetUniqueID() which must be used to provide an ID for WA_HelpGroup. If you have only one window, there is no need to pass WA_HelpGroup. HelpControl() sets the state of gadget help for all windows of a group, and Intuition ensures that all windows of the same group are consistently set. helpgroup = GetUniqueID(); for ( each window ) { win[x] = OpenWindowTags(..., WA_HelpGroup, helpgroup, TAG_DONE); } Inactive windows whose WA_HelpGroup matches the active window's are also subject to gadget help testing. IDCMP_GADGETHELP messages are sent to the window the mouse is over. The IDCMP_GADGETHELP message with an IAddress of zero means the mouse is not over the active window or any other window of the same group. This particular message is always sent to the active window (which is not necessarily the window in your group that last got a message). All system gadgets (e.g., close, drag, size, depth) have GMORE_GADGETHELP set, so GadgetHelp-aware applications can (almost must) provide help on them too. You can check the gadget->GadgetType & 0xF0 field for GTYP_CLOSE, etc. Later include files define GTYP_SYSTYPEMASK to be this value (0xF0). The gadgethelp.c example on the DevCon disks illustrates the correct handling of IDCMP_GADGETHELP messages. Gadget Support for ScrollRaster() Damage Handling Intuition now notices and repairs damage when boopsi gadgets use ScrollRaster(). (Such damage occurs when the gadget is in a simple-refresh window and part of the scrolled area is obscured). Such gadgets must set GMORE_SCROLLRASTER in order to benefit from this magic repair feature. Note that ScrollWindowRaster() is for applications. Boopsi gadgets must not use ScrollWindowRaster(), but rather use ScrollRaster() or ScrollRasterBF(). Miscellaneous Gadget Features There is an important new Boopsi function in Intuition called DoGadgetMethodA(), that invokes the specified method, but includes a valid GadgetInfo structure if possible. SetGadgetAttrsA() has been re-implemented to go through DoGadgetMethodA(). Two SetGadgetAttrsA() bugs were fixed in the process. First, if a requester is off-window, it has no layer. SetGadgetAttrsA() of a gadget in such a requester wasn't being sent to the gadget, but now OM_SET is sent with a GadgetInfo of NULL. Second, there was no locking around the call. DoGadgetMethodA() is preferable to a direct Boopsi invocation (namely DoMethod()) because it offers both a valid GadgetInfo structure and arbitration around other gadget activity. The default string edit hook now ignores Return or Enter keystrokes that have the repeat-qualifier set. PROPNEWLOOK proportional gadgets in the borders of an active window have their knobs rendered in FILLPEN instead of SHINEPEN. When you click on the knob, they become SHINEPEN as before. This looks a lot better, is more consistent with inactive windows, and finally restores that all-important feedback to these prop gadgets. Imagery Features Under V37 and prior, Intuition handled ghosting a gadget by blasting a pattern of dots over its select area. This did not allow boopsi images to manage their own disabled rendering. For V39, Intuition has defined a new read-only attribute for image classes, called IA_SupportsDisable. If an image class returns TRUE in response to an OM_GET request of this attribute, it is asking to take responsibility for performing ghosting based on image state. When a gadget is first added to a window, Intuition will check its image to determine if it has the IA_SupportsDisable attribute. When such a gadget is disabled, Intuition skips its own disabled rendering, and draws the image using DrawImageState() using the IDS_DISABLED or the new IDS_SELECTEDDISABLED state. The ROM boopsi image class for rendering frames, "frameiclass", now supports the standard frame types used by GadTools and recommended by the Amiga User Interface Style Guide, including the standard GadTools-style bevelled box, the GadTools string-gadget ridge, and the AppWindow icon drop-box specified by the Style Guide. The imagery for the standard system arrows has been improved. The GadTools checkbox and GadTools radio-button images are now marked as scalable to allow GadTools to support scaled checkboxes and radio-buttons. The basic gadget types (classic prop, bool, string) now support GFLG_LABELIMAGE. Enhancements to Menus NewLook Title Bar and Menus On aware screens, the title-bar has a nicer appearance. For V39, Intuition defines three additional pens in the DrawInfo, which are used to control the rendering of the screen title bar and menus. These pens are: o BARDETAILPEN - pen used for details like text in the title bar and text or graphics in menus. o BARBLOCKPEN - pen used to fill the solid areas of the title bar and menus. o BARTRIMPEN - pen to use for the trim-line under the screen title bar. It is intended that BARDETAILPEN and BARTRIMPEN should be black or dark, and that BARBLOCKPEN should be white or light-colored. The handling of defaults is a bit involved because of compatibility issues. Applications that specify no SA_Pens array or ones who specify an SA_Pens array with at least one explicit pen provided get compatible defaults. Applications whose SA_Pens array consists solely of {~0} will get the new colors. Finally, screens which specify SA_LikeWorkbench will get the user's preferred pen-array, which allows the user to control the menu and title bar colors. Under V37 and earlier, the menus themselves are drawn using the window's DetailPen and BlockPen, while the colors of the MenuItems are determined by the imagery (IntuiTexts or Images) chosen. For compatibility, old applications will have their menus rendered in V37-compatible colors. Applications will want to take advantage of NewLook menus when present, but they must request them through the {WA_NewLookMenus,TRUE} tag. This instructs Intuition to use BARDETAILPEN and BARBLOCKPEN for rendering the elements of your menus, instead of relying on the window's DetailPen and BlockPen. Note that the application (or any menu-building library) should ensure that the colors of struct IntuiText or struct Images used by MenuItems use matching pens. You can instruct GadTools to use the new colors by passing {GTMN_NewLookMenus,TRUE} to LayoutMenusA(). Intuition also ensures that the Amiga-key and checkmark symbols are colored to match the menu and are scaled to match the screen's font. If you are using a font other than the screen's font for the menus, you must create custom Amiga-key and checkmark symbols using "sysiclass". This image class recognizes a new tag, SYSIA_ReferenceFont, which you can use to set the size of a checkmark or Amiga-key symbol appropriately for your chosen font. You can then use the (V36) WA_CheckMark tag or the new WA_AmigaKey tag to override the imagery Intuition will use in the menus. Per screen, the default Amiga-key and checkmark images used will be appropriately colored and scaled to the screen's font. (You can find pointers to their imagery in the DrawInfo structure for that screen). HIGHCOMP menu items in NewLook menus complement in such a way that pixels colored in BARDETAILPEN highlight into BARBLOCKPEN, and vice-versa. The flag which indicates whether a window is using NewLook menus is publicly readable (WFLG_NEWLOOKMENUS). Other Enhancements Drawing Tablet Support As an input device, a drawing tablet poses special problems for Intuition and for the tablet driver writer. Some of the problems include getting auxiliary information such as pressure through the IntuiMessage channel and providing suitable scaling. As well, the absolute nature of tablet devices poses some interesting problems for features like autoscroll. V37 added a simple tablet input event, but this was not enough. There now is a new subclass of IECLASS_NEWPOINTERPOS called IESUBCLASS_NEWTABLET. This subclass solves tablet handling quite nicely. The tablet driver fills out a few tablet-oriented properties (like the current value and range in X and Y), and then submits the InputEvent to input.device. Later, Intuition establishes the active screen and the rectangle to which the tablet should scale itself, then calls back the driver through a hook. This allows the tablet driver to handle screen resolution changes, oversized scrolling screens, pulled down screens, and attached screens. The tablet driver can scale according to some tablet preferences settings it manages (for example, preserve aspect, center, best fit horizontal, best fit vertical). Intuition supplies reasonable default scaling for simple tablet drivers that leave the hook NULL. See struct IENewTablet in . Windows that request the new WA_TabletMessages property receive extended IntuiMessages, which include a pointer to a TabletData structure. If this IntuiMessage originated from a tablet event, the TabletData pointer will be non-NULL, and the structure will have some information such as sub-pixel position. In addition, there is a pointer to a tag-list, and there are definitions for standard tags such as pressure, tilt, additional buttons, and a Z-coordinate. The definition and important comments on the TabletData structure can be found in . As an example, pressure is passed in with the TABLETA_Pressure tag. the pressure reading of the stylus. The ti_Data member is the pressure, which should be normalized to fill a signed long integer. Typical devices would not generate negative pressure, but the possibility is not precluded. The Preferences program shipped with a tablet driver for a pressure-sensitive device might offer two pressure sensitivity settings. The "contact threshold" would be the pressure below which no contact should be reported by the driver. This is the "zero point" for reported pressure. The "click threshold" would the pressure at which a button transition should be reported (by setting the InputEvent ie_Code to indicate a downpress of the select button). The tablet would send position/pressure events even when the pressure was below the click threshold (but above the contact threshold, of course). When a tablet driver sends a new tablet event and the active window is tablet-aware, IDCMP_MOUSEMOVE events are sent to that window even if the pixel-level mouse-position is unchanged. This is to allow applications to hear changes in sub-pixel position or other parameters such as pressure. This means that tablet drivers must be careful to only send events when something actually changed. If an input event is a tablet event, boopsi gadgets can get a pointer to the TabletData structure in the gpInput structure they receive through the GM_GOACTIVE and GM_HANDLEINPUT messages. Miscellaneous Features The new TimedDisplayAlert() function allows for alerts that time-out without user-intervention. Exec uses this new function to aid unattended operation of the Amiga, particularly in kiosk and video applications. In struct Preferences, the unused WorkName[] field is now split into PrtDevName[], DefaultSerUnit, and DefaultPrtUnit, for multi-serial preferences and more flexible printer-preferences. OpenScreenTagList(), OpenScreen(), OpenWindowTagList(), OpenWindow(), and the internal BorderPatrol() routine now go through stack-swapping. This protects applications from increased stack usage in these calls. The Preferences LaceWB field (and whether the pretend screen mode from GetScreenData() is lace or not) now solely depends on the height of the text overscan rectangle of the true mode of the Workbench. This helps older applications opening on modes such as double-NTSC 640x400. Intuition now handles MakeVPort() failure. Intuition will blank any failed ViewPort, and attempt to remake it at each opportunity. MakeScreen(), RethinkDisplay(), and RemakeDisplay() now have return codes that reflect MakeVPort() failure. Rendering Optimizations Several important rendering optimizations make Intuition appear snappier and cleaner. Here is a partial list: o When a WFLG_ACTIVATE window is opened, Intuition now activates it synchronously. The big benefit is that the window's border is no longer drawn inactive then activate. o EasyRequests and AutoRequests used to consist of a window with a requester inside, which meant two layers. This consumed memory and slowed down requester and other window operations. Now, the gadgets and imagery are brought up directly in the window, saving a layer. o The window sizing/dragging rubber-band box is now much faster. o The bar-layer of each screen no longer does any backfill processing, since Intuition fully re-renders the screen bar anyway. o Intuition now avoids spurious border and gadget refresh and sending a spurious IDCMP_REFRESHWINDOW event. Formerly, if an application had not cleared its window's damage when another damage-causing operation (e.g., menus, window sizing/movement) occurred on the same screen, another round of refresh was performed. Intuition now can tell if the window's layer had been damaged since the last IDCMP_REFRESHWINDOW message went out. o Menus are brought on-screen somewhat faster than before, and are removed very much faster than before. (3.1 and up only) o A lot of work has been done to reduce window border and gadget flashing during window resize operations. (3.1 and up only) Bug Fixes o NextPubScreen() could write a zero-byte one byte past the end of the buffer the caller supplies. It no longer does this. o Clicking in the no-window area of a screen now makes that screen the active screen (for purposes of autoscrolling). o Fixed a long-standing bug where REQCLEAR messages weren't being sent when a requester having no layer is taken down while other requesters are still up in the window. o Setting a negative minimum width or height with WindowLimits() no longer allows you to crash the computer by turning a window inside out. o SetWindowTitles() now properly erases remnants of the previous title, even when odd extenders happen. o A ghosted string gadget no longer causes patterning in string gadgets precede it in the list and have a non-zero container background-pen. o NewModifyProp() of a disabled prop gadget no longer clears away part of the ghosting. o SetGadgetAttrs() to a proportional gadget no longer can cause the window's installed clip-region to be lost. o The mouse-pointer no longer blanks in the first gap when three interlaced screens up. o Several causes of sprite-pointer jumping have been fixed. o The ROM default sprite pointer now is the 2.0/3.0 one, not the 1.3 one. o DClips of coerced ViewPorts are finally scaled as correctly as possible. If you used a boopsi string gadget as an integer gadget, with Intuition supplying the buffer, and you specified a STRINGA_MaxChars of > 15, you would get a mismatched FreeMem() when the gadget is disposed. This is now fixed. There is a bug in 3.0 (not in 2.0x and fixed in 3.1) where the autoscroll boundary was inadvertently switched to be the DClip of the active screen, where it used to be the "hull" of the DClips of all the screens. If there are two screens in the system with different DClips, the mouse can be way outside the DClip of the smaller screen. If that screen is active, it will AutoScroll at a ridiculous rate. For example, if the mouse is seventeen pixels below its DClip, moving it down one pixel causes the screen to autoscroll by eighteen, instead of one. This is now fixed. Starting with 3.1, Intuition now updates its internal time values based on (nearly) ANY InputEvent it receives, instead of just IECLASS_TIMER ones. The problem was that outgoing IntuiMessages get their time from this internal time, which meant that IntuiMessage time was the time-stamp of the most recent timer tick, instead of the time-stamp of the event that actually triggered this IntuiMessage. This problem completely precludes correlating an IntuiMessage with the InputEvent that caused it, which is important for tablet people, for example. A SetPatch for earlier ROM versions is being considered. In 3.00, there is a bug where the part of a window obscuring the title-bar area of a SCREENQUIET screen wasn't erased when the window was closed or moved away. Effectively, Intuition was relying on a layers side-effect that was optimized out for V39. Intuition fixes this for 3.1. Starting with 3.1, when Intuition splits a single InputEvent into button and movement components, the button event is now sent first. This fixes some inconsistencies with extended input information like pressure, as well as odd behavior of the qualifiers, in particular IEQUALIFIER_MIDBUTTON.