16747b715Smrg Multi-monitor Mode Setting APIs 26747b715Smrg Keith Packard, <keithp@keithp.com 36747b715Smrg 6 March 2007 46747b715Smrg 56747b715Smrg1. Introduction 66747b715Smrg 76747b715SmrgThis document describes a set of mode setting APIs added in X server version 86747b715Smrg1.3 that support multiple monitors per card. These interfaces expose the 96747b715Smrgunderlying hardware CRTC and output concepts to the xf86 DDX layer so that 106747b715Smrgthe implementation of initial server setup and mode changes through 116747b715Smrgextensions can be shared across drivers. In addition, these new interfaces 126747b715Smrgsupport a new configuration mechanism as well which allows each monitor to 136747b715Smrgbe customized separately providing a consistent cross-driver configuration 146747b715Smrgmechanism that supports the full range of output features. 156747b715Smrg 166747b715SmrgAll of the code implementing this interface can be found in hw/xfree86/modes 176747b715Smrgin the X server sources. 186747b715Smrg 196747b715Smrg2. Overview 206747b715Smrg 216747b715SmrgThis document describes both the driver API and the configuration data 226747b715Smrgplaced in xorg.conf; these are entirely separate as the driver has no 236747b715Smrginteraction with the configuration information at all. Much of the structure 246747b715Smrghere is cloned from the RandR extension version 1.2 additions which deal 256747b715Smrgwith the same kinds of information. 266747b715Smrg 276747b715Smrg2.1 API overview 286747b715Smrg 296747b715SmrgThe mode setting API is expressed through two new driver-visible objects, 306747b715Smrgthe 'CRTC' (xf86CrtcRec) and the 'Output' (xf86OutputRec). A CRTC refers to 316747b715Smrghardware within the video system that can scan a subset of the framebuffer 326747b715Smrgand generate a video signal. An Output receives that signal and transmits it 336747b715Smrgto a monitor, projector or other device. 346747b715Smrg 356747b715SmrgThe xf86CrtcRec and xf86OutputRec contain a small amount of state data 366747b715Smrgrelated to the object along with a pointer to a set of functions provided by 376747b715Smrgthe driver that manipulate the object in fairly simple ways. 386747b715Smrg 396747b715SmrgTo emulate older behaviour, one of the outputs is picked as the 'compat' 406747b715Smrgoutput; this output changes over time as outputs are detected and used, the 416747b715Smrggoal is to always have one 'special' output which is used for operations 426747b715Smrgwhich need a single defined monitor (like XFree86-VidModeExtension mode 436747b715Smrgsetting, RandR 1.1 mode setting, DDC property setting, etc.). 446747b715Smrg 456747b715Smrg2.1.1 Output overview 466747b715Smrg 476747b715SmrgAs outputs are connected to monitors, they hold a list of modes supported by 486747b715Smrgthe monitor. If the monitor and output support DDC, then the list of modes 496747b715Smrggenerally comes from the EDID data in the monitor. Otherwise, the server 506747b715Smrguses the standard VESA modes, pruned by monitor timing. If the configuration 516747b715Smrgfile doesn't contain monitor timing data, the server uses default timing 526747b715Smrginformation which supports 640x480, 800x600 and 1024x768 all with a 60Hz 536747b715Smrgrefresh rate. 546747b715Smrg 556747b715SmrgAs hardware often limits possible configuration combinations, each output 566747b715Smrgknows the set of CRTCs that it can be connected to as well as the set of 57ed6184dfSmrgother outputs which can be simultaneously connected to a CRTC. 586747b715Smrg 596747b715Smrg2.1.2 CRTC overview 606747b715Smrg 616747b715SmrgCRTCs serve only to stream frame buffer data to outputs using a mode line. 626747b715SmrgIdeally, they would not be presented to the user at all, and in fact the 636747b715Smrgconfiguration file doesn't expose them. The RandR 1.2 protocol does, but the 646747b715Smrghope there is that client-side applications will hide them carefully away. 656747b715Smrg 666747b715SmrgEach crtc has an associated cursor, along with the current configuration. 676747b715SmrgAll of the data needed to determine valid configurations is contained within 686747b715Smrgthe Outputs. 696747b715Smrg 706747b715Smrg2.2 Configuration overview 716747b715Smrg 726747b715SmrgAs outputs drive monitors, the "Monitor" section has been repurposed to 736747b715Smrgdefine their configuration. This provides for a bit more syntax than 746747b715Smrgthe large list of driver-specific options that were used in the past for 756747b715Smrgsimilar configuration. 766747b715Smrg 776747b715SmrgHowever, the existing "Monitor" section referenced by the active "Screen" 786747b715Smrgsection no longer has any use at all; some sensible meaning for this 796747b715Smrgparameter is needed now that a Screen can have multiple Monitors. 806747b715Smrg 816747b715Smrg3. Public Functions 826747b715Smrg 836747b715Smrg3.1 PreInit functions 846747b715Smrg 856747b715SmrgThese functions should be used during the driver PreInit phase, they are 866747b715Smrgarranged in the order they should be invoked. 876747b715Smrg 886747b715Smrg void 896747b715Smrg xf86CrtcConfigInit (ScrnInfoPtr scrn 906747b715Smrg const xf86CrtcConfigFuncsRec *funcs) 916747b715Smrg 926747b715SmrgThis function allocates and initializes structures needed to track CRTC and 936747b715SmrgOutput state. 946747b715Smrg 956747b715Smrg void 966747b715Smrg xf86CrtcSetSizeRange (ScrnInfoPtr scrn, 976747b715Smrg int minWidth, int minHeight, 986747b715Smrg int maxWidth, int maxHeight) 996747b715Smrg 1006747b715SmrgThis sets the range of screen sizes supported by the driver. 1016747b715Smrg 1026747b715Smrg xf86CrtcPtr 1036747b715Smrg xf86CrtcCreate (ScrnInfoPtr scrn, 1046747b715Smrg const xf86CrtcFuncsRec *funcs) 1056747b715Smrg 1066747b715SmrgCreate one CRTC object. See the discussion below for a description of the 1076747b715Smrgcontents of the xf86CrtcFuncsRec. Note that this is done in PreInit, so it 1086747b715Smrgshould not be re-invoked at each server generation. Create one of these for 1096747b715Smrgeach CRTC present in the hardware. 1106747b715Smrg 1116747b715Smrg xf86OutputPtr 1126747b715Smrg xf86OutputCreate (ScrnInfoPtr scrn, 1136747b715Smrg const xf86OutputFuncsRec *funcs, 1146747b715Smrg const char *name) 1156747b715Smrg 1166747b715SmrgCreate one Output object. See the discussion below for a description of the 1176747b715Smrgcontents of the xf86OutputFuncsRec. This is also called from PreInit and 1186747b715Smrgneed not be re-invoked at each ScreenInit time. An Output should be created 1196747b715Smrgfor every Output present in the hardware, not just for outputs which have 1206747b715Smrgdetected monitors. 1216747b715Smrg 1226747b715Smrg Bool 1236747b715Smrg xf86OutputRename (xf86OutputPtr output, const char *name) 1246747b715Smrg 1256747b715SmrgIf necessary, the name of an output can be changed after it is created using 1266747b715Smrgthis function. 1276747b715Smrg 1286747b715Smrg Bool 1296747b715Smrg xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) 1306747b715Smrg 1316747b715SmrgUsing the resources provided, and the configuration specified by the user, 1326747b715Smrgthis function computes an initial configuration for the server. It tries to 1336747b715Smrgenable as much hardware as possible using some fairly simple heuristics. 1346747b715Smrg 1356747b715SmrgThe 'canGrow' parameter indicates that the frame buffer does not have a fixed 13635c4bbdfSmrgsize. When the frame buffer has a fixed size, the configuration selects a 13735c4bbdfSmrg'reasonablely large' frame buffer so that common reconfiguration options are 13835c4bbdfSmrgpossible. For resizable frame buffers, the frame buffer is set to the smallest 13935c4bbdfSmrgsize that encloses the desired configuration. 1406747b715Smrg 1416747b715Smrg3.2 ScreenInit functions 1426747b715Smrg 1436747b715SmrgThese functions should be used during the driver ScreenInit phase. 1446747b715Smrg 1456747b715Smrg Bool 1466747b715Smrg xf86DiDGAInit (ScreenPtr screen, unsigned long dga_address) 1476747b715Smrg 1486747b715SmrgThis function provides driver-independent accelerated DGA support for some 1496747b715Smrgof the DGA operations; using this, the driver can avoid needing to implement 1506747b715Smrgany of the rest of DGA. 1516747b715Smrg 1526747b715Smrg Bool 1536747b715Smrg xf86SaveScreen(ScreenPtr pScreen, int mode) 1546747b715Smrg 1556747b715SmrgStick this in pScreen->SaveScreen and the core X screen saver will be 1566747b715Smrgimplemented by disabling outputs and crtcs using their dpms functions. 1576747b715Smrg 1586747b715Smrg void 1596747b715Smrg xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) 1606747b715Smrg 1616747b715SmrgPass this function to xf86DPMSInit and all DPMS mode switching will be 1626747b715Smrgmanaged by using the dpms functions provided by the Outputs and CRTCs. 1636747b715Smrg 1646747b715Smrg Bool 1656747b715Smrg xf86CrtcScreenInit (ScreenPtr screen) 1666747b715Smrg 1676747b715SmrgThis function completes the screen initialization process for the crtc and 1686747b715Smrgoutput objects. Call it near the end of the ScreenInit function, after the 1696747b715Smrgframe buffer and acceleration layers have been added. 1706747b715Smrg 1716747b715Smrg3.3 EnterVT functions 1726747b715Smrg 1736747b715SmrgFunctions used during EnterVT, or whenever the current configuration needs 1746747b715Smrgto be applied to the hardware. 1756747b715Smrg 1766747b715Smrg Bool 1776747b715Smrg xf86SetDesiredModes (ScrnInfoPtr scrn) 1786747b715Smrg 1796747b715Smrgxf86InitialConfiguration selects the desired configuration at PreInit time; 1806747b715Smrgwhen the server finally hits ScreenInit, xf86SetDesiredModes is used by the 1816747b715Smrgdriver to take that configuration and apply it to the hardware. In addition, 1826747b715Smrgsuccessful mode selection at other times updates the configuration that will 1836747b715Smrgbe used by this function, so LeaveVT/EnterVT pairs can simply invoke this 1846747b715Smrgand return to the previous configuration. 1856747b715Smrg 1866747b715Smrg3.4 SwitchMode functions 1876747b715Smrg 1886747b715SmrgFunctions called from the pScrn->SwitchMode hook, which is used by the 1896747b715SmrgXFree86-VidModeExtension and the keypad mode switch commands. 1906747b715Smrg 1916747b715Smrg Bool 1926747b715Smrg xf86SetSingleMode (ScrnInfoPtr scrn, 1936747b715Smrg DisplayModePtr desired, 1946747b715Smrg Rotation rotation) 1956747b715Smrg 1966747b715SmrgThis function applies the specified mode to all active outputs. Which is to 1976747b715Smrgsay, it picks reasonable modes for all active outputs, attempting to get the 1986747b715Smrgscreen to the specified size while not breaking anything that is currently 1996747b715Smrgworking. 2006747b715Smrg 2016747b715Smrg3.7 get_modes functions 2026747b715Smrg 2036747b715SmrgFunctions called during output->get_modes to help build lists of modes 2046747b715Smrg 2056747b715Smrg xf86MonPtr 2066747b715Smrg xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) 2076747b715Smrg 2086747b715SmrgThis returns the EDID data structure for the 'output' using the I2C bus 2096747b715Smrg'pDDCBus'. This has no effect on 'output' itself. 2106747b715Smrg 2116747b715Smrg void 2126747b715Smrg xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) 2136747b715Smrg 2146747b715SmrgOnce the EDID data has been fetched, this call applies the EDID data to the 2156747b715Smrgoutput object, setting the physical size and also various properties, like 2166747b715Smrgthe DDC root window property (when output is the 'compat' output), and the 2176747b715SmrgRandR 1.2 EDID output properties. 2186747b715Smrg 2196747b715Smrg DisplayModePtr 2206747b715Smrg xf86OutputGetEDIDModes (xf86OutputPtr output) 2216747b715Smrg 2226747b715SmrgGiven an EDID data structure, this function computes a list of suitable 2236747b715Smrgmodes. This function also applies a sequence of 'quirks' during this process 2246747b715Smrgso that the returned modes may not actually match the mode data present in 2256747b715Smrgthe EDID data. 2266747b715Smrg 2276747b715Smrg3.6 Other functions 2286747b715Smrg 2296747b715SmrgThese remaining functions in the API can be used by the driver as needed. 2306747b715Smrg 2316747b715Smrg Bool 2326747b715Smrg xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, 2336747b715Smrg int x, int y) 2346747b715Smrg 2356747b715SmrgApplies a mode to a CRTC. All of the outputs which are currently using the 2366747b715Smrgspecified CRTC are included in the mode setting process. 'x' and 'y' are the 2376747b715Smrgoffset within the frame buffer that the crtc is placed at. No checking is 2386747b715Smrgdone in this function to ensure that the mode is usable by the active 2396747b715Smrgoutputs. 2406747b715Smrg 2416747b715Smrg void 2426747b715Smrg xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) 2436747b715Smrg 2446747b715SmrgThis discards the mode lists for all outputs, re-detects monitor presence 2456747b715Smrgand then acquires new mode lists for all monitors which are not disconnected. 2466747b715SmrgMonitor configuration data is used to modify the mode lists returned by the 2476747b715Smrgoutputs. 'maxX' and 'maxY' limit the maximum size modes that will be 2486747b715Smrgreturned. 2496747b715Smrg 2506747b715Smrg void 2516747b715Smrg xf86SetScrnInfoModes (ScrnInfoPtr pScrn) 2526747b715Smrg 2536747b715SmrgThis copies the 'compat' output mode list into the pScrn modes list which is 2546747b715Smrgused by the XFree86-VidModeExtension and the keypad mode switching 2556747b715Smrgoperations. The current 'desired' mode for the CRTC associated with the 2566747b715Smrg'compat' output is placed first in this list to indicate the current mode. 2576747b715SmrgUsually, the driver won't need to call this function as 2586747b715Smrgxf86InitialConfiguration will do so automatically, as well as any RandR 2596747b715Smrgfunctions which reprobe for modes. However, if the driver reprobes for modes 2606747b715Smrgat other times using xf86ProbeOutputModes, this function needs to be called. 2616747b715Smrg 2626747b715Smrg Bool 2636747b715Smrg xf86DiDGAReInit (ScreenPtr pScreen) 2646747b715Smrg 2656747b715SmrgThis is similar to xf86SetScrnInfoModes, but it applies the 'compat' output 2666747b715Smrgmode list to the set of modes advertised by the DGA extension; it needs to 2676747b715Smrgbe called whenever xf86ProbeOutputModes is invoked. 2686747b715Smrg 2696747b715Smrg void 2706747b715Smrg xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) 2716747b715Smrg 2726747b715SmrgAfter any sequence of calls using xf86CrtcSetMode, this function cleans up 2736747b715Smrgany leftover Output and CRTC objects by disabling them, saving power. It is 2746747b715Smrgsafe to call this whenever the server is running as it only disables objects 2756747b715Smrgwhich are not currently in use. 2766747b715Smrg 2776747b715Smrg4. CRTC operations 2786747b715Smrg 2796747b715Smrg4.1 CRTC functions 2806747b715Smrg 2816747b715SmrgThese functions provide an abstract interface for the CRTC object; most 2826747b715Smrgmanipulation of the CRTC object is done through these functions. 2836747b715Smrg 2846747b715Smrg void 2856747b715Smrg crtc->funcs->dpms (xf86CrtcPtr crtc, int mode) 2866747b715Smrg 2876747b715SmrgWhere 'mode' is one of DPMSModeOff, DPMSModeSuspend, DPMSModeStandby or 2886747b715SmrgDPMSModeOn. This requests that the crtc go to the specified power state. 2896747b715SmrgWhen changing power states, the output dpms functions are invoked before the 2906747b715Smrgcrtc dpms functions. 2916747b715Smrg 2926747b715Smrg void 2936747b715Smrg crtc->funcs->save (xf86CrtcPtr crtc) 2946747b715Smrg 2956747b715Smrg void 2966747b715Smrg crtc->funcs->restore (xf86CrtcPtr crtc) 2976747b715Smrg 2986747b715SmrgPreserve/restore any register contents related to the CRTC. These are 2996747b715Smrgstrictly a convenience for the driver writer; if the existing driver has 3006747b715Smrgfully operation save/restore functions, you need not place any additional 3016747b715Smrgcode here. In particular, the server itself never uses this function. 3026747b715Smrg 3036747b715Smrg Bool 3046747b715Smrg crtc->funcs->lock (xf86CrtcPtr crtc) 3056747b715Smrg 3066747b715Smrg void 3076747b715Smrg crtc->funcs->unlock (xf86CrtcPtr crtc) 3086747b715Smrg 3096747b715SmrgThese functions are invoked around mode setting operations; the intent is 3106747b715Smrgthat DRI locking be done here to prevent DRI applications from manipulating 3116747b715Smrgthe hardware while the server is busy changing the output configuration. If 3126747b715Smrgthe lock function returns FALSE, the unlock function will not be invoked. 3136747b715Smrg 3146747b715Smrg Bool 3156747b715Smrg crtc->funcs->mode_fixup (xf86CrtcPtr crtc, 3166747b715Smrg DisplayModePtr mode, 3176747b715Smrg DisplayModePtr adjusted_mode) 3186747b715Smrg 3196747b715SmrgThis call gives the CRTC a chance to see what mode will be set and to 3206747b715Smrgcomment on the mode by changing 'adjusted_mode' as needed. This function 3216747b715Smrgshall not modify the state of the crtc hardware at all. If the CRTC cannot 3226747b715Smrgaccept this mode, this function may return FALSE. 3236747b715Smrg 3246747b715Smrg void 3256747b715Smrg crtc->funcs->prepare (xf86CrtcPtr crtc) 3266747b715Smrg 3276747b715SmrgThis call is made just before the mode is set to make the hardware ready for 3286747b715Smrgthe operation. A usual function to perform here is to disable the crtc so 3296747b715Smrgthat mode setting can occur with clocks turned off and outputs deactivated. 3306747b715Smrg 3316747b715Smrg void 3326747b715Smrg crtc->funcs->mode_set (xf86CrtcPtr crtc, 3336747b715Smrg DisplayModePtr mode, 3346747b715Smrg DisplayModePtr adjusted_mode) 3356747b715Smrg 3366747b715SmrgThis function applies the specified mode (possibly adjusted by the CRTC 3376747b715Smrgand/or Outputs). 3386747b715Smrg 3396747b715Smrg void 3406747b715Smrg crtc->funcs->commit (xf86CrtcPtr crtc) 3416747b715Smrg 3426747b715SmrgOnce the mode has been applied to the CRTC and Outputs, this function is 3436747b715Smrginvoked to let the hardware turn things back on. 3446747b715Smrg 3456747b715Smrg void 3466747b715Smrg crtc->funcs->gamma_set (xf86CrtcPtr crtc, CARD16 *red, 3476747b715Smrg CARD16 *green, CARD16 *blue, int size) 3486747b715Smrg 3496747b715SmrgThis function adjusts the gamma ramps for the specified crtc. 3506747b715Smrg 3516747b715Smrg void * 3526747b715Smrg crtc->funcs->shadow_allocate (xf86CrtcPtr crtc, int width, int height) 3536747b715Smrg 3546747b715SmrgThis function allocates frame buffer space for a shadow frame buffer. When 3556747b715Smrgallocated, the crtc must scan from the shadow instead of the main frame 3566747b715Smrgbuffer. This is used for rotation. The address returned is passed to the 3576747b715Smrgshadow_create function. This function should return NULL on failure. 3586747b715Smrg 3596747b715Smrg PixmapPtr 3606747b715Smrg crtc->funcs->shadow_create (xf86CrtcPtr crtc, void *data, 3616747b715Smrg int width, int height) 3626747b715Smrg 3636747b715SmrgThis function creates a pixmap object that will be used as a shadow of the 3646747b715Smrgmain frame buffer for CRTCs which are rotated or reflected. 'data' is the 3656747b715Smrgvalue returned by shadow_allocate. 3666747b715Smrg 3676747b715Smrg void 3686747b715Smrg crtc->funcs->shadow_destroy (xf86CrtcPtr crtc, PixmapPtr pPixmap, 3696747b715Smrg void *data) 3706747b715Smrg 3716747b715SmrgDestroys any associated shadow objects. If pPixmap is NULL, then a pixmap 3726747b715Smrgwas not created, but 'data' may still be non-NULL indicating that the shadow 3736747b715Smrghad been allocated. 3746747b715Smrg 3756747b715Smrg void 3766747b715Smrg crtc->funcs->destroy (xf86CrtcPtr crtc) 3776747b715Smrg 3786747b715SmrgWhen a CRTC is destroyed (which only happens in error cases), this function 3796747b715Smrgcan clean up any driver-specific data. 3806747b715Smrg 3816747b715Smrg4.2 CRTC fields 3826747b715Smrg 3836747b715SmrgThe CRTC object is not opaque; there are several fields of interest to the 3846747b715Smrgdriver writer. 3856747b715Smrg 3866747b715Smrg struct _xf86Crtc { 3876747b715Smrg /** 3886747b715Smrg * Associated ScrnInfo 3896747b715Smrg */ 3906747b715Smrg ScrnInfoPtr scrn; 3916747b715Smrg 3926747b715Smrg /** 3936747b715Smrg * Active state of this CRTC 3946747b715Smrg * 3956747b715Smrg * Set when this CRTC is driving one or more outputs 3966747b715Smrg */ 3976747b715Smrg Bool enabled; 3986747b715Smrg 3996747b715Smrg /** Track whether cursor is within CRTC range */ 4006747b715Smrg Bool cursorInRange; 4016747b715Smrg 4026747b715Smrg /** Track state of cursor associated with this CRTC */ 4036747b715Smrg Bool cursorShown; 4046747b715Smrg 4056747b715Smrg /** 4066747b715Smrg * Active mode 4076747b715Smrg * 4086747b715Smrg * This reflects the mode as set in the CRTC currently 4096747b715Smrg * It will be cleared when the VT is not active or 4106747b715Smrg * during server startup 4116747b715Smrg */ 4126747b715Smrg DisplayModeRec mode; 4136747b715Smrg Rotation rotation; 4146747b715Smrg PixmapPtr rotatedPixmap; 4156747b715Smrg void *rotatedData; 4166747b715Smrg 4176747b715Smrg /** 4186747b715Smrg * Position on screen 4196747b715Smrg * 4206747b715Smrg * Locates this CRTC within the frame buffer 4216747b715Smrg */ 4226747b715Smrg int x, y; 4236747b715Smrg 4246747b715Smrg /** 4256747b715Smrg * Desired mode 4266747b715Smrg * 4276747b715Smrg * This is set to the requested mode, independent of 4286747b715Smrg * whether the VT is active. In particular, it receives 4296747b715Smrg * the startup configured mode and saves the active mode 4306747b715Smrg * on VT switch. 4316747b715Smrg */ 4326747b715Smrg DisplayModeRec desiredMode; 4336747b715Smrg Rotation desiredRotation; 4346747b715Smrg int desiredX, desiredY; 4356747b715Smrg 4366747b715Smrg /** crtc-specific functions */ 4376747b715Smrg const xf86CrtcFuncsRec *funcs; 4386747b715Smrg 4396747b715Smrg /** 4406747b715Smrg * Driver private 4416747b715Smrg * 4426747b715Smrg * Holds driver-private information 4436747b715Smrg */ 4446747b715Smrg void *driver_private; 4456747b715Smrg #ifdef RANDR_12_INTERFACE 4466747b715Smrg /** 4476747b715Smrg * RandR crtc 4486747b715Smrg * 4496747b715Smrg * When RandR 1.2 is available, this 4506747b715Smrg * points at the associated crtc object 4516747b715Smrg */ 4526747b715Smrg RRCrtcPtr randr_crtc; 4536747b715Smrg #else 4546747b715Smrg void *randr_crtc; 4556747b715Smrg #endif 4566747b715Smrg }; 4576747b715Smrg 4586747b715Smrg 4596747b715Smrg5. Output functions. 4606747b715Smrg 4616747b715Smrg6. Configuration 4626747b715Smrg 4636747b715SmrgBecause the configuration file syntax is fixed, 4646747b715Smrgthis was done by creating new "Driver" section options that hook specific 4656747b715Smrgoutputs to specific "Monitor" sections in the file. The option: 4666747b715Smrgsection of the form: 4676747b715Smrg 4686747b715Smrg Option "monitor-VGA" "My VGA Monitor" 4696747b715Smrg 4706747b715Smrgconnects the VGA output of this driver to the "Monitor" section with 4716747b715SmrgIdentifier "My VGA Monitor". All of the usual monitor options can now be 4726747b715Smrgplaced in that "Monitor" section and will be applied to the VGA output 4736747b715Smrgconfiguration. 474