1
/*****************************************************************************
3
* utouch-frame - Touch Frame Library
5
* Copyright (C) 2011 Canonical Ltd.
7
* This program is free software: you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation, either version 3 of the License, or (at your
10
* option) any later version.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* General Public License for more details.
17
* You should have received a copy of the GNU General Public License along
18
* with this program. If not, see <http://www.gnu.org/licenses/>.
20
****************************************************************************/
22
#include "v2/x11/window_x11.h"
26
#include "utouch/frame_x11.h"
30
#include "v2/x11/device_x11.h"
35
WindowX11::WindowX11(::Window window, const SharedUFDevice& device,
39
device_(static_cast<UFDeviceX11*>(device.get())) {
44
void CopyOldValue(const UFFrame* frame, UFTouch* touch, UFAxisType type) {
48
status = frame->GetPreviousTouchValue(touch, type, &value);
49
if (status != UFStatusSuccess) {
50
fprintf(stderr, "Warning: failed to get previous touch value\n");
54
touch->SetValue(type, value);
59
bool WindowX11::HandleDeviceEvent(const XIDeviceEvent* event,
60
SharedUFFrame* frame) {
62
switch (event->evtype) {
64
state = UFTouchStateBegin;
68
case XI_TouchUpdateUnowned:
69
state = UFTouchStateUpdate;
73
state = UFTouchStateEnd;
80
*frame = SharedUFFrame(new UFFrame(shared_from_this(), current_frame_));
82
const Value* value = new Value(frame_x11_create_window_id(window_));
83
(*frame)->InsertProperty(UFFramePropertyWindowId, value);
84
value = new Value(device_->shared_from_this());
85
(*frame)->InsertProperty(UFFramePropertyDevice, value);
87
UFTouchId touch_id = frame_x11_create_touch_id(event->detail);
88
std::shared_ptr<UFTouch> touch(new UFTouch(state, touch_id, event->event_x,
89
event->event_y, event->time));
91
if (event->evtype == XI_TouchBegin) {
92
value = new Value(false);
93
touch->InsertProperty(UFTouchPropertyOwned, value);
95
bool owned = current_frame_->IsTouchOwned(touch_id);
96
value = new Value(owned);
97
touch->InsertProperty(UFTouchPropertyOwned, value);
100
value = new Value(event->flags & XITouchPendingEnd);
101
touch->InsertProperty(UFTouchPropertyPendingEnd, value);
106
i < event->valuators.mask_len * 8 &&
107
i < static_cast<int>(device_->axis_map().size());
109
UFAxisType type = device_->axis_map().find(i)->second;
110
if (XIMaskIsSet(event->valuators.mask, i))
111
touch->SetValue(type, event->valuators.values[j++]);
113
CopyOldValue(frame->get(), touch.get(), type);
116
for (; i < static_cast<int>(device_->axis_map().size()); ++i) {
117
UFAxisType type = device_->axis_map().find(i)->second;
118
CopyOldValue(frame->get(), touch.get(), type);
121
(*frame)->UpdateTouch(touch);
123
current_frame_ = *frame;
128
bool WindowX11::HandleOwnershipEvent(const XITouchOwnershipEvent* event,
129
SharedUFFrame* frame) {
130
*frame = SharedUFFrame(new UFFrame(shared_from_this(), current_frame_));
132
const Value* value = new Value(frame_x11_create_window_id(window_));
133
(*frame)->InsertProperty(UFFramePropertyWindowId, value);
134
value = new Value(device_->shared_from_this());
135
(*frame)->InsertProperty(UFFramePropertyDevice, value);
137
UFTouch* touch = (*frame)->CopyTouch(event->touchid, UFTouchStateUpdate);
141
value = new Value(event->time);
142
touch->InsertProperty(UFTouchPropertyTime, value);
143
value = new Value(true);
144
touch->InsertProperty(UFTouchPropertyOwned, value);
146
(*frame)->UpdateTouch(SharedUFTouch(touch));
148
current_frame_ = *frame;
150
if (accepted_touches_.count(event->touchid)) {
151
XIAllowTouchEvents(display_, device_->id(), event->touchid,
153
accepted_touches_.erase(event->touchid);
154
} else if (rejected_touches_.count(event->touchid)) {
155
XIAllowTouchEvents(display_, device_->id(), event->touchid,
156
XITouchOwnerRejectEnd);
157
rejected_touches_.erase(event->touchid);
163
UFStatus WindowX11::AcceptTouch(UFTouchId touch_id) {
164
if (current_frame_->IsTouchOwned(touch_id)) {
165
if (XIAllowTouchEvents(display_, device_->id(), touch_id,
167
return UFStatusErrorGeneric;
169
/* Flush output buffer so touches are actually accepted ASAP. The server
170
* can't perform pointer emulation while the currently emulated touch is
171
* still potentially active for pointer emulation. */
174
accepted_touches_.insert(touch_id);
177
return UFStatusSuccess;
180
UFStatus WindowX11::RejectTouch(UFTouchId touch_id) {
181
if (current_frame_->IsTouchOwned(touch_id)) {
182
if (XIAllowTouchEvents(display_, device_->id(), touch_id,
183
XITouchOwnerRejectEnd))
184
return UFStatusErrorGeneric;
186
/* Flush output buffer so touches are actually rejected ASAP. The server
187
* can't perform pointer emulation while the currently emulated touch is
188
* still potentially active for pointer emulation. */
191
rejected_touches_.insert(touch_id);
194
return UFStatusSuccess;
198
} // namespace utouch