Merge changes Ie5fdacb1,If9adb952,Idb10efa4,Ifbcf97a0,I8dbfde56 am: 31b74d7fd3 am: f95c6cd89d am: 5b0f100a12 am: 9173b2e80d am: a3609e6a71

Original change: https://android-review.googlesource.com/c/platform/system/teeui/+/1308624

Change-Id: I2de87139e5039ecacf0d26d4eb5bac853bc64a8c
diff --git a/libteeui/example/Android.bp b/libteeui/example/Android.bp
index b2e8a26..2949bf1 100644
--- a/libteeui/example/Android.bp
+++ b/libteeui/example/Android.bp
@@ -2,8 +2,11 @@
     name: "libteeui_example_layout",
     defaults: ["keystore_defaults"],
     srcs: [
+        "examples.cpp",
+        "example_utils.cpp",
         "fonts.S",
-        "teeui.cpp",
+        "phys_button_example.cpp",
+        "touch_button_example.cpp",
     ],
     static_libs: [
         "libft2.nodep",
diff --git a/libteeui/example/example_utils.cpp b/libteeui/example/example_utils.cpp
new file mode 100644
index 0000000..b707356
--- /dev/null
+++ b/libteeui/example/example_utils.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+
+#include <teeui/label.h>
+#include <teeui/localization/ConfirmationUITranslations.h>
+
+#include "example_utils.h"
+
+namespace teeui {
+namespace example {
+
+uint32_t alfaCombineChannel(uint32_t shift, double alfa, uint32_t a, uint32_t b) {
+    a >>= shift;
+    a &= 0xff;
+    b >>= shift;
+    b &= 0xff;
+    double acc = alfa * a + (1 - alfa) * b;
+    if (acc <= 0) return 0;
+    uint32_t result = acc;
+    if (result > 255) return 255 << shift;
+    return result << shift;
+}
+
+Error FrameBuffer::drawPixel(uint32_t x, uint32_t y, uint32_t color) const {
+    size_t pos = (top_ + y) * lineStride_ + x + left_;
+    if (pos >= size_in_elements_) {
+        return Error::OutOfBoundsDrawing;
+    }
+    double alfa = (color & 0xff000000) >> 24;
+    alfa /= 255.0;
+    auto acc = buffer_[pos];
+    buffer_[pos] = alfaCombineChannel(0, alfa, color, acc) |
+                   alfaCombineChannel(8, alfa, color, acc) |
+                   alfaCombineChannel(16, alfa, color, acc);
+    return Error::OK;
+}
+
+void translate(LabelImpl* label) {
+    uint64_t textId = label->textId();
+    const char* translation =
+        localization::lookup(static_cast<localization::TranslationId>(textId));
+    label->setText({&translation[0], &translation[strlen(translation)]});
+}
+
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/example_utils.h b/libteeui/example/example_utils.h
new file mode 100644
index 0000000..568542d
--- /dev/null
+++ b/libteeui/example/example_utils.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stddef.h>
+
+#include <teeui/label.h>
+
+namespace teeui {
+namespace example {
+
+/*
+ * AOSP color scheme constants.
+ */
+constexpr static const Color kShieldColor = Color(0xff778500);
+constexpr static const Color kShieldColorInv = Color(0xffc4cb80);
+constexpr static const Color kTextColor = Color(0xff212121);
+constexpr static const Color kTextColorInv = Color(0xffdedede);
+constexpr static const Color kBackGroundColor = Color(0xffffffff);
+constexpr static const Color kBackGroundColorInv = Color(0xff212121);
+
+uint32_t alfaCombineChannel(uint32_t shift, double alfa, uint32_t a, uint32_t b);
+
+template <typename T> uint32_t renderPixel(uint32_t x, uint32_t y, const T& e) {
+    return e.bounds_.drawPoint(Point<pxs>(x, y));
+}
+
+struct FrameBuffer {
+    uint32_t left_;
+    uint32_t top_;
+    uint32_t width_;
+    uint32_t height_;
+    uint32_t* buffer_;
+    size_t size_in_elements_;
+    uint32_t lineStride_;
+
+    Error drawPixel(uint32_t x, uint32_t y, uint32_t color) const;
+};
+
+template <typename... Elements>
+Error drawElements(std::tuple<Elements...>& layout, const PixelDrawer& drawPixel) {
+    // Error::operator|| is overloaded, so we don't get short circuit evaluation.
+    // But we get the first error that occurs. We will still try and draw the remaining
+    // elements in the order they appear in the layout tuple.
+    return (std::get<Elements>(layout).draw(drawPixel) || ...);
+}
+
+template <typename... Elements>
+Error handleAllEvent(std::tuple<Elements...>& layout, const Event& event) {
+    return (std::get<Elements>(layout).hit(event) || ...);
+}
+
+void translate(LabelImpl* label);
+
+template <typename T, typename Layout> void translateLabel(Layout* layout) {
+    translate(&std::get<T>(*layout));
+}
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/examples.cpp b/libteeui/example/examples.cpp
new file mode 100644
index 0000000..7528414
--- /dev/null
+++ b/libteeui/example/examples.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "phys_button_example.h"
+#include "touch_button_example.h"
+
+namespace teeui {
+namespace example {
+
+std::unique_ptr<ITeeuiExample> createExample(Examples example) {
+    switch (example) {
+    case Examples::PhysButton:
+        return phys_button::createTeeuiExample();
+    case Examples::TouchButton:
+        return touch_button::createTeeuiExample();
+    }
+}
+
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/layout/common_layout_params.h b/libteeui/example/layout/common_layout_params.h
new file mode 100644
index 0000000..9ba2537
--- /dev/null
+++ b/libteeui/example/layout/common_layout_params.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <teeui/utils.h>
+
+#include "fonts.h"
+
+namespace teeui {
+namespace example {
+
+DECLARE_PARAMETER(RightEdgeOfScreen);
+DECLARE_PARAMETER(BottomOfScreen);
+DECLARE_PARAMETER(DefaultFontSize);  // 14_dp regular and 18_dp magnified
+DECLARE_PARAMETER(BodyFontSize);     // 16_dp regular and 20_dp magnified
+DECLARE_TYPED_PARAMETER(ShieldColor, ::teeui::Color);
+DECLARE_TYPED_PARAMETER(ColorText, ::teeui::Color);
+DECLARE_TYPED_PARAMETER(ColorBG, ::teeui::Color);
+
+CONSTANT(BorderWidth, 24_dp);
+
+DECLARE_FONT_BUFFER(RobotoMedium, RobotoMedium, RobotoMedium_length);
+DECLARE_FONT_BUFFER(RobotoRegular, RobotoRegular, RobotoRegular_length);
+DECLARE_FONT_BUFFER(Shield, Shield, Shield_length);
+
+CONSTANT(DefaultFont, FONT(RobotoRegular));
+
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/layout.h b/libteeui/example/layout/phys_button_layout.h
similarity index 87%
rename from libteeui/example/layout.h
rename to libteeui/example/layout/phys_button_layout.h
index 7318a0c..a3f1fe7 100644
--- a/libteeui/example/layout.h
+++ b/libteeui/example/layout/phys_button_layout.h
@@ -19,31 +19,24 @@
 #include <teeui/button.h>
 #include <teeui/label.h>
 #include <teeui/localization/ConfirmationUITranslations.h>
-#include <teeui/utils.h>
 
-#include "fonts.h"
+#include "common_layout_params.h"
 
 using teeui::localization::TranslationId;
 
 namespace teeui {
+namespace example {
+namespace phys_button {
 
-DECLARE_PARAMETER(RightEdgeOfScreen);
-DECLARE_PARAMETER(BottomOfScreen);
 DECLARE_PARAMETER(PowerButtonTop);
 DECLARE_PARAMETER(PowerButtonBottom);
 DECLARE_PARAMETER(VolUpButtonTop);
 DECLARE_PARAMETER(VolUpButtonBottom);
-DECLARE_PARAMETER(DefaultFontSize);  // 14_dp regular and 18_dp magnified
-DECLARE_PARAMETER(BodyFontSize);     // 16_dp regular and 20_dp magnified
-DECLARE_TYPED_PARAMETER(ShieldColor, ::teeui::Color);
-DECLARE_TYPED_PARAMETER(ColorText, ::teeui::Color);
-DECLARE_TYPED_PARAMETER(ColorBG, ::teeui::Color);
 
 NEW_PARAMETER_SET(ConUIParameters, RightEdgeOfScreen, BottomOfScreen, PowerButtonTop,
                   PowerButtonBottom, VolUpButtonTop, VolUpButtonBottom, DefaultFontSize,
                   BodyFontSize, ShieldColor, ColorText, ColorBG);
 
-CONSTANT(BorderWidth, 24_dp);
 CONSTANT(PowerButtonCenter, (PowerButtonTop() + PowerButtonBottom()) / 2_px);
 CONSTANT(VolUpButtonCenter, (VolUpButtonTop() + VolUpButtonBottom()) / 2.0_px);
 CONSTANT(GrayZone, 12_dp);
@@ -59,12 +52,6 @@
                         CONVEX_OBJECT(Vec2d{6.0_dp - SQRT8, 6.0_dp}, Vec2d{6.0_dp, 6.0_dp},
                                       Vec2d{0.0_dp, 12.0_dp}, Vec2d{-SQRT2, 12.0_dp - SQRT2})));
 
-DECLARE_FONT_BUFFER(RobotoMedium, RobotoMedium, RobotoMedium_length);
-DECLARE_FONT_BUFFER(RobotoRegular, RobotoRegular, RobotoRegular_length);
-DECLARE_FONT_BUFFER(Shield, Shield, Shield_length);
-
-CONSTANT(DefaultFont, FONT(RobotoRegular));
-
 BEGIN_ELEMENT(LabelOK, teeui::Label)
 FontSize(DefaultFontSize());
 LineHeight(20_dp);
@@ -166,4 +153,6 @@
 NEW_LAYOUT(ConfUILayout, LabelOK, IconPower, LabelCancel, IconVolUp, IconShield, LabelTitle,
            LabelHint, LabelBody);
 
-}  // namespace teeui
+}  // namespace phys_button
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/layout/touch_button_layout.h b/libteeui/example/layout/touch_button_layout.h
new file mode 100644
index 0000000..a7eab50
--- /dev/null
+++ b/libteeui/example/layout/touch_button_layout.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <teeui/button.h>
+#include <teeui/label.h>
+#include <teeui/localization/ConfirmationUITranslations.h>
+
+#include "common_layout_params.h"
+
+using teeui::localization::TranslationId;
+
+namespace teeui {
+namespace example {
+namespace touch_button {
+
+DECLARE_TYPED_PARAMETER(ColorButton, ::teeui::Color);
+
+NEW_PARAMETER_SET(ConfUIParameters, RightEdgeOfScreen, BottomOfScreen, DefaultFontSize,
+                  BodyFontSize, ShieldColor, ColorText, ColorBG, ColorButton);
+
+CONSTANT(IconShieldDistanceFromTop, 100_dp);
+CONSTANT(LabelBorderZone, 4_dp);
+CONSTANT(RightLabelEdge, RightEdgeOfScreen() - BorderWidth);
+CONSTANT(LabelWidth, RightLabelEdge - BorderWidth);
+CONSTANT(ButtonHeight, 72_dp);
+CONSTANT(ButtonPositionX, 0);
+CONSTANT(ButtonPositionY, BottomOfScreen() - ButtonHeight);
+CONSTANT(ButtonWidth, 130_dp);
+CONSTANT(ButtonLabelDistance, 12_dp);
+
+BEGIN_ELEMENT(IconShield, teeui::Label)
+FontSize(24_dp);
+LineHeight(24_dp);
+NumberOfLines(1);
+Dimension(LabelWidth, HeightFromLines);
+Position(BorderWidth, IconShieldDistanceFromTop);
+DefaultText("A");  // ShieldTTF has just one glyph at the code point for capital A
+TextColor(ShieldColor());
+HorizontalTextAlignment(Alignment::CENTER);
+Font(FONT(Shield));
+END_ELEMENT();
+
+BEGIN_ELEMENT(LabelTitle, teeui::Label)
+FontSize(20_dp);
+LineHeight(20_dp);
+NumberOfLines(1);
+Dimension(LabelWidth, HeightFromLines);
+Position(BorderWidth, BOTTOM_EDGE_OF(IconShield) + 16_dp);
+DefaultText("Android Protected Confirmation");
+Font(FONT(RobotoMedium));
+VerticallyCentered;
+TextColor(ColorText());
+TextID(TEXT_ID(TranslationId::TITLE));
+END_ELEMENT();
+
+BEGIN_ELEMENT(IconOk, teeui::Button, ConvexObjectCount(1))
+Dimension(ButtonWidth, ButtonHeight - BorderWidth);
+Position(RightEdgeOfScreen() - ButtonWidth - BorderWidth, ButtonPositionY + ButtonLabelDistance);
+CornerRadius(4_dp);
+ButtonColor(ColorButton());
+RoundTopLeft;
+RoundBottomLeft;
+RoundTopRight;
+RoundBottomRight;
+END_ELEMENT();
+
+BEGIN_ELEMENT(LabelOK, teeui::Label)
+FontSize(BodyFontSize());
+LineHeight(BodyFontSize() * 1.4_px);
+NumberOfLines(1);
+Dimension(ButtonWidth - (LabelBorderZone * 2_dp),
+          ButtonHeight - BorderWidth - (LabelBorderZone * 2_dp));
+Position(RightEdgeOfScreen() - ButtonWidth - BorderWidth + LabelBorderZone,
+         ButtonPositionY + ButtonLabelDistance + LabelBorderZone);
+DefaultText("Confirm");
+Font(FONT(RobotoMedium));
+HorizontalTextAlignment(Alignment::CENTER);
+VerticalTextAlignment(Alignment::CENTER);
+TextColor(ColorBG());
+TextID(TEXT_ID(TranslationId::CONFIRM));
+END_ELEMENT();
+
+BEGIN_ELEMENT(LabelCancel, teeui::Label)
+FontSize(BodyFontSize());
+LineHeight(BodyFontSize() * 1.4_px);
+NumberOfLines(1);
+Dimension(ButtonWidth - (LabelBorderZone * 2_dp),
+          ButtonHeight - BorderWidth - (LabelBorderZone * 2_dp));
+Position(BorderWidth + LabelBorderZone, ButtonPositionY + ButtonLabelDistance + LabelBorderZone);
+DefaultText("Cancel");
+HorizontalTextAlignment(Alignment::LEFT);
+Font(FONT(RobotoMedium));
+VerticallyCentered;
+TextColor(ColorButton());
+TextID(TEXT_ID(TranslationId::CANCEL));
+END_ELEMENT();
+
+BEGIN_ELEMENT(LabelHint, teeui::Label)
+FontSize(DefaultFontSize());
+LineHeight(DefaultFontSize() * 1.5_px);
+NumberOfLines(4);
+Dimension(LabelWidth, HeightFromLines);
+Position(BorderWidth, ButtonPositionY - dim_h - 48_dp);
+DefaultText("This confirmation provides an extra layer of security for the action you're "
+            "about to take.");
+VerticalTextAlignment(Alignment::BOTTOM);
+TextColor(ColorText());
+Font(DefaultFont);
+TextID(TEXT_ID(TranslationId::DESCRIPTION));
+END_ELEMENT();
+
+BEGIN_ELEMENT(LabelBody, teeui::Label)
+FontSize(BodyFontSize());
+LineHeight(BodyFontSize() * 1.4_px);
+NumberOfLines(20);
+Position(BorderWidth, BOTTOM_EDGE_OF(LabelTitle) + 16_dp);
+Dimension(LabelWidth, LabelHint::pos_y - pos_y - 24_dp);
+DefaultText("12345678901234567890123456789012345678901234567890123456789012345678901234567890123456"
+            "78901234567890");
+TextColor(ColorText());
+Font(FONT(RobotoRegular));
+END_ELEMENT();
+
+NEW_LAYOUT(ConfUILayout, IconShield, LabelTitle, LabelHint, LabelBody, IconOk, LabelOK,
+           LabelCancel);
+}  // namespace touch_button
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/phys_button_example.cpp b/libteeui/example/phys_button_example.cpp
new file mode 100644
index 0000000..e490925
--- /dev/null
+++ b/libteeui/example/phys_button_example.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "phys_button_example.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "example_utils.h"
+#include "layout/phys_button_layout.h"
+
+#include <memory>
+
+namespace teeui {
+namespace example {
+namespace phys_button {
+
+template <typename Layout> static void translateLabels(Layout* layout) {
+    translateLabel<LabelOK>(layout);
+    translateLabel<LabelCancel>(layout);
+    translateLabel<LabelTitle>(layout);
+    translateLabel<LabelHint>(layout);
+}
+
+class GUIStatePhysButtons : public ITeeuiExample {
+  public:
+    bool inverted_;
+    std::string confirmationMessage_;
+    layout_t<ConfUILayout> layoutInstance_ = {};
+
+    GUIStatePhysButtons() : inverted_(false), layoutInstance_{} {}
+
+    void selectLanguage(const char* language_id) override {
+        teeui::localization::selectLangId(language_id);
+        translateLabels(&layoutInstance_);
+    }
+
+    void setConfirmationMessage(std::string confirmationMessage) override {
+        confirmationMessage_ = std::move(confirmationMessage);
+        std::get<LabelBody>(layoutInstance_)
+            .setText({&*confirmationMessage_.begin(), &*confirmationMessage_.end()});
+    }
+
+    uint32_t setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted = false) override;
+    EventResult onEvent(uint32_t, uint32_t, uint32_t) override { return EventResult::NONE; }
+
+    uint32_t renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t lineStride,
+                                uint32_t* buffer,
+                                size_t buffer_size_in_elements_not_bytes) override;
+};
+
+std::unique_ptr<ITeeuiExample> createTeeuiExample() {
+    return std::make_unique<GUIStatePhysButtons>();
+}
+
+static context<ConUIParameters> setLayoutParams(DeviceInfo& deviceInfo, bool magnified,
+                                                bool inverted) {
+    context<ConUIParameters> ctx(deviceInfo.mm2px_, deviceInfo.dp2px_);
+    ctx.setParam<RightEdgeOfScreen>(pxs(deviceInfo.width_));
+    ctx.setParam<BottomOfScreen>(pxs(deviceInfo.height_));
+    ctx.setParam<PowerButtonTop>(mms(deviceInfo.powerButtonTopMm_));
+    ctx.setParam<PowerButtonBottom>(mms(deviceInfo.powerButtonBottomMm_));
+    ctx.setParam<VolUpButtonTop>(mms(deviceInfo.volUpButtonTopMm_));
+    ctx.setParam<VolUpButtonBottom>(mms(deviceInfo.volUpButtonBottomMm_));
+    if (magnified) {
+        ctx.setParam<DefaultFontSize>(18_dp);
+        ctx.setParam<BodyFontSize>(20_dp);
+    } else {
+        ctx.setParam<DefaultFontSize>(14_dp);
+        ctx.setParam<BodyFontSize>(16_dp);
+    }
+    if (inverted) {
+        ctx.setParam<ShieldColor>(kShieldColorInv);
+        ctx.setParam<ColorText>(kTextColorInv);
+        ctx.setParam<ColorBG>(kBackGroundColorInv);
+    } else {
+        ctx.setParam<ShieldColor>(kShieldColor);
+        ctx.setParam<ColorText>(kTextColor);
+        ctx.setParam<ColorBG>(kBackGroundColor);
+    }
+    return ctx;
+}
+
+uint32_t GUIStatePhysButtons::setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted) {
+    layoutInstance_ =
+        instantiateLayout(ConfUILayout(), setLayoutParams(device_info, magnified, inverted));
+    inverted_ = inverted;
+
+    return 0;
+}
+
+uint32_t GUIStatePhysButtons::renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h,
+                                                 uint32_t lineStride, uint32_t* buffer,
+                                                 size_t buffer_size_in_elements_not_bytes) {
+    uint32_t afterLastPixelIndex = 0;
+    if (__builtin_add_overflow(y, h, &afterLastPixelIndex) ||
+        __builtin_add_overflow(afterLastPixelIndex, -1, &afterLastPixelIndex) ||
+        __builtin_mul_overflow(afterLastPixelIndex, lineStride, &afterLastPixelIndex) ||
+        __builtin_add_overflow(afterLastPixelIndex, x, &afterLastPixelIndex) ||
+        __builtin_add_overflow(afterLastPixelIndex, w, &afterLastPixelIndex) ||
+        afterLastPixelIndex > buffer_size_in_elements_not_bytes) {
+        return uint32_t(Error::OutOfBoundsDrawing);
+    }
+
+    uint32_t* begin = buffer + (y * lineStride + x);
+
+    Color bgColor = inverted_ ? kBackGroundColorInv : kBackGroundColor;
+
+    for (uint32_t yi = 0; yi < h; ++yi) {
+        for (uint32_t xi = 0; xi < w; ++xi) {
+            begin[xi] = bgColor;
+        }
+        begin += lineStride;
+    }
+    FrameBuffer fb;
+    fb.left_ = x;
+    fb.top_ = y;
+    fb.width_ = w;
+    fb.height_ = h;
+    fb.buffer_ = buffer;
+    fb.size_in_elements_ = buffer_size_in_elements_not_bytes;
+    fb.lineStride_ = lineStride;
+
+    auto pixelDrawer = makePixelDrawer(
+        [&fb](uint32_t x, uint32_t y, Color color) -> Error { return fb.drawPixel(x, y, color); });
+
+    if (auto error = drawElements(layoutInstance_, pixelDrawer)) {
+        return uint32_t(error.code());
+    }
+
+    return 0;  // OK
+}
+
+}  // namespace phys_button
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/phys_button_example.h b/libteeui/example/phys_button_example.h
new file mode 100644
index 0000000..268f2d4
--- /dev/null
+++ b/libteeui/example/phys_button_example.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <teeui/example/example.h>
+
+namespace teeui {
+namespace example {
+namespace phys_button {
+
+std::unique_ptr<ITeeuiExample> createTeeuiExample();
+
+}  // namespace phys_button
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/example/teeui.cpp b/libteeui/example/teeui.cpp
deleted file mode 100644
index b415283..0000000
--- a/libteeui/example/teeui.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "layout.h"
-#include <cassert>
-#include <iostream>
-#include <teeui/example/teeui.h>
-#include <teeui/localization/ConfirmationUITranslations.h>
-#include <typeinfo>
-
-using namespace teeui;
-
-static DeviceInfo sDeviceInfo;
-static bool sMagnified;
-static bool sInverted;
-static std::string sConfirmationMessage;
-
-/*
- * AOSP color scheme constants.
- */
-constexpr static const Color kShieldColor = Color(0xff778500);
-constexpr static const Color kShieldColorInv = Color(0xffc4cb80);
-constexpr static const Color kTextColor = Color(0xff212121);
-constexpr static const Color kTextColorInv = Color(0xffdedede);
-constexpr static const Color kBackGroundColor = Color(0xffffffff);
-constexpr static const Color kBackGroundColorInv = Color(0xff212121);
-
-void setConfirmationMessage(const char* confirmationMessage) {
-    sConfirmationMessage = confirmationMessage;
-}
-
-uint32_t alfaCombineChannel(uint32_t shift, double alfa, uint32_t a, uint32_t b) {
-    a >>= shift;
-    a &= 0xff;
-    b >>= shift;
-    b &= 0xff;
-    double acc = alfa * a + (1 - alfa) * b;
-    if (acc <= 0) return 0;
-    uint32_t result = acc;
-    if (result > 255) return 255 << shift;
-    return result << shift;
-}
-
-template <typename T> uint32_t renderPixel(uint32_t x, uint32_t y, const T& e) {
-    return e.bounds_.drawPoint(Point<pxs>(x, y));
-}
-
-struct FrameBuffer {
-    uint32_t left_;
-    uint32_t top_;
-    uint32_t width_;
-    uint32_t height_;
-    uint32_t* buffer_;
-    size_t size_in_elements_;
-    uint32_t lineStride_;
-
-    Error drawPixel(uint32_t x, uint32_t y, uint32_t color) const {
-        size_t pos = (top_ + y) * lineStride_ + x + left_;
-        if (pos >= size_in_elements_) {
-            return Error::OutOfBoundsDrawing;
-        }
-        double alfa = (color & 0xff000000) >> 24;
-        alfa /= 255.0;
-        auto acc = buffer_[pos];
-        buffer_[pos] = alfaCombineChannel(0, alfa, color, acc) |
-                       alfaCombineChannel(8, alfa, color, acc) |
-                       alfaCombineChannel(16, alfa, color, acc);
-        return Error::OK;
-    }
-};
-
-template <typename... Elements>
-Error drawElements(std::tuple<Elements...>& layout, const PixelDrawer& drawPixel) {
-    // Error::operator|| is overloaded, so we don't get short circuit evaluation.
-    // But we get the first error that occurs. We will still try and draw the remaining
-    // elements in the order they appear in the layout tuple.
-    return (std::get<Elements>(layout).draw(drawPixel) || ...);
-}
-
-uint32_t setDeviceInfo(DeviceInfo deviceInfo, bool magnified, bool inverted) {
-    sDeviceInfo = deviceInfo;
-    sMagnified = magnified;
-    sInverted = inverted;
-    return 0;
-}
-
-void selectLanguage(const char* language_id) {
-    teeui::localization::selectLangId(language_id);
-}
-
-void translate(LabelImpl* label) {
-    uint64_t textId = label->textId();
-    const char* translation =
-        teeui::localization::lookup(static_cast<teeui::localization::TranslationId>(textId));
-    label->setText({&translation[0], &translation[strlen(translation)]});
-}
-
-template <typename... Elements> void translateLabels(std::tuple<Elements...>& layout) {
-    translate(&std::get<LabelOK>(layout));
-    translate(&std::get<LabelCancel>(layout));
-    translate(&std::get<LabelTitle>(layout));
-    translate(&std::get<LabelHint>(layout));
-}
-
-uint32_t renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t lineStride,
-                            uint32_t* buffer, size_t buffer_size_in_elements_not_bytes) {
-    uint32_t afterLastPixelIndex = 0;
-    if (__builtin_add_overflow(y, h, &afterLastPixelIndex) ||
-        __builtin_add_overflow(afterLastPixelIndex, -1, &afterLastPixelIndex) ||
-        __builtin_mul_overflow(afterLastPixelIndex, lineStride, &afterLastPixelIndex) ||
-        __builtin_add_overflow(afterLastPixelIndex, x, &afterLastPixelIndex) ||
-        __builtin_add_overflow(afterLastPixelIndex, w, &afterLastPixelIndex) ||
-        afterLastPixelIndex > buffer_size_in_elements_not_bytes) {
-        return uint32_t(Error::OutOfBoundsDrawing);
-    }
-    context<ConUIParameters> ctx(sDeviceInfo.mm2px_, sDeviceInfo.dp2px_);
-    ctx.setParam<RightEdgeOfScreen>(pxs(sDeviceInfo.width_));
-    ctx.setParam<BottomOfScreen>(pxs(sDeviceInfo.height_));
-    ctx.setParam<PowerButtonTop>(mms(sDeviceInfo.powerButtonTopMm_));
-    ctx.setParam<PowerButtonBottom>(mms(sDeviceInfo.powerButtonBottomMm_));
-    ctx.setParam<VolUpButtonTop>(mms(sDeviceInfo.volUpButtonTopMm_));
-    ctx.setParam<VolUpButtonBottom>(mms(sDeviceInfo.volUpButtonBottomMm_));
-    if (sMagnified) {
-        ctx.setParam<DefaultFontSize>(18_dp);
-        ctx.setParam<BodyFontSize>(20_dp);
-    } else {
-        ctx.setParam<DefaultFontSize>(14_dp);
-        ctx.setParam<BodyFontSize>(16_dp);
-    }
-
-    if (sInverted) {
-        ctx.setParam<ShieldColor>(kShieldColorInv);
-        ctx.setParam<ColorText>(kTextColorInv);
-        ctx.setParam<ColorBG>(kBackGroundColorInv);
-    } else {
-        ctx.setParam<ShieldColor>(kShieldColor);
-        ctx.setParam<ColorText>(kTextColor);
-        ctx.setParam<ColorBG>(kBackGroundColor);
-    }
-
-    auto layoutInstance = instantiateLayout(ConfUILayout(), ctx);
-
-    translateLabels(layoutInstance);
-
-    uint32_t* begin = buffer + (y * lineStride + x);
-
-    Color bgColor = sInverted ? kBackGroundColorInv : kBackGroundColor;
-
-    for (uint32_t yi = 0; yi < h; ++yi) {
-        for (uint32_t xi = 0; xi < w; ++xi) {
-            begin[xi] = bgColor;
-        }
-        begin += lineStride;
-    }
-    FrameBuffer fb;
-    fb.left_ = x;
-    fb.top_ = y;
-    fb.width_ = w;
-    fb.height_ = h;
-    fb.buffer_ = buffer;
-    fb.size_in_elements_ = buffer_size_in_elements_not_bytes;
-    fb.lineStride_ = lineStride;
-
-    auto pixelDrawer = makePixelDrawer(
-        [&fb](uint32_t x, uint32_t y, Color color) -> Error { return fb.drawPixel(x, y, color); });
-
-    std::get<LabelBody>(layoutInstance)
-        .setText({&*sConfirmationMessage.begin(), &*sConfirmationMessage.end()});
-
-    if (auto error = drawElements(layoutInstance, pixelDrawer)) {
-        return uint32_t(error.code());
-    }
-
-    return 0;  // OK
-}
diff --git a/libteeui/example/touch_button_example.cpp b/libteeui/example/touch_button_example.cpp
new file mode 100644
index 0000000..c909dbb
--- /dev/null
+++ b/libteeui/example/touch_button_example.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "touch_button_example.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "example_utils.h"
+#include "layout/touch_button_layout.h"
+
+namespace teeui {
+namespace example {
+namespace touch_button {
+
+template <typename Layout> static void translateLabels(Layout* layout) {
+    translateLabel<LabelOK>(layout);
+    translateLabel<LabelCancel>(layout);
+    translateLabel<LabelTitle>(layout);
+    translateLabel<LabelHint>(layout);
+}
+
+class GUIStateTouch : public ITeeuiExample {
+  private:
+    bool okTapped_ = false;
+    bool cancelTapped_ = false;
+    EventResult eventResult_ = EventResult::NONE;
+
+  public:
+    bool inverted_;
+    std::string confirmationMessage_;
+    layout_t<ConfUILayout> layoutInstance_ = {};
+
+    GUIStateTouch() : okTapped_(false), cancelTapped_(false), inverted_(false), layoutInstance_{} {}
+
+    bool isOkTapped() const { return okTapped_; }
+    bool isCancelTapped() const { return cancelTapped_; }
+
+    Error tapOk(Event e) {
+        if (e.event_ == EventType::KeyUp) {
+            okTapped_ = true;
+            eventResult_ = EventResult::CONFIRM;
+        }
+        return Error::OK;
+    }
+
+    Error tapCancel(Event e) {
+        if (e.event_ == EventType::KeyUp) {
+            cancelTapped_ = true;
+            eventResult_ = EventResult::CANCEL;
+        }
+        return Error::OK;
+    }
+
+    void selectLanguage(const char* language_id) override {
+        teeui::localization::selectLangId(language_id);
+        translateLabels(&layoutInstance_);
+    }
+
+    void setConfirmationMessage(std::string confirmationMessage) override {
+        confirmationMessage_ = std::move(confirmationMessage);
+        std::get<LabelBody>(layoutInstance_)
+            .setText({&*confirmationMessage_.begin(), &*confirmationMessage_.end()});
+    }
+
+    uint32_t setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted = false) override;
+
+    EventResult onEvent(uint32_t x, uint32_t y, uint32_t) override;
+
+    uint32_t renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t lineStride,
+                                uint32_t* buffer,
+                                size_t buffer_size_in_elements_not_bytes) override;
+};
+
+std::unique_ptr<ITeeuiExample> createTeeuiExample() {
+    return std::make_unique<GUIStateTouch>();
+}
+
+EventResult GUIStateTouch::onEvent(uint32_t x, uint32_t y, uint32_t) {
+    eventResult_ = EventResult::NONE;
+    Event event{x, y, EventType::KeyUp};
+    handleAllEvent(layoutInstance_, event);
+    return eventResult_;
+}
+
+static context<ConfUIParameters> setLayoutParams(DeviceInfo& deviceInfo, bool magnified,
+                                                 bool inverted) {
+    context<ConfUIParameters> ctx(deviceInfo.mm2px_, deviceInfo.dp2px_);
+    ctx.setParam<RightEdgeOfScreen>(pxs(deviceInfo.width_));
+    ctx.setParam<BottomOfScreen>(pxs(deviceInfo.height_));
+    if (magnified) {
+        ctx.setParam<DefaultFontSize>(18_dp);
+        ctx.setParam<BodyFontSize>(20_dp);
+    } else {
+        ctx.setParam<DefaultFontSize>(14_dp);
+        ctx.setParam<BodyFontSize>(16_dp);
+    }
+    if (inverted) {
+        ctx.setParam<ShieldColor>(kShieldColorInv);
+        ctx.setParam<ColorText>(kTextColorInv);
+        ctx.setParam<ColorBG>(kBackGroundColorInv);
+        ctx.setParam<ColorButton>(kShieldColorInv);
+    } else {
+        ctx.setParam<ShieldColor>(kShieldColor);
+        ctx.setParam<ColorText>(kTextColor);
+        ctx.setParam<ColorBG>(kBackGroundColor);
+        ctx.setParam<ColorButton>(kShieldColor);
+    }
+    return ctx;
+}
+
+uint32_t GUIStateTouch::setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted) {
+    layoutInstance_ =
+        instantiateLayout(ConfUILayout(), setLayoutParams(device_info, magnified, inverted));
+    inverted_ = inverted;
+    std::get<LabelOK>(layoutInstance_)
+        .setCB(makeCallback<Error, Event>(
+            [](Event e, void* p) -> Error { return reinterpret_cast<GUIStateTouch*>(p)->tapOk(e); },
+            this));
+    std::get<LabelCancel>(layoutInstance_)
+        .setCB(makeCallback<Error, Event>(
+            [](Event e, void* p) -> Error {
+                return reinterpret_cast<GUIStateTouch*>(p)->tapCancel(e);
+            },
+            this));
+    return 0;
+}
+
+uint32_t GUIStateTouch::renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h,
+                                           uint32_t lineStride, uint32_t* buffer,
+                                           size_t buffer_size_in_elements_not_bytes) {
+    uint32_t afterLastPixelIndex = 0;
+    if (__builtin_add_overflow(y, h, &afterLastPixelIndex) ||
+        __builtin_add_overflow(afterLastPixelIndex, -1, &afterLastPixelIndex) ||
+        __builtin_mul_overflow(afterLastPixelIndex, lineStride, &afterLastPixelIndex) ||
+        __builtin_add_overflow(afterLastPixelIndex, x, &afterLastPixelIndex) ||
+        __builtin_add_overflow(afterLastPixelIndex, w, &afterLastPixelIndex) ||
+        afterLastPixelIndex > buffer_size_in_elements_not_bytes) {
+        return uint32_t(Error::OutOfBoundsDrawing);
+    }
+
+    uint32_t* begin = buffer + (y * lineStride + x);
+
+    Color bgColor = inverted_ ? kBackGroundColorInv : kBackGroundColor;
+
+    for (uint32_t yi = 0; yi < h; ++yi) {
+        for (uint32_t xi = 0; xi < w; ++xi) {
+            begin[xi] = bgColor;
+        }
+        begin += lineStride;
+    }
+    FrameBuffer fb;
+    fb.left_ = x;
+    fb.top_ = y;
+    fb.width_ = w;
+    fb.height_ = h;
+    fb.buffer_ = buffer;
+    fb.size_in_elements_ = buffer_size_in_elements_not_bytes;
+    fb.lineStride_ = lineStride;
+
+    auto pixelDrawer = makePixelDrawer(
+        [&fb](uint32_t x, uint32_t y, Color color) -> Error { return fb.drawPixel(x, y, color); });
+
+    if (auto error = drawElements(layoutInstance_, pixelDrawer)) {
+        return uint32_t(error.code());
+    }
+
+    return 0;  // OK
+}
+
+}  // namespace touch_button
+}  // namespace example
+}  // namespace teeui
diff --git a/libteeui/example/touch_button_example.h b/libteeui/example/touch_button_example.h
new file mode 100644
index 0000000..90b8554
--- /dev/null
+++ b/libteeui/example/touch_button_example.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <teeui/example/example.h>
+
+namespace teeui {
+namespace example {
+namespace touch_button {
+
+std::unique_ptr<ITeeuiExample> createTeeuiExample();
+
+}
+}  // namespace example
+}  // namespace teeui
\ No newline at end of file
diff --git a/libteeui/include/teeui/example/example.h b/libteeui/include/teeui/example/example.h
new file mode 100644
index 0000000..07df995
--- /dev/null
+++ b/libteeui/include/teeui/example/example.h
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+#include <string>
+
+#pragma once
+
+namespace teeui {
+namespace example {
+
+struct DeviceInfo {
+    uint32_t width_;
+    uint32_t height_;
+    double dp2px_;
+    double mm2px_;
+    double powerButtonTopMm_;
+    double powerButtonBottomMm_;
+    double volUpButtonTopMm_;
+    double volUpButtonBottomMm_;
+};
+
+enum class EventResult : uint32_t {
+    NONE,
+    CONFIRM,
+    CANCEL,
+};
+
+class ITeeuiExample {
+  public:
+    virtual void selectLanguage(const char*) = 0;
+    virtual void setConfirmationMessage(std::string) = 0;
+    virtual uint32_t setDeviceInfo(DeviceInfo, bool, bool) = 0;
+    virtual uint32_t renderUIIntoBuffer(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t*,
+                                        size_t) = 0;
+    virtual EventResult onEvent(uint32_t x, uint32_t y, uint32_t) = 0;
+
+    virtual ~ITeeuiExample() {}
+};
+
+enum class Examples : uint32_t {
+    PhysButton,
+    TouchButton,
+};
+
+static constexpr const int8_t kFrameBufferError = -1;
+static constexpr const int8_t kLayoutExampleError = -2;
+static constexpr const char* kPhysButtonLayout = "Physical button";
+static constexpr const char* kTouchButtonLayout = "Touch button";
+
+static constexpr const char* kAvailableLayouts[] = {
+    kPhysButtonLayout,
+    kTouchButtonLayout,
+};
+
+#define NUM_LAYOUTS ((sizeof(kAvailableLayouts) / sizeof(kAvailableLayouts[0])))
+
+std::unique_ptr<ITeeuiExample> createExample(Examples example);
+
+}  // namespace example
+}  // namespace teeui
diff --git a/libteeui/include/teeui/example/teeui.h b/libteeui/include/teeui/example/teeui.h
deleted file mode 100644
index 3ee37f4..0000000
--- a/libteeui/include/teeui/example/teeui.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef TEEUI_LIBTEEUI_INCLUDE_TEEUI_H_
-#define TEEUI_LIBTEEUI_INCLUDE_TEEUI_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-struct DeviceInfo {
-    uint32_t width_;
-    uint32_t height_;
-    double dp2px_;
-    double mm2px_;
-    double powerButtonTopMm_;
-    double powerButtonBottomMm_;
-    double volUpButtonTopMm_;
-    double volUpButtonBottomMm_;
-};
-
-uint32_t setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted = false);
-uint32_t renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t lineStride,
-                            uint32_t* buffer, size_t buffer_size_in_elements_not_bytes);
-
-void selectLanguage(const char* language_id);
-
-void setConfirmationMessage(const char* confirmationMessage);
-
-#endif  // TEEUI_LIBTEEUI_INCLUDE_TEEUI_H_
diff --git a/libteeui/include/teeui/label.h b/libteeui/include/teeui/label.h
index b3b9114..845922a 100644
--- a/libteeui/include/teeui/label.h
+++ b/libteeui/include/teeui/label.h
@@ -83,6 +83,9 @@
     uint64_t textId() const { return textId_; }
 
     Error draw(const PixelDrawer& drawPixel, const Box<pxs>& bounds, LineInfo* lineInfo);
+    void setCB(CallbackEvent cbEvent) { cbEvent_ = std::move(cbEvent); }
+    optional<CallbackEvent> getCB() { return cbEvent_; }
+    Error hit(const Event& event, const Box<pxs>& bounds);
 
   private:
     pxs fontSize_;
@@ -93,6 +96,7 @@
     Color textColor_;
     FontBuffer font_;
     uint64_t textId_;
+    optional<CallbackEvent> cbEvent_;
 };
 
 /**
@@ -124,6 +128,8 @@
         LabelImpl::LineInfo lineInfo = {Derived::label_number_of_lines, lines};
         return LabelImpl::draw(drawPixel, this->bounds_, &lineInfo);
     }
+
+    Error hit(const Event& event) { return LabelImpl::hit(event, this->bounds_); }
 };
 
 }  //  namespace teeui
diff --git a/libteeui/include/teeui/utils.h b/libteeui/include/teeui/utils.h
index 850d1b0..985761a 100644
--- a/libteeui/include/teeui/utils.h
+++ b/libteeui/include/teeui/utils.h
@@ -259,7 +259,6 @@
     }
 };
 
-template <typename Param, typename Numeric = DefaultNumericType> class context;
 template <typename T1, typename T2, typename Numeric, template <typename> class Op> struct BinOp;
 
 template <typename T1, typename T2, typename Numeric> using add = BinOp<T1, T2, Numeric, Add>;
@@ -435,6 +434,8 @@
     constexpr static const bool value = true;
 };
 
+template <typename Param, typename Numeric = DefaultNumericType> class context;
+
 template <typename... ParamsNames, typename... ParamTypes, typename Numeric>
 class context<MetaList<MetaParam<ParamsNames, ParamTypes>...>, Numeric> {
     Numeric mm2px_;
@@ -858,6 +859,18 @@
 }
 #endif
 
+enum class EventType : uint8_t {
+    KeyDown,
+    KeyUp,
+    KeyMoved,
+};
+
+struct Event {
+    uint32_t x_;
+    uint32_t y_;
+    EventType event_;
+};
+
 template <typename Fn> struct Callback;
 
 template <typename Ret, typename... Args> struct Callback<Ret(Args...)> {
@@ -882,6 +895,7 @@
     }
 };
 
+using CallbackEvent = Callback<Error(Event)>;
 using PixelDrawer = Callback<Error(uint32_t, uint32_t, Color)>;
 
 template <typename Fn>
@@ -900,6 +914,7 @@
                   context = Derived::dim_h} {}
 
     Error draw(const PixelDrawer&) { return Error::OK; }
+    Error hit(const Event&) { return Error::OK; }
 };
 
 template <typename... Elements, typename Context>
diff --git a/libteeui/src/label.cpp b/libteeui/src/label.cpp
index 8267bf2..34d8eb0 100644
--- a/libteeui/src/label.cpp
+++ b/libteeui/src/label.cpp
@@ -136,4 +136,14 @@
     return Error::OK;
 }
 
+Error LabelImpl::hit(const Event& event, const Box<pxs>& bounds) {
+    using intpxs = Coordinate<px, int64_t>;
+    if (bounds.contains(Point<intpxs>(event.x_, event.y_))) {
+        optional<CallbackEvent> callback = getCB();
+        if (callback) {
+            return callback.value()(event);
+        }
+    }
+    return Error::OK;
+}
 }  // namespace teeui
diff --git a/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h b/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h
index 10b10a8..b5bb08d 100644
--- a/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h
+++ b/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h
@@ -10,10 +10,10 @@
 /*
  * Class:     com_android_framebufferizer_NativeRenderer
  * Method:    setDeviceInfo
- * Signature: (Lcom/android/framebufferizer/utils/DeviceInfo;ZZ)I
+ * Signature: (Lcom/android/framebufferizer/utils/DeviceInfo;ZZLjava/lang/String;)I
  */
 JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_setDeviceInfo(
-    JNIEnv*, jclass, jobject, jboolean, jboolean);
+    JNIEnv*, jclass, jobject, jboolean, jboolean, jstring);
 
 /*
  * Class:     com_android_framebufferizer_NativeRenderer
@@ -41,12 +41,28 @@
 
 /*
  * Class:     com_android_framebufferizer_NativeRenderer
+ * Method:    getAvailableLayouts
+ * Signature: ()[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_com_android_framebufferizer_NativeRenderer_getAvailableLayouts(JNIEnv*, jclass);
+
+/*
+ * Class:     com_android_framebufferizer_NativeRenderer
  * Method:    setConfimationMessage
  * Signature: (Ljava/lang/String;)V
  */
 JNIEXPORT void JNICALL
 Java_com_android_framebufferizer_NativeRenderer_setConfimationMessage(JNIEnv*, jclass, jstring);
 
+/*
+ * Class:     com_android_framebufferizer_NativeRenderer
+ * Method:    onEvent
+ * Signature: (III)I
+ */
+JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_onEvent(JNIEnv*, jclass,
+                                                                               jint, jint, jint);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libteeui_jni/libteeui_jni.cpp b/libteeui_jni/libteeui_jni.cpp
index 960140b..1beae12 100644
--- a/libteeui_jni/libteeui_jni.cpp
+++ b/libteeui_jni/libteeui_jni.cpp
@@ -16,7 +16,7 @@
  */
 
 #include <jni.h>
-#include <teeui/example/teeui.h>
+#include <teeui/example/example.h>
 #include <teeui/localization/ConfirmationUITranslations.h>
 
 using teeui::localization::getLanguages;
@@ -124,13 +124,18 @@
 using JByteArray = JArray<jbyteArray>;
 using JString = JArray<jstring>;
 
+static std::unique_ptr<teeui::example::ITeeuiExample> sCurrentExample;
+
 /*
  * Class:     com_android_framebufferizer_NativeRenderer
  * Method:    setDeviceInfo
- * Signature: (Lcom/android/framebufferizer/utils/DeviceInfo;ZZ)I
+ * Signature: (Lcom/android/framebufferizer/utils/DeviceInfo;ZZLjava/lang/String;)I
  */
 extern "C" JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_setDeviceInfo(
-    JNIEnv* env, jclass, jobject jDeviceInfo, jboolean magnified, jboolean inverted) {
+    JNIEnv* env, jclass, jobject jDeviceInfo, jboolean magnified, jboolean inverted,
+    jstring layout_type) {
+    JString layout(env, layout_type);
+    using namespace teeui::example;
     jclass cDeviceInfo = env->FindClass("Lcom/android/framebufferizer/utils/DeviceInfo;");
     jmethodID method = env->GetMethodID(cDeviceInfo, "getWidthPx", "()I");
     DeviceInfo device_info;
@@ -149,7 +154,10 @@
     device_info.volUpButtonTopMm_ = env->CallDoubleMethod(jDeviceInfo, method);
     method = env->GetMethodID(cDeviceInfo, "getVolUpButtonBottomMm", "()D");
     device_info.volUpButtonBottomMm_ = env->CallDoubleMethod(jDeviceInfo, method);
-    return setDeviceInfo(device_info, magnified, inverted);
+    sCurrentExample =
+        createExample((strcmp(layout.begin(), kTouchButtonLayout) == 0) ? Examples::TouchButton
+                                                                        : Examples::PhysButton);
+    return sCurrentExample->setDeviceInfo(device_info, magnified, inverted);
 }
 
 /*
@@ -161,10 +169,14 @@
     JNIEnv* env, jclass, jint x, jint y, jint width, jint height, jint lineStride,
     jintArray jbuffer) {
     JIntArray buffer(env, jbuffer);
-    if (!buffer) return 1;
-    return renderUIIntoBuffer((uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height,
-                              (uint32_t)lineStride, (uint32_t*)buffer.begin(), buffer.size());
+    using namespace teeui::example;
+    if (!buffer) return kFrameBufferError;
+    if (!sCurrentExample) return kLayoutExampleError;
+    return sCurrentExample->renderUIIntoBuffer((uint32_t)x, (uint32_t)y, (uint32_t)width,
+                                               (uint32_t)height, (uint32_t)lineStride,
+                                               (uint32_t*)buffer.begin(), buffer.size());
 }
+
 /*
  * Class:     com_android_confirmationui_Translation_selectLangID
  * Method:    selectLangID
@@ -172,10 +184,8 @@
  */
 extern "C" JNIEXPORT void JNICALL
 Java_com_android_framebufferizer_NativeRenderer_setLanguage(JNIEnv* env, jclass, jstring jlang_id) {
-    jboolean isCopy = false;
-    const char* lang_id = (env)->GetStringUTFChars(jlang_id, &isCopy);
-    selectLanguage(lang_id);
-    (env)->ReleaseStringUTFChars(jlang_id, lang_id);
+    JString lang_id(env, jlang_id);
+    if (sCurrentExample) sCurrentExample->selectLanguage(lang_id.begin());
 }
 /*
  * Class:     com_android_confirmationui_Translation_selectLangID
@@ -197,6 +207,28 @@
 
     return language_ids;
 }
+
+/*
+ * Class:     com_android_framebufferizer_NativeRenderer
+ * Method:    getAvailableLayouts
+ * Signature: ()[Ljava/lang/String;
+ */
+extern "C" JNIEXPORT jobjectArray JNICALL
+Java_com_android_framebufferizer_NativeRenderer_getAvailableLayouts(JNIEnv* env, jclass) {
+    using namespace teeui::example;
+    jobjectArray available_layouts;
+    const char* const* native_data = kAvailableLayouts;
+    size_t list_size = NUM_LAYOUTS;
+
+    available_layouts = (jobjectArray)env->NewObjectArray(
+        list_size, env->FindClass("java/lang/String"), env->NewStringUTF(""));
+
+    for (size_t i = 0; i < list_size; i++)
+        env->SetObjectArrayElement(available_layouts, i, env->NewStringUTF(native_data[i]));
+
+    return available_layouts;
+}
+
 /*
  * Class:     com_android_framebufferizer_NativeRenderer
  * Method:    setConfimationMessage
@@ -206,5 +238,18 @@
 Java_com_android_framebufferizer_NativeRenderer_setConfimationMessage(
     JNIEnv* env, jclass, jstring jConfirmationMessage) {
     JString confirmationMessage(env, jConfirmationMessage);
-    setConfirmationMessage(confirmationMessage.begin());
+    if (sCurrentExample) sCurrentExample->setConfirmationMessage(confirmationMessage.begin());
 }
+
+/*
+ * Class:     com_android_framebufferizer_NativeRenderer
+ * Method:    onEvent
+ * Signature: (III)I
+ */
+extern "C" JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_onEvent(
+    JNIEnv*, jclass, jint x, jint y, jint event) {
+    if (sCurrentExample) {
+        return (jint)sCurrentExample->onEvent((uint32_t)x, (uint32_t)y, (uint32_t)event);
+    }
+    return 0;
+}
\ No newline at end of file
diff --git a/test/include/teeui/test/teeui_render_test.h b/test/include/teeui/test/teeui_render_test.h
index e405032..cc28afd 100644
--- a/test/include/teeui/test/teeui_render_test.h
+++ b/test/include/teeui/test/teeui_render_test.h
@@ -23,7 +23,8 @@
 // Initializes the test with the device configuration with command line params.
 extern void initRenderTest(int argc, char** argv);
 
-extern int runRenderTest(const char* language, bool magnified);
+extern int runRenderTest(const char* language, bool magnified, bool inverted = false,
+                         const char* confirmationMessage = "", const char* layout = "");
 
 }  // namespace test
 
diff --git a/test/teeui_device_config.cpp b/test/teeui_device_config.cpp
index 5d271bb..ff8bf71 100644
--- a/test/teeui_device_config.cpp
+++ b/test/teeui_device_config.cpp
@@ -19,7 +19,7 @@
 #include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
-#include <teeui/example/teeui.h>
+#include <teeui/example/example.h>
 #include <unistd.h>
 
 #include "teeui_device_config.h"
@@ -31,20 +31,29 @@
 
 namespace test {
 
+using namespace example;
+
 void initRenderTest(int argc, char** argv) {
     ::teeui::test::TeeuiRenderTest::Instance()->initFromOptions(argc, argv);
 }
 
-int runRenderTest(const char* language, bool magnified) {
+int runRenderTest(const char* language, bool magnified, bool inverted,
+                  const char* confirmationMessage, const char* layout) {
+    std::unique_ptr<ITeeuiExample> sCurrentExample = createExample(
+        (strcmp(layout, kTouchButtonLayout) == 0) ? Examples::TouchButton : Examples::PhysButton);
+
     DeviceInfo* device_info_ptr = &TeeuiRenderTest::Instance()->device_info;
-    selectLanguage(language);
-    setDeviceInfo(*device_info_ptr, magnified);
+    sCurrentExample->setDeviceInfo(*device_info_ptr, magnified, inverted);
     uint32_t w = device_info_ptr->width_;
     uint32_t h = device_info_ptr->height_;
     uint32_t linestride = w;
     uint32_t buffer_size = h * linestride;
     std::vector<uint32_t> buffer(buffer_size);
-    int error = renderUIIntoBuffer(0, 0, w, h, linestride, buffer.data(), buffer_size);
+    sCurrentExample->setConfirmationMessage(confirmationMessage);
+    sCurrentExample->selectLanguage(language);
+
+    int error =
+        sCurrentExample->renderUIIntoBuffer(0, 0, w, h, linestride, buffer.data(), buffer_size);
     return error;
 }
 
diff --git a/test/teeui_device_config.h b/test/teeui_device_config.h
index 58cb2cd..7bcfa5a 100644
--- a/test/teeui_device_config.h
+++ b/test/teeui_device_config.h
@@ -21,7 +21,7 @@
 #include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
-#include <teeui/example/teeui.h>
+#include <teeui/example/example.h>
 #include <unistd.h>
 
 #include <teeui/test/teeui_render_test.h>
@@ -35,7 +35,7 @@
 class TeeuiRenderTest : public ::testing::Test {
   public:
     // Default device configuration set to Blueline
-    DeviceInfo device_info = {
+    example::DeviceInfo device_info = {
         1080,         // width in px
         2160,         // height om px
         2.62135,      // dp2px pixel per density independent pixel
diff --git a/test/teeui_draw_label_text_test.cpp b/test/teeui_draw_label_text_test.cpp
index e37d8c0..1f08551 100644
--- a/test/teeui_draw_label_text_test.cpp
+++ b/test/teeui_draw_label_text_test.cpp
@@ -14,14 +14,12 @@
  * limitations under the License.
  */
 
-/* Generated by generate_teeui_render_tests - DO NOT EDIT */
-
 #include <getopt.h>
 #include <gtest/gtest.h>
 #include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
-#include <teeui/example/teeui.h>
+#include <teeui/example/example.h>
 #include <unistd.h>
 
 #include "teeui_device_config.h"
@@ -43,39 +41,67 @@
 
 class TeeuiDrawLabelTextTest : public ::testing::Test {};
 
-TEST_F(TeeuiDrawLabelTextTest, Test_12_char_8_group) {
-    setConfirmationMessage(kText12Character8Group);
-    int error = runRenderTest("en", false /* magnified */);
+TEST_F(TeeuiDrawLabelTextTest, Test_12_char_8_group_phys_button_layout) {
+    int error = runRenderTest("en", false /* magnified */, &kText12Character8Group[0]);
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiDrawLabelTextTest, Test_12_char_8_group_M) {
-    setConfirmationMessage(kText12Character8Group);
-    int error = runRenderTest("en", true /* magnified */);
+TEST_F(TeeuiDrawLabelTextTest, Test_12_char_8_group_phys_button_layout_magnified) {
+    int error = runRenderTest("en", true /* magnified */, &kText12Character8Group[0]);
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiDrawLabelTextTest, Test_100_char_1_group) {
-    setConfirmationMessage(kText100Character1Group);
-    int error = runRenderTest("en", false /* magnified */);
+TEST_F(TeeuiDrawLabelTextTest, Test_100_char_1_group_phys_button_layout) {
+    int error = runRenderTest("en", false /* magnified */, &kText100Character1Group[0]);
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiDrawLabelTextTest, Test_100_char_1_group_M) {
-    setConfirmationMessage(kText100Character1Group);
-    int error = runRenderTest("en", true /* magnified */);
+TEST_F(TeeuiDrawLabelTextTest, Test_100_char_1_group_phys_button_layout_magnified) {
+    int error = runRenderTest("en", true /* magnified */, &kText100Character1Group[0]);
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiDrawLabelTextTest, Test_empty_text) {
-    setConfirmationMessage("");
-    int error = runRenderTest("en", false /* magnified */);
+TEST_F(TeeuiDrawLabelTextTest, Test_empty_text_phys_button_layout) {
+    int error = runRenderTest("en", false /* magnified */, "");
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiDrawLabelTextTest, Test_empty_text_M) {
-    setConfirmationMessage("");
-    int error = runRenderTest("en", true /* magnified */);
+TEST_F(TeeuiDrawLabelTextTest, Test_empty_text_phys_button_layout_magnified) {
+    int error = runRenderTest("en", true /* magnified */, "");
+    ASSERT_EQ(error, 0);
+}
+
+TEST_F(TeeuiDrawLabelTextTest, Test_12_char_8_group_touch_button_layout) {
+    int error = runRenderTest("en", false /* magnified */, &kText12Character8Group[0],
+                              example::kTouchButtonLayout);
+    ASSERT_EQ(error, 0);
+}
+
+TEST_F(TeeuiDrawLabelTextTest, Test_12_char_8_group_touch_button_layout_magnified) {
+    int error = runRenderTest("en", true /* magnified */, &kText12Character8Group[0],
+                              example::kTouchButtonLayout);
+    ASSERT_EQ(error, 0);
+}
+
+TEST_F(TeeuiDrawLabelTextTest, Test_100_char_1_group_touch_button_layout) {
+    int error = runRenderTest("en", false /* magnified */, &kText100Character1Group[0],
+                              example::kTouchButtonLayout);
+    ASSERT_EQ(error, 0);
+}
+
+TEST_F(TeeuiDrawLabelTextTest, Test_100_char_1_group_touch_button_layout_magnified) {
+    int error = runRenderTest("en", true /* magnified */, &kText100Character1Group[0],
+                              example::kTouchButtonLayout);
+    ASSERT_EQ(error, 0);
+}
+
+TEST_F(TeeuiDrawLabelTextTest, Test_empty_text_touch_button_layout) {
+    int error = runRenderTest("en", false /* magnified */, "", example::kTouchButtonLayout);
+    ASSERT_EQ(error, 0);
+}
+
+TEST_F(TeeuiDrawLabelTextTest, Test_empty_text_touch_button_layout_magnified) {
+    int error = runRenderTest("en", true /* magnified */, "", example::kTouchButtonLayout);
     ASSERT_EQ(error, 0);
 }
 
diff --git a/test/teeui_locale_test.cpp b/test/teeui_locale_test.cpp
index dfd568e..c81921b 100644
--- a/test/teeui_locale_test.cpp
+++ b/test/teeui_locale_test.cpp
@@ -21,7 +21,7 @@
 #include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
-#include <teeui/example/teeui.h>
+#include <teeui/example/example.h>
 #include <unistd.h>
 
 #include "teeui_device_config.h"
@@ -40,7 +40,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_en_M) {
+TEST_F(TeeuiLocaleTest, Test_en_magnified) {
     int error = runRenderTest("en", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -50,7 +50,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AF_M) {
+TEST_F(TeeuiLocaleTest, Test_AF_magnified) {
     int error = runRenderTest("af", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -60,7 +60,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AM_M) {
+TEST_F(TeeuiLocaleTest, Test_AM_magnified) {
     int error = runRenderTest("am", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -70,7 +70,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AR_M) {
+TEST_F(TeeuiLocaleTest, Test_AR_magnified) {
     int error = runRenderTest("ar", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -80,7 +80,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AR_EG_M) {
+TEST_F(TeeuiLocaleTest, Test_AR_EG_magnified) {
     int error = runRenderTest("ar-EG", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -90,7 +90,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AR_JO_M) {
+TEST_F(TeeuiLocaleTest, Test_AR_JO_magnified) {
     int error = runRenderTest("ar-JO", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -100,7 +100,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AR_MA_M) {
+TEST_F(TeeuiLocaleTest, Test_AR_MA_magnified) {
     int error = runRenderTest("ar-MA", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -110,7 +110,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AR_SA_M) {
+TEST_F(TeeuiLocaleTest, Test_AR_SA_magnified) {
     int error = runRenderTest("ar-SA", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -120,7 +120,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AR_XB_M) {
+TEST_F(TeeuiLocaleTest, Test_AR_XB_magnified) {
     int error = runRenderTest("ar-XB", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -130,7 +130,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AS_M) {
+TEST_F(TeeuiLocaleTest, Test_AS_magnified) {
     int error = runRenderTest("as", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -140,7 +140,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_AZ_M) {
+TEST_F(TeeuiLocaleTest, Test_AZ_magnified) {
     int error = runRenderTest("az", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -150,7 +150,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_BE_M) {
+TEST_F(TeeuiLocaleTest, Test_BE_magnified) {
     int error = runRenderTest("be", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -160,7 +160,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_BG_M) {
+TEST_F(TeeuiLocaleTest, Test_BG_magnified) {
     int error = runRenderTest("bg", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -170,7 +170,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_BN_M) {
+TEST_F(TeeuiLocaleTest, Test_BN_magnified) {
     int error = runRenderTest("bn", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -180,7 +180,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_BS_M) {
+TEST_F(TeeuiLocaleTest, Test_BS_magnified) {
     int error = runRenderTest("bs", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -190,7 +190,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_CA_M) {
+TEST_F(TeeuiLocaleTest, Test_CA_magnified) {
     int error = runRenderTest("ca", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -200,7 +200,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_CS_M) {
+TEST_F(TeeuiLocaleTest, Test_CS_magnified) {
     int error = runRenderTest("cs", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -210,7 +210,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_DA_M) {
+TEST_F(TeeuiLocaleTest, Test_DA_magnified) {
     int error = runRenderTest("da", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -220,7 +220,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_DE_M) {
+TEST_F(TeeuiLocaleTest, Test_DE_magnified) {
     int error = runRenderTest("de", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -230,7 +230,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_DE_AT_M) {
+TEST_F(TeeuiLocaleTest, Test_DE_AT_magnified) {
     int error = runRenderTest("de-AT", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -240,7 +240,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_DE_CH_M) {
+TEST_F(TeeuiLocaleTest, Test_DE_CH_magnified) {
     int error = runRenderTest("de-CH", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -250,7 +250,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EL_M) {
+TEST_F(TeeuiLocaleTest, Test_EL_magnified) {
     int error = runRenderTest("el", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -260,7 +260,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_AU_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_AU_magnified) {
     int error = runRenderTest("en-AU", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -270,7 +270,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_CA_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_CA_magnified) {
     int error = runRenderTest("en-CA", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -280,7 +280,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_GB_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_GB_magnified) {
     int error = runRenderTest("en-GB", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -290,7 +290,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_IE_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_IE_magnified) {
     int error = runRenderTest("en-IE", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -300,7 +300,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_IN_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_IN_magnified) {
     int error = runRenderTest("en-IN", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -310,7 +310,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_NZ_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_NZ_magnified) {
     int error = runRenderTest("en-NZ", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -320,7 +320,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_SG_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_SG_magnified) {
     int error = runRenderTest("en-SG", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -330,7 +330,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_XA_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_XA_magnified) {
     int error = runRenderTest("en-XA", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -340,7 +340,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_XC_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_XC_magnified) {
     int error = runRenderTest("en-XC", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -350,7 +350,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EN_ZA_M) {
+TEST_F(TeeuiLocaleTest, Test_EN_ZA_magnified) {
     int error = runRenderTest("en-ZA", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -360,7 +360,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_magnified) {
     int error = runRenderTest("es", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -370,7 +370,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_419_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_419_magnified) {
     int error = runRenderTest("es-419", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -380,7 +380,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_AR_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_AR_magnified) {
     int error = runRenderTest("es-AR", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -390,7 +390,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_BO_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_BO_magnified) {
     int error = runRenderTest("es-BO", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -400,7 +400,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_CL_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_CL_magnified) {
     int error = runRenderTest("es-CL", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -410,7 +410,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_CO_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_CO_magnified) {
     int error = runRenderTest("es-CO", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -420,7 +420,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_CR_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_CR_magnified) {
     int error = runRenderTest("es-CR", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -430,7 +430,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_DO_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_DO_magnified) {
     int error = runRenderTest("es-DO", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -440,7 +440,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_EC_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_EC_magnified) {
     int error = runRenderTest("es-EC", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -450,7 +450,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_GT_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_GT_magnified) {
     int error = runRenderTest("es-GT", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -460,7 +460,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_HN_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_HN_magnified) {
     int error = runRenderTest("es-HN", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -470,7 +470,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_MX_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_MX_magnified) {
     int error = runRenderTest("es-MX", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -480,7 +480,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_NI_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_NI_magnified) {
     int error = runRenderTest("es-NI", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -490,7 +490,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_PA_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_PA_magnified) {
     int error = runRenderTest("es-PA", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -500,7 +500,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_PE_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_PE_magnified) {
     int error = runRenderTest("es-PE", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -510,7 +510,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_PR_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_PR_magnified) {
     int error = runRenderTest("es-PR", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -520,7 +520,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_PY_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_PY_magnified) {
     int error = runRenderTest("es-PY", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -530,7 +530,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_SV_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_SV_magnified) {
     int error = runRenderTest("es-SV", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -540,7 +540,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_US_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_US_magnified) {
     int error = runRenderTest("es-US", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -550,7 +550,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_UY_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_UY_magnified) {
     int error = runRenderTest("es-UY", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -560,7 +560,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ES_VE_M) {
+TEST_F(TeeuiLocaleTest, Test_ES_VE_magnified) {
     int error = runRenderTest("es-VE", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -570,7 +570,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ET_M) {
+TEST_F(TeeuiLocaleTest, Test_ET_magnified) {
     int error = runRenderTest("et", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -580,7 +580,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_EU_M) {
+TEST_F(TeeuiLocaleTest, Test_EU_magnified) {
     int error = runRenderTest("eu", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -590,7 +590,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_FA_M) {
+TEST_F(TeeuiLocaleTest, Test_FA_magnified) {
     int error = runRenderTest("fa", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -600,7 +600,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_FI_M) {
+TEST_F(TeeuiLocaleTest, Test_FI_magnified) {
     int error = runRenderTest("fi", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -610,7 +610,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_FIL_M) {
+TEST_F(TeeuiLocaleTest, Test_FIL_magnified) {
     int error = runRenderTest("fil", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -620,7 +620,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_FR_M) {
+TEST_F(TeeuiLocaleTest, Test_FR_magnified) {
     int error = runRenderTest("fr", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -630,7 +630,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_FR_CA_M) {
+TEST_F(TeeuiLocaleTest, Test_FR_CA_magnified) {
     int error = runRenderTest("fr-CA", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -640,7 +640,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_FR_CH_M) {
+TEST_F(TeeuiLocaleTest, Test_FR_CH_magnified) {
     int error = runRenderTest("fr-CH", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -650,7 +650,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_GL_M) {
+TEST_F(TeeuiLocaleTest, Test_GL_magnified) {
     int error = runRenderTest("gl", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -660,7 +660,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_GSW_M) {
+TEST_F(TeeuiLocaleTest, Test_GSW_magnified) {
     int error = runRenderTest("gsw", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -670,7 +670,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_GU_M) {
+TEST_F(TeeuiLocaleTest, Test_GU_magnified) {
     int error = runRenderTest("gu", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -680,7 +680,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_HE_M) {
+TEST_F(TeeuiLocaleTest, Test_HE_magnified) {
     int error = runRenderTest("he", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -690,7 +690,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_HI_M) {
+TEST_F(TeeuiLocaleTest, Test_HI_magnified) {
     int error = runRenderTest("hi", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -700,7 +700,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_HR_M) {
+TEST_F(TeeuiLocaleTest, Test_HR_magnified) {
     int error = runRenderTest("hr", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -710,7 +710,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_HU_M) {
+TEST_F(TeeuiLocaleTest, Test_HU_magnified) {
     int error = runRenderTest("hu", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -720,7 +720,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_HY_M) {
+TEST_F(TeeuiLocaleTest, Test_HY_magnified) {
     int error = runRenderTest("hy", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -730,7 +730,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ID_M) {
+TEST_F(TeeuiLocaleTest, Test_ID_magnified) {
     int error = runRenderTest("id", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -740,7 +740,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_IN_M) {
+TEST_F(TeeuiLocaleTest, Test_IN_magnified) {
     int error = runRenderTest("in", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -750,7 +750,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_IS_M) {
+TEST_F(TeeuiLocaleTest, Test_IS_magnified) {
     int error = runRenderTest("is", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -760,7 +760,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_IT_M) {
+TEST_F(TeeuiLocaleTest, Test_IT_magnified) {
     int error = runRenderTest("it", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -770,7 +770,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_IW_M) {
+TEST_F(TeeuiLocaleTest, Test_IW_magnified) {
     int error = runRenderTest("iw", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -780,7 +780,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_JA_M) {
+TEST_F(TeeuiLocaleTest, Test_JA_magnified) {
     int error = runRenderTest("ja", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -790,7 +790,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_KA_M) {
+TEST_F(TeeuiLocaleTest, Test_KA_magnified) {
     int error = runRenderTest("ka", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -800,7 +800,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_KK_M) {
+TEST_F(TeeuiLocaleTest, Test_KK_magnified) {
     int error = runRenderTest("kk", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -810,7 +810,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_KM_M) {
+TEST_F(TeeuiLocaleTest, Test_KM_magnified) {
     int error = runRenderTest("km", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -820,7 +820,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_KN_M) {
+TEST_F(TeeuiLocaleTest, Test_KN_magnified) {
     int error = runRenderTest("kn", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -830,7 +830,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_KO_M) {
+TEST_F(TeeuiLocaleTest, Test_KO_magnified) {
     int error = runRenderTest("ko", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -840,7 +840,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_KY_M) {
+TEST_F(TeeuiLocaleTest, Test_KY_magnified) {
     int error = runRenderTest("ky", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -850,7 +850,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_LN_M) {
+TEST_F(TeeuiLocaleTest, Test_LN_magnified) {
     int error = runRenderTest("ln", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -860,7 +860,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_LO_M) {
+TEST_F(TeeuiLocaleTest, Test_LO_magnified) {
     int error = runRenderTest("lo", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -870,7 +870,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_LT_M) {
+TEST_F(TeeuiLocaleTest, Test_LT_magnified) {
     int error = runRenderTest("lt", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -880,7 +880,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_LV_M) {
+TEST_F(TeeuiLocaleTest, Test_LV_magnified) {
     int error = runRenderTest("lv", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -890,7 +890,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_MK_M) {
+TEST_F(TeeuiLocaleTest, Test_MK_magnified) {
     int error = runRenderTest("mk", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -900,7 +900,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ML_M) {
+TEST_F(TeeuiLocaleTest, Test_ML_magnified) {
     int error = runRenderTest("ml", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -910,7 +910,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_MN_M) {
+TEST_F(TeeuiLocaleTest, Test_MN_magnified) {
     int error = runRenderTest("mn", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -920,7 +920,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_MO_M) {
+TEST_F(TeeuiLocaleTest, Test_MO_magnified) {
     int error = runRenderTest("mo", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -930,7 +930,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_MR_M) {
+TEST_F(TeeuiLocaleTest, Test_MR_magnified) {
     int error = runRenderTest("mr", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -940,7 +940,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_MS_M) {
+TEST_F(TeeuiLocaleTest, Test_MS_magnified) {
     int error = runRenderTest("ms", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -950,7 +950,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_MY_M) {
+TEST_F(TeeuiLocaleTest, Test_MY_magnified) {
     int error = runRenderTest("my", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -960,7 +960,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_NB_M) {
+TEST_F(TeeuiLocaleTest, Test_NB_magnified) {
     int error = runRenderTest("nb", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -970,7 +970,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_NE_M) {
+TEST_F(TeeuiLocaleTest, Test_NE_magnified) {
     int error = runRenderTest("ne", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -980,7 +980,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_NL_M) {
+TEST_F(TeeuiLocaleTest, Test_NL_magnified) {
     int error = runRenderTest("nl", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -990,7 +990,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_NO_M) {
+TEST_F(TeeuiLocaleTest, Test_NO_magnified) {
     int error = runRenderTest("no", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1000,7 +1000,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_OR_M) {
+TEST_F(TeeuiLocaleTest, Test_OR_magnified) {
     int error = runRenderTest("or", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1010,7 +1010,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_PA_M) {
+TEST_F(TeeuiLocaleTest, Test_PA_magnified) {
     int error = runRenderTest("pa", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1020,7 +1020,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_PL_M) {
+TEST_F(TeeuiLocaleTest, Test_PL_magnified) {
     int error = runRenderTest("pl", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1030,7 +1030,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_PT_M) {
+TEST_F(TeeuiLocaleTest, Test_PT_magnified) {
     int error = runRenderTest("pt", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1040,7 +1040,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_PT_BR_M) {
+TEST_F(TeeuiLocaleTest, Test_PT_BR_magnified) {
     int error = runRenderTest("pt-BR", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1050,7 +1050,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_PT_PT_M) {
+TEST_F(TeeuiLocaleTest, Test_PT_PT_magnified) {
     int error = runRenderTest("pt-PT", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1060,7 +1060,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_RO_M) {
+TEST_F(TeeuiLocaleTest, Test_RO_magnified) {
     int error = runRenderTest("ro", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1070,7 +1070,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_RU_M) {
+TEST_F(TeeuiLocaleTest, Test_RU_magnified) {
     int error = runRenderTest("ru", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1080,7 +1080,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SI_M) {
+TEST_F(TeeuiLocaleTest, Test_SI_magnified) {
     int error = runRenderTest("si", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1090,7 +1090,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SK_M) {
+TEST_F(TeeuiLocaleTest, Test_SK_magnified) {
     int error = runRenderTest("sk", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1100,7 +1100,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SL_M) {
+TEST_F(TeeuiLocaleTest, Test_SL_magnified) {
     int error = runRenderTest("sl", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1110,7 +1110,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SQ_M) {
+TEST_F(TeeuiLocaleTest, Test_SQ_magnified) {
     int error = runRenderTest("sq", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1120,7 +1120,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SR_M) {
+TEST_F(TeeuiLocaleTest, Test_SR_magnified) {
     int error = runRenderTest("sr", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1130,7 +1130,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SR_LATN_M) {
+TEST_F(TeeuiLocaleTest, Test_SR_LATN_magnified) {
     int error = runRenderTest("sr-Latn", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1140,7 +1140,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SV_M) {
+TEST_F(TeeuiLocaleTest, Test_SV_magnified) {
     int error = runRenderTest("sv", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1150,7 +1150,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_SW_M) {
+TEST_F(TeeuiLocaleTest, Test_SW_magnified) {
     int error = runRenderTest("sw", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1160,7 +1160,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_TA_M) {
+TEST_F(TeeuiLocaleTest, Test_TA_magnified) {
     int error = runRenderTest("ta", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1170,7 +1170,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_TE_M) {
+TEST_F(TeeuiLocaleTest, Test_TE_magnified) {
     int error = runRenderTest("te", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1180,7 +1180,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_TH_M) {
+TEST_F(TeeuiLocaleTest, Test_TH_magnified) {
     int error = runRenderTest("th", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1190,7 +1190,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_TL_M) {
+TEST_F(TeeuiLocaleTest, Test_TL_magnified) {
     int error = runRenderTest("tl", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1200,7 +1200,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_TR_M) {
+TEST_F(TeeuiLocaleTest, Test_TR_magnified) {
     int error = runRenderTest("tr", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1210,7 +1210,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_UK_M) {
+TEST_F(TeeuiLocaleTest, Test_UK_magnified) {
     int error = runRenderTest("uk", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1220,7 +1220,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_UR_M) {
+TEST_F(TeeuiLocaleTest, Test_UR_magnified) {
     int error = runRenderTest("ur", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1230,7 +1230,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_UZ_M) {
+TEST_F(TeeuiLocaleTest, Test_UZ_magnified) {
     int error = runRenderTest("uz", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1240,7 +1240,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_VI_M) {
+TEST_F(TeeuiLocaleTest, Test_VI_magnified) {
     int error = runRenderTest("vi", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1250,7 +1250,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ZH_M) {
+TEST_F(TeeuiLocaleTest, Test_ZH_magnified) {
     int error = runRenderTest("zh", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1260,7 +1260,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ZH_CN_M) {
+TEST_F(TeeuiLocaleTest, Test_ZH_CN_magnified) {
     int error = runRenderTest("zh-CN", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1270,7 +1270,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ZH_HK_M) {
+TEST_F(TeeuiLocaleTest, Test_ZH_HK_magnified) {
     int error = runRenderTest("zh-HK", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1280,7 +1280,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ZH_TW_M) {
+TEST_F(TeeuiLocaleTest, Test_ZH_TW_magnified) {
     int error = runRenderTest("zh-TW", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
@@ -1290,7 +1290,7 @@
     ASSERT_EQ(error, 0);
 }
 
-TEST_F(TeeuiLocaleTest, Test_ZU_M) {
+TEST_F(TeeuiLocaleTest, Test_ZU_magnified) {
     int error = runRenderTest("zu", true /* magnified */);
     ASSERT_EQ(error, 0);
 }
diff --git a/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java b/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java
index eca320e..991e61b 100644
--- a/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java
+++ b/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java
@@ -23,9 +23,11 @@
          System.loadLibrary("teeui_jni");
     }
 
-    public static native int setDeviceInfo(DeviceInfo deviceInfo, boolean magnified, boolean inverted);
+    public static native int setDeviceInfo(DeviceInfo deviceInfo, boolean magnified, boolean inverted, String touchLayout);
     public static native int renderBuffer(int x, int y, int width, int height, int lineStride, int[] buffer);
     public static native void setLanguage(String language_id);
     public static native String[] getLanguageIdList();
     public static native void setConfimationMessage(String confimationMessage);
+    public static native int onEvent(int x, int y, int event);
+    public static native String[] getAvailableLayouts();
 }
diff --git a/tools/framebufferizer/src/com/android/framebufferizer/utils/Config.java b/tools/framebufferizer/src/com/android/framebufferizer/utils/Config.java
index 708551c..9e5baed 100644
--- a/tools/framebufferizer/src/com/android/framebufferizer/utils/Config.java
+++ b/tools/framebufferizer/src/com/android/framebufferizer/utils/Config.java
@@ -30,6 +30,7 @@
 public class Config {
     public static final String KEY_MAGNIFIED = "magnified";
     public static final String KEY_INVERTED = "inverted";
+    public static final String KEY_LAYOUT = "layout";
     public static final String KEY_LOCALE = "locale";
     public static final String KEY_DEVICE = "device";
     public static final String KEY_MESSAGE = "message";
diff --git a/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java b/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java
index e627e47..a81e1db 100644
--- a/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java
+++ b/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java
@@ -17,30 +17,23 @@
 package com.android.framebufferizer.utils;
 
 import com.android.framebufferizer.NativeRenderer;
-
-import java.awt.*;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.ActionListener;
-import java.awt.event.ActionEvent;
 import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
 import java.awt.image.DataBufferInt;
+import java.awt.image.RenderedImage;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.awt.image.ColorModel;
 import java.awt.image.DirectColorModel;
 import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
 import java.awt.image.WritableRaster;
-import java.io.*;
-import java.util.Map;
-import java.util.Iterator;
-import java.util.Set;
-
 import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
 
-public class FrameBufferBuffer extends JPanel implements ComponentListener, MouseMotionListener {
+public class FrameBufferBuffer extends JPanel implements ComponentListener, MouseMotionListener,
+        MouseListener {
     public class MagnifiedView extends JPanel implements ComponentListener {
         private BufferedImage mImage;
 
@@ -91,6 +84,19 @@
 
     }
 
+    public static enum EVENT_RESULT{
+        NONE(0), CONFIRM(1) ,CANCEL(2);
+        private int id;
+
+        EVENT_RESULT(int id){
+          this.id = id;
+        }
+
+        public int getValue(){
+          return id;
+        }
+    }
+
     public class ConfigSelector extends JPanel implements ActionListener {
         private final String languages[];
 
@@ -98,12 +104,16 @@
             languages = NativeRenderer.getLanguageIdList();
         }
 
+        private final String layouts[] = NativeRenderer.getAvailableLayouts();
         private JComboBox<String> deviceSelector = new JComboBox(DeviceInfoDB.Device.values());
         private JCheckBox magnifiedCheckbox = new JCheckBox("Magnified");
         private JCheckBox invertedCheckbox = new JCheckBox("Inverted");
+
         private JComboBox<String> localeSelector = new JComboBox(languages);
         private JTextField confirmationMessage = new JTextField();
 
+        private JComboBox<String> layoutSelector = new JComboBox(layouts);
+
         protected ConfigSelector() {
             System.err.println("ConfigSelector");
             this.setLayout(new GridBagLayout());
@@ -139,23 +149,36 @@
             c = new GridBagConstraints();
             c.gridx = 0;
             c.gridy = 2;
+            this.add(new JLabel("Select Layout:"), c);
+
+            layoutSelector.addActionListener(this);
+            c = new GridBagConstraints();
+            c.gridx = 1;
+            c.gridy = 2;
+            c.gridwidth = 2;
+            c.fill = GridBagConstraints.HORIZONTAL;
+            this.add(layoutSelector, c);
+
+            c = new GridBagConstraints();
+            c.gridx = 0;
+            c.gridy = 3;
             this.add(new JLabel("UIOptions:"), c);
 
             magnifiedCheckbox.addActionListener(this);
             c = new GridBagConstraints();
             c.gridx = 1;
-            c.gridy = 2;
+            c.gridy = 3;
             this.add(magnifiedCheckbox, c);
 
             invertedCheckbox.addActionListener(this);
             c = new GridBagConstraints();
             c.gridx = 2;
-            c.gridy = 2;
+            c.gridy = 3;
             this.add(invertedCheckbox, c);
 
             c = new GridBagConstraints();
             c.gridx = 0;
-            c.gridy = 3;
+            c.gridy = 4;
             this.add(new JLabel("Confirmation message:"), c);
 
             confirmationMessage.setText(
@@ -163,7 +186,7 @@
             confirmationMessage.addActionListener(this);
             c = new GridBagConstraints();
             c.gridx = 1;
-            c.gridy = 3;
+            c.gridy = 4;
             c.fill = GridBagConstraints.BOTH;
             c.gridwidth = 2;
             this.add(confirmationMessage, c);
@@ -176,6 +199,7 @@
             config.setValue(Config.KEY_MAGNIFIED, getConfigSelector().magnified());
             config.setValue(Config.KEY_INVERTED, getConfigSelector().inverted());
             config.setValue(Config.KEY_MESSAGE, getConfigSelector().confirmationMessage());
+            config.setValue(Config.KEY_LAYOUT, getConfigSelector().currentLayout());
         }
 
         public void actionPerformed(ActionEvent e) {
@@ -191,6 +215,10 @@
             return (String) localeSelector.getSelectedItem();
         }
 
+        public String currentLayout() {
+            return (String) layoutSelector.getSelectedItem();
+        }
+
         public boolean magnified() {
             return magnifiedCheckbox.isSelected();
         }
@@ -209,6 +237,7 @@
     private MagnifiedView mMagnifiedView;
     private ConfigSelector mConfigSelector;
     private JFrame mFrame;
+    private double mScale;
 
     public MagnifiedView getMagnifiedView() {
         if (mMagnifiedView == null) {
@@ -225,6 +254,36 @@
     }
 
     @Override
+    public void mouseReleased(MouseEvent e) {
+        if (e.MOUSE_RELEASED == MouseEvent.MOUSE_RELEASED) {
+            double x = e.getPoint().x / mScale;
+            double y = e.getPoint().y / mScale;
+            int value = NativeRenderer.onEvent((int)x, (int)y, MouseEvent.MOUSE_RELEASED);
+            if(value == EVENT_RESULT.CONFIRM.getValue()){
+                JOptionPane.showMessageDialog((Component) e.getSource(), "Confirm clicked.");
+            } else if (value == EVENT_RESULT.CANCEL.getValue()){
+                JOptionPane.showMessageDialog((Component) e.getSource(), "Cancel clicked.");
+            }
+        }
+    }
+
+    @Override
+    public void mouseClicked(MouseEvent e){
+    }
+
+    @Override
+    public void mousePressed(MouseEvent e){
+    }
+
+    @Override
+    public void mouseEntered(MouseEvent e){
+    }
+
+    @Override
+    public void mouseExited(MouseEvent e){
+    }
+
+    @Override
     public void mouseDragged(MouseEvent e) {
 
     }
@@ -285,6 +344,9 @@
                 case Config.KEY_MESSAGE:
                     getConfigSelector().confirmationMessage.setText((String) element.getValue());
                     break;
+                case Config.KEY_LAYOUT:
+                    getConfigSelector().layoutSelector.setSelectedItem((String) element.getValue());
+                    break;
                 }
             }
         }
@@ -297,6 +359,7 @@
         renderNativeBuffer();
         addComponentListener(this);
         addMouseMotionListener(this);
+        addMouseListener(this);
     }
 
     @Override
@@ -332,11 +395,12 @@
     }
 
     public void renderNativeBuffer() {
+        final int LAYOUT_EXAMPLE_ERROR = -2;
+        final int FRAME_BUFFER_ERROR = -1;
         DeviceInfo deviceInfo = DeviceInfoDB.getDeviceInfo(getConfigSelector().currentDevice());
         boolean magnified = getConfigSelector().magnified();
         boolean inverted = getConfigSelector().inverted();
-        NativeRenderer.setLanguage(getConfigSelector().currentLocale());
-        NativeRenderer.setConfimationMessage(getConfigSelector().confirmationMessage());
+
         int w = deviceInfo.getWidthPx();
         int h = deviceInfo.getHeightPx();
         final int linestride = w;
@@ -351,24 +415,29 @@
                     new int[] { rMask, gMask, bMask }, null);
             ColorModel colorModel = new DirectColorModel(bpp, rMask, gMask, bMask);
             BufferedImage image = new BufferedImage(colorModel, raster, true, null);
-            NativeRenderer.setDeviceInfo(deviceInfo, magnified, inverted);
+            NativeRenderer.setDeviceInfo(deviceInfo, magnified, inverted, getConfigSelector().currentLayout());
+            NativeRenderer.setLanguage(getConfigSelector().currentLocale());
+            NativeRenderer.setConfimationMessage(getConfigSelector().confirmationMessage());
             error = NativeRenderer.renderBuffer(0, 0, w, h, linestride, mBuffer.getData());
-            if (error != 0) {
+            if(error == FRAME_BUFFER_ERROR){
+                System.out.println("Error framebuffer not initilized " + error);
+            } else if(error == LAYOUT_EXAMPLE_ERROR){
+                System.out.println("Error layout example not initilized " + error);
+            } else if (error != 0) {
                 System.out.println("Error rendering native buffer " + error);
             }
 
             mImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
             Graphics2D gc = mImage.createGraphics();
-            double scale = 0.0;
             if (w / (double) h > getWidth() / (double) getHeight()) {
-                scale = (double) getWidth() / (double) w;
+                mScale = (double) getWidth() / (double) w;
             } else {
-                scale = (double) getHeight() / (double) h;
+                mScale = (double) getHeight() / (double) h;
             }
             gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
             gc.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
             gc.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
-            gc.drawRenderedImage(image, AffineTransform.getScaleInstance(scale, scale));
+            gc.drawRenderedImage(image, AffineTransform.getScaleInstance(mScale, mScale));
         }
         repaint();
     }