There are three types of mode calls:
The ggiCheck*Mode functions test whether a given mode is acceptable or suggest a better one,
The ggiSet*Mode functions try to set the specified mode and fail if that is impossible. ggiSetMode then returns a better suggestion, as ggiCheck*Mode do. (The suggested mode is not silently set.)
ggiGetMode returns the mode that is currently set.
If a given mode can not be set, the structure passed is changed to the suggested mode as follows:
Resolutions are always adjusted up. If you want the next lower, start out at 1,1 (or somewhere else reasonable) and jump up the ladder.
Only if the maximum resolution would be exceeded, resolutions are adjusted down to the maximum.
The above applies to visible and virtual size. If there is interference between them, the visible size is satified first if possible, then the virtual size.
Note that the adjustment of one value do not normally affect other values. For example, if (visible) 320x100 (virtual 320x200) is requested, the visible size may be adjusted to 320x200, but virtual size will be left alone. Of course, if the virtual size becomes less than visible size, then it will be adjusted as well. A good rule of thumb is that anything returned by ggiCheckMode is minimally valid.
Font sizes (i.e. the size of the pixel in textmodes) are handled the other way round: they are adjusted down except when there is nothing below.
Graphtype:
The basic rationale is to change graphtype only, if the card does not support it at all. If the maximum resolution is exceeded, then that is adjusted down and not the graphtype. This assumes, that if you request true-color, you really want that and not so badly the resolution you requested. If this is not the case, you can still retry with another graphtype or GT_AUTO.
If it is necessary to change to change the graphtype, the order should be ascending (if possible), i.e. 1->4->8->15->16->24/32 bit. So you always get a mode which can do more than you requested. Only when no better modes are available, the type is adjusted down.
It is possible to pass GGI_AUTO as any of the parameters. GGI_AUTO is a placeholder (e.g. the program does not care about a specific parameter). The display target will reset GGI_AUTO parameter to a default, such as the maximum, preferred, or GGI_DEFMODE resolution, while being compatible with the other settings. The presence of GGI_AUTO is not flagged as an error.
If ggiSet{Graph,Text}Mode is given GGI_AUTO as one or more of its arguments, it will silently set a mode. To get back this mode, you must use ggiGetMode.
Note: The resulting mode is guaranteed to be valid; if not, the application can assume that it cannot set any mode on the given visual and give up.