mirror of
https://github.com/brl/mutter.git
synced 2025-02-17 05:44:08 +00:00
x11: Add support for scroll valuators on XInput2.2
This commit is contained in:
parent
6b07f8a3df
commit
676a317439
@ -50,6 +50,16 @@ typedef struct _ClutterKeyInfo
|
|||||||
ClutterModifierType modifiers;
|
ClutterModifierType modifiers;
|
||||||
} ClutterKeyInfo;
|
} ClutterKeyInfo;
|
||||||
|
|
||||||
|
typedef struct _ClutterScrollInfo
|
||||||
|
{
|
||||||
|
guint axis_id;
|
||||||
|
ClutterScrollDirection direction;
|
||||||
|
gdouble increment;
|
||||||
|
|
||||||
|
gdouble last_value;
|
||||||
|
guint last_value_valid : 1;
|
||||||
|
} ClutterScrollInfo;
|
||||||
|
|
||||||
struct _ClutterInputDevice
|
struct _ClutterInputDevice
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
@ -102,6 +112,8 @@ struct _ClutterInputDevice
|
|||||||
guint n_keys;
|
guint n_keys;
|
||||||
GArray *keys;
|
GArray *keys;
|
||||||
|
|
||||||
|
GArray *scroll_info;
|
||||||
|
|
||||||
guint has_cursor : 1;
|
guint has_cursor : 1;
|
||||||
guint is_enabled : 1;
|
guint is_enabled : 1;
|
||||||
};
|
};
|
||||||
@ -170,6 +182,17 @@ gboolean _clutter_input_device_translate_axis (ClutterInputDev
|
|||||||
gdouble value,
|
gdouble value,
|
||||||
gdouble *axis_value);
|
gdouble *axis_value);
|
||||||
|
|
||||||
|
void _clutter_input_device_add_scroll_info (ClutterInputDevice *device,
|
||||||
|
guint index_,
|
||||||
|
ClutterScrollDirection direction,
|
||||||
|
gdouble increment);
|
||||||
|
void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device);
|
||||||
|
gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device,
|
||||||
|
guint index_,
|
||||||
|
gdouble value,
|
||||||
|
ClutterScrollDirection *direction_p,
|
||||||
|
gdouble *delta_p);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_DEVICE_MANAGER_PRIVATE_H__ */
|
#endif /* __CLUTTER_DEVICE_MANAGER_PRIVATE_H__ */
|
||||||
|
@ -1444,3 +1444,99 @@ clutter_input_device_keycode_to_evdev (ClutterInputDevice *device,
|
|||||||
hardware_keycode,
|
hardware_keycode,
|
||||||
evdev_keycode);
|
evdev_keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_input_device_add_scroll_info (ClutterInputDevice *device,
|
||||||
|
guint index_,
|
||||||
|
ClutterScrollDirection direction,
|
||||||
|
gdouble increment)
|
||||||
|
{
|
||||||
|
ClutterScrollInfo info;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||||
|
g_return_if_fail (index_ < clutter_input_device_get_n_axes (device));
|
||||||
|
|
||||||
|
info.axis_id = index_;
|
||||||
|
info.direction = direction;
|
||||||
|
info.increment = increment;
|
||||||
|
info.last_value_valid = FALSE;
|
||||||
|
|
||||||
|
if (device->scroll_info == NULL)
|
||||||
|
{
|
||||||
|
device->scroll_info = g_array_new (FALSE,
|
||||||
|
FALSE,
|
||||||
|
sizeof (ClutterScrollInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_append_val (device->scroll_info, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_clutter_input_device_get_scroll_delta (ClutterInputDevice *device,
|
||||||
|
guint index_,
|
||||||
|
gdouble value,
|
||||||
|
ClutterScrollDirection *direction_p,
|
||||||
|
gdouble *delta_p)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||||
|
g_return_val_if_fail (index_ < clutter_input_device_get_n_axes (device), FALSE);
|
||||||
|
|
||||||
|
if (device->scroll_info == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < device->scroll_info->len; i++)
|
||||||
|
{
|
||||||
|
ClutterScrollInfo *info = &g_array_index (device->scroll_info,
|
||||||
|
ClutterScrollInfo,
|
||||||
|
i);
|
||||||
|
|
||||||
|
if (info->axis_id == index_)
|
||||||
|
{
|
||||||
|
if (direction_p != NULL)
|
||||||
|
*direction_p = info->direction;
|
||||||
|
|
||||||
|
if (delta_p != NULL)
|
||||||
|
*delta_p = 0.0;
|
||||||
|
|
||||||
|
if (info->last_value_valid)
|
||||||
|
{
|
||||||
|
if (delta_p != NULL)
|
||||||
|
{
|
||||||
|
*delta_p = (value - info->last_value)
|
||||||
|
/ info->increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->last_value = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->last_value = value;
|
||||||
|
info->last_value_valid = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_input_device_reset_scroll_info (ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (device->scroll_info == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < device->scroll_info->len; i++)
|
||||||
|
{
|
||||||
|
ClutterScrollInfo *info = &g_array_index (device->scroll_info,
|
||||||
|
ClutterScrollInfo,
|
||||||
|
i);
|
||||||
|
|
||||||
|
info->last_value_valid = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -239,7 +239,12 @@ clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_XINPUT_2
|
#ifdef HAVE_XINPUT_2
|
||||||
int major = 2;
|
int major = 2;
|
||||||
|
|
||||||
|
#ifdef HAVE_XINPUT_2_2
|
||||||
|
int minor = 2;
|
||||||
|
#else
|
||||||
int minor = 0;
|
int minor = 0;
|
||||||
|
#endif /* HAVE_XINPUT_2_2 */
|
||||||
|
|
||||||
if (XIQueryVersion (backend_x11->xdpy, &major, &minor) != BadRequest)
|
if (XIQueryVersion (backend_x11->xdpy, &major, &minor) != BadRequest)
|
||||||
{
|
{
|
||||||
|
@ -154,6 +154,32 @@ translate_device_classes (Display *xdisplay,
|
|||||||
(XIValuatorClassInfo *) class_info);
|
(XIValuatorClassInfo *) class_info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef XINPUT_2_2
|
||||||
|
case XIScrollClass:
|
||||||
|
{
|
||||||
|
XIScrollClassInfo *scroll_info = (XIScrollClassInfo *) class_info;
|
||||||
|
ClutterScrollDirection direction;
|
||||||
|
|
||||||
|
if (scroll_info->scroll_type == XIScrollTypeVertical)
|
||||||
|
direction = CLUTTER_SCROLL_DOWN;
|
||||||
|
else
|
||||||
|
direction = CLUTTER_SCROLL_RIGHT;
|
||||||
|
|
||||||
|
CLUTTER_NOTE (BACKEND, "Scroll valuator %d: %s, increment: %f",
|
||||||
|
scroll_info->number,
|
||||||
|
scroll_info->scroll_type == XIScrollTypeVertical
|
||||||
|
? "vertical"
|
||||||
|
: "horizontal",
|
||||||
|
scroll_info->increment);
|
||||||
|
|
||||||
|
_clutter_input_device_add_scroll_info (device,
|
||||||
|
scroll_info->number,
|
||||||
|
direction,
|
||||||
|
scroll_info->increment);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* XINPUT_2_2 */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -541,6 +567,51 @@ translate_axes (ClutterInputDevice *device,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gdouble
|
||||||
|
scroll_valuators_changed (ClutterInputDevice *device,
|
||||||
|
XIValuatorState *valuators,
|
||||||
|
gdouble *dx_p,
|
||||||
|
gdouble *dy_p)
|
||||||
|
{
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
guint n_axes, n_val, i;
|
||||||
|
double *values;
|
||||||
|
|
||||||
|
n_axes = clutter_input_device_get_n_axes (device);
|
||||||
|
values = valuators->values;
|
||||||
|
|
||||||
|
*dx_p = *dy_p = 0.0;
|
||||||
|
|
||||||
|
n_val = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++)
|
||||||
|
{
|
||||||
|
ClutterScrollDirection direction;
|
||||||
|
gdouble delta;
|
||||||
|
|
||||||
|
if (!XIMaskIsSet (valuators->mask, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_clutter_input_device_get_scroll_delta (device, i,
|
||||||
|
values[n_val],
|
||||||
|
&direction,
|
||||||
|
&delta))
|
||||||
|
{
|
||||||
|
retval = TRUE;
|
||||||
|
|
||||||
|
if (direction == CLUTTER_SCROLL_UP ||
|
||||||
|
direction == CLUTTER_SCROLL_DOWN)
|
||||||
|
*dx_p = delta;
|
||||||
|
else
|
||||||
|
*dy_p = delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_val += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static ClutterTranslateReturn
|
static ClutterTranslateReturn
|
||||||
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||||
gpointer native,
|
gpointer native,
|
||||||
@ -793,6 +864,44 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
|||||||
case XI_Motion:
|
case XI_Motion:
|
||||||
{
|
{
|
||||||
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
|
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
|
||||||
|
gdouble delta_x, delta_y;
|
||||||
|
|
||||||
|
source_device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||||
|
GINT_TO_POINTER (xev->sourceid));
|
||||||
|
|
||||||
|
if (scroll_valuators_changed (source_device,
|
||||||
|
&xev->valuators,
|
||||||
|
&delta_x, &delta_y))
|
||||||
|
{
|
||||||
|
event->scroll.type = event->type = CLUTTER_SCROLL;
|
||||||
|
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
|
||||||
|
|
||||||
|
event->scroll.stage = stage;
|
||||||
|
event->scroll.time = xev->time;
|
||||||
|
event->scroll.x = xev->event_x;
|
||||||
|
event->scroll.y = xev->event_y;
|
||||||
|
event->scroll.modifier_state =
|
||||||
|
_clutter_input_device_xi2_translate_state (&xev->mods,
|
||||||
|
&xev->buttons);
|
||||||
|
|
||||||
|
clutter_event_set_scroll_delta (event, delta_x, delta_y);
|
||||||
|
clutter_event_set_source_device (event, source_device);
|
||||||
|
|
||||||
|
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||||
|
GINT_TO_POINTER (xev->deviceid));
|
||||||
|
clutter_event_set_device (event, device);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (EVENT,
|
||||||
|
"smooth scroll: win:0x%x device:%s (x:%.2f, y:%.2f, delta:%f, %f)",
|
||||||
|
(unsigned int) stage_x11->xwin,
|
||||||
|
event->scroll.device->device_name,
|
||||||
|
event->scroll.x,
|
||||||
|
event->scroll.y,
|
||||||
|
delta_x, delta_y);
|
||||||
|
|
||||||
|
retval = CLUTTER_TRANSLATE_QUEUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
event->motion.type = event->type = CLUTTER_MOTION;
|
event->motion.type = event->type = CLUTTER_MOTION;
|
||||||
|
|
||||||
@ -805,8 +914,6 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
|||||||
_clutter_input_device_xi2_translate_state (&xev->mods,
|
_clutter_input_device_xi2_translate_state (&xev->mods,
|
||||||
&xev->buttons);
|
&xev->buttons);
|
||||||
|
|
||||||
source_device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
|
||||||
GINT_TO_POINTER (xev->sourceid));
|
|
||||||
clutter_event_set_source_device (event, source_device);
|
clutter_event_set_source_device (event, source_device);
|
||||||
|
|
||||||
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user