From c42392c80a7e145999d0a86ae775068451b7963f Mon Sep 17 00:00:00 2001 From: Jiajian Wu Date: Wed, 26 Apr 2023 22:05:53 +0800 Subject: [PATCH] sdl: sdl_gpu: support screen rotation Signed-off-by: Jiajian Wu --- sdl/sdl_common.c | 43 +++++++++++++++++++++++++++-------- sdl/sdl_gpu.c | 59 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 17 deletions(-) diff --git a/sdl/sdl_common.c b/sdl/sdl_common.c index b34c7fee..b35bd83b 100644 --- a/sdl/sdl_common.c +++ b/sdl/sdl_common.c @@ -38,6 +38,7 @@ static char buf[KEYBOARD_BUFFER_SIZE]; /********************** * GLOBAL FUNCTIONS **********************/ +extern int monitor_rotated(void); /** * Get the current position and state of the mouse * @param indev_drv pointer to the related input device driver @@ -113,6 +114,8 @@ int quit_filter(void * userdata, SDL_Event * event) void mouse_handler(SDL_Event * event) { + int rotated = monitor_rotated(); + int16_t x, y; switch(event->type) { case SDL_MOUSEBUTTONUP: if(event->button.button == SDL_BUTTON_LEFT) @@ -121,31 +124,51 @@ void mouse_handler(SDL_Event * event) case SDL_MOUSEBUTTONDOWN: if(event->button.button == SDL_BUTTON_LEFT) { left_button_down = true; - last_x = event->motion.x / SDL_ZOOM; - last_y = event->motion.y / SDL_ZOOM; + x = event->motion.x / SDL_ZOOM; + y = event->motion.y / SDL_ZOOM; } break; case SDL_MOUSEMOTION: - last_x = event->motion.x / SDL_ZOOM; - last_y = event->motion.y / SDL_ZOOM; + x = event->motion.x / SDL_ZOOM; + y = event->motion.y / SDL_ZOOM; break; case SDL_FINGERUP: left_button_down = false; - last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; - last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; + x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; + y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; break; case SDL_FINGERDOWN: left_button_down = true; - last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; - last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; + x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; + y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; break; case SDL_FINGERMOTION: - last_x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; - last_y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; + x = LV_HOR_RES * event->tfinger.x / SDL_ZOOM; + y = LV_VER_RES * event->tfinger.y / SDL_ZOOM; break; } + switch (rotated) + { + case LV_DISP_ROT_NONE: + default: + last_x = x; + last_y = y; + break; + case LV_DISP_ROT_90: + last_x = y; + last_y = LV_VER_RES - x; + break; + case LV_DISP_ROT_180: + last_x = LV_HOR_RES - x; + last_y = LV_VER_RES - y; + break; + case LV_DISP_ROT_270: + last_x = LV_HOR_RES - y; + last_y = x; + break; + } } diff --git a/sdl/sdl_gpu.c b/sdl/sdl_gpu.c index 51ce536c..f7960bec 100644 --- a/sdl/sdl_gpu.c +++ b/sdl/sdl_gpu.c @@ -50,8 +50,11 @@ typedef struct { lv_draw_sdl_drv_param_t drv_param; lv_coord_t hor_res; lv_coord_t ver_res; + lv_coord_t d_hor_res; + lv_coord_t d_ver_res; SDL_Window * window; SDL_Texture * texture; + int rotated; }monitor_t; /********************** @@ -93,17 +96,20 @@ void sdl_init(void) void sdl_disp_drv_init(lv_disp_drv_t * disp_drv, lv_coord_t hor_res, lv_coord_t ver_res) { + int rotated = disp_drv->rotated <= LV_DISP_ROT_270 ? disp_drv->rotated : LV_DISP_ROT_NONE; monitor_t *m = lv_mem_alloc(sizeof(monitor_t)); m->hor_res = hor_res; m->ver_res = ver_res; + m->rotated = rotated; window_create(m); hor_res = m->hor_res; ver_res = m->ver_res; lv_disp_drv_init(disp_drv); disp_drv->direct_mode = 1; disp_drv->flush_cb = monitor_flush; - disp_drv->hor_res = hor_res; - disp_drv->ver_res = ver_res; + disp_drv->hor_res = m->d_hor_res; + disp_drv->ver_res = m->d_ver_res; + disp_drv->rotated = LV_DISP_ROT_NONE; lv_disp_draw_buf_t *disp_buf = lv_mem_alloc(sizeof(lv_disp_draw_buf_t)); lv_disp_draw_buf_init(disp_buf, m->texture, NULL, hor_res * ver_res); disp_drv->draw_buf = disp_buf; @@ -144,14 +150,25 @@ void sdl_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_colo void sdl_display_resize(lv_disp_t *disp, int width, int height) { lv_disp_drv_t *driver = disp->driver; + monitor_t *m = (monitor_t *)driver->user_data; SDL_Renderer *renderer = ((lv_draw_sdl_drv_param_t *) driver->user_data)->renderer; if (driver->draw_buf->buf1) { SDL_DestroyTexture(driver->draw_buf->buf1); } - SDL_Texture *texture = lv_draw_sdl_create_screen_texture(renderer, width, height); + if (m->rotated == LV_DISP_ROT_90 || + m->rotated == LV_DISP_ROT_270) { + m->d_hor_res = height; + m->d_ver_res = width; + } else { + m->d_hor_res = width; + m->d_ver_res = height; + } + m->hor_res = width; + m->ver_res = height; + SDL_Texture *texture = lv_draw_sdl_create_screen_texture(renderer, m->d_hor_res, m->d_ver_res); lv_disp_draw_buf_init(driver->draw_buf, texture, NULL, width * height); - driver->hor_res = (lv_coord_t) width; - driver->ver_res = (lv_coord_t) height; + driver->hor_res = (lv_coord_t) m->d_hor_res; + driver->ver_res = (lv_coord_t) m->d_ver_res; SDL_RendererInfo renderer_info; SDL_GetRendererInfo(renderer, &renderer_info); SDL_assert(renderer_info.flags & SDL_RENDERER_TARGETTEXTURE); @@ -233,6 +250,20 @@ static void sdl_event_handler(lv_timer_t * t) } } +int monitor_rotated(void) +{ + int rotated = LV_DISP_ROT_NONE; + + lv_disp_t *cur = lv_disp_get_next(NULL); + if (cur) { + lv_disp_t * tmp = cur; + monitor_t * m = tmp->driver->user_data; + rotated = m->rotated; + } + + return rotated; +} + static void monitor_sdl_clean_up(void) { for (lv_disp_t *cur = lv_disp_get_next(NULL); cur; ) { @@ -258,6 +289,15 @@ static void window_create(monitor_t * m) m->ver_res = rect.h; } + if (m->rotated == LV_DISP_ROT_90 || + m->rotated == LV_DISP_ROT_270) { + m->d_hor_res = m->ver_res; + m->d_ver_res = m->hor_res; + } else { + m->d_hor_res = m->hor_res; + m->d_ver_res = m->ver_res; + } + m->window = SDL_CreateWindow("TFT Simulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m->hor_res * SDL_ZOOM, m->ver_res * SDL_ZOOM, @@ -265,7 +305,7 @@ static void window_create(monitor_t * m) m->drv_param.renderer = SDL_CreateRenderer(m->window, -1, SDL_RENDERER_ACCELERATED); - m->texture = lv_draw_sdl_create_screen_texture(m->drv_param.renderer, m->hor_res, m->ver_res); + m->texture = lv_draw_sdl_create_screen_texture(m->drv_param.renderer, m->d_hor_res, m->d_ver_res); /* For first frame */ SDL_SetRenderTarget(m->drv_param.renderer, m->texture); } @@ -275,6 +315,7 @@ static void window_update(lv_disp_drv_t *disp_drv, void * buf) SDL_Renderer *renderer = ((lv_draw_sdl_drv_param_t *) disp_drv->user_data)->renderer; monitor_t *m = (monitor_t *)disp_drv->user_data; SDL_Texture *texture = buf; + SDL_Rect dst; SDL_SetRenderTarget(renderer, NULL); SDL_RenderClear(renderer); #if LV_COLOR_SCREEN_TRANSP @@ -284,10 +325,14 @@ static void window_update(lv_disp_drv_t *disp_drv, void * buf) SDL_RenderDrawRect(renderer, &r); #endif + dst.x = (m->hor_res - m->d_hor_res) / 2; + dst.y = (m->ver_res - m->d_ver_res) / 2; + dst.w = m->d_hor_res; + dst.h = m->d_ver_res; /*Update the renderer with the texture containing the rendered image*/ SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); SDL_RenderSetClipRect(renderer, NULL); - SDL_RenderCopy(renderer, texture, NULL, NULL); + SDL_RenderCopyEx(renderer, texture, NULL, &dst, 90.0 * m->rotated, NULL, SDL_FLIP_NONE); SDL_RenderPresent(renderer); SDL_SetRenderTarget(renderer, texture); } -- 2.25.1