Removed separate-update-render and single-threaded modes
[platform/core/uifw/dali-adaptor.git] / adaptors / x11 / x-events / debug / x-input2-debug.cpp
1  // EXTERNAL INCLUDES
2 #include <X11/X.h>
3 #include <X11/Xlib.h>
4 #include <X11/extensions/XInput2.h>
5 #include <X11/extensions/XI2.h>
6
7 #ifdef DEBUG_ENABLED
8 #include <dali/integration-api/debug.h>
9 #include <dali/public-api/common/dali-vector.h>
10 #include <ostream>
11 #include <iomanip>
12 #endif
13
14 namespace Dali
15 {
16
17 namespace Internal
18 {
19
20 namespace Adaptor
21 {
22
23 namespace X11Debug
24 {
25
26 #ifdef DEBUG_ENABLED
27
28 namespace
29 {
30
31
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");
34
35 struct XNameId
36 {
37   const char* const name;
38   int id;
39 };
40
41 const XNameId eventTable[]=
42 {
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      }
66 };
67
68 const XNameId deviceTypeTable[]=
69 {
70     { "Master Pointer "    ,XIMasterPointer     },
71     { "Master Keyboard"    ,XIMasterKeyboard    },
72     { "Slave Pointer  "    ,XISlavePointer      },
73     { "Slave Keyboard "    ,XISlaveKeyboard     },
74     { "Floating Slave "    ,XIFloatingSlave     }
75 };
76
77 const XNameId inputClassTable[]=
78 {
79     { "Key"      ,XIKeyClass       },
80     { "Button"   ,XIButtonClass    },
81     { "Valuator" ,XIValuatorClass  },
82     { "Scroll"   ,XIScrollClass    },
83     { "Touch"    ,XITouchClass     }
84 };
85
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] );
89
90 const char* GetEventName( int eventId )
91 {
92   for( unsigned int i = 0; i < numberEvents; ++i )
93   {
94     if( eventTable[i].id == eventId )
95     {
96       return eventTable[i].name;
97     }
98   }
99   return "unknown event";
100 }
101 const char* GetDeviceHierachyName( int deviceType )
102 {
103   for( unsigned int i = 0; i < numberDevices; ++i )
104   {
105     if( deviceTypeTable[i].id == deviceType )
106     {
107       return deviceTypeTable[i].name;
108     }
109   }
110   return "unknown device";
111 }
112 const char* GetInputClassName( int classId )
113 {
114   for( unsigned int i = 0; i < numberInputClasses; ++i )
115   {
116     if( inputClassTable[i].id == classId )
117     {
118       return inputClassTable[i].name;
119     }
120   }
121   return "unknown input class name";
122 }
123
124 std::string GetInputDeviceInfo( const XIDeviceInfo* device, bool master )
125 {
126   // formatted output similar to xinput -list except it includes class + source information
127   int startWidth = 45;
128
129   std::string slavePadding="  ↳ ";
130   if( master )
131   {
132     // slave entries are shifted to the right
133     startWidth += 4;
134     slavePadding="";
135   }
136
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: ";
142
143   for( int n = 0; n < device->num_classes; ++n )
144   {
145     XIAnyClassInfo *classInfo = device->classes[n];
146     oss << GetInputClassName( classInfo->type ) << ", source ( "<< classInfo->sourceid << ")";
147   }
148   oss << "\n";
149
150   return oss.str();
151 }
152
153
154 }// unanmed namespace
155
156 void LogInputDeviceInfo( const XIDeviceInfo* devices, unsigned int numberOfDevices )
157 {
158   // early exit if the filter is not enabled in debug mode
159   if( ! gInputDeviceLogFilter->IsEnabledFor( Debug::General ) )
160   {
161     return;
162   }
163
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;
170
171   // go through the device list and sort by type
172   for( unsigned int i = 0; i < numberOfDevices; ++i, ++device )
173   {
174     switch( device->use )
175     {
176       case XIMasterPointer:
177       {
178         masterPointer = device;
179         break;
180       }
181       case XIMasterKeyboard:
182       {
183         masterKeyboard = device;
184         break;
185       }
186       case XISlavePointer:
187       {
188         slavePointers.PushBack( device );
189         break;
190       }
191       case XISlaveKeyboard:
192       {
193         slaveKeyboards.PushBack( device );
194         break;
195       }
196       case XIFloatingSlave:
197       {
198         floatingSlaves.PushBack( device );
199         break;
200       }
201       default:
202       {
203         break;
204       }
205     }
206   }
207
208   std::ostringstream oss;
209
210   oss << "\n" << GetInputDeviceInfo( masterKeyboard , true);
211   for( VectorBase::SizeType i = 0; i < slaveKeyboards.Count(); ++i )
212   {
213     oss << GetInputDeviceInfo( slaveKeyboards[i], false );
214   }
215   oss <<  "\n" << GetInputDeviceInfo( masterPointer, true );
216   for( VectorBase::SizeType i = 0; i < slavePointers.Count(); ++i )
217   {
218     oss << GetInputDeviceInfo( slavePointers[i], false);
219   }
220   for( VectorBase::SizeType i = 0; i < floatingSlaves.Count(); ++i )
221   {
222     oss <<  GetInputDeviceInfo( floatingSlaves[i], false );
223   }
224
225  // DALI_LOG_ERROR_NOFN( "%s \n",oss.str().c_str() );
226   DALI_LOG_INFO( gInputDeviceLogFilter, Debug::General, "%s\n", oss.str().c_str() );
227 }
228
229 void LogXI2Event( XGenericEventCookie* cookie )
230 {
231   // early exit if the filter is not enabled
232   if( ! gInputEventLogFilter->IsEnabledFor( Debug::General ) )
233   {
234     return;
235   }
236
237   std::ostringstream oss;
238   oss << "XI2 event:" << GetEventName( cookie->evtype );
239
240   XIDeviceEvent *event = static_cast< XIDeviceEvent* >(cookie->data);
241
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)
245   {
246     oss << "base " << event->mods.base << "latched " << event->mods.latched;
247     oss << "locked " << event->mods.locked << "effective " << event->mods.effective;
248
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
257
258   }
259
260    // Mouse button state
261   oss << " button state\n";
262   for( int i =0; i< event->buttons.mask_len ; i++)
263   {
264     oss << "," << int(event->buttons.mask[i]);
265   }
266
267  // DALI_LOG_ERROR_NOFN( "%s \n",oss.str().c_str() );
268   DALI_LOG_INFO( gInputEventLogFilter, Debug::General, "%s\n", oss.str().c_str() );
269
270 }
271
272
273
274 #else
275
276 void LogInputDeviceInfo( const XIDeviceInfo* devices, unsigned int numberOfDevices)
277 {
278 }
279 void LogXI2Event( XGenericEventCookie* cookie )
280 {
281 }
282
283 #endif
284
285
286 } // X11 Debug
287 } // namespace Adaptor
288 } // namespace Internal
289 } // namespace Dali