xorg-server: Changes to 'upstream-experimental'
configure.ac | 6
hw/xfree86/Makefile.am | 1
hw/xfree86/common/xf86Module.h | 2
hw/xfree86/common/xf86xv.c | 66 ++++
hw/xfree86/common/xf86xv.h | 3
hw/xfree86/common/xf86xvpriv.h | 1
hw/xfree86/ddc/xf86DDC.c | 7
hw/xfree86/fbdevhw/fbdevhw.c | 160 +++++++---
hw/xfree86/loader/Makefile.am | 3
hw/xfree86/loader/loadmod.c | 3
hw/xfree86/loader/xf86sym.c | 7
hw/xfree86/modes/Makefile.am | 4
hw/xfree86/modes/xf86Crtc.c | 49 +++
hw/xfree86/modes/xf86Crtc.h | 114 +++++++
hw/xfree86/modes/xf86Cursors.c | 607 +++++++++++++++++++++++++++++++++++++++++
hw/xfree86/modes/xf86RandR12.c | 7
hw/xfree86/modes/xf86Rotate.c | 93 ++++--
hw/xfree86/ramdac/Makefile.am | 6
hw/xfree86/ramdac/xf86Cursor.h | 3
randr/mirandr.c | 11
randr/randr.c | 2
randr/randrstr.h | 27 -
randr/rrcrtc.c | 175 ++++++-----
randr/rrinfo.c | 11
randr/rroutput.c | 54 +--
randr/rrproperty.c | 184 ++++++++----
26 files changed, 1290 insertions(+), 316 deletions(-)
New commits:
commit 00e33f87f429a5e9e29da30071f03972a4033b8d
Author: Keith Packard <keithp@neko.keithp.com>
Date: Mon Mar 26 21:21:50 2007 -0700
Set version to 1.2.99.903 (1.3 RC3)
diff --git a/configure.ac b/configure.ac
index ed2c631..6ba4d03 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@ dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
dnl This is the not the Xorg version number, it's the server version number.
dnl Yes, that's weird.
-AC_INIT([xorg-server], 1.2.99.902, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.2.99.903, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
AM_MAINTAINER_MODE
@@ -40,8 +40,8 @@ DEFAULT_VENDOR_NAME_SHORT="X.Org"
DEFAULT_VERSION_MAJOR=1
DEFAULT_VERSION_MINOR=2
DEFAULT_VERSION_PATCH=99
-DEFAULT_VERSION_SNAP=902
-DEFAULT_RELEASE_DATE="14 March 2007"
+DEFAULT_VERSION_SNAP=903
+DEFAULT_RELEASE_DATE="26 March 2007"
DEFAULT_VENDOR_WEB="http://wiki.x.org"
dnl this gets generated by autoheader, and thus contains all the defines. we
commit 4fd2d3aedfae838940d61598466f89fdb47b1557
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Tue Jan 23 10:15:22 2007 +0100
Bump video driver ABI version to 1.2.
This is necessary because server-1.2-branch bumped to 1.1 for xf86CVTMode and
we have xf86XVFillKeyHelperDrawable on top of that.
(cherry picked from commit 788cfce911793a26aed16f38f30678ecee82c873)
Conflicts:
hw/xfree86/common/xf86Module.h
Avoid picking up XInput ABI change.
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index edae6f2..e54d9be 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -84,7 +84,7 @@ typedef enum {
* mask is 0xFFFF0000.
*/
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 3)
-#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(1, 1)
+#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(1, 2)
#define ABI_XINPUT_VERSION SET_ABI_VERSION(0, 7)
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(0, 3)
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 5)
commit dc914ced69e1e619a944c7dcb940c25e195cd4f3
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Sun Oct 15 16:48:59 2006 +0200
Add per-drawable Xv colour key helper function.
This allows overlay Xv adaptors to work slightly better with compositing
managers.
Bump the video driver ABI minor so drivers only need to check for this at build
time.
(cherry picked from commit a232693c8c2a206aac47c07b133c071938204e0b)
Conflicts:
hw/xfree86/common/xf86Module.h
Avoid picking up XInput ABI version change.
diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 89cb6ba..3e908b8 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -974,6 +974,7 @@ xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
if(!winPriv) {
winPriv = xalloc(sizeof(XF86XVWindowRec));
if(!winPriv) return BadAlloc;
+ memset(winPriv, 0, sizeof(XF86XVWindowRec));
winPriv->PortRec = portPriv;
winPriv->next = PrivRoot;
pWin->devPrivates[XF86XVWindowIndex].ptr = (pointer)winPriv;
@@ -1026,6 +1027,9 @@ xf86XVDestroyWindow(WindowPtr pWin)
pPriv->pDraw = NULL;
tmp = WinPriv;
+ if(WinPriv->pGC) {
+ FreeGC(WinPriv->pGC, 0);
+ }
WinPriv = WinPriv->next;
xfree(tmp);
}
@@ -1118,6 +1122,8 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
while(WinPriv) {
pPriv = WinPriv->PortRec;
+ if(!pPriv) goto next;
+
if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
REGION_DESTROY(pScreen, pPriv->pCompositeClip);
@@ -1148,6 +1154,7 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
}
}
+next:
pPrev = WinPriv;
WinPriv = WinPriv->next;
}
@@ -1739,9 +1746,13 @@ xf86XVPutImage(
REGION_UNINIT(pScreen, &VPReg);
}
- if(portPriv->pDraw) {
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
+
+ /* Register our port with the new window */
+ ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(ret != Success) goto PUT_IMAGE_BAILOUT;
if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
clippedAway = TRUE;
@@ -1772,7 +1783,6 @@ xf86XVPutImage(
if((ret == Success) &&
(portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
- xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
portPriv->isOn = XV_ON;
portPriv->pDraw = pDraw;
portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
@@ -1813,6 +1823,56 @@ xf86XVQueryImageAttributes(
format->id, width, height, pitches, offsets);
}
+
+_X_EXPORT void
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ WindowPtr pWin = (WindowPtr)pDraw;
+ XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin);
+ GCPtr pGC = NULL;
+ XID pval[2];
+ BoxPtr pbox = REGION_RECTS(clipboxes);
+ int i, nbox = REGION_NUM_RECTS(clipboxes);
+ xRectangle *rects;
+
+ if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+ if(pPriv)
+ pGC = pPriv->pGC;
+
+ if(!pGC) {
+ int status;
+ pval[0] = key;
+ pval[1] = IncludeInferiors;
+ pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status);
+ if(!pGC) return;
+ ValidateGC(pDraw, pGC);
+ if (pPriv) pPriv->pGC = pGC;
+ } else if (key != pGC->fgPixel){
+ pval[0] = key;
+ ChangeGC(pGC, GCForeground, pval);
+ ValidateGC(pDraw, pGC);
+ }
+
+ REGION_TRANSLATE(pDraw->pScreen, clipboxes, -pDraw->x, -pDraw->y);
+
+ rects = ALLOCATE_LOCAL(nbox * sizeof(xRectangle));
+
+ for(i = 0; i < nbox; i++, pbox++) {
+ rects[i].x = pbox->x1;
+ rects[i].y = pbox->y1;
+ rects[i].width = pbox->x2 - pbox->x1;
+ rects[i].height = pbox->y2 - pbox->y1;
+ }
+
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects);
+
+ if (!pPriv) FreeGC(pGC, 0);
+
+ DEALLOCATE_LOCAL(rects);
+}
+
_X_EXPORT void
xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
{
diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h
index e0feb57..817e2b9 100644
--- a/hw/xfree86/common/xf86xv.h
+++ b/hw/xfree86/common/xf86xv.h
@@ -232,6 +232,9 @@ void xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr);
void
xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes);
+void
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes);
+
Bool
xf86XVClipVideoHelper(
BoxPtr dst,
diff --git a/hw/xfree86/common/xf86xvpriv.h b/hw/xfree86/common/xf86xvpriv.h
index ced0536..e716c9c 100644
--- a/hw/xfree86/common/xf86xvpriv.h
+++ b/hw/xfree86/common/xf86xvpriv.h
@@ -80,6 +80,7 @@ typedef struct {
typedef struct _XF86XVWindowRec{
XvPortRecPrivatePtr PortRec;
struct _XF86XVWindowRec *next;
+ GCPtr pGC;
} XF86XVWindowRec, *XF86XVWindowPtr;
#endif /* _XF86XVPRIV_H_ */
diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c
index 3103976..09d6681 100644
--- a/hw/xfree86/loader/xf86sym.c
+++ b/hw/xfree86/loader/xf86sym.c
@@ -632,6 +632,7 @@ _X_HIDDEN void *xfree86LookupTab[] = {
SYMFUNC(xf86XVAllocateVideoAdaptorRec)
SYMFUNC(xf86XVFreeVideoAdaptorRec)
SYMFUNC(xf86XVFillKeyHelper)
+ SYMFUNC(xf86XVFillKeyHelperDrawable)
SYMFUNC(xf86XVClipVideoHelper)
SYMFUNC(xf86XVCopyYUV12ToPacked)
SYMFUNC(xf86XVCopyPacked)
commit 96636598ee8a024b2fc93e2779b581446fa22d83
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Fri Jan 19 18:30:21 2007 +0100
fbdevhw: Only deal with RGB weight if default visual is True- or DirectColor.
(cherry picked from commit 14d6a9b327381a6bb2dac59c62728e5fd0f0bcfb)
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 8b163be..a573b8f 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -187,9 +187,16 @@ xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
pScrn->virtualX;
var->yres_virtual = pScrn->virtualY;
var->bits_per_pixel = pScrn->bitsPerPixel;
- var->red.length = pScrn->weight.red;
- var->green.length = pScrn->weight.green;
- var->blue.length = pScrn->weight.blue;
+ if (pScrn->defaultVisual == TrueColor ||
+ pScrn->defaultVisual == DirectColor) {
+ var->red.length = pScrn->weight.red;
+ var->green.length = pScrn->weight.green;
+ var->blue.length = pScrn->weight.blue;
+ } else {
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ }
}
static void
@@ -746,15 +753,18 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
return FALSE;
}
- /* XXX: This is a hack, but it should be a NOP for all the setups that
- * worked before and actually seems to fix some others...
- */
- pScrn->offset.red = fPtr->var.red.offset;
- pScrn->offset.green = fPtr->var.green.offset;
- pScrn->offset.blue = fPtr->var.blue.offset;
- pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
- pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
- pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
+ if (pScrn->defaultVisual == TrueColor ||
+ pScrn->defaultVisual == DirectColor) {
+ /* XXX: This is a hack, but it should be a NOP for all the setups that
+ * worked before and actually seems to fix some others...
+ */
+ pScrn->offset.red = fPtr->var.red.offset;
+ pScrn->offset.green = fPtr->var.green.offset;
+ pScrn->offset.blue = fPtr->var.blue.offset;
+ pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
+ pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
+ pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
+ }
return TRUE;
}
commit 7679b2c6139ee7345b4f65ab84384162bbd796ae
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Fri Jan 19 18:28:05 2007 +0100
fbdevhw: Consider mode set equal to mode requested if virtual width is larger.
(cherry picked from commit 27a01e100bff21ac0b70c6d72071d7226fc91264)
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 8f78b85..8b163be 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -229,23 +229,23 @@ xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
}
static Bool
-fbdev_modes_equal(struct fb_var_screeninfo *one, struct fb_var_screeninfo *two)
-{
- return (one->xres_virtual == two->xres_virtual &&
- one->yres_virtual == two->yres_virtual &&
- one->bits_per_pixel == two->bits_per_pixel &&
- one->red.length == two->red.length &&
- one->green.length == two->green.length &&
- one->blue.length == two->blue.length &&
- one->xres == two->xres && one->yres == two->yres &&
- one->pixclock == two->pixclock &&
- one->right_margin == two->right_margin &&
- one->hsync_len == two->hsync_len &&
- one->left_margin == two->left_margin &&
- one->lower_margin == two->lower_margin &&
- one->vsync_len == two->vsync_len &&
- one->upper_margin == two->upper_margin &&
- one->sync == two->sync && one->vmode == two->vmode);
+fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req)
+{
+ return (set->xres_virtual >= req->xres_virtual &&
+ set->yres_virtual == req->yres_virtual &&
+ set->bits_per_pixel == req->bits_per_pixel &&
+ set->red.length == req->red.length &&
+ set->green.length == req->green.length &&
+ set->blue.length == req->blue.length &&
+ set->xres == req->xres && set->yres == req->yres &&
+ set->pixclock == req->pixclock &&
+ set->right_margin == req->right_margin &&
+ set->hsync_len == req->hsync_len &&
+ set->left_margin == req->left_margin &&
+ set->lower_margin == req->lower_margin &&
+ set->vsync_len == req->vsync_len &&
+ set->upper_margin == req->upper_margin &&
+ set->sync == req->sync && set->vmode == req->vmode);
}
static void
commit 1c2793d3ec4c82c7205abb10a1f4d093864425ea
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Sun Dec 31 17:59:44 2006 +0100
fbdevhw: Override RGB offsets and masks after setting initial mode.
This is a hack, but it should be a NOP for all the setups that worked before
and actually seems to fix some others...
Based on a patch by Peter Teichmann from
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=338241 .
(cherry picked from commit dc5eb4523298f966bd5fd9ae6672160034b5e82c)
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index a9288a7..8f78b85 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -745,6 +745,17 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
"FBIOGET_VSCREENINFO: %s\n", strerror(errno));
return FALSE;
}
+
+ /* XXX: This is a hack, but it should be a NOP for all the setups that
+ * worked before and actually seems to fix some others...
+ */
+ pScrn->offset.red = fPtr->var.red.offset;
+ pScrn->offset.green = fPtr->var.green.offset;
+ pScrn->offset.blue = fPtr->var.blue.offset;
+ pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
+ pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
+ pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
+
return TRUE;
}
commit d7bcad9c694a13c702e429d8364035850d8f8bb7
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Sun Dec 31 17:23:31 2006 +0100
fbdevhw: Use displayWidth for fbdev virtual width when appropriate.
The fbdev API doesn't allow setting the pitch explicitly, so we have to set
the virtual width to the pitch we're using for drawing. This fixes corruption
after changing the virtual width with RandR.
(cherry picked from commit d077c0da470ab7291e8d838eaace57b066477d6f)
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 83b0dc1..a9288a7 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -183,7 +183,8 @@ print_xfree_mode(char *txt, DisplayModePtr mode)
static void
xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
{
- var->xres_virtual = pScrn->virtualX;
+ var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth :
+ pScrn->virtualX;
var->yres_virtual = pScrn->virtualY;
var->bits_per_pixel = pScrn->bitsPerPixel;
var->red.length = pScrn->weight.red;
commit 28af734cb7f2e5e40f6524411f77eba0e3960a8d
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Sat Dec 30 16:44:31 2006 +0100
fbdevhw: Fix some issues with the previous commit.
Fix a TRACE_ENTER typo and only update the internal fbdev mode state cache
after actually setting a mode.
(cherry picked from commit c385bcf0bde38dd869f7065f859dd4b4126f5690)
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 303ad14..83b0dc1 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -496,7 +496,7 @@ fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
struct fb_var_screeninfo req_var = fPtr->var, set_var;
- TRACE_ENTER("ModeInit");
+ TRACE_ENTER("SetMode");
xfree2fbdev_fblayout(pScrn, &req_var);
xfree2fbdev_timing(mode, &req_var);
@@ -528,7 +528,8 @@ fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
return FALSE;
}
- fPtr->var = set_var;
+ if (!check)
+ fPtr->var = set_var;
return TRUE;
}
commit c0459d7476f408806b1e7202b960ee0b3911774a
Author: Michel Dänzer <michel@tungstengraphics.com>
Date: Sat Dec 30 10:18:28 2006 +0100
fbdevhw: Consolidate modeset ioctl calling, report failure if it modifies mode.
The fbdev API allows the driver to 'accept' modes it doesn't really support by
modifying it to the nearest supported mode. Without this check, e.g. vesafb
would appear to accept all modes, even though it actually can't set any modes
other than the bootup mode at all.
(cherry picked from commit f6815cb68b0f6698497348fc6e4214dacef33b95)
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 70bed62..303ad14 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -227,6 +227,26 @@ xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
var->vmode = FB_VMODE_NONINTERLACED;
}
+static Bool
+fbdev_modes_equal(struct fb_var_screeninfo *one, struct fb_var_screeninfo *two)
+{
+ return (one->xres_virtual == two->xres_virtual &&
+ one->yres_virtual == two->yres_virtual &&
+ one->bits_per_pixel == two->bits_per_pixel &&
+ one->red.length == two->red.length &&
+ one->green.length == two->green.length &&
+ one->blue.length == two->blue.length &&
+ one->xres == two->xres && one->yres == two->yres &&
+ one->pixclock == two->pixclock &&
+ one->right_margin == two->right_margin &&
+ one->hsync_len == two->hsync_len &&
+ one->left_margin == two->left_margin &&
+ one->lower_margin == two->lower_margin &&
+ one->vsync_len == two->vsync_len &&
+ one->upper_margin == two->upper_margin &&
+ one->sync == two->sync && one->vmode == two->vmode);
+}
+
static void
fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
{
@@ -470,13 +490,52 @@ fbdevHWGetVidmem(ScrnInfoPtr pScrn)
return fPtr->fix.smem_len;
}
+static Bool
+fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ struct fb_var_screeninfo req_var = fPtr->var, set_var;
+
+ TRACE_ENTER("ModeInit");
+
+ xfree2fbdev_fblayout(pScrn, &req_var);
+ xfree2fbdev_timing(mode, &req_var);
+
+#if DEBUG
+ print_xfree_mode("init", mode);
+ print_fbdev_mode("init", &req_var);
+#endif
+
+ set_var = req_var;
+
+ if (check)
+ set_var.activate = FB_ACTIVATE_TEST;
+
+ if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (!fbdev_modes_equal(&set_var, &req_var)) {
+ if (!check)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO succeeded but modified "
+ "mode\n");
+#if DEBUG
+ print_fbdev_mode("returned", &set_var);
+#endif
+ return FALSE;
+ }
+
+ fPtr->var = set_var;
+
+ return TRUE;
+}
+
void
fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- int virtX = pScrn->display->virtualX;
- int virtY = pScrn->display->virtualY;
- struct fb_var_screeninfo var;
char **modename;
DisplayModePtr mode,this,last = pScrn->modes;
@@ -484,6 +543,9 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
if (NULL == pScrn->display->modes)
return;
+ pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+
for (modename = pScrn->display->modes; *modename != NULL; modename++) {
for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
if (0 == strcmp(mode->name,*modename))
@@ -493,27 +555,20 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
"\tmode \"%s\" not found\n", *modename);
continue;
}
- memset(&var,0,sizeof(var));
- xfree2fbdev_timing(mode,&var);
- var.xres_virtual = virtX;
- var.yres_virtual = virtY;
- var.bits_per_pixel = pScrn->bitsPerPixel;
- var.red.length = pScrn->weight.red;
- var.green.length = pScrn->weight.green;
- var.blue.length = pScrn->weight.blue;
-
- var.activate = FB_ACTIVATE_TEST;
- if (var.xres_virtual < var.xres) var.xres_virtual = var.xres;
- if (var.yres_virtual < var.yres) var.yres_virtual = var.yres;
- if (-1 == ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&var))) {
+
+ if (!fbdevHWSetMode(pScrn, mode, TRUE)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"\tmode \"%s\" test failed\n", *modename);
continue;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"\tmode \"%s\" ok\n", *modename);
- if (virtX < var.xres) virtX = var.xres;
- if (virtY < var.yres) virtY = var.yres;
+
+ if (pScrn->virtualX < mode->HDisplay)
+ pScrn->virtualX = mode->HDisplay;
+ if (pScrn->virtualY < mode->VDisplay)
+ pScrn->virtualY = mode->VDisplay;
+
if (NULL == pScrn->modes) {
pScrn->modes = xnfalloc(sizeof(DisplayModeRec));
this = pScrn->modes;
@@ -530,8 +585,6 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
}
last = this;
}
- pScrn->virtualX = virtX;
- pScrn->virtualY = virtY;
}
DisplayModePtr
@@ -673,21 +726,12 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- TRACE_ENTER("ModeInit");
- xfree2fbdev_fblayout(pScrn, &fPtr->var);
- xfree2fbdev_timing(mode, &fPtr->var);
-#if DEBUG
- print_xfree_mode("init",mode);
- print_fbdev_mode("init",&fPtr->var);
-#endif
pScrn->vtSema = TRUE;
/* set */
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+ if (!fbdevHWSetMode(pScrn, mode, FALSE))
return FALSE;
- }
+
/* read back */
if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -767,18 +811,12 @@ ModeStatus
fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- struct fb_var_screeninfo var;
TRACE_ENTER("ValidMode");
- memcpy(&var,&fPtr->var,sizeof(var));
- xfree2fbdev_timing(mode, &var);
- var.activate = FB_ACTIVATE_TEST;
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+
+ if (!fbdevHWSetMode(pScrn, mode, TRUE))
return MODE_BAD;
- }
+
return MODE_OK;
}
@@ -786,15 +824,12 @@ Bool
fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
TRACE_ENTER("SwitchMode");
- xfree2fbdev_timing(mode, &fPtr->var);
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+
+ if (!fbdevHWSetMode(pScrn, mode, FALSE))
return FALSE;
- }
+
return TRUE;
}
commit 57e87e0d006cbf1f5b175fe02eeb981f741d92f0
Author: Keith Packard <keithp@neko.keithp.com>
Date: Fri Mar 23 23:41:36 2007 -0700
Make pending properties force mode set. And, remove AttachScreen calls.
Yes, two changes in one commit. Sorry 'bout that.
The first change ensures that when pending property values have been
changed, a mode set to the current mode will actually do something, rather
than being identified as a no-op. In addition, the driver no longer needs to
manage the migration of pending to current values, that is handled both
within the xf86 mode setting code (to deal with non-RandR changes) as well
as within the RandR extension itself.
The second change eliminates the two-call Create/AttachScreen stuff that was
done in a failed attempt to create RandR resources before the screen
structures were allocated. Merging these back into the Create function is
cleaner.
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index b9895d9..7d86b66 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -312,7 +312,13 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
{
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc)
+ {
output->funcs->commit(output);
+#ifdef RANDR_12_INTERFACE
+ if (output->randr_output)
+ RRPostPendingProperties (output->randr_output);
+#endif
+ }
}
/* XXX free adjustedmode */
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 4213fea..6f52ee2 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1011,8 +1011,7 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86CrtcPtr crtc = config->crtc[c];
- crtc->randr_crtc = RRCrtcCreate (crtc);
- RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
+ crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
RRCrtcGammaSetSize (crtc->randr_crtc, 256);
}
/*
@@ -1022,13 +1021,13 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86OutputPtr output = config->output[o];
- output->randr_output = RROutputCreate (output->name,
+ output->randr_output = RROutputCreate (pScreen, output->name,
strlen (output->name),
output);
- RROutputAttachScreen (output->randr_output, pScreen);
if (output->funcs->create_resources != NULL)
output->funcs->create_resources(output);
+ RRPostPendingProperties (output->randr_output);
}
return TRUE;
}
diff --git a/randr/mirandr.c b/randr/mirandr.c
index 47136fb..3c4991e 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -133,20 +133,13 @@ miRandRInit (ScreenPtr pScreen)
if (!mode)
return FALSE;
- crtc = RRCrtcCreate (NULL);
+ crtc = RRCrtcCreate (pScreen, NULL);
if (!crtc)
return FALSE;
- if (!RRCrtcAttachScreen (crtc, pScreen))
- {
- RRCrtcDestroy (crtc);
- return FALSE;
- }
- output = RROutputCreate ("screen", 6, NULL);
+ output = RROutputCreate (pScreen, "screen", 6, NULL);
if (!output)
return FALSE;
- if (!RROutputAttachScreen (output, pScreen))
- return FALSE;
if (!RROutputSetClones (output, NULL, 0))
return FALSE;
if (!RROutputSetModes (output, &mode, 1, 0))
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 40d3eec..6deaf47 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -138,6 +138,7 @@ struct _rrOutput {
RRModePtr *userModes;
Bool changed;
RRPropertyPtr properties;
+ Bool pendingProperties;
void *devPrivate;
};
@@ -496,7 +497,7 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
* Create a CRTC
*/
RRCrtcPtr
-RRCrtcCreate (void *devPrivate);
+RRCrtcCreate (ScreenPtr pScreen, void *devPrivate);
/*
* Set the allowed rotations on a CRTC
@@ -505,14 +506,6 @@ void
RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
/*
- * Attach a CRTC to a screen. Once done, this cannot be
- * undone without destroying the CRTC; it is separate from Create
- * only to allow an xf86-based driver to create objects in preinit
- */
-Bool
-RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen);
-
-/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
*/
@@ -668,19 +661,12 @@ RROutputChanged (RROutputPtr output, Bool configChanged);
*/
RROutputPtr
-RROutputCreate (const char *name,
+RROutputCreate (ScreenPtr pScreen,
+ const char *name,
int nameLength,
void *devPrivate);
/*
- * Attach an output to a screen, again split from creation so
- * xf86 DDXen can create randr resources before the ScreenRec
- * exists
- */
-Bool
-RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen);
-
-/*
* Notify extension that output parameters have been changed
*/
Bool
@@ -760,7 +746,7 @@ void
RRDeleteOutputProperty (RROutputPtr output, Atom property);
Bool
-RRPostPendingProperty (RROutputPtr output, Atom property);
+RRPostPendingProperties (RROutputPtr output);
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index da88253..1a2a3a7 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -51,17 +51,32 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
* Create a CRTC
*/
RRCrtcPtr
-RRCrtcCreate (void *devPrivate)
+RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
{
- RRCrtcPtr crtc;
-
+ RRCrtcPtr crtc;
+ RRCrtcPtr *crtcs;
+ rrScrPrivPtr pScrPriv;
+
if (!RRInit())
return NULL;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ /* make space for the crtc pointer */
+ if (pScrPriv->numCrtcs)
+ crtcs = xrealloc (pScrPriv->crtcs,
+ (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
+ else
+ crtcs = xalloc (sizeof (RRCrtcPtr));
+ if (!crtcs)
+ return FALSE;
+ pScrPriv->crtcs = crtcs;
+
crtc = xalloc (sizeof (RRCrtcRec));
if (!crtc)
return NULL;
crtc->id = FakeClientID (0);
- crtc->pScreen = NULL;
+ crtc->pScreen = pScreen;
crtc->mode = NULL;
crtc->x = 0;
crtc->y = 0;
@@ -77,6 +92,10 @@ RRCrtcCreate (void *devPrivate)
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
return NULL;
+ /* attach the screen and crtc together */
+ crtc->pScreen = pScreen;
+ pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
+
return crtc;
}
@@ -90,36 +109,6 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
}
/*
- * Attach a Crtc to a screen. This is done as a separate step
- * so that an xf86-based driver can create CRTCs in PreInit
- * before the Screen has been created
- */
-
-Bool
-RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen)
-{
- rrScrPriv (pScreen);
- RRCrtcPtr *crtcs;
-
- /* make space for the crtc pointer */
- if (pScrPriv->numCrtcs)
- crtcs = xrealloc (pScrPriv->crtcs,
- (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
- else
- crtcs = xalloc (sizeof (RRCrtcPtr));
- if (!crtcs)
- return FALSE;
-
- /* attach the screen and crtc together */
- crtc->pScreen = pScreen;
- pScrPriv->crtcs = crtcs;
- pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
-
- RRCrtcChanged (crtc, TRUE);
- return TRUE;
-}
-
-/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
*/
@@ -258,6 +247,22 @@ RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
WriteEventsToClient (client, 1, (xEvent *) &ce);
}
+static Bool
+RRCrtcPendingProperties (RRCrtcPtr crtc)
+{
+ ScreenPtr pScreen = crtc->pScreen;
+ rrScrPriv(pScreen);
+ int o;
+
+ for (o = 0; o < pScrPriv->numOutputs; o++)
+ {
+ RROutputPtr output = pScrPriv->outputs[o];
+ if (output->crtc == crtc && output->pendingProperties)
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
* Request that the Crtc be reconfigured
*/
@@ -280,7 +285,8 @@ RRCrtcSet (RRCrtcPtr crtc,
crtc->y == y &&
crtc->rotation == rotation &&
crtc->numOutputs == numOutputs &&
- !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)))
+ !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
+ !RRCrtcPendingProperties (crtc))
{
ret = TRUE;
}
@@ -337,7 +343,13 @@ RRCrtcSet (RRCrtcPtr crtc,
#endif
}
if (ret)
+ {
+ int o;
RRTellChanged (pScreen);
+
+ for (o = 0; o < numOutputs; o++)
+ RRPostPendingProperties (outputs[o]);
+ }
}
return ret;
}
diff --git a/randr/rrinfo.c b/randr/rrinfo.c
index 549d501..5ef1a6b 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -91,19 +91,12 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
if (pScrPriv->numOutputs == 0 &&
pScrPriv->numCrtcs == 0)
{
- crtc = RRCrtcCreate (NULL);
+ crtc = RRCrtcCreate (pScreen, NULL);
if (!crtc)
return;
- if (!RRCrtcAttachScreen (crtc, pScreen))
- {
- RRCrtcDestroy (crtc);
- return;
- }
- output = RROutputCreate ("default", 7, NULL);
+ output = RROutputCreate (pScreen, "default", 7, NULL);
if (!output)
return;
- if (!RROutputAttachScreen (output, pScreen))
- return;
RROutputSetCrtcs (output, &crtc, 1);
RROutputSetCrtc (output, crtc);
RROutputSetConnection (output, RR_Connected);
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 09f2afd..c773279 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -47,19 +47,35 @@ RROutputChanged (RROutputPtr output, Bool configChanged)
*/
RROutputPtr
-RROutputCreate (const char *name,
+RROutputCreate (ScreenPtr pScreen,
+ const char *name,
int nameLength,
void *devPrivate)
{
- RROutputPtr output;
+ RROutputPtr output;
+ RROutputPtr *outputs;
+ rrScrPrivPtr pScrPriv;
if (!RRInit())
return NULL;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv->numOutputs)
+ outputs = xrealloc (pScrPriv->outputs,
+ (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
+ else
+ outputs = xalloc (sizeof (RROutputPtr));
+ if (!outputs)
+ return FALSE;
+
+ pScrPriv->outputs = outputs;
+
output = xalloc (sizeof (RROutputRec) + nameLength + 1);
if (!output)
return NULL;
output->id = FakeClientID (0);
- output->pScreen = NULL;
+ output->pScreen = pScreen;
output->name = (char *) (output + 1);
output->nameLength = nameLength;
memcpy (output->name, name, nameLength);
@@ -85,36 +101,11 @@ RROutputCreate (const char *name,
if (!AddResource (output->id, RROutputType, (pointer) output))
return NULL;
+ pScrPriv->outputs[pScrPriv->numOutputs++] = output;
return output;
}
/*
- * Attach an Output to a screen. This is done as a separate step
- * so that an xf86-based driver can create Outputs in PreInit
- * before the Screen has been created
- */
-
-Bool
-RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen)
-{
- rrScrPriv (pScreen);
- RROutputPtr *outputs;
-
- if (pScrPriv->numOutputs)
- outputs = xrealloc (pScrPriv->outputs,
- (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
- else
- outputs = xalloc (sizeof (RROutputPtr));
- if (!outputs)
- return FALSE;
- output->pScreen = pScreen;
- pScrPriv->outputs = outputs;
- pScrPriv->outputs[pScrPriv->numOutputs++] = output;
- RROutputChanged (output, FALSE);
- return TRUE;
-}
-
-/*
* Notify extension that output parameters have been changed
*/
Bool
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index afac351..00dd750 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -27,7 +27,7 @@
static void
RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask)
{
-
+
}
void
@@ -50,7 +50,7 @@ RRDeleteAllOutputProperties (RROutputPtr output)
xfree(prop->current.data);
if (prop->pending.data)
xfree(prop->pending.data);
- xfree(prop);
+ xfree(prop);
}
}
@@ -67,7 +67,7 @@ static RRPropertyPtr
RRCreateOutputProperty (Atom property)
{
RRPropertyPtr prop;
-
+
prop = (RRPropertyPtr)xalloc(sizeof(RRPropertyRec));
if (!prop)
return NULL;
@@ -139,7 +139,7 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
prop = RRQueryOutputProperty (output, property);
if (!prop) /* just add to list */
{
- prop = RRCreateOutputProperty (property);
+ prop = RRCreateOutputProperty (property);
if (!prop)
return(BadAlloc);
add = TRUE;
@@ -149,11 +149,11 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
prop_value = &prop->pending;
else
prop_value = &prop->current;
-
+
/* To append or prepend to a property the request format and type
- must match those of the already defined property. The
- existing format and type are irrelevant when using the mode
- "PropModeReplace" since they will be written over. */
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
if ((format != prop_value->format) && (mode != PropModeReplace))
return(BadMatch);
@@ -167,8 +167,8 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
if (mode == PropModeReplace || len > 0)
{
- pointer new_data, old_data;
-
+ pointer new_data = NULL, old_data = NULL;
+
total_size = total_len * size_in_bytes;
new_value.data = (pointer)xalloc (total_size);
if (!new_value.data && total_size)
@@ -197,11 +197,12 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
(prop_value->size * size_in_bytes));
break;
}
- memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
+ if (new_data)
+ memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
if (old_data)
memcpy ((char *) old_data, (char *) prop_value->data,
prop_value->size * size_in_bytes);
-
+
if (pending && pScrPriv->rrOutputSetProperty &&
!pScrPriv->rrOutputSetProperty(output->pScreen, output,
prop->propertyName, &new_value))
@@ -214,18 +215,21 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
xfree (prop_value->data);
*prop_value = new_value;
}
-
+
else if (len == 0)
{
/* do nothing */
}
-
+
if (add)
{
prop->next = output->properties;
output->properties = prop;
}
+ if (pending && prop->is_pending)
+ output->pendingProperties = TRUE;
+
if (sendevent)
{
event.type = RREventBase + RRNotify;
@@ -240,30 +244,45 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
}
Bool
-RRPostPendingProperty (RROutputPtr output, Atom property)
+RRPostPendingProperties (RROutputPtr output)
{
- RRPropertyPtr prop = RRQueryOutputProperty (output, property);
- RRPropertyValuePtr pending_value;
- RRPropertyValuePtr current_value;
-
- if (!prop)
- return FALSE;
- if (!prop->is_pending)
- return FALSE;
- pending_value = &prop->pending;
- current_value = &prop->current;
-
- if (pending_value->type == current_value->type &&
- pending_value->format == current_value->format &&
- pending_value->size == current_value->size &&
- !memcmp (pending_value->data, current_value->data, pending_value->size))
+ RRPropertyValuePtr pending_value;
+ RRPropertyValuePtr current_value;
+ RRPropertyPtr property;
+ Bool ret = TRUE;
+
+ if (!output->pendingProperties)
return TRUE;
- if (RRChangeOutputProperty (output, property,
- pending_value->type, pending_value->format, PropModeReplace,
- pending_value->size, pending_value->data, TRUE, FALSE) != Success)
- return FALSE;
- return TRUE;
+ output->pendingProperties = FALSE;
+ for (property = output->properties; property; property = property->next)
+ {
+ /* Skip non-pending properties */
+ if (!property->is_pending)
+ continue;
+
+ pending_value = &property->pending;
+ current_value = &property->current;
+
+ /*
+ * If the pending and current values are equal, don't mark it
+ * as changed (which would deliver an event)
+ */
+ if (pending_value->type == current_value->type &&
+ pending_value->format == current_value->format &&
+ pending_value->size == current_value->size &&
+ !memcmp (pending_value->data, current_value->data,
+ pending_value->size))
+ continue;
+
+ if (RRChangeOutputProperty (output, property->propertyName,
+ pending_value->type, pending_value->format,
+ PropModeReplace, pending_value->size,
+ pending_value->data, TRUE,
+ FALSE) != Success)
+ ret = FALSE;
+ }
+ return ret;
}
RRPropertyPtr
commit 36e5227215e0912ddf8a010db042467f00efe0fc
Author: Keith Packard <keithp@neko.keithp.com>
Date: Fri Mar 23 14:39:10 2007 -0700
Ensure that crtc desired values track most recent mode.
desiredX and desiredY were not recorded during xf86InitialConfiguration.
desiredX, desiredY and desiredRotation were not recorded during
xf86SetSingleMode.
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 2341715..b9895d9 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1589,6 +1589,8 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
{
crtc->desiredMode = *mode;
crtc->desiredRotation = output->initial_rotation;
+ crtc->desiredX = output->initial_x;
+ crtc->desiredY = output->initial_y;
crtc->enabled = TRUE;
crtc->x = output->initial_x;
crtc->y = output->initial_y;
@@ -1813,7 +1815,12 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
if (!xf86CrtcSetMode (crtc, crtc_mode, rotation, 0, 0))
ok = FALSE;
else
+ {
crtc->desiredMode = *crtc_mode;
+ crtc->desiredRotation = rotation;
+ crtc->desiredX = 0;
+ crtc->desiredY = 0;
+ }
}
xf86DisableUnusedFunctions(pScrn);
return ok;
commit 945aa0aa556429b50dea8e8ebc0008304b093eb7
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Fri Mar 23 01:17:14 2007 -0700
Incorrect extra memory copy in RRChangeOutputProperty.
Left over from previous version of the code, this memmove will break when
the mode is not Replace.
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index a57bd74..afac351 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -177,8 +177,6 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
RRDestroyOutputProperty (prop);
return BadAlloc;
}
- if (len)
- memmove((char *)new_value.data, (char *)value, total_size);
new_value.size = len;
new_value.type = type;
new_value.format = format;
commit 8eb288fbd69e2ffd02521d2c6a964c8180d08ec8
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Fri Mar 23 01:05:55 2007 -0700
Fix Pending property API, adding RRPostPendingProperty.
Pending Properties take effect when the driver says they do, so provide an
API to tell DIX when a property effect is made. Also, allow driver
to reject property values in RRChangeOutputProperty.
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index fad0752..2341715 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1923,7 +1923,7 @@ xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
if (data_len != 0) {
RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
- PropModeReplace, data_len, data, FALSE);
+ PropModeReplace, data_len, data, FALSE, TRUE);
} else {
RRDeleteOutputProperty(output->randr_output, edid_atom);
}
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 3968103..40d3eec 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -759,10 +759,13 @@ RRQueryOutputProperty (RROutputPtr output, Atom property);
void
RRDeleteOutputProperty (RROutputPtr output, Atom property);
+Bool
+RRPostPendingProperty (RROutputPtr output, Atom property);
+
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
- pointer value, Bool sendevent);
+ pointer value, Bool sendevent, Bool pending);
int
RRConfigureOutputProperty (RROutputPtr output, Atom property,
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index e020d5b..a57bd74 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -121,19 +121,19 @@ RRDeleteOutputProperty (RROutputPtr output, Atom property)
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
- pointer value, Bool sendevent)
+ pointer value, Bool sendevent, Bool pending)
{
RRPropertyPtr prop;
xRROutputPropertyNotifyEvent event;
rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
- int sizeInBytes;
- int totalSize;
- pointer data;
+ int size_in_bytes;
+ int total_size;
+ unsigned long total_len;
RRPropertyValuePtr prop_value;
+ RRPropertyValueRec new_value;
Bool add = FALSE;
- sizeInBytes = format >> 3;
- totalSize = len * sizeInBytes;
+ size_in_bytes = format >> 3;
/* first see if property already exists */
prop = RRQueryOutputProperty (output, property);
@@ -145,7 +145,7 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
add = TRUE;
mode = PropModeReplace;
}
- if (prop->is_pending)
+ if (pending && prop->is_pending)
prop_value = &prop->pending;
else
prop_value = &prop->current;
@@ -159,68 +159,75 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
return(BadMatch);
if ((prop_value->type != type) && (mode != PropModeReplace))
return(BadMatch);
+ new_value = *prop_value;
if (mode == PropModeReplace)
+ total_len = len;
+ else
+ total_len = prop_value->size + len;
+
+ if (mode == PropModeReplace || len > 0)
{
- if (totalSize != prop_value->size * (prop_value->format >> 3))
+ pointer new_data, old_data;
+
+ total_size = total_len * size_in_bytes;
+ new_value.data = (pointer)xalloc (total_size);
+ if (!new_value.data && total_size)
{
- if (prop_value->data)
- data = (pointer)xrealloc(prop_value->data, totalSize);
- else
- data = (pointer)xalloc (totalSize);
- if (!data && len)
- {
- if (add)
- RRDestroyOutputProperty (prop);
- return(BadAlloc);
- }
- prop_value->data = data;
+ if (add)
+ RRDestroyOutputProperty (prop);
+ return BadAlloc;
}
if (len)
- memmove((char *)prop_value->data, (char *)value, totalSize);
- prop_value->size = len;
- prop_value->type = type;
- prop_value->format = format;
+ memmove((char *)new_value.data, (char *)value, total_size);
+ new_value.size = len;
+ new_value.type = type;
+ new_value.format = format;
+
+ switch (mode) {
+ case PropModeReplace:
+ new_data = new_value.data;
+ old_data = NULL;
+ break;
+ case PropModeAppend:
+ new_data = (pointer) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ old_data = new_value.data;
+ break;
+ case PropModePrepend:
+ new_data = new_value.data;
+ old_data = (pointer) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ break;
+ }
+ memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
+ if (old_data)
+ memcpy ((char *) old_data, (char *) prop_value->data,
+ prop_value->size * size_in_bytes);
+
+ if (pending && pScrPriv->rrOutputSetProperty &&
+ !pScrPriv->rrOutputSetProperty(output->pScreen, output,
+ prop->propertyName, &new_value))
+ {
+ if (new_value.data)
+ xfree (new_value.data);
+ return (BadValue);
+ }
+ if (prop_value->data)
+ xfree (prop_value->data);
+ *prop_value = new_value;
}
+
else if (len == 0)
{
/* do nothing */
}
- else if (mode == PropModeAppend)
- {
- data = (pointer)xrealloc(prop_value->data,
- sizeInBytes * (len + prop_value->size));
- if (!data)
- return(BadAlloc);
- prop_value->data = data;
- memmove(&((char *)data)[prop_value->size * sizeInBytes],
- (char *)value,
- totalSize);
- prop_value->size += len;
- }
- else if (mode == PropModePrepend)
- {
- data = (pointer)xalloc(sizeInBytes * (len + prop_value->size));
- if (!data)
- return(BadAlloc);
- memmove(&((char *)data)[totalSize], (char *)prop_value->data,
- (int)(prop_value->size * sizeInBytes));
- memmove((char *)data, (char *)value, totalSize);
- xfree(prop_value->data);
- prop_value->data = data;
- prop_value->size += len;
- }
+
if (add)
{
prop->next = output->properties;
output->properties = prop;
}
- if (!prop->is_pending && pScrPriv->rrOutputSetProperty) {
- /* What should we do in case of failure? */
- pScrPriv->rrOutputSetProperty(output->pScreen, output,
- prop->propertyName, prop_value);
- }
-
if (sendevent)
{
event.type = RREventBase + RRNotify;
@@ -234,6 +241,33 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
return(Success);
}
+Bool
+RRPostPendingProperty (RROutputPtr output, Atom property)
+{
+ RRPropertyPtr prop = RRQueryOutputProperty (output, property);
+ RRPropertyValuePtr pending_value;
+ RRPropertyValuePtr current_value;
+
+ if (!prop)
+ return FALSE;
+ if (!prop->is_pending)
+ return FALSE;
+ pending_value = &prop->pending;
+ current_value = &prop->current;
+
+ if (pending_value->type == current_value->type &&
+ pending_value->format == current_value->format &&
+ pending_value->size == current_value->size &&
+ !memcmp (pending_value->data, current_value->data, pending_value->size))
+ return TRUE;
+
+ if (RRChangeOutputProperty (output, property,
+ pending_value->type, pending_value->format, PropModeReplace,
+ pending_value->size, pending_value->data, TRUE, FALSE) != Success)
+ return FALSE;
+ return TRUE;
+}
+
RRPropertyPtr
RRQueryOutputProperty (RROutputPtr output, Atom property)
{
@@ -474,7 +508,7 @@ ProcRRChangeOutputProperty (ClientPtr client)
err = RRChangeOutputProperty(output, stuff->property,
stuff->type, (int)format,
- (int)mode, len, (pointer)&stuff[1], TRUE);
+ (int)mode, len, (pointer)&stuff[1], TRUE, TRUE);
if (err != Success)
return err;
else
@@ -508,8 +542,8 @@ int
ProcRRGetOutputProperty (ClientPtr client)
{
REQUEST(xRRGetOutputPropertyReq);
- RRPropertyPtr prop, *prev;
- RRPropertyValuePtr prop_value;
+ RRPropertyPtr prop, *prev;
+ RRPropertyValuePtr prop_value;
unsigned long n, len, ind;
RROutputPtr output;
xRRGetOutputPropertyReply reply;
@@ -600,7 +634,10 @@ ProcRRGetOutputProperty (ClientPtr client)
reply.bytesAfter = n - (ind + len);
reply.format = prop_value->format;
reply.length = (len + 3) >> 2;
- reply.nItems = len / (prop_value->format / 8 );
+ if (prop_value->format)
+ reply.nItems = len / (prop_value->format / 8);
+ else
+ reply.nItems = 0;
reply.propertyType = prop_value->type;
if (stuff->delete && (reply.bytesAfter == 0))
commit 9ca7ba5d6012295a77ed773c656e786440da973d
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Fri Mar 23 01:03:40 2007 -0700
Make sure RandR events are delivered from RRCrtcSet.
Some paths were skipping the event delivery stage.
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 1b3c230..da88253 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -271,6 +271,8 @@ RRCrtcSet (RRCrtcPtr crtc,
RROutputPtr *outputs)
{
ScreenPtr pScreen = crtc->pScreen;
+ Bool ret = FALSE;
+ rrScrPriv(pScreen);
/* See if nothing changed */
if (crtc->mode == mode &&
@@ -280,61 +282,64 @@ RRCrtcSet (RRCrtcPtr crtc,
crtc->numOutputs == numOutputs &&
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)))
{
- return TRUE;
+ ret = TRUE;
}
- if (pScreen)
+ else
{
#if RANDR_12_INTERFACE
- rrScrPriv(pScreen);
if (pScrPriv->rrCrtcSet)
{
- return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
- rotation, numOutputs, outputs);
+ ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
+ rotation, numOutputs, outputs);
}
+ else
#endif
-#if RANDR_10_INTERFACE
- if (pScrPriv->rrSetConfig)
{
- RRScreenSize size;
- RRScreenRate rate;
- Bool ret;
-
- if (!mode)
- {
- RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
- return TRUE;
- }
-
- size.width = mode->mode.width;
- size.height = mode->mode.height;
- if (outputs[0]->mmWidth && outputs[0]->mmHeight)
- {
- size.mmWidth = outputs[0]->mmWidth;
- size.mmHeight = outputs[0]->mmHeight;
- }
- else
- {
- size.mmWidth = pScreen->mmWidth;
- size.mmHeight = pScreen->mmHeight;
- }
- size.nRates = 1;
- rate.rate = RRVerticalRefresh (&mode->mode);
- size.pRates = &rate;
- ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
- /*
- * Old 1.0 interface tied screen size to mode size
- */
- if (ret)
+#if RANDR_10_INTERFACE
+ if (pScrPriv->rrSetConfig)
{
- RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
- RRScreenSizeNotify (pScreen);
+ RRScreenSize size;
+ RRScreenRate rate;
+
+ if (!mode)
+ {
+ RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
+ ret = TRUE;
+ }
+ else
+ {
+ size.width = mode->mode.width;
+ size.height = mode->mode.height;
+ if (outputs[0]->mmWidth && outputs[0]->mmHeight)
+ {
+ size.mmWidth = outputs[0]->mmWidth;
+ size.mmHeight = outputs[0]->mmHeight;
+ }
+ else
+ {
+ size.mmWidth = pScreen->mmWidth;
+ size.mmHeight = pScreen->mmHeight;
+ }
+ size.nRates = 1;
+ rate.rate = RRVerticalRefresh (&mode->mode);
+ size.pRates = &rate;
+ ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
+ /*
+ * Old 1.0 interface tied screen size to mode size
+ */
+ if (ret)
+ {
+ RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
+ RRScreenSizeNotify (pScreen);
+ }
+ }
}
- return ret;
- }
#endif
- RRTellChanged (pScreen);
+ }
+ if (ret)
+ RRTellChanged (pScreen);
}
- return FALSE;
+ return ret;
}
/*
@@ -716,6 +721,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
goto sendReply;
}
+#if 0
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
@@ -726,6 +732,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
rep.status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
+#endif
/*
* Validate requested rotation
commit 492c768065f49306a2194a88edf96b85de0ff4ff
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Fri Mar 23 00:59:11 2007 -0700
Clean up xf86CrtcRec and xf86OutputRec objects at CloseScreen.
Erase pointers to structures which are freed at server reset time.
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index a875cdf..fad0752 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -573,11 +573,25 @@ xf86CrtcCloseScreen (int index, ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o, c;
screen->CloseScreen = config->CloseScreen;
xf86RotateCloseScreen (screen);
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ output->crtc = NULL;
+ output->randr_output = NULL;
+ }
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ crtc->randr_crtc = NULL;
+ }
return screen->CloseScreen (index, screen);
}
commit 16f4c0c1750824f2e5a001cef82a4122a7a2beb0
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Fri Mar 23 00:57:18 2007 -0700
Clear allocated RandR screen private structure.
Use xcalloc instead of xalloc when allocating this structure to ensure
consistent contents at startup.
diff --git a/randr/randr.c b/randr/randr.c
index 5fa9baf..4dd0ee5 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -230,7 +230,7 @@ Bool RRScreenInit(ScreenPtr pScreen)
RRScreenGeneration = serverGeneration;
}
- pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
+ pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec));
if (!pScrPriv)
return FALSE;
commit f8db7665dcd7af78ca4db2461e0bf787ec662cb1
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Tue Mar 20 07:17:27 2007 -0700
Clean up Rotate state on server reset.
The rotation state is stored in the xf86_config structure which is not
re-initialized at server reset time. Clean it up at CloseScreen time.
diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c
index f468b1f..3103976 100644
--- a/hw/xfree86/loader/xf86sym.c
+++ b/hw/xfree86/loader/xf86sym.c
@@ -1180,6 +1180,7 @@ _X_HIDDEN void *xfree86LookupTab[] = {
SYMVAR(pciNumBuses)
/* modes */
+ SYMVAR(xf86CrtcConfigPrivateIndex)
SYMFUNC(xf86CrtcConfigInit)
SYMFUNC(xf86CrtcConfigPrivateIndex)
SYMFUNC(xf86CrtcCreate)
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 1a42920..a875cdf 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -566,6 +566,22 @@ xf86CrtcCreateScreenResources (ScreenPtr screen)
}
/*
+ * Clean up config on server reset
+ */
+static Bool
+xf86CrtcCloseScreen (int index, ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ screen->CloseScreen = config->CloseScreen;
+
+ xf86RotateCloseScreen (screen);
+
+ return screen->CloseScreen (index, screen);
+}
+
+/*
* Called at ScreenInit time to set up
*/
Bool
@@ -596,6 +612,10 @@ xf86CrtcScreenInit (ScreenPtr screen)
/* Wrap CreateScreenResources so we can initialize the RandR code */
config->CreateScreenResources = screen->CreateScreenResources;
screen->CreateScreenResources = xf86CrtcCreateScreenResources;
+
+ config->CloseScreen = screen->CloseScreen;
+ screen->CloseScreen = xf86CrtcCloseScreen;
+
return TRUE;
}
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index b751592..42daf60 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -544,6 +544,8 @@ typedef struct _xf86CrtcConfig {
CreateScreenResourcesProcPtr CreateScreenResources;
+ CloseScreenProcPtr CloseScreen;
+
/* Cursor information */
xf86CursorInfoPtr cursor_info;
CursorPtr cursor;
@@ -593,6 +595,12 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
Bool
xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
+/*
+ * Clean up rotation during CloseScreen
+ */
+void
+xf86RotateCloseScreen (ScreenPtr pScreen);
+
/**
* Return whether any output is assigned to the crtc
*/
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index e82b69e..e8fafd0 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -321,36 +321,68 @@ xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
{
}
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+static void
+xf86RotateDestroy (xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
ScreenPtr pScreen = pScrn->pScreen;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
- if (rotation == RR_Rotate_0)
+ /* Free memory from rotation */
+ if (crtc->rotatedPixmap || crtc->rotatedData)
{
- /* Free memory from rotation */
+ crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
if (crtc->rotatedPixmap || crtc->rotatedData)
- {
- crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
+ return;
- if (xf86_config->rotation_damage)
+ /*
+ * Clean up damage structures when no crtcs are rotated
+ */
+ if (xf86_config->rotation_damage)
+ {
+ /* Free damage structure */
+ if (xf86_config->rotation_damage_registered)
{
- /* Free damage structure */
DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
xf86_config->rotation_damage);
xf86_config->rotation_damage_registered = FALSE;
- DamageDestroy (xf86_config->rotation_damage);
- xf86_config->rotation_damage = NULL;
- /* Free block/wakeup handler */
- RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
- xf86RotateWakeupHandler,
- (pointer) pScreen);
}
+ DamageDestroy (xf86_config->rotation_damage);
+ xf86_config->rotation_damage = NULL;
+ /* Free block/wakeup handler */
+ RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
+ xf86RotateWakeupHandler,
+ (pointer) pScreen);
+ }
+}
+
+void
+xf86RotateCloseScreen (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ xf86RotateDestroy (xf86_config->crtc[c]);
+}
+
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+
+ if (rotation == RR_Rotate_0)
+ {
+ xf86RotateDestroy (crtc);
}
else
{
commit 0f80340a526b2838b9f39145f29941222e84184b
Author: Keith Packard <keithp@neko.keithp.com>
Date: Sat Mar 17 20:14:05 2007 -0700
Slow down DDC I2C bus using a RiseFallTime of 20us for old monitors.
This time value makes the bus run slowly enough for even the least reliable
of monitors. Thanks to Pavel Troller for finding the necessary change.
diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c
index 0f24c52..8080c8d 100644
--- a/hw/xfree86/ddc/xf86DDC.c
+++ b/hw/xfree86/ddc/xf86DDC.c
@@ -337,6 +337,12 @@ DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len)
unsigned char *R_Buffer;
int i;
+ /*
+ * Slow down the bus so that older monitors don't
+ * miss things.
+ */
+ pBus->RiseFallTime = 20;
+
if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) {
dev = xf86CreateI2CDevRec();
dev->DevName = "ddc2";
commit 52fccb9d9fdbb1c9dc3f5225600004cd94e42a4a
Author: Keith Packard <keithp@neko.keithp.com>
Date: Sat Mar 17 17:26:11 2007 -0700
Remove extra (and wrong) I2C ByteTimeout setting in DDC code.
The DDC code sets the I2C timeouts to VESA standards, except that it had an
extra setting of the ByteTimeout value which was wrong (off by a factor of
50). Removing this should help DDC work on many more monitors. Note that the
Intel driver duplicated these settings, along with the error. Yay for cult
and paste coding.
diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c
index 4ce585c..0f24c52 100644
--- a/hw/xfree86/ddc/xf86DDC.c
+++ b/hw/xfree86/ddc/xf86DDC.c
@@ -344,7 +344,6 @@ DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len)
dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
dev->StartTimeout = 550;
dev->BitTimeout = 40;
- dev->ByteTimeout = 40;
dev->AcknTimeout = 40;
dev->pI2CBus = pBus;
commit f521308ad2c06afa00143d3ab407e18d5293d497
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Thu Mar 15 20:26:07 2007 -0700
Correct ref counting of RRMode structures
RRModes are referenced by the resource db, RROutput and RRCrtc structures.
Ensure that the mode reference count is decremented each time a reference is
lost from one of these sources. The missing destroys were in
RRCrtcDestroyResource and RROutputDestroyResource, which only happen at
server reset time, so modes would be unavailable in subsequent server
generations.
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 43a6fca..1b3c230 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -370,6 +370,8 @@ RRCrtcDestroyResource (pointer value, XID pid)
}
if (crtc->gammaRed)
xfree (crtc->gammaRed);
+ if (crtc->mode)
+ RRModeDestroy (crtc->mode);
xfree (crtc);
return 1;
}
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 31ec924..09f2afd 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -406,9 +406,12 @@ RROutputDestroyResource (pointer value, XID pid)
}
}
}
- /* XXX destroy all modes? */
if (output->modes)
+ {
+ for (m = 0; m < output->numModes; m++)
+ RRModeDestroy (output->modes[m]);
xfree (output->modes);
+ }
for (m = 0; m < output->numUserModes; m++)
RRModeDestroy (output->userModes[m]);
commit b14f003b0ed1252766c9e3b1c086ea2809521047
Author: Keith Packard <keithp@neko.keithp.com>
Date: Thu Mar 15 16:16:16 2007 -0700
Don't wedge when rotating more than one CRTC.
Rotation block handler was re-registering the rotation damage structure,
creating an infinite loop in the damage code. Track registration of the
damage structure to avoid this.
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index df8a8aa..b751592 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -529,7 +529,8 @@ typedef struct _xf86CrtcConfig {
int maxWidth, maxHeight;
/* For crtc-based rotation */
- DamagePtr rotationDamage;
+ DamagePtr rotation_damage;
+ Bool rotation_damage_registered;
/* DGA */
unsigned int dga_flags;
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 6826b62..e82b69e 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -251,9 +251,13 @@ xf86RotatePrepare (ScreenPtr pScreen)
crtc->rotatedData,
crtc->mode.HDisplay,
crtc->mode.VDisplay);
- /* Hook damage to screen pixmap */
- DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotationDamage);
+ if (!xf86_config->rotation_damage_registered)
+ {
+ /* Hook damage to screen pixmap */
+ DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ xf86_config->rotation_damage);
+ xf86_config->rotation_damage_registered = TRUE;
+ }
xf86CrtcDamageShadow (crtc);
}
@@ -265,7 +269,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- DamagePtr damage = xf86_config->rotationDamage;
+ DamagePtr damage = xf86_config->rotation_damage;
RegionPtr region;
if (!damage)
@@ -334,13 +338,14 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
crtc->rotatedData = NULL;
}
- if (xf86_config->rotationDamage)
+ if (xf86_config->rotation_damage)
{
/* Free damage structure */
DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotationDamage);
- DamageDestroy (xf86_config->rotationDamage);
- xf86_config->rotationDamage = NULL;
+ xf86_config->rotation_damage);
+ xf86_config->rotation_damage_registered = FALSE;
+ DamageDestroy (xf86_config->rotation_damage);
+ xf86_config->rotation_damage = NULL;
/* Free block/wakeup handler */
RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
xf86RotateWakeupHandler,
@@ -382,13 +387,13 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
xf86CrtcDamageShadow (crtc);
}
- if (!xf86_config->rotationDamage)
+ if (!xf86_config->rotation_damage)
{
/* Create damage structure */
- xf86_config->rotationDamage = DamageCreate (NULL, NULL,
+ xf86_config->rotation_damage = DamageCreate (NULL, NULL,
DamageReportNone,
TRUE, pScreen, pScreen);
- if (!xf86_config->rotationDamage)
+ if (!xf86_config->rotation_damage)
goto bail2;
/* Assign block/wakeup handler */
@@ -402,8 +407,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
if (0)
{
bail3:
- DamageDestroy (xf86_config->rotationDamage);
- xf86_config->rotationDamage = NULL;
+ DamageDestroy (xf86_config->rotation_damage);
+ xf86_config->rotation_damage = NULL;
bail2:
if (shadow || shadowData)
commit 5b77bf2d020b1ee56c1c5f2db089a8f7f64a76a6
Author: Keith Packard <keithp@neko.keithp.com>
Date: Thu Mar 15 10:50:45 2007 -0700
Allow xf86_reload_cursors during server init.
xf86_reload_cursors is supposed to be called from the crtc mode setting
commit hook; as that happens during server initialization, check for this
case.
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 095df48..009cccf 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -548,12 +548,24 @@ xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
void
xf86_reload_cursors (ScreenPtr screen)
{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
- CursorPtr cursor = xf86_config->cursor;
+ ScrnInfoPtr scrn;
+ xf86CrtcConfigPtr xf86_config;
+ xf86CursorInfoPtr cursor_info;
+ CursorPtr cursor;
int x, y;
+ /* initial mode setting will not have set a screen yet */
+ if (!screen)
+ return;
+ scrn = xf86Screens[screen->myNum];
+ xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ /* make sure the cursor code has been initialized */
+ cursor_info = xf86_config->cursor_info;
+ if (!cursor_info)
+ return;
+
+ cursor = xf86_config->cursor;
GetSpritePosition (&x, &y);
if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
(*cursor_info->HideCursor)(scrn);
commit 4d81c99a4660a0bf9014f789de55edabd185bd14
Author: Keith Packard <keithp@guitar.keithp.com>
Date: Wed Mar 14 23:59:29 2007 -0700
Create driver-independent CRTC-based cursor layer.
This moves most of the cursor management code out of the intel driver and
into the general server code. Of course, the hope is that this code will be
useful for other driver writers as well.
Check out xf86Crtc.h for the usage information, making sure you add the
needed hooks to the crtc funcs structure for your driver.
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 35f1aa9..0701cf5 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -48,6 +48,7 @@ XORG_LIBS = \
parser/libxf86config.a \
dixmods/libdixmods.la \
modes/libxf86modes.a \
+ ramdac/libramdac.a \
ddc/libddc.a \
i2c/libi2c.a \
@XORG_LIBS@
diff --git a/hw/xfree86/loader/Makefile.am b/hw/xfree86/loader/Makefile.am
index 0a89d08..61bcb22 100644
--- a/hw/xfree86/loader/Makefile.am
+++ b/hw/xfree86/loader/Makefile.am
@@ -2,7 +2,8 @@ noinst_LIBRARIES = libloader.a
INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(srcdir)/../dixmods/extmod \
-I$(srcdir)/../vbe -I$(top_srcdir)/miext/cw -I$(srcdir)/../int10 \
- -I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes
+ -I$(srcdir)/../ddc -I$(srcdir)/../i2c -I$(srcdir)/../modes \
+ -I$(srcdir)/../ramdac
#AM_LDFLAGS = -r
AM_CFLAGS = -DIN_LOADER $(XORG_CFLAGS)
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index e489212..c220d8a 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -841,6 +841,7 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
static const char *compiled_in_modules[] = {
"ddc",
"i2c",
+ "ramdac",
NULL
};
@@ -861,7 +862,7 @@ doLoadModule(const char *module, const char *path, const char **subdirlist,
PatternPtr patterns = NULL;
int noncanonical = 0;
char *m = NULL;
- char **cim;
+ const char **cim;
xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c
index 2f1f6af..f468b1f 100644
--- a/hw/xfree86/loader/xf86sym.c
+++ b/hw/xfree86/loader/xf86sym.c
@@ -1230,6 +1230,11 @@ _X_HIDDEN void *xfree86LookupTab[] = {
SYMFUNC(xf86RandR12SetConfig)
SYMFUNC(xf86RandR12SetRotations)
#endif
+ SYMFUNC(xf86_cursors_init)
+ SYMFUNC(xf86_reload_cursors)
+ SYMFUNC(xf86_show_cursors)
+ SYMFUNC(xf86_hide_cursors)
+ SYMFUNC(xf86_cursors_fini)
SYMFUNC(xf86DoEDID_DDC1)
SYMFUNC(xf86DoEDID_DDC2)
diff --git a/hw/xfree86/modes/Makefile.am b/hw/xfree86/modes/Makefile.am
index 60d2553..0841a6d 100644
--- a/hw/xfree86/modes/Makefile.am
+++ b/hw/xfree86/modes/Makefile.am
@@ -3,6 +3,7 @@ noinst_LIBRARIES = libxf86modes.a
libxf86modes_a_SOURCES = \
xf86Crtc.c \
xf86Crtc.h \
+ xf86Cursors.c \
xf86cvt.c \
xf86DiDGA.c \
xf86EdidModes.c \
@@ -16,7 +17,8 @@ libxf86modes_a_SOURCES = \
INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
-I$(srcdir)/../loader -I$(srcdir)/../rac -I$(srcdir)/../parser \
-I$(srcdir)/../scanpci -I$(srcdir)/../vbe -I$(srcdir)/../int10 \
- -I$(srcdir)/../vgahw -I$(srcdir)/../dixmods/extmod
+ -I$(srcdir)/../vgahw -I$(srcdir)/../ramdac \
+ -I$(srcdir)/../dixmods/extmod
sdk_HEADERS = \
xf86Crtc.h \
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 6152ae4..df8a8aa 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -28,6 +28,7 @@
#include "xf86Rename.h"
#endif
#include "xf86Modes.h"
+#include "xf86Cursor.h"
#include "damage.h"
/* Compat definitions for older X Servers. */
@@ -37,6 +38,9 @@
#ifndef M_T_DRIVER
#define M_T_DRIVER 0x40
#endif
+#ifndef HARDWARE_CURSOR_ARGB
+#define HARDWARE_CURSOR_ARGB 0x00004000
+#endif
typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
@@ -155,6 +159,42 @@ typedef struct _xf86CrtcFuncs {
(*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data);
/**
+ * Set cursor colors
+ */
+ void
+ (*set_cursor_colors) (xf86CrtcPtr crtc, int bg, int fg);
+
+ /**
+ * Set cursor position
+ */
+ void
+ (*set_cursor_position) (xf86CrtcPtr crtc, int x, int y);
+
+ /**
+ * Show cursor
+ */
+ void
+ (*show_cursor) (xf86CrtcPtr crtc);
+
+ /**
+ * Hide cursor
+ */
+ void
+ (*hide_cursor) (xf86CrtcPtr crtc);
+
+ /**
+ * Load monochrome image
+ */
+ void
+ (*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image);
+
+ /**
+ * Load ARGB image
+ */
+ void
+ (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image);
+
+ /**
* Clean up driver-specific bits of the crtc
*/
void
@@ -174,12 +214,6 @@ struct _xf86Crtc {
*/
Bool enabled;
- /** Track whether cursor is within CRTC range */
- Bool cursorInRange;
-
- /** Track state of cursor associated with this CRTC */
- Bool cursorShown;
-
/**
* Active mode
*
@@ -232,6 +266,19 @@ struct _xf86Crtc {
#else
void *randr_crtc;
#endif
+
+ /**
+ * Current cursor is ARGB
+ */
+ Bool cursor_argb;
+ /**
+ * Track whether cursor is within CRTC range
+ */
+ Bool cursor_in_range;
+ /**
+ * Track state of cursor associated with this CRTC
+ */
+ Bool cursor_shown;
};
typedef struct _xf86OutputFuncs {
@@ -495,6 +542,13 @@ typedef struct _xf86CrtcConfig {
const xf86CrtcConfigFuncsRec *funcs;
CreateScreenResourcesProcPtr CreateScreenResources;
+
+ /* Cursor information */
+ xf86CursorInfoPtr cursor_info;
+ CursorPtr cursor;
+ CARD8 *cursor_image;
+ Bool cursor_on;
+ CARD32 cursor_fg, cursor_bg;
} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
extern int xf86CrtcConfigPrivateIndex;
@@ -637,4 +691,41 @@ xf86ConnectorGetName(xf86ConnectorType connector);
Bool
xf86SetDesiredModes (ScrnInfoPtr pScrn);
+/**
+ * Initialize the CRTC-based cursor code. CRTC function vectors must
+ * contain relevant cursor setting functions.
+ *
+ * Driver should call this from ScreenInit function
+ */
+Bool
+xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags);
+
+/**
+ * Called when anything on the screen is reconfigured.
+ *
+ * Reloads cursor images as needed, then adjusts cursor positions.
+ *
+ * Driver should call this from crtc commit function.
+ */
+void
+xf86_reload_cursors (ScreenPtr screen);
+
+/**
+ * Called from EnterVT to turn the cursors back on
+ */
+void
+xf86_show_cursors (ScrnInfoPtr scrn);
+
+/**
+ * Called by the driver to turn cursors off
+ */
+void
+xf86_hide_cursors (ScrnInfoPtr scrn);
+
+/**
+ * Clean up CRTC-based cursor code. Driver must call this at CloseScreen time.
+ */
+void
+xf86_cursors_fini (ScreenPtr screen);
+
#endif /* _XF86CRTC_H_ */
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
new file mode 100644
index 0000000..095df48
--- /dev/null
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * 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>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86RandR12.h"
+#include "X11/extensions/render.h"
+#define DPMS_SERVER
+#include "X11/extensions/dpms.h"
+#include "X11/Xatom.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+#include "cursorstr.h"
+
+/*
+ * Given a screen coordinate, rotate back to a cursor source coordinate
+ */
+static void
+xf86_crtc_rotate_coord (Rotation rotation,
+ int width,
+ int height,
+ int x_dst,
+ int y_dst,
+ int *x_src,
+ int *y_src)
+{
+ if (rotation & RR_Reflect_X)
+ x_dst = width - x_dst - 1;
+ if (rotation & RR_Reflect_Y)
+ y_dst = height - y_dst - 1;
+
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ *x_src = x_dst;
+ *y_src = y_dst;
+ break;
+ case RR_Rotate_90:
+ *x_src = height - y_dst - 1;
+ *y_src = x_dst;
+ break;
+ case RR_Rotate_180:
+ *x_src = width - x_dst - 1;
+ *y_src = height - y_dst - 1;
+ break;
+ case RR_Rotate_270:
+ *x_src = y_dst;
+ *y_src = width - x_dst - 1;
+ break;
+ }
+}
+
+/*
+ * Convert an x coordinate to a position within the cursor bitmap
+ */
+static int
+cursor_bitpos (int flags, int x, Bool mask)
+{
+ if (flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)
+ mask = !mask;
+ if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED)
+ x = (x & ~3) | (3 - (x & 3));
+ if (flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST)
+ x = (x & ~7) | (7 - (x & 7));
+ if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1)
+ x = (x << 1) + mask;
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8)
+ x = ((x & ~7) << 1) | (mask << 3) | (x & 7);
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16)
+ x = ((x & ~15) << 1) | (mask << 4) | (x & 15);
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32)
+ x = ((x & ~31) << 1) | (mask << 5) | (x & 31);
+ else if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64)
+ x = ((x & ~63) << 1) | (mask << 6) | (x & 63);
+ return x;
+}
+
+/*
+ * Fetch one bit from a cursor bitmap
+ */
+static CARD8
+get_bit (CARD8 *image, int stride, int flags, int x, int y, Bool mask)
+{
+ x = cursor_bitpos (flags, x, mask);
+ image += y * stride;
+ return (image[(x >> 3)] >> (x & 7)) & 1;
+}
+
+/*
+ * Set one bit in a cursor bitmap
+ */
+static void
+set_bit (CARD8 *image, int stride, int flags, int x, int y, Bool mask)
+{
+ x = cursor_bitpos (flags, x, mask);
+ image += y * stride;
+ image[(x >> 3)] |= 1 << (x & 7);
+}
+
+/*
+ * Load a two color cursor into a driver that supports only ARGB cursors
+ */
+static void
+xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
+ int x, y;
+ int xin, yin;
+ int stride = cursor_info->MaxWidth >> 2;
+ int flags = cursor_info->Flags;
+ CARD32 bits;
+
+#ifdef ARGB_CURSOR
+ crtc->cursor_argb = FALSE;
+#endif
+
+ for (y = 0; y < cursor_info->MaxHeight; y++)
+ for (x = 0; x < cursor_info->MaxWidth; x++)
+ {
+ xf86_crtc_rotate_coord (crtc->rotation,
+ cursor_info->MaxWidth,
+ cursor_info->MaxHeight,
+ x, y, &xin, &yin);
+ if (get_bit (src, stride, flags, xin, yin, TRUE) ==
+ ((flags & HARDWARE_CURSOR_INVERT_MASK) == 0))
+ {
+ if (get_bit (src, stride, flags, xin, yin, FALSE))
+ bits = xf86_config->cursor_fg;
+ else
+ bits = xf86_config->cursor_bg;
+ }
+ else
+ bits = 0;
+ cursor_image[y * cursor_info->MaxWidth + x] = bits;
+ }
+ crtc->funcs->load_cursor_argb (crtc, cursor_image);
+}
+
+/*
+ * Set the colors for a two-color cursor (ignore for ARGB cursors)
+ */
+static void
+xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg)
+{
+ ScreenPtr screen = scrn->pScreen;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ CursorPtr cursor = xf86_config->cursor;
+ int c;
+ CARD8 *bits = cursor ? cursor->devPriv[screen->myNum] : NULL;
+
+ /* Save ARGB versions of these colors */
+ xf86_config->cursor_fg = (CARD32) fg | 0xff000000;
+ xf86_config->cursor_bg = (CARD32) bg | 0xff000000;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled && !crtc->cursor_argb)
+ {
+ if (crtc->funcs->load_cursor_image)
+ crtc->funcs->set_cursor_colors (crtc, bg, fg);
+ else if (bits)
+ xf86_crtc_convert_cursor_to_argb (crtc, bits);
+ }
+ }
+}
+
+static void
+xf86_crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+ if (crtc->cursor_shown)
+ {
+ crtc->funcs->hide_cursor (crtc);
+ crtc->cursor_shown = FALSE;
+ }
+}
+
+void
+xf86_hide_cursors (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ xf86_config->cursor_on = FALSE;
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_hide_cursor (crtc);
+ }
+}
+
+static void
+xf86_crtc_show_cursor (xf86CrtcPtr crtc)
+{
+ if (!crtc->cursor_shown && crtc->cursor_in_range)
+ {
+ crtc->funcs->show_cursor (crtc);
+ crtc->cursor_shown = TRUE;
+ }
+}
+
+void
+xf86_show_cursors (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ xf86_config->cursor_on = TRUE;
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_show_cursor (crtc);
+ }
+}
+
+static void
+xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ DisplayModePtr mode = &crtc->mode;
+ int x_temp;
+ int y_temp;
+ Bool in_range;
+
+ /*
+ * Move to crtc coordinate space
+ */
+ x -= crtc->x;
+ y -= crtc->y;
+
+ /*
+ * Rotate
+ */
+ switch ((crtc->rotation) & 0xf) {
+ case RR_Rotate_0:
+ break;
+ case RR_Rotate_90:
+ x_temp = y;
+ y_temp = mode->VDisplay - cursor_info->MaxWidth - x;
+ x = x_temp;
+ y = y_temp;
+ break;
+ case RR_Rotate_180:
+ x_temp = mode->HDisplay - cursor_info->MaxWidth - x;
+ y_temp = mode->VDisplay - cursor_info->MaxHeight - y;
+ x = x_temp;
+ y = y_temp;
+ break;
+ case RR_Rotate_270:
+ x_temp = mode->HDisplay - cursor_info->MaxHeight - y;
+ y_temp = x;
+ x = x_temp;
+ y = y_temp;
+ break;
+ }
+
+ /*
+ * Reflect
+ */
+ if (crtc->rotation & RR_Reflect_X)
+ x = mode->HDisplay - cursor_info->MaxWidth - x;
+ if (crtc->rotation & RR_Reflect_Y)
+ y = mode->VDisplay - cursor_info->MaxHeight - y;
+
+ /*
+ * Disable the cursor when it is outside the viewport
+ */
+ in_range = TRUE;
+ if (x >= mode->HDisplay || y >= mode->VDisplay ||
+ x <= -cursor_info->MaxWidth || y <= -cursor_info->MaxHeight)
+ {
+ in_range = FALSE;
+ x = 0;
+ y = 0;
+ }
+
+ crtc->cursor_in_range = in_range;
+
+ if (in_range)
+ {
+ crtc->funcs->set_cursor_position (crtc, x, y);
+ xf86_crtc_show_cursor (crtc);
+ }
+ else
+ xf86_crtc_hide_cursor (crtc);
+}
+
+static void
+xf86_set_cursor_position (ScrnInfoPtr scrn, int x, int y)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ /* undo what xf86HWCurs did to the coordinates */
+ x += scrn->frameX0;
+ y += scrn->frameY0;
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_set_cursor_position (crtc, x, y);
+ }
+}
+
+/*
+ * Load a two-color cursor into a crtc, performing rotation as needed
+ */
+static void
+xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ CARD8 *cursor_image;
+
+#ifdef ARGB_CURSOR
+ crtc->cursor_argb = FALSE;
+#endif
+
+ if (crtc->rotation == RR_Rotate_0)
+ cursor_image = src;
+ else
+ {
+ int x, y;
+ int xin, yin;
+ int stride = cursor_info->MaxWidth >> 2;
+ int flags = cursor_info->Flags;
+
+ cursor_image = xf86_config->cursor_image;
+ memset(cursor_image, 0, cursor_info->MaxWidth * stride);
+
+ for (y = 0; y < cursor_info->MaxHeight; y++)
+ for (x = 0; x < cursor_info->MaxWidth; x++)
+ {
+ xf86_crtc_rotate_coord (crtc->rotation,
+ cursor_info->MaxWidth,
+ cursor_info->MaxHeight,
+ x, y, &xin, &yin);
+ if (get_bit(src, stride, flags, xin, yin, FALSE))
+ set_bit(cursor_image, stride, flags, x, y, FALSE);
+ if (get_bit(src, stride, flags, xin, yin, TRUE))
+ set_bit(cursor_image, stride, flags, x, y, TRUE);
+ }
+ }
+ crtc->funcs->load_cursor_image (crtc, cursor_image);
+}
+
+/*
+ * Load a cursor image into all active CRTCs
+ */
+static void
+xf86_load_cursor_image (ScrnInfoPtr scrn, unsigned char *src)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ {
+ if (crtc->funcs->load_cursor_image)
+ xf86_crtc_load_cursor_image (crtc, src);
+ else if (crtc->funcs->load_cursor_argb)
+ xf86_crtc_convert_cursor_to_argb (crtc, src);
+ }
+ }
+}
+
+static Bool
+xf86_use_hw_cursor (ScreenPtr screen, CursorPtr cursor)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+
+ xf86_config->cursor = cursor;
+
+ if (cursor->bits->width > cursor_info->MaxWidth ||
+ cursor->bits->height> cursor_info->MaxHeight)
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+xf86_use_hw_cursor_argb (ScreenPtr screen, CursorPtr cursor)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+
+ xf86_config->cursor = cursor;
+
+ /* Make sure ARGB support is available */
+ if ((cursor_info->Flags & HARDWARE_CURSOR_ARGB) == 0)
+ return FALSE;
+
+ if (cursor->bits->width > cursor_info->MaxWidth ||
+ cursor->bits->height> cursor_info->MaxHeight)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ CARD32 *cursor_image = (CARD32 *) xf86_config->cursor_image;
+ CARD32 *cursor_source = (CARD32 *) cursor->bits->argb;
+ int x, y;
+ int xin, yin;
+ CARD32 bits;
+ int source_width = cursor->bits->width;
+ int source_height = cursor->bits->height;
+ int image_width = cursor_info->MaxWidth;
+ int image_height = cursor_info->MaxHeight;
+
+ for (y = 0; y < image_height; y++)
+ for (x = 0; x < image_width; x++)
+ {
+ xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
+ x, y, &xin, &yin);
+ if (xin < source_width && yin < source_height)
+ bits = cursor_source[yin * source_width + xin];
+ else
+ bits = 0;
+ cursor_image[y * image_width + x] = bits;
+ }
+
+ crtc->funcs->load_cursor_argb (crtc, cursor_image);
+}
+
+static void
+xf86_load_cursor_argb (ScrnInfoPtr scrn, CursorPtr cursor)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->enabled)
+ xf86_crtc_load_cursor_argb (crtc, cursor);
+ }
+}
+
+Bool
+xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info;
+
+ cursor_info = xf86CreateCursorInfoRec();
+ if (!cursor_info)
+ return FALSE;
+
+ xf86_config->cursor_image = xalloc (max_width * max_height * 4);
+
+ if (!xf86_config->cursor_image)
+ {
+ xf86DestroyCursorInfoRec (cursor_info);
+ return FALSE;
+ }
+
+ xf86_config->cursor_info = cursor_info;
+
+ cursor_info->MaxWidth = max_width;
+ cursor_info->MaxHeight = max_height;
+ cursor_info->Flags = flags;
+
+ cursor_info->SetCursorColors = xf86_set_cursor_colors;
+ cursor_info->SetCursorPosition = xf86_set_cursor_position;
+ cursor_info->LoadCursorImage = xf86_load_cursor_image;
+ cursor_info->HideCursor = xf86_hide_cursors;
+ cursor_info->ShowCursor = xf86_show_cursors;
+ cursor_info->UseHWCursor = xf86_use_hw_cursor;
+#ifdef ARGB_CURSOR
+ if (flags & HARDWARE_CURSOR_ARGB)
+ {
+ cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
+ cursor_info->LoadCursorARGB = xf86_load_cursor_argb;
+ }
+#endif
+
+ xf86_config->cursor = NULL;
+ xf86_hide_cursors (scrn);
+
+ return xf86InitCursor (screen, cursor_info);
+}
+
+/**
+ * Called when anything on the screen is reconfigured.
+ *
+ * Reloads cursor images as needed, then adjusts cursor positions
+ */
+
+void
+xf86_reload_cursors (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+ CursorPtr cursor = xf86_config->cursor;
+ int x, y;
+
+ GetSpritePosition (&x, &y);
+ if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
+ (*cursor_info->HideCursor)(scrn);
+
+ if (cursor)
+ {
+#ifdef ARGB_CURSOR
+ if (cursor->bits->argb && cursor_info->LoadCursorARGB)
+ (*cursor_info->LoadCursorARGB) (scrn, cursor);
+ else
+#endif
+ (*cursor_info->LoadCursorImage)(cursor_info->pScrn,
+ cursor->devPriv[screen->myNum]);
+
+ (*cursor_info->SetCursorPosition)(cursor_info->pScrn, x, y);
+ (*cursor_info->ShowCursor)(cursor_info->pScrn);
+ }
+}
+
+/**
+ * Clean up CRTC-based cursor code
+ */
+void
+xf86_cursors_fini (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ if (xf86_config->cursor_info)
+ {
+ xf86DestroyCursorInfoRec (xf86_config->cursor_info);
+ xf86_config->cursor_info = NULL;
+ }
+ if (xf86_config->cursor_image)
+ {
+ xfree (xf86_config->cursor_image);
+ xf86_config->cursor_image = NULL;
+ }
+}
diff --git a/hw/xfree86/ramdac/Makefile.am b/hw/xfree86/ramdac/Makefile.am
index c9afdad..6725ed3 100644
--- a/hw/xfree86/ramdac/Makefile.am
+++ b/hw/xfree86/ramdac/Makefile.am
@@ -1,8 +1,6 @@
-module_LTLIBRARIES = libramdac.la
+noinst_LIBRARIES = libramdac.a
-libramdac_la_LDFLAGS = -avoid-version
-
-libramdac_la_SOURCES = xf86RamDacMod.c xf86RamDac.c xf86RamDacCmap.c \
+libramdac_a_SOURCES = xf86RamDac.c xf86RamDacCmap.c \
xf86Cursor.c xf86HWCurs.c IBM.c BT.c TI.c \
xf86BitOrder.c
diff --git a/hw/xfree86/ramdac/xf86Cursor.h b/hw/xfree86/ramdac/xf86Cursor.h
index 08cca6b..469f48f 100644
--- a/hw/xfree86/ramdac/xf86Cursor.h
+++ b/hw/xfree86/ramdac/xf86Cursor.h
@@ -44,5 +44,8 @@ void xf86ForceHWCursor (ScreenPtr pScreen, Bool on);
#define HARDWARE_CURSOR_NIBBLE_SWAPPED 0x00000800
#define HARDWARE_CURSOR_SHOW_TRANSPARENT 0x00001000
#define HARDWARE_CURSOR_UPDATE_UNHIDDEN 0x00002000
+#ifdef ARGB_CURSOR
+#define HARDWARE_CURSOR_ARGB 0x00004000
+#endif
#endif /* _XF86CURSOR_H */
Reply to: