Compare commits

...

12 Commits

Author SHA1 Message Date
Chris Michael 868ea0fb76 check siginfo si_code to verify that SIGUSR2 comes from user
When VT switching away and back, the kernel uses SIGUSR1 and SIGUSR2
to notify us of a vt switch event. That same signal was being trapped
here to toggle display of the 'fps' window. If we check the signal's
si_code, we can tell if this signal came from the kernel (as in vt
switch) or from the user (as is sent in 'kill'). This fixes the issue
of VT-switching back and forth under DRM would cause the compositor
'fps' display to appear.

Signed-off-by: Chris Michael <cpmichael@osg.samsung.com>
2016-01-21 11:44:19 -05:00
Mike Blumenkrantz 0973acbd60 remove _e_comp_wl_focus_down_set()
this function does nothing for wayland clients and never should have
been used in this file
2016-01-21 09:26:55 -05:00
Mike Blumenkrantz 73bcac7e72 reenable fallthrough surface (un)mapping for subsurfaces during commit
subsurfaces have no shell interface and rely upon the map state of parent
surfaces to determine whether they are mapped
2016-01-21 09:26:55 -05:00
Mike Blumenkrantz b14a9ca273 add render updates for cursor clients if damages exist during set_cursor
this indicates a cursor surface which has been committed but could not be
rendered due to lack of shell interface and cursor hint
2016-01-21 09:26:55 -05:00
Mike Blumenkrantz 86fc2b4019 remove duplicate visibility setting blocks from wayland surface commit
this is already present (and identical) in state commit
2016-01-21 09:26:55 -05:00
Mike Blumenkrantz 04aebcbeda always apply damages and input regions during wayland commit
mapped status is not relevant according to spec
2016-01-21 09:26:55 -05:00
Mike Blumenkrantz cd2ed1fc78 do not set focus in wayland client show callback for cursor clients 2016-01-21 09:26:55 -05:00
Mike Blumenkrantz 813a78ca05 automatically mark wayland cursor surfaces as visible during set_cursor
a cursor client should be shown/hidden as needed despite its lack of a
shell interface, and having a special flag to identify these types of
surfaces makes it easier to do that
2016-01-21 09:26:55 -05:00
Mike Blumenkrantz 8999b6029d add wayland-only mouse action for translating a button press to a key
in some cases it might be desirable to remap a mouse button to a key.
this is not very user-friendly since it requires device-specific key names
which need to be translated to/from files such as /usr/share/X11/xkb/keycodes/evdev

 #SamsungFeatures
2016-01-21 09:26:55 -05:00
Mike Blumenkrantz efc247c376 add function for wayland compositors to generate (fake) keyboard events
in automated testing scenarios, being able to generate input events is useful
for detecting regressions related to keyboard actions

this depends on an xkbcommon function which is expected to be in the 0.6.0
release, so dlsym here in order to make that a runtime dependency for now
since this is not going to be a widely-used feature

 #SamsungFeatures
2016-01-21 09:26:55 -05:00
Chris Michael a4f3966afe fix compiler warning about comparison between signed and unsigned ints
Signed-off-by: Chris Michael <cpmichael@osg.samsung.com>
2016-01-21 09:26:55 -05:00
Chris Michael 5ec50a9e74 Add support for configuring output rotations
When running under DRM, this patch adds support for getting the
supported rotations of an output, listing them in the Screen Setup
dialog, and adds the ability to set a rotation on a given screen

Signed-off-by: Chris Michael <cpmichael@osg.samsung.com>
2016-01-20 10:54:18 -05:00
8 changed files with 182 additions and 58 deletions

View File

@ -2941,6 +2941,52 @@ ACT_FN_GO(kbd_layout_prev, EINA_UNUSED)
e_xkb_layout_prev(); e_xkb_layout_prev();
} }
#ifdef HAVE_WAYLAND
ACT_FN_GO_MOUSE(mouse_to_key, )
{
const char *p, *nextp, *key = NULL;
const char *mods[] =
{
"shift",
"ctrl",
"alt",
"win",
"altgr",
NULL
};
int modifiers = 0, mod = 0;
if ((!params) || (!params[0]) || (params[0] == '+')) return;
for (p = params; p; p = nextp)
{
const char **m;
nextp = strchr(p + 1, '+');
if (!nextp) break;
for (m = mods; *m; m++)
{
if (strncmp(p, *m, nextp - p)) continue;
modifiers |= 1 << (m - mods);
break;
}
key = nextp;
}
if (key)
key++;
else
key = params;
if (!key[0]) return;
mod |= (ECORE_EVENT_MODIFIER_SHIFT * !!(modifiers & E_BINDING_MODIFIER_SHIFT));
mod |= (ECORE_EVENT_MODIFIER_CTRL * !!(modifiers & E_BINDING_MODIFIER_CTRL));
mod |= (ECORE_EVENT_MODIFIER_ALT * !!(modifiers & E_BINDING_MODIFIER_ALT));
mod |= (ECORE_EVENT_MODIFIER_WIN * !!(modifiers & E_BINDING_MODIFIER_WIN));
mod |= (ECORE_EVENT_MODIFIER_ALTGR * !!(modifiers & E_BINDING_MODIFIER_ALTGR));
e_comp_wl_input_keyboard_event_generate(key, mod, 0);
e_comp_wl_input_keyboard_event_generate(key, mod, 1);
}
#endif
ACT_FN_GO(module_enable, ) ACT_FN_GO(module_enable, )
{ {
E_Module *m; E_Module *m;
@ -2999,6 +3045,27 @@ static Eina_List *action_list = NULL;
static Eina_List *action_names = NULL; static Eina_List *action_names = NULL;
static Eina_List *action_groups = NULL; static Eina_List *action_groups = NULL;
static void
_e_actions_post_init(void *d EINA_UNUSED)
{
#ifdef HAVE_WAYLAND
E_Action *act;
/* wayland-specific actions */
if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
{
/* mouse -> key */
/* "key" here is the platform-specific key name;
* /usr/share/X11/xkb/keycodes/evdev is probably what your system is using
*/
ACT_GO_MOUSE(mouse_to_key);
e_action_predef_name_set(N_("Mouse Remapping"),
N_("Mouse to key"), "mouse_to_key",
NULL, "[AD02] [ctrl+shift+alt+win+altgr+AD02]", 1);
}
#endif
}
/* externally accessible functions */ /* externally accessible functions */
EINTERN int EINTERN int
@ -3561,6 +3628,8 @@ e_actions_init(void)
N_("Previous keyboard layout"), "kbd_layout_prev", N_("Previous keyboard layout"), "kbd_layout_prev",
NULL, NULL, 0); NULL, NULL, 0);
ecore_job_add(_e_actions_post_init, NULL);
return 1; return 1;
} }

View File

@ -817,6 +817,12 @@ _e_comp_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Event_Key *
static Eina_Bool static Eina_Bool
_e_comp_signal_user(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Event_Signal_User *ev) _e_comp_signal_user(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Event_Signal_User *ev)
{ {
siginfo_t sig;
sig = ev->data;
/* anything sent via 'kill' will set this code to SI_USER */
if (sig.si_code != SI_USER) return ECORE_CALLBACK_PASS_ON;
if (ev->number == 1) if (ev->number == 1)
{ {
// e uses this to pop up config panel // e uses this to pop up config panel

View File

@ -54,16 +54,6 @@ _e_comp_wl_configure_send(E_Client *ec, Eina_Bool edges)
w, h); w, h);
} }
static void
_e_comp_wl_focus_down_set(E_Client *ec)
{
Ecore_Window win = 0;
win = e_client_util_pwin_get(ec);
e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, win);
e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, win);
}
static void static void
_e_comp_wl_focus_check(void) _e_comp_wl_focus_check(void)
{ {
@ -123,7 +113,7 @@ _e_comp_wl_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN
if (!ec->override) e_hints_window_visible_set(ec); if (!ec->override) e_hints_window_visible_set(ec);
if (!ec->ignored) if ((!ec->ignored) && (!ec->comp_data->cursor))
{ {
if (ec->new_client) if (ec->new_client)
ec->take_focus = !starting; ec->take_focus = !starting;
@ -1070,7 +1060,8 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
{ {
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap)) if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
ec->comp_data->shell.unmap(ec->comp_data->shell.surface); ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
else if (e_client_has_xwindow(ec)) else if (ec->comp_data->cursor || e_client_has_xwindow(ec) ||
(ec->comp_data->sub.data && ec->comp_data->sub.data->parent->comp_data->mapped))
{ {
ec->visible = EINA_FALSE; ec->visible = EINA_FALSE;
evas_object_hide(ec->frame); evas_object_hide(ec->frame);
@ -1084,7 +1075,8 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
{ {
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map)) if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map))
ec->comp_data->shell.map(ec->comp_data->shell.surface); ec->comp_data->shell.map(ec->comp_data->shell.surface);
else if (e_client_has_xwindow(ec)) else if (ec->comp_data->cursor || e_client_has_xwindow(ec) ||
(ec->comp_data->sub.data && ec->comp_data->sub.data->parent->comp_data->mapped))
{ {
ec->visible = EINA_TRUE; ec->visible = EINA_TRUE;
ec->ignored = 0; ec->ignored = 0;
@ -1163,7 +1155,6 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
state->frames = NULL; state->frames = NULL;
ec->ignored = ignored; ec->ignored = ignored;
if (!ec->comp_data->mapped) goto unmapped;
/* put state damages into surface */ /* put state damages into surface */
if ((!e_comp->nocomp) && (ec->frame)) if ((!e_comp->nocomp) && (ec->frame))
@ -1227,13 +1218,6 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
/* clear input tiler */ /* clear input tiler */
eina_tiler_clear(state->input); eina_tiler_clear(state->input);
} }
return;
unmapped:
/* clear pending damages */
EINA_LIST_FREE(state->damages, dmg)
eina_rectangle_free(dmg);
} }
static void static void
@ -2744,44 +2728,10 @@ e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id)
EINTERN Eina_Bool EINTERN Eina_Bool
e_comp_wl_surface_commit(E_Client *ec) e_comp_wl_surface_commit(E_Client *ec)
{ {
Eina_Bool ignored;
_e_comp_wl_surface_state_commit(ec, &ec->comp_data->pending); _e_comp_wl_surface_state_commit(ec, &ec->comp_data->pending);
if (!e_comp_object_damage_exists(ec->frame)) if (!e_comp_object_damage_exists(ec->frame))
e_pixmap_image_clear(ec->pixmap, 1); e_pixmap_image_clear(ec->pixmap, 1);
ignored = ec->ignored;
if (!e_pixmap_usable_get(ec->pixmap))
{
if (ec->comp_data->mapped)
{
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
else if (e_client_has_xwindow(ec))
{
ec->visible = EINA_FALSE;
evas_object_hide(ec->frame);
ec->comp_data->mapped = 0;
}
}
}
else
{
if (!ec->comp_data->mapped)
{
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map))
ec->comp_data->shell.map(ec->comp_data->shell.surface);
else if (e_client_has_xwindow(ec))
{
ec->visible = EINA_TRUE;
ec->ignored = 0;
evas_object_show(ec->frame);
ec->comp_data->mapped = 1;
}
}
}
ec->ignored = ignored;
return EINA_TRUE; return EINA_TRUE;
} }

View File

@ -300,6 +300,7 @@ struct _E_Comp_Wl_Client_Data
Eina_Bool set_win_type : 1; Eina_Bool set_win_type : 1;
Eina_Bool frame_update : 1; Eina_Bool frame_update : 1;
Eina_Bool maximize_pre : 1; Eina_Bool maximize_pre : 1;
Eina_Bool cursor : 1;
}; };
struct _E_Comp_Wl_Output struct _E_Comp_Wl_Output

View File

@ -7,6 +7,7 @@
#endif #endif
E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1; E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
static xkb_keycode_t (*_xkb_keymap_key_by_name)(void *, const char *);
static void static void
_e_comp_wl_input_update_seat_caps(void) _e_comp_wl_input_update_seat_caps(void)
@ -58,12 +59,16 @@ _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resou
ec = wl_resource_get_user_data(surface_resource); ec = wl_resource_get_user_data(surface_resource);
if (!ec->re_manage) if (!ec->re_manage)
{ {
ec->re_manage = 1; ec->comp_data->cursor = ec->re_manage = 1;
ec->ignored = 0; ec->ignored = 0;
ec->lock_focus_out = ec->layer_block = ec->visible = ec->override = 1; ec->lock_focus_out = ec->layer_block = ec->visible = ec->override = 1;
ec->icccm.title = eina_stringshare_add("noshadow"); ec->icccm.title = eina_stringshare_add("noshadow");
evas_object_pass_events_set(ec->frame, 1); evas_object_pass_events_set(ec->frame, 1);
evas_object_show(ec->frame);
if (e_comp_object_damage_exists(ec->frame))
e_comp_object_render_update_add(ec->frame);
ec->comp_data->mapped = 1;
e_client_focus_stack_set(eina_list_remove(e_client_focus_stack_get(), ec)); e_client_focus_stack_set(eina_list_remove(e_client_focus_stack_get(), ec));
EC_CHANGED(ec); EC_CHANGED(ec);
} }
@ -437,6 +442,8 @@ e_comp_wl_input_init(void)
E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new(); E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
_xkb_keymap_key_by_name = dlsym(NULL, "xkb_keymap_key_by_name");
return EINA_TRUE; return EINA_TRUE;
} }
@ -678,3 +685,66 @@ e_comp_wl_input_keyboard_modifers_clear(void)
e_comp_wl_input_keyboard_modifiers_serialize(); e_comp_wl_input_keyboard_modifiers_serialize();
} }
static void
_event_generate(const char *key, const char *keyname, int mods, Eina_Bool up)
{
Ecore_Event_Key *ev;
int keycode;
/* "key" here is the platform-specific key name;
* /usr/share/X11/xkb/keycodes/evdev is probably what your system is using
*/
keycode = _xkb_keymap_key_by_name(e_comp_wl->xkb.keymap, keyname ?: key);
if (!keycode)
{
ERR("no keycode found for key '%s'", key);
return;
}
ev = calloc(1, sizeof(Ecore_Event_Key) + (2 * (strlen(key) + 1)));
ev->keyname = (char *)(ev + 1);
ev->key = ev->keyname + strlen(key) + 1;
strcpy((char *)ev->keyname, key);
strcpy((char *)ev->key, key);
ev->window = e_comp->ee_win;
ev->event_window = e_comp->ee_win;
ev->timestamp = 0;
ev->modifiers = mods;
ev->keycode = keycode;
ecore_event_add(up ? ECORE_EVENT_KEY_UP : ECORE_EVENT_KEY_DOWN, ev, NULL, NULL);
}
static void
_event_generate_mods(int mods, Eina_Bool up)
{
if (!mods) return;
if (mods & ECORE_EVENT_MODIFIER_SHIFT)
_event_generate("Shift", "LFSH", mods, up);
if (mods & ECORE_EVENT_MODIFIER_CTRL)
_event_generate("Control_L", "LCTL", mods, up);
if (mods & ECORE_EVENT_MODIFIER_ALT)
_event_generate("Alt_L", "LALT", mods, up);
if (mods & ECORE_EVENT_MODIFIER_WIN)
_event_generate("Super_L", "LWIN", mods, up);
if (mods & ECORE_EVENT_MODIFIER_ALTGR)
_event_generate("Mode_switch", "ALGR", mods, up);
}
E_API void
e_comp_wl_input_keyboard_event_generate(const char *key, int mods, Eina_Bool up)
{
if (!_xkb_keymap_key_by_name)
{
ERR("xkbcommon >= 0.6.0 required for keyboard event generation!");
return;
}
if (!up)
_event_generate_mods(mods, up);
_event_generate(key, NULL, mods, up);
if (up)
_event_generate_mods(mods, up);
}

View File

@ -32,5 +32,6 @@ E_API void e_comp_wl_input_touch_enabled_set(Eina_Bool enabled);
E_API void e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout, E_API void e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map); struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map);
E_API void e_comp_wl_input_keyboard_event_generate(const char *key, int mods, Eina_Bool up);
# endif # endif
#endif #endif

View File

@ -35,7 +35,8 @@ _xkb_changed_state(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{ {
Ecore_X_Event_Xkb *ev = (Ecore_X_Event_Xkb *)event; Ecore_X_Event_Xkb *ev = (Ecore_X_Event_Xkb *)event;
if (ev->group < 0 || ev->group >= eina_list_count(e_config->xkb.used_layouts)) if (ev->group < 0 ||
ev->group >= (int)eina_list_count(e_config->xkb.used_layouts))
return ECORE_CALLBACK_PASS_ON; return ECORE_CALLBACK_PASS_ON;
e_config->xkb.cur_group = ev->group; e_config->xkb.cur_group = ev->group;

View File

@ -452,6 +452,8 @@ _drm_randr_create(void)
if (ok) if (ok)
{ {
unsigned int rotations;
if (!possible) if (!possible)
{ {
unsigned int refresh; unsigned int refresh;
@ -474,7 +476,27 @@ _drm_randr_create(void)
s->config.geom.w, s->config.geom.h); s->config.geom.w, s->config.geom.h);
} }
/* TODO: are rotations possible ?? */ rotations =
ecore_drm_output_supported_rotations_get(output,
ECORE_DRM_PLANE_TYPE_PRIMARY);
if (rotations & ECORE_DRM_PLANE_ROTATION_NORMAL)
s->info.can_rot_0 = EINA_TRUE;
if (rotations & ECORE_DRM_PLANE_ROTATION_90)
s->info.can_rot_90 = EINA_TRUE;
if (rotations & ECORE_DRM_PLANE_ROTATION_180)
s->info.can_rot_180 = EINA_TRUE;
if (rotations & ECORE_DRM_PLANE_ROTATION_270)
s->info.can_rot_270 = EINA_TRUE;
if (cs)
{
if (cs->profile)
s->config.profile = strdup(cs->profile);
else
s->config.profile = NULL;
s->config.scale_multiplier = cs->scale_multiplier;
}
} }
r->screens = eina_list_append(r->screens, s); r->screens = eina_list_append(r->screens, s);
@ -580,6 +602,10 @@ _drm_randr_apply(void)
ecore_drm_output_mode_set(out, mode, ecore_drm_output_mode_set(out, mode,
s->config.geom.x, s->config.geom.y); s->config.geom.x, s->config.geom.y);
ecore_drm_output_rotation_set(out,
ECORE_DRM_PLANE_TYPE_PRIMARY,
orient);
if (s->config.priority == top_priority) if (s->config.priority == top_priority)
ecore_drm_output_primary_set(out); ecore_drm_output_primary_set(out);