Merge lp:~dandrader/geis/lp1045785 into lp:geis
- lp1045785
- Merge into trunk
Proposed by
Daniel d'Andrada
Status: | Merged |
---|---|
Merged at revision: | 283 |
Proposed branch: | lp:~dandrader/geis/lp1045785 |
Merge into: | lp:geis |
Diff against target: |
1186 lines (+617/-177) 16 files modified
libgeis/backend/dbus/geis_dbus_backend.c (+6/-0) libgeis/backend/grail/geis_grail_backend.c (+263/-132) libgeis/backend/grail/geis_grail_backend.h (+7/-0) libgeis/backend/grail/geis_grail_token.c (+10/-0) libgeis/backend/grail/geis_ugsubscription_store.c (+50/-37) libgeis/backend/grail/geis_ugsubscription_store.h (+22/-4) libgeis/backend/test_fixture/geis_backend_test_fixture.c (+7/-0) libgeis/geis_backend_protected.h (+1/-0) libgeis/geis_backend_token.c (+9/-1) libgeis/geis_backend_token.h (+11/-0) libgeis/geis_subscription.c (+15/-2) testsuite/geis2/Makefile.am (+1/-0) testsuite/geis2/gtest_gbe_configure_new_devices.cpp (+201/-0) testsuite/geis2/gtest_grail_backend.cpp (+3/-0) testsuite/geis2/gtest_grail_backend.h (+3/-1) testsuite/x11_mocks/x11_mocks.c (+8/-0) |
To merge this branch: | bzr merge lp:~dandrader/geis/lp1045785 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas (community) | Approve | ||
Review via email:
|
Commit message
Description of the change
Fixes bug 1045785.
Improved handling of gesture configuration options for GeisSubscriptions
- You can now call geis_subscripti
- configuration options remain valid for devices that become available *after* the subscription is configured.
Also a number of memory leaks were plugged along the way.
To post a comment you must log in.
lp:~dandrader/geis/lp1045785
updated
- 289. By Daniel d'Andrada
-
Fix comments in tests
* Remove the "actual outcome" from the test description. It doesn't make sense
to have it there and it's also no longer the actual outcome.* Correct comment on the drag threshold
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'libgeis/backend/dbus/geis_dbus_backend.c' | |||
2 | --- libgeis/backend/dbus/geis_dbus_backend.c 2012-07-24 16:04:12 +0000 | |||
3 | +++ libgeis/backend/dbus/geis_dbus_backend.c 2012-09-05 18:11:18 +0000 | |||
4 | @@ -156,6 +156,11 @@ | |||
5 | 156 | return GEIS_STATUS_UNKNOWN_ERROR; | 156 | return GEIS_STATUS_UNKNOWN_ERROR; |
6 | 157 | } | 157 | } |
7 | 158 | 158 | ||
8 | 159 | static void | ||
9 | 160 | _geis_dbus_token_free_subscription_pdata(GeisBackendToken token GEIS_UNUSED, | ||
10 | 161 | GeisSubscription subscription GEIS_UNUSED) | ||
11 | 162 | { | ||
12 | 163 | } | ||
13 | 159 | 164 | ||
14 | 160 | static struct GeisBackendTokenVtable _token_vtbl = { | 165 | static struct GeisBackendTokenVtable _token_vtbl = { |
15 | 161 | _geis_dbus_token_clone, | 166 | _geis_dbus_token_clone, |
16 | @@ -163,6 +168,7 @@ | |||
17 | 163 | _geis_dbus_token_compose, | 168 | _geis_dbus_token_compose, |
18 | 164 | _geis_dbus_token_activate, | 169 | _geis_dbus_token_activate, |
19 | 165 | _geis_dbus_token_deactivate, | 170 | _geis_dbus_token_deactivate, |
20 | 171 | _geis_dbus_token_free_subscription_pdata | ||
21 | 166 | }; | 172 | }; |
22 | 167 | 173 | ||
23 | 168 | 174 | ||
24 | 169 | 175 | ||
25 | === modified file 'libgeis/backend/grail/geis_grail_backend.c' | |||
26 | --- libgeis/backend/grail/geis_grail_backend.c 2012-08-27 21:58:31 +0000 | |||
27 | +++ libgeis/backend/grail/geis_grail_backend.c 2012-09-05 18:11:18 +0000 | |||
28 | @@ -106,29 +106,27 @@ | |||
29 | 106 | GeisBoolean send_synchronous_events; | 106 | GeisBoolean send_synchronous_events; |
30 | 107 | }; | 107 | }; |
31 | 108 | 108 | ||
32 | 109 | |||
33 | 110 | /** | 109 | /** |
36 | 111 | * A table of supported grail cofiguration properties and their GEIS | 110 | Holds backend-specific information regarding a GeisSubscription |
35 | 112 | * equivalents. | ||
37 | 113 | */ | 111 | */ |
39 | 114 | static const struct GeisGrailConfigProperties | 112 | struct GeisGrailSubscriptionData |
40 | 115 | { | 113 | { |
54 | 116 | GeisString geis_config_name; | 114 | GeisUGSubscriptionStore ugstore; |
55 | 117 | GeisAttrType geis_value_type; | 115 | |
56 | 118 | UGSubscriptionProperty grail_property_name; | 116 | /* configuration options |
57 | 119 | } _grail_be_config_properties[] = { | 117 | NULL if not set by user, in which case grail defaults are used */ |
58 | 120 | { GEIS_CONFIG_DRAG_TIMEOUT, GEIS_ATTR_TYPE_INTEGER, UGSubscriptionPropertyDragTimeout }, | 118 | uint64_t *drag_timeout; |
59 | 121 | { GEIS_CONFIG_DRAG_THRESHOLD, GEIS_ATTR_TYPE_FLOAT, UGSubscriptionPropertyDragThreshold }, | 119 | float *drag_threshold; |
60 | 122 | { GEIS_CONFIG_PINCH_TIMEOUT, GEIS_ATTR_TYPE_INTEGER, UGSubscriptionPropertyPinchTimeout }, | 120 | uint64_t *pinch_timeout; |
61 | 123 | { GEIS_CONFIG_PINCH_THRESHOLD, GEIS_ATTR_TYPE_FLOAT, UGSubscriptionPropertyPinchThreshold }, | 121 | float *pinch_threshold; |
62 | 124 | { GEIS_CONFIG_ROTATE_TIMEOUT, GEIS_ATTR_TYPE_INTEGER, UGSubscriptionPropertyRotateTimeout }, | 122 | uint64_t *rotate_timeout; |
63 | 125 | { GEIS_CONFIG_ROTATE_THRESHOLD, GEIS_ATTR_TYPE_FLOAT, UGSubscriptionPropertyRotateThreshold }, | 123 | float *rotate_threshold; |
64 | 126 | { GEIS_CONFIG_TAP_TIMEOUT, GEIS_ATTR_TYPE_INTEGER, UGSubscriptionPropertyTapTimeout }, | 124 | uint64_t *tap_timeout; |
65 | 127 | { GEIS_CONFIG_TAP_THRESHOLD, GEIS_ATTR_TYPE_FLOAT, UGSubscriptionPropertyTapThreshold }, | 125 | float *tap_threshold; |
53 | 128 | { NULL, 0, 0 } | ||
66 | 129 | }; | 126 | }; |
67 | 130 | 127 | ||
68 | 131 | 128 | ||
69 | 129 | |||
70 | 132 | static GeisStatus | 130 | static GeisStatus |
71 | 133 | _grail_be_activate_for_device(GeisGrailBackend gbe, | 131 | _grail_be_activate_for_device(GeisGrailBackend gbe, |
72 | 134 | GeisFilter filter, | 132 | GeisFilter filter, |
73 | @@ -839,7 +837,8 @@ | |||
74 | 839 | it != geis_subscription_bag_end(gbe->subscription_bag); | 837 | it != geis_subscription_bag_end(gbe->subscription_bag); |
75 | 840 | it = geis_subscription_bag_iterator_next(gbe->subscription_bag, it)) | 838 | it = geis_subscription_bag_iterator_next(gbe->subscription_bag, it)) |
76 | 841 | { | 839 | { |
78 | 842 | GeisUGSubscriptionStore ugstore = geis_subscription_pdata(*it); | 840 | struct GeisGrailSubscriptionData *subscription_data = geis_subscription_pdata(*it); |
79 | 841 | GeisUGSubscriptionStore ugstore = subscription_data->ugstore; | ||
80 | 843 | for (GeisFilterIterator fit = geis_subscription_filter_begin(*it); | 842 | for (GeisFilterIterator fit = geis_subscription_filter_begin(*it); |
81 | 844 | fit != geis_subscription_filter_end(*it); | 843 | fit != geis_subscription_filter_end(*it); |
82 | 845 | fit = geis_subscription_filter_next(*it, fit)) | 844 | fit = geis_subscription_filter_next(*it, fit)) |
83 | @@ -1702,12 +1701,11 @@ | |||
84 | 1702 | * subscriptions have the same property value setting. | 1701 | * subscriptions have the same property value setting. |
85 | 1703 | */ | 1702 | */ |
86 | 1704 | static GeisStatus | 1703 | static GeisStatus |
88 | 1705 | _grail_be_get_ugsub_property(GeisSubscription geis_subscription, | 1704 | _grail_be_get_ugsub_property(GeisUGSubscriptionStore ugstore, |
89 | 1706 | UGSubscriptionProperty grail_property, | 1705 | UGSubscriptionProperty grail_property, |
90 | 1707 | GeisPointer grail_value) | 1706 | GeisPointer grail_value) |
91 | 1708 | { | 1707 | { |
92 | 1709 | GeisStatus retval = GEIS_STATUS_UNKNOWN_ERROR; | 1708 | GeisStatus retval = GEIS_STATUS_UNKNOWN_ERROR; |
93 | 1710 | GeisUGSubscriptionStore ugstore = geis_subscription_pdata(geis_subscription); | ||
94 | 1711 | if (ugstore) | 1709 | if (ugstore) |
95 | 1712 | { | 1710 | { |
96 | 1713 | for (GeisSize i = 0; i < geis_ugsubscription_count(ugstore); ++i) | 1711 | for (GeisSize i = 0; i < geis_ugsubscription_count(ugstore); ++i) |
97 | @@ -1731,29 +1729,65 @@ | |||
98 | 1731 | * Sets a given grail property to a specified value. | 1729 | * Sets a given grail property to a specified value. |
99 | 1732 | */ | 1730 | */ |
100 | 1733 | static GeisStatus | 1731 | static GeisStatus |
102 | 1734 | _grail_be_set_ugsub_property(GeisSubscription geis_subscription, | 1732 | _grail_be_set_ugsub_property(GeisUGSubscriptionStore ugstore, |
103 | 1735 | UGSubscriptionProperty grail_property, | 1733 | UGSubscriptionProperty grail_property, |
104 | 1736 | GeisPointer grail_value) | 1734 | GeisPointer grail_value) |
105 | 1737 | { | 1735 | { |
109 | 1738 | GeisStatus retval = GEIS_STATUS_UNKNOWN_ERROR; | 1736 | /* OBS: it's still a success if there's no grail subscription */ |
110 | 1739 | GeisUGSubscriptionStore ugstore = geis_subscription_pdata(geis_subscription); | 1737 | GeisStatus retval = GEIS_STATUS_SUCCESS; |
111 | 1740 | if (ugstore) | 1738 | for (GeisSize i = 0; i < geis_ugsubscription_count(ugstore); ++i) |
112 | 1741 | { | 1739 | { |
123 | 1742 | for (GeisSize i = 0; i < geis_ugsubscription_count(ugstore); ++i) | 1740 | UGSubscription ugsub = geis_ugsubscription_get_ugsubscription_at(ugstore, |
124 | 1743 | { | 1741 | i); |
125 | 1744 | UGSubscription ugsub = geis_ugsubscription_get_ugsubscription_at(ugstore, | 1742 | if (UGStatusSuccess == grail_subscription_set_property(ugsub, |
126 | 1745 | i); | 1743 | grail_property, |
127 | 1746 | if (UGStatusSuccess == grail_subscription_set_property(ugsub, | 1744 | grail_value)) |
128 | 1747 | grail_property, | 1745 | { |
129 | 1748 | grail_value)) | 1746 | retval = GEIS_STATUS_SUCCESS; |
130 | 1749 | { | 1747 | } |
131 | 1750 | retval = GEIS_STATUS_SUCCESS; | 1748 | else |
132 | 1751 | } | 1749 | { |
133 | 1750 | retval = GEIS_STATUS_UNKNOWN_ERROR; | ||
134 | 1752 | } | 1751 | } |
135 | 1753 | } | 1752 | } |
136 | 1754 | return retval; | 1753 | return retval; |
137 | 1755 | } | 1754 | } |
138 | 1756 | 1755 | ||
139 | 1756 | static GeisStatus | ||
140 | 1757 | _grail_be_get_integer_configuration(GeisUGSubscriptionStore ugstore, | ||
141 | 1758 | uint64_t *prop, | ||
142 | 1759 | UGSubscriptionProperty grail_prop, | ||
143 | 1760 | GeisPointer geis_value) | ||
144 | 1761 | { | ||
145 | 1762 | if (prop) | ||
146 | 1763 | { | ||
147 | 1764 | *((GeisInteger*)geis_value) = *prop; | ||
148 | 1765 | return GEIS_STATUS_SUCCESS; | ||
149 | 1766 | } | ||
150 | 1767 | else | ||
151 | 1768 | { | ||
152 | 1769 | return _grail_be_get_ugsub_property(ugstore, grail_prop, geis_value); | ||
153 | 1770 | } | ||
154 | 1771 | |||
155 | 1772 | } | ||
156 | 1773 | |||
157 | 1774 | static GeisStatus | ||
158 | 1775 | _grail_be_get_float_configuration(GeisUGSubscriptionStore ugstore, | ||
159 | 1776 | float *prop, | ||
160 | 1777 | UGSubscriptionProperty grail_prop, | ||
161 | 1778 | GeisPointer geis_value) | ||
162 | 1779 | { | ||
163 | 1780 | if (prop) | ||
164 | 1781 | { | ||
165 | 1782 | *((GeisFloat*)geis_value) = *prop; | ||
166 | 1783 | return GEIS_STATUS_SUCCESS; | ||
167 | 1784 | } | ||
168 | 1785 | else | ||
169 | 1786 | { | ||
170 | 1787 | return _grail_be_get_ugsub_property(ugstore, grail_prop, geis_value); | ||
171 | 1788 | } | ||
172 | 1789 | |||
173 | 1790 | } | ||
174 | 1757 | 1791 | ||
175 | 1758 | /* | 1792 | /* |
176 | 1759 | * Dispatches the get-configuration call. | 1793 | * Dispatches the get-configuration call. |
177 | @@ -1765,42 +1799,75 @@ | |||
178 | 1765 | GeisPointer item_value) | 1799 | GeisPointer item_value) |
179 | 1766 | { | 1800 | { |
180 | 1767 | GeisStatus retval = GEIS_STATUS_NOT_SUPPORTED; | 1801 | GeisStatus retval = GEIS_STATUS_NOT_SUPPORTED; |
182 | 1768 | for (int i = 0; _grail_be_config_properties[i].geis_config_name; ++i) | 1802 | |
183 | 1803 | struct GeisGrailSubscriptionData *subscription_data = | ||
184 | 1804 | geis_subscription_pdata(subscription); | ||
185 | 1805 | if (!subscription_data) | ||
186 | 1769 | { | 1806 | { |
217 | 1770 | if (0 == strcmp(item_name, _grail_be_config_properties[i].geis_config_name)) | 1807 | return retval; |
218 | 1771 | { | 1808 | } |
219 | 1772 | switch (_grail_be_config_properties[i].geis_value_type) | 1809 | |
220 | 1773 | { | 1810 | #define GEIS_GRAIL_CHECK_GESTURE_CONFIG(gesture, Gesture, GESTURE) \ |
221 | 1774 | case GEIS_ATTR_TYPE_INTEGER: | 1811 | if (strcmp(item_name, GEIS_CONFIG_##GESTURE##_TIMEOUT) == 0) \ |
222 | 1775 | { | 1812 | { \ |
223 | 1776 | uint64_t value; | 1813 | retval = _grail_be_get_integer_configuration( \ |
224 | 1777 | retval = _grail_be_get_ugsub_property(subscription, | 1814 | subscription_data->ugstore, \ |
225 | 1778 | _grail_be_config_properties[i].grail_property_name, | 1815 | subscription_data->gesture##_timeout, \ |
226 | 1779 | &value); | 1816 | UGSubscriptionProperty##Gesture##Timeout, \ |
227 | 1780 | *(GeisInteger*)item_value = value; | 1817 | item_value); \ |
228 | 1781 | break; | 1818 | } \ |
229 | 1782 | } | 1819 | else if (strcmp(item_name, GEIS_CONFIG_##GESTURE##_THRESHOLD) == 0) \ |
230 | 1783 | case GEIS_ATTR_TYPE_FLOAT: | 1820 | { \ |
231 | 1784 | { | 1821 | retval = _grail_be_get_float_configuration( \ |
232 | 1785 | float value; | 1822 | subscription_data->ugstore, \ |
233 | 1786 | retval = _grail_be_get_ugsub_property(subscription, | 1823 | subscription_data->gesture##_threshold, \ |
234 | 1787 | _grail_be_config_properties[i].grail_property_name, | 1824 | UGSubscriptionProperty##Gesture##Threshold, \ |
235 | 1788 | &value); | 1825 | item_value); \ |
236 | 1789 | *(GeisFloat*)item_value = value; | 1826 | } |
237 | 1790 | break; | 1827 | |
238 | 1791 | } | 1828 | GEIS_GRAIL_CHECK_GESTURE_CONFIG(drag, Drag, DRAG) |
239 | 1792 | default: | 1829 | else GEIS_GRAIL_CHECK_GESTURE_CONFIG(pinch, Pinch, PINCH) |
240 | 1793 | geis_error("configuration value of unknown type requested"); | 1830 | else GEIS_GRAIL_CHECK_GESTURE_CONFIG(rotate, Rotate, ROTATE) |
241 | 1794 | retval = GEIS_STATUS_UNKNOWN_ERROR; | 1831 | else GEIS_GRAIL_CHECK_GESTURE_CONFIG(tap, Tap, TAP) |
242 | 1795 | break; | 1832 | |
243 | 1796 | } | 1833 | #undef GEIS_GRAIL_CHECK_GESTURE_CONFIG |
214 | 1797 | break; | ||
215 | 1798 | } | ||
216 | 1799 | } | ||
244 | 1800 | 1834 | ||
245 | 1801 | return retval; | 1835 | return retval; |
246 | 1802 | } | 1836 | } |
247 | 1803 | 1837 | ||
248 | 1838 | static GeisStatus | ||
249 | 1839 | _grail_be_set_integer_configuration(GeisUGSubscriptionStore ugstore, | ||
250 | 1840 | uint64_t **prop, | ||
251 | 1841 | UGSubscriptionProperty grail_prop, | ||
252 | 1842 | GeisPointer geis_value) | ||
253 | 1843 | { | ||
254 | 1844 | if (!*prop) | ||
255 | 1845 | *prop = malloc(sizeof(uint64_t)); | ||
256 | 1846 | |||
257 | 1847 | **prop = *((GeisInteger*)geis_value); | ||
258 | 1848 | |||
259 | 1849 | if (ugstore) | ||
260 | 1850 | return _grail_be_set_ugsub_property(ugstore, grail_prop, *prop); | ||
261 | 1851 | else | ||
262 | 1852 | return GEIS_STATUS_SUCCESS; | ||
263 | 1853 | } | ||
264 | 1854 | |||
265 | 1855 | static GeisStatus | ||
266 | 1856 | _grail_be_set_float_configuration(GeisUGSubscriptionStore ugstore, | ||
267 | 1857 | float **prop, | ||
268 | 1858 | UGSubscriptionProperty grail_prop, | ||
269 | 1859 | GeisPointer geis_value) | ||
270 | 1860 | { | ||
271 | 1861 | if (!*prop) | ||
272 | 1862 | *prop = malloc(sizeof(float)); | ||
273 | 1863 | |||
274 | 1864 | **prop = *((GeisFloat*)geis_value); | ||
275 | 1865 | |||
276 | 1866 | if (ugstore) | ||
277 | 1867 | return _grail_be_set_ugsub_property(ugstore, grail_prop, *prop); | ||
278 | 1868 | else | ||
279 | 1869 | return GEIS_STATUS_SUCCESS; | ||
280 | 1870 | } | ||
281 | 1804 | 1871 | ||
282 | 1805 | /* | 1872 | /* |
283 | 1806 | * Dispatches the set-configuration call. | 1873 | * Dispatches the set-configuration call. |
284 | @@ -1813,41 +1880,42 @@ | |||
285 | 1813 | { | 1880 | { |
286 | 1814 | GeisStatus retval = GEIS_STATUS_NOT_SUPPORTED; | 1881 | GeisStatus retval = GEIS_STATUS_NOT_SUPPORTED; |
287 | 1815 | 1882 | ||
289 | 1816 | for (int i = 0; _grail_be_config_properties[i].geis_config_name; ++i) | 1883 | struct GeisGrailSubscriptionData *subscription_data = |
290 | 1884 | geis_subscription_pdata(subscription); | ||
291 | 1885 | if (!subscription_data) | ||
292 | 1817 | { | 1886 | { |
321 | 1818 | if (0 == strcmp(item_name, _grail_be_config_properties[i].geis_config_name)) | 1887 | subscription_data = calloc(1, sizeof(struct GeisGrailSubscriptionData)); |
322 | 1819 | { | 1888 | geis_subscription_set_pdata(subscription, subscription_data); |
323 | 1820 | switch (_grail_be_config_properties[i].geis_value_type) | 1889 | } |
324 | 1821 | { | 1890 | |
325 | 1822 | case GEIS_ATTR_TYPE_INTEGER: | 1891 | #define GEIS_GRAIL_CHECK_GESTURE_CONFIG(gesture, Gesture, GESTURE) \ |
326 | 1823 | { | 1892 | if (strcmp(item_name, GEIS_CONFIG_##GESTURE##_TIMEOUT) == 0) \ |
327 | 1824 | uint64_t value = *(GeisInteger *)item_value; | 1893 | { \ |
328 | 1825 | retval = _grail_be_set_ugsub_property(subscription, | 1894 | retval = _grail_be_set_integer_configuration( \ |
329 | 1826 | _grail_be_config_properties[i].grail_property_name, | 1895 | subscription_data->ugstore, \ |
330 | 1827 | &value); | 1896 | &(subscription_data->gesture##_timeout), \ |
331 | 1828 | break; | 1897 | UGSubscriptionProperty##Gesture##Timeout, \ |
332 | 1829 | } | 1898 | item_value); \ |
333 | 1830 | case GEIS_ATTR_TYPE_FLOAT: | 1899 | } \ |
334 | 1831 | { | 1900 | else if (strcmp(item_name, GEIS_CONFIG_##GESTURE##_THRESHOLD) == 0) \ |
335 | 1832 | float value = *(GeisFloat *)item_value; | 1901 | { \ |
336 | 1833 | retval = _grail_be_set_ugsub_property(subscription, | 1902 | retval = _grail_be_set_float_configuration( \ |
337 | 1834 | _grail_be_config_properties[i].grail_property_name, | 1903 | subscription_data->ugstore, \ |
338 | 1835 | &value); | 1904 | &(subscription_data->gesture##_threshold), \ |
339 | 1836 | break; | 1905 | UGSubscriptionProperty##Gesture##Threshold, \ |
340 | 1837 | } | 1906 | item_value); \ |
341 | 1838 | default: | 1907 | } |
342 | 1839 | geis_error("configuration value of unknown type requested"); | 1908 | |
343 | 1840 | retval = GEIS_STATUS_UNKNOWN_ERROR; | 1909 | GEIS_GRAIL_CHECK_GESTURE_CONFIG(drag, Drag, DRAG) |
344 | 1841 | break; | 1910 | else GEIS_GRAIL_CHECK_GESTURE_CONFIG(pinch, Pinch, PINCH) |
345 | 1842 | } | 1911 | else GEIS_GRAIL_CHECK_GESTURE_CONFIG(rotate, Rotate, ROTATE) |
346 | 1843 | break; | 1912 | else GEIS_GRAIL_CHECK_GESTURE_CONFIG(tap, Tap, TAP) |
347 | 1844 | } | 1913 | |
348 | 1845 | } | 1914 | #undef GEIS_GRAIL_CHECK_GESTURE_CONFIG |
349 | 1846 | 1915 | ||
350 | 1847 | return retval; | 1916 | return retval; |
351 | 1848 | } | 1917 | } |
352 | 1849 | 1918 | ||
353 | 1850 | |||
354 | 1851 | static struct GeisBackendVtable gbe_vtbl = { | 1919 | static struct GeisBackendVtable gbe_vtbl = { |
355 | 1852 | _geis_grail_backend_construct, | 1920 | _geis_grail_backend_construct, |
356 | 1853 | _geis_grail_backend_finalize, | 1921 | _geis_grail_backend_finalize, |
357 | @@ -1855,10 +1923,9 @@ | |||
358 | 1855 | _grail_be_accept_gesture, | 1923 | _grail_be_accept_gesture, |
359 | 1856 | _grail_be_reject_gesture, | 1924 | _grail_be_reject_gesture, |
360 | 1857 | _grail_be_get_configuration, | 1925 | _grail_be_get_configuration, |
362 | 1858 | _grail_be_set_configuration, | 1926 | _grail_be_set_configuration |
363 | 1859 | }; | 1927 | }; |
364 | 1860 | 1928 | ||
365 | 1861 | |||
366 | 1862 | static GeisStatus | 1929 | static GeisStatus |
367 | 1863 | _geis_grail_filter_gestures(GeisGrailBackend gbe, | 1930 | _geis_grail_filter_gestures(GeisGrailBackend gbe, |
368 | 1864 | GeisFilter filter, | 1931 | GeisFilter filter, |
369 | @@ -2029,6 +2096,45 @@ | |||
370 | 2029 | } | 2096 | } |
371 | 2030 | 2097 | ||
372 | 2031 | 2098 | ||
373 | 2099 | static void | ||
374 | 2100 | _geis_grail_set_ugsubscription_properties(GeisGrailBackend gbe, | ||
375 | 2101 | UGSubscription ugsub, | ||
376 | 2102 | GeisSubscription subscription) | ||
377 | 2103 | { | ||
378 | 2104 | struct GeisGrailSubscriptionData *subscription_data = geis_subscription_pdata(subscription); | ||
379 | 2105 | |||
380 | 2106 | GeisBoolean geis_use_atomic_gestures = GEIS_FALSE; | ||
381 | 2107 | geis_get_configuration(gbe->geis, | ||
382 | 2108 | GEIS_CONFIG_ATOMIC_GESTURES, | ||
383 | 2109 | &geis_use_atomic_gestures); | ||
384 | 2110 | int grail_use_atomic_gestures = (geis_use_atomic_gestures == GEIS_TRUE); | ||
385 | 2111 | grail_subscription_set_property(ugsub, | ||
386 | 2112 | UGSubscriptionPropertyAtomicGestures, | ||
387 | 2113 | &grail_use_atomic_gestures); | ||
388 | 2114 | |||
389 | 2115 | |||
390 | 2116 | #define GEIS_GRAIL_SYNC_GESTURE_PROPERTIES(gesture, Gesture) \ | ||
391 | 2117 | if (subscription_data->gesture##_timeout) \ | ||
392 | 2118 | { \ | ||
393 | 2119 | grail_subscription_set_property(ugsub, \ | ||
394 | 2120 | UGSubscriptionProperty##Gesture##Timeout, \ | ||
395 | 2121 | subscription_data->gesture##_timeout); \ | ||
396 | 2122 | } \ | ||
397 | 2123 | if (subscription_data->gesture##_threshold) \ | ||
398 | 2124 | { \ | ||
399 | 2125 | grail_subscription_set_property(ugsub, \ | ||
400 | 2126 | UGSubscriptionProperty##Gesture##Threshold, \ | ||
401 | 2127 | subscription_data->gesture##_threshold); \ | ||
402 | 2128 | } | ||
403 | 2129 | |||
404 | 2130 | GEIS_GRAIL_SYNC_GESTURE_PROPERTIES(drag, Drag); | ||
405 | 2131 | GEIS_GRAIL_SYNC_GESTURE_PROPERTIES(pinch, Pinch); | ||
406 | 2132 | GEIS_GRAIL_SYNC_GESTURE_PROPERTIES(rotate, Rotate); | ||
407 | 2133 | GEIS_GRAIL_SYNC_GESTURE_PROPERTIES(tap, Tap); | ||
408 | 2134 | |||
409 | 2135 | #undef GEIS_GRAIL_SYNC_GESTURE_PROPERTIES | ||
410 | 2136 | } | ||
411 | 2137 | |||
412 | 2032 | /** | 2138 | /** |
413 | 2033 | * Activates a subscription for a (device, region). | 2139 | * Activates a subscription for a (device, region). |
414 | 2034 | */ | 2140 | */ |
415 | @@ -2042,56 +2148,45 @@ | |||
416 | 2042 | GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; | 2148 | GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; |
417 | 2043 | GeisInteger device_id = geis_device_id(device); | 2149 | GeisInteger device_id = geis_device_id(device); |
418 | 2044 | UFDevice ufdevice = _grail_be_ufdevice_from_device_id(gbe, device_id); | 2150 | UFDevice ufdevice = _grail_be_ufdevice_from_device_id(gbe, device_id); |
420 | 2045 | GeisUGSubscriptionStore ugstore = geis_subscription_pdata(subscription); | 2151 | struct GeisGrailSubscriptionData *subscription_data = geis_subscription_pdata(subscription); |
421 | 2152 | GeisUGSubscriptionStore ugstore = subscription_data->ugstore; | ||
422 | 2046 | UGSubscription ugsub = geis_ugsubscription_get_ugsubscription(ugstore, | 2153 | UGSubscription ugsub = geis_ugsubscription_get_ugsubscription(ugstore, |
423 | 2047 | filter, | 2154 | filter, |
424 | 2048 | ufdevice, | 2155 | ufdevice, |
425 | 2049 | window_id); | 2156 | window_id); |
426 | 2157 | |||
427 | 2158 | if (!ugsub) | ||
428 | 2159 | { | ||
429 | 2160 | ugsub = geis_ugsubscription_create_ugsubscription(ugstore, | ||
430 | 2161 | filter, | ||
431 | 2162 | ufdevice, | ||
432 | 2163 | window_id); | ||
433 | 2164 | _geis_grail_set_ugsubscription_properties(gbe, ugsub, subscription); | ||
434 | 2165 | } | ||
435 | 2166 | |||
436 | 2050 | if (!ugsub) | 2167 | if (!ugsub) |
437 | 2051 | { | 2168 | { |
438 | 2052 | geis_error("can not retrieve UGSubscription for (device, window)"); | 2169 | geis_error("can not retrieve UGSubscription for (device, window)"); |
439 | 2053 | goto final_exit; | 2170 | goto final_exit; |
440 | 2054 | } | 2171 | } |
441 | 2055 | 2172 | ||
442 | 2056 | UGStatus ugstatus = UGStatusErrorGeneric; | ||
443 | 2057 | GeisBoolean geis_use_atomic_gestures = GEIS_FALSE; | ||
444 | 2058 | geis_get_configuration(gbe->geis, | ||
445 | 2059 | GEIS_CONFIG_ATOMIC_GESTURES, | ||
446 | 2060 | &geis_use_atomic_gestures); | ||
447 | 2061 | int grail_use_atomic_gestures = (geis_use_atomic_gestures == GEIS_TRUE); | ||
448 | 2062 | ugstatus = grail_subscription_set_property(ugsub, | ||
449 | 2063 | UGSubscriptionPropertyAtomicGestures, | ||
450 | 2064 | &grail_use_atomic_gestures); | ||
451 | 2065 | |||
452 | 2066 | status = _geis_grail_filter_gestures(gbe, filter, subscription, ugsub); | 2173 | status = _geis_grail_filter_gestures(gbe, filter, subscription, ugsub); |
453 | 2067 | 2174 | ||
454 | 2068 | UGGestureTypeMask ugmask; | ||
455 | 2069 | ugstatus = grail_subscription_get_property(ugsub, | ||
456 | 2070 | UGSubscriptionPropertyMask, | ||
457 | 2071 | &ugmask); | ||
458 | 2072 | if (ugstatus != UGStatusSuccess) | ||
459 | 2073 | { | ||
460 | 2074 | geis_error("failed to get UGSubscription mask"); | ||
461 | 2075 | goto final_exit; | ||
462 | 2076 | } | ||
463 | 2077 | |||
464 | 2078 | if (filter) | 2175 | if (filter) |
465 | 2079 | geis_debug("subscription='%s' filter='%s' device=%d '%s' window=0x%08x " | 2176 | geis_debug("subscription='%s' filter='%s' device=%d '%s' window=0x%08x " |
467 | 2080 | "ugsub=%p atomic=%d", | 2177 | "ugsub=%p", |
468 | 2081 | geis_subscription_name(subscription), | 2178 | geis_subscription_name(subscription), |
469 | 2082 | geis_filter_name(filter), | 2179 | geis_filter_name(filter), |
470 | 2083 | device_id, geis_device_name(device), | 2180 | device_id, geis_device_name(device), |
471 | 2084 | window_id, | 2181 | window_id, |
474 | 2085 | (void *)ugsub, | 2182 | (void *)ugsub); |
473 | 2086 | grail_use_atomic_gestures); | ||
475 | 2087 | else | 2183 | else |
476 | 2088 | geis_debug("subscription='%s' no-filter device=%d '%s' window=0x%08x " | 2184 | geis_debug("subscription='%s' no-filter device=%d '%s' window=0x%08x " |
478 | 2089 | "ugsub=%p atomic=%d", | 2185 | "ugsub=%p", |
479 | 2090 | geis_subscription_name(subscription), | 2186 | geis_subscription_name(subscription), |
480 | 2091 | device_id, geis_device_name(device), | 2187 | device_id, geis_device_name(device), |
481 | 2092 | window_id, | 2188 | window_id, |
484 | 2093 | (void *)ugsub, | 2189 | (void *)ugsub); |
483 | 2094 | grail_use_atomic_gestures); | ||
485 | 2095 | 2190 | ||
486 | 2096 | status = geis_grail_window_grab_store_grab(gbe->window_grabs, window_id); | 2191 | status = geis_grail_window_grab_store_grab(gbe->window_grabs, window_id); |
487 | 2097 | if (status != GEIS_STATUS_SUCCESS) | 2192 | if (status != GEIS_STATUS_SUCCESS) |
488 | @@ -2100,7 +2195,7 @@ | |||
489 | 2100 | goto final_exit; | 2195 | goto final_exit; |
490 | 2101 | } | 2196 | } |
491 | 2102 | 2197 | ||
493 | 2103 | ugstatus = grail_subscription_activate(gbe->grail, ugsub); | 2198 | UGStatus ugstatus = grail_subscription_activate(gbe->grail, ugsub); |
494 | 2104 | if (ugstatus != UGStatusSuccess) | 2199 | if (ugstatus != UGStatusSuccess) |
495 | 2105 | { | 2200 | { |
496 | 2106 | status = GEIS_STATUS_UNKNOWN_ERROR; | 2201 | status = GEIS_STATUS_UNKNOWN_ERROR; |
497 | @@ -2264,16 +2359,22 @@ | |||
498 | 2264 | goto final_exit; | 2359 | goto final_exit; |
499 | 2265 | } | 2360 | } |
500 | 2266 | 2361 | ||
506 | 2267 | GeisUGSubscriptionStore ugstore = geis_subscription_pdata(subscription); | 2362 | struct GeisGrailSubscriptionData *subscription_data = |
507 | 2268 | if (ugstore == NULL) | 2363 | geis_subscription_pdata(subscription); |
508 | 2269 | { | 2364 | if (!subscription_data) |
509 | 2270 | ugstore = geis_ugsubscription_store_new(); | 2365 | { |
510 | 2271 | if (!ugstore) | 2366 | subscription_data = calloc(1, sizeof(struct GeisGrailSubscriptionData)); |
511 | 2367 | geis_subscription_set_pdata(subscription, subscription_data); | ||
512 | 2368 | } | ||
513 | 2369 | |||
514 | 2370 | if (subscription_data->ugstore == NULL) | ||
515 | 2371 | { | ||
516 | 2372 | subscription_data->ugstore = geis_ugsubscription_store_new(); | ||
517 | 2373 | if (!subscription_data->ugstore) | ||
518 | 2272 | { | 2374 | { |
519 | 2273 | geis_error("error creating grail subscription store"); | 2375 | geis_error("error creating grail subscription store"); |
520 | 2274 | goto final_exit; | 2376 | goto final_exit; |
521 | 2275 | } | 2377 | } |
522 | 2276 | geis_subscription_set_pdata(subscription, ugstore); | ||
523 | 2277 | } | 2378 | } |
524 | 2278 | 2379 | ||
525 | 2279 | if (geis_subscription_filter_count(subscription) > 0) | 2380 | if (geis_subscription_filter_count(subscription) > 0) |
526 | @@ -2313,7 +2414,9 @@ | |||
527 | 2313 | goto final_exit; | 2414 | goto final_exit; |
528 | 2314 | } | 2415 | } |
529 | 2315 | 2416 | ||
531 | 2316 | GeisUGSubscriptionStore ugstore = geis_subscription_pdata(subscription); | 2417 | struct GeisGrailSubscriptionData *subscription_data = |
532 | 2418 | geis_subscription_pdata(subscription); | ||
533 | 2419 | GeisUGSubscriptionStore ugstore = subscription_data->ugstore; | ||
534 | 2317 | if (ugstore) | 2420 | if (ugstore) |
535 | 2318 | { | 2421 | { |
536 | 2319 | for (GeisSize i = 0; i < geis_ugsubscription_count(ugstore); ++i) | 2422 | for (GeisSize i = 0; i < geis_ugsubscription_count(ugstore); ++i) |
537 | @@ -2347,6 +2450,34 @@ | |||
538 | 2347 | return status; | 2450 | return status; |
539 | 2348 | } | 2451 | } |
540 | 2349 | 2452 | ||
541 | 2453 | /* | ||
542 | 2454 | Frees the memory allocated for the GEIS subscription private data | ||
543 | 2455 | */ | ||
544 | 2456 | void | ||
545 | 2457 | geis_grail_backend_free_subscription_pdata(GeisGrailBackend gbe GEIS_UNUSED, | ||
546 | 2458 | GeisSubscription subscription) | ||
547 | 2459 | { | ||
548 | 2460 | struct GeisGrailSubscriptionData *subscription_data = | ||
549 | 2461 | geis_subscription_pdata(subscription); | ||
550 | 2462 | if (!subscription_data) | ||
551 | 2463 | return; | ||
552 | 2464 | |||
553 | 2465 | if (subscription_data->ugstore) | ||
554 | 2466 | geis_ugsubscription_delete(subscription_data->ugstore); | ||
555 | 2467 | |||
556 | 2468 | free(subscription_data->drag_timeout); | ||
557 | 2469 | free(subscription_data->drag_threshold); | ||
558 | 2470 | free(subscription_data->pinch_timeout); | ||
559 | 2471 | free(subscription_data->pinch_threshold); | ||
560 | 2472 | free(subscription_data->rotate_timeout); | ||
561 | 2473 | free(subscription_data->rotate_threshold); | ||
562 | 2474 | free(subscription_data->tap_timeout); | ||
563 | 2475 | free(subscription_data->tap_threshold); | ||
564 | 2476 | |||
565 | 2477 | free(subscription_data); | ||
566 | 2478 | |||
567 | 2479 | geis_subscription_set_pdata(subscription, NULL); | ||
568 | 2480 | } | ||
569 | 2350 | 2481 | ||
570 | 2351 | /** | 2482 | /** |
571 | 2352 | * Registers the back end with the GEIS back end registry. | 2483 | * Registers the back end with the GEIS back end registry. |
572 | 2353 | 2484 | ||
573 | === modified file 'libgeis/backend/grail/geis_grail_backend.h' | |||
574 | --- libgeis/backend/grail/geis_grail_backend.h 2012-03-31 16:15:35 +0000 | |||
575 | +++ libgeis/backend/grail/geis_grail_backend.h 2012-09-05 18:11:18 +0000 | |||
576 | @@ -40,4 +40,11 @@ | |||
577 | 40 | geis_grail_backend_deactivate_subscription(GeisGrailBackend gbe, | 40 | geis_grail_backend_deactivate_subscription(GeisGrailBackend gbe, |
578 | 41 | GeisSubscription subscription); | 41 | GeisSubscription subscription); |
579 | 42 | 42 | ||
580 | 43 | /** | ||
581 | 44 | * Frees the memory allocated for the GEIS subscription private data | ||
582 | 45 | */ | ||
583 | 46 | void | ||
584 | 47 | geis_grail_backend_free_subscription_pdata(GeisGrailBackend gbe, | ||
585 | 48 | GeisSubscription subscription); | ||
586 | 49 | |||
587 | 43 | #endif /* GEIS_BACKEND_GRAIL_BACKEND_H_ */ | 50 | #endif /* GEIS_BACKEND_GRAIL_BACKEND_H_ */ |
588 | 44 | 51 | ||
589 | === modified file 'libgeis/backend/grail/geis_grail_token.c' | |||
590 | --- libgeis/backend/grail/geis_grail_token.c 2012-03-31 16:15:35 +0000 | |||
591 | +++ libgeis/backend/grail/geis_grail_token.c 2012-09-05 18:11:18 +0000 | |||
592 | @@ -126,6 +126,15 @@ | |||
593 | 126 | return status; | 126 | return status; |
594 | 127 | } | 127 | } |
595 | 128 | 128 | ||
596 | 129 | /** | ||
597 | 130 | * Frees the memory allocated for the GEIS subscription private data | ||
598 | 131 | */ | ||
599 | 132 | static void | ||
600 | 133 | _geis_grail_token_free_subscription_pdata(GeisBackendToken token, GeisSubscription sub) | ||
601 | 134 | { | ||
602 | 135 | GeisGrailToken gdt = _geis_grail_token_from_geis_token(token); | ||
603 | 136 | geis_grail_backend_free_subscription_pdata(gdt->be, sub); | ||
604 | 137 | } | ||
605 | 129 | 138 | ||
606 | 130 | /** | 139 | /** |
607 | 131 | * Creates Grail-back-end-specific back end token. | 140 | * Creates Grail-back-end-specific back end token. |
608 | @@ -140,6 +149,7 @@ | |||
609 | 140 | _geis_grail_token_compose, | 149 | _geis_grail_token_compose, |
610 | 141 | _geis_grail_token_activate, | 150 | _geis_grail_token_activate, |
611 | 142 | _geis_grail_token_deactivate, | 151 | _geis_grail_token_deactivate, |
612 | 152 | _geis_grail_token_free_subscription_pdata | ||
613 | 143 | }; | 153 | }; |
614 | 144 | 154 | ||
615 | 145 | GeisGrailToken token = _geis_grail_token_allocate(); | 155 | GeisGrailToken token = _geis_grail_token_allocate(); |
616 | 146 | 156 | ||
617 | === modified file 'libgeis/backend/grail/geis_ugsubscription_store.c' | |||
618 | --- libgeis/backend/grail/geis_ugsubscription_store.c 2012-06-21 21:17:25 +0000 | |||
619 | +++ libgeis/backend/grail/geis_ugsubscription_store.c 2012-09-05 18:11:18 +0000 | |||
620 | @@ -59,7 +59,8 @@ | |||
621 | 59 | { | 59 | { |
622 | 60 | for (GeisSize i = 0; i < geis_bag_count(store); ++i) | 60 | for (GeisSize i = 0; i < geis_bag_count(store); ++i) |
623 | 61 | { | 61 | { |
625 | 62 | grail_subscription_delete(*(UGSubscription*)geis_bag_at(store, i)); | 62 | struct GeisUGSubscription * s = (struct GeisUGSubscription *)geis_bag_at(store, i); |
626 | 63 | grail_subscription_delete(s->ugsub); | ||
627 | 63 | } | 64 | } |
628 | 64 | geis_bag_delete(store); | 65 | geis_bag_delete(store); |
629 | 65 | } | 66 | } |
630 | @@ -86,6 +87,53 @@ | |||
631 | 86 | return ((GeisUGSubscription)geis_bag_at(store, index))->ugsub; | 87 | return ((GeisUGSubscription)geis_bag_at(store, index))->ugsub; |
632 | 87 | } | 88 | } |
633 | 88 | 89 | ||
634 | 90 | /* | ||
635 | 91 | * Creates a new UGSubscription and adds it to the store. | ||
636 | 92 | */ | ||
637 | 93 | UGSubscription | ||
638 | 94 | geis_ugsubscription_create_ugsubscription(GeisUGSubscriptionStore store, | ||
639 | 95 | GeisFilter filter, | ||
640 | 96 | UFDevice device, | ||
641 | 97 | GeisInteger region_id) | ||
642 | 98 | { | ||
643 | 99 | UGSubscription ugsub = NULL; | ||
644 | 100 | |||
645 | 101 | UGStatus ugstatus = grail_subscription_new(&ugsub); | ||
646 | 102 | if (ugstatus != UGStatusSuccess) | ||
647 | 103 | { | ||
648 | 104 | geis_error("failed to create grail subscription"); | ||
649 | 105 | goto final_exit; | ||
650 | 106 | } | ||
651 | 107 | |||
652 | 108 | ugstatus = grail_subscription_set_property(ugsub, | ||
653 | 109 | UGSubscriptionPropertyDevice, | ||
654 | 110 | &device); | ||
655 | 111 | if (ugstatus != UGStatusSuccess) | ||
656 | 112 | { | ||
657 | 113 | geis_error("failed to set UGSubscription device property"); | ||
658 | 114 | } | ||
659 | 115 | |||
660 | 116 | UFWindowId window_id = frame_x11_create_window_id(region_id); | ||
661 | 117 | ugstatus = grail_subscription_set_property(ugsub, | ||
662 | 118 | UGSubscriptionPropertyWindow, | ||
663 | 119 | &window_id); | ||
664 | 120 | if (ugstatus != UGStatusSuccess) | ||
665 | 121 | { | ||
666 | 122 | geis_error("failed to set UGSubscription window property"); | ||
667 | 123 | } | ||
668 | 124 | |||
669 | 125 | struct GeisUGSubscription s = { | ||
670 | 126 | .filter = filter, | ||
671 | 127 | .device = device, | ||
672 | 128 | .region_id = region_id, | ||
673 | 129 | .ugsub = ugsub | ||
674 | 130 | }; | ||
675 | 131 | geis_bag_append(store, &s); | ||
676 | 132 | |||
677 | 133 | final_exit: | ||
678 | 134 | return ugsub; | ||
679 | 135 | } | ||
680 | 136 | |||
681 | 89 | 137 | ||
682 | 90 | /* | 138 | /* |
683 | 91 | * Gets a UGSubscription from the store. | 139 | * Gets a UGSubscription from the store. |
684 | @@ -97,6 +145,7 @@ | |||
685 | 97 | GeisInteger region_id) | 145 | GeisInteger region_id) |
686 | 98 | { | 146 | { |
687 | 99 | UGSubscription ugsub = NULL; | 147 | UGSubscription ugsub = NULL; |
688 | 148 | |||
689 | 100 | for (GeisSize i = 0; i < geis_bag_count(store); ++i) | 149 | for (GeisSize i = 0; i < geis_bag_count(store); ++i) |
690 | 101 | { | 150 | { |
691 | 102 | GeisUGSubscription s = (GeisUGSubscription)geis_bag_at(store, i); | 151 | GeisUGSubscription s = (GeisUGSubscription)geis_bag_at(store, i); |
692 | @@ -107,42 +156,6 @@ | |||
693 | 107 | } | 156 | } |
694 | 108 | } | 157 | } |
695 | 109 | 158 | ||
696 | 110 | if (!ugsub) | ||
697 | 111 | { | ||
698 | 112 | UGStatus ugstatus = grail_subscription_new(&ugsub); | ||
699 | 113 | if (ugstatus != UGStatusSuccess) | ||
700 | 114 | { | ||
701 | 115 | geis_error("failed to create grail subscription"); | ||
702 | 116 | goto final_exit; | ||
703 | 117 | } | ||
704 | 118 | |||
705 | 119 | ugstatus = grail_subscription_set_property(ugsub, | ||
706 | 120 | UGSubscriptionPropertyDevice, | ||
707 | 121 | &device); | ||
708 | 122 | if (ugstatus != UGStatusSuccess) | ||
709 | 123 | { | ||
710 | 124 | geis_error("failed to set UGSubscription device property"); | ||
711 | 125 | } | ||
712 | 126 | |||
713 | 127 | UFWindowId window_id = frame_x11_create_window_id(region_id); | ||
714 | 128 | ugstatus = grail_subscription_set_property(ugsub, | ||
715 | 129 | UGSubscriptionPropertyWindow, | ||
716 | 130 | &window_id); | ||
717 | 131 | if (ugstatus != UGStatusSuccess) | ||
718 | 132 | { | ||
719 | 133 | geis_error("failed to set UGSubscription window property"); | ||
720 | 134 | } | ||
721 | 135 | |||
722 | 136 | struct GeisUGSubscription s = { | ||
723 | 137 | .filter = filter, | ||
724 | 138 | .device = device, | ||
725 | 139 | .region_id = region_id, | ||
726 | 140 | .ugsub = ugsub | ||
727 | 141 | }; | ||
728 | 142 | geis_bag_append(store, &s); | ||
729 | 143 | } | ||
730 | 144 | |||
731 | 145 | final_exit: | ||
732 | 146 | return ugsub; | 159 | return ugsub; |
733 | 147 | } | 160 | } |
734 | 148 | 161 | ||
735 | 149 | 162 | ||
736 | === modified file 'libgeis/backend/grail/geis_ugsubscription_store.h' | |||
737 | --- libgeis/backend/grail/geis_ugsubscription_store.h 2012-06-21 21:17:25 +0000 | |||
738 | +++ libgeis/backend/grail/geis_ugsubscription_store.h 2012-09-05 18:11:18 +0000 | |||
739 | @@ -64,8 +64,7 @@ | |||
740 | 64 | * @param[in] store The grail subscription store. | 64 | * @param[in] store The grail subscription store. |
741 | 65 | * @param[in] index Indicates a ugsub. | 65 | * @param[in] index Indicates a ugsub. |
742 | 66 | * | 66 | * |
745 | 67 | * Gets a UGSubscription from the store for the identified device and region. | 67 | * Gets a UGSubscription from the store at the given index. |
744 | 68 | * If no such UGSubscription is available, it creates one first. | ||
746 | 69 | * | 68 | * |
747 | 70 | * @returns a valid UGSubscription or NULL to indicate failure. | 69 | * @returns a valid UGSubscription or NULL to indicate failure. |
748 | 71 | */ | 70 | */ |
749 | @@ -73,6 +72,27 @@ | |||
750 | 73 | geis_ugsubscription_get_ugsubscription_at(GeisUGSubscriptionStore store, | 72 | geis_ugsubscription_get_ugsubscription_at(GeisUGSubscriptionStore store, |
751 | 74 | GeisSize index); | 73 | GeisSize index); |
752 | 75 | 74 | ||
753 | 75 | /* | ||
754 | 76 | * Creates a new UGSubscription and adds it to the store. | ||
755 | 77 | * @param[in] store The grail subscription store. | ||
756 | 78 | * @param[in] filter Identifies a filter. | ||
757 | 79 | * @param[in] device Identifies a device. | ||
758 | 80 | * @param[in] region_id Identifies a region. | ||
759 | 81 | * | ||
760 | 82 | * Creates a new UGSubscription for the identified filter, device, | ||
761 | 83 | * and region. It's added to the store. A separate grail subscription | ||
762 | 84 | * is required for each (filter, device, window) because filters on a | ||
763 | 85 | * geis subscription are ORed, meaning each filter may have a different | ||
764 | 86 | * minimum touch requirement. | ||
765 | 87 | * | ||
766 | 88 | * @returns a valid UGSubscription or NULL to indicate failure. | ||
767 | 89 | */ | ||
768 | 90 | UGSubscription | ||
769 | 91 | geis_ugsubscription_create_ugsubscription(GeisUGSubscriptionStore store, | ||
770 | 92 | GeisFilter filter, | ||
771 | 93 | UFDevice device, | ||
772 | 94 | GeisInteger region_id); | ||
773 | 95 | |||
774 | 76 | /** | 96 | /** |
775 | 77 | * Gets a UGSubscription from the store. | 97 | * Gets a UGSubscription from the store. |
776 | 78 | * @param[in] store The grail subscription store. | 98 | * @param[in] store The grail subscription store. |
777 | @@ -85,8 +105,6 @@ | |||
778 | 85 | * device, window) because filters on a geis subscription are ORed, meaning each | 105 | * device, window) because filters on a geis subscription are ORed, meaning each |
779 | 86 | * filter may have a different minimum touch requirement. | 106 | * filter may have a different minimum touch requirement. |
780 | 87 | * | 107 | * |
781 | 88 | * If no such UGSubscription is available, it creates one first. | ||
782 | 89 | * | ||
783 | 90 | * @returns a valid UGSubscription or NULL to indicate failure. | 108 | * @returns a valid UGSubscription or NULL to indicate failure. |
784 | 91 | */ | 109 | */ |
785 | 92 | UGSubscription | 110 | UGSubscription |
786 | 93 | 111 | ||
787 | === modified file 'libgeis/backend/test_fixture/geis_backend_test_fixture.c' | |||
788 | --- libgeis/backend/test_fixture/geis_backend_test_fixture.c 2012-07-24 16:04:12 +0000 | |||
789 | +++ libgeis/backend/test_fixture/geis_backend_test_fixture.c 2012-09-05 18:11:18 +0000 | |||
790 | @@ -82,6 +82,7 @@ | |||
791 | 82 | static void _token_compose(GeisBackendToken, GeisBackendToken); | 82 | static void _token_compose(GeisBackendToken, GeisBackendToken); |
792 | 83 | static GeisStatus _token_activate(GeisBackendToken, GeisSubscription); | 83 | static GeisStatus _token_activate(GeisBackendToken, GeisSubscription); |
793 | 84 | static GeisStatus _token_deactivate(GeisBackendToken, GeisSubscription); | 84 | static GeisStatus _token_deactivate(GeisBackendToken, GeisSubscription); |
794 | 85 | static void _token_free_subscription_pdata(GeisBackendToken, GeisSubscription); | ||
795 | 85 | 86 | ||
796 | 86 | static struct GeisBackendTokenVtable _token_vtbl = { | 87 | static struct GeisBackendTokenVtable _token_vtbl = { |
797 | 87 | _token_clone, | 88 | _token_clone, |
798 | @@ -89,6 +90,7 @@ | |||
799 | 89 | _token_compose, | 90 | _token_compose, |
800 | 90 | _token_activate, | 91 | _token_activate, |
801 | 91 | _token_deactivate, | 92 | _token_deactivate, |
802 | 93 | _token_free_subscription_pdata | ||
803 | 92 | }; | 94 | }; |
804 | 93 | 95 | ||
805 | 94 | static GeisGestureClass g_poke_class = NULL; | 96 | static GeisGestureClass g_poke_class = NULL; |
806 | @@ -424,6 +426,11 @@ | |||
807 | 424 | return status; | 426 | return status; |
808 | 425 | } | 427 | } |
809 | 426 | 428 | ||
810 | 429 | void | ||
811 | 430 | _token_free_subscription_pdata(GeisBackendToken gbtoken GEIS_UNUSED, | ||
812 | 431 | GeisSubscription subscription GEIS_UNUSED) | ||
813 | 432 | { | ||
814 | 433 | } | ||
815 | 427 | 434 | ||
816 | 428 | __attribute__((constructor)) | 435 | __attribute__((constructor)) |
817 | 429 | static void _register_test_fixture() | 436 | static void _register_test_fixture() |
818 | 430 | 437 | ||
819 | === modified file 'libgeis/geis_backend_protected.h' | |||
820 | --- libgeis/geis_backend_protected.h 2012-04-17 23:43:04 +0000 | |||
821 | +++ libgeis/geis_backend_protected.h 2012-09-05 18:11:18 +0000 | |||
822 | @@ -58,6 +58,7 @@ | |||
823 | 58 | void (* compose)(GeisBackendToken, GeisBackendToken); | 58 | void (* compose)(GeisBackendToken, GeisBackendToken); |
824 | 59 | GeisStatus (* activate)(GeisBackendToken, GeisSubscription); | 59 | GeisStatus (* activate)(GeisBackendToken, GeisSubscription); |
825 | 60 | GeisStatus (* deactivate)(GeisBackendToken, GeisSubscription); | 60 | GeisStatus (* deactivate)(GeisBackendToken, GeisSubscription); |
826 | 61 | void (* free_subscription_pdata)(GeisBackendToken, GeisSubscription); | ||
827 | 61 | } *GeisBackendTokenVtable; | 62 | } *GeisBackendTokenVtable; |
828 | 62 | 63 | ||
829 | 63 | 64 | ||
830 | 64 | 65 | ||
831 | === modified file 'libgeis/geis_backend_token.c' | |||
832 | --- libgeis/geis_backend_token.c 2011-10-17 16:52:22 +0000 | |||
833 | +++ libgeis/geis_backend_token.c 2012-09-05 18:11:18 +0000 | |||
834 | @@ -77,4 +77,12 @@ | |||
835 | 77 | return token->vtbl->deactivate(token, subscription); | 77 | return token->vtbl->deactivate(token, subscription); |
836 | 78 | } | 78 | } |
837 | 79 | 79 | ||
839 | 80 | 80 | /** | |
840 | 81 | * Frees the private data that the backend allocated for a given subscription | ||
841 | 82 | */ | ||
842 | 83 | void | ||
843 | 84 | geis_backend_token_free_subscription_pdata(GeisBackendToken token, | ||
844 | 85 | GeisSubscription subscription) | ||
845 | 86 | { | ||
846 | 87 | token->vtbl->free_subscription_pdata(token, subscription); | ||
847 | 88 | } | ||
848 | 81 | 89 | ||
849 | === modified file 'libgeis/geis_backend_token.h' | |||
850 | --- libgeis/geis_backend_token.h 2011-10-17 16:52:22 +0000 | |||
851 | +++ libgeis/geis_backend_token.h 2012-09-05 18:11:18 +0000 | |||
852 | @@ -101,4 +101,15 @@ | |||
853 | 101 | geis_backend_token_deactivate(GeisBackendToken token, | 101 | geis_backend_token_deactivate(GeisBackendToken token, |
854 | 102 | GeisSubscription subscription); | 102 | GeisSubscription subscription); |
855 | 103 | 103 | ||
856 | 104 | /** | ||
857 | 105 | * Frees the private data that the backend allocated for a given subscription | ||
858 | 106 | * | ||
859 | 107 | * @param[in] token The backend token. | ||
860 | 108 | * @param[in] subscription The subscription that will have its backend private data | ||
861 | 109 | * freed | ||
862 | 110 | */ | ||
863 | 111 | void | ||
864 | 112 | geis_backend_token_free_subscription_pdata(GeisBackendToken token, | ||
865 | 113 | GeisSubscription subscription); | ||
866 | 114 | |||
867 | 104 | #endif /* GEIS_BACKEND_TOKEN_H_ */ | 115 | #endif /* GEIS_BACKEND_TOKEN_H_ */ |
868 | 105 | 116 | ||
869 | === modified file 'libgeis/geis_subscription.c' | |||
870 | --- libgeis/geis_subscription.c 2012-06-21 21:17:25 +0000 | |||
871 | +++ libgeis/geis_subscription.c 2012-09-05 18:11:18 +0000 | |||
872 | @@ -337,8 +337,6 @@ | |||
873 | 337 | if (sub->sub_backend_token) | 337 | if (sub->sub_backend_token) |
874 | 338 | { | 338 | { |
875 | 339 | status = geis_backend_token_deactivate(sub->sub_backend_token, sub); | 339 | status = geis_backend_token_deactivate(sub->sub_backend_token, sub); |
876 | 340 | geis_backend_token_delete(sub->sub_backend_token); | ||
877 | 341 | sub->sub_backend_token = NULL; | ||
878 | 342 | } | 340 | } |
879 | 343 | return status; | 341 | return status; |
880 | 344 | } | 342 | } |
881 | @@ -426,6 +424,14 @@ | |||
882 | 426 | { | 424 | { |
883 | 427 | geis_debug("destroying subscription \"%s\" id %d", sub->sub_name, sub->sub_id); | 425 | geis_debug("destroying subscription \"%s\" id %d", sub->sub_name, sub->sub_id); |
884 | 428 | geis_subscription_deactivate(sub); | 426 | geis_subscription_deactivate(sub); |
885 | 427 | |||
886 | 428 | if (sub->sub_backend_token) | ||
887 | 429 | { | ||
888 | 430 | geis_backend_token_free_subscription_pdata(sub->sub_backend_token, sub); | ||
889 | 431 | geis_backend_token_delete(sub->sub_backend_token); | ||
890 | 432 | sub->sub_backend_token = NULL; | ||
891 | 433 | } | ||
892 | 434 | |||
893 | 429 | if (sub->sub_geis != NULL) | 435 | if (sub->sub_geis != NULL) |
894 | 430 | { | 436 | { |
895 | 431 | geis_unref(sub->sub_geis); | 437 | geis_unref(sub->sub_geis); |
896 | @@ -507,6 +513,13 @@ | |||
897 | 507 | geis_error("error adding filter to subscription"); | 513 | geis_error("error adding filter to subscription"); |
898 | 508 | goto error_exit; | 514 | goto error_exit; |
899 | 509 | } | 515 | } |
900 | 516 | else | ||
901 | 517 | { | ||
902 | 518 | /* since we're taking ownership of the filter, we're removing the initial | ||
903 | 519 | reference that belonged to the API user, created in geis_filter_new(). | ||
904 | 520 | Now the only remaining reference is the one held by our geis_filter_bag */ | ||
905 | 521 | geis_filter_unref(filter); | ||
906 | 522 | } | ||
907 | 510 | 523 | ||
908 | 511 | error_exit: | 524 | error_exit: |
909 | 512 | return status; | 525 | return status; |
910 | 513 | 526 | ||
911 | === modified file 'testsuite/geis2/Makefile.am' | |||
912 | --- testsuite/geis2/Makefile.am 2012-07-24 22:18:36 +0000 | |||
913 | +++ testsuite/geis2/Makefile.am 2012-09-05 18:11:18 +0000 | |||
914 | @@ -48,6 +48,7 @@ | |||
915 | 48 | gtest_geis2_grail_backend_SOURCES = \ | 48 | gtest_geis2_grail_backend_SOURCES = \ |
916 | 49 | gtest_grail_backend.h gtest_grail_backend.cpp \ | 49 | gtest_grail_backend.h gtest_grail_backend.cpp \ |
917 | 50 | gtest_gbe_accept_ended_grail_gesture.cpp \ | 50 | gtest_gbe_accept_ended_grail_gesture.cpp \ |
918 | 51 | gtest_gbe_configure_new_devices.cpp \ | ||
919 | 51 | gtest_gbe_deactivate_sub.cpp \ | 52 | gtest_gbe_deactivate_sub.cpp \ |
920 | 52 | gtest_gbe_direct_touch_coords.cpp \ | 53 | gtest_gbe_direct_touch_coords.cpp \ |
921 | 53 | gtest_gbe_construction_finished.cpp \ | 54 | gtest_gbe_construction_finished.cpp \ |
922 | 54 | 55 | ||
923 | === added file 'testsuite/geis2/gtest_gbe_configure_new_devices.cpp' | |||
924 | --- testsuite/geis2/gtest_gbe_configure_new_devices.cpp 1970-01-01 00:00:00 +0000 | |||
925 | +++ testsuite/geis2/gtest_gbe_configure_new_devices.cpp 2012-09-05 18:11:18 +0000 | |||
926 | @@ -0,0 +1,201 @@ | |||
927 | 1 | #include "gtest_grail_backend.h" | ||
928 | 2 | #include "x11_mocks.h" | ||
929 | 3 | |||
930 | 4 | /* | ||
931 | 5 | Regression test for bug LP#1045785 | ||
932 | 6 | https://bugs.launchpad.net/geis/+bug/1045785 | ||
933 | 7 | |||
934 | 8 | Steps to reproduce the issue: | ||
935 | 9 | 1 - create a subscription, set some configuration options | ||
936 | 10 | (geis_subscription_set_configuration) and activate it. | ||
937 | 11 | 2 - connect a new multitouch device to your computer (e.g. pair an Apple | ||
938 | 12 | Magic Trackpad) | ||
939 | 13 | |||
940 | 14 | Expected outcome: | ||
941 | 15 | Gestures from that new multitouch device follow the configurations set by | ||
942 | 16 | the subscription. | ||
943 | 17 | */ | ||
944 | 18 | |||
945 | 19 | class ConfigureNewDevice : public Geis2GrailBackendBase | ||
946 | 20 | { | ||
947 | 21 | protected: | ||
948 | 22 | ConfigureNewDevice(); | ||
949 | 23 | |||
950 | 24 | virtual void OnEventInitComplete(GeisEvent event); | ||
951 | 25 | virtual void OnEventClassAvailable(GeisEvent event); | ||
952 | 26 | virtual void OnEventGestureBegin(GeisEvent event); | ||
953 | 27 | |||
954 | 28 | void CreateSubscription(); | ||
955 | 29 | void SendXInput2Events(); | ||
956 | 30 | |||
957 | 31 | /* signals that a new device has been added */ | ||
958 | 32 | void SendXIDeviceAddedEvent(); | ||
959 | 33 | |||
960 | 34 | GeisSubscription _subscription; | ||
961 | 35 | GeisGestureClass _drag_class; | ||
962 | 36 | }; | ||
963 | 37 | |||
964 | 38 | ConfigureNewDevice::ConfigureNewDevice() | ||
965 | 39 | : _subscription(nullptr), | ||
966 | 40 | _drag_class(nullptr) | ||
967 | 41 | { | ||
968 | 42 | } | ||
969 | 43 | |||
970 | 44 | void ConfigureNewDevice::OnEventInitComplete(GeisEvent event) | ||
971 | 45 | { | ||
972 | 46 | CreateSubscription(); | ||
973 | 47 | |||
974 | 48 | /* The new device comes only after the subscription has been created and | ||
975 | 49 | configured */ | ||
976 | 50 | CreateXMockTouchScreenDevice(); | ||
977 | 51 | SendXIDeviceAddedEvent(); | ||
978 | 52 | |||
979 | 53 | SendXInput2Events(); | ||
980 | 54 | } | ||
981 | 55 | |||
982 | 56 | void ConfigureNewDevice::OnEventClassAvailable(GeisEvent event) | ||
983 | 57 | { | ||
984 | 58 | GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_CLASS); | ||
985 | 59 | GeisGestureClass gesture_class = | ||
986 | 60 | reinterpret_cast<GeisGestureClass>(geis_attr_value_to_pointer(attr)); | ||
987 | 61 | |||
988 | 62 | if (strcmp(geis_gesture_class_name(gesture_class), GEIS_GESTURE_DRAG) == 0) | ||
989 | 63 | { | ||
990 | 64 | _drag_class = gesture_class; | ||
991 | 65 | geis_gesture_class_ref(gesture_class); | ||
992 | 66 | } | ||
993 | 67 | } | ||
994 | 68 | |||
995 | 69 | void ConfigureNewDevice::OnEventGestureBegin(GeisEvent event) | ||
996 | 70 | { | ||
997 | 71 | /* There should be no drag gesture since we set a huge drag threshold. */ | ||
998 | 72 | |||
999 | 73 | GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_GROUPSET); | ||
1000 | 74 | GeisGroupSet group_set = | ||
1001 | 75 | reinterpret_cast<GeisGroupSet>(geis_attr_value_to_pointer(attr)); | ||
1002 | 76 | GeisGroup group = geis_groupset_group(group_set, 0); | ||
1003 | 77 | GeisFrame frame = geis_group_frame(group, 0); | ||
1004 | 78 | |||
1005 | 79 | ASSERT_NE(nullptr, _drag_class); | ||
1006 | 80 | GeisBoolean is_drag = geis_frame_is_class(frame, _drag_class); | ||
1007 | 81 | ASSERT_FALSE(is_drag); | ||
1008 | 82 | } | ||
1009 | 83 | |||
1010 | 84 | void ConfigureNewDevice::CreateSubscription() | ||
1011 | 85 | { | ||
1012 | 86 | GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; | ||
1013 | 87 | GeisFilter filter = nullptr; | ||
1014 | 88 | |||
1015 | 89 | _subscription = geis_subscription_new(_geis, "2-fingers drag", | ||
1016 | 90 | GEIS_SUBSCRIPTION_NONE); | ||
1017 | 91 | |||
1018 | 92 | filter = geis_filter_new(_geis, "filter"); | ||
1019 | 93 | ASSERT_NE(nullptr, filter); | ||
1020 | 94 | |||
1021 | 95 | status = geis_filter_add_term(filter, | ||
1022 | 96 | GEIS_FILTER_CLASS, | ||
1023 | 97 | GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, GEIS_GESTURE_DRAG, | ||
1024 | 98 | GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, 2, | ||
1025 | 99 | nullptr); | ||
1026 | 100 | ASSERT_EQ(GEIS_STATUS_SUCCESS, status); | ||
1027 | 101 | |||
1028 | 102 | status = geis_filter_add_term(filter, | ||
1029 | 103 | GEIS_FILTER_REGION, | ||
1030 | 104 | GEIS_REGION_ATTRIBUTE_WINDOWID, GEIS_FILTER_OP_EQ, | ||
1031 | 105 | DefaultRootWindow(xmock_display), | ||
1032 | 106 | nullptr); | ||
1033 | 107 | ASSERT_EQ(GEIS_STATUS_SUCCESS, status); | ||
1034 | 108 | |||
1035 | 109 | status = geis_subscription_add_filter(_subscription, filter); | ||
1036 | 110 | ASSERT_EQ(GEIS_STATUS_SUCCESS, status); | ||
1037 | 111 | |||
1038 | 112 | /* Set a huge threshold (in meters) so that no drag can be recognized */ | ||
1039 | 113 | GeisFloat drag_threshold = 1000.0f; | ||
1040 | 114 | status = geis_subscription_set_configuration(_subscription, | ||
1041 | 115 | GEIS_CONFIG_DRAG_THRESHOLD, &drag_threshold); | ||
1042 | 116 | ASSERT_EQ(GEIS_STATUS_SUCCESS, status); | ||
1043 | 117 | |||
1044 | 118 | status = geis_subscription_activate(_subscription); | ||
1045 | 119 | ASSERT_EQ(GEIS_STATUS_SUCCESS, status); | ||
1046 | 120 | } | ||
1047 | 121 | |||
1048 | 122 | void ConfigureNewDevice::SendXInput2Events() | ||
1049 | 123 | { | ||
1050 | 124 | /* Emulate a simple 2 fingers drag */ | ||
1051 | 125 | |||
1052 | 126 | /* event type, touch id, X and Y */ | ||
1053 | 127 | SendTouchEvent(XI_TouchBegin, 1, 10.0f, 10.0f); | ||
1054 | 128 | SendTouchEvent(XI_TouchBegin, 2, 20.0f, 10.0f); | ||
1055 | 129 | |||
1056 | 130 | xmock_server_time += 2; | ||
1057 | 131 | |||
1058 | 132 | /* touch id */ | ||
1059 | 133 | SendTouchOwnershipEvent(1); | ||
1060 | 134 | SendTouchOwnershipEvent(2); | ||
1061 | 135 | |||
1062 | 136 | xmock_server_time += 20; | ||
1063 | 137 | |||
1064 | 138 | SendTouchEvent(XI_TouchUpdate, 1, 10.0f, 25.0f); | ||
1065 | 139 | SendTouchEvent(XI_TouchUpdate, 2, 20.0f, 25.0f); | ||
1066 | 140 | |||
1067 | 141 | xmock_server_time += 20; | ||
1068 | 142 | |||
1069 | 143 | SendTouchEvent(XI_TouchUpdate, 1, 10.0f, 35.0f); | ||
1070 | 144 | SendTouchEvent(XI_TouchUpdate, 2, 20.0f, 35.0f); | ||
1071 | 145 | |||
1072 | 146 | xmock_server_time += 20; | ||
1073 | 147 | |||
1074 | 148 | SendTouchEvent(XI_TouchEnd, 1, 10.0f, 50.0f); | ||
1075 | 149 | SendTouchEvent(XI_TouchEnd, 2, 20.0f, 50.0f); | ||
1076 | 150 | } | ||
1077 | 151 | |||
1078 | 152 | void ConfigureNewDevice::SendXIDeviceAddedEvent() | ||
1079 | 153 | { | ||
1080 | 154 | XEvent event; | ||
1081 | 155 | XGenericEventCookie *xcookie = 0; | ||
1082 | 156 | XIHierarchyEvent *hierarchy_event; | ||
1083 | 157 | XIHierarchyInfo *info; | ||
1084 | 158 | |||
1085 | 159 | info = (XIHierarchyInfo*)calloc(1, sizeof(XIHierarchyInfo)); | ||
1086 | 160 | info->deviceid = xmock_devices[0].deviceid; | ||
1087 | 161 | info->enabled = True; | ||
1088 | 162 | info->flags = XISlaveAdded; | ||
1089 | 163 | |||
1090 | 164 | hierarchy_event = (XIHierarchyEvent*)calloc(1, sizeof(XIHierarchyEvent)); | ||
1091 | 165 | hierarchy_event->type = GenericEvent; | ||
1092 | 166 | hierarchy_event->serial = _xevent_serial_number++; | ||
1093 | 167 | hierarchy_event->display = xmock_display; | ||
1094 | 168 | hierarchy_event->extension = xmock_xi2_opcode; | ||
1095 | 169 | hierarchy_event->evtype = XI_HierarchyChanged; | ||
1096 | 170 | hierarchy_event->time = xmock_server_time; | ||
1097 | 171 | hierarchy_event->flags = XISlaveAdded; | ||
1098 | 172 | hierarchy_event->num_info = 1; | ||
1099 | 173 | hierarchy_event->info = info; | ||
1100 | 174 | |||
1101 | 175 | event.type = GenericEvent; | ||
1102 | 176 | xcookie = &event.xcookie; | ||
1103 | 177 | xcookie->extension = xmock_xi2_opcode; | ||
1104 | 178 | xcookie->evtype = XI_HierarchyChanged; | ||
1105 | 179 | xcookie->data = hierarchy_event; | ||
1106 | 180 | xmock_add_to_event_queue(&event); | ||
1107 | 181 | } | ||
1108 | 182 | |||
1109 | 183 | TEST_F(ConfigureNewDevice, Test) | ||
1110 | 184 | { | ||
1111 | 185 | _geis = geis_new(GEIS_INIT_GRAIL_BACKEND, | ||
1112 | 186 | GEIS_INIT_NO_ATOMIC_GESTURES, | ||
1113 | 187 | nullptr); | ||
1114 | 188 | ASSERT_NE(nullptr, _geis); | ||
1115 | 189 | |||
1116 | 190 | Run(); | ||
1117 | 191 | |||
1118 | 192 | if (_subscription) | ||
1119 | 193 | geis_subscription_delete(_subscription); | ||
1120 | 194 | |||
1121 | 195 | if (_drag_class) | ||
1122 | 196 | geis_gesture_class_unref(_drag_class); | ||
1123 | 197 | |||
1124 | 198 | geis_delete(_geis); | ||
1125 | 199 | |||
1126 | 200 | DestroyXMockDevices(); | ||
1127 | 201 | } | ||
1128 | 0 | 202 | ||
1129 | === modified file 'testsuite/geis2/gtest_grail_backend.cpp' | |||
1130 | --- testsuite/geis2/gtest_grail_backend.cpp 2012-07-05 17:13:06 +0000 | |||
1131 | +++ testsuite/geis2/gtest_grail_backend.cpp 2012-09-05 18:11:18 +0000 | |||
1132 | @@ -168,6 +168,9 @@ | |||
1133 | 168 | case GEIS_EVENT_INIT_COMPLETE: | 168 | case GEIS_EVENT_INIT_COMPLETE: |
1134 | 169 | OnEventInitComplete(event); | 169 | OnEventInitComplete(event); |
1135 | 170 | break; | 170 | break; |
1136 | 171 | case GEIS_EVENT_CLASS_AVAILABLE: | ||
1137 | 172 | OnEventClassAvailable(event); | ||
1138 | 173 | break; | ||
1139 | 171 | case GEIS_EVENT_GESTURE_BEGIN: | 174 | case GEIS_EVENT_GESTURE_BEGIN: |
1140 | 172 | OnEventGestureBegin(event); | 175 | OnEventGestureBegin(event); |
1141 | 173 | break; | 176 | break; |
1142 | 174 | 177 | ||
1143 | === modified file 'testsuite/geis2/gtest_grail_backend.h' | |||
1144 | --- testsuite/geis2/gtest_grail_backend.h 2012-07-05 17:13:06 +0000 | |||
1145 | +++ testsuite/geis2/gtest_grail_backend.h 2012-09-05 18:11:18 +0000 | |||
1146 | @@ -47,6 +47,7 @@ | |||
1147 | 47 | void DestroyXMockDevices(); | 47 | void DestroyXMockDevices(); |
1148 | 48 | 48 | ||
1149 | 49 | virtual void OnEventInitComplete(GeisEvent event) {} | 49 | virtual void OnEventInitComplete(GeisEvent event) {} |
1150 | 50 | virtual void OnEventClassAvailable(GeisEvent event) {} | ||
1151 | 50 | virtual void OnEventGestureBegin(GeisEvent event) {} | 51 | virtual void OnEventGestureBegin(GeisEvent event) {} |
1152 | 51 | virtual void OnEventGestureUpdate(GeisEvent event) {} | 52 | virtual void OnEventGestureUpdate(GeisEvent event) {} |
1153 | 52 | virtual void OnEventGestureEnd(GeisEvent event) {} | 53 | virtual void OnEventGestureEnd(GeisEvent event) {} |
1154 | @@ -59,11 +60,12 @@ | |||
1155 | 59 | void GetGestureTimestampInEvent(GeisInteger *timestamp, GeisEvent event); | 60 | void GetGestureTimestampInEvent(GeisInteger *timestamp, GeisEvent event); |
1156 | 60 | 61 | ||
1157 | 61 | Geis _geis; | 62 | Geis _geis; |
1158 | 62 | private: | ||
1159 | 63 | 63 | ||
1160 | 64 | /* holds the serial number to be used on the next synthetic XEvent */ | 64 | /* holds the serial number to be used on the next synthetic XEvent */ |
1161 | 65 | int _xevent_serial_number; | 65 | int _xevent_serial_number; |
1162 | 66 | 66 | ||
1163 | 67 | private: | ||
1164 | 68 | |||
1165 | 67 | bool DispatchAndProcessEvents(); | 69 | bool DispatchAndProcessEvents(); |
1166 | 68 | 70 | ||
1167 | 69 | void AcceptRejectGestureInEvent(GeisEvent event, bool accept); | 71 | void AcceptRejectGestureInEvent(GeisEvent event, bool accept); |
1168 | 70 | 72 | ||
1169 | === modified file 'testsuite/x11_mocks/x11_mocks.c' | |||
1170 | --- testsuite/x11_mocks/x11_mocks.c 2012-04-25 17:23:11 +0000 | |||
1171 | +++ testsuite/x11_mocks/x11_mocks.c 2012-09-05 18:11:18 +0000 | |||
1172 | @@ -194,6 +194,14 @@ | |||
1173 | 194 | free(device_event->valuators.mask); | 194 | free(device_event->valuators.mask); |
1174 | 195 | free(device_event->valuators.values); | 195 | free(device_event->valuators.values); |
1175 | 196 | } | 196 | } |
1176 | 197 | else if (cookie->evtype == XI_HierarchyChanged) | ||
1177 | 198 | { | ||
1178 | 199 | XIHierarchyEvent *hierarchy_event = (XIHierarchyEvent*) cookie->data; | ||
1179 | 200 | for (int i = 0; i < hierarchy_event->num_info; ++i) | ||
1180 | 201 | { | ||
1181 | 202 | free(&(hierarchy_event->info[i])); | ||
1182 | 203 | } | ||
1183 | 204 | } | ||
1184 | 197 | free(cookie->data); | 205 | free(cookie->data); |
1185 | 198 | } | 206 | } |
1186 | 199 | } | 207 | } |
* It doesn't make much sense to include the current actual outcome in the test description because it will no longer be the actual outcome after the branch is merged :). The test could also fail in other ways in the future.
* Typo in a test comment: "Set a huge threshold (in meters) so that there's no *change* a drag can be"
Everything else looks good to me! This is a great improvement over the current functionality :).