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 <fusion/shmalloc.h>
38 #include <fusion/vector.h>
39 
40 #include <core/core.h>
41 #include <core/layers_internal.h>
42 #include <core/windows_internal.h>
43 
44 #include <unique/device.h>
45 #include <unique/internal.h>
46 #include <unique/input_channel.h>
47 
48 
49 D_DEBUG_DOMAIN( UniQuE_InputChan, "UniQuE/InputChan", "UniQuE's Input Channel" );
50 
51 
52 static const ReactionFunc unique_input_channel_globals[] = {
53      _unique_window_input_channel_listener,
54      NULL
55 };
56 
57 /**************************************************************************************************/
58 
59 DFBResult
unique_input_channel_create(CoreDFB * core,UniqueContext * context,UniqueInputChannel ** ret_channel)60 unique_input_channel_create( CoreDFB             *core,
61                              UniqueContext       *context,
62                              UniqueInputChannel **ret_channel )
63 {
64      UniqueInputChannel *channel;
65 
66      D_DEBUG_AT( UniQuE_InputChan, "unique_input_channel_create( context %p )\n", context );
67 
68      D_MAGIC_ASSERT( context, UniqueContext );
69 
70      D_ASSERT( ret_channel != NULL );
71 
72      /* Allocate channel data. */
73      channel = SHCALLOC( context->shmpool, 1, sizeof(UniqueInputChannel) );
74      if (!channel) {
75           D_WARN( "out of (shared) memory" );
76           return D_OOSHM();
77      }
78 
79      /* Initialize channel data. */
80      channel->context = context;
81 
82      /* Create reactor for dispatching events. */
83      channel->reactor = fusion_reactor_new( sizeof(UniqueInputEvent),
84                                             "UniQuE Input Channel", dfb_core_world(core) );
85      if (!channel->reactor) {
86           SHFREE( context->shmpool, channel );
87           return DFB_FUSION;
88      }
89 
90      fusion_reactor_set_lock( channel->reactor, &context->stack->context->lock );
91 
92      D_MAGIC_SET( channel, UniqueInputChannel );
93 
94      D_DEBUG_AT( UniQuE_InputChan, "  -> channel created (%p)\n", channel );
95 
96      *ret_channel = channel;
97 
98      return DFB_OK;
99 }
100 
101 DFBResult
unique_input_channel_destroy(UniqueInputChannel * channel)102 unique_input_channel_destroy( UniqueInputChannel *channel )
103 {
104      UniqueContext *context;
105 
106      D_MAGIC_ASSERT( channel, UniqueInputChannel );
107 
108      context = channel->context;
109 
110      D_MAGIC_ASSERT( context, UniqueContext );
111 
112      D_DEBUG_AT( UniQuE_InputChan, "unique_input_channel_destroy( %p )\n", channel );
113 
114      fusion_reactor_free( channel->reactor );
115 
116      D_MAGIC_CLEAR( channel );
117 
118      SHFREE( context->shmpool, channel );
119 
120      return DFB_OK;
121 }
122 
123 
124 DFBResult
unique_input_channel_attach(UniqueInputChannel * channel,ReactionFunc func,void * ctx,Reaction * reaction)125 unique_input_channel_attach( UniqueInputChannel *channel,
126                              ReactionFunc        func,
127                              void               *ctx,
128                              Reaction           *reaction )
129 {
130      D_MAGIC_ASSERT( channel, UniqueInputChannel );
131 
132      return fusion_reactor_attach( channel->reactor, func, ctx, reaction );
133 }
134 
135 DFBResult
unique_input_channel_detach(UniqueInputChannel * channel,Reaction * reaction)136 unique_input_channel_detach( UniqueInputChannel *channel,
137                              Reaction           *reaction )
138 {
139      D_MAGIC_ASSERT( channel, UniqueInputChannel );
140 
141      return fusion_reactor_detach( channel->reactor, reaction );
142 }
143 
144 DFBResult
unique_input_channel_attach_global(UniqueInputChannel * channel,int index,void * ctx,GlobalReaction * reaction)145 unique_input_channel_attach_global( UniqueInputChannel *channel,
146                                     int                 index,
147                                     void               *ctx,
148                                     GlobalReaction     *reaction )
149 {
150      D_MAGIC_ASSERT( channel, UniqueInputChannel );
151 
152      return fusion_reactor_attach_global( channel->reactor, index, ctx, reaction );
153 }
154 
155 DFBResult
unique_input_channel_detach_global(UniqueInputChannel * channel,GlobalReaction * reaction)156 unique_input_channel_detach_global( UniqueInputChannel *channel,
157                                     GlobalReaction     *reaction )
158 {
159      D_MAGIC_ASSERT( channel, UniqueInputChannel );
160 
161      return fusion_reactor_detach_global( channel->reactor, reaction );
162 }
163 
164 DFBResult
unique_input_channel_dispatch(UniqueInputChannel * channel,const UniqueInputEvent * event)165 unique_input_channel_dispatch( UniqueInputChannel     *channel,
166                                const UniqueInputEvent *event )
167 {
168      D_MAGIC_ASSERT( channel, UniqueInputChannel );
169 
170      D_ASSERT( event != NULL );
171 
172      D_DEBUG_AT( UniQuE_InputChan, "unique_input_channel_dispatch( %p, %p ) <- type 0x%08x\n",
173                  channel, event, event->type );
174 
175      switch (event->type) {
176           case UIET_MOTION:
177                D_DEBUG_AT( UniQuE_InputChan, "  -> MOTION   %d, %d, buttons 0x%04x\n",
178                            event->pointer.x, event->pointer.y, event->pointer.buttons );
179                break;
180           case UIET_BUTTON:
181                D_DEBUG_AT( UniQuE_InputChan, "  -> BUTTON   %d, %d, buttons 0x%04x, button %d, %s\n",
182                            event->pointer.x, event->pointer.y,
183                            event->pointer.buttons, event->pointer.button,
184                            event->pointer.press ? "pressed" : "released" );
185                break;
186           case UIET_WHEEL:
187                D_DEBUG_AT( UniQuE_InputChan, "  -> WHEEL    %d\n", event->wheel.value );
188                break;
189           case UIET_KEY:
190                D_DEBUG_AT( UniQuE_InputChan, "  -> KEY      0x%08x, modifiers 0x%04x, %s\n",
191                            event->keyboard.key_symbol, event->keyboard.modifiers,
192                            event->keyboard.press ? "pressed" : "released" );
193                break;
194           case UIET_CHANNEL:
195                D_DEBUG_AT( UniQuE_InputChan, "  -> CHANNEL  %d, %d, index %d, %s\n",
196                            event->channel.x, event->channel.y, event->channel.index,
197                            event->channel.selected ? "selected" : "deselected" );
198                break;
199           default:
200                D_DEBUG_AT( UniQuE_InputChan, "  -> unknown type 0x%08x\n", event->type );
201                break;
202      }
203 
204      return fusion_reactor_dispatch( channel->reactor, event, true, unique_input_channel_globals );
205 }
206 
207