Home | History | Annotate | Download | only in events
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/scoped_ptr.h"
      6 #include "testing/gtest/include/gtest/gtest.h"
      7 #include "ui/events/event.h"
      8 #include "ui/events/event_utils.h"
      9 #include "ui/events/keycodes/dom4/keycode_converter.h"
     10 #include "ui/events/test/events_test_utils.h"
     11 
     12 #if defined(USE_X11)
     13 #include <X11/Xlib.h>
     14 #include "ui/events/test/events_test_utils_x11.h"
     15 #include "ui/gfx/x/x11_types.h"
     16 #endif
     17 
     18 namespace ui {
     19 
     20 TEST(EventTest, NoNativeEvent) {
     21   KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, 0, false);
     22   EXPECT_FALSE(keyev.HasNativeEvent());
     23 }
     24 
     25 TEST(EventTest, NativeEvent) {
     26 #if defined(OS_WIN)
     27   MSG native_event = { NULL, WM_KEYUP, VKEY_A, 0 };
     28   KeyEvent keyev(native_event, false);
     29   EXPECT_TRUE(keyev.HasNativeEvent());
     30 #elif defined(USE_X11)
     31   ScopedXI2Event event;
     32   event.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, 0);
     33   KeyEvent keyev(event, false);
     34   EXPECT_TRUE(keyev.HasNativeEvent());
     35 #endif
     36 }
     37 
     38 TEST(EventTest, GetCharacter) {
     39   // Check if Control+Enter returns 10.
     40   KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN, false);
     41   EXPECT_EQ(10, keyev1.GetCharacter());
     42   // Check if Enter returns 13.
     43   KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, 0, false);
     44   EXPECT_EQ(13, keyev2.GetCharacter());
     45 
     46 #if defined(USE_X11)
     47   // For X11, test the functions with native_event() as well. crbug.com/107837
     48   ScopedXI2Event event;
     49   event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
     50   KeyEvent keyev3(event, false);
     51   EXPECT_EQ(10, keyev3.GetCharacter());
     52 
     53   event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, 0);
     54   KeyEvent keyev4(event, false);
     55   EXPECT_EQ(13, keyev4.GetCharacter());
     56 #endif
     57 }
     58 
     59 TEST(EventTest, ClickCount) {
     60   const gfx::Point origin(0, 0);
     61   MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, 0);
     62   for (int i = 1; i <=3 ; ++i) {
     63     mouseev.SetClickCount(i);
     64     EXPECT_EQ(i, mouseev.GetClickCount());
     65   }
     66 }
     67 
     68 TEST(EventTest, Repeated) {
     69   const gfx::Point origin(0, 0);
     70   MouseEvent mouse_ev1(ET_MOUSE_PRESSED, origin, origin, 0);
     71   MouseEvent mouse_ev2(ET_MOUSE_PRESSED, origin, origin, 0);
     72   LocatedEventTestApi test_ev1(&mouse_ev1);
     73   LocatedEventTestApi test_ev2(&mouse_ev2);
     74 
     75   base::TimeDelta start = base::TimeDelta::FromMilliseconds(0);
     76   base::TimeDelta soon = start + base::TimeDelta::FromMilliseconds(1);
     77   base::TimeDelta later = start + base::TimeDelta::FromMilliseconds(1000);
     78 
     79   // Close point.
     80   test_ev1.set_location(gfx::Point(0, 0));
     81   test_ev2.set_location(gfx::Point(1, 0));
     82   test_ev1.set_time_stamp(start);
     83   test_ev2.set_time_stamp(soon);
     84   EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
     85 
     86   // Too far.
     87   test_ev1.set_location(gfx::Point(0, 0));
     88   test_ev2.set_location(gfx::Point(10, 0));
     89   test_ev1.set_time_stamp(start);
     90   test_ev2.set_time_stamp(soon);
     91   EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
     92 
     93   // Too long a time between clicks.
     94   test_ev1.set_location(gfx::Point(0, 0));
     95   test_ev2.set_location(gfx::Point(0, 0));
     96   test_ev1.set_time_stamp(start);
     97   test_ev2.set_time_stamp(later);
     98   EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
     99 }
    100 
    101 TEST(EventTest, KeyEvent) {
    102   static const struct {
    103     KeyboardCode key_code;
    104     int flags;
    105     uint16 character;
    106   } kTestData[] = {
    107     { VKEY_A, 0, 'a' },
    108     { VKEY_A, EF_SHIFT_DOWN, 'A' },
    109     { VKEY_A, EF_CAPS_LOCK_DOWN, 'A' },
    110     { VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'a' },
    111     { VKEY_A, EF_CONTROL_DOWN, 0x01 },
    112     { VKEY_A, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x01' },
    113     { VKEY_Z, 0, 'z' },
    114     { VKEY_Z, EF_SHIFT_DOWN, 'Z' },
    115     { VKEY_Z, EF_CAPS_LOCK_DOWN, 'Z' },
    116     { VKEY_Z, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'z' },
    117     { VKEY_Z, EF_CONTROL_DOWN, '\x1A' },
    118     { VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1A' },
    119 
    120     { VKEY_2, EF_CONTROL_DOWN, '\0' },
    121     { VKEY_2, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
    122     { VKEY_6, EF_CONTROL_DOWN, '\0' },
    123     { VKEY_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1E' },
    124     { VKEY_OEM_MINUS, EF_CONTROL_DOWN, '\0' },
    125     { VKEY_OEM_MINUS, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1F' },
    126     { VKEY_OEM_4, EF_CONTROL_DOWN, '\x1B' },
    127     { VKEY_OEM_4, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
    128     { VKEY_OEM_5, EF_CONTROL_DOWN, '\x1C' },
    129     { VKEY_OEM_5, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
    130     { VKEY_OEM_6, EF_CONTROL_DOWN, '\x1D' },
    131     { VKEY_OEM_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
    132     { VKEY_RETURN, EF_CONTROL_DOWN, '\x0A' },
    133 
    134     { VKEY_0, 0, '0' },
    135     { VKEY_0, EF_SHIFT_DOWN, ')' },
    136     { VKEY_0, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, ')' },
    137     { VKEY_0, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
    138 
    139     { VKEY_9, 0, '9' },
    140     { VKEY_9, EF_SHIFT_DOWN, '(' },
    141     { VKEY_9, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, '(' },
    142     { VKEY_9, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
    143 
    144     { VKEY_NUMPAD0, EF_CONTROL_DOWN, '\0' },
    145     { VKEY_NUMPAD0, EF_SHIFT_DOWN, '0' },
    146 
    147     { VKEY_NUMPAD9, EF_CONTROL_DOWN, '\0' },
    148     { VKEY_NUMPAD9, EF_SHIFT_DOWN, '9' },
    149 
    150     { VKEY_TAB, EF_CONTROL_DOWN, '\0' },
    151     { VKEY_TAB, EF_SHIFT_DOWN, '\t' },
    152 
    153     { VKEY_MULTIPLY, EF_CONTROL_DOWN, '\0' },
    154     { VKEY_MULTIPLY, EF_SHIFT_DOWN, '*' },
    155     { VKEY_ADD, EF_CONTROL_DOWN, '\0' },
    156     { VKEY_ADD, EF_SHIFT_DOWN, '+' },
    157     { VKEY_SUBTRACT, EF_CONTROL_DOWN, '\0' },
    158     { VKEY_SUBTRACT, EF_SHIFT_DOWN, '-' },
    159     { VKEY_DECIMAL, EF_CONTROL_DOWN, '\0' },
    160     { VKEY_DECIMAL, EF_SHIFT_DOWN, '.' },
    161     { VKEY_DIVIDE, EF_CONTROL_DOWN, '\0' },
    162     { VKEY_DIVIDE, EF_SHIFT_DOWN, '/' },
    163 
    164     { VKEY_OEM_1, EF_CONTROL_DOWN, '\0' },
    165     { VKEY_OEM_1, EF_SHIFT_DOWN, ':' },
    166     { VKEY_OEM_PLUS, EF_CONTROL_DOWN, '\0' },
    167     { VKEY_OEM_PLUS, EF_SHIFT_DOWN, '+' },
    168     { VKEY_OEM_COMMA, EF_CONTROL_DOWN, '\0' },
    169     { VKEY_OEM_COMMA, EF_SHIFT_DOWN, '<' },
    170     { VKEY_OEM_PERIOD, EF_CONTROL_DOWN, '\0' },
    171     { VKEY_OEM_PERIOD, EF_SHIFT_DOWN, '>' },
    172     { VKEY_OEM_3, EF_CONTROL_DOWN, '\0' },
    173     { VKEY_OEM_3, EF_SHIFT_DOWN, '~' },
    174   };
    175 
    176   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestData); ++i) {
    177     KeyEvent key(ET_KEY_PRESSED,
    178                  kTestData[i].key_code,
    179                  kTestData[i].flags,
    180                  false);
    181     EXPECT_EQ(kTestData[i].character, key.GetCharacter())
    182         << " Index:" << i << " key_code:" << kTestData[i].key_code;
    183   }
    184 }
    185 
    186 TEST(EventTest, KeyEventDirectUnicode) {
    187   KeyEvent key(ET_KEY_PRESSED, VKEY_UNKNOWN, EF_SHIFT_DOWN, false);
    188   key.set_character(0x1234U);
    189   EXPECT_EQ(0x1234U, key.GetCharacter());
    190   KeyEvent key2(ET_KEY_RELEASED, VKEY_UNKNOWN, EF_CONTROL_DOWN, false);
    191   key2.set_character(0x4321U);
    192   EXPECT_EQ(0x4321U, key2.GetCharacter());
    193 }
    194 
    195 TEST(EventTest, NormalizeKeyEventFlags) {
    196 #if defined(USE_X11)
    197   // Normalize flags when KeyEvent is created from XEvent.
    198   ScopedXI2Event event;
    199   {
    200     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
    201     KeyEvent keyev(event, false);
    202     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
    203   }
    204   {
    205     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
    206     KeyEvent keyev(event, false);
    207     EXPECT_EQ(EF_NONE, keyev.flags());
    208   }
    209   {
    210     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
    211     KeyEvent keyev(event, false);
    212     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
    213   }
    214   {
    215     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
    216     KeyEvent keyev(event, false);
    217     EXPECT_EQ(EF_NONE, keyev.flags());
    218   }
    219   {
    220     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_MENU,  EF_ALT_DOWN);
    221     KeyEvent keyev(event, false);
    222     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
    223   }
    224   {
    225     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
    226     KeyEvent keyev(event, false);
    227     EXPECT_EQ(EF_NONE, keyev.flags());
    228   }
    229 #endif
    230 
    231   // Do not normalize flags for synthesized events without
    232   // KeyEvent::NormalizeFlags called explicitly.
    233   {
    234     KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN, false);
    235     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
    236   }
    237   {
    238     KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN, false);
    239     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
    240     keyev.NormalizeFlags();
    241     EXPECT_EQ(EF_NONE, keyev.flags());
    242   }
    243   {
    244     KeyEvent keyev(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN, false);
    245     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
    246   }
    247   {
    248     KeyEvent keyev(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN, false);
    249     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
    250     keyev.NormalizeFlags();
    251     EXPECT_EQ(EF_NONE, keyev.flags());
    252   }
    253   {
    254     KeyEvent keyev(ET_KEY_PRESSED, VKEY_MENU,  EF_ALT_DOWN, false);
    255     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
    256   }
    257   {
    258     KeyEvent keyev(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN, false);
    259     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
    260     keyev.NormalizeFlags();
    261     EXPECT_EQ(EF_NONE, keyev.flags());
    262   }
    263 }
    264 
    265 TEST(EventTest, KeyEventCopy) {
    266   KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE, false);
    267   scoped_ptr<KeyEvent> copied_key(new KeyEvent(key));
    268   EXPECT_EQ(copied_key->type(), key.type());
    269   EXPECT_EQ(copied_key->key_code(), key.key_code());
    270 }
    271 
    272 TEST(EventTest, KeyEventCode) {
    273   KeycodeConverter* conv = KeycodeConverter::GetInstance();
    274 
    275   const char kCodeForSpace[] = "Space";
    276   const uint16 kNativeCodeSpace = conv->CodeToNativeKeycode(kCodeForSpace);
    277   ASSERT_NE(conv->InvalidNativeKeycode(), kNativeCodeSpace);
    278 
    279   {
    280     KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kCodeForSpace, EF_NONE, false);
    281     EXPECT_EQ(kCodeForSpace, key.code());
    282   }
    283   {
    284     // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be
    285     // the specified value.
    286     KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kCodeForSpace, EF_NONE, false);
    287     EXPECT_EQ(kCodeForSpace, key.code());
    288   }
    289   {
    290     // If the synthetic event is initialized without code, it returns
    291     // an empty string.
    292     // TODO(komatsu): Fill a fallback value assuming the US keyboard layout.
    293     KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE, false);
    294     EXPECT_TRUE(key.code().empty());
    295   }
    296 #if defined(USE_X11)
    297   {
    298     // KeyEvent converts from the native keycode (XKB) to the code.
    299     ScopedXI2Event xevent;
    300     xevent.InitKeyEvent(ET_KEY_PRESSED, VKEY_SPACE, kNativeCodeSpace);
    301     KeyEvent key(xevent, false);
    302     EXPECT_EQ(kCodeForSpace, key.code());
    303   }
    304 #endif  // USE_X11
    305 #if defined(OS_WIN)
    306   {
    307     // Test a non extended key.
    308     ASSERT_EQ((kNativeCodeSpace & 0xFF), kNativeCodeSpace);
    309 
    310     const LPARAM lParam = GetLParamFromScanCode(kNativeCodeSpace);
    311     MSG native_event = { NULL, WM_KEYUP, VKEY_SPACE, lParam };
    312     KeyEvent key(native_event, false);
    313 
    314     // KeyEvent converts from the native keycode (scan code) to the code.
    315     EXPECT_EQ(kCodeForSpace, key.code());
    316   }
    317   {
    318     const char kCodeForHome[]  = "Home";
    319     const uint16 kNativeCodeHome  = 0xe047;
    320 
    321     // 'Home' is an extended key with 0xe000 bits.
    322     ASSERT_NE((kNativeCodeHome & 0xFF), kNativeCodeHome);
    323     const LPARAM lParam = GetLParamFromScanCode(kNativeCodeHome);
    324 
    325     MSG native_event = { NULL, WM_KEYUP, VKEY_HOME, lParam };
    326     KeyEvent key(native_event, false);
    327 
    328     // KeyEvent converts from the native keycode (scan code) to the code.
    329     EXPECT_EQ(kCodeForHome, key.code());
    330   }
    331 #endif  // OS_WIN
    332 }
    333 
    334 }  // namespace ui
    335