Bug 714416 - Add rotation support to gonk backend, r=cjones

This commit is contained in:
Michael Wu 2012-02-06 17:47:11 -08:00
parent 9b97572b79
commit 10ba38d0c6
3 changed files with 97 additions and 12 deletions

View File

@ -59,6 +59,8 @@
#include "nsGkAtoms.h"
#include "nsGUIEvent.h"
#include "nsIObserverService.h"
#include "nsIScreen.h"
#include "nsScreenManagerGonk.h"
#include "nsWindow.h"
#include "android/log.h"
@ -347,6 +349,19 @@ GeckoInputReaderPolicy::getDisplayInfo(int32_t displayId,
int32_t* height,
int32_t* orientation)
{
MOZ_STATIC_ASSERT(nsIScreen::ROTATION_0_DEG ==
InputReaderPolicyInterface::ROTATION_0,
"Orientation enums not matched!");
MOZ_STATIC_ASSERT(nsIScreen::ROTATION_90_DEG ==
InputReaderPolicyInterface::ROTATION_90,
"Orientation enums not matched!");
MOZ_STATIC_ASSERT(nsIScreen::ROTATION_180_DEG ==
InputReaderPolicyInterface::ROTATION_180,
"Orientation enums not matched!");
MOZ_STATIC_ASSERT(nsIScreen::ROTATION_270_DEG ==
InputReaderPolicyInterface::ROTATION_270,
"Orientation enums not matched!");
// 0 is the default displayId. We only support one display
if (displayId)
return false;
@ -356,7 +371,7 @@ GeckoInputReaderPolicy::getDisplayInfo(int32_t displayId,
if (height)
*height = gScreenBounds.height;
if (orientation)
*orientation = ROTATION_0;
*orientation = nsScreenGonk::GetRotation();
return true;
}

View File

@ -54,6 +54,10 @@ public:
NS_IMETHOD GetAvailRect(PRInt32* aLeft, PRInt32* aTop, PRInt32* aWidth, PRInt32* aHeight);
NS_IMETHOD GetPixelDepth(PRInt32* aPixelDepth);
NS_IMETHOD GetColorDepth(PRInt32* aColorDepth);
NS_IMETHOD GetRotation(PRUint32* aRotation);
NS_IMETHOD SetRotation(PRUint32 aRotation);
static uint32_t GetRotation();
};
class nsScreenManagerGonk : public nsIScreenManager

View File

@ -64,6 +64,9 @@ using namespace mozilla::layers;
using namespace mozilla::widget;
nsIntRect gScreenBounds;
static uint32_t sScreenRotation;
static nsIntRect sVirtualBounds;
static gfxMatrix sRotationMatrix;
static nsRefPtr<GLContext> sGLContext;
static nsTArray<nsWindow *> sTopWindows;
@ -93,6 +96,7 @@ nsWindow::nsWindow()
NS_RUNTIMEABORT("Can't open GL context and can't fall back on /dev/graphics/fb0 ...");
}
}
sVirtualBounds = gScreenBounds;
}
}
@ -119,7 +123,9 @@ nsWindow::DoDraw(void)
LayerManager* lm = gWindowToRedraw->GetLayerManager();
if (LayerManager::LAYERS_OPENGL == lm->GetBackendType()) {
static_cast<LayerManagerOGL*>(lm)->SetClippingRegion(event.region);
LayerManagerOGL* oglm = static_cast<LayerManagerOGL*>(lm);
oglm->SetClippingRegion(event.region);
oglm->SetWorldTransform(sRotationMatrix);
gWindowToRedraw->mEventCallback(&event);
} else if (LayerManager::LAYERS_BASIC == lm->GetBackendType()) {
MOZ_ASSERT(sFramebufferOpen);
@ -162,7 +168,7 @@ nsWindow::Create(nsIWidget *aParent,
nsDeviceContext *aContext,
nsWidgetInitData *aInitData)
{
BaseCreate(aParent, IS_TOPLEVEL() ? gScreenBounds : aRect,
BaseCreate(aParent, IS_TOPLEVEL() ? sVirtualBounds : aRect,
aHandleEventFunction, aContext, aInitData);
mBounds = aRect;
@ -171,7 +177,7 @@ nsWindow::Create(nsIWidget *aParent,
mParent = parent;
if (!aNativeParent) {
mBounds = gScreenBounds;
mBounds = sVirtualBounds;
}
if (!IS_TOPLEVEL())
@ -179,7 +185,7 @@ nsWindow::Create(nsIWidget *aParent,
sTopWindows.AppendElement(this);
Resize(0, 0, gScreenBounds.width, gScreenBounds.height, false);
Resize(0, 0, sVirtualBounds.width, sVirtualBounds.height, false);
return NS_OK;
}
@ -264,9 +270,10 @@ nsWindow::Resize(PRInt32 aX,
event.time = PR_Now() / 1000;
nsIntRect rect(aX, aY, aWidth, aHeight);
mBounds = rect;
event.windowSize = &rect;
event.mWinWidth = gScreenBounds.width;
event.mWinHeight = gScreenBounds.height;
event.mWinWidth = sVirtualBounds.width;
event.mWinHeight = sVirtualBounds.height;
(*mEventCallback)(&event);
@ -436,7 +443,7 @@ nsWindow::BringToTop()
nsGUIEvent event(true, NS_ACTIVATE, this);
(*mEventCallback)(&event);
Invalidate(gScreenBounds);
Invalidate(sVirtualBounds);
}
void
@ -477,11 +484,11 @@ NS_IMETHODIMP
nsScreenGonk::GetRect(PRInt32 *outLeft, PRInt32 *outTop,
PRInt32 *outWidth, PRInt32 *outHeight)
{
*outLeft = gScreenBounds.x;
*outTop = gScreenBounds.y;
*outLeft = sVirtualBounds.x;
*outTop = sVirtualBounds.y;
*outWidth = gScreenBounds.width;
*outHeight = gScreenBounds.height;
*outWidth = sVirtualBounds.width;
*outHeight = sVirtualBounds.height;
return NS_OK;
}
@ -509,6 +516,65 @@ nsScreenGonk::GetColorDepth(PRInt32 *aColorDepth)
return GetPixelDepth(aColorDepth);
}
NS_IMETHODIMP
nsScreenGonk::GetRotation(PRUint32* aRotation)
{
*aRotation = sScreenRotation;
return NS_OK;
}
NS_IMETHODIMP
nsScreenGonk::SetRotation(PRUint32 aRotation)
{
if (!(ROTATION_0_DEG <= aRotation && aRotation <= ROTATION_270_DEG))
return NS_ERROR_ILLEGAL_VALUE;
if (sScreenRotation == aRotation)
return NS_OK;
sScreenRotation = aRotation;
sRotationMatrix.Reset();
switch (aRotation) {
case nsIScreen::ROTATION_0_DEG:
sVirtualBounds = gScreenBounds;
break;
case nsIScreen::ROTATION_90_DEG:
sRotationMatrix.Translate(gfxPoint(gScreenBounds.width, 0));
sRotationMatrix.Rotate(M_PI / 2);
sVirtualBounds = nsIntRect(0, 0, gScreenBounds.height,
gScreenBounds.width);
break;
case nsIScreen::ROTATION_180_DEG:
sRotationMatrix.Translate(gfxPoint(gScreenBounds.width,
gScreenBounds.height));
sRotationMatrix.Rotate(M_PI);
sVirtualBounds = gScreenBounds;
break;
case nsIScreen::ROTATION_270_DEG:
sRotationMatrix.Translate(gfxPoint(0, gScreenBounds.height));
sRotationMatrix.Rotate(M_PI * 3 / 2);
sVirtualBounds = nsIntRect(0, 0, gScreenBounds.height,
gScreenBounds.width);
break;
default:
MOZ_NOT_REACHED("Unknown rotation");
break;
}
for (unsigned int i = 0; i < sTopWindows.Length(); i++)
sTopWindows[i]->Resize(sVirtualBounds.width,
sVirtualBounds.height,
!i);
return NS_OK;
}
uint32_t
nsScreenGonk::GetRotation()
{
return sScreenRotation;
}
NS_IMPL_ISUPPORTS1(nsScreenManagerGonk, nsIScreenManager)
nsScreenManagerGonk::nsScreenManagerGonk()