screen_rotation: Fix logic & tzsr free & init 95/314995/2
authorTaeHyeon Jeong <thyeon.jeong@samsung.com>
Wed, 17 Jul 2024 08:18:24 +0000 (17:18 +0900)
committerDoyoun Kang <doyoun.kang@samsung.com>
Thu, 25 Jul 2024 06:14:22 +0000 (06:14 +0000)
Change-Id: I15b2b102b3400e1f26c83b270f7254793b02f82a

src/bin/server/e_screen_rotation.c

index 6827ace..5777427 100644 (file)
@@ -7,46 +7,62 @@ typedef struct _E_Comp_Screen_Tzsr
 {
    struct ds_tizen_screen_rotation_info *info;
    E_Client *ec;
-   struct wl_listener destroy;
+   struct wl_listener ec_destroy;
 } E_Comp_Screen_Tzsr;
 
 static Eina_List *tzsr_list;
 
 static struct wl_listener transform;
+static struct wl_listener gsr_destroy;
+static struct ds_tizen_screen_rotation *g_screen_rotation = NULL;
+
+static void _tz_screen_rotation_cb_ec_destroy(struct wl_listener *listener, void *data);
 
 static E_Comp_Screen_Tzsr*
-_tz_surface_rotation_find(E_Client *ec)
+_tz_screen_rotation_find(E_Client *ec)
 {
-   E_Comp_Screen_Tzsr *tzsr;
-   Eina_List *l;
-
-   EINA_LIST_FOREACH(tzsr_list, l, tzsr)
-     {
-        if (tzsr->ec == ec)
-          return tzsr;
-     }
+   E_Comp_Screen_Tzsr *tzsr = NULL;
+   struct wl_listener *listener;
 
-   return NULL;
+   listener = e_client_destroy_listener_get(ec, _tz_screen_rotation_cb_ec_destroy);
+   if (listener)
+      return wl_container_of(listener, tzsr, ec_destroy);
+   
+   return tzsr;
 }
 
 static void
-_tz_screen_rotation_info_cb_destroy(struct wl_listener *listener, void *data)
+_tz_screen_rotation_free(E_Comp_Screen_Tzsr *tzsr)
 {
-   E_Comp_Screen_Tzsr *tzsr;
+   ELOGF("TRANSFORM", "|tzsr(%p) freed", tzsr->ec, tzsr);
 
-   tzsr = wl_container_of(listener, tzsr, destroy);
    tzsr_list = eina_list_remove(tzsr_list, tzsr);
+   wl_list_remove(&tzsr->ec_destroy.link);
+
    free(tzsr);
 }
 
 static void
+_tz_screen_rotation_cb_ec_destroy(struct wl_listener *listener, void *data)
+{
+   E_Comp_Screen_Tzsr *tzsr;
+   tzsr = wl_container_of(listener, tzsr, ec_destroy);
+
+   _tz_screen_rotation_free(tzsr);
+}
+
+static void
 _tz_screen_rotation_cb_get_ignore_output_transform(struct wl_listener *listener, void *data)
 {
+   E_Comp_Screen_Tzsr *tzsr;
+   E_Client *ec;
+   E_Hwc_Policy hwc_policy;
+   E_Output *output;
+   E_Zone *zone;
+   Eina_Bool ignore = EINA_TRUE;
    struct ds_tizen_screen_rotation_info *info;
    struct ds_surface *ds_surface;
    struct wl_resource *surface_resource;
-   E_Comp_Screen_Tzsr *tzsr;
-   E_Client *ec;
 
    info = (struct ds_tizen_screen_rotation_info*)data;
    EINA_SAFETY_ON_NULL_RETURN(info);
@@ -58,6 +74,7 @@ _tz_screen_rotation_cb_get_ignore_output_transform(struct wl_listener *listener,
    EINA_SAFETY_ON_NULL_RETURN(surface_resource);
 
    ec = e_client_from_surface_resource(surface_resource);
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    tzsr = E_NEW(E_Comp_Screen_Tzsr, 1);
    if (!tzsr)
@@ -68,26 +85,59 @@ _tz_screen_rotation_cb_get_ignore_output_transform(struct wl_listener *listener,
 
    tzsr->ec = ec;
    tzsr->info = info;
-   tzsr->destroy.notify = _tz_screen_rotation_info_cb_destroy;
-   ds_tizen_screen_rotation_info_add_destroy_listener(info, &tzsr->destroy);
+   tzsr->ec_destroy.notify = _tz_screen_rotation_cb_ec_destroy;
+   e_client_destroy_listener_add(ec, &tzsr->ec_destroy);
 
    tzsr_list = eina_list_append(tzsr_list, tzsr);
+
+   zone = e_comp_zone_find_by_ec(ec);
+   if (zone)
+     {
+        output = e_output_find(zone->output_id);
+        if (output)
+          {
+             hwc_policy = e_hwc_policy_get(output->hwc);
+             if (hwc_policy == E_HWC_POLICY_WINDOWS)
+               ignore = EINA_FALSE;
+          }
+     }
+
+   ELOGF("TRANSFORM", "|tzsr(%p) client_ignore(%d) ignore(%d)",
+         ec, tzsr, e_config->screen_rotation_client_ignore, ignore);
+
+   e_comp_screen_rotation_ignore_output_transform_send(ec, ignore);
+}
+
+static void
+_tz_screen_rotation_cb_destroy(struct wl_listener *listener, void *data)
+{
+   E_Comp_Screen_Tzsr *tzsr;
+   Eina_List *l, *ll;
+
+   EINA_LIST_FOREACH_SAFE(tzsr_list, l, ll, tzsr)
+     {
+        _tz_screen_rotation_free(tzsr);
+     }
 }
 
 EINTERN Eina_Bool
 e_screen_rotation_init()
 {
-   struct ds_tizen_screen_rotation *screen_rotation;
+   if (g_screen_rotation)
+      return EINA_TRUE;
 
-   screen_rotation = ds_tizen_screen_rotation_create(e_comp_wl->wl.disp);
-   if (!screen_rotation)
+   g_screen_rotation = ds_tizen_screen_rotation_create(e_comp_wl->wl.disp);
+   if (!g_screen_rotation)
      {
         ERR("Could not add tizen_screen_rotation to wayland globals");
         return EINA_FALSE;
      }
 
    transform.notify = _tz_screen_rotation_cb_get_ignore_output_transform;
-   ds_tizen_screen_rotation_add_get_ignore_output_transform_info_listener(screen_rotation, &transform);
+   ds_tizen_screen_rotation_add_get_ignore_output_transform_info_listener(g_screen_rotation, &transform);
+
+   gsr_destroy.notify = _tz_screen_rotation_cb_destroy;
+   ds_tizen_screen_rotation_add_destroy_listener(g_screen_rotation, &gsr_destroy);
 
    return EINA_TRUE;
 }
@@ -102,7 +152,7 @@ e_screen_rotation_ignore_output_transform_send(E_Client *ec, Eina_Bool ignore)
 {
    E_Comp_Screen_Tzsr *tzsr;
    
-   tzsr = _tz_surface_rotation_find(ec);
+   tzsr = _tz_screen_rotation_find(ec);
    EINA_SAFETY_ON_NULL_RETURN(tzsr);
 
    ELOGF("TRANSFORM", "|tzsr(%p) ignore_output_transform(%d)", ec, tzsr, ignore);
@@ -113,5 +163,5 @@ e_screen_rotation_ignore_output_transform_send(E_Client *ec, Eina_Bool ignore)
 EINTERN Eina_Bool
 e_screen_rotation_ignore_output_transform_watch(E_Client *ec)
 {
-   return (_tz_surface_rotation_find(ec)) ? EINA_TRUE : EINA_FALSE;
+   return (_tz_screen_rotation_find(ec)) ? EINA_TRUE : EINA_FALSE;
 }