1706f2543Smrg Multi-monitor Mode Setting APIs 2706f2543Smrg Keith Packard, <keithp@keithp.com 3706f2543Smrg 6 March 2007 4706f2543Smrg 5706f2543Smrg1. Introduction 6706f2543Smrg 7706f2543SmrgThis document describes a set of mode setting APIs added in X server version 8706f2543Smrg1.3 that support multiple monitors per card. These interfaces expose the 9706f2543Smrgunderlying hardware CRTC and output concepts to the xf86 DDX layer so that 10706f2543Smrgthe implementation of initial server setup and mode changes through 11706f2543Smrgextensions can be shared across drivers. In addition, these new interfaces 12706f2543Smrgsupport a new configuration mechanism as well which allows each monitor to 13706f2543Smrgbe customized separately providing a consistent cross-driver configuration 14706f2543Smrgmechanism that supports the full range of output features. 15706f2543Smrg 16706f2543SmrgAll of the code implementing this interface can be found in hw/xfree86/modes 17706f2543Smrgin the X server sources. 18706f2543Smrg 19706f2543Smrg2. Overview 20706f2543Smrg 21706f2543SmrgThis document describes both the driver API and the configuration data 22706f2543Smrgplaced in xorg.conf; these are entirely separate as the driver has no 23706f2543Smrginteraction with the configuration information at all. Much of the structure 24706f2543Smrghere is cloned from the RandR extension version 1.2 additions which deal 25706f2543Smrgwith the same kinds of information. 26706f2543Smrg 27706f2543Smrg2.1 API overview 28706f2543Smrg 29706f2543SmrgThe mode setting API is expressed through two new driver-visible objects, 30706f2543Smrgthe 'CRTC' (xf86CrtcRec) and the 'Output' (xf86OutputRec). A CRTC refers to 31706f2543Smrghardware within the video system that can scan a subset of the framebuffer 32706f2543Smrgand generate a video signal. An Output receives that signal and transmits it 33706f2543Smrgto a monitor, projector or other device. 34706f2543Smrg 35706f2543SmrgThe xf86CrtcRec and xf86OutputRec contain a small amount of state data 36706f2543Smrgrelated to the object along with a pointer to a set of functions provided by 37706f2543Smrgthe driver that manipulate the object in fairly simple ways. 38706f2543Smrg 39706f2543SmrgTo emulate older behaviour, one of the outputs is picked as the 'compat' 40706f2543Smrgoutput; this output changes over time as outputs are detected and used, the 41706f2543Smrggoal is to always have one 'special' output which is used for operations 42706f2543Smrgwhich need a single defined monitor (like XFree86-VidModeExtension mode 43706f2543Smrgsetting, RandR 1.1 mode setting, DDC property setting, etc.). 44706f2543Smrg 45706f2543Smrg2.1.1 Output overview 46706f2543Smrg 47706f2543SmrgAs outputs are connected to monitors, they hold a list of modes supported by 48706f2543Smrgthe monitor. If the monitor and output support DDC, then the list of modes 49706f2543Smrggenerally comes from the EDID data in the monitor. Otherwise, the server 50706f2543Smrguses the standard VESA modes, pruned by monitor timing. If the configuration 51706f2543Smrgfile doesn't contain monitor timing data, the server uses default timing 52706f2543Smrginformation which supports 640x480, 800x600 and 1024x768 all with a 60Hz 53706f2543Smrgrefresh rate. 54706f2543Smrg 55706f2543SmrgAs hardware often limits possible configuration combinations, each output 56706f2543Smrgknows the set of CRTCs that it can be connected to as well as the set of 57706f2543Smrgother outputs which can be simutaneously connected to a CRTC. 58706f2543Smrg 59706f2543Smrg2.1.2 CRTC overview 60706f2543Smrg 61706f2543SmrgCRTCs serve only to stream frame buffer data to outputs using a mode line. 62706f2543SmrgIdeally, they would not be presented to the user at all, and in fact the 63706f2543Smrgconfiguration file doesn't expose them. The RandR 1.2 protocol does, but the 64706f2543Smrghope there is that client-side applications will hide them carefully away. 65706f2543Smrg 66706f2543SmrgEach crtc has an associated cursor, along with the current configuration. 67706f2543SmrgAll of the data needed to determine valid configurations is contained within 68706f2543Smrgthe Outputs. 69706f2543Smrg 70706f2543Smrg2.2 Configuration overview 71706f2543Smrg 72706f2543SmrgAs outputs drive monitors, the "Monitor" section has been repurposed to 73706f2543Smrgdefine their configuration. This provides for a bit more syntax than 74706f2543Smrgthe large list of driver-specific options that were used in the past for 75706f2543Smrgsimilar configuration. 76706f2543Smrg 77706f2543SmrgHowever, the existing "Monitor" section referenced by the active "Screen" 78706f2543Smrgsection no longer has any use at all; some sensible meaning for this 79706f2543Smrgparameter is needed now that a Screen can have multiple Monitors. 80706f2543Smrg 81706f2543Smrg3. Public Functions 82706f2543Smrg 83706f2543Smrg3.1 PreInit functions 84706f2543Smrg 85706f2543SmrgThese functions should be used during the driver PreInit phase, they are 86706f2543Smrgarranged in the order they should be invoked. 87706f2543Smrg 88706f2543Smrg void 89706f2543Smrg xf86CrtcConfigInit (ScrnInfoPtr scrn 90706f2543Smrg const xf86CrtcConfigFuncsRec *funcs) 91706f2543Smrg 92706f2543SmrgThis function allocates and initializes structures needed to track CRTC and 93706f2543SmrgOutput state. 94706f2543Smrg 95706f2543Smrg void 96706f2543Smrg xf86CrtcSetSizeRange (ScrnInfoPtr scrn, 97706f2543Smrg int minWidth, int minHeight, 98706f2543Smrg int maxWidth, int maxHeight) 99706f2543Smrg 100706f2543SmrgThis sets the range of screen sizes supported by the driver. 101706f2543Smrg 102706f2543Smrg xf86CrtcPtr 103706f2543Smrg xf86CrtcCreate (ScrnInfoPtr scrn, 104706f2543Smrg const xf86CrtcFuncsRec *funcs) 105706f2543Smrg 106706f2543SmrgCreate one CRTC object. See the discussion below for a description of the 107706f2543Smrgcontents of the xf86CrtcFuncsRec. Note that this is done in PreInit, so it 108706f2543Smrgshould not be re-invoked at each server generation. Create one of these for 109706f2543Smrgeach CRTC present in the hardware. 110706f2543Smrg 111706f2543Smrg xf86OutputPtr 112706f2543Smrg xf86OutputCreate (ScrnInfoPtr scrn, 113706f2543Smrg const xf86OutputFuncsRec *funcs, 114706f2543Smrg const char *name) 115706f2543Smrg 116706f2543SmrgCreate one Output object. See the discussion below for a description of the 117706f2543Smrgcontents of the xf86OutputFuncsRec. This is also called from PreInit and 118706f2543Smrgneed not be re-invoked at each ScreenInit time. An Output should be created 119706f2543Smrgfor every Output present in the hardware, not just for outputs which have 120706f2543Smrgdetected monitors. 121706f2543Smrg 122706f2543Smrg Bool 123706f2543Smrg xf86OutputRename (xf86OutputPtr output, const char *name) 124706f2543Smrg 125706f2543SmrgIf necessary, the name of an output can be changed after it is created using 126706f2543Smrgthis function. 127706f2543Smrg 128706f2543Smrg Bool 129706f2543Smrg xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) 130706f2543Smrg 131706f2543SmrgUsing the resources provided, and the configuration specified by the user, 132706f2543Smrgthis function computes an initial configuration for the server. It tries to 133706f2543Smrgenable as much hardware as possible using some fairly simple heuristics. 134706f2543Smrg 135706f2543SmrgThe 'canGrow' parameter indicates that the frame buffer does not have a fixed 136706f2543Smrgsize (fixed size frame buffers are required by XAA). When the frame buffer 137706f2543Smrghas a fixed size, the configuration selects a 'reasonablely large' frame 138706f2543Smrgbuffer so that common reconfiguration options are possible. For resizable 139706f2543Smrgframe buffers, the frame buffer is set to the smallest size that encloses 140706f2543Smrgthe desired configuration. 141706f2543Smrg 142706f2543Smrg3.2 ScreenInit functions 143706f2543Smrg 144706f2543SmrgThese functions should be used during the driver ScreenInit phase. 145706f2543Smrg 146706f2543Smrg Bool 147706f2543Smrg xf86DiDGAInit (ScreenPtr screen, unsigned long dga_address) 148706f2543Smrg 149706f2543SmrgThis function provides driver-independent accelerated DGA support for some 150706f2543Smrgof the DGA operations; using this, the driver can avoid needing to implement 151706f2543Smrgany of the rest of DGA. 152706f2543Smrg 153706f2543Smrg Bool 154706f2543Smrg xf86SaveScreen(ScreenPtr pScreen, int mode) 155706f2543Smrg 156706f2543SmrgStick this in pScreen->SaveScreen and the core X screen saver will be 157706f2543Smrgimplemented by disabling outputs and crtcs using their dpms functions. 158706f2543Smrg 159706f2543Smrg void 160706f2543Smrg xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) 161706f2543Smrg 162706f2543SmrgPass this function to xf86DPMSInit and all DPMS mode switching will be 163706f2543Smrgmanaged by using the dpms functions provided by the Outputs and CRTCs. 164706f2543Smrg 165706f2543Smrg Bool 166706f2543Smrg xf86CrtcScreenInit (ScreenPtr screen) 167706f2543Smrg 168706f2543SmrgThis function completes the screen initialization process for the crtc and 169706f2543Smrgoutput objects. Call it near the end of the ScreenInit function, after the 170706f2543Smrgframe buffer and acceleration layers have been added. 171706f2543Smrg 172706f2543Smrg3.3 EnterVT functions 173706f2543Smrg 174706f2543SmrgFunctions used during EnterVT, or whenever the current configuration needs 175706f2543Smrgto be applied to the hardware. 176706f2543Smrg 177706f2543Smrg Bool 178706f2543Smrg xf86SetDesiredModes (ScrnInfoPtr scrn) 179706f2543Smrg 180706f2543Smrgxf86InitialConfiguration selects the desired configuration at PreInit time; 181706f2543Smrgwhen the server finally hits ScreenInit, xf86SetDesiredModes is used by the 182706f2543Smrgdriver to take that configuration and apply it to the hardware. In addition, 183706f2543Smrgsuccessful mode selection at other times updates the configuration that will 184706f2543Smrgbe used by this function, so LeaveVT/EnterVT pairs can simply invoke this 185706f2543Smrgand return to the previous configuration. 186706f2543Smrg 187706f2543Smrg3.4 SwitchMode functions 188706f2543Smrg 189706f2543SmrgFunctions called from the pScrn->SwitchMode hook, which is used by the 190706f2543SmrgXFree86-VidModeExtension and the keypad mode switch commands. 191706f2543Smrg 192706f2543Smrg Bool 193706f2543Smrg xf86SetSingleMode (ScrnInfoPtr scrn, 194706f2543Smrg DisplayModePtr desired, 195706f2543Smrg Rotation rotation) 196706f2543Smrg 197706f2543SmrgThis function applies the specified mode to all active outputs. Which is to 198706f2543Smrgsay, it picks reasonable modes for all active outputs, attempting to get the 199706f2543Smrgscreen to the specified size while not breaking anything that is currently 200706f2543Smrgworking. 201706f2543Smrg 202706f2543Smrg3.7 get_modes functions 203706f2543Smrg 204706f2543SmrgFunctions called during output->get_modes to help build lists of modes 205706f2543Smrg 206706f2543Smrg xf86MonPtr 207706f2543Smrg xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) 208706f2543Smrg 209706f2543SmrgThis returns the EDID data structure for the 'output' using the I2C bus 210706f2543Smrg'pDDCBus'. This has no effect on 'output' itself. 211706f2543Smrg 212706f2543Smrg void 213706f2543Smrg xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) 214706f2543Smrg 215706f2543SmrgOnce the EDID data has been fetched, this call applies the EDID data to the 216706f2543Smrgoutput object, setting the physical size and also various properties, like 217706f2543Smrgthe DDC root window property (when output is the 'compat' output), and the 218706f2543SmrgRandR 1.2 EDID output properties. 219706f2543Smrg 220706f2543Smrg DisplayModePtr 221706f2543Smrg xf86OutputGetEDIDModes (xf86OutputPtr output) 222706f2543Smrg 223706f2543SmrgGiven an EDID data structure, this function computes a list of suitable 224706f2543Smrgmodes. This function also applies a sequence of 'quirks' during this process 225706f2543Smrgso that the returned modes may not actually match the mode data present in 226706f2543Smrgthe EDID data. 227706f2543Smrg 228706f2543Smrg3.6 Other functions 229706f2543Smrg 230706f2543SmrgThese remaining functions in the API can be used by the driver as needed. 231706f2543Smrg 232706f2543Smrg Bool 233706f2543Smrg xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, 234706f2543Smrg int x, int y) 235706f2543Smrg 236706f2543SmrgApplies a mode to a CRTC. All of the outputs which are currently using the 237706f2543Smrgspecified CRTC are included in the mode setting process. 'x' and 'y' are the 238706f2543Smrgoffset within the frame buffer that the crtc is placed at. No checking is 239706f2543Smrgdone in this function to ensure that the mode is usable by the active 240706f2543Smrgoutputs. 241706f2543Smrg 242706f2543Smrg void 243706f2543Smrg xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) 244706f2543Smrg 245706f2543SmrgThis discards the mode lists for all outputs, re-detects monitor presence 246706f2543Smrgand then acquires new mode lists for all monitors which are not disconnected. 247706f2543SmrgMonitor configuration data is used to modify the mode lists returned by the 248706f2543Smrgoutputs. 'maxX' and 'maxY' limit the maximum size modes that will be 249706f2543Smrgreturned. 250706f2543Smrg 251706f2543Smrg void 252706f2543Smrg xf86SetScrnInfoModes (ScrnInfoPtr pScrn) 253706f2543Smrg 254706f2543SmrgThis copies the 'compat' output mode list into the pScrn modes list which is 255706f2543Smrgused by the XFree86-VidModeExtension and the keypad mode switching 256706f2543Smrgoperations. The current 'desired' mode for the CRTC associated with the 257706f2543Smrg'compat' output is placed first in this list to indicate the current mode. 258706f2543SmrgUsually, the driver won't need to call this function as 259706f2543Smrgxf86InitialConfiguration will do so automatically, as well as any RandR 260706f2543Smrgfunctions which reprobe for modes. However, if the driver reprobes for modes 261706f2543Smrgat other times using xf86ProbeOutputModes, this function needs to be called. 262706f2543Smrg 263706f2543Smrg Bool 264706f2543Smrg xf86DiDGAReInit (ScreenPtr pScreen) 265706f2543Smrg 266706f2543SmrgThis is similar to xf86SetScrnInfoModes, but it applies the 'compat' output 267706f2543Smrgmode list to the set of modes advertised by the DGA extension; it needs to 268706f2543Smrgbe called whenever xf86ProbeOutputModes is invoked. 269706f2543Smrg 270706f2543Smrg void 271706f2543Smrg xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) 272706f2543Smrg 273706f2543SmrgAfter any sequence of calls using xf86CrtcSetMode, this function cleans up 274706f2543Smrgany leftover Output and CRTC objects by disabling them, saving power. It is 275706f2543Smrgsafe to call this whenever the server is running as it only disables objects 276706f2543Smrgwhich are not currently in use. 277706f2543Smrg 278706f2543Smrg4. CRTC operations 279706f2543Smrg 280706f2543Smrg4.1 CRTC functions 281706f2543Smrg 282706f2543SmrgThese functions provide an abstract interface for the CRTC object; most 283706f2543Smrgmanipulation of the CRTC object is done through these functions. 284706f2543Smrg 285706f2543Smrg void 286706f2543Smrg crtc->funcs->dpms (xf86CrtcPtr crtc, int mode) 287706f2543Smrg 288706f2543SmrgWhere 'mode' is one of DPMSModeOff, DPMSModeSuspend, DPMSModeStandby or 289706f2543SmrgDPMSModeOn. This requests that the crtc go to the specified power state. 290706f2543SmrgWhen changing power states, the output dpms functions are invoked before the 291706f2543Smrgcrtc dpms functions. 292706f2543Smrg 293706f2543Smrg void 294706f2543Smrg crtc->funcs->save (xf86CrtcPtr crtc) 295706f2543Smrg 296706f2543Smrg void 297706f2543Smrg crtc->funcs->restore (xf86CrtcPtr crtc) 298706f2543Smrg 299706f2543SmrgPreserve/restore any register contents related to the CRTC. These are 300706f2543Smrgstrictly a convenience for the driver writer; if the existing driver has 301706f2543Smrgfully operation save/restore functions, you need not place any additional 302706f2543Smrgcode here. In particular, the server itself never uses this function. 303706f2543Smrg 304706f2543Smrg Bool 305706f2543Smrg crtc->funcs->lock (xf86CrtcPtr crtc) 306706f2543Smrg 307706f2543Smrg void 308706f2543Smrg crtc->funcs->unlock (xf86CrtcPtr crtc) 309706f2543Smrg 310706f2543SmrgThese functions are invoked around mode setting operations; the intent is 311706f2543Smrgthat DRI locking be done here to prevent DRI applications from manipulating 312706f2543Smrgthe hardware while the server is busy changing the output configuration. If 313706f2543Smrgthe lock function returns FALSE, the unlock function will not be invoked. 314706f2543Smrg 315706f2543Smrg Bool 316706f2543Smrg crtc->funcs->mode_fixup (xf86CrtcPtr crtc, 317706f2543Smrg DisplayModePtr mode, 318706f2543Smrg DisplayModePtr adjusted_mode) 319706f2543Smrg 320706f2543SmrgThis call gives the CRTC a chance to see what mode will be set and to 321706f2543Smrgcomment on the mode by changing 'adjusted_mode' as needed. This function 322706f2543Smrgshall not modify the state of the crtc hardware at all. If the CRTC cannot 323706f2543Smrgaccept this mode, this function may return FALSE. 324706f2543Smrg 325706f2543Smrg void 326706f2543Smrg crtc->funcs->prepare (xf86CrtcPtr crtc) 327706f2543Smrg 328706f2543SmrgThis call is made just before the mode is set to make the hardware ready for 329706f2543Smrgthe operation. A usual function to perform here is to disable the crtc so 330706f2543Smrgthat mode setting can occur with clocks turned off and outputs deactivated. 331706f2543Smrg 332706f2543Smrg void 333706f2543Smrg crtc->funcs->mode_set (xf86CrtcPtr crtc, 334706f2543Smrg DisplayModePtr mode, 335706f2543Smrg DisplayModePtr adjusted_mode) 336706f2543Smrg 337706f2543SmrgThis function applies the specified mode (possibly adjusted by the CRTC 338706f2543Smrgand/or Outputs). 339706f2543Smrg 340706f2543Smrg void 341706f2543Smrg crtc->funcs->commit (xf86CrtcPtr crtc) 342706f2543Smrg 343706f2543SmrgOnce the mode has been applied to the CRTC and Outputs, this function is 344706f2543Smrginvoked to let the hardware turn things back on. 345706f2543Smrg 346706f2543Smrg void 347706f2543Smrg crtc->funcs->gamma_set (xf86CrtcPtr crtc, CARD16 *red, 348706f2543Smrg CARD16 *green, CARD16 *blue, int size) 349706f2543Smrg 350706f2543SmrgThis function adjusts the gamma ramps for the specified crtc. 351706f2543Smrg 352706f2543Smrg void * 353706f2543Smrg crtc->funcs->shadow_allocate (xf86CrtcPtr crtc, int width, int height) 354706f2543Smrg 355706f2543SmrgThis function allocates frame buffer space for a shadow frame buffer. When 356706f2543Smrgallocated, the crtc must scan from the shadow instead of the main frame 357706f2543Smrgbuffer. This is used for rotation. The address returned is passed to the 358706f2543Smrgshadow_create function. This function should return NULL on failure. 359706f2543Smrg 360706f2543Smrg PixmapPtr 361706f2543Smrg crtc->funcs->shadow_create (xf86CrtcPtr crtc, void *data, 362706f2543Smrg int width, int height) 363706f2543Smrg 364706f2543SmrgThis function creates a pixmap object that will be used as a shadow of the 365706f2543Smrgmain frame buffer for CRTCs which are rotated or reflected. 'data' is the 366706f2543Smrgvalue returned by shadow_allocate. 367706f2543Smrg 368706f2543Smrg void 369706f2543Smrg crtc->funcs->shadow_destroy (xf86CrtcPtr crtc, PixmapPtr pPixmap, 370706f2543Smrg void *data) 371706f2543Smrg 372706f2543SmrgDestroys any associated shadow objects. If pPixmap is NULL, then a pixmap 373706f2543Smrgwas not created, but 'data' may still be non-NULL indicating that the shadow 374706f2543Smrghad been allocated. 375706f2543Smrg 376706f2543Smrg void 377706f2543Smrg crtc->funcs->destroy (xf86CrtcPtr crtc) 378706f2543Smrg 379706f2543SmrgWhen a CRTC is destroyed (which only happens in error cases), this function 380706f2543Smrgcan clean up any driver-specific data. 381706f2543Smrg 382706f2543Smrg4.2 CRTC fields 383706f2543Smrg 384706f2543SmrgThe CRTC object is not opaque; there are several fields of interest to the 385706f2543Smrgdriver writer. 386706f2543Smrg 387706f2543Smrg struct _xf86Crtc { 388706f2543Smrg /** 389706f2543Smrg * Associated ScrnInfo 390706f2543Smrg */ 391706f2543Smrg ScrnInfoPtr scrn; 392706f2543Smrg 393706f2543Smrg /** 394706f2543Smrg * Active state of this CRTC 395706f2543Smrg * 396706f2543Smrg * Set when this CRTC is driving one or more outputs 397706f2543Smrg */ 398706f2543Smrg Bool enabled; 399706f2543Smrg 400706f2543Smrg /** Track whether cursor is within CRTC range */ 401706f2543Smrg Bool cursorInRange; 402706f2543Smrg 403706f2543Smrg /** Track state of cursor associated with this CRTC */ 404706f2543Smrg Bool cursorShown; 405706f2543Smrg 406706f2543Smrg /** 407706f2543Smrg * Active mode 408706f2543Smrg * 409706f2543Smrg * This reflects the mode as set in the CRTC currently 410706f2543Smrg * It will be cleared when the VT is not active or 411706f2543Smrg * during server startup 412706f2543Smrg */ 413706f2543Smrg DisplayModeRec mode; 414706f2543Smrg Rotation rotation; 415706f2543Smrg PixmapPtr rotatedPixmap; 416706f2543Smrg void *rotatedData; 417706f2543Smrg 418706f2543Smrg /** 419706f2543Smrg * Position on screen 420706f2543Smrg * 421706f2543Smrg * Locates this CRTC within the frame buffer 422706f2543Smrg */ 423706f2543Smrg int x, y; 424706f2543Smrg 425706f2543Smrg /** 426706f2543Smrg * Desired mode 427706f2543Smrg * 428706f2543Smrg * This is set to the requested mode, independent of 429706f2543Smrg * whether the VT is active. In particular, it receives 430706f2543Smrg * the startup configured mode and saves the active mode 431706f2543Smrg * on VT switch. 432706f2543Smrg */ 433706f2543Smrg DisplayModeRec desiredMode; 434706f2543Smrg Rotation desiredRotation; 435706f2543Smrg int desiredX, desiredY; 436706f2543Smrg 437706f2543Smrg /** crtc-specific functions */ 438706f2543Smrg const xf86CrtcFuncsRec *funcs; 439706f2543Smrg 440706f2543Smrg /** 441706f2543Smrg * Driver private 442706f2543Smrg * 443706f2543Smrg * Holds driver-private information 444706f2543Smrg */ 445706f2543Smrg void *driver_private; 446706f2543Smrg #ifdef RANDR_12_INTERFACE 447706f2543Smrg /** 448706f2543Smrg * RandR crtc 449706f2543Smrg * 450706f2543Smrg * When RandR 1.2 is available, this 451706f2543Smrg * points at the associated crtc object 452706f2543Smrg */ 453706f2543Smrg RRCrtcPtr randr_crtc; 454706f2543Smrg #else 455706f2543Smrg void *randr_crtc; 456706f2543Smrg #endif 457706f2543Smrg }; 458706f2543Smrg 459706f2543Smrg 460706f2543Smrg5. Output functions. 461706f2543Smrg 462706f2543Smrg6. Configuration 463706f2543Smrg 464706f2543SmrgBecause the configuration file syntax is fixed, 465706f2543Smrgthis was done by creating new "Driver" section options that hook specific 466706f2543Smrgoutputs to specific "Monitor" sections in the file. The option: 467706f2543Smrgsection of the form: 468706f2543Smrg 469706f2543Smrg Option "monitor-VGA" "My VGA Monitor" 470706f2543Smrg 471706f2543Smrgconnects the VGA output of this driver to the "Monitor" section with 472706f2543SmrgIdentifier "My VGA Monitor". All of the usual monitor options can now be 473706f2543Smrgplaced in that "Monitor" section and will be applied to the VGA output 474706f2543Smrgconfiguration. 475