Merge lp:~dandrader/frame/backend into lp:frame

Proposed by Daniel d'Andrada
Status: Merged
Merged at revision: 90
Proposed branch: lp:~dandrader/frame/backend
Merge into: lp:frame
Diff against target: 1092 lines (+817/-28)
13 files modified
include/oif/frame_backend.h (+254/-0)
src/device.cpp (+93/-6)
src/device.h (+7/-1)
src/event.cpp (+37/-0)
src/event.h (+1/-0)
src/frame.cpp (+82/-16)
src/frame.h (+9/-0)
src/libframe.ver (+34/-0)
src/touch.cpp (+80/-0)
src/touch.h (+13/-2)
src/x11/device_x11.cpp (+0/-3)
test/regular/Makefile.am (+1/-0)
test/regular/backend.cpp (+206/-0)
To merge this branch: bzr merge lp:~dandrader/frame/backend
Reviewer Review Type Date Requested Status
Chase Douglas (community) Approve
Review via email: mp+121230@code.launchpad.net

Commit message

Adds a backend API.

So that any client can adapt frame+grail to work on top of their input system, without relying on frame to provide a suitable backend implementation.

This API also removes the need to mock libframe when writing grail tests.

Description of the change

Adds a backend API.

So that any client can adapt frame+grail to work on top of their input system, without relying on frame to provide a suitable backend implementation.

This API also removes the need to mock libframe when writing grail tests.

To post a comment you must log in.
Revision history for this message
Chase Douglas (chasedouglas) wrote :

This is a great start! With a few changes we will hopefully be good to go :).

* The Doxygen comments for functions should have an extra newline between the summary and the extra description. The following function comments should be updated:
  frame_event_set_device()
  frame_device_add_axis()

* I would rather namespace the backend functions so they are clearly distinct from the frontend functions. For example, frame_device_new() should be frame_backend_device_new(), and frame_device_get_frontend() could be frame_backend_device_get_device().

* UFBackendDevice_ isn't an invariant because it is not fully initialized after the constructor returns. The constructor could be UFBackendDevice_(oif::frame::UFDevice* device), where the shared_ptr is initialized with the value of device. Then frame_backend_device_new() could simply be:

UFBackendDevice frame_device_new()
{
  return new UFBackendDevice_(new oif::frame::UFDevice);
}

This holds for UFBackendFrame and UFBackendTouch as well.

* Why can't we infer the number of axes from the number of added axes, rather than by having to manually set the value. The same for number of touches in the frame.

The simple fix would be to get the current value, increment it, then reinsert it into the device or frame when an axis or touch is added. The number of active touches would be set to the same value as the number of touches in the frame. The caller would need to set the total number of active touches *after* all frame touches have been added. A sanity check that the number of active touches is greater than or equal to the number of frame touches would be good.

* I understand how events are created, but how are they enqueued to a frame instance? How are devices added to a frame instance?

review: Needs Fixing
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> * Why can't we infer the number of axes from the number of added axes, rather
> than by having to manually set the value. The same for number of touches in
> the frame.

Because it's inefficient. If you add 10 items you will redefine the counter property 10 times.

It also hides the fact that number_of_foo is just a property that can be set independently from the entities they refer to. Besides, the idea of the backend interface is to enable the user to manually and directly build frame data as they will, to feed grail. No real logic expected here. All responsibility is in the hands of the user. The equivalent of a header defining some structs.

> * I understand how events are created, but how are they enqueued to a frame
> instance? How are devices added to a frame instance?

There's no need for a frame instance if you're using the backend interface. The whole point is that you manually create frame events to feed them to grail (through grail_process_frame_event). In that sense, libframe is reduced to being just a header defining some data containers that grail understands.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> * I would rather namespace the backend functions so they are clearly distinct
> from the frontend functions. For example, frame_device_new() should be
> frame_backend_device_new(), and frame_device_get_frontend() could be
> frame_backend_device_get_device().

Makes all the sense.
I was striving for shorter function names. :)

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Updated according to comments (expect for auto-setting "count" properties)

Revision history for this message
Chase Douglas (chasedouglas) wrote :

* The frame_backend_device_delete() doxygen comment is a bit wonky, since it's one sentence split up for the summary and extended detail. It just needs to be slightly fixed up wording-wise.

* Daniel and I chatted on IRC about fixing up how the number of device axes and number of touches in a frame are calculated and reported. Those will be fixed in this proposal as well.

review: Needs Fixing
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> * The frame_backend_device_delete() doxygen comment is a bit wonky, since it's
> one sentence split up for the summary and extended detail. It just needs to be
> slightly fixed up wording-wise.

Yeah, that was a mistake. Autopilot was on when that happened.

>
> * Daniel and I chatted on IRC about fixing up how the number of device axes
> and number of touches in a frame are calculated and reported. Those will be
> fixed in this proposal as well.

Done.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

* In frame_device_get_property(), the value parameter should be reinterpret_cast'd instead of static_cast'd. The same is true for frame_frame_get_property(). Casts from void* to a concrete pointer should always be reinterpret casted (according to thumper).

* frame_frame_get_property_unsigned_int_() has an erroneously added empty line at the top.

Everything else looks good. I'm approving based on these changes. Great stuff!

review: Approve
lp:~dandrader/frame/backend updated
90. By Daniel d'Andrada

Adds a backend API.

So that any client can adapt frame+grail to work on top of their input system
without relying on frame to provide a suitable backend implementation.

This API also removes the need to mock libframe when writing grail tests.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'include/oif/frame_backend.h'
--- include/oif/frame_backend.h 1970-01-01 00:00:00 +0000
+++ include/oif/frame_backend.h 2012-08-29 18:56:18 +0000
@@ -0,0 +1,254 @@
1/**
2 * @file oif/frame_backend.h
3 * API for creating objects.
4 */
5
6#ifndef FRAME_OIF_FRAME_BACKEND_H_
7#define FRAME_OIF_FRAME_BACKEND_H_
8
9/* front end definitions */
10#include <oif/frame.h>
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
16/** Handle for a device to be used on the backend API */
17typedef struct UFBackendDevice_* UFBackendDevice;
18
19/** Handle for a frame to be used on the backend API */
20typedef struct UFBackendFrame_* UFBackendFrame;
21
22/** Handle for a touch to be used on the backend API */
23typedef struct UFBackendTouch_* UFBackendTouch;
24
25/********************************************************************
26 * Event
27 ********************************************************************/
28
29/**
30 * Creates a new event with a reference count of one.
31 */
32FRAME_PUBLIC
33UFEvent frame_event_new();
34
35/**
36 * Sets the type of the given event
37 */
38FRAME_PUBLIC
39void frame_event_set_type(UFEvent event, UFEventType type);
40
41/**
42 * Sets the device property of the given event
43 *
44 * It increases the reference count of the corresponding UFDevice by one.
45 */
46FRAME_PUBLIC
47void frame_event_set_device(UFEvent event, UFBackendDevice device);
48
49/**
50 * Sets the frame property of the given event
51 *
52 * It increases the reference count of the corresponding UFFrame by one.
53 */
54FRAME_PUBLIC
55void frame_event_set_frame(UFEvent event, UFBackendFrame frame);
56
57/**
58 * Sets the time of the given event
59 */
60FRAME_PUBLIC
61void frame_event_set_time(UFEvent event, uint64_t time);
62
63/********************************************************************
64 * Device
65 ********************************************************************/
66
67/**
68 * Creates a new UFDevice and returns its backend handle.
69 */
70FRAME_PUBLIC
71UFBackendDevice frame_backend_device_new();
72
73/**
74 * Returns a UFDevice instance given its backend handle.
75 */
76FRAME_PUBLIC
77UFDevice frame_backend_device_get_device(UFBackendDevice device);
78
79/**
80 * Sets the "Name" property of the given device
81 */
82FRAME_PUBLIC
83void frame_backend_device_set_name(UFBackendDevice device, const char *name);
84
85/**
86 * Sets the "Direct" property of the given device
87 */
88FRAME_PUBLIC
89void frame_backend_device_set_direct(UFBackendDevice device, int direct);
90
91/**
92 * Sets the "Independent" property of the given device
93 */
94FRAME_PUBLIC
95void frame_backend_device_set_independent(UFBackendDevice device, int independent);
96
97/**
98 * Sets the "SemiMT" property of the given device
99 */
100FRAME_PUBLIC
101void frame_backend_device_set_semi_mt(UFBackendDevice device, int semi_mt);
102
103/**
104 * Sets the "MaxTouches" property of the given device
105 */
106FRAME_PUBLIC
107void frame_backend_device_set_max_touches(UFBackendDevice device, unsigned int max_touches);
108
109/**
110 * Sets the "WindowResolutionX" and "WindowResolutionY" properties of the
111 * given device.
112 */
113FRAME_PUBLIC
114void frame_backend_device_set_window_resolution(UFBackendDevice device, float x, float y);
115
116/**
117 * Adds an axis to the device
118 */
119FRAME_PUBLIC
120void frame_backend_device_add_axis(UFBackendDevice device,
121 UFAxisType type,
122 float min, float max, float resolution);
123
124/**
125 * Deletes the backend handle of a UFDevice, decreasing its reference count by one.
126 */
127FRAME_PUBLIC
128void frame_backend_device_delete(UFBackendDevice device);
129
130/********************************************************************
131 * Frame
132 ********************************************************************/
133
134/**
135 * Creates a new UFFrame and returns its backend handle.
136 */
137FRAME_PUBLIC
138UFBackendFrame frame_backend_frame_new();
139
140/**
141 * Returns a UFFrame instance given its backend handle.
142 */
143FRAME_PUBLIC
144UFFrame frame_backend_frame_get_frame(UFBackendFrame frame);
145
146/**
147 * Sets the "Device" property of the given frame
148 */
149FRAME_PUBLIC
150void frame_backend_frame_set_device(UFBackendFrame frame, UFBackendDevice device);
151
152/**
153 * Sets the "WindowId" property of the given frame
154 */
155FRAME_PUBLIC
156void frame_backend_frame_set_window_id(UFBackendFrame frame, UFWindowId window_id);
157
158/**
159 * Sets the "ActiveTouches" property of the given frame
160 *
161 * If unset this property returns the number of touches.
162 */
163FRAME_PUBLIC
164void frame_backend_frame_set_active_touches(UFBackendFrame frame, unsigned int active_touches);
165
166/**
167 * Adds a UFTouch to the given frame.
168 */
169FRAME_PUBLIC
170void frame_backend_frame_add_touch(UFBackendFrame frame, UFBackendTouch touch);
171
172/**
173 * Deletes the backend handle of a UFFrame,
174 * decreasing its reference count by one.
175 */
176FRAME_PUBLIC
177void frame_backend_frame_delete(UFBackendFrame frame);
178
179/********************************************************************
180 * Touch
181 ********************************************************************/
182
183/**
184 * Creates a new UFTouch and returns its backend handle.
185 */
186FRAME_PUBLIC
187UFBackendTouch frame_backend_touch_new();
188
189/**
190 * Returns a UFTouch instance given its backend handle.
191 */
192FRAME_PUBLIC
193UFTouch frame_backend_touch_get_touch(UFBackendTouch touch);
194
195/**
196 * Sets the "Id" property of the given touch
197 */
198FRAME_PUBLIC
199void frame_backend_touch_set_id(UFBackendTouch touch, UFTouchId id);
200
201/**
202 * Sets the "State" property of the given touch
203 */
204FRAME_PUBLIC
205void frame_backend_touch_set_state(UFBackendTouch touch, UFTouchState state);
206
207/**
208 * Sets the "WindowX" and "WindowY" properties of the given touch
209 */
210FRAME_PUBLIC
211void frame_backend_touch_set_window_pos(UFBackendTouch touch, float x, float y);
212
213/**
214 * Sets the "Time" property of the given touch
215 */
216FRAME_PUBLIC
217void frame_backend_touch_set_time(UFBackendTouch touch, uint64_t time);
218
219/**
220 * Sets the "StartTime" property of the given touch
221 */
222FRAME_PUBLIC
223void frame_backend_touch_set_start_time(UFBackendTouch touch, uint64_t start_time);
224
225/**
226 * Sets the "Owned" property of the given touch
227 */
228FRAME_PUBLIC
229void frame_backend_touch_set_owned(UFBackendTouch touch, int owned);
230
231/**
232 * Sets the "PendingEnd" property of the given touch
233 */
234FRAME_PUBLIC
235void frame_backend_touch_set_pending_end(UFBackendTouch touch, int pending_end);
236
237/**
238 * Sets the value of an axis of the given touch
239 */
240FRAME_PUBLIC
241void frame_backend_touch_set_value(UFBackendTouch touch, UFAxisType type, float value);
242
243/**
244 * Deletes the backend handle of a UFTouch,
245 * decreasing its reference count by one.
246 */
247FRAME_PUBLIC
248void frame_backend_touch_delete(UFBackendTouch touch);
249
250#ifdef __cplusplus
251}
252#endif
253
254#endif /* FRAME_OIF_FRAME_BACKEND_H_ */
0255
=== modified file 'src/device.cpp'
--- src/device.cpp 2012-06-21 19:41:40 +0000
+++ src/device.cpp 2012-08-29 18:56:18 +0000
@@ -24,6 +24,8 @@
2424
25#include "axis.h"25#include "axis.h"
2626
27#include <oif/frame_backend.h>
28
27namespace oif {29namespace oif {
28namespace frame {30namespace frame {
2931
@@ -75,18 +77,30 @@
75UFStatus frame_device_get_property_unsigned_int_(UFDevice device,77UFStatus frame_device_get_property_unsigned_int_(UFDevice device,
76 UFDeviceProperty property,78 UFDeviceProperty property,
77 unsigned int *value) {79 unsigned int *value) {
78 return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(80
79 property,81 if (property == UFDevicePropertyNumAxes) {
80 value);82 *value = static_cast<const oif::frame::UFDevice*>(device)->axes_.size();
83 return UFStatusSuccess;
84 } else {
85 return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(
86 property,
87 value);
88 }
81}89}
8290
83#undef frame_device_get_property /* Override C11 generic selections macro */91#undef frame_device_get_property /* Override C11 generic selections macro */
84FRAME_PUBLIC92FRAME_PUBLIC
85UFStatus frame_device_get_property(UFDevice device, UFDeviceProperty property,93UFStatus frame_device_get_property(UFDevice device, UFDeviceProperty property,
86 void *value) {94 void *value) {
87 return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(95 if (property == UFDevicePropertyNumAxes) {
88 property,96 *reinterpret_cast<unsigned int *>(value) =
89 value);97 static_cast<const oif::frame::UFDevice*>(device)->axes_.size();
98 return UFStatusSuccess;
99 } else {
100 return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(
101 property,
102 value);
103 }
90}104}
91105
92UFStatus frame_device_get_axis_by_index(UFDevice device, unsigned int index,106UFStatus frame_device_get_axis_by_index(UFDevice device, unsigned int index,
@@ -129,4 +143,77 @@
129 return resolution;143 return resolution;
130}144}
131145
146UFBackendDevice frame_backend_device_new()
147{
148 return new UFBackendDevice_(new oif::frame::UFDevice);
149}
150
151UFDevice frame_backend_device_get_device(UFBackendDevice device)
152{
153 return device->shared_ptr.get();
154}
155
156void frame_backend_device_delete(UFBackendDevice device)
157{
158 delete device;
159}
160
161void frame_backend_device_set_name(UFBackendDevice device, const char *name)
162{
163 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
164 InsertProperty(UFDevicePropertyName,
165 new oif::frame::Value(name));
166}
167
168void frame_backend_device_set_direct(UFBackendDevice device, int direct)
169{
170 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
171 InsertProperty(UFDevicePropertyDirect,
172 new oif::frame::Value(direct));
173}
174
175void frame_backend_device_set_independent(UFBackendDevice device, int independent)
176{
177 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
178 InsertProperty(UFDevicePropertyIndependent,
179 new oif::frame::Value(independent));
180}
181
182void frame_backend_device_set_semi_mt(UFBackendDevice device, int semi_mt)
183{
184 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
185 InsertProperty(UFDevicePropertySemiMT,
186 new oif::frame::Value(semi_mt));
187}
188
189void frame_backend_device_set_max_touches(UFBackendDevice device, unsigned int max_touches)
190{
191 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
192 InsertProperty(UFDevicePropertyMaxTouches,
193 new oif::frame::Value(max_touches));
194}
195
196void frame_backend_device_set_window_resolution(UFBackendDevice device, float x, float y)
197{
198 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
199 InsertProperty(UFDevicePropertyWindowResolutionX,
200 new oif::frame::Value(x));
201
202 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
203 InsertProperty(UFDevicePropertyWindowResolutionY,
204 new oif::frame::Value(y));
205}
206
207void frame_backend_device_add_axis(UFBackendDevice device,
208 UFAxisType type,
209 float min, float max, float resolution)
210{
211 using oif::frame::UFAxis;
212
213 UFAxis_* axis = new UFAxis(type, min, max, resolution);
214
215 static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
216 axes_[type] = std::unique_ptr<UFAxis>(static_cast<UFAxis*>(axis));
217}
218
132} // extern "C"219} // extern "C"
133220
=== modified file 'src/device.h'
--- src/device.h 2012-06-21 19:41:40 +0000
+++ src/device.h 2012-08-29 18:56:18 +0000
@@ -32,6 +32,13 @@
32 virtual ~UFDevice_() {};32 virtual ~UFDevice_() {};
33};33};
3434
35struct UFBackendDevice_ {
36 UFBackendDevice_(oif::frame::UFDevice* device)
37 : shared_ptr(device) {}
38
39 oif::frame::SharedUFDevice shared_ptr;
40};
41
35namespace oif {42namespace oif {
36namespace frame {43namespace frame {
3744
@@ -45,7 +52,6 @@
45 UFDevice(const UFDevice&) = delete;52 UFDevice(const UFDevice&) = delete;
46 UFDevice& operator=(const UFDevice&) = delete;53 UFDevice& operator=(const UFDevice&) = delete;
4754
48 protected:
49 typedef std::unique_ptr<UFAxis> UniqueUFAxis;55 typedef std::unique_ptr<UFAxis> UniqueUFAxis;
5056
51 std::map<UFAxisType, UniqueUFAxis> axes_;57 std::map<UFAxisType, UniqueUFAxis> axes_;
5258
=== modified file 'src/event.cpp'
--- src/event.cpp 2012-06-21 19:41:40 +0000
+++ src/event.cpp 2012-08-29 18:56:18 +0000
@@ -22,10 +22,17 @@
2222
23#include "event.h"23#include "event.h"
24#include "frame.h"24#include "frame.h"
25#include "device.h"
26
27#include <oif/frame_backend.h>
2528
26namespace oif {29namespace oif {
27namespace frame {30namespace frame {
2831
32UFEvent::UFEvent()
33 : ref_count_(1) {
34}
35
29UFEvent::UFEvent(UFEventType type, const Value* data, uint64_t time)36UFEvent::UFEvent(UFEventType type, const Value* data, uint64_t time)
30 : ref_count_(1) {37 : ref_count_(1) {
31 const Value* value;38 const Value* value;
@@ -70,6 +77,10 @@
7077
71extern "C" {78extern "C" {
7279
80UFEvent frame_event_new() {
81 return new oif::frame::UFEvent;
82}
83
73void frame_event_ref(UFEvent event) {84void frame_event_ref(UFEvent event) {
74 static_cast<oif::frame::UFEvent*>(event)->Ref();85 static_cast<oif::frame::UFEvent*>(event)->Ref();
75}86}
@@ -140,4 +151,30 @@
140 return time;151 return time;
141}152}
142153
154void frame_event_set_type(UFEvent event, UFEventType type)
155{
156 static_cast<oif::frame::UFEvent*>(event)->
157 InsertProperty(UFEventPropertyType, new oif::frame::Value(type));
158}
159
160void frame_event_set_device(UFEvent event, UFBackendDevice device)
161{
162 static_cast<oif::frame::UFEvent*>(event)->
163 InsertProperty(UFEventPropertyDevice,
164 new oif::frame::Value(device->shared_ptr));
165}
166
167void frame_event_set_frame(UFEvent event, UFBackendFrame frame)
168{
169 static_cast<oif::frame::UFEvent*>(event)->
170 InsertProperty(UFEventPropertyFrame,
171 new oif::frame::Value(frame->shared_ptr));
172}
173
174void frame_event_set_time(UFEvent event, uint64_t time)
175{
176 static_cast<oif::frame::UFEvent*>(event)->
177 InsertProperty(UFEventPropertyTime, new oif::frame::Value(time));
178}
179
143} // extern "C"180} // extern "C"
144181
=== modified file 'src/event.h'
--- src/event.h 2012-06-21 19:41:40 +0000
+++ src/event.h 2012-08-29 18:56:18 +0000
@@ -37,6 +37,7 @@
3737
38class UFEvent : public UFEvent_, public Property<UFEventProperty> {38class UFEvent : public UFEvent_, public Property<UFEventProperty> {
39 public:39 public:
40 UFEvent();
40 UFEvent(UFEventType type, const Value* data, uint64_t time);41 UFEvent(UFEventType type, const Value* data, uint64_t time);
41 ~UFEvent();42 ~UFEvent();
4243
4344
=== modified file 'src/frame.cpp'
--- src/frame.cpp 2012-06-21 19:41:40 +0000
+++ src/frame.cpp 2012-08-29 18:56:18 +0000
@@ -23,9 +23,12 @@
23#include <assert.h>23#include <assert.h>
24#include <stdio.h>24#include <stdio.h>
2525
26#include "device.h"
26#include "touch.h"27#include "touch.h"
27#include "window.h"28#include "window.h"
2829
30#include <oif/frame_backend.h>
31
29namespace oif {32namespace oif {
30namespace frame {33namespace frame {
3134
@@ -93,6 +96,12 @@
9396
94} // namespace97} // namespace
9598
99void UFFrame::AddTouch(const SharedUFTouch& touch)
100{
101 touches_map_[touch->id()] = touches_array_.size();
102 touches_array_.push_back(touch);
103}
104
96void UFFrame::UpdateTouch(const SharedUFTouch& touch) {105void UFFrame::UpdateTouch(const SharedUFTouch& touch) {
97 auto map_it = touches_map_.find(touch->id());106 auto map_it = touches_map_.find(touch->id());
98107
@@ -102,14 +111,7 @@
102 CopyStartTime(touches_array_[map_it->second], touch);111 CopyStartTime(touches_array_[map_it->second], touch);
103 touches_array_[map_it->second] = touch;112 touches_array_[map_it->second] = touch;
104 } else {113 } else {
105 touches_map_[touch->id()] = touches_array_.size();114 AddTouch(touch);
106 touches_array_.push_back(touch);
107
108 const Value *value;
109 value = new Value(static_cast<unsigned int>(touches_map_.size()));
110 InsertProperty(UFFramePropertyNumTouches, value);
111 value = new Value(static_cast<unsigned int>(touches_map_.size()));
112 InsertProperty(UFFramePropertyActiveTouches, value);
113 }115 }
114 break;116 break;
115117
@@ -211,8 +213,21 @@
211 UFFrameProperty property,213 UFFrameProperty property,
212 unsigned int *value) {214 unsigned int *value) {
213 const oif::frame::UFFrame* ufframe =215 const oif::frame::UFFrame* ufframe =
214 static_cast<const oif::frame::UFFrame*>(frame);216 static_cast<const oif::frame::UFFrame*>(frame);
215 return ufframe->GetProperty(property, value);217
218 if (property == UFFramePropertyNumTouches) {
219 *value = ufframe->GetNumTouches();
220 return UFStatusSuccess;
221 } else if (property == UFFramePropertyActiveTouches) {
222 UFStatus status = ufframe->GetProperty(property, value);
223 if (status != UFStatusSuccess) {
224 *value = ufframe->GetNumTouches();
225 status = UFStatusSuccess;
226 }
227 return status;
228 } else {
229 return ufframe->GetProperty(property, value);
230 }
216}231}
217232
218#undef frame_frame_get_property /* Override C11 generic selections macro */233#undef frame_frame_get_property /* Override C11 generic selections macro */
@@ -221,7 +236,20 @@
221 void *value) {236 void *value) {
222 const oif::frame::UFFrame* ufframe =237 const oif::frame::UFFrame* ufframe =
223 static_cast<const oif::frame::UFFrame*>(frame);238 static_cast<const oif::frame::UFFrame*>(frame);
224 return ufframe->GetProperty(property, value);239
240 if (property == UFFramePropertyNumTouches) {
241 *reinterpret_cast<unsigned int *>(value) = ufframe->GetNumTouches();
242 return UFStatusSuccess;
243 } else if (property == UFFramePropertyActiveTouches) {
244 UFStatus status = ufframe->GetProperty(property, value);
245 if (status != UFStatusSuccess) {
246 *reinterpret_cast<unsigned int *>(value) = ufframe->GetNumTouches();
247 status = UFStatusSuccess;
248 }
249 return status;
250 } else {
251 return ufframe->GetProperty(property, value);
252 }
225}253}
226254
227UFStatus frame_frame_get_touch_by_index(UFFrame frame, unsigned int index,255UFStatus frame_frame_get_touch_by_index(UFFrame frame, unsigned int index,
@@ -269,13 +297,9 @@
269}297}
270298
271uint32_t frame_frame_get_num_touches(UFFrame frame) {299uint32_t frame_frame_get_num_touches(UFFrame frame) {
272 unsigned int num_touches;
273 const oif::frame::UFFrame* ufframe =300 const oif::frame::UFFrame* ufframe =
274 static_cast<const oif::frame::UFFrame*>(frame);301 static_cast<const oif::frame::UFFrame*>(frame);
275 UFStatus status = ufframe->GetProperty(UFFramePropertyNumTouches,302 return ufframe->GetNumTouches();
276 &num_touches);
277 assert(status == UFStatusSuccess);
278 return num_touches;
279}303}
280304
281UFDevice frame_frame_get_device(UFFrame frame) {305UFDevice frame_frame_get_device(UFFrame frame) {
@@ -287,4 +311,46 @@
287 return device;311 return device;
288}312}
289313
314UFBackendFrame frame_backend_frame_new()
315{
316 return new UFBackendFrame_(new oif::frame::UFFrame);
317}
318
319UFFrame frame_backend_frame_get_frame(UFBackendFrame frame)
320{
321 return frame->shared_ptr.get();
322}
323
324void frame_backend_frame_set_device(UFBackendFrame frame, UFBackendDevice device)
325{
326 static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
327 InsertProperty(UFFramePropertyDevice,
328 new oif::frame::Value(device->shared_ptr));
329}
330
331void frame_backend_frame_set_window_id(UFBackendFrame frame, UFWindowId window_id)
332{
333 static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
334 InsertProperty(UFFramePropertyWindowId,
335 new oif::frame::Value(window_id));
336}
337
338void frame_backend_frame_set_active_touches(UFBackendFrame frame, unsigned int active_touches)
339{
340 static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
341 InsertProperty(UFFramePropertyActiveTouches,
342 new oif::frame::Value(active_touches));
343}
344
345void frame_backend_frame_add_touch(UFBackendFrame frame, UFBackendTouch touch)
346{
347 static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
348 AddTouch(touch->shared_ptr);
349}
350
351void frame_backend_frame_delete(UFBackendFrame frame)
352{
353 delete frame;
354}
355
290} // extern "C"356} // extern "C"
291357
=== modified file 'src/frame.h'
--- src/frame.h 2012-06-21 19:41:40 +0000
+++ src/frame.h 2012-08-29 18:56:18 +0000
@@ -33,6 +33,13 @@
33 virtual ~UFFrame_() {}33 virtual ~UFFrame_() {}
34};34};
3535
36struct UFBackendFrame_ {
37 UFBackendFrame_(oif::frame::UFFrame* frame)
38 : shared_ptr(frame) {}
39
40 oif::frame::SharedUFFrame shared_ptr;
41};
42
36namespace oif {43namespace oif {
37namespace frame {44namespace frame {
3845
@@ -43,8 +50,10 @@
4350
44 UFTouch* CopyTouch(UFTouchId touchid, UFTouchState new_state) const;51 UFTouch* CopyTouch(UFTouchId touchid, UFTouchState new_state) const;
45 bool IsTouchOwned(UFTouchId touchid);52 bool IsTouchOwned(UFTouchId touchid);
53 void AddTouch(const SharedUFTouch& touch);
46 void UpdateTouch(const SharedUFTouch& touch);54 void UpdateTouch(const SharedUFTouch& touch);
47 bool IsEnded() const;55 bool IsEnded() const;
56 unsigned int GetNumTouches() const { return touches_array_.size(); }
48 UFStatus GetPreviousTouchValue(const UFTouch* touch, UFAxisType type,57 UFStatus GetPreviousTouchValue(const UFTouch* touch, UFAxisType type,
49 float* value) const;58 float* value) const;
50 UFStatus GetPreviousTouchProperty(const UFTouch* touch,59 UFStatus GetPreviousTouchProperty(const UFTouch* touch,
5160
=== modified file 'src/libframe.ver'
--- src/libframe.ver 2012-06-21 19:41:40 +0000
+++ src/libframe.ver 2012-08-29 18:56:18 +0000
@@ -61,6 +61,40 @@
61 frame_x11_get_touch_id;61 frame_x11_get_touch_id;
62 frame_x11_create_touch_id;62 frame_x11_create_touch_id;
6363
64 frame_event_new;
65 frame_event_set_type;
66 frame_event_set_device;
67 frame_event_set_frame;
68 frame_event_set_time;
69 frame_backend_device_new;
70 frame_backend_device_get_device;
71 frame_backend_device_delete;
72 frame_backend_device_set_name;
73 frame_backend_device_set_direct;
74 frame_backend_device_set_independent;
75 frame_backend_device_set_semi_mt;
76 frame_backend_device_set_max_touches;
77 frame_backend_device_set_window_resolution;
78 frame_backend_device_add_axis;
79 frame_backend_frame_new;
80 frame_backend_frame_get_frame;
81 frame_backend_frame_set_device;
82 frame_backend_frame_set_window_id;
83 frame_backend_frame_set_active_touches;
84 frame_backend_frame_add_touch;
85 frame_backend_frame_delete;
86 frame_backend_touch_new;
87 frame_backend_touch_get_touch;
88 frame_backend_touch_set_id;
89 frame_backend_touch_set_state;
90 frame_backend_touch_set_window_pos;
91 frame_backend_touch_set_time;
92 frame_backend_touch_set_start_time;
93 frame_backend_touch_set_owned;
94 frame_backend_touch_set_pending_end;
95 frame_backend_touch_set_value;
96 frame_backend_touch_delete;
97
64 local:98 local:
65 *;99 *;
66};100};
67101
=== modified file 'src/touch.cpp'
--- src/touch.cpp 2012-06-21 19:41:40 +0000
+++ src/touch.cpp 2012-08-29 18:56:18 +0000
@@ -24,6 +24,8 @@
2424
25#include "frame.h"25#include "frame.h"
2626
27#include <oif/frame_backend.h>
28
27namespace oif {29namespace oif {
28namespace frame {30namespace frame {
2931
@@ -205,4 +207,82 @@
205 return start_time;207 return start_time;
206}208}
207209
210UFBackendTouch frame_backend_touch_new()
211{
212 return new UFBackendTouch_(new oif::frame::UFTouch);
213}
214
215UFTouch frame_backend_touch_get_touch(UFBackendTouch touch)
216{
217 return touch->shared_ptr.get();
218}
219
220void frame_backend_touch_set_id(UFBackendTouch touch_backend, UFTouchId id)
221{
222 oif::frame::UFTouch *touch =
223 static_cast<oif::frame::UFTouch*>(touch_backend->shared_ptr.get());
224
225 touch->InsertProperty(UFTouchPropertyId, new oif::frame::Value(id));
226 touch->SetId(id);
227}
228
229void frame_backend_touch_set_state(UFBackendTouch touch_backend, UFTouchState state)
230{
231 oif::frame::UFTouch *touch =
232 static_cast<oif::frame::UFTouch*>(touch_backend->shared_ptr.get());
233
234 touch->InsertProperty(UFTouchPropertyState, new oif::frame::Value(state));
235 touch->SetState(state);
236}
237
238void frame_backend_touch_set_window_pos(UFBackendTouch touch, float x, float y)
239{
240 static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
241 InsertProperty(UFTouchPropertyWindowX,
242 new oif::frame::Value(x));
243
244 static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
245 InsertProperty(UFTouchPropertyWindowY,
246 new oif::frame::Value(y));
247}
248
249void frame_backend_touch_set_time(UFBackendTouch touch, uint64_t time)
250{
251 static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
252 InsertProperty(UFTouchPropertyTime,
253 new oif::frame::Value(time));
254}
255
256void frame_backend_touch_set_start_time(UFBackendTouch touch, uint64_t start_time)
257{
258 static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
259 InsertProperty(UFTouchPropertyStartTime,
260 new oif::frame::Value(start_time));
261}
262
263void frame_backend_touch_set_owned(UFBackendTouch touch, int owned)
264{
265 static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
266 InsertProperty(UFTouchPropertyOwned,
267 new oif::frame::Value(owned));
268}
269
270void frame_backend_touch_set_pending_end(UFBackendTouch touch, int pending_end)
271{
272 static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
273 InsertProperty(UFTouchPropertyPendingEnd,
274 new oif::frame::Value(pending_end));
275}
276
277void frame_backend_touch_set_value(UFBackendTouch touch, UFAxisType type, float value)
278{
279 static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
280 SetValue(type, value);
281}
282
283void frame_backend_touch_delete(UFBackendTouch touch)
284{
285 delete touch;
286}
287
208} // extern "C"288} // extern "C"
209289
=== modified file 'src/touch.h'
--- src/touch.h 2012-06-21 19:41:40 +0000
+++ src/touch.h 2012-08-29 18:56:18 +0000
@@ -34,16 +34,27 @@
34 virtual ~UFTouch_() {}34 virtual ~UFTouch_() {}
35};35};
3636
37struct UFBackendTouch_ {
38 UFBackendTouch_(oif::frame::UFTouch* touch)
39 : shared_ptr(touch) {}
40
41 oif::frame::SharedUFTouch shared_ptr;
42};
43
37namespace oif {44namespace oif {
38namespace frame {45namespace frame {
3946
40class UFTouch : public UFTouch_, public Property<UFTouchProperty> {47class UFTouch : public UFTouch_, public Property<UFTouchProperty> {
41 public:48 public:
49 UFTouch() {}
42 UFTouch(UFTouchState state, UFTouchId id, float x, float y,50 UFTouch(UFTouchState state, UFTouchId id, float x, float y,
43 uint64_t time);51 uint64_t time);
44 UFTouch(const UFTouch& touch, UFTouchState new_state);52 UFTouch(const UFTouch& touch, UFTouchState new_state);
4553
54 void SetId(UFTouchId id) { id_ = id; }
46 UFTouchId id() const { return id_; }55 UFTouchId id() const { return id_; }
56
57 void SetState(UFTouchState state) { state_ = state; }
47 UFTouchState state() const { return state_; }58 UFTouchState state() const { return state_; }
4859
49 void SetValue(UFAxisType type, float value);60 void SetValue(UFAxisType type, float value);
@@ -53,8 +64,8 @@
53 UFTouch& operator=(const UFTouch&) = delete;64 UFTouch& operator=(const UFTouch&) = delete;
5465
55 private:66 private:
56 const UFTouchId id_;67 UFTouchId id_;
57 const UFTouchState state_;68 UFTouchState state_;
58 std::map<UFAxisType, float> values_;69 std::map<UFAxisType, float> values_;
59};70};
6071
6172
=== modified file 'src/x11/device_x11.cpp'
--- src/x11/device_x11.cpp 2012-06-21 19:41:40 +0000
+++ src/x11/device_x11.cpp 2012-08-29 18:56:18 +0000
@@ -135,9 +135,6 @@
135 }135 }
136 }136 }
137137
138 value = new Value(static_cast<unsigned int>(axes_.size()));
139 InsertProperty(UFDevicePropertyNumAxes, value);
140
141 /* X11 doesn't provide us the real physical resolution of the display */138 /* X11 doesn't provide us the real physical resolution of the display */
142 value = new Value(0.f);139 value = new Value(0.f);
143 InsertProperty(UFDevicePropertyWindowResolutionX, value);140 InsertProperty(UFDevicePropertyWindowResolutionX, value);
144141
=== modified file 'test/regular/Makefile.am'
--- test/regular/Makefile.am 2012-07-25 22:36:11 +0000
+++ test/regular/Makefile.am 2012-08-29 18:56:18 +0000
@@ -38,6 +38,7 @@
3838
39check_regular_SOURCES = \39check_regular_SOURCES = \
40 accept-ended-touch.cpp \40 accept-ended-touch.cpp \
41 backend.cpp \
41 frame-fixture.cpp \42 frame-fixture.cpp \
42 frame-fixture.h43 frame-fixture.h
4344
4445
=== added file 'test/regular/backend.cpp'
--- test/regular/backend.cpp 1970-01-01 00:00:00 +0000
+++ test/regular/backend.cpp 2012-08-29 18:56:18 +0000
@@ -0,0 +1,206 @@
1#include <gtest/gtest.h>
2#include "oif/frame_backend.h"
3
4TEST(Backend, Touch)
5{
6 UFStatus status;
7
8 UFBackendTouch touch_backend = frame_backend_touch_new();
9 ASSERT_TRUE(touch_backend != nullptr);
10
11 UFTouch touch = frame_backend_touch_get_touch(touch_backend);
12 ASSERT_TRUE(touch != nullptr);
13
14 frame_backend_touch_set_id(touch_backend, 123);
15 ASSERT_EQ(123, frame_touch_get_id(touch));
16
17 frame_backend_touch_set_state(touch_backend, UFTouchStateUpdate);
18 ASSERT_EQ(UFTouchStateUpdate, frame_touch_get_state(touch));
19
20 frame_backend_touch_set_window_pos(touch_backend, 1.2f, 3.4f);
21 ASSERT_EQ(1.2f, frame_touch_get_window_x(touch));
22 ASSERT_EQ(3.4f, frame_touch_get_window_y(touch));
23
24 frame_backend_touch_set_time(touch_backend, 852);
25 ASSERT_EQ(852, frame_touch_get_time(touch));
26
27 frame_backend_touch_set_start_time(touch_backend, 555);
28 ASSERT_EQ(555, frame_touch_get_start_time(touch));
29
30 frame_backend_touch_set_owned(touch_backend, 1);
31 int owned = 0;
32 status = frame_touch_get_property(touch, UFTouchPropertyOwned, &owned);
33 ASSERT_EQ(UFStatusSuccess, status);
34 ASSERT_EQ(1, owned);
35
36 frame_backend_touch_set_pending_end(touch_backend, 1);
37 int pending_end = 0;
38 status = frame_touch_get_property(touch, UFTouchPropertyPendingEnd, &pending_end);
39 ASSERT_EQ(UFStatusSuccess, status);
40 ASSERT_EQ(1, pending_end);
41
42 frame_backend_touch_set_value(touch_backend, UFAxisTypeTouchMajor, 987.6f);
43 float touch_major = 0.0f;
44 status = frame_touch_get_value(touch, UFAxisTypeTouchMajor, &touch_major);
45 ASSERT_EQ(UFStatusSuccess, status);
46 ASSERT_EQ(987.6f, touch_major);
47
48 frame_backend_touch_delete(touch_backend);
49}
50
51TEST(Backend, Device)
52{
53 UFStatus status;
54
55 UFBackendDevice device_backend = frame_backend_device_new();
56 ASSERT_NE(nullptr, device_backend);
57
58 UFDevice device = frame_backend_device_get_device(device_backend);
59 ASSERT_NE(nullptr, device);
60
61 const char *name = nullptr;
62 status = frame_device_get_property(device, UFDevicePropertyName, &name);
63 ASSERT_EQ(UFStatusErrorUnknownProperty, status);
64 frame_backend_device_set_name(device_backend, "Hello World");
65 status = frame_device_get_property(device, UFDevicePropertyName, &name);
66 ASSERT_EQ(UFStatusSuccess, status);
67 ASSERT_STREQ("Hello World", name);
68
69 int direct = 0;
70 status = frame_device_get_property(device, UFDevicePropertyDirect, &direct);
71 ASSERT_EQ(UFStatusErrorUnknownProperty, status);
72 frame_backend_device_set_direct(device_backend, 1);
73 status = frame_device_get_property(device, UFDevicePropertyDirect, &direct);
74 ASSERT_EQ(UFStatusSuccess, status);
75 ASSERT_EQ(1, direct);
76
77 int independent = 0;
78 status = frame_device_get_property(device, UFDevicePropertyIndependent, &independent);
79 ASSERT_EQ(UFStatusErrorUnknownProperty, status);
80 frame_backend_device_set_independent(device_backend, 1);
81 status = frame_device_get_property(device, UFDevicePropertyIndependent, &independent);
82 ASSERT_EQ(UFStatusSuccess, status);
83 ASSERT_EQ(1, independent);
84
85 int semi_mt = 0;
86 status = frame_device_get_property(device, UFDevicePropertySemiMT, &semi_mt);
87 ASSERT_EQ(UFStatusErrorUnknownProperty, status);
88 frame_backend_device_set_semi_mt(device_backend, 1);
89 status = frame_device_get_property(device, UFDevicePropertySemiMT, &semi_mt);
90 ASSERT_EQ(UFStatusSuccess, status);
91 ASSERT_EQ(1, semi_mt);
92
93 unsigned int max_touches = 0;
94 status = frame_device_get_property(device, UFDevicePropertyMaxTouches, &max_touches);
95 ASSERT_EQ(UFStatusErrorUnknownProperty, status);
96 frame_backend_device_set_max_touches(device_backend, 5);
97 status = frame_device_get_property(device, UFDevicePropertyMaxTouches, &max_touches);
98 ASSERT_EQ(UFStatusSuccess, status);
99 ASSERT_EQ(5, max_touches);
100
101 frame_backend_device_set_window_resolution(device_backend, 1024.0f, 768.0f);
102 ASSERT_EQ(1024.0f, frame_device_get_window_resolution_x(device));
103 ASSERT_EQ(768.0f, frame_device_get_window_resolution_y(device));
104
105 unsigned int num_axes = 0;
106 status = frame_device_get_property(device, UFDevicePropertyNumAxes, &num_axes);
107 ASSERT_EQ(UFStatusSuccess, status);
108 ASSERT_EQ(0, num_axes);
109 frame_backend_device_add_axis(device_backend,
110 UFAxisTypePressure, 1.0f, 1000.0f, 3.5f);
111 status = frame_device_get_property(device, UFDevicePropertyNumAxes, &num_axes);
112 ASSERT_EQ(UFStatusSuccess, status);
113 ASSERT_EQ(1, num_axes);
114 UFAxis axis = nullptr;
115 status = frame_device_get_axis_by_type(device, UFAxisTypePressure, &axis);
116 ASSERT_EQ(UFStatusSuccess, status);
117 ASSERT_NE(nullptr, axis);
118 ASSERT_EQ(UFAxisTypePressure, frame_axis_get_type(axis));
119 ASSERT_EQ(1.0f, frame_axis_get_minimum(axis));
120 ASSERT_EQ(1000.0f, frame_axis_get_maximum(axis));
121 ASSERT_EQ(3.5f, frame_axis_get_resolution(axis));
122
123 frame_backend_device_delete(device_backend);
124}
125
126TEST(Backend, Frame)
127{
128 UFStatus status;
129
130 UFBackendFrame frame_backend = frame_backend_frame_new();
131 ASSERT_NE(nullptr, frame_backend);
132
133 UFFrame frame = frame_backend_frame_get_frame(frame_backend);
134 ASSERT_NE(nullptr, frame);
135
136 UFBackendDevice device_backend = frame_backend_device_new();
137 UFDevice device = frame_backend_device_get_device(device_backend);
138
139 frame_backend_frame_set_device(frame_backend, device_backend);
140 ASSERT_EQ(device, frame_frame_get_device(frame));
141
142 frame_backend_frame_set_window_id(frame_backend, 123);
143 ASSERT_EQ(123, frame_frame_get_window_id(frame));
144
145
146 unsigned int active_touches = 0;
147 UFBackendTouch touch_backend = frame_backend_touch_new();
148 UFTouch touch = frame_backend_touch_get_touch(touch_backend);
149 frame_backend_touch_set_id(touch_backend, 10);
150 UFTouch touch_retrieved = nullptr;
151 ASSERT_EQ(0, frame_frame_get_num_touches(frame));
152 status = frame_frame_get_property(frame, UFFramePropertyActiveTouches, &active_touches);
153 ASSERT_EQ(UFStatusSuccess, status);
154 ASSERT_EQ(0, active_touches);
155 frame_backend_frame_add_touch(frame_backend, touch_backend);
156 ASSERT_EQ(1, frame_frame_get_num_touches(frame));
157 status = frame_frame_get_property(frame, UFFramePropertyActiveTouches, &active_touches);
158 ASSERT_EQ(UFStatusSuccess, status);
159 ASSERT_EQ(1, active_touches);
160 status = frame_frame_get_touch_by_id(frame, 10, &touch_retrieved);
161 ASSERT_EQ(UFStatusSuccess, status);
162 ASSERT_EQ(touch, touch_retrieved);
163
164 frame_backend_frame_set_active_touches(frame_backend, 3);
165 status = frame_frame_get_property(frame, UFFramePropertyActiveTouches, &active_touches);
166 ASSERT_EQ(UFStatusSuccess, status);
167 ASSERT_EQ(3, active_touches);
168
169 frame_backend_frame_delete(frame_backend);
170 frame_backend_device_delete(device_backend);
171 frame_backend_touch_delete(touch_backend);
172}
173
174TEST(Backend, Event)
175{
176 UFStatus status;
177
178 UFEvent event = frame_event_new();
179 ASSERT_NE(nullptr, event);
180
181 frame_event_set_type(event, UFEventTypeDeviceRemoved);
182 ASSERT_EQ(UFEventTypeDeviceRemoved, frame_event_get_type(event));
183
184 UFBackendDevice device_backend = frame_backend_device_new();
185 UFDevice device = frame_backend_device_get_device(device_backend);
186 UFDevice device_retrieved = nullptr;
187 frame_event_set_device(event, device_backend);
188 status = frame_event_get_property(event, UFEventPropertyDevice, &device_retrieved);
189 ASSERT_EQ(UFStatusSuccess, status);
190 ASSERT_EQ(device, device_retrieved);
191
192 UFBackendFrame frame_backend = frame_backend_frame_new();
193 UFFrame frame = frame_backend_frame_get_frame(frame_backend);
194 UFFrame frame_retrieved = nullptr;
195 frame_event_set_frame(event, frame_backend);
196 status = frame_event_get_property(event, UFEventPropertyFrame, &frame_retrieved);
197 ASSERT_EQ(UFStatusSuccess, status);
198 ASSERT_EQ(frame, frame_retrieved);
199
200 frame_event_set_time(event, 1234);
201 ASSERT_EQ(1234, frame_event_get_time(event));
202
203 frame_event_unref(event);
204 frame_backend_device_delete(device_backend);
205 frame_backend_frame_delete(frame_backend);
206}

Subscribers

People subscribed via source and target branches