Compare commits
103 Commits
citadel
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
![]() |
208e292df1 | ||
![]() |
548e5138fc | ||
![]() |
6b8d95d9c4 | ||
![]() |
faec8d29b0 | ||
![]() |
4b88a769d2 | ||
![]() |
6704e986a0 | ||
![]() |
d55b44df50 | ||
![]() |
6496cd7c55 | ||
![]() |
6f3ce4de24 | ||
![]() |
034aff4306 | ||
![]() |
af5f93377a | ||
![]() |
abd858fb69 | ||
![]() |
09e02a772e | ||
![]() |
c850aa9733 | ||
![]() |
5a1c7e4a54 | ||
![]() |
e324f0fad0 | ||
![]() |
5978531963 | ||
![]() |
bc111bf958 | ||
![]() |
074d78bd9b | ||
![]() |
2e604709df | ||
![]() |
6c265c131f | ||
![]() |
06adde5c6b | ||
![]() |
a2616d83e8 | ||
![]() |
92bc79fd51 | ||
![]() |
ef67fab737 | ||
![]() |
9acb7f0eed | ||
![]() |
c678cdab5a | ||
![]() |
91f6b3b5bc | ||
![]() |
696915a951 | ||
![]() |
2e07c55241 | ||
![]() |
0f0848191e | ||
![]() |
4b0d3f44e1 | ||
![]() |
4f794d3acb | ||
![]() |
3252ef5dd7 | ||
![]() |
0c9bbbe90e | ||
![]() |
bb62d9e4b0 | ||
![]() |
579220a762 | ||
![]() |
575a4ca281 | ||
![]() |
4b7f2905d6 | ||
![]() |
c7758046eb | ||
![]() |
e64112de64 | ||
![]() |
05f385c8ee | ||
![]() |
8a2b529ca3 | ||
![]() |
0c92417178 | ||
![]() |
543d232b51 | ||
![]() |
4398d63566 | ||
![]() |
dc022a67b0 | ||
![]() |
60fa895ae3 | ||
![]() |
7bb3fe25aa | ||
![]() |
6c5bba94fd | ||
![]() |
667b2726f5 | ||
![]() |
1d3588ba48 | ||
![]() |
16317cec12 | ||
![]() |
f3991c0164 | ||
![]() |
b07d9c5f92 | ||
![]() |
be51a8c18c | ||
![]() |
11c86f9cb3 | ||
![]() |
87c0821a30 | ||
![]() |
03f2bade19 | ||
![]() |
a3825f2085 | ||
![]() |
8b2a89041a | ||
![]() |
52da5fe4f2 | ||
![]() |
307be1e495 | ||
![]() |
9b3ca86b7c | ||
![]() |
da55f15156 | ||
![]() |
b13fe4895f | ||
![]() |
aae4a6065c | ||
![]() |
1555ecad11 | ||
![]() |
292b4dd605 | ||
![]() |
4766e2f858 | ||
![]() |
e3fe8c3dd1 | ||
![]() |
d3e1ce7dbc | ||
![]() |
63ad2c958d | ||
![]() |
849cc3d7f5 | ||
![]() |
8d8c933eb4 | ||
![]() |
2363f4c30b | ||
![]() |
5d45722362 | ||
![]() |
cef6520836 | ||
![]() |
0fbbeb0c82 | ||
![]() |
b97519bb6e | ||
![]() |
60b3f628a6 | ||
![]() |
37deba9557 | ||
![]() |
89cefd037f | ||
![]() |
c9efadacd1 | ||
![]() |
df724f5c75 | ||
![]() |
44bb21c7aa | ||
![]() |
73e705a49b | ||
![]() |
2316dfe394 | ||
![]() |
9597b5a703 | ||
![]() |
0be0a14225 | ||
![]() |
7fafec21b6 | ||
![]() |
88f03d3a26 | ||
![]() |
edc399e5cf | ||
![]() |
908a331fa8 | ||
![]() |
3083e98254 | ||
![]() |
7dc1a28c8c | ||
![]() |
3ce5b34ade | ||
![]() |
5677fbb64d | ||
![]() |
e7f29e764f | ||
![]() |
5563bfe7d9 | ||
![]() |
cd00e69ce3 | ||
![]() |
fe1d297680 | ||
![]() |
67a31633d8 |
@ -12715,6 +12715,9 @@ clutter_actor_event (ClutterActor *actor,
|
|||||||
signal_num = -1;
|
signal_num = -1;
|
||||||
detail = quark_stage;
|
detail = quark_stage;
|
||||||
break;
|
break;
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
break;
|
||||||
case CLUTTER_EVENT_LAST: /* Just keep compiler warnings quiet */
|
case CLUTTER_EVENT_LAST: /* Just keep compiler warnings quiet */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -387,44 +387,6 @@ typedef enum
|
|||||||
CLUTTER_MODIFIER_MASK = 0x5c001fff
|
CLUTTER_MODIFIER_MASK = 0x5c001fff
|
||||||
} ClutterModifierType;
|
} ClutterModifierType;
|
||||||
|
|
||||||
/**
|
|
||||||
* ClutterKeyboardA11yFlags:
|
|
||||||
* @CLUTTER_A11Y_KEYBOARD_ENABLED:
|
|
||||||
* @CLUTTER_A11Y_TIMEOUT_ENABLED:
|
|
||||||
* @CLUTTER_A11Y_MOUSE_KEYS_ENABLED:
|
|
||||||
* @CLUTTER_A11Y_SLOW_KEYS_ENABLED:
|
|
||||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS:
|
|
||||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT:
|
|
||||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT:
|
|
||||||
* @CLUTTER_A11Y_BOUNCE_KEYS_ENABLED:
|
|
||||||
* @CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT:
|
|
||||||
* @CLUTTER_A11Y_TOGGLE_KEYS_ENABLED:
|
|
||||||
* @CLUTTER_A11Y_STICKY_KEYS_ENABLED:
|
|
||||||
* @CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF:
|
|
||||||
* @CLUTTER_A11Y_STICKY_KEYS_BEEP:
|
|
||||||
* @CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP:
|
|
||||||
*
|
|
||||||
* Keyboard accessibility features applied to a ClutterInputDevice keyboard.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
CLUTTER_A11Y_KEYBOARD_ENABLED = 1 << 0,
|
|
||||||
CLUTTER_A11Y_TIMEOUT_ENABLED = 1 << 1,
|
|
||||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
|
|
||||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
|
|
||||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
|
|
||||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
|
|
||||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
|
|
||||||
CLUTTER_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
|
|
||||||
CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
|
|
||||||
CLUTTER_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
|
|
||||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
|
|
||||||
CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
|
|
||||||
CLUTTER_A11Y_STICKY_KEYS_BEEP = 1 << 12,
|
|
||||||
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
|
|
||||||
} ClutterKeyboardA11yFlags;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterPointerA11yFlags:
|
* ClutterPointerA11yFlags:
|
||||||
* @CLUTTER_A11Y_POINTER_ENABLED:
|
* @CLUTTER_A11Y_POINTER_ENABLED:
|
||||||
@ -906,6 +868,8 @@ typedef enum /*< prefix=CLUTTER >*/
|
|||||||
CLUTTER_PAD_BUTTON_RELEASE,
|
CLUTTER_PAD_BUTTON_RELEASE,
|
||||||
CLUTTER_PAD_STRIP,
|
CLUTTER_PAD_STRIP,
|
||||||
CLUTTER_PAD_RING,
|
CLUTTER_PAD_RING,
|
||||||
|
CLUTTER_DEVICE_ADDED,
|
||||||
|
CLUTTER_DEVICE_REMOVED,
|
||||||
|
|
||||||
CLUTTER_EVENT_LAST /* helper */
|
CLUTTER_EVENT_LAST /* helper */
|
||||||
} ClutterEventType;
|
} ClutterEventType;
|
||||||
@ -1630,12 +1594,6 @@ typedef enum
|
|||||||
CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER,
|
CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER,
|
||||||
} ClutterInputDevicePadSource;
|
} ClutterInputDevicePadSource;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE,
|
|
||||||
CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE,
|
|
||||||
} ClutterInputDeviceMapping;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0,
|
CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0,
|
||||||
|
@ -414,6 +414,8 @@ clutter_event_get_position (const ClutterEvent *event,
|
|||||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||||
case CLUTTER_PAD_STRIP:
|
case CLUTTER_PAD_STRIP:
|
||||||
case CLUTTER_PAD_RING:
|
case CLUTTER_PAD_RING:
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
graphene_point_init (position, 0.f, 0.f);
|
graphene_point_init (position, 0.f, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -487,6 +489,8 @@ clutter_event_set_coords (ClutterEvent *event,
|
|||||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||||
case CLUTTER_PAD_STRIP:
|
case CLUTTER_PAD_STRIP:
|
||||||
case CLUTTER_PAD_RING:
|
case CLUTTER_PAD_RING:
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLUTTER_ENTER:
|
case CLUTTER_ENTER:
|
||||||
@ -1158,6 +1162,11 @@ clutter_event_set_device (ClutterEvent *event,
|
|||||||
case CLUTTER_PAD_RING:
|
case CLUTTER_PAD_RING:
|
||||||
event->pad_ring.device = device;
|
event->pad_ring.device = device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
event->device.device = device;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1254,6 +1263,11 @@ clutter_event_get_device (const ClutterEvent *event)
|
|||||||
case CLUTTER_PAD_RING:
|
case CLUTTER_PAD_RING:
|
||||||
device = event->pad_ring.device;
|
device = event->pad_ring.device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
device = event->device.device;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
@ -1407,6 +1421,8 @@ clutter_event_copy (const ClutterEvent *event)
|
|||||||
sizeof (gdouble) * n_axes);
|
sizeof (gdouble) * n_axes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1461,6 +1477,9 @@ clutter_event_free (ClutterEvent *event)
|
|||||||
case CLUTTER_TOUCH_CANCEL:
|
case CLUTTER_TOUCH_CANCEL:
|
||||||
g_free (event->touch.axes);
|
g_free (event->touch.axes);
|
||||||
break;
|
break;
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1485,40 +1504,17 @@ ClutterEvent *
|
|||||||
clutter_event_get (void)
|
clutter_event_get (void)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = _clutter_context_get_default ();
|
ClutterMainContext *context = _clutter_context_get_default ();
|
||||||
|
ClutterEvent *event;
|
||||||
|
|
||||||
if (context->events_queue == NULL)
|
event = g_async_queue_try_pop (context->events_queue);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (g_queue_is_empty (context->events_queue))
|
return event;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return g_queue_pop_tail (context->events_queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static gboolean
|
||||||
* clutter_event_peek:
|
spin_context (gpointer data)
|
||||||
*
|
|
||||||
* Returns a pointer to the first event from the event queue but
|
|
||||||
* does not remove it.
|
|
||||||
*
|
|
||||||
* Return value: (transfer none): A #ClutterEvent or NULL if queue empty.
|
|
||||||
*
|
|
||||||
* Since: 0.4
|
|
||||||
*/
|
|
||||||
ClutterEvent *
|
|
||||||
clutter_event_peek (void)
|
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = _clutter_context_get_default ();
|
return G_SOURCE_REMOVE;
|
||||||
|
|
||||||
g_return_val_if_fail (context != NULL, NULL);
|
|
||||||
|
|
||||||
if (context->events_queue == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (g_queue_is_empty (context->events_queue))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return g_queue_peek_tail (context->events_queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1526,21 +1522,9 @@ _clutter_event_push (const ClutterEvent *event,
|
|||||||
gboolean do_copy)
|
gboolean do_copy)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = _clutter_context_get_default ();
|
ClutterMainContext *context = _clutter_context_get_default ();
|
||||||
ClutterInputDevice *device;
|
|
||||||
|
|
||||||
g_assert (context != NULL);
|
g_assert (context != NULL);
|
||||||
|
|
||||||
if (context->events_queue == NULL)
|
|
||||||
context->events_queue = g_queue_new ();
|
|
||||||
|
|
||||||
/* disabled devices don't propagate events */
|
|
||||||
device = clutter_event_get_device (event);
|
|
||||||
if (device != NULL)
|
|
||||||
{
|
|
||||||
if (!clutter_input_device_get_enabled (device))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_copy)
|
if (do_copy)
|
||||||
{
|
{
|
||||||
ClutterEvent *copy;
|
ClutterEvent *copy;
|
||||||
@ -1549,7 +1533,8 @@ _clutter_event_push (const ClutterEvent *event,
|
|||||||
event = copy;
|
event = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_queue_push_head (context->events_queue, (gpointer) event);
|
g_async_queue_push (context->events_queue, (gpointer) event);
|
||||||
|
g_idle_add (spin_context, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1586,10 +1571,7 @@ clutter_events_pending (void)
|
|||||||
|
|
||||||
g_return_val_if_fail (context != NULL, FALSE);
|
g_return_val_if_fail (context != NULL, FALSE);
|
||||||
|
|
||||||
if (context->events_queue == NULL)
|
return g_async_queue_length (context->events_queue) > 0;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return g_queue_is_empty (context->events_queue) == FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1728,6 +1710,8 @@ clutter_event_get_axes (const ClutterEvent *event,
|
|||||||
case CLUTTER_EVENT_LAST:
|
case CLUTTER_EVENT_LAST:
|
||||||
case CLUTTER_PROXIMITY_IN:
|
case CLUTTER_PROXIMITY_IN:
|
||||||
case CLUTTER_PROXIMITY_OUT:
|
case CLUTTER_PROXIMITY_OUT:
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLUTTER_SCROLL:
|
case CLUTTER_SCROLL:
|
||||||
|
@ -121,6 +121,7 @@ typedef struct _ClutterProximityEvent ClutterProximityEvent;
|
|||||||
typedef struct _ClutterPadButtonEvent ClutterPadButtonEvent;
|
typedef struct _ClutterPadButtonEvent ClutterPadButtonEvent;
|
||||||
typedef struct _ClutterPadStripEvent ClutterPadStripEvent;
|
typedef struct _ClutterPadStripEvent ClutterPadStripEvent;
|
||||||
typedef struct _ClutterPadRingEvent ClutterPadRingEvent;
|
typedef struct _ClutterPadRingEvent ClutterPadRingEvent;
|
||||||
|
typedef struct _ClutterDeviceEvent ClutterDeviceEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterAnyEvent:
|
* ClutterAnyEvent:
|
||||||
@ -544,6 +545,17 @@ struct _ClutterPadRingEvent
|
|||||||
guint32 mode;
|
guint32 mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _ClutterDeviceEvent
|
||||||
|
{
|
||||||
|
ClutterEventType type;
|
||||||
|
guint32 time;
|
||||||
|
ClutterEventFlags flags;
|
||||||
|
ClutterStage *stage;
|
||||||
|
ClutterActor *source;
|
||||||
|
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterEvent:
|
* ClutterEvent:
|
||||||
*
|
*
|
||||||
@ -570,6 +582,7 @@ union _ClutterEvent
|
|||||||
ClutterPadButtonEvent pad_button;
|
ClutterPadButtonEvent pad_button;
|
||||||
ClutterPadStripEvent pad_strip;
|
ClutterPadStripEvent pad_strip;
|
||||||
ClutterPadRingEvent pad_ring;
|
ClutterPadRingEvent pad_ring;
|
||||||
|
ClutterDeviceEvent device;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -601,8 +614,6 @@ gboolean clutter_events_pending (void);
|
|||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
ClutterEvent * clutter_event_get (void);
|
ClutterEvent * clutter_event_get (void);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
ClutterEvent * clutter_event_peek (void);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void clutter_event_put (const ClutterEvent *event);
|
void clutter_event_put (const ClutterEvent *event);
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
|
@ -61,15 +61,6 @@ typedef struct _ClutterScrollInfo
|
|||||||
guint last_value_valid : 1;
|
guint last_value_valid : 1;
|
||||||
} ClutterScrollInfo;
|
} ClutterScrollInfo;
|
||||||
|
|
||||||
typedef struct _ClutterTouchInfo
|
|
||||||
{
|
|
||||||
ClutterEventSequence *sequence;
|
|
||||||
ClutterActor *actor;
|
|
||||||
|
|
||||||
float current_x;
|
|
||||||
float current_y;
|
|
||||||
} ClutterTouchInfo;
|
|
||||||
|
|
||||||
typedef struct _ClutterPtrA11yData
|
typedef struct _ClutterPtrA11yData
|
||||||
{
|
{
|
||||||
int n_btn_pressed;
|
int n_btn_pressed;
|
||||||
@ -120,25 +111,18 @@ struct _ClutterInputDevice
|
|||||||
/* the current click count */
|
/* the current click count */
|
||||||
int click_count;
|
int click_count;
|
||||||
|
|
||||||
/* the stage the device is on */
|
|
||||||
ClutterStage *stage;
|
|
||||||
|
|
||||||
/* the current state */
|
/* the current state */
|
||||||
float current_x;
|
|
||||||
float current_y;
|
|
||||||
uint32_t current_time;
|
|
||||||
int current_button_number;
|
int current_button_number;
|
||||||
ClutterModifierType current_state;
|
ClutterModifierType current_state;
|
||||||
|
|
||||||
/* the current touch points states */
|
/* the current touch points targets */
|
||||||
GHashTable *touch_sequences_info;
|
GHashTable *touch_sequence_actors;
|
||||||
|
|
||||||
/* the previous state, used for click count generation */
|
/* the previous state, used for click count generation */
|
||||||
int previous_x;
|
int previous_x;
|
||||||
int previous_y;
|
int previous_y;
|
||||||
uint32_t previous_time;
|
uint32_t previous_time;
|
||||||
int previous_button_number;
|
int previous_button_number;
|
||||||
ClutterModifierType previous_state;
|
|
||||||
|
|
||||||
GArray *axes;
|
GArray *axes;
|
||||||
|
|
||||||
@ -157,8 +141,6 @@ struct _ClutterInputDevice
|
|||||||
int n_strips;
|
int n_strips;
|
||||||
int n_mode_groups;
|
int n_mode_groups;
|
||||||
|
|
||||||
ClutterInputDeviceMapping mapping_mode;
|
|
||||||
|
|
||||||
guint has_cursor : 1;
|
guint has_cursor : 1;
|
||||||
guint is_enabled : 1;
|
guint is_enabled : 1;
|
||||||
|
|
||||||
@ -180,33 +162,11 @@ CLUTTER_EXPORT
|
|||||||
void clutter_input_device_update_from_tool (ClutterInputDevice *device,
|
void clutter_input_device_update_from_tool (ClutterInputDevice *device,
|
||||||
ClutterInputDeviceTool *tool);
|
ClutterInputDeviceTool *tool);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void _clutter_input_device_set_stage (ClutterInputDevice *device,
|
|
||||||
ClutterStage *stage);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void _clutter_input_device_set_coords (ClutterInputDevice *device,
|
|
||||||
ClutterEventSequence *sequence,
|
|
||||||
gfloat x,
|
|
||||||
gfloat y,
|
|
||||||
ClutterStage *stage);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void _clutter_input_device_set_state (ClutterInputDevice *device,
|
|
||||||
ClutterModifierType state);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void _clutter_input_device_set_time (ClutterInputDevice *device,
|
|
||||||
guint32 time_);
|
|
||||||
void _clutter_input_device_set_actor (ClutterInputDevice *device,
|
|
||||||
ClutterEventSequence *sequence,
|
|
||||||
ClutterActor *actor,
|
|
||||||
gboolean emit_crossing);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
ClutterActor * clutter_input_device_update (ClutterInputDevice *device,
|
ClutterActor * clutter_input_device_update (ClutterInputDevice *device,
|
||||||
ClutterEventSequence *sequence,
|
ClutterEventSequence *sequence,
|
||||||
gboolean emit_crossing);
|
ClutterStage *stage,
|
||||||
CLUTTER_EXPORT
|
gboolean emit_crossing,
|
||||||
void _clutter_input_device_add_event_sequence (ClutterInputDevice *device,
|
ClutterEvent *for_event);
|
||||||
ClutterEvent *event);
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
|
void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
|
||||||
ClutterEvent *event);
|
ClutterEvent *event);
|
||||||
@ -214,6 +174,12 @@ CLUTTER_EXPORT
|
|||||||
void _clutter_input_device_set_n_keys (ClutterInputDevice *device,
|
void _clutter_input_device_set_n_keys (ClutterInputDevice *device,
|
||||||
guint n_keys);
|
guint n_keys);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
|
void clutter_input_device_set_key (ClutterInputDevice *device,
|
||||||
|
guint index_,
|
||||||
|
guint keyval,
|
||||||
|
ClutterModifierType modifiers);
|
||||||
|
|
||||||
|
CLUTTER_EXPORT
|
||||||
gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device,
|
gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device,
|
||||||
guint index_,
|
guint index_,
|
||||||
gdouble value,
|
gdouble value,
|
||||||
@ -252,4 +218,9 @@ ClutterInputDeviceTool *
|
|||||||
guint64 serial,
|
guint64 serial,
|
||||||
ClutterInputDeviceToolType type);
|
ClutterInputDeviceToolType type);
|
||||||
|
|
||||||
|
CLUTTER_EXPORT
|
||||||
|
gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device,
|
||||||
|
guint hardware_keycode,
|
||||||
|
guint *evdev_keycode);
|
||||||
|
|
||||||
#endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */
|
#endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */
|
||||||
|
@ -61,7 +61,6 @@ enum
|
|||||||
PROP_DEVICE_MODE,
|
PROP_DEVICE_MODE,
|
||||||
|
|
||||||
PROP_HAS_CURSOR,
|
PROP_HAS_CURSOR,
|
||||||
PROP_ENABLED,
|
|
||||||
|
|
||||||
PROP_N_AXES,
|
PROP_N_AXES,
|
||||||
|
|
||||||
@ -72,12 +71,10 @@ enum
|
|||||||
PROP_N_RINGS,
|
PROP_N_RINGS,
|
||||||
PROP_N_MODE_GROUPS,
|
PROP_N_MODE_GROUPS,
|
||||||
PROP_DEVICE_NODE,
|
PROP_DEVICE_NODE,
|
||||||
PROP_MAPPING_MODE,
|
|
||||||
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _clutter_input_device_free_touch_info (gpointer data);
|
|
||||||
static void on_cursor_actor_destroy (ClutterActor *actor,
|
static void on_cursor_actor_destroy (ClutterActor *actor,
|
||||||
ClutterInputDevice *device);
|
ClutterInputDevice *device);
|
||||||
static void on_cursor_actor_reactive_changed (ClutterActor *actor,
|
static void on_cursor_actor_reactive_changed (ClutterActor *actor,
|
||||||
@ -114,7 +111,7 @@ clutter_input_device_dispose (GObject *gobject)
|
|||||||
g_clear_pointer (&device->axes, g_array_unref);
|
g_clear_pointer (&device->axes, g_array_unref);
|
||||||
g_clear_pointer (&device->keys, g_array_unref);
|
g_clear_pointer (&device->keys, g_array_unref);
|
||||||
g_clear_pointer (&device->scroll_info, g_array_unref);
|
g_clear_pointer (&device->scroll_info, g_array_unref);
|
||||||
g_clear_pointer (&device->touch_sequences_info, g_hash_table_unref);
|
g_clear_pointer (&device->touch_sequence_actors, g_hash_table_unref);
|
||||||
|
|
||||||
if (device->cursor_actor)
|
if (device->cursor_actor)
|
||||||
{
|
{
|
||||||
@ -191,10 +188,6 @@ clutter_input_device_set_property (GObject *gobject,
|
|||||||
self->has_cursor = g_value_get_boolean (value);
|
self->has_cursor = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ENABLED:
|
|
||||||
clutter_input_device_set_enabled (self, g_value_get_boolean (value));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_VENDOR_ID:
|
case PROP_VENDOR_ID:
|
||||||
self->vendor_id = g_value_dup_string (value);
|
self->vendor_id = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
@ -219,10 +212,6 @@ clutter_input_device_set_property (GObject *gobject,
|
|||||||
self->node_path = g_value_dup_string (value);
|
self->node_path = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_MAPPING_MODE:
|
|
||||||
self->mapping_mode = g_value_get_enum (value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -271,10 +260,6 @@ clutter_input_device_get_property (GObject *gobject,
|
|||||||
g_value_set_uint (value, clutter_input_device_get_n_axes (self));
|
g_value_set_uint (value, clutter_input_device_get_n_axes (self));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ENABLED:
|
|
||||||
g_value_set_boolean (value, self->is_enabled);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_VENDOR_ID:
|
case PROP_VENDOR_ID:
|
||||||
g_value_set_string (value, self->vendor_id);
|
g_value_set_string (value, self->vendor_id);
|
||||||
break;
|
break;
|
||||||
@ -299,10 +284,6 @@ clutter_input_device_get_property (GObject *gobject,
|
|||||||
g_value_set_string (value, self->node_path);
|
g_value_set_string (value, self->node_path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_MAPPING_MODE:
|
|
||||||
g_value_set_enum (value, self->mapping_mode);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -402,25 +383,6 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass)
|
|||||||
FALSE,
|
FALSE,
|
||||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
|
||||||
/**
|
|
||||||
* ClutterInputDevice:enabled:
|
|
||||||
*
|
|
||||||
* Whether the device is enabled.
|
|
||||||
*
|
|
||||||
* A device with the #ClutterInputDevice:device-mode property set
|
|
||||||
* to %CLUTTER_INPUT_MODE_MASTER cannot be disabled.
|
|
||||||
*
|
|
||||||
* A device must be enabled in order to receive events from it.
|
|
||||||
*
|
|
||||||
* Since: 1.6
|
|
||||||
*/
|
|
||||||
obj_props[PROP_ENABLED] =
|
|
||||||
g_param_spec_boolean ("enabled",
|
|
||||||
P_("Enabled"),
|
|
||||||
P_("Whether the device is enabled"),
|
|
||||||
FALSE,
|
|
||||||
CLUTTER_PARAM_READWRITE);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterInputDevice:n-axes:
|
* ClutterInputDevice:n-axes:
|
||||||
*
|
*
|
||||||
@ -506,14 +468,6 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass)
|
|||||||
NULL,
|
NULL,
|
||||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
|
||||||
obj_props[PROP_MAPPING_MODE] =
|
|
||||||
g_param_spec_enum ("mapping-mode",
|
|
||||||
P_("Device mapping mode"),
|
|
||||||
P_("Device mapping mode"),
|
|
||||||
CLUTTER_TYPE_INPUT_DEVICE_MAPPING,
|
|
||||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE,
|
|
||||||
CLUTTER_PARAM_READWRITE);
|
|
||||||
|
|
||||||
gobject_class->dispose = clutter_input_device_dispose;
|
gobject_class->dispose = clutter_input_device_dispose;
|
||||||
gobject_class->set_property = clutter_input_device_set_property;
|
gobject_class->set_property = clutter_input_device_set_property;
|
||||||
gobject_class->get_property = clutter_input_device_get_property;
|
gobject_class->get_property = clutter_input_device_get_property;
|
||||||
@ -528,91 +482,15 @@ clutter_input_device_init (ClutterInputDevice *self)
|
|||||||
|
|
||||||
self->click_count = 0;
|
self->click_count = 0;
|
||||||
|
|
||||||
self->current_time = self->previous_time = CLUTTER_CURRENT_TIME;
|
self->previous_time = CLUTTER_CURRENT_TIME;
|
||||||
self->current_x = self->previous_x = -1;
|
self->previous_x = -1;
|
||||||
self->current_y = self->previous_y = -1;
|
self->previous_y = -1;
|
||||||
self->current_button_number = self->previous_button_number = -1;
|
self->current_button_number = self->previous_button_number = -1;
|
||||||
self->current_state = self->previous_state = 0;
|
|
||||||
|
|
||||||
self->touch_sequences_info =
|
self->touch_sequence_actors = g_hash_table_new (NULL, NULL);
|
||||||
g_hash_table_new_full (NULL, NULL,
|
|
||||||
NULL, _clutter_input_device_free_touch_info);
|
|
||||||
self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL);
|
self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterTouchInfo *
|
|
||||||
_clutter_input_device_ensure_touch_info (ClutterInputDevice *device,
|
|
||||||
ClutterEventSequence *sequence,
|
|
||||||
ClutterStage *stage)
|
|
||||||
{
|
|
||||||
ClutterTouchInfo *info;
|
|
||||||
|
|
||||||
info = g_hash_table_lookup (device->touch_sequences_info, sequence);
|
|
||||||
|
|
||||||
if (info == NULL)
|
|
||||||
{
|
|
||||||
info = g_slice_new0 (ClutterTouchInfo);
|
|
||||||
info->sequence = sequence;
|
|
||||||
g_hash_table_insert (device->touch_sequences_info, sequence, info);
|
|
||||||
|
|
||||||
if (g_hash_table_size (device->touch_sequences_info) == 1)
|
|
||||||
_clutter_input_device_set_stage (device, stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* clutter_input_device_set_coords:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
* @sequence: a #ClutterEventSequence or NULL
|
|
||||||
* @x: X coordinate of the device
|
|
||||||
* @y: Y coordinate of the device
|
|
||||||
*
|
|
||||||
* Stores the last known coordinates of the device
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_clutter_input_device_set_coords (ClutterInputDevice *device,
|
|
||||||
ClutterEventSequence *sequence,
|
|
||||||
gfloat x,
|
|
||||||
gfloat y,
|
|
||||||
ClutterStage *stage)
|
|
||||||
{
|
|
||||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
|
||||||
|
|
||||||
if (sequence == NULL)
|
|
||||||
{
|
|
||||||
if (device->current_x != x)
|
|
||||||
device->current_x = x;
|
|
||||||
|
|
||||||
if (device->current_y != y)
|
|
||||||
device->current_y = y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ClutterTouchInfo *info;
|
|
||||||
info = _clutter_input_device_ensure_touch_info (device, sequence, stage);
|
|
||||||
info->current_x = x;
|
|
||||||
info->current_y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* clutter_input_device_set_state:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
* @state: a bitmask of modifiers
|
|
||||||
*
|
|
||||||
* Stores the last known modifiers state of the device
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_clutter_input_device_set_state (ClutterInputDevice *device,
|
|
||||||
ClutterModifierType state)
|
|
||||||
{
|
|
||||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
|
||||||
|
|
||||||
device->current_state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_input_device_get_modifier_state:
|
* clutter_input_device_get_modifier_state:
|
||||||
* @device: a #ClutterInputDevice
|
* @device: a #ClutterInputDevice
|
||||||
@ -627,69 +505,17 @@ _clutter_input_device_set_state (ClutterInputDevice *device,
|
|||||||
ClutterModifierType
|
ClutterModifierType
|
||||||
clutter_input_device_get_modifier_state (ClutterInputDevice *device)
|
clutter_input_device_get_modifier_state (ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
|
uint32_t modifiers;
|
||||||
|
ClutterSeat *seat;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0);
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0);
|
||||||
|
|
||||||
return device->current_state;
|
seat = clutter_input_device_get_seat (device);
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
if (!clutter_seat_query_state (seat, device, NULL, NULL, &modifiers))
|
||||||
* clutter_input_device_set_time:
|
return 0;
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
* @time_: the time
|
|
||||||
*
|
|
||||||
* Stores the last known event time of the device
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_clutter_input_device_set_time (ClutterInputDevice *device,
|
|
||||||
guint32 time_)
|
|
||||||
{
|
|
||||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
|
||||||
|
|
||||||
if (device->current_time != time_)
|
return modifiers;
|
||||||
device->current_time = time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* clutter_input_device_set_stage:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
* @stage: a #ClutterStage or %NULL
|
|
||||||
*
|
|
||||||
* Stores the stage under the device
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_clutter_input_device_set_stage (ClutterInputDevice *device,
|
|
||||||
ClutterStage *stage)
|
|
||||||
{
|
|
||||||
if (device->stage == stage)
|
|
||||||
return;
|
|
||||||
|
|
||||||
device->stage = stage;
|
|
||||||
|
|
||||||
/* we leave the ->cursor_actor in place in order to check
|
|
||||||
* if we left the stage without crossing it again; this way
|
|
||||||
* we can emit a leave event on the cursor actor right before
|
|
||||||
* we emit the leave event on the stage.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* clutter_input_device_get_stage:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
*
|
|
||||||
* Retrieves the stage currently associated with @device.
|
|
||||||
*
|
|
||||||
* Return value: The stage currently associated with @device.
|
|
||||||
*/
|
|
||||||
ClutterStage *
|
|
||||||
_clutter_input_device_get_stage (ClutterInputDevice *device)
|
|
||||||
{
|
|
||||||
return device->stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_clutter_input_device_free_touch_info (gpointer data)
|
|
||||||
{
|
|
||||||
g_slice_free (ClutterTouchInfo, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -703,12 +529,8 @@ _clutter_input_device_associate_actor (ClutterInputDevice *device,
|
|||||||
{
|
{
|
||||||
GList *sequences =
|
GList *sequences =
|
||||||
g_hash_table_lookup (device->inv_touch_sequence_actors, actor);
|
g_hash_table_lookup (device->inv_touch_sequence_actors, actor);
|
||||||
ClutterTouchInfo *info;
|
|
||||||
ClutterStage *stage = CLUTTER_STAGE (clutter_actor_get_stage (actor));
|
|
||||||
|
|
||||||
info = _clutter_input_device_ensure_touch_info (device, sequence, stage);
|
|
||||||
info->actor = actor;
|
|
||||||
|
|
||||||
|
g_hash_table_insert (device->touch_sequence_actors, sequence, actor);
|
||||||
g_hash_table_insert (device->inv_touch_sequence_actors,
|
g_hash_table_insert (device->inv_touch_sequence_actors,
|
||||||
actor, g_list_prepend (sequences, sequence));
|
actor, g_list_prepend (sequences, sequence));
|
||||||
}
|
}
|
||||||
@ -736,13 +558,7 @@ _clutter_input_device_unassociate_actor (ClutterInputDevice *device,
|
|||||||
actor);
|
actor);
|
||||||
|
|
||||||
for (l = sequences; l != NULL; l = l->next)
|
for (l = sequences; l != NULL; l = l->next)
|
||||||
{
|
g_hash_table_remove (device->touch_sequence_actors, l->data);
|
||||||
ClutterTouchInfo *info =
|
|
||||||
g_hash_table_lookup (device->touch_sequences_info, l->data);
|
|
||||||
|
|
||||||
if (info)
|
|
||||||
info->actor = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free (sequences);
|
g_list_free (sequences);
|
||||||
g_hash_table_remove (device->inv_touch_sequence_actors, actor);
|
g_hash_table_remove (device->inv_touch_sequence_actors, actor);
|
||||||
@ -795,17 +611,31 @@ on_cursor_actor_reactive_changed (ClutterActor *actor,
|
|||||||
* - set to %TRUE the :has-pointer property of the new pointer
|
* - set to %TRUE the :has-pointer property of the new pointer
|
||||||
* actor
|
* actor
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
_clutter_input_device_set_actor (ClutterInputDevice *device,
|
_clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||||
ClutterEventSequence *sequence,
|
ClutterEventSequence *sequence,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
gboolean emit_crossing)
|
gboolean emit_crossing,
|
||||||
|
graphene_point_t coords,
|
||||||
|
uint32_t time_)
|
||||||
{
|
{
|
||||||
ClutterActor *old_actor = clutter_input_device_get_actor (device, sequence);
|
ClutterActor *old_actor = clutter_input_device_get_actor (device, sequence);
|
||||||
|
ClutterStage *stage = NULL;
|
||||||
|
|
||||||
if (old_actor == actor)
|
if (old_actor == actor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (emit_crossing)
|
||||||
|
{
|
||||||
|
if (actor)
|
||||||
|
stage = CLUTTER_STAGE (clutter_actor_get_stage (actor));
|
||||||
|
else if (old_actor)
|
||||||
|
stage = CLUTTER_STAGE (clutter_actor_get_stage (old_actor));
|
||||||
|
|
||||||
|
if (!stage)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (old_actor != NULL)
|
if (old_actor != NULL)
|
||||||
{
|
{
|
||||||
ClutterActor *tmp_old_actor;
|
ClutterActor *tmp_old_actor;
|
||||||
@ -815,12 +645,12 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
|
|||||||
ClutterEvent *event;
|
ClutterEvent *event;
|
||||||
|
|
||||||
event = clutter_event_new (CLUTTER_LEAVE);
|
event = clutter_event_new (CLUTTER_LEAVE);
|
||||||
event->crossing.time = device->current_time;
|
event->crossing.time = time_;
|
||||||
event->crossing.flags = 0;
|
event->crossing.flags = 0;
|
||||||
event->crossing.stage = device->stage;
|
event->crossing.stage = stage;
|
||||||
event->crossing.source = old_actor;
|
event->crossing.source = old_actor;
|
||||||
event->crossing.x = device->current_x;
|
event->crossing.x = coords.x;
|
||||||
event->crossing.y = device->current_y;
|
event->crossing.y = coords.y;
|
||||||
event->crossing.related = actor;
|
event->crossing.related = actor;
|
||||||
event->crossing.sequence = sequence;
|
event->crossing.sequence = sequence;
|
||||||
clutter_event_set_device (event, device);
|
clutter_event_set_device (event, device);
|
||||||
@ -852,11 +682,11 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
|
|||||||
ClutterEvent *event;
|
ClutterEvent *event;
|
||||||
|
|
||||||
event = clutter_event_new (CLUTTER_ENTER);
|
event = clutter_event_new (CLUTTER_ENTER);
|
||||||
event->crossing.time = device->current_time;
|
event->crossing.time = time_;
|
||||||
event->crossing.flags = 0;
|
event->crossing.flags = 0;
|
||||||
event->crossing.stage = device->stage;
|
event->crossing.stage = stage;
|
||||||
event->crossing.x = device->current_x;
|
event->crossing.x = coords.x;
|
||||||
event->crossing.y = device->current_y;
|
event->crossing.y = coords.y;
|
||||||
event->crossing.source = actor;
|
event->crossing.source = actor;
|
||||||
event->crossing.related = old_actor;
|
event->crossing.related = old_actor;
|
||||||
event->crossing.sequence = sequence;
|
event->crossing.sequence = sequence;
|
||||||
@ -907,56 +737,6 @@ clutter_input_device_get_device_id (ClutterInputDevice *device)
|
|||||||
return device->id;
|
return device->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* clutter_input_device_set_enabled:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
* @enabled: %TRUE to enable the @device
|
|
||||||
*
|
|
||||||
* Enables or disables a #ClutterInputDevice.
|
|
||||||
*
|
|
||||||
* Only devices with a #ClutterInputDevice:device-mode property set
|
|
||||||
* to %CLUTTER_INPUT_MODE_SLAVE or %CLUTTER_INPUT_MODE_FLOATING can
|
|
||||||
* be disabled.
|
|
||||||
*
|
|
||||||
* Since: 1.6
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
clutter_input_device_set_enabled (ClutterInputDevice *device,
|
|
||||||
gboolean enabled)
|
|
||||||
{
|
|
||||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
|
||||||
|
|
||||||
enabled = !!enabled;
|
|
||||||
|
|
||||||
if (!enabled && device->device_mode == CLUTTER_INPUT_MODE_MASTER)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (device->is_enabled == enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
device->is_enabled = enabled;
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (device), obj_props[PROP_ENABLED]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clutter_input_device_get_enabled:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
*
|
|
||||||
* Retrieves whether @device is enabled.
|
|
||||||
*
|
|
||||||
* Return value: %TRUE if the device is enabled
|
|
||||||
*
|
|
||||||
* Since: 1.6
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
clutter_input_device_get_enabled (ClutterInputDevice *device)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
|
||||||
|
|
||||||
return device->is_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_input_device_get_coords:
|
* clutter_input_device_get_coords:
|
||||||
* @device: a #ClutterInputDevice
|
* @device: a #ClutterInputDevice
|
||||||
@ -978,27 +758,14 @@ clutter_input_device_get_coords (ClutterInputDevice *device,
|
|||||||
ClutterEventSequence *sequence,
|
ClutterEventSequence *sequence,
|
||||||
graphene_point_t *point)
|
graphene_point_t *point)
|
||||||
{
|
{
|
||||||
|
ClutterSeat *seat;
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||||
g_return_val_if_fail (point != NULL, FALSE);
|
g_return_val_if_fail (point != NULL, FALSE);
|
||||||
|
|
||||||
if (sequence == NULL)
|
seat = clutter_input_device_get_seat (device);
|
||||||
{
|
|
||||||
point->x = device->current_x;
|
|
||||||
point->y = device->current_y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ClutterTouchInfo *info =
|
|
||||||
g_hash_table_lookup (device->touch_sequences_info, sequence);
|
|
||||||
|
|
||||||
if (info == NULL)
|
return clutter_seat_query_state (seat, device, sequence, point, NULL);
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
point->x = info->current_x;
|
|
||||||
point->y = info->current_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1018,27 +785,29 @@ clutter_input_device_get_coords (ClutterInputDevice *device,
|
|||||||
ClutterActor *
|
ClutterActor *
|
||||||
clutter_input_device_update (ClutterInputDevice *device,
|
clutter_input_device_update (ClutterInputDevice *device,
|
||||||
ClutterEventSequence *sequence,
|
ClutterEventSequence *sequence,
|
||||||
gboolean emit_crossing)
|
ClutterStage *stage,
|
||||||
|
gboolean emit_crossing,
|
||||||
|
ClutterEvent *for_event)
|
||||||
{
|
{
|
||||||
ClutterStage *stage;
|
|
||||||
ClutterActor *new_cursor_actor;
|
ClutterActor *new_cursor_actor;
|
||||||
ClutterActor *old_cursor_actor;
|
ClutterActor *old_cursor_actor;
|
||||||
graphene_point_t point = GRAPHENE_POINT_INIT (-1.0f, -1.0f);
|
graphene_point_t point = GRAPHENE_POINT_INIT (-1.0f, -1.0f);
|
||||||
ClutterInputDeviceType device_type = device->device_type;
|
ClutterInputDeviceType device_type = device->device_type;
|
||||||
|
uint32_t time_;
|
||||||
|
|
||||||
g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
|
g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
|
||||||
device_type != CLUTTER_PAD_DEVICE);
|
device_type != CLUTTER_PAD_DEVICE);
|
||||||
|
|
||||||
stage = device->stage;
|
if (for_event)
|
||||||
if (G_UNLIKELY (stage == NULL))
|
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (EVENT, "No stage defined for device %d '%s'",
|
clutter_event_get_coords (for_event, &point.x, &point.y);
|
||||||
clutter_input_device_get_device_id (device),
|
time_ = clutter_event_get_time (for_event);
|
||||||
clutter_input_device_get_device_name (device));
|
}
|
||||||
return NULL;
|
else
|
||||||
|
{
|
||||||
|
clutter_input_device_get_coords (device, sequence, &point);
|
||||||
|
time_ = CLUTTER_CURRENT_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
clutter_input_device_get_coords (device, sequence, &point);
|
|
||||||
|
|
||||||
old_cursor_actor = clutter_input_device_get_actor (device, sequence);
|
old_cursor_actor = clutter_input_device_get_actor (device, sequence);
|
||||||
new_cursor_actor =
|
new_cursor_actor =
|
||||||
@ -1065,7 +834,8 @@ clutter_input_device_update (ClutterInputDevice *device,
|
|||||||
|
|
||||||
_clutter_input_device_set_actor (device, sequence,
|
_clutter_input_device_set_actor (device, sequence,
|
||||||
new_cursor_actor,
|
new_cursor_actor,
|
||||||
emit_crossing);
|
emit_crossing,
|
||||||
|
point, time_);
|
||||||
|
|
||||||
return new_cursor_actor;
|
return new_cursor_actor;
|
||||||
}
|
}
|
||||||
@ -1086,37 +856,12 @@ ClutterActor *
|
|||||||
clutter_input_device_get_actor (ClutterInputDevice *device,
|
clutter_input_device_get_actor (ClutterInputDevice *device,
|
||||||
ClutterEventSequence *sequence)
|
ClutterEventSequence *sequence)
|
||||||
{
|
{
|
||||||
ClutterTouchInfo *info;
|
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||||
|
|
||||||
if (sequence == NULL)
|
if (sequence == NULL)
|
||||||
return device->cursor_actor;
|
return device->cursor_actor;
|
||||||
|
|
||||||
info = g_hash_table_lookup (device->touch_sequences_info, sequence);
|
return g_hash_table_lookup (device->touch_sequence_actors, sequence);
|
||||||
|
|
||||||
g_return_val_if_fail (info != NULL, NULL);
|
|
||||||
|
|
||||||
return info->actor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clutter_input_device_get_pointer_stage:
|
|
||||||
* @device: a #ClutterInputDevice of type %CLUTTER_POINTER_DEVICE
|
|
||||||
*
|
|
||||||
* Retrieves the #ClutterStage underneath the pointer of @device
|
|
||||||
*
|
|
||||||
* Return value: (transfer none): a pointer to the #ClutterStage or %NULL
|
|
||||||
*
|
|
||||||
* Since: 1.2
|
|
||||||
*/
|
|
||||||
ClutterStage *
|
|
||||||
clutter_input_device_get_pointer_stage (ClutterInputDevice *device)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
|
||||||
g_return_val_if_fail (device->device_type == CLUTTER_POINTER_DEVICE, NULL);
|
|
||||||
|
|
||||||
return device->stage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1177,95 +922,6 @@ clutter_input_device_get_device_mode (ClutterInputDevice *device)
|
|||||||
return device->device_mode;
|
return device->device_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* clutter_input_device_update_from_event:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
* @event: a #ClutterEvent
|
|
||||||
* @update_stage: whether to update the #ClutterStage of the @device
|
|
||||||
* using the stage of the event
|
|
||||||
*
|
|
||||||
* Forcibly updates the state of the @device using a #ClutterEvent
|
|
||||||
*
|
|
||||||
* This function should never be used by applications: it is meant
|
|
||||||
* for integration with embedding toolkits, like clutter-gtk
|
|
||||||
*
|
|
||||||
* Embedding toolkits that disable the event collection inside Clutter
|
|
||||||
* need to use this function to update the state of input devices depending
|
|
||||||
* on a #ClutterEvent that they are going to submit to the event handling code
|
|
||||||
* in Clutter though clutter_do_event(). Since the input devices hold the state
|
|
||||||
* that is going to be used to fill in fields like the #ClutterButtonEvent
|
|
||||||
* click count, or to emit synthesized events like %CLUTTER_ENTER and
|
|
||||||
* %CLUTTER_LEAVE, it is necessary for embedding toolkits to also be
|
|
||||||
* responsible of updating the input device state.
|
|
||||||
*
|
|
||||||
* For instance, this might be the code to translate an embedding toolkit
|
|
||||||
* native motion notification into a Clutter #ClutterMotionEvent and ask
|
|
||||||
* Clutter to process it:
|
|
||||||
*
|
|
||||||
* |[
|
|
||||||
* ClutterEvent c_event;
|
|
||||||
*
|
|
||||||
* translate_native_event_to_clutter (native_event, &c_event);
|
|
||||||
*
|
|
||||||
* clutter_do_event (&c_event);
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* Before letting clutter_do_event() process the event, it is necessary to call
|
|
||||||
* clutter_input_device_update_from_event():
|
|
||||||
*
|
|
||||||
* |[
|
|
||||||
* ClutterEvent c_event;
|
|
||||||
* ClutterDeviceManager *manager;
|
|
||||||
* ClutterInputDevice *device;
|
|
||||||
*
|
|
||||||
* translate_native_event_to_clutter (native_event, &c_event);
|
|
||||||
*
|
|
||||||
* // get the seat
|
|
||||||
* seat = clutter_backend_get_deafult_seat (clutter_get_default_backend ());
|
|
||||||
*
|
|
||||||
* // use the default Core Pointer that Clutter backends register by default
|
|
||||||
* device = clutter_seat_get_pointer (seat);
|
|
||||||
*
|
|
||||||
* // update the state of the input device
|
|
||||||
* clutter_input_device_update_from_event (device, &c_event, FALSE);
|
|
||||||
*
|
|
||||||
* clutter_do_event (&c_event);
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* The @update_stage boolean argument should be used when the input device
|
|
||||||
* enters and leaves a #ClutterStage; it will use the #ClutterStage field
|
|
||||||
* of the passed @event to update the stage associated to the input device.
|
|
||||||
*
|
|
||||||
* Since: 1.2
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
clutter_input_device_update_from_event (ClutterInputDevice *device,
|
|
||||||
ClutterEvent *event,
|
|
||||||
gboolean update_stage)
|
|
||||||
{
|
|
||||||
ClutterModifierType event_state;
|
|
||||||
ClutterEventSequence *sequence;
|
|
||||||
ClutterStage *event_stage;
|
|
||||||
gfloat event_x, event_y;
|
|
||||||
guint32 event_time;
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
|
||||||
g_return_if_fail (event != NULL);
|
|
||||||
|
|
||||||
event_state = clutter_event_get_state (event);
|
|
||||||
event_time = clutter_event_get_time (event);
|
|
||||||
event_stage = clutter_event_get_stage (event);
|
|
||||||
sequence = clutter_event_get_event_sequence (event);
|
|
||||||
clutter_event_get_coords (event, &event_x, &event_y);
|
|
||||||
|
|
||||||
_clutter_input_device_set_coords (device, sequence, event_x, event_y, event_stage);
|
|
||||||
_clutter_input_device_set_state (device, event_state);
|
|
||||||
_clutter_input_device_set_time (device, event_time);
|
|
||||||
|
|
||||||
if (update_stage)
|
|
||||||
_clutter_input_device_set_stage (device, event_stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
* clutter_input_device_reset_axes:
|
* clutter_input_device_reset_axes:
|
||||||
* @device: a #ClutterInputDevice
|
* @device: a #ClutterInputDevice
|
||||||
@ -1646,31 +1302,6 @@ _clutter_input_device_remove_slave (ClutterInputDevice *master,
|
|||||||
master->slaves = g_list_remove (master->slaves, slave);
|
master->slaves = g_list_remove (master->slaves, slave);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*< private >
|
|
||||||
* clutter_input_device_add_sequence:
|
|
||||||
* @device: a #ClutterInputDevice
|
|
||||||
* @sequence: a #ClutterEventSequence
|
|
||||||
*
|
|
||||||
* Start tracking informations related to a touch point (position,
|
|
||||||
* actor underneath the touch point).
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_clutter_input_device_add_event_sequence (ClutterInputDevice *device,
|
|
||||||
ClutterEvent *event)
|
|
||||||
{
|
|
||||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
|
||||||
ClutterStage *stage;
|
|
||||||
|
|
||||||
if (sequence == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
stage = clutter_event_get_stage (event);
|
|
||||||
if (stage == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_clutter_input_device_ensure_touch_info (device, sequence, stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
* clutter_input_device_remove_sequence:
|
* clutter_input_device_remove_sequence:
|
||||||
* @device: a #ClutterInputDevice
|
* @device: a #ClutterInputDevice
|
||||||
@ -1683,25 +1314,25 @@ _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
|
|||||||
ClutterEvent *event)
|
ClutterEvent *event)
|
||||||
{
|
{
|
||||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
||||||
ClutterTouchInfo *info =
|
ClutterActor *actor =
|
||||||
g_hash_table_lookup (device->touch_sequences_info, sequence);
|
g_hash_table_lookup (device->touch_sequence_actors, sequence);
|
||||||
|
|
||||||
if (info == NULL)
|
if (actor != NULL)
|
||||||
return;
|
|
||||||
|
|
||||||
if (info->actor != NULL)
|
|
||||||
{
|
{
|
||||||
GList *sequences =
|
GList *sequences =
|
||||||
g_hash_table_lookup (device->inv_touch_sequence_actors, info->actor);
|
g_hash_table_lookup (device->inv_touch_sequence_actors, actor);
|
||||||
|
graphene_point_t point;
|
||||||
|
|
||||||
sequences = g_list_remove (sequences, sequence);
|
sequences = g_list_remove (sequences, sequence);
|
||||||
|
|
||||||
g_hash_table_replace (device->inv_touch_sequence_actors,
|
g_hash_table_replace (device->inv_touch_sequence_actors,
|
||||||
info->actor, sequences);
|
actor, sequences);
|
||||||
_clutter_input_device_set_actor (device, sequence, NULL, TRUE);
|
clutter_event_get_coords (event, &point.x, &point.y);
|
||||||
|
_clutter_input_device_set_actor (device, sequence, NULL, TRUE, point,
|
||||||
|
clutter_event_get_time (event));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_remove (device->touch_sequences_info, sequence);
|
g_hash_table_remove (device->touch_sequence_actors, sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2391,43 +2022,6 @@ clutter_input_device_get_device_node (ClutterInputDevice *device)
|
|||||||
return device->node_path;
|
return device->node_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterInputDeviceMapping
|
|
||||||
clutter_input_device_get_mapping_mode (ClutterInputDevice *device)
|
|
||||||
{
|
|
||||||
ClutterInputDeviceType device_type;
|
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device),
|
|
||||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
|
||||||
|
|
||||||
device_type = clutter_input_device_get_device_type (device);
|
|
||||||
g_return_val_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
|
||||||
device_type == CLUTTER_PEN_DEVICE ||
|
|
||||||
device_type == CLUTTER_ERASER_DEVICE,
|
|
||||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
|
||||||
|
|
||||||
return device->mapping_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
|
||||||
ClutterInputDeviceMapping mapping)
|
|
||||||
{
|
|
||||||
ClutterInputDeviceType device_type;
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
|
||||||
|
|
||||||
device_type = clutter_input_device_get_device_type (device);
|
|
||||||
g_return_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
|
||||||
device_type == CLUTTER_PEN_DEVICE ||
|
|
||||||
device_type == CLUTTER_ERASER_DEVICE);
|
|
||||||
|
|
||||||
if (device->mapping_mode == mapping)
|
|
||||||
return;
|
|
||||||
|
|
||||||
device->mapping_mode = mapping;
|
|
||||||
g_object_notify (G_OBJECT (device), "mapping-mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
clutter_input_device_is_grouped (ClutterInputDevice *device,
|
clutter_input_device_is_grouped (ClutterInputDevice *device,
|
||||||
ClutterInputDevice *other_device)
|
ClutterInputDevice *other_device)
|
||||||
|
@ -95,18 +95,11 @@ CLUTTER_EXPORT
|
|||||||
ClutterActor * clutter_input_device_get_actor (ClutterInputDevice *device,
|
ClutterActor * clutter_input_device_get_actor (ClutterInputDevice *device,
|
||||||
ClutterEventSequence *sequence);
|
ClutterEventSequence *sequence);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
ClutterStage * clutter_input_device_get_pointer_stage (ClutterInputDevice *device);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device);
|
const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device);
|
ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
gboolean clutter_input_device_get_has_cursor (ClutterInputDevice *device);
|
gboolean clutter_input_device_get_has_cursor (ClutterInputDevice *device);
|
||||||
CLUTTER_EXPORT
|
|
||||||
void clutter_input_device_set_enabled (ClutterInputDevice *device,
|
|
||||||
gboolean enabled);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
gboolean clutter_input_device_get_enabled (ClutterInputDevice *device);
|
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
guint clutter_input_device_get_n_axes (ClutterInputDevice *device);
|
guint clutter_input_device_get_n_axes (ClutterInputDevice *device);
|
||||||
@ -122,11 +115,6 @@ gboolean clutter_input_device_get_axis_value (ClutterInputDev
|
|||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
guint clutter_input_device_get_n_keys (ClutterInputDevice *device);
|
guint clutter_input_device_get_n_keys (ClutterInputDevice *device);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
void clutter_input_device_set_key (ClutterInputDevice *device,
|
|
||||||
guint index_,
|
|
||||||
guint keyval,
|
|
||||||
ClutterModifierType modifiers);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
gboolean clutter_input_device_get_key (ClutterInputDevice *device,
|
gboolean clutter_input_device_get_key (ClutterInputDevice *device,
|
||||||
guint index_,
|
guint index_,
|
||||||
guint *keyval,
|
guint *keyval,
|
||||||
@ -137,11 +125,6 @@ ClutterInputDevice * clutter_input_device_get_associated_device (ClutterInput
|
|||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
GList * clutter_input_device_get_slave_devices (ClutterInputDevice *device);
|
GList * clutter_input_device_get_slave_devices (ClutterInputDevice *device);
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void clutter_input_device_update_from_event (ClutterInputDevice *device,
|
|
||||||
ClutterEvent *event,
|
|
||||||
gboolean update_stage);
|
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
void clutter_input_device_grab (ClutterInputDevice *device,
|
void clutter_input_device_grab (ClutterInputDevice *device,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
@ -161,11 +144,6 @@ CLUTTER_EXPORT
|
|||||||
ClutterActor * clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice *device,
|
ClutterActor * clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice *device,
|
||||||
ClutterEventSequence *sequence);
|
ClutterEventSequence *sequence);
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device,
|
|
||||||
guint hardware_keycode,
|
|
||||||
guint *evdev_keycode);
|
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
const gchar * clutter_input_device_get_vendor_id (ClutterInputDevice *device);
|
const gchar * clutter_input_device_get_vendor_id (ClutterInputDevice *device);
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
@ -193,12 +171,6 @@ gint clutter_input_device_get_mode_switch_button_group (Clutt
|
|||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
const gchar * clutter_input_device_get_device_node (ClutterInputDevice *device);
|
const gchar * clutter_input_device_get_device_node (ClutterInputDevice *device);
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
ClutterInputDeviceMapping clutter_input_device_get_mapping_mode (ClutterInputDevice *device);
|
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
|
||||||
ClutterInputDeviceMapping mapping);
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
gboolean clutter_input_device_is_grouped (ClutterInputDevice *device,
|
gboolean clutter_input_device_is_grouped (ClutterInputDevice *device,
|
||||||
ClutterInputDevice *other_device);
|
ClutterInputDevice *other_device);
|
||||||
|
@ -454,6 +454,7 @@ clutter_input_method_forward_key (ClutterInputMethod *im,
|
|||||||
ClutterInputMethodPrivate *priv;
|
ClutterInputMethodPrivate *priv;
|
||||||
ClutterInputDevice *keyboard;
|
ClutterInputDevice *keyboard;
|
||||||
ClutterSeat *seat;
|
ClutterSeat *seat;
|
||||||
|
ClutterStageManager *stage_manager;
|
||||||
ClutterStage *stage;
|
ClutterStage *stage;
|
||||||
ClutterEvent *event;
|
ClutterEvent *event;
|
||||||
|
|
||||||
@ -464,10 +465,9 @@ clutter_input_method_forward_key (ClutterInputMethod *im,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||||
|
stage_manager = clutter_stage_manager_get_default ();
|
||||||
|
stage = clutter_stage_manager_get_default_stage (stage_manager);
|
||||||
keyboard = clutter_seat_get_keyboard (seat);
|
keyboard = clutter_seat_get_keyboard (seat);
|
||||||
stage = _clutter_input_device_get_stage (keyboard);
|
|
||||||
if (stage == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
event = clutter_event_new (press ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
|
event = clutter_event_new (press ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
|
||||||
event->key.time = time_;
|
event->key.time = time_;
|
||||||
|
@ -697,6 +697,8 @@ _clutter_context_get_default (void)
|
|||||||
ctx->settings = clutter_settings_get_default ();
|
ctx->settings = clutter_settings_get_default ();
|
||||||
_clutter_settings_set_backend (ctx->settings, ctx->backend);
|
_clutter_settings_set_backend (ctx->settings, ctx->backend);
|
||||||
|
|
||||||
|
ctx->events_queue = g_async_queue_new ();
|
||||||
|
|
||||||
ctx->last_repaint_id = 1;
|
ctx->last_repaint_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1621,7 +1623,9 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
|
|
||||||
emit_crossing_event (event, device);
|
emit_crossing_event (event, device);
|
||||||
|
|
||||||
actor = clutter_input_device_update (device, NULL, FALSE);
|
actor = clutter_input_device_update (device, NULL,
|
||||||
|
CLUTTER_STAGE (stage), FALSE,
|
||||||
|
event);
|
||||||
if (actor != stage)
|
if (actor != stage)
|
||||||
{
|
{
|
||||||
ClutterEvent *crossing;
|
ClutterEvent *crossing;
|
||||||
@ -1770,21 +1774,9 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the backend provides a device then we should
|
actor = clutter_input_device_update (device, NULL,
|
||||||
* already have everything we need to update it and
|
CLUTTER_STAGE (stage),
|
||||||
* get the actor underneath
|
TRUE, event);
|
||||||
*/
|
|
||||||
if (device != NULL)
|
|
||||||
actor = clutter_input_device_update (device, NULL, TRUE);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CLUTTER_NOTE (EVENT, "No device found: picking");
|
|
||||||
|
|
||||||
actor = _clutter_stage_do_pick (CLUTTER_STAGE (stage),
|
|
||||||
x, y,
|
|
||||||
CLUTTER_PICK_REACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actor == NULL)
|
if (actor == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1860,9 +1852,6 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
sequence =
|
sequence =
|
||||||
clutter_event_get_event_sequence (event);
|
clutter_event_get_event_sequence (event);
|
||||||
|
|
||||||
if (event->type == CLUTTER_TOUCH_BEGIN)
|
|
||||||
_clutter_input_device_add_event_sequence (device, event);
|
|
||||||
|
|
||||||
clutter_event_get_coords (event, &x, &y);
|
clutter_event_get_coords (event, &x, &y);
|
||||||
|
|
||||||
/* Only do a pick to find the source if source is not already set
|
/* Only do a pick to find the source if source is not already set
|
||||||
@ -1892,17 +1881,9 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device != NULL)
|
actor = clutter_input_device_update (device, sequence,
|
||||||
actor = clutter_input_device_update (device, sequence, TRUE);
|
CLUTTER_STAGE (stage),
|
||||||
else
|
TRUE, event);
|
||||||
{
|
|
||||||
CLUTTER_NOTE (EVENT, "No device found: picking");
|
|
||||||
|
|
||||||
actor = _clutter_stage_do_pick (CLUTTER_STAGE (stage),
|
|
||||||
x, y,
|
|
||||||
CLUTTER_PICK_REACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actor == NULL)
|
if (actor == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1954,6 +1935,11 @@ _clutter_process_event_details (ClutterActor *stage,
|
|||||||
case CLUTTER_CLIENT_MESSAGE:
|
case CLUTTER_CLIENT_MESSAGE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
_clutter_event_process_filters (event);
|
||||||
|
break;
|
||||||
|
|
||||||
case CLUTTER_EVENT_LAST:
|
case CLUTTER_EVENT_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2302,39 +2288,16 @@ void
|
|||||||
_clutter_clear_events_queue (void)
|
_clutter_clear_events_queue (void)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = _clutter_context_get_default ();
|
ClutterMainContext *context = _clutter_context_get_default ();
|
||||||
|
ClutterEvent *event;
|
||||||
|
|
||||||
if (context->events_queue != NULL)
|
/* Lock the queue for as long as it lives */
|
||||||
{
|
g_async_queue_lock (context->events_queue);
|
||||||
g_queue_foreach (context->events_queue,
|
|
||||||
(GFunc) clutter_event_free,
|
|
||||||
NULL);
|
|
||||||
g_queue_free (context->events_queue);
|
|
||||||
context->events_queue = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
while ((event = g_async_queue_try_pop_unlocked (context->events_queue)))
|
||||||
_clutter_clear_events_queue_for_stage (ClutterStage *stage)
|
clutter_event_free (event);
|
||||||
{
|
|
||||||
ClutterMainContext *context = _clutter_context_get_default ();
|
|
||||||
GList *l, *next;
|
|
||||||
|
|
||||||
if (context->events_queue == NULL)
|
g_async_queue_unref (context->events_queue);
|
||||||
return;
|
context->events_queue = NULL;
|
||||||
|
|
||||||
/* Remove any pending events for this stage from the event queue */
|
|
||||||
for (l = context->events_queue->head; l; l = next)
|
|
||||||
{
|
|
||||||
ClutterEvent *event = l->data;
|
|
||||||
|
|
||||||
next = l->next;
|
|
||||||
|
|
||||||
if (event->any.stage == stage)
|
|
||||||
{
|
|
||||||
g_queue_delete_link (context->events_queue, l);
|
|
||||||
clutter_event_free (event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterPickMode
|
ClutterPickMode
|
||||||
|
@ -71,6 +71,9 @@ gboolean clutter_actor_has_transitions (ClutterActor *actor);
|
|||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
ClutterFrameClock * clutter_actor_pick_frame_clock (ClutterActor *self,
|
ClutterFrameClock * clutter_actor_pick_frame_clock (ClutterActor *self,
|
||||||
ClutterActor **out_actor);
|
ClutterActor **out_actor);
|
||||||
|
CLUTTER_EXPORT
|
||||||
|
gboolean clutter_seat_handle_event_post (ClutterSeat *seat,
|
||||||
|
const ClutterEvent *event);
|
||||||
|
|
||||||
#undef __CLUTTER_H_INSIDE__
|
#undef __CLUTTER_H_INSIDE__
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ struct _ClutterMainContext
|
|||||||
ClutterStageManager *stage_manager;
|
ClutterStageManager *stage_manager;
|
||||||
|
|
||||||
/* the main event queue */
|
/* the main event queue */
|
||||||
GQueue *events_queue;
|
GAsyncQueue *events_queue;
|
||||||
|
|
||||||
/* the event filters added via clutter_event_add_filter. these are
|
/* the event filters added via clutter_event_add_filter. these are
|
||||||
* ordered from least recently added to most recently added */
|
* ordered from least recently added to most recently added */
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "clutter-input-device-tool.h"
|
#include "clutter-input-device-tool.h"
|
||||||
#include "clutter-input-pointer-a11y-private.h"
|
#include "clutter-input-pointer-a11y-private.h"
|
||||||
#include "clutter-marshal.h"
|
#include "clutter-marshal.h"
|
||||||
|
#include "clutter-mutter.h"
|
||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-seat.h"
|
#include "clutter-seat.h"
|
||||||
#include "clutter-virtual-input-device.h"
|
#include "clutter-virtual-input-device.h"
|
||||||
@ -65,9 +66,6 @@ struct _ClutterSeatPrivate
|
|||||||
|
|
||||||
unsigned int inhibit_unfocus_count;
|
unsigned int inhibit_unfocus_count;
|
||||||
|
|
||||||
/* Keyboard a11y */
|
|
||||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
|
||||||
|
|
||||||
/* Pointer a11y */
|
/* Pointer a11y */
|
||||||
ClutterPointerA11ySettings pointer_a11y_settings;
|
ClutterPointerA11ySettings pointer_a11y_settings;
|
||||||
};
|
};
|
||||||
@ -404,43 +402,6 @@ clutter_seat_get_keymap (ClutterSeat *seat)
|
|||||||
return CLUTTER_SEAT_GET_CLASS (seat)->get_keymap (seat);
|
return CLUTTER_SEAT_GET_CLASS (seat)->get_keymap (seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
|
|
||||||
ClutterKbdA11ySettings *b)
|
|
||||||
{
|
|
||||||
return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat,
|
|
||||||
ClutterKbdA11ySettings *settings)
|
|
||||||
{
|
|
||||||
ClutterSeatClass *seat_class;
|
|
||||||
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_SEAT (seat));
|
|
||||||
|
|
||||||
if (are_kbd_a11y_settings_equal (&priv->kbd_a11y_settings, settings))
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv->kbd_a11y_settings = *settings;
|
|
||||||
|
|
||||||
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
|
|
||||||
if (seat_class->apply_kbd_a11y_settings)
|
|
||||||
seat_class->apply_kbd_a11y_settings (seat, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat,
|
|
||||||
ClutterKbdA11ySettings *settings)
|
|
||||||
{
|
|
||||||
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_SEAT (seat));
|
|
||||||
|
|
||||||
*settings = priv->kbd_a11y_settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
clutter_seat_ensure_a11y_state (ClutterSeat *seat)
|
clutter_seat_ensure_a11y_state (ClutterSeat *seat)
|
||||||
{
|
{
|
||||||
@ -674,6 +635,40 @@ clutter_seat_compress_motion (ClutterSeat *seat,
|
|||||||
seat_class->compress_motion (seat, event, to_discard);
|
seat_class->compress_motion (seat, event, to_discard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
clutter_seat_handle_event_post (ClutterSeat *seat,
|
||||||
|
const ClutterEvent *event)
|
||||||
|
{
|
||||||
|
ClutterSeatClass *seat_class;
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE);
|
||||||
|
g_return_val_if_fail (event, FALSE);
|
||||||
|
|
||||||
|
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
|
||||||
|
|
||||||
|
if (seat_class->handle_event_post)
|
||||||
|
seat_class->handle_event_post (seat, event);
|
||||||
|
|
||||||
|
device = clutter_event_get_source_device (event);
|
||||||
|
g_assert_true (CLUTTER_IS_INPUT_DEVICE (device));
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
g_signal_emit (seat, signals[DEVICE_ADDED], 0, device);
|
||||||
|
break;
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
g_signal_emit (seat, signals[DEVICE_REMOVED], 0, device);
|
||||||
|
g_object_run_dispose (G_OBJECT (device));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clutter_seat_warp_pointer (ClutterSeat *seat,
|
clutter_seat_warp_pointer (ClutterSeat *seat,
|
||||||
int x,
|
int x,
|
||||||
@ -709,3 +704,20 @@ clutter_seat_get_touch_mode (ClutterSeat *seat)
|
|||||||
|
|
||||||
return touch_mode;
|
return touch_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
clutter_seat_query_state (ClutterSeat *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
graphene_point_t *coords,
|
||||||
|
ClutterModifierType *modifiers)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||||
|
|
||||||
|
return CLUTTER_SEAT_GET_CLASS (seat)->query_state (seat,
|
||||||
|
device,
|
||||||
|
sequence,
|
||||||
|
coords,
|
||||||
|
modifiers);
|
||||||
|
}
|
||||||
|
@ -37,24 +37,6 @@ CLUTTER_EXPORT
|
|||||||
G_DECLARE_DERIVABLE_TYPE (ClutterSeat, clutter_seat,
|
G_DECLARE_DERIVABLE_TYPE (ClutterSeat, clutter_seat,
|
||||||
CLUTTER, SEAT, GObject)
|
CLUTTER, SEAT, GObject)
|
||||||
|
|
||||||
/**
|
|
||||||
* ClutterKbdA11ySettings:
|
|
||||||
*
|
|
||||||
* The #ClutterKbdA11ySettings structure contains keyboard accessibility
|
|
||||||
* settings
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef struct _ClutterKbdA11ySettings
|
|
||||||
{
|
|
||||||
ClutterKeyboardA11yFlags controls;
|
|
||||||
gint slowkeys_delay;
|
|
||||||
gint debounce_delay;
|
|
||||||
gint timeout_delay;
|
|
||||||
gint mousekeys_init_delay;
|
|
||||||
gint mousekeys_max_speed;
|
|
||||||
gint mousekeys_accel_time;
|
|
||||||
} ClutterKbdA11ySettings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterPointerA11ySettings:
|
* ClutterPointerA11ySettings:
|
||||||
*
|
*
|
||||||
@ -106,10 +88,19 @@ struct _ClutterSeatClass
|
|||||||
ClutterEvent *event,
|
ClutterEvent *event,
|
||||||
const ClutterEvent *to_discard);
|
const ClutterEvent *to_discard);
|
||||||
|
|
||||||
|
gboolean (* handle_event_post) (ClutterSeat *seat,
|
||||||
|
const ClutterEvent *event);
|
||||||
|
|
||||||
void (* warp_pointer) (ClutterSeat *seat,
|
void (* warp_pointer) (ClutterSeat *seat,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
|
|
||||||
|
gboolean (* query_state) (ClutterSeat *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
graphene_point_t *coords,
|
||||||
|
ClutterModifierType *modifiers);
|
||||||
|
|
||||||
/* Event platform data */
|
/* Event platform data */
|
||||||
void (* copy_event_data) (ClutterSeat *seat,
|
void (* copy_event_data) (ClutterSeat *seat,
|
||||||
const ClutterEvent *src,
|
const ClutterEvent *src,
|
||||||
@ -117,10 +108,6 @@ struct _ClutterSeatClass
|
|||||||
void (* free_event_data) (ClutterSeat *seat,
|
void (* free_event_data) (ClutterSeat *seat,
|
||||||
ClutterEvent *event);
|
ClutterEvent *event);
|
||||||
|
|
||||||
/* Keyboard accessibility */
|
|
||||||
void (* apply_kbd_a11y_settings) (ClutterSeat *seat,
|
|
||||||
ClutterKbdA11ySettings *settings);
|
|
||||||
|
|
||||||
/* Virtual devices */
|
/* Virtual devices */
|
||||||
ClutterVirtualInputDevice * (* create_virtual_device) (ClutterSeat *seat,
|
ClutterVirtualInputDevice * (* create_virtual_device) (ClutterSeat *seat,
|
||||||
ClutterInputDeviceType device_type);
|
ClutterInputDeviceType device_type);
|
||||||
@ -140,12 +127,6 @@ void clutter_seat_bell_notify (ClutterSeat *seat);
|
|||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
ClutterKeymap * clutter_seat_get_keymap (ClutterSeat *seat);
|
ClutterKeymap * clutter_seat_get_keymap (ClutterSeat *seat);
|
||||||
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat,
|
|
||||||
ClutterKbdA11ySettings *settings);
|
|
||||||
CLUTTER_EXPORT
|
|
||||||
void clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat,
|
|
||||||
ClutterKbdA11ySettings *settings);
|
|
||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
void clutter_seat_ensure_a11y_state (ClutterSeat *seat);
|
void clutter_seat_ensure_a11y_state (ClutterSeat *seat);
|
||||||
|
|
||||||
@ -188,4 +169,11 @@ void clutter_seat_warp_pointer (ClutterSeat *seat,
|
|||||||
CLUTTER_EXPORT
|
CLUTTER_EXPORT
|
||||||
gboolean clutter_seat_get_touch_mode (ClutterSeat *seat);
|
gboolean clutter_seat_get_touch_mode (ClutterSeat *seat);
|
||||||
|
|
||||||
|
CLUTTER_EXPORT
|
||||||
|
gboolean clutter_seat_query_state (ClutterSeat *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
graphene_point_t *coords,
|
||||||
|
ClutterModifierType *modifiers);
|
||||||
|
|
||||||
#endif /* CLUTTER_SEAT_H */
|
#endif /* CLUTTER_SEAT_H */
|
||||||
|
@ -1013,7 +1013,6 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
|||||||
{
|
{
|
||||||
ClutterStagePrivate *priv;
|
ClutterStagePrivate *priv;
|
||||||
gboolean first_event;
|
gboolean first_event;
|
||||||
ClutterInputDevice *device;
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
|
|
||||||
@ -1024,25 +1023,6 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
|||||||
if (copy_event)
|
if (copy_event)
|
||||||
event = clutter_event_copy (event);
|
event = clutter_event_copy (event);
|
||||||
|
|
||||||
/* if needed, update the state of the input device of the event.
|
|
||||||
* we do it here to avoid calling the same code from every backend
|
|
||||||
* event processing function
|
|
||||||
*/
|
|
||||||
device = clutter_event_get_device (event);
|
|
||||||
if (device != NULL &&
|
|
||||||
event->type != CLUTTER_PROXIMITY_IN &&
|
|
||||||
event->type != CLUTTER_PROXIMITY_OUT)
|
|
||||||
{
|
|
||||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
|
||||||
guint32 event_time = clutter_event_get_time (event);
|
|
||||||
gfloat event_x, event_y;
|
|
||||||
|
|
||||||
clutter_event_get_coords (event, &event_x, &event_y);
|
|
||||||
|
|
||||||
_clutter_input_device_set_coords (device, sequence, event_x, event_y, stage);
|
|
||||||
_clutter_input_device_set_time (device, event_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first_event)
|
if (first_event)
|
||||||
{
|
{
|
||||||
gboolean compressible = event->type == CLUTTER_MOTION ||
|
gboolean compressible = event->type == CLUTTER_MOTION ||
|
||||||
@ -1363,7 +1343,7 @@ clutter_stage_update_devices (ClutterStage *stage,
|
|||||||
for (l = devices; l; l = l->next)
|
for (l = devices; l; l = l->next)
|
||||||
{
|
{
|
||||||
ClutterInputDevice *device = l->data;
|
ClutterInputDevice *device = l->data;
|
||||||
clutter_input_device_update (device, NULL, TRUE);
|
clutter_input_device_update (device, NULL, stage, TRUE, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1680,7 +1660,7 @@ clutter_stage_dispose (GObject *object)
|
|||||||
|
|
||||||
clutter_actor_hide (CLUTTER_ACTOR (object));
|
clutter_actor_hide (CLUTTER_ACTOR (object));
|
||||||
|
|
||||||
_clutter_clear_events_queue_for_stage (stage);
|
_clutter_clear_events_queue ();
|
||||||
|
|
||||||
if (priv->impl != NULL)
|
if (priv->impl != NULL)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "backends/meta-backend-types.h"
|
#include "backends/meta-backend-types.h"
|
||||||
#include "backends/meta-cursor-renderer.h"
|
#include "backends/meta-cursor-renderer.h"
|
||||||
#include "backends/meta-egl.h"
|
#include "backends/meta-egl.h"
|
||||||
|
#include "backends/meta-input-mapper-private.h"
|
||||||
#include "backends/meta-input-settings-private.h"
|
#include "backends/meta-input-settings-private.h"
|
||||||
#include "backends/meta-monitor-manager-private.h"
|
#include "backends/meta-monitor-manager-private.h"
|
||||||
#include "backends/meta-orientation-manager.h"
|
#include "backends/meta-orientation-manager.h"
|
||||||
@ -67,7 +68,8 @@ struct _MetaBackendClass
|
|||||||
|
|
||||||
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
|
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
|
||||||
GError **error);
|
GError **error);
|
||||||
MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
|
MetaCursorRenderer * (* get_cursor_renderer) (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device);
|
||||||
MetaCursorTracker * (* create_cursor_tracker) (MetaBackend *backend);
|
MetaCursorTracker * (* create_cursor_tracker) (MetaBackend *backend);
|
||||||
MetaRenderer * (* create_renderer) (MetaBackend *backend,
|
MetaRenderer * (* create_renderer) (MetaBackend *backend,
|
||||||
GError **error);
|
GError **error);
|
||||||
@ -105,6 +107,8 @@ struct _MetaBackendClass
|
|||||||
void (* set_numlock) (MetaBackend *backend,
|
void (* set_numlock) (MetaBackend *backend,
|
||||||
gboolean numlock_state);
|
gboolean numlock_state);
|
||||||
|
|
||||||
|
void (* set_pointer_constraint) (MetaBackend *backend,
|
||||||
|
MetaPointerConstraint *constraint);
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_init_backend (GType backend_gtype);
|
void meta_init_backend (GType backend_gtype);
|
||||||
@ -129,6 +133,8 @@ META_EXPORT_TEST
|
|||||||
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
|
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
|
||||||
MetaOrientationManager * meta_backend_get_orientation_manager (MetaBackend *backend);
|
MetaOrientationManager * meta_backend_get_orientation_manager (MetaBackend *backend);
|
||||||
MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend);
|
MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend);
|
||||||
|
MetaCursorRenderer * meta_backend_get_cursor_renderer_for_device (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device);
|
||||||
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
|
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
MetaRenderer * meta_backend_get_renderer (MetaBackend *backend);
|
MetaRenderer * meta_backend_get_renderer (MetaBackend *backend);
|
||||||
@ -171,6 +177,7 @@ gboolean meta_is_stage_views_enabled (void);
|
|||||||
|
|
||||||
gboolean meta_is_stage_views_scaled (void);
|
gboolean meta_is_stage_views_scaled (void);
|
||||||
|
|
||||||
|
MetaInputMapper *meta_backend_get_input_mapper (MetaBackend *backend);
|
||||||
MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend);
|
MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend);
|
||||||
|
|
||||||
void meta_backend_notify_keymap_changed (MetaBackend *backend);
|
void meta_backend_notify_keymap_changed (MetaBackend *backend);
|
||||||
@ -191,4 +198,12 @@ GList * meta_backend_get_gpus (MetaBackend *backend);
|
|||||||
WacomDeviceDatabase * meta_backend_get_wacom_database (MetaBackend *backend);
|
WacomDeviceDatabase * meta_backend_get_wacom_database (MetaBackend *backend);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void meta_backend_add_hw_cursor_inhibitor (MetaBackend *backend,
|
||||||
|
MetaHwCursorInhibitor *inhibitor);
|
||||||
|
|
||||||
|
void meta_backend_remove_hw_cursor_inhibitor (MetaBackend *backend,
|
||||||
|
MetaHwCursorInhibitor *inhibitor);
|
||||||
|
|
||||||
|
gboolean meta_backend_is_hw_cursors_inhibited (MetaBackend *backend);
|
||||||
|
|
||||||
#endif /* META_BACKEND_PRIVATE_H */
|
#endif /* META_BACKEND_PRIVATE_H */
|
||||||
|
@ -53,8 +53,10 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "backends/meta-cursor-renderer.h"
|
||||||
#include "backends/meta-cursor-tracker-private.h"
|
#include "backends/meta-cursor-tracker-private.h"
|
||||||
#include "backends/meta-idle-monitor-private.h"
|
#include "backends/meta-idle-monitor-private.h"
|
||||||
|
#include "backends/meta-input-mapper-private.h"
|
||||||
#include "backends/meta-input-settings-private.h"
|
#include "backends/meta-input-settings-private.h"
|
||||||
#include "backends/meta-logical-monitor.h"
|
#include "backends/meta-logical-monitor.h"
|
||||||
#include "backends/meta-monitor-manager-dummy.h"
|
#include "backends/meta-monitor-manager-dummy.h"
|
||||||
@ -120,8 +122,9 @@ struct _MetaBackendPrivate
|
|||||||
MetaMonitorManager *monitor_manager;
|
MetaMonitorManager *monitor_manager;
|
||||||
MetaOrientationManager *orientation_manager;
|
MetaOrientationManager *orientation_manager;
|
||||||
MetaCursorTracker *cursor_tracker;
|
MetaCursorTracker *cursor_tracker;
|
||||||
MetaCursorRenderer *cursor_renderer;
|
GHashTable *cursor_renderers;
|
||||||
MetaInputSettings *input_settings;
|
MetaInputSettings *input_settings;
|
||||||
|
MetaInputMapper *input_mapper;
|
||||||
MetaRenderer *renderer;
|
MetaRenderer *renderer;
|
||||||
#ifdef HAVE_EGL
|
#ifdef HAVE_EGL
|
||||||
MetaEgl *egl;
|
MetaEgl *egl;
|
||||||
@ -150,6 +153,7 @@ struct _MetaBackendPrivate
|
|||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
|
|
||||||
GList *gpus;
|
GList *gpus;
|
||||||
|
GList *hw_cursor_inhibitors;
|
||||||
|
|
||||||
gboolean is_pointer_position_initialized;
|
gboolean is_pointer_position_initialized;
|
||||||
|
|
||||||
@ -173,6 +177,14 @@ struct _MetaBackendPrivate
|
|||||||
};
|
};
|
||||||
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
||||||
|
|
||||||
|
typedef struct _MetaBackendSource MetaBackendSource;
|
||||||
|
|
||||||
|
struct _MetaBackendSource
|
||||||
|
{
|
||||||
|
GSource parent;
|
||||||
|
MetaBackend *backend;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initable_iface_init (GInitableIface *initable_iface);
|
initable_iface_init (GInitableIface *initable_iface);
|
||||||
|
|
||||||
@ -213,6 +225,8 @@ meta_backend_finalize (GObject *object)
|
|||||||
g_clear_pointer (&priv->wacom_db, libwacom_database_destroy);
|
g_clear_pointer (&priv->wacom_db, libwacom_database_destroy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
g_hash_table_unref (priv->cursor_renderers);
|
||||||
|
|
||||||
if (priv->sleep_signal_id)
|
if (priv->sleep_signal_id)
|
||||||
g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
|
g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
|
||||||
if (priv->upower_watch_id)
|
if (priv->upower_watch_id)
|
||||||
@ -264,6 +278,19 @@ reset_pointer_position (MetaBackend *backend)
|
|||||||
primary->rect.y + primary->rect.height * 0.9);
|
primary->rect.y + primary->rect.height * 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_cursors (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
MetaCursorRenderer *renderer;
|
||||||
|
GHashTableIter iter;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, priv->cursor_renderers);
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &renderer))
|
||||||
|
meta_cursor_renderer_force_update (renderer);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_backend_monitors_changed (MetaBackend *backend)
|
meta_backend_monitors_changed (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
@ -289,7 +316,7 @@ meta_backend_monitors_changed (MetaBackend *backend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_cursor_renderer_force_update (priv->cursor_renderer);
|
update_cursors (backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -355,8 +382,19 @@ on_device_added (ClutterSeat *seat,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = META_BACKEND (user_data);
|
MetaBackend *backend = META_BACKEND (user_data);
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
ClutterInputDeviceType device_type;
|
||||||
|
|
||||||
create_device_monitor (backend, device);
|
create_device_monitor (backend, device);
|
||||||
|
device_type = clutter_input_device_get_device_type (device);
|
||||||
|
|
||||||
|
if (device_type == CLUTTER_TOUCHSCREEN_DEVICE ||
|
||||||
|
device_type == CLUTTER_TABLET_DEVICE ||
|
||||||
|
device_type == CLUTTER_PEN_DEVICE ||
|
||||||
|
device_type == CLUTTER_ERASER_DEVICE ||
|
||||||
|
device_type == CLUTTER_CURSOR_DEVICE ||
|
||||||
|
device_type == CLUTTER_PAD_DEVICE)
|
||||||
|
meta_input_mapper_add_device (priv->input_mapper, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
@ -428,6 +466,8 @@ on_device_removed (ClutterSeat *seat,
|
|||||||
|
|
||||||
destroy_device_monitor (backend, device);
|
destroy_device_monitor (backend, device);
|
||||||
|
|
||||||
|
meta_input_mapper_remove_device (priv->input_mapper, device);
|
||||||
|
|
||||||
/* If the device the user last interacted goes away, check again pointer
|
/* If the device the user last interacted goes away, check again pointer
|
||||||
* visibility.
|
* visibility.
|
||||||
*/
|
*/
|
||||||
@ -438,6 +478,7 @@ on_device_removed (ClutterSeat *seat,
|
|||||||
ClutterInputDeviceType device_type;
|
ClutterInputDeviceType device_type;
|
||||||
|
|
||||||
priv->current_device = NULL;
|
priv->current_device = NULL;
|
||||||
|
g_clear_handle_id (&priv->device_update_idle_id, g_source_remove);
|
||||||
|
|
||||||
device_type = clutter_input_device_get_device_type (device);
|
device_type = clutter_input_device_get_device_type (device);
|
||||||
has_touchscreen = check_has_slave_touchscreen (seat);
|
has_touchscreen = check_has_slave_touchscreen (seat);
|
||||||
@ -504,6 +545,42 @@ meta_backend_create_input_settings (MetaBackend *backend)
|
|||||||
return META_BACKEND_GET_CLASS (backend)->create_input_settings (backend);
|
return META_BACKEND_GET_CLASS (backend)->create_input_settings (backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_mapper_device_mapped_cb (MetaInputMapper *mapper,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
float matrix[6],
|
||||||
|
MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
MetaInputSettings *input_settings = priv->input_settings;
|
||||||
|
|
||||||
|
meta_input_settings_set_device_matrix (input_settings, device, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_mapper_device_enabled_cb (MetaInputMapper *mapper,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
gboolean enabled,
|
||||||
|
MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
MetaInputSettings *input_settings = priv->input_settings;
|
||||||
|
|
||||||
|
meta_input_settings_set_device_enabled (input_settings, device, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_mapper_device_aspect_ratio_cb (MetaInputMapper *mapper,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
double aspect_ratio,
|
||||||
|
MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
MetaInputSettings *input_settings = priv->input_settings;
|
||||||
|
|
||||||
|
meta_input_settings_set_device_aspect_ratio (input_settings, device, aspect_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_backend_real_post_init (MetaBackend *backend)
|
meta_backend_real_post_init (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
@ -519,8 +596,6 @@ meta_backend_real_post_init (MetaBackend *backend)
|
|||||||
|
|
||||||
meta_backend_sync_screen_size (backend);
|
meta_backend_sync_screen_size (backend);
|
||||||
|
|
||||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
|
||||||
|
|
||||||
priv->device_monitors =
|
priv->device_monitors =
|
||||||
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
|
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
|
||||||
|
|
||||||
@ -529,7 +604,8 @@ meta_backend_real_post_init (MetaBackend *backend)
|
|||||||
g_signal_connect_object (seat, "device-added",
|
g_signal_connect_object (seat, "device-added",
|
||||||
G_CALLBACK (on_device_added), backend, 0);
|
G_CALLBACK (on_device_added), backend, 0);
|
||||||
g_signal_connect_object (seat, "device-removed",
|
g_signal_connect_object (seat, "device-removed",
|
||||||
G_CALLBACK (on_device_removed), backend, 0);
|
G_CALLBACK (on_device_removed), backend,
|
||||||
|
G_CONNECT_AFTER);
|
||||||
|
|
||||||
set_initial_pointer_visibility (backend, seat);
|
set_initial_pointer_visibility (backend, seat);
|
||||||
|
|
||||||
@ -544,6 +620,14 @@ meta_backend_real_post_init (MetaBackend *backend)
|
|||||||
meta_input_settings_maybe_restore_numlock_state (priv->input_settings);
|
meta_input_settings_maybe_restore_numlock_state (priv->input_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->input_mapper = meta_input_mapper_new ();
|
||||||
|
g_signal_connect (priv->input_mapper, "device-mapped",
|
||||||
|
G_CALLBACK (input_mapper_device_mapped_cb), backend);
|
||||||
|
g_signal_connect (priv->input_mapper, "device-enabled",
|
||||||
|
G_CALLBACK (input_mapper_device_enabled_cb), backend);
|
||||||
|
g_signal_connect (priv->input_mapper, "device-aspect-ratio",
|
||||||
|
G_CALLBACK (input_mapper_device_aspect_ratio_cb), backend);
|
||||||
|
|
||||||
#ifdef HAVE_REMOTE_DESKTOP
|
#ifdef HAVE_REMOTE_DESKTOP
|
||||||
priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
|
priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
|
||||||
priv->screen_cast = meta_screen_cast_new (backend,
|
priv->screen_cast = meta_screen_cast_new (backend,
|
||||||
@ -916,10 +1000,18 @@ clutter_source_dispatch (GSource *source,
|
|||||||
GSourceFunc callback,
|
GSourceFunc callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
MetaBackendSource *backend_source = (MetaBackendSource *) source;
|
||||||
|
MetaBackendPrivate *priv =
|
||||||
|
meta_backend_get_instance_private (backend_source->backend);
|
||||||
ClutterEvent *event = clutter_event_get ();
|
ClutterEvent *event = clutter_event_get ();
|
||||||
|
ClutterSeat *seat;
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
{
|
{
|
||||||
|
event->any.stage =
|
||||||
|
CLUTTER_STAGE (meta_backend_get_stage (backend_source->backend));
|
||||||
|
seat = clutter_backend_get_default_seat (priv->clutter_backend);
|
||||||
|
clutter_seat_handle_event_post (seat, event);
|
||||||
clutter_do_event (event);
|
clutter_do_event (event);
|
||||||
clutter_event_free (event);
|
clutter_event_free (event);
|
||||||
}
|
}
|
||||||
@ -945,6 +1037,7 @@ static gboolean
|
|||||||
init_clutter (MetaBackend *backend,
|
init_clutter (MetaBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaBackendSource *backend_source;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
clutter_set_custom_backend_func (meta_get_clutter_backend);
|
clutter_set_custom_backend_func (meta_get_clutter_backend);
|
||||||
@ -956,7 +1049,9 @@ init_clutter (MetaBackend *backend,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
source = g_source_new (&clutter_source_funcs, sizeof (GSource));
|
source = g_source_new (&clutter_source_funcs, sizeof (MetaBackendSource));
|
||||||
|
backend_source = (MetaBackendSource *) source;
|
||||||
|
backend_source->backend = backend;
|
||||||
g_source_attach (source, NULL);
|
g_source_attach (source, NULL);
|
||||||
g_source_unref (source);
|
g_source_unref (source);
|
||||||
|
|
||||||
@ -1081,8 +1176,25 @@ MetaCursorRenderer *
|
|||||||
meta_backend_get_cursor_renderer (MetaBackend *backend)
|
meta_backend_get_cursor_renderer (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
ClutterInputDevice *pointer;
|
||||||
|
ClutterSeat *seat;
|
||||||
|
|
||||||
return priv->cursor_renderer;
|
seat = clutter_backend_get_default_seat (priv->clutter_backend);
|
||||||
|
pointer = clutter_seat_get_pointer (seat);
|
||||||
|
|
||||||
|
return meta_backend_get_cursor_renderer_for_device (backend, pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaCursorRenderer *
|
||||||
|
meta_backend_get_cursor_renderer_for_device (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (META_IS_BACKEND (backend), NULL);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||||
|
g_return_val_if_fail (clutter_input_device_get_device_type (device) !=
|
||||||
|
CLUTTER_KEYBOARD_DEVICE, NULL);
|
||||||
|
|
||||||
|
return META_BACKEND_GET_CLASS (backend)->get_cursor_renderer (backend, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1329,7 +1441,7 @@ meta_backend_get_client_pointer_constraint (MetaBackend *backend)
|
|||||||
* @constraint: (nullable): the client constraint to follow.
|
* @constraint: (nullable): the client constraint to follow.
|
||||||
*
|
*
|
||||||
* Sets the current pointer constraint and removes (and unrefs) the previous
|
* Sets the current pointer constraint and removes (and unrefs) the previous
|
||||||
* one. If @constrant is %NULL, this means that there is no
|
* one. If @constraint is %NULL, this means that there is no
|
||||||
* #MetaPointerConstraint active.
|
* #MetaPointerConstraint active.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -1338,11 +1450,8 @@ meta_backend_set_client_pointer_constraint (MetaBackend *backend,
|
|||||||
{
|
{
|
||||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
|
||||||
g_assert (!constraint || !priv->client_pointer_constraint);
|
META_BACKEND_GET_CLASS (backend)->set_pointer_constraint (backend, constraint);
|
||||||
|
g_set_object (&priv->client_pointer_constraint, constraint);
|
||||||
g_clear_object (&priv->client_pointer_constraint);
|
|
||||||
if (constraint)
|
|
||||||
priv->client_pointer_constraint = g_object_ref (constraint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterBackend *
|
ClutterBackend *
|
||||||
@ -1408,6 +1517,14 @@ meta_is_stage_views_scaled (void)
|
|||||||
return layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
|
return layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaInputMapper *
|
||||||
|
meta_backend_get_input_mapper (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
|
||||||
|
return priv->input_mapper;
|
||||||
|
}
|
||||||
|
|
||||||
MetaInputSettings *
|
MetaInputSettings *
|
||||||
meta_backend_get_input_settings (MetaBackend *backend)
|
meta_backend_get_input_settings (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
@ -1474,3 +1591,40 @@ meta_backend_get_wacom_database (MetaBackend *backend)
|
|||||||
return priv->wacom_db;
|
return priv->wacom_db;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_backend_add_hw_cursor_inhibitor (MetaBackend *backend,
|
||||||
|
MetaHwCursorInhibitor *inhibitor)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
|
||||||
|
priv->hw_cursor_inhibitors = g_list_prepend (priv->hw_cursor_inhibitors,
|
||||||
|
inhibitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_backend_remove_hw_cursor_inhibitor (MetaBackend *backend,
|
||||||
|
MetaHwCursorInhibitor *inhibitor)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
|
||||||
|
priv->hw_cursor_inhibitors = g_list_remove (priv->hw_cursor_inhibitors,
|
||||||
|
inhibitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_backend_is_hw_cursors_inhibited (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = priv->hw_cursor_inhibitors; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaHwCursorInhibitor *inhibitor = l->data;
|
||||||
|
|
||||||
|
if (meta_hw_cursor_inhibitor_is_cursor_inhibited (inhibitor))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "backends/meta-backend-private.h"
|
||||||
|
#include "backends/meta-logical-monitor.h"
|
||||||
#include "backends/meta-stage-private.h"
|
#include "backends/meta-stage-private.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "clutter/clutter-mutter.h"
|
#include "clutter/clutter-mutter.h"
|
||||||
@ -44,6 +46,7 @@ enum
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_BACKEND,
|
PROP_BACKEND,
|
||||||
|
PROP_DEVICE,
|
||||||
|
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
@ -57,6 +60,7 @@ struct _MetaCursorRendererPrivate
|
|||||||
float current_x;
|
float current_x;
|
||||||
float current_y;
|
float current_y;
|
||||||
|
|
||||||
|
ClutterInputDevice *device;
|
||||||
MetaCursorSprite *displayed_cursor;
|
MetaCursorSprite *displayed_cursor;
|
||||||
MetaCursorSprite *overlay_cursor;
|
MetaCursorSprite *overlay_cursor;
|
||||||
|
|
||||||
@ -77,14 +81,13 @@ static guint signals[LAST_SIGNAL];
|
|||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static gboolean
|
gboolean
|
||||||
meta_hw_cursor_inhibitor_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor,
|
meta_hw_cursor_inhibitor_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor)
|
||||||
MetaCursorSprite *cursor_sprite)
|
|
||||||
{
|
{
|
||||||
MetaHwCursorInhibitorInterface *iface =
|
MetaHwCursorInhibitorInterface *iface =
|
||||||
META_HW_CURSOR_INHIBITOR_GET_IFACE (inhibitor);
|
META_HW_CURSOR_INHIBITOR_GET_IFACE (inhibitor);
|
||||||
|
|
||||||
return iface->is_cursor_sprite_inhibited (inhibitor, cursor_sprite);
|
return iface->is_cursor_inhibited (inhibitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -203,6 +206,9 @@ meta_cursor_renderer_get_property (GObject *object,
|
|||||||
case PROP_BACKEND:
|
case PROP_BACKEND:
|
||||||
g_value_set_object (value, priv->backend);
|
g_value_set_object (value, priv->backend);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DEVICE:
|
||||||
|
g_value_set_object (value, priv->device);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -224,6 +230,9 @@ meta_cursor_renderer_set_property (GObject *object,
|
|||||||
case PROP_BACKEND:
|
case PROP_BACKEND:
|
||||||
priv->backend = g_value_get_object (value);
|
priv->backend = g_value_get_object (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DEVICE:
|
||||||
|
priv->device = g_value_get_object (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -284,6 +293,14 @@ meta_cursor_renderer_class_init (MetaCursorRendererClass *klass)
|
|||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
obj_props[PROP_DEVICE] =
|
||||||
|
g_param_spec_object ("device",
|
||||||
|
"device",
|
||||||
|
"Input device",
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||||
|
|
||||||
signals[CURSOR_PAINTED] = g_signal_new ("cursor-painted",
|
signals[CURSOR_PAINTED] = g_signal_new ("cursor-painted",
|
||||||
@ -332,6 +349,41 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
find_highest_logical_monitor_scale (MetaBackend *backend,
|
||||||
|
MetaCursorSprite *cursor_sprite)
|
||||||
|
{
|
||||||
|
MetaMonitorManager *monitor_manager =
|
||||||
|
meta_backend_get_monitor_manager (backend);
|
||||||
|
MetaCursorRenderer *cursor_renderer =
|
||||||
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
graphene_rect_t cursor_rect;
|
||||||
|
GList *logical_monitors;
|
||||||
|
GList *l;
|
||||||
|
float highest_scale = 0.0;
|
||||||
|
|
||||||
|
cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
|
||||||
|
cursor_sprite);
|
||||||
|
|
||||||
|
logical_monitors =
|
||||||
|
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
||||||
|
for (l = logical_monitors; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaLogicalMonitor *logical_monitor = l->data;
|
||||||
|
graphene_rect_t logical_monitor_rect =
|
||||||
|
meta_rectangle_to_graphene_rect (&logical_monitor->rect);
|
||||||
|
|
||||||
|
if (!graphene_rect_intersection (&cursor_rect,
|
||||||
|
&logical_monitor_rect,
|
||||||
|
NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
highest_scale = MAX (highest_scale, logical_monitor->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return highest_scale;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
|
meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
|
||||||
MetaCursorSprite *cursor_sprite)
|
MetaCursorSprite *cursor_sprite)
|
||||||
@ -340,9 +392,14 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
|
|||||||
gboolean handled_by_backend;
|
gboolean handled_by_backend;
|
||||||
|
|
||||||
if (cursor_sprite)
|
if (cursor_sprite)
|
||||||
meta_cursor_sprite_prepare_at (cursor_sprite,
|
{
|
||||||
(int) priv->current_x,
|
float scale = find_highest_logical_monitor_scale (priv->backend,
|
||||||
(int) priv->current_y);
|
cursor_sprite);
|
||||||
|
meta_cursor_sprite_prepare_at (cursor_sprite,
|
||||||
|
MAX (1, scale),
|
||||||
|
(int) priv->current_x,
|
||||||
|
(int) priv->current_y);
|
||||||
|
}
|
||||||
|
|
||||||
handled_by_backend =
|
handled_by_backend =
|
||||||
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
|
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
|
||||||
@ -354,10 +411,12 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MetaCursorRenderer *
|
MetaCursorRenderer *
|
||||||
meta_cursor_renderer_new (MetaBackend *backend)
|
meta_cursor_renderer_new (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_CURSOR_RENDERER,
|
return g_object_new (META_TYPE_CURSOR_RENDERER,
|
||||||
"backend", backend,
|
"backend", backend,
|
||||||
|
"device", device,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,30 +443,18 @@ meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
meta_cursor_renderer_update_position (MetaCursorRenderer *renderer)
|
||||||
float x,
|
|
||||||
float y)
|
|
||||||
{
|
{
|
||||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||||
|
graphene_point_t pos;
|
||||||
|
|
||||||
priv->current_x = x;
|
clutter_input_device_get_coords (priv->device, NULL, &pos);
|
||||||
priv->current_y = y;
|
priv->current_x = pos.x;
|
||||||
|
priv->current_y = pos.y;
|
||||||
|
|
||||||
meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor);
|
meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
graphene_point_t
|
|
||||||
meta_cursor_renderer_get_position (MetaCursorRenderer *renderer)
|
|
||||||
{
|
|
||||||
MetaCursorRendererPrivate *priv =
|
|
||||||
meta_cursor_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
return (graphene_point_t) {
|
|
||||||
.x = priv->current_x,
|
|
||||||
.y = priv->current_y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaCursorSprite *
|
MetaCursorSprite *
|
||||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
||||||
{
|
{
|
||||||
@ -428,44 +475,11 @@ meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer)
|
|||||||
return meta_overlay_is_visible (priv->stage_overlay);
|
return meta_overlay_is_visible (priv->stage_overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
ClutterInputDevice *
|
||||||
meta_cursor_renderer_add_hw_cursor_inhibitor (MetaCursorRenderer *renderer,
|
meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer)
|
||||||
MetaHwCursorInhibitor *inhibitor)
|
|
||||||
{
|
{
|
||||||
MetaCursorRendererPrivate *priv =
|
MetaCursorRendererPrivate *priv =
|
||||||
meta_cursor_renderer_get_instance_private (renderer);
|
meta_cursor_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
priv->hw_cursor_inhibitors = g_list_prepend (priv->hw_cursor_inhibitors,
|
return priv->device;
|
||||||
inhibitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer,
|
|
||||||
MetaHwCursorInhibitor *inhibitor)
|
|
||||||
{
|
|
||||||
MetaCursorRendererPrivate *priv =
|
|
||||||
meta_cursor_renderer_get_instance_private (renderer);
|
|
||||||
|
|
||||||
priv->hw_cursor_inhibitors = g_list_remove (priv->hw_cursor_inhibitors,
|
|
||||||
inhibitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer,
|
|
||||||
MetaCursorSprite *cursor_sprite)
|
|
||||||
{
|
|
||||||
MetaCursorRendererPrivate *priv =
|
|
||||||
meta_cursor_renderer_get_instance_private (renderer);
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
for (l = priv->hw_cursor_inhibitors; l; l = l->next)
|
|
||||||
{
|
|
||||||
MetaHwCursorInhibitor *inhibitor = l->data;
|
|
||||||
|
|
||||||
if (meta_hw_cursor_inhibitor_is_cursor_sprite_inhibited (inhibitor,
|
|
||||||
cursor_sprite))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
@ -38,10 +38,11 @@ struct _MetaHwCursorInhibitorInterface
|
|||||||
{
|
{
|
||||||
GTypeInterface parent_iface;
|
GTypeInterface parent_iface;
|
||||||
|
|
||||||
gboolean (* is_cursor_sprite_inhibited) (MetaHwCursorInhibitor *inhibitor,
|
gboolean (* is_cursor_inhibited) (MetaHwCursorInhibitor *inhibitor);
|
||||||
MetaCursorSprite *cursor_sprite);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gboolean meta_hw_cursor_inhibitor_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor);
|
||||||
|
|
||||||
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
|
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
|
||||||
G_DECLARE_DERIVABLE_TYPE (MetaCursorRenderer, meta_cursor_renderer,
|
G_DECLARE_DERIVABLE_TYPE (MetaCursorRenderer, meta_cursor_renderer,
|
||||||
META, CURSOR_RENDERER, GObject);
|
META, CURSOR_RENDERER, GObject);
|
||||||
@ -54,35 +55,25 @@ struct _MetaCursorRendererClass
|
|||||||
MetaCursorSprite *cursor_sprite);
|
MetaCursorSprite *cursor_sprite);
|
||||||
};
|
};
|
||||||
|
|
||||||
MetaCursorRenderer * meta_cursor_renderer_new (MetaBackend *backend);
|
MetaCursorRenderer * meta_cursor_renderer_new (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||||
MetaCursorSprite *cursor_sprite);
|
MetaCursorSprite *cursor_sprite);
|
||||||
|
|
||||||
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
void meta_cursor_renderer_update_position (MetaCursorRenderer *renderer);
|
||||||
float x,
|
|
||||||
float y);
|
|
||||||
graphene_point_t meta_cursor_renderer_get_position (MetaCursorRenderer *renderer);
|
|
||||||
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
|
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
|
||||||
|
|
||||||
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
||||||
|
|
||||||
gboolean meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer);
|
gboolean meta_cursor_renderer_is_overlay_visible (MetaCursorRenderer *renderer);
|
||||||
|
|
||||||
void meta_cursor_renderer_add_hw_cursor_inhibitor (MetaCursorRenderer *renderer,
|
|
||||||
MetaHwCursorInhibitor *inhibitor);
|
|
||||||
|
|
||||||
void meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer,
|
|
||||||
MetaHwCursorInhibitor *inhibitor);
|
|
||||||
|
|
||||||
gboolean meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer,
|
|
||||||
MetaCursorSprite *cursor_sprite);
|
|
||||||
|
|
||||||
graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
||||||
MetaCursorSprite *cursor_sprite);
|
MetaCursorSprite *cursor_sprite);
|
||||||
|
|
||||||
void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
|
void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
|
||||||
MetaCursorSprite *cursor_sprite);
|
MetaCursorSprite *cursor_sprite);
|
||||||
|
ClutterInputDevice * meta_cursor_renderer_get_input_device (MetaCursorRenderer *renderer);
|
||||||
|
|
||||||
void meta_cursor_renderer_update_stage_overlay (MetaCursorRenderer *renderer,
|
void meta_cursor_renderer_update_stage_overlay (MetaCursorRenderer *renderer,
|
||||||
MetaCursorSprite *cursor_sprite);
|
MetaCursorSprite *cursor_sprite);
|
||||||
|
@ -41,16 +41,12 @@ void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
|||||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||||
MetaCursorSprite *cursor_sprite);
|
MetaCursorSprite *cursor_sprite);
|
||||||
|
|
||||||
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker);
|
||||||
float new_x,
|
|
||||||
float new_y);
|
|
||||||
|
|
||||||
void meta_cursor_tracker_track_position (MetaCursorTracker *tracker);
|
void meta_cursor_tracker_track_position (MetaCursorTracker *tracker);
|
||||||
|
|
||||||
void meta_cursor_tracker_untrack_position (MetaCursorTracker *tracker);
|
void meta_cursor_tracker_untrack_position (MetaCursorTracker *tracker);
|
||||||
|
|
||||||
MetaCursorSprite * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
|
|
||||||
|
|
||||||
MetaBackend * meta_cursor_tracker_get_backend (MetaCursorTracker *tracker);
|
MetaBackend * meta_cursor_tracker_get_backend (MetaCursorTracker *tracker);
|
||||||
|
|
||||||
void meta_cursor_tracker_notify_cursor_changed (MetaCursorTracker *tracker);
|
void meta_cursor_tracker_notify_cursor_changed (MetaCursorTracker *tracker);
|
||||||
|
@ -31,15 +31,12 @@
|
|||||||
|
|
||||||
#include "backends/meta-cursor-tracker-private.h"
|
#include "backends/meta-cursor-tracker-private.h"
|
||||||
|
|
||||||
#include <gdk/gdk.h>
|
|
||||||
#include <gdk/gdkx.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "cogl/cogl.h"
|
#include "cogl/cogl.h"
|
||||||
#include "core/display-private.h"
|
#include "core/display-private.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "meta-marshal.h"
|
|
||||||
#include "meta/main.h"
|
#include "meta/main.h"
|
||||||
#include "meta/util.h"
|
#include "meta/util.h"
|
||||||
|
|
||||||
@ -303,14 +300,8 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
|
|||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
0,
|
0,
|
||||||
NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
meta_marshal_VOID__FLOAT_FLOAT,
|
G_TYPE_NONE, 0);
|
||||||
G_TYPE_NONE, 2,
|
|
||||||
G_TYPE_FLOAT,
|
|
||||||
G_TYPE_FLOAT);
|
|
||||||
g_signal_set_va_marshaller (signals[CURSOR_MOVED],
|
|
||||||
G_TYPE_FROM_CLASS (klass),
|
|
||||||
meta_marshal_VOID__FLOAT_FLOATv);
|
|
||||||
|
|
||||||
signals[VISIBILITY_CHANGED] = g_signal_new ("visibility-changed",
|
signals[VISIBILITY_CHANGED] = g_signal_new ("visibility-changed",
|
||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
@ -437,88 +428,23 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
meta_cursor_tracker_update_position (MetaCursorTracker *tracker)
|
||||||
float new_x,
|
|
||||||
float new_y)
|
|
||||||
{
|
{
|
||||||
MetaCursorTrackerPrivate *priv =
|
g_signal_emit (tracker, signals[CURSOR_MOVED], 0);
|
||||||
meta_cursor_tracker_get_instance_private (tracker);
|
|
||||||
MetaCursorRenderer *cursor_renderer =
|
|
||||||
meta_backend_get_cursor_renderer (priv->backend);
|
|
||||||
gboolean position_changed;
|
|
||||||
|
|
||||||
if (priv->x != new_x || priv->y != new_y)
|
|
||||||
{
|
|
||||||
position_changed = TRUE;
|
|
||||||
priv->x = new_x;
|
|
||||||
priv->y = new_y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
position_changed = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_cursor_renderer_set_position (cursor_renderer, new_x, new_y);
|
|
||||||
|
|
||||||
if (position_changed)
|
|
||||||
g_signal_emit (tracker, signals[CURSOR_MOVED], 0, new_x, new_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
get_pointer_position_gdk (int *x,
|
|
||||||
int *y,
|
|
||||||
int *mods)
|
|
||||||
{
|
|
||||||
GdkSeat *gseat;
|
|
||||||
GdkDevice *gdevice;
|
|
||||||
GdkScreen *gscreen;
|
|
||||||
|
|
||||||
gseat = gdk_display_get_default_seat (gdk_display_get_default ());
|
|
||||||
gdevice = gdk_seat_get_pointer (gseat);
|
|
||||||
|
|
||||||
gdk_device_get_position (gdevice, &gscreen, x, y);
|
|
||||||
if (mods)
|
|
||||||
gdk_device_get_state (gdevice,
|
|
||||||
gdk_screen_get_root_window (gscreen),
|
|
||||||
NULL, (GdkModifierType*)mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
get_pointer_position_clutter (int *x,
|
|
||||||
int *y,
|
|
||||||
int *mods)
|
|
||||||
{
|
|
||||||
ClutterSeat *seat;
|
|
||||||
ClutterInputDevice *cdevice;
|
|
||||||
graphene_point_t point;
|
|
||||||
|
|
||||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
|
||||||
cdevice = clutter_seat_get_pointer (seat);
|
|
||||||
|
|
||||||
clutter_input_device_get_coords (cdevice, NULL, &point);
|
|
||||||
if (x)
|
|
||||||
*x = point.x;
|
|
||||||
if (y)
|
|
||||||
*y = point.y;
|
|
||||||
if (mods)
|
|
||||||
*mods = clutter_input_device_get_modifier_state (cdevice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
|
meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
|
||||||
int *x,
|
graphene_point_t *coords,
|
||||||
int *y,
|
|
||||||
ClutterModifierType *mods)
|
ClutterModifierType *mods)
|
||||||
{
|
{
|
||||||
/* We can't use the clutter interface when not running as a wayland compositor,
|
ClutterSeat *seat;
|
||||||
because we need to query the server, rather than using the last cached value.
|
ClutterInputDevice *cdevice;
|
||||||
OTOH, on wayland we can't use GDK, because that only sees the events
|
|
||||||
we forward to xwayland.
|
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||||
*/
|
cdevice = clutter_seat_get_pointer (seat);
|
||||||
if (meta_is_wayland_compositor ())
|
|
||||||
get_pointer_position_clutter (x, y, (int*)mods);
|
clutter_seat_query_state (seat, cdevice, NULL, coords, mods);
|
||||||
else
|
|
||||||
get_pointer_position_gdk (x, y, (int*)mods);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -579,16 +505,6 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
|||||||
|
|
||||||
g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0);
|
g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaCursorSprite *
|
|
||||||
meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker)
|
|
||||||
{
|
|
||||||
MetaCursorTrackerPrivate *priv =
|
|
||||||
meta_cursor_tracker_get_instance_private (tracker);
|
|
||||||
|
|
||||||
return priv->displayed_cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaBackend *
|
MetaBackend *
|
||||||
meta_cursor_tracker_get_backend (MetaCursorTracker *tracker)
|
meta_cursor_tracker_get_backend (MetaCursorTracker *tracker)
|
||||||
{
|
{
|
||||||
|
@ -179,11 +179,12 @@ meta_cursor_sprite_get_texture_transform (MetaCursorSprite *sprite)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
|
meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
|
||||||
int x,
|
float best_scale,
|
||||||
int y)
|
int x,
|
||||||
|
int y)
|
||||||
{
|
{
|
||||||
g_signal_emit (sprite, signals[PREPARE_AT], 0, x, y);
|
g_signal_emit (sprite, signals[PREPARE_AT], 0, best_scale, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -226,7 +227,8 @@ meta_cursor_sprite_class_init (MetaCursorSpriteClass *klass)
|
|||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
0,
|
0,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 2,
|
G_TYPE_NONE, 3,
|
||||||
|
G_TYPE_FLOAT,
|
||||||
G_TYPE_INT,
|
G_TYPE_INT,
|
||||||
G_TYPE_INT);
|
G_TYPE_INT);
|
||||||
signals[TEXTURE_CHANGED] = g_signal_new ("texture-changed",
|
signals[TEXTURE_CHANGED] = g_signal_new ("texture-changed",
|
||||||
|
@ -43,6 +43,7 @@ struct _MetaCursorSpriteClass
|
|||||||
};
|
};
|
||||||
|
|
||||||
void meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
|
void meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
|
||||||
|
float best_scale,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
#define META_INPUT_MAPPER_H
|
#define META_INPUT_MAPPER_H
|
||||||
|
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
#include "meta-monitor-manager-private.h"
|
|
||||||
|
#include "backends/meta-backend-types.h"
|
||||||
|
|
||||||
#define META_TYPE_INPUT_MAPPER (meta_input_mapper_get_type ())
|
#define META_TYPE_INPUT_MAPPER (meta_input_mapper_get_type ())
|
||||||
|
|
||||||
@ -33,10 +34,9 @@ G_DECLARE_FINAL_TYPE (MetaInputMapper, meta_input_mapper,
|
|||||||
MetaInputMapper * meta_input_mapper_new (void);
|
MetaInputMapper * meta_input_mapper_new (void);
|
||||||
|
|
||||||
void meta_input_mapper_add_device (MetaInputMapper *mapper,
|
void meta_input_mapper_add_device (MetaInputMapper *mapper,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device);
|
||||||
gboolean builtin);
|
|
||||||
void meta_input_mapper_remove_device (MetaInputMapper *mapper,
|
void meta_input_mapper_remove_device (MetaInputMapper *mapper,
|
||||||
ClutterInputDevice *device);
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
ClutterInputDevice *
|
ClutterInputDevice *
|
||||||
meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
|
meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
|
||||||
@ -46,4 +46,7 @@ MetaLogicalMonitor *
|
|||||||
meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
|
meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
|
||||||
ClutterInputDevice *device);
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
|
GSettings * meta_input_mapper_get_tablet_settings (MetaInputMapper *mapper,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
#endif /* META_INPUT_MAPPER_H */
|
#endif /* META_INPUT_MAPPER_H */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <gudev/gudev.h>
|
#include <gudev/gudev.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "backends/meta-input-device-private.h"
|
||||||
#include "meta-input-mapper-private.h"
|
#include "meta-input-mapper-private.h"
|
||||||
#include "meta-monitor-manager-private.h"
|
#include "meta-monitor-manager-private.h"
|
||||||
#include "meta-logical-monitor.h"
|
#include "meta-logical-monitor.h"
|
||||||
@ -59,6 +60,7 @@ typedef enum
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
META_MATCH_CONFIG, /* Specified by config */
|
||||||
META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */
|
META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */
|
||||||
META_MATCH_SIZE, /* Size from input device and output match */
|
META_MATCH_SIZE, /* Size from input device and output match */
|
||||||
META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */
|
META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */
|
||||||
@ -72,6 +74,7 @@ struct _MetaMapperInputInfo
|
|||||||
ClutterInputDevice *device;
|
ClutterInputDevice *device;
|
||||||
MetaInputMapper *mapper;
|
MetaInputMapper *mapper;
|
||||||
MetaMapperOutputInfo *output;
|
MetaMapperOutputInfo *output;
|
||||||
|
GSettings *settings;
|
||||||
guint builtin : 1;
|
guint builtin : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,24 +102,149 @@ struct _DeviceCandidates
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
DEVICE_MAPPED,
|
DEVICE_MAPPED,
|
||||||
|
DEVICE_ENABLED,
|
||||||
|
DEVICE_ASPECT_RATIO,
|
||||||
N_SIGNALS
|
N_SIGNALS
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint signals[N_SIGNALS] = { 0, };
|
static guint signals[N_SIGNALS] = { 0, };
|
||||||
|
|
||||||
|
static void mapper_recalculate_input (MetaInputMapper *mapper,
|
||||||
|
MetaMapperInputInfo *input);
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static GSettings *
|
||||||
|
get_device_settings (ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
const gchar *group, *schema, *vendor, *product;
|
||||||
|
ClutterInputDeviceType type;
|
||||||
|
GSettings *settings;
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
|
type = clutter_input_device_get_device_type (device);
|
||||||
|
|
||||||
|
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||||
|
{
|
||||||
|
group = "touchscreens";
|
||||||
|
schema = "org.gnome.desktop.peripherals.touchscreen";
|
||||||
|
}
|
||||||
|
else if (type == CLUTTER_TABLET_DEVICE ||
|
||||||
|
type == CLUTTER_PEN_DEVICE ||
|
||||||
|
type == CLUTTER_ERASER_DEVICE ||
|
||||||
|
type == CLUTTER_CURSOR_DEVICE ||
|
||||||
|
type == CLUTTER_PAD_DEVICE)
|
||||||
|
{
|
||||||
|
group = "tablets";
|
||||||
|
schema = "org.gnome.desktop.peripherals.tablet";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
vendor = clutter_input_device_get_vendor_id (device);
|
||||||
|
product = clutter_input_device_get_product_id (device);
|
||||||
|
path = g_strdup_printf ("/org/gnome/desktop/peripherals/%s/%s:%s/",
|
||||||
|
group, vendor, product);
|
||||||
|
|
||||||
|
settings = g_settings_new_with_path (schema, path);
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaMonitor *
|
||||||
|
logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor,
|
||||||
|
const char *vendor,
|
||||||
|
const char *product,
|
||||||
|
const char *serial)
|
||||||
|
{
|
||||||
|
GList *monitors;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
monitors = meta_logical_monitor_get_monitors (logical_monitor);
|
||||||
|
for (l = monitors; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaMonitor *monitor = l->data;
|
||||||
|
|
||||||
|
if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 &&
|
||||||
|
g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 &&
|
||||||
|
g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0)
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
find_settings_monitor (MetaInputMapper *mapper,
|
||||||
|
GSettings *settings,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
MetaMonitor **out_monitor,
|
||||||
|
MetaLogicalMonitor **out_logical_monitor)
|
||||||
|
{
|
||||||
|
MetaMonitor *monitor;
|
||||||
|
guint n_values;
|
||||||
|
GList *logical_monitors;
|
||||||
|
GList *l;
|
||||||
|
gchar **edid;
|
||||||
|
|
||||||
|
edid = g_settings_get_strv (settings, "output");
|
||||||
|
n_values = g_strv_length (edid);
|
||||||
|
|
||||||
|
if (n_values != 3)
|
||||||
|
{
|
||||||
|
g_warning ("EDID configuration for device '%s' "
|
||||||
|
"is incorrect, must have 3 values",
|
||||||
|
clutter_input_device_get_device_name (device));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*edid[0] && !*edid[1] && !*edid[2])
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
logical_monitors =
|
||||||
|
meta_monitor_manager_get_logical_monitors (mapper->monitor_manager);
|
||||||
|
for (l = logical_monitors; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaLogicalMonitor *logical_monitor = l->data;
|
||||||
|
|
||||||
|
monitor = logical_monitor_find_monitor (logical_monitor,
|
||||||
|
edid[0], edid[1], edid[2]);
|
||||||
|
if (monitor)
|
||||||
|
{
|
||||||
|
if (out_monitor)
|
||||||
|
*out_monitor = monitor;
|
||||||
|
if (out_logical_monitor)
|
||||||
|
*out_logical_monitor = logical_monitor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_strfreev (edid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
settings_output_changed_cb (GSettings *settings,
|
||||||
|
const gchar *key,
|
||||||
|
MetaMapperInputInfo *info)
|
||||||
|
{
|
||||||
|
mapper_recalculate_input (info->mapper, info);
|
||||||
|
}
|
||||||
|
|
||||||
static MetaMapperInputInfo *
|
static MetaMapperInputInfo *
|
||||||
mapper_input_info_new (ClutterInputDevice *device,
|
mapper_input_info_new (ClutterInputDevice *device,
|
||||||
MetaInputMapper *mapper,
|
MetaInputMapper *mapper)
|
||||||
gboolean builtin)
|
|
||||||
{
|
{
|
||||||
MetaMapperInputInfo *info;
|
MetaMapperInputInfo *info;
|
||||||
|
|
||||||
info = g_new0 (MetaMapperInputInfo, 1);
|
info = g_new0 (MetaMapperInputInfo, 1);
|
||||||
info->mapper = mapper;
|
info->mapper = mapper;
|
||||||
info->device = device;
|
info->device = device;
|
||||||
info->builtin = builtin;
|
info->settings = get_device_settings (device);
|
||||||
|
|
||||||
|
g_signal_connect (info->settings, "changed::output",
|
||||||
|
G_CALLBACK (settings_output_changed_cb), info);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -124,6 +252,7 @@ mapper_input_info_new (ClutterInputDevice *device,
|
|||||||
static void
|
static void
|
||||||
mapper_input_info_free (MetaMapperInputInfo *info)
|
mapper_input_info_free (MetaMapperInputInfo *info)
|
||||||
{
|
{
|
||||||
|
g_object_unref (info->settings);
|
||||||
g_free (info);
|
g_free (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,13 +303,36 @@ mapper_input_info_set_output (MetaMapperInputInfo *input,
|
|||||||
MetaMapperOutputInfo *output,
|
MetaMapperOutputInfo *output,
|
||||||
MetaMonitor *monitor)
|
MetaMonitor *monitor)
|
||||||
{
|
{
|
||||||
|
MetaInputMapper *mapper = input->mapper;
|
||||||
|
float matrix[6] = { 1, 0, 0, 0, 1, 0 };
|
||||||
|
double aspect_ratio;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
if (input->output == output)
|
if (input->output == output)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
input->output = output;
|
input->output = output;
|
||||||
|
|
||||||
|
if (output && monitor)
|
||||||
|
{
|
||||||
|
meta_monitor_manager_get_monitor_matrix (mapper->monitor_manager,
|
||||||
|
monitor,
|
||||||
|
output->logical_monitor,
|
||||||
|
matrix);
|
||||||
|
meta_monitor_get_current_resolution (monitor, &width, &height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_monitor_manager_get_screen_size (mapper->monitor_manager,
|
||||||
|
&width, &height);
|
||||||
|
}
|
||||||
|
|
||||||
|
aspect_ratio = (double) width / height;
|
||||||
|
|
||||||
g_signal_emit (input->mapper, signals[DEVICE_MAPPED], 0,
|
g_signal_emit (input->mapper, signals[DEVICE_MAPPED], 0,
|
||||||
input->device,
|
input->device, matrix);
|
||||||
output ? output->logical_monitor : NULL, monitor);
|
g_signal_emit (input->mapper, signals[DEVICE_ASPECT_RATIO], 0,
|
||||||
|
input->device, aspect_ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -361,6 +513,32 @@ guess_candidates (MetaInputMapper *mapper,
|
|||||||
MetaOutputMatchType best = N_OUTPUT_MATCHES;
|
MetaOutputMatchType best = N_OUTPUT_MATCHES;
|
||||||
GList *monitors, *l;
|
GList *monitors, *l;
|
||||||
MetaMonitor *matched_monitor = NULL;
|
MetaMonitor *matched_monitor = NULL;
|
||||||
|
gboolean builtin = FALSE;
|
||||||
|
gboolean integrated = TRUE;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBWACOM
|
||||||
|
if (clutter_input_device_get_device_type (input->device) != CLUTTER_TOUCHSCREEN_DEVICE)
|
||||||
|
{
|
||||||
|
WacomDevice *wacom_device;
|
||||||
|
WacomIntegrationFlags flags = 0;
|
||||||
|
|
||||||
|
wacom_device =
|
||||||
|
meta_input_device_get_wacom_device (META_INPUT_DEVICE (input->device));
|
||||||
|
|
||||||
|
if (wacom_device)
|
||||||
|
{
|
||||||
|
flags = libwacom_get_integration_flags (wacom_device);
|
||||||
|
|
||||||
|
if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
|
||||||
|
WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
integrated = (flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
|
||||||
|
WACOM_DEVICE_INTEGRATED_DISPLAY)) != 0;
|
||||||
|
builtin = (flags & WACOM_DEVICE_INTEGRATED_SYSTEM) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager);
|
monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager);
|
||||||
|
|
||||||
@ -375,18 +553,23 @@ guess_candidates (MetaInputMapper *mapper,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (find_size_match (input, monitors, &matched_monitor))
|
if (integrated && find_size_match (input, monitors, &matched_monitor))
|
||||||
{
|
{
|
||||||
best = MIN (best, META_MATCH_SIZE);
|
best = MIN (best, META_MATCH_SIZE);
|
||||||
info->candidates[META_MATCH_SIZE] = matched_monitor;
|
info->candidates[META_MATCH_SIZE] = matched_monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->builtin || best == N_OUTPUT_MATCHES)
|
if (builtin || best == N_OUTPUT_MATCHES)
|
||||||
{
|
{
|
||||||
best = MIN (best, META_MATCH_IS_BUILTIN);
|
best = MIN (best, META_MATCH_IS_BUILTIN);
|
||||||
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);
|
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_settings_monitor (mapper, input->settings, input->device,
|
||||||
|
&info->candidates[META_MATCH_CONFIG], NULL);
|
||||||
|
if (info->candidates[META_MATCH_CONFIG])
|
||||||
|
best = MIN (best, META_MATCH_CONFIG);
|
||||||
|
|
||||||
info->best = best;
|
info->best = best;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,6 +707,37 @@ input_mapper_monitors_changed_cb (MetaMonitorManager *monitor_manager,
|
|||||||
mapper_update_outputs (mapper);
|
mapper_update_outputs (mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_mapper_power_save_mode_changed_cb (MetaMonitorManager *monitor_manager,
|
||||||
|
MetaInputMapper *mapper)
|
||||||
|
{
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
MetaLogicalMonitor *logical_monitor;
|
||||||
|
MetaMonitor *builtin;
|
||||||
|
MetaPowerSave power_save_mode;
|
||||||
|
gboolean on;
|
||||||
|
|
||||||
|
power_save_mode =
|
||||||
|
meta_monitor_manager_get_power_save_mode (mapper->monitor_manager);
|
||||||
|
on = power_save_mode == META_POWER_SAVE_ON;
|
||||||
|
|
||||||
|
if (!find_builtin_output (mapper, &builtin))
|
||||||
|
return;
|
||||||
|
|
||||||
|
logical_monitor = meta_monitor_get_logical_monitor (builtin);
|
||||||
|
if (!logical_monitor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
device =
|
||||||
|
meta_input_mapper_get_logical_monitor_device (mapper,
|
||||||
|
logical_monitor,
|
||||||
|
CLUTTER_TOUCHSCREEN_DEVICE);
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_signal_emit (mapper, signals[DEVICE_ENABLED], 0, device, on);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
input_mapper_device_removed_cb (ClutterSeat *seat,
|
input_mapper_device_removed_cb (ClutterSeat *seat,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
@ -576,6 +790,9 @@ meta_input_mapper_constructed (GObject *object)
|
|||||||
mapper->monitor_manager = meta_backend_get_monitor_manager (backend);
|
mapper->monitor_manager = meta_backend_get_monitor_manager (backend);
|
||||||
g_signal_connect (mapper->monitor_manager, "monitors-changed-internal",
|
g_signal_connect (mapper->monitor_manager, "monitors-changed-internal",
|
||||||
G_CALLBACK (input_mapper_monitors_changed_cb), mapper);
|
G_CALLBACK (input_mapper_monitors_changed_cb), mapper);
|
||||||
|
g_signal_connect (mapper->monitor_manager, "power-save-mode-changed",
|
||||||
|
G_CALLBACK (input_mapper_power_save_mode_changed_cb),
|
||||||
|
mapper);
|
||||||
|
|
||||||
mapper_update_outputs (mapper);
|
mapper_update_outputs (mapper);
|
||||||
}
|
}
|
||||||
@ -594,9 +811,27 @@ meta_input_mapper_class_init (MetaInputMapperClass *klass)
|
|||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
0,
|
0,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 3,
|
G_TYPE_NONE, 2,
|
||||||
CLUTTER_TYPE_INPUT_DEVICE,
|
CLUTTER_TYPE_INPUT_DEVICE,
|
||||||
G_TYPE_POINTER, G_TYPE_POINTER);
|
G_TYPE_POINTER);
|
||||||
|
signals[DEVICE_ENABLED] =
|
||||||
|
g_signal_new ("device-enabled",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 2,
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE,
|
||||||
|
G_TYPE_BOOLEAN);
|
||||||
|
signals[DEVICE_ASPECT_RATIO] =
|
||||||
|
g_signal_new ("device-aspect-ratio",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 2,
|
||||||
|
CLUTTER_TYPE_INPUT_DEVICE,
|
||||||
|
G_TYPE_DOUBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -618,8 +853,7 @@ meta_input_mapper_new (void)
|
|||||||
|
|
||||||
void
|
void
|
||||||
meta_input_mapper_add_device (MetaInputMapper *mapper,
|
meta_input_mapper_add_device (MetaInputMapper *mapper,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device)
|
||||||
gboolean builtin)
|
|
||||||
{
|
{
|
||||||
MetaMapperInputInfo *info;
|
MetaMapperInputInfo *info;
|
||||||
|
|
||||||
@ -629,7 +863,7 @@ meta_input_mapper_add_device (MetaInputMapper *mapper,
|
|||||||
if (g_hash_table_contains (mapper->input_devices, device))
|
if (g_hash_table_contains (mapper->input_devices, device))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
info = mapper_input_info_new (device, mapper, builtin);
|
info = mapper_input_info_new (device, mapper);
|
||||||
g_hash_table_insert (mapper->input_devices, device, info);
|
g_hash_table_insert (mapper->input_devices, device, info);
|
||||||
mapper_recalculate_input (mapper, info);
|
mapper_recalculate_input (mapper, info);
|
||||||
}
|
}
|
||||||
@ -676,6 +910,43 @@ meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterInputDevice *
|
||||||
|
find_grouped_pen (ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
GList *l, *devices;
|
||||||
|
ClutterInputDeviceType device_type;
|
||||||
|
ClutterInputDevice *pen = NULL;
|
||||||
|
ClutterSeat *seat;
|
||||||
|
|
||||||
|
device_type = clutter_input_device_get_device_type (device);
|
||||||
|
|
||||||
|
if (device_type == CLUTTER_TABLET_DEVICE ||
|
||||||
|
device_type == CLUTTER_PEN_DEVICE)
|
||||||
|
return device;
|
||||||
|
|
||||||
|
seat = clutter_input_device_get_seat (device);
|
||||||
|
devices = clutter_seat_list_devices (seat);
|
||||||
|
|
||||||
|
for (l = devices; l; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterInputDevice *other_device = l->data;
|
||||||
|
|
||||||
|
device_type = clutter_input_device_get_device_type (other_device);
|
||||||
|
|
||||||
|
if ((device_type == CLUTTER_TABLET_DEVICE ||
|
||||||
|
device_type == CLUTTER_PEN_DEVICE) &&
|
||||||
|
clutter_input_device_is_grouped (device, other_device))
|
||||||
|
{
|
||||||
|
pen = other_device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (devices);
|
||||||
|
|
||||||
|
return pen;
|
||||||
|
}
|
||||||
|
|
||||||
MetaLogicalMonitor *
|
MetaLogicalMonitor *
|
||||||
meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
|
meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
|
||||||
ClutterInputDevice *device)
|
ClutterInputDevice *device)
|
||||||
@ -685,6 +956,13 @@ meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
|
|||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
|
if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
|
||||||
|
{
|
||||||
|
device = find_grouped_pen (device);
|
||||||
|
if (!device)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, mapper->output_devices);
|
g_hash_table_iter_init (&iter, mapper->output_devices);
|
||||||
|
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor,
|
while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor,
|
||||||
@ -701,3 +979,19 @@ meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSettings *
|
||||||
|
meta_input_mapper_get_tablet_settings (MetaInputMapper *mapper,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
MetaMapperInputInfo *input;
|
||||||
|
|
||||||
|
g_return_val_if_fail (META_IS_INPUT_MAPPER (mapper), NULL);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||||
|
|
||||||
|
input = g_hash_table_lookup (mapper->input_devices, device);
|
||||||
|
if (!input)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return input->settings;
|
||||||
|
}
|
||||||
|
@ -36,6 +36,62 @@
|
|||||||
G_DECLARE_DERIVABLE_TYPE (MetaInputSettings, meta_input_settings,
|
G_DECLARE_DERIVABLE_TYPE (MetaInputSettings, meta_input_settings,
|
||||||
META, INPUT_SETTINGS, GObject)
|
META, INPUT_SETTINGS, GObject)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MetaKeyboardA11yFlags:
|
||||||
|
* @CLUTTER_A11Y_KEYBOARD_ENABLED:
|
||||||
|
* @CLUTTER_A11Y_TIMEOUT_ENABLED:
|
||||||
|
* @CLUTTER_A11Y_MOUSE_KEYS_ENABLED:
|
||||||
|
* @CLUTTER_A11Y_SLOW_KEYS_ENABLED:
|
||||||
|
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS:
|
||||||
|
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT:
|
||||||
|
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT:
|
||||||
|
* @CLUTTER_A11Y_BOUNCE_KEYS_ENABLED:
|
||||||
|
* @CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT:
|
||||||
|
* @CLUTTER_A11Y_TOGGLE_KEYS_ENABLED:
|
||||||
|
* @CLUTTER_A11Y_STICKY_KEYS_ENABLED:
|
||||||
|
* @CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF:
|
||||||
|
* @CLUTTER_A11Y_STICKY_KEYS_BEEP:
|
||||||
|
* @CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP:
|
||||||
|
*
|
||||||
|
* Keyboard accessibility features applied to a ClutterInputDevice keyboard.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
META_A11Y_KEYBOARD_ENABLED = 1 << 0,
|
||||||
|
META_A11Y_TIMEOUT_ENABLED = 1 << 1,
|
||||||
|
META_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
|
||||||
|
META_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
|
||||||
|
META_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
|
||||||
|
META_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
|
||||||
|
META_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
|
||||||
|
META_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
|
||||||
|
META_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
|
||||||
|
META_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
|
||||||
|
META_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
|
||||||
|
META_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
|
||||||
|
META_A11Y_STICKY_KEYS_BEEP = 1 << 12,
|
||||||
|
META_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
|
||||||
|
} MetaKeyboardA11yFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MetaKbdA11ySettings:
|
||||||
|
*
|
||||||
|
* The #MetaKbdA11ySettings structure contains keyboard accessibility
|
||||||
|
* settings
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct _MetaKbdA11ySettings
|
||||||
|
{
|
||||||
|
MetaKeyboardA11yFlags controls;
|
||||||
|
gint slowkeys_delay;
|
||||||
|
gint debounce_delay;
|
||||||
|
gint timeout_delay;
|
||||||
|
gint mousekeys_init_delay;
|
||||||
|
gint mousekeys_max_speed;
|
||||||
|
gint mousekeys_accel_time;
|
||||||
|
} MetaKbdA11ySettings;
|
||||||
|
|
||||||
struct _MetaInputSettingsClass
|
struct _MetaInputSettingsClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
@ -92,10 +148,9 @@ struct _MetaInputSettingsClass
|
|||||||
void (* set_tablet_mapping) (MetaInputSettings *settings,
|
void (* set_tablet_mapping) (MetaInputSettings *settings,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
GDesktopTabletMapping mapping);
|
GDesktopTabletMapping mapping);
|
||||||
void (* set_tablet_keep_aspect) (MetaInputSettings *settings,
|
void (* set_tablet_aspect_ratio) (MetaInputSettings *settings,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
MetaLogicalMonitor *logical_monitor,
|
double ratio);
|
||||||
gboolean keep_aspect);
|
|
||||||
void (* set_tablet_area) (MetaInputSettings *settings,
|
void (* set_tablet_area) (MetaInputSettings *settings,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
gdouble padding_left,
|
gdouble padding_left,
|
||||||
@ -137,26 +192,31 @@ struct _MetaInputSettingsClass
|
|||||||
ClutterInputDevice *device);
|
ClutterInputDevice *device);
|
||||||
};
|
};
|
||||||
|
|
||||||
GSettings * meta_input_settings_get_tablet_settings (MetaInputSettings *settings,
|
|
||||||
ClutterInputDevice *device);
|
|
||||||
MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
|
|
||||||
ClutterInputDevice *device);
|
|
||||||
|
|
||||||
GDesktopTabletMapping meta_input_settings_get_tablet_mapping (MetaInputSettings *settings,
|
|
||||||
ClutterInputDevice *device);
|
|
||||||
|
|
||||||
gboolean meta_input_settings_is_pad_button_grabbed (MetaInputSettings *input_settings,
|
|
||||||
ClutterInputDevice *pad,
|
|
||||||
guint button);
|
|
||||||
|
|
||||||
gboolean meta_input_settings_handle_pad_event (MetaInputSettings *input_settings,
|
|
||||||
const ClutterEvent *event);
|
|
||||||
gchar * meta_input_settings_get_pad_action_label (MetaInputSettings *input_settings,
|
|
||||||
ClutterInputDevice *pad,
|
|
||||||
MetaPadActionType action,
|
|
||||||
guint number);
|
|
||||||
|
|
||||||
void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings);
|
void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings);
|
||||||
void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings);
|
void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings);
|
||||||
|
|
||||||
|
void meta_input_settings_set_device_matrix (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
float matrix[6]);
|
||||||
|
void meta_input_settings_set_device_enabled (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
gboolean enabled);
|
||||||
|
void meta_input_settings_set_device_aspect_ratio (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
double aspect_ratio);
|
||||||
|
|
||||||
|
void meta_input_settings_get_kbd_a11y_settings (MetaInputSettings *input_settings,
|
||||||
|
MetaKbdA11ySettings *a11y_settings);
|
||||||
|
|
||||||
|
void meta_input_settings_add_device (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
void meta_input_settings_remove_device (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
void meta_input_settings_notify_tool_change (MetaInputSettings *input_settings,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
ClutterInputDeviceTool *tool);
|
||||||
|
void meta_input_settings_notify_kbd_a11y_change (MetaInputSettings *input_settings,
|
||||||
|
MetaKeyboardA11yFlags new_flags,
|
||||||
|
MetaKeyboardA11yFlags what_changed);
|
||||||
|
|
||||||
#endif /* META_INPUT_SETTINGS_PRIVATE_H */
|
#endif /* META_INPUT_SETTINGS_PRIVATE_H */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,7 @@
|
|||||||
#include "backends/meta-cursor.h"
|
#include "backends/meta-cursor.h"
|
||||||
#include "backends/meta-display-config-shared.h"
|
#include "backends/meta-display-config-shared.h"
|
||||||
#include "backends/meta-monitor-transform.h"
|
#include "backends/meta-monitor-transform.h"
|
||||||
|
#include "backends/meta-viewport-info.h"
|
||||||
#include "core/util-private.h"
|
#include "core/util-private.h"
|
||||||
#include "meta/display.h"
|
#include "meta/display.h"
|
||||||
#include "meta/meta-monitor-manager.h"
|
#include "meta/meta-monitor-manager.h"
|
||||||
@ -405,4 +406,6 @@ meta_find_output_assignment (MetaOutputAssignment **outputs,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manager);
|
||||||
|
|
||||||
#endif /* META_MONITOR_MANAGER_PRIVATE_H */
|
#endif /* META_MONITOR_MANAGER_PRIVATE_H */
|
||||||
|
@ -3175,3 +3175,37 @@ meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager,
|
|||||||
|
|
||||||
return gnome_pnp_ids_get_pnp_id (manager->pnp_ids, vendor);
|
return gnome_pnp_ids_get_pnp_id (manager->pnp_ids, vendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaViewportInfo *
|
||||||
|
meta_monitor_manager_get_viewports (MetaMonitorManager *manager)
|
||||||
|
{
|
||||||
|
MetaViewportInfo *info;
|
||||||
|
GArray *views, *scales;
|
||||||
|
GList *logical_monitors, *l;
|
||||||
|
|
||||||
|
views = g_array_new (FALSE, FALSE, sizeof (cairo_rectangle_int_t));
|
||||||
|
scales = g_array_new (FALSE, FALSE, sizeof (float));
|
||||||
|
|
||||||
|
logical_monitors = meta_monitor_manager_get_logical_monitors (manager);
|
||||||
|
|
||||||
|
for (l = logical_monitors; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaLogicalMonitor *logical_monitor = l->data;
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
float scale;
|
||||||
|
|
||||||
|
rect = logical_monitor->rect;
|
||||||
|
g_array_append_val (views, rect);
|
||||||
|
|
||||||
|
scale = logical_monitor->scale;
|
||||||
|
g_array_append_val (scales, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
info = meta_viewport_info_new ((cairo_rectangle_int_t *) views->data,
|
||||||
|
(float *) scales->data,
|
||||||
|
views->len);
|
||||||
|
g_array_unref (views);
|
||||||
|
g_array_unref (scales);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
@ -39,8 +39,19 @@
|
|||||||
|
|
||||||
#include "backends/meta-pointer-constraint.h"
|
#include "backends/meta-pointer-constraint.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
|
#include "backends/native/meta-backend-native.h"
|
||||||
|
#include "backends/native/meta-pointer-constraint-native.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
struct _MetaPointerConstraint
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
cairo_region_t *region;
|
||||||
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaPointerConstraint, meta_pointer_constraint, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (MetaPointerConstraint, meta_pointer_constraint, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -53,9 +64,40 @@ meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MetaPointerConstraint *
|
||||||
|
meta_pointer_constraint_new (const cairo_region_t *region)
|
||||||
|
{
|
||||||
|
MetaPointerConstraint *constraint;
|
||||||
|
|
||||||
|
constraint = g_object_new (META_TYPE_POINTER_CONSTRAINT, NULL);
|
||||||
|
constraint->region = cairo_region_copy (region);
|
||||||
|
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_region_t *
|
||||||
|
meta_pointer_constraint_get_region (MetaPointerConstraint *constraint)
|
||||||
|
{
|
||||||
|
return constraint->region;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaPointerConstraintImpl, meta_pointer_constraint_impl,
|
||||||
|
G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_constraint_impl_init (MetaPointerConstraintImpl *impl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_constraint_impl_class_init (MetaPointerConstraintImplClass *klass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_pointer_constraint_constrain:
|
* meta_pointer_constraint_impl_constrain:
|
||||||
* @constraint: a #MetaPointerConstraint.
|
* @impl: a #MetaPointerConstraintImpl.
|
||||||
* @device; the device of the pointer.
|
* @device; the device of the pointer.
|
||||||
* @time: the timestamp (in ms) of the event.
|
* @time: the timestamp (in ms) of the event.
|
||||||
* @prev_x: X-coordinate of the previous pointer position.
|
* @prev_x: X-coordinate of the previous pointer position.
|
||||||
@ -67,17 +109,25 @@ meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass)
|
|||||||
* if needed.
|
* if needed.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
meta_pointer_constraint_constrain (MetaPointerConstraint *constraint,
|
meta_pointer_constraint_impl_constrain (MetaPointerConstraintImpl *impl,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
guint32 time,
|
uint32_t time,
|
||||||
float prev_x,
|
float prev_x,
|
||||||
float prev_y,
|
float prev_y,
|
||||||
float *x,
|
float *x,
|
||||||
float *y)
|
float *y)
|
||||||
{
|
{
|
||||||
META_POINTER_CONSTRAINT_GET_CLASS (constraint)->constrain (constraint,
|
META_POINTER_CONSTRAINT_IMPL_GET_CLASS (impl)->constrain (impl,
|
||||||
device,
|
device,
|
||||||
time,
|
time,
|
||||||
prev_x, prev_y,
|
prev_x, prev_y,
|
||||||
x, y);
|
x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_pointer_constraint_impl_ensure_constrained (MetaPointerConstraintImpl *impl,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
META_POINTER_CONSTRAINT_IMPL_GET_CLASS (impl)->ensure_constrained (impl,
|
||||||
|
device);
|
||||||
}
|
}
|
||||||
|
@ -32,34 +32,45 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define META_TYPE_POINTER_CONSTRAINT (meta_pointer_constraint_get_type ())
|
#define META_TYPE_POINTER_CONSTRAINT (meta_pointer_constraint_get_type ())
|
||||||
G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraint, meta_pointer_constraint,
|
G_DECLARE_FINAL_TYPE (MetaPointerConstraint, meta_pointer_constraint,
|
||||||
META, POINTER_CONSTRAINT, GObject);
|
META, POINTER_CONSTRAINT, GObject);
|
||||||
|
|
||||||
|
MetaPointerConstraint * meta_pointer_constraint_new (const cairo_region_t *region);
|
||||||
|
cairo_region_t * meta_pointer_constraint_get_region (MetaPointerConstraint *constraint);
|
||||||
|
|
||||||
|
#define META_TYPE_POINTER_CONSTRAINT_IMPL (meta_pointer_constraint_impl_get_type ())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraintImpl, meta_pointer_constraint_impl,
|
||||||
|
META, POINTER_CONSTRAINT_IMPL, GObject);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MetaPointerConstraintClass:
|
* MetaPointerConstraintImplClass:
|
||||||
* @constrain: the virtual function pointer for
|
* @constrain: the virtual function pointer for
|
||||||
* meta_pointer_constraint_constrain().
|
* meta_pointer_constraint_impl_constrain().
|
||||||
*/
|
*/
|
||||||
struct _MetaPointerConstraintClass
|
struct _MetaPointerConstraintImplClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (*constrain) (MetaPointerConstraint *constraint,
|
void (* constrain) (MetaPointerConstraintImpl *impl,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
guint32 time,
|
uint32_t time,
|
||||||
float prev_x,
|
float prev_x,
|
||||||
float prev_y,
|
float prev_y,
|
||||||
float *x,
|
float *x,
|
||||||
float *y);
|
float *y);
|
||||||
|
void (* ensure_constrained) (MetaPointerConstraintImpl *impl,
|
||||||
|
ClutterInputDevice *device);
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_pointer_constraint_constrain (MetaPointerConstraint *constraint,
|
void meta_pointer_constraint_impl_constrain (MetaPointerConstraintImpl *impl,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
guint32 time,
|
uint32_t time,
|
||||||
float prev_x,
|
float prev_x,
|
||||||
float prev_y,
|
float prev_y,
|
||||||
float *x,
|
float *x,
|
||||||
float *y);
|
float *y);
|
||||||
|
void meta_pointer_constraint_impl_ensure_constrained (MetaPointerConstraintImpl *impl,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -83,19 +83,6 @@ get_backend (MetaScreenCastAreaStreamSrc *area_src)
|
|||||||
return meta_screen_cast_get_backend (screen_cast);
|
return meta_screen_cast_get_backend (screen_cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorRenderer *
|
|
||||||
get_cursor_renderer (MetaScreenCastAreaStreamSrc *area_src)
|
|
||||||
{
|
|
||||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
|
||||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
|
||||||
MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream);
|
|
||||||
MetaScreenCast *screen_cast =
|
|
||||||
meta_screen_cast_session_get_screen_cast (session);
|
|
||||||
MetaBackend *backend = meta_screen_cast_get_backend (screen_cast);
|
|
||||||
|
|
||||||
return meta_backend_get_cursor_renderer (backend);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src,
|
meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src,
|
||||||
int *width,
|
int *width,
|
||||||
@ -142,9 +129,11 @@ is_cursor_in_stream (MetaScreenCastAreaStreamSrc *area_src)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
graphene_point_t cursor_position;
|
graphene_point_t cursor_position;
|
||||||
|
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
return graphene_rect_contains_point (&area_rect, &cursor_position);
|
return graphene_rect_contains_point (&area_rect, &cursor_position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,8 +173,6 @@ sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
cursor_moved (MetaCursorTracker *cursor_tracker,
|
cursor_moved (MetaCursorTracker *cursor_tracker,
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
MetaScreenCastAreaStreamSrc *area_src)
|
MetaScreenCastAreaStreamSrc *area_src)
|
||||||
{
|
{
|
||||||
sync_cursor_state (area_src);
|
sync_cursor_state (area_src);
|
||||||
@ -202,14 +189,14 @@ cursor_changed (MetaCursorTracker *cursor_tracker,
|
|||||||
static void
|
static void
|
||||||
inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
|
inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
|
||||||
{
|
{
|
||||||
MetaCursorRenderer *cursor_renderer;
|
|
||||||
MetaHwCursorInhibitor *inhibitor;
|
MetaHwCursorInhibitor *inhibitor;
|
||||||
|
MetaBackend *backend;
|
||||||
|
|
||||||
g_return_if_fail (!area_src->hw_cursor_inhibited);
|
g_return_if_fail (!area_src->hw_cursor_inhibited);
|
||||||
|
|
||||||
cursor_renderer = get_cursor_renderer (area_src);
|
backend = get_backend (area_src);
|
||||||
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
|
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
|
||||||
meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor);
|
meta_backend_add_hw_cursor_inhibitor (backend, inhibitor);
|
||||||
|
|
||||||
area_src->hw_cursor_inhibited = TRUE;
|
area_src->hw_cursor_inhibited = TRUE;
|
||||||
}
|
}
|
||||||
@ -217,14 +204,14 @@ inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
|
|||||||
static void
|
static void
|
||||||
uninhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
|
uninhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
|
||||||
{
|
{
|
||||||
MetaCursorRenderer *cursor_renderer;
|
|
||||||
MetaHwCursorInhibitor *inhibitor;
|
MetaHwCursorInhibitor *inhibitor;
|
||||||
|
MetaBackend *backend;
|
||||||
|
|
||||||
g_return_if_fail (area_src->hw_cursor_inhibited);
|
g_return_if_fail (area_src->hw_cursor_inhibited);
|
||||||
|
|
||||||
cursor_renderer = get_cursor_renderer (area_src);
|
backend = get_backend (area_src);
|
||||||
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
|
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
|
||||||
meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor);
|
meta_backend_remove_hw_cursor_inhibitor (backend, inhibitor);
|
||||||
|
|
||||||
area_src->hw_cursor_inhibited = FALSE;
|
area_src->hw_cursor_inhibited = FALSE;
|
||||||
}
|
}
|
||||||
@ -506,6 +493,8 @@ meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *s
|
|||||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||||
MetaBackend *backend = get_backend (area_src);
|
MetaBackend *backend = get_backend (area_src);
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorRenderer *cursor_renderer =
|
||||||
meta_backend_get_cursor_renderer (backend);
|
meta_backend_get_cursor_renderer (backend);
|
||||||
MetaCursorSprite *cursor_sprite;
|
MetaCursorSprite *cursor_sprite;
|
||||||
@ -526,7 +515,7 @@ meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *s
|
|||||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||||
scale = meta_screen_cast_area_stream_get_scale (area_stream);
|
scale = meta_screen_cast_area_stream_get_scale (area_stream);
|
||||||
|
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
cursor_position.x -= area->x;
|
cursor_position.x -= area->x;
|
||||||
cursor_position.y -= area->y;
|
cursor_position.y -= area->y;
|
||||||
cursor_position.x *= scale;
|
cursor_position.x *= scale;
|
||||||
@ -568,8 +557,7 @@ meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *s
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor,
|
meta_screen_cast_area_stream_src_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor)
|
||||||
MetaCursorSprite *cursor_sprite)
|
|
||||||
{
|
{
|
||||||
MetaScreenCastAreaStreamSrc *area_src =
|
MetaScreenCastAreaStreamSrc *area_src =
|
||||||
META_SCREEN_CAST_AREA_STREAM_SRC (inhibitor);
|
META_SCREEN_CAST_AREA_STREAM_SRC (inhibitor);
|
||||||
@ -580,8 +568,8 @@ meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibit
|
|||||||
static void
|
static void
|
||||||
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
|
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
|
||||||
{
|
{
|
||||||
iface->is_cursor_sprite_inhibited =
|
iface->is_cursor_inhibited =
|
||||||
meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited;
|
meta_screen_cast_area_stream_src_is_cursor_inhibited;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaScreenCastAreaStreamSrc *
|
MetaScreenCastAreaStreamSrc *
|
||||||
|
@ -170,9 +170,11 @@ is_cursor_in_stream (MetaScreenCastMonitorStreamSrc *monitor_src)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
graphene_point_t cursor_position;
|
graphene_point_t cursor_position;
|
||||||
|
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
return graphene_rect_contains_point (&logical_monitor_rect,
|
return graphene_rect_contains_point (&logical_monitor_rect,
|
||||||
&cursor_position);
|
&cursor_position);
|
||||||
}
|
}
|
||||||
@ -221,8 +223,6 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
cursor_moved (MetaCursorTracker *cursor_tracker,
|
cursor_moved (MetaCursorTracker *cursor_tracker,
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
MetaScreenCastMonitorStreamSrc *monitor_src)
|
MetaScreenCastMonitorStreamSrc *monitor_src)
|
||||||
{
|
{
|
||||||
sync_cursor_state (monitor_src);
|
sync_cursor_state (monitor_src);
|
||||||
@ -236,30 +236,17 @@ cursor_changed (MetaCursorTracker *cursor_tracker,
|
|||||||
sync_cursor_state (monitor_src);
|
sync_cursor_state (monitor_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorRenderer *
|
|
||||||
get_cursor_renderer (MetaScreenCastMonitorStreamSrc *monitor_src)
|
|
||||||
{
|
|
||||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
|
|
||||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
|
||||||
MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream);
|
|
||||||
MetaScreenCast *screen_cast =
|
|
||||||
meta_screen_cast_session_get_screen_cast (session);
|
|
||||||
MetaBackend *backend = meta_screen_cast_get_backend (screen_cast);
|
|
||||||
|
|
||||||
return meta_backend_get_cursor_renderer (backend);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
|
inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
|
||||||
{
|
{
|
||||||
MetaCursorRenderer *cursor_renderer;
|
|
||||||
MetaHwCursorInhibitor *inhibitor;
|
MetaHwCursorInhibitor *inhibitor;
|
||||||
|
MetaBackend *backend;
|
||||||
|
|
||||||
g_return_if_fail (!monitor_src->hw_cursor_inhibited);
|
g_return_if_fail (!monitor_src->hw_cursor_inhibited);
|
||||||
|
|
||||||
cursor_renderer = get_cursor_renderer (monitor_src);
|
backend = get_backend (monitor_src);
|
||||||
inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
|
inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
|
||||||
meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor);
|
meta_backend_add_hw_cursor_inhibitor (backend, inhibitor);
|
||||||
|
|
||||||
monitor_src->hw_cursor_inhibited = TRUE;
|
monitor_src->hw_cursor_inhibited = TRUE;
|
||||||
}
|
}
|
||||||
@ -267,14 +254,14 @@ inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
|
|||||||
static void
|
static void
|
||||||
uninhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
|
uninhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
|
||||||
{
|
{
|
||||||
MetaCursorRenderer *cursor_renderer;
|
|
||||||
MetaHwCursorInhibitor *inhibitor;
|
MetaHwCursorInhibitor *inhibitor;
|
||||||
|
MetaBackend *backend;
|
||||||
|
|
||||||
g_return_if_fail (monitor_src->hw_cursor_inhibited);
|
g_return_if_fail (monitor_src->hw_cursor_inhibited);
|
||||||
|
|
||||||
cursor_renderer = get_cursor_renderer (monitor_src);
|
backend = get_backend (monitor_src);
|
||||||
inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
|
inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
|
||||||
meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor);
|
meta_backend_remove_hw_cursor_inhibitor (backend, inhibitor);
|
||||||
|
|
||||||
monitor_src->hw_cursor_inhibited = FALSE;
|
monitor_src->hw_cursor_inhibited = FALSE;
|
||||||
}
|
}
|
||||||
@ -598,6 +585,8 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc
|
|||||||
MetaBackend *backend = get_backend (monitor_src);
|
MetaBackend *backend = get_backend (monitor_src);
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorRenderer *cursor_renderer =
|
||||||
meta_backend_get_cursor_renderer (backend);
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
MetaCursorSprite *cursor_sprite;
|
MetaCursorSprite *cursor_sprite;
|
||||||
MetaMonitor *monitor;
|
MetaMonitor *monitor;
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
@ -627,7 +616,7 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc
|
|||||||
else
|
else
|
||||||
view_scale = 1.0;
|
view_scale = 1.0;
|
||||||
|
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
cursor_position.x -= logical_monitor_rect.origin.x;
|
cursor_position.x -= logical_monitor_rect.origin.x;
|
||||||
cursor_position.y -= logical_monitor_rect.origin.y;
|
cursor_position.y -= logical_monitor_rect.origin.y;
|
||||||
cursor_position.x *= view_scale;
|
cursor_position.x *= view_scale;
|
||||||
@ -669,8 +658,7 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor,
|
meta_screen_cast_monitor_stream_src_is_cursor_inhibited (MetaHwCursorInhibitor *inhibitor)
|
||||||
MetaCursorSprite *cursor_sprite)
|
|
||||||
{
|
{
|
||||||
MetaScreenCastMonitorStreamSrc *monitor_src =
|
MetaScreenCastMonitorStreamSrc *monitor_src =
|
||||||
META_SCREEN_CAST_MONITOR_STREAM_SRC (inhibitor);
|
META_SCREEN_CAST_MONITOR_STREAM_SRC (inhibitor);
|
||||||
@ -681,8 +669,8 @@ meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhi
|
|||||||
static void
|
static void
|
||||||
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
|
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
|
||||||
{
|
{
|
||||||
iface->is_cursor_sprite_inhibited =
|
iface->is_cursor_inhibited =
|
||||||
meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited;
|
meta_screen_cast_monitor_stream_src_is_cursor_inhibited;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaScreenCastMonitorStreamSrc *
|
MetaScreenCastMonitorStreamSrc *
|
||||||
|
@ -110,6 +110,8 @@ maybe_draw_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src,
|
|||||||
MetaBackend *backend = get_backend (window_src);
|
MetaBackend *backend = get_backend (window_src);
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorRenderer *cursor_renderer =
|
||||||
meta_backend_get_cursor_renderer (backend);
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
MetaCursorSprite *cursor_sprite;
|
MetaCursorSprite *cursor_sprite;
|
||||||
CoglTexture *cursor_texture;
|
CoglTexture *cursor_texture;
|
||||||
MetaScreenCastWindow *screen_cast_window;
|
MetaScreenCastWindow *screen_cast_window;
|
||||||
@ -133,7 +135,7 @@ maybe_draw_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
screen_cast_window = window_src->screen_cast_window;
|
screen_cast_window = window_src->screen_cast_window;
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
||||||
cursor_sprite,
|
cursor_sprite,
|
||||||
&cursor_position,
|
&cursor_position,
|
||||||
@ -189,6 +191,8 @@ maybe_blit_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src,
|
|||||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorRenderer *cursor_renderer =
|
||||||
meta_backend_get_cursor_renderer (backend);
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
MetaScreenCastWindow *screen_cast_window;
|
MetaScreenCastWindow *screen_cast_window;
|
||||||
MetaCursorSprite *cursor_sprite;
|
MetaCursorSprite *cursor_sprite;
|
||||||
graphene_point_t relative_cursor_position;
|
graphene_point_t relative_cursor_position;
|
||||||
@ -209,7 +213,7 @@ maybe_blit_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
screen_cast_window = window_src->screen_cast_window;
|
screen_cast_window = window_src->screen_cast_window;
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
||||||
cursor_sprite,
|
cursor_sprite,
|
||||||
&cursor_position,
|
&cursor_position,
|
||||||
@ -360,13 +364,15 @@ is_cursor_in_stream (MetaScreenCastWindowStreamSrc *window_src)
|
|||||||
MetaBackend *backend = get_backend (window_src);
|
MetaBackend *backend = get_backend (window_src);
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorRenderer *cursor_renderer =
|
||||||
meta_backend_get_cursor_renderer (backend);
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
MetaCursorSprite *cursor_sprite;
|
MetaCursorSprite *cursor_sprite;
|
||||||
graphene_point_t cursor_position;
|
graphene_point_t cursor_position;
|
||||||
MetaScreenCastWindow *screen_cast_window;
|
MetaScreenCastWindow *screen_cast_window;
|
||||||
|
|
||||||
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
||||||
|
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
|
|
||||||
screen_cast_window = window_src->screen_cast_window;
|
screen_cast_window = window_src->screen_cast_window;
|
||||||
return meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
return meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
||||||
@ -394,8 +400,6 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
cursor_moved (MetaCursorTracker *cursor_tracker,
|
cursor_moved (MetaCursorTracker *cursor_tracker,
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
MetaScreenCastWindowStreamSrc *window_src)
|
MetaScreenCastWindowStreamSrc *window_src)
|
||||||
{
|
{
|
||||||
sync_cursor_state (window_src);
|
sync_cursor_state (window_src);
|
||||||
@ -541,6 +545,8 @@ meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc
|
|||||||
MetaBackend *backend = get_backend (window_src);
|
MetaBackend *backend = get_backend (window_src);
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorRenderer *cursor_renderer =
|
||||||
meta_backend_get_cursor_renderer (backend);
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaCursorTracker *cursor_tracker =
|
||||||
|
meta_backend_get_cursor_tracker (backend);
|
||||||
MetaScreenCastWindow *screen_cast_window = window_src->screen_cast_window;
|
MetaScreenCastWindow *screen_cast_window = window_src->screen_cast_window;
|
||||||
MetaCursorSprite *cursor_sprite;
|
MetaCursorSprite *cursor_sprite;
|
||||||
graphene_point_t cursor_position;
|
graphene_point_t cursor_position;
|
||||||
@ -549,7 +555,7 @@ meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc
|
|||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
||||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &cursor_position, NULL);
|
||||||
|
|
||||||
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
||||||
cursor_sprite,
|
cursor_sprite,
|
||||||
|
212
src/backends/meta-viewport-info.c
Normal file
212
src/backends/meta-viewport-info.c
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "meta-viewport-info.h"
|
||||||
|
#include "core/main-private.h"
|
||||||
|
#include "core/boxes-private.h"
|
||||||
|
|
||||||
|
typedef struct _ViewInfo ViewInfo;
|
||||||
|
|
||||||
|
struct _ViewInfo
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _MetaViewportInfo
|
||||||
|
{
|
||||||
|
GObject parent_class;
|
||||||
|
GArray *views;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaViewportInfo, meta_viewport_info, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_viewport_info_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MetaViewportInfo *info = META_VIEWPORT_INFO (object);
|
||||||
|
|
||||||
|
g_array_unref (info->views);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_viewport_info_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_viewport_info_class_init (MetaViewportInfoClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = meta_viewport_info_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_viewport_info_init (MetaViewportInfo *info)
|
||||||
|
{
|
||||||
|
info->views = g_array_new (FALSE, FALSE, sizeof (ViewInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaViewportInfo *
|
||||||
|
meta_viewport_info_new (cairo_rectangle_int_t *views,
|
||||||
|
float *scales,
|
||||||
|
guint n_views)
|
||||||
|
{
|
||||||
|
MetaViewportInfo *viewport_info;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
viewport_info = g_object_new (META_TYPE_VIEWPORT_INFO, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < n_views; i++)
|
||||||
|
{
|
||||||
|
ViewInfo info;
|
||||||
|
|
||||||
|
info.rect = views[i];
|
||||||
|
info.scale = scales[i];
|
||||||
|
g_array_append_val (viewport_info->views, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewport_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_viewport_info_get_view_at (MetaViewportInfo *viewport_info,
|
||||||
|
float x,
|
||||||
|
float y)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < viewport_info->views->len; i++)
|
||||||
|
{
|
||||||
|
ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
|
||||||
|
|
||||||
|
if (META_POINT_IN_RECT (x, y, info->rect))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_viewport_info_get_view (MetaViewportInfo *viewport_info,
|
||||||
|
int idx,
|
||||||
|
cairo_rectangle_int_t *rect,
|
||||||
|
float *scale)
|
||||||
|
{
|
||||||
|
ViewInfo *info;
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= viewport_info->views->len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
info = &g_array_index (viewport_info->views, ViewInfo, idx);
|
||||||
|
if (rect)
|
||||||
|
*rect = info->rect;
|
||||||
|
if (scale)
|
||||||
|
*scale = info->scale;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
view_has_neighbor (cairo_rectangle_int_t *view,
|
||||||
|
cairo_rectangle_int_t *neighbor,
|
||||||
|
MetaDisplayDirection neighbor_direction)
|
||||||
|
{
|
||||||
|
switch (neighbor_direction)
|
||||||
|
{
|
||||||
|
case META_DISPLAY_RIGHT:
|
||||||
|
if (neighbor->x == (view->x + view->width) &&
|
||||||
|
meta_rectangle_vert_overlap (neighbor, view))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case META_DISPLAY_LEFT:
|
||||||
|
if (view->x == (neighbor->x + neighbor->width) &&
|
||||||
|
meta_rectangle_vert_overlap (neighbor, view))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case META_DISPLAY_UP:
|
||||||
|
if (view->y == (neighbor->y + neighbor->height) &&
|
||||||
|
meta_rectangle_horiz_overlap (neighbor, view))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case META_DISPLAY_DOWN:
|
||||||
|
if (neighbor->y == (view->y + view->height) &&
|
||||||
|
meta_rectangle_horiz_overlap (neighbor, view))
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_viewport_info_get_neighbor (MetaViewportInfo *viewport_info,
|
||||||
|
int idx,
|
||||||
|
MetaDisplayDirection direction)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!meta_viewport_info_get_view (viewport_info, idx, &rect, NULL))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < viewport_info->views->len; i++)
|
||||||
|
{
|
||||||
|
ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
|
||||||
|
|
||||||
|
if (idx == i)
|
||||||
|
continue;
|
||||||
|
if (view_has_neighbor (&rect, &info->rect, direction))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_viewport_info_get_num_views (MetaViewportInfo *info)
|
||||||
|
{
|
||||||
|
return info->views->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_viewport_info_get_extents (MetaViewportInfo *viewport_info,
|
||||||
|
float *width,
|
||||||
|
float *height)
|
||||||
|
{
|
||||||
|
int min_x = G_MAXINT, min_y = G_MAXINT, max_x = G_MININT, max_y = G_MININT, i;
|
||||||
|
|
||||||
|
for (i = 0; i < viewport_info->views->len; i++)
|
||||||
|
{
|
||||||
|
ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
|
||||||
|
|
||||||
|
min_x = MIN (min_x, info->rect.x);
|
||||||
|
max_x = MAX (max_x, info->rect.x + info->rect.width);
|
||||||
|
min_y = MIN (min_y, info->rect.y);
|
||||||
|
max_y = MAX (max_y, info->rect.y + info->rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width)
|
||||||
|
*width = (float) max_x - min_x;
|
||||||
|
if (height)
|
||||||
|
*height = (float) max_y - min_y;
|
||||||
|
}
|
57
src/backends/meta-viewport-info.h
Normal file
57
src/backends/meta-viewport-info.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_VIEWPORT_INFO_H
|
||||||
|
#define META_VIEWPORT_INFO_H
|
||||||
|
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "meta/display.h"
|
||||||
|
|
||||||
|
#define META_TYPE_VIEWPORT_INFO (meta_viewport_info_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaViewportInfo, meta_viewport_info,
|
||||||
|
META, VIEWPORT_INFO, GObject)
|
||||||
|
|
||||||
|
MetaViewportInfo * meta_viewport_info_new (cairo_rectangle_int_t *views,
|
||||||
|
float *scales,
|
||||||
|
guint n_views);
|
||||||
|
|
||||||
|
int meta_viewport_info_get_view_at (MetaViewportInfo *info,
|
||||||
|
float x,
|
||||||
|
float y);
|
||||||
|
|
||||||
|
gboolean meta_viewport_info_get_view (MetaViewportInfo *viewport_info,
|
||||||
|
int idx,
|
||||||
|
cairo_rectangle_int_t *rect,
|
||||||
|
float *scale);
|
||||||
|
|
||||||
|
int meta_viewport_info_get_neighbor (MetaViewportInfo *info,
|
||||||
|
int idx,
|
||||||
|
MetaDisplayDirection direction);
|
||||||
|
int meta_viewport_info_get_num_views (MetaViewportInfo *info);
|
||||||
|
|
||||||
|
void meta_viewport_info_get_extents (MetaViewportInfo *info,
|
||||||
|
float *width,
|
||||||
|
float *height);
|
||||||
|
|
||||||
|
#endif /* META_VIEWPORT_INFO_H */
|
@ -22,5 +22,6 @@
|
|||||||
#define META_BACKEND_NATIVE_TYPES_H
|
#define META_BACKEND_NATIVE_TYPES_H
|
||||||
|
|
||||||
typedef struct _MetaBackendNative MetaBackendNative;
|
typedef struct _MetaBackendNative MetaBackendNative;
|
||||||
|
typedef struct _MetaSeatNative MetaSeatNative;
|
||||||
|
|
||||||
#endif /* META_BACKEND_NATIVE_TYPES_H */
|
#endif /* META_BACKEND_NATIVE_TYPES_H */
|
||||||
|
@ -48,10 +48,9 @@
|
|||||||
#include "backends/meta-pointer-constraint.h"
|
#include "backends/meta-pointer-constraint.h"
|
||||||
#include "backends/meta-settings-private.h"
|
#include "backends/meta-settings-private.h"
|
||||||
#include "backends/meta-stage-private.h"
|
#include "backends/meta-stage-private.h"
|
||||||
#include "backends/native/meta-barrier-native.h"
|
|
||||||
#include "backends/native/meta-clutter-backend-native.h"
|
#include "backends/native/meta-clutter-backend-native.h"
|
||||||
#include "backends/native/meta-cursor-renderer-native.h"
|
|
||||||
#include "backends/native/meta-event-native.h"
|
#include "backends/native/meta-event-native.h"
|
||||||
|
#include "backends/native/meta-input-device-native.h"
|
||||||
#include "backends/native/meta-input-settings-native.h"
|
#include "backends/native/meta-input-settings-native.h"
|
||||||
#include "backends/native/meta-kms.h"
|
#include "backends/native/meta-kms.h"
|
||||||
#include "backends/native/meta-kms-device.h"
|
#include "backends/native/meta-kms-device.h"
|
||||||
@ -71,7 +70,7 @@ struct _MetaBackendNative
|
|||||||
MetaLauncher *launcher;
|
MetaLauncher *launcher;
|
||||||
MetaUdev *udev;
|
MetaUdev *udev;
|
||||||
MetaKms *kms;
|
MetaKms *kms;
|
||||||
MetaBarrierManagerNative *barrier_manager;
|
MetaInputSettings *input_settings;
|
||||||
|
|
||||||
gulong udev_device_added_handler_id;
|
gulong udev_device_added_handler_id;
|
||||||
};
|
};
|
||||||
@ -99,239 +98,11 @@ meta_backend_native_finalize (GObject *object)
|
|||||||
g_clear_object (&native->udev);
|
g_clear_object (&native->udev);
|
||||||
g_clear_object (&native->kms);
|
g_clear_object (&native->kms);
|
||||||
meta_launcher_free (native->launcher);
|
meta_launcher_free (native->launcher);
|
||||||
|
g_clear_object (&native->input_settings);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
constrain_to_barriers (ClutterInputDevice *device,
|
|
||||||
guint32 time,
|
|
||||||
float *new_x,
|
|
||||||
float *new_y)
|
|
||||||
{
|
|
||||||
MetaBackendNative *native = META_BACKEND_NATIVE (meta_get_backend ());
|
|
||||||
|
|
||||||
meta_barrier_manager_native_process (native->barrier_manager,
|
|
||||||
device,
|
|
||||||
time,
|
|
||||||
new_x, new_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
constrain_to_client_constraint (ClutterInputDevice *device,
|
|
||||||
guint32 time,
|
|
||||||
float prev_x,
|
|
||||||
float prev_y,
|
|
||||||
float *x,
|
|
||||||
float *y)
|
|
||||||
{
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
MetaPointerConstraint *constraint =
|
|
||||||
meta_backend_get_client_pointer_constraint (backend);
|
|
||||||
|
|
||||||
if (!constraint)
|
|
||||||
return;
|
|
||||||
|
|
||||||
meta_pointer_constraint_constrain (constraint, device,
|
|
||||||
time, prev_x, prev_y, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The pointer constrain code is mostly a rip-off of the XRandR code from Xorg.
|
|
||||||
* (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder)
|
|
||||||
*
|
|
||||||
* Copyright © 2006 Keith Packard
|
|
||||||
* Copyright 2010 Red Hat, Inc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
constrain_all_screen_monitors (ClutterInputDevice *device,
|
|
||||||
MetaMonitorManager *monitor_manager,
|
|
||||||
float *x,
|
|
||||||
float *y)
|
|
||||||
{
|
|
||||||
graphene_point_t current;
|
|
||||||
float cx, cy;
|
|
||||||
GList *logical_monitors, *l;
|
|
||||||
|
|
||||||
clutter_input_device_get_coords (device, NULL, ¤t);
|
|
||||||
|
|
||||||
cx = current.x;
|
|
||||||
cy = current.y;
|
|
||||||
|
|
||||||
/* if we're trying to escape, clamp to the CRTC we're coming from */
|
|
||||||
|
|
||||||
logical_monitors =
|
|
||||||
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
|
||||||
for (l = logical_monitors; l; l = l->next)
|
|
||||||
{
|
|
||||||
MetaLogicalMonitor *logical_monitor = l->data;
|
|
||||||
int left, right, top, bottom;
|
|
||||||
|
|
||||||
left = logical_monitor->rect.x;
|
|
||||||
right = left + logical_monitor->rect.width;
|
|
||||||
top = logical_monitor->rect.y;
|
|
||||||
bottom = top + logical_monitor->rect.height;
|
|
||||||
|
|
||||||
if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom))
|
|
||||||
{
|
|
||||||
if (*x < left)
|
|
||||||
*x = left;
|
|
||||||
if (*x >= right)
|
|
||||||
*x = right - 1;
|
|
||||||
if (*y < top)
|
|
||||||
*y = top;
|
|
||||||
if (*y >= bottom)
|
|
||||||
*y = bottom - 1;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pointer_constrain_callback (ClutterInputDevice *device,
|
|
||||||
guint32 time,
|
|
||||||
float prev_x,
|
|
||||||
float prev_y,
|
|
||||||
float *new_x,
|
|
||||||
float *new_y,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
|
|
||||||
/* Constrain to barriers */
|
|
||||||
constrain_to_barriers (device, time, new_x, new_y);
|
|
||||||
|
|
||||||
/* Constrain to pointer lock */
|
|
||||||
constrain_to_client_constraint (device, time, prev_x, prev_y, new_x, new_y);
|
|
||||||
|
|
||||||
/* if we're moving inside a monitor, we're fine */
|
|
||||||
if (meta_monitor_manager_get_logical_monitor_at (monitor_manager,
|
|
||||||
*new_x, *new_y))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* if we're trying to escape, clamp to the CRTC we're coming from */
|
|
||||||
constrain_all_screen_monitors (device, monitor_manager, new_x, new_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
relative_motion_across_outputs (MetaMonitorManager *monitor_manager,
|
|
||||||
MetaLogicalMonitor *current,
|
|
||||||
float cur_x,
|
|
||||||
float cur_y,
|
|
||||||
float *dx_inout,
|
|
||||||
float *dy_inout)
|
|
||||||
{
|
|
||||||
MetaLogicalMonitor *cur = current;
|
|
||||||
float x = cur_x, y = cur_y;
|
|
||||||
float target_x = cur_x, target_y = cur_y;
|
|
||||||
float dx = *dx_inout, dy = *dy_inout;
|
|
||||||
MetaDisplayDirection direction = -1;
|
|
||||||
|
|
||||||
while (cur)
|
|
||||||
{
|
|
||||||
MetaLine2 left, right, top, bottom, motion;
|
|
||||||
MetaVector2 intersection;
|
|
||||||
|
|
||||||
motion = (MetaLine2) {
|
|
||||||
.a = { x, y },
|
|
||||||
.b = { x + (dx * cur->scale), y + (dy * cur->scale) }
|
|
||||||
};
|
|
||||||
left = (MetaLine2) {
|
|
||||||
{ cur->rect.x, cur->rect.y },
|
|
||||||
{ cur->rect.x, cur->rect.y + cur->rect.height }
|
|
||||||
};
|
|
||||||
right = (MetaLine2) {
|
|
||||||
{ cur->rect.x + cur->rect.width, cur->rect.y },
|
|
||||||
{ cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height }
|
|
||||||
};
|
|
||||||
top = (MetaLine2) {
|
|
||||||
{ cur->rect.x, cur->rect.y },
|
|
||||||
{ cur->rect.x + cur->rect.width, cur->rect.y }
|
|
||||||
};
|
|
||||||
bottom = (MetaLine2) {
|
|
||||||
{ cur->rect.x, cur->rect.y + cur->rect.height },
|
|
||||||
{ cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height }
|
|
||||||
};
|
|
||||||
|
|
||||||
target_x = motion.b.x;
|
|
||||||
target_y = motion.b.y;
|
|
||||||
|
|
||||||
if (direction != META_DISPLAY_RIGHT &&
|
|
||||||
meta_line2_intersects_with (&motion, &left, &intersection))
|
|
||||||
direction = META_DISPLAY_LEFT;
|
|
||||||
else if (direction != META_DISPLAY_LEFT &&
|
|
||||||
meta_line2_intersects_with (&motion, &right, &intersection))
|
|
||||||
direction = META_DISPLAY_RIGHT;
|
|
||||||
else if (direction != META_DISPLAY_DOWN &&
|
|
||||||
meta_line2_intersects_with (&motion, &top, &intersection))
|
|
||||||
direction = META_DISPLAY_UP;
|
|
||||||
else if (direction != META_DISPLAY_UP &&
|
|
||||||
meta_line2_intersects_with (&motion, &bottom, &intersection))
|
|
||||||
direction = META_DISPLAY_DOWN;
|
|
||||||
else
|
|
||||||
/* We reached the dest logical monitor */
|
|
||||||
break;
|
|
||||||
|
|
||||||
x = intersection.x;
|
|
||||||
y = intersection.y;
|
|
||||||
dx -= intersection.x - motion.a.x;
|
|
||||||
dy -= intersection.y - motion.a.y;
|
|
||||||
|
|
||||||
cur = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager,
|
|
||||||
cur, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
*dx_inout = target_x - cur_x;
|
|
||||||
*dy_inout = target_y - cur_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
relative_motion_filter (ClutterInputDevice *device,
|
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
float *dx,
|
|
||||||
float *dy,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaMonitorManager *monitor_manager = user_data;
|
|
||||||
MetaLogicalMonitor *logical_monitor, *dest_logical_monitor;
|
|
||||||
float new_dx, new_dy;
|
|
||||||
|
|
||||||
if (meta_is_stage_views_scaled ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager,
|
|
||||||
x, y);
|
|
||||||
if (!logical_monitor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
new_dx = (*dx) * logical_monitor->scale;
|
|
||||||
new_dy = (*dy) * logical_monitor->scale;
|
|
||||||
|
|
||||||
dest_logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager,
|
|
||||||
x + new_dx,
|
|
||||||
y + new_dy);
|
|
||||||
if (dest_logical_monitor &&
|
|
||||||
dest_logical_monitor != logical_monitor)
|
|
||||||
{
|
|
||||||
/* If we are crossing monitors, attempt to bisect the distance on each
|
|
||||||
* axis and apply the relative scale for each of them.
|
|
||||||
*/
|
|
||||||
new_dx = *dx;
|
|
||||||
new_dy = *dy;
|
|
||||||
relative_motion_across_outputs (monitor_manager, logical_monitor,
|
|
||||||
x, y, &new_dx, &new_dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
*dx = new_dx;
|
|
||||||
*dy = new_dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ClutterBackend *
|
static ClutterBackend *
|
||||||
meta_backend_native_create_clutter_backend (MetaBackend *backend)
|
meta_backend_native_create_clutter_backend (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
@ -339,18 +110,47 @@ meta_backend_native_create_clutter_backend (MetaBackend *backend)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_backend_native_post_init (MetaBackend *backend)
|
update_viewports (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaMonitorManager *monitor_manager =
|
||||||
|
meta_backend_get_monitor_manager (backend);
|
||||||
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
MetaSeatNative *seat =
|
||||||
|
META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
|
||||||
|
MetaViewportInfo *viewports;
|
||||||
|
|
||||||
|
viewports = meta_monitor_manager_get_viewports (monitor_manager);
|
||||||
|
meta_seat_native_set_viewports (seat, viewports);
|
||||||
|
g_object_unref (viewports);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kbd_a11y_changed_cb (MetaInputSettings *input_settings,
|
||||||
|
MetaKbdA11ySettings *a11y_settings,
|
||||||
|
MetaBackend *backend)
|
||||||
{
|
{
|
||||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
||||||
MetaSettings *settings = meta_backend_get_settings (backend);
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
meta_seat_native_set_pointer_constrain_callback (META_SEAT_NATIVE (seat),
|
device = clutter_seat_get_keyboard (seat);
|
||||||
pointer_constrain_callback,
|
if (device)
|
||||||
NULL, NULL);
|
meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device),
|
||||||
meta_seat_native_set_relative_motion_filter (META_SEAT_NATIVE (seat),
|
a11y_settings);
|
||||||
relative_motion_filter,
|
}
|
||||||
meta_backend_get_monitor_manager (backend));
|
|
||||||
|
static void
|
||||||
|
meta_backend_native_post_init (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendNative *native = META_BACKEND_NATIVE (backend);
|
||||||
|
MetaSettings *settings = meta_backend_get_settings (backend);
|
||||||
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
MetaSeatNative *seat =
|
||||||
|
META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
|
||||||
|
|
||||||
|
native->input_settings = meta_seat_impl_get_input_settings (seat->impl);
|
||||||
|
g_signal_connect_object (native->input_settings, "kbd-a11y-changed",
|
||||||
|
G_CALLBACK (kbd_a11y_changed_cb), backend, 0);
|
||||||
|
|
||||||
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
|
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
|
||||||
|
|
||||||
@ -368,6 +168,8 @@ meta_backend_native_post_init (MetaBackend *backend)
|
|||||||
g_warning ("Failed to set RT scheduler: %m");
|
g_warning ("Failed to set RT scheduler: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_viewports (backend);
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND
|
#ifdef HAVE_WAYLAND
|
||||||
meta_backend_init_wayland (backend);
|
meta_backend_init_wayland (backend);
|
||||||
#endif
|
#endif
|
||||||
@ -377,15 +179,26 @@ static MetaMonitorManager *
|
|||||||
meta_backend_native_create_monitor_manager (MetaBackend *backend,
|
meta_backend_native_create_monitor_manager (MetaBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error,
|
MetaMonitorManager *manager;
|
||||||
"backend", backend,
|
|
||||||
NULL);
|
manager = g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error,
|
||||||
|
"backend", backend,
|
||||||
|
NULL);
|
||||||
|
g_signal_connect_swapped (manager, "monitors-changed-internal",
|
||||||
|
G_CALLBACK (update_viewports), backend);
|
||||||
|
|
||||||
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorRenderer *
|
static MetaCursorRenderer *
|
||||||
meta_backend_native_create_cursor_renderer (MetaBackend *backend)
|
meta_backend_native_get_cursor_renderer (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
return META_CURSOR_RENDERER (meta_cursor_renderer_native_new (backend));
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
MetaSeatNative *seat =
|
||||||
|
META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
|
||||||
|
|
||||||
|
return meta_seat_native_get_cursor_renderer (seat, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaRenderer *
|
static MetaRenderer *
|
||||||
@ -405,7 +218,9 @@ meta_backend_native_create_renderer (MetaBackend *backend,
|
|||||||
static MetaInputSettings *
|
static MetaInputSettings *
|
||||||
meta_backend_native_create_input_settings (MetaBackend *backend)
|
meta_backend_native_create_input_settings (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
|
MetaBackendNative *native = META_BACKEND_NATIVE (backend);
|
||||||
|
|
||||||
|
return native->input_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaLogicalMonitor *
|
static MetaLogicalMonitor *
|
||||||
@ -414,10 +229,11 @@ meta_backend_native_get_current_logical_monitor (MetaBackend *backend)
|
|||||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
MetaMonitorManager *monitor_manager =
|
MetaMonitorManager *monitor_manager =
|
||||||
meta_backend_get_monitor_manager (backend);
|
meta_backend_get_monitor_manager (backend);
|
||||||
int x, y;
|
graphene_point_t point;
|
||||||
|
|
||||||
meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||||
return meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
|
return meta_monitor_manager_get_logical_monitor_at (monitor_manager,
|
||||||
|
point.x, point.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -427,27 +243,13 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
|||||||
const char *options)
|
const char *options)
|
||||||
{
|
{
|
||||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
struct xkb_rule_names names;
|
|
||||||
struct xkb_keymap *keymap;
|
|
||||||
struct xkb_context *context;
|
|
||||||
ClutterSeat *seat;
|
ClutterSeat *seat;
|
||||||
|
|
||||||
names.rules = DEFAULT_XKB_RULES_FILE;
|
|
||||||
names.model = DEFAULT_XKB_MODEL;
|
|
||||||
names.layout = layouts;
|
|
||||||
names.variant = variants;
|
|
||||||
names.options = options;
|
|
||||||
|
|
||||||
context = meta_create_xkb_context ();
|
|
||||||
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
||||||
xkb_context_unref (context);
|
|
||||||
|
|
||||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||||
meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat), keymap);
|
meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat),
|
||||||
|
layouts, variants, options);
|
||||||
|
|
||||||
meta_backend_notify_keymap_changed (backend);
|
meta_backend_notify_keymap_changed (backend);
|
||||||
|
|
||||||
xkb_keymap_unref (keymap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xkb_keymap *
|
static struct xkb_keymap *
|
||||||
@ -499,6 +301,25 @@ meta_backend_native_set_numlock (MetaBackend *backend,
|
|||||||
numlock_state);
|
numlock_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_backend_native_set_pointer_constraint (MetaBackend *backend,
|
||||||
|
MetaPointerConstraint *constraint)
|
||||||
|
{
|
||||||
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
||||||
|
MetaPointerConstraintImpl *constraint_impl = NULL;
|
||||||
|
cairo_region_t *region;
|
||||||
|
|
||||||
|
if (constraint)
|
||||||
|
{
|
||||||
|
region = meta_pointer_constraint_get_region (constraint);
|
||||||
|
constraint_impl = meta_pointer_constraint_impl_native_new (constraint, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_seat_native_set_pointer_constraint (META_SEAT_NATIVE (seat),
|
||||||
|
constraint_impl);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_backend_native_update_screen_size (MetaBackend *backend,
|
meta_backend_native_update_screen_size (MetaBackend *backend,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
@ -662,7 +483,6 @@ meta_backend_native_initable_init (GInitable *initable,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
native->udev = meta_udev_new (native);
|
native->udev = meta_udev_new (native);
|
||||||
native->barrier_manager = meta_barrier_manager_native_new ();
|
|
||||||
|
|
||||||
native->kms = meta_kms_new (META_BACKEND (native), error);
|
native->kms = meta_kms_new (META_BACKEND (native), error);
|
||||||
if (!native->kms)
|
if (!native->kms)
|
||||||
@ -695,7 +515,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
|||||||
backend_class->post_init = meta_backend_native_post_init;
|
backend_class->post_init = meta_backend_native_post_init;
|
||||||
|
|
||||||
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
|
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
|
||||||
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
|
backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer;
|
||||||
backend_class->create_renderer = meta_backend_native_create_renderer;
|
backend_class->create_renderer = meta_backend_native_create_renderer;
|
||||||
backend_class->create_input_settings = meta_backend_native_create_input_settings;
|
backend_class->create_input_settings = meta_backend_native_create_input_settings;
|
||||||
|
|
||||||
@ -707,6 +527,8 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
|||||||
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
|
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
|
||||||
backend_class->update_screen_size = meta_backend_native_update_screen_size;
|
backend_class->update_screen_size = meta_backend_native_update_screen_size;
|
||||||
backend_class->set_numlock = meta_backend_native_set_numlock;
|
backend_class->set_numlock = meta_backend_native_set_numlock;
|
||||||
|
|
||||||
|
backend_class->set_pointer_constraint = meta_backend_native_set_pointer_constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -742,12 +564,6 @@ meta_activate_vt (int vt, GError **error)
|
|||||||
return meta_launcher_activate_vt (launcher, vt, error);
|
return meta_launcher_activate_vt (launcher, vt, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaBarrierManagerNative *
|
|
||||||
meta_backend_native_get_barrier_manager (MetaBackendNative *native)
|
|
||||||
{
|
|
||||||
return native->barrier_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_activate_session:
|
* meta_activate_session:
|
||||||
*
|
*
|
||||||
@ -809,7 +625,6 @@ void meta_backend_native_resume (MetaBackendNative *native)
|
|||||||
meta_backend_get_monitor_manager (backend);
|
meta_backend_get_monitor_manager (backend);
|
||||||
MetaMonitorManagerKms *monitor_manager_kms =
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||||
MetaInputSettings *input_settings;
|
|
||||||
MetaIdleMonitor *idle_monitor;
|
MetaIdleMonitor *idle_monitor;
|
||||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
MetaSeatNative *seat =
|
MetaSeatNative *seat =
|
||||||
@ -831,8 +646,7 @@ void meta_backend_native_resume (MetaBackendNative *native)
|
|||||||
idle_monitor = meta_idle_monitor_get_core ();
|
idle_monitor = meta_idle_monitor_get_core ();
|
||||||
meta_idle_monitor_reset_idletime (idle_monitor);
|
meta_idle_monitor_reset_idletime (idle_monitor);
|
||||||
|
|
||||||
input_settings = meta_backend_get_input_settings (backend);
|
meta_input_settings_maybe_restore_numlock_state (native->input_settings);
|
||||||
meta_input_settings_maybe_restore_numlock_state (input_settings);
|
|
||||||
|
|
||||||
clutter_seat_ensure_a11y_state (CLUTTER_SEAT (seat));
|
clutter_seat_ensure_a11y_state (CLUTTER_SEAT (seat));
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,14 @@
|
|||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/meta-barrier-private.h"
|
#include "backends/meta-barrier-private.h"
|
||||||
#include "backends/native/meta-backend-native.h"
|
#include "backends/native/meta-seat-native.h"
|
||||||
#include "backends/native/meta-backend-native-private.h"
|
|
||||||
#include "meta/barrier.h"
|
#include "meta/barrier.h"
|
||||||
#include "meta/util.h"
|
#include "meta/util.h"
|
||||||
|
|
||||||
struct _MetaBarrierManagerNative
|
struct _MetaBarrierManagerNative
|
||||||
{
|
{
|
||||||
GHashTable *barriers;
|
GHashTable *barriers;
|
||||||
|
GMutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -78,6 +78,7 @@ struct _MetaBarrierImplNative
|
|||||||
int trigger_serial;
|
int trigger_serial;
|
||||||
guint32 last_event_time;
|
guint32 last_event_time;
|
||||||
MetaBarrierDirection blocked_dir;
|
MetaBarrierDirection blocked_dir;
|
||||||
|
GMainContext *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaBarrierImplNative,
|
G_DEFINE_TYPE (MetaBarrierImplNative,
|
||||||
@ -341,6 +342,48 @@ typedef struct _MetaBarrierEventData
|
|||||||
float dy;
|
float dy;
|
||||||
} MetaBarrierEventData;
|
} MetaBarrierEventData;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MetaBarrierEvent *event;
|
||||||
|
MetaBarrier *barrier;
|
||||||
|
MetaBarrierState state;
|
||||||
|
} MetaBarrierIdleData;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
emit_event_idle (MetaBarrierIdleData *idle_data)
|
||||||
|
{
|
||||||
|
if (idle_data->state == META_BARRIER_STATE_HELD)
|
||||||
|
_meta_barrier_emit_hit_signal (idle_data->barrier, idle_data->event);
|
||||||
|
else
|
||||||
|
_meta_barrier_emit_left_signal (idle_data->barrier, idle_data->event);
|
||||||
|
|
||||||
|
meta_barrier_event_unref (idle_data->event);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_event (MetaBarrierImplNative *self,
|
||||||
|
MetaBarrierEvent *event)
|
||||||
|
{
|
||||||
|
MetaBarrierIdleData *idle_data;
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
idle_data = g_new0 (MetaBarrierIdleData, 1);
|
||||||
|
idle_data->state = self->state;
|
||||||
|
idle_data->barrier = self->barrier;
|
||||||
|
idle_data->event = event;
|
||||||
|
|
||||||
|
source = g_idle_source_new ();
|
||||||
|
g_source_set_priority (source, G_PRIORITY_HIGH);
|
||||||
|
g_source_set_callback (source,
|
||||||
|
(GSourceFunc) emit_event_idle,
|
||||||
|
idle_data,
|
||||||
|
g_free);
|
||||||
|
|
||||||
|
g_source_attach (source, self->context);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_barrier_event (MetaBarrierImplNative *self,
|
emit_barrier_event (MetaBarrierImplNative *self,
|
||||||
guint32 time,
|
guint32 time,
|
||||||
@ -351,7 +394,6 @@ emit_barrier_event (MetaBarrierImplNative *self,
|
|||||||
float dx,
|
float dx,
|
||||||
float dy)
|
float dy)
|
||||||
{
|
{
|
||||||
MetaBarrier *barrier = self->barrier;
|
|
||||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||||
MetaBarrierState old_state = self->state;
|
MetaBarrierState old_state = self->state;
|
||||||
|
|
||||||
@ -390,12 +432,7 @@ emit_barrier_event (MetaBarrierImplNative *self,
|
|||||||
|
|
||||||
self->last_event_time = time;
|
self->last_event_time = time;
|
||||||
|
|
||||||
if (self->state == META_BARRIER_STATE_HELD)
|
emit_event (self, event);
|
||||||
_meta_barrier_emit_hit_signal (barrier, event);
|
|
||||||
else
|
|
||||||
_meta_barrier_emit_left_signal (barrier, event);
|
|
||||||
|
|
||||||
meta_barrier_event_unref (event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -480,6 +517,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
|||||||
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
|
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
g_mutex_lock (&manager->mutex);
|
||||||
|
|
||||||
prev_x = prev_pos.x;
|
prev_x = prev_pos.x;
|
||||||
prev_y = prev_pos.y;
|
prev_y = prev_pos.y;
|
||||||
|
|
||||||
@ -524,6 +563,8 @@ meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
|||||||
g_hash_table_foreach (manager->barriers,
|
g_hash_table_foreach (manager->barriers,
|
||||||
maybe_emit_barrier_event,
|
maybe_emit_barrier_event,
|
||||||
&barrier_event_data);
|
&barrier_event_data);
|
||||||
|
|
||||||
|
g_mutex_unlock (&manager->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -550,7 +591,10 @@ _meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
|
|||||||
{
|
{
|
||||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||||
|
|
||||||
|
g_mutex_lock (&self->manager->mutex);
|
||||||
g_hash_table_remove (self->manager->barriers, self);
|
g_hash_table_remove (self->manager->barriers, self);
|
||||||
|
g_mutex_unlock (&self->manager->mutex);
|
||||||
|
g_main_context_unref (self->context);
|
||||||
self->is_active = FALSE;
|
self->is_active = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,18 +602,21 @@ MetaBarrierImpl *
|
|||||||
meta_barrier_impl_native_new (MetaBarrier *barrier)
|
meta_barrier_impl_native_new (MetaBarrier *barrier)
|
||||||
{
|
{
|
||||||
MetaBarrierImplNative *self;
|
MetaBarrierImplNative *self;
|
||||||
MetaBackendNative *native;
|
|
||||||
MetaBarrierManagerNative *manager;
|
MetaBarrierManagerNative *manager;
|
||||||
|
ClutterBackend *backend = clutter_get_default_backend ();
|
||||||
|
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
|
||||||
|
|
||||||
self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);
|
self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);
|
||||||
|
|
||||||
self->barrier = barrier;
|
self->barrier = barrier;
|
||||||
self->is_active = TRUE;
|
self->is_active = TRUE;
|
||||||
|
self->context = g_main_context_ref_thread_default ();
|
||||||
|
|
||||||
native = META_BACKEND_NATIVE (meta_get_backend ());
|
manager = meta_seat_native_get_barrier_manager (META_SEAT_NATIVE (seat));
|
||||||
manager = meta_backend_native_get_barrier_manager (native);
|
|
||||||
self->manager = manager;
|
self->manager = manager;
|
||||||
|
g_mutex_lock (&manager->mutex);
|
||||||
g_hash_table_add (manager->barriers, self);
|
g_hash_table_add (manager->barriers, self);
|
||||||
|
g_mutex_unlock (&manager->mutex);
|
||||||
|
|
||||||
return META_BARRIER_IMPL (self);
|
return META_BARRIER_IMPL (self);
|
||||||
}
|
}
|
||||||
@ -597,6 +644,7 @@ meta_barrier_manager_native_new (void)
|
|||||||
manager = g_new0 (MetaBarrierManagerNative, 1);
|
manager = g_new0 (MetaBarrierManagerNative, 1);
|
||||||
|
|
||||||
manager->barriers = g_hash_table_new (NULL, NULL);
|
manager->barriers = g_hash_table_new (NULL, NULL);
|
||||||
|
g_mutex_init (&manager->mutex);
|
||||||
|
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,7 @@
|
|||||||
#define META_CURSOR_RENDERER_NATIVE_H
|
#define META_CURSOR_RENDERER_NATIVE_H
|
||||||
|
|
||||||
#include "backends/meta-cursor-renderer.h"
|
#include "backends/meta-cursor-renderer.h"
|
||||||
|
#include "backends/native/meta-kms-cursor-renderer.h"
|
||||||
#include "meta/meta-backend.h"
|
#include "meta/meta-backend.h"
|
||||||
|
|
||||||
#define META_TYPE_CURSOR_RENDERER_NATIVE (meta_cursor_renderer_native_get_type ())
|
#define META_TYPE_CURSOR_RENDERER_NATIVE (meta_cursor_renderer_native_get_type ())
|
||||||
@ -33,6 +34,10 @@ G_DECLARE_FINAL_TYPE (MetaCursorRendererNative, meta_cursor_renderer_native,
|
|||||||
META, CURSOR_RENDERER_NATIVE,
|
META, CURSOR_RENDERER_NATIVE,
|
||||||
MetaCursorRenderer)
|
MetaCursorRenderer)
|
||||||
|
|
||||||
MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend);
|
MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
|
void meta_cursor_renderer_native_set_kms_cursor_renderer (MetaCursorRendererNative *native,
|
||||||
|
MetaKmsCursorRenderer *kms_cursor_renderer);
|
||||||
|
|
||||||
#endif /* META_CURSOR_RENDERER_NATIVE_H */
|
#endif /* META_CURSOR_RENDERER_NATIVE_H */
|
||||||
|
@ -24,9 +24,10 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <cairo-gobject.h>
|
#include <cairo-gobject.h>
|
||||||
|
|
||||||
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/native/meta-input-device-tool-native.h"
|
#include "backends/native/meta-input-device-tool-native.h"
|
||||||
#include "backends/native/meta-input-device-native.h"
|
#include "backends/native/meta-input-device-native.h"
|
||||||
#include "backends/native/meta-seat-native.h"
|
#include "backends/native/meta-seat-impl.h"
|
||||||
#include "clutter/clutter-mutter.h"
|
#include "clutter/clutter-mutter.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaInputDeviceNative,
|
G_DEFINE_TYPE (MetaInputDeviceNative,
|
||||||
@ -61,19 +62,11 @@ meta_input_device_native_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (object);
|
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (object);
|
||||||
MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (object);
|
MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (object);
|
||||||
ClutterBackend *backend;
|
|
||||||
ClutterSeat *seat;
|
|
||||||
|
|
||||||
if (device_evdev->libinput_device)
|
if (device_evdev->libinput_device)
|
||||||
libinput_device_unref (device_evdev->libinput_device);
|
libinput_device_unref (device_evdev->libinput_device);
|
||||||
|
|
||||||
meta_input_device_native_release_touch_slots (device_evdev,
|
meta_seat_impl_release_device_id (device_evdev->seat_impl, device);
|
||||||
g_get_monotonic_time ());
|
|
||||||
g_clear_pointer (&device_evdev->touches, g_hash_table_unref);
|
|
||||||
|
|
||||||
backend = clutter_get_default_backend ();
|
|
||||||
seat = clutter_backend_get_default_seat (backend);
|
|
||||||
meta_seat_native_release_device_id (META_SEAT_NATIVE (seat), device);
|
|
||||||
|
|
||||||
clear_slow_keys (device_evdev);
|
clear_slow_keys (device_evdev);
|
||||||
stop_bounce_keys (device_evdev);
|
stop_bounce_keys (device_evdev);
|
||||||
@ -225,7 +218,7 @@ meta_input_device_native_is_grouped (ClutterInputDevice *device,
|
|||||||
static void
|
static void
|
||||||
meta_input_device_native_bell_notify (MetaInputDeviceNative *device)
|
meta_input_device_native_bell_notify (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
clutter_seat_bell_notify (CLUTTER_SEAT (device->seat));
|
meta_seat_impl_notify_bell (device->seat_impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -250,10 +243,11 @@ static guint
|
|||||||
get_slow_keys_delay (ClutterInputDevice *device)
|
get_slow_keys_delay (ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
|
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
|
||||||
ClutterKbdA11ySettings a11y_settings;
|
MetaKbdA11ySettings a11y_settings;
|
||||||
|
MetaInputSettings *input_settings;
|
||||||
|
|
||||||
clutter_seat_get_kbd_a11y_settings (CLUTTER_SEAT (device_native->seat),
|
input_settings = meta_seat_impl_get_input_settings (device_native->seat_impl);
|
||||||
&a11y_settings);
|
meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings);
|
||||||
/* Settings use int, we use uint, make sure we dont go negative */
|
/* Settings use int, we use uint, make sure we dont go negative */
|
||||||
return MAX (0, a11y_settings.slowkeys_delay);
|
return MAX (0, a11y_settings.slowkeys_delay);
|
||||||
}
|
}
|
||||||
@ -274,7 +268,7 @@ trigger_slow_keys (gpointer data)
|
|||||||
device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event);
|
device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event);
|
||||||
meta_input_device_native_free_pending_slow_key (slow_keys_event);
|
meta_input_device_native_free_pending_slow_key (slow_keys_event);
|
||||||
|
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT)
|
if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_ACCEPT)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
@ -312,7 +306,7 @@ start_slow_keys (ClutterEvent *event,
|
|||||||
slow_keys_event);
|
slow_keys_event);
|
||||||
device->slow_keys_list = g_list_append (device->slow_keys_list, slow_keys_event);
|
device->slow_keys_list = g_list_append (device->slow_keys_list, slow_keys_event);
|
||||||
|
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS)
|
if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_PRESS)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,7 +326,7 @@ stop_slow_keys (ClutterEvent *event,
|
|||||||
device->slow_keys_list = g_list_delete_link (device->slow_keys_list, item);
|
device->slow_keys_list = g_list_delete_link (device->slow_keys_list, item);
|
||||||
meta_input_device_native_free_pending_slow_key (slow_keys_event);
|
meta_input_device_native_free_pending_slow_key (slow_keys_event);
|
||||||
|
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT)
|
if (device->a11y_flags & META_A11Y_SLOW_KEYS_BEEP_REJECT)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -346,10 +340,11 @@ static guint
|
|||||||
get_debounce_delay (ClutterInputDevice *device)
|
get_debounce_delay (ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
|
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
|
||||||
ClutterKbdA11ySettings a11y_settings;
|
MetaKbdA11ySettings a11y_settings;
|
||||||
|
MetaInputSettings *input_settings;
|
||||||
|
|
||||||
clutter_seat_get_kbd_a11y_settings (CLUTTER_SEAT (device_native->seat),
|
input_settings = meta_seat_impl_get_input_settings (device_native->seat_impl);
|
||||||
&a11y_settings);
|
meta_input_settings_get_kbd_a11y_settings (input_settings, &a11y_settings);
|
||||||
/* Settings use int, we use uint, make sure we dont go negative */
|
/* Settings use int, we use uint, make sure we dont go negative */
|
||||||
return MAX (0, a11y_settings.debounce_delay);
|
return MAX (0, a11y_settings.debounce_delay);
|
||||||
}
|
}
|
||||||
@ -387,7 +382,7 @@ stop_bounce_keys (MetaInputDeviceNative *device)
|
|||||||
static void
|
static void
|
||||||
notify_bounce_keys_reject (MetaInputDeviceNative *device)
|
notify_bounce_keys_reject (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT)
|
if (device->a11y_flags & META_A11Y_BOUNCE_KEYS_BEEP_REJECT)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,10 +421,9 @@ key_event_is_modifier (ClutterEvent *event)
|
|||||||
static void
|
static void
|
||||||
notify_stickykeys_mask (MetaInputDeviceNative *device)
|
notify_stickykeys_mask (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
g_signal_emit_by_name (device->seat,
|
meta_seat_impl_notify_kbd_a11y_mods_state_changed (device->seat_impl,
|
||||||
"kbd-a11y-mods-state-changed",
|
device->stickykeys_latched_mask,
|
||||||
device->stickykeys_latched_mask,
|
device->stickykeys_locked_mask);
|
||||||
device->stickykeys_locked_mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -437,15 +431,19 @@ update_internal_xkb_state (MetaInputDeviceNative *device,
|
|||||||
xkb_mod_mask_t new_latched_mask,
|
xkb_mod_mask_t new_latched_mask,
|
||||||
xkb_mod_mask_t new_locked_mask)
|
xkb_mod_mask_t new_locked_mask)
|
||||||
{
|
{
|
||||||
MetaSeatNative *seat = device->seat;
|
MetaSeatImpl *seat_impl = device->seat_impl;
|
||||||
xkb_mod_mask_t depressed_mods;
|
xkb_mod_mask_t depressed_mods;
|
||||||
xkb_mod_mask_t latched_mods;
|
xkb_mod_mask_t latched_mods;
|
||||||
xkb_mod_mask_t locked_mods;
|
xkb_mod_mask_t locked_mods;
|
||||||
xkb_mod_mask_t group_mods;
|
xkb_mod_mask_t group_mods;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
|
||||||
depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
|
g_rw_lock_writer_lock (&seat_impl->state_lock);
|
||||||
latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED);
|
|
||||||
locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED);
|
xkb_state = meta_seat_impl_get_xkb_state (seat_impl);
|
||||||
|
depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||||
|
latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED);
|
||||||
|
locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED);
|
||||||
|
|
||||||
latched_mods &= ~device->stickykeys_latched_mask;
|
latched_mods &= ~device->stickykeys_latched_mask;
|
||||||
locked_mods &= ~device->stickykeys_locked_mask;
|
locked_mods &= ~device->stickykeys_locked_mask;
|
||||||
@ -456,14 +454,16 @@ update_internal_xkb_state (MetaInputDeviceNative *device,
|
|||||||
latched_mods |= device->stickykeys_latched_mask;
|
latched_mods |= device->stickykeys_latched_mask;
|
||||||
locked_mods |= device->stickykeys_locked_mask;
|
locked_mods |= device->stickykeys_locked_mask;
|
||||||
|
|
||||||
group_mods = xkb_state_serialize_layout (seat->xkb, XKB_STATE_LAYOUT_EFFECTIVE);
|
group_mods = xkb_state_serialize_layout (xkb_state, XKB_STATE_LAYOUT_EFFECTIVE);
|
||||||
|
|
||||||
xkb_state_update_mask (seat->xkb,
|
xkb_state_update_mask (xkb_state,
|
||||||
depressed_mods,
|
depressed_mods,
|
||||||
latched_mods,
|
latched_mods,
|
||||||
locked_mods,
|
locked_mods,
|
||||||
0, 0, group_mods);
|
0, 0, group_mods);
|
||||||
notify_stickykeys_mask (device);
|
notify_stickykeys_mask (device);
|
||||||
|
|
||||||
|
g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -472,23 +472,25 @@ update_stickykeys_event (ClutterEvent *event,
|
|||||||
xkb_mod_mask_t new_latched_mask,
|
xkb_mod_mask_t new_latched_mask,
|
||||||
xkb_mod_mask_t new_locked_mask)
|
xkb_mod_mask_t new_locked_mask)
|
||||||
{
|
{
|
||||||
MetaSeatNative *seat = device->seat;
|
MetaSeatImpl *seat_impl = device->seat_impl;
|
||||||
xkb_mod_mask_t effective_mods;
|
xkb_mod_mask_t effective_mods;
|
||||||
xkb_mod_mask_t latched_mods;
|
xkb_mod_mask_t latched_mods;
|
||||||
xkb_mod_mask_t locked_mods;
|
xkb_mod_mask_t locked_mods;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
|
||||||
update_internal_xkb_state (device, new_latched_mask, new_locked_mask);
|
update_internal_xkb_state (device, new_latched_mask, new_locked_mask);
|
||||||
|
|
||||||
effective_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_EFFECTIVE);
|
xkb_state = meta_seat_impl_get_xkb_state (seat_impl);
|
||||||
latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED);
|
effective_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
|
||||||
locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED);
|
latched_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED);
|
||||||
|
locked_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED);
|
||||||
|
|
||||||
_clutter_event_set_state_full (event,
|
_clutter_event_set_state_full (event,
|
||||||
seat->button_state,
|
seat_impl->button_state,
|
||||||
device->stickykeys_depressed_mask,
|
device->stickykeys_depressed_mask,
|
||||||
latched_mods,
|
latched_mods,
|
||||||
locked_mods,
|
locked_mods,
|
||||||
effective_mods | seat->button_state);
|
effective_mods | seat_impl->button_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -498,23 +500,22 @@ notify_stickykeys_change (MetaInputDeviceNative *device)
|
|||||||
device->stickykeys_depressed_mask = 0;
|
device->stickykeys_depressed_mask = 0;
|
||||||
update_internal_xkb_state (device, 0, 0);
|
update_internal_xkb_state (device, 0, 0);
|
||||||
|
|
||||||
g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat,
|
meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl,
|
||||||
"kbd-a11y-flags-changed",
|
device->a11y_flags,
|
||||||
device->a11y_flags,
|
META_A11Y_STICKY_KEYS_ENABLED);
|
||||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_stickykeys_off (MetaInputDeviceNative *device)
|
set_stickykeys_off (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
device->a11y_flags &= ~CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
device->a11y_flags &= ~META_A11Y_STICKY_KEYS_ENABLED;
|
||||||
notify_stickykeys_change (device);
|
notify_stickykeys_change (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_stickykeys_on (MetaInputDeviceNative *device)
|
set_stickykeys_on (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
device->a11y_flags |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
device->a11y_flags |= META_A11Y_STICKY_KEYS_ENABLED;
|
||||||
notify_stickykeys_change (device);
|
notify_stickykeys_change (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,45 +530,45 @@ clear_stickykeys_event (ClutterEvent *event,
|
|||||||
static void
|
static void
|
||||||
set_slowkeys_off (MetaInputDeviceNative *device)
|
set_slowkeys_off (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
device->a11y_flags &= ~CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
device->a11y_flags &= ~META_A11Y_SLOW_KEYS_ENABLED;
|
||||||
|
|
||||||
g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat,
|
meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl,
|
||||||
"kbd-a11y-flags-changed",
|
device->a11y_flags,
|
||||||
device->a11y_flags,
|
META_A11Y_SLOW_KEYS_ENABLED);
|
||||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_slowkeys_on (MetaInputDeviceNative *device)
|
set_slowkeys_on (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
device->a11y_flags |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
device->a11y_flags |= META_A11Y_SLOW_KEYS_ENABLED;
|
||||||
|
|
||||||
g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat,
|
meta_seat_impl_notify_kbd_a11y_flags_changed (device->seat_impl,
|
||||||
"kbd-a11y-flags-changed",
|
device->a11y_flags,
|
||||||
device->a11y_flags,
|
META_A11Y_SLOW_KEYS_ENABLED);
|
||||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_stickykeys_press (ClutterEvent *event,
|
handle_stickykeys_press (ClutterEvent *event,
|
||||||
MetaInputDeviceNative *device)
|
MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
MetaSeatNative *seat = device->seat;
|
MetaSeatImpl *seat_impl = device->seat_impl;
|
||||||
xkb_mod_mask_t depressed_mods;
|
xkb_mod_mask_t depressed_mods;
|
||||||
xkb_mod_mask_t new_latched_mask;
|
xkb_mod_mask_t new_latched_mask;
|
||||||
xkb_mod_mask_t new_locked_mask;
|
xkb_mod_mask_t new_locked_mask;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
|
||||||
if (!key_event_is_modifier (event))
|
if (!key_event_is_modifier (event))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (device->stickykeys_depressed_mask &&
|
if (device->stickykeys_depressed_mask &&
|
||||||
(device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF))
|
(device->a11y_flags & META_A11Y_STICKY_KEYS_TWO_KEY_OFF))
|
||||||
{
|
{
|
||||||
clear_stickykeys_event (event, device);
|
clear_stickykeys_event (event, device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
|
xkb_state = meta_seat_impl_get_xkb_state (seat_impl);
|
||||||
|
depressed_mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||||
/* Ignore the lock modifier mask, that one cannot be sticky, yet the
|
/* Ignore the lock modifier mask, that one cannot be sticky, yet the
|
||||||
* CAPS_LOCK key itself counts as a modifier as it might be remapped
|
* CAPS_LOCK key itself counts as a modifier as it might be remapped
|
||||||
* to some other modifier which can be sticky.
|
* to some other modifier which can be sticky.
|
||||||
@ -600,14 +601,16 @@ static void
|
|||||||
handle_stickykeys_release (ClutterEvent *event,
|
handle_stickykeys_release (ClutterEvent *event,
|
||||||
MetaInputDeviceNative *device)
|
MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
MetaSeatNative *seat = device->seat;
|
MetaSeatImpl *seat_impl = device->seat_impl;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
|
||||||
|
xkb_state = meta_seat_impl_get_xkb_state (seat_impl);
|
||||||
device->stickykeys_depressed_mask =
|
device->stickykeys_depressed_mask =
|
||||||
xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
|
xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||||
|
|
||||||
if (key_event_is_modifier (event))
|
if (key_event_is_modifier (event))
|
||||||
{
|
{
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_BEEP)
|
if (device->a11y_flags & META_A11Y_STICKY_KEYS_BEEP)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -626,10 +629,10 @@ trigger_toggle_slowkeys (gpointer data)
|
|||||||
|
|
||||||
device->toggle_slowkeys_timer = 0;
|
device->toggle_slowkeys_timer = 0;
|
||||||
|
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP)
|
if (device->a11y_flags & META_A11Y_FEATURE_STATE_CHANGE_BEEP)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
|
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_ENABLED)
|
if (device->a11y_flags & META_A11Y_SLOW_KEYS_ENABLED)
|
||||||
set_slowkeys_off (device);
|
set_slowkeys_off (device);
|
||||||
else
|
else
|
||||||
set_slowkeys_on (device);
|
set_slowkeys_on (device);
|
||||||
@ -688,10 +691,10 @@ handle_enablekeys_release (ClutterEvent *event,
|
|||||||
{
|
{
|
||||||
device->shift_count = 0;
|
device->shift_count = 0;
|
||||||
|
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP)
|
if (device->a11y_flags & META_A11Y_FEATURE_STATE_CHANGE_BEEP)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
|
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_ENABLED)
|
if (device->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED)
|
||||||
set_stickykeys_off (device);
|
set_stickykeys_off (device);
|
||||||
else
|
else
|
||||||
set_stickykeys_on (device);
|
set_stickykeys_on (device);
|
||||||
@ -758,8 +761,8 @@ emulate_button_click (MetaInputDeviceNative *device)
|
|||||||
#define MOUSEKEYS_CURVE (1.0 + (((double) 50.0) * 0.001))
|
#define MOUSEKEYS_CURVE (1.0 + (((double) 50.0) * 0.001))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_mousekeys_params (MetaInputDeviceNative *device,
|
update_mousekeys_params (MetaInputDeviceNative *device,
|
||||||
ClutterKbdA11ySettings *settings)
|
MetaKbdA11ySettings *settings)
|
||||||
{
|
{
|
||||||
/* Prevent us from broken settings values */
|
/* Prevent us from broken settings values */
|
||||||
device->mousekeys_max_speed = MAX (1, settings->mousekeys_max_speed);
|
device->mousekeys_max_speed = MAX (1, settings->mousekeys_max_speed);
|
||||||
@ -841,8 +844,12 @@ emulate_pointer_motion (MetaInputDeviceNative *device_evdev,
|
|||||||
static gboolean
|
static gboolean
|
||||||
is_numlock_active (MetaInputDeviceNative *device)
|
is_numlock_active (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
MetaSeatNative *seat = device->seat;
|
MetaSeatImpl *seat_impl = device->seat_impl;
|
||||||
return xkb_state_mod_name_is_active (seat->xkb,
|
struct xkb_state *xkb_state;
|
||||||
|
|
||||||
|
xkb_state = meta_seat_impl_get_xkb_state (seat_impl);
|
||||||
|
|
||||||
|
return xkb_state_mod_name_is_active (xkb_state,
|
||||||
"Mod2",
|
"Mod2",
|
||||||
XKB_STATE_MODS_LOCKED);
|
XKB_STATE_MODS_LOCKED);
|
||||||
}
|
}
|
||||||
@ -862,7 +869,7 @@ enable_mousekeys (MetaInputDeviceNative *device_evdev)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
device->accessibility_virtual_device =
|
device->accessibility_virtual_device =
|
||||||
clutter_seat_create_virtual_device (CLUTTER_SEAT (device_evdev->seat),
|
clutter_seat_create_virtual_device (clutter_input_device_get_seat (device),
|
||||||
CLUTTER_POINTER_DEVICE);
|
CLUTTER_POINTER_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1128,7 +1135,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
|
|||||||
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
|
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
|
||||||
goto emit_event;
|
goto emit_event;
|
||||||
|
|
||||||
if (device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
|
if (device_evdev->a11y_flags & META_A11Y_KEYBOARD_ENABLED)
|
||||||
{
|
{
|
||||||
if (event->type == CLUTTER_KEY_PRESS)
|
if (event->type == CLUTTER_KEY_PRESS)
|
||||||
handle_enablekeys_press (event, device_evdev);
|
handle_enablekeys_press (event, device_evdev);
|
||||||
@ -1136,7 +1143,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
|
|||||||
handle_enablekeys_release (event, device_evdev);
|
handle_enablekeys_release (event, device_evdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED)
|
if (device_evdev->a11y_flags & META_A11Y_MOUSE_KEYS_ENABLED)
|
||||||
{
|
{
|
||||||
if (event->type == CLUTTER_KEY_PRESS &&
|
if (event->type == CLUTTER_KEY_PRESS &&
|
||||||
handle_mousekeys_press (event, device_evdev))
|
handle_mousekeys_press (event, device_evdev))
|
||||||
@ -1146,7 +1153,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
|
|||||||
return; /* swallow event */
|
return; /* swallow event */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((device_evdev->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_ENABLED) &&
|
if ((device_evdev->a11y_flags & META_A11Y_BOUNCE_KEYS_ENABLED) &&
|
||||||
(get_debounce_delay (device) != 0))
|
(get_debounce_delay (device) != 0))
|
||||||
{
|
{
|
||||||
if ((event->type == CLUTTER_KEY_PRESS) && debounce_key (event, device_evdev))
|
if ((event->type == CLUTTER_KEY_PRESS) && debounce_key (event, device_evdev))
|
||||||
@ -1159,7 +1166,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
|
|||||||
start_bounce_keys (event, device_evdev);
|
start_bounce_keys (event, device_evdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((device_evdev->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_ENABLED) &&
|
if ((device_evdev->a11y_flags & META_A11Y_SLOW_KEYS_ENABLED) &&
|
||||||
(get_slow_keys_delay (device) != 0))
|
(get_slow_keys_delay (device) != 0))
|
||||||
{
|
{
|
||||||
if (event->type == CLUTTER_KEY_PRESS)
|
if (event->type == CLUTTER_KEY_PRESS)
|
||||||
@ -1170,7 +1177,7 @@ meta_input_device_native_process_kbd_a11y_event (ClutterEvent *eve
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_evdev->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_ENABLED)
|
if (device_evdev->a11y_flags & META_A11Y_STICKY_KEYS_ENABLED)
|
||||||
{
|
{
|
||||||
if (event->type == CLUTTER_KEY_PRESS)
|
if (event->type == CLUTTER_KEY_PRESS)
|
||||||
handle_stickykeys_press (event, device_evdev);
|
handle_stickykeys_press (event, device_evdev);
|
||||||
@ -1183,34 +1190,34 @@ emit_event:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device,
|
meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device,
|
||||||
ClutterKbdA11ySettings *settings)
|
MetaKbdA11ySettings *settings)
|
||||||
{
|
{
|
||||||
ClutterKeyboardA11yFlags changed_flags = (device->a11y_flags ^ settings->controls);
|
MetaKeyboardA11yFlags changed_flags = (device->a11y_flags ^ settings->controls);
|
||||||
|
|
||||||
if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_SLOW_KEYS_ENABLED))
|
if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_SLOW_KEYS_ENABLED))
|
||||||
clear_slow_keys (device);
|
clear_slow_keys (device);
|
||||||
|
|
||||||
if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_BOUNCE_KEYS_ENABLED))
|
if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_BOUNCE_KEYS_ENABLED))
|
||||||
device->debounce_key = 0;
|
device->debounce_key = 0;
|
||||||
|
|
||||||
if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_STICKY_KEYS_ENABLED))
|
if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_STICKY_KEYS_ENABLED))
|
||||||
{
|
{
|
||||||
device->stickykeys_depressed_mask = 0;
|
device->stickykeys_depressed_mask = 0;
|
||||||
update_internal_xkb_state (device, 0, 0);
|
update_internal_xkb_state (device, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
|
if (changed_flags & META_A11Y_KEYBOARD_ENABLED)
|
||||||
{
|
{
|
||||||
device->toggle_slowkeys_timer = 0;
|
device->toggle_slowkeys_timer = 0;
|
||||||
device->shift_count = 0;
|
device->shift_count = 0;
|
||||||
device->last_shift_time = 0;
|
device->last_shift_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_MOUSE_KEYS_ENABLED))
|
if (changed_flags & (META_A11Y_KEYBOARD_ENABLED | META_A11Y_MOUSE_KEYS_ENABLED))
|
||||||
{
|
{
|
||||||
if (settings->controls &
|
if (settings->controls &
|
||||||
(CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_MOUSE_KEYS_ENABLED))
|
(META_A11Y_KEYBOARD_ENABLED | META_A11Y_MOUSE_KEYS_ENABLED))
|
||||||
enable_mousekeys (device);
|
enable_mousekeys (device);
|
||||||
else
|
else
|
||||||
disable_mousekeys (device);
|
disable_mousekeys (device);
|
||||||
@ -1224,48 +1231,10 @@ meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device
|
|||||||
void
|
void
|
||||||
meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device)
|
meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
if (device->a11y_flags & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED)
|
if (device->a11y_flags & META_A11Y_TOGGLE_KEYS_ENABLED)
|
||||||
meta_input_device_native_bell_notify (device);
|
meta_input_device_native_bell_notify (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
release_device_touch_slot (gpointer value)
|
|
||||||
{
|
|
||||||
MetaTouchState *touch_state = value;
|
|
||||||
|
|
||||||
meta_seat_native_release_touch_state (touch_state->seat, touch_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaTouchState *
|
|
||||||
meta_input_device_native_acquire_touch_state (MetaInputDeviceNative *device,
|
|
||||||
int device_slot)
|
|
||||||
{
|
|
||||||
MetaTouchState *touch_state;
|
|
||||||
|
|
||||||
touch_state = meta_seat_native_acquire_touch_state (device->seat,
|
|
||||||
device_slot);
|
|
||||||
g_hash_table_insert (device->touches,
|
|
||||||
GINT_TO_POINTER (device_slot),
|
|
||||||
touch_state);
|
|
||||||
|
|
||||||
return touch_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaTouchState *
|
|
||||||
meta_input_device_native_lookup_touch_state (MetaInputDeviceNative *device,
|
|
||||||
int device_slot)
|
|
||||||
{
|
|
||||||
return g_hash_table_lookup (device->touches, GINT_TO_POINTER (device_slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_input_device_native_release_touch_state (MetaInputDeviceNative *device,
|
|
||||||
MetaTouchState *touch_state)
|
|
||||||
{
|
|
||||||
g_hash_table_remove (device->touches,
|
|
||||||
GINT_TO_POINTER (touch_state->device_slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass)
|
meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass)
|
||||||
{
|
{
|
||||||
@ -1305,9 +1274,6 @@ meta_input_device_native_init (MetaInputDeviceNative *self)
|
|||||||
cairo_matrix_init_identity (&self->device_matrix);
|
cairo_matrix_init_identity (&self->device_matrix);
|
||||||
self->device_aspect_ratio = 0;
|
self->device_aspect_ratio = 0;
|
||||||
self->output_ratio = 0;
|
self->output_ratio = 0;
|
||||||
|
|
||||||
self->touches = g_hash_table_new_full (NULL, NULL,
|
|
||||||
NULL, release_device_touch_slot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1320,7 +1286,7 @@ meta_input_device_native_init (MetaInputDeviceNative *self)
|
|||||||
* it with the provided seat.
|
* it with the provided seat.
|
||||||
*/
|
*/
|
||||||
ClutterInputDevice *
|
ClutterInputDevice *
|
||||||
meta_input_device_native_new (MetaSeatNative *seat,
|
meta_input_device_native_new (MetaSeatImpl *seat_impl,
|
||||||
struct libinput_device *libinput_device)
|
struct libinput_device *libinput_device)
|
||||||
{
|
{
|
||||||
MetaInputDeviceNative *device;
|
MetaInputDeviceNative *device;
|
||||||
@ -1333,7 +1299,7 @@ meta_input_device_native_new (MetaSeatNative *seat,
|
|||||||
type = meta_input_device_native_determine_type (libinput_device);
|
type = meta_input_device_native_determine_type (libinput_device);
|
||||||
vendor = g_strdup_printf ("%.4x", libinput_device_get_id_vendor (libinput_device));
|
vendor = g_strdup_printf ("%.4x", libinput_device_get_id_vendor (libinput_device));
|
||||||
product = g_strdup_printf ("%.4x", libinput_device_get_id_product (libinput_device));
|
product = g_strdup_printf ("%.4x", libinput_device_get_id_product (libinput_device));
|
||||||
device_id = meta_seat_native_acquire_device_id (seat);
|
device_id = meta_seat_impl_acquire_device_id (seat_impl);
|
||||||
node_path = g_strdup_printf ("/dev/input/%s", libinput_device_get_sysname (libinput_device));
|
node_path = g_strdup_printf ("/dev/input/%s", libinput_device_get_sysname (libinput_device));
|
||||||
|
|
||||||
if (libinput_device_has_capability (libinput_device,
|
if (libinput_device_has_capability (libinput_device,
|
||||||
@ -1349,17 +1315,16 @@ meta_input_device_native_new (MetaSeatNative *seat,
|
|||||||
"name", libinput_device_get_name (libinput_device),
|
"name", libinput_device_get_name (libinput_device),
|
||||||
"device-type", type,
|
"device-type", type,
|
||||||
"device-mode", CLUTTER_INPUT_MODE_SLAVE,
|
"device-mode", CLUTTER_INPUT_MODE_SLAVE,
|
||||||
"enabled", TRUE,
|
|
||||||
"vendor-id", vendor,
|
"vendor-id", vendor,
|
||||||
"product-id", product,
|
"product-id", product,
|
||||||
"n-rings", n_rings,
|
"n-rings", n_rings,
|
||||||
"n-strips", n_strips,
|
"n-strips", n_strips,
|
||||||
"n-mode-groups", n_groups,
|
"n-mode-groups", n_groups,
|
||||||
"device-node", node_path,
|
"device-node", node_path,
|
||||||
"seat", seat,
|
"seat", seat_impl->seat,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
device->seat = seat;
|
device->seat_impl = seat_impl;
|
||||||
device->libinput_device = libinput_device;
|
device->libinput_device = libinput_device;
|
||||||
|
|
||||||
libinput_device_set_user_data (libinput_device, device);
|
libinput_device_set_user_data (libinput_device, device);
|
||||||
@ -1382,7 +1347,7 @@ meta_input_device_native_new (MetaSeatNative *seat,
|
|||||||
* Create a new virtual ClutterInputDevice of the given type.
|
* Create a new virtual ClutterInputDevice of the given type.
|
||||||
*/
|
*/
|
||||||
ClutterInputDevice *
|
ClutterInputDevice *
|
||||||
meta_input_device_native_new_virtual (MetaSeatNative *seat,
|
meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl,
|
||||||
ClutterInputDeviceType type,
|
ClutterInputDeviceType type,
|
||||||
ClutterInputMode mode)
|
ClutterInputMode mode)
|
||||||
{
|
{
|
||||||
@ -1406,25 +1371,24 @@ meta_input_device_native_new_virtual (MetaSeatNative *seat,
|
|||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
device_id = meta_seat_native_acquire_device_id (seat);
|
device_id = meta_seat_impl_acquire_device_id (seat_impl);
|
||||||
device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE,
|
device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE,
|
||||||
"id", device_id,
|
"id", device_id,
|
||||||
"name", name,
|
"name", name,
|
||||||
"device-type", type,
|
"device-type", type,
|
||||||
"device-mode", mode,
|
"device-mode", mode,
|
||||||
"enabled", TRUE,
|
"seat", seat_impl->seat,
|
||||||
"seat", seat,
|
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
device->seat = seat;
|
device->seat_impl = seat_impl;
|
||||||
|
|
||||||
return CLUTTER_INPUT_DEVICE (device);
|
return CLUTTER_INPUT_DEVICE (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaSeatNative *
|
MetaSeatImpl *
|
||||||
meta_input_device_native_get_seat (MetaInputDeviceNative *device)
|
meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device)
|
||||||
{
|
{
|
||||||
return device->seat;
|
return device->seat_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1484,17 +1448,16 @@ meta_input_device_native_get_libinput_device (ClutterInputDevice *device)
|
|||||||
|
|
||||||
void
|
void
|
||||||
meta_input_device_native_translate_coordinates (ClutterInputDevice *device,
|
meta_input_device_native_translate_coordinates (ClutterInputDevice *device,
|
||||||
ClutterStage *stage,
|
MetaViewportInfo *viewports,
|
||||||
float *x,
|
float *x,
|
||||||
float *y)
|
float *y)
|
||||||
{
|
{
|
||||||
MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device);
|
||||||
double min_x = 0, min_y = 0, max_x = 1, max_y = 1;
|
double min_x = 0, min_y = 0, max_x = 1, max_y = 1;
|
||||||
double stage_width, stage_height;
|
float stage_width, stage_height;
|
||||||
double x_d, y_d;
|
double x_d, y_d;
|
||||||
|
|
||||||
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
meta_viewport_info_get_extents (viewports, &stage_width, &stage_height);
|
||||||
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
|
||||||
x_d = *x / stage_width;
|
x_d = *x / stage_width;
|
||||||
y_d = *y / stage_height;
|
y_d = *y / stage_height;
|
||||||
|
|
||||||
@ -1518,23 +1481,50 @@ meta_input_device_native_translate_coordinates (ClutterInputDevice *device,
|
|||||||
*y = CLAMP (y_d, MIN (min_y, max_y), MAX (min_y, max_y)) * stage_height;
|
*y = CLAMP (y_d, MIN (min_y, max_y), MAX (min_y, max_y)) * stage_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
MetaInputDeviceMapping
|
||||||
meta_input_device_native_release_touch_slots (MetaInputDeviceNative *device_evdev,
|
meta_input_device_native_get_mapping_mode (ClutterInputDevice *device)
|
||||||
uint64_t time_us)
|
|
||||||
{
|
{
|
||||||
GHashTableIter iter;
|
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
|
||||||
MetaTouchState *touch_state;
|
ClutterInputDeviceType device_type;
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, device_evdev->touches);
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device),
|
||||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch_state))
|
META_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
||||||
{
|
|
||||||
meta_seat_native_notify_touch_event (touch_state->seat,
|
device_type = clutter_input_device_get_device_type (device);
|
||||||
CLUTTER_INPUT_DEVICE (device_evdev),
|
g_return_val_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
||||||
CLUTTER_TOUCH_CANCEL,
|
device_type == CLUTTER_PEN_DEVICE ||
|
||||||
time_us,
|
device_type == CLUTTER_ERASER_DEVICE,
|
||||||
touch_state->seat_slot,
|
META_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
||||||
touch_state->coords.x,
|
|
||||||
touch_state->coords.y);
|
return device_native->mapping_mode;
|
||||||
g_hash_table_iter_remove (&iter);
|
}
|
||||||
}
|
|
||||||
|
void
|
||||||
|
meta_input_device_native_set_mapping_mode (ClutterInputDevice *device,
|
||||||
|
MetaInputDeviceMapping mapping)
|
||||||
|
{
|
||||||
|
MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device);
|
||||||
|
ClutterInputDeviceType device_type;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||||
|
|
||||||
|
device_type = clutter_input_device_get_device_type (device);
|
||||||
|
g_return_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
||||||
|
device_type == CLUTTER_PEN_DEVICE ||
|
||||||
|
device_type == CLUTTER_ERASER_DEVICE);
|
||||||
|
|
||||||
|
if (device_native->mapping_mode == mapping)
|
||||||
|
return;
|
||||||
|
|
||||||
|
device_native->mapping_mode = mapping;
|
||||||
|
g_object_notify (G_OBJECT (device), "mapping-mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_input_device_native_update_coords (MetaInputDeviceNative *device_native,
|
||||||
|
double x,
|
||||||
|
double y)
|
||||||
|
{
|
||||||
|
device_native->pointer_x = x;
|
||||||
|
device_native->pointer_y = y;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include "backends/meta-input-device-private.h"
|
#include "backends/meta-input-device-private.h"
|
||||||
|
#include "backends/meta-input-settings-private.h"
|
||||||
#include "backends/native/meta-seat-native.h"
|
#include "backends/native/meta-seat-native.h"
|
||||||
#include "clutter/clutter-mutter.h"
|
#include "clutter/clutter-mutter.h"
|
||||||
|
|
||||||
@ -54,6 +55,12 @@
|
|||||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||||
META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNativeClass))
|
META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNativeClass))
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
META_INPUT_DEVICE_MAPPING_ABSOLUTE,
|
||||||
|
META_INPUT_DEVICE_MAPPING_RELATIVE,
|
||||||
|
} MetaInputDeviceMapping;
|
||||||
|
|
||||||
typedef struct _MetaInputDeviceNative MetaInputDeviceNative;
|
typedef struct _MetaInputDeviceNative MetaInputDeviceNative;
|
||||||
typedef struct _MetaInputDeviceNativeClass MetaInputDeviceNativeClass;
|
typedef struct _MetaInputDeviceNativeClass MetaInputDeviceNativeClass;
|
||||||
|
|
||||||
@ -62,17 +69,20 @@ struct _MetaInputDeviceNative
|
|||||||
ClutterInputDevice parent;
|
ClutterInputDevice parent;
|
||||||
|
|
||||||
struct libinput_device *libinput_device;
|
struct libinput_device *libinput_device;
|
||||||
MetaSeatNative *seat;
|
MetaSeatImpl *seat_impl;
|
||||||
ClutterInputDeviceTool *last_tool;
|
ClutterInputDeviceTool *last_tool;
|
||||||
|
|
||||||
cairo_matrix_t device_matrix;
|
cairo_matrix_t device_matrix;
|
||||||
double device_aspect_ratio; /* w:h */
|
double device_aspect_ratio; /* w:h */
|
||||||
double output_ratio; /* w:h */
|
double output_ratio; /* w:h */
|
||||||
|
MetaInputDeviceMapping mapping_mode;
|
||||||
|
|
||||||
GHashTable *touches;
|
/* Pointer position */
|
||||||
|
double pointer_x;
|
||||||
|
double pointer_y;
|
||||||
|
|
||||||
/* Keyboard a11y */
|
/* Keyboard a11y */
|
||||||
ClutterKeyboardA11yFlags a11y_flags;
|
MetaKeyboardA11yFlags a11y_flags;
|
||||||
GList *slow_keys_list;
|
GList *slow_keys_list;
|
||||||
guint debounce_timer;
|
guint debounce_timer;
|
||||||
uint16_t debounce_key;
|
uint16_t debounce_key;
|
||||||
@ -99,17 +109,16 @@ struct _MetaInputDeviceNativeClass
|
|||||||
ClutterInputDeviceClass parent_class;
|
ClutterInputDeviceClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GType meta_input_device_native_get_type (void) G_GNUC_CONST;
|
GType meta_input_device_native_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ClutterInputDevice * meta_input_device_native_new (MetaSeatNative *seat,
|
ClutterInputDevice * meta_input_device_native_new (MetaSeatImpl *seat_impl,
|
||||||
struct libinput_device *libinput_device);
|
struct libinput_device *libinput_device);
|
||||||
|
|
||||||
ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatNative *seat,
|
ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatImpl *seat_impl,
|
||||||
ClutterInputDeviceType type,
|
ClutterInputDeviceType type,
|
||||||
ClutterInputMode mode);
|
ClutterInputMode mode);
|
||||||
|
|
||||||
MetaSeatNative * meta_input_device_native_get_seat (MetaInputDeviceNative *device);
|
MetaSeatImpl * meta_input_device_native_get_seat_impl (MetaInputDeviceNative *device);
|
||||||
|
|
||||||
void meta_input_device_native_update_leds (MetaInputDeviceNative *device,
|
void meta_input_device_native_update_leds (MetaInputDeviceNative *device,
|
||||||
enum libinput_led leds);
|
enum libinput_led leds);
|
||||||
@ -118,27 +127,23 @@ ClutterInputDeviceType meta_input_device_native_determine_type (struct libin
|
|||||||
|
|
||||||
|
|
||||||
void meta_input_device_native_translate_coordinates (ClutterInputDevice *device,
|
void meta_input_device_native_translate_coordinates (ClutterInputDevice *device,
|
||||||
ClutterStage *stage,
|
MetaViewportInfo *viewports,
|
||||||
float *x,
|
float *x,
|
||||||
float *y);
|
float *y);
|
||||||
|
|
||||||
void meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device,
|
MetaInputDeviceMapping meta_input_device_native_get_mapping_mode (ClutterInputDevice *device);
|
||||||
ClutterKbdA11ySettings *settings);
|
void meta_input_device_native_set_mapping_mode (ClutterInputDevice *device,
|
||||||
|
MetaInputDeviceMapping mapping);
|
||||||
|
|
||||||
MetaTouchState * meta_input_device_native_acquire_touch_state (MetaInputDeviceNative *device,
|
void meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device,
|
||||||
int device_slot);
|
MetaKbdA11ySettings *settings);
|
||||||
|
|
||||||
MetaTouchState * meta_input_device_native_lookup_touch_state (MetaInputDeviceNative *device,
|
|
||||||
int device_slot);
|
|
||||||
|
|
||||||
void meta_input_device_native_release_touch_state (MetaInputDeviceNative *device,
|
|
||||||
MetaTouchState *touch_state);
|
|
||||||
|
|
||||||
void meta_input_device_native_release_touch_slots (MetaInputDeviceNative *device_evdev,
|
|
||||||
uint64_t time_us);
|
|
||||||
|
|
||||||
void meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device_evdev);
|
void meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device_evdev);
|
||||||
|
|
||||||
struct libinput_device * meta_input_device_native_get_libinput_device (ClutterInputDevice *device);
|
struct libinput_device * meta_input_device_native_get_libinput_device (ClutterInputDevice *device);
|
||||||
|
|
||||||
|
void meta_input_device_native_update_coords (MetaInputDeviceNative *device_native,
|
||||||
|
double x,
|
||||||
|
double y);
|
||||||
|
|
||||||
#endif /* META_INPUT_DEVICE_NATIVE_H */
|
#endif /* META_INPUT_DEVICE_NATIVE_H */
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
|
|
||||||
#include "backends/meta-logical-monitor.h"
|
|
||||||
#include "backends/native/meta-backend-native.h"
|
#include "backends/native/meta-backend-native.h"
|
||||||
#include "backends/native/meta-input-device-native.h"
|
#include "backends/native/meta-input-device-native.h"
|
||||||
#include "backends/native/meta-input-device-tool-native.h"
|
#include "backends/native/meta-input-device-tool-native.h"
|
||||||
@ -34,6 +33,55 @@
|
|||||||
|
|
||||||
G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
|
G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_SEAT_IMPL,
|
||||||
|
N_PROPS,
|
||||||
|
};
|
||||||
|
|
||||||
|
GParamSpec *props[N_PROPS] = { 0 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_input_settings_native_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
MetaInputSettingsNative *input_settings_native =
|
||||||
|
META_INPUT_SETTINGS_NATIVE (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SEAT_IMPL:
|
||||||
|
input_settings_native->seat_impl = g_value_get_object (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_input_settings_native_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
MetaInputSettingsNative *input_settings_native =
|
||||||
|
META_INPUT_SETTINGS_NATIVE (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_SEAT_IMPL:
|
||||||
|
g_value_set_object (value, input_settings_native->seat_impl);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_input_settings_native_set_send_events (MetaInputSettings *settings,
|
meta_input_settings_native_set_send_events (MetaInputSettings *settings,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
@ -70,8 +118,19 @@ meta_input_settings_native_set_matrix (MetaInputSettings *settings,
|
|||||||
{
|
{
|
||||||
cairo_matrix_t dev_matrix;
|
cairo_matrix_t dev_matrix;
|
||||||
|
|
||||||
cairo_matrix_init (&dev_matrix, matrix[0], matrix[3], matrix[1],
|
if (clutter_input_device_get_device_type (device) ==
|
||||||
matrix[4], matrix[2], matrix[5]);
|
CLUTTER_TOUCHSCREEN_DEVICE ||
|
||||||
|
meta_input_device_native_get_mapping_mode (device) ==
|
||||||
|
META_INPUT_DEVICE_MAPPING_ABSOLUTE)
|
||||||
|
{
|
||||||
|
cairo_matrix_init (&dev_matrix, matrix[0], matrix[3], matrix[1],
|
||||||
|
matrix[4], matrix[2], matrix[5]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cairo_matrix_init_identity (&dev_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
g_object_set (device, "device-matrix", &dev_matrix, NULL);
|
g_object_set (device, "device-matrix", &dev_matrix, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,11 +435,11 @@ meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
|
|||||||
guint delay,
|
guint delay,
|
||||||
guint interval)
|
guint interval)
|
||||||
{
|
{
|
||||||
ClutterSeat *seat;
|
MetaInputSettingsNative *input_settings_native;
|
||||||
|
|
||||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
input_settings_native = META_INPUT_SETTINGS_NATIVE (settings);
|
||||||
meta_seat_native_set_keyboard_repeat (META_SEAT_NATIVE (seat),
|
meta_seat_impl_set_keyboard_repeat (input_settings_native->seat_impl,
|
||||||
enabled, delay, interval);
|
enabled, delay, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -502,49 +561,26 @@ meta_input_settings_native_set_tablet_mapping (MetaInputSettings *settings,
|
|||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
GDesktopTabletMapping mapping)
|
GDesktopTabletMapping mapping)
|
||||||
{
|
{
|
||||||
ClutterInputDeviceMapping dev_mapping;
|
MetaInputDeviceMapping dev_mapping;
|
||||||
|
|
||||||
if (mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE)
|
if (mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE)
|
||||||
dev_mapping = CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE;
|
dev_mapping = META_INPUT_DEVICE_MAPPING_ABSOLUTE;
|
||||||
else if (mapping == G_DESKTOP_TABLET_MAPPING_RELATIVE)
|
else if (mapping == G_DESKTOP_TABLET_MAPPING_RELATIVE)
|
||||||
dev_mapping = CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE;
|
dev_mapping = META_INPUT_DEVICE_MAPPING_RELATIVE;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clutter_input_device_set_mapping_mode (device, dev_mapping);
|
meta_input_device_native_set_mapping_mode (device, dev_mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_input_settings_native_set_tablet_keep_aspect (MetaInputSettings *settings,
|
meta_input_settings_native_set_tablet_aspect_ratio (MetaInputSettings *settings,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
MetaLogicalMonitor *logical_monitor,
|
gdouble aspect_ratio)
|
||||||
gboolean keep_aspect)
|
|
||||||
{
|
{
|
||||||
double aspect_ratio = 0;
|
if (meta_input_device_native_get_mapping_mode (device) ==
|
||||||
|
META_INPUT_DEVICE_MAPPING_RELATIVE)
|
||||||
if (keep_aspect)
|
aspect_ratio = 0;
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
if (logical_monitor)
|
|
||||||
{
|
|
||||||
width = logical_monitor->rect.width;
|
|
||||||
height = logical_monitor->rect.height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MetaMonitorManager *monitor_manager;
|
|
||||||
MetaBackend *backend;
|
|
||||||
|
|
||||||
backend = meta_get_backend ();
|
|
||||||
monitor_manager = meta_backend_get_monitor_manager (backend);
|
|
||||||
meta_monitor_manager_get_screen_size (monitor_manager,
|
|
||||||
&width,
|
|
||||||
&height);
|
|
||||||
}
|
|
||||||
|
|
||||||
aspect_ratio = (double) width / height;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_set (device, "output-aspect-ratio", aspect_ratio, NULL);
|
g_object_set (device, "output-aspect-ratio", aspect_ratio, NULL);
|
||||||
}
|
}
|
||||||
@ -688,6 +724,10 @@ static void
|
|||||||
meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
||||||
{
|
{
|
||||||
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->set_property = meta_input_settings_native_set_property;
|
||||||
|
object_class->get_property = meta_input_settings_native_get_property;
|
||||||
|
|
||||||
input_settings_class->set_send_events = meta_input_settings_native_set_send_events;
|
input_settings_class->set_send_events = meta_input_settings_native_set_send_events;
|
||||||
input_settings_class->set_matrix = meta_input_settings_native_set_matrix;
|
input_settings_class->set_matrix = meta_input_settings_native_set_matrix;
|
||||||
@ -707,7 +747,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
|||||||
input_settings_class->set_disable_while_typing = meta_input_settings_native_set_disable_while_typing;
|
input_settings_class->set_disable_while_typing = meta_input_settings_native_set_disable_while_typing;
|
||||||
|
|
||||||
input_settings_class->set_tablet_mapping = meta_input_settings_native_set_tablet_mapping;
|
input_settings_class->set_tablet_mapping = meta_input_settings_native_set_tablet_mapping;
|
||||||
input_settings_class->set_tablet_keep_aspect = meta_input_settings_native_set_tablet_keep_aspect;
|
input_settings_class->set_tablet_aspect_ratio = meta_input_settings_native_set_tablet_aspect_ratio;
|
||||||
input_settings_class->set_tablet_area = meta_input_settings_native_set_tablet_area;
|
input_settings_class->set_tablet_area = meta_input_settings_native_set_tablet_area;
|
||||||
|
|
||||||
input_settings_class->set_mouse_accel_profile = meta_input_settings_native_set_mouse_accel_profile;
|
input_settings_class->set_mouse_accel_profile = meta_input_settings_native_set_mouse_accel_profile;
|
||||||
@ -722,9 +762,27 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
|||||||
|
|
||||||
input_settings_class->has_two_finger_scroll = meta_input_settings_native_has_two_finger_scroll;
|
input_settings_class->has_two_finger_scroll = meta_input_settings_native_has_two_finger_scroll;
|
||||||
input_settings_class->is_trackball_device = meta_input_settings_native_is_trackball_device;
|
input_settings_class->is_trackball_device = meta_input_settings_native_is_trackball_device;
|
||||||
|
|
||||||
|
props[PROP_SEAT_IMPL] =
|
||||||
|
g_param_spec_object ("seat-impl",
|
||||||
|
"Seat Impl",
|
||||||
|
"Seat Impl",
|
||||||
|
PROP_SEAT_IMPL,
|
||||||
|
CLUTTER_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_input_settings_native_init (MetaInputSettingsNative *settings)
|
meta_input_settings_native_init (MetaInputSettingsNative *settings)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaInputSettings *
|
||||||
|
meta_input_settings_native_new (MetaSeatImpl *seat)
|
||||||
|
{
|
||||||
|
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE,
|
||||||
|
"seat-impl", seat,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ typedef struct _MetaInputSettingsNativeClass MetaInputSettingsNativeClass;
|
|||||||
struct _MetaInputSettingsNative
|
struct _MetaInputSettingsNative
|
||||||
{
|
{
|
||||||
MetaInputSettings parent_instance;
|
MetaInputSettings parent_instance;
|
||||||
|
MetaSeatImpl *seat_impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaInputSettingsNativeClass
|
struct _MetaInputSettingsNativeClass
|
||||||
@ -46,4 +47,6 @@ struct _MetaInputSettingsNativeClass
|
|||||||
|
|
||||||
GType meta_input_settings_native_get_type (void) G_GNUC_CONST;
|
GType meta_input_settings_native_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
MetaInputSettings * meta_input_settings_native_new (MetaSeatImpl *seat);
|
||||||
|
|
||||||
#endif /* META_INPUT_SETTINGS_NATIVE_H */
|
#endif /* META_INPUT_SETTINGS_NATIVE_H */
|
||||||
|
@ -25,10 +25,6 @@
|
|||||||
#include "backends/native/meta-keymap-native.h"
|
#include "backends/native/meta-keymap-native.h"
|
||||||
#include "backends/native/meta-seat-native.h"
|
#include "backends/native/meta-seat-native.h"
|
||||||
|
|
||||||
static const char *option_xkb_layout = "us";
|
|
||||||
static const char *option_xkb_variant = "";
|
|
||||||
static const char *option_xkb_options = "";
|
|
||||||
|
|
||||||
typedef struct _MetaKeymapNative MetaKeymapNative;
|
typedef struct _MetaKeymapNative MetaKeymapNative;
|
||||||
|
|
||||||
struct _MetaKeymapNative
|
struct _MetaKeymapNative
|
||||||
@ -36,6 +32,8 @@ struct _MetaKeymapNative
|
|||||||
ClutterKeymap parent_instance;
|
ClutterKeymap parent_instance;
|
||||||
|
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
|
gboolean num_lock;
|
||||||
|
gboolean caps_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaKeymapNative, meta_keymap_native,
|
G_DEFINE_TYPE (MetaKeymapNative, meta_keymap_native,
|
||||||
@ -54,31 +52,17 @@ meta_keymap_native_finalize (GObject *object)
|
|||||||
static gboolean
|
static gboolean
|
||||||
meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap)
|
meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap)
|
||||||
{
|
{
|
||||||
struct xkb_state *xkb_state;
|
MetaKeymapNative *keymap_native = META_KEYMAP_NATIVE (keymap);
|
||||||
ClutterSeat *seat;
|
|
||||||
|
|
||||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
return keymap_native->num_lock;
|
||||||
xkb_state = meta_seat_native_get_xkb_state (META_SEAT_NATIVE (seat));
|
|
||||||
|
|
||||||
return xkb_state_mod_name_is_active (xkb_state,
|
|
||||||
XKB_MOD_NAME_NUM,
|
|
||||||
XKB_STATE_MODS_LATCHED |
|
|
||||||
XKB_STATE_MODS_LOCKED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap)
|
meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap)
|
||||||
{
|
{
|
||||||
struct xkb_state *xkb_state;
|
MetaKeymapNative *keymap_native = META_KEYMAP_NATIVE (keymap);
|
||||||
ClutterSeat *seat;
|
|
||||||
|
|
||||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
return keymap_native->caps_lock;
|
||||||
xkb_state = meta_seat_native_get_xkb_state (META_SEAT_NATIVE (seat));
|
|
||||||
|
|
||||||
return xkb_state_mod_name_is_active (xkb_state,
|
|
||||||
XKB_MOD_NAME_CAPS,
|
|
||||||
XKB_STATE_MODS_LATCHED |
|
|
||||||
XKB_STATE_MODS_LOCKED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PangoDirection
|
static PangoDirection
|
||||||
@ -103,19 +87,6 @@ meta_keymap_native_class_init (MetaKeymapNativeClass *klass)
|
|||||||
static void
|
static void
|
||||||
meta_keymap_native_init (MetaKeymapNative *keymap)
|
meta_keymap_native_init (MetaKeymapNative *keymap)
|
||||||
{
|
{
|
||||||
struct xkb_context *ctx;
|
|
||||||
struct xkb_rule_names names;
|
|
||||||
|
|
||||||
names.rules = "evdev";
|
|
||||||
names.model = "pc105";
|
|
||||||
names.layout = option_xkb_layout;
|
|
||||||
names.variant = option_xkb_variant;
|
|
||||||
names.options = option_xkb_options;
|
|
||||||
|
|
||||||
ctx = meta_create_xkb_context ();
|
|
||||||
g_assert (ctx);
|
|
||||||
keymap->keymap = xkb_keymap_new_from_names (ctx, &names, 0);
|
|
||||||
xkb_context_unref (ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -132,3 +103,24 @@ meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap)
|
|||||||
{
|
{
|
||||||
return keymap->keymap;
|
return keymap->keymap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_keymap_native_update (MetaKeymapNative *keymap)
|
||||||
|
{
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
ClutterSeat *seat;
|
||||||
|
|
||||||
|
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||||
|
xkb_state = meta_seat_impl_get_xkb_state (META_SEAT_NATIVE (seat)->impl);
|
||||||
|
|
||||||
|
keymap->num_lock =
|
||||||
|
xkb_state_mod_name_is_active (xkb_state,
|
||||||
|
XKB_MOD_NAME_NUM,
|
||||||
|
XKB_STATE_MODS_LATCHED |
|
||||||
|
XKB_STATE_MODS_LOCKED);
|
||||||
|
keymap->caps_lock =
|
||||||
|
xkb_state_mod_name_is_active (xkb_state,
|
||||||
|
XKB_MOD_NAME_CAPS,
|
||||||
|
XKB_STATE_MODS_LATCHED |
|
||||||
|
XKB_STATE_MODS_LOCKED);
|
||||||
|
}
|
||||||
|
@ -32,5 +32,6 @@ G_DECLARE_FINAL_TYPE (MetaKeymapNative, meta_keymap_native,
|
|||||||
void meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap,
|
void meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap,
|
||||||
struct xkb_keymap *xkb_keymap);
|
struct xkb_keymap *xkb_keymap);
|
||||||
struct xkb_keymap * meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap);
|
struct xkb_keymap * meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap);
|
||||||
|
void meta_keymap_native_update (MetaKeymapNative *keymap);
|
||||||
|
|
||||||
#endif /* META_KEYMAP_NATIVE_H */
|
#endif /* META_KEYMAP_NATIVE_H */
|
||||||
|
1700
src/backends/native/meta-kms-cursor-renderer.c
Normal file
1700
src/backends/native/meta-kms-cursor-renderer.c
Normal file
File diff suppressed because it is too large
Load Diff
43
src/backends/native/meta-kms-cursor-renderer.h
Normal file
43
src/backends/native/meta-kms-cursor-renderer.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_KMS_CURSOR_RENDERER_H
|
||||||
|
#define META_KMS_CURSOR_RENDERER_H
|
||||||
|
|
||||||
|
#include "backends/meta-cursor-renderer.h"
|
||||||
|
#include "meta/meta-backend.h"
|
||||||
|
|
||||||
|
#define META_TYPE_KMS_CURSOR_RENDERER (meta_kms_cursor_renderer_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaKmsCursorRenderer, meta_kms_cursor_renderer,
|
||||||
|
META, KMS_CURSOR_RENDERER,
|
||||||
|
GObject)
|
||||||
|
|
||||||
|
MetaKmsCursorRenderer * meta_kms_cursor_renderer_new (MetaBackend *backend);
|
||||||
|
void meta_kms_cursor_renderer_invalidate_state (MetaKmsCursorRenderer *kms_renderer);
|
||||||
|
gboolean meta_kms_cursor_renderer_update_cursor (MetaKmsCursorRenderer *kms_cursor_renderer,
|
||||||
|
MetaCursorSprite *sprite);
|
||||||
|
void meta_kms_cursor_renderer_set_cursor_renderer (MetaKmsCursorRenderer *kms_renderer,
|
||||||
|
MetaCursorRenderer *renderer);
|
||||||
|
|
||||||
|
#endif /* META_KMS_CURSOR_RENDERER_H */
|
@ -528,9 +528,9 @@ meta_launcher_new (GError **error)
|
|||||||
|
|
||||||
meta_clutter_backend_native_set_seat_id (self->seat_id);
|
meta_clutter_backend_native_set_seat_id (self->seat_id);
|
||||||
|
|
||||||
meta_seat_native_set_device_callbacks (on_evdev_device_open,
|
meta_seat_impl_set_device_callbacks (on_evdev_device_open,
|
||||||
on_evdev_device_close,
|
on_evdev_device_close,
|
||||||
self);
|
self);
|
||||||
|
|
||||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||||
|
|
||||||
|
676
src/backends/native/meta-pointer-constraint-native.c
Normal file
676
src/backends/native/meta-pointer-constraint-native.c
Normal file
@ -0,0 +1,676 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2020 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Jonas Ådahl <jadahl@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
#include "core/meta-border.h"
|
||||||
|
#include "meta-pointer-constraint-native.h"
|
||||||
|
|
||||||
|
struct _MetaPointerConstraintImplNative
|
||||||
|
{
|
||||||
|
MetaPointerConstraintImpl parent;
|
||||||
|
MetaPointerConstraint *constraint;
|
||||||
|
cairo_region_t *region;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaPointerConstraintImplNative,
|
||||||
|
meta_pointer_constraint_impl_native,
|
||||||
|
META_TYPE_POINTER_CONSTRAINT_IMPL);
|
||||||
|
|
||||||
|
typedef struct _MetaBox
|
||||||
|
{
|
||||||
|
int x1;
|
||||||
|
int y1;
|
||||||
|
int x2;
|
||||||
|
int y2;
|
||||||
|
} MetaBox;
|
||||||
|
|
||||||
|
static MetaBorder *
|
||||||
|
add_border (GArray *borders,
|
||||||
|
float x1,
|
||||||
|
float y1,
|
||||||
|
float x2,
|
||||||
|
float y2,
|
||||||
|
MetaBorderMotionDirection blocking_directions)
|
||||||
|
{
|
||||||
|
MetaBorder border;
|
||||||
|
|
||||||
|
border = (MetaBorder) {
|
||||||
|
.line = (MetaLine2) {
|
||||||
|
.a = (MetaVector2) {
|
||||||
|
.x = x1,
|
||||||
|
.y = y1,
|
||||||
|
},
|
||||||
|
.b = (MetaVector2) {
|
||||||
|
.x = x2,
|
||||||
|
.y = y2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.blocking_directions = blocking_directions,
|
||||||
|
};
|
||||||
|
|
||||||
|
g_array_append_val (borders, border);
|
||||||
|
|
||||||
|
return &g_array_index (borders, MetaBorder, borders->len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
compare_lines_x (gconstpointer a,
|
||||||
|
gconstpointer b)
|
||||||
|
{
|
||||||
|
const MetaBorder *border_a = a;
|
||||||
|
const MetaBorder *border_b = b;
|
||||||
|
|
||||||
|
if (border_a->line.a.x == border_b->line.a.x)
|
||||||
|
return border_a->line.b.x < border_b->line.b.x;
|
||||||
|
else
|
||||||
|
return border_a->line.a.x > border_b->line.a.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_non_overlapping_edges (MetaBox *boxes,
|
||||||
|
unsigned int band_above_start,
|
||||||
|
unsigned int band_below_start,
|
||||||
|
unsigned int band_below_end,
|
||||||
|
GArray *borders)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
GArray *band_merge;
|
||||||
|
MetaBorder *border;
|
||||||
|
MetaBorder *prev_border;
|
||||||
|
MetaBorder *new_border;
|
||||||
|
|
||||||
|
band_merge = g_array_new (FALSE, FALSE, sizeof *border);
|
||||||
|
|
||||||
|
/* Add bottom band of previous row, and top band of current row, and
|
||||||
|
* sort them so lower left x coordinate comes first. If there are two
|
||||||
|
* borders with the same left x coordinate, the wider one comes first.
|
||||||
|
*/
|
||||||
|
for (i = band_above_start; i < band_below_start; i++)
|
||||||
|
{
|
||||||
|
MetaBox *box = &boxes[i];
|
||||||
|
add_border (band_merge, box->x1, box->y2, box->x2, box->y2,
|
||||||
|
META_BORDER_MOTION_DIRECTION_POSITIVE_Y);
|
||||||
|
}
|
||||||
|
for (i = band_below_start; i < band_below_end; i++)
|
||||||
|
{
|
||||||
|
MetaBox *box= &boxes[i];
|
||||||
|
add_border (band_merge, box->x1, box->y1, box->x2, box->y1,
|
||||||
|
META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
|
||||||
|
}
|
||||||
|
g_array_sort (band_merge, compare_lines_x);
|
||||||
|
|
||||||
|
/* Combine the two combined bands so that any overlapping border is
|
||||||
|
* eliminated. */
|
||||||
|
prev_border = NULL;
|
||||||
|
for (i = 0; i < band_merge->len; i++)
|
||||||
|
{
|
||||||
|
border = &g_array_index (band_merge, MetaBorder, i);
|
||||||
|
|
||||||
|
g_assert (border->line.a.y == border->line.b.y);
|
||||||
|
g_assert (!prev_border ||
|
||||||
|
prev_border->line.a.y == border->line.a.y);
|
||||||
|
g_assert (!prev_border ||
|
||||||
|
(prev_border->line.a.x != border->line.a.x ||
|
||||||
|
prev_border->line.b.x != border->line.b.x));
|
||||||
|
g_assert (!prev_border ||
|
||||||
|
prev_border->line.a.x <= border->line.a.x);
|
||||||
|
|
||||||
|
if (prev_border &&
|
||||||
|
prev_border->line.a.x == border->line.a.x)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ------------ +
|
||||||
|
* ------- =
|
||||||
|
* [ ]-----
|
||||||
|
*/
|
||||||
|
prev_border->line.a.x = border->line.b.x;
|
||||||
|
}
|
||||||
|
else if (prev_border &&
|
||||||
|
prev_border->line.b.x == border->line.b.x)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ------------ +
|
||||||
|
* ------ =
|
||||||
|
* ------[ ]
|
||||||
|
*/
|
||||||
|
prev_border->line.b.x = border->line.a.x;
|
||||||
|
}
|
||||||
|
else if (prev_border &&
|
||||||
|
prev_border->line.b.x == border->line.a.x)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* -------- +
|
||||||
|
* ------ =
|
||||||
|
* --------------
|
||||||
|
*/
|
||||||
|
prev_border->line.b.x = border->line.b.x;
|
||||||
|
}
|
||||||
|
else if (prev_border &&
|
||||||
|
prev_border->line.b.x >= border->line.a.x)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* --------------- +
|
||||||
|
* ------ =
|
||||||
|
* -----[ ]----
|
||||||
|
*/
|
||||||
|
new_border = add_border (borders,
|
||||||
|
border->line.b.x,
|
||||||
|
border->line.b.y,
|
||||||
|
prev_border->line.b.x,
|
||||||
|
prev_border->line.b.y,
|
||||||
|
prev_border->blocking_directions);
|
||||||
|
prev_border->line.b.x = border->line.a.x;
|
||||||
|
prev_border = new_border;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_assert (!prev_border ||
|
||||||
|
prev_border->line.b.x < border->line.a.x);
|
||||||
|
/*
|
||||||
|
* First border or non-overlapping.
|
||||||
|
*
|
||||||
|
* ----- +
|
||||||
|
* ----- =
|
||||||
|
* ----- -----
|
||||||
|
*/
|
||||||
|
g_array_append_val (borders, *border);
|
||||||
|
prev_border = &g_array_index (borders, MetaBorder, borders->len - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free (band_merge, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_band_bottom_edges (MetaBox *boxes,
|
||||||
|
int band_start,
|
||||||
|
int band_end,
|
||||||
|
GArray *borders)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = band_start; i < band_end; i++)
|
||||||
|
{
|
||||||
|
add_border (borders,
|
||||||
|
boxes[i].x1, boxes[i].y2,
|
||||||
|
boxes[i].x2, boxes[i].y2,
|
||||||
|
META_BORDER_MOTION_DIRECTION_POSITIVE_Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
region_to_outline (cairo_region_t *region,
|
||||||
|
GArray *borders)
|
||||||
|
{
|
||||||
|
MetaBox *boxes;
|
||||||
|
int num_boxes;
|
||||||
|
int i;
|
||||||
|
int top_most, bottom_most;
|
||||||
|
int current_roof;
|
||||||
|
int prev_top;
|
||||||
|
int band_start, prev_band_start;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove any overlapping lines from the set of rectangles. Note that
|
||||||
|
* pixman regions are grouped as rows of rectangles, where rectangles
|
||||||
|
* in one row never touch or overlap and are all of the same height.
|
||||||
|
*
|
||||||
|
* -------- --- -------- ---
|
||||||
|
* | | | | | | | |
|
||||||
|
* ----------====---- --- ----------- ----- ---
|
||||||
|
* | | => | |
|
||||||
|
* ----==========--------- ----- ----------
|
||||||
|
* | | | |
|
||||||
|
* ------------------- -------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
num_boxes = cairo_region_num_rectangles (region);
|
||||||
|
boxes = g_new (MetaBox, num_boxes);
|
||||||
|
for (i = 0; i < num_boxes; i++)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
cairo_region_get_rectangle (region, i, &rect);
|
||||||
|
boxes[i] = (MetaBox) {
|
||||||
|
.x1 = rect.x,
|
||||||
|
.y1 = rect.y,
|
||||||
|
.x2 = rect.x + rect.width,
|
||||||
|
.y2 = rect.y + rect.height,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
prev_top = 0;
|
||||||
|
top_most = boxes[0].y1;
|
||||||
|
current_roof = top_most;
|
||||||
|
bottom_most = boxes[num_boxes - 1].y2;
|
||||||
|
band_start = 0;
|
||||||
|
prev_band_start = 0;
|
||||||
|
for (i = 0; i < num_boxes; i++)
|
||||||
|
{
|
||||||
|
/* Detect if there is a vertical empty space, and add the lower
|
||||||
|
* level of the previous band if so was the case. */
|
||||||
|
if (i > 0 &&
|
||||||
|
boxes[i].y1 != prev_top &&
|
||||||
|
boxes[i].y1 != boxes[i - 1].y2)
|
||||||
|
{
|
||||||
|
current_roof = boxes[i].y1;
|
||||||
|
add_band_bottom_edges (boxes,
|
||||||
|
band_start,
|
||||||
|
i,
|
||||||
|
borders);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special case adding the last band, since it won't be handled
|
||||||
|
* by the band change detection below. */
|
||||||
|
if (boxes[i].y1 != current_roof && i == num_boxes - 1)
|
||||||
|
{
|
||||||
|
if (boxes[i].y1 != prev_top)
|
||||||
|
{
|
||||||
|
/* The last band is a single box, so we don't
|
||||||
|
* have a prev_band_start to tell us when the
|
||||||
|
* previous band started. */
|
||||||
|
add_non_overlapping_edges (boxes,
|
||||||
|
band_start,
|
||||||
|
i,
|
||||||
|
i + 1,
|
||||||
|
borders);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
add_non_overlapping_edges (boxes,
|
||||||
|
prev_band_start,
|
||||||
|
band_start,
|
||||||
|
i + 1,
|
||||||
|
borders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detect when passing a band and combine the top border of the
|
||||||
|
* just passed band with the bottom band of the previous band.
|
||||||
|
*/
|
||||||
|
if (boxes[i].y1 != top_most && boxes[i].y1 != prev_top)
|
||||||
|
{
|
||||||
|
/* Combine the two passed bands. */
|
||||||
|
if (prev_top != current_roof)
|
||||||
|
{
|
||||||
|
add_non_overlapping_edges (boxes,
|
||||||
|
prev_band_start,
|
||||||
|
band_start,
|
||||||
|
i,
|
||||||
|
borders);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_band_start = band_start;
|
||||||
|
band_start = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the top border if the box is part of the current roof. */
|
||||||
|
if (boxes[i].y1 == current_roof)
|
||||||
|
{
|
||||||
|
add_border (borders,
|
||||||
|
boxes[i].x1, boxes[i].y1,
|
||||||
|
boxes[i].x2, boxes[i].y1,
|
||||||
|
META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the bottom border of the last band. */
|
||||||
|
if (boxes[i].y2 == bottom_most)
|
||||||
|
{
|
||||||
|
add_border (borders,
|
||||||
|
boxes[i].x1, boxes[i].y2,
|
||||||
|
boxes[i].x2, boxes[i].y2,
|
||||||
|
META_BORDER_MOTION_DIRECTION_POSITIVE_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Always add the left border. */
|
||||||
|
add_border (borders,
|
||||||
|
boxes[i].x1, boxes[i].y1,
|
||||||
|
boxes[i].x1, boxes[i].y2,
|
||||||
|
META_BORDER_MOTION_DIRECTION_NEGATIVE_X);
|
||||||
|
|
||||||
|
/* Always add the right border. */
|
||||||
|
add_border (borders,
|
||||||
|
boxes[i].x2, boxes[i].y1,
|
||||||
|
boxes[i].x2, boxes[i].y2,
|
||||||
|
META_BORDER_MOTION_DIRECTION_POSITIVE_X);
|
||||||
|
|
||||||
|
prev_top = boxes[i].y1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (boxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaBorder *
|
||||||
|
get_closest_border (GArray *borders,
|
||||||
|
MetaLine2 *motion,
|
||||||
|
uint32_t directions)
|
||||||
|
{
|
||||||
|
MetaBorder *border;
|
||||||
|
MetaVector2 intersection;
|
||||||
|
MetaVector2 delta;
|
||||||
|
float distance_2;
|
||||||
|
MetaBorder *closest_border = NULL;
|
||||||
|
float closest_distance_2 = DBL_MAX;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < borders->len; i++)
|
||||||
|
{
|
||||||
|
border = &g_array_index (borders, MetaBorder, i);
|
||||||
|
|
||||||
|
if (!meta_border_is_blocking_directions (border, directions))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!meta_line2_intersects_with (&border->line, motion, &intersection))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
delta = meta_vector2_subtract (intersection, motion->a);
|
||||||
|
distance_2 = delta.x*delta.x + delta.y*delta.y;
|
||||||
|
if (distance_2 < closest_distance_2)
|
||||||
|
{
|
||||||
|
closest_border = border;
|
||||||
|
closest_distance_2 = distance_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closest_border;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clamp_to_border (MetaBorder *border,
|
||||||
|
MetaLine2 *motion,
|
||||||
|
uint32_t *motion_dir)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* When clamping either rightward or downward motions, the motion needs to be
|
||||||
|
* clamped so that the destination coordinate does not end up on the border
|
||||||
|
* (see weston_pointer_clamp_event_to_region). Do this by clamping such
|
||||||
|
* motions to the border minus the smallest possible wl_fixed_t value.
|
||||||
|
*
|
||||||
|
* When clamping in either leftward or upward motion, the resulting coordinate
|
||||||
|
* needs to be clamped so that it is enough on the inside to avoid the
|
||||||
|
* inaccuracies of clutter's stage to actor transformation algorithm (the one
|
||||||
|
* used in clutter_actor_transform_stage_point) to make it end up outside the
|
||||||
|
* next motion. It also needs to be clamped so that to the wl_fixed_t
|
||||||
|
* coordinate may still be right on the border (i.e. at .0). Testing shows
|
||||||
|
* that the smallest wl_fixed_t value divided by 10 is small enough to make
|
||||||
|
* the wl_fixed_t coordinate .0 and large enough to avoid the inaccuracies of
|
||||||
|
* clutters transform algorithm.
|
||||||
|
*/
|
||||||
|
if (meta_border_is_horizontal (border))
|
||||||
|
{
|
||||||
|
if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_Y)
|
||||||
|
motion->b.y = border->line.a.y - wl_fixed_to_double (1);
|
||||||
|
else
|
||||||
|
motion->b.y = border->line.a.y + wl_fixed_to_double (1) / 10;
|
||||||
|
*motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_Y |
|
||||||
|
META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_X)
|
||||||
|
motion->b.x = border->line.a.x - wl_fixed_to_double (1);
|
||||||
|
else
|
||||||
|
motion->b.x = border->line.a.x + wl_fixed_to_double (1) / 10;
|
||||||
|
*motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_X |
|
||||||
|
META_BORDER_MOTION_DIRECTION_NEGATIVE_X);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
get_motion_directions (MetaLine2 *motion)
|
||||||
|
{
|
||||||
|
uint32_t directions = 0;
|
||||||
|
|
||||||
|
if (motion->a.x < motion->b.x)
|
||||||
|
directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_X;
|
||||||
|
else if (motion->a.x > motion->b.x)
|
||||||
|
directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_X;
|
||||||
|
if (motion->a.y < motion->b.y)
|
||||||
|
directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_Y;
|
||||||
|
else if (motion->a.y > motion->b.y)
|
||||||
|
directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_Y;
|
||||||
|
|
||||||
|
return directions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_constraint_impl_native_constraint (MetaPointerConstraintImpl *impl,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
uint32_t time,
|
||||||
|
float prev_x,
|
||||||
|
float prev_y,
|
||||||
|
float *x_inout,
|
||||||
|
float *y_inout)
|
||||||
|
{
|
||||||
|
MetaPointerConstraintImplNative *native = META_POINTER_CONSTRAINT_IMPL_NATIVE (impl);
|
||||||
|
cairo_region_t *region;
|
||||||
|
float x, y;
|
||||||
|
GArray *borders;
|
||||||
|
MetaLine2 motion;
|
||||||
|
MetaBorder *closest_border;
|
||||||
|
uint32_t directions;
|
||||||
|
|
||||||
|
region = cairo_region_reference (native->region);
|
||||||
|
x = *x_inout;
|
||||||
|
y = *y_inout;
|
||||||
|
|
||||||
|
/* For motions in a positive direction on any axis, append the smallest
|
||||||
|
* possible value representable in a Wayland absolute coordinate. This is
|
||||||
|
* in order to avoid not clamping motion that as a floating point number
|
||||||
|
* won't be clamped, but will be rounded up to be outside of the range
|
||||||
|
* of wl_fixed_t. */
|
||||||
|
if (x > prev_x)
|
||||||
|
x += (float) wl_fixed_to_double(1);
|
||||||
|
if (y > prev_y)
|
||||||
|
y += (float) wl_fixed_to_double(1);
|
||||||
|
|
||||||
|
borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate borders given the confine region we are to use. The borders
|
||||||
|
* are defined to be the outer region of the allowed area. This means
|
||||||
|
* top/left borders are "within" the allowed area, while bottom/right
|
||||||
|
* borders are outside. This needs to be considered when clamping
|
||||||
|
* confined motion vectors.
|
||||||
|
*/
|
||||||
|
region_to_outline (region, borders);
|
||||||
|
cairo_region_destroy (region);
|
||||||
|
|
||||||
|
motion = (MetaLine2) {
|
||||||
|
.a = (MetaVector2) {
|
||||||
|
.x = prev_x,
|
||||||
|
.y = prev_y,
|
||||||
|
},
|
||||||
|
.b = (MetaVector2) {
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
directions = get_motion_directions (&motion);
|
||||||
|
|
||||||
|
while (directions)
|
||||||
|
{
|
||||||
|
closest_border = get_closest_border (borders,
|
||||||
|
&motion,
|
||||||
|
directions);
|
||||||
|
if (closest_border)
|
||||||
|
clamp_to_border (closest_border, &motion, &directions);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*x_inout = motion.b.x;
|
||||||
|
*y_inout = motion.b.y;
|
||||||
|
g_array_free (borders, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
point_to_border_distance_2 (MetaBorder *border,
|
||||||
|
float x,
|
||||||
|
float y)
|
||||||
|
{
|
||||||
|
float orig_x, orig_y;
|
||||||
|
float dx, dy;
|
||||||
|
|
||||||
|
if (meta_border_is_horizontal (border))
|
||||||
|
{
|
||||||
|
if (x < border->line.a.x)
|
||||||
|
orig_x = border->line.a.x;
|
||||||
|
else if (x > border->line.b.x)
|
||||||
|
orig_x = border->line.b.x;
|
||||||
|
else
|
||||||
|
orig_x = x;
|
||||||
|
orig_y = border->line.a.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (y < border->line.a.y)
|
||||||
|
orig_y = border->line.a.y;
|
||||||
|
else if (y > border->line.b.y)
|
||||||
|
orig_y = border->line.b.y;
|
||||||
|
else
|
||||||
|
orig_y = y;
|
||||||
|
orig_x = border->line.a.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
dx = fabsf (orig_x - x);
|
||||||
|
dy = fabsf (orig_y - y);
|
||||||
|
return dx*dx + dy*dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
closest_point_behind_border (MetaBorder *border,
|
||||||
|
float *sx,
|
||||||
|
float *sy)
|
||||||
|
{
|
||||||
|
switch (border->blocking_directions)
|
||||||
|
{
|
||||||
|
case META_BORDER_MOTION_DIRECTION_POSITIVE_X:
|
||||||
|
case META_BORDER_MOTION_DIRECTION_NEGATIVE_X:
|
||||||
|
if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_X)
|
||||||
|
*sx = border->line.a.x - wl_fixed_to_double (1);
|
||||||
|
else
|
||||||
|
*sx = border->line.a.x + wl_fixed_to_double (1);
|
||||||
|
if (*sy < border->line.a.y)
|
||||||
|
*sy = border->line.a.y + wl_fixed_to_double (1);
|
||||||
|
else if (*sy > border->line.b.y)
|
||||||
|
*sy = border->line.b.y - wl_fixed_to_double (1);
|
||||||
|
break;
|
||||||
|
case META_BORDER_MOTION_DIRECTION_POSITIVE_Y:
|
||||||
|
case META_BORDER_MOTION_DIRECTION_NEGATIVE_Y:
|
||||||
|
if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_Y)
|
||||||
|
*sy = border->line.a.y - wl_fixed_to_double (1);
|
||||||
|
else
|
||||||
|
*sy = border->line.a.y + wl_fixed_to_double (1);
|
||||||
|
if (*sx < border->line.a.x)
|
||||||
|
*sx = border->line.a.x + wl_fixed_to_double (1);
|
||||||
|
else if (*sx > (border->line.b.x))
|
||||||
|
*sx = border->line.b.x - wl_fixed_to_double (1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_constraint_impl_native_ensure_constrained (MetaPointerConstraintImpl *impl,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
MetaPointerConstraintImplNative *impl_native;
|
||||||
|
graphene_point_t point;
|
||||||
|
cairo_region_t *region;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
|
||||||
|
impl_native = META_POINTER_CONSTRAINT_IMPL_NATIVE (impl);
|
||||||
|
region = cairo_region_reference (impl_native->region);
|
||||||
|
|
||||||
|
clutter_input_device_get_coords (device, NULL, &point);
|
||||||
|
x = point.x;
|
||||||
|
y = point.y;
|
||||||
|
|
||||||
|
if (!cairo_region_contains_point (region, (int) x, (int) y))
|
||||||
|
{
|
||||||
|
GArray *borders;
|
||||||
|
float closest_distance_2 = FLT_MAX;
|
||||||
|
MetaBorder *closest_border = NULL;
|
||||||
|
ClutterSeat *seat;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder));
|
||||||
|
|
||||||
|
region_to_outline (region, borders);
|
||||||
|
|
||||||
|
for (i = 0; i < borders->len; i++)
|
||||||
|
{
|
||||||
|
MetaBorder *border = &g_array_index (borders, MetaBorder, i);
|
||||||
|
float distance_2;
|
||||||
|
|
||||||
|
distance_2 = point_to_border_distance_2 (border, x, y);
|
||||||
|
if (distance_2 < closest_distance_2)
|
||||||
|
{
|
||||||
|
closest_border = border;
|
||||||
|
closest_distance_2 = distance_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closest_point_behind_border (closest_border, &x, &y);
|
||||||
|
|
||||||
|
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||||
|
clutter_seat_warp_pointer (seat, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_region_destroy (region);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_constraint_impl_native_init (MetaPointerConstraintImplNative *constraint)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_constraint_impl_native_class_init (MetaPointerConstraintImplNativeClass *klass)
|
||||||
|
{
|
||||||
|
MetaPointerConstraintImplClass *constraint_impl;
|
||||||
|
|
||||||
|
constraint_impl = META_POINTER_CONSTRAINT_IMPL_CLASS (klass);
|
||||||
|
constraint_impl->constrain = meta_pointer_constraint_impl_native_constraint;
|
||||||
|
constraint_impl->ensure_constrained =
|
||||||
|
meta_pointer_constraint_impl_native_ensure_constrained;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MetaPointerConstraintImpl *
|
||||||
|
meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint,
|
||||||
|
const cairo_region_t *region)
|
||||||
|
{
|
||||||
|
MetaPointerConstraintImplNative *impl;
|
||||||
|
|
||||||
|
impl = g_object_new (META_TYPE_POINTER_CONSTRAINT_IMPL_NATIVE, NULL);
|
||||||
|
impl->constraint = constraint;
|
||||||
|
impl->region = cairo_region_copy (region);
|
||||||
|
|
||||||
|
return META_POINTER_CONSTRAINT_IMPL (impl);
|
||||||
|
}
|
46
src/backends/native/meta-pointer-constraint-native.h
Normal file
46
src/backends/native/meta-pointer-constraint-native.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_POINTER_CONSTRAINT_NATIVE_H
|
||||||
|
#define META_POINTER_CONSTRAINT_NATIVE_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "clutter/clutter.h"
|
||||||
|
#include "backends/meta-pointer-constraint.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define META_TYPE_POINTER_CONSTRAINT_IMPL_NATIVE (meta_pointer_constraint_impl_native_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaPointerConstraintImplNative,
|
||||||
|
meta_pointer_constraint_impl_native,
|
||||||
|
META, POINTER_CONSTRAINT_IMPL_NATIVE,
|
||||||
|
MetaPointerConstraintImpl)
|
||||||
|
|
||||||
|
MetaPointerConstraintImpl * meta_pointer_constraint_impl_native_new (MetaPointerConstraint *constraint,
|
||||||
|
const cairo_region_t *region);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* META_POINTER_CONSTRAINT_NATIVE_H */
|
3428
src/backends/native/meta-seat-impl.c
Normal file
3428
src/backends/native/meta-seat-impl.c
Normal file
File diff suppressed because it is too large
Load Diff
276
src/backends/native/meta-seat-impl.h
Normal file
276
src/backends/native/meta-seat-impl.h
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Intel Corp.
|
||||||
|
* Copyright (C) 2014 Jonas Ådahl
|
||||||
|
* Copyright (C) 2016 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Damien Lespiau <damien.lespiau@intel.com>
|
||||||
|
* Author: Jonas Ådahl <jadahl@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_SEAT_IMPL_H
|
||||||
|
#define META_SEAT_IMPL_H
|
||||||
|
|
||||||
|
#include <gudev/gudev.h>
|
||||||
|
#include <libinput.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
|
||||||
|
#include "backends/meta-input-settings-private.h"
|
||||||
|
#include "backends/meta-viewport-info.h"
|
||||||
|
#include "backends/native/meta-backend-native-types.h"
|
||||||
|
#include "backends/native/meta-barrier-native.h"
|
||||||
|
#include "backends/native/meta-cursor-renderer-native.h"
|
||||||
|
#include "backends/native/meta-keymap-native.h"
|
||||||
|
#include "backends/native/meta-pointer-constraint-native.h"
|
||||||
|
#include "backends/native/meta-xkb-utils.h"
|
||||||
|
#include "clutter/clutter.h"
|
||||||
|
|
||||||
|
typedef struct _MetaTouchState MetaTouchState;
|
||||||
|
typedef struct _MetaSeatImpl MetaSeatImpl;
|
||||||
|
typedef struct _MetaEventSource MetaEventSource;
|
||||||
|
|
||||||
|
struct _MetaTouchState
|
||||||
|
{
|
||||||
|
MetaSeatImpl *seat;
|
||||||
|
|
||||||
|
int device_slot;
|
||||||
|
int seat_slot;
|
||||||
|
graphene_point_t coords;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _MetaSeatImpl
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
GMainContext *caller_context;
|
||||||
|
GMainContext *input_context;
|
||||||
|
GMainLoop *input_loop;
|
||||||
|
GThread *input_thread;
|
||||||
|
|
||||||
|
MetaSeatNative *seat;
|
||||||
|
char *seat_id;
|
||||||
|
MetaEventSource *event_source;
|
||||||
|
struct libinput *libinput;
|
||||||
|
struct libinput_seat *libinput_seat;
|
||||||
|
GRWLock state_lock;
|
||||||
|
|
||||||
|
GSList *devices;
|
||||||
|
|
||||||
|
ClutterInputDevice *core_pointer;
|
||||||
|
ClutterInputDevice *core_keyboard;
|
||||||
|
|
||||||
|
GHashTable *touch_states;
|
||||||
|
GHashTable *cursor_renderers;
|
||||||
|
|
||||||
|
struct xkb_state *xkb;
|
||||||
|
xkb_led_index_t caps_lock_led;
|
||||||
|
xkb_led_index_t num_lock_led;
|
||||||
|
xkb_led_index_t scroll_lock_led;
|
||||||
|
xkb_layout_index_t layout_idx;
|
||||||
|
uint32_t button_state;
|
||||||
|
int button_count[KEY_CNT];
|
||||||
|
|
||||||
|
int device_id_next;
|
||||||
|
GList *free_device_ids;
|
||||||
|
|
||||||
|
MetaBarrierManagerNative *barrier_manager;
|
||||||
|
MetaPointerConstraintImpl *pointer_constraint;
|
||||||
|
|
||||||
|
MetaKeymapNative *keymap;
|
||||||
|
MetaInputSettings *input_settings;
|
||||||
|
|
||||||
|
MetaViewportInfo *viewports;
|
||||||
|
|
||||||
|
GUdevClient *udev_client;
|
||||||
|
guint tablet_mode_switch_state : 1;
|
||||||
|
guint has_touchscreen : 1;
|
||||||
|
guint has_tablet_switch : 1;
|
||||||
|
guint touch_mode : 1;
|
||||||
|
guint input_thread_initialized : 1;
|
||||||
|
|
||||||
|
/* keyboard repeat */
|
||||||
|
gboolean repeat;
|
||||||
|
uint32_t repeat_delay;
|
||||||
|
uint32_t repeat_interval;
|
||||||
|
uint32_t repeat_key;
|
||||||
|
uint32_t repeat_count;
|
||||||
|
uint32_t repeat_timer;
|
||||||
|
ClutterInputDevice *repeat_device;
|
||||||
|
|
||||||
|
float pointer_x;
|
||||||
|
float pointer_y;
|
||||||
|
|
||||||
|
/* Emulation of discrete scroll events out of smooth ones */
|
||||||
|
float accum_scroll_dx;
|
||||||
|
float accum_scroll_dy;
|
||||||
|
|
||||||
|
gboolean released;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define META_TYPE_SEAT_IMPL meta_seat_impl_get_type ()
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaSeatImpl, meta_seat_impl,
|
||||||
|
META, SEAT_IMPL, GObject)
|
||||||
|
|
||||||
|
MetaSeatImpl * meta_seat_impl_new (MetaSeatNative *seat,
|
||||||
|
const gchar *seat_id);
|
||||||
|
|
||||||
|
void meta_seat_impl_run_input_task (MetaSeatImpl *impl,
|
||||||
|
GTask *task,
|
||||||
|
GSourceFunc dispatch_func);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_key (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
uint64_t time_us,
|
||||||
|
uint32_t key,
|
||||||
|
uint32_t state,
|
||||||
|
gboolean update_keys);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_relative_motion (MetaSeatImpl *seat_evdev,
|
||||||
|
ClutterInputDevice *input_device,
|
||||||
|
uint64_t time_us,
|
||||||
|
float dx,
|
||||||
|
float dy,
|
||||||
|
float dx_unaccel,
|
||||||
|
float dy_unaccel);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_absolute_motion (MetaSeatImpl *seat_evdev,
|
||||||
|
ClutterInputDevice *input_device,
|
||||||
|
uint64_t time_us,
|
||||||
|
float x,
|
||||||
|
float y,
|
||||||
|
double *axes);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_button (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDevice *input_device,
|
||||||
|
uint64_t time_us,
|
||||||
|
uint32_t button,
|
||||||
|
uint32_t state);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_scroll_continuous (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDevice *input_device,
|
||||||
|
uint64_t time_us,
|
||||||
|
double dx,
|
||||||
|
double dy,
|
||||||
|
ClutterScrollSource source,
|
||||||
|
ClutterScrollFinishFlags flags);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_discrete_scroll (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDevice *input_device,
|
||||||
|
uint64_t time_us,
|
||||||
|
double discrete_dx,
|
||||||
|
double discrete_dy,
|
||||||
|
ClutterScrollSource source);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_touch_event (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDevice *input_device,
|
||||||
|
ClutterEventType evtype,
|
||||||
|
uint64_t time_us,
|
||||||
|
int slot,
|
||||||
|
double x,
|
||||||
|
double y);
|
||||||
|
|
||||||
|
void meta_seat_impl_set_libinput_seat (MetaSeatImpl *seat,
|
||||||
|
struct libinput_seat *libinput_seat);
|
||||||
|
|
||||||
|
void meta_seat_impl_sync_leds (MetaSeatImpl *seat);
|
||||||
|
|
||||||
|
MetaTouchState * meta_seat_impl_acquire_touch_state (MetaSeatImpl *seat,
|
||||||
|
int seat_slot);
|
||||||
|
MetaTouchState * meta_seat_impl_lookup_touch_state (MetaSeatImpl *seat,
|
||||||
|
int seat_slot);
|
||||||
|
|
||||||
|
void meta_seat_impl_release_touch_state (MetaSeatImpl *seat,
|
||||||
|
int seat_slot);
|
||||||
|
|
||||||
|
gint meta_seat_impl_acquire_device_id (MetaSeatImpl *seat);
|
||||||
|
void meta_seat_impl_release_device_id (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
|
void meta_seat_impl_update_xkb_state (MetaSeatImpl *seat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MetaOpenDeviceCallback:
|
||||||
|
* @path: the device path
|
||||||
|
* @flags: flags to be passed to open
|
||||||
|
*
|
||||||
|
* This callback will be called when Clutter needs to access an input
|
||||||
|
* device. It should return an open file descriptor for the file at @path,
|
||||||
|
* or -1 if opening failed.
|
||||||
|
*/
|
||||||
|
typedef int (* MetaOpenDeviceCallback) (const char *path,
|
||||||
|
int flags,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error);
|
||||||
|
typedef void (* MetaCloseDeviceCallback) (int fd,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
void meta_seat_impl_set_device_callbacks (MetaOpenDeviceCallback open_callback,
|
||||||
|
MetaCloseDeviceCallback close_callback,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
void meta_seat_impl_release_devices (MetaSeatImpl *seat);
|
||||||
|
void meta_seat_impl_reclaim_devices (MetaSeatImpl *seat);
|
||||||
|
|
||||||
|
struct xkb_state * meta_seat_impl_get_xkb_state (MetaSeatImpl *seat);
|
||||||
|
|
||||||
|
void meta_seat_impl_set_keyboard_map (MetaSeatImpl *seat,
|
||||||
|
struct xkb_keymap *keymap);
|
||||||
|
|
||||||
|
void meta_seat_impl_set_keyboard_layout_index (MetaSeatImpl *seat,
|
||||||
|
xkb_layout_index_t idx);
|
||||||
|
|
||||||
|
void meta_seat_impl_set_keyboard_numlock (MetaSeatImpl *seat,
|
||||||
|
gboolean numlock_state);
|
||||||
|
|
||||||
|
void meta_seat_impl_set_keyboard_repeat (MetaSeatImpl *seat,
|
||||||
|
gboolean repeat,
|
||||||
|
uint32_t delay,
|
||||||
|
uint32_t interval);
|
||||||
|
|
||||||
|
MetaBarrierManagerNative * meta_seat_impl_get_barrier_manager (MetaSeatImpl *seat);
|
||||||
|
|
||||||
|
void meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat,
|
||||||
|
MetaPointerConstraintImpl *impl);
|
||||||
|
void meta_seat_impl_set_viewports (MetaSeatImpl *seat,
|
||||||
|
MetaViewportInfo *viewports);
|
||||||
|
|
||||||
|
void meta_seat_impl_warp_pointer (MetaSeatImpl *seat,
|
||||||
|
int x,
|
||||||
|
int y);
|
||||||
|
ClutterVirtualInputDevice *
|
||||||
|
meta_seat_impl_create_virtual_device (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDeviceType device_type);
|
||||||
|
gboolean meta_seat_impl_query_state (MetaSeatImpl *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
graphene_point_t *coords,
|
||||||
|
ClutterModifierType *modifiers);
|
||||||
|
ClutterInputDevice * meta_seat_impl_get_pointer (MetaSeatImpl *seat);
|
||||||
|
ClutterInputDevice * meta_seat_impl_get_keyboard (MetaSeatImpl *seat);
|
||||||
|
GSList * meta_seat_impl_get_devices (MetaSeatImpl *seat);
|
||||||
|
|
||||||
|
MetaKeymapNative * meta_seat_impl_get_keymap (MetaSeatImpl *seat);
|
||||||
|
|
||||||
|
void meta_seat_impl_notify_kbd_a11y_flags_changed (MetaSeatImpl *impl,
|
||||||
|
MetaKeyboardA11yFlags new_flags,
|
||||||
|
MetaKeyboardA11yFlags what_changed);
|
||||||
|
void meta_seat_impl_notify_kbd_a11y_mods_state_changed (MetaSeatImpl *impl,
|
||||||
|
xkb_mod_mask_t new_latched_mods,
|
||||||
|
xkb_mod_mask_t new_locked_mods);
|
||||||
|
void meta_seat_impl_notify_bell (MetaSeatImpl *impl);
|
||||||
|
|
||||||
|
MetaInputSettings * meta_seat_impl_get_input_settings (MetaSeatImpl *impl);
|
||||||
|
|
||||||
|
#endif /* META_SEAT_IMPL_H */
|
File diff suppressed because it is too large
Load Diff
@ -27,220 +27,49 @@
|
|||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
|
|
||||||
|
#include "backends/meta-viewport-info.h"
|
||||||
|
#include "backends/native/meta-barrier-native.h"
|
||||||
|
#include "backends/native/meta-cursor-renderer-native.h"
|
||||||
#include "backends/native/meta-keymap-native.h"
|
#include "backends/native/meta-keymap-native.h"
|
||||||
|
#include "backends/native/meta-pointer-constraint-native.h"
|
||||||
|
#include "backends/native/meta-seat-impl.h"
|
||||||
#include "backends/native/meta-xkb-utils.h"
|
#include "backends/native/meta-xkb-utils.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
|
|
||||||
typedef struct _MetaTouchState MetaTouchState;
|
|
||||||
typedef struct _MetaSeatNative MetaSeatNative;
|
typedef struct _MetaSeatNative MetaSeatNative;
|
||||||
typedef struct _MetaEventSource MetaEventSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MetaPointerConstrainCallback:
|
|
||||||
* @device: the core pointer device
|
|
||||||
* @time: the event time in milliseconds
|
|
||||||
* @x: (inout): the new X coordinate
|
|
||||||
* @y: (inout): the new Y coordinate
|
|
||||||
* @user_data: user data passed to this function
|
|
||||||
*
|
|
||||||
* This callback will be called for all pointer motion events, and should
|
|
||||||
* update (@x, @y) to constrain the pointer position appropriately.
|
|
||||||
* The subsequent motion event will use the updated values as the new coordinates.
|
|
||||||
* Note that the coordinates are not clamped to the stage size, and the callback
|
|
||||||
* must make sure that this happens before it returns.
|
|
||||||
* Also note that the event will be emitted even if the pointer is constrained
|
|
||||||
* to be in the same position.
|
|
||||||
*/
|
|
||||||
typedef void (* MetaPointerConstrainCallback) (ClutterInputDevice *device,
|
|
||||||
uint32_t time,
|
|
||||||
float prev_x,
|
|
||||||
float prev_y,
|
|
||||||
float *x,
|
|
||||||
float *y,
|
|
||||||
gpointer user_data);
|
|
||||||
typedef void (* MetaRelativeMotionFilter) (ClutterInputDevice *device,
|
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
float *dx,
|
|
||||||
float *dy,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
struct _MetaTouchState
|
|
||||||
{
|
|
||||||
MetaSeatNative *seat;
|
|
||||||
|
|
||||||
int device_slot;
|
|
||||||
int seat_slot;
|
|
||||||
graphene_point_t coords;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaSeatNative
|
struct _MetaSeatNative
|
||||||
{
|
{
|
||||||
ClutterSeat parent_instance;
|
ClutterSeat parent_instance;
|
||||||
|
|
||||||
|
MetaSeatImpl *impl;
|
||||||
char *seat_id;
|
char *seat_id;
|
||||||
MetaEventSource *event_source;
|
|
||||||
struct libinput *libinput;
|
|
||||||
struct libinput_seat *libinput_seat;
|
|
||||||
|
|
||||||
GSList *devices;
|
GList *devices;
|
||||||
|
struct xkb_keymap *xkb_keymap;
|
||||||
|
xkb_layout_index_t xkb_layout_index;
|
||||||
|
|
||||||
ClutterInputDevice *core_pointer;
|
ClutterInputDevice *core_pointer;
|
||||||
ClutterInputDevice *core_keyboard;
|
ClutterInputDevice *core_keyboard;
|
||||||
|
|
||||||
MetaTouchState **touch_states;
|
|
||||||
int n_alloc_touch_states;
|
|
||||||
|
|
||||||
struct xkb_state *xkb;
|
|
||||||
xkb_led_index_t caps_lock_led;
|
|
||||||
xkb_led_index_t num_lock_led;
|
|
||||||
xkb_led_index_t scroll_lock_led;
|
|
||||||
xkb_layout_index_t layout_idx;
|
|
||||||
uint32_t button_state;
|
|
||||||
int button_count[KEY_CNT];
|
|
||||||
|
|
||||||
ClutterStage *stage;
|
|
||||||
ClutterStageManager *stage_manager;
|
|
||||||
gulong stage_added_handler;
|
|
||||||
gulong stage_removed_handler;
|
|
||||||
|
|
||||||
int device_id_next;
|
|
||||||
GList *free_device_ids;
|
|
||||||
|
|
||||||
MetaPointerConstrainCallback constrain_callback;
|
|
||||||
gpointer constrain_data;
|
|
||||||
GDestroyNotify constrain_data_notify;
|
|
||||||
|
|
||||||
MetaRelativeMotionFilter relative_motion_filter;
|
|
||||||
gpointer relative_motion_filter_user_data;
|
|
||||||
|
|
||||||
GSList *event_filters;
|
|
||||||
|
|
||||||
MetaKeymapNative *keymap;
|
MetaKeymapNative *keymap;
|
||||||
|
MetaCursorRenderer *cursor_renderer;
|
||||||
GUdevClient *udev_client;
|
MetaKmsCursorRenderer *kms_cursor_renderer;
|
||||||
guint tablet_mode_switch_state : 1;
|
GHashTable *tablet_cursors;
|
||||||
guint has_touchscreen : 1;
|
|
||||||
guint has_tablet_switch : 1;
|
|
||||||
guint touch_mode : 1;
|
|
||||||
|
|
||||||
/* keyboard repeat */
|
|
||||||
gboolean repeat;
|
|
||||||
uint32_t repeat_delay;
|
|
||||||
uint32_t repeat_interval;
|
|
||||||
uint32_t repeat_key;
|
|
||||||
uint32_t repeat_count;
|
|
||||||
uint32_t repeat_timer;
|
|
||||||
ClutterInputDevice *repeat_device;
|
|
||||||
|
|
||||||
float pointer_x;
|
|
||||||
float pointer_y;
|
|
||||||
|
|
||||||
/* Emulation of discrete scroll events out of smooth ones */
|
|
||||||
float accum_scroll_dx;
|
|
||||||
float accum_scroll_dy;
|
|
||||||
|
|
||||||
gboolean released;
|
gboolean released;
|
||||||
|
gboolean touch_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define META_TYPE_SEAT_NATIVE meta_seat_native_get_type ()
|
#define META_TYPE_SEAT_NATIVE meta_seat_native_get_type ()
|
||||||
G_DECLARE_FINAL_TYPE (MetaSeatNative, meta_seat_native,
|
G_DECLARE_FINAL_TYPE (MetaSeatNative, meta_seat_native,
|
||||||
META, SEAT_NATIVE, ClutterSeat)
|
META, SEAT_NATIVE, ClutterSeat)
|
||||||
|
|
||||||
void meta_seat_native_notify_key (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *device,
|
|
||||||
uint64_t time_us,
|
|
||||||
uint32_t key,
|
|
||||||
uint32_t state,
|
|
||||||
gboolean update_keys);
|
|
||||||
|
|
||||||
void meta_seat_native_notify_relative_motion (MetaSeatNative *seat_evdev,
|
|
||||||
ClutterInputDevice *input_device,
|
|
||||||
uint64_t time_us,
|
|
||||||
float dx,
|
|
||||||
float dy,
|
|
||||||
float dx_unaccel,
|
|
||||||
float dy_unaccel);
|
|
||||||
|
|
||||||
void meta_seat_native_notify_absolute_motion (MetaSeatNative *seat_evdev,
|
|
||||||
ClutterInputDevice *input_device,
|
|
||||||
uint64_t time_us,
|
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
double *axes);
|
|
||||||
|
|
||||||
void meta_seat_native_notify_button (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *input_device,
|
|
||||||
uint64_t time_us,
|
|
||||||
uint32_t button,
|
|
||||||
uint32_t state);
|
|
||||||
|
|
||||||
void meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *input_device,
|
|
||||||
uint64_t time_us,
|
|
||||||
double dx,
|
|
||||||
double dy,
|
|
||||||
ClutterScrollSource source,
|
|
||||||
ClutterScrollFinishFlags flags);
|
|
||||||
|
|
||||||
void meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *input_device,
|
|
||||||
uint64_t time_us,
|
|
||||||
double discrete_dx,
|
|
||||||
double discrete_dy,
|
|
||||||
ClutterScrollSource source);
|
|
||||||
|
|
||||||
void meta_seat_native_notify_touch_event (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *input_device,
|
|
||||||
ClutterEventType evtype,
|
|
||||||
uint64_t time_us,
|
|
||||||
int slot,
|
|
||||||
double x,
|
|
||||||
double y);
|
|
||||||
|
|
||||||
void meta_seat_native_set_libinput_seat (MetaSeatNative *seat,
|
void meta_seat_native_set_libinput_seat (MetaSeatNative *seat,
|
||||||
struct libinput_seat *libinput_seat);
|
struct libinput_seat *libinput_seat);
|
||||||
|
|
||||||
void meta_seat_native_sync_leds (MetaSeatNative *seat);
|
void meta_seat_native_sync_leds (MetaSeatNative *seat);
|
||||||
|
|
||||||
ClutterInputDevice * meta_seat_native_get_device (MetaSeatNative *seat,
|
|
||||||
int id);
|
|
||||||
|
|
||||||
MetaTouchState * meta_seat_native_acquire_touch_state (MetaSeatNative *seat,
|
|
||||||
int device_slot);
|
|
||||||
|
|
||||||
void meta_seat_native_release_touch_state (MetaSeatNative *seat,
|
|
||||||
MetaTouchState *touch_state);
|
|
||||||
|
|
||||||
void meta_seat_native_set_stage (MetaSeatNative *seat,
|
|
||||||
ClutterStage *stage);
|
|
||||||
ClutterStage * meta_seat_native_get_stage (MetaSeatNative *seat);
|
|
||||||
|
|
||||||
void meta_seat_native_clear_repeat_timer (MetaSeatNative *seat);
|
|
||||||
|
|
||||||
gint meta_seat_native_acquire_device_id (MetaSeatNative *seat);
|
|
||||||
void meta_seat_native_release_device_id (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *device);
|
|
||||||
|
|
||||||
void meta_seat_native_update_xkb_state (MetaSeatNative *seat);
|
|
||||||
|
|
||||||
void meta_seat_native_constrain_pointer (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *core_pointer,
|
|
||||||
uint64_t time_us,
|
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
float *new_x,
|
|
||||||
float *new_y);
|
|
||||||
|
|
||||||
void meta_seat_native_filter_relative_motion (MetaSeatNative *seat,
|
|
||||||
ClutterInputDevice *device,
|
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
float *dx,
|
|
||||||
float *dy);
|
|
||||||
|
|
||||||
void meta_seat_native_dispatch (MetaSeatNative *seat);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MetaOpenDeviceCallback:
|
* MetaOpenDeviceCallback:
|
||||||
* @path: the device path
|
* @path: the device path
|
||||||
@ -264,30 +93,10 @@ void meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callba
|
|||||||
void meta_seat_native_release_devices (MetaSeatNative *seat);
|
void meta_seat_native_release_devices (MetaSeatNative *seat);
|
||||||
void meta_seat_native_reclaim_devices (MetaSeatNative *seat);
|
void meta_seat_native_reclaim_devices (MetaSeatNative *seat);
|
||||||
|
|
||||||
void meta_seat_native_set_pointer_constrain_callback (MetaSeatNative *seat,
|
void meta_seat_native_set_keyboard_map (MetaSeatNative *seat,
|
||||||
MetaPointerConstrainCallback callback,
|
const char *layouts,
|
||||||
gpointer user_data,
|
const char *variants,
|
||||||
GDestroyNotify user_data_notify);
|
const char *options);
|
||||||
|
|
||||||
void meta_seat_native_set_relative_motion_filter (MetaSeatNative *seat,
|
|
||||||
MetaRelativeMotionFilter filter,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
typedef gboolean (* MetaEvdevFilterFunc) (struct libinput_event *event,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
void meta_seat_native_add_filter (MetaSeatNative *seat,
|
|
||||||
MetaEvdevFilterFunc func,
|
|
||||||
gpointer data,
|
|
||||||
GDestroyNotify destroy_notify);
|
|
||||||
void meta_seat_native_remove_filter (MetaSeatNative *seat,
|
|
||||||
MetaEvdevFilterFunc func,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
struct xkb_state * meta_seat_native_get_xkb_state (MetaSeatNative *seat);
|
|
||||||
|
|
||||||
void meta_seat_native_set_keyboard_map (MetaSeatNative *seat,
|
|
||||||
struct xkb_keymap *keymap);
|
|
||||||
|
|
||||||
struct xkb_keymap * meta_seat_native_get_keyboard_map (MetaSeatNative *seat);
|
struct xkb_keymap * meta_seat_native_get_keyboard_map (MetaSeatNative *seat);
|
||||||
|
|
||||||
@ -304,4 +113,17 @@ void meta_seat_native_set_keyboard_repeat (MetaSeatNative *seat,
|
|||||||
uint32_t delay,
|
uint32_t delay,
|
||||||
uint32_t interval);
|
uint32_t interval);
|
||||||
|
|
||||||
|
MetaBarrierManagerNative * meta_seat_native_get_barrier_manager (MetaSeatNative *seat);
|
||||||
|
|
||||||
|
void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat,
|
||||||
|
MetaPointerConstraintImpl *impl);
|
||||||
|
MetaCursorRenderer * meta_seat_native_get_cursor_renderer (MetaSeatNative *seat,
|
||||||
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
|
void meta_seat_native_set_viewports (MetaSeatNative *seat,
|
||||||
|
MetaViewportInfo *viewports);
|
||||||
|
void meta_seat_native_notify_kbd_a11y_change (MetaSeatNative *seat,
|
||||||
|
MetaKeyboardA11yFlags new_flags,
|
||||||
|
MetaKeyboardA11yFlags what_changed);
|
||||||
|
|
||||||
#endif /* META_SEAT_NATIVE_H */
|
#endif /* META_SEAT_NATIVE_H */
|
||||||
|
@ -49,6 +49,45 @@ struct _MetaVirtualInputDeviceNative
|
|||||||
int button_count[KEY_CNT];
|
int button_count[KEY_CNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t time_us;
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
} MetaVirtualEventMotion;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t time_us;
|
||||||
|
uint32_t button;
|
||||||
|
ClutterButtonState button_state;
|
||||||
|
} MetaVirtualEventButton;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t time_us;
|
||||||
|
double dx;
|
||||||
|
double dy;
|
||||||
|
ClutterScrollDirection direction;
|
||||||
|
ClutterScrollSource scroll_source;
|
||||||
|
ClutterScrollFinishFlags finish_flags;
|
||||||
|
} MetaVirtualEventScroll;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t time_us;
|
||||||
|
uint32_t key;
|
||||||
|
ClutterKeyState key_state;
|
||||||
|
} MetaVirtualEventKey;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t time_us;
|
||||||
|
int device_slot;
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
} MetaVirtualEventTouch;
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaVirtualInputDeviceNative,
|
G_DEFINE_TYPE (MetaVirtualInputDeviceNative,
|
||||||
meta_virtual_input_device_native,
|
meta_virtual_input_device_native,
|
||||||
CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
|
CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
|
||||||
@ -107,11 +146,10 @@ get_button_type (uint16_t code)
|
|||||||
return EVDEV_BUTTON_TYPE_NONE;
|
return EVDEV_BUTTON_TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
release_device (GTask *task)
|
||||||
{
|
{
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev = g_task_get_task_data (task);
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
|
||||||
int code;
|
int code;
|
||||||
uint64_t time_us;
|
uint64_t time_us;
|
||||||
|
|
||||||
@ -119,7 +157,7 @@ release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
|||||||
|
|
||||||
meta_topic (META_DEBUG_INPUT,
|
meta_topic (META_DEBUG_INPUT,
|
||||||
"Releasing pressed buttons while destroying virtual input device "
|
"Releasing pressed buttons while destroying virtual input device "
|
||||||
"(device %p)\n", virtual_device);
|
"(device %p)\n", virtual_evdev);
|
||||||
|
|
||||||
for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++)
|
for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++)
|
||||||
{
|
{
|
||||||
@ -129,19 +167,19 @@ release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
|||||||
switch (get_button_type (code))
|
switch (get_button_type (code))
|
||||||
{
|
{
|
||||||
case EVDEV_BUTTON_TYPE_KEY:
|
case EVDEV_BUTTON_TYPE_KEY:
|
||||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
meta_seat_impl_notify_key (virtual_evdev->seat->impl,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
time_us,
|
time_us,
|
||||||
code,
|
code,
|
||||||
CLUTTER_KEY_STATE_RELEASED,
|
CLUTTER_KEY_STATE_RELEASED,
|
||||||
TRUE);
|
TRUE);
|
||||||
break;
|
break;
|
||||||
case EVDEV_BUTTON_TYPE_BUTTON:
|
case EVDEV_BUTTON_TYPE_BUTTON:
|
||||||
meta_seat_native_notify_button (virtual_evdev->seat,
|
meta_seat_impl_notify_button (virtual_evdev->seat->impl,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
time_us,
|
time_us,
|
||||||
code,
|
code,
|
||||||
CLUTTER_BUTTON_STATE_RELEASED);
|
CLUTTER_BUTTON_STATE_RELEASED);
|
||||||
break;
|
break;
|
||||||
case EVDEV_BUTTON_TYPE_NONE:
|
case EVDEV_BUTTON_TYPE_NONE:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
@ -149,6 +187,31 @@ release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
|||||||
|
|
||||||
update_button_count (virtual_evdev, code, 0);
|
update_button_count (virtual_evdev, code, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_clear_object (&virtual_evdev->device);
|
||||||
|
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
notify_relative_motion (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventMotion *event = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
meta_seat_impl_notify_relative_motion (seat,
|
||||||
|
virtual_evdev->device,
|
||||||
|
event->time_us,
|
||||||
|
event->x, event->y,
|
||||||
|
event->x, event->y);
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -157,19 +220,43 @@ meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevi
|
|||||||
double dx,
|
double dx,
|
||||||
double dy)
|
double dy)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventMotion *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventMotion, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->x = dx;
|
||||||
|
event->y = dy;
|
||||||
|
|
||||||
meta_seat_native_notify_relative_motion (virtual_evdev->seat,
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
virtual_evdev->device,
|
g_task_set_task_data (task, event, g_free);
|
||||||
time_us,
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
dx, dy,
|
(GSourceFunc) notify_relative_motion);
|
||||||
dx, dy);
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
notify_absolute_motion (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventMotion *event = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
meta_seat_impl_notify_absolute_motion (seat,
|
||||||
|
virtual_evdev->device,
|
||||||
|
event->time_us,
|
||||||
|
event->x, event->y,
|
||||||
|
NULL);
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -178,19 +265,23 @@ meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevi
|
|||||||
double x,
|
double x,
|
||||||
double y)
|
double y)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventMotion *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventMotion, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->x = x;
|
||||||
|
event->y = y;
|
||||||
|
|
||||||
meta_seat_native_notify_absolute_motion (virtual_evdev->seat,
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
virtual_evdev->device,
|
g_task_set_task_data (task, event, g_free);
|
||||||
time_us,
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
x, y,
|
(GSourceFunc) notify_absolute_motion);
|
||||||
NULL);
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -213,50 +304,123 @@ translate_to_evdev_button (int clutter_button)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
notify_button (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventButton *event = g_task_get_task_data (task);
|
||||||
|
int button_count;
|
||||||
|
int evdev_button;
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
evdev_button = translate_to_evdev_button (event->button);
|
||||||
|
|
||||||
|
if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON)
|
||||||
|
{
|
||||||
|
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
|
||||||
|
evdev_button);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
button_count = update_button_count (virtual_evdev, evdev_button,
|
||||||
|
event->button_state);
|
||||||
|
if (button_count < 0 || button_count > 1)
|
||||||
|
{
|
||||||
|
g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button,
|
||||||
|
event->button_state == CLUTTER_BUTTON_STATE_PRESSED ?
|
||||||
|
"presses" : "releases");
|
||||||
|
update_button_count (virtual_evdev, evdev_button, 1 - event->button_state);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_INPUT,
|
||||||
|
"Emitting virtual button-%s of button 0x%x (device %p)\n",
|
||||||
|
event->button_state == CLUTTER_BUTTON_STATE_PRESSED ?
|
||||||
|
"press" : "release",
|
||||||
|
evdev_button, virtual_evdev);
|
||||||
|
|
||||||
|
meta_seat_impl_notify_button (seat,
|
||||||
|
virtual_evdev->device,
|
||||||
|
event->time_us,
|
||||||
|
evdev_button,
|
||||||
|
event->button_state);
|
||||||
|
out:
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device,
|
meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device,
|
||||||
uint64_t time_us,
|
uint64_t time_us,
|
||||||
uint32_t button,
|
uint32_t button,
|
||||||
ClutterButtonState button_state)
|
ClutterButtonState button_state)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventButton *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
int button_count;
|
GTask *task;
|
||||||
int evdev_button;
|
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventButton, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->button = button;
|
||||||
|
event->button_state = button_state;
|
||||||
|
|
||||||
evdev_button = translate_to_evdev_button (button);
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
|
g_task_set_task_data (task, event, g_free);
|
||||||
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
|
(GSourceFunc) notify_button);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON)
|
static gboolean
|
||||||
|
notify_key (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventKey *event = g_task_get_task_data (task);
|
||||||
|
int key_count;
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
if (get_button_type (event->key) != EVDEV_BUTTON_TYPE_KEY)
|
||||||
{
|
{
|
||||||
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
|
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", event->key);
|
||||||
evdev_button);
|
goto out;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button_count = update_button_count (virtual_evdev, evdev_button, button_state);
|
key_count = update_button_count (virtual_evdev, event->key, event->key_state);
|
||||||
if (button_count < 0 || button_count > 1)
|
if (key_count < 0 || key_count > 1)
|
||||||
{
|
{
|
||||||
g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button,
|
g_warning ("Received multiple virtual 0x%x key %s (ignoring)", event->key,
|
||||||
button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases");
|
event->key_state == CLUTTER_KEY_STATE_PRESSED ?
|
||||||
update_button_count (virtual_evdev, evdev_button, 1 - button_state);
|
"presses" : "releases");
|
||||||
return;
|
update_button_count (virtual_evdev, event->key, 1 - event->key_state);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_INPUT,
|
meta_topic (META_DEBUG_INPUT,
|
||||||
"Emitting virtual button-%s of button 0x%x (device %p)\n",
|
"Emitting virtual key-%s of key 0x%x (device %p)\n",
|
||||||
button_state == CLUTTER_BUTTON_STATE_PRESSED ? "press" : "release",
|
event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
|
||||||
evdev_button, virtual_device);
|
event->key, virtual_evdev);
|
||||||
|
|
||||||
meta_seat_native_notify_button (virtual_evdev->seat,
|
meta_seat_impl_notify_key (seat,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
time_us,
|
event->time_us,
|
||||||
evdev_button,
|
event->key,
|
||||||
button_state);
|
event->key_state,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -265,41 +429,23 @@ meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_
|
|||||||
uint32_t key,
|
uint32_t key,
|
||||||
ClutterKeyState key_state)
|
ClutterKeyState key_state)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventKey *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
int key_count;
|
GTask *task;
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventKey, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->key = key;
|
||||||
|
event->key_state = key_state;
|
||||||
|
|
||||||
if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY)
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
{
|
g_task_set_task_data (task, event, g_free);
|
||||||
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key);
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
return;
|
(GSourceFunc) notify_key);
|
||||||
}
|
g_object_unref (task);
|
||||||
|
|
||||||
key_count = update_button_count (virtual_evdev, key, key_state);
|
|
||||||
if (key_count < 0 || key_count > 1)
|
|
||||||
{
|
|
||||||
g_warning ("Received multiple virtual 0x%x key %s (ignoring)", key,
|
|
||||||
key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases");
|
|
||||||
update_button_count (virtual_evdev, key, 1 - key_state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_INPUT,
|
|
||||||
"Emitting virtual key-%s of key 0x%x (device %p)\n",
|
|
||||||
key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
|
|
||||||
key, virtual_device);
|
|
||||||
|
|
||||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
|
||||||
virtual_evdev->device,
|
|
||||||
time_us,
|
|
||||||
key,
|
|
||||||
key_state,
|
|
||||||
TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -320,7 +466,7 @@ pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_dev
|
|||||||
backend = clutter_get_default_backend ();
|
backend = clutter_get_default_backend ();
|
||||||
keymap = clutter_seat_get_keymap (clutter_backend_get_default_seat (backend));
|
keymap = clutter_seat_get_keymap (clutter_backend_get_default_seat (backend));
|
||||||
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap));
|
||||||
state = virtual_evdev->seat->xkb;
|
state = meta_seat_impl_get_xkb_state (virtual_evdev->seat->impl);
|
||||||
|
|
||||||
layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE);
|
layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE);
|
||||||
min_keycode = xkb_keymap_min_keycode (xkb_keymap);
|
min_keycode = xkb_keymap_min_keycode (xkb_keymap);
|
||||||
@ -389,35 +535,34 @@ apply_level_modifiers (ClutterVirtualInputDevice *virtual_device,
|
|||||||
key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
|
key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
|
||||||
evcode, virtual_device);
|
evcode, virtual_device);
|
||||||
|
|
||||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
meta_seat_impl_notify_key (virtual_evdev->seat->impl,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
time_us,
|
time_us,
|
||||||
evcode,
|
evcode,
|
||||||
key_state,
|
key_state,
|
||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device,
|
notify_keyval (GTask *task)
|
||||||
uint64_t time_us,
|
|
||||||
uint32_t keyval,
|
|
||||||
ClutterKeyState key_state)
|
|
||||||
{
|
{
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
g_task_get_source_object (task);
|
||||||
|
ClutterVirtualInputDevice *virtual_device =
|
||||||
|
CLUTTER_VIRTUAL_INPUT_DEVICE (virtual_evdev);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventKey *event = g_task_get_task_data (task);
|
||||||
int key_count;
|
int key_count;
|
||||||
guint keycode = 0, level = 0, evcode = 0;
|
guint keycode = 0, level = 0, evcode = 0;
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
|
||||||
time_us = g_get_monotonic_time ();
|
|
||||||
|
|
||||||
if (!pick_keycode_for_keyval_in_current_group (virtual_device,
|
if (!pick_keycode_for_keyval_in_current_group (virtual_device,
|
||||||
keyval, &keycode, &level))
|
event->key, &keycode, &level))
|
||||||
{
|
{
|
||||||
g_warning ("No keycode found for keyval %x in current group", keyval);
|
g_warning ("No keycode found for keyval %x in current group", event->key);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
clutter_input_device_keycode_to_evdev (virtual_evdev->device,
|
clutter_input_device_keycode_to_evdev (virtual_evdev->device,
|
||||||
@ -426,36 +571,66 @@ meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtu
|
|||||||
if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY)
|
if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY)
|
||||||
{
|
{
|
||||||
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", evcode);
|
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", evcode);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_count = update_button_count (virtual_evdev, evcode, key_state);
|
key_count = update_button_count (virtual_evdev, evcode, event->key_state);
|
||||||
if (key_count < 0 || key_count > 1)
|
if (key_count < 0 || key_count > 1)
|
||||||
{
|
{
|
||||||
g_warning ("Received multiple virtual 0x%x key %s (ignoring)", evcode,
|
g_warning ("Received multiple virtual 0x%x key %s (ignoring)", evcode,
|
||||||
key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases");
|
event->key_state == CLUTTER_KEY_STATE_PRESSED ?
|
||||||
update_button_count (virtual_evdev, evcode, 1 - key_state);
|
"presses" : "releases");
|
||||||
return;
|
update_button_count (virtual_evdev, evcode, 1 - event->key_state);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_INPUT,
|
meta_topic (META_DEBUG_INPUT,
|
||||||
"Emitting virtual key-%s of key 0x%x with modifier level %d, "
|
"Emitting virtual key-%s of key 0x%x with modifier level %d, "
|
||||||
"press count %d (device %p)\n",
|
"press count %d (device %p)\n",
|
||||||
key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
|
event->key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release",
|
||||||
evcode, level, key_count, virtual_device);
|
evcode, level, key_count, virtual_evdev);
|
||||||
|
|
||||||
if (key_state)
|
if (event->key_state)
|
||||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
apply_level_modifiers (virtual_device, event->time_us, level, event->key_state);
|
||||||
|
|
||||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
meta_seat_impl_notify_key (seat,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
time_us,
|
event->time_us,
|
||||||
evcode,
|
evcode,
|
||||||
key_state,
|
event->key_state,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
if (!key_state)
|
if (!event->key_state)
|
||||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
apply_level_modifiers (virtual_device, event->time_us, level, event->key_state);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device,
|
||||||
|
uint64_t time_us,
|
||||||
|
uint32_t keyval,
|
||||||
|
ClutterKeyState key_state)
|
||||||
|
{
|
||||||
|
MetaVirtualEventKey *event;
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
|
event = g_new0 (MetaVirtualEventKey, 1);
|
||||||
|
event->time_us = time_us;
|
||||||
|
event->key = keyval;
|
||||||
|
event->key_state = key_state;
|
||||||
|
|
||||||
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
|
g_task_set_task_data (task, event, g_free);
|
||||||
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
|
(GSourceFunc) notify_keyval);
|
||||||
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -487,28 +662,74 @@ direction_to_discrete (ClutterScrollDirection direction,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
notify_discrete_scroll (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventScroll *event = g_task_get_task_data (task);
|
||||||
|
double discrete_dx = 0.0, discrete_dy = 0.0;
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
direction_to_discrete (event->direction, &discrete_dx, &discrete_dy);
|
||||||
|
|
||||||
|
meta_seat_impl_notify_discrete_scroll (seat,
|
||||||
|
virtual_evdev->device,
|
||||||
|
event->time_us,
|
||||||
|
discrete_dx, discrete_dy,
|
||||||
|
event->scroll_source);
|
||||||
|
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||||
uint64_t time_us,
|
uint64_t time_us,
|
||||||
ClutterScrollDirection direction,
|
ClutterScrollDirection direction,
|
||||||
ClutterScrollSource scroll_source)
|
ClutterScrollSource scroll_source)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventScroll *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
double discrete_dx = 0.0, discrete_dy = 0.0;
|
GTask *task;
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventScroll, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->direction = direction;
|
||||||
|
event->scroll_source = scroll_source;
|
||||||
|
|
||||||
direction_to_discrete (direction, &discrete_dx, &discrete_dy);
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
|
g_task_set_task_data (task, event, g_free);
|
||||||
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
|
(GSourceFunc) notify_discrete_scroll);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
meta_seat_native_notify_discrete_scroll (virtual_evdev->seat,
|
static gboolean
|
||||||
|
notify_scroll_continuous (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventScroll *event = g_task_get_task_data (task);
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
meta_seat_impl_notify_scroll_continuous (seat,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
time_us,
|
event->time_us,
|
||||||
discrete_dx, discrete_dy,
|
event->dx, event->dy,
|
||||||
scroll_source);
|
event->scroll_source,
|
||||||
|
CLUTTER_SCROLL_FINISHED_NONE);
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -519,20 +740,58 @@ meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDe
|
|||||||
ClutterScrollSource scroll_source,
|
ClutterScrollSource scroll_source,
|
||||||
ClutterScrollFinishFlags finish_flags)
|
ClutterScrollFinishFlags finish_flags)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventScroll *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventScroll, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->dx = dx;
|
||||||
|
event->dy = dy;
|
||||||
|
event->scroll_source = scroll_source;
|
||||||
|
event->finish_flags = finish_flags;
|
||||||
|
|
||||||
meta_seat_native_notify_scroll_continuous (virtual_evdev->seat,
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
virtual_evdev->device,
|
g_task_set_task_data (task, event, g_free);
|
||||||
time_us,
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
dx, dy,
|
(GSourceFunc) notify_scroll_continuous);
|
||||||
scroll_source,
|
g_object_unref (task);
|
||||||
CLUTTER_SCROLL_FINISHED_NONE);
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
notify_touch_down (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventTouch *event = g_task_get_task_data (task);
|
||||||
|
MetaTouchState *touch_state;
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
touch_state = meta_seat_impl_acquire_touch_state (seat,
|
||||||
|
event->device_slot);
|
||||||
|
if (!touch_state)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
touch_state->coords.x = event->x;
|
||||||
|
touch_state->coords.y = event->y;
|
||||||
|
|
||||||
|
meta_seat_impl_notify_touch_event (seat,
|
||||||
|
virtual_evdev->device,
|
||||||
|
CLUTTER_TOUCH_BEGIN,
|
||||||
|
event->time_us,
|
||||||
|
touch_state->seat_slot,
|
||||||
|
touch_state->coords.x,
|
||||||
|
touch_state->coords.y);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -542,32 +801,57 @@ meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *v
|
|||||||
double x,
|
double x,
|
||||||
double y)
|
double y)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventTouch *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
MetaInputDeviceNative *device_evdev =
|
GTask *task;
|
||||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
|
||||||
MetaTouchState *touch_state;
|
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventTouch, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->device_slot = device_slot;
|
||||||
|
event->x = x;
|
||||||
|
event->y = y;
|
||||||
|
|
||||||
touch_state = meta_input_device_native_acquire_touch_state (device_evdev,
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
device_slot);
|
g_task_set_task_data (task, event, g_free);
|
||||||
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
|
(GSourceFunc) notify_touch_down);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
notify_touch_motion (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventTouch *event = g_task_get_task_data (task);
|
||||||
|
MetaTouchState *touch_state;
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
touch_state = meta_seat_impl_lookup_touch_state (seat,
|
||||||
|
event->device_slot);
|
||||||
if (!touch_state)
|
if (!touch_state)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
touch_state->coords.x = x;
|
touch_state->coords.x = event->x;
|
||||||
touch_state->coords.y = y;
|
touch_state->coords.y = event->y;
|
||||||
|
|
||||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
meta_seat_impl_notify_touch_event (seat,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
CLUTTER_TOUCH_BEGIN,
|
CLUTTER_TOUCH_UPDATE,
|
||||||
time_us,
|
event->time_us,
|
||||||
touch_state->seat_slot,
|
touch_state->seat_slot,
|
||||||
touch_state->coords.x,
|
touch_state->coords.x,
|
||||||
touch_state->coords.y);
|
touch_state->coords.y);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -577,32 +861,57 @@ meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice
|
|||||||
double x,
|
double x,
|
||||||
double y)
|
double y)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventTouch *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
MetaInputDeviceNative *device_evdev =
|
GTask *task;
|
||||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
|
||||||
MetaTouchState *touch_state;
|
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventTouch, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->device_slot = device_slot;
|
||||||
|
event->x = x;
|
||||||
|
event->y = y;
|
||||||
|
|
||||||
touch_state = meta_input_device_native_lookup_touch_state (device_evdev,
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
device_slot);
|
g_task_set_task_data (task, event, g_free);
|
||||||
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
|
(GSourceFunc) notify_touch_motion);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
notify_touch_up (GTask *task)
|
||||||
|
{
|
||||||
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
|
g_task_get_source_object (task);
|
||||||
|
MetaSeatImpl *seat = virtual_evdev->seat->impl;
|
||||||
|
MetaVirtualEventTouch *event = g_task_get_task_data (task);
|
||||||
|
MetaTouchState *touch_state;
|
||||||
|
|
||||||
|
if (event->time_us == CLUTTER_CURRENT_TIME)
|
||||||
|
event->time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
touch_state = meta_seat_impl_lookup_touch_state (seat,
|
||||||
|
event->device_slot);
|
||||||
if (!touch_state)
|
if (!touch_state)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
touch_state->coords.x = x;
|
meta_seat_impl_notify_touch_event (seat,
|
||||||
touch_state->coords.y = y;
|
virtual_evdev->device,
|
||||||
|
CLUTTER_TOUCH_END,
|
||||||
|
event->time_us,
|
||||||
|
touch_state->seat_slot,
|
||||||
|
touch_state->coords.x,
|
||||||
|
touch_state->coords.y);
|
||||||
|
|
||||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
meta_seat_impl_release_touch_state (virtual_evdev->seat->impl,
|
||||||
virtual_evdev->device,
|
touch_state->seat_slot);
|
||||||
CLUTTER_TOUCH_BEGIN,
|
|
||||||
time_us,
|
out:
|
||||||
touch_state->seat_slot,
|
g_task_return_boolean (task, TRUE);
|
||||||
touch_state->coords.x,
|
return G_SOURCE_REMOVE;
|
||||||
touch_state->coords.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -610,31 +919,22 @@ meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *vir
|
|||||||
uint64_t time_us,
|
uint64_t time_us,
|
||||||
int device_slot)
|
int device_slot)
|
||||||
{
|
{
|
||||||
|
MetaVirtualEventTouch *event;
|
||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device);
|
||||||
MetaInputDeviceNative *device_evdev =
|
GTask *task;
|
||||||
META_INPUT_DEVICE_NATIVE (virtual_evdev->device);
|
|
||||||
MetaTouchState *touch_state;
|
|
||||||
|
|
||||||
g_return_if_fail (virtual_evdev->device != NULL);
|
g_return_if_fail (virtual_evdev->device != NULL);
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
event = g_new0 (MetaVirtualEventTouch, 1);
|
||||||
time_us = g_get_monotonic_time ();
|
event->time_us = time_us;
|
||||||
|
event->device_slot = device_slot;
|
||||||
|
|
||||||
touch_state = meta_input_device_native_lookup_touch_state (device_evdev,
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
device_slot);
|
g_task_set_task_data (task, event, g_free);
|
||||||
if (!touch_state)
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
return;
|
(GSourceFunc) notify_touch_up);
|
||||||
|
g_object_unref (task);
|
||||||
meta_seat_native_notify_touch_event (virtual_evdev->seat,
|
|
||||||
virtual_evdev->device,
|
|
||||||
CLUTTER_TOUCH_BEGIN,
|
|
||||||
time_us,
|
|
||||||
touch_state->seat_slot,
|
|
||||||
touch_state->coords.x,
|
|
||||||
touch_state->coords.y);
|
|
||||||
|
|
||||||
meta_input_device_native_release_touch_state (device_evdev, touch_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -685,7 +985,6 @@ meta_virtual_input_device_native_constructed (GObject *object)
|
|||||||
MetaVirtualInputDeviceNative *virtual_evdev =
|
MetaVirtualInputDeviceNative *virtual_evdev =
|
||||||
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
|
META_VIRTUAL_INPUT_DEVICE_NATIVE (object);
|
||||||
ClutterInputDeviceType device_type;
|
ClutterInputDeviceType device_type;
|
||||||
ClutterStage *stage;
|
|
||||||
|
|
||||||
device_type = clutter_virtual_input_device_get_device_type (virtual_device);
|
device_type = clutter_virtual_input_device_get_device_type (virtual_device);
|
||||||
|
|
||||||
@ -694,16 +993,9 @@ meta_virtual_input_device_native_constructed (GObject *object)
|
|||||||
device_type, virtual_device);
|
device_type, virtual_device);
|
||||||
|
|
||||||
virtual_evdev->device =
|
virtual_evdev->device =
|
||||||
meta_input_device_native_new_virtual (virtual_evdev->seat,
|
meta_input_device_native_new_virtual (virtual_evdev->seat->impl,
|
||||||
device_type,
|
device_type,
|
||||||
CLUTTER_INPUT_MODE_SLAVE);
|
CLUTTER_INPUT_MODE_SLAVE);
|
||||||
|
|
||||||
stage = meta_seat_native_get_stage (virtual_evdev->seat);
|
|
||||||
_clutter_input_device_set_stage (virtual_evdev->device, stage);
|
|
||||||
|
|
||||||
g_signal_emit_by_name (virtual_evdev->seat,
|
|
||||||
"device-added",
|
|
||||||
virtual_evdev->device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -718,12 +1010,13 @@ meta_virtual_input_device_native_dispose (GObject *object)
|
|||||||
|
|
||||||
if (virtual_evdev->device)
|
if (virtual_evdev->device)
|
||||||
{
|
{
|
||||||
release_pressed_buttons (virtual_device);
|
GTask *task;
|
||||||
g_signal_emit_by_name (virtual_evdev->seat,
|
|
||||||
"device-removed",
|
|
||||||
virtual_evdev->device);
|
|
||||||
|
|
||||||
g_clear_object (&virtual_evdev->device);
|
task = g_task_new (virtual_device, NULL, NULL, NULL);
|
||||||
|
g_task_set_task_data (task, g_object_ref (virtual_device), g_object_unref);
|
||||||
|
meta_seat_impl_run_input_task (virtual_evdev->seat->impl, task,
|
||||||
|
(GSourceFunc) release_device);
|
||||||
|
g_object_unref (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
object_class->dispose (object);
|
object_class->dispose (object);
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
/*
|
/*
|
||||||
* _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent
|
* _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent
|
||||||
* @device: a ClutterInputDevice
|
* @device: a ClutterInputDevice
|
||||||
* @stage: the stage the event should be delivered to
|
|
||||||
* @xkb: XKB rules to translate the event
|
* @xkb: XKB rules to translate the event
|
||||||
* @_time: timestamp of the event
|
* @_time: timestamp of the event
|
||||||
* @key: a key code coming from a Linux input device
|
* @key: a key code coming from a Linux input device
|
||||||
@ -42,7 +41,6 @@
|
|||||||
ClutterEvent *
|
ClutterEvent *
|
||||||
meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||||
ClutterInputDevice *core_device,
|
ClutterInputDevice *core_device,
|
||||||
ClutterStage *stage,
|
|
||||||
struct xkb_state *xkb_state,
|
struct xkb_state *xkb_state,
|
||||||
uint32_t button_state,
|
uint32_t button_state,
|
||||||
uint32_t _time,
|
uint32_t _time,
|
||||||
@ -72,7 +70,6 @@ meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
|||||||
else
|
else
|
||||||
sym = XKB_KEY_NoSymbol;
|
sym = XKB_KEY_NoSymbol;
|
||||||
|
|
||||||
event->key.stage = stage;
|
|
||||||
event->key.time = _time;
|
event->key.time = _time;
|
||||||
meta_xkb_translate_state (event, xkb_state, button_state);
|
meta_xkb_translate_state (event, xkb_state, button_state);
|
||||||
event->key.hardware_keycode = key;
|
event->key.hardware_keycode = key;
|
||||||
@ -109,3 +106,10 @@ meta_xkb_translate_state (ClutterEvent *event,
|
|||||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
||||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE) | button_state);
|
xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE) | button_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
meta_xkb_translate_modifiers (struct xkb_state *state,
|
||||||
|
uint32_t button_state)
|
||||||
|
{
|
||||||
|
return xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE) | button_state;
|
||||||
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
ClutterEvent * meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
ClutterEvent * meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
||||||
ClutterInputDevice *core_keyboard,
|
ClutterInputDevice *core_keyboard,
|
||||||
ClutterStage *stage,
|
|
||||||
struct xkb_state *xkb_state,
|
struct xkb_state *xkb_state,
|
||||||
uint32_t button_state,
|
uint32_t button_state,
|
||||||
uint32_t _time,
|
uint32_t _time,
|
||||||
@ -36,5 +35,7 @@ ClutterEvent * meta_key_event_new_from_evdev (ClutterInputDevice *device,
|
|||||||
void meta_xkb_translate_state (ClutterEvent *event,
|
void meta_xkb_translate_state (ClutterEvent *event,
|
||||||
struct xkb_state *xkb_state,
|
struct xkb_state *xkb_state,
|
||||||
uint32_t button_state);
|
uint32_t button_state);
|
||||||
|
uint32_t meta_xkb_translate_modifiers (struct xkb_state *state,
|
||||||
|
uint32_t button_state);
|
||||||
|
|
||||||
#endif /* META_XKB_UTILS_H */
|
#endif /* META_XKB_UTILS_H */
|
||||||
|
@ -41,6 +41,7 @@ struct _MetaBackendX11Cm
|
|||||||
{
|
{
|
||||||
MetaBackendX11 parent;
|
MetaBackendX11 parent;
|
||||||
|
|
||||||
|
MetaCursorRenderer *cursor_renderer;
|
||||||
char *keymap_layouts;
|
char *keymap_layouts;
|
||||||
char *keymap_variants;
|
char *keymap_variants;
|
||||||
char *keymap_options;
|
char *keymap_options;
|
||||||
@ -116,11 +117,21 @@ meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorRenderer *
|
static MetaCursorRenderer *
|
||||||
meta_backend_x11_cm_create_cursor_renderer (MetaBackend *backend)
|
meta_backend_x11_cm_get_cursor_renderer (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11,
|
MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (backend);
|
||||||
"backend", backend,
|
|
||||||
NULL);
|
if (!x11_cm->cursor_renderer)
|
||||||
|
{
|
||||||
|
x11_cm->cursor_renderer =
|
||||||
|
g_object_new (META_TYPE_CURSOR_RENDERER_X11,
|
||||||
|
"backend", backend,
|
||||||
|
"device", device,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return x11_cm->cursor_renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorTracker *
|
static MetaCursorTracker *
|
||||||
@ -444,7 +455,7 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass)
|
|||||||
backend_class->post_init = meta_backend_x11_cm_post_init;
|
backend_class->post_init = meta_backend_x11_cm_post_init;
|
||||||
backend_class->create_renderer = meta_backend_x11_cm_create_renderer;
|
backend_class->create_renderer = meta_backend_x11_cm_create_renderer;
|
||||||
backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager;
|
backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager;
|
||||||
backend_class->create_cursor_renderer = meta_backend_x11_cm_create_cursor_renderer;
|
backend_class->get_cursor_renderer = meta_backend_x11_cm_get_cursor_renderer;
|
||||||
backend_class->create_cursor_tracker = meta_backend_x11_cm_create_cursor_tracker;
|
backend_class->create_cursor_tracker = meta_backend_x11_cm_create_cursor_tracker;
|
||||||
backend_class->create_input_settings = meta_backend_x11_cm_create_input_settings;
|
backend_class->create_input_settings = meta_backend_x11_cm_create_input_settings;
|
||||||
backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size;
|
backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size;
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "backends/x11/meta-seat-x11.h"
|
#include "backends/x11/meta-seat-x11.h"
|
||||||
#include "backends/x11/meta-stage-x11.h"
|
#include "backends/x11/meta-stage-x11.h"
|
||||||
#include "backends/x11/meta-renderer-x11.h"
|
#include "backends/x11/meta-renderer-x11.h"
|
||||||
|
#include "backends/x11/meta-xkb-a11y-x11.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "clutter/x11/clutter-x11.h"
|
#include "clutter/x11/clutter-x11.h"
|
||||||
#include "compositor/compositor-private.h"
|
#include "compositor/compositor-private.h"
|
||||||
@ -519,12 +520,24 @@ on_monitors_changed (MetaMonitorManager *manager,
|
|||||||
priv->cached_current_logical_monitor = NULL;
|
priv->cached_current_logical_monitor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_kbd_a11y_changed (MetaInputSettings *input_settings,
|
||||||
|
MetaKbdA11ySettings *a11y_settings,
|
||||||
|
MetaBackend *backend)
|
||||||
|
{
|
||||||
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
||||||
|
|
||||||
|
meta_seat_x11_apply_kbd_a11y_settings (seat, a11y_settings);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_backend_x11_post_init (MetaBackend *backend)
|
meta_backend_x11_post_init (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
MetaMonitorManager *monitor_manager;
|
MetaMonitorManager *monitor_manager;
|
||||||
|
MetaInputSettings *input_settings;
|
||||||
int major, minor;
|
int major, minor;
|
||||||
gboolean has_xi = FALSE;
|
gboolean has_xi = FALSE;
|
||||||
|
|
||||||
@ -577,6 +590,15 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
|||||||
priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay,
|
priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay,
|
||||||
"_MUTTER_TOUCH_SEQUENCE_SYNC",
|
"_MUTTER_TOUCH_SEQUENCE_SYNC",
|
||||||
False);
|
False);
|
||||||
|
|
||||||
|
input_settings = meta_backend_get_input_settings (backend);
|
||||||
|
|
||||||
|
if (input_settings)
|
||||||
|
{
|
||||||
|
g_signal_connect_object (meta_backend_get_input_settings (backend),
|
||||||
|
"kbd-a11y-changed",
|
||||||
|
G_CALLBACK (on_kbd_a11y_changed), backend, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterBackend *
|
static ClutterBackend *
|
||||||
@ -677,7 +699,7 @@ meta_backend_x11_get_current_logical_monitor (MetaBackend *backend)
|
|||||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
MetaCursorTracker *cursor_tracker;
|
MetaCursorTracker *cursor_tracker;
|
||||||
int x, y;
|
graphene_point_t point;
|
||||||
MetaMonitorManager *monitor_manager;
|
MetaMonitorManager *monitor_manager;
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
|
|
||||||
@ -685,10 +707,11 @@ meta_backend_x11_get_current_logical_monitor (MetaBackend *backend)
|
|||||||
return priv->cached_current_logical_monitor;
|
return priv->cached_current_logical_monitor;
|
||||||
|
|
||||||
cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||||
monitor_manager = meta_backend_get_monitor_manager (backend);
|
monitor_manager = meta_backend_get_monitor_manager (backend);
|
||||||
logical_monitor =
|
logical_monitor =
|
||||||
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
|
meta_monitor_manager_get_logical_monitor_at (monitor_manager,
|
||||||
|
point.x, point.y);
|
||||||
|
|
||||||
if (!logical_monitor && monitor_manager->logical_monitors)
|
if (!logical_monitor && monitor_manager->logical_monitors)
|
||||||
logical_monitor = monitor_manager->logical_monitors->data;
|
logical_monitor = monitor_manager->logical_monitors->data;
|
||||||
|
@ -69,10 +69,8 @@ static void
|
|||||||
update_position (MetaCursorTrackerX11 *tracker_x11)
|
update_position (MetaCursorTrackerX11 *tracker_x11)
|
||||||
{
|
{
|
||||||
MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11);
|
MetaCursorTracker *tracker = META_CURSOR_TRACKER (tracker_x11);
|
||||||
int x, y;
|
|
||||||
|
|
||||||
meta_cursor_tracker_get_pointer (tracker, &x, &y, NULL);
|
meta_cursor_tracker_update_position (tracker);
|
||||||
meta_cursor_tracker_update_position (tracker, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include <gudev/gudev.h>
|
#include <gudev/gudev.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "backends/meta-logical-monitor.h"
|
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "core/display-private.h"
|
#include "core/display-private.h"
|
||||||
#include "meta/meta-x11-errors.h"
|
#include "meta/meta-x11-errors.h"
|
||||||
@ -665,15 +664,6 @@ meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings,
|
|||||||
g_warning ("Could not set tablet mapping for %s",
|
g_warning ("Could not set tablet mapping for %s",
|
||||||
clutter_input_device_get_device_name (device));
|
clutter_input_device_get_device_name (device));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ClutterInputDeviceMapping dev_mapping;
|
|
||||||
|
|
||||||
dev_mapping = (mapping == G_DESKTOP_TABLET_MAPPING_ABSOLUTE) ?
|
|
||||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE :
|
|
||||||
CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE;
|
|
||||||
clutter_input_device_set_mapping_mode (device, dev_mapping);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -750,37 +740,19 @@ meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings,
|
meta_input_settings_x11_set_tablet_aspect_ratio (MetaInputSettings *settings,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
MetaLogicalMonitor *logical_monitor,
|
gdouble aspect_ratio)
|
||||||
gboolean keep_aspect)
|
|
||||||
{
|
{
|
||||||
gint32 width, height, dev_x, dev_y, dev_width, dev_height, area[4] = { 0 };
|
gint32 dev_x, dev_y, dev_width, dev_height, area[4] = { 0 };
|
||||||
|
|
||||||
if (!device_query_area (device, &dev_x, &dev_y, &dev_width, &dev_height))
|
if (!device_query_area (device, &dev_x, &dev_y, &dev_width, &dev_height))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (keep_aspect)
|
if (aspect_ratio > 0)
|
||||||
{
|
{
|
||||||
double aspect_ratio, dev_aspect;
|
double dev_aspect;
|
||||||
|
|
||||||
if (logical_monitor)
|
|
||||||
{
|
|
||||||
width = logical_monitor->rect.width;
|
|
||||||
height = logical_monitor->rect.height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MetaMonitorManager *monitor_manager;
|
|
||||||
MetaBackend *backend;
|
|
||||||
|
|
||||||
backend = meta_get_backend ();
|
|
||||||
monitor_manager = meta_backend_get_monitor_manager (backend);
|
|
||||||
meta_monitor_manager_get_screen_size (monitor_manager,
|
|
||||||
&width, &height);
|
|
||||||
}
|
|
||||||
|
|
||||||
aspect_ratio = (double) width / height;
|
|
||||||
dev_aspect = (double) dev_width / dev_height;
|
dev_aspect = (double) dev_width / dev_height;
|
||||||
|
|
||||||
if (dev_aspect > aspect_ratio)
|
if (dev_aspect > aspect_ratio)
|
||||||
@ -952,7 +924,7 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
|||||||
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;
|
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;
|
||||||
|
|
||||||
input_settings_class->set_tablet_mapping = meta_input_settings_x11_set_tablet_mapping;
|
input_settings_class->set_tablet_mapping = meta_input_settings_x11_set_tablet_mapping;
|
||||||
input_settings_class->set_tablet_keep_aspect = meta_input_settings_x11_set_tablet_keep_aspect;
|
input_settings_class->set_tablet_aspect_ratio = meta_input_settings_x11_set_tablet_aspect_ratio;
|
||||||
input_settings_class->set_tablet_area = meta_input_settings_x11_set_tablet_area;
|
input_settings_class->set_tablet_area = meta_input_settings_x11_set_tablet_area;
|
||||||
|
|
||||||
input_settings_class->set_mouse_accel_profile = meta_input_settings_x11_set_mouse_accel_profile;
|
input_settings_class->set_mouse_accel_profile = meta_input_settings_x11_set_mouse_accel_profile;
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
|
|
||||||
|
#include "backends/meta-input-settings-private.h"
|
||||||
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "backends/x11/meta-event-x11.h"
|
#include "backends/x11/meta-event-x11.h"
|
||||||
#include "backends/x11/meta-input-device-tool-x11.h"
|
#include "backends/x11/meta-input-device-tool-x11.h"
|
||||||
#include "backends/x11/meta-input-device-x11.h"
|
#include "backends/x11/meta-input-device-x11.h"
|
||||||
@ -44,6 +46,15 @@ enum
|
|||||||
PROP_TOUCH_MODE,
|
PROP_TOUCH_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _MetaTouchInfo MetaTouchInfo;
|
||||||
|
|
||||||
|
struct _MetaTouchInfo
|
||||||
|
{
|
||||||
|
ClutterEventSequence *sequence;
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
};
|
||||||
|
|
||||||
struct _MetaSeatX11
|
struct _MetaSeatX11
|
||||||
{
|
{
|
||||||
ClutterSeat parent_instance;
|
ClutterSeat parent_instance;
|
||||||
@ -52,6 +63,7 @@ struct _MetaSeatX11
|
|||||||
GList *devices;
|
GList *devices;
|
||||||
GHashTable *devices_by_id;
|
GHashTable *devices_by_id;
|
||||||
GHashTable *tools_by_serial;
|
GHashTable *tools_by_serial;
|
||||||
|
GHashTable *touch_coords;
|
||||||
MetaKeymapX11 *keymap;
|
MetaKeymapX11 *keymap;
|
||||||
|
|
||||||
int pointer_id;
|
int pointer_id;
|
||||||
@ -462,7 +474,6 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
ClutterInputDeviceType source, touch_source;
|
ClutterInputDeviceType source, touch_source;
|
||||||
ClutterInputDevice *retval;
|
ClutterInputDevice *retval;
|
||||||
ClutterInputMode mode;
|
ClutterInputMode mode;
|
||||||
gboolean is_enabled;
|
|
||||||
uint32_t num_touches = 0, num_rings = 0, num_strips = 0;
|
uint32_t num_touches = 0, num_rings = 0, num_strips = 0;
|
||||||
char *vendor_id = NULL, *product_id = NULL, *node_path = NULL;
|
char *vendor_id = NULL, *product_id = NULL, *node_path = NULL;
|
||||||
|
|
||||||
@ -508,19 +519,16 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
case XIMasterKeyboard:
|
case XIMasterKeyboard:
|
||||||
case XIMasterPointer:
|
case XIMasterPointer:
|
||||||
mode = CLUTTER_INPUT_MODE_MASTER;
|
mode = CLUTTER_INPUT_MODE_MASTER;
|
||||||
is_enabled = TRUE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XISlaveKeyboard:
|
case XISlaveKeyboard:
|
||||||
case XISlavePointer:
|
case XISlavePointer:
|
||||||
mode = CLUTTER_INPUT_MODE_SLAVE;
|
mode = CLUTTER_INPUT_MODE_SLAVE;
|
||||||
is_enabled = FALSE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XIFloatingSlave:
|
case XIFloatingSlave:
|
||||||
default:
|
default:
|
||||||
mode = CLUTTER_INPUT_MODE_FLOATING;
|
mode = CLUTTER_INPUT_MODE_FLOATING;
|
||||||
is_enabled = FALSE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,10 +540,7 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (source == CLUTTER_PAD_DEVICE)
|
if (source == CLUTTER_PAD_DEVICE)
|
||||||
{
|
get_pad_features (info, &num_rings, &num_strips);
|
||||||
is_enabled = TRUE;
|
|
||||||
get_pad_features (info, &num_rings, &num_strips);
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = g_object_new (META_TYPE_INPUT_DEVICE_X11,
|
retval = g_object_new (META_TYPE_INPUT_DEVICE_X11,
|
||||||
"name", info->name,
|
"name", info->name,
|
||||||
@ -544,7 +549,6 @@ create_device (MetaSeatX11 *seat_x11,
|
|||||||
"device-type", source,
|
"device-type", source,
|
||||||
"device-mode", mode,
|
"device-mode", mode,
|
||||||
"backend", backend,
|
"backend", backend,
|
||||||
"enabled", is_enabled,
|
|
||||||
"vendor-id", vendor_id,
|
"vendor-id", vendor_id,
|
||||||
"product-id", product_id,
|
"product-id", product_id,
|
||||||
"device-node", node_path,
|
"device-node", node_path,
|
||||||
@ -654,8 +658,6 @@ add_device (MetaSeatX11 *seat_x11,
|
|||||||
info->attachment == seat_x11->keyboard_id))
|
info->attachment == seat_x11->keyboard_id))
|
||||||
{
|
{
|
||||||
seat_x11->devices = g_list_prepend (seat_x11->devices, device);
|
seat_x11->devices = g_list_prepend (seat_x11->devices, device);
|
||||||
seat_x11->has_touchscreens |=
|
|
||||||
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -679,13 +681,9 @@ add_device (MetaSeatX11 *seat_x11,
|
|||||||
GINT_TO_POINTER (info->attachment));
|
GINT_TO_POINTER (info->attachment));
|
||||||
_clutter_input_device_set_associated_device (device, master);
|
_clutter_input_device_set_associated_device (device, master);
|
||||||
_clutter_input_device_add_slave (master, device);
|
_clutter_input_device_add_slave (master, device);
|
||||||
|
|
||||||
g_signal_emit_by_name (seat_x11, "device-added", device);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_touch_mode (seat_x11);
|
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,44 +702,55 @@ has_touchscreens (MetaSeatX11 *seat_x11)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_device (MetaSeatX11 *seat_x11,
|
remove_device (MetaSeatX11 *seat_x11,
|
||||||
int device_id)
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
ClutterInputDevice *device;
|
if (seat_x11->core_pointer == device)
|
||||||
gboolean check_touchscreens = FALSE;
|
|
||||||
|
|
||||||
device = g_hash_table_lookup (seat_x11->devices_by_id,
|
|
||||||
GINT_TO_POINTER (device_id));
|
|
||||||
|
|
||||||
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE)
|
|
||||||
check_touchscreens = TRUE;
|
|
||||||
|
|
||||||
if (device != NULL)
|
|
||||||
{
|
{
|
||||||
if (seat_x11->core_pointer == device)
|
seat_x11->core_pointer = NULL;
|
||||||
{
|
}
|
||||||
seat_x11->core_pointer = NULL;
|
else if (seat_x11->core_keyboard == device)
|
||||||
}
|
{
|
||||||
else if (seat_x11->core_keyboard == device)
|
seat_x11->core_keyboard = NULL;
|
||||||
{
|
}
|
||||||
seat_x11->core_keyboard = NULL;
|
else
|
||||||
}
|
{
|
||||||
else
|
seat_x11->devices = g_list_remove (seat_x11->devices, device);
|
||||||
{
|
}
|
||||||
seat_x11->devices = g_list_remove (seat_x11->devices, device);
|
}
|
||||||
g_signal_emit_by_name (seat_x11, "device-removed", device);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_run_dispose (G_OBJECT (device));
|
static gboolean
|
||||||
g_hash_table_remove (seat_x11->devices_by_id,
|
meta_seat_x11_handle_event_post (ClutterSeat *seat,
|
||||||
GINT_TO_POINTER (device_id));
|
const ClutterEvent *event)
|
||||||
|
{
|
||||||
|
MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat);
|
||||||
|
ClutterInputDevice *device = event->device.device;
|
||||||
|
MetaInputSettings *input_settings;
|
||||||
|
gboolean is_touch;
|
||||||
|
|
||||||
|
is_touch =
|
||||||
|
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE;
|
||||||
|
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_DEVICE_ADDED:
|
||||||
|
meta_input_settings_add_device (input_settings, device);
|
||||||
|
seat_x11->has_touchscreens |= is_touch;
|
||||||
|
break;
|
||||||
|
case CLUTTER_DEVICE_REMOVED:
|
||||||
|
if (is_touch)
|
||||||
|
seat_x11->has_touchscreens = has_touchscreens (seat_x11);
|
||||||
|
meta_input_settings_remove_device (input_settings, device);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_touchscreens)
|
if (is_touch)
|
||||||
{
|
update_touch_mode (seat_x11);
|
||||||
seat_x11->has_touchscreens = has_touchscreens (seat_x11);
|
|
||||||
update_touch_mode (seat_x11);
|
return TRUE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -803,12 +812,14 @@ device_get_tool_serial (ClutterInputDevice *device)
|
|||||||
return serial_id;
|
return serial_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
translate_hierarchy_event (ClutterBackend *backend,
|
translate_hierarchy_event (ClutterBackend *backend,
|
||||||
MetaSeatX11 *seat_x11,
|
MetaSeatX11 *seat_x11,
|
||||||
XIHierarchyEvent *ev)
|
XIHierarchyEvent *ev,
|
||||||
|
ClutterEvent *event)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
for (i = 0; i < ev->num_info; i++)
|
for (i = 0; i < ev->num_info; i++)
|
||||||
{
|
{
|
||||||
@ -828,15 +839,38 @@ translate_hierarchy_event (ClutterBackend *backend,
|
|||||||
clutter_x11_untrap_x_errors ();
|
clutter_x11_untrap_x_errors ();
|
||||||
if (info != NULL)
|
if (info != NULL)
|
||||||
{
|
{
|
||||||
add_device (seat_x11, backend, &info[0], FALSE);
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
|
device = add_device (seat_x11, backend, &info[0], FALSE);
|
||||||
|
|
||||||
|
event->any.type = CLUTTER_DEVICE_ADDED;
|
||||||
|
event->any.time = ev->time;
|
||||||
|
clutter_event_set_device (event, device);
|
||||||
|
|
||||||
|
retval = TRUE;
|
||||||
XIFreeDeviceInfo (info);
|
XIFreeDeviceInfo (info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ev->info[i].flags & XIDeviceDisabled)
|
else if (ev->info[i].flags & XIDeviceDisabled)
|
||||||
{
|
{
|
||||||
|
g_autoptr (ClutterInputDevice) device = NULL;
|
||||||
g_debug ("Hierarchy event: device disabled");
|
g_debug ("Hierarchy event: device disabled");
|
||||||
|
|
||||||
remove_device (seat_x11, ev->info[i].deviceid);
|
g_hash_table_steal_extended (seat_x11->devices_by_id,
|
||||||
|
GINT_TO_POINTER (ev->info[i].deviceid),
|
||||||
|
NULL,
|
||||||
|
(gpointer) &device);
|
||||||
|
|
||||||
|
if (device != NULL)
|
||||||
|
{
|
||||||
|
remove_device (seat_x11, device);
|
||||||
|
|
||||||
|
event->any.type = CLUTTER_DEVICE_REMOVED;
|
||||||
|
event->any.time = ev->time;
|
||||||
|
clutter_event_set_device (event, device);
|
||||||
|
|
||||||
|
retval = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ((ev->info[i].flags & XISlaveAttached) ||
|
else if ((ev->info[i].flags & XISlaveAttached) ||
|
||||||
(ev->info[i].flags & XISlaveDetached))
|
(ev->info[i].flags & XISlaveDetached))
|
||||||
@ -883,6 +917,8 @@ translate_hierarchy_event (ClutterBackend *backend,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -902,6 +938,7 @@ translate_property_event (MetaSeatX11 *seat_x11,
|
|||||||
{
|
{
|
||||||
ClutterInputDeviceTool *tool = NULL;
|
ClutterInputDeviceTool *tool = NULL;
|
||||||
ClutterInputDeviceToolType type;
|
ClutterInputDeviceToolType type;
|
||||||
|
MetaInputSettings *input_settings;
|
||||||
int serial_id;
|
int serial_id;
|
||||||
|
|
||||||
serial_id = device_get_tool_serial (device);
|
serial_id = device_get_tool_serial (device);
|
||||||
@ -922,7 +959,8 @@ translate_property_event (MetaSeatX11 *seat_x11,
|
|||||||
}
|
}
|
||||||
|
|
||||||
meta_input_device_x11_update_tool (device, tool);
|
meta_input_device_x11_update_tool (device, tool);
|
||||||
g_signal_emit_by_name (seat_x11, "tool-changed", device, tool);
|
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
||||||
|
meta_input_settings_notify_tool_change (input_settings, device, tool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,6 +1153,9 @@ get_event_stage (MetaSeatX11 *seat_x11,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case XI_HierarchyChanged:
|
||||||
|
return CLUTTER_STAGE (meta_backend_get_stage (meta_get_backend ()));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1290,13 +1331,15 @@ static void
|
|||||||
on_keymap_state_change (MetaKeymapX11 *keymap_x11,
|
on_keymap_state_change (MetaKeymapX11 *keymap_x11,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
ClutterSeat *seat = CLUTTER_SEAT (data);
|
ClutterSeat *seat = data;
|
||||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
MetaInputSettings *input_settings;
|
||||||
|
MetaKbdA11ySettings kbd_a11y_settings;
|
||||||
|
|
||||||
/* On keymaps state change, just reapply the current settings, it'll
|
/* On keymaps state change, just reapply the current settings, it'll
|
||||||
* take care of enabling/disabling mousekeys based on NumLock state.
|
* take care of enabling/disabling mousekeys based on NumLock state.
|
||||||
*/
|
*/
|
||||||
clutter_seat_get_kbd_a11y_settings (seat, &kbd_a11y_settings);
|
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
||||||
|
meta_input_settings_get_kbd_a11y_settings (input_settings, &kbd_a11y_settings);
|
||||||
meta_seat_x11_apply_kbd_a11y_settings (seat, &kbd_a11y_settings);
|
meta_seat_x11_apply_kbd_a11y_settings (seat, &kbd_a11y_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1450,6 +1493,7 @@ meta_seat_x11_finalize (GObject *object)
|
|||||||
|
|
||||||
g_hash_table_unref (seat_x11->devices_by_id);
|
g_hash_table_unref (seat_x11->devices_by_id);
|
||||||
g_hash_table_unref (seat_x11->tools_by_serial);
|
g_hash_table_unref (seat_x11->tools_by_serial);
|
||||||
|
g_hash_table_unref (seat_x11->touch_coords);
|
||||||
g_list_free (seat_x11->devices);
|
g_list_free (seat_x11->devices);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_seat_x11_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_seat_x11_parent_class)->finalize (object);
|
||||||
@ -1548,6 +1592,140 @@ meta_seat_x11_warp_pointer (ClutterSeat *seat,
|
|||||||
x, y);
|
x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
translate_state (XIButtonState *button_state,
|
||||||
|
XIModifierState *modifier_state,
|
||||||
|
XIGroupState *group_state)
|
||||||
|
{
|
||||||
|
uint32_t state = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (modifier_state)
|
||||||
|
state |= modifier_state->effective;
|
||||||
|
|
||||||
|
if (button_state)
|
||||||
|
{
|
||||||
|
for (i = 1; i < XIMaskLen (button_state->mask_len); i++)
|
||||||
|
{
|
||||||
|
if (!XIMaskIsSet (button_state->mask, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
state |= CLUTTER_BUTTON1_MASK;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
state |= CLUTTER_BUTTON2_MASK;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
state |= CLUTTER_BUTTON3_MASK;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
state |= CLUTTER_BUTTON4_MASK;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
state |= CLUTTER_BUTTON5_MASK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group_state)
|
||||||
|
state |= (group_state->effective) << 13;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_seat_x11_query_state (ClutterSeat *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
graphene_point_t *coords,
|
||||||
|
ClutterModifierType *modifiers)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *backend_x11 = META_BACKEND_X11 (meta_get_backend ());
|
||||||
|
MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat);
|
||||||
|
Window root_ret, child_ret;
|
||||||
|
double root_x, root_y, win_x, win_y;
|
||||||
|
XIButtonState button_state;
|
||||||
|
XIModifierState modifier_state;
|
||||||
|
XIGroupState group_state;
|
||||||
|
|
||||||
|
clutter_x11_trap_x_errors ();
|
||||||
|
XIQueryPointer (clutter_x11_get_default_display (),
|
||||||
|
seat_x11->pointer_id,
|
||||||
|
meta_backend_x11_get_xwindow (backend_x11),
|
||||||
|
&root_ret, &child_ret,
|
||||||
|
&root_x, &root_y, &win_x, &win_y,
|
||||||
|
&button_state, &modifier_state, &group_state);
|
||||||
|
if (clutter_x11_untrap_x_errors ())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (sequence)
|
||||||
|
{
|
||||||
|
MetaTouchInfo *touch_info;
|
||||||
|
|
||||||
|
touch_info = g_hash_table_lookup (seat_x11->touch_coords, sequence);
|
||||||
|
if (!touch_info)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (coords)
|
||||||
|
{
|
||||||
|
coords->x = touch_info->x;
|
||||||
|
coords->y = touch_info->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (coords)
|
||||||
|
{
|
||||||
|
coords->x = win_x;
|
||||||
|
coords->y = win_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modifiers)
|
||||||
|
*modifiers = translate_state (&button_state, &modifier_state, &group_state);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_seat_x11_update_touchpoint (MetaSeatX11 *seat,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
double x,
|
||||||
|
double y)
|
||||||
|
{
|
||||||
|
MetaTouchInfo *touch_info;
|
||||||
|
|
||||||
|
touch_info = g_hash_table_lookup (seat->touch_coords, sequence);
|
||||||
|
if (!touch_info)
|
||||||
|
{
|
||||||
|
touch_info = g_slice_new (MetaTouchInfo);
|
||||||
|
touch_info->sequence = sequence;
|
||||||
|
g_hash_table_insert (seat->touch_coords, sequence, touch_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
touch_info->x = x;
|
||||||
|
touch_info->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_seat_x11_remove_touchpoint (MetaSeatX11 *seat,
|
||||||
|
ClutterEventSequence *sequence)
|
||||||
|
{
|
||||||
|
g_hash_table_remove (seat->touch_coords, sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_touch_info_free (MetaTouchInfo *touch_info)
|
||||||
|
{
|
||||||
|
g_slice_free (MetaTouchInfo, touch_info);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_seat_x11_class_init (MetaSeatX11Class *klass)
|
meta_seat_x11_class_init (MetaSeatX11Class *klass)
|
||||||
{
|
{
|
||||||
@ -1566,10 +1744,11 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass)
|
|||||||
seat_class->get_keymap = meta_seat_x11_get_keymap;
|
seat_class->get_keymap = meta_seat_x11_get_keymap;
|
||||||
seat_class->copy_event_data = meta_seat_x11_copy_event_data;
|
seat_class->copy_event_data = meta_seat_x11_copy_event_data;
|
||||||
seat_class->free_event_data = meta_seat_x11_free_event_data;
|
seat_class->free_event_data = meta_seat_x11_free_event_data;
|
||||||
seat_class->apply_kbd_a11y_settings = meta_seat_x11_apply_kbd_a11y_settings;
|
|
||||||
seat_class->create_virtual_device = meta_seat_x11_create_virtual_device;
|
seat_class->create_virtual_device = meta_seat_x11_create_virtual_device;
|
||||||
seat_class->get_supported_virtual_device_types = meta_seat_x11_get_supported_virtual_device_types;
|
seat_class->get_supported_virtual_device_types = meta_seat_x11_get_supported_virtual_device_types;
|
||||||
seat_class->warp_pointer = meta_seat_x11_warp_pointer;
|
seat_class->warp_pointer = meta_seat_x11_warp_pointer;
|
||||||
|
seat_class->handle_event_post = meta_seat_x11_handle_event_post;
|
||||||
|
seat_class->query_state = meta_seat_x11_query_state;
|
||||||
|
|
||||||
props[PROP_OPCODE] =
|
props[PROP_OPCODE] =
|
||||||
g_param_spec_int ("opcode",
|
g_param_spec_int ("opcode",
|
||||||
@ -1607,6 +1786,8 @@ meta_seat_x11_init (MetaSeatX11 *seat)
|
|||||||
(GDestroyNotify) g_object_unref);
|
(GDestroyNotify) g_object_unref);
|
||||||
seat->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL,
|
seat->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
(GDestroyNotify) g_object_unref);
|
(GDestroyNotify) g_object_unref);
|
||||||
|
seat->touch_coords = g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
|
(GDestroyNotify) meta_touch_info_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaSeatX11 *
|
MetaSeatX11 *
|
||||||
@ -1672,8 +1853,7 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(xi_event->evtype == XI_HierarchyChanged ||
|
if (!(xi_event->evtype == XI_DeviceChanged ||
|
||||||
xi_event->evtype == XI_DeviceChanged ||
|
|
||||||
xi_event->evtype == XI_PropertyEvent))
|
xi_event->evtype == XI_PropertyEvent))
|
||||||
{
|
{
|
||||||
stage = get_event_stage (seat, xi_event);
|
stage = get_event_stage (seat, xi_event);
|
||||||
@ -1691,9 +1871,8 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
{
|
{
|
||||||
XIHierarchyEvent *xev = (XIHierarchyEvent *) xi_event;
|
XIHierarchyEvent *xev = (XIHierarchyEvent *) xi_event;
|
||||||
|
|
||||||
translate_hierarchy_event (backend, seat, xev);
|
retval = translate_hierarchy_event (backend, seat, xev, event);
|
||||||
}
|
}
|
||||||
retval = FALSE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XI_DeviceChanged:
|
case XI_DeviceChanged:
|
||||||
@ -1815,12 +1994,6 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
device = g_hash_table_lookup (seat->devices_by_id,
|
device = g_hash_table_lookup (seat->devices_by_id,
|
||||||
GINT_TO_POINTER (xev->deviceid));
|
GINT_TO_POINTER (xev->deviceid));
|
||||||
|
|
||||||
/* Set the stage for core events coming out of nowhere (see bug #684509) */
|
|
||||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER &&
|
|
||||||
clutter_input_device_get_pointer_stage (device) == NULL &&
|
|
||||||
stage != NULL)
|
|
||||||
_clutter_input_device_set_stage (device, stage);
|
|
||||||
|
|
||||||
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
|
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
|
||||||
{
|
{
|
||||||
/* We got these events because of the passive button grab */
|
/* We got these events because of the passive button grab */
|
||||||
@ -1978,9 +2151,6 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->stage != NULL)
|
|
||||||
_clutter_input_device_set_stage (source_device, device->stage);
|
|
||||||
|
|
||||||
if (xev->flags & XIPointerEmulated)
|
if (xev->flags & XIPointerEmulated)
|
||||||
_clutter_event_set_pointer_emulated (event, TRUE);
|
_clutter_event_set_pointer_emulated (event, TRUE);
|
||||||
|
|
||||||
@ -2012,12 +2182,6 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the stage for core events coming out of nowhere (see bug #684509) */
|
|
||||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER &&
|
|
||||||
clutter_input_device_get_pointer_stage (device) == NULL &&
|
|
||||||
stage != NULL)
|
|
||||||
_clutter_input_device_set_stage (device, stage);
|
|
||||||
|
|
||||||
if (scroll_valuators_changed (source_device,
|
if (scroll_valuators_changed (source_device,
|
||||||
&xev->valuators,
|
&xev->valuators,
|
||||||
&delta_x, &delta_y))
|
&delta_x, &delta_y))
|
||||||
@ -2070,9 +2234,6 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
event->motion.y,
|
event->motion.y,
|
||||||
&xev->valuators);
|
&xev->valuators);
|
||||||
|
|
||||||
if (device->stage != NULL)
|
|
||||||
_clutter_input_device_set_stage (source_device, device->stage);
|
|
||||||
|
|
||||||
if (xev->flags & XIPointerEmulated)
|
if (xev->flags & XIPointerEmulated)
|
||||||
_clutter_event_set_pointer_emulated (event, TRUE);
|
_clutter_event_set_pointer_emulated (event, TRUE);
|
||||||
|
|
||||||
@ -2093,8 +2254,6 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
|
XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
|
||||||
device = g_hash_table_lookup (seat->devices_by_id,
|
device = g_hash_table_lookup (seat->devices_by_id,
|
||||||
GINT_TO_POINTER (xev->deviceid));
|
GINT_TO_POINTER (xev->deviceid));
|
||||||
if (!_clutter_input_device_get_stage (device))
|
|
||||||
_clutter_input_device_set_stage (device, stage);
|
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case XI_TouchEnd:
|
case XI_TouchEnd:
|
||||||
@ -2133,6 +2292,15 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
|
event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
|
||||||
|
|
||||||
meta_stage_x11_set_user_time (stage_x11, event->touch.time);
|
meta_stage_x11_set_user_time (stage_x11, event->touch.time);
|
||||||
|
meta_seat_x11_update_touchpoint (seat,
|
||||||
|
GUINT_TO_POINTER (xev->detail),
|
||||||
|
xev->root_x,
|
||||||
|
xev->root_y);
|
||||||
|
}
|
||||||
|
else if (xi_event->evtype == XI_TouchEnd)
|
||||||
|
{
|
||||||
|
meta_seat_x11_remove_touchpoint (seat,
|
||||||
|
GUINT_TO_POINTER (xev->detail));
|
||||||
}
|
}
|
||||||
|
|
||||||
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
|
||||||
@ -2187,6 +2355,11 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
if (xev->flags & XITouchEmulatingPointer)
|
if (xev->flags & XITouchEmulatingPointer)
|
||||||
_clutter_event_set_pointer_emulated (event, TRUE);
|
_clutter_event_set_pointer_emulated (event, TRUE);
|
||||||
|
|
||||||
|
meta_seat_x11_update_touchpoint (seat,
|
||||||
|
event->touch.sequence,
|
||||||
|
xev->root_x,
|
||||||
|
xev->root_y);
|
||||||
|
|
||||||
g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)",
|
g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)",
|
||||||
(unsigned int) stage_x11->xwin,
|
(unsigned int) stage_x11->xwin,
|
||||||
event->touch.device->id,
|
event->touch.device->id,
|
||||||
@ -2224,14 +2397,6 @@ meta_seat_x11_translate_event (MetaSeatX11 *seat,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (device->stage == NULL)
|
|
||||||
{
|
|
||||||
g_debug ("Discarding Leave for ButtonRelease "
|
|
||||||
"event off-stage");
|
|
||||||
retval = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
event->crossing.type = event->type = CLUTTER_LEAVE;
|
event->crossing.type = event->type = CLUTTER_LEAVE;
|
||||||
|
|
||||||
event->crossing.stage = stage;
|
event->crossing.stage = stage;
|
||||||
|
@ -78,47 +78,55 @@ static void
|
|||||||
check_settings_changed (ClutterSeat *seat)
|
check_settings_changed (ClutterSeat *seat)
|
||||||
{
|
{
|
||||||
Display *xdisplay = clutter_x11_get_default_display ();
|
Display *xdisplay = clutter_x11_get_default_display ();
|
||||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
MetaKbdA11ySettings kbd_a11y_settings;
|
||||||
ClutterKeyboardA11yFlags what_changed = 0;
|
MetaKeyboardA11yFlags what_changed = 0;
|
||||||
|
MetaInputSettings *input_settings;
|
||||||
XkbDescRec *desc;
|
XkbDescRec *desc;
|
||||||
|
|
||||||
desc = get_xkb_desc_rec (xdisplay);
|
desc = get_xkb_desc_rec (xdisplay);
|
||||||
if (!desc)
|
if (!desc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clutter_seat_get_kbd_a11y_settings (seat, &kbd_a11y_settings);
|
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
||||||
|
meta_input_settings_get_kbd_a11y_settings (input_settings,
|
||||||
|
&kbd_a11y_settings);
|
||||||
|
|
||||||
if (desc->ctrls->enabled_ctrls & XkbSlowKeysMask &&
|
if (desc->ctrls->enabled_ctrls & XkbSlowKeysMask &&
|
||||||
!(kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED))
|
!(kbd_a11y_settings.controls & META_A11Y_SLOW_KEYS_ENABLED))
|
||||||
{
|
{
|
||||||
what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
what_changed |= META_A11Y_SLOW_KEYS_ENABLED;
|
||||||
kbd_a11y_settings.controls |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
kbd_a11y_settings.controls |= META_A11Y_SLOW_KEYS_ENABLED;
|
||||||
}
|
}
|
||||||
else if (!(desc->ctrls->enabled_ctrls & XkbSlowKeysMask) &&
|
else if (!(desc->ctrls->enabled_ctrls & XkbSlowKeysMask) &&
|
||||||
kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED)
|
kbd_a11y_settings.controls & META_A11Y_SLOW_KEYS_ENABLED)
|
||||||
{
|
{
|
||||||
what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
what_changed |= META_A11Y_SLOW_KEYS_ENABLED;
|
||||||
kbd_a11y_settings.controls &= ~CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
kbd_a11y_settings.controls &= ~META_A11Y_SLOW_KEYS_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc->ctrls->enabled_ctrls & XkbStickyKeysMask &&
|
if (desc->ctrls->enabled_ctrls & XkbStickyKeysMask &&
|
||||||
!(kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED))
|
!(kbd_a11y_settings.controls & META_A11Y_STICKY_KEYS_ENABLED))
|
||||||
{
|
{
|
||||||
what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
what_changed |= META_A11Y_STICKY_KEYS_ENABLED;
|
||||||
kbd_a11y_settings.controls |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
kbd_a11y_settings.controls |= META_A11Y_STICKY_KEYS_ENABLED;
|
||||||
}
|
}
|
||||||
else if (!(desc->ctrls->enabled_ctrls & XkbStickyKeysMask) &&
|
else if (!(desc->ctrls->enabled_ctrls & XkbStickyKeysMask) &&
|
||||||
kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED)
|
kbd_a11y_settings.controls & META_A11Y_STICKY_KEYS_ENABLED)
|
||||||
{
|
{
|
||||||
what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
what_changed |= META_A11Y_STICKY_KEYS_ENABLED;
|
||||||
kbd_a11y_settings.controls &= ~CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
kbd_a11y_settings.controls &= ~META_A11Y_STICKY_KEYS_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (what_changed)
|
if (what_changed)
|
||||||
g_signal_emit_by_name (seat,
|
{
|
||||||
"kbd-a11y-flags-changed",
|
meta_input_settings_notify_kbd_a11y_change (input_settings,
|
||||||
kbd_a11y_settings.controls,
|
kbd_a11y_settings.controls,
|
||||||
what_changed);
|
what_changed);
|
||||||
|
g_signal_emit_by_name (seat,
|
||||||
|
"kbd-a11y-flags-changed",
|
||||||
|
kbd_a11y_settings.controls,
|
||||||
|
what_changed);
|
||||||
|
}
|
||||||
|
|
||||||
XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
|
XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
|
||||||
}
|
}
|
||||||
@ -182,10 +190,10 @@ set_value_mask (gboolean flag,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
set_xkb_ctrl (XkbDescRec *desc,
|
set_xkb_ctrl (XkbDescRec *desc,
|
||||||
ClutterKeyboardA11yFlags settings,
|
MetaKeyboardA11yFlags settings,
|
||||||
ClutterKeyboardA11yFlags flag,
|
MetaKeyboardA11yFlags flag,
|
||||||
unsigned long mask)
|
unsigned long mask)
|
||||||
{
|
{
|
||||||
gboolean result = (settings & flag) == flag;
|
gboolean result = (settings & flag) == flag;
|
||||||
desc->ctrls->enabled_ctrls = set_value_mask (result, desc->ctrls->enabled_ctrls, mask);
|
desc->ctrls->enabled_ctrls = set_value_mask (result, desc->ctrls->enabled_ctrls, mask);
|
||||||
@ -194,8 +202,8 @@ set_xkb_ctrl (XkbDescRec *desc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
||||||
ClutterKbdA11ySettings *kbd_a11y_settings)
|
MetaKbdA11ySettings *kbd_a11y_settings)
|
||||||
{
|
{
|
||||||
Display *xdisplay = clutter_x11_get_default_display ();
|
Display *xdisplay = clutter_x11_get_default_display ();
|
||||||
XkbDescRec *desc;
|
XkbDescRec *desc;
|
||||||
@ -206,13 +214,13 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* general */
|
/* general */
|
||||||
enable_accessX = kbd_a11y_settings->controls & CLUTTER_A11Y_KEYBOARD_ENABLED;
|
enable_accessX = kbd_a11y_settings->controls & META_A11Y_KEYBOARD_ENABLED;
|
||||||
|
|
||||||
desc->ctrls->enabled_ctrls = set_value_mask (enable_accessX,
|
desc->ctrls->enabled_ctrls = set_value_mask (enable_accessX,
|
||||||
desc->ctrls->enabled_ctrls,
|
desc->ctrls->enabled_ctrls,
|
||||||
XkbAccessXKeysMask);
|
XkbAccessXKeysMask);
|
||||||
|
|
||||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, CLUTTER_A11Y_TIMEOUT_ENABLED,
|
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, META_A11Y_TIMEOUT_ENABLED,
|
||||||
XkbAccessXTimeoutMask))
|
XkbAccessXTimeoutMask))
|
||||||
{
|
{
|
||||||
desc->ctrls->ax_timeout = kbd_a11y_settings->timeout_delay;
|
desc->ctrls->ax_timeout = kbd_a11y_settings->timeout_delay;
|
||||||
@ -226,17 +234,17 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_FEATURE_STATE_CHANGE_BEEP,
|
||||||
desc->ctrls->ax_options,
|
desc->ctrls->ax_options,
|
||||||
XkbAccessXFeedbackMask | XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask);
|
XkbAccessXFeedbackMask | XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask);
|
||||||
|
|
||||||
/* bounce keys */
|
/* bounce keys */
|
||||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||||
CLUTTER_A11Y_BOUNCE_KEYS_ENABLED, XkbBounceKeysMask))
|
META_A11Y_BOUNCE_KEYS_ENABLED, XkbBounceKeysMask))
|
||||||
{
|
{
|
||||||
desc->ctrls->debounce_delay = kbd_a11y_settings->debounce_delay;
|
desc->ctrls->debounce_delay = kbd_a11y_settings->debounce_delay;
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_BOUNCE_KEYS_BEEP_REJECT,
|
||||||
desc->ctrls->ax_options,
|
desc->ctrls->ax_options,
|
||||||
XkbAccessXFeedbackMask | XkbAX_BKRejectFBMask);
|
XkbAccessXFeedbackMask | XkbAX_BKRejectFBMask);
|
||||||
}
|
}
|
||||||
@ -248,7 +256,7 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
|||||||
desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask);
|
desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask);
|
||||||
}
|
}
|
||||||
else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
|
META_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
|
||||||
{
|
{
|
||||||
int mk_max_speed;
|
int mk_max_speed;
|
||||||
int mk_accel_time;
|
int mk_accel_time;
|
||||||
@ -273,16 +281,16 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
|||||||
|
|
||||||
/* slow keys */
|
/* slow keys */
|
||||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED, XkbSlowKeysMask))
|
META_A11Y_SLOW_KEYS_ENABLED, XkbSlowKeysMask))
|
||||||
{
|
{
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_PRESS,
|
||||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKPressFBMask);
|
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKPressFBMask);
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_ACCEPT,
|
||||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKAcceptFBMask);
|
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKAcceptFBMask);
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_SLOW_KEYS_BEEP_REJECT,
|
||||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKRejectFBMask);
|
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKRejectFBMask);
|
||||||
desc->ctrls->slow_keys_delay = kbd_a11y_settings->slowkeys_delay;
|
desc->ctrls->slow_keys_delay = kbd_a11y_settings->slowkeys_delay;
|
||||||
/* anything larger than 500 seems to loose all keyboard input */
|
/* anything larger than 500 seems to loose all keyboard input */
|
||||||
@ -292,20 +300,20 @@ meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
|||||||
|
|
||||||
/* sticky keys */
|
/* sticky keys */
|
||||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED, XkbStickyKeysMask))
|
META_A11Y_STICKY_KEYS_ENABLED, XkbStickyKeysMask))
|
||||||
{
|
{
|
||||||
desc->ctrls->ax_options |= XkbAX_LatchToLockMask;
|
desc->ctrls->ax_options |= XkbAX_LatchToLockMask;
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_STICKY_KEYS_TWO_KEY_OFF,
|
||||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_TwoKeysMask);
|
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_TwoKeysMask);
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_BEEP,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_STICKY_KEYS_BEEP,
|
||||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_StickyKeysFBMask);
|
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_StickyKeysFBMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* toggle keys */
|
/* toggle keys */
|
||||||
desc->ctrls->ax_options =
|
desc->ctrls->ax_options =
|
||||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED,
|
set_value_mask (kbd_a11y_settings->controls & META_A11Y_TOGGLE_KEYS_ENABLED,
|
||||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask);
|
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask);
|
||||||
|
|
||||||
set_xkb_desc_rec (xdisplay, desc);
|
set_xkb_desc_rec (xdisplay, desc);
|
||||||
|
@ -26,11 +26,12 @@
|
|||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#include "backends/meta-input-settings-private.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat,
|
||||||
ClutterKbdA11ySettings *kbd_a11y_settings);
|
MetaKbdA11ySettings *kbd_a11y_settings);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_seat_x11_a11y_init (ClutterSeat *seat);
|
meta_seat_x11_a11y_init (ClutterSeat *seat);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
typedef struct _MetaBackendX11NestedPrivate
|
typedef struct _MetaBackendX11NestedPrivate
|
||||||
{
|
{
|
||||||
MetaGpu *gpu;
|
MetaGpu *gpu;
|
||||||
|
MetaCursorRenderer *cursor_renderer;
|
||||||
} MetaBackendX11NestedPrivate;
|
} MetaBackendX11NestedPrivate;
|
||||||
|
|
||||||
static GInitableIface *initable_parent_iface;
|
static GInitableIface *initable_parent_iface;
|
||||||
@ -63,11 +64,23 @@ meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorRenderer *
|
static MetaCursorRenderer *
|
||||||
meta_backend_x11_nested_create_cursor_renderer (MetaBackend *backend)
|
meta_backend_x11_nested_get_cursor_renderer (MetaBackend *backend,
|
||||||
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED,
|
MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (backend);
|
||||||
"backend", backend,
|
MetaBackendX11NestedPrivate *priv =
|
||||||
NULL);
|
meta_backend_x11_nested_get_instance_private (backend_x11_nested);
|
||||||
|
|
||||||
|
if (!priv->cursor_renderer)
|
||||||
|
{
|
||||||
|
priv->cursor_renderer =
|
||||||
|
g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED,
|
||||||
|
"backend", backend,
|
||||||
|
"device", device,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return priv->cursor_renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaInputSettings *
|
static MetaInputSettings *
|
||||||
@ -275,7 +288,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
|
|||||||
backend_class->post_init = meta_backend_x11_nested_post_init;
|
backend_class->post_init = meta_backend_x11_nested_post_init;
|
||||||
backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
|
backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
|
||||||
backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
|
backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
|
||||||
backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer;
|
backend_class->get_cursor_renderer = meta_backend_x11_nested_get_cursor_renderer;
|
||||||
backend_class->create_input_settings = meta_backend_x11_nested_create_input_settings;
|
backend_class->create_input_settings = meta_backend_x11_nested_create_input_settings;
|
||||||
backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size;
|
backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size;
|
||||||
backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events;
|
backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "core/keybindings-private.h"
|
#include "core/keybindings-private.h"
|
||||||
#include "core/meta-gesture-tracker-private.h"
|
#include "core/meta-gesture-tracker-private.h"
|
||||||
|
#include "core/meta-pad-action-mapper.h"
|
||||||
#include "core/stack-tracker.h"
|
#include "core/stack-tracker.h"
|
||||||
#include "core/startup-notification-private.h"
|
#include "core/startup-notification-private.h"
|
||||||
#include "meta/barrier.h"
|
#include "meta/barrier.h"
|
||||||
@ -199,9 +200,6 @@ struct _MetaDisplay
|
|||||||
|
|
||||||
MetaKeyBindingManager key_binding_manager;
|
MetaKeyBindingManager key_binding_manager;
|
||||||
|
|
||||||
/* Monitor cache */
|
|
||||||
unsigned int monitor_cache_invalidated : 1;
|
|
||||||
|
|
||||||
/* Opening the display */
|
/* Opening the display */
|
||||||
unsigned int display_opening : 1;
|
unsigned int display_opening : 1;
|
||||||
|
|
||||||
@ -215,6 +213,7 @@ struct _MetaDisplay
|
|||||||
ClutterEventSequence *pointer_emulating_sequence;
|
ClutterEventSequence *pointer_emulating_sequence;
|
||||||
|
|
||||||
ClutterActor *current_pad_osd;
|
ClutterActor *current_pad_osd;
|
||||||
|
MetaPadActionMapper *pad_action_mapper;
|
||||||
|
|
||||||
MetaStartupNotification *startup_notification;
|
MetaStartupNotification *startup_notification;
|
||||||
|
|
||||||
|
@ -45,8 +45,7 @@
|
|||||||
#include "backends/meta-cursor-tracker-private.h"
|
#include "backends/meta-cursor-tracker-private.h"
|
||||||
#include "backends/meta-idle-monitor-dbus.h"
|
#include "backends/meta-idle-monitor-dbus.h"
|
||||||
#include "backends/meta-input-device-private.h"
|
#include "backends/meta-input-device-private.h"
|
||||||
#include "backends/meta-input-settings-private.h"
|
#include "backends/meta-input-mapper-private.h"
|
||||||
#include "backends/meta-logical-monitor.h"
|
|
||||||
#include "backends/meta-stage-private.h"
|
#include "backends/meta-stage-private.h"
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "backends/x11/meta-event-x11.h"
|
#include "backends/x11/meta-event-x11.h"
|
||||||
@ -844,6 +843,8 @@ meta_display_open (void)
|
|||||||
|
|
||||||
meta_prefs_add_listener (prefs_changed_callback, display);
|
meta_prefs_add_listener (prefs_changed_callback, display);
|
||||||
|
|
||||||
|
display->pad_action_mapper = meta_pad_action_mapper_new ();
|
||||||
|
|
||||||
/* Get events */
|
/* Get events */
|
||||||
meta_display_init_events (display);
|
meta_display_init_events (display);
|
||||||
|
|
||||||
@ -1120,6 +1121,7 @@ meta_display_close (MetaDisplay *display,
|
|||||||
|
|
||||||
meta_clipboard_manager_shutdown (display);
|
meta_clipboard_manager_shutdown (display);
|
||||||
g_clear_object (&display->selection);
|
g_clear_object (&display->selection);
|
||||||
|
g_clear_object (&display->pad_action_mapper);
|
||||||
|
|
||||||
g_object_unref (display);
|
g_object_unref (display);
|
||||||
the_display = NULL;
|
the_display = NULL;
|
||||||
@ -1629,43 +1631,9 @@ meta_cursor_for_grab_op (MetaGrabOp op)
|
|||||||
return META_CURSOR_DEFAULT;
|
return META_CURSOR_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float
|
|
||||||
find_highest_logical_monitor_scale (MetaBackend *backend,
|
|
||||||
MetaCursorSprite *cursor_sprite)
|
|
||||||
{
|
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
MetaCursorRenderer *cursor_renderer =
|
|
||||||
meta_backend_get_cursor_renderer (backend);
|
|
||||||
graphene_rect_t cursor_rect;
|
|
||||||
GList *logical_monitors;
|
|
||||||
GList *l;
|
|
||||||
float highest_scale = 0.0;
|
|
||||||
|
|
||||||
cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
|
|
||||||
cursor_sprite);
|
|
||||||
|
|
||||||
logical_monitors =
|
|
||||||
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
|
||||||
for (l = logical_monitors; l; l = l->next)
|
|
||||||
{
|
|
||||||
MetaLogicalMonitor *logical_monitor = l->data;
|
|
||||||
graphene_rect_t logical_monitor_rect =
|
|
||||||
meta_rectangle_to_graphene_rect (&logical_monitor->rect);
|
|
||||||
|
|
||||||
if (!graphene_rect_intersection (&cursor_rect,
|
|
||||||
&logical_monitor_rect,
|
|
||||||
NULL))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
highest_scale = MAX (highest_scale, logical_monitor->scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
return highest_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
|
root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
|
||||||
|
float best_scale,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
MetaDisplay *display)
|
MetaDisplay *display)
|
||||||
@ -1675,14 +1643,11 @@ root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
|
|||||||
|
|
||||||
if (meta_is_stage_views_scaled ())
|
if (meta_is_stage_views_scaled ())
|
||||||
{
|
{
|
||||||
float scale;
|
if (best_scale != 0.0)
|
||||||
|
|
||||||
scale = find_highest_logical_monitor_scale (backend, cursor_sprite);
|
|
||||||
if (scale != 0.0)
|
|
||||||
{
|
{
|
||||||
float ceiled_scale;
|
float ceiled_scale;
|
||||||
|
|
||||||
ceiled_scale = ceilf (scale);
|
ceiled_scale = ceilf (best_scale);
|
||||||
meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
|
meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
|
||||||
(int) ceiled_scale);
|
(int) ceiled_scale);
|
||||||
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
||||||
@ -2944,7 +2909,7 @@ meta_display_request_pad_osd (MetaDisplay *display,
|
|||||||
gboolean edition_mode)
|
gboolean edition_mode)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaInputSettings *input_settings;
|
MetaInputMapper *input_mapper;
|
||||||
const gchar *layout_path = NULL;
|
const gchar *layout_path = NULL;
|
||||||
ClutterActor *osd;
|
ClutterActor *osd;
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
@ -2960,13 +2925,13 @@ meta_display_request_pad_osd (MetaDisplay *display,
|
|||||||
if (display->current_pad_osd)
|
if (display->current_pad_osd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
input_mapper = meta_backend_get_input_mapper (meta_get_backend ());
|
||||||
|
|
||||||
if (input_settings)
|
if (input_mapper)
|
||||||
{
|
{
|
||||||
settings = meta_input_settings_get_tablet_settings (input_settings, pad);
|
settings = meta_input_mapper_get_tablet_settings (input_mapper, pad);
|
||||||
logical_monitor =
|
logical_monitor =
|
||||||
meta_input_settings_get_tablet_logical_monitor (input_settings, pad);
|
meta_input_mapper_get_device_logical_monitor (input_mapper, pad);
|
||||||
#ifdef HAVE_LIBWACOM
|
#ifdef HAVE_LIBWACOM
|
||||||
wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad));
|
wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad));
|
||||||
layout_path = libwacom_get_layout_filename (wacom_device);
|
layout_path = libwacom_get_layout_filename (wacom_device);
|
||||||
@ -2999,12 +2964,12 @@ meta_display_get_pad_action_label (MetaDisplay *display,
|
|||||||
MetaPadActionType action_type,
|
MetaPadActionType action_type,
|
||||||
guint action_number)
|
guint action_number)
|
||||||
{
|
{
|
||||||
MetaInputSettings *settings;
|
|
||||||
gchar *label;
|
gchar *label;
|
||||||
|
|
||||||
/* First, lookup the action, as imposed by settings */
|
/* First, lookup the action, as imposed by settings */
|
||||||
settings = meta_backend_get_input_settings (meta_get_backend ());
|
label = meta_pad_action_mapper_get_action_label (display->pad_action_mapper,
|
||||||
label = meta_input_settings_get_pad_action_label (settings, pad, action_type, action_number);
|
pad, action_type,
|
||||||
|
action_number);
|
||||||
if (label)
|
if (label)
|
||||||
return label;
|
return label;
|
||||||
|
|
||||||
@ -3050,15 +3015,15 @@ static gint
|
|||||||
lookup_tablet_monitor (MetaDisplay *display,
|
lookup_tablet_monitor (MetaDisplay *display,
|
||||||
ClutterInputDevice *device)
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
MetaInputSettings *input_settings;
|
MetaInputMapper *input_mapper;
|
||||||
MetaLogicalMonitor *monitor;
|
MetaLogicalMonitor *monitor;
|
||||||
gint monitor_idx = -1;
|
gint monitor_idx = -1;
|
||||||
|
|
||||||
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
input_mapper = meta_backend_get_input_mapper (meta_get_backend ());
|
||||||
if (!input_settings)
|
if (!input_mapper)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
monitor = meta_input_settings_get_tablet_logical_monitor (input_settings, device);
|
monitor = meta_input_mapper_get_device_logical_monitor (input_mapper, device);
|
||||||
|
|
||||||
if (monitor)
|
if (monitor)
|
||||||
{
|
{
|
||||||
@ -3144,9 +3109,6 @@ static void
|
|||||||
on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
|
on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
|
||||||
MetaDisplay *display)
|
MetaDisplay *display)
|
||||||
{
|
{
|
||||||
MetaBackend *backend;
|
|
||||||
MetaCursorRenderer *cursor_renderer;
|
|
||||||
|
|
||||||
meta_workspace_manager_reload_work_areas (display->workspace_manager);
|
meta_workspace_manager_reload_work_areas (display->workspace_manager);
|
||||||
|
|
||||||
/* Fix up monitor for all windows on this display */
|
/* Fix up monitor for all windows on this display */
|
||||||
@ -3159,10 +3121,6 @@ on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
|
|||||||
meta_display_resize_func, 0);
|
meta_display_resize_func, 0);
|
||||||
|
|
||||||
meta_display_queue_check_fullscreen (display);
|
meta_display_queue_check_fullscreen (display);
|
||||||
|
|
||||||
backend = meta_get_backend ();
|
|
||||||
cursor_renderer = meta_backend_get_cursor_renderer (backend);
|
|
||||||
meta_cursor_renderer_force_update (cursor_renderer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3750,18 +3708,18 @@ meta_display_get_pointer_window (MetaDisplay *display,
|
|||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
int x, y;
|
graphene_point_t point;
|
||||||
|
|
||||||
if (not_this_one)
|
if (not_this_one)
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing mouse window excluding %s\n", not_this_one->desc);
|
"Focusing mouse window excluding %s\n", not_this_one->desc);
|
||||||
|
|
||||||
meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||||
|
|
||||||
window = meta_stack_get_default_focus_window_at_point (display->stack,
|
window = meta_stack_get_default_focus_window_at_point (display->stack,
|
||||||
workspace_manager->active_workspace,
|
workspace_manager->active_workspace,
|
||||||
not_this_one,
|
not_this_one,
|
||||||
x, y);
|
point.x, point.y);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
@ -263,8 +263,7 @@ meta_display_handle_event (MetaDisplay *display,
|
|||||||
handle_pad_event = !display->current_pad_osd || is_mode_switch;
|
handle_pad_event = !display->current_pad_osd || is_mode_switch;
|
||||||
|
|
||||||
if (handle_pad_event &&
|
if (handle_pad_event &&
|
||||||
meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend),
|
meta_pad_action_mapper_handle_event (display->pad_action_mapper, event))
|
||||||
event))
|
|
||||||
{
|
{
|
||||||
bypass_wayland = bypass_clutter = TRUE;
|
bypass_wayland = bypass_clutter = TRUE;
|
||||||
goto out;
|
goto out;
|
||||||
@ -279,25 +278,22 @@ meta_display_handle_event (MetaDisplay *display,
|
|||||||
#ifdef HAVE_WAYLAND
|
#ifdef HAVE_WAYLAND
|
||||||
if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION)
|
if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION)
|
||||||
{
|
{
|
||||||
MetaWaylandCompositor *compositor;
|
MetaCursorRenderer *cursor_renderer;
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
compositor = meta_wayland_compositor_get_default ();
|
device = clutter_event_get_device (event);
|
||||||
|
cursor_renderer = meta_backend_get_cursor_renderer_for_device (backend,
|
||||||
|
device);
|
||||||
|
if (cursor_renderer)
|
||||||
|
meta_cursor_renderer_update_position (cursor_renderer);
|
||||||
|
|
||||||
if (meta_wayland_tablet_manager_consumes_event (compositor->tablet_manager, event))
|
if (device == clutter_seat_get_pointer (clutter_input_device_get_seat (device)))
|
||||||
{
|
|
||||||
meta_wayland_tablet_manager_update_cursor_position (compositor->tablet_manager, event);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
MetaCursorTracker *cursor_tracker =
|
MetaCursorTracker *cursor_tracker =
|
||||||
meta_backend_get_cursor_tracker (backend);
|
meta_backend_get_cursor_tracker (backend);
|
||||||
|
|
||||||
meta_cursor_tracker_update_position (cursor_tracker,
|
meta_cursor_tracker_update_position (cursor_tracker);
|
||||||
event->motion.x,
|
|
||||||
event->motion.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
display->monitor_cache_invalidated = TRUE;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
852
src/core/meta-pad-action-mapper.c
Normal file
852
src/core/meta-pad-action-mapper.c
Normal file
@ -0,0 +1,852 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014-2020 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib/gi18n-lib.h>
|
||||||
|
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBWACOM
|
||||||
|
#include <libwacom/libwacom.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "meta-pad-action-mapper.h"
|
||||||
|
#include "backends/meta-input-device-private.h"
|
||||||
|
#include "backends/meta-logical-monitor.h"
|
||||||
|
#include "backends/meta-monitor.h"
|
||||||
|
#include "core/display-private.h"
|
||||||
|
|
||||||
|
typedef struct _PadMappingInfo PadMappingInfo;
|
||||||
|
|
||||||
|
struct _PadMappingInfo
|
||||||
|
{
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
GSettings *settings;
|
||||||
|
guint *group_modes;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
META_PAD_DIRECTION_NONE = -1,
|
||||||
|
META_PAD_DIRECTION_UP = 0,
|
||||||
|
META_PAD_DIRECTION_DOWN,
|
||||||
|
META_PAD_DIRECTION_CW,
|
||||||
|
META_PAD_DIRECTION_CCW,
|
||||||
|
} MetaPadDirection;
|
||||||
|
|
||||||
|
struct _MetaPadActionMapper
|
||||||
|
{
|
||||||
|
GObject parent_class;
|
||||||
|
|
||||||
|
GHashTable *pads;
|
||||||
|
ClutterSeat *seat;
|
||||||
|
ClutterVirtualInputDevice *virtual_pad_keyboard;
|
||||||
|
MetaMonitorManager *monitor_manager;
|
||||||
|
gulong monitors_changed_id;
|
||||||
|
|
||||||
|
/* Pad ring/strip emission */
|
||||||
|
struct {
|
||||||
|
ClutterInputDevice *pad;
|
||||||
|
MetaPadActionType action;
|
||||||
|
guint number;
|
||||||
|
gdouble value;
|
||||||
|
} last_pad_action_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaPadActionMapper, meta_pad_action_mapper, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pad_action_mapper_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MetaPadActionMapper *mapper = META_PAD_ACTION_MAPPER (object);
|
||||||
|
|
||||||
|
g_hash_table_unref (mapper->pads);
|
||||||
|
g_signal_handler_disconnect (mapper->monitor_manager,
|
||||||
|
mapper->monitors_changed_id);
|
||||||
|
g_object_unref (mapper->monitor_manager);
|
||||||
|
g_clear_object (&mapper->virtual_pad_keyboard);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_pad_action_mapper_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pad_action_mapper_class_init (MetaPadActionMapperClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = meta_pad_action_mapper_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSettings *
|
||||||
|
lookup_device_settings (ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
const gchar *vendor, *product;
|
||||||
|
GSettings *settings;
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
|
vendor = clutter_input_device_get_vendor_id (device);
|
||||||
|
product = clutter_input_device_get_product_id (device);
|
||||||
|
path = g_strdup_printf ("/org/gnome/desktop/peripherals/tablets/%s:%s/",
|
||||||
|
vendor, product);
|
||||||
|
|
||||||
|
settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet",
|
||||||
|
path);
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PadMappingInfo *
|
||||||
|
pad_mapping_info_new (ClutterInputDevice *pad)
|
||||||
|
{
|
||||||
|
PadMappingInfo *info;
|
||||||
|
|
||||||
|
info = g_new0 (PadMappingInfo, 1);
|
||||||
|
info->device = pad;
|
||||||
|
info->settings = lookup_device_settings (pad);
|
||||||
|
info->group_modes =
|
||||||
|
g_new0 (guint, clutter_input_device_get_n_mode_groups (pad));
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pad_mapping_info_free (PadMappingInfo *info)
|
||||||
|
{
|
||||||
|
g_object_unref (info->settings);
|
||||||
|
g_free (info->group_modes);
|
||||||
|
g_free (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_added (ClutterSeat *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
MetaPadActionMapper *mapper)
|
||||||
|
{
|
||||||
|
PadMappingInfo *info;
|
||||||
|
|
||||||
|
if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
|
||||||
|
{
|
||||||
|
info = pad_mapping_info_new (device);
|
||||||
|
g_hash_table_insert (mapper->pads, device, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_removed (ClutterSeat *seat,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
MetaPadActionMapper *mapper)
|
||||||
|
{
|
||||||
|
g_hash_table_remove (mapper->pads, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pad_action_mapper_init (MetaPadActionMapper *mapper)
|
||||||
|
{
|
||||||
|
mapper->pads = g_hash_table_new_full (NULL, NULL, NULL,
|
||||||
|
(GDestroyNotify) pad_mapping_info_free);
|
||||||
|
|
||||||
|
mapper->seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||||
|
g_signal_connect (mapper->seat, "device-added",
|
||||||
|
G_CALLBACK (device_added), mapper);
|
||||||
|
g_signal_connect (mapper->seat, "device-removed",
|
||||||
|
G_CALLBACK (device_removed), mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaPadActionMapper *
|
||||||
|
meta_pad_action_mapper_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (META_TYPE_PAD_ACTION_MAPPER, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSettings *
|
||||||
|
lookup_pad_action_settings (ClutterInputDevice *device,
|
||||||
|
MetaPadActionType action,
|
||||||
|
guint number,
|
||||||
|
MetaPadDirection direction,
|
||||||
|
gint mode)
|
||||||
|
{
|
||||||
|
const gchar *vendor, *product, *action_type, *detail_type = NULL;
|
||||||
|
GSettings *settings;
|
||||||
|
GString *path;
|
||||||
|
gchar action_label;
|
||||||
|
|
||||||
|
vendor = clutter_input_device_get_vendor_id (device);
|
||||||
|
product = clutter_input_device_get_product_id (device);
|
||||||
|
|
||||||
|
action_label = 'A' + number;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case META_PAD_ACTION_BUTTON:
|
||||||
|
action_type = "button";
|
||||||
|
break;
|
||||||
|
case META_PAD_ACTION_RING:
|
||||||
|
g_assert (direction == META_PAD_DIRECTION_CW ||
|
||||||
|
direction == META_PAD_DIRECTION_CCW);
|
||||||
|
action_type = "ring";
|
||||||
|
detail_type = (direction == META_PAD_DIRECTION_CW) ? "cw" : "ccw";
|
||||||
|
break;
|
||||||
|
case META_PAD_ACTION_STRIP:
|
||||||
|
g_assert (direction == META_PAD_DIRECTION_UP ||
|
||||||
|
direction == META_PAD_DIRECTION_DOWN);
|
||||||
|
action_type = "strip";
|
||||||
|
detail_type = (direction == META_PAD_DIRECTION_UP) ? "up" : "down";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = g_string_new (NULL);
|
||||||
|
g_string_append_printf (path, "/org/gnome/desktop/peripherals/tablets/%s:%s/%s%c",
|
||||||
|
vendor, product, action_type, action_label);
|
||||||
|
|
||||||
|
if (detail_type)
|
||||||
|
g_string_append_printf (path, "-%s", detail_type);
|
||||||
|
|
||||||
|
if (mode >= 0)
|
||||||
|
g_string_append_printf (path, "-mode-%d", mode);
|
||||||
|
|
||||||
|
g_string_append_c (path, '/');
|
||||||
|
|
||||||
|
settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet.pad-button",
|
||||||
|
path->str);
|
||||||
|
g_string_free (path, TRUE);
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GDesktopPadButtonAction
|
||||||
|
meta_pad_action_mapper_get_button_action (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
guint button)
|
||||||
|
{
|
||||||
|
GDesktopPadButtonAction action;
|
||||||
|
GSettings *settings;
|
||||||
|
|
||||||
|
g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper),
|
||||||
|
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad),
|
||||||
|
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
|
||||||
|
|
||||||
|
settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON,
|
||||||
|
button, META_PAD_DIRECTION_NONE, -1);
|
||||||
|
action = g_settings_get_enum (settings, "action");
|
||||||
|
g_object_unref (settings);
|
||||||
|
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
cycle_logical_monitors (MetaPadActionMapper *mapper,
|
||||||
|
MetaLogicalMonitor *current_logical_monitor,
|
||||||
|
MetaLogicalMonitor **next_logical_monitor)
|
||||||
|
{
|
||||||
|
MetaMonitorManager *monitor_manager = mapper->monitor_manager;
|
||||||
|
GList *logical_monitors;
|
||||||
|
|
||||||
|
/* We cycle between:
|
||||||
|
* - the span of all monitors (current_output = NULL)
|
||||||
|
* - each monitor individually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
logical_monitors =
|
||||||
|
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
||||||
|
|
||||||
|
if (!current_logical_monitor)
|
||||||
|
{
|
||||||
|
*next_logical_monitor = logical_monitors->data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
l = g_list_find (logical_monitors, current_logical_monitor);
|
||||||
|
if (l->next)
|
||||||
|
*next_logical_monitor = l->next->data;
|
||||||
|
else
|
||||||
|
*next_logical_monitor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaMonitor *
|
||||||
|
logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor,
|
||||||
|
const char *vendor,
|
||||||
|
const char *product,
|
||||||
|
const char *serial)
|
||||||
|
{
|
||||||
|
GList *monitors;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
monitors = meta_logical_monitor_get_monitors (logical_monitor);
|
||||||
|
for (l = monitors; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaMonitor *monitor = l->data;
|
||||||
|
|
||||||
|
if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 &&
|
||||||
|
g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 &&
|
||||||
|
g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0)
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pad_action_mapper_find_monitor (MetaPadActionMapper *mapper,
|
||||||
|
GSettings *settings,
|
||||||
|
ClutterInputDevice *device,
|
||||||
|
MetaMonitor **out_monitor,
|
||||||
|
MetaLogicalMonitor **out_logical_monitor)
|
||||||
|
{
|
||||||
|
MetaMonitorManager *monitor_manager;
|
||||||
|
MetaMonitor *monitor;
|
||||||
|
guint n_values;
|
||||||
|
GList *logical_monitors;
|
||||||
|
GList *l;
|
||||||
|
gchar **edid;
|
||||||
|
|
||||||
|
edid = g_settings_get_strv (settings, "output");
|
||||||
|
n_values = g_strv_length (edid);
|
||||||
|
|
||||||
|
if (n_values != 3)
|
||||||
|
{
|
||||||
|
g_warning ("EDID configuration for device '%s' "
|
||||||
|
"is incorrect, must have 3 values",
|
||||||
|
clutter_input_device_get_device_name (device));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*edid[0] && !*edid[1] && !*edid[2])
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
monitor_manager = mapper->monitor_manager;
|
||||||
|
logical_monitors =
|
||||||
|
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
||||||
|
for (l = logical_monitors; l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaLogicalMonitor *logical_monitor = l->data;
|
||||||
|
|
||||||
|
monitor = logical_monitor_find_monitor (logical_monitor,
|
||||||
|
edid[0], edid[1], edid[2]);
|
||||||
|
if (monitor)
|
||||||
|
{
|
||||||
|
if (out_monitor)
|
||||||
|
*out_monitor = monitor;
|
||||||
|
if (out_logical_monitor)
|
||||||
|
*out_logical_monitor = logical_monitor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_strfreev (edid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pad_action_mapper_cycle_tablet_output (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *device)
|
||||||
|
{
|
||||||
|
PadMappingInfo *info;
|
||||||
|
MetaLogicalMonitor *logical_monitor = NULL;
|
||||||
|
const gchar *edid[4] = { 0 }, *pretty_name = NULL;
|
||||||
|
#ifdef HAVE_LIBWACOM
|
||||||
|
WacomDevice *wacom_device;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_return_if_fail (META_IS_PAD_ACTION_MAPPER (mapper));
|
||||||
|
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||||
|
g_return_if_fail (clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE ||
|
||||||
|
clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE);
|
||||||
|
|
||||||
|
info = g_hash_table_lookup (mapper->pads, device);
|
||||||
|
g_return_if_fail (info != NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBWACOM
|
||||||
|
wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device));
|
||||||
|
|
||||||
|
if (wacom_device)
|
||||||
|
{
|
||||||
|
/* Output rotation only makes sense on external tablets */
|
||||||
|
if (libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pretty_name = libwacom_get_name (wacom_device);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
meta_pad_action_mapper_find_monitor (mapper, info->settings, device,
|
||||||
|
NULL, &logical_monitor);
|
||||||
|
|
||||||
|
if (!cycle_logical_monitors (mapper,
|
||||||
|
logical_monitor,
|
||||||
|
&logical_monitor))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (logical_monitor)
|
||||||
|
{
|
||||||
|
MetaMonitor *monitor;
|
||||||
|
|
||||||
|
/* Pick an arbitrary monitor in the logical monitor to represent it. */
|
||||||
|
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
||||||
|
edid[0] = meta_monitor_get_vendor (monitor);
|
||||||
|
edid[1] = meta_monitor_get_product (monitor);
|
||||||
|
edid[2] = meta_monitor_get_serial (monitor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
edid[0] = "";
|
||||||
|
edid[1] = "";
|
||||||
|
edid[2] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
g_settings_set_strv (info->settings, "output", edid);
|
||||||
|
meta_display_show_tablet_mapping_notification (meta_get_display (),
|
||||||
|
device, pretty_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_pad_action_mapper_is_button_grabbed (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
guint button)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), FALSE);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), FALSE);
|
||||||
|
g_return_val_if_fail (clutter_input_device_get_device_type (pad) ==
|
||||||
|
CLUTTER_PAD_DEVICE, FALSE);
|
||||||
|
|
||||||
|
return (meta_pad_action_mapper_get_button_action (mapper, pad, button) !=
|
||||||
|
G_DESKTOP_PAD_BUTTON_ACTION_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emulate_modifiers (ClutterVirtualInputDevice *device,
|
||||||
|
ClutterModifierType mods,
|
||||||
|
ClutterKeyState state)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
struct {
|
||||||
|
ClutterModifierType mod;
|
||||||
|
guint keyval;
|
||||||
|
} mod_map[] = {
|
||||||
|
{ CLUTTER_SHIFT_MASK, CLUTTER_KEY_Shift_L },
|
||||||
|
{ CLUTTER_CONTROL_MASK, CLUTTER_KEY_Control_L },
|
||||||
|
{ CLUTTER_MOD1_MASK, CLUTTER_KEY_Meta_L }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (mod_map); i++)
|
||||||
|
{
|
||||||
|
if ((mods & mod_map[i].mod) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
clutter_virtual_input_device_notify_keyval (device,
|
||||||
|
clutter_get_current_event_time (),
|
||||||
|
mod_map[i].keyval, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pad_action_mapper_emulate_keybinding (MetaPadActionMapper *mapper,
|
||||||
|
const gchar *accel,
|
||||||
|
gboolean is_press)
|
||||||
|
{
|
||||||
|
ClutterKeyState state;
|
||||||
|
guint key, mods;
|
||||||
|
|
||||||
|
if (!accel || !*accel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* FIXME: This is appalling */
|
||||||
|
gtk_accelerator_parse (accel, &key, &mods);
|
||||||
|
|
||||||
|
if (!mapper->virtual_pad_keyboard)
|
||||||
|
{
|
||||||
|
ClutterBackend *backend;
|
||||||
|
ClutterSeat *seat;
|
||||||
|
|
||||||
|
backend = clutter_get_default_backend ();
|
||||||
|
seat = clutter_backend_get_default_seat (backend);
|
||||||
|
|
||||||
|
mapper->virtual_pad_keyboard =
|
||||||
|
clutter_seat_create_virtual_device (seat,
|
||||||
|
CLUTTER_KEYBOARD_DEVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
state = is_press ? CLUTTER_KEY_STATE_PRESSED : CLUTTER_KEY_STATE_RELEASED;
|
||||||
|
|
||||||
|
if (is_press)
|
||||||
|
emulate_modifiers (mapper->virtual_pad_keyboard, mods, state);
|
||||||
|
|
||||||
|
clutter_virtual_input_device_notify_keyval (mapper->virtual_pad_keyboard,
|
||||||
|
clutter_get_current_event_time (),
|
||||||
|
key, state);
|
||||||
|
if (!is_press)
|
||||||
|
emulate_modifiers (mapper->virtual_pad_keyboard, mods, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_pad_action_mapper_handle_button (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
const ClutterPadButtonEvent *event)
|
||||||
|
{
|
||||||
|
GDesktopPadButtonAction action;
|
||||||
|
gint button, group, mode;
|
||||||
|
gboolean is_press;
|
||||||
|
GSettings *settings;
|
||||||
|
gchar *accel;
|
||||||
|
|
||||||
|
g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), FALSE);
|
||||||
|
g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
|
||||||
|
event->type == CLUTTER_PAD_BUTTON_RELEASE, FALSE);
|
||||||
|
|
||||||
|
button = event->button;
|
||||||
|
mode = event->mode;
|
||||||
|
group = clutter_input_device_get_mode_switch_button_group (pad, button);
|
||||||
|
is_press = event->type == CLUTTER_PAD_BUTTON_PRESS;
|
||||||
|
|
||||||
|
if (is_press && group >= 0)
|
||||||
|
{
|
||||||
|
guint n_modes = clutter_input_device_get_group_n_modes (pad, group);
|
||||||
|
const gchar *pretty_name = NULL;
|
||||||
|
PadMappingInfo *info;
|
||||||
|
#ifdef HAVE_LIBWACOM
|
||||||
|
WacomDevice *wacom_device;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
info = g_hash_table_lookup (mapper->pads, pad);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBWACOM
|
||||||
|
wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad));
|
||||||
|
|
||||||
|
if (wacom_device)
|
||||||
|
pretty_name = libwacom_get_name (wacom_device);
|
||||||
|
#endif
|
||||||
|
meta_display_notify_pad_group_switch (meta_get_display (), pad,
|
||||||
|
pretty_name, group, mode, n_modes);
|
||||||
|
info->group_modes[group] = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
action = meta_pad_action_mapper_get_button_action (mapper, pad, button);
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR:
|
||||||
|
if (is_press)
|
||||||
|
meta_pad_action_mapper_cycle_tablet_output (mapper, pad);
|
||||||
|
return TRUE;
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_HELP:
|
||||||
|
if (is_press)
|
||||||
|
meta_display_request_pad_osd (meta_get_display (), pad, FALSE);
|
||||||
|
return TRUE;
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING:
|
||||||
|
settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON,
|
||||||
|
button, META_PAD_DIRECTION_NONE, -1);
|
||||||
|
accel = g_settings_get_string (settings, "keybinding");
|
||||||
|
meta_pad_action_mapper_emulate_keybinding (mapper, accel, is_press);
|
||||||
|
g_object_unref (settings);
|
||||||
|
g_free (accel);
|
||||||
|
return TRUE;
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_NONE:
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_pad_action_mapper_handle_action (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
MetaPadActionType action,
|
||||||
|
guint number,
|
||||||
|
MetaPadDirection direction,
|
||||||
|
guint mode)
|
||||||
|
{
|
||||||
|
GSettings *settings;
|
||||||
|
gboolean handled = FALSE;
|
||||||
|
gchar *accel;
|
||||||
|
|
||||||
|
settings = lookup_pad_action_settings (pad, action, number, direction, mode);
|
||||||
|
accel = g_settings_get_string (settings, "keybinding");
|
||||||
|
|
||||||
|
if (accel && *accel)
|
||||||
|
{
|
||||||
|
meta_pad_action_mapper_emulate_keybinding (mapper, accel, TRUE);
|
||||||
|
meta_pad_action_mapper_emulate_keybinding (mapper, accel, FALSE);
|
||||||
|
handled = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (settings);
|
||||||
|
g_free (accel);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_pad_action_mapper_get_action_direction (MetaPadActionMapper *mapper,
|
||||||
|
const ClutterEvent *event,
|
||||||
|
MetaPadDirection *direction)
|
||||||
|
{
|
||||||
|
ClutterInputDevice *pad = clutter_event_get_device (event);
|
||||||
|
MetaPadActionType pad_action;
|
||||||
|
gboolean has_direction = FALSE;
|
||||||
|
MetaPadDirection inc_dir, dec_dir;
|
||||||
|
guint number;
|
||||||
|
gdouble value;
|
||||||
|
|
||||||
|
*direction = META_PAD_DIRECTION_NONE;
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_PAD_RING:
|
||||||
|
pad_action = META_PAD_ACTION_RING;
|
||||||
|
number = event->pad_ring.ring_number;
|
||||||
|
value = event->pad_ring.angle;
|
||||||
|
inc_dir = META_PAD_DIRECTION_CW;
|
||||||
|
dec_dir = META_PAD_DIRECTION_CCW;
|
||||||
|
break;
|
||||||
|
case CLUTTER_PAD_STRIP:
|
||||||
|
pad_action = META_PAD_ACTION_STRIP;
|
||||||
|
number = event->pad_strip.strip_number;
|
||||||
|
value = event->pad_strip.value;
|
||||||
|
inc_dir = META_PAD_DIRECTION_DOWN;
|
||||||
|
dec_dir = META_PAD_DIRECTION_UP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapper->last_pad_action_info.pad == pad &&
|
||||||
|
mapper->last_pad_action_info.action == pad_action &&
|
||||||
|
mapper->last_pad_action_info.number == number &&
|
||||||
|
value >= 0 && mapper->last_pad_action_info.value >= 0)
|
||||||
|
{
|
||||||
|
*direction = (value - mapper->last_pad_action_info.value) > 0 ?
|
||||||
|
inc_dir : dec_dir;
|
||||||
|
has_direction = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper->last_pad_action_info.pad = pad;
|
||||||
|
mapper->last_pad_action_info.action = pad_action;
|
||||||
|
mapper->last_pad_action_info.number = number;
|
||||||
|
mapper->last_pad_action_info.value = value;
|
||||||
|
return has_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_pad_action_mapper_handle_event (MetaPadActionMapper *mapper,
|
||||||
|
const ClutterEvent *event)
|
||||||
|
{
|
||||||
|
ClutterInputDevice *pad;
|
||||||
|
MetaPadDirection direction = META_PAD_DIRECTION_NONE;
|
||||||
|
|
||||||
|
pad = clutter_event_get_source_device ((ClutterEvent *) event);
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_PAD_BUTTON_PRESS:
|
||||||
|
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||||
|
return meta_pad_action_mapper_handle_button (mapper, pad,
|
||||||
|
&event->pad_button);
|
||||||
|
case CLUTTER_PAD_RING:
|
||||||
|
if (!meta_pad_action_mapper_get_action_direction (mapper,
|
||||||
|
event, &direction))
|
||||||
|
return FALSE;
|
||||||
|
return meta_pad_action_mapper_handle_action (mapper, pad,
|
||||||
|
META_PAD_ACTION_RING,
|
||||||
|
event->pad_ring.ring_number,
|
||||||
|
direction,
|
||||||
|
event->pad_ring.mode);
|
||||||
|
case CLUTTER_PAD_STRIP:
|
||||||
|
if (!meta_pad_action_mapper_get_action_direction (mapper,
|
||||||
|
event, &direction))
|
||||||
|
return FALSE;
|
||||||
|
return meta_pad_action_mapper_handle_action (mapper, pad,
|
||||||
|
META_PAD_ACTION_STRIP,
|
||||||
|
event->pad_strip.strip_number,
|
||||||
|
direction,
|
||||||
|
event->pad_strip.mode);
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
compose_directional_action_label (GSettings *direction1,
|
||||||
|
GSettings *direction2)
|
||||||
|
{
|
||||||
|
gchar *accel1, *accel2, *str = NULL;
|
||||||
|
|
||||||
|
accel1 = g_settings_get_string (direction1, "keybinding");
|
||||||
|
accel2 = g_settings_get_string (direction2, "keybinding");
|
||||||
|
|
||||||
|
if (accel1 && *accel1 && accel2 && *accel2)
|
||||||
|
str = g_strdup_printf ("%s / %s", accel1, accel2);
|
||||||
|
|
||||||
|
g_free (accel1);
|
||||||
|
g_free (accel2);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
meta_pad_action_mapper_get_ring_label (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
guint number,
|
||||||
|
guint mode)
|
||||||
|
{
|
||||||
|
GSettings *settings1, *settings2;
|
||||||
|
gchar *label;
|
||||||
|
|
||||||
|
/* We only allow keybinding actions with those */
|
||||||
|
settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number,
|
||||||
|
META_PAD_DIRECTION_CW, mode);
|
||||||
|
settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number,
|
||||||
|
META_PAD_DIRECTION_CCW, mode);
|
||||||
|
label = compose_directional_action_label (settings1, settings2);
|
||||||
|
g_object_unref (settings1);
|
||||||
|
g_object_unref (settings2);
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
meta_pad_action_mapper_get_strip_label (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
guint number,
|
||||||
|
guint mode)
|
||||||
|
{
|
||||||
|
GSettings *settings1, *settings2;
|
||||||
|
gchar *label;
|
||||||
|
|
||||||
|
/* We only allow keybinding actions with those */
|
||||||
|
settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number,
|
||||||
|
META_PAD_DIRECTION_UP, mode);
|
||||||
|
settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number,
|
||||||
|
META_PAD_DIRECTION_DOWN, mode);
|
||||||
|
label = compose_directional_action_label (settings1, settings2);
|
||||||
|
g_object_unref (settings1);
|
||||||
|
g_object_unref (settings2);
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
meta_pad_action_mapper_get_button_label (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
guint button)
|
||||||
|
{
|
||||||
|
GDesktopPadButtonAction action;
|
||||||
|
gint group;
|
||||||
|
|
||||||
|
g_return_val_if_fail (META_IS_PAD_ACTION_MAPPER (mapper), NULL);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), NULL);
|
||||||
|
g_return_val_if_fail (clutter_input_device_get_device_type (pad) ==
|
||||||
|
CLUTTER_PAD_DEVICE, NULL);
|
||||||
|
|
||||||
|
group = clutter_input_device_get_mode_switch_button_group (pad, button);
|
||||||
|
|
||||||
|
if (group >= 0)
|
||||||
|
{
|
||||||
|
/* TRANSLATORS: This string refers to a button that switches between
|
||||||
|
* different modes.
|
||||||
|
*/
|
||||||
|
return g_strdup_printf (_("Mode Switch (Group %d)"), group);
|
||||||
|
}
|
||||||
|
|
||||||
|
action = meta_pad_action_mapper_get_button_action (mapper, pad, button);
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING:
|
||||||
|
{
|
||||||
|
GSettings *settings;
|
||||||
|
gchar *accel;
|
||||||
|
|
||||||
|
settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON,
|
||||||
|
button, META_PAD_DIRECTION_NONE, -1);
|
||||||
|
accel = g_settings_get_string (settings, "keybinding");
|
||||||
|
g_object_unref (settings);
|
||||||
|
|
||||||
|
return accel;
|
||||||
|
}
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR:
|
||||||
|
/* TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||||
|
* mapping through the available outputs.
|
||||||
|
*/
|
||||||
|
return g_strdup (_("Switch monitor"));
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_HELP:
|
||||||
|
return g_strdup (_("Show on-screen help"));
|
||||||
|
case G_DESKTOP_PAD_BUTTON_ACTION_NONE:
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
get_current_pad_mode (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
MetaPadActionType action_type,
|
||||||
|
guint number)
|
||||||
|
{
|
||||||
|
PadMappingInfo *info;
|
||||||
|
guint group = 0, n_groups;
|
||||||
|
|
||||||
|
info = g_hash_table_lookup (mapper->pads, pad);
|
||||||
|
n_groups = clutter_input_device_get_n_mode_groups (pad);
|
||||||
|
|
||||||
|
if (!info->group_modes || n_groups == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (action_type == META_PAD_ACTION_RING ||
|
||||||
|
action_type == META_PAD_ACTION_STRIP)
|
||||||
|
{
|
||||||
|
/* Assume features are evenly distributed in groups */
|
||||||
|
group = number % n_groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info->group_modes[group];
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
meta_pad_action_mapper_get_action_label (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
MetaPadActionType action_type,
|
||||||
|
guint number)
|
||||||
|
{
|
||||||
|
guint mode;
|
||||||
|
|
||||||
|
switch (action_type)
|
||||||
|
{
|
||||||
|
case META_PAD_ACTION_BUTTON:
|
||||||
|
return meta_pad_action_mapper_get_button_label (mapper, pad, number);
|
||||||
|
case META_PAD_ACTION_RING:
|
||||||
|
mode = get_current_pad_mode (mapper, pad, action_type, number);
|
||||||
|
return meta_pad_action_mapper_get_ring_label (mapper, pad, number, mode);
|
||||||
|
case META_PAD_ACTION_STRIP:
|
||||||
|
mode = get_current_pad_mode (mapper, pad, action_type, number);
|
||||||
|
return meta_pad_action_mapper_get_strip_label (mapper, pad, number, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
46
src/core/meta-pad-action-mapper.h
Normal file
46
src/core/meta-pad-action-mapper.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_PAD_ACTION_MAPPER_H
|
||||||
|
#define META_PAD_ACTION_MAPPER_H
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include "meta/display.h"
|
||||||
|
|
||||||
|
#define META_TYPE_PAD_ACTION_MAPPER (meta_pad_action_mapper_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaPadActionMapper, meta_pad_action_mapper,
|
||||||
|
META, PAD_ACTION_MAPPER, GObject)
|
||||||
|
|
||||||
|
MetaPadActionMapper * meta_pad_action_mapper_new (void);
|
||||||
|
|
||||||
|
gboolean meta_pad_action_mapper_is_button_grabbed (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
guint button);
|
||||||
|
gboolean meta_pad_action_mapper_handle_event (MetaPadActionMapper *mapper,
|
||||||
|
const ClutterEvent *event);
|
||||||
|
gchar * meta_pad_action_mapper_get_action_label (MetaPadActionMapper *mapper,
|
||||||
|
ClutterInputDevice *pad,
|
||||||
|
MetaPadActionType action,
|
||||||
|
guint number);
|
||||||
|
|
||||||
|
#endif /* META_PAD_ACTION_MAPPER_H */
|
@ -8183,19 +8183,19 @@ window_focus_on_pointer_rest_callback (gpointer data)
|
|||||||
MetaDisplay *display = window->display;
|
MetaDisplay *display = window->display;
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
int root_x, root_y;
|
graphene_point_t point;
|
||||||
guint32 timestamp;
|
guint32 timestamp;
|
||||||
|
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
meta_cursor_tracker_get_pointer (cursor_tracker, &root_x, &root_y, NULL);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||||
|
|
||||||
if (root_x != focus_data->pointer_x ||
|
if ((int) point.x != focus_data->pointer_x ||
|
||||||
root_y != focus_data->pointer_y)
|
(int) point.y != focus_data->pointer_y)
|
||||||
{
|
{
|
||||||
focus_data->pointer_x = root_x;
|
focus_data->pointer_x = point.x;
|
||||||
focus_data->pointer_y = root_y;
|
focus_data->pointer_y = point.y;
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,6 +233,8 @@ mutter_sources = [
|
|||||||
'backends/meta-settings-private.h',
|
'backends/meta-settings-private.h',
|
||||||
'backends/meta-stage.c',
|
'backends/meta-stage.c',
|
||||||
'backends/meta-stage-private.h',
|
'backends/meta-stage-private.h',
|
||||||
|
'backends/meta-viewport-info.c',
|
||||||
|
'backends/meta-viewport-info.h',
|
||||||
'backends/x11/cm/meta-backend-x11-cm.c',
|
'backends/x11/cm/meta-backend-x11-cm.c',
|
||||||
'backends/x11/cm/meta-backend-x11-cm.h',
|
'backends/x11/cm/meta-backend-x11-cm.h',
|
||||||
'backends/x11/cm/meta-cursor-sprite-xfixes.c',
|
'backends/x11/cm/meta-cursor-sprite-xfixes.c',
|
||||||
@ -374,6 +376,7 @@ mutter_sources = [
|
|||||||
'core/meta-inhibit-shortcuts-dialog-default.c',
|
'core/meta-inhibit-shortcuts-dialog-default.c',
|
||||||
'core/meta-inhibit-shortcuts-dialog-default-private.h',
|
'core/meta-inhibit-shortcuts-dialog-default-private.h',
|
||||||
'core/meta-launch-context.c',
|
'core/meta-launch-context.c',
|
||||||
|
'core/meta-pad-action-mapper.c',
|
||||||
'core/meta-selection.c',
|
'core/meta-selection.c',
|
||||||
'core/meta-selection-source.c',
|
'core/meta-selection-source.c',
|
||||||
'core/meta-selection-source-memory.c',
|
'core/meta-selection-source-memory.c',
|
||||||
@ -672,6 +675,8 @@ if have_native_backend
|
|||||||
'backends/native/meta-kms-crtc-private.h',
|
'backends/native/meta-kms-crtc-private.h',
|
||||||
'backends/native/meta-kms-crtc.c',
|
'backends/native/meta-kms-crtc.c',
|
||||||
'backends/native/meta-kms-crtc.h',
|
'backends/native/meta-kms-crtc.h',
|
||||||
|
'backends/native/meta-kms-cursor-renderer.c',
|
||||||
|
'backends/native/meta-kms-cursor-renderer.h',
|
||||||
'backends/native/meta-kms-device-private.h',
|
'backends/native/meta-kms-device-private.h',
|
||||||
'backends/native/meta-kms-device.c',
|
'backends/native/meta-kms-device.c',
|
||||||
'backends/native/meta-kms-device.h',
|
'backends/native/meta-kms-device.h',
|
||||||
@ -695,9 +700,13 @@ if have_native_backend
|
|||||||
'backends/native/meta-kms-utils.h',
|
'backends/native/meta-kms-utils.h',
|
||||||
'backends/native/meta-kms.c',
|
'backends/native/meta-kms.c',
|
||||||
'backends/native/meta-kms.h',
|
'backends/native/meta-kms.h',
|
||||||
|
'backends/native/meta-pointer-constraint-native.c',
|
||||||
|
'backends/native/meta-pointer-constraint-native.h',
|
||||||
'backends/native/meta-renderer-native-gles3.c',
|
'backends/native/meta-renderer-native-gles3.c',
|
||||||
'backends/native/meta-renderer-native-gles3.h',
|
'backends/native/meta-renderer-native-gles3.h',
|
||||||
'backends/native/meta-renderer-native.h',
|
'backends/native/meta-renderer-native.h',
|
||||||
|
'backends/native/meta-seat-impl.c',
|
||||||
|
'backends/native/meta-seat-impl.h',
|
||||||
'backends/native/meta-seat-native.c',
|
'backends/native/meta-seat-native.c',
|
||||||
'backends/native/meta-seat-native.h',
|
'backends/native/meta-seat-native.h',
|
||||||
'backends/native/meta-stage-native.c',
|
'backends/native/meta-stage-native.c',
|
||||||
@ -749,14 +758,6 @@ dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
|
|||||||
)
|
)
|
||||||
mutter_built_sources += dbus_idle_monitor_built_sources
|
mutter_built_sources += dbus_idle_monitor_built_sources
|
||||||
|
|
||||||
mutter_marshal = gnome.genmarshal('meta-marshal',
|
|
||||||
sources: ['meta-marshal.list'],
|
|
||||||
prefix: 'meta_marshal',
|
|
||||||
internal: true,
|
|
||||||
valist_marshallers: true,
|
|
||||||
)
|
|
||||||
mutter_built_sources += mutter_marshal
|
|
||||||
|
|
||||||
if have_profiler
|
if have_profiler
|
||||||
mutter_sources += [
|
mutter_sources += [
|
||||||
'backends/meta-profiler.c',
|
'backends/meta-profiler.c',
|
||||||
|
@ -1 +0,0 @@
|
|||||||
VOID:FLOAT,FLOAT
|
|
@ -50,8 +50,7 @@ CoglTexture *meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker);
|
|||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
void meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
|
void meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
|
||||||
int *x,
|
graphene_point_t *coords,
|
||||||
int *y,
|
|
||||||
ClutterModifierType *mods);
|
ClutterModifierType *mods);
|
||||||
|
|
||||||
META_EXPORT
|
META_EXPORT
|
||||||
|
@ -173,8 +173,6 @@ seat_device_added_cb (ClutterSeat *seat,
|
|||||||
g_print ("*** enabling device '%s' ***\n",
|
g_print ("*** enabling device '%s' ***\n",
|
||||||
clutter_input_device_get_device_name (device));
|
clutter_input_device_get_device_name (device));
|
||||||
|
|
||||||
clutter_input_device_set_enabled (device, TRUE);
|
|
||||||
|
|
||||||
hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR
|
hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR
|
||||||
G_DIR_SEPARATOR_S
|
G_DIR_SEPARATOR_S
|
||||||
"redhand.png",
|
"redhand.png",
|
||||||
@ -272,8 +270,6 @@ test_devices_main (int argc, char **argv)
|
|||||||
g_print ("*** enabling device '%s' ***\n",
|
g_print ("*** enabling device '%s' ***\n",
|
||||||
clutter_input_device_get_device_name (device));
|
clutter_input_device_get_device_name (device));
|
||||||
|
|
||||||
clutter_input_device_set_enabled (device, TRUE);
|
|
||||||
|
|
||||||
hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR
|
hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR
|
||||||
G_DIR_SEPARATOR_S
|
G_DIR_SEPARATOR_S
|
||||||
"redhand.png",
|
"redhand.png",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
#include <clutter/clutter-mutter.h>
|
||||||
|
|
||||||
#include "tests/clutter-test-utils.h"
|
#include "tests/clutter-test-utils.h"
|
||||||
|
|
||||||
@ -109,7 +110,6 @@ static gboolean perf_fake_mouse_cb (gpointer stage)
|
|||||||
event2->crossing.related = NULL;
|
event2->crossing.related = NULL;
|
||||||
|
|
||||||
clutter_event_set_device (event2, device);
|
clutter_event_set_device (event2, device);
|
||||||
clutter_input_device_update_from_event (device, event2, TRUE);
|
|
||||||
|
|
||||||
clutter_event_put (event2);
|
clutter_event_put (event2);
|
||||||
clutter_event_free (event2);
|
clutter_event_free (event2);
|
||||||
|
@ -41,667 +41,70 @@
|
|||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/meta-pointer-constraint.h"
|
#include "backends/meta-pointer-constraint.h"
|
||||||
#include "compositor/meta-surface-actor-wayland.h"
|
|
||||||
#include "core/meta-border.h"
|
|
||||||
#include "wayland/meta-wayland-pointer-constraints.h"
|
#include "wayland/meta-wayland-pointer-constraints.h"
|
||||||
#include "wayland/meta-wayland-pointer.h"
|
#include "wayland/meta-wayland-pointer.h"
|
||||||
#include "wayland/meta-wayland-seat.h"
|
#include "wayland/meta-wayland-seat.h"
|
||||||
#include "wayland/meta-wayland-surface.h"
|
#include "wayland/meta-wayland-surface.h"
|
||||||
|
|
||||||
struct _MetaPointerConfinementWayland
|
typedef struct _MetaPointerConfinementWaylandPrivate MetaPointerConfinementWaylandPrivate;
|
||||||
{
|
|
||||||
MetaPointerConstraint parent;
|
|
||||||
|
|
||||||
|
struct _MetaPointerConfinementWaylandPrivate
|
||||||
|
{
|
||||||
MetaWaylandPointerConstraint *constraint;
|
MetaWaylandPointerConstraint *constraint;
|
||||||
|
gboolean enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _MetaBox
|
enum
|
||||||
{
|
{
|
||||||
int x1;
|
PROP_0,
|
||||||
int y1;
|
PROP_WAYLAND_POINTER_CONSTRAINT,
|
||||||
int x2;
|
N_PROPS,
|
||||||
int y2;
|
};
|
||||||
} MetaBox;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaPointerConfinementWayland, meta_pointer_confinement_wayland,
|
static GParamSpec *props[N_PROPS] = { 0 };
|
||||||
META_TYPE_POINTER_CONSTRAINT);
|
|
||||||
|
|
||||||
static MetaBorder *
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaPointerConfinementWayland,
|
||||||
add_border (GArray *borders,
|
meta_pointer_confinement_wayland,
|
||||||
float x1, float y1,
|
G_TYPE_OBJECT)
|
||||||
float x2, float y2,
|
|
||||||
MetaBorderMotionDirection blocking_directions)
|
|
||||||
{
|
|
||||||
MetaBorder border;
|
|
||||||
|
|
||||||
border = (MetaBorder) {
|
|
||||||
.line = (MetaLine2) {
|
|
||||||
.a = (MetaVector2) {
|
|
||||||
.x = x1,
|
|
||||||
.y = y1,
|
|
||||||
},
|
|
||||||
.b = (MetaVector2) {
|
|
||||||
.x = x2,
|
|
||||||
.y = y2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.blocking_directions = blocking_directions,
|
|
||||||
};
|
|
||||||
|
|
||||||
g_array_append_val (borders, border);
|
|
||||||
|
|
||||||
return &g_array_index (borders, MetaBorder, borders->len - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gint
|
|
||||||
compare_lines_x (gconstpointer a, gconstpointer b)
|
|
||||||
{
|
|
||||||
const MetaBorder *border_a = a;
|
|
||||||
const MetaBorder *border_b = b;
|
|
||||||
|
|
||||||
if (border_a->line.a.x == border_b->line.a.x)
|
|
||||||
return border_a->line.b.x < border_b->line.b.x;
|
|
||||||
else
|
|
||||||
return border_a->line.a.x > border_b->line.a.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_non_overlapping_edges (MetaBox *boxes,
|
meta_pointer_confinement_wayland_update (MetaPointerConfinementWayland *self)
|
||||||
unsigned int band_above_start,
|
|
||||||
unsigned int band_below_start,
|
|
||||||
unsigned int band_below_end,
|
|
||||||
GArray *borders)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
MetaPointerConstraint *constraint;
|
||||||
GArray *band_merge;
|
|
||||||
MetaBorder *border;
|
|
||||||
MetaBorder *prev_border;
|
|
||||||
MetaBorder *new_border;
|
|
||||||
|
|
||||||
band_merge = g_array_new (FALSE, FALSE, sizeof *border);
|
constraint =
|
||||||
|
META_POINTER_CONFINEMENT_WAYLAND_GET_CLASS (self)->create_constraint (self);
|
||||||
/* Add bottom band of previous row, and top band of current row, and
|
meta_backend_set_client_pointer_constraint (meta_get_backend (), constraint);
|
||||||
* sort them so lower left x coordinate comes first. If there are two
|
g_object_unref (constraint);
|
||||||
* borders with the same left x coordinate, the wider one comes first.
|
|
||||||
*/
|
|
||||||
for (i = band_above_start; i < band_below_start; i++)
|
|
||||||
{
|
|
||||||
MetaBox *box = &boxes[i];
|
|
||||||
add_border (band_merge, box->x1, box->y2, box->x2, box->y2,
|
|
||||||
META_BORDER_MOTION_DIRECTION_POSITIVE_Y);
|
|
||||||
}
|
|
||||||
for (i = band_below_start; i < band_below_end; i++)
|
|
||||||
{
|
|
||||||
MetaBox *box= &boxes[i];
|
|
||||||
add_border (band_merge, box->x1, box->y1, box->x2, box->y1,
|
|
||||||
META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
|
|
||||||
}
|
|
||||||
g_array_sort (band_merge, compare_lines_x);
|
|
||||||
|
|
||||||
/* Combine the two combined bands so that any overlapping border is
|
|
||||||
* eliminated. */
|
|
||||||
prev_border = NULL;
|
|
||||||
for (i = 0; i < band_merge->len; i++)
|
|
||||||
{
|
|
||||||
border = &g_array_index (band_merge, MetaBorder, i);
|
|
||||||
|
|
||||||
g_assert (border->line.a.y == border->line.b.y);
|
|
||||||
g_assert (!prev_border ||
|
|
||||||
prev_border->line.a.y == border->line.a.y);
|
|
||||||
g_assert (!prev_border ||
|
|
||||||
(prev_border->line.a.x != border->line.a.x ||
|
|
||||||
prev_border->line.b.x != border->line.b.x));
|
|
||||||
g_assert (!prev_border ||
|
|
||||||
prev_border->line.a.x <= border->line.a.x);
|
|
||||||
|
|
||||||
if (prev_border &&
|
|
||||||
prev_border->line.a.x == border->line.a.x)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* ------------ +
|
|
||||||
* ------- =
|
|
||||||
* [ ]-----
|
|
||||||
*/
|
|
||||||
prev_border->line.a.x = border->line.b.x;
|
|
||||||
}
|
|
||||||
else if (prev_border &&
|
|
||||||
prev_border->line.b.x == border->line.b.x)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* ------------ +
|
|
||||||
* ------ =
|
|
||||||
* ------[ ]
|
|
||||||
*/
|
|
||||||
prev_border->line.b.x = border->line.a.x;
|
|
||||||
}
|
|
||||||
else if (prev_border &&
|
|
||||||
prev_border->line.b.x == border->line.a.x)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* -------- +
|
|
||||||
* ------ =
|
|
||||||
* --------------
|
|
||||||
*/
|
|
||||||
prev_border->line.b.x = border->line.b.x;
|
|
||||||
}
|
|
||||||
else if (prev_border &&
|
|
||||||
prev_border->line.b.x >= border->line.a.x)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* --------------- +
|
|
||||||
* ------ =
|
|
||||||
* -----[ ]----
|
|
||||||
*/
|
|
||||||
new_border = add_border (borders,
|
|
||||||
border->line.b.x,
|
|
||||||
border->line.b.y,
|
|
||||||
prev_border->line.b.x,
|
|
||||||
prev_border->line.b.y,
|
|
||||||
prev_border->blocking_directions);
|
|
||||||
prev_border->line.b.x = border->line.a.x;
|
|
||||||
prev_border = new_border;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_assert (!prev_border ||
|
|
||||||
prev_border->line.b.x < border->line.a.x);
|
|
||||||
/*
|
|
||||||
* First border or non-overlapping.
|
|
||||||
*
|
|
||||||
* ----- +
|
|
||||||
* ----- =
|
|
||||||
* ----- -----
|
|
||||||
*/
|
|
||||||
g_array_append_val (borders, *border);
|
|
||||||
prev_border = &g_array_index (borders, MetaBorder, borders->len - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_array_free (band_merge, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_band_bottom_edges (MetaBox *boxes,
|
|
||||||
int band_start,
|
|
||||||
int band_end,
|
|
||||||
GArray *borders)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = band_start; i < band_end; i++)
|
|
||||||
{
|
|
||||||
add_border (borders,
|
|
||||||
boxes[i].x1, boxes[i].y2,
|
|
||||||
boxes[i].x2, boxes[i].y2,
|
|
||||||
META_BORDER_MOTION_DIRECTION_POSITIVE_Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
region_to_outline (cairo_region_t *region,
|
|
||||||
GArray *borders)
|
|
||||||
{
|
|
||||||
MetaBox *boxes;
|
|
||||||
int num_boxes;
|
|
||||||
int i;
|
|
||||||
int top_most, bottom_most;
|
|
||||||
int current_roof;
|
|
||||||
int prev_top;
|
|
||||||
int band_start, prev_band_start;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove any overlapping lines from the set of rectangles. Note that
|
|
||||||
* pixman regions are grouped as rows of rectangles, where rectangles
|
|
||||||
* in one row never touch or overlap and are all of the same height.
|
|
||||||
*
|
|
||||||
* -------- --- -------- ---
|
|
||||||
* | | | | | | | |
|
|
||||||
* ----------====---- --- ----------- ----- ---
|
|
||||||
* | | => | |
|
|
||||||
* ----==========--------- ----- ----------
|
|
||||||
* | | | |
|
|
||||||
* ------------------- -------------------
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
num_boxes = cairo_region_num_rectangles (region);
|
|
||||||
boxes = g_new (MetaBox, num_boxes);
|
|
||||||
for (i = 0; i < num_boxes; i++)
|
|
||||||
{
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
cairo_region_get_rectangle (region, i, &rect);
|
|
||||||
boxes[i] = (MetaBox) {
|
|
||||||
.x1 = rect.x,
|
|
||||||
.y1 = rect.y,
|
|
||||||
.x2 = rect.x + rect.width,
|
|
||||||
.y2 = rect.y + rect.height,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
prev_top = 0;
|
|
||||||
top_most = boxes[0].y1;
|
|
||||||
current_roof = top_most;
|
|
||||||
bottom_most = boxes[num_boxes - 1].y2;
|
|
||||||
band_start = 0;
|
|
||||||
prev_band_start = 0;
|
|
||||||
for (i = 0; i < num_boxes; i++)
|
|
||||||
{
|
|
||||||
/* Detect if there is a vertical empty space, and add the lower
|
|
||||||
* level of the previous band if so was the case. */
|
|
||||||
if (i > 0 &&
|
|
||||||
boxes[i].y1 != prev_top &&
|
|
||||||
boxes[i].y1 != boxes[i - 1].y2)
|
|
||||||
{
|
|
||||||
current_roof = boxes[i].y1;
|
|
||||||
add_band_bottom_edges (boxes,
|
|
||||||
band_start,
|
|
||||||
i,
|
|
||||||
borders);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special case adding the last band, since it won't be handled
|
|
||||||
* by the band change detection below. */
|
|
||||||
if (boxes[i].y1 != current_roof && i == num_boxes - 1)
|
|
||||||
{
|
|
||||||
if (boxes[i].y1 != prev_top)
|
|
||||||
{
|
|
||||||
/* The last band is a single box, so we don't
|
|
||||||
* have a prev_band_start to tell us when the
|
|
||||||
* previous band started. */
|
|
||||||
add_non_overlapping_edges (boxes,
|
|
||||||
band_start,
|
|
||||||
i,
|
|
||||||
i + 1,
|
|
||||||
borders);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
add_non_overlapping_edges (boxes,
|
|
||||||
prev_band_start,
|
|
||||||
band_start,
|
|
||||||
i + 1,
|
|
||||||
borders);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Detect when passing a band and combine the top border of the
|
|
||||||
* just passed band with the bottom band of the previous band.
|
|
||||||
*/
|
|
||||||
if (boxes[i].y1 != top_most && boxes[i].y1 != prev_top)
|
|
||||||
{
|
|
||||||
/* Combine the two passed bands. */
|
|
||||||
if (prev_top != current_roof)
|
|
||||||
{
|
|
||||||
add_non_overlapping_edges (boxes,
|
|
||||||
prev_band_start,
|
|
||||||
band_start,
|
|
||||||
i,
|
|
||||||
borders);
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_band_start = band_start;
|
|
||||||
band_start = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the top border if the box is part of the current roof. */
|
|
||||||
if (boxes[i].y1 == current_roof)
|
|
||||||
{
|
|
||||||
add_border (borders,
|
|
||||||
boxes[i].x1, boxes[i].y1,
|
|
||||||
boxes[i].x2, boxes[i].y1,
|
|
||||||
META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the bottom border of the last band. */
|
|
||||||
if (boxes[i].y2 == bottom_most)
|
|
||||||
{
|
|
||||||
add_border (borders,
|
|
||||||
boxes[i].x1, boxes[i].y2,
|
|
||||||
boxes[i].x2, boxes[i].y2,
|
|
||||||
META_BORDER_MOTION_DIRECTION_POSITIVE_Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Always add the left border. */
|
|
||||||
add_border (borders,
|
|
||||||
boxes[i].x1, boxes[i].y1,
|
|
||||||
boxes[i].x1, boxes[i].y2,
|
|
||||||
META_BORDER_MOTION_DIRECTION_NEGATIVE_X);
|
|
||||||
|
|
||||||
/* Always add the right border. */
|
|
||||||
add_border (borders,
|
|
||||||
boxes[i].x2, boxes[i].y1,
|
|
||||||
boxes[i].x2, boxes[i].y2,
|
|
||||||
META_BORDER_MOTION_DIRECTION_POSITIVE_X);
|
|
||||||
|
|
||||||
prev_top = boxes[i].y1;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (boxes);
|
|
||||||
}
|
|
||||||
|
|
||||||
static MetaBorder *
|
|
||||||
get_closest_border (GArray *borders,
|
|
||||||
MetaLine2 *motion,
|
|
||||||
uint32_t directions)
|
|
||||||
{
|
|
||||||
MetaBorder *border;
|
|
||||||
MetaVector2 intersection;
|
|
||||||
MetaVector2 delta;
|
|
||||||
float distance_2;
|
|
||||||
MetaBorder *closest_border = NULL;
|
|
||||||
float closest_distance_2 = DBL_MAX;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < borders->len; i++)
|
|
||||||
{
|
|
||||||
border = &g_array_index (borders, MetaBorder, i);
|
|
||||||
|
|
||||||
if (!meta_border_is_blocking_directions (border, directions))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!meta_line2_intersects_with (&border->line, motion, &intersection))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
delta = meta_vector2_subtract (intersection, motion->a);
|
|
||||||
distance_2 = delta.x*delta.x + delta.y*delta.y;
|
|
||||||
if (distance_2 < closest_distance_2)
|
|
||||||
{
|
|
||||||
closest_border = border;
|
|
||||||
closest_distance_2 = distance_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return closest_border;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
clamp_to_border (MetaBorder *border,
|
|
||||||
MetaLine2 *motion,
|
|
||||||
uint32_t *motion_dir)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* When clamping either rightward or downward motions, the motion needs to be
|
|
||||||
* clamped so that the destination coordinate does not end up on the border
|
|
||||||
* (see weston_pointer_clamp_event_to_region). Do this by clamping such
|
|
||||||
* motions to the border minus the smallest possible wl_fixed_t value.
|
|
||||||
*
|
|
||||||
* When clamping in either leftward or upward motion, the resulting coordinate
|
|
||||||
* needs to be clamped so that it is enough on the inside to avoid the
|
|
||||||
* inaccuracies of clutter's stage to actor transformation algorithm (the one
|
|
||||||
* used in clutter_actor_transform_stage_point) to make it end up outside the
|
|
||||||
* next motion. It also needs to be clamped so that to the wl_fixed_t
|
|
||||||
* coordinate may still be right on the border (i.e. at .0). Testing shows
|
|
||||||
* that the smallest wl_fixed_t value divided by 10 is small enough to make
|
|
||||||
* the wl_fixed_t coordinate .0 and large enough to avoid the inaccuracies of
|
|
||||||
* clutters transform algorithm.
|
|
||||||
*/
|
|
||||||
if (meta_border_is_horizontal (border))
|
|
||||||
{
|
|
||||||
if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_Y)
|
|
||||||
motion->b.y = border->line.a.y - wl_fixed_to_double (1);
|
|
||||||
else
|
|
||||||
motion->b.y = border->line.a.y + wl_fixed_to_double (1) / 10;
|
|
||||||
*motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_Y |
|
|
||||||
META_BORDER_MOTION_DIRECTION_NEGATIVE_Y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_X)
|
|
||||||
motion->b.x = border->line.a.x - wl_fixed_to_double (1);
|
|
||||||
else
|
|
||||||
motion->b.x = border->line.a.x + wl_fixed_to_double (1) / 10;
|
|
||||||
*motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_X |
|
|
||||||
META_BORDER_MOTION_DIRECTION_NEGATIVE_X);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t
|
|
||||||
get_motion_directions (MetaLine2 *motion)
|
|
||||||
{
|
|
||||||
uint32_t directions = 0;
|
|
||||||
|
|
||||||
if (motion->a.x < motion->b.x)
|
|
||||||
directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_X;
|
|
||||||
else if (motion->a.x > motion->b.x)
|
|
||||||
directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_X;
|
|
||||||
if (motion->a.y < motion->b.y)
|
|
||||||
directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_Y;
|
|
||||||
else if (motion->a.y > motion->b.y)
|
|
||||||
directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_Y;
|
|
||||||
|
|
||||||
return directions;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_pointer_confinement_wayland_constrain (MetaPointerConstraint *constraint,
|
|
||||||
ClutterInputDevice *device,
|
|
||||||
guint32 time,
|
|
||||||
float prev_x,
|
|
||||||
float prev_y,
|
|
||||||
float *x,
|
|
||||||
float *y)
|
|
||||||
{
|
|
||||||
MetaPointerConfinementWayland *self =
|
|
||||||
META_POINTER_CONFINEMENT_WAYLAND (constraint);
|
|
||||||
MetaWaylandSurface *surface;
|
|
||||||
cairo_region_t *region;
|
|
||||||
float sx, sy;
|
|
||||||
float prev_sx, prev_sy;
|
|
||||||
GArray *borders;
|
|
||||||
MetaLine2 motion;
|
|
||||||
MetaBorder *closest_border;
|
|
||||||
uint32_t directions;
|
|
||||||
|
|
||||||
surface = meta_wayland_pointer_constraint_get_surface (self->constraint);
|
|
||||||
|
|
||||||
meta_wayland_surface_get_relative_coordinates (surface, *x, *y, &sx, &sy);
|
|
||||||
meta_wayland_surface_get_relative_coordinates (surface, prev_x, prev_y,
|
|
||||||
&prev_sx, &prev_sy);
|
|
||||||
|
|
||||||
/* For motions in a positive direction on any axis, append the smallest
|
|
||||||
* possible value representable in a Wayland absolute coordinate. This is
|
|
||||||
* in order to avoid not clamping motion that as a floating point number
|
|
||||||
* won't be clamped, but will be rounded up to be outside of the range
|
|
||||||
* of wl_fixed_t. */
|
|
||||||
if (sx > prev_sx)
|
|
||||||
sx += (float)wl_fixed_to_double(1);
|
|
||||||
if (sy > prev_sy)
|
|
||||||
sy += (float)wl_fixed_to_double(1);
|
|
||||||
|
|
||||||
borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generate borders given the confine region we are to use. The borders
|
|
||||||
* are defined to be the outer region of the allowed area. This means
|
|
||||||
* top/left borders are "within" the allowed area, while bottom/right
|
|
||||||
* borders are outside. This needs to be considered when clamping
|
|
||||||
* confined motion vectors.
|
|
||||||
*/
|
|
||||||
region =
|
|
||||||
meta_wayland_pointer_constraint_calculate_effective_region (self->constraint);
|
|
||||||
region_to_outline (region, borders);
|
|
||||||
cairo_region_destroy (region);
|
|
||||||
|
|
||||||
motion = (MetaLine2) {
|
|
||||||
.a = (MetaVector2) {
|
|
||||||
.x = prev_sx,
|
|
||||||
.y = prev_sy,
|
|
||||||
},
|
|
||||||
.b = (MetaVector2) {
|
|
||||||
.x = sx,
|
|
||||||
.y = sy,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
directions = get_motion_directions (&motion);
|
|
||||||
|
|
||||||
while (directions)
|
|
||||||
{
|
|
||||||
closest_border = get_closest_border (borders,
|
|
||||||
&motion,
|
|
||||||
directions);
|
|
||||||
if (closest_border)
|
|
||||||
clamp_to_border (closest_border, &motion, &directions);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_wayland_surface_get_absolute_coordinates (surface,
|
|
||||||
motion.b.x, motion.b.y,
|
|
||||||
x, y);
|
|
||||||
|
|
||||||
g_array_free (borders, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float
|
|
||||||
point_to_border_distance_2 (MetaBorder *border,
|
|
||||||
float x,
|
|
||||||
float y)
|
|
||||||
{
|
|
||||||
float orig_x, orig_y;
|
|
||||||
float dx, dy;
|
|
||||||
|
|
||||||
if (meta_border_is_horizontal (border))
|
|
||||||
{
|
|
||||||
if (x < border->line.a.x)
|
|
||||||
orig_x = border->line.a.x;
|
|
||||||
else if (x > border->line.b.x)
|
|
||||||
orig_x = border->line.b.x;
|
|
||||||
else
|
|
||||||
orig_x = x;
|
|
||||||
orig_y = border->line.a.y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (y < border->line.a.y)
|
|
||||||
orig_y = border->line.a.y;
|
|
||||||
else if (y > border->line.b.y)
|
|
||||||
orig_y = border->line.b.y;
|
|
||||||
else
|
|
||||||
orig_y = y;
|
|
||||||
orig_x = border->line.a.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx = fabsf (orig_x - x);
|
|
||||||
dy = fabsf (orig_y - y);
|
|
||||||
return dx*dx + dy*dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
warp_to_behind_border (MetaBorder *border,
|
|
||||||
float *sx,
|
|
||||||
float *sy)
|
|
||||||
{
|
|
||||||
switch (border->blocking_directions)
|
|
||||||
{
|
|
||||||
case META_BORDER_MOTION_DIRECTION_POSITIVE_X:
|
|
||||||
case META_BORDER_MOTION_DIRECTION_NEGATIVE_X:
|
|
||||||
if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_X)
|
|
||||||
*sx = border->line.a.x - wl_fixed_to_double (1);
|
|
||||||
else
|
|
||||||
*sx = border->line.a.x + wl_fixed_to_double (1);
|
|
||||||
if (*sy < border->line.a.y)
|
|
||||||
*sy = border->line.a.y + wl_fixed_to_double (1);
|
|
||||||
else if (*sy > border->line.b.y)
|
|
||||||
*sy = border->line.b.y - wl_fixed_to_double (1);
|
|
||||||
break;
|
|
||||||
case META_BORDER_MOTION_DIRECTION_POSITIVE_Y:
|
|
||||||
case META_BORDER_MOTION_DIRECTION_NEGATIVE_Y:
|
|
||||||
if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_Y)
|
|
||||||
*sy = border->line.a.y - wl_fixed_to_double (1);
|
|
||||||
else
|
|
||||||
*sy = border->line.a.y + wl_fixed_to_double (1);
|
|
||||||
if (*sx < border->line.a.x)
|
|
||||||
*sx = border->line.a.x + wl_fixed_to_double (1);
|
|
||||||
else if (*sx > (border->line.b.x))
|
|
||||||
*sx = border->line.b.x - wl_fixed_to_double (1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_pointer_confinement_wayland_maybe_warp (MetaPointerConfinementWayland *self)
|
|
||||||
{
|
|
||||||
MetaWaylandSeat *seat;
|
|
||||||
MetaWaylandSurface *surface;
|
|
||||||
graphene_point_t point;
|
|
||||||
float sx;
|
|
||||||
float sy;
|
|
||||||
cairo_region_t *region;
|
|
||||||
|
|
||||||
seat = meta_wayland_pointer_constraint_get_seat (self->constraint);
|
|
||||||
surface = meta_wayland_pointer_constraint_get_surface (self->constraint);
|
|
||||||
|
|
||||||
clutter_input_device_get_coords (seat->pointer->device, NULL, &point);
|
|
||||||
meta_wayland_surface_get_relative_coordinates (surface,
|
|
||||||
point.x, point.y,
|
|
||||||
&sx, &sy);
|
|
||||||
|
|
||||||
region =
|
|
||||||
meta_wayland_pointer_constraint_calculate_effective_region (self->constraint);
|
|
||||||
|
|
||||||
if (!cairo_region_contains_point (region, (int)sx, (int)sy))
|
|
||||||
{
|
|
||||||
GArray *borders;
|
|
||||||
float closest_distance_2 = FLT_MAX;
|
|
||||||
MetaBorder *closest_border = NULL;
|
|
||||||
ClutterSeat *seat;
|
|
||||||
unsigned int i;
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
|
|
||||||
borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder));
|
|
||||||
|
|
||||||
region_to_outline (region, borders);
|
|
||||||
|
|
||||||
for (i = 0; i < borders->len; i++)
|
|
||||||
{
|
|
||||||
MetaBorder *border = &g_array_index (borders, MetaBorder, i);
|
|
||||||
float distance_2;
|
|
||||||
|
|
||||||
distance_2 = point_to_border_distance_2 (border, sx, sy);
|
|
||||||
if (distance_2 < closest_distance_2)
|
|
||||||
{
|
|
||||||
closest_border = border;
|
|
||||||
closest_distance_2 = distance_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
warp_to_behind_border (closest_border, &sx, &sy);
|
|
||||||
|
|
||||||
meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y);
|
|
||||||
|
|
||||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
|
||||||
clutter_seat_warp_pointer (seat, (int)x, (int)y);
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_region_destroy (region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
surface_geometry_changed (MetaWaylandSurface *surface,
|
surface_geometry_changed (MetaWaylandSurface *surface,
|
||||||
MetaPointerConfinementWayland *self)
|
MetaPointerConfinementWayland *self)
|
||||||
{
|
{
|
||||||
meta_pointer_confinement_wayland_maybe_warp (self);
|
meta_pointer_confinement_wayland_update (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_position_changed (MetaWindow *window,
|
window_position_changed (MetaWindow *window,
|
||||||
MetaPointerConfinementWayland *self)
|
MetaPointerConfinementWayland *self)
|
||||||
{
|
{
|
||||||
meta_pointer_confinement_wayland_maybe_warp (self);
|
meta_pointer_confinement_wayland_update (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaPointerConstraint *
|
void
|
||||||
meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint)
|
meta_pointer_confinement_wayland_enable (MetaPointerConfinementWayland *confinement)
|
||||||
{
|
{
|
||||||
GObject *object;
|
MetaPointerConfinementWaylandPrivate *priv;
|
||||||
MetaPointerConfinementWayland *confinement;
|
MetaWaylandPointerConstraint *constraint;
|
||||||
MetaWaylandSurface *surface;
|
MetaWaylandSurface *surface;
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
|
|
||||||
object = g_object_new (META_TYPE_POINTER_CONFINEMENT_WAYLAND, NULL);
|
priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
|
||||||
confinement = META_POINTER_CONFINEMENT_WAYLAND (object);
|
g_assert (!priv->enabled);
|
||||||
|
|
||||||
confinement->constraint = constraint;
|
priv->enabled = TRUE;
|
||||||
|
constraint = priv->constraint;
|
||||||
|
|
||||||
surface = meta_wayland_pointer_constraint_get_surface (constraint);
|
surface = meta_wayland_pointer_constraint_get_surface (constraint);
|
||||||
g_signal_connect_object (surface,
|
g_signal_connect_object (surface,
|
||||||
@ -720,7 +123,34 @@ meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint)
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return META_POINTER_CONSTRAINT (confinement);
|
meta_pointer_confinement_wayland_update (confinement);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_pointer_confinement_wayland_disable (MetaPointerConfinementWayland *confinement)
|
||||||
|
{
|
||||||
|
MetaPointerConfinementWaylandPrivate *priv;
|
||||||
|
MetaWaylandPointerConstraint *constraint;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
|
||||||
|
constraint = priv->constraint;
|
||||||
|
g_assert (priv->enabled);
|
||||||
|
|
||||||
|
priv->enabled = FALSE;
|
||||||
|
surface = meta_wayland_pointer_constraint_get_surface (constraint);
|
||||||
|
g_signal_handlers_disconnect_by_func (surface, surface_geometry_changed,
|
||||||
|
confinement);
|
||||||
|
|
||||||
|
window = meta_wayland_surface_get_window (surface);
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (window, window_position_changed,
|
||||||
|
confinement);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_backend_set_client_pointer_constraint (meta_get_backend (), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -728,11 +158,110 @@ meta_pointer_confinement_wayland_init (MetaPointerConfinementWayland *confinemen
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_confinement_wayland_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
MetaPointerConfinementWayland *confinement;
|
||||||
|
MetaPointerConfinementWaylandPrivate *priv;
|
||||||
|
|
||||||
|
confinement = META_POINTER_CONFINEMENT_WAYLAND (object);
|
||||||
|
priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_WAYLAND_POINTER_CONSTRAINT:
|
||||||
|
g_value_set_object (value, priv->constraint);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_pointer_confinement_wayland_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
MetaPointerConfinementWayland *confinement;
|
||||||
|
MetaPointerConfinementWaylandPrivate *priv;
|
||||||
|
|
||||||
|
confinement = META_POINTER_CONFINEMENT_WAYLAND (object);
|
||||||
|
priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_WAYLAND_POINTER_CONSTRAINT:
|
||||||
|
priv->constraint = g_value_get_object (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MetaPointerConstraint *
|
||||||
|
meta_pointer_confinement_wayland_create_constraint (MetaPointerConfinementWayland *confinement)
|
||||||
|
{
|
||||||
|
MetaPointerConfinementWaylandPrivate *priv;
|
||||||
|
MetaPointerConstraint *constraint;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
cairo_region_t *region;
|
||||||
|
float dx, dy;
|
||||||
|
|
||||||
|
priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
|
||||||
|
|
||||||
|
surface = meta_wayland_pointer_constraint_get_surface (priv->constraint);
|
||||||
|
region =
|
||||||
|
meta_wayland_pointer_constraint_calculate_effective_region (priv->constraint);
|
||||||
|
|
||||||
|
meta_wayland_surface_get_absolute_coordinates (surface, 0, 0, &dx, &dy);
|
||||||
|
cairo_region_translate (region, dx, dy);
|
||||||
|
|
||||||
|
constraint = meta_pointer_constraint_new (region);
|
||||||
|
cairo_region_destroy (region);
|
||||||
|
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_pointer_confinement_wayland_class_init (MetaPointerConfinementWaylandClass *klass)
|
meta_pointer_confinement_wayland_class_init (MetaPointerConfinementWaylandClass *klass)
|
||||||
{
|
{
|
||||||
MetaPointerConstraintClass *pointer_constraint_class =
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
META_POINTER_CONSTRAINT_CLASS (klass);
|
|
||||||
|
|
||||||
pointer_constraint_class->constrain = meta_pointer_confinement_wayland_constrain;
|
object_class->set_property = meta_pointer_confinement_wayland_set_property;
|
||||||
|
object_class->get_property = meta_pointer_confinement_wayland_get_property;
|
||||||
|
|
||||||
|
klass->create_constraint = meta_pointer_confinement_wayland_create_constraint;
|
||||||
|
|
||||||
|
props[PROP_WAYLAND_POINTER_CONSTRAINT] =
|
||||||
|
g_param_spec_object ("wayland-pointer-constraint",
|
||||||
|
"Wayland pointer constraint",
|
||||||
|
"Wayland pointer constraint",
|
||||||
|
META_TYPE_WAYLAND_POINTER_CONSTRAINT,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaPointerConfinementWayland *
|
||||||
|
meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint)
|
||||||
|
{
|
||||||
|
return g_object_new (META_TYPE_POINTER_CONFINEMENT_WAYLAND,
|
||||||
|
"wayland-pointer-constraint", constraint,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandPointerConstraint *
|
||||||
|
meta_pointer_confinement_wayland_get_wayland_pointer_constraint (MetaPointerConfinementWayland *confinement)
|
||||||
|
{
|
||||||
|
MetaPointerConfinementWaylandPrivate *priv;
|
||||||
|
|
||||||
|
priv = meta_pointer_confinement_wayland_get_instance_private (confinement);
|
||||||
|
return priv->constraint;
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,23 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define META_TYPE_POINTER_CONFINEMENT_WAYLAND (meta_pointer_confinement_wayland_get_type ())
|
#define META_TYPE_POINTER_CONFINEMENT_WAYLAND (meta_pointer_confinement_wayland_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaPointerConfinementWayland,
|
G_DECLARE_DERIVABLE_TYPE (MetaPointerConfinementWayland,
|
||||||
meta_pointer_confinement_wayland,
|
meta_pointer_confinement_wayland,
|
||||||
META, POINTER_CONFINEMENT_WAYLAND,
|
META, POINTER_CONFINEMENT_WAYLAND,
|
||||||
MetaPointerConstraint);
|
GObject)
|
||||||
|
|
||||||
MetaPointerConstraint *meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint);
|
struct _MetaPointerConfinementWaylandClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
MetaPointerConstraint * (*create_constraint) (MetaPointerConfinementWayland *confinement);
|
||||||
|
};
|
||||||
|
|
||||||
|
MetaPointerConfinementWayland *meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint);
|
||||||
|
MetaWaylandPointerConstraint *
|
||||||
|
meta_pointer_confinement_wayland_get_wayland_pointer_constraint (MetaPointerConfinementWayland *confinement);
|
||||||
|
void meta_pointer_confinement_wayland_enable (MetaPointerConfinementWayland *confinement);
|
||||||
|
void meta_pointer_confinement_wayland_disable (MetaPointerConfinementWayland *confinement);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -37,33 +37,55 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include "backends/meta-pointer-constraint.h"
|
#include "backends/meta-backend-private.h"
|
||||||
|
#include "compositor/meta-surface-actor-wayland.h"
|
||||||
|
|
||||||
struct _MetaPointerLockWayland
|
struct _MetaPointerLockWayland
|
||||||
{
|
{
|
||||||
MetaPointerConstraint parent;
|
GObject parent;
|
||||||
|
MetaWaylandPointerConstraint *constraint;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland,
|
G_DEFINE_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland,
|
||||||
META_TYPE_POINTER_CONSTRAINT);
|
META_TYPE_POINTER_CONFINEMENT_WAYLAND)
|
||||||
|
|
||||||
static void
|
static MetaPointerConstraint *
|
||||||
meta_pointer_lock_wayland_constrain (MetaPointerConstraint *constraint,
|
meta_pointer_lock_wayland_create_constraint (MetaPointerConfinementWayland *confinement)
|
||||||
ClutterInputDevice *device,
|
|
||||||
guint32 time,
|
|
||||||
float prev_x,
|
|
||||||
float prev_y,
|
|
||||||
float *x,
|
|
||||||
float *y)
|
|
||||||
{
|
{
|
||||||
*x = prev_x;
|
MetaBackend *backend = meta_get_backend ();
|
||||||
*y = prev_y;
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
||||||
|
ClutterInputDevice *pointer = clutter_seat_get_pointer (seat);
|
||||||
|
MetaWaylandPointerConstraint *wayland_constraint;
|
||||||
|
MetaPointerConstraint *constraint;
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
graphene_point_t point;
|
||||||
|
cairo_region_t *region;
|
||||||
|
float sx, sy, x, y;
|
||||||
|
|
||||||
|
clutter_input_device_get_coords (pointer, NULL, &point);
|
||||||
|
wayland_constraint =
|
||||||
|
meta_pointer_confinement_wayland_get_wayland_pointer_constraint (confinement);
|
||||||
|
surface = meta_wayland_pointer_constraint_get_surface (wayland_constraint);
|
||||||
|
meta_wayland_surface_get_relative_coordinates (surface,
|
||||||
|
point.x, point.y,
|
||||||
|
&sx, &sy);
|
||||||
|
|
||||||
|
meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y);
|
||||||
|
region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { (int) x, (int) y, 1 , 1 });
|
||||||
|
|
||||||
|
constraint = meta_pointer_constraint_new (region);
|
||||||
|
cairo_region_destroy (region);
|
||||||
|
|
||||||
|
return constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaPointerConstraint *
|
MetaPointerConfinementWayland *
|
||||||
meta_pointer_lock_wayland_new (void)
|
meta_pointer_lock_wayland_new (MetaWaylandPointerConstraint *constraint)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_POINTER_LOCK_WAYLAND, NULL);
|
return g_object_new (META_TYPE_POINTER_LOCK_WAYLAND,
|
||||||
|
"wayland-pointer-constraint", constraint,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -74,8 +96,9 @@ meta_pointer_lock_wayland_init (MetaPointerLockWayland *lock_wayland)
|
|||||||
static void
|
static void
|
||||||
meta_pointer_lock_wayland_class_init (MetaPointerLockWaylandClass *klass)
|
meta_pointer_lock_wayland_class_init (MetaPointerLockWaylandClass *klass)
|
||||||
{
|
{
|
||||||
MetaPointerConstraintClass *pointer_constraint_class =
|
MetaPointerConfinementWaylandClass *confinement_class =
|
||||||
META_POINTER_CONSTRAINT_CLASS (klass);
|
META_POINTER_CONFINEMENT_WAYLAND_CLASS (klass);
|
||||||
|
|
||||||
pointer_constraint_class->constrain = meta_pointer_lock_wayland_constrain;
|
confinement_class->create_constraint =
|
||||||
|
meta_pointer_lock_wayland_create_constraint;
|
||||||
}
|
}
|
||||||
|
@ -27,15 +27,15 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include "backends/meta-pointer-constraint.h"
|
#include "wayland/meta-pointer-confinement-wayland.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define META_TYPE_POINTER_LOCK_WAYLAND (meta_pointer_lock_wayland_get_type ())
|
#define META_TYPE_POINTER_LOCK_WAYLAND (meta_pointer_lock_wayland_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland,
|
G_DECLARE_FINAL_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland,
|
||||||
META, POINTER_LOCK_WAYLAND, MetaPointerConstraint);
|
META, POINTER_LOCK_WAYLAND, MetaPointerConfinementWayland)
|
||||||
|
|
||||||
MetaPointerConstraint *meta_pointer_lock_wayland_new (void);
|
MetaPointerConfinementWayland *meta_pointer_lock_wayland_new (MetaWaylandPointerConstraint *constraint);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
|
cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||||
|
float best_scale,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
MetaWaylandCursorSurface *cursor_surface)
|
MetaWaylandCursorSurface *cursor_surface)
|
||||||
@ -186,6 +187,7 @@ meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
|
|||||||
META_WAYLAND_CURSOR_SURFACE (surface->role);
|
META_WAYLAND_CURSOR_SURFACE (surface->role);
|
||||||
MetaWaylandCursorSurfacePrivate *priv =
|
MetaWaylandCursorSurfacePrivate *priv =
|
||||||
meta_wayland_cursor_surface_get_instance_private (cursor_surface);
|
meta_wayland_cursor_surface_get_instance_private (cursor_surface);
|
||||||
|
ClutterInputDevice *device;
|
||||||
graphene_point_t point;
|
graphene_point_t point;
|
||||||
graphene_rect_t logical_monitor_rect;
|
graphene_rect_t logical_monitor_rect;
|
||||||
|
|
||||||
@ -195,7 +197,8 @@ meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
|
|||||||
logical_monitor_rect =
|
logical_monitor_rect =
|
||||||
meta_rectangle_to_graphene_rect (&logical_monitor->rect);
|
meta_rectangle_to_graphene_rect (&logical_monitor->rect);
|
||||||
|
|
||||||
point = meta_cursor_renderer_get_position (priv->cursor_renderer);
|
device = meta_cursor_renderer_get_input_device (priv->cursor_renderer);
|
||||||
|
clutter_input_device_get_coords (device, NULL, &point);
|
||||||
|
|
||||||
return graphene_rect_contains_point (&logical_monitor_rect, &point);
|
return graphene_rect_contains_point (&logical_monitor_rect, &point);
|
||||||
}
|
}
|
||||||
|
@ -74,16 +74,15 @@ static MetaLogicalMonitor *
|
|||||||
dnd_surface_find_logical_monitor (MetaWaylandActorSurface *actor_surface)
|
dnd_surface_find_logical_monitor (MetaWaylandActorSurface *actor_surface)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorTracker *cursor_tracker =
|
||||||
meta_backend_get_cursor_renderer (backend);
|
meta_backend_get_cursor_tracker (backend);
|
||||||
MetaMonitorManager *monitor_manager =
|
MetaMonitorManager *monitor_manager =
|
||||||
meta_backend_get_monitor_manager (backend);
|
meta_backend_get_monitor_manager (backend);
|
||||||
graphene_point_t pointer_pos;
|
graphene_point_t point;
|
||||||
|
|
||||||
pointer_pos = meta_cursor_renderer_get_position (cursor_renderer);
|
meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
|
||||||
return meta_monitor_manager_get_logical_monitor_at (monitor_manager,
|
return meta_monitor_manager_get_logical_monitor_at (monitor_manager,
|
||||||
pointer_pos.x,
|
point.x, point.y);
|
||||||
pointer_pos.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
|
@ -68,7 +68,7 @@ struct _MetaWaylandPointerConstraint
|
|||||||
wl_fixed_t x_hint;
|
wl_fixed_t x_hint;
|
||||||
wl_fixed_t y_hint;
|
wl_fixed_t y_hint;
|
||||||
|
|
||||||
MetaPointerConstraint *constraint;
|
MetaPointerConfinementWayland *confinement;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _MetaWaylandSurfacePointerConstraintsData
|
typedef struct _MetaWaylandSurfacePointerConstraintsData
|
||||||
@ -375,7 +375,7 @@ meta_wayland_pointer_constraint_notify_deactivated (MetaWaylandPointerConstraint
|
|||||||
zwp_confined_pointer_v1_send_unconfined (resource);
|
zwp_confined_pointer_v1_send_unconfined (resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaPointerConstraint *
|
static MetaPointerConfinementWayland *
|
||||||
meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerConstraint *constraint)
|
meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerConstraint *constraint)
|
||||||
{
|
{
|
||||||
struct wl_resource *resource = constraint->resource;
|
struct wl_resource *resource = constraint->resource;
|
||||||
@ -384,7 +384,7 @@ meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerCon
|
|||||||
&zwp_locked_pointer_v1_interface,
|
&zwp_locked_pointer_v1_interface,
|
||||||
&locked_pointer_interface))
|
&locked_pointer_interface))
|
||||||
{
|
{
|
||||||
return meta_pointer_lock_wayland_new ();
|
return meta_pointer_lock_wayland_new (constraint);
|
||||||
}
|
}
|
||||||
else if (wl_resource_instance_of (resource,
|
else if (wl_resource_instance_of (resource,
|
||||||
&zwp_confined_pointer_v1_interface,
|
&zwp_confined_pointer_v1_interface,
|
||||||
@ -399,8 +399,6 @@ meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerCon
|
|||||||
static void
|
static void
|
||||||
meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint)
|
meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
|
|
||||||
g_assert (!constraint->is_enabled);
|
g_assert (!constraint->is_enabled);
|
||||||
|
|
||||||
constraint->is_enabled = TRUE;
|
constraint->is_enabled = TRUE;
|
||||||
@ -408,20 +406,25 @@ meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint
|
|||||||
meta_wayland_pointer_start_grab (constraint->seat->pointer,
|
meta_wayland_pointer_start_grab (constraint->seat->pointer,
|
||||||
&constraint->grab);
|
&constraint->grab);
|
||||||
|
|
||||||
constraint->constraint =
|
constraint->confinement =
|
||||||
meta_wayland_pointer_constraint_create_pointer_constraint (constraint);
|
meta_wayland_pointer_constraint_create_pointer_constraint (constraint);
|
||||||
meta_backend_set_client_pointer_constraint (backend, constraint->constraint);
|
meta_pointer_confinement_wayland_enable (constraint->confinement);
|
||||||
g_object_add_weak_pointer (G_OBJECT (constraint->constraint),
|
g_object_add_weak_pointer (G_OBJECT (constraint->confinement),
|
||||||
(gpointer *) &constraint->constraint);
|
(gpointer *) &constraint->confinement);
|
||||||
g_object_unref (constraint->constraint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constraint)
|
meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constraint)
|
||||||
{
|
{
|
||||||
constraint->is_enabled = FALSE;
|
constraint->is_enabled = FALSE;
|
||||||
|
|
||||||
|
if (constraint->confinement)
|
||||||
|
{
|
||||||
|
meta_pointer_confinement_wayland_disable (constraint->confinement);
|
||||||
|
g_object_unref (constraint->confinement);
|
||||||
|
}
|
||||||
|
|
||||||
meta_wayland_pointer_constraint_notify_deactivated (constraint);
|
meta_wayland_pointer_constraint_notify_deactivated (constraint);
|
||||||
meta_backend_set_client_pointer_constraint (meta_get_backend (), NULL);
|
|
||||||
meta_wayland_pointer_end_grab (constraint->grab.pointer);
|
meta_wayland_pointer_end_grab (constraint->grab.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1044,7 +1044,11 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
|||||||
void
|
void
|
||||||
meta_wayland_pointer_repick (MetaWaylandPointer *pointer)
|
meta_wayland_pointer_repick (MetaWaylandPointer *pointer)
|
||||||
{
|
{
|
||||||
clutter_input_device_update (pointer->device, NULL, FALSE);
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||||
|
|
||||||
|
clutter_input_device_update (pointer->device, NULL, stage, FALSE,
|
||||||
|
CLUTTER_CURRENT_TIME);
|
||||||
repick_for_event (pointer, NULL);
|
repick_for_event (pointer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1164,8 +1168,13 @@ pointer_set_cursor (struct wl_client *client,
|
|||||||
|
|
||||||
if (surface)
|
if (surface)
|
||||||
{
|
{
|
||||||
|
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||||
|
ClutterSeat *clutter_seat =
|
||||||
|
clutter_backend_get_default_seat (clutter_backend);
|
||||||
|
ClutterInputDevice *device = clutter_seat_get_pointer (clutter_seat);
|
||||||
MetaCursorRenderer *cursor_renderer =
|
MetaCursorRenderer *cursor_renderer =
|
||||||
meta_backend_get_cursor_renderer (meta_get_backend ());
|
meta_backend_get_cursor_renderer_for_device (meta_get_backend (),
|
||||||
|
device);
|
||||||
MetaWaylandCursorSurface *cursor_surface;
|
MetaWaylandCursorSurface *cursor_surface;
|
||||||
|
|
||||||
cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role);
|
cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role);
|
||||||
|
@ -242,30 +242,3 @@ meta_wayland_tablet_manager_ensure_seat (MetaWaylandTabletManager *manager,
|
|||||||
|
|
||||||
return tablet_seat;
|
return tablet_seat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
meta_wayland_tablet_manager_update_cursor_position (MetaWaylandTabletManager *manager,
|
|
||||||
const ClutterEvent *event)
|
|
||||||
{
|
|
||||||
MetaWaylandTabletSeat *tablet_seat = NULL;
|
|
||||||
MetaWaylandTabletTool *tool = NULL;
|
|
||||||
ClutterInputDeviceTool *device_tool;
|
|
||||||
ClutterInputDevice *device;
|
|
||||||
|
|
||||||
device = clutter_event_get_source_device (event);
|
|
||||||
device_tool = clutter_event_get_device_tool (event);
|
|
||||||
|
|
||||||
if (device)
|
|
||||||
tablet_seat = meta_wayland_tablet_manager_lookup_seat (manager, device);
|
|
||||||
|
|
||||||
if (tablet_seat && device_tool)
|
|
||||||
tool = meta_wayland_tablet_seat_lookup_tool (tablet_seat, device_tool);
|
|
||||||
|
|
||||||
if (tool)
|
|
||||||
{
|
|
||||||
gfloat new_x, new_y;
|
|
||||||
|
|
||||||
clutter_event_get_coords (event, &new_x, &new_y);
|
|
||||||
meta_wayland_tablet_tool_set_cursor_position (tool, new_x, new_y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -50,7 +50,4 @@ MetaWaylandTabletSeat *
|
|||||||
meta_wayland_tablet_manager_ensure_seat (MetaWaylandTabletManager *manager,
|
meta_wayland_tablet_manager_ensure_seat (MetaWaylandTabletManager *manager,
|
||||||
MetaWaylandSeat *seat);
|
MetaWaylandSeat *seat);
|
||||||
|
|
||||||
void meta_wayland_tablet_manager_update_cursor_position (MetaWaylandTabletManager *manager,
|
|
||||||
const ClutterEvent *event);
|
|
||||||
|
|
||||||
#endif /* META_WAYLAND_TABLET_MANAGER_H */
|
#endif /* META_WAYLAND_TABLET_MANAGER_H */
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
|
|
||||||
#include "backends/meta-input-settings-private.h"
|
#include "backends/meta-input-settings-private.h"
|
||||||
|
#include "core/display-private.h"
|
||||||
#include "compositor/meta-surface-actor-wayland.h"
|
#include "compositor/meta-surface-actor-wayland.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#include "wayland/meta-wayland-tablet-pad-group.h"
|
#include "wayland/meta-wayland-tablet-pad-group.h"
|
||||||
@ -244,15 +245,14 @@ tablet_pad_set_feedback (struct wl_client *client,
|
|||||||
{
|
{
|
||||||
MetaWaylandTabletPad *pad = wl_resource_get_user_data (resource);
|
MetaWaylandTabletPad *pad = wl_resource_get_user_data (resource);
|
||||||
MetaWaylandTabletPadGroup *group = tablet_pad_lookup_button_group (pad, button);
|
MetaWaylandTabletPadGroup *group = tablet_pad_lookup_button_group (pad, button);
|
||||||
MetaInputSettings *input_settings;
|
MetaPadActionMapper *mapper;
|
||||||
|
|
||||||
if (!group || group->mode_switch_serial != serial)
|
if (!group || group->mode_switch_serial != serial)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
mapper = meta_get_display ()->pad_action_mapper;
|
||||||
|
|
||||||
if (input_settings &&
|
if (meta_pad_action_mapper_is_button_grabbed (mapper, pad->device, button))
|
||||||
meta_input_settings_is_pad_button_grabbed (input_settings, pad->device, button))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (meta_wayland_tablet_pad_group_is_mode_switch_button (group, button))
|
if (meta_wayland_tablet_pad_group_is_mode_switch_button (group, button))
|
||||||
@ -367,15 +367,14 @@ static gboolean
|
|||||||
meta_wayland_tablet_pad_handle_event_action (MetaWaylandTabletPad *pad,
|
meta_wayland_tablet_pad_handle_event_action (MetaWaylandTabletPad *pad,
|
||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
MetaInputSettings *input_settings;
|
MetaPadActionMapper *mapper;
|
||||||
ClutterInputDevice *device;
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
device = clutter_event_get_source_device (event);
|
device = clutter_event_get_source_device (event);
|
||||||
input_settings = meta_backend_get_input_settings (meta_get_backend ());
|
mapper = meta_get_display ()->pad_action_mapper;
|
||||||
|
|
||||||
if (input_settings &&
|
if (meta_pad_action_mapper_is_button_grabbed (mapper, device,
|
||||||
meta_input_settings_is_pad_button_grabbed (input_settings, device,
|
event->pad_button.button))
|
||||||
event->pad_button.button))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -395,6 +395,7 @@ tablet_tool_handle_cursor_surface_destroy (struct wl_listener *listener,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
|
tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
|
||||||
|
float best_scale,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
MetaWaylandTabletTool *tool)
|
MetaWaylandTabletTool *tool)
|
||||||
@ -931,7 +932,14 @@ meta_wayland_tablet_tool_update (MetaWaylandTabletTool *tool,
|
|||||||
break;
|
break;
|
||||||
case CLUTTER_PROXIMITY_IN:
|
case CLUTTER_PROXIMITY_IN:
|
||||||
if (!tool->cursor_renderer)
|
if (!tool->cursor_renderer)
|
||||||
tool->cursor_renderer = meta_cursor_renderer_new (meta_get_backend ());
|
{
|
||||||
|
MetaCursorRenderer *renderer;
|
||||||
|
|
||||||
|
renderer =
|
||||||
|
meta_backend_get_cursor_renderer_for_device (meta_get_backend (),
|
||||||
|
clutter_event_get_source_device (event));
|
||||||
|
g_set_object (&tool->cursor_renderer, renderer);
|
||||||
|
}
|
||||||
tool->current_tablet =
|
tool->current_tablet =
|
||||||
meta_wayland_tablet_seat_lookup_tablet (tool->seat,
|
meta_wayland_tablet_seat_lookup_tablet (tool->seat,
|
||||||
clutter_event_get_source_device (event));
|
clutter_event_get_source_device (event));
|
||||||
@ -976,15 +984,6 @@ meta_wayland_tablet_tool_handle_event (MetaWaylandTabletTool *tool,
|
|||||||
return CLUTTER_EVENT_STOP;
|
return CLUTTER_EVENT_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *tool,
|
|
||||||
float new_x,
|
|
||||||
float new_y)
|
|
||||||
{
|
|
||||||
if (tool->cursor_renderer)
|
|
||||||
meta_cursor_renderer_set_position (tool->cursor_renderer, new_x, new_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
||||||
MetaWaylandSurface *surface)
|
MetaWaylandSurface *surface)
|
||||||
|
@ -78,10 +78,6 @@ void meta_wayland_tablet_tool_update (MetaWaylandTabletTool *t
|
|||||||
gboolean meta_wayland_tablet_tool_handle_event (MetaWaylandTabletTool *tool,
|
gboolean meta_wayland_tablet_tool_handle_event (MetaWaylandTabletTool *tool,
|
||||||
const ClutterEvent *event);
|
const ClutterEvent *event);
|
||||||
|
|
||||||
void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *tool,
|
|
||||||
float new_x,
|
|
||||||
float new_y);
|
|
||||||
|
|
||||||
gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
|
||||||
MetaWaylandSurface *surface,
|
MetaWaylandSurface *surface,
|
||||||
uint32_t serial);
|
uint32_t serial);
|
||||||
|
@ -401,35 +401,34 @@ touch_send_frame_event (MetaWaylandTouch *touch)
|
|||||||
g_list_free (surfaces);
|
g_list_free (surfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
check_send_frame_event (MetaWaylandTouch *touch,
|
queue_frame_event_cb (MetaWaylandTouch *touch)
|
||||||
const ClutterEvent *event)
|
|
||||||
{
|
{
|
||||||
gboolean send_frame_event;
|
touch_send_frame_event (touch);
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
touch->queued_frame_id = 0;
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
ClutterEventSequence *sequence;
|
|
||||||
gint32 slot;
|
|
||||||
|
|
||||||
if (META_IS_BACKEND_NATIVE (backend))
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_or_queue_frame_event (MetaWaylandTouch *touch)
|
||||||
|
{
|
||||||
|
if (clutter_events_pending ())
|
||||||
{
|
{
|
||||||
sequence = clutter_event_get_event_sequence (event);
|
if (!touch->queued_frame_id)
|
||||||
slot = meta_event_native_sequence_get_slot (sequence);
|
{
|
||||||
touch->frame_slots &= ~(1 << slot);
|
touch->queued_frame_id =
|
||||||
|
g_idle_add_full (CLUTTER_PRIORITY_EVENTS + 1,
|
||||||
if (touch->frame_slots == 0)
|
(GSourceFunc) queue_frame_event_cb,
|
||||||
send_frame_event = TRUE;
|
touch, NULL);
|
||||||
else
|
}
|
||||||
send_frame_event = FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* HAVE_NATIVE_BACKEND */
|
|
||||||
{
|
{
|
||||||
send_frame_event = TRUE;
|
/* There's no more events */
|
||||||
|
g_clear_handle_id (&touch->queued_frame_id, g_source_remove);
|
||||||
|
touch_send_frame_event (touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send_frame_event)
|
|
||||||
touch_send_frame_event (touch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -450,11 +449,15 @@ meta_wayland_touch_handle_event (MetaWaylandTouch *touch,
|
|||||||
handle_touch_end (touch, event);
|
handle_touch_end (touch, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_TOUCH_CANCEL:
|
||||||
|
meta_wayland_touch_cancel (touch);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_send_frame_event (touch, event);
|
send_or_queue_frame_event (touch);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,45 +514,6 @@ meta_wayland_touch_cancel (MetaWaylandTouch *touch)
|
|||||||
g_list_free (surfaces);
|
g_list_free (surfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
|
||||||
static gboolean
|
|
||||||
evdev_filter_func (struct libinput_event *event,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
MetaWaylandTouch *touch = data;
|
|
||||||
|
|
||||||
switch (libinput_event_get_type (event))
|
|
||||||
{
|
|
||||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
|
||||||
case LIBINPUT_EVENT_TOUCH_UP:
|
|
||||||
case LIBINPUT_EVENT_TOUCH_MOTION: {
|
|
||||||
struct libinput_event_touch *touch_event;
|
|
||||||
int32_t slot;
|
|
||||||
|
|
||||||
touch_event = libinput_event_get_touch_event (event);
|
|
||||||
slot = libinput_event_touch_get_slot (touch_event);
|
|
||||||
|
|
||||||
/* XXX: Could theoretically overflow, 64 slots should be
|
|
||||||
* enough for most hw/usecases though.
|
|
||||||
*/
|
|
||||||
touch->frame_slots |= (1 << slot);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
|
||||||
/* Clutter translates this into individual CLUTTER_TOUCH_CANCEL events,
|
|
||||||
* which are not so useful when sending a global signal as the protocol
|
|
||||||
* requires.
|
|
||||||
*/
|
|
||||||
meta_wayland_touch_cancel (touch);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CLUTTER_EVENT_PROPAGATE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_touch_enable (MetaWaylandTouch *touch)
|
meta_wayland_touch_enable (MetaWaylandTouch *touch)
|
||||||
{
|
{
|
||||||
@ -561,35 +525,11 @@ meta_wayland_touch_enable (MetaWaylandTouch *touch)
|
|||||||
#endif /* HAVE_NATIVE_BACKEND */
|
#endif /* HAVE_NATIVE_BACKEND */
|
||||||
|
|
||||||
wl_list_init (&touch->resource_list);
|
wl_list_init (&touch->resource_list);
|
||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
if (META_IS_BACKEND_NATIVE (backend))
|
|
||||||
{
|
|
||||||
ClutterBackend *backend = clutter_get_default_backend ();
|
|
||||||
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
|
|
||||||
|
|
||||||
meta_seat_native_add_filter (META_SEAT_NATIVE (seat),
|
|
||||||
evdev_filter_func, touch, NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_touch_disable (MetaWaylandTouch *touch)
|
meta_wayland_touch_disable (MetaWaylandTouch *touch)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
if (META_IS_BACKEND_NATIVE (backend))
|
|
||||||
{
|
|
||||||
ClutterBackend *backend = clutter_get_default_backend ();
|
|
||||||
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
|
|
||||||
|
|
||||||
meta_seat_native_remove_filter (META_SEAT_NATIVE (seat),
|
|
||||||
evdev_filter_func, touch);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
meta_wayland_touch_cancel (touch);
|
meta_wayland_touch_cancel (touch);
|
||||||
|
|
||||||
g_clear_pointer (&touch->touch_surfaces, g_hash_table_unref);
|
g_clear_pointer (&touch->touch_surfaces, g_hash_table_unref);
|
||||||
|
@ -41,10 +41,9 @@ struct _MetaWaylandTouch
|
|||||||
|
|
||||||
struct wl_list resource_list;
|
struct wl_list resource_list;
|
||||||
|
|
||||||
|
guint queued_frame_id;
|
||||||
GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */
|
GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */
|
||||||
GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */
|
GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */
|
||||||
|
|
||||||
guint64 frame_slots;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_wayland_touch_enable (MetaWaylandTouch *touch);
|
void meta_wayland_touch_enable (MetaWaylandTouch *touch);
|
||||||
|
@ -2802,7 +2802,7 @@ query_pressed_buttons (MetaWindow *window)
|
|||||||
ClutterModifierType mods;
|
ClutterModifierType mods;
|
||||||
int button = 0;
|
int button = 0;
|
||||||
|
|
||||||
meta_cursor_tracker_get_pointer (tracker, NULL, NULL, &mods);
|
meta_cursor_tracker_get_pointer (tracker, NULL, &mods);
|
||||||
|
|
||||||
if (mods & CLUTTER_BUTTON1_MASK)
|
if (mods & CLUTTER_BUTTON1_MASK)
|
||||||
button |= 1 << 1;
|
button |= 1 << 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user