1 /*
2 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
4
5 All rights reserved.
6
7 Written by Denis Oliver Kropp <dok@directfb.org>,
8 Andreas Hundt <andi@fischlustig.de>,
9 Sven Neumann <neo@directfb.org>,
10 Ville Syrjälä <syrjala@sci.fi> and
11 Claudio Ciccani <klan@users.sf.net>.
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27 */
28
29 #include <config.h>
30
31 #include <directfb.h>
32
33 #include <direct/debug.h>
34 #include <direct/messages.h>
35 #include <direct/util.h>
36
37 #include <core/gfxcard.h>
38 #include <core/state.h>
39 #include <core/windows_internal.h>
40
41 #include <misc/util.h>
42
43 #include <unique/context.h>
44 #include <unique/device.h>
45 #include <unique/internal.h>
46
47
48 D_DEBUG_DOMAIN( UniQuE_Pointer, "UniQuE/Pointer", "UniQuE's Pointer Device Class" );
49
50
51 typedef struct {
52 int magic;
53
54 int x;
55 int y;
56 } PointerData;
57
58 /**************************************************************************************************/
59
60 static DFBResult
pointer_initialize(UniqueDevice * device,void * data,void * ctx)61 pointer_initialize( UniqueDevice *device,
62 void *data,
63 void *ctx )
64 {
65 PointerData *pointer = data;
66
67 D_MAGIC_ASSERT( device, UniqueDevice );
68
69 D_DEBUG_AT( UniQuE_Pointer, "pointer_initialize( %p, %p, %p )\n", device, data, ctx );
70
71 D_MAGIC_SET( pointer, PointerData );
72
73 return DFB_OK;
74 }
75
76 static void
pointer_shutdown(UniqueDevice * device,void * data,void * ctx)77 pointer_shutdown( UniqueDevice *device,
78 void *data,
79 void *ctx )
80 {
81 PointerData *pointer = data;
82
83 D_MAGIC_ASSERT( device, UniqueDevice );
84 D_MAGIC_ASSERT( pointer, PointerData );
85
86 D_DEBUG_AT( UniQuE_Pointer, "pointer_shutdown( %p, %p, %p )\n", device, data, ctx );
87
88 D_MAGIC_CLEAR( pointer );
89 }
90
91 static void
pointer_connected(UniqueDevice * device,void * data,void * ctx,CoreInputDevice * source)92 pointer_connected( UniqueDevice *device,
93 void *data,
94 void *ctx,
95 CoreInputDevice *source )
96 {
97 PointerData *pointer = data;
98
99 (void) pointer;
100
101 D_MAGIC_ASSERT( device, UniqueDevice );
102 D_MAGIC_ASSERT( pointer, PointerData );
103
104 D_ASSERT( source != NULL );
105
106 D_DEBUG_AT( UniQuE_Pointer, "pointer_connected( %p, %p, %p, %p )\n",
107 device, data, ctx, source );
108 }
109
110 static void
pointer_disconnected(UniqueDevice * device,void * data,void * ctx,CoreInputDevice * source)111 pointer_disconnected( UniqueDevice *device,
112 void *data,
113 void *ctx,
114 CoreInputDevice *source )
115 {
116 PointerData *pointer = data;
117
118 (void) pointer;
119
120 D_MAGIC_ASSERT( device, UniqueDevice );
121 D_MAGIC_ASSERT( pointer, PointerData );
122
123 D_ASSERT( source != NULL );
124
125 D_DEBUG_AT( UniQuE_Pointer, "pointer_disconnected( %p, %p, %p, %p )\n",
126 device, data, ctx, source );
127 }
128
129 static void
pointer_process_event(UniqueDevice * device,void * data,void * ctx,const DFBInputEvent * event)130 pointer_process_event( UniqueDevice *device,
131 void *data,
132 void *ctx,
133 const DFBInputEvent *event )
134 {
135 UniqueInputEvent evt;
136 PointerData *pointer = data;
137 UniqueContext *context = ctx;
138 CoreWindowStack *stack;
139
140 D_MAGIC_ASSERT( device, UniqueDevice );
141 D_MAGIC_ASSERT( pointer, PointerData );
142 D_MAGIC_ASSERT( context, UniqueContext );
143
144 D_ASSERT( event != NULL );
145
146 D_DEBUG_AT( UniQuE_Pointer, "pointer_process_event( %p, %p, %p, %p ) <- type 0x%08x\n",
147 device, data, ctx, event, event->type );
148
149 stack = context->stack;
150
151 D_ASSERT( stack != NULL );
152
153 switch (event->type) {
154 case DIET_AXISMOTION: {
155 /*int x = pointer->x;
156 int y = pointer->y;*/
157 int x = stack->cursor.x;
158 int y = stack->cursor.y;
159
160 if (event->flags & DIEF_AXISREL) {
161 int rel = event->axisrel;
162
163 /* handle cursor acceleration */
164 if (rel > stack->cursor.threshold)
165 rel += (rel - stack->cursor.threshold)
166 * stack->cursor.numerator
167 / stack->cursor.denominator;
168 else if (rel < -stack->cursor.threshold)
169 rel += (rel + stack->cursor.threshold)
170 * stack->cursor.numerator
171 / stack->cursor.denominator;
172
173 switch (event->axis) {
174 case DIAI_X:
175 x += rel;
176 break;
177
178 case DIAI_Y:
179 y += rel;
180 break;
181
182 default:
183 return;
184 }
185 }
186 else if (event->flags & DIEF_AXISABS) {
187 switch (event->axis) {
188 case DIAI_X:
189 x = event->axisabs;
190 break;
191
192 case DIAI_Y:
193 y = event->axisabs;
194 break;
195
196 default:
197 return;
198 }
199 }
200 else
201 return;
202
203 if (x < 0)
204 x = 0;
205 else if (x >= context->width)
206 x = context->width - 1;
207
208 if (y < 0)
209 y = 0;
210 else if (y >= context->height)
211 y = context->height - 1;
212
213 if (x == pointer->x && y == pointer->y)
214 return;
215
216 pointer->x = x;
217 pointer->y = y;
218
219 evt.type = UIET_MOTION;
220
221 evt.pointer.device_id = event->device_id;
222 evt.pointer.x = x;
223 evt.pointer.y = y;
224 evt.pointer.buttons = event->buttons;
225
226 unique_device_dispatch( device, &evt );
227 break;
228 }
229
230 case DIET_BUTTONPRESS:
231 case DIET_BUTTONRELEASE:
232 evt.type = UIET_BUTTON;
233
234 evt.pointer.device_id = event->device_id;
235 evt.pointer.press = (event->type == DIET_BUTTONPRESS);
236 evt.pointer.x = pointer->x;
237 evt.pointer.y = pointer->y;
238 evt.pointer.button = event->button;
239 evt.pointer.buttons = event->buttons;
240
241 unique_device_dispatch( device, &evt );
242 break;
243
244 default:
245 break;
246 }
247 }
248
249
250 const UniqueDeviceClass unique_pointer_device_class = {
251 data_size: sizeof(PointerData),
252
253 Initialize: pointer_initialize,
254 Shutdown: pointer_shutdown,
255 Connected: pointer_connected,
256 Disconnected: pointer_disconnected,
257 ProcessEvent: pointer_process_event
258 };
259
260