# Aros/Developer/Docs/Libraries/Intuition

* Navbar for the Aros wikibook
* Aros User
* Aros User Docs
* Aros User FAQs
* Aros User Applications
* Aros User DOS Shell
* Aros/User/AmigaLegacy
* Aros Dev Docs
* Aros Developer Docs
* Porting Software from AmigaOS/SDL
* For Zune Beginners
* Zune .MUI Classes
* For SDL Beginners
* Aros Developer BuildSystem
* Specific platforms
* Aros x86 Complete System HCL
* Aros x86 Audio/Video Support
* Aros x86 Network Support
* Aros Intel AMD x86 Installing
* Aros Storage Support IDE SATA etc
* Aros Poseidon USB Support
* x86-64 Support
* Motorola 68k Amiga Support
* Linux and FreeBSD Support
* Windows Mingw and MacOSX Support
* Android Support
* Arm Raspberry Pi Support
* PPC Power Architecture
* misc
* Aros Public License

## Introduction

* V34 = Amiga OS1.3
* V36 = Amiga OS2.x
* V37 = Amiga OS3.0
* V40 = Amiga OS3.1 AROS starting compatibility level
* V44 = Amiga OS3.5 OS3.9
* V45 = Amiga OS4
A typical application or game will involve...
* Setup any libraries, screen(s), windows.
* Setup any required intuition-based gadgets, menus and requesters or zune (mui based) gadgets, menus and requesters.
* Wait for a message from Intuition/Zune about user activity or other events.
* Copy needed data from the message and tell Intuition/Zune you received it by replying. Look at the data and take the appropriate action. e.g. (presses a key on the keyboard, moves the mouse, gadgets hits, menu item selection, time elapsing, disk insertion, disk removal, and window rearrangement.)
* Repeat until the user wants to quit. (then closes windows, screen(s) and libraries)

## Screens

Most of the time, you will not need to setup a screen as you will frequently use an already in use public screen (Wanderer, Scalos or another WB replacement), so you can jump to opening windows on that screen.
AROS (like Amigas before) supports a concept called screens, each screen can be setup with a specific resolution and color depth, limited by the monitor drivers or CRT or LCD display used.
* Own public screen where main application can "host" additional modules with same screen specs etc. if needed
* Default shared public screen (NULL usually known as Wanderer, Scalos or Workbook) means multiple applications reside on the same screen which saves memory
* Last option, is a custom screen creates a new display for each application, i.e. if you want a specific resolution and color depth. Opening any new screen uses memory.

### Opening a Screen using OpenScreenTags

Below is the public structure that is already setup inside AROS, a template as such, for quick use in programming.
Each line adds and stores a bit of information about the screen in use. Each additional struct inside the Screen struct is an already existing 'blob' of pre-defined data storage inside AROS. A lot of AROS depends on struct's being used inside newer struct's to aid and speed up development.
every screen has a struct ViewPort (screen represent by graphics library) and each screen has a drawinfo (high level) and struct RastPort (low level handle that graphics library uses to draw on that screen). View is the whole display, including all visible screens accessed by ViewAddress
Tags are a list of parameter names followed comma and then by a value. For example, to specify the DefaultTitle of a screen you use the SA_Title followed a comma and then by the title in quotes and there are many other tags that can be used to define bits of a screen, see later for a list. The last tag item should always be TAG_DONE.
The title bar of the screen, not the title bar of the window, is drawn in front of the window. If moving the window from its default 0,0 position with WA_Top and/or WA_Left (SA_ShowTitle is FALSE of course), just ignore those tags in fullscreen mode instead of setting them to 0.

### Opening or Locking a Public Screen

If you do not wish to use a custom screen, then you can use an existing public screen such as Wanderer. Screens can be closed at any time, so to prevent that, the public screen should be locked while the application is running. You can do this using the LockPubScreen function.
where name is the name of the Public Screen to lock.If no name (NULL) is given then it will use the Workbench public screen. Once done with the Public screen you can then Unlock it

### Screen Reference
#### Screen Tags
## Windows

Below is another public structure that is already setup inside AROS, a template as such, for quick use in programming.
Having set a screen, you can now have as many windows on that screen as you want.
Opening Windows is very similar to opening screens, OpenWindowTags with window tags as well...
As Screen tags started with SA_, Window tags start with WA_ and in the case of WA_IDCMP and WA_Flags have further sub-tags. A list follows later...
So when I do window->Width / rport->TxWidth, the number of columns ends up being greater than the visible area, so text goes off screen, same for height. Is there a way to get the window size less the attached gadgets/widgets? For a non borderless window (aka normal window ), the usable width is w->Width - w->BorderLeft - w->BorderRight, and the height, w->Height - w->BorderTop - w->BorderBottom.
For a GimmeZeroZero window, use w->GZZWidth and w->GZZHeight instead w->Width and w->Height. GZZWidth and GZZHeight are maintained for non-GZZ windows, too. You don't need to calculate them yourself.
To be able to resize a window you need to set WA_MinWidth, WA_MinHeight, WA_MaxWidth and WA_MaxHeight because they all default to WA_Width resp. WA_Height.

### Window Example

For AROS you should omit all the usual #?Base (GfxBase, IntuitionBase, DOSBase,... ) declarations and "OpenLibrary & CloseLibrary" calls for them because AROS GCC compiler opens and closes them automatically for you when it sees a reference. Most of the core libraries are auto opened by the compiler.
This is for background knowledge only. When a library is opened, it will return a pointer to a Library structure or a Base structure specific to that library otherwise it will return a NULL value. Converting old Commodore examples is probably a good way to get understanding of Amiga program to AROS program differences. NOTE those old examples need editing because of OpenLibrary, CloseLibrary and #?base stuff... In the past, to close a library, use the CloseLibrary function and provide the pointer to the Library or Base structure which was returned in the OpenLibrary. It is normal practice to test that the library was opened before trying to close it.
See AROS website examples, Aros/Developer/Docs/Examples/SimpleWindowIntuition and here

### Windows Reference
#### Windows Tags
## Event Handling

A window can receive events destined for it. The usual way is for the application to ask Intuition to send it messages which are based on the input event that Intuition has processed. These messages, called IntuiMessages, are standard Amiga Exec messages, and are sent to a port called an Intuition Direct Communications Message Port, or IDCMP. Every window may have an IDCMP associated with it. Although AmigaOS(TM) started with intuition events, AROS has incorporated these as well for backwards compatibility purposes but recommends using Zune instead, see here Zune
Intuition Events
Input = Hardware Device -> HIDD or .device -> Event Handler -> IDCMP or Console -> Application
Output = Application -> Console or intuition -> graphics library -> display monitor

### IDCMP

An application will have messages sent to it by any intuition event. These messages, IntuiMessages, are standard Exec messages, and are sent to a port called an IDCMP. Every window may/will have an IDCMP associated with it (Window->UserPort). Keys will not work automatically in a window. You must setup it by WA_IDCMP, tags.
* IDCMP_VANILLAKEY - events provide for simple ASCII text and standard control keys like space, return and backspace
* IDCMP_RAWKEY - returns all keycodes, both key-up and key-down, including function keys (it's mean keyboards, moving, gadget (close/resize) and many other things)

#### Look here for more about keycodes http://en.wikibooks.org/wiki/Aros/Developer/Docs/Libraries/Keymap
### INTUITICKS

Basically, creating an IDCMP loop to check for user input and/or timer events. Then you probably set up a timer device call that will give you those events. You have to update your window content with the help of IDCMP_INTUITICKS ("ticks" roughly ten times a second). These tick events are to be used as wake up call, and not as timers.
Of course you might want to only update the content every 3rd intuitick for example and only, if the proportional gadget has changed etc.

### Tablets

old and new style tablets events as defined in Intuition
System support for tablets started on WB 2.x. At that time, tablet drivers were supposed to send informations to the input device as events such as (X,Y) range and coordinates plus the pressure. This method is known today as old style tablet events.
Starting from WB3.0, a new kind of tablet events has been defined to support more tablet's features such as proximity, tilt, etc. This method is known as new style tablet events.
All IntuiMessages are now slightly extended. The ExtIntuiMessage structure has an additional field for tablet data, which is usually NULL. If a tablet driver which is sending IESUBCLASS_NEWTABLET events is installed in the system, windows with the WA_TabletMessages property set will find that eim_TabletData points to the TabletData structure. Applications must first check that this field is non-NULL; it will be NULL for certain kinds of message, including mouse activity generated from other than the tablet (i.e. the keyboard equivalents or the mouse itself).
WA_TabletMessages - (BOOL) Set to TRUE to request extended IntuiMessages for your window. If a tablet driver is generating IESUBCLASS_NEWTABLET input events, you will be able to receive extended tablet information with most IntuiMessages. See the eim_TabletData field of the ExtIntuiMessage structure. Defaults to FALSE. (V39)
(WA_Dummy + 0x37) is a boolean. Set to TRUE to request that tablet information be included in IntuiMessages sent to your window. Requires that something (i.e. a tablet driver) feed IESUBCLASS_NEWTABLET InputEvents into the system. For a pointer to the TabletData, examine the ExtIntuiMessage->eim_TabletData field.
Intuition supports the IESUBCLASS_NEWTABLET subclass of the IECLASS_NEWPOINTERPOS event.
The ie_EventAddress of such an event points to a TabletData structure
The TabletData structure contains certain elements including a taglist. The taglist can be used for special tablet parameters. A tablet driver should include only those tag-items the tablet supports. An application can listen for any tag-items that interest it. Note: an application must set the WA_TabletMessages attribute to TRUE to receive this extended information in its IntuiMessages.
The definitions given here MUST be followed. Pay careful attention to normalization and the interpretation of signs.
TABLETA_TabletZ: the current value of the tablet in the Z direction. This unsigned value should typically be in the natural units of the tablet. You should also provide TABLETA_RangeZ.
TABLETA_RangeZ: the maximum value of the tablet in the Z direction. Normally specified along with TABLETA_TabletZ, this allows the application to scale the actual Z value across its range.
TABLETA_AngleX: the angle of rotation or tilt about the X-axis. This number should be normalized to fill a signed long integer. Positive values imply a clockwise rotation about the X-axis when viewing from +X towards the origin.
TABLETA_AngleY: the angle of rotation or tilt about the Y-axis. This number should be normalized to fill a signed long integer. Positive values imply a clockwise rotation about the Y-axis when viewing from +Y towards the origin.
TABLETA_AngleZ: the angle of rotation or tilt about the Z axis. This number should be normalized to fill a signed long integer. Positive values imply a clockwise rotation about the Z-axis when viewing from +Z towards the origin.
Note: a stylus that supports tilt should use the TABLETA_AngleX and TABLETA_AngleY attributes. Tilting the stylus so the tip points towards increasing or decreasing X is actually a rotation around the Y-axis. Thus, if the stylus tip points towards positive X, then that tilt is represented as a negative TABLETA_AngleY. Likewise, if the stylus tip points towards positive Y, that tilt is represented by positive TABLETA_AngleX.
TABLETA_Pressure: the pressure reading of the stylus. The pressure should be normalized to fill a signed long integer. Typical devices won't generate negative pressure, but the possibility is not precluded. The pressure threshold which is considered to cause a button-click is expected to be set in a Preferences program supplied by the tablet vendor. The tablet driver would send IECODE_LBUTTON-type events as the pressure crossed that threshold.
TABLETA_ButtonBits: ti_Data is a long integer whose bits are to be interpreted at the state of the first 32 buttons of the tablet.
TABLETA_InProximity: ti_Data is a boolean. For tablets that support proximity, they should send the TABLETA_InProximity,FALSE} tag item when the stylus is out of proximity. Can be used as a mouse-blanking commodity which keys off this to blank the mouse. When this tag is absent, the stylus is assumed to be in proximity.
TABLETA_ResolutionX: ti_Data is an unsigned long integer which is the x-axis resolution in dots per inch.
TABLETA_ResolutionY: ti_Data is an unsigned long integer which is the y-axis resolution in dots per inch.

## GUI Systems

Although AmigaOS(TM) started out with intuition based Menus, Gadgets, Requesters and Events.
The Amiga has introduced many alternatives like GadTools, BOOPSI, ASL, BGui, ReqTools, ClassAct and MUI. AROS has chosen a MUI rewrite (Zune) to be the default GUI tool set, for example Zune (MUI) Menus.
The rest of this page contains information (intuition based only) and is of backwards compatibility only.

### Defining Menus

If you want to define your own menus, then I think intuition.library also covers you there, although menus are best left till later as IMHO they are overly complex & error prone.
For each main menu heading (i.e. top option) in the menu bar, you declare one Menu structure for each. For each item or sub-item within a menu, you declare one a MenuItem structure for each. You should use more MenuItem than Menu. Text-based menus require an additional IntuiText structure for each menu and (sub)item. (they appear the most). Image menus require the image struct.
To use Menus you need to use the Menu and MenuItem structures, and then attached them to a Window. Please note than the IntuiTexts and Image structure should be defined before the MenuItem structures that are calling them.

### Adding and Removing Menus from a Window

To add or remove a menu from a window, you need to use the following commands:
BOOL SetMenuStrip( struct Window *window, struct Menu *menu )
void ClearMenuStrip( struct Window *window )
Use the SetMenuStrip command after the Window has been defined and opened and provide the address of the Window and the address of the last Menu structure in the linked list. Before closing a window, you must use ClearMenuStrip command first to remove the menu from the screen before closing a Window. Attaching menus to windows rather than screens can allow your program to have flexibility so if you had multiple windows open you can customise the menu to suit the appropriate window, for example, in a paint package or video program you can have smaller windows with their own menus.

### Enabling and Disabling Menu Items

It is possible to enable or disable menu items, when you don`t wish a user to have access to a menu function. This can be done with the OnMenu and OffMenu functions:
void OffMenu( struct Window *window, unsigned long menuNumber)
void OnMenu( struct Window *window, unsigned long menuNumber )
Just provide the menu number of the item to enable or disable. If you change the CHECKED or ITEMENABLED values of menu items then you can refresh the menu using ResetMenuStrip command which is similar and faster than using SetMenuStrip command.

### Menu Example
## Requesters

AROS supports several types of requesters: original system (intuition) and ASL, ReqTools and MUI (recommended). The intuition AutoRequest and Request functions are now deprecated.
Doesn't the file requester returns a full path? Requires extra steps.

### EasyRequest

EasyRequest provides a simple way to make a requester that allows the user to select one of a limited number of choices
LONG EasyRequest( struct Window *window, struct EasyStruct *easyStruct, ULONG *idcmpPtr, APTR argl, ... );
LONG EasyRequestArgst struct Window *window, struct EasyStruct *easyStruct, ULONG *idcmpPtr, APTR ergs );

### Requester Example
#### ASL

Take a look here as well

#### Intuition

It is a very easy to use and just needs a Window with which to attach, a structure, a pointer to a list of IDCMP flags and optional arguments.

### Requester Reference

BuildSysRequest(Window)
FreeSysRequest (Window)
AutoRequest( Window, BodyText, PosText, NegText, PosFlags, NegFlags, Width, Height)

## Gadgets

Each gadget (used in a window or requester) creates a separate Gadget struct
Highlighting flags
GFLG_GADGHNONE - GFLG_GADGHCOMP - GFLG_GADGHBOX - GFLG_GADGHIMAGE -
In addition to the highlighting flags, these other values may be set in the Flags field of the Gadget structure.
GFLG_GADGIMAGE - GFLG_RELBOTTOM - GFLG_RELRIGHT - GFLG_RELWIDTH - GFLG_RELHEIGHT - GFLG_SELECTED - GFLG_DISABLED - GFLG_STRINGEXTEND - GFLG_TABCYCLE -
Gadget Activation Flags - may be set in the Activation field of the Gadget structure.
GACT_TOGGLESELECT GACT_IMMEDIATE GACT_RELVERIFY GACT_ENDGADGET GACT_FOLLOWMOUSE
Border Flags
GACT_RIGHTBORDER GACT_LEFTBORDER GACT_TOPBORDER GACT_BOTTOMBORDER
The following flags apply only to string gadgets:
GACT_STRINGCENTER GACT_STRINGRIGHT GACT_STRINGLEFT GACT_LONGINT GACT_ALTKEYMAP GACT_BOOLEXTEND GACT_STRINGEXTEND
If you use old-fashioned struct Gadget, you need to calculate and set BODY and POT fields of the PropInfo structure appropriately.
Read more gadtools.library.

### String

String gadgets require their own special structure called the StringInfo structure. For a string gadget, set the GadgetType field in the Gadget structure to GTYP_STRGADGET. Set the SpecialInfo field to point to an instance of a StringInfo structure, which must be initialized by the application.

### Custom

Custom string editing

### Proportional

In the Gadget structure, set the GadgetType field to GTYP_PROPGADGET and place the address of the PropInfo structure in the SpecialInfo field.
To change the flags and the pot and body variables after the gadget is displayed, the program can call NewModifyProp.
void NewModifyProp( struct Gadget *gadget, struct Window *window, struct Requester *requester,

### BOOPSI

BOOPSI is great for GUI stuff and runtime class loading/method dispatching. It's written in C and the designers made a *very* good job when you realise the limitations of the language for this kind of system. But consider if we had decent C++ support since the start of Amigas, sure BOOPSI would have been written in it.
The thing is, BOOPSI lends itself well to event-driven code (such as a GUI) where the users interaction is rate determining. However, the method dispatch mechanisms and data access methods are vastly slower (by virtue of how they work) than a C++ virtual function call, let alone a non-virtual or static member func.
You wouldn't want to rely on BOOPSI for all your OOP needs. Imagine the speed penalty of the method calls used in a time critical loop. Ouch :-)
If you use BOOPSI scrollers, you can set Total, Visible and Top attributes. And you can let it send you messages when the user moves the bar. Intuition comes with its own BOOPSI scroller class - the propgclass. It is better integrated inside the window border.
BOOPSI

#### Classes

BOOPSIClasses

## Misc

There also seems to be a problem with sending the SA_PubSig signal to the SA_PubTask. The SA_PubTask gets the signal, if UnlockPubScreen is called and this was the last lock. This is independent of the number of windows on the screen.
So this can happen:
As you can see in, it seems to be not necessary to lock a pubscreen to open a window on it, at least, if you own it.

### Starting from
#### shell-only applications

On AROS, you have your normal entry point as main(int argc, char **argv).
If argc == 0, then argv actually points to a struct WBStartup.
If argc > 0, then the program was started from CLI.
There are two ways to start a program - CLI method & WB method - from shell or from workbench. The shell method is easier. For apps you send two arguments, the program name & filename to open. So argc = 2, argv[ 0 ] = program name & argv[ 1 ] = full path.
But when you start from workbench the shell argc = 0. But workbench (Wanderer or Magellan) sends a WB message. In the message argc = 2. Again argv[ 0 ] = program name & argv[ 1 ] = full path. But the way workbench deals with the path is different. Just like using a file requester there is a PathPart & FilePart. Yo can grab the FilePart without the PathPart. So when the picture file & program are in the same directory no problem. It doesn't need a full path.
So to resolve the issue, need to revise the code in main for the WB message to get the PathPart & then use AddPart to combine PathPart + FilePart to get a full path not just a filename.
However, programs run from CLI *MUST* call Permit for each Forbid since the final 'rts' drops back to shell, and does not terminate the process.
Semaphores should be used when possible. Forbid/Permit should only be used when there is no alternative. Semaphores can be very useful for things like access to memory pools, lists that could be modified by other threads, etc. etc.
Some programs use the technique of starting a new process and clearing cli_Module in order to detach from the shell they are run from. At least for FileX (see contrib/aminet/disk/moni/filex/main.c), this doesn't seem to work anymore. FileX only works if the SYNC argument is used to disable this behaviour.
Does the standard startup code or shell support detaching like this? Perhaps the seglist is being unloaded regardless of the value placed in cli_Module.
Would it be feasible to keep libraries open at exit if cli_Module has been cleared by the program? And could they then be closed when the detached process exits? Not really because it wouldn't fix more common "split segment list" way of detaching.
How does that differ from what FileX does? :-| I presume the similarity of the SegmentSplit function name is misleading. Yeah, FileX does not do any segment split tricks (perhaps it originally did?), it only clears cli_Module. "Standard" segment list split is to have 2 (or more) segments, code in first segment unlinks following segment(s) from single linked segment list -> only first segment is freed by dos.
It is aroscbase that is set to NULL (guess it is also freed) when original process exists. Which is of course still in use by detached process.. Ouch. I guess FileX doesn't use detach.o? It should to avoid such problems.
It implies to include aros/detach.h and to not link against the standard startup module but against detach.o as Fabio just said. It is done in the mmakefile.src by detach=yes assertion. One can even choose where the detachment has to occur by using the Detach function.
AmigaOS libnix opens own console only for libc I/O. It does not reassign default dos.library streams to it. In other words: when the program is started from CLI, libc I/O (printf, write, stdin, stdout, etc.) is directed into dos.library default streams. When program is started from Workbench, libc opens own window for own I/O, but does not touch dos.library streams. As a consequence, when started from WB, printf will send a string to __stdiowin, but Printf will send it to NIL:.

#### Wanderer

OpenWorkbenchObjectA
That final Forbid guarantees the Workbench don't have a change to UnLoadSeg the seglist of the program while the program is still executes.
If there is no Forbid, the ReplyMsg results in task scheduling, and Workbench get change to run. Workbench UnLoadSeg the seglist, and the last few instructions are executed on unallocated memory. This will lead into crashes.
There is no need for final Permit, since the process will RemTask(NULL) itself eventually (default Task EndPC), and this completely removes the process anyway.

### Using Screens

use intuition.library/StartScreenNotifyTagList in order to allow screen preferences changes without having to close/reopen it
There are some additional functions you can use to manipulate screens.
See Intuition Reference documentation for further commands.

### Backfill Hook

see this thread
And here the open screen call:
Please don't use ULONG's to store/cast pointers in your code. use APTR/IPTR where appropriate.
If the code you posted is the code in its entirety, then the reason why it doesn't work maybe because of the way you have filled sbackfillhook. in Demos/scrbackfill the hook is filled like:
HookEntry is defined in clib/alib_protos.h and MyBackfillFunc is:
Or just look in Demos/scrbackfill.c

### Windows Misc

To hide a window (and make in reappear again!), use ChangeWindowShape. Still have no idea, how to make a window opened with WA_Visible=FALSE visible again ;)
If we get a MENUVERIFY message, we look at the according open window. If it has WFLG_RMBTRAP cleared at the time of the mouse click, we display an according AROS intuition menu.
the busy pointer, I have tried adding ..
as I will only get the default pointer and not the current one that might be set by an application using SetWindowPointer or SetPointer functions.
Is there a way to get the current pointer bitmap? You could always patch the necessary function at runtime so that your own routine would be called with the necessary information, and then do what you need (as well as call the original function to actually set the visible pointer).
* intercept the call,
* copy the bitmap so that I can use it for my own purpose
* forward the call to the original function
Digging into it is seems that it's not SetWindowPointerA that I shall patch but rather ChangeExtSpriteA. SetWindowPointer is used when a new pointer is set for a window, this pointer will therefore be used when the window is active. But ChangeExtSprite is called each time the pointer changes, i.e. also when active window is changing.
Is there a way to get notification of the current pointer change? An application can change the pointer image at any time by calling SetWindowPointer, for example to show the busy pointer. These changes are not reflected by a file change and will not cause a DOS notification.