337199 Key event/text input regressions on Mac after bug 332579, RETURN key events double-processed. Also: 337277 Typed characters appear twice after visiting site with Java applet, 337338 Typing special characters (accents) and symbols with Option fails, 337370 Japanese IME broken, 336357 Keystrokes inserted twice into text input fields. Rework key event and TSM handlers. r=josh sr=shaver a/1.8.1=me&shaver

This commit is contained in:
mark%moxienet.com 2006-05-22 00:34:35 +00:00
parent 8842500aa4
commit dc97c80e35
9 changed files with 204 additions and 264 deletions

View File

@ -103,7 +103,6 @@ CPPSRCS = nsAppShell.cpp \
nsMimeMapper.cpp \
nsNativeThemeMac.cpp \
nsSound.cpp \
nsTSMStrategy.cpp \
nsToolkitBase.cpp \
nsToolkit.cpp \
nsWidgetFactory.cpp \

View File

@ -49,13 +49,8 @@
#include "nsCarbonHelpers.h"
#include "nsIRollupListener.h"
#include "nsIMenuRollup.h"
#include "nsTSMStrategy.h"
#include "nsGfxUtils.h"
#ifndef XP_MACOSX
#include <locale>
#endif
#define PINK_PROFILING_ACTIVATE 0
#if PINK_PROFILING_ACTIVATE
#include "profilerutils.h"
@ -92,20 +87,6 @@ nsMacEventDispatchHandler gEventDispatchHandler;
static void ConvertKeyEventToContextMenuEvent(const nsKeyEvent* inKeyEvent, nsMouseEvent* outCMEvent);
static inline PRBool IsContextMenuKey(const nsKeyEvent& inKeyEvent);
class StPackedBoolSetter {
public:
StPackedBoolSetter(PRPackedBool& aFlag): mFlag(aFlag) {
mFlag = PR_TRUE;
};
~StPackedBoolSetter() {
mFlag = PR_FALSE;
};
protected:
PRPackedBool& mFlag;
};
//-------------------------------------------------------------------------
//
@ -362,23 +343,17 @@ void nsMacEventDispatchHandler::SetGlobalPoint(Point inPoint)
//-------------------------------------------------------------------------
nsMacEventHandler::nsMacEventHandler(nsMacWindow* aTopLevelWidget)
{
OSErr err;
InterfaceTypeList supportedServices;
mTopLevelWidget = aTopLevelWidget;
nsTSMStrategy tsmstrategy;
//
// create a TSMDocument for this window. We are allocating a TSM document for
// each Mac window
//
mTSMDocument = nsnull;
if (tsmstrategy.UseUnicodeForInputMethod()) {
supportedServices[0] = kUnicodeDocument;
} else {
supportedServices[0] = kTextService;
}
OSErr err;
InterfaceTypeList supportedServices;
mTopLevelWidget = aTopLevelWidget;
//
// create a TSMDocument for this window. We are allocating a TSM document for
// each Mac window
//
mTSMDocument = nsnull;
supportedServices[0] = kUnicodeDocument;
err = ::NewTSMDocument(1, supportedServices,&mTSMDocument, (long)this);
NS_ASSERTION(err==noErr, "nsMacEventHandler::nsMacEventHandler: NewTSMDocument failed.");
#ifdef DEBUG_TSM
@ -393,7 +368,8 @@ nsMacEventHandler::nsMacEventHandler(nsMacWindow* aTopLevelWidget)
mIMEIsComposing = PR_FALSE;
mIMECompositionStr = nsnull;
mHandlingKeyEvent = PR_FALSE;
mKeyIgnore = PR_FALSE;
mKeyHandled = PR_FALSE;
}
@ -690,10 +666,8 @@ enum
};
static PRUint32 ConvertMacToRaptorKeyCode(UInt32 eventMessage, UInt32 eventModifiers)
static PRUint32 ConvertMacToRaptorKeyCode(char charCode, UInt32 keyCode, UInt32 eventModifiers)
{
UInt8 charCode = (eventMessage & charCodeMask);
UInt8 keyCode = (eventMessage & keyCodeMask) >> 8;
PRUint32 raptorKeyCode = 0;
switch (keyCode)
@ -881,7 +855,7 @@ void nsMacEventHandler::InitializeKeyEvent(nsKeyEvent& aKeyEvent,
} // if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) )
else
{
aKeyEvent.keyCode = ConvertMacToRaptorKeyCode(aOSEvent.message, aOSEvent.modifiers);
aKeyEvent.keyCode = ConvertMacToRaptorKeyCode(aOSEvent.message & charCodeMask, (aOSEvent.message & keyCodeMask) >> 8, aOSEvent.modifiers);
aKeyEvent.charCode = 0;
} // else for if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) )
@ -1045,12 +1019,6 @@ PRUint32 nsMacEventHandler::ConvertKeyEventToUnicode(EventRecord& aOSEvent)
PRBool nsMacEventHandler::HandleKeyEvent(EventRecord& aOSEvent)
{
// Avoid reentrancy
if (mHandlingKeyEvent)
return PR_FALSE;
StPackedBoolSetter handling(mHandlingKeyEvent);
nsresult result = NS_ERROR_UNEXPECTED;
nsWindow* checkFocusedWidget;
@ -1166,34 +1134,17 @@ IsContextMenuKey(const nsKeyEvent& inKeyEvent)
//-------------------------------------------------------------------------
PRBool nsMacEventHandler::HandleUKeyEvent(const PRUnichar* text, long charCount, EventRecord& aOSEvent)
{
// Avoid reentrancy
if (mHandlingKeyEvent)
// The focused widget changed in HandleKeyUpDownEvent, so no NS_KEY_PRESS
// events should be generated.
if (mKeyIgnore)
return PR_FALSE;
StPackedBoolSetter handling(mHandlingKeyEvent);
nsresult result = NS_ERROR_UNEXPECTED;
// get the focused widget
nsWindow* focusedWidget = gEventDispatchHandler.GetActive();
if (!focusedWidget)
focusedWidget = mTopLevelWidget;
// simulate key down event if this isn't an autoKey event
if (aOSEvent.what == keyDown)
{
nsKeyEvent keyDownEvent(PR_TRUE, NS_KEY_DOWN, nsnull);
InitializeKeyEvent(keyDownEvent, aOSEvent, focusedWidget, NS_KEY_DOWN, PR_FALSE);
result = focusedWidget->DispatchWindowEvent(keyDownEvent);
NS_ASSERTION(NS_SUCCEEDED(result), "cannot DispatchWindowEvent keydown");
// check if focus changed; see also HandleKeyEvent above
nsWindow *checkFocusedWidget = gEventDispatchHandler.GetActive();
if (!checkFocusedWidget)
checkFocusedWidget = mTopLevelWidget;
if (checkFocusedWidget != focusedWidget)
return result;
}
// simulate key press events
if (!IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8))
{
@ -1205,6 +1156,10 @@ PRBool nsMacEventHandler::HandleUKeyEvent(const PRUnichar* text, long charCount,
InitializeKeyEvent(keyPressEvent, aOSEvent, focusedWidget, NS_KEY_PRESS, PR_FALSE);
keyPressEvent.charCode = text[i];
// If keydown default was prevented, do same for keypress
if (mKeyHandled)
keyPressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
// control key is special in that it doesn't give us letters
// it generates a charcode of 0x01 for control-a
// so we offset to do the right thing for gecko (as in HandleKeyEvent)
@ -2669,3 +2624,100 @@ nsresult nsMacEventHandler::ResetInputState()
return NS_OK;
}
PRBool
nsMacEventHandler::HandleKeyUpDownEvent(EventHandlerCallRef aHandlerCallRef,
EventRef aEvent)
{
PRUint32 eventKind = ::GetEventKind(aEvent);
NS_ASSERTION(eventKind == kEventRawKeyDown ||
eventKind == kEventRawKeyUp,
"Unknown event kind");
PRBool handled = PR_FALSE;
nsWindow* focusedWidget = gEventDispatchHandler.GetActive();
if (!focusedWidget)
focusedWidget = mTopLevelWidget;
PRUint32 modifiers = 0;
OSStatus err = ::GetEventParameter(aEvent, kEventParamKeyModifiers,
typeUInt32, NULL,
sizeof(modifiers), NULL,
&modifiers);
NS_ASSERTION(err == noErr, "Could not get kEventParamKeyModifiers");
PRUint32 keyCode = 0;
err = ::GetEventParameter(aEvent, kEventParamKeyCode,
typeUInt32, NULL,
sizeof(keyCode), NULL,
&keyCode);
NS_ASSERTION(err == noErr, "Could not get kEventParamKeyCode");
PRUint8 charCode = 0;
::GetEventParameter(aEvent, kEventParamKeyMacCharCodes,
typeChar, NULL,
sizeof(charCode), NULL,
&charCode);
// Failure is not a fatal condition.
// The event's nativeMsg field historically held an EventRecord. Some
// consumers (plugins) rely on this behavior. Note that
// ConvertEventRefToEventRecord can return false and produce a null
// event record in some cases, such as when entering an IME session.
EventRecord eventRecord;
::ConvertEventRefToEventRecord(aEvent, &eventRecord);
// kEventRawKeyDown or kEventRawKeyUp only
PRUint32 message = (eventKind == kEventRawKeyUp ? NS_KEY_UP : NS_KEY_DOWN);
nsKeyEvent upDownEvent(PR_TRUE, message, nsnull);
upDownEvent.time = PR_IntervalNow();
upDownEvent.widget = focusedWidget;
upDownEvent.nativeMsg = (void*)&eventRecord;
upDownEvent.isShift = ((modifiers & shiftKey) != 0);
upDownEvent.isControl = ((modifiers & controlKey) != 0);
upDownEvent.isAlt = ((modifiers & optionKey) != 0);
upDownEvent.isMeta = ((modifiers & cmdKey) != 0);
upDownEvent.keyCode = ConvertMacToRaptorKeyCode(charCode, keyCode,
modifiers);
upDownEvent.charCode = 0;
handled = focusedWidget->DispatchWindowEvent(upDownEvent);
if (eventKind == kEventRawKeyUp)
return handled;
// kEventRawKeyDown only. Prepare for a possible NS_KEY_PRESS event.
nsWindow* checkFocusedWidget = gEventDispatchHandler.GetActive();
if (!checkFocusedWidget)
checkFocusedWidget = mTopLevelWidget;
// Set a flag indicating that NS_KEY_PRESS events should not be dispatched,
// because focus changed.
PRBool lastIgnore = PR_FALSE;
if (checkFocusedWidget != focusedWidget) {
lastIgnore = mKeyIgnore;
mKeyIgnore = PR_TRUE;
}
// Set a flag indicating that the NS_KEY_DOWN event came back with
// preventDefault, and NS_KEY_PRESS events should have the same flag set.
PRBool lastHandled = PR_FALSE;
if (handled) {
lastHandled = mKeyHandled;
mKeyHandled = PR_TRUE;
}
// The event needs further processing.
// - If no input method is active, an event will be delivered to the
// kEventTextInputUnicodeForKeyEvent handler, which will call
// HandleUKeyEvent, which takes care of dispatching NS_KEY_PRESS events.
// - If an input method is active, an event will be delivered to the
// kEventTextInputUpdateActiveInputArea handler, which will call
// UnicodeHandleUpdateInputArea to handle the input session.
::CallNextEventHandler(aHandlerCallRef, aEvent);
mKeyHandled = lastHandled;
mKeyIgnore = lastIgnore;
return handled;
}

View File

@ -131,6 +131,8 @@ public:
virtual nsresult HandleUnicodeGetSelectedText(nsAString& outString);
virtual nsresult ResetInputState();
virtual PRBool HandleUKeyEvent(const PRUnichar* text, long charCount, EventRecord& aOSEvent);
virtual PRBool HandleKeyUpDownEvent(EventHandlerCallRef aHandlerCallRef,
EventRef aEvent);
//
// Synthetic events, generated internally to do things at specific times and
@ -172,7 +174,8 @@ protected:
nsPoint mIMEPos;
nsAutoString *mIMECompositionStr;
PRPackedBool mIMEIsComposing;
PRPackedBool mHandlingKeyEvent;
PRPackedBool mKeyIgnore;
PRPackedBool mKeyHandled;
};
#endif // MacMacEventHandler_h__

View File

@ -81,9 +81,12 @@ nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit)
{ kEventClassMouse, kEventMouseUp },
{ kEventClassMouse, kEventMouseMoved },
{ kEventClassMouse, kEventMouseDragged },
#if 0
// These are now handled by nsMacWindow::KeyEventHandler
{ kEventClassKeyboard, kEventRawKeyDown },
{ kEventClassKeyboard, kEventRawKeyUp },
{ kEventClassKeyboard, kEventRawKeyRepeat },
#endif
{ kEventClassWindow, kEventWindowUpdate },
{ kEventClassWindow, kEventWindowActivated },
{ kEventClassWindow, kEventWindowDeactivated },

View File

@ -42,7 +42,6 @@
#include <Script.h>
#include <TextServices.h>
#include <AEDataModel.h>
#include "nsTSMStrategy.h"
#include "nsCarbonHelpers.h"
@ -67,7 +66,6 @@ AEEventHandlerUPP nsMacTSMMessagePump::mGetSelectedTextUPP = NULL;
nsMacTSMMessagePump::nsMacTSMMessagePump()
{
OSErr err;
nsTSMStrategy tsmstrategy;
mPos2OffsetUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::PositionToOffsetHandler);
NS_ASSERTION(mPos2OffsetUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[Pos2Pffset] failed");
@ -75,11 +73,7 @@ nsMacTSMMessagePump::nsMacTSMMessagePump()
mOffset2PosUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::OffsetToPositionHandler);
NS_ASSERTION(mPos2OffsetUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[Pos2Pffset] failed");
if (tsmstrategy.UseUnicodeForInputMethod()) {
mUpdateUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeUpdateHandler);
} else {
mUpdateUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UpdateHandler);
}
mUpdateUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeUpdateHandler);
NS_ASSERTION(mPos2OffsetUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[Pos2Pffset] failed");
err = AEInstallEventHandler(kTextServiceClass, kPos2Offset, mPos2OffsetUPP, (long)this, false);
@ -91,20 +85,17 @@ nsMacTSMMessagePump::nsMacTSMMessagePump()
err = AEInstallEventHandler(kTextServiceClass, kUpdateActiveInputArea, mUpdateUPP, (long)this, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[Update] failed");
if (tsmstrategy.UseUnicodeForKeyboard()) {
mKeyboardUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeNotFromInputMethodHandler);
NS_ASSERTION(mKeyboardUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[FromInputMethod] failed");
mKeyboardUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeNotFromInputMethodHandler);
NS_ASSERTION(mKeyboardUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[FromInputMethod] failed");
err = AEInstallEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, (long)this, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[FromInputMethod] failed");
err = AEInstallEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, (long)this, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[FromInputMethod] failed");
mGetSelectedTextUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeGetSelectedTextHandler);
NS_ASSERTION(mGetSelectedTextUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[GetSelectedText] failed");
mGetSelectedTextUPP = NewAEEventHandlerUPP(nsMacTSMMessagePump::UnicodeGetSelectedTextHandler);
NS_ASSERTION(mGetSelectedTextUPP!=NULL, "nsMacTSMMessagePump::InstallTSMAEHandlers: NewAEEventHandlerUPP[GetSelectedText] failed");
err = AEInstallEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, (long)this, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[GetSelectedText] failed");
}
err = AEInstallEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, (long)this, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::InstallTSMAEHandlers: AEInstallEventHandler[GetSelectedText] failed");
}
@ -125,16 +116,13 @@ nsMacTSMMessagePump::~nsMacTSMMessagePump()
::DisposeAEEventHandlerUPP(mOffset2PosUPP);
::DisposeAEEventHandlerUPP(mUpdateUPP);
nsTSMStrategy tsmstrategy;
if (tsmstrategy.UseUnicodeForKeyboard()) {
err = AERemoveEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[FromInputMethod] failed");
::DisposeAEEventHandlerUPP(mKeyboardUPP);
err = AERemoveEventHandler(kTextServiceClass, kUnicodeNotFromInputMethod, mKeyboardUPP, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[FromInputMethod] failed");
::DisposeAEEventHandlerUPP(mKeyboardUPP);
err = AERemoveEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[GetSelectedText] failed");
::DisposeAEEventHandlerUPP(mGetSelectedTextUPP);
}
err = AERemoveEventHandler(kTextServiceClass, kGetSelectedText, mGetSelectedTextUPP, false);
NS_ASSERTION(err==noErr, "nsMacTSMMessagePump::RemoveTSMAEHandlers: AERemoveEventHandler[GetSelectedText] failed");
::DisposeAEEventHandlerUPP(mGetSelectedTextUPP);
}

View File

@ -563,25 +563,25 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
if ( mWindowType != eWindowType_invisible &&
mWindowType != eWindowType_plugin &&
mWindowType != eWindowType_java) {
const EventTypeSpec scrollEventList[] = {
{ kEventClassMouse, kEventMouseWheelMoved }
const EventTypeSpec kScrollEventList[] = {
{ kEventClassMouse, kEventMouseWheelMoved },
};
// note, passing NULL as the final param to IWEH() causes the UPP to be
// disposed automatically when the event target (the window) goes away.
// See CarbonEvents.h for info.
err = ::InstallWindowEventHandler(mWindowPtr,
NewEventHandlerUPP(ScrollEventHandler),
GetEventTypeCount(scrollEventList),
scrollEventList, this, NULL);
NS_ASSERTION(err == noErr,
"Couldn't install Carbon Scroll Event handlers");
static EventHandlerUPP sScrollEventHandlerUPP;
if (!sScrollEventHandlerUPP)
sScrollEventHandlerUPP = ::NewEventHandlerUPP(ScrollEventHandler);
err = ::InstallWindowEventHandler(mWindowPtr,
sScrollEventHandlerUPP,
GetEventTypeCount(kScrollEventList),
kScrollEventList,
(void*)this,
NULL);
NS_ASSERTION(err == noErr, "Couldn't install scroll event handler");
}
// Since we can only call IWEH() once for each event class such as
// kEventClassWindow, we register all the event types that we are going to
// handle here.
const EventTypeSpec windEventList[] = {
// Window event handler
const EventTypeSpec kWindowEventList[] = {
// to enable live resizing
{ kEventClassWindow, kEventWindowBoundsChanged },
// to roll up popups when we're minimized
@ -594,12 +594,35 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
{ kEventClassWindow, kEventWindowUpdate },
};
PRUint32 typeCount = GetEventTypeCount(windEventList);
static EventHandlerUPP sWindowEventHandlerUPP;
if (!sWindowEventHandlerUPP)
sWindowEventHandlerUPP = ::NewEventHandlerUPP(WindowEventHandler);
err = ::InstallWindowEventHandler(mWindowPtr,
NewEventHandlerUPP(WindowEventHandler),
typeCount, windEventList, this, NULL);
NS_ASSERTION(err == noErr, "Couldn't install sheet Event handlers");
sWindowEventHandlerUPP,
GetEventTypeCount(kWindowEventList),
kWindowEventList,
(void*)this,
NULL);
NS_ASSERTION(err == noErr, "Couldn't install window event handler");
// Key event handler
const EventTypeSpec kKeyEventList[] = {
{ kEventClassKeyboard, kEventRawKeyDown },
{ kEventClassKeyboard, kEventRawKeyUp },
};
static EventHandlerUPP sKeyEventHandlerUPP;
if (!sKeyEventHandlerUPP)
sKeyEventHandlerUPP = ::NewEventHandlerUPP(KeyEventHandler);
err = ::InstallWindowEventHandler(mWindowPtr,
sKeyEventHandlerUPP,
GetEventTypeCount(kKeyEventList),
kKeyEventList,
NS_STATIC_CAST(void*, this),
NULL);
NS_ASSERTION(err == noErr, "Couldn't install key event handler");
// register tracking and receive handlers with the native Drag Manager
if ( mDragTrackingHandlerUPP ) {
@ -2193,3 +2216,21 @@ NS_IMETHODIMP nsMacWindow::Update()
return rv;
}
pascal OSStatus
nsMacWindow::KeyEventHandler(EventHandlerCallRef aHandlerCallRef,
EventRef aEvent,
void* aUserData)
{
nsMacWindow* self = NS_STATIC_CAST(nsMacWindow*, aUserData);
NS_ASSERTION(self, "No self?");
NS_ASSERTION(self->mMacEventHandler.get(), "No mMacEventHandler?");
PRBool handled = self->mMacEventHandler->HandleKeyUpDownEvent(aHandlerCallRef,
aEvent);
if (!handled)
return eventNotHandledErr;
return noErr;
}

View File

@ -151,6 +151,9 @@ protected:
EventRef inEvent, void* userData ) ;
pascal static OSStatus ScrollEventHandler ( EventHandlerCallRef inHandlerChain,
EventRef inEvent, void* userData ) ;
pascal static OSStatus KeyEventHandler(EventHandlerCallRef aHandlerCallRef,
EventRef aEvent,
void* aUserData);
nsresult GetDesktopRect(Rect* desktopRect);
PRPackedBool mWindowMadeHere; // true if we created the window

View File

@ -1,95 +0,0 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Frank Yung-Fong Tang <ftang@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <Gestalt.h>
#include "nsTSMStrategy.h"
#ifdef DEBUG
//#define FORCE_USE_UNICODE_API
//#define FORCE_NOT_USE_UNICODE_API
#endif
PRBool nsTSMStrategy::gUseUnicodeForInputMethod = PR_FALSE;
PRBool nsTSMStrategy::gUseUnicodeForKeyboard = PR_FALSE;
PRBool nsTSMStrategy::gInit = PR_FALSE;
void nsTSMStrategy::Init()
{
if ( !gInit)
{
gInit = PR_TRUE;
OSErr err;
long version;
err = Gestalt(gestaltTSMgrVersion, &version);
if ((err == noErr) && (version >= gestaltTSMgr15))
{
// only enable if OS 9.0 or greater; there is a bug
// (in at least OS 8.6) that causes double input (Bug #106022)
// see also bug #110828
err = Gestalt(gestaltSystemVersion, &version);
PRBool doEnable = (err == noErr) && (version >= 0x900);
gUseUnicodeForKeyboard = doEnable;
gUseUnicodeForInputMethod = doEnable;
}
#ifdef FORCE_USE_UNICODE_API
gUseUnicodeForInputMethod = PR_TRUE;
#elif defined( FORCE_NOT_USE_UNICODE_API )
gUseUnicodeForInputMethod = PR_FALSE;
#endif
// there are no way we can use unicode for keyboard, but not using
// Unicode for IME
if ( !gUseUnicodeForInputMethod)
gUseUnicodeForKeyboard = PR_FALSE;
}
}
PRBool nsTSMStrategy::UseUnicodeForInputMethod()
{
Init();
return gUseUnicodeForInputMethod;
}
PRBool nsTSMStrategy::UseUnicodeForKeyboard()
{
Init();
return gUseUnicodeForKeyboard;
}

View File

@ -1,54 +0,0 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Frank Yung-Fong Tang <ftang@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTSMStrategy_h__
#define nsTSMStrategyr_h__
#include "nscore.h"
class nsTSMStrategy {
public:
PRBool UseUnicodeForInputMethod();
PRBool UseUnicodeForKeyboard();
private:
static PRBool gUseUnicodeForInputMethod;
static PRBool gUseUnicodeForKeyboard;
static PRBool gInit;
void Init();
};
#endif // nsTSMStrategy_h__