javauis/eswt_qt/xlibutils/native/os.cpp
branchRCL_3
changeset 25 ae942d28ec0e
equal deleted inserted replaced
24:6c158198356e 25:ae942d28ec0e
       
     1 // Description: Testing utility for emulating pointer/key input events in X. 
       
     2 
       
     3 #include <QApplication>
       
     4 #include <Xlib.h>
       
     5 #include <new>
       
     6 
       
     7 #include "os.h"
       
     8 
       
     9 namespace Java {
       
    10     namespace XlibUtils {
       
    11         typedef enum
       
    12         {
       
    13             NO_ERROR        = 0,
       
    14             NO_DISPLAY      = 1,
       
    15             NO_FOCUSWINDOW  = 2,
       
    16             NO_ROOTWINDOW   = 3,
       
    17             NO_MEMORY       = 4,
       
    18             SENDEVENT_ERR   = 5
       
    19         } XlibUtilsErr;
       
    20     }
       
    21 }
       
    22 
       
    23 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_uitestutils_XlibUtils_XSendKeyToFocusWindow
       
    24   ( JNIEnv*, jclass, jint aKeycode, jint aModifiers, jint aPressOrRelease )
       
    25 {
       
    26     int keycode      = static_cast<int>( aKeycode );
       
    27     int modifiers    = static_cast<int>( aModifiers );
       
    28     bool press       = ( aPressOrRelease == 0 ? true : false );
       
    29     jint retVal      = 0;
       
    30     Display* display = NULL;
       
    31     
       
    32     try
       
    33     {
       
    34         display = ::XOpenDisplay( NULL ); 
       
    35         if( !display )
       
    36         {
       
    37             throw Java::XlibUtils::NO_DISPLAY;
       
    38         }
       
    39         
       
    40         Window focusWindow  = 0;
       
    41         int focusState      = 0;
       
    42         ::XGetInputFocus( display,  &focusWindow, &focusState );
       
    43         
       
    44         Window rootWindow = ::XDefaultRootWindow( display );
       
    45 
       
    46         if( focusWindow == None )
       
    47         {
       
    48             throw Java::XlibUtils::NO_FOCUSWINDOW;
       
    49         }
       
    50         else if( rootWindow == None )
       
    51         {
       
    52             throw Java::XlibUtils::NO_ROOTWINDOW;
       
    53         }
       
    54         else
       
    55         {
       
    56             XKeyEvent* event = new(std::nothrow) XKeyEvent();
       
    57             if( !event )
       
    58             {
       
    59                 throw Java::XlibUtils::NO_MEMORY;
       
    60             }
       
    61             event->type        = ( press ? KeyPress : KeyRelease );
       
    62             event->serial      = None;
       
    63             event->send_event  = false;
       
    64             event->display     = display;
       
    65             event->window      = focusWindow;
       
    66             event->root        = rootWindow;
       
    67             event->subwindow   = None;
       
    68             event->time        = CurrentTime;
       
    69             event->x           = 0;
       
    70             event->y           = 0;
       
    71             event->x_root      = 0;
       
    72             event->y_root      = 0;
       
    73             event->state       = modifiers;
       
    74             event->keycode     = keycode;
       
    75             event->same_screen = True;
       
    76 
       
    77             if( ::XSendEvent( display,
       
    78                               event->window,
       
    79                               false,
       
    80                               0,
       
    81                               reinterpret_cast<XEvent*>(event)) == 0 )
       
    82             {
       
    83                 throw Java::XlibUtils::SENDEVENT_ERR;
       
    84             }
       
    85             ::XFlush( display );
       
    86         }
       
    87      }
       
    88      catch(Java::XlibUtils::XlibUtilsErr e)
       
    89      {
       
    90         retVal = static_cast<jint>( e );
       
    91      }
       
    92     if( retVal != Java::XlibUtils::NO_DISPLAY )
       
    93     {
       
    94         ::XCloseDisplay( display );
       
    95     }
       
    96     return retVal;
       
    97 }
       
    98 
       
    99 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_uitestutils_XlibUtils_XKeysymToKeycode
       
   100   (JNIEnv*, jclass, jint aKeysym)
       
   101     {
       
   102     int keysym      = static_cast<int>(aKeysym);
       
   103     KeyCode keycode = 0;
       
   104     
       
   105     Display* display = ::XOpenDisplay( NULL );
       
   106     if( display )
       
   107     {
       
   108         keycode = ::XKeysymToKeycode( display, keysym );
       
   109         ::XCloseDisplay( display );
       
   110     }
       
   111     return keycode;
       
   112     }
       
   113 
       
   114 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_uitestutils_XlibUtils_XSendPointerEvent
       
   115   (JNIEnv*, jclass, jint aX, jint aY, jint aButton, jint aPressOrRelease)
       
   116     {
       
   117     bool press       = ( aPressOrRelease == 0 ? true : false );
       
   118     int x            = static_cast<int>(aX);
       
   119     int y            = static_cast<int>(aY);
       
   120     jint retVal      = 0;
       
   121     Display* display = NULL;
       
   122     int buttonNMask  = 1 << (7 + aButton); // Button1Mask, Button2Mask, ..., Button5Mask
       
   123     
       
   124     try
       
   125     {
       
   126         display = ::XOpenDisplay( NULL ); 
       
   127         if( !display )
       
   128         {
       
   129             throw Java::XlibUtils::NO_DISPLAY;
       
   130         }
       
   131         
       
   132         Window rootWindow = ::XDefaultRootWindow( display );
       
   133         if( rootWindow == None )
       
   134         {
       
   135             throw Java::XlibUtils::NO_ROOTWINDOW;
       
   136         }
       
   137 
       
   138         // Release events don't seem to work if we do pointer warp. 
       
   139         // Pointer is warped only for press events. Releases use the
       
   140         // current cursor position to determine the window where to 
       
   141         // send the event to. 
       
   142         if( press )
       
   143         {
       
   144             ::XWarpPointer( display, None, rootWindow, 0, 0, 0, 0, x, y );
       
   145         }
       
   146 
       
   147         XButtonEvent* event = new(std::nothrow) XButtonEvent();
       
   148         if( !event )
       
   149         {
       
   150             throw Java::XlibUtils::NO_MEMORY;
       
   151         }
       
   152                 
       
   153         event->type         = ( press ? ButtonPress : ButtonRelease );
       
   154         event->serial       = None;
       
   155         event->send_event   = False;
       
   156         event->display      = display;
       
   157 //      event->window       = ;
       
   158 //      event->root         = ;
       
   159 //      event->subWindow    = ;
       
   160         event->time         = CurrentTime;
       
   161 //      event->x            = ;
       
   162 //      event->y            = ;
       
   163 //      event->x_root       = ;
       
   164 //      event->y_root       = ;
       
   165 //      event->state        = ;
       
   166         event->button       = aButton;
       
   167         event->same_screen  = True;
       
   168         
       
   169         ::XQueryPointer( display, 
       
   170                          rootWindow, 
       
   171                          &event->root, 
       
   172                          &event->window,
       
   173                          &event->x_root, 
       
   174                          &event->y_root, 
       
   175                          &event->x, 
       
   176                          &event->y, 
       
   177                          &event->state );
       
   178         
       
   179         event->subwindow    = event->window;
       
   180         event->state        = buttonNMask;
       
   181         
       
   182         // Find the top window at cursor position. 
       
   183         while( event->subwindow )
       
   184         {
       
   185             event->window = event->subwindow;
       
   186             
       
   187             ::XQueryPointer( display, 
       
   188                              event->window,
       
   189                              &event->root, 
       
   190                              &event->subwindow,
       
   191                              &event->x_root, 
       
   192                              &event->y_root,
       
   193                              &event->x, 
       
   194                              &event->y,
       
   195                              &event->state );
       
   196         }
       
   197 
       
   198         // For release event just adjust the coordinates in the event. 
       
   199         // Cursor is actually never moved to the release event location. 
       
   200         if( !press )
       
   201         {
       
   202             int delta_x = x - event->x_root;
       
   203             int delta_y = y - event->y_root;
       
   204             
       
   205             event->x      += delta_x;
       
   206             event->y      += delta_y;
       
   207             event->x_root += delta_x;
       
   208             event->y_root += delta_y;
       
   209         }
       
   210 
       
   211         // Double click interval is set to zero in QApplication to avoid getting
       
   212         // unwanted double-click events. It's common that test cases just keep
       
   213         // clicking in the middle of a widget and tests execute in rapidly. 
       
   214         QApplication* app = qApp;
       
   215         if(app) app->setDoubleClickInterval( 0 );
       
   216         
       
   217         event->time         = CurrentTime;
       
   218         event->state        = (press ? buttonNMask : 0);
       
   219 
       
   220         // Unless the window is a tooltip or other window which will be ignored
       
   221         // by the window manager, set input focus to make window activate like 
       
   222         // clicking with real mouse. 
       
   223         XWindowAttributes attr;
       
   224         ::memset(&attr, 0, sizeof(attr));
       
   225         ::XGetWindowAttributes(display, event->window, &attr);
       
   226         if(attr.override_redirect == False) 
       
   227         {
       
   228             ::XSetInputFocus(display, event->window, RevertToNone, CurrentTime);
       
   229         }
       
   230         
       
   231         if( ::XSendEvent( display, 
       
   232                           PointerWindow, 
       
   233                           True, 
       
   234                           0, 
       
   235                           reinterpret_cast<XEvent*>(event) ) == 0)
       
   236         {
       
   237             throw Java::XlibUtils::SENDEVENT_ERR;
       
   238         }
       
   239 
       
   240         ::XFlush( display );
       
   241      }
       
   242      catch(Java::XlibUtils::XlibUtilsErr e)
       
   243      {
       
   244         retVal = static_cast<jint>( e );
       
   245      }
       
   246      
       
   247     if( retVal != Java::XlibUtils::NO_DISPLAY )
       
   248     {
       
   249         ::XCloseDisplay( display );
       
   250     }
       
   251       
       
   252     return retVal;
       
   253     }
       
   254 
       
   255 
       
   256 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_uitestutils_XlibUtils_XSendPointerMoveEvent
       
   257   (JNIEnv *, jclass, jint aX, jint aY, jint aButton)
       
   258     {
       
   259     int x            = static_cast<int>(aX);
       
   260     int y            = static_cast<int>(aY);
       
   261     jint retVal      = 0;
       
   262     Display* display = NULL;
       
   263     int buttonNMask  = 1 << (7 + aButton); // Button1Mask, Button2Mask, ..., Button5Mask
       
   264     
       
   265     try
       
   266     {
       
   267         display = ::XOpenDisplay( NULL ); 
       
   268         if( !display )
       
   269         {
       
   270             throw Java::XlibUtils::NO_DISPLAY;
       
   271         }
       
   272         
       
   273         Window rootWindow = ::XDefaultRootWindow( display );
       
   274         if( rootWindow == None )
       
   275         {
       
   276             throw Java::XlibUtils::NO_ROOTWINDOW;
       
   277         }
       
   278 
       
   279         XMotionEvent* event = new(std::nothrow) XMotionEvent();
       
   280         if( !event )
       
   281         {
       
   282             throw Java::XlibUtils::NO_MEMORY;
       
   283         }
       
   284                 
       
   285         event->type         = MotionNotify;
       
   286         event->serial       = None;
       
   287         event->send_event   = False;
       
   288         event->display      = display;
       
   289 //      event->window       = ;
       
   290 //      event->root         = ;
       
   291 //      event->subWindow    = ;
       
   292         event->time         = CurrentTime;
       
   293 //      event->x            = ;
       
   294 //      event->y            = ;
       
   295 //      event->x_root       = ;
       
   296 //      event->y_root       = ;
       
   297 //      event->state        = ;
       
   298         event->is_hint      = NotifyNormal;
       
   299         event->same_screen  = True;
       
   300         
       
   301         ::XQueryPointer( display, 
       
   302                          rootWindow, 
       
   303                          &event->root, 
       
   304                          &event->window,
       
   305                          &event->x_root, 
       
   306                          &event->y_root, 
       
   307                          &event->x, 
       
   308                          &event->y, 
       
   309                          &event->state );
       
   310         
       
   311         event->subwindow    = event->window;
       
   312         event->state        = buttonNMask;
       
   313         
       
   314         // Find the top window at cursor position. 
       
   315         while( event->subwindow )
       
   316         {
       
   317             event->window = event->subwindow;
       
   318             
       
   319             ::XQueryPointer( display, 
       
   320                              event->window,
       
   321                              &event->root, 
       
   322                              &event->subwindow,
       
   323                              &event->x_root, 
       
   324                              &event->y_root,
       
   325                              &event->x, 
       
   326                              &event->y,
       
   327                              &event->state );
       
   328         }
       
   329 
       
   330         // For motion event just adjust the coordinates in the event. 
       
   331         // Cursor is actually never moved to the motion event location. 
       
   332         int delta_x = x - event->x_root;
       
   333         int delta_y = y - event->y_root;
       
   334 
       
   335         event->x      += delta_x;
       
   336         event->y      += delta_y;
       
   337         event->x_root += delta_x;
       
   338         event->y_root += delta_y;
       
   339 
       
   340         event->state   = buttonNMask;
       
   341 
       
   342         if( ::XSendEvent( display, 
       
   343                           PointerWindow, 
       
   344                           True, 
       
   345                           0, 
       
   346                           reinterpret_cast<XEvent*>(event) ) == 0)
       
   347         {
       
   348             throw Java::XlibUtils::SENDEVENT_ERR;
       
   349         }
       
   350 
       
   351         ::XFlush( display );
       
   352      }
       
   353      catch(Java::XlibUtils::XlibUtilsErr e)
       
   354      {
       
   355         retVal = static_cast<jint>( e );
       
   356      }
       
   357      
       
   358     if( retVal != Java::XlibUtils::NO_DISPLAY )
       
   359     {
       
   360         ::XCloseDisplay( display );
       
   361     }
       
   362       
       
   363     return retVal;
       
   364     }
       
   365