Drivers that care about crtc positions on the screen to ensure that vblank
works correctly need to be notified when crtcs are changed.

Provide a hook in the mode setting code that is invoked whenever any
configuration is done to the screen.

Use this new hook in the DRI code so that DRI clients are notified and
receive updated information.

Signed-off-by: Keith Packard <[EMAIL PROTECTED]>
---
 hw/xfree86/dri/Makefile.am  |    5 +++++
 hw/xfree86/dri/dri.c        |   19 +++++++++++++++++++
 hw/xfree86/dri/dristruct.h  |    2 ++
 hw/xfree86/loader/xf86sym.c |    3 +++
 hw/xfree86/modes/xf86Crtc.c |   33 +++++++++++++++++++++++++++++++++
 hw/xfree86/modes/xf86Crtc.h |   14 ++++++++++++++
 6 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/dri/Makefile.am b/hw/xfree86/dri/Makefile.am
index e17cea7..3ec30be 100644
--- a/hw/xfree86/dri/Makefile.am
+++ b/hw/xfree86/dri/Makefile.am
@@ -1,6 +1,11 @@
 libdri_la_LTLIBRARIES = libdri.la
 libdri_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \
                    -I$(top_srcdir)/hw/xfree86/os-support \
+                   -I$(top_srcdir)/hw/xfree86/modes \
+                   -I$(top_srcdir)/hw/xfree86/ddc \
+                   -I$(top_srcdir)/hw/xfree86/i2c \
+                   -I$(top_srcdir)/hw/xfree86/parser \
+                   -I$(top_srcdir)/hw/xfree86/ramdac \
                    -I$(top_srcdir)/hw/xfree86/os-support/bus \
                    -I$(top_srcdir)/glx \
                    -I$(top_srcdir)/GL/include \
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 3713659..1a3e091 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -302,6 +302,18 @@ DRIOpenDRMMaster(ScrnInfoPtr pScrn,
     return FALSE;
 }
 
+static void
+DRIClipNotifyAllDrawables(ScreenPtr pScreen);
+
+static void
+dri_crtc_notify(ScreenPtr pScreen)
+{
+    DRIScreenPrivPtr  pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+    DRIClipNotifyAllDrawables(pScreen);
+    xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+    xf86_crtc_notify(pScreen);
+    pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen, 
dri_crtc_notify);
+}
 
 Bool
 DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
@@ -605,6 +617,9 @@ DRIFinishScreenInit(ScreenPtr pScreen)
     pDRIPriv->DestroyWindow             = pScreen->DestroyWindow;
     pScreen->DestroyWindow              = DRIDestroyWindow;
 
+    pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen,
+                                                      dri_crtc_notify);
+                                                      
     if (pDRIInfo->wrap.CopyWindow) {
        pDRIPriv->wrap.CopyWindow       = pScreen->CopyWindow;
        pScreen->CopyWindow             = pDRIInfo->wrap.CopyWindow;
@@ -658,6 +673,9 @@ DRICloseScreen(ScreenPtr pScreen)
                pScreen->DestroyWindow          = pDRIPriv->DestroyWindow;
                pDRIPriv->DestroyWindow         = NULL;
            }
+
+           xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+
            if (pDRIInfo->wrap.CopyWindow) {
                pScreen->CopyWindow             = pDRIPriv->wrap.CopyWindow;
                pDRIPriv->wrap.CopyWindow       = NULL;
@@ -671,6 +689,7 @@ DRICloseScreen(ScreenPtr pScreen)
                pScrn->AdjustFrame              = pDRIPriv->wrap.AdjustFrame;
                pDRIPriv->wrap.AdjustFrame      = NULL;
            }
+           
            pDRIPriv->wrapped = FALSE;
        }
 
diff --git a/hw/xfree86/dri/dristruct.h b/hw/xfree86/dri/dristruct.h
index ae970d8..fc929c2 100644
--- a/hw/xfree86/dri/dristruct.h
+++ b/hw/xfree86/dri/dristruct.h
@@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define DRI_STRUCT_H
 
 #include "xf86drm.h"
+#include "xf86Crtc.h"
 
 
 #define DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin) ((DRIDrawablePrivPtr) \
@@ -106,6 +107,7 @@ typedef struct _DRIScreenPrivRec
     XF86DRILSAREAPtr    pLSAREA;      /* Mapped pointer to SAREA containing 
lock */
     int*                pLockRefCount;
     int*                pLockingContext;
+    xf86_crtc_notify_proc_ptr  xf86_crtc_notify;
 } DRIScreenPrivRec, *DRIScreenPrivPtr;
 
 
diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c
index 4891be2..373a651 100644
--- a/hw/xfree86/loader/xf86sym.c
+++ b/hw/xfree86/loader/xf86sym.c
@@ -914,6 +914,9 @@ _X_HIDDEN void *xfree86LookupTab[] = {
     SYMFUNC(xf86_hide_cursors)
     SYMFUNC(xf86_cursors_fini)
     SYMFUNC(xf86_crtc_clip_video_helper)
+    SYMFUNC(xf86_wrap_crtc_notify)
+    SYMFUNC(xf86_unwrap_crtc_notify)
+    SYMFUNC(xf86_crtc_notify)
 
     SYMFUNC(xf86DoEDID_DDC1)
     SYMFUNC(xf86DoEDID_DDC2)
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index df47598..774e1fe 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2571,6 +2571,8 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
            memset(&crtc->mode, 0, sizeof(crtc->mode));
        }
     }
+    if (pScrn->pScreen)
+       xf86_crtc_notify(pScrn->pScreen);
 }
 
 #ifdef RANDR_12_INTERFACE
@@ -2825,3 +2827,34 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
 
     return ret;
 }
+
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
+{
+    ScrnInfoPtr                scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr  config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86_crtc_notify_proc_ptr  old;
+    
+    old = config->xf86_crtc_notify;
+    config->xf86_crtc_notify = new;
+    return old;
+}
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old)
+{
+    ScrnInfoPtr                scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr  config = XF86_CRTC_CONFIG_PTR(scrn);
+
+    config->xf86_crtc_notify = old;
+}
+
+void
+xf86_crtc_notify(ScreenPtr screen)
+{
+    ScrnInfoPtr                scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr  config = XF86_CRTC_CONFIG_PTR(scrn);
+    
+    if (config->xf86_crtc_notify)
+       config->xf86_crtc_notify(screen);
+}
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 83b1f13..ef8589e 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -569,6 +569,8 @@ typedef struct _xf86CrtcConfigFuncs {
              int               height);
 } xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
 
+typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
+
 typedef struct _xf86CrtcConfig {
     int                        num_output;
     xf86OutputPtr      *output;
@@ -621,6 +623,9 @@ typedef struct _xf86CrtcConfig {
     /* wrap screen BlockHandler for rotation */
     ScreenBlockHandlerProcPtr  BlockHandler;
 
+    /* callback when crtc configuration changes */
+    xf86_crtc_notify_proc_ptr  xf86_crtc_notify;
+
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
 extern int xf86CrtcConfigPrivateIndex;
@@ -838,4 +843,13 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
                            INT32       width,
                            INT32       height);
     
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new);
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr pScreen, xf86_crtc_notify_proc_ptr old);
+
+void
+xf86_crtc_notify(ScreenPtr pScreen);
+
 #endif /* _XF86CRTC_H_ */
-- 
1.5.6.5

_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to