aboutsummaryrefslogblamecommitdiffstats
path: root/src/lib/ecore_x/ecore_x_events.c
blob: 11d098826e460effca1b2ab457dc6f3576bed8c9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                    
                                

                   
                  
                   
 

                     
                  
                          

                            
                          
 





                                   
                           
 


                                       






                                 



                            

                                                                

                                                         



                                        
















                                                                     
                             


                                              





                                    


                                  











                                                  
                        



                                                     
                                                  


                                     
 
           
                                                      
                                        





                                      

                                                    
      
 
           
 
 
         
                                        
                                               
 
                          
                               
 
                                           


                                             
          
                                          
 

                                                 
                                        

                                                                   
                                        
 
 
         
                                          
                                                 



                               
                                           


                                             
          
                                          
 

                                                 
                                        

                                                                   
                                        
 
 
           
                                                      
                                        
 

                               

          
                                     
                        
                  
           
 
 
           
                                                            
                                              
 
                                     
                               

          
                 
                 
                    
 
                   
           
 
 


                                            


                                      
                                             

                                     
                                            
 
                                    
                                           

                                    
                                           
 

                                             
 
                                   
                                          

                                
                                       

                                 
                                        
 
                                  
                                         
 
                    
 
 
    

                                          



                             


                                            









                                  



                             
                                                 
          
            












                                                       









                                       




                                                          






                                                
 

           
                                                                       


















                                               
                                                  




                             
























                                                                                              
                           
                                   
 
                      
                        

                    
                    

                            
                        
                         
           
                                         
 
                                      


                                                                        

                




                                        
      
 

                  


                                              
                             
                                





                                 
               



                                                                 


                                                                       

                      
 





                                                                  
          
                   
 
                                

                                                        

                          
                                       
                               
               
                                         







                                                                      
                                




                                           

           
               
 
 
                          
                              


                                            



                               


                                              









                                    


                               
                                                   
          
                 















                                                       


                                                                          
      











                                                                                                 

                                                       
           









                                                        
                






























                                                                       
                
                                                           
                



                                            
                
           
      
 


                                                                          
                   
                                                

                           
                                  
      
 









                                       
 






                                           












                                                                   
            
 

    

                                               
                                       
                   
                                      
                                                      
 

    
                                               
 
                                                               
 
 


                                                 
                                                             
 



                                                  
         
 

                                                                                                                                                                    
                                      
                                                                    
      

                                   
                                                       
               
                 












                                                                       
                                                      
           






                                           
                                                
            
                                             












                                                                

                                                                           



                                                     



                                                            

                             

                                                                      
                      

                                                                     



                        


       








                                                                            




                                                                             





                                       
                   

                                                                              

















                                                                 
           
                                       
        




                                                           

                                                          

                                                                                


















                                                                           
         
      
 



                                                    
                                      
                                                                                                                                                                      
                                 
                                                                     
      







                                                                         




                                                                          
 









                                                                           




                                                                            
      
 



                                                   
  





                                                              
   



















                                                                             
 



                                                  
                                      



















                                                                            
               






                                                                       
                                             
          
                                          





                                                     
                                            
                                                    
                                          
                                                      
                                            

                                                     
                                                  
                                                         
                                                 
                                                          
                                                  
                                                           
                                                    
                                                                  
                                                            




                                                             
 



                                                  
                                      



















                                                                            
               






                                                                       
                                             
          
                                          





                                                     
                                            
                                                    
                                          
                                                      
                                            

                                                     
                                                  
                                                         
                                                 
                                                          
                                                  
                                                           
                                                    
                                                                  
                                                            







                                                              
 




                                              
 
                                      
 
                                                        
          
            
 
                                  
 
                                           
                                         
                                                      
                                                
                                              
                                       
                                                
                                         

                                               
                                               
                                                   
                                              
                                                    
                                               
                                                     
                                                 
                                                            
                                                         
                                                   
                                              
                                                       
                                                   
                                                      
                                                  
 
                                      
                                                                 
 




                                               
 
                                      
 
                                                         
          
            
 
                                  
 
                                           
                                         
                                                      
                                                
                                              
                                       
                                                
                                         

                                               
                                               
                                                   
                                              
                                                    
                                               
                                                     
                                                 
                                                            
                                                         
                                                   
                                              
                                                       
                                                   
                                                      
                                                  
 
                                      
                                                                  
 

    
                                                               
 
                                      
                                      
 




                                            
 
                                      
                                                      
          
            
 





                                      
                                    
                                                               
 




                                                     
 
                                      
                                                      
          
            
 





                                             
                                            
                                                               
 



                                                       
                                      
                                                                  

                                                
 
                                                                    
             
               
 


                                                               
                              
          
                              
 
                                                                             
    
 





                                                   
                                      
                                                      
          
            
 
                                         
                                            
                                               
                     
       
                     
 




                                                  
                                      
                                                               
 




                                                    
 
                                      
                                                       
          
            

                                          
                                               
                                      
                                         
                                 
 
                                                                

                                                         
 




                                                  
 
                                      
                                                    
          
            
 
                                  
                                       
                                      
                                             
                                                             
 




                                                
 
                                      
                                                    
          
            
 
                                
                                     
                                      
                                                             
 




                                                 
 
                                      
                                                            
          
            
 
                                       
                                      
                                          
                                                                     
 




                                                     
 
                                      
                                                        
          
            
 
                                     
                                          

                                        
                                                                 
 




                                                      
 
                                      
                                                         
          
            
 
                                      
                                           








                                                      
                                                                  
 



                                                       

                                             
                                      
                                                                 
          
            
 
                                             
                                                    







                                                        
 
                                                 
                                            
                                                      
                                            
                                                      
                                             
                                                         
                                                
                                                         
                                               
 
                                                                          
 

    
                                                                
 
                                      
                                      
 



                                                    

                                          
                                      
                                                              
          
            
 



                                          
                                                                       
 

    
                                                      
 
                                 
 
                                      
                                                     
          
            
 


                                              
                                            
       
                                            
 
                                      
                                                              
 

    
                                                       
 
                                         
 
                                      
                                                             
          
            
 


                                                     
                                            
       
                                            
 
                                      
                                                                      
 



                                                     
                                      


                                       
                                                           
             
               
 


                                        
                                           
                                         
                                                                    
    
 



                                                     
                               

                                    
 

                                           
                                                                 

                                                              
                                                     
      

                                                                  
      
   
                                    







                                                     

                                               





                                                                 
 



                                                       

                                      
                     

                
 
                                           
                                      



                                                       

                                                      

                                                      
                                                
                                                    
                                                                   
 
                                                                            
                                                    
      




                                                                         
                                          









                                                                                

                                                                            
                           
                










                                                                                 







                                                                               
      
 



                                                      



                                     
 
                                           
                                      
                                            
 
                                                                   
      



                                                                                







                                                                           
                                  

                    

       






                                                                               
 
                                                         
          



                             
 

                                         
                       
                                             
                                                                        

                                                   
                                              
                                                          
                                                
                                                     
                                           
                                                          
                                                
       
                                            
 
                                                                        
 
                                                     
                                                               
 





                                                     
                                      
                                                        
          
            
 



                                                    
                              
       
                               
 
                                                                 
 



                                                    
                                      



                                                                             


                                                                          
      
                                               
 

                                                                   
                 
 



                                                                            
                                                                               


                                             
      



                                                                        
                 







                                                                                 
      
                                           
                                       
                                                                    
      

                                    
 
                                                        
                       
 
                                                
 








                                                                       
                     





                                                                    











                                                                                         
                                       













                                                                        
                                  







                                                  
                                                          













                                                                                 
                                                              
      
                                          
                                                                       
      

                                       
 
                                                
 


                                                                            
                 





                                                                   
                                                        

                                                           
                       






                                                                    
      
                                        
                                                                     
      

                                     
 
                                                
 



                                                                
                 













                                                                        
                       










                                                                  
      
                                       
                                                        
                                                                    
      

                                    
 
                                                
 


                                                                            
                 



                                                        
                       
 



                                                                 
                                      
                                                                   
      

                                   
 
                                                
 



                                                                    
                 

                                               
                                                                     

                                                       
                       






                                                                
      
                                          
                                                                       
      

                                       
                                        
 
                                                
 



                                                                
                 









                                                                         
                                    






                                                                          
                       















                                                                    
      

                                                                      


                                                                  
                       


                                           
                                                         
                                                
                                                      
                                                
                                                         




                     
 
                                                

                                                                          
           
                        
                                                     
 


                                                                           
           

                                                                          
           
                        
                                                     
 


                                                                           
           
 

                                              
                                                                           
      
                                                                          

                                                          
      
                                              
 

                                                                  
                 
 



                                                     
                                                                           
      
                                                                         
                                              
      



                                                            
                 
 


                                              
 
                                                                     
      

                                                   
      
                                               
 

                                                                   
                 
 

                                        
                                                                            
      
                                                                       


                                                          
      
                              
                                
 

                                                  
                 



                                                 
 
                                                                      
                                                           
                                           



                                                     
            
                                                  
 


                                           

                                                                          
                                
                                                  
           
      


                                                    

                                                               
                                                                              
                                          

                                                         
                                                   


                                                                
      





                                                             
                                










                                                                       
      
       
      




                                                            
                 



                                                       
                                           
                               
                                                   

                                                                     
      
 

    
                                                    
 
                                   

                                    
 
                                      
 
                                    
      
                           
                                        

              
                           


                                                                              

              

                          
                                     

              











                                                       


                                                                
 

    
                                                  
 

                                 
 
                                      

                                                     
          
            
 

                                

                             
                         

                                         

                     

                                     

                      

                                      

              






                                   
                                                              
 

    




                                                        
 
                                      

                                                           
          
            
 
                                      

                                                      
                       
       
                        
 

                                                                    
                           
                 
                            
 

    



                                                  
 
                                      

                                                          
          
            
 

                                                              
 





                                                
 
                                      
                                                      
 
                                                   
          
            
 
                                    
                                      
                                                            
 







                                                  
                                      

                                                      
                                    

                                                      
          
            
 

                                

                                        

                                                  


                                            
                                                   
                                                               
 









                                                                            
          
            
 


                                




                                          
                                                                   
 









                                                                              
          
            
 



                                   
                                          

                                                   
                                                                     
 









                                                                                
          
            
 



                                       
                                              
                                                  
       
                                                  
                                                                              
 





                                                  
                                      
                                                
                                           


                                

                                                                    
 
                                 

                                                                      
 
                                   

                                                                        
 
              


                                                   

      

                               
 



                                                           
                                             
                                         


                                           
                                      
                         


                             
            






                                                         
                                              
                                                    
                                                

                                               
                                                    
                                                
       
                                            


                                                                        
 

                               




                                                  
                                       

                           
                                      

                                              
                                               
          
            















                                                               
 

                                

           

                                             
 

                                                          


                    
                                                                     


                   
 



                                                  

                                
                             
 
                                           
                                          
 







                                                          
                                                
          
            
 
                                                       








                                          
 

                                           
                
                                           
                                   
                            

                                                                          


                                                     
                         
 
 












                                                             
            
























                                                                      
            

























                                                                     
            

























                                                                              
            
























                                                                    
            













                                                                         
                                                         









                                                            
            












                                                                     
                                                          









                                                             
            








                                                                      
 
                                 
                






                                                                 



                                         
 
                               

 
                                             












                                                                            


                                                            

                                                                         

                                                


                                                     

                                                   

                                                                                
      

                            
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* ifdef HAVE_CONFIG_H */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <langinfo.h>

#include "Ecore.h"
#include "ecore_private.h"
#include "ecore_x_private.h"
#include "Ecore_X.h"
#include "Ecore_X_Atoms.h"

/** OpenBSD does not define CODESET
 * FIXME ??
 */

#ifndef CODESET
#define CODESET "INVALID"
#endif /* ifndef CODESET */

typedef struct _Ecore_X_Mouse_Down_Info
{
   EINA_INLIST;
   int       dev;
   Window    last_win;
   Window    last_last_win;
   Window    last_event_win;
   Window    last_last_event_win;
   Time      last_time;
   Time      last_last_time;
   Eina_Bool did_double : 1;
   Eina_Bool did_triple : 1;
} Ecore_X_Mouse_Down_Info;

static int _ecore_x_last_event_mouse_move = 0;
static Ecore_Event *_ecore_x_last_event_mouse_move_event = NULL;
static Eina_Inlist *_ecore_x_mouse_down_info_list = NULL;

#ifdef ECORE_XKB
static Eina_Hash *emitted_events = NULL;
#endif

static void
_ecore_x_mouse_down_info_clear(void)
{
   Eina_Inlist *l = _ecore_x_mouse_down_info_list;
   Ecore_X_Mouse_Down_Info *info = NULL;
   while (l)
     {
        info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info);
        l = eina_inlist_remove(l, l);
        free(info);
     }
   _ecore_x_mouse_down_info_list = NULL;
}

void
_ecore_x_events_init(void)
{
   //Actually, Nothing to do.
#ifdef ECORE_XKB
   emitted_events = eina_hash_int64_new(NULL);
#endif
}

void
_ecore_x_events_shutdown(void)
{
   _ecore_x_mouse_down_info_clear();
#ifdef ECORE_XKB
   eina_hash_free(emitted_events);
#endif
}

static Ecore_X_Mouse_Down_Info *
_ecore_x_mouse_down_info_get(int dev)
{
   Eina_Inlist *l = _ecore_x_mouse_down_info_list;
   Ecore_X_Mouse_Down_Info *info = NULL;

   //Return the exist info
   EINA_INLIST_FOREACH(l, info)
     if (info->dev == dev) return info;

   //New Device. Add it.
   info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info));
   if (!info) return NULL;

   info->dev = dev;
   l = eina_inlist_append(l, (Eina_Inlist *)info);
   _ecore_x_mouse_down_info_list = l;
   return info;
}

static void
_ecore_x_event_free_mouse_move(void *data EINA_UNUSED,
                               void *ev)
{
   Ecore_Event_Mouse_Move *e;

   e = ev;
   if (_ecore_x_last_event_mouse_move)
     {
        _ecore_x_last_event_mouse_move_event = NULL;
        _ecore_x_last_event_mouse_move = 0;
     }

   free(e);
}

EAPI void
ecore_x_event_mask_set(Ecore_X_Window w,
                       Ecore_X_Event_Mask mask)
{
   XWindowAttributes attr;
   XSetWindowAttributes s_attr;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);

   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);

   if (!w)
     w = DefaultRootWindow(_ecore_x_disp);

   memset(&attr, 0, sizeof(XWindowAttributes));
   XGetWindowAttributes(_ecore_x_disp, w, &attr);
   if (_ecore_xlib_sync) ecore_x_sync();
   s_attr.event_mask = mask | attr.your_event_mask;
   XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
   if (_ecore_xlib_sync) ecore_x_sync();
}

EAPI void
ecore_x_event_mask_unset(Ecore_X_Window w,
                         Ecore_X_Event_Mask mask)
{
   XWindowAttributes attr;
   XSetWindowAttributes s_attr;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);

   EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);

   if (!w)
     w = DefaultRootWindow(_ecore_x_disp);

   memset(&attr, 0, sizeof(XWindowAttributes));
   XGetWindowAttributes(_ecore_x_disp, w, &attr);
   if (_ecore_xlib_sync) ecore_x_sync();
   s_attr.event_mask = attr.your_event_mask & ~mask;
   XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
   if (_ecore_xlib_sync) ecore_x_sync();
}

static void
_ecore_x_event_free_xdnd_enter(void *data EINA_UNUSED,
                               void *ev)
{
   Ecore_X_Event_Xdnd_Enter *e;
   int i;

   e = ev;
   for (i = 0; i < e->num_types; i++)
     XFree(e->types[i]);
   free(e->types);
   free(e);
}

static void
_ecore_x_event_free_selection_notify(void *data EINA_UNUSED,
                                     void *ev)
{
   Ecore_X_Event_Selection_Notify *e;
   Ecore_X_Selection_Data *sel;

   e = ev;
   sel = e->data;
   if (sel->free)
     sel->free(sel);

   free(e->target);
   free(e);
}

static unsigned int
_ecore_x_event_modifiers(unsigned int state)
{
   unsigned int modifiers = 0;

   if (state & ECORE_X_MODIFIER_SHIFT)
     modifiers |= ECORE_EVENT_MODIFIER_SHIFT;

   if (state & ECORE_X_MODIFIER_CTRL)
     modifiers |= ECORE_EVENT_MODIFIER_CTRL;

   if (state & ECORE_X_MODIFIER_ALT)
     modifiers |= ECORE_EVENT_MODIFIER_ALT;

   if (state & ECORE_X_MODIFIER_WIN)
     modifiers |= ECORE_EVENT_MODIFIER_WIN;

   if (state & ECORE_X_MODIFIER_ALTGR)
     modifiers |= ECORE_EVENT_MODIFIER_ALTGR;

   if (state & ECORE_X_LOCK_SCROLL)
     modifiers |= ECORE_EVENT_LOCK_SCROLL;

   if (state & ECORE_X_LOCK_NUM)
     modifiers |= ECORE_EVENT_LOCK_NUM;

   if (state & ECORE_X_LOCK_CAPS)
     modifiers |= ECORE_EVENT_LOCK_CAPS;

   if (state & ECORE_X_LOCK_SHIFT)
     modifiers |= ECORE_EVENT_LOCK_SHIFT;

   return modifiers;
}

void
_ecore_mouse_move(unsigned int timestamp,
                  unsigned int xmodifiers,
                  int x,
                  int y,
                  int x_root,
                  int y_root,
                  unsigned int event_window,
                  unsigned int window,
                  unsigned int root_win,
                  int same_screen,
                  int dev,
                  double radx,
                  double rady,
                  double pressure,
                  double angle,
                  double mx,
                  double my,
                  double mrx,
                  double mry)
{
   Ecore_Event_Mouse_Move *e;
   Ecore_Event *event;

   e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
   if (!e)
     return;

   e->window = window;
   e->root_window = root_win;
   e->timestamp = timestamp;
   e->same_screen = same_screen;
   e->event_window = event_window;

   e->modifiers = _ecore_x_event_modifiers(xmodifiers);
   e->x = x;
   e->y = y;
   e->root.x = x_root;
   e->root.y = y_root;

   e->multi.device = dev;
   e->multi.radius = (radx + rady) / 2;
   e->multi.radius_x = radx;
   e->multi.radius_y = rady;
   e->multi.pressure = pressure;
   e->multi.angle = angle;
   e->multi.x = mx;
   e->multi.y = my;
   e->multi.root.x = mrx;
   e->multi.root.y = mry;

   event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE,
                           e,
                           _ecore_x_event_free_mouse_move,
                           NULL);

   _ecore_x_event_last_time = timestamp;
   _ecore_x_event_last_win = window;
   _ecore_x_event_last_root_x = x_root;
   _ecore_x_event_last_root_y = y_root;

   _ecore_x_last_event_mouse_move_event = event;
}

static void
_ecore_x_event_free_axis_update_event(void *data EINA_UNUSED, void *ev)
{
   Ecore_Event_Axis_Update *e = ev;
   if (e) free(e->axis);
   free(e);
}

void
_ecore_x_axis_update(Ecore_Window window,
                     Ecore_Window event_window,
                     Ecore_Window root_window,
                     unsigned int timestamp,
                     int devid,
                     int toolid,
                     int naxis,
                     Ecore_Axis *axis)
{
   Ecore_Event_Axis_Update *e;
   int i;

   e = calloc(1, sizeof(Ecore_Event_Axis_Update));
   if (!e)
     {
        if (axis) free(axis);
        return;
     }

   e->window = window;
   e->event_window = event_window;
   e->root_window = root_window;

   e->timestamp = timestamp;

   e->device = devid;
   e->toolid = toolid;

   e->naxis = naxis;
   e->axis = axis;

   INF("Axis update [%d] (%d) with %d events:", ECORE_EVENT_AXIS_UPDATE, e->device, e->naxis);
   for (i = 0; i < naxis; i++)
     {
        INF("AXIS %d = %f", e->axis[i].label, e->axis[i].value);
     }

   ecore_event_add(ECORE_EVENT_AXIS_UPDATE, e, _ecore_x_event_free_axis_update_event, NULL);

   _ecore_x_event_last_time = timestamp;
}

static void
_ecore_key_press(int event,
                 XKeyEvent *xevent)
{
   Ecore_Event_Key *e;
   char *compose = NULL;
   char *tmp = NULL;
   char *keyname;
   char *key = NULL;
   char keyname_buffer[256];
   char compose_buffer[256];
   KeySym sym, sym2 = 0;
   XComposeStatus status;
   int val;
   int key_len, keyname_len, compose_len;

   _ecore_x_last_event_mouse_move = 0;
   sym = _ecore_x_XKeycodeToKeysym(xevent->display, xevent->keycode, 0);
   keyname = XKeysymToString(sym);

   if (!keyname)
     {
        snprintf(keyname_buffer,
                 sizeof(keyname_buffer),
                 "Keycode-%i",
                 xevent->keycode);
        keyname = keyname_buffer;
     }

   key = NULL;
   compose = NULL;
   val = XLookupString(xevent,
                       compose_buffer,
                       sizeof(compose_buffer),
                       &sym2,
                       &status);

   if (sym != sym2)
     key = XKeysymToString(sym2);
   if (!key)
     key = keyname;

   if (val > 0)
     {
        compose_buffer[val] = 0;
        compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8",
                                   compose_buffer);
        if (!compose)
          ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
              "Is Eina built with iconv support?", compose_buffer);
        tmp = compose;
     }

   key_len = strlen(key);
   keyname_len = strlen(keyname);
   compose_len = (compose) ? strlen(compose) : 0;

   e = calloc(1, sizeof(Ecore_Event_Key) + key_len + keyname_len +
              compose_len + 3);
   if (!e)
     goto on_error;

   e->keyname = (char *)(e + 1);
   e->key = e->keyname + keyname_len + 1;
   e->compose = (compose) ? e->key + key_len + 1 : NULL;
   e->string = e->compose;

   strcpy((char *)e->keyname, keyname);
   strcpy((char *)e->key, key);
   if (compose)
     strcpy((char *)e->compose, compose);

   e->modifiers = _ecore_x_event_modifiers(xevent->state);

   e->timestamp = xevent->time;
   e->window = xevent->subwindow ? xevent->subwindow : xevent->window;
   e->event_window = xevent->window;
   e->same_screen = xevent->same_screen;
   e->root_window = xevent->root;
   e->keycode = xevent->keycode;

   ecore_event_add(event, e, NULL, NULL);

   _ecore_x_event_last_time = e->timestamp;

on_error:
   if (tmp)
     free(tmp);
}

Ecore_Event_Mouse_Button *
_ecore_mouse_button(int event,
                    unsigned int timestamp,
                    unsigned int xmodifiers,
                    unsigned int buttons,
                    int x,
                    int y,
                    int x_root,
                    int y_root,
                    unsigned int event_window,
                    unsigned int window,
                    unsigned int root_win,
                    int same_screen,
                    int dev,
                    double radx,
                    double rady,
                    double pressure,
                    double angle,
                    double mx,
                    double my,
                    double mrx,
                    double mry)
{
   Ecore_Event_Mouse_Button *e;

   e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
   if (!e)
     return NULL;

   e->window = window;
   e->root_window = root_win;
   e->timestamp = timestamp;
   e->same_screen = same_screen;
   e->event_window = event_window;

   e->buttons = buttons;
   e->modifiers = _ecore_x_event_modifiers(xmodifiers);
   e->double_click = 0;
   e->triple_click = 0;
   e->x = x;
   e->y = y;
   e->root.x = x_root;
   e->root.y = y_root;

   Ecore_X_Mouse_Down_Info *down_info = _ecore_x_mouse_down_info_get(dev);

   if (down_info)
     {
        //If mouse cancel event occred, should reset down info related with double & triple click
        if (event == ECORE_EVENT_MOUSE_BUTTON_CANCEL)
          {
             down_info->last_win = 0;
             down_info->last_last_win = 0;
             down_info->last_event_win = 0;
             down_info->last_last_event_win = 0;
             down_info->last_time = 0;
             down_info->last_last_time = 0;
             down_info->did_double = EINA_FALSE;
             down_info->did_triple = EINA_FALSE;
          }
        if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
            down_info->did_triple)
          {
             down_info->last_win = 0;
             down_info->last_last_win = 0;
             down_info->last_event_win = 0;
             down_info->last_last_event_win = 0;
             down_info->last_time = 0;
             down_info->last_last_time = 0;
          }
        if (event_window == window)
          {
             if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
               {
                  //Check Double Clicked
                  if (((int)(timestamp - down_info->last_time) <=
                       (int)(1000 * _ecore_x_double_click_time)) &&
                      (window == down_info->last_win) &&
                      (event_window == down_info->last_event_win))
                    {
                       e->double_click = 1;
                       down_info->did_double = EINA_TRUE;
                    }
                  else
                    {
                       down_info->did_double = EINA_FALSE;
                       down_info->did_triple = EINA_FALSE;
                    }

                  //Check Triple Clicked
                  if (((int)(timestamp - down_info->last_last_time) <=
                       (int)(2 * 1000 * _ecore_x_double_click_time)) &&
                      (window == down_info->last_win) &&
                      (window == down_info->last_last_win) &&
                      (event_window == down_info->last_event_win) &&
                      (event_window == down_info->last_last_event_win)
                      )
                    {
                       e->triple_click = 1;
                       down_info->did_triple = EINA_TRUE;
                    }
                  else
                    {
                       down_info->did_triple = EINA_FALSE;
                    }
               }
             else if (event == ECORE_EVENT_MOUSE_BUTTON_UP)
               {
                  if (down_info->did_double)
                    e->double_click = 1;
                  if (down_info->did_triple)
                    e->triple_click = 1;
               }
          }
     }

   /* NB: Block commented out as _ecore_x_mouse_up_count appears to have
    * no use. The variable is also commented out above. This code block is
    * the only place that this variable is used, and appears to serve no
    * purpose. - dh
      if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN
       && !e->double_click
       && !e->triple_click)
      _ecore_x_mouse_up_count = 0;
    */

   e->multi.device = dev;
   e->multi.radius = (radx + rady) / 2;
   e->multi.radius_x = radx;
   e->multi.radius_y = rady;
   e->multi.pressure = pressure;
   e->multi.angle = angle;
   e->multi.x = mx;
   e->multi.y = my;
   e->multi.root.x = mrx;
   e->multi.root.y = mry;

   _ecore_x_event_last_time = e->timestamp;
   _ecore_x_event_last_win = e->window;
   _ecore_x_event_last_root_x = x_root;
   _ecore_x_event_last_root_y = y_root;

   ecore_event_add(event, e, NULL, NULL);

   if ((down_info) &&
       (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
       (window == event_window) &&
       (!down_info->did_triple))
     {
        down_info->last_last_win = down_info->last_win;
        down_info->last_win = window;
        down_info->last_last_event_win = down_info->last_event_win;
        down_info->last_event_win = event_window;
        down_info->last_last_time = down_info->last_time;
        down_info->last_time = timestamp;
     }

   return e;
}

void
_ecore_x_event_handle_any_event(XEvent *xevent)
{
   XEvent *ev = malloc(sizeof(XEvent));
   if (!ev) return;
   memcpy(ev, xevent, sizeof(XEvent));
   ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
}

void
_ecore_x_event_handle_key_press(XEvent *xevent)
{
   _ecore_key_press(ECORE_EVENT_KEY_DOWN, (XKeyEvent *)xevent);
}

void
_ecore_x_event_handle_key_release(XEvent *xevent)
{
   _ecore_key_press(ECORE_EVENT_KEY_UP, (XKeyEvent *)xevent);
}

void
_ecore_x_event_handle_button_press(XEvent *xevent)
{
   int i;

   INF("ButtonEvent:press time=%u x=%d y=%d button=%d", (unsigned int)xevent->xbutton.time, (int)xevent->xbutton.x, (int)xevent->xbutton.y, xevent->xbutton.button);

   _ecore_x_last_event_mouse_move = 0;
   if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 8))
     {
        Ecore_Event_Mouse_Wheel *e;

        e = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
        if (!e)
          return;

        e->timestamp = xevent->xbutton.time;
        e->modifiers = _ecore_x_event_modifiers(xevent->xbutton.state);
        switch (xevent->xbutton.button)
          {
           case 4: e->direction = 0; e->z = -1; break;

           case 5: e->direction = 0; e->z = 1; break;

           case 6: e->direction = 1; e->z = -1; break;

           case 7: e->direction = 1; e->z = 1; break;

           default: e->direction = 0; e->z = 0; break;
          }

        e->x = xevent->xbutton.x;
        e->y = xevent->xbutton.y;
        e->root.x = xevent->xbutton.x_root;
        e->root.y = xevent->xbutton.y_root;

        if (xevent->xbutton.subwindow)
          e->window = xevent->xbutton.subwindow;
        else
          e->window = xevent->xbutton.window;

        e->event_window = xevent->xbutton.window;
        e->same_screen = xevent->xbutton.same_screen;
        e->root_window = xevent->xbutton.root;

        _ecore_x_event_last_time = e->timestamp;
        _ecore_x_event_last_win = e->window;
        _ecore_x_event_last_root_x = xevent->xbutton.x_root;
        _ecore_x_event_last_root_y = xevent->xbutton.y_root;
        ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);

        for (i = 0; i < _ecore_window_grabs_num; i++)
          {
             if ((_ecore_window_grabs[i].win == xevent->xbutton.window) ||
                 (_ecore_window_grabs[i].win == xevent->xbutton.subwindow))
               {
                  Eina_Bool replay = EINA_FALSE;

                  if (_ecore_window_grab_replay_func)
                    replay = _ecore_window_grab_replay_func(
                        _ecore_window_grab_replay_data,
                        ECORE_EVENT_MOUSE_WHEEL,
                        e);

                  if (replay)
                    XAllowEvents(xevent->xbutton.display,
                                 ReplayPointer, xevent->xbutton.time);
                  else
                    XAllowEvents(xevent->xbutton.display,
                                 AsyncPointer, xevent->xbutton.time);

                  break;
               }
          }
     }
   else
     {
        {
           _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
                             xevent->xbutton.x, xevent->xbutton.y,
                             xevent->xbutton.x_root, xevent->xbutton.y_root,
                             xevent->xbutton.window,
                             (xevent->xbutton.subwindow ? xevent->xbutton.
                              subwindow : xevent->xbutton.window),
                             xevent->xbutton.root,
                             xevent->xbutton.same_screen,
                             0, 1, 1,
                             1.0, // pressure
                             0.0, // angle
                             xevent->xbutton.x, xevent->xbutton.y,
                             xevent->xbutton.x_root, xevent->xbutton.y_root);
        }
        {
           Ecore_Event_Mouse_Button *e;
           int event_window;
           int window;

           window =
             (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->
              xbutton.window);
           event_window = xevent->xbutton.window;

           e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
                                   xevent->xbutton.time,
                                   xevent->xbutton.state,
                                   xevent->xbutton.button,
                                   xevent->xbutton.x,
                                   xevent->xbutton.y,
                                   xevent->xbutton.x_root,
                                   xevent->xbutton.y_root,
                                   event_window,
                                   window,
                                   xevent->xbutton.root,
                                   xevent->xbutton.same_screen,
                                   0,
                                   1,
                                   1,
                                   1.0,
// pressure
                                   0.0,
// angle
                                   xevent->xbutton.x,
                                   xevent->xbutton.y,
                                   xevent->xbutton.x_root,
                                   xevent->xbutton.y_root);
           if (e)
             for (i = 0; i < _ecore_window_grabs_num; i++)
               {
                  if ((_ecore_window_grabs[i].win == xevent->xbutton.window) ||
                      (_ecore_window_grabs[i].win == xevent->xbutton.subwindow))
                    {
                       Eina_Bool replay = EINA_FALSE;

                       if (_ecore_window_grab_replay_func)
                         replay = _ecore_window_grab_replay_func(
                             _ecore_window_grab_replay_data,
                             ECORE_EVENT_MOUSE_BUTTON_DOWN,
                             e);

                       if (replay)
                         XAllowEvents(xevent->xbutton.display,
                                      ReplayPointer, xevent->xbutton.time);
                       else
                         XAllowEvents(xevent->xbutton.display,
                                      AsyncPointer, xevent->xbutton.time);

                       break;
                    }
               }
        }
     }
}

void
_ecore_x_event_handle_button_release(XEvent *xevent)
{
   _ecore_x_last_event_mouse_move = 0;
   INF("ButtonEvent:release time=%u x=%d y=%d button=%d", (unsigned int)xevent->xbutton.time, (int)xevent->xbutton.x, (int)xevent->xbutton.y, xevent->xbutton.button);
   /* filter out wheel buttons */
   if ((xevent->xbutton.button <= 3) || (xevent->xbutton.button > 7))
     {
        _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
                          xevent->xbutton.x, xevent->xbutton.y,
                          xevent->xbutton.x_root, xevent->xbutton.y_root,
                          xevent->xbutton.window,
                          (xevent->xbutton.subwindow ? xevent->xbutton.
                           subwindow : xevent->xbutton.window),
                          xevent->xbutton.root,
                          xevent->xbutton.same_screen,
                          0, 1, 1,
                          1.0, // pressure
                          0.0, // angle
                          xevent->xbutton.x, xevent->xbutton.y,
                          xevent->xbutton.x_root, xevent->xbutton.y_root);

        _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
                            xevent->xbutton.time, xevent->xbutton.state,
                            xevent->xbutton.button,
                            xevent->xbutton.x, xevent->xbutton.y,
                            xevent->xbutton.x_root, xevent->xbutton.y_root,
                            xevent->xbutton.window,
                            (xevent->xbutton.subwindow ? xevent->xbutton.
                             subwindow : xevent->xbutton.window),
                            xevent->xbutton.root,
                            xevent->xbutton.same_screen,
                            0, 1, 1,
                            1.0, // pressure
                            0.0, // angle
                            xevent->xbutton.x, xevent->xbutton.y,
                            xevent->xbutton.x_root, xevent->xbutton.y_root);
     }
}

void
_ecore_x_event_handle_motion_notify(XEvent *xevent)
{
/*
   if (_ecore_x_last_event_mouse_move)
     {
        ecore_event_del(_ecore_x_last_event_mouse_move_event);
        _ecore_x_last_event_mouse_move = 0;
        _ecore_x_last_event_mouse_move_event = NULL;
     }
 */
   _ecore_mouse_move(xevent->xmotion.time, xevent->xmotion.state,
                     xevent->xmotion.x, xevent->xmotion.y,
                     xevent->xmotion.x_root, xevent->xmotion.y_root,
                     xevent->xmotion.window,
                     (xevent->xmotion.subwindow ? xevent->xmotion.subwindow :
                      xevent->xmotion.window),
                     xevent->xmotion.root,
                     xevent->xmotion.same_screen,
                     0, 1, 1,
                     1.0,   // pressure
                     0.0,   // angle
                     xevent->xmotion.x, xevent->xmotion.y,
                     xevent->xmotion.x_root, xevent->xmotion.y_root);

   _ecore_x_last_event_mouse_move = 1;

   /* Xdnd handling */
   _ecore_x_dnd_drag(xevent->xmotion.root,
                     xevent->xmotion.x_root,
                     xevent->xmotion.y_root);
}

void
_ecore_x_event_handle_enter_notify(XEvent *xevent)
{
   _ecore_x_last_event_mouse_move = 0;
   {
      _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
                        xevent->xcrossing.x, xevent->xcrossing.y,
                        xevent->xcrossing.x_root, xevent->xcrossing.y_root,
                        xevent->xcrossing.window,
                        (xevent->xcrossing.subwindow ? xevent->xcrossing.
                         subwindow : xevent->xcrossing.window),
                        xevent->xcrossing.root,
                        xevent->xcrossing.same_screen,
                        0, 1, 1,
                        1.0, // pressure
                        0.0, // angle
                        xevent->xcrossing.x, xevent->xcrossing.y,
                        xevent->xcrossing.x_root, xevent->xcrossing.y_root);
   }
   {
      Ecore_X_Event_Mouse_In *e;

      e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
      if (!e)
        return;

      e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
      e->x = xevent->xcrossing.x;
      e->y = xevent->xcrossing.y;
      e->root.x = xevent->xcrossing.x_root;
      e->root.y = xevent->xcrossing.y_root;
      if (xevent->xcrossing.subwindow)
        e->win = xevent->xcrossing.subwindow;
      else
        e->win = xevent->xcrossing.window;

      e->same_screen = xevent->xcrossing.same_screen;
      e->root_win = xevent->xcrossing.root;
      e->event_win = xevent->xcrossing.window;

      if (xevent->xcrossing.mode == NotifyNormal)
        e->mode = ECORE_X_EVENT_MODE_NORMAL;
      else if (xevent->xcrossing.mode == NotifyGrab)
        e->mode = ECORE_X_EVENT_MODE_GRAB;
      else if (xevent->xcrossing.mode == NotifyUngrab)
        e->mode = ECORE_X_EVENT_MODE_UNGRAB;

      if (xevent->xcrossing.detail == NotifyAncestor)
        e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
      else if (xevent->xcrossing.detail == NotifyVirtual)
        e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
      else if (xevent->xcrossing.detail == NotifyInferior)
        e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
      else if (xevent->xcrossing.detail == NotifyNonlinear)
        e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
      else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
        e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;

      e->time = xevent->xcrossing.time;
      _ecore_x_event_last_time = e->time;
      ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
   }
}

void
_ecore_x_event_handle_leave_notify(XEvent *xevent)
{
   _ecore_x_last_event_mouse_move = 0;
   {
      _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
                        xevent->xcrossing.x, xevent->xcrossing.y,
                        xevent->xcrossing.x_root, xevent->xcrossing.y_root,
                        xevent->xcrossing.window,
                        (xevent->xcrossing.subwindow ? xevent->xcrossing.
                         subwindow : xevent->xcrossing.window),
                        xevent->xcrossing.root,
                        xevent->xcrossing.same_screen,
                        0, 1, 1,
                        1.0, // pressure
                        0.0, // angle
                        xevent->xcrossing.x, xevent->xcrossing.y,
                        xevent->xcrossing.x_root, xevent->xcrossing.y_root);
   }
   {
      Ecore_X_Event_Mouse_Out *e;

      e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
      if (!e)
        return;

      e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
      e->x = xevent->xcrossing.x;
      e->y = xevent->xcrossing.y;
      e->root.x = xevent->xcrossing.x_root;
      e->root.y = xevent->xcrossing.y_root;
      if (xevent->xcrossing.subwindow)
        e->win = xevent->xcrossing.subwindow;
      else
        e->win = xevent->xcrossing.window;

      e->same_screen = xevent->xcrossing.same_screen;
      e->root_win = xevent->xcrossing.root;
      e->event_win = xevent->xcrossing.window;

      if (xevent->xcrossing.mode == NotifyNormal)
        e->mode = ECORE_X_EVENT_MODE_NORMAL;
      else if (xevent->xcrossing.mode == NotifyGrab)
        e->mode = ECORE_X_EVENT_MODE_GRAB;
      else if (xevent->xcrossing.mode == NotifyUngrab)
        e->mode = ECORE_X_EVENT_MODE_UNGRAB;

      if (xevent->xcrossing.detail == NotifyAncestor)
        e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
      else if (xevent->xcrossing.detail == NotifyVirtual)
        e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
      else if (xevent->xcrossing.detail == NotifyInferior)
        e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
      else if (xevent->xcrossing.detail == NotifyNonlinear)
        e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
      else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
        e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;

      e->time = xevent->xcrossing.time;
      _ecore_x_event_last_time = e->time;
      _ecore_x_event_last_win = e->win;
      _ecore_x_event_last_root_x = e->root.x;
      _ecore_x_event_last_root_y = e->root.y;
      ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
   }
}

void
_ecore_x_event_handle_focus_in(XEvent *xevent)
{
   Ecore_X_Event_Window_Focus_In *e;

   _ecore_x_last_event_mouse_move = 0;

   e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
   if (!e)
     return;

   e->win = xevent->xfocus.window;

   if (xevent->xfocus.mode == NotifyNormal)
     e->mode = ECORE_X_EVENT_MODE_NORMAL;
   else if (xevent->xfocus.mode == NotifyWhileGrabbed)
     e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
   else if (xevent->xfocus.mode == NotifyGrab)
     e->mode = ECORE_X_EVENT_MODE_GRAB;
   else if (xevent->xfocus.mode == NotifyUngrab)
     e->mode = ECORE_X_EVENT_MODE_UNGRAB;

   if (xevent->xfocus.detail == NotifyAncestor)
     e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
   else if (xevent->xfocus.detail == NotifyVirtual)
     e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
   else if (xevent->xfocus.detail == NotifyInferior)
     e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
   else if (xevent->xfocus.detail == NotifyNonlinear)
     e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
   else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
     e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
   else if (xevent->xfocus.detail == NotifyPointer)
     e->detail = ECORE_X_EVENT_DETAIL_POINTER;
   else if (xevent->xfocus.detail == NotifyPointerRoot)
     e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
   else if (xevent->xfocus.detail == NotifyDetailNone)
     e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;

   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
}

void
_ecore_x_event_handle_focus_out(XEvent *xevent)
{
   Ecore_X_Event_Window_Focus_Out *e;

   _ecore_x_last_event_mouse_move = 0;

   e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
   if (!e)
     return;

   e->win = xevent->xfocus.window;

   if (xevent->xfocus.mode == NotifyNormal)
     e->mode = ECORE_X_EVENT_MODE_NORMAL;
   else if (xevent->xfocus.mode == NotifyWhileGrabbed)
     e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
   else if (xevent->xfocus.mode == NotifyGrab)
     e->mode = ECORE_X_EVENT_MODE_GRAB;
   else if (xevent->xfocus.mode == NotifyUngrab)
     e->mode = ECORE_X_EVENT_MODE_UNGRAB;

   if (xevent->xfocus.detail == NotifyAncestor)
     e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
   else if (xevent->xfocus.detail == NotifyVirtual)
     e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
   else if (xevent->xfocus.detail == NotifyInferior)
     e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
   else if (xevent->xfocus.detail == NotifyNonlinear)
     e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
   else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
     e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
   else if (xevent->xfocus.detail == NotifyPointer)
     e->detail = ECORE_X_EVENT_DETAIL_POINTER;
   else if (xevent->xfocus.detail == NotifyPointerRoot)
     e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
   else if (xevent->xfocus.detail == NotifyDetailNone)
     e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;

   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
}

void
_ecore_x_event_handle_keymap_notify(XEvent *xevent EINA_UNUSED)
{
   _ecore_x_last_event_mouse_move = 0;
   /* FIXME: handle this event type */
}

void
_ecore_x_event_handle_expose(XEvent *xevent)
{
   Ecore_X_Event_Window_Damage *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
   if (!e)
     return;

   e->win = xevent->xexpose.window;
   e->time = _ecore_x_event_last_time;
   e->x = xevent->xexpose.x;
   e->y = xevent->xexpose.y;
   e->w = xevent->xexpose.width;
   e->h = xevent->xexpose.height;
   e->count = xevent->xexpose.count;
   ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
}

void
_ecore_x_event_handle_graphics_expose(XEvent *xevent)
{
   Ecore_X_Event_Window_Damage *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
   if (!e)
     return;

   e->win = xevent->xgraphicsexpose.drawable;
   e->time = _ecore_x_event_last_time;
   e->x = xevent->xgraphicsexpose.x;
   e->y = xevent->xgraphicsexpose.y;
   e->w = xevent->xgraphicsexpose.width;
   e->h = xevent->xgraphicsexpose.height;
   e->count = xevent->xgraphicsexpose.count;
   ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
}

void
_ecore_x_event_handle_visibility_notify(XEvent *xevent)
{
   _ecore_x_last_event_mouse_move = 0;
//   if (xevent->xvisibility.state != VisibilityPartiallyObscured)
   {
      Ecore_X_Event_Window_Visibility_Change *e;

      e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
      if (!e)
        return;

      e->win = xevent->xvisibility.window;
      e->time = _ecore_x_event_last_time;
      if (xevent->xvisibility.state == VisibilityFullyObscured)
        e->fully_obscured = 1;
      else
        e->fully_obscured = 0;

      ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
   }
}

void
_ecore_x_event_handle_create_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Create *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
   if (!e)
     return;

   e->win = xevent->xcreatewindow.window;
   e->parent = xevent->xcreatewindow.parent;
   if (xevent->xcreatewindow.override_redirect)
     e->override = 1;
   else
     e->override = 0;

   e->x = xevent->xcreatewindow.x;
   e->y = xevent->xcreatewindow.y;
   e->w = xevent->xcreatewindow.width;
   e->h = xevent->xcreatewindow.height;
   e->border = xevent->xcreatewindow.border_width;
   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
}

void
_ecore_x_event_handle_destroy_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Destroy *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
   if (!e)
     return;

   e->win = xevent->xdestroywindow.window;
   e->event_win = xevent->xdestroywindow.event;
   e->time = _ecore_x_event_last_time;
   if (e->win == _ecore_x_event_last_win)
     _ecore_x_event_last_win = 0;

   ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
   while (_ecore_x_window_grab_remove(e->win, -1, 0, 0));
   while (_ecore_x_key_grab_remove(e->win, NULL, 0, 0));
}

void
_ecore_x_event_handle_unmap_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Hide *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
   if (!e)
     return;

   e->win = xevent->xunmap.window;
   e->event_win = xevent->xunmap.event;
   e->time = _ecore_x_event_last_time;
   e->send_event = xevent->xunmap.send_event;
   ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
}

void
_ecore_x_event_handle_map_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Show *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
   if (!e)
     return;

   e->win = xevent->xmap.window;
   e->event_win = xevent->xmap.event;
   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
}

void
_ecore_x_event_handle_map_request(XEvent *xevent)
{
   Ecore_X_Event_Window_Show_Request *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
   if (!e)
     return;

   e->win = xevent->xmaprequest.window;
   e->time = _ecore_x_event_last_time;
   e->parent = xevent->xmaprequest.parent;
   ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
}

void
_ecore_x_event_handle_reparent_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Reparent *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
   if (!e)
     return;

   e->win = xevent->xreparent.window;
   e->event_win = xevent->xreparent.event;
   e->parent = xevent->xreparent.parent;
   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
}

void
_ecore_x_event_handle_configure_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Configure *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
   if (!e)
     return;

   e->win = xevent->xconfigure.window;
   e->event_win = xevent->xconfigure.event;
   e->abovewin = xevent->xconfigure.above;
   e->x = xevent->xconfigure.x;
   e->y = xevent->xconfigure.y;
   e->w = xevent->xconfigure.width;
   e->h = xevent->xconfigure.height;
   e->border = xevent->xconfigure.border_width;
   e->override = xevent->xconfigure.override_redirect;
   e->from_wm = xevent->xconfigure.send_event;
   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
}

void
_ecore_x_event_handle_configure_request(XEvent *xevent)
{
   Ecore_X_Event_Window_Configure_Request *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
   if (!e)
     return;

   e->win = xevent->xconfigurerequest.window;
   e->parent_win = xevent->xconfigurerequest.parent;
   e->abovewin = xevent->xconfigurerequest.above;
   e->x = xevent->xconfigurerequest.x;
   e->y = xevent->xconfigurerequest.y;
   e->w = xevent->xconfigurerequest.width;
   e->h = xevent->xconfigurerequest.height;
   e->border = xevent->xconfigurerequest.border_width;
   e->value_mask = xevent->xconfigurerequest.value_mask;
   e->time = _ecore_x_event_last_time;

   if (xevent->xconfigurerequest.detail == Above)
     e->detail = ECORE_X_WINDOW_STACK_ABOVE;
   else if (xevent->xconfigurerequest.detail == Below)
     e->detail = ECORE_X_WINDOW_STACK_BELOW;
   else if (xevent->xconfigurerequest.detail == TopIf)
     e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
   else if (xevent->xconfigurerequest.detail == BottomIf)
     e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
   else if (xevent->xconfigurerequest.detail == Opposite)
     e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;

   ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
}

void
_ecore_x_event_handle_gravity_notify(XEvent *xevent EINA_UNUSED)
{
   _ecore_x_last_event_mouse_move = 0;
   /* FIXME: handle this event type */
}

void
_ecore_x_event_handle_resize_request(XEvent *xevent)
{
   Ecore_X_Event_Window_Resize_Request *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
   if (!e)
     return;

   e->win = xevent->xresizerequest.window;
   e->w = xevent->xresizerequest.width;
   e->h = xevent->xresizerequest.height;
   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
}

void
_ecore_x_event_handle_circulate_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Stack *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
   if (!e)
     return;

   e->win = xevent->xcirculate.window;
   e->event_win = xevent->xcirculate.event;
   if (xevent->xcirculate.place == PlaceOnTop)
     e->detail = ECORE_X_WINDOW_STACK_ABOVE;
   else
     e->detail = ECORE_X_WINDOW_STACK_BELOW;

   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
}

void
_ecore_x_event_handle_circulate_request(XEvent *xevent)
{
   Ecore_X_Event_Window_Stack_Request *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
   if (!e)
     return;

   e->win = xevent->xcirculaterequest.window;
   e->parent = xevent->xcirculaterequest.parent;
   if (xevent->xcirculaterequest.place == PlaceOnTop)
     e->detail = ECORE_X_WINDOW_STACK_ABOVE;
   else
     e->detail = ECORE_X_WINDOW_STACK_BELOW;

   e->time = _ecore_x_event_last_time;
   ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
}

void
_ecore_x_event_handle_property_notify(XEvent *xevent)
{
   _ecore_x_last_event_mouse_move = 0;
   {
      Ecore_X_Event_Window_Property *e;

      e = calloc(1, sizeof(Ecore_X_Event_Window_Property));
      if (!e)
        return;

      e->win = xevent->xproperty.window;
      e->atom = xevent->xproperty.atom;
      e->time = xevent->xproperty.time;
      e->state = !!xevent->xproperty.state;
      _ecore_x_event_last_time = e->time;
      ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
   }
}

void
_ecore_x_event_handle_selection_clear(XEvent *xevent)
{
   Ecore_X_Selection_Intern *d;
   Ecore_X_Event_Selection_Clear *e;
   Ecore_X_Atom sel;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   _ecore_x_last_event_mouse_move = 0;
   d = _ecore_x_selection_get(xevent->xselectionclear.selection);
   if (d && (xevent->xselectionclear.time <= d->time)) return;
/* errr..... why? paranoia.
   if (d && (xevent->xselectionclear.time > d->time))
     {
        _ecore_x_selection_set(None, NULL, 0,
                               xevent->xselectionclear.selection);
     }
 */
/* Generate event for app cleanup */
   e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
   e->win = xevent->xselectionclear.window;
   e->time = xevent->xselectionclear.time;
   e->atom = sel = xevent->xselectionclear.selection;
   if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
     e->selection = ECORE_X_SELECTION_PRIMARY;
   else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
     e->selection = ECORE_X_SELECTION_SECONDARY;
   else if (sel == ECORE_X_ATOM_SELECTION_XDND)
     e->selection = ECORE_X_SELECTION_XDND;
   else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
     e->selection = ECORE_X_SELECTION_CLIPBOARD;
   else
     e->selection = ECORE_X_SELECTION_OTHER;

   ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
}

void
_ecore_x_event_handle_selection_request(XEvent *xevent)
{
   Ecore_X_Event_Selection_Request *e;
   Ecore_X_Selection_Intern *sd;
   void *data = NULL;
   int len;
   int typesize;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   _ecore_x_last_event_mouse_move = 0;
   /*
    * Generate a selection request event.
    */
   e = malloc(sizeof(Ecore_X_Event_Selection_Request));
   e->owner = xevent->xselectionrequest.owner;
   e->requestor = xevent->xselectionrequest.requestor;
   e->time = xevent->xselectionrequest.time;
   e->selection = xevent->xselectionrequest.selection;
   e->target = xevent->xselectionrequest.target;
   e->property = xevent->xselectionrequest.property;
   ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);

   if ((sd = _ecore_x_selection_get(xevent->xselectionrequest.selection)) &&
       (sd->win == xevent->xselectionrequest.owner))
     {
        Ecore_X_Selection_Intern *si;

        si = _ecore_x_selection_get(xevent->xselectionrequest.selection);
        if (si->data)
          {
             Ecore_X_Atom property = None;
             Ecore_X_Atom type;

             /* Set up defaults for strings first */
             type = xevent->xselectionrequest.target;
             typesize = 8;
             len = sd->length;

             if (!ecore_x_selection_convert(xevent->xselectionrequest.selection,
                                            xevent->xselectionrequest.target,
                                            &data, &len, &type, &typesize))
               /* Refuse selection, conversion to requested target failed */
               property = None;
             else if (data)
               {
                  /* FIXME: This does not properly handle large data transfers */
                  ecore_x_window_prop_property_set(
                    xevent->xselectionrequest.requestor,
                    xevent->xselectionrequest.
                    property,
                    type,
                    typesize,
                    data,
                    len);
                  property = xevent->xselectionrequest.property;
                  free(data);
               }

             ecore_x_selection_notify_send(xevent->xselectionrequest.requestor,
                                           xevent->xselectionrequest.selection,
                                           xevent->xselectionrequest.target,
                                           property,
                                           xevent->xselectionrequest.time);
          }
     }
}

void
_ecore_x_event_handle_selection_notify(XEvent *xevent)
{
   Ecore_X_Event_Selection_Notify *e;
   unsigned char *data = NULL;
   Ecore_X_Atom selection;
   int num_ret, format;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   _ecore_x_last_event_mouse_move = 0;
   selection = xevent->xselection.selection;

   if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS)
     {
        format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
                                                  xevent->xselection.property,
                                                  XA_ATOM, 32, &data, &num_ret);
        if (!format)
          {
             /* fallback if targets handling is not working and try get the
              * selection directly */
             XConvertSelection(_ecore_x_disp, selection,
                               ECORE_X_ATOM_UTF8_STRING,
                               selection,
                               xevent->xselection.requestor,
                               CurrentTime);
             if (data) free(data);
             return;
          }
     }
   else
     {
        format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
                                                  xevent->xselection.property,
                                                  AnyPropertyType, 8, &data,
                                                  &num_ret);
        if (!format) return;
     }

   e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
   if (!e)
     {
        if (data) free(data);
        return;
     }

   e->win = xevent->xselection.requestor;
   e->time = xevent->xselection.time;
   e->atom = selection;
   e->property = xevent->xselection.property;
   e->target = _ecore_x_selection_target_get(xevent->xselection.target);

   if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
     e->selection = ECORE_X_SELECTION_PRIMARY;
   else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
     e->selection = ECORE_X_SELECTION_SECONDARY;
   else if (selection == ECORE_X_ATOM_SELECTION_XDND)
     e->selection = ECORE_X_SELECTION_XDND;
   else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
     e->selection = ECORE_X_SELECTION_CLIPBOARD;
   else
     e->selection = ECORE_X_SELECTION_OTHER;

   e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);

   ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
                   _ecore_x_event_free_selection_notify, NULL);
}

void
_ecore_x_event_handle_colormap_notify(XEvent *xevent)
{
   Ecore_X_Event_Window_Colormap *e;

   _ecore_x_last_event_mouse_move = 0;
   e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap));
   if (!e)
     return;

   e->win = xevent->xcolormap.window;
   e->cmap = xevent->xcolormap.colormap;
   e->time = _ecore_x_event_last_time;
   if (xevent->xcolormap.state == ColormapInstalled)
     e->installed = EINA_TRUE;
   else
     e->installed = EINA_FALSE;

   ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
}

void
_ecore_x_event_handle_client_message(XEvent *xevent)
{
   _ecore_x_last_event_mouse_move = 0;
   /* Special client message event handling here. need to put LOTS of if */
   /* checks here and generate synthetic events per special message known */
   /* otherwise generate generic client message event. this would handle*/
   /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
   if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
       (xevent->xclient.format == 32) &&
       (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW))
     {
        Ecore_X_Event_Window_Delete_Request *e;

        e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
        if (!e)
          return;

        e->win = xevent->xclient.window;
        e->time = _ecore_x_event_last_time;
        ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
     }
   else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
            (xevent->xclient.format == 32) &&
/* Ignore move and resize with keyboard */
            (xevent->xclient.data.l[2] < 9))
     {
        Ecore_X_Event_Window_Move_Resize_Request *e;

        e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
        if (!e)
          return;

        e->win = xevent->xclient.window;
        e->x = xevent->xclient.data.l[0];
        e->y = xevent->xclient.data.l[1];
        e->direction = xevent->xclient.data.l[2];
        e->button = xevent->xclient.data.l[3];
        e->source = xevent->xclient.data.l[4];
        ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
     }
   /* Xdnd Client Message Handling Begin */
   /* Message Type: XdndEnter target */
   else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER)
     {
        Ecore_X_Event_Xdnd_Enter *e;
        Ecore_X_DND_Target *target;

        e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
        if (!e) return;

        LOGFN(__FILE__, __LINE__, __FUNCTION__);

        target = _ecore_x_dnd_target_get();
        target->state = ECORE_X_DND_TARGET_ENTERED;
        target->source = xevent->xclient.data.l[0];
        target->win = xevent->xclient.window;
        target->version = (int)(xevent->xclient.data.l[1] >> 24);
        if (target->version > ECORE_X_DND_VERSION)
          {
             WRN("DND: Requested version %d, we only support up to %d",
                 target->version, ECORE_X_DND_VERSION);
             free(e);
             return;
          }

        if (xevent->xclient.data.l[1] & 0x1UL)
          {
             /* source supports more than 3 types, fetch property */
             unsigned char *data;
             Ecore_X_Atom *types;
             int i, num_ret;

             LOGFN(__FILE__, __LINE__, __FUNCTION__);
             if (!(ecore_x_window_prop_property_get(target->source,
                                                    ECORE_X_ATOM_XDND_TYPE_LIST,
                                                    XA_ATOM,
                                                    32, &data, &num_ret)))
               {
                  WRN(
                    "DND: Could not fetch data type list from source window, aborting.");
                  if (data) free(data);
                  free(e);
                  return;
               }

             types = (Ecore_X_Atom *)data;
             e->types = calloc(num_ret, sizeof(char *));
             if (e->types)
               {
                  LOGFN(__FILE__, __LINE__, __FUNCTION__);
                  for (i = 0; i < num_ret; i++)
                    e->types[i] = XGetAtomName(_ecore_x_disp, types[i]);
               }

             e->num_types = num_ret;
             if (data) free(data);
          }
        else
          {
             int i = 0;

             e->types = calloc(3, sizeof(char *));
             if (e->types)
               {
                  LOGFN(__FILE__, __LINE__, __FUNCTION__);
                  while ((i < 3) && (xevent->xclient.data.l[i + 2]))
                    {
                       e->types[i] = XGetAtomName(_ecore_x_disp,
                                                  xevent->xclient.data.l[i + 2]);
                       i++;
                    }
               }

             e->num_types = i;
          }

        e->win = target->win;
        e->source = target->source;
        ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e,
                        _ecore_x_event_free_xdnd_enter, NULL);
     }
   /* Message Type: XdndPosition target */
   else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION)
     {
        Ecore_X_Event_Xdnd_Position *e;
        Ecore_X_DND_Target *target;

        LOGFN(__FILE__, __LINE__, __FUNCTION__);

        target = _ecore_x_dnd_target_get();
        if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
            (target->win != xevent->xclient.window))
          return;

        target->pos.x = xevent->xclient.data.l[2] >> 16;
        target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL;
        target->action = xevent->xclient.data.l[4]; /* Version 2 */

        target->time = (target->version >= 1) ?
          (Time)xevent->xclient.data.l[3] : CurrentTime;

        e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
        if (!e) return;

        e->win = target->win;
        e->source = target->source;
        e->position.x = target->pos.x;
        e->position.y = target->pos.y;
        e->action = target->action;
        ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
     }
   /* Message Type: XdndStatus source */
   else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS)
     {
        Ecore_X_Event_Xdnd_Status *e;
        Ecore_X_DND_Source *source;

        LOGFN(__FILE__, __LINE__, __FUNCTION__);

        source = _ecore_x_dnd_source_get();
        /* Make sure source/target match */
        if ((source->win != xevent->xclient.window) ||
            (source->dest != (Window)xevent->xclient.data.l[0]))
          return;

        source->await_status = 0;

        source->will_accept = xevent->xclient.data.l[1] & 0x1UL;
        source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1;

        source->rectangle.x = xevent->xclient.data.l[2] >> 16;
        source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL;
        source->rectangle.width = xevent->xclient.data.l[3] >> 16;
        source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL;

        source->accepted_action = xevent->xclient.data.l[4];

        e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
        if (!e) return;

        e->win = source->win;
        e->target = source->dest;
        e->will_accept = source->will_accept;
        e->rectangle.x = source->rectangle.x;
        e->rectangle.y = source->rectangle.y;
        e->rectangle.width = source->rectangle.width;
        e->rectangle.height = source->rectangle.height;
        e->action = source->accepted_action;

        ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
     }
   /* Message Type: XdndLeave target */
   /* Pretend the whole thing never happened, sort of */
   else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE)
     {
        Ecore_X_Event_Xdnd_Leave *e;
        Ecore_X_DND_Target *target;

        LOGFN(__FILE__, __LINE__, __FUNCTION__);

        target = _ecore_x_dnd_target_get();
        if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
            (target->win != xevent->xclient.window))
          return;

        target->state = ECORE_X_DND_TARGET_IDLE;

        e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
        if (!e) return;

        e->win = xevent->xclient.window;
        e->source = (Window)xevent->xclient.data.l[0];
        ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
     }
   /* Message Type: XdndDrop target */
   else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP)
     {
        Ecore_X_Event_Xdnd_Drop *e;
        Ecore_X_DND_Target *target;

        LOGFN(__FILE__, __LINE__, __FUNCTION__);

        target = _ecore_x_dnd_target_get();
        /* Match source/target */
        if ((target->source != (Window)xevent->xclient.data.l[0]) ||
            (target->win != xevent->xclient.window))
          return;

        target->time = (target->version >= 1) ?
          (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time;

        e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
        if (!e) return;

        e->win = target->win;
        e->source = target->source;
        e->action = target->action;
        e->position.x = target->pos.x;
        e->position.y = target->pos.y;
        ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
     }
   /* Message Type: XdndFinished source */
   else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED)
     {
        Ecore_X_Event_Xdnd_Finished *e;
        Ecore_X_DND_Source *source;
        Eina_Bool completed = EINA_TRUE;

        LOGFN(__FILE__, __LINE__, __FUNCTION__);

        source = _ecore_x_dnd_source_get();
        /* Match source/target */
        if ((source->win != xevent->xclient.window) ||
            (source->dest != (Window)xevent->xclient.data.l[0]))
          return;

        if ((source->version < 5) || (xevent->xclient.data.l[1] & 0x1UL))
          {
             LOGFN(__FILE__, __LINE__, __FUNCTION__);
             /* Target successfully performed drop action */
             ecore_x_selection_xdnd_clear();
             source->state = ECORE_X_DND_SOURCE_IDLE;
          }
        else if (source->version >= 5)
          {
             completed = EINA_FALSE;
             source->state = ECORE_X_DND_SOURCE_CONVERTING;

             /* FIXME: Probably need to add a timer to switch back to idle
              * and discard the selection data */
          }

        e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
        if (!e) return;

        e->win = source->win;
        e->target = source->dest;
        e->completed = completed;
        if (source->version >= 5)
          {
             source->accepted_action = xevent->xclient.data.l[2];
             e->action = source->accepted_action;
          }
        else
          {
             source->accepted_action = 0;
             e->action = source->action;
          }

        ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
     }
   else if (xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_STATE)
     {
        Ecore_X_Event_Window_State_Request *e;

        e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
        if (!e) return;

        e->win = xevent->xclient.window;
        if (xevent->xclient.data.l[0] == 0)
          e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
        else if (xevent->xclient.data.l[0] == 1)
          e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
        else if (xevent->xclient.data.l[0] == 2)
          e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
        else
          {
             free(e);
             return;
          }

        LOGFN(__FILE__, __LINE__, __FUNCTION__);
        e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]);
        if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
          {
//	     char *name;
             LOGFN(__FILE__, __LINE__, __FUNCTION__);

//	     name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]);
//	     if (name) ERR("Unknown state: %s", name);
//	     XFree(name);
          }
        e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]);
        if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
          {
//	     char *name;
             LOGFN(__FILE__, __LINE__, __FUNCTION__);

//	     name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]);
//	     if (name) ERR("Unknown state: %s", name);
//	     XFree(name);
          }

        e->source = xevent->xclient.data.l[3];

        ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
     }
   else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE)
            && (xevent->xclient.format == 32)
            && (xevent->xclient.data.l[0] == IconicState))
     {
        Ecore_X_Event_Window_State_Request *e;

        e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
        if (!e)
          return;

        e->win = xevent->xclient.window;
        e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
        e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;

        ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
     }
   else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
            && (xevent->xclient.format == 32))
     {
        Ecore_X_Event_Desktop_Change *e;

        e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
        if (!e)
          return;

        e->win = xevent->xclient.window;
        e->desk = xevent->xclient.data.l[0];
        e->source = xevent->xclient.data.l[1];

        ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
     }
   else if (xevent->xclient.message_type ==
            ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS)
     {
        Ecore_X_Event_Frame_Extents_Request *e;

        e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
        if (!e)
          return;

        e->win = xevent->xclient.window;

        ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
     }
   else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS)
            && ((Ecore_X_Atom)xevent->xclient.data.l[0] ==
                ECORE_X_ATOM_NET_WM_PING)
            && (xevent->xclient.format == 32))
     {
        Ecore_X_Event_Ping *e;
        Ecore_X_Window root = 0;

        e = calloc(1, sizeof(Ecore_X_Event_Ping));
        if (!e)
          return;

        e->win = xevent->xclient.window;
        e->time = xevent->xclient.data.l[1];
        e->event_win = xevent->xclient.data.l[2];

        /* send a reply anyway - we are alive... eventloop at least */
        ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
        if (ScreenCount(_ecore_x_disp) > 1)
          {
             LOGFN(__FILE__, __LINE__, __FUNCTION__);
             root = ecore_x_window_root_get(e->win);
          }
        else
          root = DefaultRootWindow(_ecore_x_disp);

        if (xevent->xclient.window != root)
          {
             xevent->xclient.window = root;
             XSendEvent(_ecore_x_disp, root, False,
                        SubstructureRedirectMask | SubstructureNotifyMask,
                        xevent);
             if (_ecore_xlib_sync) ecore_x_sync();
          }
     }
   else if ((xevent->xclient.message_type ==
             ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
            (xevent->xclient.format == 8))
     _ecore_x_netwm_startup_info_begin(xevent->xclient.window,
                                       xevent->xclient.data.b);
   else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
            (xevent->xclient.format ==