mirror of
				https://gitee.com/jiuyilian/embedded-framework.git
				synced 2025-10-24 18:20:15 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			305 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
 * @file win_drv.c
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
/*********************
 | 
						|
 *      INCLUDES
 | 
						|
 *********************/
 | 
						|
#include "win_drv.h"
 | 
						|
#if USE_WINDOWS
 | 
						|
 | 
						|
#include <windows.h>
 | 
						|
#include <windowsx.h>
 | 
						|
#include "lvgl/lvgl.h"
 | 
						|
 | 
						|
#if LV_COLOR_DEPTH < 16
 | 
						|
#error Windows driver only supports true RGB colors at this time
 | 
						|
#endif
 | 
						|
 | 
						|
/**********************
 | 
						|
 *       DEFINES
 | 
						|
 **********************/
 | 
						|
 | 
						|
 #define WINDOW_STYLE (WS_OVERLAPPEDWINDOW & ~(WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME))
 | 
						|
 | 
						|
/**********************
 | 
						|
 *      TYPEDEFS
 | 
						|
 **********************/
 | 
						|
 | 
						|
/**********************
 | 
						|
 *  STATIC PROTOTYPES
 | 
						|
 **********************/
 | 
						|
static void do_register(void);
 | 
						|
static void win_drv_flush(lv_disp_t *drv, lv_area_t *area, const lv_color_t * color_p);
 | 
						|
static void win_drv_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
 | 
						|
static void win_drv_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
 | 
						|
static void win_drv_read(lv_indev_t *drv, lv_indev_data_t * data);
 | 
						|
static void msg_handler(void *param);
 | 
						|
 | 
						|
static COLORREF lv_color_to_colorref(const lv_color_t color);
 | 
						|
 | 
						|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 | 
						|
 | 
						|
 | 
						|
/**********************
 | 
						|
 *  GLOBAL VARIABLES
 | 
						|
 **********************/
 | 
						|
 | 
						|
bool lv_win_exit_flag = false;
 | 
						|
lv_disp_t *lv_windows_disp;
 | 
						|
 | 
						|
/**********************
 | 
						|
 *  STATIC VARIABLES
 | 
						|
 **********************/
 | 
						|
static HWND hwnd;
 | 
						|
static uint32_t *fbp = NULL; /* Raw framebuffer memory */
 | 
						|
static bool mouse_pressed;
 | 
						|
static int mouse_x, mouse_y;
 | 
						|
 | 
						|
 | 
						|
/**********************
 | 
						|
 *      MACROS
 | 
						|
 **********************/
 | 
						|
 | 
						|
/**********************
 | 
						|
 *   GLOBAL FUNCTIONS
 | 
						|
 **********************/
 | 
						|
const char g_szClassName[] = "LVGL";
 | 
						|
 | 
						|
HWND windrv_init(void)
 | 
						|
{
 | 
						|
    WNDCLASSEX wc;
 | 
						|
    RECT winrect;
 | 
						|
    HICON lvgl_icon;
 | 
						|
 | 
						|
    //Step 1: Registering the Window Class
 | 
						|
    wc.cbSize        = sizeof(WNDCLASSEX);
 | 
						|
    wc.style         = 0;
 | 
						|
    wc.lpfnWndProc   = WndProc;
 | 
						|
    wc.cbClsExtra    = 0;
 | 
						|
    wc.cbWndExtra    = 0;
 | 
						|
    wc.hInstance     = GetModuleHandle(NULL);
 | 
						|
    lvgl_icon        = (HICON) LoadImage( NULL, "lvgl_icon.bmp", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
 | 
						|
 | 
						|
    if(lvgl_icon == NULL)
 | 
						|
        lvgl_icon = LoadIcon(NULL, IDI_APPLICATION);
 | 
						|
 | 
						|
    wc.hIcon         = lvgl_icon;
 | 
						|
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
 | 
						|
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
 | 
						|
    wc.lpszMenuName  = NULL;
 | 
						|
    wc.lpszClassName = g_szClassName;
 | 
						|
    wc.hIconSm       = lvgl_icon;
 | 
						|
 | 
						|
    if(!RegisterClassEx(&wc))
 | 
						|
    {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    winrect.left = 0;
 | 
						|
    winrect.right = WINDOW_HOR_RES - 1;
 | 
						|
    winrect.top = 0;
 | 
						|
    winrect.bottom = WINDOW_VER_RES - 1;
 | 
						|
    AdjustWindowRectEx(&winrect, WINDOW_STYLE, FALSE, WS_EX_CLIENTEDGE);
 | 
						|
    OffsetRect(&winrect, -winrect.left, -winrect.top);
 | 
						|
    // Step 2: Creating the Window
 | 
						|
    hwnd = CreateWindowEx(
 | 
						|
        WS_EX_CLIENTEDGE,
 | 
						|
        g_szClassName,
 | 
						|
        "LVGL Simulator",
 | 
						|
        WINDOW_STYLE,
 | 
						|
        CW_USEDEFAULT, CW_USEDEFAULT, winrect.right, winrect.bottom,
 | 
						|
        NULL, NULL, GetModuleHandle(NULL), NULL);
 | 
						|
 | 
						|
    if(hwnd == NULL)
 | 
						|
    {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    ShowWindow(hwnd, SW_SHOWDEFAULT);
 | 
						|
    UpdateWindow(hwnd);
 | 
						|
 | 
						|
 | 
						|
    lv_task_create(msg_handler, 0, LV_TASK_PRIO_HIGHEST, NULL);
 | 
						|
    lv_win_exit_flag = false;
 | 
						|
    do_register();
 | 
						|
}
 | 
						|
 | 
						|
/**********************
 | 
						|
 *   STATIC FUNCTIONS
 | 
						|
 **********************/
 | 
						|
 | 
						|
static void do_register(void)
 | 
						|
{
 | 
						|
    static lv_disp_draw_buf_t disp_buf_1;
 | 
						|
    static lv_color_t buf1_1[WINDOW_HOR_RES * 100];                      /*A buffer for 10 rows*/
 | 
						|
    lv_disp_draw_buf_init(&disp_draw_buf_1, buf1_1, NULL, WINDOW_HOR_RES * 100);   /*Initialize the display buffer*/
 | 
						|
 | 
						|
 | 
						|
    /*-----------------------------------
 | 
						|
     * Register the display in LVGLGL
 | 
						|
     *----------------------------------*/
 | 
						|
 | 
						|
    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
 | 
						|
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/
 | 
						|
 | 
						|
    /*Set up the functions to access to your display*/
 | 
						|
 | 
						|
    /*Set the resolution of the display*/
 | 
						|
    disp_drv.hor_res = WINDOW_HOR_RES;
 | 
						|
    disp_drv.ver_res = WINDOW_VER_RES;
 | 
						|
 | 
						|
    /*Used to copy the buffer's content to the display*/
 | 
						|
    disp_drv.flush_cb = win_drv_flush;
 | 
						|
 | 
						|
    /*Set a display buffer*/
 | 
						|
    disp_drv.draw_buf = &disp_buf_1;
 | 
						|
 | 
						|
    /*Finally register the driver*/
 | 
						|
    lv_windows_disp = lv_disp_drv_register(&disp_drv);
 | 
						|
    static lv_indev_drv_t indev_drv;
 | 
						|
    lv_indev_drv_init(&indev_drv);
 | 
						|
    indev_drv.type = LV_INDEV_TYPE_POINTER;
 | 
						|
    indev_drv.read_cb = win_drv_read;
 | 
						|
    lv_indev_drv_register(&indev_drv);
 | 
						|
}
 | 
						|
 | 
						|
static void msg_handler(void *param)
 | 
						|
{
 | 
						|
    (void)param;
 | 
						|
 | 
						|
    MSG msg;
 | 
						|
    BOOL bRet;
 | 
						|
    if( (bRet = PeekMessage( &msg, NULL, 0, 0, TRUE )) != 0)
 | 
						|
    {
 | 
						|
        if (bRet == -1)
 | 
						|
        {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            TranslateMessage(&msg);
 | 
						|
            DispatchMessage(&msg);
 | 
						|
        }
 | 
						|
        if(msg.message == WM_QUIT)
 | 
						|
            lv_win_exit_flag = true;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 static void win_drv_read(lv_indev_t *drv, lv_indev_data_t * data)
 | 
						|
{
 | 
						|
    data->state = mouse_pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
 | 
						|
    data->point.x = mouse_x;
 | 
						|
    data->point.y = mouse_y;
 | 
						|
}
 | 
						|
 | 
						|
 static void on_paint(void)
 | 
						|
 {
 | 
						|
    HBITMAP bmp = CreateBitmap(WINDOW_HOR_RES, WINDOW_VER_RES, 1, 32, fbp);
 | 
						|
    PAINTSTRUCT ps;
 | 
						|
 | 
						|
    HDC hdc = BeginPaint(hwnd, &ps);
 | 
						|
 | 
						|
    HDC hdcMem = CreateCompatibleDC(hdc);
 | 
						|
    HBITMAP hbmOld = SelectObject(hdcMem, bmp);
 | 
						|
 | 
						|
    BitBlt(hdc, 0, 0, WINDOW_HOR_RES, WINDOW_VER_RES, hdcMem, 0, 0, SRCCOPY);
 | 
						|
 | 
						|
    SelectObject(hdcMem, hbmOld);
 | 
						|
    DeleteDC(hdcMem);
 | 
						|
 | 
						|
    EndPaint(hwnd, &ps);
 | 
						|
    DeleteObject(bmp);
 | 
						|
 | 
						|
}
 | 
						|
/**
 | 
						|
 * Flush a buffer to the marked area
 | 
						|
 * @param x1 left coordinate
 | 
						|
 * @param y1 top coordinate
 | 
						|
 * @param x2 right coordinate
 | 
						|
 * @param y2 bottom coordinate
 | 
						|
 * @param color_p an array of colors
 | 
						|
 */
 | 
						|
static void win_drv_flush(lv_disp_t *drv, lv_area_t *area, const lv_color_t * color_p)
 | 
						|
{
 | 
						|
    win_drv_map(area->x1, area->y1, area->x2, area->y2, color_p);
 | 
						|
    lv_disp_flush_ready(drv);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Put a color map to the marked area
 | 
						|
 * @param x1 left coordinate
 | 
						|
 * @param y1 top coordinate
 | 
						|
 * @param x2 right coordinate
 | 
						|
 * @param y2 bottom coordinate
 | 
						|
 * @param color_p an array of colors
 | 
						|
 */
 | 
						|
static void win_drv_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
 | 
						|
{
 | 
						|
    for(int y = y1; y <= y2; y++)
 | 
						|
    {
 | 
						|
        for(int x = x1; x <= x2; x++)
 | 
						|
        {
 | 
						|
            fbp[y*WINDOW_HOR_RES+x] = lv_color_to32(*color_p);
 | 
						|
            color_p++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    InvalidateRect(hwnd, NULL, FALSE);
 | 
						|
    UpdateWindow(hwnd);
 | 
						|
}
 | 
						|
 | 
						|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
    HDC hdc;
 | 
						|
    PAINTSTRUCT ps;
 | 
						|
    switch(msg) {
 | 
						|
    case WM_CREATE:
 | 
						|
        fbp = malloc(4*WINDOW_HOR_RES*WINDOW_VER_RES);
 | 
						|
        if(fbp == NULL)
 | 
						|
            return 1;
 | 
						|
        SetTimer(hwnd, 0, 10, (TIMERPROC)lv_task_handler);
 | 
						|
        SetTimer(hwnd, 1, 25, NULL);
 | 
						|
 | 
						|
        return 0;
 | 
						|
    case WM_MOUSEMOVE:
 | 
						|
    case WM_LBUTTONDOWN:
 | 
						|
    case WM_LBUTTONUP:
 | 
						|
        mouse_x = GET_X_LPARAM(lParam);
 | 
						|
        mouse_y = GET_Y_LPARAM(lParam);
 | 
						|
        if(msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) {
 | 
						|
            mouse_pressed = (msg == WM_LBUTTONDOWN);
 | 
						|
        }
 | 
						|
        return 0;
 | 
						|
    case WM_CLOSE:
 | 
						|
        free(fbp);
 | 
						|
        fbp = NULL;
 | 
						|
        DestroyWindow(hwnd);
 | 
						|
        return 0;
 | 
						|
    case WM_PAINT:
 | 
						|
        on_paint();
 | 
						|
        return 0;
 | 
						|
    case WM_TIMER:
 | 
						|
        lv_tick_inc(25);
 | 
						|
        return 0;
 | 
						|
    case WM_DESTROY:
 | 
						|
        PostQuitMessage(0);
 | 
						|
        return 0;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return DefWindowProc(hwnd, msg, wParam, lParam);
 | 
						|
}
 | 
						|
static COLORREF lv_color_to_colorref(const lv_color_t color)
 | 
						|
{
 | 
						|
    uint32_t raw_color = lv_color_to32(color);
 | 
						|
    lv_color32_t tmp;
 | 
						|
    tmp.full = raw_color;
 | 
						|
    uint32_t colorref = RGB(tmp.ch.red, tmp.ch.green, tmp.ch.blue);
 | 
						|
    return colorref;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
 |