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
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;
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. */
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)
{
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