aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/modes
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/modes')
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.c158
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.h2
-rw-r--r--xorg-server/hw/xfree86/modes/xf86DiDGA.c2
-rw-r--r--xorg-server/hw/xfree86/modes/xf86RandR12.c86
4 files changed, 218 insertions, 30 deletions
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c
index a1947241b..38bc58cbc 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.c
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c
@@ -118,7 +118,7 @@ xf86CrtcCreate(ScrnInfoPtr scrn, const xf86CrtcFuncsRec * funcs)
/* Preallocate gamma at a sensible size. */
crtc->gamma_size = 256;
- crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof(CARD16));
+ crtc->gamma_red = xallocarray(crtc->gamma_size, 3 * sizeof(CARD16));
if (!crtc->gamma_red) {
free(crtc);
return NULL;
@@ -127,10 +127,10 @@ xf86CrtcCreate(ScrnInfoPtr scrn, const xf86CrtcFuncsRec * funcs)
crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
if (xf86_config->crtc)
- crtcs = realloc(xf86_config->crtc,
- (xf86_config->num_crtc + 1) * sizeof(xf86CrtcPtr));
+ crtcs = reallocarray(xf86_config->crtc,
+ xf86_config->num_crtc + 1, sizeof(xf86CrtcPtr));
else
- crtcs = malloc((xf86_config->num_crtc + 1) * sizeof(xf86CrtcPtr));
+ crtcs = xallocarray(xf86_config->num_crtc + 1, sizeof(xf86CrtcPtr));
if (!crtcs) {
free(crtc->gamma_red);
free(crtc);
@@ -620,11 +620,12 @@ xf86OutputCreate(ScrnInfoPtr scrn,
}
if (xf86_config->output)
- outputs = realloc(xf86_config->output,
- (xf86_config->num_output +
- 1) * sizeof(xf86OutputPtr));
+ outputs = reallocarray(xf86_config->output,
+ xf86_config->num_output + 1,
+ sizeof(xf86OutputPtr));
else
- outputs = malloc((xf86_config->num_output + 1) * sizeof(xf86OutputPtr));
+ outputs = xallocarray(xf86_config->num_output + 1,
+ sizeof(xf86OutputPtr));
if (!outputs) {
free(output);
return NULL;
@@ -942,7 +943,7 @@ xf86PickCrtcs(ScrnInfoPtr scrn,
if (modes[n] == NULL)
return best_score;
- crtcs = malloc(config->num_output * sizeof(xf86CrtcPtr));
+ crtcs = xallocarray(config->num_output, sizeof(xf86CrtcPtr));
if (!crtcs)
return best_score;
@@ -1123,6 +1124,15 @@ xf86InitialOutputPositions(ScrnInfoPtr scrn, DisplayModePtr * modes)
int o;
int min_x, min_y;
+ /* check for initial right-of heuristic */
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ if (output->initial_x || output->initial_y)
+ return TRUE;
+ }
+
for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o];
@@ -2102,6 +2112,118 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
return match;
}
+static int
+numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled)
+{
+ int i = 0, p;
+
+ for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
+
+ return i;
+}
+
+static Bool
+xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+ DisplayModePtr *modes, Bool *enabled,
+ int width, int height)
+{
+ int o;
+ int w = 0;
+ Bool has_tile = FALSE;
+ uint32_t configured_outputs;
+
+ if (scrn->preferClone)
+ return FALSE;
+
+ if (numEnabledOutputs(config, enabled) < 2)
+ return FALSE;
+
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ DisplayModePtr mode =
+ xf86OutputHasPreferredMode(config->output[o], width, height);
+
+ if (!mode)
+ return FALSE;
+
+ w += mode->HDisplay;
+ }
+
+ if (w > width)
+ return FALSE;
+
+ w = 0;
+ configured_outputs = 0;
+
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ DisplayModePtr mode =
+ xf86OutputHasPreferredMode(config->output[o], width, height);
+
+ if (configured_outputs & (1 << o))
+ continue;
+
+ if (config->output[o]->tile_info.group_id) {
+ has_tile = TRUE;
+ continue;
+ }
+
+ config->output[o]->initial_x = w;
+ w += mode->HDisplay;
+
+ configured_outputs |= (1 << o);
+ modes[o] = mode;
+ }
+
+ if (has_tile) {
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ int ht, vt, ot;
+ int add_x, cur_x = w;
+ struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile;
+ if (configured_outputs & (1 << o))
+ continue;
+ if (!tile_info->group_id)
+ continue;
+
+ if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0)
+ continue;
+
+ for (ht = 0; ht < tile_info->num_h_tile; ht++) {
+ int cur_y = 0;
+ add_x = 0;
+ for (vt = 0; vt < tile_info->num_v_tile; vt++) {
+
+ for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) {
+
+ DisplayModePtr mode =
+ xf86OutputHasPreferredMode(config->output[ot], width, height);
+ if (!config->output[ot]->tile_info.group_id)
+ continue;
+
+ this_tile = &config->output[ot]->tile_info;
+ if (this_tile->group_id != tile_info->group_id)
+ continue;
+
+ if (this_tile->tile_h_loc != ht ||
+ this_tile->tile_v_loc != vt)
+ continue;
+
+ config->output[ot]->initial_x = cur_x;
+ config->output[ot]->initial_y = cur_y;
+
+ if (vt == 0)
+ add_x = this_tile->tile_h_size;
+ cur_y += this_tile->tile_v_size;
+ configured_outputs |= (1 << ot);
+ modes[ot] = mode;
+ }
+ }
+ cur_x += add_x;
+ }
+ w = cur_x;
+ }
+ }
+ return TRUE;
+}
+
static Bool
xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
DisplayModePtr * modes, Bool *enabled,
@@ -2178,14 +2300,10 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
*/
if (!ret)
do {
- int i = 0;
float aspect = 0.0;
DisplayModePtr a = NULL, b = NULL;
- /* count the number of enabled outputs */
- for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++);
-
- if (i != 1)
+ if (numEnabledOutputs(config, enabled) != 1)
break;
p = -1;
@@ -2334,7 +2452,7 @@ xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
int i, size = 256;
CARD16 *red, *green, *blue;
- red = malloc(3 * size * sizeof(CARD16));
+ red = xallocarray(size, 3 * sizeof(CARD16));
green = red + size;
blue = green + size;
@@ -2491,6 +2609,8 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
else {
if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
+ else if (xf86TargetRightOf(scrn, config, modes, enabled, width, height))
+ xf86DrvMsg(i, X_INFO, "Using spanning desktop for initial modes\n");
else if (xf86TargetPreferred
(scrn, config, modes, enabled, width, height))
xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
@@ -2510,9 +2630,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow)
"Output %s enabled but has no modes\n",
config->output[o]->name);
else
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "Output %s using initial mode %s\n",
- config->output[o]->name, modes[o]->name);
+ xf86DrvMsg (scrn->scrnIndex, X_INFO,
+ "Output %s using initial mode %s +%d+%d\n",
+ config->output[o]->name, modes[o]->name,
+ config->output[o]->initial_x,
+ config->output[o]->initial_y);
}
/*
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h
index 3c5bbcfd5..8b0160845 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.h
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h
@@ -745,6 +745,8 @@ xf86CompatOutput(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ if (config->compat_output < 0)
+ return NULL;
return config->output[config->compat_output];
}
diff --git a/xorg-server/hw/xfree86/modes/xf86DiDGA.c b/xorg-server/hw/xfree86/modes/xf86DiDGA.c
index 3f1a3309f..645727441 100644
--- a/xorg-server/hw/xfree86/modes/xf86DiDGA.c
+++ b/xorg-server/hw/xfree86/modes/xf86DiDGA.c
@@ -60,7 +60,7 @@ xf86_dga_get_modes(ScreenPtr pScreen)
if (!num)
return FALSE;
- modes = malloc(num * sizeof(DGAModeRec));
+ modes = xallocarray(num, sizeof(DGAModeRec));
if (!modes)
return FALSE;
diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c
index b1c306a88..0d446da64 100644
--- a/xorg-server/hw/xfree86/modes/xf86RandR12.c
+++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c
@@ -1058,7 +1058,7 @@ xf86RandR12CrtcNotify(RRCrtcPtr randr_crtc)
DisplayModePtr mode = &crtc->mode;
Bool ret;
- randr_outputs = malloc(config->num_output * sizeof(RROutputPtr));
+ randr_outputs = xallocarray(config->num_output, sizeof(RROutputPtr));
if (!randr_outputs)
return FALSE;
x = crtc->x;
@@ -1150,7 +1150,7 @@ xf86RandR12CrtcSet(ScreenPtr pScreen,
if (!crtc->scrn->vtSema)
return FALSE;
- save_crtcs = malloc(config->num_output * sizeof(xf86CrtcPtr));
+ save_crtcs = xallocarray(config->num_output, sizeof(xf86CrtcPtr));
if ((randr_mode != NULL) != crtc->enabled)
changed = TRUE;
else if (randr_mode && !xf86RandRModeMatches(randr_mode, &crtc->mode))
@@ -1255,9 +1255,8 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
if (randr_crtc->gammaSize != crtc->gamma_size) {
CARD16 *tmp_ptr;
- tmp_ptr =
- realloc(crtc->gamma_red,
- 3 * randr_crtc->gammaSize * sizeof(CARD16));
+ tmp_ptr = reallocarray(crtc->gamma_red,
+ randr_crtc->gammaSize, 3 * sizeof(CARD16));
if (!tmp_ptr)
return FALSE;
crtc->gamma_red = tmp_ptr;
@@ -1298,9 +1297,8 @@ xf86RandR12CrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc)
if (randr_crtc->gammaSize != crtc->gamma_size) {
CARD16 *tmp_ptr;
- tmp_ptr =
- realloc(randr_crtc->gammaRed,
- 3 * crtc->gamma_size * sizeof(CARD16));
+ tmp_ptr = reallocarray(randr_crtc->gammaRed,
+ crtc->gamma_size, 3 * sizeof(CARD16));
if (!tmp_ptr)
return FALSE;
randr_crtc->gammaRed = tmp_ptr;
@@ -1394,7 +1392,7 @@ xf86RROutputSetModes(RROutputPtr randr_output, DisplayModePtr modes)
nmode++;
if (nmode) {
- rrmodes = malloc(nmode * sizeof(RRModePtr));
+ rrmodes = xallocarray(nmode, sizeof(RRModePtr));
if (!rrmodes)
return FALSE;
@@ -1449,8 +1447,8 @@ xf86RandR12SetInfo12(ScreenPtr pScreen)
int o, c, l;
int nclone;
- clones = malloc(config->num_output * sizeof(RROutputPtr));
- crtcs = malloc(config->num_crtc * sizeof(RRCrtcPtr));
+ clones = xallocarray(config->num_output, sizeof(RROutputPtr));
+ crtcs = xallocarray(config->num_crtc, sizeof(RRCrtcPtr));
for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o];
@@ -1564,6 +1562,70 @@ xf86RandR12CreateObjects12(ScreenPtr pScreen)
return TRUE;
}
+static void
+xf86RandR12CreateMonitors(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int o, ot;
+ int ht, vt;
+ int ret;
+ char buf[25];
+
+ for (o = 0; o < config->num_output; o++) {
+ xf86OutputPtr output = config->output[o];
+ struct xf86CrtcTileInfo *tile_info = &output->tile_info, *this_tile;
+ RRMonitorPtr monitor;
+ int output_num, num_outputs;
+ if (!tile_info->group_id)
+ continue;
+
+ if (tile_info->tile_h_loc ||
+ tile_info->tile_v_loc)
+ continue;
+
+ num_outputs = tile_info->num_h_tile * tile_info->num_v_tile;
+
+ monitor = RRMonitorAlloc(num_outputs);
+ if (!monitor)
+ return;
+ monitor->pScreen = pScreen;
+ snprintf(buf, 25, "Auto-Monitor-%d", tile_info->group_id);
+ monitor->name = MakeAtom(buf, strlen(buf), TRUE);
+ monitor->primary = 0;
+ monitor->automatic = TRUE;
+ memset(&monitor->geometry.box, 0, sizeof(monitor->geometry.box));
+
+ output_num = 0;
+ for (ht = 0; ht < tile_info->num_h_tile; ht++) {
+ for (vt = 0; vt < tile_info->num_v_tile; vt++) {
+
+ for (ot = 0; ot < config->num_output; ot++) {
+ this_tile = &config->output[ot]->tile_info;
+
+ if (this_tile->group_id != tile_info->group_id)
+ continue;
+
+ if (this_tile->tile_h_loc != ht ||
+ this_tile->tile_v_loc != vt)
+ continue;
+
+ monitor->outputs[output_num] = config->output[ot]->randr_output->id;
+ output_num++;
+
+ }
+
+ }
+ }
+
+ ret = RRMonitorAdd(serverClient, pScreen, monitor);
+ if (ret) {
+ RRMonitorFree(monitor);
+ return;
+ }
+ }
+}
+
static Bool
xf86RandR12CreateScreenResources12(ScreenPtr pScreen)
{
@@ -1579,6 +1641,8 @@ xf86RandR12CreateScreenResources12(ScreenPtr pScreen)
RRScreenSetSizeRange(pScreen, config->minWidth, config->minHeight,
config->maxWidth, config->maxHeight);
+
+ xf86RandR12CreateMonitors(pScreen);
return TRUE;
}