[Xorg] X.org driver support for RandR rotation

Alex Deucher alexdeucher at gmail.com
Tue Jul 27 06:29:05 PDT 2004


On Tue, 27 Jul 2004 11:17:52 +0200, Egbert Eich
<eich at pdx.freedesktop.org> wrote:
> Aaron Plattner writes:
>  > Hello,
>  >
>  > Currently, there is no way for a driver to be notified of RandR events.  This
>  > patch adds ScrnInfoRec functions which a driver can hook into to register which
>  > rotations are supported and be notified when RandR events happen.  This is
>  > necessary mainly for hardware rotation support.
>  >
>  > There are a few bugs that occur when the screen is rotated 90 or 270 degrees.  A
>  > few functions compare pScreen->{width,height} to mode sizes, which is incorrect
>  > when the dimensions of the root window are swapped.  This patch changes these
>  > functions to use virtualX and virtualY, which are not swapped in rotated modes.
>  > This bug also affects drivers such as nv and fbdev that support the "Rotate"
>  > option in the config file.  (To reproduce, use nv with 'Option "Rotate" "CW"'
>  > and then try using Ctrl-Alt-+ and -).
>  >
>  > -- Aaron Plattner
>  >
> 
> Aaron,
> 
> Thank you for your patch! I would like to make a few comments:
> 
> 1. Only drivers that support rotation entirely in HW would benefit from this
> extension. About a year ago I have tried implementing a software solution
> taking advantage of the layer code. I failed as the layer code is not
> able to deal with the private structures to the drawables that each function
> in the rendering layer can allocate in a graceful way:
> When layers are switched a different chain of functions is called. This
> may leave some privates unallocated which will be used in a different layer
> (from a different rotation).
> I did not investigate further on this issue as the plan is to handle screen
> rotation when doing the screen composition in the long run.
> We should explore how your proposed changes can fit into this picture.
> 
> 2. There is no sample implementation in any of the X.Org drivers yet.
> However to include a new functionality like this into the DDX I feel we
> should have at least one sample implementation for an open source driver.
> Maybe you can provide an implementation for the nv driver.

I thought the smi driver supported this as a driver specific option. 
If not, the complete databooks for smi chips are available on their
website:
http://www.siliconmotion.com

Alex

> 
> 3. Also - and I admit this is a question of personal taste - should we use up
> two function slots in the ScrnInfoRec structure for this or can we get by
> with just one that is used both for query and setup?
> 
> Cheers,
>         Egbert.
> 
>  > Index: hw/xfree86/common/xf86Cursor.c
>  > ===================================================================
>  > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86Cursor.c,v
>  > retrieving revision 1.1.1.2
>  > diff -u -r1.1.1.2 xf86Cursor.c
>  > --- hw/xfree86/common/xf86Cursor.c   25 Nov 2003 19:28:32 -0000      1.1.1.2
>  > +++ hw/xfree86/common/xf86Cursor.c   23 Jul 2004 22:29:21 -0000
>  > @@ -222,7 +222,7 @@
>  >    if (mode == pScr->currentMode)
>  >      return TRUE;
>  >
>  > -  if (mode->HDisplay > pScreen->width || mode->VDisplay > pScreen->height)
>  > +  if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY)
>  >      return FALSE;
>  >
>  >    pCursorScreen = miPointerCurrentScreen();
>  > Index: hw/xfree86/common/xf86Init.c
>  > ===================================================================
>  > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86Init.c,v
>  > retrieving revision 1.2
>  > diff -u -r1.2 xf86Init.c
>  > --- hw/xfree86/common/xf86Init.c     23 Apr 2004 19:20:32 -0000      1.2
>  > +++ hw/xfree86/common/xf86Init.c     23 Jul 2004 22:29:21 -0000
>  > @@ -897,6 +897,8 @@
>  >      xf86Screens[i]->DPMSSet = NULL;
>  >      xf86Screens[i]->LoadPalette = NULL;
>  >      xf86Screens[i]->SetOverscan = NULL;
>  > +    xf86Screens[i]->RRGetInfo = NULL;
>  > +    xf86Screens[i]->RRSetConfig = NULL;
>  >      scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
>  >        if (scr_index == i) {
>  >      /*
>  > Index: hw/xfree86/common/xf86RandR.c
>  > ===================================================================
>  > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v
>  > retrieving revision 1.2
>  > diff -u -r1.2 xf86RandR.c
>  > --- hw/xfree86/common/xf86RandR.c    23 Apr 2004 19:20:32 -0000      1.2
>  > +++ hw/xfree86/common/xf86RandR.c    23 Jul 2004 22:29:21 -0000
>  > @@ -38,6 +38,7 @@
>  >      CloseScreenProcPtr                  CloseScreen;
>  >      int                                 virtualX;
>  >      int                                 virtualY;
>  > +    Rotation                            rotation;
>  >  } XF86RandRInfoRec, *XF86RandRInfoPtr;
>  >
>  >  static int      xf86RandRIndex;
>  > @@ -77,8 +78,8 @@
>  >          return FALSE;
>  >      RRRegisterRate (pScreen, pSize, refresh);
>  >      if (mode == scrp->currentMode &&
>  > -        mode->HDisplay == pScreen->width && mode->VDisplay == pScreen->height)
>  > -        RRSetCurrentConfig (pScreen, RR_Rotate_0, refresh, pSize);
>  > +        mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
>  > +        RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
>  >      if (mode->next == scrp->modes)
>  >          break;
>  >      }
>  > @@ -93,12 +94,17 @@
>  >      if (!pSize)
>  >          return FALSE;
>  >      RRRegisterRate (pScreen, pSize, refresh0);
>  > -    if (pScreen->width == randrp->virtualX &&
>  > -        pScreen->height == randrp->virtualY)
>  > +    if (scrp->virtualX == randrp->virtualX &&
>  > +        scrp->virtualY == randrp->virtualY)
>  >      {
>  > -        RRSetCurrentConfig (pScreen, RR_Rotate_0, refresh0, pSize);
>  > +        RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
>  >      }
>  >      }
>  > +
>  > +    /* If there is driver support for randr, let it set our supported rotations */
>  > +    if(scrp->RRGetInfo)
>  > +    return (*scrp->RRGetInfo)(scrp, rotations);
>  > +
>  >      return TRUE;
>  >  }
>  >
>  > @@ -125,8 +131,17 @@
>  >      scrp->virtualX = mode->HDisplay;
>  >      scrp->virtualY = mode->VDisplay;
>  >      }
>  > -    pScreen->width = scrp->virtualX;
>  > -    pScreen->height = scrp->virtualY;
>  > +    if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
>  > +    {
>  > +    /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
>  > +    pScreen->width = scrp->virtualY;
>  > +    pScreen->height = scrp->virtualX;
>  > +    }
>  > +    else
>  > +    {
>  > +    pScreen->width = scrp->virtualX;
>  > +    pScreen->height = scrp->virtualY;
>  > +    }
>  >      if (!xf86SwitchMode (pScreen, mode))
>  >      {
>  >      scrp->virtualX = pScreen->width = oldWidth;
>  > @@ -160,6 +175,8 @@
>  >      int                         px, py;
>  >      Bool                useVirtual = FALSE;
>  >
>  > +    randrp->rotation = rotation;
>  > +
>  >      miPointerPosition (&px, &py);
>  >      for (mode = scrp->modes; ; mode = mode->next)
>  >      {
>  > @@ -179,6 +196,12 @@
>  >          return FALSE;
>  >      }
>  >      }
>  > +
>  > +    /* Have the driver do its thing. */
>  > +    if (scrp->RRSetConfig &&
>  > +        !(*scrp->RRSetConfig)(scrp, rotation, rate, pSize->width, pSize->height))
>  > +    return FALSE;
>  > +
>  >      if (!xf86RandRSetMode (pScreen, mode, useVirtual))
>  >      return FALSE;
>  >      /*
>  > @@ -189,6 +212,7 @@
>  >      if (px < pSize->width && py < pSize->height)
>  >          (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
>  >      }
>  > +
>  >      return TRUE;
>  >  }
>  >
>  > @@ -277,6 +301,8 @@
>  >      randrp->CloseScreen = pScreen->CloseScreen;
>  >      pScreen->CloseScreen = xf86RandRCloseScreen;
>  >
>  > +    randrp->rotation = RR_Rotate_0;
>  > +
>  >      pScreen->devPrivates[xf86RandRIndex].ptr = randrp;
>  >      return TRUE;
>  >  }
>  > Index: hw/xfree86/common/xf86str.h
>  > ===================================================================
>  > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86str.h,v
>  > retrieving revision 1.1.1.2
>  > diff -u -r1.1.1.2 xf86str.h
>  > --- hw/xfree86/common/xf86str.h      25 Nov 2003 19:28:33 -0000      1.1.1.2
>  > +++ hw/xfree86/common/xf86str.h      23 Jul 2004 22:29:22 -0000
>  > @@ -476,7 +476,7 @@
>  >  /* These values should be adjusted when new fields are added to ScrnInfoRec */
>  >  #define NUM_RESERVED_INTS           16
>  >  #define NUM_RESERVED_POINTERS               15
>  > -#define NUM_RESERVED_FUNCS          12
>  > +#define NUM_RESERVED_FUNCS          10
>  >
>  >  typedef pointer (*funcPointer)(void);
>  >
>  > @@ -767,6 +767,8 @@
>  >  typedef void xf86DPMSSetProc                  (ScrnInfoPtr, int, int);
>  >  typedef void xf86LoadPaletteProc   (ScrnInfoPtr, int, int *, LOCO *, VisualPtr);
>  >  typedef void xf86SetOverscanProc          (ScrnInfoPtr, int);
>  > +typedef Bool xf86RRGetInfoProc            (ScrnInfoPtr, unsigned short *);
>  > +typedef Bool xf86RRSetConfigProc          (ScrnInfoPtr, int, int, int, int);
>  >
>  >  /*
>  >   * ScrnInfoRec
>  > @@ -921,6 +923,8 @@
>  >      xf86DPMSSetProc                 *DPMSSet;
>  >      xf86LoadPaletteProc                     *LoadPalette;
>  >      xf86SetOverscanProc                     *SetOverscan;
>  > +    xf86RRGetInfoProc                       *RRGetInfo;
>  > +    xf86RRSetConfigProc                     *RRSetConfig;
>  >
>  >      /*
>  >       * This can be used when the minor ABI version is incremented.
>  > _______________________________________________
>  > xorg mailing list
>  > xorg at freedesktop.org
>  > http://freedesktop.org/mailman/listinfo/xorg
> _______________________________________________
> xorg mailing list
> xorg at freedesktop.org
> http://freedesktop.org/mailman/listinfo/xorg
>



More information about the xorg mailing list