4 #include <X11/extensions/XInput2.h>
5 #include <X11/extensions/XI2.h>
8 #include <dali/integration-api/debug.h>
9 #include <dali/public-api/common/dali-vector.h>
32 Integration::Log::Filter* gInputDeviceLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_X_INPUT_DEVICES");
33 Integration::Log::Filter* gInputEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_X_INPUT_EVENTS");
37 const char* const name;
41 const XNameId eventTable[]=
43 { "XI_KeyPress" ,XI_KeyPress },
44 { "XI_KeyRelease" ,XI_KeyRelease },
45 { "XI_ButtonPress" ,XI_ButtonPress },
46 { "XI_ButtonRelease" ,XI_ButtonRelease },
47 { "XI_Motion" ,XI_Motion },
48 { "XI_Enter" ,XI_Enter },
49 { "XI_Leave" ,XI_Leave },
50 { "XI_FocusIn" ,XI_FocusIn },
51 { "XI_FocusOut" ,XI_FocusOut },
52 { "XI_HierarchyChanged",XI_HierarchyChanged },
53 { "XI_PropertyEvent" ,XI_PropertyEvent },
54 { "XI_RawKeyPress" ,XI_RawKeyPress },
55 { "XI_RawKeyRelease" ,XI_RawKeyRelease },
56 { "XI_RawButtonPress" ,XI_RawButtonPress },
57 { "XI_RawButtonRelease",XI_RawButtonRelease },
58 { "XI_RawMotion" ,XI_RawMotion },
59 { "XI_TouchBegin" ,XI_TouchBegin },
60 { "XI_TouchUpdate" ,XI_TouchUpdate },
61 { "XI_TouchEnd" ,XI_TouchEnd },
62 { "XI_TouchOwnership" ,XI_TouchOwnership },
63 { "XI_RawTouchBegin" ,XI_RawTouchBegin },
64 { "XI_RawTouchUpdate" ,XI_RawTouchUpdate },
65 { "XI_RawTouchEnd" ,XI_RawTouchEnd }
68 const XNameId deviceTypeTable[]=
70 { "Master Pointer " ,XIMasterPointer },
71 { "Master Keyboard" ,XIMasterKeyboard },
72 { "Slave Pointer " ,XISlavePointer },
73 { "Slave Keyboard " ,XISlaveKeyboard },
74 { "Floating Slave " ,XIFloatingSlave }
77 const XNameId inputClassTable[]=
79 { "Key" ,XIKeyClass },
80 { "Button" ,XIButtonClass },
81 { "Valuator" ,XIValuatorClass },
82 { "Scroll" ,XIScrollClass },
83 { "Touch" ,XITouchClass }
86 const unsigned int numberEvents = sizeof( eventTable ) / sizeof( eventTable[0] );
87 const unsigned int numberDevices = sizeof( deviceTypeTable ) / sizeof( deviceTypeTable[0] );
88 const unsigned int numberInputClasses = sizeof( inputClassTable ) / sizeof( inputClassTable[0] );
90 const char* GetEventName( int eventId )
92 for( unsigned int i = 0; i < numberEvents; ++i )
94 if( eventTable[i].id == eventId )
96 return eventTable[i].name;
99 return "unknown event";
101 const char* GetDeviceHierachyName( int deviceType )
103 for( unsigned int i = 0; i < numberDevices; ++i )
105 if( deviceTypeTable[i].id == deviceType )
107 return deviceTypeTable[i].name;
110 return "unknown device";
112 const char* GetInputClassName( int classId )
114 for( unsigned int i = 0; i < numberInputClasses; ++i )
116 if( inputClassTable[i].id == classId )
118 return inputClassTable[i].name;
121 return "unknown input class name";
124 std::string GetInputDeviceInfo( const XIDeviceInfo* device, bool master )
126 // formatted output similar to xinput -list except it includes class + source information
129 std::string slavePadding=" ↳ ";
132 // slave entries are shifted to the right
137 std::ostringstream oss;
138 oss << "⎜" << slavePadding << std::setw(startWidth) << std::left << device->name ;
139 oss << std::setw(1) << " id= " << std::setw(1) << device->deviceid ;
140 oss << "\t[" << GetDeviceHierachyName( device->use ) << " ("<< device->attachment << ") ]";
141 oss << std::setw(1) << "\t Classes: ";
143 for( int n = 0; n < device->num_classes; ++n )
145 XIAnyClassInfo *classInfo = device->classes[n];
146 oss << GetInputClassName( classInfo->type ) << ", source ( "<< classInfo->sourceid << ")";
154 }// unanmed namespace
156 void LogInputDeviceInfo( const XIDeviceInfo* devices, unsigned int numberOfDevices )
158 // early exit if the filter is not enabled in debug mode
159 if( ! gInputDeviceLogFilter->IsEnabledFor( Debug::General ) )
164 const XIDeviceInfo* device = devices;
165 const XIDeviceInfo* masterKeyboard = NULL;
166 const XIDeviceInfo* masterPointer = NULL;
167 Dali::Vector< const XIDeviceInfo* > slaveKeyboards;
168 Dali::Vector< const XIDeviceInfo* > slavePointers;
169 Dali::Vector< const XIDeviceInfo* > floatingSlaves;
171 // go through the device list and sort by type
172 for( unsigned int i = 0; i < numberOfDevices; ++i, ++device )
174 switch( device->use )
176 case XIMasterPointer:
178 masterPointer = device;
181 case XIMasterKeyboard:
183 masterKeyboard = device;
188 slavePointers.PushBack( device );
191 case XISlaveKeyboard:
193 slaveKeyboards.PushBack( device );
196 case XIFloatingSlave:
198 floatingSlaves.PushBack( device );
208 std::ostringstream oss;
210 oss << "\n" << GetInputDeviceInfo( masterKeyboard , true);
211 for( VectorBase::SizeType i = 0; i < slaveKeyboards.Count(); ++i )
213 oss << GetInputDeviceInfo( slaveKeyboards[i], false );
215 oss << "\n" << GetInputDeviceInfo( masterPointer, true );
216 for( VectorBase::SizeType i = 0; i < slavePointers.Count(); ++i )
218 oss << GetInputDeviceInfo( slavePointers[i], false);
220 for( VectorBase::SizeType i = 0; i < floatingSlaves.Count(); ++i )
222 oss << GetInputDeviceInfo( floatingSlaves[i], false );
225 // DALI_LOG_ERROR_NOFN( "%s \n",oss.str().c_str() );
226 DALI_LOG_INFO( gInputDeviceLogFilter, Debug::General, "%s\n", oss.str().c_str() );
229 void LogXI2Event( XGenericEventCookie* cookie )
231 // early exit if the filter is not enabled
232 if( ! gInputEventLogFilter->IsEnabledFor( Debug::General ) )
237 std::ostringstream oss;
238 oss << "XI2 event:" << GetEventName( cookie->evtype );
240 XIDeviceEvent *event = static_cast< XIDeviceEvent* >(cookie->data);
242 oss << ", device_id("<< event->deviceid << ") source_id( "<< event->sourceid << ")" << ", flags: " << event->flags;
243 oss << ", root-window: " << event->root << ", event-window: "<< event->event << ", child-window:" << event->child;
244 if( cookie->evtype == XI_KeyPress)
246 oss << "base " << event->mods.base << "latched " << event->mods.latched;
247 oss << "locked " << event->mods.locked << "effective " << event->mods.effective;
249 if( event->mods.effective & ShiftMask) oss << "Shift";
250 if( event->mods.effective & LockMask) oss << "LockMask"; // caps lock
251 if( event->mods.effective & ControlMask) oss << "ControlMask";
252 if( event->mods.effective & Mod1Mask) oss << "Mod1Mask"; // alt
253 if( event->mods.effective & Mod2Mask) oss << "Mod2Mask"; // num lock
254 if( event->mods.effective & Mod3Mask) oss << "Mod3Mask";
255 if( event->mods.effective & Mod4Mask) oss << "Mod4Mask"; // WINDOWS
256 if( event->mods.effective & Mod5Mask) oss << "Mod5Mask"; // Alt gr
260 // Mouse button state
261 oss << " button state\n";
262 for( int i =0; i< event->buttons.mask_len ; i++)
264 oss << "," << int(event->buttons.mask[i]);
267 // DALI_LOG_ERROR_NOFN( "%s \n",oss.str().c_str() );
268 DALI_LOG_INFO( gInputEventLogFilter, Debug::General, "%s\n", oss.str().c_str() );
276 void LogInputDeviceInfo( const XIDeviceInfo* devices, unsigned int numberOfDevices)
279 void LogXI2Event( XGenericEventCookie* cookie )
287 } // namespace Adaptor
288 } // namespace Internal