| Index: chrome/renderer/render_view_unittest.cc
|
| ===================================================================
|
| --- chrome/renderer/render_view_unittest.cc (revision 15745)
|
| +++ chrome/renderer/render_view_unittest.cc (working copy)
|
| @@ -315,19 +315,14 @@
|
| // through the RenderWidget::OnHandleInputEvent() function.
|
| TEST_F(RenderViewTest, OnHandleKeyboardEvent) {
|
| #if defined(OS_WIN)
|
| - // Save the keyboard layout and the status.
|
| - // This test changes the keyboard layout and status. This may break
|
| - // succeeding tests. To prevent this possible break, we should save the
|
| - // layout and status here to restore when this test is finished.
|
| - HKL original_layout = GetKeyboardLayout(0);
|
| - BYTE original_key_states[256];
|
| - GetKeyboardState(&original_key_states[0]);
|
| -
|
| // Load an HTML page consisting of one <input> element and three
|
| // contentediable <div> elements.
|
| // The <input> element is used for sending keyboard events, and the <div>
|
| // elements are used for writing DOM events in the following format:
|
| - // "<keyCode>,<shiftKey>,<controlKey>,<altKey>,<metaKey>".
|
| + // "<keyCode>,<shiftKey>,<controlKey>,<altKey>".
|
| + // TODO(hbono): <http://crbug.com/2215> Our WebKit port set |ev.metaKey| to
|
| + // true when pressing an alt key, i.e. the |ev.metaKey| value is not
|
| + // trustworthy. We will check the |ev.metaKey| value when this issue is fixed.
|
| view_->set_delay_seconds_for_form_state_sync(0);
|
| LoadHTML("<html>"
|
| "<head>"
|
| @@ -339,8 +334,7 @@
|
| " (ev.which || ev.keyCode) + ',' +"
|
| " ev.shiftKey + ',' +"
|
| " ev.ctrlKey + ',' +"
|
| - " ev.altKey + ',' +"
|
| - " ev.metaKey;"
|
| + " ev.altKey;"
|
| " return true;"
|
| "}"
|
| "</script>"
|
| @@ -362,24 +356,33 @@
|
| ExecuteJavaScript("document.getElementById('test').focus();");
|
| render_thread_.sink().ClearMessages();
|
|
|
| - // Language IDs used in this test.
|
| - // This test directly loads keyboard-layout drivers and use them for
|
| - // emulating non-US keyboard layouts.
|
| - static const wchar_t* kLanguageIDs[] = {
|
| - L"00000401", // Arabic
|
| - L"00000409", // United States
|
| - L"0000040c", // French
|
| - L"0000040d", // Hebrew
|
| - L"00001009", // Canadian French
|
| + static const MockKeyboard::Layout kLayouts[] = {
|
| + MockKeyboard::LAYOUT_ARABIC,
|
| + MockKeyboard::LAYOUT_CANADIAN_FRENCH,
|
| + MockKeyboard::LAYOUT_FRENCH,
|
| + MockKeyboard::LAYOUT_HEBREW,
|
| + MockKeyboard::LAYOUT_RUSSIAN,
|
| + MockKeyboard::LAYOUT_UNITED_STATES,
|
| };
|
| - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLanguageIDs); ++i) {
|
| - // Load a keyboard-layout driver.
|
| - HKL handle = LoadKeyboardLayout(kLanguageIDs[i], KLF_ACTIVATE);
|
| - EXPECT_TRUE(handle != NULL);
|
|
|
| - // For each key code, we send two keyboard events: one when we only press
|
| - // the key, and one when we press the key and a shift key.
|
| - for (int modifiers = 0; modifiers < 2; ++modifiers) {
|
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLayouts); ++i) {
|
| + // For each key code, we send three keyboard events.
|
| + // * we press only the key;
|
| + // * we press the key and a left-shift key, and;
|
| + // * we press the key and a right-alt (AltGr) key.
|
| + // For each modifiers, we need a string used for formatting its expected
|
| + // result. (See the above comment for its format.)
|
| + static const struct {
|
| + MockKeyboard::Modifiers modifiers;
|
| + const wchar_t* expected_result;
|
| + } kModifierData[] = {
|
| + {MockKeyboard::NONE, L"false,false,false"},
|
| + {MockKeyboard::LEFT_SHIFT, L"true,false,false"},
|
| + {MockKeyboard::RIGHT_ALT, L"false,false,true"},
|
| + };
|
| +
|
| + MockKeyboard::Layout layout = kLayouts[i];
|
| + for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kModifierData); ++j) {
|
| // Virtual key codes used for this test.
|
| static const int kKeyCodes[] = {
|
| '0', '1', '2', '3', '4', '5', '6', '7',
|
| @@ -401,72 +404,30 @@
|
| VK_OEM_8,
|
| };
|
|
|
| - // Over-write the keyboard status with our modifier-key status.
|
| - // WebInputEventFactory::keyboardEvent() uses GetKeyState() to retrive
|
| - // modifier-key status. So, we update the modifier-key status with this
|
| - // SetKeyboardState() call before creating NativeWebKeyboardEvent
|
| - // instances.
|
| - BYTE key_states[256];
|
| - memset(&key_states[0], 0, sizeof(key_states));
|
| - key_states[VK_SHIFT] = (modifiers & 0x01) ? 0x80 : 0;
|
| - SetKeyboardState(&key_states[0]);
|
| -
|
| - for (size_t j = 0; j <= ARRAYSIZE_UNSAFE(kKeyCodes); ++j) {
|
| - // Retrieve the Unicode character composed from the virtual-key code
|
| - // and our modifier-key status from the keyboard-layout driver.
|
| - // This character is used for creating a WM_CHAR message and an
|
| - // expected result.
|
| - int key_code = kKeyCodes[j];
|
| - wchar_t codes[4];
|
| - int length = ToUnicodeEx(key_code, MapVirtualKey(key_code, 0),
|
| - &key_states[0], &codes[0],
|
| - ARRAYSIZE_UNSAFE(codes), 0, handle);
|
| - if (length != 1)
|
| + MockKeyboard::Modifiers modifiers = kModifierData[j].modifiers;
|
| + for (size_t k = 0; k <= ARRAYSIZE_UNSAFE(kKeyCodes); ++k) {
|
| + // Send a keyboard event to the RenderView object.
|
| + // We should test a keyboard event only when the given keyboard-layout
|
| + // driver is installed in a PC and the driver can assign a Unicode
|
| + // charcter for the given tuple (key-code and modifiers).
|
| + int key_code = kKeyCodes[k];
|
| + std::wstring char_code;
|
| + if (SendKeyEvent(layout, key_code, modifiers, &char_code) < 0)
|
| continue;
|
|
|
| - // Create IPC messages from Windows messages and send them to our
|
| - // back-end.
|
| - // A keyboard event of Windows consists of three Windows messages:
|
| - // WM_KEYDOWN, WM_CHAR, and WM_KEYUP.
|
| - // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand,
|
| - // WM_CHAR sends a composed Unicode character.
|
| - NativeWebKeyboardEvent keydown_event(NULL, WM_KEYDOWN, key_code, 0);
|
| - scoped_ptr<IPC::Message> keydown_message(
|
| - new ViewMsg_HandleInputEvent(0));
|
| - keydown_message->WriteData(
|
| - reinterpret_cast<const char*>(&keydown_event),
|
| - sizeof(WebKit::WebKeyboardEvent));
|
| - view_->OnHandleInputEvent(*keydown_message);
|
| -
|
| - NativeWebKeyboardEvent char_event(NULL, WM_CHAR, codes[0], 0);
|
| - scoped_ptr<IPC::Message> char_message(new ViewMsg_HandleInputEvent(0));
|
| - char_message->WriteData(reinterpret_cast<const char*>(&char_event),
|
| - sizeof(WebKit::WebKeyboardEvent));
|
| - view_->OnHandleInputEvent(*char_message);
|
| -
|
| - NativeWebKeyboardEvent keyup_event(NULL, WM_KEYUP, key_code, 0);
|
| - scoped_ptr<IPC::Message> keyup_message(new ViewMsg_HandleInputEvent(0));
|
| - keyup_message->WriteData(reinterpret_cast<const char*>(&keyup_event),
|
| - sizeof(WebKit::WebKeyboardEvent));
|
| - view_->OnHandleInputEvent(*keyup_message);
|
| -
|
| // Create an expected result from the virtual-key code, the character
|
| // code, and the modifier-key status.
|
| // We format a string that emulates a DOM-event string produced hy
|
| // our JavaScript function. (See the above comment for the format.)
|
| - static const wchar_t* kModifiers[] = {
|
| - L"false,false,false,false",
|
| - L"true,false,false,false",
|
| - };
|
| static wchar_t expected_result[1024];
|
| wsprintf(&expected_result[0],
|
| L"\x000A" // texts in the <input> element
|
| L"%d,%s\x000A" // texts in the first <div> element
|
| L"%d,%s\x000A" // texts in the second <div> element
|
| L"%d,%s", // texts in the third <div> element
|
| - key_code, kModifiers[modifiers],
|
| - codes[0], kModifiers[modifiers],
|
| - key_code, kModifiers[modifiers]);
|
| + key_code, kModifierData[j].expected_result,
|
| + char_code[0], kModifierData[j].expected_result,
|
| + key_code, kModifierData[j].expected_result);
|
|
|
| // Retrieve the text in the test page and compare it with the expected
|
| // text created from a virtual-key code, a character code, and the
|
| @@ -478,13 +439,217 @@
|
| EXPECT_EQ(expected_result, output);
|
| }
|
| }
|
| + }
|
| +#else
|
| + NOTIMPLEMENTED();
|
| +#endif
|
| +}
|
|
|
| - UnloadKeyboardLayout(handle);
|
| +// Test that our EditorClientImpl class can insert characters when we send
|
| +// keyboard events through the RenderWidget::OnHandleInputEvent() function.
|
| +// This test is for preventing regressions caused only when we use non-US
|
| +// keyboards, such as Issue 10846.
|
| +TEST_F(RenderViewTest, InsertCharacters) {
|
| +#if defined(OS_WIN)
|
| + static const struct {
|
| + MockKeyboard::Layout layout;
|
| + const wchar_t* expected_result;
|
| + } kLayouts[] = {
|
| +#if 0
|
| + // Disabled these keyboard layouts because buildbots do not have their
|
| + // keyboard-layout drivers installed.
|
| + {MockKeyboard::LAYOUT_ARABIC,
|
| + L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
|
| + L"\x0038\x0039\x0634\x0624\x064a\x062b\x0628\x0644"
|
| + L"\x0627\x0647\x062a\x0646\x0645\x0629\x0649\x062e"
|
| + L"\x062d\x0636\x0642\x0633\x0641\x0639\x0631\x0635"
|
| + L"\x0621\x063a\x0626\x0643\x003d\x0648\x002d\x0632"
|
| + L"\x0638\x0630\x062c\x005c\x062f\x0637\x0028\x0021"
|
| + L"\x0040\x0023\x0024\x0025\x005e\x0026\x002a\x0029"
|
| + L"\x0650\x007d\x005d\x064f\x005b\x0623\x00f7\x0640"
|
| + L"\x060c\x002f\x2019\x0622\x00d7\x061b\x064e\x064c"
|
| + L"\x064d\x2018\x007b\x064b\x0652\x0625\x007e\x003a"
|
| + L"\x002b\x002c\x005f\x002e\x061f\x0651\x003c\x007c"
|
| + L"\x003e\x0022\x0030\x0031\x0032\x0033\x0034\x0035"
|
| + L"\x0036\x0037\x0038\x0039\x0634\x0624\x064a\x062b"
|
| + L"\x0628\x0644\x0627\x0647\x062a\x0646\x0645\x0629"
|
| + L"\x0649\x062e\x062d\x0636\x0642\x0633\x0641\x0639"
|
| + L"\x0631\x0635\x0621\x063a\x0626\x0643\x003d\x0648"
|
| + L"\x002d\x0632\x0638\x0630\x062c\x005c\x062f\x0637"
|
| + },
|
| + {MockKeyboard::LAYOUT_HEBREW,
|
| + L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
|
| + L"\x0038\x0039\x05e9\x05e0\x05d1\x05d2\x05e7\x05db"
|
| + L"\x05e2\x05d9\x05df\x05d7\x05dc\x05da\x05e6\x05de"
|
| + L"\x05dd\x05e4\x002f\x05e8\x05d3\x05d0\x05d5\x05d4"
|
| + L"\x0027\x05e1\x05d8\x05d6\x05e3\x003d\x05ea\x002d"
|
| + L"\x05e5\x002e\x003b\x005d\x005c\x005b\x002c\x0028"
|
| + L"\x0021\x0040\x0023\x0024\x0025\x005e\x0026\x002a"
|
| + L"\x0029\x0041\x0042\x0043\x0044\x0045\x0046\x0047"
|
| + L"\x0048\x0049\x004a\x004b\x004c\x004d\x004e\x004f"
|
| + L"\x0050\x0051\x0052\x0053\x0054\x0055\x0056\x0057"
|
| + L"\x0058\x0059\x005a\x003a\x002b\x003e\x005f\x003c"
|
| + L"\x003f\x007e\x007d\x007c\x007b\x0022\x0030\x0031"
|
| + L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039"
|
| + L"\x05e9\x05e0\x05d1\x05d2\x05e7\x05db\x05e2\x05d9"
|
| + L"\x05df\x05d7\x05dc\x05da\x05e6\x05de\x05dd\x05e4"
|
| + L"\x002f\x05e8\x05d3\x05d0\x05d5\x05d4\x0027\x05e1"
|
| + L"\x05d8\x05d6\x05e3\x003d\x05ea\x002d\x05e5\x002e"
|
| + L"\x003b\x005d\x005c\x005b\x002c"
|
| + },
|
| +#endif
|
| + {MockKeyboard::LAYOUT_CANADIAN_FRENCH,
|
| + L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
|
| + L"\x0038\x0039\x0061\x0062\x0063\x0064\x0065\x0066"
|
| + L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e"
|
| + L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076"
|
| + L"\x0077\x0078\x0079\x007a\x003b\x003d\x002c\x002d"
|
| + L"\x002e\x00e9\x003c\x0029\x0021\x0022\x002f\x0024"
|
| + L"\x0025\x003f\x0026\x002a\x0028\x0041\x0042\x0043"
|
| + L"\x0044\x0045\x0046\x0047\x0048\x0049\x004a\x004b"
|
| + L"\x004c\x004d\x004e\x004f\x0050\x0051\x0052\x0053"
|
| + L"\x0054\x0055\x0056\x0057\x0058\x0059\x005a\x003a"
|
| + L"\x002b\x0027\x005f\x002e\x00c9\x003e\x0030\x0031"
|
| + L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039"
|
| + L"\x0061\x0062\x0063\x0064\x0065\x0066\x0067\x0068"
|
| + L"\x0069\x006a\x006b\x006c\x006d\x006e\x006f\x0070"
|
| + L"\x0071\x0072\x0073\x0074\x0075\x0076\x0077\x0078"
|
| + L"\x0079\x007a\x003b\x003d\x002c\x002d\x002e\x00e9"
|
| + L"\x003c"
|
| + },
|
| + {MockKeyboard::LAYOUT_FRENCH,
|
| + L"\x00e0\x0026\x00e9\x0022\x0027\x0028\x002d\x00e8"
|
| + L"\x005f\x00e7\x0061\x0062\x0063\x0064\x0065\x0066"
|
| + L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e"
|
| + L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076"
|
| + L"\x0077\x0078\x0079\x007a\x0024\x003d\x002c\x003b"
|
| + L"\x003a\x00f9\x0029\x002a\x0021\x0030\x0031\x0032"
|
| + L"\x0033\x0034\x0035\x0036\x0037\x0038\x0039\x0041"
|
| + L"\x0042\x0043\x0044\x0045\x0046\x0047\x0048\x0049"
|
| + L"\x004a\x004b\x004c\x004d\x004e\x004f\x0050\x0051"
|
| + L"\x0052\x0053\x0054\x0055\x0056\x0057\x0058\x0059"
|
| + L"\x005a\x00a3\x002b\x003f\x002e\x002f\x0025\x00b0"
|
| + L"\x00b5\x00e0\x0026\x00e9\x0022\x0027\x0028\x002d"
|
| + L"\x00e8\x005f\x00e7\x0061\x0062\x0063\x0064\x0065"
|
| + L"\x0066\x0067\x0068\x0069\x006a\x006b\x006c\x006d"
|
| + L"\x006e\x006f\x0070\x0071\x0072\x0073\x0074\x0075"
|
| + L"\x0076\x0077\x0078\x0079\x007a\x0024\x003d\x002c"
|
| + L"\x003b\x003a\x00f9\x0029\x002a\x0021"
|
| + },
|
| + {MockKeyboard::LAYOUT_RUSSIAN,
|
| + L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
|
| + L"\x0038\x0039\x0444\x0438\x0441\x0432\x0443\x0430"
|
| + L"\x043f\x0440\x0448\x043e\x043b\x0434\x044c\x0442"
|
| + L"\x0449\x0437\x0439\x043a\x044b\x0435\x0433\x043c"
|
| + L"\x0446\x0447\x043d\x044f\x0436\x003d\x0431\x002d"
|
| + L"\x044e\x002e\x0451\x0445\x005c\x044a\x044d\x0029"
|
| + L"\x0021\x0022\x2116\x003b\x0025\x003a\x003f\x002a"
|
| + L"\x0028\x0424\x0418\x0421\x0412\x0423\x0410\x041f"
|
| + L"\x0420\x0428\x041e\x041b\x0414\x042c\x0422\x0429"
|
| + L"\x0417\x0419\x041a\x042b\x0415\x0413\x041c\x0426"
|
| + L"\x0427\x041d\x042f\x0416\x002b\x0411\x005f\x042e"
|
| + L"\x002c\x0401\x0425\x002f\x042a\x042d\x0030\x0031"
|
| + L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039"
|
| + L"\x0444\x0438\x0441\x0432\x0443\x0430\x043f\x0440"
|
| + L"\x0448\x043e\x043b\x0434\x044c\x0442\x0449\x0437"
|
| + L"\x0439\x043a\x044b\x0435\x0433\x043c\x0446\x0447"
|
| + L"\x043d\x044f\x0436\x003d\x0431\x002d\x044e\x002e"
|
| + L"\x0451\x0445\x005c\x044a\x044d"
|
| + },
|
| + {MockKeyboard::LAYOUT_UNITED_STATES,
|
| + L"\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037"
|
| + L"\x0038\x0039\x0061\x0062\x0063\x0064\x0065\x0066"
|
| + L"\x0067\x0068\x0069\x006a\x006b\x006c\x006d\x006e"
|
| + L"\x006f\x0070\x0071\x0072\x0073\x0074\x0075\x0076"
|
| + L"\x0077\x0078\x0079\x007a\x003b\x003d\x002c\x002d"
|
| + L"\x002e\x002f\x0060\x005b\x005c\x005d\x0027\x0029"
|
| + L"\x0021\x0040\x0023\x0024\x0025\x005e\x0026\x002a"
|
| + L"\x0028\x0041\x0042\x0043\x0044\x0045\x0046\x0047"
|
| + L"\x0048\x0049\x004a\x004b\x004c\x004d\x004e\x004f"
|
| + L"\x0050\x0051\x0052\x0053\x0054\x0055\x0056\x0057"
|
| + L"\x0058\x0059\x005a\x003a\x002b\x003c\x005f\x003e"
|
| + L"\x003f\x007e\x007b\x007c\x007d\x0022\x0030\x0031"
|
| + L"\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039"
|
| + L"\x0061\x0062\x0063\x0064\x0065\x0066\x0067\x0068"
|
| + L"\x0069\x006a\x006b\x006c\x006d\x006e\x006f\x0070"
|
| + L"\x0071\x0072\x0073\x0074\x0075\x0076\x0077\x0078"
|
| + L"\x0079\x007a\x003b\x003d\x002c\x002d\x002e\x002f"
|
| + L"\x0060\x005b\x005c\x005d\x0027"
|
| + },
|
| + };
|
| +
|
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kLayouts); ++i) {
|
| + // Load an HTML page consisting of one <div> element.
|
| + // This <div> element is used by the EditorClientImpl class to insert
|
| + // characters received through the RenderWidget::OnHandleInputEvent()
|
| + // function.
|
| + view_->set_delay_seconds_for_form_state_sync(0);
|
| + LoadHTML("<html>"
|
| + "<head>"
|
| + "<title></title>"
|
| + "</head>"
|
| + "<body>"
|
| + "<div id='test' contenteditable='true'>"
|
| + "</div>"
|
| + "</body>"
|
| + "</html>");
|
| + ExecuteJavaScript("document.getElementById('test').focus();");
|
| + render_thread_.sink().ClearMessages();
|
| +
|
| + // For each key code, we send three keyboard events.
|
| + // * Pressing only the key;
|
| + // * Pressing the key and a left-shift key, and;
|
| + // * Pressing the key and a right-alt (AltGr) key.
|
| + static const MockKeyboard::Modifiers kModifiers[] = {
|
| + MockKeyboard::NONE,
|
| + MockKeyboard::LEFT_SHIFT,
|
| + MockKeyboard::RIGHT_ALT,
|
| + };
|
| +
|
| + MockKeyboard::Layout layout = kLayouts[i].layout;
|
| + for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kModifiers); ++j) {
|
| + // Virtual key codes used for this test.
|
| + static const int kKeyCodes[] = {
|
| + '0', '1', '2', '3', '4', '5', '6', '7',
|
| + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
| + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
| + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
| + 'W', 'X', 'Y', 'Z',
|
| + VK_OEM_1,
|
| + VK_OEM_PLUS,
|
| + VK_OEM_COMMA,
|
| + VK_OEM_MINUS,
|
| + VK_OEM_PERIOD,
|
| + VK_OEM_2,
|
| + VK_OEM_3,
|
| + VK_OEM_4,
|
| + VK_OEM_5,
|
| + VK_OEM_6,
|
| + VK_OEM_7,
|
| + VK_OEM_8,
|
| + };
|
| +
|
| + MockKeyboard::Modifiers modifiers = kModifiers[j];
|
| + for (size_t k = 0; k <= ARRAYSIZE_UNSAFE(kKeyCodes); ++k) {
|
| + // Send a keyboard event to the RenderView object.
|
| + // We should test a keyboard event only when the given keyboard-layout
|
| + // driver is installed in a PC and the driver can assign a Unicode
|
| + // charcter for the given tuple (layout, key-code, and modifiers).
|
| + int key_code = kKeyCodes[k];
|
| + std::wstring char_code;
|
| + if (SendKeyEvent(layout, key_code, modifiers, &char_code) < 0)
|
| + continue;
|
| + }
|
| + }
|
| +
|
| + // Retrieve the text in the test page and compare it with the expected
|
| + // text created from a virtual-key code, a character code, and the
|
| + // modifier-key status.
|
| + const int kMaxOutputCharacters = 4096;
|
| + std::wstring output;
|
| + GetMainFrame()->GetContentAsPlainText(kMaxOutputCharacters, &output);
|
| + EXPECT_EQ(kLayouts[i].expected_result, output);
|
| }
|
| -
|
| - // Restore the keyboard layout and status.
|
| - SetKeyboardState(&original_key_states[0]);
|
| - ActivateKeyboardLayout(original_layout, KLF_RESET);
|
| #else
|
| NOTIMPLEMENTED();
|
| #endif
|
|
|