hw/xfree86/modes: Add optional driver API for RRSetCrtcConfigs

This provides a driver hook which can either completely replace, or
just validate the parameters for, the RRSetCrtcConfigs request.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
This commit is contained in:
Keith Packard 2010-12-04 20:12:26 -08:00
parent d94a035ea9
commit 86c489c319
2 changed files with 163 additions and 28 deletions

View File

@ -647,6 +647,29 @@ struct _xf86Output {
INT16 initialBorder[4];
};
typedef enum _xf86SetConfigResponse {
xf86SetConfigFailed, /* set_config failed */
xf86SetConfigChecked, /* set_config validated the configuration */
xf86SetConfigDone, /* set_config finished the work */
} xf86SetConfigResponse;
typedef struct _xf86CrtcSetConfig {
xf86CrtcPtr crtc;
int x, y;
DisplayModeRec mode;
Rotation rotation;
int numOutputs;
xf86OutputPtr *outputs;
struct pict_f_transform sprite_position_transform;
struct pict_f_transform sprite_image_transform;
/* Probably want some internal structure for the pixmap so that
* this can be set before the server is running
*/
PixmapPtr pixmap;
int pixmap_x, pixmap_y;
} xf86CrtcSetConfigRec, *xf86CrtcSetConfigPtr;
typedef struct _xf86CrtcConfigFuncs {
/**
* Requests that the driver resize the screen.
@ -664,6 +687,12 @@ typedef struct _xf86CrtcConfigFuncs {
(*resize)(ScrnInfoPtr scrn,
int width,
int height);
xf86SetConfigResponse
(*set_config) (ScrnInfoPtr scrn,
RRScreenConfigPtr screen_config,
xf86CrtcSetConfigPtr crtc_configs,
int num_configs);
} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);

View File

@ -1746,6 +1746,112 @@ xf86RandR14SetCrtcSpriteTransform(ScreenPtr pScreen,
xf86_reload_cursors(pScreen);
}
static Bool
xf86RRConvertCrtcConfig(xf86CrtcSetConfigPtr xf86_config,
RRCrtcConfigPtr rr_config)
{
RRCrtcPtr rr_crtc = rr_config->crtc;
xf86CrtcPtr crtc = rr_crtc->devPrivate;
ScrnInfoPtr scrn = xf86Screens[rr_crtc->pScreen->myNum];
int o;
xf86_config->crtc = crtc;
xf86_config->x = rr_config->x;
xf86_config->y = rr_config->y;
xf86RandRModeConvert(scrn, rr_config->mode, &xf86_config->mode);
xf86_config->rotation = rr_config->rotation;
xf86_config->numOutputs = rr_config->numOutputs;
xf86_config->outputs = calloc(rr_config->numOutputs, sizeof (xf86OutputPtr));
if (!xf86_config->outputs)
return FALSE;
for (o = 0; o < rr_config->numOutputs; o++)
xf86_config->outputs[o] = rr_config->outputs[o]->devPrivate;
xf86_config->sprite_position_transform = rr_config->sprite_position_transform;
xf86_config->sprite_image_transform = rr_config->sprite_image_transform;
xf86_config->pixmap = rr_config->pixmap;
xf86_config->pixmap_x = rr_config->pixmap_x;
xf86_config->pixmap_y = rr_config->pixmap_y;
return TRUE;
}
static void
xf86FreeCrtcSetConfigs(xf86CrtcSetConfigPtr xf86_crtc_configs, int num_configs)
{
int i;
for (i = 0; i < num_configs; i++)
free(xf86_crtc_configs[i].outputs);
free(xf86_crtc_configs);
}
static Bool
xf86RRSetCrtcConfigs(ScreenPtr screen,
RRScreenConfigPtr screen_config,
RRCrtcConfigPtr crtc_configs,
int num_configs)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
if (config->funcs->set_config) {
xf86CrtcSetConfigPtr xf86_crtc_configs;
int i;
xf86SetConfigResponse response;
/*
* Convert RRCrtcConfigRecs to xf86CrtcSetConfigs
*/
xf86_crtc_configs = calloc(num_configs, sizeof (xf86CrtcSetConfigRec));
if (!xf86_crtc_configs)
return FALSE;
for (i = 0; i < num_configs; i++)
if (!xf86RRConvertCrtcConfig(&xf86_crtc_configs[i], &crtc_configs[i])) {
xf86FreeCrtcSetConfigs(xf86_crtc_configs, num_configs);
return FALSE;
}
/*
* Ask the driver to set the configuration
*/
response = (*config->funcs->set_config)(scrn,
screen_config,
xf86_crtc_configs,
num_configs);
xf86FreeCrtcSetConfigs(xf86_crtc_configs, num_configs);
/*
* The driver is allowed to answer with one of three
* responses:
*/
switch (response) {
case xf86SetConfigFailed:
/* The configuration isn't usable, or some error
* occurred while setting it. Everything has been
* cleaned up and we're ready to return an error
* back to the client
*/
return FALSE;
case xf86SetConfigDone:
/* The configuration was acceptable, and the whole
* mode setting experience is over. Nothing more to do
* here.
*/
return TRUE;
case xf86SetConfigChecked:
/* The configuration was acceptable, but the driver
* didn't actually do anything. Go ask the DIX code
* to do the mode setting operation using the simpler
* interfaces
*/
break;
}
}
return miRRSetCrtcConfigs(screen, screen_config, crtc_configs, num_configs);
}
static Bool
xf86RandR12EnterVT (int screen_index, int flags)
{
@ -1797,7 +1903,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
pScrn->PointerMoved = xf86RandR12PointerMoved;
pScrn->ChangeGamma = xf86RandR12ChangeGamma;
rp->rrSetCrtcSpriteTransform = xf86RandR14SetCrtcSpriteTransform;
rp->rrSetCrtcConfigs = miRRSetCrtcConfigs;
rp->rrSetCrtcConfigs = xf86RRSetCrtcConfigs;
randrp->orig_EnterVT = pScrn->EnterVT;
pScrn->EnterVT = xf86RandR12EnterVT;