LittlevGL evaluation part 3
Progress! Parts 1 and 2 are here:
http://bkhome.org/news/201808/first-go-at-evaluating-littlevgl.html
http://bkhome.org/news/201808/tentative-first-step-framebuffer-with-littlevgl.html
I didn't know how to get the mouse working without X, so posted a question to the developer's site:
https://github.com/littlevgl/lvgl/issues/374
Now have a window with buttons, and a mouse! Furthermore, it is
compiled statically with uClibc and the executable is 217KB -- bigger
than it needs to be as have included more modules than actually used.
I used my fork of Landley's uClibc-based Aboriginal chrootable filesystem:
http://distro.ibiblio.org/easyos/project/aboriginal/
...follow the instructions, and you will end up with a filesystem folder that you can chroot into.
LittlevGL is the pc-simulator tarball, as explained in the earlier
posts. But first, the exciting part... I excited from X and executed
'demo":
The "mouse pointer" is that little power-button symbol, don't yet
know how to create a proper image. I can move the pointer over a button,
click, and get output on the screen. Yay!
My changes to 'lv_conf.h':
#define LV_COLOR_DEPTH 24 /* BKColor depth: 1/8/16/24*/
Changes to 'lv_drv_conf.h':
#define USE_FBDEV 1
...
#define USE_EVDEV 1
Here is my 'Makefile':
#Here is my 'main.c':
# Makefile
#
CC = gcc
#CFLAGS = -Wall -Wshadow -Wundef -Wmaybe-uninitialized
CFLAGS = -Wall -Wshadow -Wundef
CFLAGS += -O3 -g3 -I./
#LDFLAGS += -lSDL2 -lm
BIN = demo
VPATH =
LDFLAGS = -static
LVGL_DIR = ${shell pwd}
MAINSRC = main.c
#LIBRARIES
include ./lvgl/lv_core/lv_core.mk
include ./lvgl/lv_hal/lv_hal.mk
include ./lvgl/lv_objx/lv_objx.mk
include ./lvgl/lv_misc/lv_fonts/lv_fonts.mk
include ./lvgl/lv_misc/lv_misc.mk
include ./lvgl/lv_themes/lv_themes.mk
include ./lvgl/lv_draw/lv_draw.mk
#DRIVERS
include ./lv_drivers/display/display.mk
include ./lv_drivers/indev/indev.mk
OBJEXT ?= .o
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
OBJS = $(AOBJS) $(COBJS)
## MAINOBJ -> OBJFILES
all: clean default
%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@
@echo "CC $<"
default: $(AOBJS) $(COBJS) $(MAINOBJ)
$(CC) -o $(BIN) $(MAINOBJ) $(AOBJS) $(COBJS) $(LDFLAGS)
clean:
rm -f $(BIN) $(AOBJS) $(COBJS) $(MAINOBJ)
#include "lvgl/lvgl.h"What we have now is a great jumping-off point for creating useful apps.
#include "lv_drivers/display/fbdev.h"
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <stdio.h>
//Add a display for the LittlevGL using the frame buffer driver
void register_display(void)
{
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.disp_flush = fbdev_flush; //It flushes the internal graphical buffer to the frame buffer
lv_disp_drv_register(&disp_drv);
}
static lv_res_t btn_click_action(lv_obj_t * btn)
{
uint8_t id = lv_obj_get_free_num(btn);
printf("Button %d is released\n", id);
/* The button is released.
* Make something here */
return LV_RES_OK; /*Return OK if the button is not deleted*/
}
int main(void)
{
/*LittlevGL init*/
lv_init();
/*Linux frame buffer device init*/
fbdev_init();
// get a display
register_display();
// enable event input
evdev_init();
// get an input device like mouse
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read = evdev_read;
// lv_indev_drv_register(&indev_drv);
lv_indev_t * mouse_indev = lv_indev_drv_register(&indev_drv);
lv_obj_t * cursor_obj = lv_img_create(lv_scr_act(), NULL); /*Create an image for the cursor */
lv_img_set_src(cursor_obj, SYMBOL_POWER); /*For simlicity add a built in symbol not an image*/
lv_indev_set_cursor(mouse_indev, cursor_obj); /* connect the object to the driver*/
/*Create a title label*/
lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Default buttons");
lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 5);
/*Create a normal button*/
lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
lv_cont_set_fit(btn1, true, true); /*Enable resizing horizontally and vertically*/
lv_obj_align(btn1, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
lv_obj_set_free_num(btn1, 1); /*Set a unique number for the button*/
lv_btn_set_action(btn1, LV_BTN_ACTION_CLICK, btn_click_action);
/*Add a label to the button*/
label = lv_label_create(btn1, NULL);
lv_label_set_text(label, "Normal");
/*Copy the button and set toggled state. (The release action is copied too)*/
lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), btn1);
lv_obj_align(btn2, btn1, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
lv_btn_set_state(btn2, LV_BTN_STATE_TGL_REL); /*Set toggled state*/
lv_obj_set_free_num(btn2, 2); /*Set a unique number for the button*/
/*Add a label to the toggled button*/
label = lv_label_create(btn2, NULL);
lv_label_set_text(label, "Toggled");
/*Copy the button and set inactive state.*/
lv_obj_t * btn3 = lv_btn_create(lv_scr_act(), btn1);
lv_obj_align(btn3, btn2, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
lv_btn_set_state(btn3, LV_BTN_STATE_INA); /*Set inactive state*/
lv_obj_set_free_num(btn3, 3); /*Set a unique number for the button*/
/*Add a label to the inactive button*/
label = lv_label_create(btn3, NULL);
lv_label_set_text(label, "Inactive");
/*Handle LitlevGL tasks (tickless mode)*/
while(1)
{
lv_tick_inc(5);
lv_task_handler();
usleep(5000);
}
return 0;
}