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
1=== added file 'include/oif/frame_backend.h'
2--- include/oif/frame_backend.h 1970-01-01 00:00:00 +0000
3+++ include/oif/frame_backend.h 2012-08-29 18:56:18 +0000
4@@ -0,0 +1,254 @@
5+/**
6+ * @file oif/frame_backend.h
7+ * API for creating objects.
8+ */
9+
10+#ifndef FRAME_OIF_FRAME_BACKEND_H_
11+#define FRAME_OIF_FRAME_BACKEND_H_
12+
13+/* front end definitions */
14+#include <oif/frame.h>
15+
16+#ifdef __cplusplus
17+extern "C" {
18+#endif
19+
20+/** Handle for a device to be used on the backend API */
21+typedef struct UFBackendDevice_* UFBackendDevice;
22+
23+/** Handle for a frame to be used on the backend API */
24+typedef struct UFBackendFrame_* UFBackendFrame;
25+
26+/** Handle for a touch to be used on the backend API */
27+typedef struct UFBackendTouch_* UFBackendTouch;
28+
29+/********************************************************************
30+ * Event
31+ ********************************************************************/
32+
33+/**
34+ * Creates a new event with a reference count of one.
35+ */
36+FRAME_PUBLIC
37+UFEvent frame_event_new();
38+
39+/**
40+ * Sets the type of the given event
41+ */
42+FRAME_PUBLIC
43+void frame_event_set_type(UFEvent event, UFEventType type);
44+
45+/**
46+ * Sets the device property of the given event
47+ *
48+ * It increases the reference count of the corresponding UFDevice by one.
49+ */
50+FRAME_PUBLIC
51+void frame_event_set_device(UFEvent event, UFBackendDevice device);
52+
53+/**
54+ * Sets the frame property of the given event
55+ *
56+ * It increases the reference count of the corresponding UFFrame by one.
57+ */
58+FRAME_PUBLIC
59+void frame_event_set_frame(UFEvent event, UFBackendFrame frame);
60+
61+/**
62+ * Sets the time of the given event
63+ */
64+FRAME_PUBLIC
65+void frame_event_set_time(UFEvent event, uint64_t time);
66+
67+/********************************************************************
68+ * Device
69+ ********************************************************************/
70+
71+/**
72+ * Creates a new UFDevice and returns its backend handle.
73+ */
74+FRAME_PUBLIC
75+UFBackendDevice frame_backend_device_new();
76+
77+/**
78+ * Returns a UFDevice instance given its backend handle.
79+ */
80+FRAME_PUBLIC
81+UFDevice frame_backend_device_get_device(UFBackendDevice device);
82+
83+/**
84+ * Sets the "Name" property of the given device
85+ */
86+FRAME_PUBLIC
87+void frame_backend_device_set_name(UFBackendDevice device, const char *name);
88+
89+/**
90+ * Sets the "Direct" property of the given device
91+ */
92+FRAME_PUBLIC
93+void frame_backend_device_set_direct(UFBackendDevice device, int direct);
94+
95+/**
96+ * Sets the "Independent" property of the given device
97+ */
98+FRAME_PUBLIC
99+void frame_backend_device_set_independent(UFBackendDevice device, int independent);
100+
101+/**
102+ * Sets the "SemiMT" property of the given device
103+ */
104+FRAME_PUBLIC
105+void frame_backend_device_set_semi_mt(UFBackendDevice device, int semi_mt);
106+
107+/**
108+ * Sets the "MaxTouches" property of the given device
109+ */
110+FRAME_PUBLIC
111+void frame_backend_device_set_max_touches(UFBackendDevice device, unsigned int max_touches);
112+
113+/**
114+ * Sets the "WindowResolutionX" and "WindowResolutionY" properties of the
115+ * given device.
116+ */
117+FRAME_PUBLIC
118+void frame_backend_device_set_window_resolution(UFBackendDevice device, float x, float y);
119+
120+/**
121+ * Adds an axis to the device
122+ */
123+FRAME_PUBLIC
124+void frame_backend_device_add_axis(UFBackendDevice device,
125+ UFAxisType type,
126+ float min, float max, float resolution);
127+
128+/**
129+ * Deletes the backend handle of a UFDevice, decreasing its reference count by one.
130+ */
131+FRAME_PUBLIC
132+void frame_backend_device_delete(UFBackendDevice device);
133+
134+/********************************************************************
135+ * Frame
136+ ********************************************************************/
137+
138+/**
139+ * Creates a new UFFrame and returns its backend handle.
140+ */
141+FRAME_PUBLIC
142+UFBackendFrame frame_backend_frame_new();
143+
144+/**
145+ * Returns a UFFrame instance given its backend handle.
146+ */
147+FRAME_PUBLIC
148+UFFrame frame_backend_frame_get_frame(UFBackendFrame frame);
149+
150+/**
151+ * Sets the "Device" property of the given frame
152+ */
153+FRAME_PUBLIC
154+void frame_backend_frame_set_device(UFBackendFrame frame, UFBackendDevice device);
155+
156+/**
157+ * Sets the "WindowId" property of the given frame
158+ */
159+FRAME_PUBLIC
160+void frame_backend_frame_set_window_id(UFBackendFrame frame, UFWindowId window_id);
161+
162+/**
163+ * Sets the "ActiveTouches" property of the given frame
164+ *
165+ * If unset this property returns the number of touches.
166+ */
167+FRAME_PUBLIC
168+void frame_backend_frame_set_active_touches(UFBackendFrame frame, unsigned int active_touches);
169+
170+/**
171+ * Adds a UFTouch to the given frame.
172+ */
173+FRAME_PUBLIC
174+void frame_backend_frame_add_touch(UFBackendFrame frame, UFBackendTouch touch);
175+
176+/**
177+ * Deletes the backend handle of a UFFrame,
178+ * decreasing its reference count by one.
179+ */
180+FRAME_PUBLIC
181+void frame_backend_frame_delete(UFBackendFrame frame);
182+
183+/********************************************************************
184+ * Touch
185+ ********************************************************************/
186+
187+/**
188+ * Creates a new UFTouch and returns its backend handle.
189+ */
190+FRAME_PUBLIC
191+UFBackendTouch frame_backend_touch_new();
192+
193+/**
194+ * Returns a UFTouch instance given its backend handle.
195+ */
196+FRAME_PUBLIC
197+UFTouch frame_backend_touch_get_touch(UFBackendTouch touch);
198+
199+/**
200+ * Sets the "Id" property of the given touch
201+ */
202+FRAME_PUBLIC
203+void frame_backend_touch_set_id(UFBackendTouch touch, UFTouchId id);
204+
205+/**
206+ * Sets the "State" property of the given touch
207+ */
208+FRAME_PUBLIC
209+void frame_backend_touch_set_state(UFBackendTouch touch, UFTouchState state);
210+
211+/**
212+ * Sets the "WindowX" and "WindowY" properties of the given touch
213+ */
214+FRAME_PUBLIC
215+void frame_backend_touch_set_window_pos(UFBackendTouch touch, float x, float y);
216+
217+/**
218+ * Sets the "Time" property of the given touch
219+ */
220+FRAME_PUBLIC
221+void frame_backend_touch_set_time(UFBackendTouch touch, uint64_t time);
222+
223+/**
224+ * Sets the "StartTime" property of the given touch
225+ */
226+FRAME_PUBLIC
227+void frame_backend_touch_set_start_time(UFBackendTouch touch, uint64_t start_time);
228+
229+/**
230+ * Sets the "Owned" property of the given touch
231+ */
232+FRAME_PUBLIC
233+void frame_backend_touch_set_owned(UFBackendTouch touch, int owned);
234+
235+/**
236+ * Sets the "PendingEnd" property of the given touch
237+ */
238+FRAME_PUBLIC
239+void frame_backend_touch_set_pending_end(UFBackendTouch touch, int pending_end);
240+
241+/**
242+ * Sets the value of an axis of the given touch
243+ */
244+FRAME_PUBLIC
245+void frame_backend_touch_set_value(UFBackendTouch touch, UFAxisType type, float value);
246+
247+/**
248+ * Deletes the backend handle of a UFTouch,
249+ * decreasing its reference count by one.
250+ */
251+FRAME_PUBLIC
252+void frame_backend_touch_delete(UFBackendTouch touch);
253+
254+#ifdef __cplusplus
255+}
256+#endif
257+
258+#endif /* FRAME_OIF_FRAME_BACKEND_H_ */
259
260=== modified file 'src/device.cpp'
261--- src/device.cpp 2012-06-21 19:41:40 +0000
262+++ src/device.cpp 2012-08-29 18:56:18 +0000
263@@ -24,6 +24,8 @@
264
265 #include "axis.h"
266
267+#include <oif/frame_backend.h>
268+
269 namespace oif {
270 namespace frame {
271
272@@ -75,18 +77,30 @@
273 UFStatus frame_device_get_property_unsigned_int_(UFDevice device,
274 UFDeviceProperty property,
275 unsigned int *value) {
276- return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(
277- property,
278- value);
279+
280+ if (property == UFDevicePropertyNumAxes) {
281+ *value = static_cast<const oif::frame::UFDevice*>(device)->axes_.size();
282+ return UFStatusSuccess;
283+ } else {
284+ return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(
285+ property,
286+ value);
287+ }
288 }
289
290 #undef frame_device_get_property /* Override C11 generic selections macro */
291 FRAME_PUBLIC
292 UFStatus frame_device_get_property(UFDevice device, UFDeviceProperty property,
293 void *value) {
294- return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(
295- property,
296- value);
297+ if (property == UFDevicePropertyNumAxes) {
298+ *reinterpret_cast<unsigned int *>(value) =
299+ static_cast<const oif::frame::UFDevice*>(device)->axes_.size();
300+ return UFStatusSuccess;
301+ } else {
302+ return static_cast<const oif::frame::UFDevice*>(device)->GetProperty(
303+ property,
304+ value);
305+ }
306 }
307
308 UFStatus frame_device_get_axis_by_index(UFDevice device, unsigned int index,
309@@ -129,4 +143,77 @@
310 return resolution;
311 }
312
313+UFBackendDevice frame_backend_device_new()
314+{
315+ return new UFBackendDevice_(new oif::frame::UFDevice);
316+}
317+
318+UFDevice frame_backend_device_get_device(UFBackendDevice device)
319+{
320+ return device->shared_ptr.get();
321+}
322+
323+void frame_backend_device_delete(UFBackendDevice device)
324+{
325+ delete device;
326+}
327+
328+void frame_backend_device_set_name(UFBackendDevice device, const char *name)
329+{
330+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
331+ InsertProperty(UFDevicePropertyName,
332+ new oif::frame::Value(name));
333+}
334+
335+void frame_backend_device_set_direct(UFBackendDevice device, int direct)
336+{
337+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
338+ InsertProperty(UFDevicePropertyDirect,
339+ new oif::frame::Value(direct));
340+}
341+
342+void frame_backend_device_set_independent(UFBackendDevice device, int independent)
343+{
344+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
345+ InsertProperty(UFDevicePropertyIndependent,
346+ new oif::frame::Value(independent));
347+}
348+
349+void frame_backend_device_set_semi_mt(UFBackendDevice device, int semi_mt)
350+{
351+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
352+ InsertProperty(UFDevicePropertySemiMT,
353+ new oif::frame::Value(semi_mt));
354+}
355+
356+void frame_backend_device_set_max_touches(UFBackendDevice device, unsigned int max_touches)
357+{
358+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
359+ InsertProperty(UFDevicePropertyMaxTouches,
360+ new oif::frame::Value(max_touches));
361+}
362+
363+void frame_backend_device_set_window_resolution(UFBackendDevice device, float x, float y)
364+{
365+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
366+ InsertProperty(UFDevicePropertyWindowResolutionX,
367+ new oif::frame::Value(x));
368+
369+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
370+ InsertProperty(UFDevicePropertyWindowResolutionY,
371+ new oif::frame::Value(y));
372+}
373+
374+void frame_backend_device_add_axis(UFBackendDevice device,
375+ UFAxisType type,
376+ float min, float max, float resolution)
377+{
378+ using oif::frame::UFAxis;
379+
380+ UFAxis_* axis = new UFAxis(type, min, max, resolution);
381+
382+ static_cast<oif::frame::UFDevice*>(device->shared_ptr.get())->
383+ axes_[type] = std::unique_ptr<UFAxis>(static_cast<UFAxis*>(axis));
384+}
385+
386 } // extern "C"
387
388=== modified file 'src/device.h'
389--- src/device.h 2012-06-21 19:41:40 +0000
390+++ src/device.h 2012-08-29 18:56:18 +0000
391@@ -32,6 +32,13 @@
392 virtual ~UFDevice_() {};
393 };
394
395+struct UFBackendDevice_ {
396+ UFBackendDevice_(oif::frame::UFDevice* device)
397+ : shared_ptr(device) {}
398+
399+ oif::frame::SharedUFDevice shared_ptr;
400+};
401+
402 namespace oif {
403 namespace frame {
404
405@@ -45,7 +52,6 @@
406 UFDevice(const UFDevice&) = delete;
407 UFDevice& operator=(const UFDevice&) = delete;
408
409- protected:
410 typedef std::unique_ptr<UFAxis> UniqueUFAxis;
411
412 std::map<UFAxisType, UniqueUFAxis> axes_;
413
414=== modified file 'src/event.cpp'
415--- src/event.cpp 2012-06-21 19:41:40 +0000
416+++ src/event.cpp 2012-08-29 18:56:18 +0000
417@@ -22,10 +22,17 @@
418
419 #include "event.h"
420 #include "frame.h"
421+#include "device.h"
422+
423+#include <oif/frame_backend.h>
424
425 namespace oif {
426 namespace frame {
427
428+UFEvent::UFEvent()
429+ : ref_count_(1) {
430+}
431+
432 UFEvent::UFEvent(UFEventType type, const Value* data, uint64_t time)
433 : ref_count_(1) {
434 const Value* value;
435@@ -70,6 +77,10 @@
436
437 extern "C" {
438
439+UFEvent frame_event_new() {
440+ return new oif::frame::UFEvent;
441+}
442+
443 void frame_event_ref(UFEvent event) {
444 static_cast<oif::frame::UFEvent*>(event)->Ref();
445 }
446@@ -140,4 +151,30 @@
447 return time;
448 }
449
450+void frame_event_set_type(UFEvent event, UFEventType type)
451+{
452+ static_cast<oif::frame::UFEvent*>(event)->
453+ InsertProperty(UFEventPropertyType, new oif::frame::Value(type));
454+}
455+
456+void frame_event_set_device(UFEvent event, UFBackendDevice device)
457+{
458+ static_cast<oif::frame::UFEvent*>(event)->
459+ InsertProperty(UFEventPropertyDevice,
460+ new oif::frame::Value(device->shared_ptr));
461+}
462+
463+void frame_event_set_frame(UFEvent event, UFBackendFrame frame)
464+{
465+ static_cast<oif::frame::UFEvent*>(event)->
466+ InsertProperty(UFEventPropertyFrame,
467+ new oif::frame::Value(frame->shared_ptr));
468+}
469+
470+void frame_event_set_time(UFEvent event, uint64_t time)
471+{
472+ static_cast<oif::frame::UFEvent*>(event)->
473+ InsertProperty(UFEventPropertyTime, new oif::frame::Value(time));
474+}
475+
476 } // extern "C"
477
478=== modified file 'src/event.h'
479--- src/event.h 2012-06-21 19:41:40 +0000
480+++ src/event.h 2012-08-29 18:56:18 +0000
481@@ -37,6 +37,7 @@
482
483 class UFEvent : public UFEvent_, public Property<UFEventProperty> {
484 public:
485+ UFEvent();
486 UFEvent(UFEventType type, const Value* data, uint64_t time);
487 ~UFEvent();
488
489
490=== modified file 'src/frame.cpp'
491--- src/frame.cpp 2012-06-21 19:41:40 +0000
492+++ src/frame.cpp 2012-08-29 18:56:18 +0000
493@@ -23,9 +23,12 @@
494 #include <assert.h>
495 #include <stdio.h>
496
497+#include "device.h"
498 #include "touch.h"
499 #include "window.h"
500
501+#include <oif/frame_backend.h>
502+
503 namespace oif {
504 namespace frame {
505
506@@ -93,6 +96,12 @@
507
508 } // namespace
509
510+void UFFrame::AddTouch(const SharedUFTouch& touch)
511+{
512+ touches_map_[touch->id()] = touches_array_.size();
513+ touches_array_.push_back(touch);
514+}
515+
516 void UFFrame::UpdateTouch(const SharedUFTouch& touch) {
517 auto map_it = touches_map_.find(touch->id());
518
519@@ -102,14 +111,7 @@
520 CopyStartTime(touches_array_[map_it->second], touch);
521 touches_array_[map_it->second] = touch;
522 } else {
523- touches_map_[touch->id()] = touches_array_.size();
524- touches_array_.push_back(touch);
525-
526- const Value *value;
527- value = new Value(static_cast<unsigned int>(touches_map_.size()));
528- InsertProperty(UFFramePropertyNumTouches, value);
529- value = new Value(static_cast<unsigned int>(touches_map_.size()));
530- InsertProperty(UFFramePropertyActiveTouches, value);
531+ AddTouch(touch);
532 }
533 break;
534
535@@ -211,8 +213,21 @@
536 UFFrameProperty property,
537 unsigned int *value) {
538 const oif::frame::UFFrame* ufframe =
539- static_cast<const oif::frame::UFFrame*>(frame);
540- return ufframe->GetProperty(property, value);
541+ static_cast<const oif::frame::UFFrame*>(frame);
542+
543+ if (property == UFFramePropertyNumTouches) {
544+ *value = ufframe->GetNumTouches();
545+ return UFStatusSuccess;
546+ } else if (property == UFFramePropertyActiveTouches) {
547+ UFStatus status = ufframe->GetProperty(property, value);
548+ if (status != UFStatusSuccess) {
549+ *value = ufframe->GetNumTouches();
550+ status = UFStatusSuccess;
551+ }
552+ return status;
553+ } else {
554+ return ufframe->GetProperty(property, value);
555+ }
556 }
557
558 #undef frame_frame_get_property /* Override C11 generic selections macro */
559@@ -221,7 +236,20 @@
560 void *value) {
561 const oif::frame::UFFrame* ufframe =
562 static_cast<const oif::frame::UFFrame*>(frame);
563- return ufframe->GetProperty(property, value);
564+
565+ if (property == UFFramePropertyNumTouches) {
566+ *reinterpret_cast<unsigned int *>(value) = ufframe->GetNumTouches();
567+ return UFStatusSuccess;
568+ } else if (property == UFFramePropertyActiveTouches) {
569+ UFStatus status = ufframe->GetProperty(property, value);
570+ if (status != UFStatusSuccess) {
571+ *reinterpret_cast<unsigned int *>(value) = ufframe->GetNumTouches();
572+ status = UFStatusSuccess;
573+ }
574+ return status;
575+ } else {
576+ return ufframe->GetProperty(property, value);
577+ }
578 }
579
580 UFStatus frame_frame_get_touch_by_index(UFFrame frame, unsigned int index,
581@@ -269,13 +297,9 @@
582 }
583
584 uint32_t frame_frame_get_num_touches(UFFrame frame) {
585- unsigned int num_touches;
586 const oif::frame::UFFrame* ufframe =
587 static_cast<const oif::frame::UFFrame*>(frame);
588- UFStatus status = ufframe->GetProperty(UFFramePropertyNumTouches,
589- &num_touches);
590- assert(status == UFStatusSuccess);
591- return num_touches;
592+ return ufframe->GetNumTouches();
593 }
594
595 UFDevice frame_frame_get_device(UFFrame frame) {
596@@ -287,4 +311,46 @@
597 return device;
598 }
599
600+UFBackendFrame frame_backend_frame_new()
601+{
602+ return new UFBackendFrame_(new oif::frame::UFFrame);
603+}
604+
605+UFFrame frame_backend_frame_get_frame(UFBackendFrame frame)
606+{
607+ return frame->shared_ptr.get();
608+}
609+
610+void frame_backend_frame_set_device(UFBackendFrame frame, UFBackendDevice device)
611+{
612+ static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
613+ InsertProperty(UFFramePropertyDevice,
614+ new oif::frame::Value(device->shared_ptr));
615+}
616+
617+void frame_backend_frame_set_window_id(UFBackendFrame frame, UFWindowId window_id)
618+{
619+ static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
620+ InsertProperty(UFFramePropertyWindowId,
621+ new oif::frame::Value(window_id));
622+}
623+
624+void frame_backend_frame_set_active_touches(UFBackendFrame frame, unsigned int active_touches)
625+{
626+ static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
627+ InsertProperty(UFFramePropertyActiveTouches,
628+ new oif::frame::Value(active_touches));
629+}
630+
631+void frame_backend_frame_add_touch(UFBackendFrame frame, UFBackendTouch touch)
632+{
633+ static_cast<oif::frame::UFFrame*>(frame->shared_ptr.get())->
634+ AddTouch(touch->shared_ptr);
635+}
636+
637+void frame_backend_frame_delete(UFBackendFrame frame)
638+{
639+ delete frame;
640+}
641+
642 } // extern "C"
643
644=== modified file 'src/frame.h'
645--- src/frame.h 2012-06-21 19:41:40 +0000
646+++ src/frame.h 2012-08-29 18:56:18 +0000
647@@ -33,6 +33,13 @@
648 virtual ~UFFrame_() {}
649 };
650
651+struct UFBackendFrame_ {
652+ UFBackendFrame_(oif::frame::UFFrame* frame)
653+ : shared_ptr(frame) {}
654+
655+ oif::frame::SharedUFFrame shared_ptr;
656+};
657+
658 namespace oif {
659 namespace frame {
660
661@@ -43,8 +50,10 @@
662
663 UFTouch* CopyTouch(UFTouchId touchid, UFTouchState new_state) const;
664 bool IsTouchOwned(UFTouchId touchid);
665+ void AddTouch(const SharedUFTouch& touch);
666 void UpdateTouch(const SharedUFTouch& touch);
667 bool IsEnded() const;
668+ unsigned int GetNumTouches() const { return touches_array_.size(); }
669 UFStatus GetPreviousTouchValue(const UFTouch* touch, UFAxisType type,
670 float* value) const;
671 UFStatus GetPreviousTouchProperty(const UFTouch* touch,
672
673=== modified file 'src/libframe.ver'
674--- src/libframe.ver 2012-06-21 19:41:40 +0000
675+++ src/libframe.ver 2012-08-29 18:56:18 +0000
676@@ -61,6 +61,40 @@
677 frame_x11_get_touch_id;
678 frame_x11_create_touch_id;
679
680+ frame_event_new;
681+ frame_event_set_type;
682+ frame_event_set_device;
683+ frame_event_set_frame;
684+ frame_event_set_time;
685+ frame_backend_device_new;
686+ frame_backend_device_get_device;
687+ frame_backend_device_delete;
688+ frame_backend_device_set_name;
689+ frame_backend_device_set_direct;
690+ frame_backend_device_set_independent;
691+ frame_backend_device_set_semi_mt;
692+ frame_backend_device_set_max_touches;
693+ frame_backend_device_set_window_resolution;
694+ frame_backend_device_add_axis;
695+ frame_backend_frame_new;
696+ frame_backend_frame_get_frame;
697+ frame_backend_frame_set_device;
698+ frame_backend_frame_set_window_id;
699+ frame_backend_frame_set_active_touches;
700+ frame_backend_frame_add_touch;
701+ frame_backend_frame_delete;
702+ frame_backend_touch_new;
703+ frame_backend_touch_get_touch;
704+ frame_backend_touch_set_id;
705+ frame_backend_touch_set_state;
706+ frame_backend_touch_set_window_pos;
707+ frame_backend_touch_set_time;
708+ frame_backend_touch_set_start_time;
709+ frame_backend_touch_set_owned;
710+ frame_backend_touch_set_pending_end;
711+ frame_backend_touch_set_value;
712+ frame_backend_touch_delete;
713+
714 local:
715 *;
716 };
717
718=== modified file 'src/touch.cpp'
719--- src/touch.cpp 2012-06-21 19:41:40 +0000
720+++ src/touch.cpp 2012-08-29 18:56:18 +0000
721@@ -24,6 +24,8 @@
722
723 #include "frame.h"
724
725+#include <oif/frame_backend.h>
726+
727 namespace oif {
728 namespace frame {
729
730@@ -205,4 +207,82 @@
731 return start_time;
732 }
733
734+UFBackendTouch frame_backend_touch_new()
735+{
736+ return new UFBackendTouch_(new oif::frame::UFTouch);
737+}
738+
739+UFTouch frame_backend_touch_get_touch(UFBackendTouch touch)
740+{
741+ return touch->shared_ptr.get();
742+}
743+
744+void frame_backend_touch_set_id(UFBackendTouch touch_backend, UFTouchId id)
745+{
746+ oif::frame::UFTouch *touch =
747+ static_cast<oif::frame::UFTouch*>(touch_backend->shared_ptr.get());
748+
749+ touch->InsertProperty(UFTouchPropertyId, new oif::frame::Value(id));
750+ touch->SetId(id);
751+}
752+
753+void frame_backend_touch_set_state(UFBackendTouch touch_backend, UFTouchState state)
754+{
755+ oif::frame::UFTouch *touch =
756+ static_cast<oif::frame::UFTouch*>(touch_backend->shared_ptr.get());
757+
758+ touch->InsertProperty(UFTouchPropertyState, new oif::frame::Value(state));
759+ touch->SetState(state);
760+}
761+
762+void frame_backend_touch_set_window_pos(UFBackendTouch touch, float x, float y)
763+{
764+ static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
765+ InsertProperty(UFTouchPropertyWindowX,
766+ new oif::frame::Value(x));
767+
768+ static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
769+ InsertProperty(UFTouchPropertyWindowY,
770+ new oif::frame::Value(y));
771+}
772+
773+void frame_backend_touch_set_time(UFBackendTouch touch, uint64_t time)
774+{
775+ static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
776+ InsertProperty(UFTouchPropertyTime,
777+ new oif::frame::Value(time));
778+}
779+
780+void frame_backend_touch_set_start_time(UFBackendTouch touch, uint64_t start_time)
781+{
782+ static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
783+ InsertProperty(UFTouchPropertyStartTime,
784+ new oif::frame::Value(start_time));
785+}
786+
787+void frame_backend_touch_set_owned(UFBackendTouch touch, int owned)
788+{
789+ static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
790+ InsertProperty(UFTouchPropertyOwned,
791+ new oif::frame::Value(owned));
792+}
793+
794+void frame_backend_touch_set_pending_end(UFBackendTouch touch, int pending_end)
795+{
796+ static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
797+ InsertProperty(UFTouchPropertyPendingEnd,
798+ new oif::frame::Value(pending_end));
799+}
800+
801+void frame_backend_touch_set_value(UFBackendTouch touch, UFAxisType type, float value)
802+{
803+ static_cast<oif::frame::UFTouch*>(touch->shared_ptr.get())->
804+ SetValue(type, value);
805+}
806+
807+void frame_backend_touch_delete(UFBackendTouch touch)
808+{
809+ delete touch;
810+}
811+
812 } // extern "C"
813
814=== modified file 'src/touch.h'
815--- src/touch.h 2012-06-21 19:41:40 +0000
816+++ src/touch.h 2012-08-29 18:56:18 +0000
817@@ -34,16 +34,27 @@
818 virtual ~UFTouch_() {}
819 };
820
821+struct UFBackendTouch_ {
822+ UFBackendTouch_(oif::frame::UFTouch* touch)
823+ : shared_ptr(touch) {}
824+
825+ oif::frame::SharedUFTouch shared_ptr;
826+};
827+
828 namespace oif {
829 namespace frame {
830
831 class UFTouch : public UFTouch_, public Property<UFTouchProperty> {
832 public:
833+ UFTouch() {}
834 UFTouch(UFTouchState state, UFTouchId id, float x, float y,
835 uint64_t time);
836 UFTouch(const UFTouch& touch, UFTouchState new_state);
837
838+ void SetId(UFTouchId id) { id_ = id; }
839 UFTouchId id() const { return id_; }
840+
841+ void SetState(UFTouchState state) { state_ = state; }
842 UFTouchState state() const { return state_; }
843
844 void SetValue(UFAxisType type, float value);
845@@ -53,8 +64,8 @@
846 UFTouch& operator=(const UFTouch&) = delete;
847
848 private:
849- const UFTouchId id_;
850- const UFTouchState state_;
851+ UFTouchId id_;
852+ UFTouchState state_;
853 std::map<UFAxisType, float> values_;
854 };
855
856
857=== modified file 'src/x11/device_x11.cpp'
858--- src/x11/device_x11.cpp 2012-06-21 19:41:40 +0000
859+++ src/x11/device_x11.cpp 2012-08-29 18:56:18 +0000
860@@ -135,9 +135,6 @@
861 }
862 }
863
864- value = new Value(static_cast<unsigned int>(axes_.size()));
865- InsertProperty(UFDevicePropertyNumAxes, value);
866-
867 /* X11 doesn't provide us the real physical resolution of the display */
868 value = new Value(0.f);
869 InsertProperty(UFDevicePropertyWindowResolutionX, value);
870
871=== modified file 'test/regular/Makefile.am'
872--- test/regular/Makefile.am 2012-07-25 22:36:11 +0000
873+++ test/regular/Makefile.am 2012-08-29 18:56:18 +0000
874@@ -38,6 +38,7 @@
875
876 check_regular_SOURCES = \
877 accept-ended-touch.cpp \
878+ backend.cpp \
879 frame-fixture.cpp \
880 frame-fixture.h
881
882
883=== added file 'test/regular/backend.cpp'
884--- test/regular/backend.cpp 1970-01-01 00:00:00 +0000
885+++ test/regular/backend.cpp 2012-08-29 18:56:18 +0000
886@@ -0,0 +1,206 @@
887+#include <gtest/gtest.h>
888+#include "oif/frame_backend.h"
889+
890+TEST(Backend, Touch)
891+{
892+ UFStatus status;
893+
894+ UFBackendTouch touch_backend = frame_backend_touch_new();
895+ ASSERT_TRUE(touch_backend != nullptr);
896+
897+ UFTouch touch = frame_backend_touch_get_touch(touch_backend);
898+ ASSERT_TRUE(touch != nullptr);
899+
900+ frame_backend_touch_set_id(touch_backend, 123);
901+ ASSERT_EQ(123, frame_touch_get_id(touch));
902+
903+ frame_backend_touch_set_state(touch_backend, UFTouchStateUpdate);
904+ ASSERT_EQ(UFTouchStateUpdate, frame_touch_get_state(touch));
905+
906+ frame_backend_touch_set_window_pos(touch_backend, 1.2f, 3.4f);
907+ ASSERT_EQ(1.2f, frame_touch_get_window_x(touch));
908+ ASSERT_EQ(3.4f, frame_touch_get_window_y(touch));
909+
910+ frame_backend_touch_set_time(touch_backend, 852);
911+ ASSERT_EQ(852, frame_touch_get_time(touch));
912+
913+ frame_backend_touch_set_start_time(touch_backend, 555);
914+ ASSERT_EQ(555, frame_touch_get_start_time(touch));
915+
916+ frame_backend_touch_set_owned(touch_backend, 1);
917+ int owned = 0;
918+ status = frame_touch_get_property(touch, UFTouchPropertyOwned, &owned);
919+ ASSERT_EQ(UFStatusSuccess, status);
920+ ASSERT_EQ(1, owned);
921+
922+ frame_backend_touch_set_pending_end(touch_backend, 1);
923+ int pending_end = 0;
924+ status = frame_touch_get_property(touch, UFTouchPropertyPendingEnd, &pending_end);
925+ ASSERT_EQ(UFStatusSuccess, status);
926+ ASSERT_EQ(1, pending_end);
927+
928+ frame_backend_touch_set_value(touch_backend, UFAxisTypeTouchMajor, 987.6f);
929+ float touch_major = 0.0f;
930+ status = frame_touch_get_value(touch, UFAxisTypeTouchMajor, &touch_major);
931+ ASSERT_EQ(UFStatusSuccess, status);
932+ ASSERT_EQ(987.6f, touch_major);
933+
934+ frame_backend_touch_delete(touch_backend);
935+}
936+
937+TEST(Backend, Device)
938+{
939+ UFStatus status;
940+
941+ UFBackendDevice device_backend = frame_backend_device_new();
942+ ASSERT_NE(nullptr, device_backend);
943+
944+ UFDevice device = frame_backend_device_get_device(device_backend);
945+ ASSERT_NE(nullptr, device);
946+
947+ const char *name = nullptr;
948+ status = frame_device_get_property(device, UFDevicePropertyName, &name);
949+ ASSERT_EQ(UFStatusErrorUnknownProperty, status);
950+ frame_backend_device_set_name(device_backend, "Hello World");
951+ status = frame_device_get_property(device, UFDevicePropertyName, &name);
952+ ASSERT_EQ(UFStatusSuccess, status);
953+ ASSERT_STREQ("Hello World", name);
954+
955+ int direct = 0;
956+ status = frame_device_get_property(device, UFDevicePropertyDirect, &direct);
957+ ASSERT_EQ(UFStatusErrorUnknownProperty, status);
958+ frame_backend_device_set_direct(device_backend, 1);
959+ status = frame_device_get_property(device, UFDevicePropertyDirect, &direct);
960+ ASSERT_EQ(UFStatusSuccess, status);
961+ ASSERT_EQ(1, direct);
962+
963+ int independent = 0;
964+ status = frame_device_get_property(device, UFDevicePropertyIndependent, &independent);
965+ ASSERT_EQ(UFStatusErrorUnknownProperty, status);
966+ frame_backend_device_set_independent(device_backend, 1);
967+ status = frame_device_get_property(device, UFDevicePropertyIndependent, &independent);
968+ ASSERT_EQ(UFStatusSuccess, status);
969+ ASSERT_EQ(1, independent);
970+
971+ int semi_mt = 0;
972+ status = frame_device_get_property(device, UFDevicePropertySemiMT, &semi_mt);
973+ ASSERT_EQ(UFStatusErrorUnknownProperty, status);
974+ frame_backend_device_set_semi_mt(device_backend, 1);
975+ status = frame_device_get_property(device, UFDevicePropertySemiMT, &semi_mt);
976+ ASSERT_EQ(UFStatusSuccess, status);
977+ ASSERT_EQ(1, semi_mt);
978+
979+ unsigned int max_touches = 0;
980+ status = frame_device_get_property(device, UFDevicePropertyMaxTouches, &max_touches);
981+ ASSERT_EQ(UFStatusErrorUnknownProperty, status);
982+ frame_backend_device_set_max_touches(device_backend, 5);
983+ status = frame_device_get_property(device, UFDevicePropertyMaxTouches, &max_touches);
984+ ASSERT_EQ(UFStatusSuccess, status);
985+ ASSERT_EQ(5, max_touches);
986+
987+ frame_backend_device_set_window_resolution(device_backend, 1024.0f, 768.0f);
988+ ASSERT_EQ(1024.0f, frame_device_get_window_resolution_x(device));
989+ ASSERT_EQ(768.0f, frame_device_get_window_resolution_y(device));
990+
991+ unsigned int num_axes = 0;
992+ status = frame_device_get_property(device, UFDevicePropertyNumAxes, &num_axes);
993+ ASSERT_EQ(UFStatusSuccess, status);
994+ ASSERT_EQ(0, num_axes);
995+ frame_backend_device_add_axis(device_backend,
996+ UFAxisTypePressure, 1.0f, 1000.0f, 3.5f);
997+ status = frame_device_get_property(device, UFDevicePropertyNumAxes, &num_axes);
998+ ASSERT_EQ(UFStatusSuccess, status);
999+ ASSERT_EQ(1, num_axes);
1000+ UFAxis axis = nullptr;
1001+ status = frame_device_get_axis_by_type(device, UFAxisTypePressure, &axis);
1002+ ASSERT_EQ(UFStatusSuccess, status);
1003+ ASSERT_NE(nullptr, axis);
1004+ ASSERT_EQ(UFAxisTypePressure, frame_axis_get_type(axis));
1005+ ASSERT_EQ(1.0f, frame_axis_get_minimum(axis));
1006+ ASSERT_EQ(1000.0f, frame_axis_get_maximum(axis));
1007+ ASSERT_EQ(3.5f, frame_axis_get_resolution(axis));
1008+
1009+ frame_backend_device_delete(device_backend);
1010+}
1011+
1012+TEST(Backend, Frame)
1013+{
1014+ UFStatus status;
1015+
1016+ UFBackendFrame frame_backend = frame_backend_frame_new();
1017+ ASSERT_NE(nullptr, frame_backend);
1018+
1019+ UFFrame frame = frame_backend_frame_get_frame(frame_backend);
1020+ ASSERT_NE(nullptr, frame);
1021+
1022+ UFBackendDevice device_backend = frame_backend_device_new();
1023+ UFDevice device = frame_backend_device_get_device(device_backend);
1024+
1025+ frame_backend_frame_set_device(frame_backend, device_backend);
1026+ ASSERT_EQ(device, frame_frame_get_device(frame));
1027+
1028+ frame_backend_frame_set_window_id(frame_backend, 123);
1029+ ASSERT_EQ(123, frame_frame_get_window_id(frame));
1030+
1031+
1032+ unsigned int active_touches = 0;
1033+ UFBackendTouch touch_backend = frame_backend_touch_new();
1034+ UFTouch touch = frame_backend_touch_get_touch(touch_backend);
1035+ frame_backend_touch_set_id(touch_backend, 10);
1036+ UFTouch touch_retrieved = nullptr;
1037+ ASSERT_EQ(0, frame_frame_get_num_touches(frame));
1038+ status = frame_frame_get_property(frame, UFFramePropertyActiveTouches, &active_touches);
1039+ ASSERT_EQ(UFStatusSuccess, status);
1040+ ASSERT_EQ(0, active_touches);
1041+ frame_backend_frame_add_touch(frame_backend, touch_backend);
1042+ ASSERT_EQ(1, frame_frame_get_num_touches(frame));
1043+ status = frame_frame_get_property(frame, UFFramePropertyActiveTouches, &active_touches);
1044+ ASSERT_EQ(UFStatusSuccess, status);
1045+ ASSERT_EQ(1, active_touches);
1046+ status = frame_frame_get_touch_by_id(frame, 10, &touch_retrieved);
1047+ ASSERT_EQ(UFStatusSuccess, status);
1048+ ASSERT_EQ(touch, touch_retrieved);
1049+
1050+ frame_backend_frame_set_active_touches(frame_backend, 3);
1051+ status = frame_frame_get_property(frame, UFFramePropertyActiveTouches, &active_touches);
1052+ ASSERT_EQ(UFStatusSuccess, status);
1053+ ASSERT_EQ(3, active_touches);
1054+
1055+ frame_backend_frame_delete(frame_backend);
1056+ frame_backend_device_delete(device_backend);
1057+ frame_backend_touch_delete(touch_backend);
1058+}
1059+
1060+TEST(Backend, Event)
1061+{
1062+ UFStatus status;
1063+
1064+ UFEvent event = frame_event_new();
1065+ ASSERT_NE(nullptr, event);
1066+
1067+ frame_event_set_type(event, UFEventTypeDeviceRemoved);
1068+ ASSERT_EQ(UFEventTypeDeviceRemoved, frame_event_get_type(event));
1069+
1070+ UFBackendDevice device_backend = frame_backend_device_new();
1071+ UFDevice device = frame_backend_device_get_device(device_backend);
1072+ UFDevice device_retrieved = nullptr;
1073+ frame_event_set_device(event, device_backend);
1074+ status = frame_event_get_property(event, UFEventPropertyDevice, &device_retrieved);
1075+ ASSERT_EQ(UFStatusSuccess, status);
1076+ ASSERT_EQ(device, device_retrieved);
1077+
1078+ UFBackendFrame frame_backend = frame_backend_frame_new();
1079+ UFFrame frame = frame_backend_frame_get_frame(frame_backend);
1080+ UFFrame frame_retrieved = nullptr;
1081+ frame_event_set_frame(event, frame_backend);
1082+ status = frame_event_get_property(event, UFEventPropertyFrame, &frame_retrieved);
1083+ ASSERT_EQ(UFStatusSuccess, status);
1084+ ASSERT_EQ(frame, frame_retrieved);
1085+
1086+ frame_event_set_time(event, 1234);
1087+ ASSERT_EQ(1234, frame_event_get_time(event));
1088+
1089+ frame_event_unref(event);
1090+ frame_backend_device_delete(device_backend);
1091+ frame_backend_frame_delete(frame_backend);
1092+}

Subscribers

People subscribed via source and target branches