e_mod_main: use transform_core_input_transform instead of manual scale calculate 40/319240/4
authorJunseok Kim <juns.kim@samsung.com>
Fri, 18 Oct 2024 06:27:12 +0000 (15:27 +0900)
committerJunseok Kim <juns.kim@samsung.com>
Thu, 7 Nov 2024 08:25:15 +0000 (17:25 +0900)
The past patch used to get transformed coordinate via manually calculate function when send the geometry of input panel.
(refer patch: 7eacf4f854227b28361d0a417edd21d6fe8e58f9)

However, the issue with e_client_transform_core_input_transform returning unexpected value
is due to a problem in the module's incorrect use of the Z-coordinate scaling value to 0.

To restore this to its original state and handle rotated coordinates by transform,
modify to use the E20 Core's API for obtaining transformed coordinates.

Change-Id: Ia082b53b1d33bab24168d8a9f4983fb96f62ce9b

src/e_mod_main.c

index 127bc7873bda6b5d484ae86b4fcc81dbbadcf90c..224392ba20d10f8f18c5ed3d7f4325bd01d402cd 100644 (file)
@@ -181,75 +181,40 @@ _e_text_input_log_show(struct wl_resource *resource, uint32_t code, const char *
    LOGE("%s() is failed. msg : %s\n", warning_msg, msg);
 }
 
+typedef void (*_coord_transform_func)(E_Client *ec, int in_x, int in_y, int *out_x, int *out_y);
+
 static void
-_e_text_input_transform_core_move_scale_get(E_Client *ec, int *move_x, int *move_y, double *scale_x, double *scale_y, int *angle)
+_transform_core_input_transform(E_Client *transform_ec, int in_x, int in_y, int in_w, int in_h, int *out_x, int *out_y, int *out_w, int *out_h, _coord_transform_func transform_func)
 {
-   int i, count;
-   double sx = 1.0, sy = 1.0;
-   int mx = 0, my = 0;
-   int ang = 0;
-
-   if (!ec) return;
-
-   count = e_client_transform_core_transform_count_get((E_Client *)ec);
+   int p1_x, p1_y, p2_x, p2_y, p3_x, p3_y, p4_x, p4_y;
+   int res_x, res_y, res_w, res_h;
 
-   if (count <= 0) return;
-
-   for (i = 0; i < count; ++i)
-     {
-        double dsx, dsy;
-        int x = 0, y = 0, rz = 0;
-        E_Util_Transform *transform = NULL;
+   transform_func(transform_ec, in_x, in_y, &p1_x, &p1_y);
+   transform_func(transform_ec, in_x, in_y+in_h, &p2_x, &p2_y);
+   transform_func(transform_ec, in_x+in_w, in_y, &p3_x, &p3_y);
+   transform_func(transform_ec, in_x+in_w, in_y+in_h, &p4_x, &p4_y);
 
-        transform = e_client_transform_core_transform_get((E_Client *)ec, i);
-        if (!transform) continue;
+   res_x = MIN(MIN(p1_x, p2_x), MIN(p3_x, p4_x));
+   res_y = MIN(MIN(p1_y, p2_y), MIN(p3_y, p4_y));
+   res_w = MAX(MAX(p1_x, p2_x), MAX(p3_x, p4_x)) - res_x;
+   res_h = MAX(MAX(p1_y, p2_y), MAX(p3_y, p4_y)) - res_y;
 
-        e_util_transform_move_round_get(transform, &x, &y, NULL);
-        e_util_transform_scale_get(transform, &dsx, &dsy, NULL);
-        e_util_transform_rotation_round_get(transform, NULL, NULL, &rz);
-
-        mx += x;
-        my += y;
-        sx *= dsx;
-        sy *= dsy;
-        ang += rz;
-        ang = ang % 360;
-     }
-
-   if (move_x) *move_x = mx;
-   if (move_y) *move_y = my;
-   if (scale_x) *scale_x = sx;
-   if (scale_y) *scale_y = sy;
-   if (angle) *angle = ang;
+   if (out_x) *out_x = res_x;
+   if (out_y) *out_y = res_y;
+   if (out_w) *out_w = res_w;
+   if (out_h) *out_h = res_h;
 }
 
 static void
-_e_text_input_transform_core_scale_adjust(E_Client *ec, int in_x, int in_y, int in_w, int in_h, int *out_x, int *out_y, int *out_w, int *out_h, Eina_Bool reverse)
+_e_text_input_transform_core_input_geom_inv_transform(E_Client *transform_ec, int in_x, int in_y, int in_w, int in_h, int *out_x, int *out_y, int *out_w, int *out_h)
 {
-   double scale_x = 1.0, scale_y = 1.0;
-   int move_x = 0, move_y = 0;
-   int rotation_angle = 0;
-
-   if (!ec) return;
-
-   _e_text_input_transform_core_move_scale_get(ec, &move_x, &move_y, &scale_x, &scale_y, &rotation_angle);
-
-   if (!reverse)
-     {
-        if (out_x) *out_x = in_x + move_x;
-        if (out_y) *out_y = in_y + move_y;
-        if (out_w) *out_w = in_w * scale_x;
-        if (out_h) *out_h = in_h * scale_y;
-     }
-   else
-     {
-        if (out_x) *out_x = (in_x - move_x) / scale_x;
-        if (out_y) *out_y = (in_y - move_y) / scale_y;
-        if (out_w) *out_w = in_w / scale_x;
-        if (out_h) *out_h = in_h / scale_y;
-     }
+   _transform_core_input_transform(transform_ec, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h, e_client_transform_core_input_inv_transform);
+}
 
-   // TODO: need rotation
+static void
+_e_text_input_transform_core_input_geom_transform(E_Client *transform_ec, int in_x, int in_y, int in_w, int in_h, int *out_x, int *out_y, int *out_w, int *out_h)
+{
+   _transform_core_input_transform(transform_ec, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h, e_client_transform_core_input_transform);
 }
 
 static void
@@ -262,7 +227,6 @@ _e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int
    int new_w = w;
    int new_h = h;
    int zx, zy, zw, zh;
-   int old_x, old_y, old_w, old_h;
    int rot_x, rot_y, rot_w, rot_h;
    E_Client *ips_ec = NULL;
    Eina_List *l;
@@ -277,8 +241,8 @@ _e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int
       Accordingly, this function performs the following steps as a workaround:
 
       1. Modify the incoming client coordinate system to match the display server's coordinate system according to the keyboard's rotation angle.
-      2. Calculate the geometry suitable for the output scale by applying the opposite values ​​of the keyboard's transform core scale and move.
-      3. Apply the transform core scale and move values ​​of client_surface_ec to calculate the geometry matching the client scale.
+      2. Apply the inverted transform of the keyboard to the geometry of the keyboard in order to match the screen scale.
+      3. Apply the transform of the client to the geometry of step 2 to match the scale of client.
       4. Change the geometry to fit the client coordinate system according to the client_surface_ec's rotation angle.
       5. Pass the value to client_surface_ec. */
 
@@ -313,111 +277,118 @@ _e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int
         switch (angle)
           {
             case 90:
-                new_x = y;
-                new_y = zh - x - w;
-                new_w = h;
-                new_h = w;
+                rot_x = y;
+                rot_y = zh - x - w;
+                rot_w = h;
+                rot_h = w;
                 break;
             case 180:
-                new_x = zw - y - h;
-                new_y = zh - x - w;
-                new_w = w;
-                new_h = h;
+                rot_x = zw - y - h;
+                rot_y = zh - x - w;
+                rot_w = w;
+                rot_h = h;
                 break;
             case 270:
-                new_x = zw - y - h;
-                new_y = x;
-                new_w = h;
-                new_h = w;
+                rot_x = zw - y - h;
+                rot_y = x;
+                rot_w = h;
+                rot_h = w;
                 break;
             case 0:
             default:
-                new_x = x;
-                new_y = y;
-                new_w = w;
-                new_h = h;
+                rot_x = x;
+                rot_y = y;
+                rot_w = w;
+                rot_h = h;
                 break;
           }
 
-        LOGI("ips_ec(%p): angle:%d, geom(%d, %d, %dx%d) -> angle:0, geom(%d, %d, %dx%d)", ips_ec, angle, x, y, w, h, new_x, new_y, new_w, new_h);
-        x = new_x;
-        y = new_y;
-        w = new_w;
-        h = new_h;
-     }
-
-
-   if (client_surface_ec)
-     {
-        angle = client_surface_ec->e.state.rot.ang.next < 0 ?
-            client_surface_ec->e.state.rot.ang.curr :
-            client_surface_ec->e.state.rot.ang.next;
-
-        LOGI("curr : %d, next : %d, angle : %d\n", client_surface_ec->e.state.rot.ang.curr,
-             client_surface_ec->e.state.rot.ang.next, angle);
+        LOGI("ips_ec(%p): angle:%d, geom(%d, %d, %dx%d) -> angle:0, geom(%d, %d, %dx%d)", ips_ec, angle, x, y, w, h, rot_x, rot_y, rot_w, rot_h);
+        x = rot_x;
+        y = rot_y;
+        w = rot_w;
+        h = rot_h;
      }
 
-   // 2. Calculate the geometry suitable for the output scale by applying the opposite values ​​of the keyboard's transform core scale and move.
+   // 2. Apply the inverted transform of the keyboard to the geometry of the keyboard in order to match the screen scale.
    if (ips_ec && !(e_input_panel_floating_mode_get()))
      {
         if (e_client_transform_core_enable_get(ips_ec))
           {
-             e_client_transform_core_input_inv_transform(ips_ec, x, y, &new_x, &new_y);
-             e_client_transform_core_input_inv_transform(ips_ec, x + w, y + h, &new_w, &new_h);
-             new_w = new_w - new_x;
-             new_h = new_h - new_y;
+             _e_text_input_transform_core_input_geom_inv_transform(ips_ec, x, y, w, h, &new_x, &new_y, &new_w, &new_h);
              LOGI("input panel(%p) using transform. (%d, %d, %dx%d) -> (%d, %d, %dx%d)", ips_ec, x, y, w, h, new_x, new_y, new_w, new_h);
+             x = new_x;
+             y = new_y;
+             w = new_w;
+             h = new_h;
           }
      }
    else if (!ips_ec)
      LOGI("couldn't find input panel client");
 
-   // 3. Apply the transform core scale and move values ​​of client_surface_ec to calculate the geometry matching the client scale.
+   // 3. Apply the transform of the client to the geometry of step 2 to match the scale of client.
    if (e_client_transform_core_enable_get(client_surface_ec))
      {
-        old_x = new_x;
-        old_y = new_y;
-        old_w = new_w;
-        old_h = new_h;
-        _e_text_input_transform_core_scale_adjust(client_surface_ec, old_x, old_y, old_w, old_h, &new_x, &new_y, &new_w, &new_h, EINA_TRUE);
-        LOGI("client_surface_ec(%p) using transform. (%d, %d, %dx%d) -> (%d, %d, %dx%d)", client_surface_ec, old_x, old_y, old_w, old_h, new_x, new_y, new_w, new_h);
+        _e_text_input_transform_core_input_geom_transform(client_surface_ec, x, y, w, h, &new_x, &new_y, &new_w, &new_h);
+        LOGI("client_surface_ec(%p) using transform. (%d, %d, %dx%d) -> (%d, %d, %dx%d)", client_surface_ec, x, y, w, h, new_x, new_y, new_w, new_h);
+        x = new_x;
+        y = new_y;
+        w = new_w;
+        h = new_h;
      }
 
    // 4. Change the geometry to fit the client coordinate system according to the client_surface_ec's rotation angle.
-   e_client_base_output_resolution_desk_useful_geometry_get(client_surface_ec, &zx, &zy, &zw, &zh, EINA_TRUE);
-   LOGI("client surface ec(%p) zx(%d) zy(%d) zw(%d) zh(%d)", client_surface_ec, zx, zy, zw, zh);
-   switch (angle)
+   if (client_surface_ec)
      {
-       case 90:
-           rot_x = zh - new_y - new_h;
-           rot_y = new_x;
-           rot_w = new_h;
-           rot_h = new_w;
-           break;
-       case 180:
-           rot_x = zh - new_y - new_h;
-           rot_y = zw - new_x - new_w;
-           rot_w = new_w;
-           rot_h = new_h;
-           break;
-       case 270:
-           rot_x = new_y;
-           rot_y = zw - new_x - new_w;
-           rot_w = new_h;
-           rot_h = new_w;
-           break;
-       case 0:
-       default:
-           rot_x = new_x;
-           rot_y = new_y;
-           rot_w = new_w;
-           rot_h = new_h;
-           break;
+        angle = client_surface_ec->e.state.rot.ang.next < 0 ?
+            client_surface_ec->e.state.rot.ang.curr :
+            client_surface_ec->e.state.rot.ang.next;
+
+        LOGI("curr : %d, next : %d, angle : %d\n", client_surface_ec->e.state.rot.ang.curr,
+             client_surface_ec->e.state.rot.ang.next, angle);
+
+        e_client_base_output_resolution_desk_useful_geometry_get(client_surface_ec, &zx, &zy, &zw, &zh, EINA_TRUE);
+        LOGI("client surface ec(%p) zx(%d) zy(%d) zw(%d) zh(%d)", client_surface_ec, zx, zy, zw, zh);
+
+        switch (angle)
+          {
+            case 90:
+                rot_x = zh - y - h;
+                rot_y = x;
+                rot_w = h;
+                rot_h = w;
+                break;
+            case 180:
+                rot_x = zh - y - h;
+                rot_y = zw - x - w;
+                rot_w = w;
+                rot_h = h;
+                break;
+            case 270:
+                rot_x = y;
+                rot_y = zw - x - w;
+                rot_w = h;
+                rot_h = w;
+                break;
+            case 0:
+            default:
+                rot_x = x;
+                rot_y = y;
+                rot_w = w;
+                rot_h = h;
+                break;
+          }
+        LOGI("ips_ec(%p): angle:0, geom(%d, %d, %dx%d) -> angle:%d, geom(%d, %d, %dx%d)", ips_ec, x, y, w, h, angle, rot_x, rot_y, rot_w, rot_h);
+        x = rot_x;
+        y = rot_y;
+        w = rot_w;
+        h = rot_h;
      }
-   LOGI("final result of ips_ec(%p): angle:0, geom(%d, %d, %dx%d) -> angle:%d, geom(%d, %d, %dx%d)", ips_ec, new_x, new_y, new_w, new_h, angle, rot_x, rot_y, rot_w, rot_h);
+
+   LOGI("final result of ips_ec(%p): geom(%d, %d, %dx%d)", ips_ec, x, y, w, h);
 
    // 5. Pass the value to client_surface_ec
-   snprintf(geometry, sizeof(geometry), "%d,%d,%d,%d", rot_x, rot_y, rot_w, rot_h);
+   snprintf(geometry, sizeof(geometry), "%d,%d,%d,%d", x, y, w, h);
 
    switch(angle)
      {
@@ -430,7 +401,7 @@ _e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int
            break;
      }
 
-   wl_text_input_send_input_panel_geometry(resource, rot_x, rot_y, rot_w, rot_h);
+   wl_text_input_send_input_panel_geometry(resource, x, y, w, h);
 }
 
 static gboolean