[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