From 9c400b33b913c82429e7ae1aad831642fac63f99 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 21 Oct 2022 16:40:30 +0900 Subject: [PATCH] tinyds-tdm: create cursor and show it when mouse connected cursor is a simple red box for now. (cursor size: 10x16) Change-Id: Ie2b323c15f4086e327fba9a66885ea738eea6271 --- examples/tinyds-tdm-renderer.c | 63 +++++++++++++++++++++++++++ examples/tinyds-tdm-renderer.h | 19 ++++++++ examples/tinyds-tdm.c | 98 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 178 insertions(+), 2 deletions(-) diff --git a/examples/tinyds-tdm-renderer.c b/examples/tinyds-tdm-renderer.c index 0074dc9..dd891b6 100644 --- a/examples/tinyds-tdm-renderer.c +++ b/examples/tinyds-tdm-renderer.c @@ -68,6 +68,57 @@ renderer_set_bg_color(struct tinyds_renderer *renderer, pthread_mutex_unlock(&renderer->mutex); } +#ifdef USE_CURSOR +void +renderer_cursor_create(struct tinyds_renderer *renderer, + uint8_t r, uint8_t g, uint8_t b, uint32_t width, uint32_t height) +{ + pixman_color_t color; + + pthread_mutex_lock(&renderer->mutex); + + color_rgb888(&color, r, g, b); + + renderer->cursor_image = pixman_image_create_solid_fill(&color); + assert(renderer->cursor_image); + + renderer->damaged = true; + + renderer->cursor.w = width; + renderer->cursor.h = height; + + pthread_mutex_unlock(&renderer->mutex); +} + +void +renderer_cursor_destroy(struct tinyds_renderer *renderer) +{ + pthread_mutex_lock(&renderer->mutex); + + if (renderer->cursor_image) + { + pixman_image_unref(renderer->cursor_image); + renderer->cursor_image = NULL; + } + + renderer->damaged = true; + + pthread_mutex_unlock(&renderer->mutex); +} + +void +renderer_cursor_update(struct tinyds_renderer *renderer, + uint32_t x, uint32_t y) +{ + pthread_mutex_lock(&renderer->mutex); + + renderer->cursor.x = x; + renderer->cursor.y = y; + + pthread_mutex_unlock(&renderer->mutex); +} +#endif + void renderer_add_texture(struct tinyds_renderer *renderer, tbm_surface_h tbm_surface, int x, int y) @@ -151,6 +202,18 @@ renderer_thread_func(void *data) pixman_image_get_height(dst_image)); } +#ifdef USE_CURSOR + if (renderer->cursor_image) { + pixman_image_composite32(PIXMAN_OP_OVER, + renderer->cursor_image, + NULL, + dst_image, + 0, 0, 0, 0, + renderer->cursor.x, renderer->cursor.y, + renderer->cursor.w, renderer->cursor.h); + } +#endif + wl_list_for_each_safe(texture, texture_tmp, &renderer->textures, link) { ds_dbg("Draw texture(%p)", texture); pixman_image_composite32(PIXMAN_OP_OVER, diff --git a/examples/tinyds-tdm-renderer.h b/examples/tinyds-tdm-renderer.h index 5f3e6fd..943e2be 100644 --- a/examples/tinyds-tdm-renderer.h +++ b/examples/tinyds-tdm-renderer.h @@ -7,6 +7,8 @@ #include #include +#define USE_CURSOR + struct tinyds_renderer { tbm_surface_queue_h surface_queue; @@ -19,6 +21,14 @@ struct tinyds_renderer pixman_image_t *bg_image; +#ifdef USE_CURSOR + pixman_image_t *cursor_image; + + struct { + uint32_t x, y, w, h; + } cursor; +#endif + bool damaged; bool destroying; }; @@ -45,4 +55,13 @@ void renderer_add_texture(struct tinyds_renderer *renderer, tbm_surface_h tbm_surface, int x, int y); void renderer_draw(struct tinyds_renderer *renderer); +#ifdef USE_CURSOR +void renderer_cursor_create(struct tinyds_renderer *renderer, + uint8_t r, uint8_t g, uint8_t b, uint32_t width, uint32_t height); +void renderer_cursor_destroy(struct tinyds_renderer *renderer); +void +renderer_cursor_update(struct tinyds_renderer *renderer, + uint32_t x, uint32_t y); +#endif + #endif diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index abed3ab..2a54e3d 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -33,6 +33,8 @@ #include #define USE_TDM_BUFFER_QUEUE +#define CURSOR_W 10 +#define CURSOR_H 16 #ifdef USE_TDM_BUFFER_QUEUE #include "pixman-tbm-helper.h" @@ -74,6 +76,11 @@ struct tinyds_output struct ds_tdm_output_hwc *hwc; struct ds_tdm_output_hwc_window *bg_hwc_window; + +#ifdef USE_CURSOR + bool cursor_enabled; + struct ds_tdm_output_hwc_window *cursor_hwc_window; +#endif }; struct tinyds_dpms @@ -631,6 +638,10 @@ backend_handle_new_output(struct wl_listener *listener, void *data) ds_tdm_output_hwc_window_set_dest_size(output->bg_hwc_window, output->width, output->height); ds_tdm_output_hwc_window_set_transform(output->bg_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL); +#ifdef USE_CURSOR + output->cursor_enabled = false; +#endif + output->output_destroy.notify = output_handle_destroy; ds_output_add_destroy_listener(ds_output, &output->output_destroy); @@ -640,6 +651,8 @@ backend_handle_new_output(struct wl_listener *listener, void *data) ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height); server->output = output; + server->output_x = (double)(output->width) / 2; + server->output_y = (double)(output->height) / 2; output_schedule_commit(output); } @@ -1109,6 +1122,25 @@ output_commit(struct tinyds_output *output) need_target = true; } +#ifdef USE_CURSOR + if (output->cursor_hwc_window) { + src_box.x = 0; + src_box.y = 0; + src_box.width = CURSOR_W; + src_box.height = CURSOR_H; + + ds_tdm_output_hwc_window_set_src_box(output->cursor_hwc_window, &src_box); + ds_tdm_output_hwc_window_set_position(output->cursor_hwc_window, output->server->output_x, output->server->output_y); + ds_tdm_output_hwc_window_set_dest_size(output->cursor_hwc_window, CURSOR_W, CURSOR_H); + ds_tdm_output_hwc_window_set_transform(output->cursor_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL); + + ds_tdm_output_hwc_window_set_composition(output->cursor_hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT); + num_windows++; + need_target = true; + } +#endif + if (num_windows) { composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows); if (!composited_hwc_windows) @@ -1138,6 +1170,10 @@ output_commit(struct tinyds_output *output) ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL); if (view->mapped) { +#ifdef USE_CURSOR + ds_tdm_output_hwc_window_set_composition(view->hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT); +#endif ds_tdm_output_hwc_window_set_composition(view->hwc_window, DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE); @@ -1153,6 +1189,13 @@ output_commit(struct tinyds_output *output) composited_hwc_windows[current_num_windows] = output->bg_hwc_window; current_num_windows++; } + +#ifdef USE_CURSOR + if (output->cursor_hwc_window) { + composited_hwc_windows[current_num_windows] = output->cursor_hwc_window; + current_num_windows++; + } +#endif } if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows, @@ -1708,6 +1751,13 @@ touch_handle_down(struct wl_listener *listener, void *data) ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface), event->time_msec, event->id, sx, sy); } + +#ifdef USE_CURSOR + if (server->output && server->output->cursor_enabled) { + renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y); + draw_server_with_damage(server); + } +#endif } static void @@ -1748,6 +1798,13 @@ touch_handle_motion(struct wl_listener *listener, void *data) ds_seat_touch_notify_motion(server->seat, event->time_msec, event->id, sx, sy); } + +#ifdef USE_CURSOR + if (server->output && server->output->cursor_enabled) { + renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y); + draw_server_with_damage(server); + } +#endif } static void @@ -1780,6 +1837,7 @@ static void pointer_handle_device_destroy(struct wl_listener *listener, void *data) { struct tinyds_pointer *pointer; + struct tinyds_server *server; pointer = wl_container_of(listener, pointer, destroy); @@ -1791,6 +1849,22 @@ pointer_handle_device_destroy(struct wl_listener *listener, void *data) wl_list_remove(&pointer->frame.link); wl_list_remove(&pointer->link); +#ifdef USE_CURSOR + server = pointer->server; + if (server->output && wl_list_empty(&server->pointers)) + { + server->output->cursor_enabled = false; + renderer_cursor_destroy(&server->output->renderer); + + if (server->output->cursor_hwc_window) + { + ds_tdm_output_hwc_window_destroy(server->output->cursor_hwc_window); + server->output->cursor_hwc_window = NULL; + } + draw_server_with_damage(server); + } +#endif + free(pointer); } @@ -1849,6 +1923,13 @@ pointer_handle_motion(struct wl_listener *listener, void *data) ds_seat_pointer_notify_motion(pointer->server->seat, event->time_msec, sx, sy); } + +#ifdef USE_CURSOR + if (server->output && server->output->cursor_enabled) { + renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y); + draw_server_with_damage(server); + } +#endif } static void @@ -1888,8 +1969,6 @@ server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) pointer->dev = dev; pointer->server = server; - server->output_x = 200; - server->output_y = 200; pointer->destroy.notify = pointer_handle_device_destroy; ds_input_device_add_destroy_listener(dev, &pointer->destroy); @@ -1908,6 +1987,21 @@ server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) pointer->focused_view = NULL; +#ifdef USE_CURSOR + if (server->output && wl_list_empty(&server->pointers)) { + server->output_x = (double)(server->output->width) / 2; + server->output_y = (double)(server->output->height) / 2; + + server->output->cursor_enabled = true; + renderer_cursor_create(&server->output->renderer, 255, 0, 0, CURSOR_W, CURSOR_H); + renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y); + + server->output->cursor_hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc); + assert(server->output->cursor_hwc_window); + draw_server_with_damage(server); + } +#endif + wl_list_insert(&server->pointers, &pointer->link); ds_inf("Pointer(%p) added", pointer); -- 2.7.4