tinyds-tdm: create cursor and show it when mouse connected 60/283360/1
authorduna.oh <duna.oh@samsung.com>
Fri, 21 Oct 2022 07:40:30 +0000 (16:40 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 25 Oct 2022 06:36:30 +0000 (15:36 +0900)
cursor is a simple red box for now. (cursor size: 10x16)

Change-Id: Ie2b323c15f4086e327fba9a66885ea738eea6271

examples/tinyds-tdm-renderer.c
examples/tinyds-tdm-renderer.h
examples/tinyds-tdm.c

index 0074dc9..dd891b6 100644 (file)
@@ -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,
index 5f3e6fd..943e2be 100644 (file)
@@ -7,6 +7,8 @@
 #include <tbm_surface.h>
 #include <wayland-server.h>
 
+#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
index abed3ab..2a54e3d 100644 (file)
@@ -33,6 +33,8 @@
 #include <libds-tizen/policy.h>
 
 #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);