librui: Draw UI using libtdm/libtbm 35/146635/9
authorŁukasz Stelmach <l.stelmach@samsung.com>
Tue, 12 Sep 2017 14:17:14 +0000 (16:17 +0200)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Thu, 21 Sep 2017 08:08:55 +0000 (10:08 +0200)
Change-Id: I0fc2525539e17394de932e668a30f98717bc544f
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
[ Applied Tizen Coding style ]
Signed-off-by: Karol Lewandowski <k.lewandowsk@samsung.com>
Makefile.am
configure.ac
packaging/initrd-recovery.spec
src/librui/graphics-fbdev.c
src/librui/graphics-tdm.c [new file with mode: 0644]
src/librui/graphics.c
src/librui/tdm-if.c [new file with mode: 0755]
src/librui/tdm-if.h [new file with mode: 0755]
src/system-recovery/recovery-main.c

index 875ccf8..3d732e7 100644 (file)
@@ -67,8 +67,6 @@ noinst_LTLIBRARIES += \
        librui.la
 
 librui_la_SOURCES = \
-       src/librui/graphics-fbdev-common.c \
-       src/librui/graphics-fbdev.c \
        src/librui/graphics.c \
        src/librui/input-events.c \
        src/librui/resources.c \
@@ -79,8 +77,19 @@ librui_la_SOURCES = \
        src/librui/rui-rulers.c \
        src/librui/rui.c
 
+if HAVE_TDM
+librui_la_SOURCES += \
+       src/librui/graphics-tdm.c \
+       src/librui/tdm-if.c
+else
+librui_la_SOURCES += \
+       src/librui/graphics-fbdev-common.c \
+       src/librui/graphics-fbdev.c
+endif
+
 librui_la_CFLAGS = \
        $(LIBPNG_CFLAGS) \
+       $(LIBTDM_CFLAGS) \
        $(VCONF_INTERNAL_KEYS) \
        $(AM_CFLAGS) \
        -I $(top_srcdir)/src/librui \
@@ -88,6 +97,7 @@ librui_la_CFLAGS = \
 
 librui_la_LIBADD = \
        $(LIBPNG_LIBS) \
+       $(LIBTDM_LIBS) \
        $(AM_LIBS)
 endif
 
index 48b4953..54e08e0 100644 (file)
@@ -62,6 +62,9 @@ AC_SUBST([OUR_LDFLAGS], "$our_ldflags")
 M4_DEFINES=
 
 # ------------------------------------------------------------------------------
+AC_ARG_WITH([tdm],
+       AS_HELP_STRING([--without-tdm], [disable TDM/TBM graphical backend (default: test)]))
+
 AC_ARG_ENABLE([recovery-gui],
         AS_HELP_STRING([--disable-recovery-gui], [disable recovery gui mode]),
                 [case "${enableval}" in
@@ -70,11 +73,22 @@ AC_ARG_ENABLE([recovery-gui],
                         *) AC_MSG_ERROR(bad value ${enableval} for --disable-recovery-gui) ;;
                 esac],
                 enable_recovery_gui=yes)
+
+have_libtdm=no
 if test "x$enable_recovery_gui" == "xyes"; then
         M4_DEFINES="$M4_DEFINES -DRECOVERY_GUI"
         AC_SUBST([OUR_CFLAGS], "$OUR_CFLAGS -DRECOVERY_GUI")
        PKG_CHECK_MODULES(LIBPNG, [libpng])
        PKG_CHECK_MODULES(VCONF_INTERNAL_KEYS, [vconf-internal-keys])
+       if test "x$with_tdm" != "xno"; then
+               PKG_CHECK_MODULES(LIBTDM,
+                       [libtdm >= 1.7.0],
+                       [AC_DEFINE(HAVE_TDM, 1, [Define if using TDM/TBM graphical backend])
+                       have_libtdm=yes])
+               if test "x$with_tdm" = "xyes" -a "x$have_libtdm" = "xno"; then
+                       AC_MSG_ERROR([--with-tdm has been specified but libtdm is not available.])
+               fi
+       fi
        RECOVERY_GUI="GUI"
 else
        RECOVERY_GUI="NO"
@@ -82,6 +96,7 @@ fi
 
 AC_SUBST([RECOVERY_GUI])
 AM_CONDITIONAL([RECOVERY_GUI], [test "x$enable_recovery_gui" != "xno"])
+AM_CONDITIONAL([HAVE_TDM], [test "x$have_libtdm" = "xyes"])
 
 # ------------------------------------------------------------------------------
 AC_SUBST(M4_DEFINES)
@@ -92,10 +107,9 @@ AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
 AC_MSG_RESULT([
         $PACKAGE_NAME $VERSION
-
+        =====================
         prefix:                  ${prefix}
-
         recovery gui mode:       ${enable_recovery_gui}
-
+        with TDM:                ${have_libtdm}
         OUR CFLAGS:              ${OUR_CFLAGS} ${CFLAGS}
 ])
index 715c096..9d9a2c4 100644 (file)
@@ -12,6 +12,7 @@ Source1001:     initrd-recovery.manifest
 BuildRequires:  autoconf
 BuildRequires:  automake
 BuildRequires:  libtool
+BuildRequires:  pkgconfig(libtdm)
 
 Requires:       system-recovery
 
index a151010..c0211c9 100644 (file)
@@ -46,16 +46,16 @@ fbdev_common fb_data = {
        .gr_draw                = NULL
 };
 
-static gr_backend my_backend = {
-       .init   = fbdev_init,
-       .flip   = fbdev_flip,
-       .exit   = fbdev_exit,
-       .data   = (void *)&fb_data
+static gr_backend fbdev_backend = {
+       .init   = fbdev_init,
+       .flip   = fbdev_flip,
+       .exit   = fbdev_exit,
+       .data   = (void *)&fb_data
 };
 
 gr_backend *open_fbdev(void)
 {
-       return &my_backend;
+       return &fbdev_backend;
 }
 
 static void fbdev_blank(gr_backend *backend, bool blank)
diff --git a/src/librui/graphics-tdm.c b/src/librui/graphics-tdm.c
new file mode 100644 (file)
index 0000000..0cbe536
--- /dev/null
@@ -0,0 +1,101 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil -*-
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <tdm.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "graphics.h"
+#include "tdm-if.h"
+
+static gr_surface tdm_init(gr_backend *);
+static gr_surface tdm_flip(gr_backend *);
+static bool tdm_exit(gr_backend *);
+
+struct _tdm_data {
+       GRSurface gr_framebuffer;
+};
+
+static struct _tdm_data tdm_data;
+
+static gr_backend tdm_backend = {
+       .init   = tdm_init,
+       .flip   = tdm_flip,
+       .exit   = tdm_exit,
+       .data   = (void*)&tdm_data,
+};
+
+gr_backend *open_tdm(void)
+{
+       return &tdm_backend;
+}
+
+gr_surface tdm_init(gr_backend *backend)
+{
+       struct _tdm_data *data = (struct _tdm_data*)backend->data;
+       gr_surface gr_draw = (gr_surface)&data->gr_framebuffer;
+
+       if (tdm_if_display_init() < 0)
+               return NULL;
+
+       tdm_if_lcd_off();
+
+       gr_draw->width = tdm_if_display_width();
+       gr_draw->height = tdm_if_display_height();
+       gr_draw->pixel_bytes = 4; /* XXX */
+       gr_draw->row_bytes = tdm_if_display_stride();
+       gr_draw->data = malloc(tdm_if_display_bufsize());
+       if (gr_draw->data == NULL)
+               return NULL;
+
+       tdm_if_lcd_on();
+       return gr_draw;
+}
+
+gr_surface tdm_flip(gr_backend *backend)
+{
+       struct _tdm_data *data = (struct _tdm_data*)backend->data;
+       gr_surface gr_draw = (gr_surface)&data->gr_framebuffer;
+
+       tdm_if_buffer_update(gr_draw->data);
+       tdm_if_display_update();
+
+       return gr_draw;
+}
+
+bool tdm_exit(gr_backend *backend)
+{
+       struct _tdm_data *data = (struct _tdm_data*)backend->data;
+       gr_surface gr_draw = (gr_surface)&data->gr_framebuffer;
+
+       tdm_if_display_deinit();
+
+       if (gr_draw->data != NULL)
+               free(gr_draw->data);
+
+       return true;
+}
index 03f5605..f564ab5 100644 (file)
@@ -464,7 +464,11 @@ bool gr_init(void)
 {
        gr_init_font();
 
+#ifdef HAVE_TDM
+       g_backend = open_tdm();
+#else
        g_backend = open_fbdev();
+#endif
        gr_draw = g_backend->init(g_backend);
        if (gr_draw == NULL)
                return false;
diff --git a/src/librui/tdm-if.c b/src/librui/tdm-if.c
new file mode 100755 (executable)
index 0000000..7f2371b
--- /dev/null
@@ -0,0 +1,360 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil -*-
+ *
+ * system-recovery
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ * Based on tdm-if.c from tota-ua.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "tdm-if.h"
+
+#define LOGD(format, ...) printf("[TDM-IF] " format "\n", ##__VA_ARGS__)
+
+#define C(b, m)                     (((b) >> (m)) & 0xFF)
+#define B(c, s)                     ((((unsigned int)(c)) & 0xff) << (s))
+#define FOURCC(a, b, c, d)     (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
+#define FOURCC_STR(id)     C(id, 0), C(id, 8), C(id, 16), C(id, 24)
+#define FOURCC_ID(str)     FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
+
+static tdm_if_disp s_st_disp;
+
+static void tdm_if_display_commit_handler_cb(tdm_output *output, unsigned int sequence,
+                                                unsigned int tv_sec, unsigned int tv_usec,
+                                                void *user_data)
+{
+       LOGD("commit_handle_cb!!");
+
+       return ;
+}
+
+int tdm_if_display_init(void)
+{
+       const tdm_output_mode *output_modes, *preferred_mode;
+       tdm_info_layer layer_info;
+       tdm_layer_capability layer_caps;
+       tdm_output_conn_status conn_status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+       tdm_output_type output_type = TDM_OUTPUT_TYPE_Unknown;
+       tdm_output *output = NULL;
+       int buf_cnt;
+       tdm_error err = TDM_ERROR_NONE;
+       tdm_if_disp *st_disp = &s_st_disp;
+       int i, j;
+       int layer_count = 0;
+       int output_count = 0;
+
+       LOGD("START");
+
+       st_disp->disp = tdm_display_init(&err);
+       if (!st_disp->disp) {
+               LOGD("failed to init tdm_display. error num = %d", err);
+               goto exit;
+       }
+
+       err = tdm_display_get_fd(st_disp->disp, &st_disp->tdm_fd);
+       if (err != TDM_ERROR_NONE) {
+               LOGD("failed to get tdm fd. error num = %d", err);
+               goto exit;
+       }
+
+       st_disp->drm_fd = tdm_helper_get_fd("TDM_DRM_MASTER_FD");
+       if (st_disp->drm_fd == -1) {
+               LOGD("failed to get tdm fd. error num = %d", err);
+               goto exit;
+       }
+
+       err = tdm_display_get_output_count(st_disp->disp, &output_count);
+       if (err != TDM_ERROR_NONE) {
+               LOGD("failed to get output count. error num = %d", err);
+               goto exit;
+       }
+
+       if (output_count < 1) {
+               LOGD("insufficient number of outputs");
+               goto exit;
+       }
+
+       for (i = 0; i < output_count; i++) {
+               output = tdm_display_get_output(st_disp->disp, i, &err);
+               if (err != TDM_ERROR_NONE) {
+                       LOGD("failed to get outout. error num = %d", err);
+                       goto exit;
+               }
+
+               err = tdm_output_get_output_type(output, &output_type);
+               if (err != TDM_ERROR_NONE) {
+                       LOGD("failed to get output type. error num = %d", err);
+                       goto exit;
+               }
+
+               err = tdm_output_get_conn_status(output, &conn_status);
+               if (err != TDM_ERROR_NONE) {
+                       LOGD("failed to get output connection status. error num = %d", err);
+                       goto exit;
+               }
+
+               LOGD("output_type=%d  conn_status=%d", output_type, conn_status);
+               if ((output_type == TDM_OUTPUT_TYPE_LVDS) ||
+                   (output_type == TDM_OUTPUT_TYPE_DSI)) {
+                       int cnt = 0;
+                       err = tdm_output_get_available_modes(output, &output_modes, &cnt);
+                       if (err != TDM_ERROR_NONE) {
+                               LOGD("failed to get output available modes. error num = %d", err);
+                               goto exit;
+                       }
+                       LOGD("%d output modes available", cnt);
+
+                       preferred_mode = output_modes;
+                       for (j = 0; j < cnt; j++) {
+                               if (output_modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) {
+                                       preferred_mode = &output_modes[i];
+                                       break;
+                               }
+                       }
+
+                       /* GET MODE INFO */
+                       st_disp->output = output;
+                       st_disp->width = preferred_mode->hdisplay;
+                       st_disp->height = preferred_mode->vdisplay;
+
+                       err = tdm_output_set_mode(st_disp->output, preferred_mode);
+                       if (err != TDM_ERROR_NONE) {
+                               LOGD("unable to set mode: \"%s\"", preferred_mode->name);
+                               goto exit;
+                       }
+
+                       /* informational */
+                       unsigned int width_mm = 0;
+                       unsigned int height_mm = 0;
+                       err = tdm_output_get_physical_size(output, &width_mm, &height_mm);
+                       LOGD("TDM_OUTPUT_MODE:name[%s] mode:wh[%d %d] mm[%d %d]",
+                            preferred_mode->name, st_disp->width, st_disp->height, width_mm, height_mm);
+
+                       break;
+               }
+       }
+
+       /* SET LAYER */
+       err = tdm_output_get_layer_count(st_disp->output, &layer_count);
+       if (err != TDM_ERROR_NONE) {
+               LOGD("failed to get number of layers");
+               goto exit;
+       }
+       if (layer_count < 1) {
+               LOGD("insufficient number of layers: %d", layer_count);
+               goto exit;
+       }
+
+       for (i = 0; i < layer_count; i++) {
+               st_disp->layer = tdm_output_get_layer(st_disp->output, i, &err);
+               if (err != TDM_ERROR_NONE) {
+                       LOGD("failed to get layer: %d", i);
+                       goto exit;
+               }
+
+               err = tdm_layer_get_capabilities(st_disp->layer, &layer_caps);
+               if (err != TDM_ERROR_NONE) {
+                       LOGD("failed to get layer capabilities: %d", i);
+                       goto exit;
+               }
+
+               if ((layer_caps & TDM_LAYER_CAPABILITY_PRIMARY) &&
+                   (layer_caps & TDM_LAYER_CAPABILITY_GRAPHIC))
+                       break;
+       }
+
+       layer_info.src_config.size.h = st_disp->width;
+       layer_info.src_config.size.v = st_disp->height;
+       layer_info.src_config.pos.x = 0;
+       layer_info.src_config.pos.y = 0;
+       layer_info.src_config.pos.w = st_disp->width;
+       layer_info.src_config.pos.h = st_disp->height;
+       layer_info.src_config.format = TBM_FORMAT_ARGB8888;
+       layer_info.dst_pos.x = 0;
+       layer_info.dst_pos.y = 0;
+       layer_info.dst_pos.w = st_disp->width;
+       layer_info.dst_pos.h = st_disp->height;
+       layer_info.transform = TDM_TRANSFORM_NORMAL;
+
+       err = tdm_layer_set_info(st_disp->layer, &layer_info);
+       if (err != TDM_ERROR_NONE) {
+               LOGD("failed to get output layer. error num = %d", err);
+               goto exit;
+       }
+
+       for (buf_cnt = 0; buf_cnt < MAX_BUF; buf_cnt++) {
+               tbm_surface_error_e e;
+               tbm_surface_info_s si;
+
+               st_disp->surf[buf_cnt] = tbm_surface_internal_create_with_flags(st_disp->width,
+                                                                               st_disp->height,
+                                                                               TBM_FORMAT_ARGB8888,
+                                                                               TBM_BO_SCANOUT);
+               e = get_last_result();
+               if (e != TBM_SURFACE_ERROR_NONE ||
+                   !st_disp->surf[buf_cnt]){
+                       LOGD("failed to create tbm_surface!");
+                       goto exit;
+               }
+
+               e = tbm_surface_get_info(st_disp->surf[buf_cnt], &si);
+               if (e != TBM_SURFACE_ERROR_NONE) {
+                       LOGD("failed to get info for tbm_surface!");
+                       goto exit;
+               }
+
+               LOGD("surface created: %dx%d %c%c%c%c bpp:%d size:%d planes:%d stride:%d",
+                    si.width, si.height,
+                    FOURCC_STR(si.format),
+                    si.bpp, si.size, si.num_planes,
+                    si.planes[0].stride);
+
+               if (si.num_planes != 1) {
+                       LOGD("unsupported number of planes: %d", si.num_planes);
+                       goto exit;
+               }
+               st_disp->buffer_size = si.planes[0].size;
+               st_disp->stride = si.planes[0].stride;
+       }
+
+
+       st_disp->current_buf_id = 0;
+
+       for (i = 0; i < MAX_BUF; i++) {
+               tdm_if_buffer_update(NULL);
+               tdm_if_display_update();
+       }
+
+       LOGD("DONE");
+       return 0;
+exit:
+       tdm_if_display_deinit();
+       return -1;
+}
+
+void tdm_if_display_deinit(void)
+{
+       int buf_cnt = 0;
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       tdm_if_lcd_off();
+
+       if (st_disp->disp != NULL) {
+               /* RELEASE RESOURCE */
+               for (buf_cnt = 0; buf_cnt < MAX_BUF; buf_cnt++) {
+                       if (st_disp->surf[buf_cnt] != NULL)
+                               tbm_surface_destroy(st_disp->surf[buf_cnt]);
+               }
+
+               tdm_display_deinit(st_disp->disp);
+               st_disp->disp = NULL;
+       }
+}
+
+int tdm_if_display_width(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       return st_disp->width;
+}
+
+int tdm_if_display_height(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       return st_disp->height;
+}
+
+int tdm_if_display_bufsize(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       return st_disp->buffer_size;
+}
+
+int tdm_if_display_stride(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       return st_disp->stride;
+}
+
+void tdm_if_buffer_update(unsigned char *buffer)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       int buf_cnt = st_disp->current_buf_id;
+       tbm_surface_info_s tbm_surface_info;
+       tbm_surface_error_e err;
+       uint32_t *surface;
+
+       err = tbm_surface_map(st_disp->surf[buf_cnt], TBM_SURF_OPTION_WRITE, &tbm_surface_info);
+       if (err != TBM_SURFACE_ERROR_NONE) {
+               LOGD("tbm_surface_map failed!");
+               return;
+       }
+
+       surface = (uint32_t*)tbm_surface_info.planes[0].ptr;
+
+       if (buffer == NULL)
+               memset(surface, 0, st_disp->buffer_size);
+       else
+               memcpy(surface, buffer, st_disp->buffer_size);
+
+       tbm_surface_unmap(st_disp->surf[buf_cnt]);
+}
+
+void tdm_if_display_update(void)
+{
+       /* DISPLAY UPDATE */
+       int buf_cnt = 0;
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       buf_cnt = st_disp->current_buf_id;
+       st_disp->current_buf_id = (st_disp->current_buf_id + 1)%MAX_BUF;
+
+       tdm_layer_set_buffer(st_disp->layer, st_disp->surf[buf_cnt]);
+
+       // TODO: sync or async??
+       tdm_output_commit(st_disp->output, 1, tdm_if_display_commit_handler_cb, st_disp);
+}
+
+void tdm_if_lcd_on(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       LOGD("DPMS ON!");
+       tdm_output_set_dpms(st_disp->output, TDM_OUTPUT_DPMS_ON);
+}
+
+void tdm_if_lcd_off(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       LOGD("DPMS OFF!");
+       tdm_output_set_dpms(st_disp->output, TDM_OUTPUT_DPMS_OFF);
+}
diff --git a/src/librui/tdm-if.h b/src/librui/tdm-if.h
new file mode 100755 (executable)
index 0000000..9c92e7d
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil -*-
+ *
+ * system-recovery
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ * Based on tdm-if.h from tota-ua.
+ */
+
+#ifndef __TDM_IF_H__
+#define __TDM_IF_H__
+
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+#include <tdm.h>
+#include <tdm_helper.h>
+
+#define MAX_BUF 2
+#define RGB32_BPP 32
+#define RGB32_PITCH 4
+
+typedef struct _tdm_if_disp {
+       tdm_display *disp;
+       tdm_output *output;
+       tdm_layer *layer;
+       int tdm_fd;
+       int drm_fd;
+       tbm_surface_h surf[MAX_BUF];
+       int buffer_size;
+       int width;
+       int height;
+       int stride;
+       int current_buf_id;
+} tdm_if_disp;
+
+typedef enum {
+       FRONT_BUFFER = 0,
+       BACK_BUFFER
+} BUFFER_TYPE;
+
+extern tdm_if_disp s_disp;
+
+int tdm_if_display_init(void);
+void tdm_if_display_deinit(void);
+void tdm_if_display_update(void);
+int tdm_if_display_width(void);
+int tdm_if_display_height(void);
+int tdm_if_display_bufsize(void);
+int tdm_if_display_stride(void);
+
+void tdm_if_buffer_update(unsigned char *buffer);
+
+void tdm_if_lcd_on(void);
+void tdm_if_lcd_off(void);
+
+#endif /* __TDM_IF_H__ */
index ed535a5..48866ed 100644 (file)
@@ -23,6 +23,7 @@
 #include <signal.h>
 #include <unistd.h>
 #include <stdbool.h>
+#include <stdlib.h>
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -87,6 +88,20 @@ void run_factory_reset(void)
 int main(void)
 {
        LOGD("[main] recovery started.\n");
+#ifdef HAVE_TDM
+       /* These should be set externally */
+
+       /*
+        * Under normal circumstances XDG_RUNTIME_DIR is set during
+        * session setup (login). On initrd there is no session. This
+        * is used in libwayland-server and there is no default value.
+        */
+       setenv("XDG_RUNTIME_DIR", "/run", 1);
+
+       /* Tell TBM to work without an external wayland display manager. */
+       setenv("TBM_DISPLAY_SERVER", "1", 1);
+#endif
+
        if (!recovery_rui_init()) {
                LOGD("Can't initialize GUI.\n");
                return 1;