[SailfishDevel] Landscape mode in Sailfish?

Thomas Perl th.perl at gmail.com
Sat Apr 5 08:45:08 UTC 2014


On 05 Apr 2014, at 09:29, Iosif Hamlatzis <i.hamlatzis at gmail.com> wrote:
> Is there a c/c++ (not Qt and QML) API that I can use to force landscape mode?
> 
> Generally speaking is there an API (not Qt and QML) documentation anywhere?

In general, you can use set_buffer_transform on the Wayland surface:
http://wayland.freedesktop.org/docs/html/protocol-spec-interface-wl_surface.html

You also want to set the orientation and/or other window flags, that’s a Wayland protocol extension from QtWayland, which lipstick (the window manger in SFOS) uses:
https://github.com/qtproject/qtwayland/blob/stable/src/extensions/surface-extension.xml

In SDL, you can get the Wayland display, surface and shell surface via the SDL_syswm interface:
https://hg.libsdl.org/SDL/file/default/include/SDL_syswm.h

In almost all cases, it’s better to just rotate the contents of your drawing (by doing a 90 degree rotation in your projection matrix) and then also map the input events. This makes it a little easier for the compositor to optimize drawing of fullscreen content, and gives the compositor better chances of ideally just reading out the window contents directly onto the framebuffer without any additional transformation (independent of whether or not the target device has hardware composer functionality or not - in case it has, it might not be so problematic, but in case the target device doesn’t have a hwc or it isn’t used fully, the rotation to frame buffer orientation would have to happen using GL, and that takes away some fill rate [think: textured fullscreen quad] from the GPU’s per-frame budget at runtime - mapping input events and modifying the projection matrix on resize is very very very cheap in comparison).

A simple resize function that is rotation-aware could look like this:

bool resize(int w, int h)
{
    setViewport(0, 0, w, h);

    projection = Matrix4x4();

    if (h > w) {
        std::swap(w, h);
        projection *= Matrix4x4::rotation(-90.f, 0.f, 0.f, 1.f);
        rotated = true;
    } else {
        rotated = false;
    }

    // do your normal projection things here
}

When you call that method you store the “rotated” value somewhere and then access it when input events come in to transform their coordinates (for a more generic approach, you can also un-project the projection like the old gluUnProject does, and don’t have to care about rotation or not - you will always turn window coordinates into object coordinates):

Point2D maptouch(Point2D pos)
{
    if (rotated) {
        return Point2D(height - pos.y, pos.x);
    }

    return pos;
}

HTH :)
Thomas


More information about the Devel mailing list