Skip to content

Commit

Permalink
Add support for framebuffer rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Kerner committed Apr 13, 2011
1 parent d5c354f commit 0d0e44c
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 2 deletions.
148 changes: 146 additions & 2 deletions hw/kdrive/fbdev/fbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,143 @@ fbdevSetShadow (ScreenPtr pScreen)


#ifdef RANDR
static Bool
fbdevRandRGetInfoHW (ScreenPtr pScreen, Rotation *rotations)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
FbdevScrPriv *scrpriv = screen->driver;
FbdevPriv *priv = pScreenPriv->card->driver;
RRScreenSizePtr pSize;
Rotation randr;
int n;

*rotations = RR_Rotate_All;

for (n = 0; n < pScreen->numDepths; n++)
if (pScreen->allowedDepths[n].numVids)
break;
if (n == pScreen->numDepths)
return FALSE;

pSize = RRRegisterSize (pScreen,
screen->width,
screen->height,
screen->width_mm,
screen->height_mm);

switch (priv->var.rotate) {
case FB_ROTATE_CCW:
randr = RR_Rotate_90;
break;
case FB_ROTATE_UD:
randr = RR_Rotate_180;
break;
case FB_ROTATE_CW:
randr = RR_Rotate_270;
break;
case FB_ROTATE_UR:
default:
randr = RR_Rotate_0;
}

RRSetCurrentConfig (pScreen, randr, 0, pSize);

return TRUE;
}

static Bool
fbdevRandRSetConfigHW (ScreenPtr pScreen,
Rotation randr,
int rate,
RRScreenSizePtr pSize)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
FbdevScrPriv *scrpriv = screen->driver;
FbdevPriv *priv = pScreenPriv->card->driver;
Bool wasEnabled = pScreenPriv->enabled;
FbdevScrPriv oldscr;
int oldwidth;
int oldheight;
int oldmmwidth;
int oldmmheight;

if (wasEnabled)
KdDisableScreen (pScreen);

oldscr = *scrpriv;

oldwidth = screen->width;
oldheight = screen->height;
oldmmwidth = pScreen->mmWidth;
oldmmheight = pScreen->mmHeight;

/*
* Set new configuration
*/

fbdevUnmapFramebuffer (screen);

switch (randr) {
case RR_Rotate_90:
priv->var.rotate = FB_ROTATE_CCW;
break;
case RR_Rotate_180:
priv->var.rotate = FB_ROTATE_UD;
break;
case RR_Rotate_270:
priv->var.rotate = FB_ROTATE_CW;
break;
default:
priv->var.rotate = FB_ROTATE_UR;
}

priv->var.width = pSize->width;
priv->var.height = pSize->height;

/* reconfigure FB */
ioctl (priv->fd, FBIOPUT_VSCREENINFO, &priv->var);

/* fetch new variable and fix info from FB */
ioctl (priv->fd, FBIOGET_VSCREENINFO, &priv->var);
ioctl (priv->fd, FBIOGET_FSCREENINFO, &priv->fix);

if (!fbdevMapFramebuffer (screen))
goto bail4;

fbdevSetScreenSizes (screen->pScreen);

/*
* Set frame buffer mapping
*/
(*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
pScreen->width,
pScreen->height,
screen->fb.depth,
screen->fb.bitsPerPixel,
screen->fb.byteStride,
screen->fb.frameBuffer);

if (wasEnabled)
KdEnableScreen (pScreen);

return TRUE;

bail4:
fbdevUnmapFramebuffer (screen);
*scrpriv = oldscr;
(void) fbdevMapFramebuffer (screen);
pScreen->width = oldwidth;
pScreen->height = oldheight;
pScreen->mmWidth = oldmmwidth;
pScreen->mmHeight = oldmmheight;

if (wasEnabled)
KdEnableScreen (pScreen);
return FALSE;
}

static Bool
fbdevRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
{
Expand Down Expand Up @@ -563,13 +700,20 @@ static Bool
fbdevRandRInit (ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;

if (!RRScreenInit (pScreen))
return FALSE;

pScrPriv = rrGetScrPriv(pScreen);
pScrPriv->rrGetInfo = fbdevRandRGetInfo;
pScrPriv->rrSetConfig = fbdevRandRSetConfig;
if (screen->hwRotation) {
pScrPriv->rrGetInfo = fbdevRandRGetInfoHW;
pScrPriv->rrSetConfig = fbdevRandRSetConfigHW;
} else {
pScrPriv->rrGetInfo = fbdevRandRGetInfo;
pScrPriv->rrSetConfig = fbdevRandRSetConfig;
}
return TRUE;
}
#endif
Expand Down
9 changes: 9 additions & 0 deletions hw/kdrive/src/kdrive.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ ddxGiveUp (void)
AbortDDX ();
}

Bool kdHwRotation;
Bool kdDumbDriver;
Bool kdSoftCursor;

Expand Down Expand Up @@ -391,6 +392,7 @@ KdParseScreen (KdScreenInfo *screen,
int i;
int pixels, mm;

screen->hwRotation = kdHwRotation;
screen->dumb = kdDumbDriver;
screen->softCursor = kdSoftCursor;
screen->origin = kdOrigin;
Expand Down Expand Up @@ -440,6 +442,7 @@ KdParseScreen (KdScreenInfo *screen,

kdOrigin.x += screen->width;
kdOrigin.y = 0;
kdHwRotation = FALSE;
kdDumbDriver = FALSE;
kdSoftCursor = FALSE;
kdSubpixelOrder = SubPixelUnknown;
Expand Down Expand Up @@ -536,6 +539,7 @@ KdUseMsg (void)
ErrorF("-2button Emulate 3 button mouse\n");
ErrorF("-3button Disable 3 button mouse emulation\n");
ErrorF("-rawcoord Don't transform pointer coordinates on rotation\n");
ErrorF("-hwrotation Enable hardware screen rotation\n");
ErrorF("-dumb Disable hardware acceleration\n");
ErrorF("-softCursor Force software cursor\n");
ErrorF("-videoTest Start the server, pause momentarily and exit\n");
Expand Down Expand Up @@ -596,6 +600,11 @@ KdProcessArgument (int argc, char **argv, int i)
kdRawPointerCoordinates = 1;
return 1;
}
if (!strcmp (argv[i], "-hwrotation"))
{
kdHwRotation = TRUE;
return 1;
}
if (!strcmp (argv[i], "-dumb"))
{
kdDumbDriver = TRUE;
Expand Down
1 change: 1 addition & 0 deletions hw/kdrive/src/kdrive.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ typedef struct _KdScreenInfo {
int subpixel_order;
Bool dumb;
Bool softCursor;
Bool hwRotation;
int mynum;
DDXPointRec origin;
KdFrameBuffer fb;
Expand Down

0 comments on commit 0d0e44c

Please sign in to comment.