зеркало из https://github.com/mozilla/pjs.git
Relanding fix for bug 287179 unmodified charCode is generated for keypress event when both ctrl and shift are held down, patch by Dainis Jonitis r=emaijala sr=me for changes since previous attempts (see previous checkins for superreviewers)
This commit is contained in:
Родитель
2c19163739
Коммит
84dd62f553
|
@ -67,9 +67,9 @@ REQUIRES = xpcom \
|
|||
xuldoc \
|
||||
view \
|
||||
imglib2 \
|
||||
uriloader \
|
||||
webbrowserpersist \
|
||||
unicharutil \
|
||||
uriloader \
|
||||
webbrowserpersist \
|
||||
unicharutil \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_CAIRO_GFX
|
||||
|
@ -82,6 +82,7 @@ CPPSRCS = \
|
|||
nsAppShell.cpp \
|
||||
nsLookAndFeel.cpp \
|
||||
nsToolkit.cpp \
|
||||
nsKeyboardLayout.cpp \
|
||||
nsDataObj.cpp \
|
||||
nsDataObjCollection.cpp \
|
||||
nsClipboard.cpp \
|
||||
|
|
|
@ -225,6 +225,22 @@ PRUint32 VirtualKey::GetNativeUniChars (PRUint8 aShiftState, PRUint16* aUniChars
|
|||
|
||||
|
||||
|
||||
KeyboardLayout::KeyboardLayout ()
|
||||
{
|
||||
#ifndef WINCE
|
||||
mDeadKeyTableListHead = nsnull;
|
||||
#endif
|
||||
|
||||
LoadLayout ();
|
||||
}
|
||||
|
||||
KeyboardLayout::~KeyboardLayout ()
|
||||
{
|
||||
#ifndef WINCE
|
||||
ReleaseDeadKeyTables ();
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool KeyboardLayout::IsPrintableCharKey (PRUint8 aVirtualKey)
|
||||
{
|
||||
#ifndef WINCE
|
||||
|
@ -361,37 +377,39 @@ void KeyboardLayout::LoadLayout ()
|
|||
NS_ASSERTION (vki < NS_ARRAY_LENGTH (mVirtualKeys), "invalid index");
|
||||
|
||||
PRUint16 uniChars [5];
|
||||
WORD ascii;
|
||||
WORD ascii [2]; // On Win9x ToAsciiEx returns WORD per character, on Win2k BYTE per character.
|
||||
PRInt32 rv;
|
||||
|
||||
if (nsToolkit::mIsNT)
|
||||
rv = ::ToUnicode (virtualKey, 0, kbdState, (LPWSTR)uniChars, NS_ARRAY_LENGTH (uniChars), 0);
|
||||
else
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, &ascii, 0, mKeyboardLayout);
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, ascii, 0, mKeyboardLayout);
|
||||
|
||||
if (rv == -1) // dead-key
|
||||
if (rv < 0) // dead-key
|
||||
{
|
||||
shiftStatesWithDeadKeys |= 1 << shiftState;
|
||||
|
||||
// Repeat dead-key to deactivate it and get its character representation.
|
||||
PRUint16 deadChar;
|
||||
PRUint16 deadChar [2];
|
||||
|
||||
if (nsToolkit::mIsNT)
|
||||
::ToUnicode (virtualKey, 0, kbdState, (LPWSTR)&deadChar, 1, 0);
|
||||
rv = ::ToUnicode (virtualKey, 0, kbdState, (LPWSTR)deadChar, NS_ARRAY_LENGTH (deadChar), 0);
|
||||
else
|
||||
{
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, &ascii, 0, mKeyboardLayout);
|
||||
::MultiByteToWideChar (mCodePage, 0, (LPCSTR)&ascii, rv, (WCHAR*)&deadChar, 1);
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, ascii, 0, mKeyboardLayout);
|
||||
::MultiByteToWideChar (mCodePage, 0, (LPCSTR)ascii, 1, (WCHAR*)deadChar, 1);
|
||||
}
|
||||
|
||||
mVirtualKeys [vki].SetDeadChar (shiftState, deadChar);
|
||||
NS_ASSERTION (rv == 2, "Expecting twice repeated dead-key character");
|
||||
|
||||
mVirtualKeys [vki].SetDeadChar (shiftState, deadChar [0]);
|
||||
} else
|
||||
{
|
||||
if (rv == 1) // dead-key can pair only with exactly one base character.
|
||||
shiftStatesWithBaseChars |= 1 << shiftState;
|
||||
|
||||
if (!nsToolkit::mIsNT)
|
||||
rv = ::MultiByteToWideChar (mCodePage, 0, (LPCSTR)&ascii, rv, (WCHAR*)uniChars, NS_ARRAY_LENGTH (uniChars));
|
||||
rv = ::MultiByteToWideChar (mCodePage, 0, (LPCSTR)ascii, rv, (WCHAR*)uniChars, NS_ARRAY_LENGTH (uniChars));
|
||||
|
||||
mVirtualKeys [vki].SetNormalChars (shiftState, uniChars, rv);
|
||||
}
|
||||
|
@ -485,11 +503,12 @@ void KeyboardLayout::SetShiftState (PBYTE aKbdState, PRUint8 aShiftState)
|
|||
|
||||
inline PRInt32 KeyboardLayout::GetKeyIndex (PRUint8 aVirtualKey)
|
||||
{
|
||||
// Currently these 49 (NUM_OF_KEYS) virtual keys are assumed
|
||||
// Currently these 50 (NUM_OF_KEYS) virtual keys are assumed
|
||||
// to produce visible representation:
|
||||
// 0x20 - VK_SPACE ' '
|
||||
// 0x30..0x39 '0'..'9'
|
||||
// 0x41..0x5A 'A'..'Z'
|
||||
// 0x6E - VK_DECIMAL '.'
|
||||
// 0xBA - VK_OEM_1 ';:' for US
|
||||
// 0xBB - VK_OEM_PLUS '+' any country
|
||||
// 0xBC - VK_OEM_COMMA ',' any country
|
||||
|
@ -513,14 +532,14 @@ inline PRInt32 KeyboardLayout::GetKeyIndex (PRUint8 aVirtualKey)
|
|||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, // 30
|
||||
-1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 40
|
||||
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -1, -1, -1, -1, -1, // 50
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 60
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, -1, // 60
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 70
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 90
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // A0
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, 38, 39, 40, 41, 42, // B0
|
||||
43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // C0
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 45, 46, 47, 48, // D0
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, 39, 40, 41, 42, 43, // B0
|
||||
44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // C0
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, // D0
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // E0
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // F0
|
||||
};
|
||||
|
@ -577,13 +596,13 @@ PRBool KeyboardLayout::EnsureDeadKeyActive (PRBool aIsActive, PRUint8 aDeadKey,
|
|||
else
|
||||
rv = ::ToAsciiEx (aDeadKey, 0, (PBYTE)aDeadKeyKbdState, dummyChars, 0, mKeyboardLayout);
|
||||
// returned values:
|
||||
// -1 - Dead key state is active. The keyboard driver will wait for next character.
|
||||
// <0 - Dead key state is active. The keyboard driver will wait for next character.
|
||||
// 1 - Previous pressed key was a valid base character that produced exactly one composite character.
|
||||
// >1 - Previous pressed key does not produce any composite characters. Return dead-key character
|
||||
// followed by base character(s).
|
||||
} while ((rv == -1) != aIsActive);
|
||||
} while ((rv < 0) != aIsActive);
|
||||
|
||||
return (rv == -1);
|
||||
return (rv < 0);
|
||||
}
|
||||
|
||||
void KeyboardLayout::DeactivateDeadKeyState ()
|
||||
|
@ -644,26 +663,16 @@ PRUint32 KeyboardLayout::GetDeadKeyCombinations (PRUint8 aDeadKey, const PBYTE a
|
|||
// Depending on the character the followed the dead-key, the keyboard driver can produce
|
||||
// one composite character, or a dead-key character followed by a second character.
|
||||
PRUint16 compositeChars [5];
|
||||
WORD ascii [2]; // On Win9x ToAsciiEx returns WORD per character, on Win2k BYTE per character.
|
||||
PRInt32 rv;
|
||||
|
||||
if (nsToolkit::mIsNT)
|
||||
rv = ::ToUnicode (virtualKey, 0, kbdState, (LPWSTR)compositeChars, NS_ARRAY_LENGTH (compositeChars), 0);
|
||||
else
|
||||
{
|
||||
WORD ascii;
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, &ascii, 0, mKeyboardLayout);
|
||||
|
||||
if (rv == 1)
|
||||
::MultiByteToWideChar (mCodePage, 0, (LPCSTR)&ascii, 1, (WCHAR*)compositeChars, NS_ARRAY_LENGTH (compositeChars));
|
||||
}
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, ascii, 0, mKeyboardLayout);
|
||||
|
||||
switch (rv)
|
||||
{
|
||||
case -1:
|
||||
// Unexpected dead-key
|
||||
deadKeyActive = PR_FALSE;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
// This key combination does not produce any characters. The dead-key is still in active state.
|
||||
break;
|
||||
|
@ -678,14 +687,15 @@ PRUint32 KeyboardLayout::GetDeadKeyCombinations (PRUint8 aDeadKey, const PBYTE a
|
|||
rv = ::ToUnicode (virtualKey, 0, kbdState, (LPWSTR)baseChars, NS_ARRAY_LENGTH (baseChars), 0);
|
||||
else
|
||||
{
|
||||
WORD ascii;
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, &ascii, 0, mKeyboardLayout);
|
||||
::MultiByteToWideChar (mCodePage, 0, (LPCSTR)ascii, 1, (WCHAR*)compositeChars, NS_ARRAY_LENGTH (compositeChars));
|
||||
|
||||
if (rv == 1)
|
||||
::MultiByteToWideChar (mCodePage, 0, (LPCSTR)&ascii, 1, (WCHAR*)baseChars, NS_ARRAY_LENGTH (baseChars));
|
||||
rv = ::ToAsciiEx (virtualKey, 0, kbdState, ascii, 0, mKeyboardLayout);
|
||||
rv = ::MultiByteToWideChar (mCodePage, 0, (LPCSTR)ascii, rv, (WCHAR*)baseChars, NS_ARRAY_LENGTH (baseChars));
|
||||
}
|
||||
|
||||
if (entries < aMaxEntries)
|
||||
NS_ASSERTION (rv == 1, "One base character expected");
|
||||
|
||||
if (rv == 1 && entries < aMaxEntries)
|
||||
if (AddDeadKeyEntry (baseChars [0], compositeChars [0], aDeadKeyArray, entries))
|
||||
entries++;
|
||||
|
||||
|
@ -694,7 +704,8 @@ PRUint32 KeyboardLayout::GetDeadKeyCombinations (PRUint8 aDeadKey, const PBYTE a
|
|||
}
|
||||
|
||||
default:
|
||||
// More than one character generated. This is not a valid dead-key and base character combination.
|
||||
// 1. Unexpected dead-key. Dead-key chaining is not supported.
|
||||
// 2. More than one character generated. This is not a valid dead-key and base character combination.
|
||||
deadKeyActive = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -49,10 +49,10 @@
|
|||
#define VK_OEM_PERIOD 0xBE // '.' any country
|
||||
#define VK_OEM_2 0xBF // '/?' for US
|
||||
#define VK_OEM_3 0xC0 // '`~' for US
|
||||
#define VK_OEM_4 0xDB // '[{' for US
|
||||
#define VK_OEM_5 0xDC // '\|' for US
|
||||
#define VK_OEM_6 0xDD // ']}' for US
|
||||
#define VK_OEM_7 0xDE // ''"' for US
|
||||
#define VK_OEM_4 0xDB // '[{' for US
|
||||
#define VK_OEM_5 0xDC // '\|' for US
|
||||
#define VK_OEM_6 0xDD // ']}' for US
|
||||
#define VK_OEM_7 0xDE // ''"' for US
|
||||
#define VK_OEM_8 0xDF
|
||||
|
||||
|
||||
|
@ -143,7 +143,7 @@ class KeyboardLayout
|
|||
PRUint8 data [1];
|
||||
};
|
||||
|
||||
#define NUM_OF_KEYS 49
|
||||
#define NUM_OF_KEYS 50
|
||||
|
||||
UINT mCodePage; // Used for Win9x only
|
||||
HKL mKeyboardLayout;
|
||||
|
@ -172,17 +172,8 @@ class KeyboardLayout
|
|||
#endif
|
||||
|
||||
public:
|
||||
KeyboardLayout ()
|
||||
{
|
||||
LoadLayout ();
|
||||
}
|
||||
|
||||
~KeyboardLayout ()
|
||||
{
|
||||
#ifndef WINCE
|
||||
ReleaseDeadKeyTables ();
|
||||
#endif
|
||||
}
|
||||
KeyboardLayout ();
|
||||
~KeyboardLayout ();
|
||||
|
||||
static PRBool IsPrintableCharKey (PRUint8 aVirtualKey);
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
#include "nsKeyboardLayout.h"
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
|
@ -784,6 +785,7 @@ nsWindow::nsWindow() : nsBaseWidget()
|
|||
HKL nsWindow::gKeyboardLayout = 0;
|
||||
UINT nsWindow::gCurrentKeyboardCP = 0;
|
||||
PRBool nsWindow::gSwitchKeyboardLayout = PR_FALSE;
|
||||
static KeyboardLayout gKbdLayout;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -3183,9 +3185,9 @@ NS_METHOD nsWindow::EnableDragDrop(PRBool aEnable)
|
|||
UINT nsWindow::MapFromNativeToDOM(UINT aNativeKeyCode)
|
||||
{
|
||||
switch (aNativeKeyCode) {
|
||||
case 0xBA: return NS_VK_SEMICOLON;
|
||||
case 0xBB: return NS_VK_EQUALS;
|
||||
case 0xBD: return NS_VK_SUBTRACT;
|
||||
case VK_OEM_1: return NS_VK_SEMICOLON; // 0xBA, For the US standard keyboard, the ';:' key
|
||||
case VK_OEM_PLUS: return NS_VK_EQUALS; // 0xBB, For any country/region, the '+' key
|
||||
case VK_OEM_MINUS: return NS_VK_SUBTRACT; // 0xBD, For any country/region, the '-' key
|
||||
}
|
||||
|
||||
return aNativeKeyCode;
|
||||
|
@ -3265,6 +3267,8 @@ PRBool nsWindow::DispatchKeyEvent(PRUint32 aEventType, WORD aCharCode, UINT aVir
|
|||
//-------------------------------------------------------------------------
|
||||
BOOL nsWindow::OnKeyDown(UINT aVirtualKeyCode, UINT aScanCode, LPARAM aKeyData)
|
||||
{
|
||||
gKbdLayout.OnKeyDown (aVirtualKeyCode);
|
||||
|
||||
UINT virtualKeyCode = sIMEIsComposing ? aVirtualKeyCode : MapFromNativeToDOM(aVirtualKeyCode);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -3296,12 +3300,25 @@ BOOL nsWindow::OnKeyDown(UINT aVirtualKeyCode, UINT aScanCode, LPARAM aKeyData)
|
|||
if (virtualKeyCode == NS_VK_RETURN || virtualKeyCode == NS_VK_BACK ||
|
||||
(mIsControlDown && !mIsAltDown && !mIsShiftDown &&
|
||||
(virtualKeyCode == NS_VK_ADD || virtualKeyCode == NS_VK_SUBTRACT ||
|
||||
virtualKeyCode == NS_VK_EQUALS)))
|
||||
virtualKeyCode == NS_VK_EQUALS)) ||
|
||||
((mIsControlDown || mIsAltDown) && KeyboardLayout::IsPrintableCharKey (aVirtualKeyCode)))
|
||||
{
|
||||
// Remove a possible WM_CHAR or WM_SYSCHAR from the message queue
|
||||
if (gotMsg && (msg.message == WM_CHAR || msg.message == WM_SYSCHAR)) {
|
||||
// Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue.
|
||||
// They can be more than one because of:
|
||||
// * Dead-keys not pairing with base character
|
||||
// * Some keyboard layouts may map up to 4 characters to the single key
|
||||
|
||||
PRBool anyCharMessagesRemoved = PR_FALSE;
|
||||
|
||||
while (gotMsg && (msg.message == WM_CHAR || msg.message == WM_SYSCHAR))
|
||||
{
|
||||
nsToolkit::mGetMessage(&msg, mWnd, WM_KEYFIRST, WM_KEYLAST);
|
||||
} else if (virtualKeyCode == NS_VK_BACK) {
|
||||
anyCharMessagesRemoved = PR_TRUE;
|
||||
|
||||
gotMsg = nsToolkit::mPeekMessage (&msg, mWnd, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE | PM_NOYIELD);
|
||||
}
|
||||
|
||||
if (!anyCharMessagesRemoved && virtualKeyCode == NS_VK_BACK) {
|
||||
MSG imeStartCompositionMsg, imeCompositionMsg;
|
||||
if (nsToolkit::mPeekMessage(&imeStartCompositionMsg, mWnd, WM_IME_STARTCOMPOSITION, WM_IME_STARTCOMPOSITION, PM_NOREMOVE | PM_NOYIELD)
|
||||
&& nsToolkit::mPeekMessage(&imeCompositionMsg, mWnd, WM_IME_COMPOSITION, WM_IME_COMPOSITION, PM_NOREMOVE | PM_NOYIELD)
|
||||
|
@ -3336,8 +3353,10 @@ BOOL nsWindow::OnKeyDown(UINT aVirtualKeyCode, UINT aScanCode, LPARAM aKeyData)
|
|||
(msg.message == WM_CHAR || msg.message == WM_SYSCHAR || msg.message == WM_DEADCHAR)) {
|
||||
// If prevent default set for keydown, do same for keypress
|
||||
nsToolkit::mGetMessage(&msg, mWnd, msg.message, msg.message);
|
||||
|
||||
if (msg.message == WM_DEADCHAR)
|
||||
return PR_FALSE;
|
||||
|
||||
#ifdef KE_DEBUG
|
||||
printf("%s\tchar=%c\twp=%4x\tlp=%8x\n",
|
||||
(msg.message == WM_SYSCHAR) ? "WM_SYSCHAR" : "WM_CHAR",
|
||||
|
@ -3346,47 +3365,77 @@ BOOL nsWindow::OnKeyDown(UINT aVirtualKeyCode, UINT aScanCode, LPARAM aKeyData)
|
|||
return OnChar(msg.wParam, extraFlags);
|
||||
}
|
||||
|
||||
WORD asciiKey = 0;
|
||||
if (gKbdLayout.IsDeadKey ())
|
||||
return PR_FALSE;
|
||||
|
||||
PRUint8 shiftStates [5];
|
||||
PRUint16 uniChars [5];
|
||||
PRUint32 numOfUniChars = 0;
|
||||
PRUint32 numOfShiftStates = 0;
|
||||
|
||||
switch (virtualKeyCode) {
|
||||
// keys to be sent as characters
|
||||
case NS_VK_ADD : asciiKey = '+'; break;
|
||||
case NS_VK_SUBTRACT : asciiKey = '-'; break;
|
||||
case NS_VK_SEMICOLON : asciiKey = ';'; break;
|
||||
case NS_VK_EQUALS : asciiKey = '='; break;
|
||||
case NS_VK_COMMA : asciiKey = ','; break;
|
||||
case NS_VK_PERIOD : asciiKey = '.'; break;
|
||||
case NS_VK_QUOTE : asciiKey = '\''; break;
|
||||
case NS_VK_BACK_QUOTE: asciiKey = '`'; break;
|
||||
case NS_VK_DIVIDE :
|
||||
case NS_VK_SLASH : asciiKey = '/'; break;
|
||||
case NS_VK_MULTIPLY : asciiKey = '*'; break;
|
||||
case NS_VK_NUMPAD0 : asciiKey = '0'; break;
|
||||
case NS_VK_NUMPAD1 : asciiKey = '1'; break;
|
||||
case NS_VK_NUMPAD2 : asciiKey = '2'; break;
|
||||
case NS_VK_NUMPAD3 : asciiKey = '3'; break;
|
||||
case NS_VK_NUMPAD4 : asciiKey = '4'; break;
|
||||
case NS_VK_NUMPAD5 : asciiKey = '5'; break;
|
||||
case NS_VK_NUMPAD6 : asciiKey = '6'; break;
|
||||
case NS_VK_NUMPAD7 : asciiKey = '7'; break;
|
||||
case NS_VK_NUMPAD8 : asciiKey = '8'; break;
|
||||
case NS_VK_NUMPAD9 : asciiKey = '9'; break;
|
||||
case NS_VK_ADD: uniChars [0] = '+'; numOfUniChars = 1; break;
|
||||
case NS_VK_SUBTRACT: uniChars [0] = '-'; numOfUniChars = 1; break;
|
||||
case NS_VK_DIVIDE: uniChars [0] = '/'; numOfUniChars = 1; break;
|
||||
case NS_VK_MULTIPLY: uniChars [0] = '*'; numOfUniChars = 1; break;
|
||||
case NS_VK_NUMPAD0:
|
||||
case NS_VK_NUMPAD1:
|
||||
case NS_VK_NUMPAD2:
|
||||
case NS_VK_NUMPAD3:
|
||||
case NS_VK_NUMPAD4:
|
||||
case NS_VK_NUMPAD5:
|
||||
case NS_VK_NUMPAD6:
|
||||
case NS_VK_NUMPAD7:
|
||||
case NS_VK_NUMPAD8:
|
||||
case NS_VK_NUMPAD9: uniChars [0] = virtualKeyCode - NS_VK_NUMPAD0 + '0'; numOfUniChars = 1; break;
|
||||
|
||||
default:
|
||||
// NS_VK_0 - NS_VK_9 and NS_VK_A - NS_VK_Z match their ascii values
|
||||
if ((NS_VK_0 <= virtualKeyCode && virtualKeyCode <= NS_VK_9) ||
|
||||
(NS_VK_A <= virtualKeyCode && virtualKeyCode <= NS_VK_Z)) {
|
||||
asciiKey = virtualKeyCode;
|
||||
// Take the Shift state into account
|
||||
if (!mIsShiftDown
|
||||
&& NS_VK_A <= virtualKeyCode && virtualKeyCode <= NS_VK_Z) {
|
||||
asciiKey += 0x20;
|
||||
if (KeyboardLayout::IsPrintableCharKey (aVirtualKeyCode))
|
||||
numOfUniChars = numOfShiftStates = gKbdLayout.GetUniChars (uniChars, shiftStates, NS_ARRAY_LENGTH (uniChars));
|
||||
|
||||
if (mIsControlDown ^ mIsAltDown)
|
||||
{
|
||||
// XXX
|
||||
// For both Alt+key and Ctrl+key combinations we return the latin characters A..Z and
|
||||
// numbers 0..9, ignoring the real characters returned by active keyboard layout.
|
||||
// This is required to make sure that all shortcut keys (e.g. Ctrl+c, Ctrl+1, Alt+f)
|
||||
// work the same way no matter what keyboard layout you are using.
|
||||
// Currently it is impossible to use non-latin characters for keyboard shortcuts.
|
||||
|
||||
if ((NS_VK_0 <= virtualKeyCode && virtualKeyCode <= NS_VK_9) ||
|
||||
(NS_VK_A <= virtualKeyCode && virtualKeyCode <= NS_VK_Z))
|
||||
{
|
||||
uniChars [0] = virtualKeyCode;
|
||||
numOfUniChars = 1;
|
||||
numOfShiftStates = 0;
|
||||
|
||||
// For letters take the Shift state into account
|
||||
if (!mIsShiftDown &&
|
||||
NS_VK_A <= virtualKeyCode && virtualKeyCode <= NS_VK_Z)
|
||||
uniChars [0] += 0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (asciiKey)
|
||||
DispatchKeyEvent(NS_KEY_PRESS, asciiKey, 0, aKeyData, extraFlags);
|
||||
else
|
||||
if (numOfUniChars)
|
||||
{
|
||||
for (PRUint32 cnt = 0; cnt < numOfUniChars; cnt++)
|
||||
{
|
||||
if (cnt < numOfShiftStates)
|
||||
{
|
||||
// If key in combination with Alt and/or Ctrl produces a different character than without them
|
||||
// then do not report these flags because it is separate keyboard layout shift state.
|
||||
// If dead-key and base character does not produce a valid composite character then both produced
|
||||
// dead-key character and following base character may have different modifier flags, too.
|
||||
mIsShiftDown = (shiftStates [cnt] & eShift) != 0;
|
||||
mIsControlDown = (shiftStates [cnt] & eCtrl) != 0;
|
||||
mIsAltDown = (shiftStates [cnt] & eAlt) != 0;
|
||||
}
|
||||
|
||||
DispatchKeyEvent(NS_KEY_PRESS, uniChars [cnt], 0, aKeyData, extraFlags);
|
||||
}
|
||||
} else
|
||||
DispatchKeyEvent(NS_KEY_PRESS, 0, virtualKeyCode, aKeyData, extraFlags);
|
||||
|
||||
return noDefault;
|
||||
|
@ -6613,6 +6662,8 @@ BOOL nsWindow::OnInputLangChange(HKL aHKL, LRESULT *oRetValue)
|
|||
NS_IMM_GETPROPERTY(gKeyboardLayout, IGP_PROPERTY, imeProp);
|
||||
nsToolkit::mUseImeApiW = (imeProp & IME_PROP_UNICODE) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
gKbdLayout.LoadLayout();
|
||||
}
|
||||
|
||||
ResetInputState();
|
||||
|
|
Загрузка…
Ссылка в новой задаче