2007-02-16 05:36:20 +01:00
|
|
|
/*
|
2009-09-19 06:12:17 +02:00
|
|
|
* Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
|
2007-02-16 05:36:20 +01:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
* the above copyright notice appear in all copies and that both that copyright
|
|
|
|
* notice and this permission notice appear in supporting documentation, and
|
|
|
|
* that the name of the copyright holders not be used in advertising or
|
|
|
|
* publicity pertaining to distribution of the software without specific,
|
|
|
|
* written prior permission. The copyright holders make no representations
|
|
|
|
* about the suitability of this software for any purpose. It is provided "as
|
|
|
|
* is" without express or implied warranty.
|
|
|
|
*
|
|
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
|
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
|
|
* OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_XORG_CONFIG_H
|
|
|
|
#include <xorg-config.h>
|
2007-02-15 20:27:35 +01:00
|
|
|
#else
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
2007-02-16 05:36:20 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "xf86.h"
|
|
|
|
#include "os.h"
|
|
|
|
#include "mibank.h"
|
|
|
|
#include "globals.h"
|
|
|
|
#include "xf86.h"
|
|
|
|
#include "xf86Priv.h"
|
|
|
|
#include "xf86DDC.h"
|
|
|
|
#include "mipointer.h"
|
|
|
|
#include "windowstr.h"
|
2007-03-05 03:07:17 +01:00
|
|
|
#include "inputstr.h"
|
2007-02-16 05:36:20 +01:00
|
|
|
#include <randrstr.h>
|
|
|
|
#include <X11/extensions/render.h>
|
|
|
|
|
|
|
|
#include "xf86Crtc.h"
|
|
|
|
#include "xf86RandR12.h"
|
|
|
|
|
|
|
|
typedef struct _xf86RandR12Info {
|
|
|
|
int virtualX;
|
|
|
|
int virtualY;
|
|
|
|
int mmWidth;
|
|
|
|
int mmHeight;
|
|
|
|
int maxX;
|
|
|
|
int maxY;
|
2008-11-28 17:49:31 +01:00
|
|
|
int pointerX;
|
|
|
|
int pointerY;
|
2007-02-16 05:36:20 +01:00
|
|
|
Rotation rotation; /* current mode */
|
|
|
|
Rotation supported_rotations; /* driver supported */
|
2009-05-05 02:24:47 +02:00
|
|
|
|
|
|
|
/* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends
|
|
|
|
* (actually, any time that we switch back into our VT).
|
|
|
|
*
|
|
|
|
* See https://bugs.freedesktop.org/show_bug.cgi?id=21554
|
|
|
|
*/
|
|
|
|
xf86EnterVTProc *orig_EnterVT;
|
2007-02-16 05:36:20 +01:00
|
|
|
} XF86RandRInfoRec, *XF86RandRInfoPtr;
|
|
|
|
|
|
|
|
#ifdef RANDR_12_INTERFACE
|
|
|
|
static Bool xf86RandR12Init12 (ScreenPtr pScreen);
|
|
|
|
static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
|
|
|
|
#endif
|
|
|
|
|
2007-08-28 15:28:25 +02:00
|
|
|
static int xf86RandR12Generation;
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-02-16 05:36:20 +01:00
|
|
|
|
2008-08-29 00:05:40 +02:00
|
|
|
static int xf86RandR12KeyIndex;
|
2008-03-03 05:13:11 +01:00
|
|
|
static DevPrivateKey xf86RandR12Key;
|
2007-08-28 15:28:25 +02:00
|
|
|
#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
|
|
|
|
dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
|
2007-02-16 05:36:20 +01:00
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#else /* XORG_VERSION_CURRENT < 7.0 */
|
|
|
|
|
|
|
|
static int xf86RandR12Index;
|
|
|
|
#define XF86RANDRINFO(p) \
|
|
|
|
((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
|
|
|
|
|
|
|
|
#endif /* XORG_VERSION_CURRENT < 7.0 */
|
|
|
|
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
static int
|
|
|
|
xf86RandR12ModeRefresh (DisplayModePtr mode)
|
|
|
|
{
|
|
|
|
if (mode->VRefresh)
|
|
|
|
return (int) (mode->VRefresh + 0.5);
|
|
|
|
else
|
|
|
|
return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
|
|
|
|
}
|
|
|
|
|
2008-12-04 16:55:14 +01:00
|
|
|
/* Adapt panning area; return TRUE if panning area was valid without adaption */
|
2008-11-28 17:49:31 +01:00
|
|
|
static int
|
|
|
|
xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
|
|
|
|
{
|
2008-12-04 16:55:14 +01:00
|
|
|
int ret = TRUE;
|
|
|
|
|
2008-11-28 17:49:31 +01:00
|
|
|
if (crtc->version < 2)
|
|
|
|
return FALSE;
|
|
|
|
|
2008-12-04 16:55:14 +01:00
|
|
|
if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
|
|
|
|
/* Panning in X is disabled */
|
|
|
|
if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
|
|
|
|
/* Illegal configuration -> fail/disable */
|
|
|
|
ret = FALSE;
|
|
|
|
crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
|
|
|
|
crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
|
|
|
|
crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
|
|
|
|
} else {
|
|
|
|
/* Panning in X is enabled */
|
|
|
|
if (crtc->panningTotalArea.x1 < 0) {
|
|
|
|
/* Panning region outside screen -> move inside */
|
|
|
|
crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
|
|
|
|
crtc->panningTotalArea.x1 = 0;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
|
|
|
|
/* Panning region smaller than displayed area -> crop to displayed area */
|
|
|
|
crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
if (crtc->panningTotalArea.x2 > screenWidth) {
|
|
|
|
/* Panning region larger than screen -> move inside, then crop to screen */
|
|
|
|
crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
|
|
|
|
crtc->panningTotalArea.x2 = screenWidth;
|
|
|
|
ret = FALSE;
|
|
|
|
if (crtc->panningTotalArea.x1 < 0)
|
|
|
|
crtc->panningTotalArea.x1 = 0;
|
|
|
|
}
|
|
|
|
if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
|
|
|
|
/* Borders too large -> set to 0 */
|
|
|
|
crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
2008-11-28 17:49:31 +01:00
|
|
|
}
|
|
|
|
|
2008-12-04 16:55:14 +01:00
|
|
|
if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
|
|
|
|
/* Panning in Y is disabled */
|
|
|
|
if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
|
|
|
|
/* Illegal configuration -> fail/disable */
|
|
|
|
ret = FALSE;
|
|
|
|
crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
|
|
|
|
crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
|
|
|
|
crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
|
|
|
|
} else {
|
|
|
|
/* Panning in Y is enabled */
|
|
|
|
if (crtc->panningTotalArea.y1 < 0) {
|
|
|
|
/* Panning region outside screen -> move inside */
|
|
|
|
crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
|
|
|
|
crtc->panningTotalArea.y1 = 0;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
|
|
|
|
/* Panning region smaller than displayed area -> crop to displayed area */
|
|
|
|
crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
if (crtc->panningTotalArea.y2 > screenHeight) {
|
|
|
|
/* Panning region larger than screen -> move inside, then crop to screen */
|
|
|
|
crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
|
|
|
|
crtc->panningTotalArea.y2 = screenHeight;
|
|
|
|
ret = FALSE;
|
|
|
|
if (crtc->panningTotalArea.y1 < 0)
|
|
|
|
crtc->panningTotalArea.y1 = 0;
|
|
|
|
}
|
|
|
|
if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
|
|
|
|
/* Borders too large -> set to 0 */
|
|
|
|
crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
2008-11-28 17:49:31 +01:00
|
|
|
}
|
2008-12-04 16:55:14 +01:00
|
|
|
|
|
|
|
return ret;
|
2008-11-28 17:49:31 +01:00
|
|
|
}
|
|
|
|
|
2009-02-25 19:14:36 +01:00
|
|
|
/*
|
|
|
|
* The heart of the panning operation:
|
|
|
|
*
|
|
|
|
* Given a frame buffer position (fb_x, fb_y),
|
|
|
|
* and a crtc position (crtc_x, crtc_y),
|
|
|
|
* and a transform matrix which maps frame buffer to crtc,
|
|
|
|
* compute a panning position (pan_x, pan_y) that
|
|
|
|
* makes the resulting transform line those two up
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
xf86ComputeCrtcPan (Bool transform_in_use,
|
|
|
|
struct pixman_f_transform *m,
|
|
|
|
double screen_x, double screen_y,
|
|
|
|
double crtc_x, double crtc_y,
|
|
|
|
int old_pan_x, int old_pan_y,
|
|
|
|
int *new_pan_x, int *new_pan_y)
|
|
|
|
{
|
|
|
|
if (transform_in_use) {
|
|
|
|
/*
|
|
|
|
* Given the current transform, M, the current position
|
|
|
|
* on the Screen, S, and the desired position on the CRTC,
|
|
|
|
* C, compute a translation, T, such that:
|
|
|
|
*
|
|
|
|
* M T S = C
|
|
|
|
*
|
|
|
|
* where T is of the form
|
|
|
|
*
|
|
|
|
* | 1 0 dx |
|
|
|
|
* | 0 1 dy |
|
|
|
|
* | 0 0 1 |
|
|
|
|
*
|
|
|
|
* M T S =
|
|
|
|
* | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F |
|
|
|
|
* | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
|
|
|
|
* | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F |
|
|
|
|
*
|
|
|
|
* R = M S
|
|
|
|
*
|
|
|
|
* Cx F = M00 dx + M01 dy + R0
|
|
|
|
* Cy F = M10 dx + M11 dy + R1
|
|
|
|
* F = M20 dx + M21 dy + R2
|
|
|
|
*
|
|
|
|
* Zero out dx, then dy
|
|
|
|
*
|
|
|
|
* F (Cx M10 - Cy M00) =
|
|
|
|
* (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
|
|
|
|
* F (M10 - Cy M20) =
|
|
|
|
* (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
|
|
|
|
*
|
|
|
|
* F (Cx M11 - Cy M01) =
|
|
|
|
* (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
|
|
|
|
* F (M11 - Cy M21) =
|
|
|
|
* (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
|
|
|
|
*
|
|
|
|
* Make some temporaries
|
|
|
|
*
|
|
|
|
* T = | Cx M10 - Cy M00 |
|
|
|
|
* | Cx M11 - Cy M01 |
|
|
|
|
*
|
|
|
|
* U = | M10 M01 - M00 M11 |
|
|
|
|
* | M11 M00 - M01 M10 |
|
|
|
|
*
|
|
|
|
* Q = | M10 R0 - M00 R1 |
|
|
|
|
* | M11 R0 - M01 R1 |
|
|
|
|
*
|
|
|
|
* P = | M10 - Cy M20 |
|
|
|
|
* | M11 - Cy M21 |
|
|
|
|
*
|
|
|
|
* W = | M10 M21 - M20 M11 |
|
|
|
|
* | M11 M20 - M21 M10 |
|
|
|
|
*
|
|
|
|
* V = | M10 R2 - M20 R1 |
|
|
|
|
* | M11 R2 - M21 R1 |
|
|
|
|
*
|
|
|
|
* Rewrite:
|
|
|
|
*
|
|
|
|
* F T0 = U0 dy + Q0
|
|
|
|
* F P0 = W0 dy + V0
|
|
|
|
* F T1 = U1 dx + Q1
|
|
|
|
* F P1 = W1 dx + V1
|
|
|
|
*
|
|
|
|
* Solve for F (two ways)
|
|
|
|
*
|
|
|
|
* F (W0 T0 - U0 P0) = W0 Q0 - U0 V0
|
|
|
|
*
|
|
|
|
* W0 Q0 - U0 V0
|
|
|
|
* F = -------------
|
|
|
|
* W0 T0 - U0 P0
|
|
|
|
*
|
|
|
|
* F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
|
|
|
|
*
|
|
|
|
* W1 Q1 - U1 V1
|
|
|
|
* F = -------------
|
|
|
|
* W1 T1 - U1 P1
|
|
|
|
*
|
|
|
|
* We'll use which ever solution works (denominator != 0)
|
|
|
|
*
|
|
|
|
* Finally, solve for dx and dy:
|
|
|
|
*
|
|
|
|
* dx = (F T1 - Q1) / U1
|
|
|
|
* dx = (F P1 - V1) / W1
|
|
|
|
*
|
|
|
|
* dy = (F T0 - Q0) / U0
|
|
|
|
* dy = (F P0 - V0) / W0
|
|
|
|
*/
|
|
|
|
double r[3];
|
|
|
|
double q[2], u[2], t[2], v[2], w[2], p[2];
|
|
|
|
double f;
|
|
|
|
struct pict_f_vector d;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Get the un-normalized crtc coordinates again */
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2];
|
|
|
|
|
|
|
|
/* Combine values into temporaries */
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
|
|
|
|
u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
|
|
|
|
t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y;
|
|
|
|
|
|
|
|
v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
|
|
|
|
w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
|
|
|
|
p[i] = m->m[1][i] - m->m[2][i] * crtc_y;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find a way to compute f */
|
|
|
|
f = 0;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
double a = w[i] * q[i] - u[i] * v[i];
|
|
|
|
double b = w[i] * t[i] - u[i] * p[i];
|
|
|
|
if (b != 0) {
|
|
|
|
f = a/b;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Solve for the resulting transform vector */
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (u[i])
|
|
|
|
d.v[1-i] = (t[i] * f - q[i]) / u[i];
|
|
|
|
else if (w[1])
|
|
|
|
d.v[1-i] = (p[i] * f - v[i]) / w[i];
|
|
|
|
else
|
|
|
|
d.v[1-i] = 0;
|
|
|
|
}
|
|
|
|
*new_pan_x = old_pan_x - floor (d.v[0] + 0.5);
|
|
|
|
*new_pan_y = old_pan_y - floor (d.v[1] + 0.5);
|
|
|
|
} else {
|
|
|
|
*new_pan_x = screen_x - crtc_x;
|
|
|
|
*new_pan_y = screen_y - crtc_y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-28 17:49:31 +01:00
|
|
|
static void
|
|
|
|
xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
|
|
|
|
{
|
|
|
|
int newX, newY;
|
|
|
|
int width, height;
|
2009-02-25 19:14:36 +01:00
|
|
|
Bool panned = FALSE;
|
2008-11-28 17:49:31 +01:00
|
|
|
|
|
|
|
if (crtc->version < 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (! crtc->enabled ||
|
2008-12-04 18:13:40 +01:00
|
|
|
(crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
|
|
|
|
crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
|
2008-11-28 17:49:31 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
newX = crtc->x;
|
|
|
|
newY = crtc->y;
|
|
|
|
width = crtc->mode.HDisplay;
|
|
|
|
height = crtc->mode.VDisplay;
|
|
|
|
|
2008-12-04 18:13:40 +01:00
|
|
|
if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
|
|
|
|
(x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
|
|
|
|
(crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
|
2009-02-25 19:14:36 +01:00
|
|
|
(y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2)))
|
|
|
|
{
|
|
|
|
struct pict_f_vector c;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pre-clip the mouse position to the panning area so that we don't
|
|
|
|
* push the crtc outside. This doesn't deal with changes to the
|
|
|
|
* panning values, only mouse position changes.
|
|
|
|
*/
|
|
|
|
if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1)
|
|
|
|
{
|
|
|
|
if (x < crtc->panningTotalArea.x1)
|
|
|
|
x = crtc->panningTotalArea.x1;
|
|
|
|
if (x >= crtc->panningTotalArea.x2)
|
|
|
|
x = crtc->panningTotalArea.x2 - 1;
|
|
|
|
}
|
|
|
|
if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1)
|
|
|
|
{
|
|
|
|
if (y < crtc->panningTotalArea.y1)
|
|
|
|
y = crtc->panningTotalArea.y1;
|
|
|
|
if (y >= crtc->panningTotalArea.y2)
|
|
|
|
y = crtc->panningTotalArea.y2 - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
c.v[0] = x;
|
|
|
|
c.v[1] = y;
|
|
|
|
c.v[2] = 1.0;
|
|
|
|
if (crtc->transform_in_use) {
|
|
|
|
pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
|
|
|
|
} else {
|
|
|
|
c.v[0] -= crtc->x;
|
|
|
|
c.v[1] -= crtc->y;
|
|
|
|
}
|
|
|
|
|
2008-12-04 18:13:40 +01:00
|
|
|
if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
|
2009-02-25 19:14:36 +01:00
|
|
|
if (c.v[0] < crtc->panningBorder[0]) {
|
|
|
|
c.v[0] = crtc->panningBorder[0];
|
|
|
|
panned = TRUE;
|
|
|
|
}
|
|
|
|
if (c.v[0] >= width - crtc->panningBorder[2]) {
|
|
|
|
c.v[0] = width - crtc->panningBorder[2] - 1;
|
|
|
|
panned = TRUE;
|
|
|
|
}
|
2008-12-04 18:13:40 +01:00
|
|
|
}
|
|
|
|
if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
|
2009-02-25 19:14:36 +01:00
|
|
|
if (c.v[1] < crtc->panningBorder[1]) {
|
|
|
|
c.v[1] = crtc->panningBorder[1];
|
|
|
|
panned = TRUE;
|
|
|
|
}
|
|
|
|
if (c.v[1] >= height - crtc->panningBorder[3]) {
|
|
|
|
c.v[1] = height - crtc->panningBorder[3] - 1;
|
|
|
|
panned = TRUE;
|
|
|
|
}
|
2008-12-04 18:13:40 +01:00
|
|
|
}
|
2009-02-25 19:14:36 +01:00
|
|
|
if (panned)
|
|
|
|
xf86ComputeCrtcPan (crtc->transform_in_use,
|
|
|
|
&crtc->f_framebuffer_to_crtc,
|
|
|
|
x, y, c.v[0], c.v[1],
|
|
|
|
newX, newY, &newX, &newY);
|
2008-11-28 17:49:31 +01:00
|
|
|
}
|
2009-02-25 19:14:36 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Ensure that the crtc is within the panning region.
|
|
|
|
*
|
|
|
|
* XXX This computation only works when we do not have a transform
|
|
|
|
* in use.
|
|
|
|
*/
|
|
|
|
if (!crtc->transform_in_use)
|
|
|
|
{
|
|
|
|
/* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
|
|
|
|
if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
|
|
|
|
if (newX > crtc->panningTotalArea.x2 - width)
|
|
|
|
newX = crtc->panningTotalArea.x2 - width;
|
|
|
|
if (newX < crtc->panningTotalArea.x1)
|
|
|
|
newX = crtc->panningTotalArea.x1;
|
|
|
|
}
|
|
|
|
if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
|
|
|
|
if (newY > crtc->panningTotalArea.y2 - height)
|
|
|
|
newY = crtc->panningTotalArea.y2 - height;
|
|
|
|
if (newY < crtc->panningTotalArea.y1)
|
|
|
|
newY = crtc->panningTotalArea.y1;
|
|
|
|
}
|
2008-12-04 18:13:40 +01:00
|
|
|
}
|
2008-11-28 17:49:31 +01:00
|
|
|
if (newX != crtc->x || newY != crtc->y)
|
2008-12-04 16:30:38 +01:00
|
|
|
xf86CrtcSetOrigin (crtc, newX, newY);
|
2008-11-28 17:49:31 +01:00
|
|
|
}
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
static Bool
|
|
|
|
xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
|
|
|
|
{
|
|
|
|
RRScreenSizePtr pSize;
|
|
|
|
ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
DisplayModePtr mode;
|
|
|
|
int refresh0 = 60;
|
|
|
|
int maxX = 0, maxY = 0;
|
|
|
|
|
|
|
|
*rotations = randrp->supported_rotations;
|
|
|
|
|
|
|
|
if (randrp->virtualX == -1 || randrp->virtualY == -1)
|
|
|
|
{
|
|
|
|
randrp->virtualX = scrp->virtualX;
|
|
|
|
randrp->virtualY = scrp->virtualY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Re-probe the outputs for new monitors or modes */
|
2007-06-22 03:08:21 +02:00
|
|
|
if (scrp->vtSema)
|
|
|
|
{
|
|
|
|
xf86ProbeOutputModes (scrp, 0, 0);
|
|
|
|
xf86SetScrnInfoModes (scrp);
|
|
|
|
}
|
2007-02-16 05:36:20 +01:00
|
|
|
|
|
|
|
for (mode = scrp->modes; ; mode = mode->next)
|
|
|
|
{
|
|
|
|
int refresh = xf86RandR12ModeRefresh (mode);
|
|
|
|
if (randrp->maxX == 0 || randrp->maxY == 0)
|
|
|
|
{
|
|
|
|
if (maxX < mode->HDisplay)
|
|
|
|
maxX = mode->HDisplay;
|
|
|
|
if (maxY < mode->VDisplay)
|
|
|
|
maxY = mode->VDisplay;
|
|
|
|
}
|
|
|
|
if (mode == scrp->modes)
|
|
|
|
refresh0 = refresh;
|
|
|
|
pSize = RRRegisterSize (pScreen,
|
|
|
|
mode->HDisplay, mode->VDisplay,
|
|
|
|
randrp->mmWidth, randrp->mmHeight);
|
|
|
|
if (!pSize)
|
|
|
|
return FALSE;
|
|
|
|
RRRegisterRate (pScreen, pSize, refresh);
|
|
|
|
|
2008-05-16 16:52:41 +02:00
|
|
|
if (xf86ModesEqual(mode, scrp->currentMode))
|
2007-02-16 05:36:20 +01:00
|
|
|
{
|
|
|
|
RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
|
|
|
|
}
|
|
|
|
if (mode->next == scrp->modes)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (randrp->maxX == 0 || randrp->maxY == 0)
|
|
|
|
{
|
|
|
|
randrp->maxX = maxX;
|
|
|
|
randrp->maxY = maxY;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR12SetMode (ScreenPtr pScreen,
|
|
|
|
DisplayModePtr mode,
|
|
|
|
Bool useVirtual,
|
|
|
|
int mmWidth,
|
|
|
|
int mmHeight)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
int oldWidth = pScreen->width;
|
|
|
|
int oldHeight = pScreen->height;
|
|
|
|
int oldmmWidth = pScreen->mmWidth;
|
|
|
|
int oldmmHeight = pScreen->mmHeight;
|
|
|
|
WindowPtr pRoot = WindowTable[pScreen->myNum];
|
|
|
|
DisplayModePtr currentMode = NULL;
|
|
|
|
Bool ret = TRUE;
|
|
|
|
PixmapPtr pspix = NULL;
|
|
|
|
|
|
|
|
if (pRoot)
|
|
|
|
(*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
|
|
|
|
if (useVirtual)
|
|
|
|
{
|
|
|
|
scrp->virtualX = randrp->virtualX;
|
|
|
|
scrp->virtualY = randrp->virtualY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scrp->virtualX = mode->HDisplay;
|
|
|
|
scrp->virtualY = mode->VDisplay;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
|
|
|
|
{
|
|
|
|
/* If the screen is rotated 90 or 270 degrees, swap the sizes. */
|
|
|
|
pScreen->width = scrp->virtualY;
|
|
|
|
pScreen->height = scrp->virtualX;
|
|
|
|
pScreen->mmWidth = mmHeight;
|
|
|
|
pScreen->mmHeight = mmWidth;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pScreen->width = scrp->virtualX;
|
|
|
|
pScreen->height = scrp->virtualY;
|
|
|
|
pScreen->mmWidth = mmWidth;
|
|
|
|
pScreen->mmHeight = mmHeight;
|
|
|
|
}
|
|
|
|
if (scrp->currentMode == mode) {
|
|
|
|
/* Save current mode */
|
|
|
|
currentMode = scrp->currentMode;
|
|
|
|
/* Reset, just so we ensure the drivers SwitchMode is called */
|
|
|
|
scrp->currentMode = NULL;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* We know that if the driver failed to SwitchMode to the rotated
|
|
|
|
* version, then it should revert back to it's prior mode.
|
|
|
|
*/
|
|
|
|
if (!xf86SwitchMode (pScreen, mode))
|
|
|
|
{
|
|
|
|
ret = FALSE;
|
|
|
|
scrp->virtualX = pScreen->width = oldWidth;
|
|
|
|
scrp->virtualY = pScreen->height = oldHeight;
|
|
|
|
pScreen->mmWidth = oldmmWidth;
|
|
|
|
pScreen->mmHeight = oldmmHeight;
|
|
|
|
scrp->currentMode = currentMode;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Get the new Screen pixmap ptr as SwitchMode might have called
|
|
|
|
* ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
|
|
|
|
* Unfortunately.
|
|
|
|
*/
|
|
|
|
pspix = (*pScreen->GetScreenPixmap) (pScreen);
|
|
|
|
if (pspix->devPrivate.ptr)
|
|
|
|
scrp->pixmapPrivate = pspix->devPrivate;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure the layout is correct
|
|
|
|
*/
|
|
|
|
xf86ReconfigureLayout();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure the whole screen is visible
|
|
|
|
*/
|
|
|
|
xf86SetViewport (pScreen, pScreen->width, pScreen->height);
|
|
|
|
xf86SetViewport (pScreen, 0, 0);
|
|
|
|
if (pRoot)
|
|
|
|
(*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
Bool
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12SetConfig (ScreenPtr pScreen,
|
|
|
|
Rotation rotation,
|
|
|
|
int rate,
|
|
|
|
RRScreenSizePtr pSize)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
DisplayModePtr mode;
|
|
|
|
int px, py;
|
|
|
|
Bool useVirtual = FALSE;
|
|
|
|
int maxX = 0, maxY = 0;
|
|
|
|
Rotation oldRotation = randrp->rotation;
|
|
|
|
|
|
|
|
randrp->rotation = rotation;
|
|
|
|
|
|
|
|
if (randrp->virtualX == -1 || randrp->virtualY == -1)
|
|
|
|
{
|
|
|
|
randrp->virtualX = scrp->virtualX;
|
|
|
|
randrp->virtualY = scrp->virtualY;
|
|
|
|
}
|
|
|
|
|
2007-03-05 03:07:17 +01:00
|
|
|
miPointerGetPosition (inputInfo.pointer, &px, &py);
|
2007-02-16 05:36:20 +01:00
|
|
|
for (mode = scrp->modes; ; mode = mode->next)
|
|
|
|
{
|
|
|
|
if (randrp->maxX == 0 || randrp->maxY == 0)
|
|
|
|
{
|
|
|
|
if (maxX < mode->HDisplay)
|
|
|
|
maxX = mode->HDisplay;
|
|
|
|
if (maxY < mode->VDisplay)
|
|
|
|
maxY = mode->VDisplay;
|
|
|
|
}
|
|
|
|
if (mode->HDisplay == pSize->width &&
|
|
|
|
mode->VDisplay == pSize->height &&
|
|
|
|
(rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
|
|
|
|
break;
|
|
|
|
if (mode->next == scrp->modes)
|
|
|
|
{
|
|
|
|
if (pSize->width == randrp->virtualX &&
|
|
|
|
pSize->height == randrp->virtualY)
|
|
|
|
{
|
|
|
|
mode = scrp->modes;
|
|
|
|
useVirtual = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (randrp->maxX == 0 || randrp->maxY == 0)
|
|
|
|
{
|
|
|
|
randrp->maxX = maxX;
|
|
|
|
randrp->maxY = maxY;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (randrp->maxX == 0 || randrp->maxY == 0)
|
|
|
|
{
|
|
|
|
randrp->maxX = maxX;
|
|
|
|
randrp->maxY = maxY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
|
|
|
|
pSize->mmHeight)) {
|
|
|
|
randrp->rotation = oldRotation;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Move the cursor back where it belongs; SwitchMode repositions it
|
|
|
|
*/
|
2007-03-05 03:07:17 +01:00
|
|
|
if (pScreen == miPointerGetScreen(inputInfo.pointer))
|
2007-02-16 05:36:20 +01:00
|
|
|
{
|
|
|
|
px = (px >= pScreen->width ? (pScreen->width - 1) : px);
|
|
|
|
py = (py >= pScreen->height ? (pScreen->height - 1) : py);
|
|
|
|
|
|
|
|
xf86SetViewport(pScreen, px, py);
|
|
|
|
|
2007-03-05 03:07:17 +01:00
|
|
|
(*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
|
2007-02-16 05:36:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR12ScreenSetSize (ScreenPtr pScreen,
|
|
|
|
CARD16 width,
|
|
|
|
CARD16 height,
|
|
|
|
CARD32 mmWidth,
|
|
|
|
CARD32 mmHeight)
|
|
|
|
{
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
|
2007-02-28 22:36:58 +01:00
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
2007-02-16 05:36:20 +01:00
|
|
|
WindowPtr pRoot = WindowTable[pScreen->myNum];
|
2007-04-23 03:04:27 +02:00
|
|
|
PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
|
2007-02-28 22:36:58 +01:00
|
|
|
Bool ret = FALSE;
|
2008-11-28 17:49:31 +01:00
|
|
|
int c;
|
2007-02-16 05:36:20 +01:00
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-12-14 00:38:25 +01:00
|
|
|
if (xf86RandR12Key) {
|
2008-03-03 05:13:11 +01:00
|
|
|
#endif
|
2007-11-29 09:57:24 +01:00
|
|
|
if (randrp->virtualX == -1 || randrp->virtualY == -1)
|
|
|
|
{
|
|
|
|
randrp->virtualX = pScrn->virtualX;
|
|
|
|
randrp->virtualY = pScrn->virtualY;
|
|
|
|
}
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-02-16 05:36:20 +01:00
|
|
|
}
|
2008-03-03 05:13:11 +01:00
|
|
|
#endif
|
2007-08-20 05:29:37 +02:00
|
|
|
if (pRoot && pScrn->vtSema)
|
2007-02-16 05:36:20 +01:00
|
|
|
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
|
|
|
|
|
2007-02-28 22:36:58 +01:00
|
|
|
/* Let the driver update virtualX and virtualY */
|
|
|
|
if (!(*config->funcs->resize)(pScrn, width, height))
|
|
|
|
goto finish;
|
|
|
|
|
|
|
|
ret = TRUE;
|
2008-11-28 17:49:31 +01:00
|
|
|
/* Update panning information */
|
|
|
|
for (c = 0; c < config->num_crtc; c++) {
|
|
|
|
xf86CrtcPtr crtc = config->crtc[c];
|
2008-12-04 18:13:40 +01:00
|
|
|
if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
|
2008-11-28 17:49:31 +01:00
|
|
|
crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
|
2008-12-04 18:13:40 +01:00
|
|
|
if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
|
|
|
|
crtc->panningTotalArea.x2 += width - pScreen->width;
|
|
|
|
if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
|
|
|
|
crtc->panningTotalArea.y2 += height - pScreen->height;
|
|
|
|
if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
|
|
|
|
crtc->panningTrackingArea.x2 += width - pScreen->width;
|
|
|
|
if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
|
|
|
|
crtc->panningTrackingArea.y2 += height - pScreen->height;
|
2008-11-28 17:49:31 +01:00
|
|
|
xf86RandR13VerifyPanningArea (crtc, width, height);
|
|
|
|
xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
|
|
|
|
}
|
|
|
|
}
|
2007-02-28 22:36:58 +01:00
|
|
|
|
2007-04-23 03:04:27 +02:00
|
|
|
pScreen->width = pScrnPix->drawable.width = width;
|
|
|
|
pScreen->height = pScrnPix->drawable.height = height;
|
2008-03-13 22:37:12 +01:00
|
|
|
randrp->mmWidth = pScreen->mmWidth = mmWidth;
|
|
|
|
randrp->mmHeight = pScreen->mmHeight = mmHeight;
|
2007-02-16 05:36:20 +01:00
|
|
|
|
|
|
|
xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
|
|
|
|
xf86SetViewport (pScreen, 0, 0);
|
2007-02-28 22:36:58 +01:00
|
|
|
|
|
|
|
finish:
|
2007-08-20 05:29:37 +02:00
|
|
|
if (pRoot && pScrn->vtSema)
|
2007-02-16 05:36:20 +01:00
|
|
|
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
|
|
|
|
#if RANDR_12_INTERFACE
|
2007-12-14 00:38:25 +01:00
|
|
|
if (xf86RandR12Key && WindowTable[pScreen->myNum] && ret)
|
2007-02-16 05:36:20 +01:00
|
|
|
RRScreenSizeNotify (pScreen);
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
Rotation
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12GetRotation(ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
|
|
|
|
return randrp->rotation;
|
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
Bool
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12CreateScreenResources (ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
2009-04-15 10:26:06 +02:00
|
|
|
xf86CrtcConfigPtr config;
|
|
|
|
XF86RandRInfoPtr randrp;
|
2007-02-16 05:36:20 +01:00
|
|
|
int c;
|
|
|
|
int width, height;
|
|
|
|
int mmWidth, mmHeight;
|
|
|
|
#ifdef PANORAMIX
|
|
|
|
/* XXX disable RandR when using Xinerama */
|
|
|
|
if (!noPanoramiXExtension)
|
|
|
|
return TRUE;
|
|
|
|
#endif
|
|
|
|
|
2009-04-15 10:26:06 +02:00
|
|
|
config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
randrp = XF86RANDRINFO(pScreen);
|
2007-02-16 05:36:20 +01:00
|
|
|
/*
|
|
|
|
* Compute size of screen
|
|
|
|
*/
|
|
|
|
width = 0; height = 0;
|
|
|
|
for (c = 0; c < config->num_crtc; c++)
|
|
|
|
{
|
|
|
|
xf86CrtcPtr crtc = config->crtc[c];
|
2007-02-16 09:56:00 +01:00
|
|
|
int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
|
|
|
|
int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
|
2007-02-16 05:36:20 +01:00
|
|
|
|
2008-12-11 16:48:40 +01:00
|
|
|
if (crtc->enabled) {
|
|
|
|
if (crtc_width > width)
|
|
|
|
width = crtc_width;
|
|
|
|
if (crtc_height > height)
|
|
|
|
height = crtc_height;
|
|
|
|
if (crtc->panningTotalArea.x2 > width)
|
|
|
|
width = crtc->panningTotalArea.x2;
|
|
|
|
if (crtc->panningTotalArea.y2 > height)
|
|
|
|
height = crtc->panningTotalArea.y2;
|
|
|
|
}
|
2007-02-16 05:36:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (width && height)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Compute physical size of screen
|
|
|
|
*/
|
|
|
|
if (monitorResolution)
|
|
|
|
{
|
|
|
|
mmWidth = width * 25.4 / monitorResolution;
|
|
|
|
mmHeight = height * 25.4 / monitorResolution;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-02-25 20:37:05 +01:00
|
|
|
xf86OutputPtr output = xf86CompatOutput(pScrn);
|
2007-03-06 08:36:00 +01:00
|
|
|
|
2010-02-25 20:37:05 +01:00
|
|
|
if (output &&
|
|
|
|
output->conf_monitor &&
|
2007-10-24 20:31:51 +02:00
|
|
|
(output->conf_monitor->mon_width > 0 &&
|
|
|
|
output->conf_monitor->mon_height > 0))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Prefer user configured DisplaySize
|
|
|
|
*/
|
|
|
|
mmWidth = output->conf_monitor->mon_width;
|
|
|
|
mmHeight = output->conf_monitor->mon_height;
|
|
|
|
}
|
2007-03-06 08:36:00 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
2007-11-18 17:56:31 +01:00
|
|
|
* Otherwise, just set the screen to DEFAULT_DPI
|
2007-03-06 08:36:00 +01:00
|
|
|
*/
|
2007-11-18 17:56:31 +01:00
|
|
|
mmWidth = width * 25.4 / DEFAULT_DPI;
|
|
|
|
mmHeight = height * 25.4 / DEFAULT_DPI;
|
2007-03-06 08:36:00 +01:00
|
|
|
}
|
2007-02-16 05:36:20 +01:00
|
|
|
}
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
|
|
"Setting screen physical size to %d x %d\n",
|
|
|
|
mmWidth, mmHeight);
|
2008-12-11 16:48:40 +01:00
|
|
|
/*
|
|
|
|
* This is the initial setting of the screen size.
|
|
|
|
* We have to pre-set it here, otherwise panning would be adapted
|
|
|
|
* to the new screen size.
|
|
|
|
*/
|
|
|
|
pScreen->width = width;
|
|
|
|
pScreen->height = height;
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12ScreenSetSize (pScreen,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
mmWidth,
|
|
|
|
mmHeight);
|
|
|
|
}
|
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-12-14 00:38:25 +01:00
|
|
|
if (xf86RandR12Key == NULL)
|
2007-11-29 09:57:24 +01:00
|
|
|
return TRUE;
|
2008-03-03 05:13:11 +01:00
|
|
|
#endif
|
2007-11-29 09:57:24 +01:00
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
if (randrp->virtualX == -1 || randrp->virtualY == -1)
|
|
|
|
{
|
|
|
|
randrp->virtualX = pScrn->virtualX;
|
|
|
|
randrp->virtualY = pScrn->virtualY;
|
|
|
|
}
|
2007-02-16 05:13:15 +01:00
|
|
|
xf86CrtcSetScreenSubpixelOrder (pScreen);
|
2007-02-16 05:36:20 +01:00
|
|
|
#if RANDR_12_INTERFACE
|
|
|
|
if (xf86RandR12CreateScreenResources12 (pScreen))
|
|
|
|
return TRUE;
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
Bool
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12Init (ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
rrScrPrivPtr rp;
|
|
|
|
XF86RandRInfoPtr randrp;
|
|
|
|
|
|
|
|
#ifdef PANORAMIX
|
|
|
|
/* XXX disable RandR when using Xinerama */
|
|
|
|
if (!noPanoramiXExtension)
|
xfree86: belately init RandR12 if xinerama fails. (#24627)
On Fri, Dec 11, 2009 at 10:19:01AM -0800, Keith Packard wrote:
> On Wed, 9 Dec 2009 11:55:14 +1000, Peter Hutterer <peter.hutterer@who-t.net> wrote:
> > On Tue, Dec 08, 2009 at 05:24:06PM -0800, Aaron Plattner wrote:
> > > On Tue, Dec 08, 2009 at 03:52:27PM -0800, Peter Hutterer wrote:
> > > > Xorg +xinerama crashes immediately due to whacky dependency between Xinerama
> > > > and RandR12. The latter doesn't initialize if Xinerama is enabled, but if
> > > > only one screen is found, Xinerama is disabled again and RandR12 tries to
> > > > access data it never initialized.
>
> I'd sure like to have RandR get enabled when xinerama doesn't; is there
> an easy way of making that happen here? Perhaps having the RandR12 code
> disable Xinerama when only one screen is found? Or some other kludge?
you know the dependency better than I do so any hints are apreciated.
afaict, the screenInfo.numScreens (the check used by Xinerama) isn't
necessarily initialized at this point so we can't use the same check.
The following seems to work though:
From 670b3ebdb7312a6433a8f093d0820785db2aea20 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon, 14 Dec 2009 11:00:58 +1000
Subject: [PATCH] xfree86: if only one screen was found, disable Xinerama (#24627)
Xorg +xinerama crashes immediately due to whacky dependency between Xinerama
and RandR12. The latter doesn't initialize if Xinerama is enabled, but if
only one screen is found, Xinerama is disabled again and RandR12 tries to
access data it never initialized.
Dependency chain is:
- ProcessCommandLine sets noPanoramiXExtension to FALSE
- xf86RandR12Init() is a noop
- PanoramiXExtensionInit sets noPanoramiXExtension to TRUE
- xf86RandR12CreateScreenResources tries to use the devPrivates key it never
initialized.
This hack checks if there's only one screen at the time RandR12 is
initialized. If so, we expect Xinerama to fail anyhow so we disable it
ourselves and proceed as planned.
X.Org Bug 24627 <http://bugs.freedesktop.org/show_bug.cgi?id=24627>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2009-12-14 02:05:20 +01:00
|
|
|
{
|
|
|
|
if (xf86NumScreens == 1)
|
|
|
|
noPanoramiXExtension = TRUE;
|
|
|
|
else
|
|
|
|
return TRUE;
|
|
|
|
}
|
2007-02-16 05:36:20 +01:00
|
|
|
#endif
|
2007-12-14 00:38:25 +01:00
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
if (xf86RandR12Generation != serverGeneration)
|
|
|
|
xf86RandR12Generation = serverGeneration;
|
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2008-08-29 00:05:40 +02:00
|
|
|
xf86RandR12Key = &xf86RandR12KeyIndex;
|
2008-03-03 05:13:11 +01:00
|
|
|
#else
|
|
|
|
xf86RandR12Index = AllocateScreenPrivateIndex();
|
|
|
|
#endif
|
2007-02-16 05:36:20 +01:00
|
|
|
|
|
|
|
randrp = xalloc (sizeof (XF86RandRInfoRec));
|
|
|
|
if (!randrp)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (!RRScreenInit(pScreen))
|
|
|
|
{
|
|
|
|
xfree (randrp);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
rp = rrGetScrPriv(pScreen);
|
|
|
|
rp->rrGetInfo = xf86RandR12GetInfo;
|
|
|
|
rp->rrSetConfig = xf86RandR12SetConfig;
|
|
|
|
|
|
|
|
randrp->virtualX = -1;
|
|
|
|
randrp->virtualY = -1;
|
|
|
|
randrp->mmWidth = pScreen->mmWidth;
|
|
|
|
randrp->mmHeight = pScreen->mmHeight;
|
|
|
|
|
|
|
|
randrp->rotation = RR_Rotate_0; /* initial rotated mode */
|
|
|
|
|
|
|
|
randrp->supported_rotations = RR_Rotate_0;
|
|
|
|
|
|
|
|
randrp->maxX = randrp->maxY = 0;
|
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-08-28 15:28:25 +02:00
|
|
|
dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
|
2008-03-03 05:13:11 +01:00
|
|
|
#else
|
|
|
|
pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
|
|
|
|
#endif
|
2007-02-16 05:36:20 +01:00
|
|
|
|
|
|
|
#if RANDR_12_INTERFACE
|
|
|
|
if (!xf86RandR12Init12 (pScreen))
|
|
|
|
return FALSE;
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
void
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
|
|
|
|
{
|
2007-11-29 09:57:24 +01:00
|
|
|
XF86RandRInfoPtr randrp;
|
2007-02-16 11:17:11 +01:00
|
|
|
#if RANDR_12_INTERFACE
|
2007-02-16 05:36:20 +01:00
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
int c;
|
2007-02-16 11:17:11 +01:00
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
2007-11-29 09:40:53 +01:00
|
|
|
#endif
|
2007-11-29 09:57:24 +01:00
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-12-14 00:38:25 +01:00
|
|
|
if (xf86RandR12Key == NULL)
|
2007-11-29 09:40:53 +01:00
|
|
|
return;
|
2008-03-03 05:13:11 +01:00
|
|
|
#endif
|
2007-02-16 05:36:20 +01:00
|
|
|
|
2007-11-29 09:57:24 +01:00
|
|
|
randrp = XF86RANDRINFO(pScreen);
|
2007-11-29 09:40:53 +01:00
|
|
|
#if RANDR_12_INTERFACE
|
2007-02-16 05:36:20 +01:00
|
|
|
for (c = 0; c < config->num_crtc; c++) {
|
|
|
|
xf86CrtcPtr crtc = config->crtc[c];
|
|
|
|
|
|
|
|
RRCrtcSetRotations (crtc->randr_crtc, rotations);
|
|
|
|
}
|
|
|
|
#endif
|
2007-02-16 11:17:11 +01:00
|
|
|
randrp->supported_rotations = rotations;
|
2007-02-16 05:36:20 +01:00
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
void
|
2008-03-19 20:15:39 +01:00
|
|
|
xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
|
2008-03-18 23:35:44 +01:00
|
|
|
{
|
|
|
|
XF86RandRInfoPtr randrp;
|
|
|
|
#if RANDR_13_INTERFACE
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
int c;
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
|
|
|
if (xf86RandR12Key == NULL)
|
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
randrp = XF86RANDRINFO(pScreen);
|
|
|
|
#if RANDR_13_INTERFACE
|
|
|
|
for (c = 0; c < config->num_crtc; c++) {
|
|
|
|
xf86CrtcPtr crtc = config->crtc[c];
|
|
|
|
|
2008-03-19 20:15:39 +01:00
|
|
|
RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
|
2008-03-18 23:35:44 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
void
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
|
|
|
|
|
|
|
|
if (xf86RandR12Generation != serverGeneration ||
|
|
|
|
XF86RANDRINFO(pScreen)->virtualX == -1)
|
|
|
|
{
|
|
|
|
*x = pScrn->virtualX;
|
|
|
|
*y = pScrn->virtualY;
|
|
|
|
} else {
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
|
|
|
|
*x = randrp->virtualX;
|
|
|
|
*y = randrp->virtualY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if RANDR_12_INTERFACE
|
2007-02-21 08:04:26 +01:00
|
|
|
|
|
|
|
#define FLAG_BITS (RR_HSyncPositive | \
|
|
|
|
RR_HSyncNegative | \
|
|
|
|
RR_VSyncPositive | \
|
|
|
|
RR_VSyncNegative | \
|
|
|
|
RR_Interlace | \
|
|
|
|
RR_DoubleScan | \
|
|
|
|
RR_CSync | \
|
|
|
|
RR_CSyncPositive | \
|
|
|
|
RR_CSyncNegative | \
|
|
|
|
RR_HSkewPresent | \
|
|
|
|
RR_BCast | \
|
|
|
|
RR_PixelMultiplex | \
|
|
|
|
RR_DoubleClock | \
|
|
|
|
RR_ClockDivideBy2)
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandRModeMatches (RRModePtr randr_mode,
|
|
|
|
DisplayModePtr mode)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
if (match_name)
|
|
|
|
{
|
|
|
|
/* check for same name */
|
|
|
|
int len = strlen (mode->name);
|
|
|
|
if (randr_mode->mode.nameLength != len) return FALSE;
|
|
|
|
if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* check for same timings */
|
|
|
|
if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
|
|
|
|
if (randr_mode->mode.width != mode->HDisplay) return FALSE;
|
|
|
|
if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE;
|
|
|
|
if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE;
|
|
|
|
if (randr_mode->mode.hTotal != mode->HTotal) return FALSE;
|
|
|
|
if (randr_mode->mode.hSkew != mode->HSkew) return FALSE;
|
|
|
|
if (randr_mode->mode.height != mode->VDisplay) return FALSE;
|
|
|
|
if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
|
|
|
|
if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
|
|
|
|
if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
|
|
|
|
|
|
|
|
/* check for same flags (using only the XF86 valid flag bits) */
|
|
|
|
if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* everything matches */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
static Bool
|
|
|
|
xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = randr_crtc->pScreen;
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
RRModePtr randr_mode = NULL;
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
Rotation rotation;
|
|
|
|
int numOutputs;
|
|
|
|
RROutputPtr *randr_outputs;
|
|
|
|
RROutputPtr randr_output;
|
|
|
|
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
|
|
|
xf86OutputPtr output;
|
|
|
|
int i, j;
|
|
|
|
DisplayModePtr mode = &crtc->mode;
|
|
|
|
Bool ret;
|
|
|
|
|
2007-11-05 15:11:59 +01:00
|
|
|
randr_outputs = xalloc(config->num_output * sizeof (RROutputPtr));
|
2007-02-16 05:36:20 +01:00
|
|
|
if (!randr_outputs)
|
|
|
|
return FALSE;
|
|
|
|
x = crtc->x;
|
|
|
|
y = crtc->y;
|
|
|
|
rotation = crtc->rotation;
|
|
|
|
numOutputs = 0;
|
|
|
|
randr_mode = NULL;
|
|
|
|
for (i = 0; i < config->num_output; i++)
|
|
|
|
{
|
|
|
|
output = config->output[i];
|
|
|
|
if (output->crtc == crtc)
|
|
|
|
{
|
|
|
|
randr_output = output->randr_output;
|
|
|
|
randr_outputs[numOutputs++] = randr_output;
|
|
|
|
/*
|
|
|
|
* We make copies of modes, so pointer equality
|
|
|
|
* isn't sufficient
|
|
|
|
*/
|
2007-02-21 08:04:26 +01:00
|
|
|
for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
|
2007-02-16 05:36:20 +01:00
|
|
|
{
|
2007-02-21 08:04:26 +01:00
|
|
|
RRModePtr m = (j < randr_output->numModes ?
|
|
|
|
randr_output->modes[j] :
|
|
|
|
randr_output->userModes[j-randr_output->numModes]);
|
|
|
|
|
|
|
|
if (xf86RandRModeMatches (m, mode))
|
2007-02-16 05:36:20 +01:00
|
|
|
{
|
2007-02-21 08:04:26 +01:00
|
|
|
randr_mode = m;
|
2007-02-16 05:36:20 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
|
2008-03-21 10:39:49 +01:00
|
|
|
rotation,
|
|
|
|
crtc->transformPresent ? &crtc->transform : NULL,
|
|
|
|
numOutputs, randr_outputs);
|
2007-11-05 15:11:59 +01:00
|
|
|
xfree(randr_outputs);
|
2007-02-16 05:36:20 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-02-21 08:04:26 +01:00
|
|
|
/*
|
|
|
|
* Convert a RandR mode to a DisplayMode
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
xf86RandRModeConvert (ScrnInfoPtr scrn,
|
|
|
|
RRModePtr randr_mode,
|
|
|
|
DisplayModePtr mode)
|
|
|
|
{
|
2007-11-26 15:38:20 +01:00
|
|
|
memset(mode, 0, sizeof(DisplayModeRec));
|
2007-02-21 08:04:26 +01:00
|
|
|
mode->status = MODE_OK;
|
|
|
|
|
|
|
|
mode->Clock = randr_mode->mode.dotClock / 1000;
|
|
|
|
|
|
|
|
mode->HDisplay = randr_mode->mode.width;
|
|
|
|
mode->HSyncStart = randr_mode->mode.hSyncStart;
|
|
|
|
mode->HSyncEnd = randr_mode->mode.hSyncEnd;
|
|
|
|
mode->HTotal = randr_mode->mode.hTotal;
|
|
|
|
mode->HSkew = randr_mode->mode.hSkew;
|
|
|
|
|
|
|
|
mode->VDisplay = randr_mode->mode.height;
|
|
|
|
mode->VSyncStart = randr_mode->mode.vSyncStart;
|
|
|
|
mode->VSyncEnd = randr_mode->mode.vSyncEnd;
|
|
|
|
mode->VTotal = randr_mode->mode.vTotal;
|
|
|
|
mode->VScan = 0;
|
|
|
|
|
|
|
|
mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS;
|
|
|
|
|
|
|
|
xf86SetModeCrtc (mode, scrn->adjustFlags);
|
|
|
|
}
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
static Bool
|
2008-03-19 20:15:39 +01:00
|
|
|
xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|
|
|
RRCrtcPtr randr_crtc,
|
|
|
|
RRModePtr randr_mode,
|
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
Rotation rotation,
|
|
|
|
int num_randr_outputs,
|
|
|
|
RROutputPtr *randr_outputs)
|
2007-02-16 05:36:20 +01:00
|
|
|
{
|
2008-11-28 17:49:31 +01:00
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
2007-02-16 05:36:20 +01:00
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
2008-03-19 20:15:39 +01:00
|
|
|
RRTransformPtr transform;
|
2007-02-16 05:36:20 +01:00
|
|
|
Bool changed = FALSE;
|
|
|
|
int o, ro;
|
|
|
|
xf86CrtcPtr *save_crtcs;
|
|
|
|
Bool save_enabled = crtc->enabled;
|
|
|
|
|
2008-03-17 16:33:01 +01:00
|
|
|
if (!crtc->scrn->vtSema)
|
|
|
|
return FALSE;
|
|
|
|
|
2007-11-05 15:11:59 +01:00
|
|
|
save_crtcs = xalloc(config->num_output * sizeof (xf86CrtcPtr));
|
2007-02-21 08:04:26 +01:00
|
|
|
if ((randr_mode != NULL) != crtc->enabled)
|
2007-02-16 05:36:20 +01:00
|
|
|
changed = TRUE;
|
2007-02-21 08:04:26 +01:00
|
|
|
else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
|
2007-02-16 05:36:20 +01:00
|
|
|
changed = TRUE;
|
|
|
|
|
|
|
|
if (rotation != crtc->rotation)
|
|
|
|
changed = TRUE;
|
|
|
|
|
2008-03-19 20:15:39 +01:00
|
|
|
transform = RRCrtcGetTransform (randr_crtc);
|
|
|
|
if ((transform != NULL) != crtc->transformPresent)
|
|
|
|
changed = TRUE;
|
|
|
|
else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
|
|
|
|
sizeof (transform->transform)) != 0)
|
2008-03-14 05:31:12 +01:00
|
|
|
changed = TRUE;
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
if (x != crtc->x || y != crtc->y)
|
|
|
|
changed = TRUE;
|
|
|
|
for (o = 0; o < config->num_output; o++)
|
|
|
|
{
|
|
|
|
xf86OutputPtr output = config->output[o];
|
|
|
|
xf86CrtcPtr new_crtc;
|
|
|
|
|
|
|
|
save_crtcs[o] = output->crtc;
|
|
|
|
|
|
|
|
if (output->crtc == crtc)
|
|
|
|
new_crtc = NULL;
|
|
|
|
else
|
|
|
|
new_crtc = output->crtc;
|
|
|
|
for (ro = 0; ro < num_randr_outputs; ro++)
|
|
|
|
if (output->randr_output == randr_outputs[ro])
|
|
|
|
{
|
|
|
|
new_crtc = crtc;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (new_crtc != output->crtc)
|
|
|
|
{
|
|
|
|
changed = TRUE;
|
|
|
|
output->crtc = new_crtc;
|
|
|
|
}
|
|
|
|
}
|
2007-07-14 21:36:15 +02:00
|
|
|
for (ro = 0; ro < num_randr_outputs; ro++)
|
|
|
|
if (randr_outputs[ro]->pendingProperties)
|
|
|
|
changed = TRUE;
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
/* XXX need device-independent mode setting code through an API */
|
|
|
|
if (changed)
|
|
|
|
{
|
2007-02-21 08:04:26 +01:00
|
|
|
crtc->enabled = randr_mode != NULL;
|
2007-02-16 05:36:20 +01:00
|
|
|
|
2007-02-21 08:04:26 +01:00
|
|
|
if (randr_mode)
|
2007-02-16 05:36:20 +01:00
|
|
|
{
|
2007-02-21 08:04:26 +01:00
|
|
|
DisplayModeRec mode;
|
2008-03-19 20:15:39 +01:00
|
|
|
RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
|
2007-02-21 08:04:26 +01:00
|
|
|
|
|
|
|
xf86RandRModeConvert (pScrn, randr_mode, &mode);
|
2008-03-19 20:15:39 +01:00
|
|
|
if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
|
2007-02-16 05:36:20 +01:00
|
|
|
{
|
|
|
|
crtc->enabled = save_enabled;
|
|
|
|
for (o = 0; o < config->num_output; o++)
|
|
|
|
{
|
|
|
|
xf86OutputPtr output = config->output[o];
|
|
|
|
output->crtc = save_crtcs[o];
|
|
|
|
}
|
2007-11-05 15:11:59 +01:00
|
|
|
xfree(save_crtcs);
|
2007-02-16 05:36:20 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
2008-11-28 17:49:31 +01:00
|
|
|
xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
|
|
|
|
xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
|
2007-02-16 05:36:20 +01:00
|
|
|
/*
|
|
|
|
* Save the last successful setting for EnterVT
|
|
|
|
*/
|
2007-02-21 08:04:26 +01:00
|
|
|
crtc->desiredMode = mode;
|
2007-02-16 05:36:20 +01:00
|
|
|
crtc->desiredRotation = rotation;
|
2008-03-19 20:15:39 +01:00
|
|
|
if (transform) {
|
|
|
|
crtc->desiredTransform = *transform;
|
|
|
|
crtc->desiredTransformPresent = TRUE;
|
|
|
|
} else
|
|
|
|
crtc->desiredTransformPresent = FALSE;
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
crtc->desiredX = x;
|
|
|
|
crtc->desiredY = y;
|
|
|
|
}
|
|
|
|
xf86DisableUnusedFunctions (pScrn);
|
|
|
|
}
|
2007-11-05 15:11:59 +01:00
|
|
|
xfree(save_crtcs);
|
2007-02-16 05:36:20 +01:00
|
|
|
return xf86RandR12CrtcNotify (randr_crtc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
|
|
|
|
RRCrtcPtr randr_crtc)
|
|
|
|
{
|
|
|
|
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
|
|
|
|
|
|
|
if (crtc->funcs->gamma_set == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
2007-06-22 03:08:21 +02:00
|
|
|
if (!crtc->scrn->vtSema)
|
|
|
|
return TRUE;
|
|
|
|
|
2008-12-17 16:56:26 +01:00
|
|
|
/* Realloc local gamma if needed. */
|
|
|
|
if (randr_crtc->gammaSize != crtc->gamma_size) {
|
|
|
|
CARD16 *tmp_ptr;
|
|
|
|
tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16));
|
|
|
|
if (!tmp_ptr)
|
|
|
|
return FALSE;
|
|
|
|
crtc->gamma_red = tmp_ptr;
|
|
|
|
crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
|
|
|
|
crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
crtc->gamma_size = randr_crtc->gammaSize;
|
|
|
|
memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16));
|
|
|
|
memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16));
|
|
|
|
memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16));
|
|
|
|
|
2008-12-17 23:42:30 +01:00
|
|
|
/* Only set it when the crtc is actually running.
|
|
|
|
* Otherwise it will be set when it's activated.
|
|
|
|
*/
|
|
|
|
if (crtc->active)
|
|
|
|
crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
|
|
|
|
crtc->gamma_blue, crtc->gamma_size);
|
2008-12-17 16:56:26 +01:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR12CrtcGetGamma (ScreenPtr pScreen,
|
|
|
|
RRCrtcPtr randr_crtc)
|
|
|
|
{
|
|
|
|
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
|
|
|
|
|
|
|
if (!crtc->gamma_size)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Realloc randr gamma if needed. */
|
|
|
|
if (randr_crtc->gammaSize != crtc->gamma_size) {
|
|
|
|
CARD16 *tmp_ptr;
|
|
|
|
tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16));
|
|
|
|
if (!tmp_ptr)
|
|
|
|
return FALSE;
|
|
|
|
randr_crtc->gammaRed = tmp_ptr;
|
|
|
|
randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
|
|
|
|
randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
|
|
|
|
}
|
|
|
|
randr_crtc->gammaSize = crtc->gamma_size;
|
|
|
|
memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16));
|
|
|
|
memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16));
|
|
|
|
memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16));
|
2007-02-16 05:36:20 +01:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR12OutputSetProperty (ScreenPtr pScreen,
|
|
|
|
RROutputPtr randr_output,
|
|
|
|
Atom property,
|
|
|
|
RRPropertyValuePtr value)
|
|
|
|
{
|
|
|
|
xf86OutputPtr output = randr_output->devPrivate;
|
|
|
|
|
|
|
|
/* If we don't have any property handler, then we don't care what the
|
|
|
|
* user is setting properties to.
|
|
|
|
*/
|
|
|
|
if (output->funcs->set_property == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
2007-06-22 03:08:21 +02:00
|
|
|
/*
|
|
|
|
* This function gets called even when vtSema is FALSE, as
|
|
|
|
* drivers will need to remember the correct value to apply
|
|
|
|
* when the VT switch occurs
|
|
|
|
*/
|
2007-02-16 05:36:20 +01:00
|
|
|
return output->funcs->set_property(output, property, value);
|
|
|
|
}
|
|
|
|
|
2008-03-06 22:47:44 +01:00
|
|
|
static Bool
|
|
|
|
xf86RandR13OutputGetProperty (ScreenPtr pScreen,
|
|
|
|
RROutputPtr randr_output,
|
|
|
|
Atom property)
|
|
|
|
{
|
|
|
|
xf86OutputPtr output = randr_output->devPrivate;
|
|
|
|
|
|
|
|
if (output->funcs->get_property == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* Should be safe even w/o vtSema */
|
|
|
|
return output->funcs->get_property(output, property);
|
|
|
|
}
|
|
|
|
|
2007-02-19 08:49:38 +01:00
|
|
|
static Bool
|
|
|
|
xf86RandR12OutputValidateMode (ScreenPtr pScreen,
|
|
|
|
RROutputPtr randr_output,
|
|
|
|
RRModePtr randr_mode)
|
|
|
|
{
|
2007-02-21 08:04:26 +01:00
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
2007-02-19 08:49:38 +01:00
|
|
|
xf86OutputPtr output = randr_output->devPrivate;
|
2007-02-21 08:04:26 +01:00
|
|
|
DisplayModeRec mode;
|
2007-02-19 08:49:38 +01:00
|
|
|
|
2007-02-21 08:04:26 +01:00
|
|
|
xf86RandRModeConvert (pScrn, randr_mode, &mode);
|
2007-06-22 03:08:21 +02:00
|
|
|
/*
|
|
|
|
* This function may be called when vtSema is FALSE, so
|
|
|
|
* the underlying function must either avoid touching the hardware
|
|
|
|
* or return FALSE when vtSema is FALSE
|
|
|
|
*/
|
2007-02-21 08:04:26 +01:00
|
|
|
if (output->funcs->mode_valid (output, &mode) != MODE_OK)
|
2007-02-19 08:49:38 +01:00
|
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
/**
|
|
|
|
* Given a list of xf86 modes and a RandR Output object, construct
|
|
|
|
* RandR modes and assign them to the output
|
|
|
|
*/
|
|
|
|
static Bool
|
|
|
|
xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
|
|
|
|
{
|
|
|
|
DisplayModePtr mode;
|
|
|
|
RRModePtr *rrmodes = NULL;
|
|
|
|
int nmode = 0;
|
|
|
|
int npreferred = 0;
|
|
|
|
Bool ret = TRUE;
|
|
|
|
int pref;
|
|
|
|
|
|
|
|
for (mode = modes; mode; mode = mode->next)
|
|
|
|
nmode++;
|
|
|
|
|
|
|
|
if (nmode) {
|
|
|
|
rrmodes = xalloc (nmode * sizeof (RRModePtr));
|
|
|
|
|
|
|
|
if (!rrmodes)
|
|
|
|
return FALSE;
|
|
|
|
nmode = 0;
|
|
|
|
|
|
|
|
for (pref = 1; pref >= 0; pref--) {
|
|
|
|
for (mode = modes; mode; mode = mode->next) {
|
|
|
|
if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
|
|
|
|
xRRModeInfo modeInfo;
|
|
|
|
RRModePtr rrmode;
|
|
|
|
|
|
|
|
modeInfo.nameLength = strlen (mode->name);
|
|
|
|
modeInfo.width = mode->HDisplay;
|
|
|
|
modeInfo.dotClock = mode->Clock * 1000;
|
|
|
|
modeInfo.hSyncStart = mode->HSyncStart;
|
|
|
|
modeInfo.hSyncEnd = mode->HSyncEnd;
|
|
|
|
modeInfo.hTotal = mode->HTotal;
|
|
|
|
modeInfo.hSkew = mode->HSkew;
|
|
|
|
|
|
|
|
modeInfo.height = mode->VDisplay;
|
|
|
|
modeInfo.vSyncStart = mode->VSyncStart;
|
|
|
|
modeInfo.vSyncEnd = mode->VSyncEnd;
|
|
|
|
modeInfo.vTotal = mode->VTotal;
|
|
|
|
modeInfo.modeFlags = mode->Flags;
|
|
|
|
|
|
|
|
rrmode = RRModeGet (&modeInfo, mode->name);
|
|
|
|
if (rrmode) {
|
|
|
|
rrmodes[nmode++] = rrmode;
|
|
|
|
npreferred += pref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
|
|
|
|
xfree (rrmodes);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Mirror the current mode configuration to RandR
|
|
|
|
*/
|
|
|
|
static Bool
|
|
|
|
xf86RandR12SetInfo12 (ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
RROutputPtr *clones;
|
|
|
|
RRCrtcPtr *crtcs;
|
|
|
|
int ncrtc;
|
|
|
|
int o, c, l;
|
|
|
|
RRCrtcPtr randr_crtc;
|
|
|
|
int nclone;
|
|
|
|
|
2007-11-05 15:11:59 +01:00
|
|
|
clones = xalloc(config->num_output * sizeof (RROutputPtr));
|
|
|
|
crtcs = xalloc (config->num_crtc * sizeof (RRCrtcPtr));
|
2007-02-16 05:36:20 +01:00
|
|
|
for (o = 0; o < config->num_output; o++)
|
|
|
|
{
|
|
|
|
xf86OutputPtr output = config->output[o];
|
|
|
|
|
|
|
|
ncrtc = 0;
|
|
|
|
for (c = 0; c < config->num_crtc; c++)
|
|
|
|
if (output->possible_crtcs & (1 << c))
|
|
|
|
crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
|
|
|
|
|
|
|
|
if (output->crtc)
|
|
|
|
randr_crtc = output->crtc->randr_crtc;
|
|
|
|
else
|
|
|
|
randr_crtc = NULL;
|
|
|
|
|
|
|
|
if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
|
|
|
|
{
|
2007-11-05 15:11:59 +01:00
|
|
|
xfree (crtcs);
|
|
|
|
xfree (clones);
|
2007-02-16 05:36:20 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RROutputSetPhysicalSize(output->randr_output,
|
|
|
|
output->mm_width,
|
|
|
|
output->mm_height);
|
|
|
|
xf86RROutputSetModes (output->randr_output, output->probed_modes);
|
|
|
|
|
|
|
|
switch (output->status) {
|
|
|
|
case XF86OutputStatusConnected:
|
|
|
|
RROutputSetConnection (output->randr_output, RR_Connected);
|
|
|
|
break;
|
|
|
|
case XF86OutputStatusDisconnected:
|
|
|
|
RROutputSetConnection (output->randr_output, RR_Disconnected);
|
|
|
|
break;
|
|
|
|
case XF86OutputStatusUnknown:
|
|
|
|
RROutputSetConnection (output->randr_output, RR_UnknownConnection);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Valid clones
|
|
|
|
*/
|
|
|
|
nclone = 0;
|
|
|
|
for (l = 0; l < config->num_output; l++)
|
|
|
|
{
|
|
|
|
xf86OutputPtr clone = config->output[l];
|
|
|
|
|
|
|
|
if (l != o && (output->possible_clones & (1 << l)))
|
|
|
|
clones[nclone++] = clone->randr_output;
|
|
|
|
}
|
|
|
|
if (!RROutputSetClones (output->randr_output, clones, nclone))
|
|
|
|
{
|
2007-11-05 15:11:59 +01:00
|
|
|
xfree (crtcs);
|
|
|
|
xfree (clones);
|
2007-02-16 05:36:20 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2007-11-05 15:11:59 +01:00
|
|
|
xfree (crtcs);
|
|
|
|
xfree (clones);
|
2007-02-16 05:36:20 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Query the hardware for the current state, then mirror
|
|
|
|
* that to RandR
|
|
|
|
*/
|
|
|
|
static Bool
|
|
|
|
xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
|
2007-06-22 03:08:21 +02:00
|
|
|
if (!pScrn->vtSema)
|
|
|
|
return TRUE;
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86ProbeOutputModes (pScrn, 0, 0);
|
|
|
|
xf86SetScrnInfoModes (pScrn);
|
|
|
|
return xf86RandR12SetInfo12 (pScreen);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR12CreateObjects12 (ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
int c;
|
|
|
|
int o;
|
|
|
|
|
|
|
|
if (!RRInit ())
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Configure crtcs
|
|
|
|
*/
|
|
|
|
for (c = 0; c < config->num_crtc; c++)
|
|
|
|
{
|
|
|
|
xf86CrtcPtr crtc = config->crtc[c];
|
|
|
|
|
2007-03-24 07:41:36 +01:00
|
|
|
crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
|
2007-02-16 05:36:20 +01:00
|
|
|
RRCrtcGammaSetSize (crtc->randr_crtc, 256);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Configure outputs
|
|
|
|
*/
|
|
|
|
for (o = 0; o < config->num_output; o++)
|
|
|
|
{
|
|
|
|
xf86OutputPtr output = config->output[o];
|
|
|
|
|
2007-03-24 07:41:36 +01:00
|
|
|
output->randr_output = RROutputCreate (pScreen, output->name,
|
2007-02-16 05:36:20 +01:00
|
|
|
strlen (output->name),
|
|
|
|
output);
|
|
|
|
|
|
|
|
if (output->funcs->create_resources != NULL)
|
|
|
|
output->funcs->create_resources(output);
|
2007-03-24 07:41:36 +01:00
|
|
|
RRPostPendingProperties (output->randr_output);
|
2007-02-16 05:36:20 +01:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-12-14 00:38:25 +01:00
|
|
|
if (xf86RandR12Key == NULL)
|
2007-11-29 09:40:53 +01:00
|
|
|
return TRUE;
|
2008-03-03 05:13:11 +01:00
|
|
|
#endif
|
2007-11-29 09:40:53 +01:00
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
for (c = 0; c < config->num_crtc; c++)
|
2007-11-29 09:40:53 +01:00
|
|
|
xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
|
2007-02-16 05:36:20 +01:00
|
|
|
|
2007-02-28 22:36:58 +01:00
|
|
|
RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
|
|
|
|
config->maxWidth, config->maxHeight);
|
2007-02-16 05:36:20 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2007-04-09 23:12:27 +02:00
|
|
|
/*
|
|
|
|
* Something happened within the screen configuration due
|
|
|
|
* to DGA, VidMode or hot key. Tell RandR
|
|
|
|
*/
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
void
|
2007-04-09 23:12:27 +02:00
|
|
|
xf86RandR12TellChanged (ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
int c;
|
|
|
|
|
2008-03-03 05:13:11 +01:00
|
|
|
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
|
2007-12-14 00:38:25 +01:00
|
|
|
if (xf86RandR12Key == NULL)
|
2007-04-09 23:12:27 +02:00
|
|
|
return;
|
2008-03-03 05:13:11 +01:00
|
|
|
#else
|
|
|
|
if (!XF86RANDRINFO(pScreen))
|
|
|
|
return;
|
|
|
|
#endif
|
2007-11-29 09:57:24 +01:00
|
|
|
|
2007-04-09 23:12:27 +02:00
|
|
|
xf86RandR12SetInfo12 (pScreen);
|
|
|
|
for (c = 0; c < config->num_crtc; c++)
|
|
|
|
xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
|
|
|
|
|
|
|
|
RRTellChanged (pScreen);
|
|
|
|
}
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
static void
|
|
|
|
xf86RandR12PointerMoved (int scrnIndex, int x, int y)
|
|
|
|
{
|
2008-11-28 17:49:31 +01:00
|
|
|
ScreenPtr pScreen = screenInfo.screens[scrnIndex];
|
|
|
|
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
|
|
|
|
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
int c;
|
|
|
|
|
|
|
|
randrp->pointerX = x;
|
|
|
|
randrp->pointerY = y;
|
|
|
|
for (c = 0; c < config->num_crtc; c++)
|
|
|
|
xf86RandR13Pan (config->crtc[c], x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR13GetPanning (ScreenPtr pScreen,
|
|
|
|
RRCrtcPtr randr_crtc,
|
|
|
|
BoxPtr totalArea,
|
|
|
|
BoxPtr trackingArea,
|
|
|
|
INT16 *border)
|
|
|
|
{
|
|
|
|
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
|
|
|
|
|
|
|
if (crtc->version < 2)
|
|
|
|
return FALSE;
|
|
|
|
if (totalArea)
|
|
|
|
memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
|
|
|
|
if (trackingArea)
|
|
|
|
memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
|
|
|
|
if (border)
|
|
|
|
memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
xf86RandR13SetPanning (ScreenPtr pScreen,
|
|
|
|
RRCrtcPtr randr_crtc,
|
|
|
|
BoxPtr totalArea,
|
|
|
|
BoxPtr trackingArea,
|
|
|
|
INT16 *border)
|
|
|
|
{
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
2008-12-04 16:28:40 +01:00
|
|
|
BoxRec oldTotalArea;
|
|
|
|
BoxRec oldTrackingArea;
|
|
|
|
INT16 oldBorder[4];
|
|
|
|
|
2008-11-28 17:49:31 +01:00
|
|
|
|
|
|
|
if (crtc->version < 2)
|
|
|
|
return FALSE;
|
2008-12-04 16:28:40 +01:00
|
|
|
|
|
|
|
memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
|
|
|
|
memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
|
|
|
|
memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
|
|
|
|
|
2008-11-28 17:49:31 +01:00
|
|
|
if (totalArea)
|
|
|
|
memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
|
|
|
|
if (trackingArea)
|
|
|
|
memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
|
|
|
|
if (border)
|
|
|
|
memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
|
|
|
|
|
2008-12-04 16:28:40 +01:00
|
|
|
if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
|
|
|
|
xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
/* Restore old settings */
|
|
|
|
memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
|
|
|
|
memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
|
|
|
|
memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-02-16 05:36:20 +01:00
|
|
|
}
|
|
|
|
|
2009-04-17 23:46:58 +02:00
|
|
|
/*
|
|
|
|
* Compatibility with XF86VidMode's gamma changer. This necessarily clobbers
|
|
|
|
* any per-crtc setup. You asked for it...
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
gamma_to_ramp(float gamma, CARD16 *ramp, int size)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
if (gamma == 1.0)
|
|
|
|
ramp[i] = i << 8;
|
|
|
|
else
|
2009-05-14 11:35:25 +02:00
|
|
|
ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma)
|
2009-04-17 23:46:58 +02:00
|
|
|
* (double)(size - 1) * 256);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
|
|
|
|
{
|
|
|
|
CARD16 *points, *red, *green, *blue;
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
2010-02-25 20:37:05 +01:00
|
|
|
RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
|
|
|
|
int size;
|
2009-04-17 23:46:58 +02:00
|
|
|
|
2010-02-25 20:37:05 +01:00
|
|
|
if (!crtc)
|
|
|
|
return Success;
|
|
|
|
|
|
|
|
size = max(0, crtc->gammaSize);
|
2009-04-17 23:46:58 +02:00
|
|
|
if (!size)
|
|
|
|
return Success;
|
|
|
|
|
|
|
|
points = xcalloc(size, 3 * sizeof(CARD16));
|
|
|
|
if (!points)
|
|
|
|
return BadAlloc;
|
|
|
|
|
|
|
|
red = points;
|
|
|
|
green = points + size;
|
|
|
|
blue = points + 2 * size;
|
|
|
|
|
2009-07-21 14:34:47 +02:00
|
|
|
gamma_to_ramp(gamma.red, red, size);
|
|
|
|
gamma_to_ramp(gamma.green, green, size);
|
|
|
|
gamma_to_ramp(gamma.blue, blue, size);
|
|
|
|
RRCrtcGammaSet(crtc, red, green, blue);
|
2009-04-17 23:46:58 +02:00
|
|
|
|
|
|
|
xfree(points);
|
|
|
|
|
2009-05-14 11:39:16 +02:00
|
|
|
pScrn->gamma = gamma;
|
|
|
|
|
2009-04-17 23:46:58 +02:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2009-05-05 02:24:47 +02:00
|
|
|
static Bool
|
|
|
|
xf86RandR12EnterVT (int screen_index, int flags)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = screenInfo.screens[screen_index];
|
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
|
|
|
|
|
|
|
if (randrp->orig_EnterVT) {
|
|
|
|
if (!randrp->orig_EnterVT (screen_index, flags))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
|
|
|
|
}
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
static Bool
|
|
|
|
xf86RandR12Init12 (ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
|
|
rrScrPrivPtr rp = rrGetScrPriv(pScreen);
|
2009-05-05 02:24:47 +02:00
|
|
|
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
2007-02-16 05:36:20 +01:00
|
|
|
|
|
|
|
rp->rrGetInfo = xf86RandR12GetInfo12;
|
|
|
|
rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
|
|
|
|
rp->rrCrtcSet = xf86RandR12CrtcSet;
|
|
|
|
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
|
2008-12-17 16:56:26 +01:00
|
|
|
rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
|
2007-02-16 05:36:20 +01:00
|
|
|
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
|
2007-02-19 08:49:38 +01:00
|
|
|
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
|
2008-03-06 22:47:44 +01:00
|
|
|
#if RANDR_13_INTERFACE
|
|
|
|
rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
|
2008-11-28 17:49:31 +01:00
|
|
|
rp->rrGetPanning = xf86RandR13GetPanning;
|
|
|
|
rp->rrSetPanning = xf86RandR13SetPanning;
|
2008-03-06 22:47:44 +01:00
|
|
|
#endif
|
2007-02-19 08:49:38 +01:00
|
|
|
rp->rrModeDestroy = xf86RandR12ModeDestroy;
|
2007-02-16 05:36:20 +01:00
|
|
|
rp->rrSetConfig = NULL;
|
|
|
|
pScrn->PointerMoved = xf86RandR12PointerMoved;
|
2009-04-17 23:46:58 +02:00
|
|
|
pScrn->ChangeGamma = xf86RandR12ChangeGamma;
|
2009-05-05 02:24:47 +02:00
|
|
|
|
|
|
|
randrp->orig_EnterVT = pScrn->EnterVT;
|
|
|
|
pScrn->EnterVT = xf86RandR12EnterVT;
|
|
|
|
|
2007-02-16 05:36:20 +01:00
|
|
|
if (!xf86RandR12CreateObjects12 (pScreen))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Configure output modes
|
|
|
|
*/
|
|
|
|
if (!xf86RandR12SetInfo12 (pScreen))
|
|
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 08:43:34 +01:00
|
|
|
Bool
|
2007-02-16 05:36:20 +01:00
|
|
|
xf86RandR12PreInit (ScrnInfoPtr pScrn)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|