LOGE("%s() is failed. msg : %s\n", warning_msg, msg);
}
+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)
+{
+ 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);
+
+ 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 = e_client_transform_core_transform_get((E_Client *)ec, i);
+ if (!transform) continue;
+
+ 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;
+}
+
+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)
+{
+ 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;
+ }
+
+ // TODO: need rotation
+}
+
static void
_e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int y, int w, int h)
{
int new_y = y;
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;
+ /* FIXME: The input geometry be changed to match the display server's coordinate system.
+ The input geometry (x, y, w, h) is given in coordinates as the input panel (keyboard) client's angle considering rotation.
+ Because this value differs from the display server's coordinate system,
+ it should be adapt to the display server's coordinate system and calculated.
+ When delivering back to the client, it must be converted to a coordinate system suitable for the client before delivery.
+ (Consider rotation and transformation.)
+
+ 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.
+ 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. */
+
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;
-
// find input panel
EINA_LIST_FOREACH(client_surface_ec->transients, l, ips_ec)
{
if (e_input_panel_client_find(ips_ec)) break;
}
+ }
+
+ if (!ips_ec)
+ {
+ LOGI("couldn't find input panel of client surface ec:%p", client_surface_ec);
+ E_CLIENT_REVERSE_FOREACH(ips_ec)
+ {
+ if (e_input_panel_client_find(ips_ec)) break;
+ }
+ }
+
+ // 1. Modify the incoming client coordinate system to match the display server's coordinate system according to the keyboard's rotation angle.
+ if (ips_ec)
+ {
+ angle = ips_ec->e.state.rot.ang.next < 0 ?
+ ips_ec->e.state.rot.ang.curr :
+ ips_ec->e.state.rot.ang.next;
+
+ e_client_base_output_resolution_desk_useful_geometry_get(ips_ec, &zx, &zy, &zw, &zh, EINA_TRUE);
+ LOGI("ips_ec(%p) zx(%d) zy(%d) zw(%d) zh(%d)", ips_ec, zx, zy, zw, zh);
+
+ switch (angle)
+ {
+ case 90:
+ new_x = y;
+ new_y = zh - x - w;
+ new_w = h;
+ new_h = w;
+ break;
+ case 180:
+ new_x = zw - y - h;
+ new_y = zh - x - w;
+ new_w = w;
+ new_h = h;
+ break;
+ case 270:
+ new_x = zw - y - h;
+ new_y = x;
+ new_w = h;
+ new_h = w;
+ break;
+ case 0:
+ default:
+ new_x = x;
+ new_y = y;
+ new_w = w;
+ new_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);
+ }
- if (ips_ec && !(e_input_panel_floating_mode_get()))
+ // 2. Calculate the geometry suitable for the output scale by applying the opposite values of the keyboard's transform core scale and move.
+ if (ips_ec && !(e_input_panel_floating_mode_get()))
+ {
+ if (e_client_transform_core_enable_get(ips_ec))
{
- 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, w, h, &new_w, &new_h);
- LOGI("input panel using transform. (%d, %d, %dx%d) -> (%d, %d, %dx%d)", x, y, w, h, new_x, new_y, new_w, new_h);
-
- if (e_client_transform_core_enable_get(client_surface_ec))
- {
- e_client_transform_core_input_transform(client_surface_ec, new_x, new_y, &new_x, &new_y);
- e_client_transform_core_input_transform(client_surface_ec, new_w, new_h, &new_w, &new_h);
- LOGI("client_surface_ec using transform. (%d, %d, %dx%d) -> (%d, %d, %dx%d)", x, y, w, h, new_x, new_y, new_w, new_h);
- }
- }
+ 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;
+ 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);
}
- else if (!ips_ec)
- LOGI("couldn't find input panel client");
}
-
- snprintf(geometry, sizeof(geometry), "%d,%d,%d,%d", new_x, y, w, 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.
+ 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);
+ }
+
+ // 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)
+ {
+ 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;
+ LOGI("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);
+ }
+
+ // 5. Pass the value to client_surface_ec
+ snprintf(geometry, sizeof(geometry), "%d,%d,%d,%d", rot_x, rot_y, rot_w, rot_h);
switch(angle)
{
- case 90:
- case 270:
- vconf_set_str(VCONFKEY_ISF_IME_RECENT_LAND_GEOMETRY, geometry);
- break;
- default:
- vconf_set_str(VCONFKEY_ISF_IME_RECENT_PORT_GEOMETRY, geometry);
- break;
+ case 90:
+ case 270:
+ vconf_set_str(VCONFKEY_ISF_IME_RECENT_LAND_GEOMETRY, geometry);
+ break;
+ default:
+ vconf_set_str(VCONFKEY_ISF_IME_RECENT_PORT_GEOMETRY, geometry);
+ break;
}
- LOGI("angle : %d, x : %d, y : %d, w : %d, h : %d\n", angle, new_x, y, w, h);
-
- wl_text_input_send_input_panel_geometry(resource, new_x, y, w, h);
+ wl_text_input_send_input_panel_geometry(resource, rot_x, rot_y, rot_w, rot_h);
}
static gboolean