Path: blob/master/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp
42524 views
/*1* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "awt.h"2627#include <windowsx.h>28#include <zmouse.h>2930#include "jlong.h"31#include "awt_AWTEvent.h"32#include "awt_BitmapUtil.h"33#include "awt_Component.h"34#include "awt_Cursor.h"35#include "awt_Dimension.h"36#include "awt_Frame.h"37#include "awt_InputEvent.h"38#include "awt_InputTextInfor.h"39#include "awt_Insets.h"40#include "awt_KeyEvent.h"41#include "awt_MenuItem.h"42#include "awt_MouseEvent.h"43#include "awt_Palette.h"44#include "awt_Toolkit.h"45#include "awt_Window.h"46#include "awt_Win32GraphicsDevice.h"47#include "Hashtable.h"48#include "ComCtl32Util.h"4950#include <Region.h>5152#include <jawt.h>5354#include <java_awt_Toolkit.h>55#include <java_awt_FontMetrics.h>56#include <java_awt_Color.h>57#include <java_awt_Event.h>58#include <java_awt_event_KeyEvent.h>59#include <java_awt_Insets.h>60#include <sun_awt_windows_WPanelPeer.h>61#include <java_awt_event_InputEvent.h>62#include <java_awt_event_ActionEvent.h>63#include <java_awt_event_InputMethodEvent.h>64#include <sun_awt_windows_WInputMethod.h>65#include <java_awt_event_MouseEvent.h>66#include <java_awt_event_MouseWheelEvent.h>6768// Begin -- Win32 SDK include files69#include <imm.h>70#include <ime.h>71// End -- Win32 SDK include files7273#include <awt_DnDDT.h>7475LPCTSTR szAwtComponentClassName = TEXT("SunAwtComponent");76// register a message that no other window in the process (even in a plugin77// scenario) will be using78const UINT AwtComponent::WmAwtIsComponent =79::RegisterWindowMessage(szAwtComponentClassName);8081static HWND g_hwndDown = NULL;82static DCList activeDCList;83static DCList passiveDCList;8485extern void CheckFontSmoothingSettings(HWND);8687extern "C" {88// Remember the input language has changed by some user's action89// (Alt+Shift or through the language icon on the Taskbar) to control the90// race condition between the toolkit thread and the AWT event thread.91// This flag remains TRUE until the next WInputMethod.getNativeLocale() is92// issued.93BOOL g_bUserHasChangedInputLang = FALSE;94}9596BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE;97BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE;98HWND AwtComponent::sm_focusOwner = NULL;99HWND AwtComponent::sm_focusedWindow = NULL;100BOOL AwtComponent::sm_bMenuLoop = FALSE;101BOOL AwtComponent::sm_inSynthesizeFocus = FALSE;102103/************************************************************************/104// Struct for _Reshape() and ReshapeNoCheck() methods105struct ReshapeStruct {106jobject component;107jint x, y;108jint w, h;109};110// Struct for _NativeHandleEvent() method111struct NativeHandleEventStruct {112jobject component;113jobject event;114};115// Struct for _SetForeground() and _SetBackground() methods116struct SetColorStruct {117jobject component;118jint rgb;119};120// Struct for _SetFont() method121struct SetFontStruct {122jobject component;123jobject font;124};125// Struct for _CreatePrintedPixels() method126struct CreatePrintedPixelsStruct {127jobject component;128int srcx, srcy;129int srcw, srch;130jint alpha;131};132// Struct for _SetRectangularShape() method133struct SetRectangularShapeStruct {134jobject component;135jint x1, x2, y1, y2;136jobject region;137};138// Struct for _GetInsets function139struct GetInsetsStruct {140jobject window;141RECT *insets;142};143// Struct for _SetZOrder function144struct SetZOrderStruct {145jobject component;146jlong above;147};148// Struct for _SetFocus function149struct SetFocusStruct {150jobject component;151jboolean doSetFocus;152};153// Struct for _SetParent function154struct SetParentStruct {155jobject component;156jobject parentComp;157};158/************************************************************************/159160//////////////////////////////////////////////////////////////////////////161162/*************************************************************************163* AwtComponent fields164*/165166167jfieldID AwtComponent::peerID;168jfieldID AwtComponent::xID;169jfieldID AwtComponent::yID;170jfieldID AwtComponent::widthID;171jfieldID AwtComponent::heightID;172jfieldID AwtComponent::visibleID;173jfieldID AwtComponent::backgroundID;174jfieldID AwtComponent::foregroundID;175jfieldID AwtComponent::enabledID;176jfieldID AwtComponent::parentID;177jfieldID AwtComponent::graphicsConfigID;178jfieldID AwtComponent::peerGCID;179jfieldID AwtComponent::focusableID;180jfieldID AwtComponent::appContextID;181jfieldID AwtComponent::cursorID;182jfieldID AwtComponent::hwndID;183184jmethodID AwtComponent::getFontMID;185jmethodID AwtComponent::getToolkitMID;186jmethodID AwtComponent::isEnabledMID;187jmethodID AwtComponent::getLocationOnScreenMID;188jmethodID AwtComponent::replaceSurfaceDataMID;189jmethodID AwtComponent::replaceSurfaceDataLaterMID;190jmethodID AwtComponent::disposeLaterMID;191192HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0);193LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0));194UINT AwtComponent::m_CodePage195= AwtComponent::LangToCodePage(m_idLang);196197jint *AwtComponent::masks;198199static BOOL bLeftShiftIsDown = false;200static BOOL bRightShiftIsDown = false;201static UINT lastShiftKeyPressed = 0; // init to safe value202203// Added by waleed to initialize the RTL Flags204BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC ||205PRIMARYLANGID(GetInputLanguage()) == LANG_HEBREW;206BOOL AwtComponent::sm_rtlReadingOrder =207PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC;208209BOOL AwtComponent::sm_PrimaryDynamicTableBuilt = FALSE;210211HWND AwtComponent::sm_cursorOn;212BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;213214CriticalSection windowMoveLock;215BOOL windowMoveLockHeld = FALSE;216217/************************************************************************218* AwtComponent methods219*/220221AwtComponent::AwtComponent()222{223m_mouseButtonClickAllowed = 0;224m_touchDownOccurred = FALSE;225m_touchUpOccurred = FALSE;226m_touchDownPoint.x = m_touchDownPoint.y = 0;227m_touchUpPoint.x = m_touchUpPoint.y = 0;228m_callbacksEnabled = FALSE;229m_hwnd = NULL;230231m_colorForeground = 0;232m_colorBackground = 0;233m_backgroundColorSet = FALSE;234m_penForeground = NULL;235m_brushBackground = NULL;236m_DefWindowProc = NULL;237m_nextControlID = 1;238m_childList = NULL;239m_myControlID = 0;240m_hdwp = NULL;241m_validationNestCount = 0;242243m_dropTarget = NULL;244245m_InputMethod = NULL;246m_useNativeCompWindow = TRUE;247m_PendingLeadByte = 0;248m_bitsCandType = 0;249250windowMoveLockPosX = 0;251windowMoveLockPosY = 0;252windowMoveLockPosCX = 0;253windowMoveLockPosCY = 0;254255m_hCursorCache = NULL;256257m_bSubclassed = FALSE;258m_bPauseDestroy = FALSE;259260m_MessagesProcessing = 0;261m_wheelRotationAmountX = 0;262m_wheelRotationAmountY = 0;263if (!sm_PrimaryDynamicTableBuilt) {264// do it once.265AwtComponent::BuildPrimaryDynamicTable();266sm_PrimaryDynamicTableBuilt = TRUE;267}268269deadKeyActive = FALSE;270}271272AwtComponent::~AwtComponent()273{274DASSERT(AwtToolkit::IsMainThread());275276/*277* All the messages for this component are processed, native278* resources are freed, and Java object is not connected to279* the native one anymore. So we can safely destroy component's280* handle.281*/282DestroyHWnd();283}284285void AwtComponent::Dispose()286{287DASSERT(AwtToolkit::IsMainThread());288289// NOTE: in case the component/toplevel was focused, Java should290// have already taken care of proper transferring it or clearing.291292if (m_hdwp != NULL) {293// end any deferred window positioning, regardless294// of m_validationNestCount295::EndDeferWindowPos(m_hdwp);296}297298// Send final message to release all DCs associated with this component299SendMessage(WM_AWT_RELEASE_ALL_DCS);300301/* Stop message filtering. */302UnsubclassHWND();303304/* Release global ref to input method */305SetInputMethod(NULL, TRUE);306307if (m_childList != NULL) {308delete m_childList;309m_childList = NULL;310}311312DestroyDropTarget();313ReleaseDragCapture(0);314315if (m_myControlID != 0) {316AwtComponent* parent = GetParent();317if (parent != NULL)318parent->RemoveChild(m_myControlID);319}320321::RemoveProp(GetHWnd(), DrawingStateProp);322323/* Release any allocated resources. */324if (m_penForeground != NULL) {325m_penForeground->Release();326m_penForeground = NULL;327}328if (m_brushBackground != NULL) {329m_brushBackground->Release();330m_brushBackground = NULL;331}332333/* Disconnect all links. */334UnlinkObjects();335336if (m_bPauseDestroy) {337// AwtComponent::WmNcDestroy could be released now338m_bPauseDestroy = FALSE;339m_hwnd = NULL;340}341342// The component instance is deleted using AwtObject::Dispose() method343AwtObject::Dispose();344}345346/* store component pointer in window extra bytes */347void AwtComponent::SetComponentInHWND() {348DASSERT(::GetWindowLongPtr(GetHWnd(), GWLP_USERDATA) == NULL);349::SetWindowLongPtr(GetHWnd(), GWLP_USERDATA, (LONG_PTR)this);350}351352/*353* static function to get AwtComponent pointer from hWnd --354* you don't want to call this from inside a wndproc to avoid355* infinite recursion356*/357AwtComponent* AwtComponent::GetComponent(HWND hWnd) {358// Requests for Toolkit hwnd resolution happen pretty often. Check first.359if (hWnd == AwtToolkit::GetInstance().GetHWnd()) {360return NULL;361}362363// check that it's an AWT component from the same toolkit as the caller364if (::IsWindow(hWnd) &&365AwtToolkit::MainThread() == ::GetWindowThreadProcessId(hWnd, NULL))366{367DASSERT(WmAwtIsComponent != 0);368if (::SendMessage(hWnd, WmAwtIsComponent, 0, 0L)) {369return GetComponentImpl(hWnd);370}371}372return NULL;373}374375/*376* static function to get AwtComponent pointer from hWnd--377* different from GetComponent because caller knows the378* hwnd is an AWT component hwnd379*/380AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) {381AwtComponent *component =382(AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);383DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) );384DASSERT(!component || component->GetHWnd() == hWnd );385return component;386}387388/*389* Single window proc for all the components. Delegates real work to390* the component's WindowProc() member function.391*/392LRESULT CALLBACK AwtComponent::WndProc(HWND hWnd, UINT message,393WPARAM wParam, LPARAM lParam)394{395TRY;396397AwtComponent * self = AwtComponent::GetComponentImpl(hWnd);398if (self == NULL || self->GetHWnd() != hWnd ||399message == WM_UNDOCUMENTED_CLIENTSHUTDOWN) // handle log-off gracefully400{401return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam);402} else {403return self->WindowProc(message, wParam, lParam);404}405406CATCH_BAD_ALLOC_RET(0);407}408409BOOL AwtComponent::IsFocusable() {410JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);411jobject peer = GetPeer(env);412jobject target = env->GetObjectField(peer, AwtObject::targetID);413BOOL res = env->GetBooleanField(target, focusableID);414AwtWindow *pCont = GetContainer();415if (pCont) {416res &= pCont->IsFocusableWindow();417}418env->DeleteLocalRef(target);419return res;420}421422/************************************************************************423* AwtComponent dynamic methods424*425* Window class registration routines426*/427428/*429* Fix for 4964237: Win XP: Changing theme changes java dialogs title icon430*/431void AwtComponent::FillClassInfo(WNDCLASSEX *lpwc)432{433lpwc->cbSize = sizeof(WNDCLASSEX);434lpwc->style = 0L;//CS_OWNDC;435lpwc->lpfnWndProc = (WNDPROC)::DefWindowProc;436lpwc->cbClsExtra = 0;437lpwc->cbWndExtra = 0;438lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(),439lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon();440lpwc->hCursor = NULL;441lpwc->hbrBackground = NULL;442lpwc->lpszMenuName = NULL;443lpwc->lpszClassName = GetClassName();444//Fixed 6233560: PIT: Java Cup Logo on the title bar of top-level windows look blurred, Win32445lpwc->hIconSm = AwtToolkit::GetInstance().GetAwtIconSm();446}447448void AwtComponent::RegisterClass()449{450WNDCLASSEX wc;451if (!::GetClassInfoEx(AwtToolkit::GetInstance().GetModuleHandle(), GetClassName(), &wc)) {452FillClassInfo(&wc);453ATOM ret = ::RegisterClassEx(&wc);454DASSERT(ret != 0);455}456}457458void AwtComponent::UnregisterClass()459{460::UnregisterClass(GetClassName(), AwtToolkit::GetInstance().GetModuleHandle());461}462463/*464* Copy the graphicsConfig reference from Component into WComponentPeer465*/466void AwtComponent::InitPeerGraphicsConfig(JNIEnv *env, jobject peer)467{468jobject target = env->GetObjectField(peer, AwtObject::targetID);469//Get graphicsConfig object ref from Component470jobject compGC = env->GetObjectField(target,471AwtComponent::graphicsConfigID);472473//Set peer's graphicsConfig to Component's graphicsConfig474if (compGC != NULL) {475jclass win32GCCls = env->FindClass("sun/awt/Win32GraphicsConfig");476DASSERT(win32GCCls != NULL);477DASSERT(env->IsInstanceOf(compGC, win32GCCls));478if (win32GCCls == NULL) {479throw std::bad_alloc();480}481env->SetObjectField(peer, AwtComponent::peerGCID, compGC);482}483}484485void486AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title,487DWORD windowStyle,488DWORD windowExStyle,489int x, int y, int w, int h,490HWND hWndParent, HMENU hMenu,491COLORREF colorForeground,492COLORREF colorBackground,493jobject peer)494{495if (env->EnsureLocalCapacity(2) < 0) {496return;497}498499/*500* The window class of multifont label must be "BUTTON" because501* "STATIC" class can't get WM_DRAWITEM message, and m_peerObject502* member is referred in the GetClassName method of AwtLabel class.503* So m_peerObject member must be set here.504*/505if (m_peerObject == NULL) {506m_peerObject = env->NewGlobalRef(peer);507} else {508assert(env->IsSameObject(m_peerObject, peer));509}510511RegisterClass();512513jobject target = env->GetObjectField(peer, AwtObject::targetID);514jboolean visible = env->GetBooleanField(target, AwtComponent::visibleID);515m_visible = visible;516517if (visible) {518windowStyle |= WS_VISIBLE;519} else {520windowStyle &= ~WS_VISIBLE;521}522523InitPeerGraphicsConfig(env, peer);524525SetLastError(0);526HWND hwnd = ::CreateWindowEx(windowExStyle,527GetClassName(),528title,529windowStyle,530x, y, w, h,531hWndParent,532hMenu,533AwtToolkit::GetInstance().GetModuleHandle(),534NULL);535536// fix for 5088782537// check if CreateWindowsEx() returns not null value and if it does -538// create an InternalError or OutOfMemoryError based on GetLastError().539// This error is set to createError field of WObjectPeer and then540// checked and thrown in WComponentPeer constructor. We can't throw an541// error here because this code is invoked on Toolkit thread542if (hwnd == NULL)543{544DWORD dw = ::GetLastError();545jobject createError = NULL;546if (dw == ERROR_OUTOFMEMORY)547{548jstring errorMsg = JNU_NewStringPlatform(env, L"too many window handles");549if (errorMsg == NULL || env->ExceptionCheck()) {550env->ExceptionClear();551createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", "()V");552} else {553createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError",554"(Ljava/lang/String;)V",555errorMsg);556env->DeleteLocalRef(errorMsg);557}558}559else560{561TCHAR *buf;562FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,563NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),564(LPTSTR)&buf, 0, NULL);565jstring s = JNU_NewStringPlatform(env, buf);566if (s == NULL || env->ExceptionCheck()) {567env->ExceptionClear();568createError = JNU_NewObjectByName(env, "java/lang/InternalError", "()V");569} else {570createError = JNU_NewObjectByName(env, "java/lang/InternalError",571"(Ljava/lang/String;)V", s);572env->DeleteLocalRef(s);573}574LocalFree(buf);575}576if (createError != NULL) {577env->SetObjectField(peer, AwtObject::createErrorID, createError);578env->DeleteLocalRef(createError);579}580env->DeleteLocalRef(target);581return;582}583584m_hwnd = hwnd;585586::ImmAssociateContext(m_hwnd, NULL);587588SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED |589(jint)JAWT_LOCK_BOUNDS_CHANGED |590(jint)JAWT_LOCK_CLIP_CHANGED);591592LinkObjects(env, peer);593594/* Subclass the window now so that we can snoop on its messages */595SubclassHWND();596597AwtToolkit& tk = AwtToolkit::GetInstance();598if (tk.IsWin8OrLater() && tk.IsTouchKeyboardAutoShowEnabled()) {599tk.TIRegisterTouchWindow(GetHWnd(), TWF_WANTPALM);600}601602/*603* Fix for 4046446.604*/605Reshape(x, y, w, h);606607/* Set default colors. */608m_colorForeground = colorForeground;609m_colorBackground = colorBackground;610611/*612* Only set background color if the color is actually set on the613* target -- this avoids inheriting a parent's color unnecessarily,614* and has to be done here because there isn't an API to get the615* real background color from outside the AWT package.616*/617jobject bkgrd = env->GetObjectField(target, AwtComponent::backgroundID) ;618if (bkgrd != NULL) {619JNU_CallMethodByName(env, NULL, peer, "setBackground",620"(Ljava/awt/Color;)V", bkgrd);621DASSERT(!safe_ExceptionOccurred(env));622}623env->DeleteLocalRef(target);624env->DeleteLocalRef(bkgrd);625}626627/*628* Destroy this window's HWND629*/630void AwtComponent::DestroyHWnd() {631if (m_hwnd != NULL) {632AwtToolkit::DestroyComponentHWND(m_hwnd);633//AwtToolkit::DestroyComponent(this);634m_hwnd = NULL;635}636}637638/*639* Returns hwnd for target on non Toolkit thread640*/641HWND642AwtComponent::GetHWnd(JNIEnv* env, jobject target) {643if (JNU_IsNull(env, target)) {644return 0;645}646jobject peer = env->GetObjectField(target, AwtComponent::peerID);647if (JNU_IsNull(env, peer)) {648return 0;649}650HWND hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR> (651env->GetLongField(peer, AwtComponent::hwndID)));652env->DeleteLocalRef(peer);653return hwnd;654}655//656// Propagate the background color to synchronize Java field and peer's field.657// This is needed to fix 4148334658//659void AwtComponent::UpdateBackground(JNIEnv *env, jobject target)660{661if (env->EnsureLocalCapacity(1) < 0) {662return;663}664665jobject bkgrnd = env->GetObjectField(target, AwtComponent::backgroundID);666667if (bkgrnd == NULL) {668bkgrnd = JNU_NewObjectByName(env, "java/awt/Color", "(III)V",669GetRValue(m_colorBackground),670GetGValue(m_colorBackground),671GetBValue(m_colorBackground));672if (bkgrnd != NULL) {673env->SetObjectField(target, AwtComponent::backgroundID, bkgrnd);674}675}676env->DeleteLocalRef(bkgrnd);677}678679/*680* Install our window proc as the proc for our HWND, and save off the681* previous proc as the default682*/683void AwtComponent::SubclassHWND()684{685if (m_bSubclassed) {686return;687}688const WNDPROC wndproc = WndProc; // let compiler type check WndProc689m_DefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc);690m_bSubclassed = TRUE;691}692693/*694* Reinstall the original window proc as the proc for our HWND695*/696void AwtComponent::UnsubclassHWND()697{698if (!m_bSubclassed) {699return;700}701ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc, m_DefWindowProc);702m_bSubclassed = FALSE;703}704705/////////////////////////////////////706// (static method)707// Determines the top-level ancestor for a given window. If the given708// window is a top-level window, return itself.709//710// 'Top-level' includes dialogs as well.711//712HWND AwtComponent::GetTopLevelParentForWindow(HWND hwndDescendant) {713if (hwndDescendant == NULL) {714return NULL;715}716717DASSERT(IsWindow(hwndDescendant));718HWND hwnd = hwndDescendant;719for(;;) {720DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);721// a) found a non-child window so terminate722// b) found real toplevel window (e.g. EmbeddedFrame723// that is child though)724if ( (style & WS_CHILD) == 0 ||725AwtComponent::IsTopLevelHWnd(hwnd) )726{727break;728}729hwnd = ::GetParent(hwnd);730}731732return hwnd;733}734////////////////////735736jobject AwtComponent::FindHeavyweightUnderCursor(BOOL useCache) {737JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);738if (env->EnsureLocalCapacity(1) < 0) {739return NULL;740}741742HWND hit = NULL;743POINT p = { 0, 0 };744AwtComponent *comp = NULL;745746if (useCache) {747if (sm_cursorOn == NULL) {748return NULL;749}750751752DASSERT(::IsWindow(sm_cursorOn));753VERIFY(::GetCursorPos(&p));754/*755* Fix for BugTraq ID 4304024.756* Allow a non-default cursor only for the client area.757*/758comp = AwtComponent::GetComponent(sm_cursorOn);759if (comp != NULL &&760::SendMessage(sm_cursorOn, WM_NCHITTEST, 0,761MAKELPARAM(p.x, p.y)) == HTCLIENT) {762goto found;763}764}765766::GetCursorPos(&p);767hit = ::WindowFromPoint(p);768while (hit != NULL) {769comp = AwtComponent::GetComponent(hit);770771if (comp != NULL) {772INT nHittest = (INT)::SendMessage(hit, WM_NCHITTEST,7730, MAKELPARAM(p.x, p.y));774/*775* Fix for BugTraq ID 4304024.776* Allow a non-default cursor only for the client area.777*/778if (nHittest != HTCLIENT) {779/*780* When over the non-client area, send WM_SETCURSOR781* to revert the cursor to an arrow.782*/783::SendMessage(hit, WM_SETCURSOR, (WPARAM)hit,784MAKELPARAM(nHittest, WM_MOUSEMOVE));785return NULL;786} else {787sm_cursorOn = hit;788goto found;789}790}791792if ((::GetWindowLong(hit, GWL_STYLE) & WS_CHILD) == 0) {793return NULL;794}795hit = ::GetParent(hit);796}797798return NULL;799800found:801jobject localRef = comp->GetTarget(env);802jobject globalRef = env->NewGlobalRef(localRef);803env->DeleteLocalRef(localRef);804return globalRef;805}806807void AwtComponent::SetColor(COLORREF c)808{809int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());810int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen);811if (grayscale != GS_NOTGRAY) {812int g;813814g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) +815.114 * ((c >> 16) & 0xFF) + 0.5);816// c = g | (g << 8) | (g << 16);817c = PALETTERGB(g, g, g);818}819820if (m_colorForeground == c) {821return;822}823824m_colorForeground = c;825if (m_penForeground != NULL) {826m_penForeground->Release();827m_penForeground = NULL;828}829VERIFY(::InvalidateRect(GetHWnd(), NULL, FALSE));830}831832void AwtComponent::SetBackgroundColor(COLORREF c)833{834int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());835int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen);836if (grayscale != GS_NOTGRAY) {837int g;838839g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) +840.114 * ((c >> 16) & 0xFF) + 0.5);841// c = g | (g << 8) | (g << 16);842c = PALETTERGB(g, g, g);843}844845if (m_colorBackground == c) {846return;847}848m_colorBackground = c;849m_backgroundColorSet = TRUE;850if (m_brushBackground != NULL) {851m_brushBackground->Release();852m_brushBackground = NULL;853}854VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE));855}856857HPEN AwtComponent::GetForegroundPen()858{859if (m_penForeground == NULL) {860m_penForeground = AwtPen::Get(m_colorForeground);861}862return (HPEN)m_penForeground->GetHandle();863}864865COLORREF AwtComponent::GetBackgroundColor()866{867if (m_backgroundColorSet == FALSE) {868AwtComponent* c = this;869while ((c = c->GetParent()) != NULL) {870if (c->IsBackgroundColorSet()) {871return c->GetBackgroundColor();872}873}874}875return m_colorBackground;876}877878HBRUSH AwtComponent::GetBackgroundBrush()879{880if (m_backgroundColorSet == FALSE) {881if (m_brushBackground != NULL) {882m_brushBackground->Release();883m_brushBackground = NULL;884}885AwtComponent* c = this;886while ((c = c->GetParent()) != NULL) {887if (c->IsBackgroundColorSet()) {888m_brushBackground =889AwtBrush::Get(c->GetBackgroundColor());890break;891}892}893}894if (m_brushBackground == NULL) {895m_brushBackground = AwtBrush::Get(m_colorBackground);896}897return (HBRUSH)m_brushBackground->GetHandle();898}899900void AwtComponent::SetFont(AwtFont* font)901{902DASSERT(font != NULL);903if (font->GetAscent() < 0) {904AwtFont::SetupAscent(font);905}906SendMessage(WM_SETFONT, (WPARAM)font->GetHFont(), MAKELPARAM(FALSE, 0));907VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE));908}909910AwtComponent* AwtComponent::GetParent()911{912HWND hwnd = ::GetParent(GetHWnd());913if (hwnd == NULL) {914return NULL;915}916return GetComponent(hwnd);917}918919AwtWindow* AwtComponent::GetContainer()920{921AwtComponent* comp = this;922while (comp != NULL) {923if (comp->IsContainer()) {924return (AwtWindow*)comp;925}926comp = comp->GetParent();927}928return NULL;929}930931void AwtComponent::Show()932{933m_visible = true;934::ShowWindow(GetHWnd(), SW_SHOWNA);935}936937void AwtComponent::Hide()938{939m_visible = false;940::ShowWindow(GetHWnd(), SW_HIDE);941}942943BOOL944AwtComponent::SetWindowPos(HWND wnd, HWND after,945int x, int y, int w, int h, UINT flags)946{947// Conditions we shouldn't handle:948// z-order changes, correct window dimensions949if (after != NULL || (w < 32767 && h < 32767)950|| ((::GetWindowLong(wnd, GWL_STYLE) & WS_CHILD) == 0))951{952return ::SetWindowPos(wnd, after, x, y, w, h, flags);953}954WINDOWPLACEMENT wp;955::ZeroMemory(&wp, sizeof(wp));956957wp.length = sizeof(wp);958::GetWindowPlacement(wnd, &wp);959wp.rcNormalPosition.left = x;960wp.rcNormalPosition.top = y;961wp.rcNormalPosition.right = x + w;962wp.rcNormalPosition.bottom = y + h;963if ( flags & SWP_NOACTIVATE ) {964wp.showCmd = SW_SHOWNOACTIVATE;965}966::SetWindowPlacement(wnd, &wp);967return 1;968}969970void AwtComponent::Reshape(int x, int y, int w, int h) {971ReshapeNoScale(ScaleUpX(x), ScaleUpY(y), ScaleUpX(w), ScaleUpY(h));972}973974void AwtComponent::ReshapeNoScale(int x, int y, int w, int h)975{976#if defined(DEBUG)977RECT rc;978::GetWindowRect(GetHWnd(), &rc);979::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2);980DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);981#endif982983AwtWindow* container = GetContainer();984AwtComponent* parent = GetParent();985if (container != NULL && container == parent) {986container->SubtractInsetPoint(x, y);987}988DTRACE_PRINTLN4("AwtComponent::Reshape to %d, %d, %d, %d", x, y, w, h);989UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;990991RECT r;992993::GetWindowRect(GetHWnd(), &r);994// if the component size is changing , don't copy window bits995if (r.right - r.left != w || r.bottom - r.top != h) {996flags |= SWP_NOCOPYBITS;997}998999if (parent && _tcscmp(parent->GetClassName(), TEXT("SunAwtScrollPane")) == 0) {1000if (x > 0) {1001x = 0;1002}1003if (y > 0) {1004y = 0;1005}1006}1007if (m_hdwp != NULL) {1008m_hdwp = ::DeferWindowPos(m_hdwp, GetHWnd(), 0, x, y, w, h, flags);1009DASSERT(m_hdwp != NULL);1010} else {1011/*1012* Fox for 40464461013* If window has dimensions above the short int limit, ::SetWindowPos doesn't work.1014* We should use SetWindowPlacement instead.1015*/1016SetWindowPos(GetHWnd(), 0, x, y, w, h, flags);1017}1018}10191020void AwtComponent::SetScrollValues(UINT bar, int min, int value, int max)1021{1022int minTmp, maxTmp;10231024::GetScrollRange(GetHWnd(), bar, &minTmp, &maxTmp);1025if (min == INT_MAX) {1026min = minTmp;1027}1028if (value == INT_MAX) {1029value = ::GetScrollPos(GetHWnd(), bar);1030}1031if (max == INT_MAX) {1032max = maxTmp;1033}1034if (min == max) {1035max++;1036}1037::SetScrollRange(GetHWnd(), bar, min, max, FALSE);1038::SetScrollPos(GetHWnd(), bar, value, TRUE);1039}10401041/*1042* Save Global Reference of sun.awt.windows.WInputMethod object1043*/1044void AwtComponent::SetInputMethod(jobject im, BOOL useNativeCompWindow)1045{1046JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);10471048if (m_InputMethod!=NULL)1049env->DeleteGlobalRef(m_InputMethod);10501051if (im!=NULL){1052m_InputMethod = env->NewGlobalRef(im);1053m_useNativeCompWindow = useNativeCompWindow;1054} else {1055m_InputMethod = NULL;1056m_useNativeCompWindow = TRUE;1057}10581059}10601061/*1062* Opportunity to process and/or eat a message before it is dispatched1063*/1064MsgRouting AwtComponent::PreProcessMsg(MSG& msg)1065{1066return mrPassAlong;1067}10681069static UINT lastMessage = WM_NULL;10701071#ifndef SPY_MESSAGES1072#define SpyWinMessage(hwin,msg,str)1073#else10741075#define FMT_MSG(x,y) case x: _stprintf(szBuf, \1076"0x%8.8x(%s):%s\n", hwnd, szComment, y); break;1077#define WIN_MSG(x) FMT_MSG(x,#x)10781079void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) {10801081TCHAR szBuf[256];10821083switch (message) {1084WIN_MSG(WM_NULL)1085WIN_MSG(WM_CREATE)1086WIN_MSG(WM_DESTROY)1087WIN_MSG(WM_MOVE)1088WIN_MSG(WM_SIZE)1089WIN_MSG(WM_DPICHANGED)1090WIN_MSG(WM_ACTIVATE)1091WIN_MSG(WM_SETFOCUS)1092WIN_MSG(WM_KILLFOCUS)1093WIN_MSG(WM_ENABLE)1094WIN_MSG(WM_SETREDRAW)1095WIN_MSG(WM_SETTEXT)1096WIN_MSG(WM_GETTEXT)1097WIN_MSG(WM_GETTEXTLENGTH)1098WIN_MSG(WM_PAINT)1099WIN_MSG(WM_CLOSE)1100WIN_MSG(WM_QUERYENDSESSION)1101WIN_MSG(WM_QUIT)1102WIN_MSG(WM_QUERYOPEN)1103WIN_MSG(WM_ERASEBKGND)1104WIN_MSG(WM_SYSCOLORCHANGE)1105WIN_MSG(WM_ENDSESSION)1106WIN_MSG(WM_SHOWWINDOW)1107FMT_MSG(WM_WININICHANGE,"WM_WININICHANGE/WM_SETTINGCHANGE")1108WIN_MSG(WM_DEVMODECHANGE)1109WIN_MSG(WM_ACTIVATEAPP)1110WIN_MSG(WM_FONTCHANGE)1111WIN_MSG(WM_TIMECHANGE)1112WIN_MSG(WM_CANCELMODE)1113WIN_MSG(WM_SETCURSOR)1114WIN_MSG(WM_MOUSEACTIVATE)1115WIN_MSG(WM_CHILDACTIVATE)1116WIN_MSG(WM_QUEUESYNC)1117WIN_MSG(WM_GETMINMAXINFO)1118WIN_MSG(WM_PAINTICON)1119WIN_MSG(WM_ICONERASEBKGND)1120WIN_MSG(WM_NEXTDLGCTL)1121WIN_MSG(WM_SPOOLERSTATUS)1122WIN_MSG(WM_DRAWITEM)1123WIN_MSG(WM_MEASUREITEM)1124WIN_MSG(WM_DELETEITEM)1125WIN_MSG(WM_VKEYTOITEM)1126WIN_MSG(WM_CHARTOITEM)1127WIN_MSG(WM_SETFONT)1128WIN_MSG(WM_GETFONT)1129WIN_MSG(WM_SETHOTKEY)1130WIN_MSG(WM_GETHOTKEY)1131WIN_MSG(WM_QUERYDRAGICON)1132WIN_MSG(WM_COMPAREITEM)1133FMT_MSG(0x003D, "WM_GETOBJECT")1134WIN_MSG(WM_COMPACTING)1135WIN_MSG(WM_COMMNOTIFY)1136WIN_MSG(WM_WINDOWPOSCHANGING)1137WIN_MSG(WM_WINDOWPOSCHANGED)1138WIN_MSG(WM_POWER)1139WIN_MSG(WM_COPYDATA)1140WIN_MSG(WM_CANCELJOURNAL)1141WIN_MSG(WM_NOTIFY)1142WIN_MSG(WM_INPUTLANGCHANGEREQUEST)1143WIN_MSG(WM_INPUTLANGCHANGE)1144WIN_MSG(WM_TCARD)1145WIN_MSG(WM_HELP)1146WIN_MSG(WM_USERCHANGED)1147WIN_MSG(WM_NOTIFYFORMAT)1148WIN_MSG(WM_CONTEXTMENU)1149WIN_MSG(WM_STYLECHANGING)1150WIN_MSG(WM_STYLECHANGED)1151WIN_MSG(WM_DISPLAYCHANGE)1152WIN_MSG(WM_GETICON)1153WIN_MSG(WM_SETICON)1154WIN_MSG(WM_NCCREATE)1155WIN_MSG(WM_NCDESTROY)1156WIN_MSG(WM_NCCALCSIZE)1157WIN_MSG(WM_NCHITTEST)1158WIN_MSG(WM_NCPAINT)1159WIN_MSG(WM_NCACTIVATE)1160WIN_MSG(WM_GETDLGCODE)1161WIN_MSG(WM_SYNCPAINT)1162WIN_MSG(WM_NCMOUSEMOVE)1163WIN_MSG(WM_NCLBUTTONDOWN)1164WIN_MSG(WM_NCLBUTTONUP)1165WIN_MSG(WM_NCLBUTTONDBLCLK)1166WIN_MSG(WM_NCRBUTTONDOWN)1167WIN_MSG(WM_NCRBUTTONUP)1168WIN_MSG(WM_NCRBUTTONDBLCLK)1169WIN_MSG(WM_NCMBUTTONDOWN)1170WIN_MSG(WM_NCMBUTTONUP)1171WIN_MSG(WM_NCMBUTTONDBLCLK)1172WIN_MSG(WM_KEYDOWN)1173WIN_MSG(WM_KEYUP)1174WIN_MSG(WM_CHAR)1175WIN_MSG(WM_DEADCHAR)1176WIN_MSG(WM_SYSKEYDOWN)1177WIN_MSG(WM_SYSKEYUP)1178WIN_MSG(WM_SYSCHAR)1179WIN_MSG(WM_SYSDEADCHAR)1180WIN_MSG(WM_IME_STARTCOMPOSITION)1181WIN_MSG(WM_IME_ENDCOMPOSITION)1182WIN_MSG(WM_IME_COMPOSITION)1183WIN_MSG(WM_INITDIALOG)1184WIN_MSG(WM_COMMAND)1185WIN_MSG(WM_SYSCOMMAND)1186WIN_MSG(WM_TIMER)1187WIN_MSG(WM_HSCROLL)1188WIN_MSG(WM_VSCROLL)1189WIN_MSG(WM_INITMENU)1190WIN_MSG(WM_INITMENUPOPUP)1191WIN_MSG(WM_MENUSELECT)1192WIN_MSG(WM_MENUCHAR)1193WIN_MSG(WM_ENTERIDLE)1194FMT_MSG(0x0122, "WM_MENURBUTTONUP")1195FMT_MSG(0x0123, "WM_MENUDRAG")1196FMT_MSG(0x0124, "WM_MENUGETOBJECT")1197FMT_MSG(0x0125, "WM_UNINITMENUPOPUP")1198FMT_MSG(0x0126, "WM_MENUCOMMAND")1199WIN_MSG(WM_CTLCOLORMSGBOX)1200WIN_MSG(WM_CTLCOLOREDIT)1201WIN_MSG(WM_CTLCOLORLISTBOX)1202WIN_MSG(WM_CTLCOLORBTN)1203WIN_MSG(WM_CTLCOLORDLG)1204WIN_MSG(WM_CTLCOLORSCROLLBAR)1205WIN_MSG(WM_CTLCOLORSTATIC)1206WIN_MSG(WM_MOUSEMOVE)1207WIN_MSG(WM_LBUTTONDOWN)1208WIN_MSG(WM_LBUTTONUP)1209WIN_MSG(WM_LBUTTONDBLCLK)1210WIN_MSG(WM_RBUTTONDOWN)1211WIN_MSG(WM_RBUTTONUP)1212WIN_MSG(WM_RBUTTONDBLCLK)1213WIN_MSG(WM_MBUTTONDOWN)1214WIN_MSG(WM_MBUTTONUP)1215WIN_MSG(WM_MBUTTONDBLCLK)1216WIN_MSG(WM_XBUTTONDBLCLK)1217WIN_MSG(WM_XBUTTONDOWN)1218WIN_MSG(WM_XBUTTONUP)1219WIN_MSG(WM_MOUSEWHEEL)1220WIN_MSG(WM_MOUSEHWHEEL)1221WIN_MSG(WM_PARENTNOTIFY)1222WIN_MSG(WM_ENTERMENULOOP)1223WIN_MSG(WM_EXITMENULOOP)1224WIN_MSG(WM_NEXTMENU)1225WIN_MSG(WM_SIZING)1226WIN_MSG(WM_CAPTURECHANGED)1227WIN_MSG(WM_MOVING)1228WIN_MSG(WM_POWERBROADCAST)1229WIN_MSG(WM_DEVICECHANGE)1230WIN_MSG(WM_MDICREATE)1231WIN_MSG(WM_MDIDESTROY)1232WIN_MSG(WM_MDIACTIVATE)1233WIN_MSG(WM_MDIRESTORE)1234WIN_MSG(WM_MDINEXT)1235WIN_MSG(WM_MDIMAXIMIZE)1236WIN_MSG(WM_MDITILE)1237WIN_MSG(WM_MDICASCADE)1238WIN_MSG(WM_MDIICONARRANGE)1239WIN_MSG(WM_MDIGETACTIVE)1240WIN_MSG(WM_MDISETMENU)1241WIN_MSG(WM_ENTERSIZEMOVE)1242WIN_MSG(WM_EXITSIZEMOVE)1243WIN_MSG(WM_DROPFILES)1244WIN_MSG(WM_MDIREFRESHMENU)1245WIN_MSG(WM_IME_SETCONTEXT)1246WIN_MSG(WM_IME_NOTIFY)1247WIN_MSG(WM_IME_CONTROL)1248WIN_MSG(WM_IME_COMPOSITIONFULL)1249WIN_MSG(WM_IME_SELECT)1250WIN_MSG(WM_IME_CHAR)1251FMT_MSG(WM_IME_REQUEST)1252WIN_MSG(WM_IME_KEYDOWN)1253WIN_MSG(WM_IME_KEYUP)1254FMT_MSG(0x02A1, "WM_MOUSEHOVER")1255FMT_MSG(0x02A3, "WM_MOUSELEAVE")1256WIN_MSG(WM_CUT)1257WIN_MSG(WM_COPY)1258WIN_MSG(WM_PASTE)1259WIN_MSG(WM_CLEAR)1260WIN_MSG(WM_UNDO)1261WIN_MSG(WM_RENDERFORMAT)1262WIN_MSG(WM_RENDERALLFORMATS)1263WIN_MSG(WM_DESTROYCLIPBOARD)1264WIN_MSG(WM_DRAWCLIPBOARD)1265WIN_MSG(WM_PAINTCLIPBOARD)1266WIN_MSG(WM_VSCROLLCLIPBOARD)1267WIN_MSG(WM_SIZECLIPBOARD)1268WIN_MSG(WM_ASKCBFORMATNAME)1269WIN_MSG(WM_CHANGECBCHAIN)1270WIN_MSG(WM_HSCROLLCLIPBOARD)1271WIN_MSG(WM_QUERYNEWPALETTE)1272WIN_MSG(WM_PALETTEISCHANGING)1273WIN_MSG(WM_PALETTECHANGED)1274WIN_MSG(WM_HOTKEY)1275WIN_MSG(WM_PRINT)1276WIN_MSG(WM_PRINTCLIENT)1277WIN_MSG(WM_HANDHELDFIRST)1278WIN_MSG(WM_HANDHELDLAST)1279WIN_MSG(WM_AFXFIRST)1280WIN_MSG(WM_AFXLAST)1281WIN_MSG(WM_PENWINFIRST)1282WIN_MSG(WM_PENWINLAST)1283WIN_MSG(WM_AWT_COMPONENT_CREATE)1284WIN_MSG(WM_AWT_DESTROY_WINDOW)1285WIN_MSG(WM_AWT_MOUSEENTER)1286WIN_MSG(WM_AWT_MOUSEEXIT)1287WIN_MSG(WM_AWT_COMPONENT_SHOW)1288WIN_MSG(WM_AWT_COMPONENT_HIDE)1289WIN_MSG(WM_AWT_COMPONENT_SETFOCUS)1290WIN_MSG(WM_AWT_WINDOW_SETACTIVE)1291WIN_MSG(WM_AWT_LIST_SETMULTISELECT)1292WIN_MSG(WM_AWT_HANDLE_EVENT)1293WIN_MSG(WM_AWT_PRINT_COMPONENT)1294WIN_MSG(WM_AWT_RESHAPE_COMPONENT)1295WIN_MSG(WM_AWT_SETALWAYSONTOP)1296WIN_MSG(WM_AWT_BEGIN_VALIDATE)1297WIN_MSG(WM_AWT_END_VALIDATE)1298WIN_MSG(WM_AWT_FORWARD_CHAR)1299WIN_MSG(WM_AWT_FORWARD_BYTE)1300WIN_MSG(WM_AWT_SET_SCROLL_INFO)1301WIN_MSG(WM_AWT_CREATECONTEXT)1302WIN_MSG(WM_AWT_DESTROYCONTEXT)1303WIN_MSG(WM_AWT_ASSOCIATECONTEXT)1304WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER)1305WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT)1306WIN_MSG(WM_AWT_PRE_KEYDOWN)1307WIN_MSG(WM_AWT_PRE_KEYUP)1308WIN_MSG(WM_AWT_PRE_SYSKEYDOWN)1309WIN_MSG(WM_AWT_PRE_SYSKEYUP)1310WIN_MSG(WM_AWT_ENDCOMPOSITION,)1311WIN_MSG(WM_AWT_DISPOSE,)1312WIN_MSG(WM_AWT_DELETEOBJECT,)1313WIN_MSG(WM_AWT_SETCONVERSIONSTATUS,)1314WIN_MSG(WM_AWT_GETCONVERSIONSTATUS,)1315WIN_MSG(WM_AWT_SETOPENSTATUS,)1316WIN_MSG(WM_AWT_GETOPENSTATUS)1317WIN_MSG(WM_AWT_ACTIVATEKEYBOARDLAYOUT)1318WIN_MSG(WM_AWT_OPENCANDIDATEWINDOW)1319WIN_MSG(WM_AWT_DLG_SHOWMODAL,)1320WIN_MSG(WM_AWT_DLG_ENDMODAL,)1321WIN_MSG(WM_AWT_SETCURSOR,)1322WIN_MSG(WM_AWT_WAIT_FOR_SINGLE_OBJECT,)1323WIN_MSG(WM_AWT_INVOKE_METHOD,)1324WIN_MSG(WM_AWT_INVOKE_VOID_METHOD,)1325WIN_MSG(WM_AWT_EXECUTE_SYNC,)1326WIN_MSG(WM_AWT_CURSOR_SYNC)1327WIN_MSG(WM_AWT_GETDC)1328WIN_MSG(WM_AWT_RELEASEDC)1329WIN_MSG(WM_AWT_RELEASE_ALL_DCS)1330WIN_MSG(WM_AWT_SHOWCURSOR)1331WIN_MSG(WM_AWT_HIDECURSOR)1332WIN_MSG(WM_AWT_CREATE_PRINTED_PIXELS)1333WIN_MSG(WM_AWT_OBJECTLISTCLEANUP)1334default:1335sprintf(szBuf, "0x%8.8x(%s):Unknown message 0x%8.8x\n",1336hwnd, szComment, message);1337break;1338}1339printf(szBuf);1340}13411342#endif /* SPY_MESSAGES */13431344/*1345* Dispatch messages for this window class--general component1346*/1347LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)1348{1349CounterHelper ch(&m_MessagesProcessing);13501351JNILocalFrame lframe(AwtToolkit::GetEnv(), 10);1352SpyWinMessage(GetHWnd(), message,1353(message == WM_AWT_RELEASE_ALL_DCS) ? TEXT("Disposed Component") : GetClassName());13541355LRESULT retValue = 0;1356MsgRouting mr = mrDoDefault;1357AwtToolkit::GetInstance().eventNumber++;13581359static BOOL ignoreNextLBTNUP = FALSE; //Ignore next LBUTTONUP msg?13601361lastMessage = message;13621363if (message == WmAwtIsComponent) {1364// special message to identify AWT HWND's without using1365// resource hogging ::SetProp1366return (LRESULT)TRUE;1367}13681369DWORD curPos = 0;13701371UINT switchMessage = message;1372switch (switchMessage) {1373case WM_AWT_GETDC:1374{1375HDC hDC;1376// First, release the DCs scheduled for deletion1377ReleaseDCList(passiveDCList);13781379GetDCReturnStruct *returnStruct = new GetDCReturnStruct;1380returnStruct->gdiLimitReached = FALSE;1381if (AwtGDIObject::IncrementIfAvailable()) {1382hDC = ::GetDCEx(GetHWnd(), NULL,1383DCX_CACHE | DCX_CLIPCHILDREN |1384DCX_CLIPSIBLINGS);1385if (hDC != NULL) {1386// Add new DC to list of DC's associated with this Component1387activeDCList.AddDC(hDC, GetHWnd());1388} else {1389// Creation failed; decrement counter in AwtGDIObject1390AwtGDIObject::Decrement();1391}1392} else {1393hDC = NULL;1394returnStruct->gdiLimitReached = TRUE;1395}1396returnStruct->hDC = hDC;1397retValue = (LRESULT)returnStruct;1398mr = mrConsume;1399break;1400}1401case WM_AWT_RELEASEDC:1402{1403HDC hDC = (HDC)wParam;1404MoveDCToPassiveList(hDC, GetHWnd());1405ReleaseDCList(passiveDCList);1406mr = mrConsume;1407break;1408}1409case WM_AWT_RELEASE_ALL_DCS:1410{1411// Called during Component destruction. Gets current list of1412// DC's associated with Component and releases each DC.1413ReleaseDCList(GetHWnd(), activeDCList);1414ReleaseDCList(passiveDCList);1415mr = mrConsume;1416break;1417}1418case WM_AWT_SHOWCURSOR:1419::ShowCursor(TRUE);1420break;1421case WM_AWT_HIDECURSOR:1422::ShowCursor(FALSE);1423break;1424case WM_CREATE: mr = WmCreate(); break;1425case WM_CLOSE: mr = WmClose(); break;1426case WM_DESTROY: mr = WmDestroy(); break;1427case WM_NCDESTROY: mr = WmNcDestroy(); break;14281429case WM_ERASEBKGND:1430mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break;1431case WM_PAINT:1432CheckFontSmoothingSettings(GetHWnd());1433/* Set draw state */1434SetDrawState(GetDrawState() | JAWT_LOCK_CLIP_CHANGED);1435mr = WmPaint((HDC)wParam);1436break;14371438case WM_GETMINMAXINFO:1439mr = WmGetMinMaxInfo((LPMINMAXINFO)lParam);1440break;14411442case WM_WINDOWPOSCHANGING:1443{1444// We process this message so that we can synchronize access to1445// a moving window. The Scale/Blt functions in Win32BlitLoops1446// take the same windowMoveLock to ensure that a window is not1447// moving while we are trying to copy pixels into it.1448WINDOWPOS *lpPosInfo = (WINDOWPOS *)lParam;1449if ((lpPosInfo->flags & (SWP_NOMOVE | SWP_NOSIZE)) !=1450(SWP_NOMOVE | SWP_NOSIZE))1451{1452// Move or Size command.1453// Windows tends to send erroneous events that the window1454// is about to move when the coordinates are exactly the1455// same as the last time. This can cause problems with1456// our windowMoveLock CriticalSection because we enter it1457// here and never get to WM_WINDOWPOSCHANGED to release it.1458// So make sure this is a real move/size event before bothering1459// to grab the critical section.1460BOOL takeLock = FALSE;1461if (!(lpPosInfo->flags & SWP_NOMOVE) &&1462((windowMoveLockPosX != lpPosInfo->x) ||1463(windowMoveLockPosY != lpPosInfo->y)))1464{1465// Real move event1466takeLock = TRUE;1467windowMoveLockPosX = lpPosInfo->x;1468windowMoveLockPosY = lpPosInfo->y;1469}1470if (!(lpPosInfo->flags & SWP_NOSIZE) &&1471((windowMoveLockPosCX != lpPosInfo->cx) ||1472(windowMoveLockPosCY != lpPosInfo->cy)))1473{1474// Real size event1475takeLock = TRUE;1476windowMoveLockPosCX = lpPosInfo->cx;1477windowMoveLockPosCY = lpPosInfo->cy;1478}1479if (takeLock) {1480if (!windowMoveLockHeld) {1481windowMoveLock.Enter();1482windowMoveLockHeld = TRUE;1483}1484}1485}1486mr = WmWindowPosChanging(lParam);1487break;1488}1489case WM_WINDOWPOSCHANGED:1490{1491// Release lock grabbed in the POSCHANGING message1492if (windowMoveLockHeld) {1493windowMoveLockHeld = FALSE;1494windowMoveLock.Leave();1495}1496mr = WmWindowPosChanged(lParam);1497break;1498}1499case WM_MOVE: {1500RECT r;1501::GetWindowRect(GetHWnd(), &r);1502mr = WmMove(r.left, r.top);1503break;1504}1505case WM_SIZE:1506{1507RECT r;1508// fix 4128317 : use GetWindowRect for full 32-bit int precision and1509// to avoid negative client area dimensions overflowing 16-bit params - robi1510::GetWindowRect(GetHWnd(), &r);1511mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top);1512//mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam));1513SetCompositionWindow(r);1514break;1515}1516case WM_SIZING:1517mr = WmSizing();1518break;1519case WM_SHOWWINDOW:1520mr = WmShowWindow(static_cast<BOOL>(wParam),1521static_cast<UINT>(lParam)); break;1522case WM_SYSCOMMAND:1523mr = WmSysCommand(static_cast<UINT>(wParam & 0xFFF0),1524GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));1525break;1526case WM_ENTERSIZEMOVE:1527mr = WmEnterSizeMove();1528break;1529case WM_EXITSIZEMOVE:1530mr = WmExitSizeMove();1531break;1532// Bug #4039858 (Selecting menu item causes bogus mouse click event)1533case WM_ENTERMENULOOP:1534mr = WmEnterMenuLoop((BOOL)wParam);1535sm_bMenuLoop = TRUE;1536// we need to release grab if menu is shown1537if (AwtWindow::GetGrabbedWindow() != NULL) {1538AwtWindow::GetGrabbedWindow()->Ungrab();1539}1540break;1541case WM_EXITMENULOOP:1542mr = WmExitMenuLoop((BOOL)wParam);1543sm_bMenuLoop = FALSE;1544break;15451546// We don't expect any focus messages on non-proxy component,1547// except those that came from Java.1548case WM_SETFOCUS:1549if (sm_inSynthesizeFocus) {1550mr = WmSetFocus((HWND)wParam);1551} else {1552mr = mrConsume;1553}1554break;1555case WM_KILLFOCUS:1556if (sm_inSynthesizeFocus) {1557mr = WmKillFocus((HWND)wParam);1558} else {1559mr = mrConsume;1560}1561break;1562case WM_ACTIVATE: {1563UINT nState = LOWORD(wParam);1564BOOL fMinimized = (BOOL)HIWORD(wParam);1565mr = mrConsume;15661567if (!sm_suppressFocusAndActivation &&1568(!fMinimized || (nState == WA_INACTIVE)))1569{1570mr = WmActivate(nState, fMinimized, (HWND)lParam);15711572// When the window is deactivated, send WM_IME_ENDCOMPOSITION1573// message to deactivate the composition window so that1574// it won't receive keyboard input focus.1575HIMC hIMC;1576HWND hwnd = ImmGetHWnd();1577if ((hIMC = ImmGetContext(hwnd)) != NULL) {1578ImmReleaseContext(hwnd, hIMC);1579DefWindowProc(WM_IME_ENDCOMPOSITION, 0, 0);1580}1581}1582break;1583}1584case WM_MOUSEACTIVATE: {1585AwtWindow *window = GetContainer();1586if (window && window->IsFocusableWindow()) {1587// AWT/Swing will later request focus to a proper component1588// on handling the Java mouse event. Anyway, we have to1589// activate the window here as it works both for AWT & Swing.1590// Do it in our own fassion,1591window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/);1592}1593mr = mrConsume;1594retValue = MA_NOACTIVATE;1595break;1596}1597case WM_CTLCOLORMSGBOX:1598case WM_CTLCOLOREDIT:1599case WM_CTLCOLORLISTBOX:1600case WM_CTLCOLORBTN:1601case WM_CTLCOLORDLG:1602case WM_CTLCOLORSCROLLBAR:1603case WM_CTLCOLORSTATIC:1604mr = WmCtlColor((HDC)wParam, (HWND)lParam,1605message-WM_CTLCOLORMSGBOX+CTLCOLOR_MSGBOX,1606*(HBRUSH*)&retValue);1607break;1608case WM_HSCROLL:1609mr = WmHScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);1610break;1611case WM_VSCROLL:1612mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);1613break;1614// 4664415: We're seeing a WM_LBUTTONUP when the user releases the1615// mouse button after a WM_NCLBUTTONDBLCLK. We want to ignore this1616// WM_LBUTTONUP, so we set a flag in WM_NCLBUTTONDBLCLK and look for the1617// flag on a WM_LBUTTONUP. -bchristi1618case WM_NCLBUTTONDBLCLK:1619mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON | DBL_CLICK);1620if (mr == mrDoDefault) {1621ignoreNextLBTNUP = TRUE;1622}1623break;1624case WM_NCLBUTTONDOWN:1625mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON);1626ignoreNextLBTNUP = FALSE;1627break;1628case WM_NCLBUTTONUP:1629mr = WmNcMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON);1630break;1631case WM_NCRBUTTONDOWN:1632mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), RIGHT_BUTTON);1633break;1634case WM_LBUTTONUP:1635if (ignoreNextLBTNUP) {1636ignoreNextLBTNUP = FALSE;1637return mrDoDefault;1638}1639//fall-through1640case WM_LBUTTONDOWN:1641ignoreNextLBTNUP = FALSE;1642//fall-through1643case WM_LBUTTONDBLCLK:1644case WM_RBUTTONDOWN:1645case WM_RBUTTONDBLCLK:1646case WM_RBUTTONUP:1647case WM_MBUTTONDOWN:1648case WM_MBUTTONDBLCLK:1649case WM_MBUTTONUP:1650case WM_XBUTTONDBLCLK:1651case WM_XBUTTONDOWN:1652case WM_XBUTTONUP:1653case WM_MOUSEMOVE:1654case WM_MOUSEWHEEL:1655case WM_MOUSEHWHEEL:1656case WM_AWT_MOUSEENTER:1657case WM_AWT_MOUSEEXIT:1658curPos = ::GetMessagePos();1659POINT myPos;1660myPos.x = GET_X_LPARAM(curPos);1661myPos.y = GET_Y_LPARAM(curPos);1662::ScreenToClient(GetHWnd(), &myPos);1663switch(switchMessage) {1664case WM_AWT_MOUSEENTER:1665mr = WmMouseEnter(static_cast<UINT>(wParam), myPos.x, myPos.y);1666break;1667case WM_LBUTTONDOWN:1668case WM_LBUTTONDBLCLK:1669mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,1670LEFT_BUTTON);1671break;1672case WM_LBUTTONUP:1673mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,1674LEFT_BUTTON);1675break;1676case WM_MOUSEMOVE:1677mr = WmMouseMove(static_cast<UINT>(wParam), myPos.x, myPos.y);1678break;1679case WM_MBUTTONDOWN:1680case WM_MBUTTONDBLCLK:1681mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,1682MIDDLE_BUTTON);1683break;1684case WM_XBUTTONDOWN:1685case WM_XBUTTONDBLCLK:1686if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {1687if (HIWORD(wParam) == 1) {1688mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,1689X1_BUTTON);1690}1691if (HIWORD(wParam) == 2) {1692mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,1693X2_BUTTON);1694}1695}1696break;1697case WM_XBUTTONUP:1698if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {1699if (HIWORD(wParam) == 1) {1700mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,1701X1_BUTTON);1702}1703if (HIWORD(wParam) == 2) {1704mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,1705X2_BUTTON);1706}1707}1708break;1709case WM_RBUTTONDOWN:1710case WM_RBUTTONDBLCLK:1711mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,1712RIGHT_BUTTON);1713break;1714case WM_RBUTTONUP:1715mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,1716RIGHT_BUTTON);1717break;1718case WM_MBUTTONUP:1719mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,1720MIDDLE_BUTTON);1721break;1722case WM_AWT_MOUSEEXIT:1723mr = WmMouseExit(static_cast<UINT>(wParam), myPos.x, myPos.y);1724break;1725case WM_MOUSEWHEEL:1726case WM_MOUSEHWHEEL:1727mr = WmMouseWheel(GET_KEYSTATE_WPARAM(wParam),1728GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),1729GET_WHEEL_DELTA_WPARAM(wParam),1730switchMessage == WM_MOUSEHWHEEL);1731break;1732}1733break;1734case WM_TOUCH:1735WmTouch(wParam, lParam);1736break;1737case WM_SETCURSOR:1738mr = mrDoDefault;1739if (LOWORD(lParam) == HTCLIENT) {1740if (AwtComponent* comp =1741AwtComponent::GetComponent((HWND)wParam)) {1742AwtCursor::UpdateCursor(comp);1743mr = mrConsume;1744}1745}1746break;17471748case WM_KEYDOWN:1749mr = WmKeyDown(static_cast<UINT>(wParam),1750LOWORD(lParam), HIWORD(lParam), FALSE);1751break;1752case WM_KEYUP:1753mr = WmKeyUp(static_cast<UINT>(wParam),1754LOWORD(lParam), HIWORD(lParam), FALSE);1755break;1756case WM_SYSKEYDOWN:1757mr = WmKeyDown(static_cast<UINT>(wParam),1758LOWORD(lParam), HIWORD(lParam), TRUE);1759break;1760case WM_SYSKEYUP:1761mr = WmKeyUp(static_cast<UINT>(wParam),1762LOWORD(lParam), HIWORD(lParam), TRUE);1763break;1764case WM_IME_SETCONTEXT:1765// lParam is passed as pointer and it can be modified.1766mr = WmImeSetContext(static_cast<BOOL>(wParam), &lParam);1767CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1768break;1769case WM_IME_NOTIFY:1770mr = WmImeNotify(wParam, lParam);1771CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1772break;1773case WM_IME_STARTCOMPOSITION:1774mr = WmImeStartComposition();1775CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1776break;1777case WM_IME_ENDCOMPOSITION:1778mr = WmImeEndComposition();1779CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1780break;1781case WM_IME_COMPOSITION: {1782WORD dbcschar = static_cast<WORD>(wParam);1783mr = WmImeComposition(dbcschar, lParam);1784CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1785break;1786}1787case WM_IME_CONTROL:1788case WM_IME_COMPOSITIONFULL:1789case WM_IME_SELECT:1790case WM_IME_KEYUP:1791case WM_IME_KEYDOWN:1792case WM_IME_REQUEST:1793CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1794break;1795case WM_CHAR:1796mr = WmChar(static_cast<UINT>(wParam),1797LOWORD(lParam), HIWORD(lParam), FALSE);1798break;1799case WM_SYSCHAR:1800mr = WmChar(static_cast<UINT>(wParam),1801LOWORD(lParam), HIWORD(lParam), TRUE);1802break;1803case WM_IME_CHAR:1804mr = WmIMEChar(static_cast<UINT>(wParam),1805LOWORD(lParam), HIWORD(lParam), FALSE);1806break;18071808case WM_INPUTLANGCHANGEREQUEST: {1809DTRACE_PRINTLN4("WM_INPUTLANGCHANGEREQUEST: hwnd = 0x%X (%s);"//1810"0x%08X -> 0x%08X",1811GetHWnd(), GetClassName(),1812(UINT_PTR)GetKeyboardLayout(), (UINT_PTR)lParam);1813// 4267428: make sure keyboard layout is turned undead.1814static BYTE keyboardState[AwtToolkit::KB_STATE_SIZE];1815AwtToolkit::GetKeyboardState(keyboardState);1816WORD ignored;1817::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0),1818keyboardState, &ignored, 0, GetKeyboardLayout());18191820// Set this flag to block ActivateKeyboardLayout from1821// WInputMethod.activate()1822g_bUserHasChangedInputLang = TRUE;1823CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1824break;1825}1826case WM_INPUTLANGCHANGE:1827DTRACE_PRINTLN3("WM_INPUTLANGCHANGE: hwnd = 0x%X (%s);"//1828"new = 0x%08X",1829GetHWnd(), GetClassName(), (UINT)lParam);1830mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam));1831g_bUserHasChangedInputLang = TRUE;1832CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);1833// should return non-zero if we process this message1834retValue = 1;1835break;18361837case WM_AWT_FORWARD_CHAR:1838mr = WmForwardChar(LOWORD(wParam), lParam, HIWORD(wParam));1839break;18401841case WM_AWT_FORWARD_BYTE:1842mr = HandleEvent( (MSG *) lParam, (BOOL) wParam);1843break;18441845case WM_PASTE:1846mr = WmPaste();1847break;1848case WM_TIMER:1849mr = WmTimer(wParam);1850break;18511852case WM_COMMAND:1853mr = WmCommand(LOWORD(wParam), (HWND)lParam, HIWORD(wParam));1854break;1855case WM_COMPAREITEM:1856mr = WmCompareItem(static_cast<UINT>(wParam),1857*(COMPAREITEMSTRUCT*)lParam, retValue);1858break;1859case WM_DELETEITEM:1860mr = WmDeleteItem(static_cast<UINT>(wParam),1861*(DELETEITEMSTRUCT*)lParam);1862break;1863case WM_DRAWITEM:1864mr = WmDrawItem(static_cast<UINT>(wParam),1865*(DRAWITEMSTRUCT*)lParam);1866break;1867case WM_MEASUREITEM:1868mr = WmMeasureItem(static_cast<UINT>(wParam),1869*(MEASUREITEMSTRUCT*)lParam);1870break;18711872case WM_AWT_HANDLE_EVENT:1873mr = HandleEvent( (MSG *) lParam, (BOOL) wParam);1874break;18751876case WM_PRINT:1877mr = WmPrint((HDC)wParam, lParam);1878break;1879case WM_PRINTCLIENT:1880mr = WmPrintClient((HDC)wParam, lParam);1881break;18821883case WM_NCCALCSIZE:1884mr = WmNcCalcSize((BOOL)wParam, (LPNCCALCSIZE_PARAMS)lParam,1885retValue);1886break;1887case WM_NCPAINT:1888mr = WmNcPaint((HRGN)wParam);1889break;1890case WM_NCHITTEST:1891mr = WmNcHitTest(LOWORD(lParam), HIWORD(lParam), retValue);1892break;18931894case WM_AWT_RESHAPE_COMPONENT: {1895RECT* r = (RECT*)lParam;1896WPARAM checkEmbedded = wParam;1897if (checkEmbedded == CHECK_EMBEDDED && IsEmbeddedFrame()) {1898::OffsetRect(r, -r->left, -r->top);1899}1900Reshape(r->left, r->top, r->right - r->left, r->bottom - r->top);1901delete r;1902mr = mrConsume;1903break;1904}19051906case WM_AWT_SETALWAYSONTOP: {1907AwtWindow* w = (AwtWindow*)lParam;1908BOOL value = (BOOL)wParam;1909UINT flags = SWP_NOMOVE | SWP_NOSIZE;1910// transient windows shouldn't change the owner window's position in the z-order1911if (w->IsRetainingHierarchyZOrder()) {1912flags |= SWP_NOOWNERZORDER;1913}1914::SetWindowPos(w->GetHWnd(), (value != 0 ? HWND_TOPMOST : HWND_NOTOPMOST),19150,0,0,0, flags);1916break;1917}19181919case WM_AWT_BEGIN_VALIDATE:1920BeginValidate();1921mr = mrConsume;1922break;1923case WM_AWT_END_VALIDATE:1924EndValidate();1925mr = mrConsume;1926break;19271928case WM_PALETTEISCHANGING:1929mr = WmPaletteIsChanging((HWND)wParam);1930mr = mrDoDefault;1931break;1932case WM_QUERYNEWPALETTE:1933mr = WmQueryNewPalette(retValue);1934break;1935case WM_PALETTECHANGED:1936mr = WmPaletteChanged((HWND)wParam);1937break;1938case WM_STYLECHANGED:1939mr = WmStyleChanged(static_cast<int>(wParam), (LPSTYLESTRUCT)lParam);1940break;1941case WM_SETTINGCHANGE:1942CheckFontSmoothingSettings(NULL);1943mr = WmSettingChange(static_cast<UINT>(wParam), (LPCTSTR)lParam);1944break;1945case WM_CONTEXTMENU:1946mr = WmContextMenu((HWND)wParam,1947GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));1948break;19491950/*1951* These messages are used to route Win32 calls to the1952* creating thread, since these calls fail unless executed1953* there.1954*/1955case WM_AWT_COMPONENT_SHOW:1956Show();1957mr = mrConsume;1958break;1959case WM_AWT_COMPONENT_HIDE:1960Hide();1961mr = mrConsume;1962break;19631964case WM_AWT_COMPONENT_SETFOCUS:1965if ((BOOL)wParam) {1966retValue = SynthesizeWmSetFocus(GetHWnd(), NULL);1967} else {1968retValue = SynthesizeWmKillFocus(GetHWnd(), NULL);1969}1970mr = mrConsume;1971break;1972case WM_AWT_WINDOW_SETACTIVE:1973retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam);1974mr = mrConsume;1975break;19761977case WM_AWT_SET_SCROLL_INFO: {1978SCROLLINFO *si = (SCROLLINFO *) lParam;1979::SetScrollInfo(GetHWnd(), (int) wParam, si, TRUE);1980delete si;1981mr = mrConsume;1982break;1983}1984case WM_AWT_CREATE_PRINTED_PIXELS: {1985CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam;1986SIZE loc = { cpps->srcx, cpps->srcy };1987SIZE size = { cpps->srcw, cpps->srch };1988retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha);1989mr = mrConsume;1990break;1991}1992case WM_UNDOCUMENTED_CLICKMENUBAR:1993{1994if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {1995mr = mrConsume;1996}1997}1998}19992000/*2001* If not a specific Consume, it was a specific DoDefault, or a2002* PassAlong (since the default is the next in chain), then call the2003* default proc.2004*/2005if (mr != mrConsume) {2006retValue = DefWindowProc(message, wParam, lParam);2007}20082009return retValue;2010}2011/*2012* Call this instance's default window proc, or if none set, call the stock2013* Window's one.2014*/2015LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam)2016{2017return ComCtl32Util::GetInstance().DefWindowProc(m_DefWindowProc, GetHWnd(), msg, wParam, lParam);2018}20192020/*2021* This message should only be received when a window is destroyed by2022* Windows, and not Java. Window termination has been reworked so2023* this method should never be called during termination.2024*/2025MsgRouting AwtComponent::WmDestroy()2026{2027return mrConsume;2028}20292030/*2031* This message should only be received when a window is destroyed by2032* Windows, and not Java. It is sent only after child windows were destroyed.2033*/2034MsgRouting AwtComponent::WmNcDestroy()2035{2036if (m_peerObject != NULL) { // is not being terminating2037// Stay in this handler until AwtComponent::Dispose is called.2038m_bPauseDestroy = TRUE;20392040JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);2041// Post invocation event for WObjectPeer.dispose to EDT2042env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID);2043// Wait until AwtComponent::Dispose is called2044AwtToolkit::GetInstance().PumpToDestroy(this);2045}20462047return mrConsume;2048}20492050MsgRouting AwtComponent::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)2051{2052return mrDoDefault;2053}20542055MsgRouting AwtComponent::WmMove(int x, int y)2056{2057SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED)2058| static_cast<jint>(JAWT_LOCK_CLIP_CHANGED));2059return mrDoDefault;2060}20612062MsgRouting AwtComponent::WmSize(UINT type, int w, int h)2063{2064SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED)2065| static_cast<jint>(JAWT_LOCK_CLIP_CHANGED));2066return mrDoDefault;2067}20682069MsgRouting AwtComponent::WmSizing()2070{2071return mrDoDefault;2072}20732074MsgRouting AwtComponent::WmSysCommand(UINT uCmdType, int xPos, int yPos)2075{2076return mrDoDefault;2077}20782079MsgRouting AwtComponent::WmEnterSizeMove()2080{2081return mrDoDefault;2082}20832084MsgRouting AwtComponent::WmExitSizeMove()2085{2086return mrDoDefault;2087}20882089MsgRouting AwtComponent::WmEnterMenuLoop(BOOL isTrackPopupMenu)2090{2091return mrDoDefault;2092}20932094MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu)2095{2096return mrDoDefault;2097}20982099MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status)2100{2101return mrDoDefault;2102}21032104MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus)2105{2106m_wheelRotationAmountX = 0;2107m_wheelRotationAmountY = 0;2108return mrDoDefault;2109}21102111MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus)2112{2113m_wheelRotationAmountX = 0;2114m_wheelRotationAmountY = 0;2115return mrDoDefault;2116}21172118MsgRouting AwtComponent::WmCtlColor(HDC hDC, HWND hCtrl,2119UINT ctlColor, HBRUSH& retBrush)2120{2121AwtComponent* child = AwtComponent::GetComponent(hCtrl);2122if (child) {2123::SetBkColor(hDC, child->GetBackgroundColor());2124::SetTextColor(hDC, child->GetColor());2125retBrush = child->GetBackgroundBrush();2126return mrConsume;2127}2128return mrDoDefault;2129/*2130switch (ctlColor) {2131case CTLCOLOR_MSGBOX:2132case CTLCOLOR_EDIT:2133case CTLCOLOR_LISTBOX:2134case CTLCOLOR_BTN:2135case CTLCOLOR_DLG:2136case CTLCOLOR_SCROLLBAR:2137case CTLCOLOR_STATIC:2138}2139*/2140}21412142MsgRouting AwtComponent::WmHScroll(UINT scrollCode, UINT pos,2143HWND hScrollbar) {2144if (hScrollbar && hScrollbar != GetHWnd()) {2145/* the last test should never happen */2146AwtComponent* sb = GetComponent(hScrollbar);2147if (sb) {2148sb->WmHScroll(scrollCode, pos, hScrollbar);2149}2150}2151return mrDoDefault;2152}21532154MsgRouting AwtComponent::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar)2155{2156if (hScrollbar && hScrollbar != GetHWnd()) {2157/* the last test should never happen */2158AwtComponent* sb = GetComponent(hScrollbar);2159if (sb) {2160sb->WmVScroll(scrollCode, pos, hScrollbar);2161}2162}2163return mrDoDefault;2164}216521662167MsgRouting AwtComponent::WmPaint(HDC)2168{2169/* Get the rectangle that covers all update regions, if any exist. */2170RECT r;2171if (::GetUpdateRect(GetHWnd(), &r, FALSE)) {2172if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 &&2173m_peerObject != NULL && m_callbacksEnabled) {2174/*2175* Always call handlePaint, because the underlying control2176* will have painted itself (the "background") before any2177* paint method is called.2178*/2179DoCallback("handlePaint", "(IIII)V",2180r.left, r.top, r.right-r.left, r.bottom-r.top);2181}2182}2183return mrDoDefault;2184}21852186void AwtComponent::PaintUpdateRgn(const RECT *insets)2187{2188// Fix 4530093: Don't Validate if can't actually paint2189if (m_peerObject == NULL || !m_callbacksEnabled) {21902191// Fix 4745222: If we don't ValidateRgn, windows will keep sending2192// WM_PAINT messages until we do. This causes java to go into2193// a tight loop that increases CPU to 100% and starves main2194// thread which needs to complete initialization, but cant.2195::ValidateRgn(GetHWnd(), NULL);21962197return;2198}21992200HRGN rgn = ::CreateRectRgn(0,0,1,1);2201int updated = ::GetUpdateRgn(GetHWnd(), rgn, FALSE);2202/*2203* Now remove all update regions from this window -- do it2204* here instead of after the Java upcall, in case any new2205* updating is requested.2206*/2207::ValidateRgn(GetHWnd(), NULL);22082209if (updated == COMPLEXREGION || updated == SIMPLEREGION) {2210if (insets != NULL) {2211::OffsetRgn(rgn, insets->left, insets->top);2212}2213DWORD size = ::GetRegionData(rgn, 0, NULL);2214if (size == 0) {2215::DeleteObject((HGDIOBJ)rgn);2216return;2217}2218char* buffer = new char[size]; // safe because sizeof(char)==12219memset(buffer, 0, size);2220LPRGNDATA rgndata = (LPRGNDATA)buffer;2221rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);2222rgndata->rdh.iType = RDH_RECTANGLES;2223int retCode = ::GetRegionData(rgn, size, rgndata);2224VERIFY(retCode);2225if (retCode == 0) {2226delete [] buffer;2227::DeleteObject((HGDIOBJ)rgn);2228return;2229}2230/*2231* Updating rects are divided into mostly vertical and mostly horizontal2232* Each group is united together and if not empty painted separately2233*/2234RECT* r = (RECT*)(buffer + rgndata->rdh.dwSize);2235RECT* un[2] = {0, 0};2236DWORD i;2237for (i = 0; i < rgndata->rdh.nCount; i++, r++) {2238int width = r->right-r->left;2239int height = r->bottom-r->top;2240if (width > 0 && height > 0) {2241int toAdd = (width > height) ? 0: 1;2242if (un[toAdd] != 0) {2243::UnionRect(un[toAdd], un[toAdd], r);2244} else {2245un[toAdd] = r;2246}2247}2248}2249for(i = 0; i < 2; i++) {2250if (un[i] != 0) {2251DoCallback("handleExpose", "(IIII)V",2252ScaleDownX(un[i]->left),2253ScaleDownY(un[i]->top),2254ScaleDownX(un[i]->right - un[i]->left),2255ScaleDownY(un[i]->bottom - un[i]->top));2256}2257}2258delete [] buffer;2259}2260::DeleteObject((HGDIOBJ)rgn);2261}22622263MsgRouting AwtComponent::WmMouseEnter(UINT flags, int x, int y)2264{2265SendMouseEvent(java_awt_event_MouseEvent_MOUSE_ENTERED,2266::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), 0, JNI_FALSE);2267if ((flags & ALL_MK_BUTTONS) == 0) {2268AwtCursor::UpdateCursor(this);2269}2270sm_cursorOn = GetHWnd();2271return mrConsume; /* Don't pass our synthetic event on! */2272}22732274MSG*2275AwtComponent::CreateMessage(UINT message, WPARAM wParam, LPARAM lParam,2276int x = 0, int y = 0)2277{2278MSG* pMsg = new MSG;2279InitMessage(pMsg, message, wParam, lParam, x, y);2280return pMsg;2281}228222832284jint2285AwtComponent::GetDrawState(HWND hwnd) {2286return (jint)(INT_PTR)(::GetProp(hwnd, DrawingStateProp));2287}22882289void2290AwtComponent::SetDrawState(HWND hwnd, jint state) {2291::SetProp(hwnd, DrawingStateProp, (HANDLE)(INT_PTR)state);2292}22932294void2295AwtComponent::InitMessage(MSG* msg, UINT message, WPARAM wParam, LPARAM lParam,2296int x = 0, int y = 0)2297{2298msg->message = message;2299msg->wParam = wParam;2300msg->lParam = lParam;2301msg->time = ::GetMessageTime();2302msg->pt.x = x;2303msg->pt.y = y;2304}23052306MsgRouting AwtComponent::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {2307return mrDoDefault;2308}2309MsgRouting AwtComponent::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) {2310return mrDoDefault;2311}23122313MsgRouting AwtComponent::WmWindowPosChanging(LPARAM windowPos) {2314return mrDoDefault;2315}2316MsgRouting AwtComponent::WmWindowPosChanged(LPARAM windowPos) {2317return mrDoDefault;2318}23192320void AwtComponent::WmTouch(WPARAM wParam, LPARAM lParam) {2321AwtToolkit& tk = AwtToolkit::GetInstance();2322if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) {2323return;2324}23252326UINT inputsCount = LOWORD(wParam);2327TOUCHINPUT* pInputs = new TOUCHINPUT[inputsCount];2328if (pInputs != NULL) {2329if (tk.TIGetTouchInputInfo((HTOUCHINPUT)lParam, inputsCount, pInputs,2330sizeof(TOUCHINPUT)) != 0) {2331for (UINT i = 0; i < inputsCount; i++) {2332TOUCHINPUT ti = pInputs[i];2333if (ti.dwFlags & TOUCHEVENTF_PRIMARY) {2334if (ti.dwFlags & TOUCHEVENTF_DOWN) {2335m_touchDownPoint.x = ti.x / 100;2336m_touchDownPoint.y = ti.y / 100;2337::ScreenToClient(GetHWnd(), &m_touchDownPoint);2338m_touchDownOccurred = TRUE;2339} else if (ti.dwFlags & TOUCHEVENTF_UP) {2340m_touchUpPoint.x = ti.x / 100;2341m_touchUpPoint.y = ti.y / 100;2342::ScreenToClient(GetHWnd(), &m_touchUpPoint);2343m_touchUpOccurred = TRUE;2344}2345}2346}2347}2348delete[] pInputs;2349}2350}23512352/* Double-click variables. */2353static jlong multiClickTime = ::GetDoubleClickTime();2354static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK);2355static int multiClickMaxY = ::GetSystemMetrics(SM_CYDOUBLECLK);2356static AwtComponent* lastClickWnd = NULL;2357static jlong lastTime = 0;2358static int lastClickX = 0;2359static int lastClickY = 0;2360static int lastButton = 0;2361static int clickCount = 0;23622363// A static method that makes the clickCount available in the derived classes2364// overriding WmMouseDown().2365int AwtComponent::GetClickCount()2366{2367return clickCount;2368}23692370MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button)2371{2372jlong now = ::JVM_CurrentTimeMillis(NULL, 0);23732374if (lastClickWnd == this &&2375lastButton == button &&2376(now - lastTime) <= multiClickTime &&2377abs(x - lastClickX) <= multiClickMaxX &&2378abs(y - lastClickY) <= multiClickMaxY)2379{2380clickCount++;2381} else {2382clickCount = 1;2383lastClickWnd = this;2384lastButton = button;2385lastClickX = x;2386lastClickY = y;2387}2388/*2389*Set appropriate bit of the mask on WM_MOUSE_DOWN message.2390*/2391m_mouseButtonClickAllowed |= GetButtonMK(button);2392lastTime = now;23932394BOOL causedByTouchEvent = FALSE;2395if (m_touchDownOccurred &&2396(abs(m_touchDownPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) &&2397(abs(m_touchDownPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) {2398causedByTouchEvent = TRUE;2399m_touchDownOccurred = FALSE;2400}24012402MSG msg;2403InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);24042405AwtWindow *toplevel = GetContainer();2406if (toplevel && !toplevel->IsSimpleWindow()) {2407/*2408* The frame should be focused by click in case it is2409* the active window but not the focused window. See 6886678.2410*/2411if (toplevel->GetHWnd() == ::GetActiveWindow() &&2412toplevel->GetHWnd() != AwtComponent::GetFocusedWindow())2413{2414toplevel->AwtSetActiveWindow();2415}2416}24172418SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,2419GetJavaModifiers(), clickCount, JNI_FALSE,2420GetButton(button), &msg, causedByTouchEvent);2421/*2422* NOTE: this call is intentionally placed after all other code,2423* since AwtComponent::WmMouseDown() assumes that the cached id of the2424* latest retrieved message (see lastMessage in awt_Component.cpp)2425* matches the mouse message being processed.2426* SetCapture() sends WM_CAPTURECHANGED and breaks that2427* assumption.2428*/2429SetDragCapture(flags);24302431AwtWindow * owner = (AwtWindow*)GetComponent(GetTopLevelParentForWindow(GetHWnd()));2432if (AwtWindow::GetGrabbedWindow() != NULL && owner != NULL) {2433if (!AwtWindow::GetGrabbedWindow()->IsOneOfOwnersOf(owner)) {2434AwtWindow::GetGrabbedWindow()->Ungrab();2435}2436}2437return mrConsume;2438}24392440MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button)2441{2442BOOL causedByTouchEvent = FALSE;2443if (m_touchUpOccurred &&2444(abs(m_touchUpPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) &&2445(abs(m_touchUpPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) {2446causedByTouchEvent = TRUE;2447m_touchUpOccurred = FALSE;2448}24492450MSG msg;2451InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);24522453SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, ::JVM_CurrentTimeMillis(NULL, 0),2454x, y, GetJavaModifiers(), clickCount,2455(GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ?2456TRUE : FALSE), GetButton(button), &msg, causedByTouchEvent);2457/*2458* If no movement, then report a click following the button release.2459* When WM_MOUSEUP comes to a window without previous WM_MOUSEDOWN,2460* spurous MOUSE_CLICK is about to happen. See 6430553.2461*/2462if ((m_mouseButtonClickAllowed & GetButtonMK(button)) != 0) { //CLICK allowed2463SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED,2464::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(),2465clickCount, JNI_FALSE, GetButton(button));2466}2467// Exclude button from allowed to generate CLICK messages2468m_mouseButtonClickAllowed &= ~GetButtonMK(button);24692470if ((flags & ALL_MK_BUTTONS) == 0) {2471// only update if all buttons have been released2472AwtCursor::UpdateCursor(this);2473}2474/*2475* NOTE: this call is intentionally placed after all other code,2476* since AwtComponent::WmMouseUp() assumes that the cached id of the2477* latest retrieved message (see lastMessage in awt_Component.cpp)2478* matches the mouse message being processed.2479* ReleaseCapture() sends WM_CAPTURECHANGED and breaks that2480* assumption.2481*/2482ReleaseDragCapture(flags);24832484return mrConsume;2485}24862487MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y)2488{2489static AwtComponent* lastComp = NULL;2490static int lastX = 0;2491static int lastY = 0;24922493/*2494* Only report mouse move and drag events if a move or drag2495* actually happened -- Windows sends a WM_MOUSEMOVE in case the2496* app wants to modify the cursor.2497*/2498if (lastComp != this || x != lastX || y != lastY) {2499lastComp = this;2500lastX = x;2501lastY = y;2502BOOL extraButtonsEnabled = AwtToolkit::GetInstance().areExtraMouseButtonsEnabled();2503if (((flags & (ALL_MK_BUTTONS)) != 0) ||2504(extraButtonsEnabled && (flags & (X_BUTTONS)) != 0))2505// if (( extraButtonsEnabled && ( (flags & (ALL_MK_BUTTONS | X_BUTTONS)) != 0 )) ||2506// ( !extraButtonsEnabled && (((flags & (ALL_MK_BUTTONS)) != 0 )) && ((flags & (X_BUTTONS)) == 0) ))2507{2508// 6404008 : if Dragged event fired we shouldn't fire2509// Clicked event: m_firstDragSent set to TRUE.2510// This is a partial backout of 5039416 fix.2511MSG msg;2512InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);2513SendMouseEvent(java_awt_event_MouseEvent_MOUSE_DRAGGED, ::JVM_CurrentTimeMillis(NULL, 0), x, y,2514GetJavaModifiers(), 0, JNI_FALSE,2515java_awt_event_MouseEvent_NOBUTTON, &msg);2516//dragging means no more CLICKs until next WM_MOUSE_DOWN/WM_MOUSE_UP message sequence2517m_mouseButtonClickAllowed = 0;2518} else {2519MSG msg;2520InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);2521SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, ::JVM_CurrentTimeMillis(NULL, 0), x, y,2522GetJavaModifiers(), 0, JNI_FALSE,2523java_awt_event_MouseEvent_NOBUTTON, &msg);2524}2525}25262527return mrConsume;2528}25292530MsgRouting AwtComponent::WmMouseExit(UINT flags, int x, int y)2531{2532SendMouseEvent(java_awt_event_MouseEvent_MOUSE_EXITED, ::JVM_CurrentTimeMillis(NULL, 0), x,2533y, GetJavaModifiers(), 0, JNI_FALSE);2534sm_cursorOn = NULL;2535return mrConsume; /* Don't pass our synthetic event on! */2536}25372538MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,2539int wheelRotation, BOOL isHorizontal)2540{2541// convert coordinates to be Component-relative, not screen relative2542// for wheeling when outside the window, this works similar to2543// coordinates during a drag2544POINT eventPt;2545eventPt.x = x;2546eventPt.y = y;2547DTRACE_PRINT2(" original coords: %i,%i\n", x, y);2548::ScreenToClient(GetHWnd(), &eventPt);2549DTRACE_PRINT2(" new coords: %i,%i\n\n", eventPt.x, eventPt.y);25502551// set some defaults2552jint scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL;2553jint scrollUnits = 3;25542555BOOL result;2556UINT platformUnits;2557jint roundedWheelRotation;2558jdouble preciseWheelRotation;25592560// AWT interprets wheel rotation differently than win32, so we need to2561// decode wheel amount.2562jint modifiers = GetJavaModifiers();2563if (isHorizontal) {2564modifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK;2565m_wheelRotationAmountX += wheelRotation;2566roundedWheelRotation = m_wheelRotationAmountX / (WHEEL_DELTA);2567preciseWheelRotation = (jdouble) wheelRotation / (WHEEL_DELTA);2568result = ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0,2569&platformUnits, 0);2570} else {2571m_wheelRotationAmountY += wheelRotation;2572roundedWheelRotation = m_wheelRotationAmountY / (-1 * WHEEL_DELTA);2573preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);2574result = ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,2575&platformUnits, 0);2576}25772578MSG msg;2579InitMessage(&msg, lastMessage, MAKEWPARAM(flags, wheelRotation),2580MAKELPARAM(x, y));25812582if (result) {2583if (platformUnits == WHEEL_PAGESCROLL) {2584scrollType = java_awt_event_MouseWheelEvent_WHEEL_BLOCK_SCROLL;2585scrollUnits = 1;2586}2587else {2588scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL;2589scrollUnits = platformUnits;2590}2591}25922593DTRACE_PRINTLN("calling SendMouseWheelEvent");25942595SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, ::JVM_CurrentTimeMillis(NULL, 0),2596eventPt.x, eventPt.y, modifiers, 0, 0, scrollType,2597scrollUnits, roundedWheelRotation, preciseWheelRotation, &msg);25982599m_wheelRotationAmountX %= WHEEL_DELTA;2600m_wheelRotationAmountY %= WHEEL_DELTA;2601// this message could be propagated up to the parent chain2602// by the mouse message post processors2603return mrConsume;2604}26052606jint AwtComponent::GetKeyLocation(UINT wkey, UINT flags) {2607// Rector+Newcomer page 4132608// The extended keys are the Alt and Control on the right of2609// the space bar, the non-Numpad arrow keys, the non-Numpad2610// Insert, PageUp, etc. keys, and the Numpad Divide and Enter keys.2611// Note that neither Shift key is extended.2612// Although not listed in Rector+Newcomer, both Windows keys2613// (91 and 92) are extended keys, the Context Menu key2614// (property key or application key - 93) is extended,2615// and so is the NumLock key.26162617// wkey is the wParam, flags is the HIWORD of the lParam26182619// "Extended" bit is 24th in lParam, so it's 8th in flags = HIWORD(lParam)2620BOOL extended = ((1<<8) & flags);26212622if (IsNumPadKey(wkey, extended)) {2623return java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD;2624}26252626switch (wkey) {2627case VK_SHIFT:2628return AwtComponent::GetShiftKeyLocation(wkey, flags);2629case VK_CONTROL: // fall through2630case VK_MENU:2631if (extended) {2632return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;2633} else {2634return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;2635}2636case VK_LWIN:2637return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;2638case VK_RWIN:2639return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;2640default:2641break;2642}26432644// REMIND: if we add keycodes for the windows keys, we'll have to2645// include left/right discrimination code for them.26462647return java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;2648}26492650jint AwtComponent::GetShiftKeyLocation(UINT vkey, UINT flags)2651{2652// init scancodes to safe values2653UINT leftShiftScancode = 0;2654UINT rightShiftScancode = 0;26552656// First 8 bits of flags is the scancode2657UINT keyScanCode = flags & 0xFF;26582659DTRACE_PRINTLN3(2660"AwtComponent::GetShiftKeyLocation vkey = %d = 0x%x scan = %d",2661vkey, vkey, keyScanCode);26622663leftShiftScancode = ::MapVirtualKey(VK_LSHIFT, 0);2664rightShiftScancode = ::MapVirtualKey(VK_RSHIFT, 0);26652666if (keyScanCode == leftShiftScancode) {2667return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;2668}2669if (keyScanCode == rightShiftScancode) {2670return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;2671}26722673DASSERT(false);2674// Note: the above should not fail on NT (or 2000)26752676// default value2677return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;2678}26792680/* Returns Java ActionEvent modifieres.2681* When creating ActionEvent, modifiers provided by ActionEvent2682* class should be set.2683*/2684jint2685AwtComponent::GetActionModifiers()2686{2687jint modifiers = GetJavaModifiers();26882689if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) {2690modifiers |= java_awt_event_ActionEvent_CTRL_MASK;2691}2692if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) {2693modifiers |= java_awt_event_ActionEvent_SHIFT_MASK;2694}2695if (modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) {2696modifiers |= java_awt_event_ActionEvent_ALT_MASK;2697}2698return modifiers;2699}27002701/* Returns Java extended InputEvent modifieres.2702* Since ::GetKeyState returns current state and Java modifiers represent2703* state before event, modifier on changed key are inverted.2704*/2705jint2706AwtComponent::GetJavaModifiers()2707{2708jint modifiers = 0;27092710if (HIBYTE(::GetKeyState(VK_CONTROL)) != 0) {2711modifiers |= java_awt_event_InputEvent_CTRL_DOWN_MASK;2712}2713if (HIBYTE(::GetKeyState(VK_SHIFT)) != 0) {2714modifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK;2715}2716if (HIBYTE(::GetKeyState(VK_MENU)) != 0) {2717modifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK;2718}2719if (HIBYTE(::GetKeyState(VK_RMENU)) != 0) {2720modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK;2721}2722if (HIBYTE(::GetKeyState(VK_MBUTTON)) != 0) {2723modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;2724}2725if (HIBYTE(::GetKeyState(VK_RBUTTON)) != 0) {2726modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK;2727}2728if (HIBYTE(::GetKeyState(VK_LBUTTON)) != 0) {2729modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK;2730}27312732if (HIBYTE(::GetKeyState(VK_XBUTTON1)) != 0) {2733modifiers |= masks[3];2734}2735if (HIBYTE(::GetKeyState(VK_XBUTTON2)) != 0) {2736modifiers |= masks[4];2737}2738return modifiers;2739}27402741jint2742AwtComponent::GetButton(int mouseButton)2743{2744/* Mouse buttons are already set correctly for left/right handedness */2745switch(mouseButton) {2746case LEFT_BUTTON:2747return java_awt_event_MouseEvent_BUTTON1;2748case MIDDLE_BUTTON:2749return java_awt_event_MouseEvent_BUTTON2;2750case RIGHT_BUTTON:2751return java_awt_event_MouseEvent_BUTTON3;2752case X1_BUTTON: //16 :2753//just assign 4 and 5 numbers because MouseEvent class doesn't contain const identifier for them now2754return 4;2755case X2_BUTTON: //322756return 5;2757}2758return java_awt_event_MouseEvent_NOBUTTON;2759}27602761UINT2762AwtComponent::GetButtonMK(int mouseButton)2763{2764switch(mouseButton) {2765case LEFT_BUTTON:2766return MK_LBUTTON;2767case MIDDLE_BUTTON:2768return MK_MBUTTON;2769case RIGHT_BUTTON:2770return MK_RBUTTON;2771case X1_BUTTON:2772return MK_XBUTTON1;2773case X2_BUTTON:2774return MK_XBUTTON2;2775}2776return 0;2777}27782779// FIXME: Keyboard related stuff has grown so big and hairy that we2780// really need to move it into a class of its own. And, since2781// keyboard is a shared resource, AwtComponent is a bad place for it.27822783// These constants are defined in the Japanese version of VC++5.0,2784// but not the US version2785#ifndef VK_CONVERT2786#define VK_KANA 0x152787#define VK_KANJI 0x192788#define VK_CONVERT 0x1C2789#define VK_NONCONVERT 0x1D2790#endif27912792#ifndef VK_XBUTTON12793#define VK_XBUTTON1 0x052794#endif27952796#ifndef VK_XBUTTON22797#define VK_XBUTTON2 0x062798#endif27992800typedef struct {2801UINT javaKey;2802UINT windowsKey;2803} KeyMapEntry;28042805// Static table, arranged more or less spatially.2806KeyMapEntry keyMapTable[] = {2807// Modifier keys2808{java_awt_event_KeyEvent_VK_CAPS_LOCK, VK_CAPITAL},2809{java_awt_event_KeyEvent_VK_SHIFT, VK_SHIFT},2810{java_awt_event_KeyEvent_VK_CONTROL, VK_CONTROL},2811{java_awt_event_KeyEvent_VK_ALT, VK_MENU},2812{java_awt_event_KeyEvent_VK_ALT_GRAPH, VK_RMENU},2813{java_awt_event_KeyEvent_VK_NUM_LOCK, VK_NUMLOCK},28142815// Miscellaneous Windows keys2816{java_awt_event_KeyEvent_VK_WINDOWS, VK_LWIN},2817{java_awt_event_KeyEvent_VK_WINDOWS, VK_RWIN},2818{java_awt_event_KeyEvent_VK_CONTEXT_MENU, VK_APPS},28192820// Alphabet2821{java_awt_event_KeyEvent_VK_A, 'A'},2822{java_awt_event_KeyEvent_VK_B, 'B'},2823{java_awt_event_KeyEvent_VK_C, 'C'},2824{java_awt_event_KeyEvent_VK_D, 'D'},2825{java_awt_event_KeyEvent_VK_E, 'E'},2826{java_awt_event_KeyEvent_VK_F, 'F'},2827{java_awt_event_KeyEvent_VK_G, 'G'},2828{java_awt_event_KeyEvent_VK_H, 'H'},2829{java_awt_event_KeyEvent_VK_I, 'I'},2830{java_awt_event_KeyEvent_VK_J, 'J'},2831{java_awt_event_KeyEvent_VK_K, 'K'},2832{java_awt_event_KeyEvent_VK_L, 'L'},2833{java_awt_event_KeyEvent_VK_M, 'M'},2834{java_awt_event_KeyEvent_VK_N, 'N'},2835{java_awt_event_KeyEvent_VK_O, 'O'},2836{java_awt_event_KeyEvent_VK_P, 'P'},2837{java_awt_event_KeyEvent_VK_Q, 'Q'},2838{java_awt_event_KeyEvent_VK_R, 'R'},2839{java_awt_event_KeyEvent_VK_S, 'S'},2840{java_awt_event_KeyEvent_VK_T, 'T'},2841{java_awt_event_KeyEvent_VK_U, 'U'},2842{java_awt_event_KeyEvent_VK_V, 'V'},2843{java_awt_event_KeyEvent_VK_W, 'W'},2844{java_awt_event_KeyEvent_VK_X, 'X'},2845{java_awt_event_KeyEvent_VK_Y, 'Y'},2846{java_awt_event_KeyEvent_VK_Z, 'Z'},28472848// Standard numeric row2849{java_awt_event_KeyEvent_VK_0, '0'},2850{java_awt_event_KeyEvent_VK_1, '1'},2851{java_awt_event_KeyEvent_VK_2, '2'},2852{java_awt_event_KeyEvent_VK_3, '3'},2853{java_awt_event_KeyEvent_VK_4, '4'},2854{java_awt_event_KeyEvent_VK_5, '5'},2855{java_awt_event_KeyEvent_VK_6, '6'},2856{java_awt_event_KeyEvent_VK_7, '7'},2857{java_awt_event_KeyEvent_VK_8, '8'},2858{java_awt_event_KeyEvent_VK_9, '9'},28592860// Misc key from main block2861{java_awt_event_KeyEvent_VK_ENTER, VK_RETURN},2862{java_awt_event_KeyEvent_VK_SPACE, VK_SPACE},2863{java_awt_event_KeyEvent_VK_BACK_SPACE, VK_BACK},2864{java_awt_event_KeyEvent_VK_TAB, VK_TAB},2865{java_awt_event_KeyEvent_VK_ESCAPE, VK_ESCAPE},28662867// NumPad with NumLock off & extended block (rectangular)2868{java_awt_event_KeyEvent_VK_INSERT, VK_INSERT},2869{java_awt_event_KeyEvent_VK_DELETE, VK_DELETE},2870{java_awt_event_KeyEvent_VK_HOME, VK_HOME},2871{java_awt_event_KeyEvent_VK_END, VK_END},2872{java_awt_event_KeyEvent_VK_PAGE_UP, VK_PRIOR},2873{java_awt_event_KeyEvent_VK_PAGE_DOWN, VK_NEXT},2874{java_awt_event_KeyEvent_VK_CLEAR, VK_CLEAR}, // NumPad 528752876// NumPad with NumLock off & extended arrows block (triangular)2877{java_awt_event_KeyEvent_VK_LEFT, VK_LEFT},2878{java_awt_event_KeyEvent_VK_RIGHT, VK_RIGHT},2879{java_awt_event_KeyEvent_VK_UP, VK_UP},2880{java_awt_event_KeyEvent_VK_DOWN, VK_DOWN},28812882// NumPad with NumLock on: numbers2883{java_awt_event_KeyEvent_VK_NUMPAD0, VK_NUMPAD0},2884{java_awt_event_KeyEvent_VK_NUMPAD1, VK_NUMPAD1},2885{java_awt_event_KeyEvent_VK_NUMPAD2, VK_NUMPAD2},2886{java_awt_event_KeyEvent_VK_NUMPAD3, VK_NUMPAD3},2887{java_awt_event_KeyEvent_VK_NUMPAD4, VK_NUMPAD4},2888{java_awt_event_KeyEvent_VK_NUMPAD5, VK_NUMPAD5},2889{java_awt_event_KeyEvent_VK_NUMPAD6, VK_NUMPAD6},2890{java_awt_event_KeyEvent_VK_NUMPAD7, VK_NUMPAD7},2891{java_awt_event_KeyEvent_VK_NUMPAD8, VK_NUMPAD8},2892{java_awt_event_KeyEvent_VK_NUMPAD9, VK_NUMPAD9},28932894// NumPad with NumLock on2895{java_awt_event_KeyEvent_VK_MULTIPLY, VK_MULTIPLY},2896{java_awt_event_KeyEvent_VK_ADD, VK_ADD},2897{java_awt_event_KeyEvent_VK_SEPARATOR, VK_SEPARATOR},2898{java_awt_event_KeyEvent_VK_SUBTRACT, VK_SUBTRACT},2899{java_awt_event_KeyEvent_VK_DECIMAL, VK_DECIMAL},2900{java_awt_event_KeyEvent_VK_DIVIDE, VK_DIVIDE},29012902// Functional keys2903{java_awt_event_KeyEvent_VK_F1, VK_F1},2904{java_awt_event_KeyEvent_VK_F2, VK_F2},2905{java_awt_event_KeyEvent_VK_F3, VK_F3},2906{java_awt_event_KeyEvent_VK_F4, VK_F4},2907{java_awt_event_KeyEvent_VK_F5, VK_F5},2908{java_awt_event_KeyEvent_VK_F6, VK_F6},2909{java_awt_event_KeyEvent_VK_F7, VK_F7},2910{java_awt_event_KeyEvent_VK_F8, VK_F8},2911{java_awt_event_KeyEvent_VK_F9, VK_F9},2912{java_awt_event_KeyEvent_VK_F10, VK_F10},2913{java_awt_event_KeyEvent_VK_F11, VK_F11},2914{java_awt_event_KeyEvent_VK_F12, VK_F12},2915{java_awt_event_KeyEvent_VK_F13, VK_F13},2916{java_awt_event_KeyEvent_VK_F14, VK_F14},2917{java_awt_event_KeyEvent_VK_F15, VK_F15},2918{java_awt_event_KeyEvent_VK_F16, VK_F16},2919{java_awt_event_KeyEvent_VK_F17, VK_F17},2920{java_awt_event_KeyEvent_VK_F18, VK_F18},2921{java_awt_event_KeyEvent_VK_F19, VK_F19},2922{java_awt_event_KeyEvent_VK_F20, VK_F20},2923{java_awt_event_KeyEvent_VK_F21, VK_F21},2924{java_awt_event_KeyEvent_VK_F22, VK_F22},2925{java_awt_event_KeyEvent_VK_F23, VK_F23},2926{java_awt_event_KeyEvent_VK_F24, VK_F24},29272928{java_awt_event_KeyEvent_VK_PRINTSCREEN, VK_SNAPSHOT},2929{java_awt_event_KeyEvent_VK_SCROLL_LOCK, VK_SCROLL},2930{java_awt_event_KeyEvent_VK_PAUSE, VK_PAUSE},2931{java_awt_event_KeyEvent_VK_CANCEL, VK_CANCEL},2932{java_awt_event_KeyEvent_VK_HELP, VK_HELP},29332934// Japanese2935{java_awt_event_KeyEvent_VK_CONVERT, VK_CONVERT},2936{java_awt_event_KeyEvent_VK_NONCONVERT, VK_NONCONVERT},2937{java_awt_event_KeyEvent_VK_INPUT_METHOD_ON_OFF, VK_KANJI},2938{java_awt_event_KeyEvent_VK_ALPHANUMERIC, VK_DBE_ALPHANUMERIC},2939{java_awt_event_KeyEvent_VK_KATAKANA, VK_DBE_KATAKANA},2940{java_awt_event_KeyEvent_VK_HIRAGANA, VK_DBE_HIRAGANA},2941{java_awt_event_KeyEvent_VK_FULL_WIDTH, VK_DBE_DBCSCHAR},2942{java_awt_event_KeyEvent_VK_HALF_WIDTH, VK_DBE_SBCSCHAR},2943{java_awt_event_KeyEvent_VK_ROMAN_CHARACTERS, VK_DBE_ROMAN},29442945{java_awt_event_KeyEvent_VK_UNDEFINED, 0}2946};294729482949// Dynamic mapping table for OEM VK codes. This table is refilled2950// by BuildDynamicKeyMapTable when keyboard layout is switched.2951// (see NT4 DDK src/input/inc/vkoem.h for OEM VK_ values).2952struct DynamicKeyMapEntry {2953UINT windowsKey; // OEM VK codes known in advance2954UINT javaKey; // depends on input langauge (kbd layout)2955};29562957static DynamicKeyMapEntry dynamicKeyMapTable[] = {2958{0x00BA, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_12959{0x00BB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PLUS2960{0x00BC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_COMMA2961{0x00BD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_MINUS2962{0x00BE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PERIOD2963{0x00BF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_22964{0x00C0, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_32965{0x00DB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_42966{0x00DC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_52967{0x00DD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_62968{0x00DE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_72969{0x00DF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_82970{0x00E2, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_1022971{0, 0}2972};2973297429752976// Auxiliary tables used to fill the above dynamic table. We first2977// find the character for the OEM VK code using ::MapVirtualKey and2978// then go through these auxiliary tables to map it to Java VK code.29792980struct CharToVKEntry {2981WCHAR c;2982UINT javaKey;2983};29842985static const CharToVKEntry charToVKTable[] = {2986{L'!', java_awt_event_KeyEvent_VK_EXCLAMATION_MARK},2987{L'"', java_awt_event_KeyEvent_VK_QUOTEDBL},2988{L'#', java_awt_event_KeyEvent_VK_NUMBER_SIGN},2989{L'$', java_awt_event_KeyEvent_VK_DOLLAR},2990{L'&', java_awt_event_KeyEvent_VK_AMPERSAND},2991{L'\'', java_awt_event_KeyEvent_VK_QUOTE},2992{L'(', java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS},2993{L')', java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS},2994{L'*', java_awt_event_KeyEvent_VK_ASTERISK},2995{L'+', java_awt_event_KeyEvent_VK_PLUS},2996{L',', java_awt_event_KeyEvent_VK_COMMA},2997{L'-', java_awt_event_KeyEvent_VK_MINUS},2998{L'.', java_awt_event_KeyEvent_VK_PERIOD},2999{L'/', java_awt_event_KeyEvent_VK_SLASH},3000{L':', java_awt_event_KeyEvent_VK_COLON},3001{L';', java_awt_event_KeyEvent_VK_SEMICOLON},3002{L'<', java_awt_event_KeyEvent_VK_LESS},3003{L'=', java_awt_event_KeyEvent_VK_EQUALS},3004{L'>', java_awt_event_KeyEvent_VK_GREATER},3005{L'@', java_awt_event_KeyEvent_VK_AT},3006{L'[', java_awt_event_KeyEvent_VK_OPEN_BRACKET},3007{L'\\', java_awt_event_KeyEvent_VK_BACK_SLASH},3008{L']', java_awt_event_KeyEvent_VK_CLOSE_BRACKET},3009{L'^', java_awt_event_KeyEvent_VK_CIRCUMFLEX},3010{L'_', java_awt_event_KeyEvent_VK_UNDERSCORE},3011{L'`', java_awt_event_KeyEvent_VK_BACK_QUOTE},3012{L'{', java_awt_event_KeyEvent_VK_BRACELEFT},3013{L'}', java_awt_event_KeyEvent_VK_BRACERIGHT},3014{0x00A1, java_awt_event_KeyEvent_VK_INVERTED_EXCLAMATION_MARK},3015{0x20A0, java_awt_event_KeyEvent_VK_EURO_SIGN}, // ????3016{0,0}3017};30183019// For dead accents some layouts return ASCII punctuation, while some3020// return spacing accent chars, so both should be listed. NB: MS docs3021// say that conversion routings return spacing accent character, not3022// combining.3023static const CharToVKEntry charToDeadVKTable[] = {3024{L'`', java_awt_event_KeyEvent_VK_DEAD_GRAVE},3025{L'\'', java_awt_event_KeyEvent_VK_DEAD_ACUTE},3026{0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},3027{L'^', java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},3028{L'~', java_awt_event_KeyEvent_VK_DEAD_TILDE},3029{0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE},3030{0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON},3031{0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE},3032{0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT},3033{L'"', java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},3034{0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},3035{0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING},3036{0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE},3037{0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON}, // aka hacek3038{L',', java_awt_event_KeyEvent_VK_DEAD_CEDILLA},3039{0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA},3040{0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK},3041{0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA}, // ASCII ???3042{0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND},3043{0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND},3044{0x0004, java_awt_event_KeyEvent_VK_COMPOSE},3045{0,0}3046};30473048// The full map of the current keyboard state including3049// windows virtual key, scancode, java virtual key, and unicode3050// for this key sans modifiers.3051// All but first element may be 0.3052// XXX in the update releases this is an addition to the unchanged existing code3053struct DynPrimaryKeymapEntry {3054UINT wkey;3055UINT scancode;3056UINT jkey;3057WCHAR unicode;3058};30593060static DynPrimaryKeymapEntry dynPrimaryKeymap[256];30613062void3063AwtComponent::InitDynamicKeyMapTable()3064{3065static BOOL kbdinited = FALSE;30663067if (!kbdinited) {3068AwtComponent::BuildDynamicKeyMapTable();3069// We cannot build it here since JNI is not available yet:3070//AwtComponent::BuildPrimaryDynamicTable();3071kbdinited = TRUE;3072}3073}30743075void3076AwtComponent::BuildDynamicKeyMapTable()3077{3078HKL hkl = GetKeyboardLayout();30793080DTRACE_PRINTLN2("Building dynamic VK mapping tables: HKL = %08X (CP%d)",3081hkl, AwtComponent::GetCodePage());30823083// Will need this to reset layout after dead keys.3084UINT spaceScanCode = ::MapVirtualKeyEx(VK_SPACE, 0, hkl);30853086// Entries in dynamic table that maps between Java VK and Windows3087// VK are built in three steps:3088// 1. Map windows VK to ANSI character (cannot map to unicode3089// directly, since ::ToUnicode is not implemented on win9x)3090// 2. Convert ANSI char to Unicode char3091// 3. Map Unicode char to Java VK via two auxilary tables.30923093for (DynamicKeyMapEntry *dynamic = dynamicKeyMapTable;3094dynamic->windowsKey != 0;3095++dynamic)3096{3097// Defaults to VK_UNDEFINED3098dynamic->javaKey = java_awt_event_KeyEvent_VK_UNDEFINED;30993100BYTE kbdState[AwtToolkit::KB_STATE_SIZE];3101AwtToolkit::GetKeyboardState(kbdState);31023103kbdState[dynamic->windowsKey] |= 0x80; // Press the key.31043105// Unpress modifiers, since they are most likely pressed as3106// part of the keyboard switching shortcut.3107kbdState[VK_CONTROL] &= ~0x80;3108kbdState[VK_SHIFT] &= ~0x80;3109kbdState[VK_MENU] &= ~0x80;31103111char cbuf[2] = { '\0', '\0'};3112UINT scancode = ::MapVirtualKeyEx(dynamic->windowsKey, 0, hkl);3113int nchars = ::ToAsciiEx(dynamic->windowsKey, scancode, kbdState,3114(WORD*)cbuf, 0, hkl);31153116// Auxiliary table used to map Unicode character to Java VK.3117// Will assign a different table for dead keys (below).3118const CharToVKEntry *charMap = charToVKTable;31193120if (nchars < 0) { // Dead key3121// Use a different table for dead chars since different layouts3122// return different characters for the same dead key.3123charMap = charToDeadVKTable;31243125// We also need to reset layout so that next translation3126// is unaffected by the dead status. We do this by3127// translating <SPACE> key.3128kbdState[dynamic->windowsKey] &= ~0x80;3129kbdState[VK_SPACE] |= 0x80;31303131char junkbuf[2] = { '\0', '\0'};3132::ToAsciiEx(VK_SPACE, spaceScanCode, kbdState,3133(WORD*)junkbuf, 0, hkl);3134}31353136#ifdef DEBUG3137if (nchars == 0) {3138DTRACE_PRINTLN1("VK 0x%02X -> cannot convert to ANSI char",3139dynamic->windowsKey);3140continue;3141}3142else if (nchars > 1) { // can't happen, see reset code below3143DTRACE_PRINTLN3("VK 0x%02X -> converted to <0x%02X,0x%02X>",3144dynamic->windowsKey,3145(UCHAR)cbuf[0], (UCHAR)cbuf[1]);3146continue;3147}3148#endif31493150WCHAR ucbuf[2] = { L'\0', L'\0' };3151int nconverted = ::MultiByteToWideChar(AwtComponent::GetCodePage(), 0,3152cbuf, 1, ucbuf, 2);3153#ifdef DEBUG3154if (nconverted < 0) {3155DTRACE_PRINTLN3("VK 0x%02X -> ANSI 0x%02X -> MultiByteToWideChar failed (0x%X)",3156dynamic->windowsKey, (UCHAR)cbuf[0],3157::GetLastError());3158continue;3159}3160#endif31613162WCHAR uc = ucbuf[0];3163for (const CharToVKEntry *map = charMap; map->c != 0; ++map) {3164if (uc == map->c) {3165dynamic->javaKey = map->javaKey;3166break;3167}3168}31693170DTRACE_PRINTLN4("VK 0x%02X -> ANSI 0x%02X -> U+%04X -> Java VK 0x%X",3171dynamic->windowsKey, (UCHAR)cbuf[0], (UINT)ucbuf[0],3172dynamic->javaKey);3173} // for each VK_OEM_*3174}317531763177static BOOL isKanaLockAvailable()3178{3179// This method is to determine whether the Kana Lock feature is3180// available on the attached keyboard. Kana Lock feature does not3181// necessarily require that the real KANA keytop is available on3182// keyboard, so using MapVirtualKey(VK_KANA) is not sufficient for testing.3183// Instead of that we regard it as Japanese keyboard (w/ Kana Lock) if :-3184//3185// - the keyboard layout is Japanese (VK_KANA has the same value as VK_HANGUL)3186// - the keyboard is Japanese keyboard (keyboard type == 7).3187return (LOWORD(GetKeyboardLayout(0)) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT))3188&& (GetKeyboardType(0) == 7);3189}31903191void AwtComponent::JavaKeyToWindowsKey(UINT javaKey,3192UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey)3193{3194// Handle the few cases where a Java VK code corresponds to a Windows3195// key/modifier combination or applies only to specific keyboard layouts3196switch (javaKey) {3197case java_awt_event_KeyEvent_VK_ALL_CANDIDATES:3198*windowsKey = VK_CONVERT;3199*modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK;3200return;3201case java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE:3202*windowsKey = VK_CONVERT;3203*modifiers = java_awt_event_InputEvent_SHIFT_DOWN_MASK;3204return;3205case java_awt_event_KeyEvent_VK_CODE_INPUT:3206*windowsKey = VK_DBE_ALPHANUMERIC;3207*modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK;3208return;3209case java_awt_event_KeyEvent_VK_KANA_LOCK:3210if (isKanaLockAvailable()) {3211*windowsKey = VK_KANA;3212*modifiers = java_awt_event_InputEvent_CTRL_DOWN_MASK;3213return;3214}3215}32163217// for the general case, use a bi-directional table3218for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {3219if (keyMapTable[i].javaKey == javaKey) {3220*windowsKey = keyMapTable[i].windowsKey;3221*modifiers = 0;3222return;3223}3224}32253226// Bug 47666553227// Two Windows keys could map to the same Java key, so3228// give preference to the originalWindowsKey if it is3229// specified (not IGNORE_KEY).3230if (originalWindowsKey == IGNORE_KEY) {3231for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {3232if (dynamicKeyMapTable[j].javaKey == javaKey) {3233*windowsKey = dynamicKeyMapTable[j].windowsKey;3234*modifiers = 0;3235return;3236}3237}3238} else {3239BOOL found = false;3240for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {3241if (dynamicKeyMapTable[j].javaKey == javaKey) {3242*windowsKey = dynamicKeyMapTable[j].windowsKey;3243*modifiers = 0;3244found = true;3245if (*windowsKey == originalWindowsKey) {3246return; /* if ideal case found return, else keep looking */3247}3248}3249}3250if (found) {3251return;3252}3253}32543255*windowsKey = 0;3256*modifiers = 0;3257return;3258}32593260UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey)32613262{3263// Handle the few cases where we need to take the modifier into3264// consideration for the Java VK code or where we have to take the keyboard3265// layout into consideration so that function keys can get3266// recognized in a platform-independent way.3267switch (windowsKey) {3268case VK_CONVERT:3269if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {3270return java_awt_event_KeyEvent_VK_ALL_CANDIDATES;3271}3272if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0) {3273return java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE;3274}3275break;3276case VK_DBE_ALPHANUMERIC:3277if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {3278return java_awt_event_KeyEvent_VK_CODE_INPUT;3279}3280break;3281case VK_KANA:3282if (isKanaLockAvailable()) {3283return java_awt_event_KeyEvent_VK_KANA_LOCK;3284}3285break;3286};32873288// check dead key3289if (isDeadKey) {3290for (int i = 0; charToDeadVKTable[i].c != 0; i++) {3291if (charToDeadVKTable[i].c == character) {3292return charToDeadVKTable[i].javaKey;3293}3294}3295}32963297// for the general case, use a bi-directional table3298for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {3299if (keyMapTable[i].windowsKey == windowsKey) {3300return keyMapTable[i].javaKey;3301}3302}33033304for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {3305if (dynamicKeyMapTable[j].windowsKey == windowsKey) {3306if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) {3307return dynamicKeyMapTable[j].javaKey;3308}else{3309break;3310}3311}3312}33133314return java_awt_event_KeyEvent_VK_UNDEFINED;3315}33163317BOOL AwtComponent::IsNavigationKey(UINT wkey) {3318switch (wkey) {3319case VK_END:3320case VK_PRIOR: // PageUp3321case VK_NEXT: // PageDown3322case VK_HOME:3323case VK_LEFT:3324case VK_UP:3325case VK_RIGHT:3326case VK_DOWN:3327return TRUE;3328}3329return FALSE;3330}33313332// determine if a key is a numpad key (distinguishes the numpad3333// arrow keys from the non-numpad arrow keys, for example).3334BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended)3335{3336// Note: scancodes are the same for the numpad arrow keys and3337// the non-numpad arrow keys (also for PageUp, etc.).3338// The scancodes for the numpad divide and the non-numpad slash3339// are the same, but the wparams are different33403341DTRACE_PRINTLN3("AwtComponent::IsNumPadKey vkey = %d = 0x%x extended = %d",3342vkey, vkey, extended);33433344switch (vkey) {3345case VK_CLEAR: // numpad 5 with numlock off3346case VK_NUMPAD0:3347case VK_NUMPAD1:3348case VK_NUMPAD2:3349case VK_NUMPAD3:3350case VK_NUMPAD4:3351case VK_NUMPAD5:3352case VK_NUMPAD6:3353case VK_NUMPAD7:3354case VK_NUMPAD8:3355case VK_NUMPAD9:3356case VK_MULTIPLY:3357case VK_ADD:3358case VK_SEPARATOR: // numpad , not on US kbds3359case VK_SUBTRACT:3360case VK_DECIMAL:3361case VK_DIVIDE:3362case VK_NUMLOCK:3363return TRUE;3364break;3365case VK_END:3366case VK_PRIOR: // PageUp3367case VK_NEXT: // PageDown3368case VK_HOME:3369case VK_LEFT:3370case VK_UP:3371case VK_RIGHT:3372case VK_DOWN:3373case VK_INSERT:3374case VK_DELETE:3375// extended if non-numpad3376return (!extended);3377break;3378case VK_RETURN: // extended if on numpad3379return (extended);3380break;3381default:3382break;3383}33843385return FALSE;3386}3387static void3388resetKbdState( BYTE kstate[256]) {3389BYTE tmpState[256];3390WCHAR wc[2];3391memmove(tmpState, kstate, sizeof(kstate));3392tmpState[VK_SHIFT] = 0;3393tmpState[VK_CONTROL] = 0;3394tmpState[VK_MENU] = 0;33953396::ToUnicodeEx(VK_SPACE,::MapVirtualKey(VK_SPACE, 0), tmpState, wc, 2, 0, GetKeyboardLayout(0));3397}33983399// XXX in the update releases this is an addition to the unchanged existing code3400// After the call, a table will have a unicode associated with a windows virtual keycode3401// sans modifiers. With some further simplification, one can3402// derive java keycode from it, and anyway we will pass this unicode value3403// all the way up in a comment to a KeyEvent.3404void3405AwtComponent::BuildPrimaryDynamicTable() {3406JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);3407// XXX: how about that?3408//CriticalSection::Lock l(GetLock());3409//if (GetPeer(env) == NULL) {3410// /* event received during termination. */3411// return;3412//}34133414HKL hkl = GetKeyboardLayout();3415UINT sc = 0;3416BYTE kbdState[AwtToolkit::KB_STATE_SIZE];3417memset(kbdState, 0, sizeof (kbdState));34183419// Use JNI call to obtain java key code. We should keep a list3420// of currently available keycodes in a single place.3421static jclass extKeyCodesCls;3422if( extKeyCodesCls == NULL) {3423jclass extKeyCodesClsLocal = env->FindClass("sun/awt/ExtendedKeyCodes");3424DASSERT(extKeyCodesClsLocal);3425CHECK_NULL(extKeyCodesClsLocal);3426extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal);3427env->DeleteLocalRef(extKeyCodesClsLocal);3428}3429static jmethodID getExtendedKeyCodeForChar;3430if (getExtendedKeyCodeForChar == NULL) {3431getExtendedKeyCodeForChar =3432env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I");3433DASSERT(getExtendedKeyCodeForChar);3434CHECK_NULL(getExtendedKeyCodeForChar);3435}3436jint extJKC; //extended Java key code34373438for (UINT i = 0; i < 256; i++) {3439dynPrimaryKeymap[i].wkey = i;3440dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED;3441dynPrimaryKeymap[i].unicode = 0;34423443if ((sc = MapVirtualKey (i, 0)) == 0) {3444dynPrimaryKeymap[i].scancode = 0;3445continue;3446}3447dynPrimaryKeymap[i].scancode = sc;34483449// XXX process cases like VK_SHIFT etc.3450kbdState[i] = 0x80; // "key pressed".3451WCHAR wc[16];3452int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl);3453if (k == 1) {3454// unicode3455dynPrimaryKeymap[i].unicode = wc[0];3456if (dynPrimaryKeymap[i].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) {3457// Convert unicode to java keycode.3458//dynPrimaryKeymap[i].jkey = ((UINT)(wc[0]) + 0x01000000);3459//3460//XXX If this key in on the keypad, we should force a special value equal to3461//XXX an old java keycode: but how to say if it is a keypad key?3462//XXX We'll do it in WmKeyUp/Down.3463extJKC = env->CallStaticIntMethod(extKeyCodesCls,3464getExtendedKeyCodeForChar, (jint)(wc[0]));3465dynPrimaryKeymap[i].jkey = extJKC;3466}3467}else if (k == -1) {3468// dead key: use charToDeadVKTable3469dynPrimaryKeymap[i].unicode = wc[0];3470resetKbdState( kbdState );3471for (const CharToVKEntry *map = charToDeadVKTable; map->c != 0; ++map) {3472if (wc[0] == map->c) {3473dynPrimaryKeymap[i].jkey = map->javaKey;3474break;3475}3476}3477} else if (k == 0) {3478// reset3479resetKbdState( kbdState );3480}else {3481// k > 1: this key does generate multiple characters. Ignore it.3482// An example: Arabic Lam and Alef ligature.3483// There will be no extended keycode and thus shortcuts for this key.3484// XXX shouldn't we reset the kbd state?3485#ifdef DEBUG3486DTRACE_PRINTLN2("wkey 0x%02X (%d)", i,i);3487#endif3488}3489kbdState[i] = 0; // "key unpressed"3490}3491}3492void3493AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers)3494{3495if( wkey && wkey < 256 ) {3496if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) {3497// At the creation time,3498// dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /"3499dynPrimaryKeymap[wkey].jkey = jkeyLegacy;3500}3501if(dynPrimaryKeymap[wkey].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) {3502// E.g. it is non-unicode key3503dynPrimaryKeymap[wkey].jkey = jkeyLegacy;3504}3505}3506}35073508UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey)3509{3510static Hashtable transTable("VKEY translations");3511static Hashtable deadKeyFlagTable("Dead Key Flags");3512isDeadKey = FALSE;35133514// Try to translate using last saved translation3515if (ops == LOAD) {3516void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));3517void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));3518if (value != NULL) {3519isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));3520return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));3521}3522}35233524// If the windows key is a return, wkey will equal 13 ('\r')3525// In this case, we want to return 10 ('\n')3526// Since ToAscii would convert VK_RETURN to '\r', we need3527// to have a special case here.3528if (wkey == VK_RETURN)3529return '\n';35303531// high order bit in keyboardState indicates whether the key is down3532static const BYTE KEY_STATE_DOWN = 0x80;3533BYTE keyboardState[AwtToolkit::KB_STATE_SIZE];3534AwtToolkit::GetKeyboardState(keyboardState);35353536// apply modifiers to keyboard state if necessary3537BOOL shiftIsDown = FALSE;3538if (modifiers) {3539shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK;3540BOOL altIsDown = ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) ||3541(modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK));3542BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK;35433544if (shiftIsDown) {3545keyboardState[VK_SHIFT] |= KEY_STATE_DOWN;3546}35473548// fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715)3549// Here we try to resolve a conflict with ::ToAsciiEx's translating3550// ALT+number key combinations. [email protected]3551// yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail.3552if( IsNavigationKey(wkey) ) {3553keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;3554}35553556if (ctrlIsDown)3557{3558if (altIsDown) {3559// bugid 4215009: don't mess with AltGr == Ctrl + Alt3560keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;3561}3562else {3563// bugid 4098210: old event model doesn't have KEY_TYPED3564// events, so try to provide a meaningful character for3565// Ctrl+<key>. Take Ctrl into account only when we know3566// that Ctrl+<key> will be an ASCII control. Ignore by3567// default.3568keyboardState[VK_CONTROL] &= ~KEY_STATE_DOWN;35693570// Letters have Ctrl+<letter> counterparts. According to3571// <winuser.h> VK_A through VK_Z are the same as ASCII3572// 'A' through 'Z'.3573if (wkey >= 'A' && wkey <= 'Z') {3574keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;3575}3576else {3577// Non-letter controls 033 to 037 are:3578// ^[ (ESC), ^\ (FS), ^] (GS), ^^ (RS), and ^_ (US)35793580// Shift state bits returned by ::VkKeyScan in HIBYTE3581static const UINT _VKS_SHIFT_MASK = 0x01;3582static const UINT _VKS_CTRL_MASK = 0x02;3583static const UINT _VKS_ALT_MASK = 0x04;35843585// Check to see whether there is a meaningful translation3586TCHAR ch;3587short vk;3588for (ch = _T('\033'); ch < _T('\040'); ch++) {3589vk = ::VkKeyScan(ch);3590if (wkey == LOBYTE(vk)) {3591UINT shiftState = HIBYTE(vk);3592if ((shiftState & _VKS_CTRL_MASK) ||3593(!(shiftState & _VKS_SHIFT_MASK)3594== !shiftIsDown))3595{3596keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;3597}3598break;3599}3600}3601}3602} // ctrlIsDown && altIsDown3603} // ctrlIsDown3604} // modifiers36053606WORD wChar[2];3607int converted = 1;3608UINT ch = ::MapVirtualKeyEx(wkey, 2, GetKeyboardLayout());3609if (ch & 0x80000000) {3610// Dead key which is handled as a normal key3611isDeadKey = deadKeyActive = TRUE;3612} else if (deadKeyActive) {3613// We cannot use ::ToUnicodeEx if dead key is active because this will3614// break dead key function3615wChar[0] = shiftIsDown ? ch : tolower(ch);3616} else {3617UINT scancode = ::MapVirtualKey(wkey, 0);3618converted = ::ToUnicodeEx(wkey, scancode, keyboardState,3619wChar, 2, 0, GetKeyboardLayout());3620}36213622UINT translation;3623BOOL deadKeyFlag = (converted == 2);36243625// Dead Key3626if (converted < 0 || isDeadKey) {3627translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;3628} else3629// No translation available -- try known conversions or else punt.3630if (converted == 0) {3631if (wkey == VK_DELETE) {3632translation = '\177';3633} else3634if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {3635translation = '0' + wkey - VK_NUMPAD0;3636} else {3637translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;3638}3639} else3640// the caller expects a Unicode character.3641if (converted > 0) {3642translation = wChar[0];3643}3644if (ops == SAVE) {3645transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),3646reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));3647if (deadKeyFlag) {3648deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),3649reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag)));3650} else {3651deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));3652}3653}36543655isDeadKey = deadKeyFlag;3656return translation;3657}36583659MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,3660UINT flags, BOOL system)3661{3662// VK_PROCESSKEY is a special value which means3663// "Current IME wants to consume this KeyEvent"3664// Real key code is saved by IMM32.DLL and can be retrieved by3665// calling ImmGetVirtualKey();3666if (wkey == VK_PROCESSKEY) {3667return mrDoDefault;3668}3669MSG msg;3670InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN),3671wkey, MAKELPARAM(repCnt, flags));36723673UINT modifiers = GetJavaModifiers();3674jint keyLocation = GetKeyLocation(wkey, flags);3675BOOL isDeadKey = FALSE;3676UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey);3677UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);3678UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);367936803681SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,3682::JVM_CurrentTimeMillis(NULL, 0), jkey, character,3683modifiers, keyLocation, (jlong)wkey, &msg);36843685// bugid 4724007: Windows does not create a WM_CHAR for the Del key3686// for some reason, so we need to create the KEY_TYPED event on the3687// WM_KEYDOWN. Use null msg so the character doesn't get sent back3688// to the native window for processing (this event is synthesized3689// for Java - we don't want Windows trying to process it).3690if (jkey == java_awt_event_KeyEvent_VK_DELETE) {3691SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,3692::JVM_CurrentTimeMillis(NULL, 0),3693java_awt_event_KeyEvent_VK_UNDEFINED,3694character, modifiers,3695java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);3696}36973698return mrConsume;3699}37003701MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt,3702UINT flags, BOOL system)3703{37043705// VK_PROCESSKEY is a special value which means3706// "Current IME wants to consume this KeyEvent"3707// Real key code is saved by IMM32.DLL and can be retrieved by3708// calling ImmGetVirtualKey();3709if (wkey == VK_PROCESSKEY) {3710return mrDoDefault;3711}3712MSG msg;3713InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP),3714wkey, MAKELPARAM(repCnt, flags));37153716UINT modifiers = GetJavaModifiers();3717jint keyLocation = GetKeyLocation(wkey, flags);3718BOOL isDeadKey = FALSE;3719UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey);3720UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);3721UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);37223723SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,3724::JVM_CurrentTimeMillis(NULL, 0), jkey, character,3725modifiers, keyLocation, (jlong)wkey, &msg);3726return mrConsume;3727}37283729MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout)3730{3731// Normally we would be able to use charset and TranslateCharSetInfo3732// to get a code page that should be associated with this keyboard3733// layout change. However, there seems to be an NT 4.0 bug associated3734// with the WM_INPUTLANGCHANGE message, which makes the charset parameter3735// unreliable, especially on Asian systems. Our workaround uses the3736// keyboard layout handle instead.3737m_hkl = hKeyboardLayout;3738m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID3739m_CodePage = LangToCodePage(m_idLang);3740BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM3741BuildPrimaryDynamicTable();3742return mrConsume; // do not propagate to children3743}37443745// Convert Language ID to CodePage3746UINT AwtComponent::LangToCodePage(LANGID idLang)3747{3748TCHAR strCodePage[MAX_ACP_STR_LEN];3749// use the LANGID to create a LCID3750LCID idLocale = MAKELCID(idLang, SORT_DEFAULT);3751// get the ANSI code page associated with this locale3752if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE, strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 )3753return _ttoi(strCodePage);3754else3755return GetACP();3756}375737583759MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL system)3760{3761// We will simply create Java events here.3762WCHAR unicodeChar = character;3763MSG msg;3764InitMessage(&msg, WM_IME_CHAR, character,3765MAKELPARAM(repCnt, flags));37663767jint modifiers = GetJavaModifiers();3768SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,3769::JVM_CurrentTimeMillis(NULL, 0),3770java_awt_event_KeyEvent_VK_UNDEFINED,3771unicodeChar, modifiers,3772java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,3773&msg);3774return mrConsume;3775}37763777MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags,3778BOOL system)3779{3780deadKeyActive = FALSE;37813782// Will only get WmChar messages with DBCS if we create them for3783// an Edit class in the WmForwardChar method. These synthesized3784// DBCS chars are ok to pass on directly to the default window3785// procedure. They've already been filtered through the Java key3786// event queue. We will never get the trail byte since the edit3787// class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR,3788// PM_REMOVE). I would like to be able to pass this character off3789// via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to3790// like that.37913792// We will simply create Java events here.3793UINT message = system ? WM_SYSCHAR : WM_CHAR;37943795// The Alt modifier is reported in the 29th bit of the lParam,3796// i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)).3797bool alt_is_down = (flags & (1<<13)) != 0;37983799// Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu3800// We should not pass this particular combination to Java.38013802if (system && alt_is_down) {3803if (character == VK_SPACE) {3804return mrDoDefault;3805}3806}38073808// If this is a WM_CHAR (non-system) message, then the Alt flag3809// indicates that the character was typed using an AltGr key3810// (which Windows treats as Ctrl+Alt), so in this case we do NOT3811// pass the Ctrl and Alt modifiers to Java, but instead we3812// replace them with Java's AltGraph modifier. Note: the AltGraph3813// modifier does not exist in 1.1.x releases.3814jint modifiers = GetJavaModifiers();3815if (!system && alt_is_down) {3816// character typed with AltGraph3817modifiers &= ~(java_awt_event_InputEvent_ALT_DOWN_MASK3818| java_awt_event_InputEvent_CTRL_DOWN_MASK);3819modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK;3820}38213822WCHAR unicodeChar = character;38233824// Kludge: Combine pending single byte with this char for some Chinese IMEs3825if (m_PendingLeadByte != 0) {3826character = (m_PendingLeadByte & 0x00ff) | (character << 8);3827m_PendingLeadByte = 0;3828::MultiByteToWideChar(GetCodePage(), 0, (CHAR*)&character, 2,3829&unicodeChar, 1);3830}38313832if (unicodeChar == VK_RETURN) {3833// Enter key generates \r in windows, but \n is required in java3834unicodeChar = java_awt_event_KeyEvent_VK_ENTER;3835}3836MSG msg;3837InitMessage(&msg, message, character,3838MAKELPARAM(repCnt, flags));3839SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,3840::JVM_CurrentTimeMillis(NULL, 0),3841java_awt_event_KeyEvent_VK_UNDEFINED,3842unicodeChar, modifiers,3843java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,3844&msg);3845return mrConsume;3846}38473848MsgRouting AwtComponent::WmForwardChar(WCHAR character, LPARAM lParam,3849BOOL synthetic)3850{3851deadKeyActive = FALSE;38523853// just post WM_CHAR with unicode key value3854DefWindowProc(WM_CHAR, (WPARAM)character, lParam);3855return mrConsume;3856}38573858MsgRouting AwtComponent::WmPaste()3859{3860return mrDoDefault;3861}38623863// support IME Composition messages3864void AwtComponent::SetCompositionWindow(RECT& r)3865{3866HWND hwnd = ImmGetHWnd();3867HIMC hIMC = ImmGetContext(hwnd);3868if (hIMC == NULL) {3869return;3870}3871COMPOSITIONFORM cf = {CFS_DEFAULT, {0, 0}, {0, 0, 0, 0}};3872LOGFONT lf;3873HFONT hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);3874if (GetObject(hFont, sizeof(lf), (LPVOID)&lf) == sizeof(lf)) {3875ImmSetCompositionFont(hIMC, &lf);3876}3877ImmSetCompositionWindow(hIMC, &cf);3878ImmReleaseContext(hwnd, hIMC);3879}38803881void AwtComponent::OpenCandidateWindow(int x, int y)3882{3883UINT bits = 1;3884POINT p = {0, 0}; // upper left corner of the client area3885HWND hWnd = ImmGetHWnd();3886if (!::IsWindowVisible(hWnd)) {3887return;3888}3889HWND hTop = GetTopLevelParentForWindow(hWnd);3890::ClientToScreen(hTop, &p);3891int sx = ScaleUpAbsX(x) - p.x;3892int sy = ScaleUpAbsY(y) - p.y;3893if (!m_bitsCandType) {3894SetCandidateWindow(m_bitsCandType, sx, sy);3895return;3896}3897for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) {3898if ( m_bitsCandType & bits )3899SetCandidateWindow(iCandType, sx, sy);3900}3901}39023903void AwtComponent::SetCandidateWindow(int iCandType, int x, int y)3904{3905HWND hwnd = ImmGetHWnd();3906HIMC hIMC = ImmGetContext(hwnd);3907if (hIMC) {3908CANDIDATEFORM cf;3909cf.dwStyle = CFS_POINT;3910ImmGetCandidateWindow(hIMC, 0, &cf);3911if (x != cf.ptCurrentPos.x || y != cf.ptCurrentPos.y) {3912cf.dwIndex = iCandType;3913cf.dwStyle = CFS_POINT;3914cf.ptCurrentPos = {x, y};3915cf.rcArea = {0, 0, 0, 0};3916ImmSetCandidateWindow(hIMC, &cf);3917}3918COMPOSITIONFORM cfr;3919cfr.dwStyle = CFS_POINT;3920ImmGetCompositionWindow(hIMC, &cfr);3921if (x != cfr.ptCurrentPos.x || y != cfr.ptCurrentPos.y) {3922cfr.dwStyle = CFS_POINT;3923cfr.ptCurrentPos = {x, y};3924cfr.rcArea = {0, 0, 0, 0};3925ImmSetCompositionWindow(hIMC, &cfr);3926}3927ImmReleaseContext(hwnd, hIMC);3928}3929}39303931MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam)3932{3933// If the Windows input context is disabled, do not let Windows3934// display any UIs.3935HWND hwnd = ImmGetHWnd();3936HIMC hIMC = ImmGetContext(hwnd);3937if (hIMC == NULL) {3938*lplParam = 0;3939return mrDoDefault;3940}3941ImmReleaseContext(hwnd, hIMC);39423943if (fSet) {3944LPARAM lParam = *lplParam;3945if (!m_useNativeCompWindow) {3946// stop to draw native composing window.3947*lplParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;3948}3949}3950return mrDoDefault;3951}39523953MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType)3954{3955if (!m_useNativeCompWindow) {3956if (subMsg == IMN_OPENCANDIDATE || subMsg == IMN_CHANGECANDIDATE) {3957m_bitsCandType = bitsCandType;3958InquireCandidatePosition();3959} else if (subMsg == IMN_OPENSTATUSWINDOW ||3960subMsg == WM_IME_STARTCOMPOSITION ||3961subMsg == IMN_SETCANDIDATEPOS) {3962InquireCandidatePosition();3963}3964}3965return mrDoDefault;3966}39673968MsgRouting AwtComponent::WmImeStartComposition()3969{3970if (m_useNativeCompWindow) {3971RECT rc;3972::GetClientRect(GetHWnd(), &rc);3973SetCompositionWindow(rc);3974return mrDoDefault;3975} else3976return mrConsume;3977}39783979MsgRouting AwtComponent::WmImeEndComposition()3980{3981if (m_useNativeCompWindow) return mrDoDefault;39823983SendInputMethodEvent(3984java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED,3985NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0 );3986return mrConsume;3987}39883989MsgRouting AwtComponent::WmImeComposition(WORD wChar, LPARAM flags)3990{3991if (m_useNativeCompWindow) return mrDoDefault;39923993int* bndClauseW = NULL;3994jstring* readingClauseW = NULL;3995int* bndAttrW = NULL;3996BYTE* valAttrW = NULL;3997int cClauseW = 0;3998AwtInputTextInfor* textInfor = NULL;39994000try {4001HWND hwnd = ImmGetHWnd();4002HIMC hIMC = ImmGetContext(hwnd);4003DASSERT(hIMC!=0);40044005textInfor = new AwtInputTextInfor;4006textInfor->GetContextData(hIMC, flags);4007ImmReleaseContext(hwnd, hIMC);40084009jstring jtextString = textInfor->GetText();4010/* The conditions to send the input method event to AWT EDT are:40111. Whenever there is a composition message sent regarding whether4012the composition text is NULL or not. See details at bug 6222692.40132. When there is a committed message sent, in which case, we have to4014check whether the committed string is NULL or not. If the committed string4015is NULL, there is no need to send any input method event.4016(Minor note: 'jtextString' returned is the merged string in the case of4017partial commit.)4018*/4019if ((flags & GCS_RESULTSTR && jtextString != NULL) ||4020(flags & GCS_COMPSTR)) {4021int cursorPosW = textInfor->GetCursorPosition();4022// In order not to delete the readingClauseW in the catch clause,4023// calling GetAttributeInfor before GetClauseInfor.4024int cAttrW = textInfor->GetAttributeInfor(bndAttrW, valAttrW);4025cClauseW = textInfor->GetClauseInfor(bndClauseW, readingClauseW);40264027/* Send INPUT_METHOD_TEXT_CHANGED event to the WInputMethod which in turn sends4028the event to AWT EDT.40294030The last two paremeters are set to equal since we don't have recommendations for4031the visible position within the current composed text. See details at4032java.awt.event.InputMethodEvent.4033*/4034SendInputMethodEvent(java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED,4035jtextString,4036cClauseW, bndClauseW, readingClauseW,4037cAttrW, bndAttrW, valAttrW,4038textInfor->GetCommittedTextLength(),4039cursorPosW, cursorPosW);4040}4041} catch (...) {4042// since GetClauseInfor and GetAttributeInfor could throw exception, we have to release4043// the pointer here.4044delete [] bndClauseW;4045delete [] readingClauseW;4046delete [] bndAttrW;4047delete [] valAttrW;4048throw;4049}40504051/* Free the storage allocated. Since jtextString won't be passed from threads4052* to threads, we just use the local ref and it will be deleted within the destructor4053* of AwtInputTextInfor object.4054*/4055JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);4056if (cClauseW && readingClauseW) {4057for (int i = 0; i < cClauseW; i ++) {4058if (readingClauseW[i]) {4059env->DeleteLocalRef(readingClauseW[i]);4060}4061}4062}4063delete [] bndClauseW;4064delete [] readingClauseW;4065delete [] bndAttrW;4066delete [] valAttrW;4067delete textInfor;40684069return mrConsume;4070}40714072//4073// generate and post InputMethodEvent4074//4075void AwtComponent::SendInputMethodEvent(jint id, jstring text,4076int cClause, int* rgClauseBoundary, jstring* rgClauseReading,4077int cAttrBlock, int* rgAttrBoundary, BYTE *rgAttrValue,4078int commitedTextLength, int caretPos, int visiblePos)4079{4080JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);40814082// assumption for array type casting4083DASSERT(sizeof(int)==sizeof(jint));4084DASSERT(sizeof(BYTE)==sizeof(jbyte));40854086// caluse information4087jintArray clauseBoundary = NULL;4088jobjectArray clauseReading = NULL;4089if (cClause && rgClauseBoundary && rgClauseReading) {4090// convert clause boundary offset array to java array4091clauseBoundary = env->NewIntArray(cClause+1);4092DASSERT(clauseBoundary);4093CHECK_NULL(clauseBoundary);4094env->SetIntArrayRegion(clauseBoundary, 0, cClause+1, (jint *)rgClauseBoundary);4095DASSERT(!safe_ExceptionOccurred(env));40964097// convert clause reading string array to java array4098jclass stringCls = JNU_ClassString(env);4099DASSERT(stringCls);4100CHECK_NULL(stringCls);4101clauseReading = env->NewObjectArray(cClause, stringCls, NULL);4102DASSERT(clauseReading);4103CHECK_NULL(clauseReading);4104for (int i=0; i<cClause; i++) env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]);4105DASSERT(!safe_ExceptionOccurred(env));4106}410741084109// attrubute value definition in WInputMethod.java must be equal to that in IMM.H4110DASSERT(ATTR_INPUT==sun_awt_windows_WInputMethod_ATTR_INPUT);4111DASSERT(ATTR_TARGET_CONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_CONVERTED);4112DASSERT(ATTR_CONVERTED==sun_awt_windows_WInputMethod_ATTR_CONVERTED);4113DASSERT(ATTR_TARGET_NOTCONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_NOTCONVERTED);4114DASSERT(ATTR_INPUT_ERROR==sun_awt_windows_WInputMethod_ATTR_INPUT_ERROR);41154116// attribute information4117jintArray attrBoundary = NULL;4118jbyteArray attrValue = NULL;4119if (cAttrBlock && rgAttrBoundary && rgAttrValue) {4120// convert attribute boundary offset array to java array4121attrBoundary = env->NewIntArray(cAttrBlock+1);4122DASSERT(attrBoundary);4123CHECK_NULL(attrBoundary);4124env->SetIntArrayRegion(attrBoundary, 0, cAttrBlock+1, (jint *)rgAttrBoundary);4125DASSERT(!safe_ExceptionOccurred(env));41264127// convert attribute value byte array to java array4128attrValue = env->NewByteArray(cAttrBlock);4129DASSERT(attrValue);4130CHECK_NULL(attrValue);4131env->SetByteArrayRegion(attrValue, 0, cAttrBlock, (jbyte *)rgAttrValue);4132DASSERT(!safe_ExceptionOccurred(env));4133}413441354136// get global reference of WInputMethod class (run only once)4137static jclass wInputMethodCls = NULL;4138if (wInputMethodCls == NULL) {4139jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod");4140DASSERT(wInputMethodClsLocal);4141CHECK_NULL(wInputMethodClsLocal);4142wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal);4143env->DeleteLocalRef(wInputMethodClsLocal);4144}41454146// get method ID of sendInputMethodEvent() (run only once)4147static jmethodID sendIMEventMid = 0;4148if (sendIMEventMid == 0) {4149sendIMEventMid = env->GetMethodID(wInputMethodCls, "sendInputMethodEvent",4150"(IJLjava/lang/String;[I[Ljava/lang/String;[I[BIII)V");4151DASSERT(sendIMEventMid);4152CHECK_NULL(sendIMEventMid);4153}41544155// call m_InputMethod.sendInputMethod()4156env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, ::JVM_CurrentTimeMillis(NULL, 0),4157text, clauseBoundary, clauseReading, attrBoundary,4158attrValue, commitedTextLength, caretPos, visiblePos);4159if (safe_ExceptionOccurred(env)) env->ExceptionDescribe();4160DASSERT(!safe_ExceptionOccurred(env));41614162}4163416441654166//4167// Inquires candidate position according to the composed text4168//4169void AwtComponent::InquireCandidatePosition()4170{4171if (!::IsWindowVisible(GetHWnd())) {4172return;4173}4174JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);41754176// get global reference of WInputMethod class (run only once)4177static jclass wInputMethodCls = NULL;4178if (wInputMethodCls == NULL) {4179jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod");4180DASSERT(wInputMethodClsLocal);4181CHECK_NULL(wInputMethodClsLocal);4182wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal);4183env->DeleteLocalRef(wInputMethodClsLocal);4184}41854186// get method ID of sendInputMethodEvent() (run only once)4187static jmethodID inqCandPosMid = 0;4188if (inqCandPosMid == 0) {4189inqCandPosMid = env->GetMethodID(wInputMethodCls, "inquireCandidatePosition", "()V");4190DASSERT(!safe_ExceptionOccurred(env));4191DASSERT(inqCandPosMid);4192CHECK_NULL(inqCandPosMid);4193}41944195// call m_InputMethod.sendInputMethod()4196jobject candPos = env->CallObjectMethod(m_InputMethod, inqCandPosMid);4197DASSERT(!safe_ExceptionOccurred(env));4198}41994200HWND AwtComponent::ImmGetHWnd()4201{4202HWND proxy = GetProxyFocusOwner();4203return (proxy != NULL) ? proxy : GetHWnd();4204}42054206HIMC AwtComponent::ImmAssociateContext(HIMC himc)4207{4208return ::ImmAssociateContext(ImmGetHWnd(), himc);4209}42104211HWND AwtComponent::GetProxyFocusOwner()4212{4213AwtWindow *window = GetContainer();4214if (window != 0) {4215AwtFrame *owner = window->GetOwningFrameOrDialog();4216if (owner != 0) {4217return owner->GetProxyFocusOwner();4218} else if (!window->IsSimpleWindow()) { // isn't an owned simple window4219return ((AwtFrame*)window)->GetProxyFocusOwner();4220}4221}4222return (HWND)NULL;4223}42244225/* Redirects message to the focus proxy, if any */4226void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam,4227LPARAM lParam, LRESULT &retVal, MsgRouting &mr)4228{4229if (mr != mrConsume) {4230HWND proxy = GetProxyFocusOwner();4231if (proxy != NULL && ::IsWindowEnabled(proxy)) {4232retVal = ::DefWindowProc(proxy, message, wParam, lParam);4233mr = mrConsume;4234}4235}4236}42374238MsgRouting AwtComponent::WmCommand(UINT id, HWND hWndChild, UINT notifyCode)4239{4240/* Menu/Accelerator */4241if (hWndChild == 0) {4242AwtObject* obj = AwtToolkit::GetInstance().LookupCmdID(id);4243if (obj == NULL) {4244return mrConsume;4245}4246DASSERT(((AwtMenuItem*)obj)->GetID() == id);4247obj->DoCommand();4248return mrConsume;4249}4250/* Child id notification */4251else {4252AwtComponent* child = AwtComponent::GetComponent(hWndChild);4253if (child) {4254child->WmNotify(notifyCode);4255}4256}4257return mrDoDefault;4258}42594260MsgRouting AwtComponent::WmNotify(UINT notifyCode)4261{4262return mrDoDefault;4263}42644265MsgRouting AwtComponent::WmCompareItem(UINT ctrlId,4266COMPAREITEMSTRUCT &compareInfo,4267LRESULT &result)4268{4269AwtComponent* child = AwtComponent::GetComponent(compareInfo.hwndItem);4270if (child == this) {4271/* DoCallback("handleItemDelete", */4272}4273else if (child) {4274return child->WmCompareItem(ctrlId, compareInfo, result);4275}4276return mrConsume;4277}42784279MsgRouting AwtComponent::WmDeleteItem(UINT ctrlId,4280DELETEITEMSTRUCT &deleteInfo)4281{4282/*4283* Workaround for NT 4.0 bug -- if SetWindowPos is called on a AwtList4284* window, a WM_DELETEITEM message is sent to its parent with a window4285* handle of one of the list's child windows. The property lookup4286* succeeds, but the HWNDs don't match.4287*/4288if (deleteInfo.hwndItem == NULL) {4289return mrConsume;4290}4291AwtComponent* child = (AwtComponent *)AwtComponent::GetComponent(deleteInfo.hwndItem);42924293if (child && child->GetHWnd() != deleteInfo.hwndItem) {4294return mrConsume;4295}42964297if (child == this) {4298/*DoCallback("handleItemDelete", */4299}4300else if (child) {4301return child->WmDeleteItem(ctrlId, deleteInfo);4302}4303return mrConsume;4304}43054306MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo)4307{4308JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);43094310if (drawInfo.CtlType == ODT_MENU) {4311if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) {4312AwtMenu* menu = (AwtMenu*)(drawInfo.itemData);4313menu->DrawItem(drawInfo);4314}4315} else {4316return OwnerDrawItem(ctrlId, drawInfo);4317}4318return mrConsume;4319}43204321MsgRouting AwtComponent::WmMeasureItem(UINT ctrlId,4322MEASUREITEMSTRUCT &measureInfo)4323{4324JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);43254326if (measureInfo.CtlType == ODT_MENU) {4327if (measureInfo.itemData != 0) {4328AwtMenu* menu = (AwtMenu*)(measureInfo.itemData);4329HDC hDC = ::GetDC(GetHWnd());4330/* menu->MeasureItem(env, hDC, measureInfo); */4331menu->MeasureItem(hDC, measureInfo);4332::ReleaseDC(GetHWnd(), hDC);4333}4334} else {4335return OwnerMeasureItem(ctrlId, measureInfo);4336}4337return mrConsume;4338}43394340MsgRouting AwtComponent::OwnerDrawItem(UINT ctrlId,4341DRAWITEMSTRUCT &drawInfo)4342{4343AwtComponent* child = AwtComponent::GetComponent(drawInfo.hwndItem);4344if (child == this) {4345/* DoCallback("handleItemDelete", */4346} else if (child != NULL) {4347return child->WmDrawItem(ctrlId, drawInfo);4348}4349return mrConsume;4350}43514352MsgRouting AwtComponent::OwnerMeasureItem(UINT ctrlId,4353MEASUREITEMSTRUCT &measureInfo)4354{4355HWND hChild = ::GetDlgItem(GetHWnd(), measureInfo.CtlID);4356AwtComponent* child = AwtComponent::GetComponent(hChild);4357/*4358* If the parent cannot find the child's instance from its handle,4359* maybe the child is in its creation. So the child must be searched4360* from the list linked before the child's creation.4361*/4362if (child == NULL) {4363child = SearchChild((UINT)ctrlId);4364}43654366if (child == this) {4367/* DoCallback("handleItemDelete", */4368}4369else if (child) {4370return child->WmMeasureItem(ctrlId, measureInfo);4371}4372return mrConsume;4373}43744375/* for WmDrawItem method of Label, Button and Checkbox */4376void AwtComponent::DrawWindowText(HDC hDC, jobject font, jstring text,4377int x, int y)4378{4379int nOldBkMode = ::SetBkMode(hDC,TRANSPARENT);4380DASSERT(nOldBkMode != 0);4381AwtFont::drawMFString(hDC, font, text, x, y, GetCodePage());4382VERIFY(::SetBkMode(hDC,nOldBkMode));4383}43844385/*4386* Draw text in gray (the color being set to COLOR_GRAYTEXT) when the4387* component is disabled. Used only for label, checkbox and button in4388* OWNER_DRAW. It draws the text in emboss.4389*/4390void AwtComponent::DrawGrayText(HDC hDC, jobject font, jstring text,4391int x, int y)4392{4393::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT));4394AwtComponent::DrawWindowText(hDC, font, text, x+1, y+1);4395::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW));4396AwtComponent::DrawWindowText(hDC, font, text, x, y);4397}43984399/* for WmMeasureItem method of List and Choice */4400jstring AwtComponent::GetItemString(JNIEnv *env, jobject target, jint index)4401{4402jstring str = (jstring)JNU_CallMethodByName(env, NULL, target, "getItemImpl",4403"(I)Ljava/lang/String;",4404index).l;4405DASSERT(!safe_ExceptionOccurred(env));4406return str;4407}44084409/* for WmMeasureItem method of List and Choice */4410void AwtComponent::MeasureListItem(JNIEnv *env,4411MEASUREITEMSTRUCT &measureInfo)4412{4413if (env->EnsureLocalCapacity(1) < 0) {4414return;4415}4416jobject dimension = PreferredItemSize(env);4417DASSERT(dimension);4418measureInfo.itemWidth =4419env->GetIntField(dimension, AwtDimension::widthID);4420measureInfo.itemHeight =4421env->GetIntField(dimension, AwtDimension::heightID);4422env->DeleteLocalRef(dimension);4423}44244425/* for WmDrawItem method of List and Choice */4426void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo)4427{4428if (env->EnsureLocalCapacity(3) < 0) {4429return;4430}4431jobject peer = GetPeer(env);4432jobject target = env->GetObjectField(peer, AwtObject::targetID);44334434HDC hDC = drawInfo.hDC;4435RECT rect = drawInfo.rcItem;44364437BOOL bEnabled = isEnabled();4438BOOL unfocusableChoice = (drawInfo.itemState & ODS_COMBOBOXEDIT) && !IsFocusable();4439DWORD crBack, crText;4440if (drawInfo.itemState & ODS_SELECTED){4441/* Set background and text colors for selected item */4442crBack = ::GetSysColor (COLOR_HIGHLIGHT);4443crText = ::GetSysColor (COLOR_HIGHLIGHTTEXT);4444} else {4445/* Set background and text colors for unselected item */4446crBack = GetBackgroundColor();4447crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT);4448}4449if (unfocusableChoice) {4450//6190728. Shouldn't draw selection field (edit control) of an owner-drawn combo box.4451crBack = GetBackgroundColor();4452crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT);4453}44544455/* Fill item rectangle with background color */4456HBRUSH hbrBack = ::CreateSolidBrush (crBack);4457DASSERT(hbrBack);4458/* 6190728. Shouldn't draw any kind of rectangle around selection field4459* (edit control) of an owner-drawn combo box while unfocusable4460*/4461if (!unfocusableChoice){4462VERIFY(::FillRect (hDC, &rect, hbrBack));4463}4464VERIFY(::DeleteObject (hbrBack));44654466/* Set current background and text colors */4467::SetBkColor (hDC, crBack);4468::SetTextColor (hDC, crText);44694470/*draw string (with left margin of 1 point) */4471if ((int) (drawInfo.itemID) >= 0) {4472jobject font = GET_FONT(target, peer);4473jstring text = GetItemString(env, target, drawInfo.itemID);4474if (env->ExceptionCheck()) {4475env->DeleteLocalRef(font);4476env->DeleteLocalRef(target);4477return;4478}4479SIZE size = AwtFont::getMFStringSize(hDC, font, text);4480AwtFont::drawMFString(hDC, font, text,4481(GetRTL()) ? rect.right - size.cx - 14482: rect.left + 1,4483(rect.top + rect.bottom - size.cy) / 2,4484GetCodePage());4485env->DeleteLocalRef(font);4486env->DeleteLocalRef(text);4487}4488if ((drawInfo.itemState & ODS_FOCUS) &&4489(drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) {4490if (!unfocusableChoice){4491if(::DrawFocusRect(hDC, &rect) == 0)4492VERIFY(::GetLastError() == 0);4493}4494}4495env->DeleteLocalRef(target);4496}44974498/* for MeasureListItem method and WmDrawItem method of Checkbox */4499jint AwtComponent::GetFontHeight(JNIEnv *env)4500{4501if (env->EnsureLocalCapacity(4) < 0) {4502return NULL;4503}4504jobject self = GetPeer(env);4505jobject target = env->GetObjectField(self, AwtObject::targetID);45064507jobject font = GET_FONT(target, self);4508jobject toolkit = env->CallObjectMethod(target,4509AwtComponent::getToolkitMID);45104511DASSERT(!safe_ExceptionOccurred(env));45124513jobject fontMetrics =4514env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font);45154516DASSERT(!safe_ExceptionOccurred(env));45174518jint height = env->CallIntMethod(fontMetrics, AwtFont::getHeightMID);4519DASSERT(!safe_ExceptionOccurred(env));45204521env->DeleteLocalRef(target);4522env->DeleteLocalRef(font);4523env->DeleteLocalRef(toolkit);4524env->DeleteLocalRef(fontMetrics);45254526return height;4527}45284529// If you override WmPrint, make sure to save a copy of the DC on the GDI4530// stack to be restored in WmPrintClient. Windows mangles the DC in4531// ::DefWindowProc.4532MsgRouting AwtComponent::WmPrint(HDC hDC, LPARAM flags)4533{4534/*4535* DefWindowProc for WM_PRINT changes DC parameters, so we have4536* to restore it ourselves. Otherwise it will cause problems4537* when several components are printed to the same DC.4538*/4539int nOriginalDC = ::SaveDC(hDC);4540DASSERT(nOriginalDC != 0);45414542if (flags & PRF_NONCLIENT) {45434544VERIFY(::SaveDC(hDC));45454546DefWindowProc(WM_PRINT, (WPARAM)hDC,4547(flags & (PRF_NONCLIENT4548| PRF_CHECKVISIBLE | PRF_ERASEBKGND)));45494550VERIFY(::RestoreDC(hDC, -1));45514552// Special case for components with a sunken border. Windows does not4553// print the border correctly on PCL printers, so we have to do it ourselves.4554if (GetStyleEx() & WS_EX_CLIENTEDGE) {4555RECT r;4556VERIFY(::GetWindowRect(GetHWnd(), &r));4557VERIFY(::OffsetRect(&r, -r.left, -r.top));4558VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT));4559}4560}45614562if (flags & PRF_CLIENT) {45634564/*4565* Special case for components with a sunken border.4566* Windows prints a client area without offset to a border width.4567* We will first print the non-client area with the original offset,4568* then the client area with a corrected offset.4569*/4570if (GetStyleEx() & WS_EX_CLIENTEDGE) {45714572int nEdgeWidth = ::GetSystemMetrics(SM_CXEDGE);4573int nEdgeHeight = ::GetSystemMetrics(SM_CYEDGE);45744575VERIFY(::OffsetWindowOrgEx(hDC, -nEdgeWidth, -nEdgeHeight, NULL));45764577// Save a copy of the DC for WmPrintClient4578VERIFY(::SaveDC(hDC));45794580DefWindowProc(WM_PRINT, (WPARAM) hDC,4581(flags & (PRF_CLIENT4582| PRF_CHECKVISIBLE | PRF_ERASEBKGND)));45834584VERIFY(::OffsetWindowOrgEx(hDC, nEdgeWidth, nEdgeHeight, NULL));45854586} else {45874588// Save a copy of the DC for WmPrintClient4589VERIFY(::SaveDC(hDC));4590DefWindowProc(WM_PRINT, (WPARAM) hDC,4591(flags & (PRF_CLIENT4592| PRF_CHECKVISIBLE | PRF_ERASEBKGND)));4593}4594}45954596if (flags & (PRF_CHILDREN | PRF_OWNED)) {4597DefWindowProc(WM_PRINT, (WPARAM) hDC,4598(flags & ~PRF_CLIENT & ~PRF_NONCLIENT));4599}46004601VERIFY(::RestoreDC(hDC, nOriginalDC));46024603return mrConsume;4604}46054606// If you override WmPrintClient, make sure to obtain a valid copy of4607// the DC from the GDI stack. The copy of the DC should have been placed4608// there by WmPrint. Windows mangles the DC in ::DefWindowProc.4609MsgRouting AwtComponent::WmPrintClient(HDC hDC, LPARAM)4610{4611// obtain valid DC from GDI stack4612::RestoreDC(hDC, -1);46134614return mrDoDefault;4615}46164617MsgRouting AwtComponent::WmNcCalcSize(BOOL fCalcValidRects,4618LPNCCALCSIZE_PARAMS lpncsp,4619LRESULT &retVal)4620{4621return mrDoDefault;4622}46234624MsgRouting AwtComponent::WmNcPaint(HRGN hrgn)4625{4626return mrDoDefault;4627}46284629MsgRouting AwtComponent::WmNcHitTest(UINT x, UINT y, LRESULT &retVal)4630{4631return mrDoDefault;4632}46334634/**4635* WmQueryNewPalette is called whenever our component is coming to4636* the foreground; this gives us an opportunity to install our4637* custom palette. If this install actually changes entries in4638* the system palette, then we get a further call to WmPaletteChanged4639* (but note that we only need to realize our palette once).4640*/4641MsgRouting AwtComponent::WmQueryNewPalette(LRESULT &retVal)4642{4643int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());4644m_QueryNewPaletteCalled = TRUE;4645HDC hDC = ::GetDC(GetHWnd());4646DASSERT(hDC);4647AwtWin32GraphicsDevice::SelectPalette(hDC, screen);4648AwtWin32GraphicsDevice::RealizePalette(hDC, screen);4649::ReleaseDC(GetHWnd(), hDC);4650// We must realize the palettes of all of our DC's4651// There is sometimes a problem where the realization of4652// our temporary hDC here does not actually do what4653// we want. Not clear why, but presumably fallout from4654// our use of several simultaneous hDC's.4655activeDCList.RealizePalettes(screen);4656// Do not invalidate here; if the palette4657// has not changed we will get an extra repaint4658retVal = TRUE;46594660return mrDoDefault;4661}46624663/**4664* We should not need to track this event since we handle our4665* palette management effectively in the WmQueryNewPalette and4666* WmPaletteChanged methods. However, there seems to be a bug4667* on some win32 systems (e.g., NT4) whereby the palette4668* immediately after a displayChange is not yet updated to its4669* final post-display-change values (hence we adjust our palette4670* using the wrong system palette entries), then the palette is4671* updated, but a WM_PALETTECHANGED message is never sent.4672* By tracking the ISCHANGING message as well (and by tracking4673* displayChange events in the AwtToolkit object), we can account4674* for this error by forcing our WmPaletteChanged method to be4675* called and thereby realizing our logical palette and updating4676* our dynamic colorModel object.4677*/4678MsgRouting AwtComponent::WmPaletteIsChanging(HWND hwndPalChg)4679{4680if (AwtToolkit::GetInstance().HasDisplayChanged()) {4681WmPaletteChanged(hwndPalChg);4682AwtToolkit::GetInstance().ResetDisplayChanged();4683}4684return mrDoDefault;4685}46864687MsgRouting AwtComponent::WmPaletteChanged(HWND hwndPalChg)4688{4689// We need to re-realize our palette here (unless we're the one4690// that was realizing it in the first place). That will let us match the4691// remaining colors in the system palette as best we can. We always4692// invalidate because the palette will have changed when we receive this4693// message.46944695int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());4696if (hwndPalChg != GetHWnd()) {4697HDC hDC = ::GetDC(GetHWnd());4698DASSERT(hDC);4699AwtWin32GraphicsDevice::SelectPalette(hDC, screen);4700AwtWin32GraphicsDevice::RealizePalette(hDC, screen);4701::ReleaseDC(GetHWnd(), hDC);4702// We must realize the palettes of all of our DC's4703activeDCList.RealizePalettes(screen);4704}4705if (AwtWin32GraphicsDevice::UpdateSystemPalette(screen)) {4706AwtWin32GraphicsDevice::UpdateDynamicColorModel(screen);4707}4708Invalidate(NULL);4709return mrDoDefault;4710}47114712MsgRouting AwtComponent::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss)4713{4714DASSERT(!IsBadReadPtr(lpss, sizeof(STYLESTRUCT)));4715return mrDoDefault;4716}47174718MsgRouting AwtComponent::WmSettingChange(UINT wFlag, LPCTSTR pszSection)4719{4720DASSERT(!IsBadStringPtr(pszSection, 20));4721DTRACE_PRINTLN2("WM_SETTINGCHANGE: wFlag=%d pszSection=%s", (int)wFlag, pszSection);4722return mrDoDefault;4723}47244725HDC AwtComponent::GetDCFromComponent()4726{4727GetDCReturnStruct *hdcStruct =4728(GetDCReturnStruct*)SendMessage(WM_AWT_GETDC);4729HDC hdc;4730if (hdcStruct) {4731if (hdcStruct->gdiLimitReached) {4732if (jvm != NULL) {4733JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);4734if (env != NULL && !safe_ExceptionOccurred(env)) {4735JNU_ThrowByName(env, "java/awt/AWTError",4736"HDC creation failure - " \4737"exceeded maximum GDI resources");4738}4739}4740}4741hdc = hdcStruct->hDC;4742delete hdcStruct;4743} else {4744hdc = NULL;4745}4746return hdc;4747}47484749void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size)4750{4751RECT eraseR = { 0, 0, size.cx, size.cy };4752VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));4753}47544755void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)4756{4757if (!bitmapBits) {4758return;4759}47604761DWORD* dest = (DWORD*)bitmapBits;4762//XXX: might be optimized to use one loop (cy*cx -> 0)4763for (int i = 0; i < size.cy; i++ ) {4764for (int j = 0; j < size.cx; j++ ) {4765((BYTE*)(dest++))[3] = alpha;4766}4767}4768}47694770int AwtComponent::GetScreenImOn() {4771HWND hWindow = GetAncestor(GetHWnd(), GA_ROOT);4772AwtComponent *comp = AwtComponent::GetComponent(hWindow);4773if (comp && comp->IsTopLevel()) {4774return comp->GetScreenImOn();4775}4776return AwtWin32GraphicsDevice::DeviceIndexForWindow(hWindow);4777}47784779int AwtComponent::ScaleUpX(int x) {4780int screen = GetScreenImOn();4781Devices::InstanceAccess devices;4782AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4783return device == NULL ? x : device->ScaleUpX(x);4784}47854786int AwtComponent::ScaleUpAbsX(int x) {4787int screen = GetScreenImOn();4788Devices::InstanceAccess devices;4789AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4790return device == NULL ? x : device->ScaleUpAbsX(x);4791}47924793int AwtComponent::ScaleUpY(int y) {4794int screen = GetScreenImOn();4795Devices::InstanceAccess devices;4796AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4797return device == NULL ? y : device->ScaleUpY(y);4798}47994800int AwtComponent::ScaleUpAbsY(int y) {4801int screen = GetScreenImOn();4802Devices::InstanceAccess devices;4803AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4804return device == NULL ? y : device->ScaleUpAbsY(y);4805}48064807int AwtComponent::ScaleDownX(int x) {4808int screen = GetScreenImOn();4809Devices::InstanceAccess devices;4810AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4811return device == NULL ? x : device->ScaleDownX(x);4812}48134814int AwtComponent::ScaleDownAbsX(int x) {4815int screen = GetScreenImOn();4816Devices::InstanceAccess devices;4817AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4818return device == NULL ? x : device->ScaleDownAbsX(x);4819}48204821int AwtComponent::ScaleDownY(int y) {4822int screen = GetScreenImOn();4823Devices::InstanceAccess devices;4824AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4825return device == NULL ? y : device->ScaleDownY(y);4826}48274828int AwtComponent::ScaleDownAbsY(int y) {4829int screen = GetScreenImOn();4830Devices::InstanceAccess devices;4831AwtWin32GraphicsDevice* device = devices->GetDevice(screen);4832return device == NULL ? y : device->ScaleDownAbsY(y);4833}48344835jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) {4836JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);48374838if (!::IsWindowVisible(GetHWnd())) {4839return NULL;4840}48414842HDC hdc = GetDCFromComponent();4843if (!hdc) {4844return NULL;4845}4846HDC hMemoryDC = ::CreateCompatibleDC(hdc);4847void *bitmapBits = NULL;4848HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits);4849HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap);4850SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc);48514852FillBackground(hMemoryDC, size);48534854VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL));48554856// Don't bother with PRF_CHECKVISIBLE because we called IsWindowVisible4857// above.4858SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT);48594860// First make sure the system completed any drawing to the bitmap.4861::GdiFlush();48624863// WM_PRINT does not fill the alpha-channel of the ARGB bitmap4864// leaving it equal to zero. Hence we need to fill it manually. Otherwise4865// the pixels will be considered transparent when interpreting the data.4866FillAlpha(bitmapBits, size, alpha);48674868::SelectObject(hMemoryDC, hOldBitmap);48694870BITMAPINFO bmi;4871memset(&bmi, 0, sizeof(BITMAPINFO));4872bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);4873bmi.bmiHeader.biWidth = size.cx;4874bmi.bmiHeader.biHeight = -size.cy;4875bmi.bmiHeader.biPlanes = 1;4876bmi.bmiHeader.biBitCount = 32;4877bmi.bmiHeader.biCompression = BI_RGB;48784879jobject localPixelArray = env->NewIntArray(size.cx * size.cy);4880jintArray pixelArray = NULL;4881if (localPixelArray != NULL) {4882pixelArray = (jintArray)env->NewGlobalRef(localPixelArray);4883env->DeleteLocalRef(localPixelArray); localPixelArray = NULL;48844885jboolean isCopy;4886jint *pixels = env->GetIntArrayElements(pixelArray, &isCopy);48874888::GetDIBits(hMemoryDC, hBitmap, 0, size.cy, (LPVOID)pixels, &bmi,4889DIB_RGB_COLORS);48904891env->ReleaseIntArrayElements(pixelArray, pixels, 0);4892}48934894VERIFY(::DeleteObject(hBitmap));4895VERIFY(::DeleteDC(hMemoryDC));48964897return pixelArray;4898}48994900void* AwtComponent::SetNativeFocusOwner(void *self) {4901if (self == NULL) {4902// It means that the KFM wants to set focus to null4903sm_focusOwner = NULL;4904return NULL;4905}49064907JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);49084909AwtComponent *c = NULL;4910jobject peer = (jobject)self;49114912PDATA pData;4913JNI_CHECK_NULL_GOTO(peer, "peer", ret);4914pData = JNI_GET_PDATA(peer);4915if (pData == NULL) {4916goto ret;4917}4918c = (AwtComponent *)pData;49194920ret:4921if (c && ::IsWindow(c->GetHWnd())) {4922sm_focusOwner = c->GetHWnd();4923} else {4924sm_focusOwner = NULL;4925}4926env->DeleteGlobalRef(peer);4927return NULL;4928}49294930void* AwtComponent::GetNativeFocusedWindow() {4931JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);4932AwtComponent *comp =4933AwtComponent::GetComponent(AwtComponent::GetFocusedWindow());4934return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL;4935}49364937void* AwtComponent::GetNativeFocusOwner() {4938JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);4939AwtComponent *comp =4940AwtComponent::GetComponent(AwtComponent::sm_focusOwner);4941return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL;4942}49434944AwtComponent* AwtComponent::SearchChild(UINT id) {4945ChildListItem* child;4946for (child = m_childList; child != NULL;child = child->m_next) {4947if (child->m_ID == id)4948return child->m_Component;4949}4950/*4951* DASSERT(FALSE);4952* This should not be happend if all children are recorded4953*/4954return NULL; /* make compiler happy */4955}49564957void AwtComponent::RemoveChild(UINT id) {4958ChildListItem* child = m_childList;4959ChildListItem* lastChild = NULL;4960while (child != NULL) {4961if (child->m_ID == id) {4962if (lastChild == NULL) {4963m_childList = child->m_next;4964} else {4965lastChild->m_next = child->m_next;4966}4967child->m_next = NULL;4968DASSERT(child != NULL);4969delete child;4970return;4971}4972lastChild = child;4973child = child->m_next;4974}4975}49764977void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked,4978jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg)4979{4980JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);4981CriticalSection::Lock l(GetLock());4982if (GetPeer(env) == NULL) {4983/* event received during termination. */4984return;4985}49864987static jclass keyEventCls;4988if (keyEventCls == NULL) {4989jclass keyEventClsLocal = env->FindClass("java/awt/event/KeyEvent");4990DASSERT(keyEventClsLocal);4991if (keyEventClsLocal == NULL) {4992/* exception already thrown */4993return;4994}4995keyEventCls = (jclass)env->NewGlobalRef(keyEventClsLocal);4996env->DeleteLocalRef(keyEventClsLocal);4997}49984999static jmethodID keyEventConst;5000if (keyEventConst == NULL) {5001keyEventConst = env->GetMethodID(keyEventCls, "<init>",5002"(Ljava/awt/Component;IJIICI)V");5003DASSERT(keyEventConst);5004CHECK_NULL(keyEventConst);5005}5006if (env->EnsureLocalCapacity(2) < 0) {5007return;5008}5009jobject target = GetTarget(env);5010jobject keyEvent = env->NewObject(keyEventCls, keyEventConst, target,5011id, when, modifiers, raw, cooked,5012keyLocation);5013if (safe_ExceptionOccurred(env)) env->ExceptionDescribe();5014DASSERT(!safe_ExceptionOccurred(env));5015DASSERT(keyEvent != NULL);5016if (keyEvent == NULL) {5017env->DeleteLocalRef(target);5018return;5019}5020env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode);5021if( nativeCode && nativeCode < 256 ) {5022env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode));5023env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey));5024if( nativeCode < 255 ) {5025env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode));5026}else if( pMsg != NULL ) {5027// unknown key with virtual keycode 0xFF.5028// Its scancode is not in the table, pickup it from the message.5029env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF));5030}5031}5032if (pMsg != NULL) {5033AwtAWTEvent::saveMSG(env, pMsg, keyEvent);5034}5035SendEvent(keyEvent);50365037env->DeleteLocalRef(keyEvent);5038env->DeleteLocalRef(target);5039}50405041void5042AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when,5043jint raw, jint cooked,5044jint modifiers, jint keyLocation,5045jlong nativeCode,5046MSG *msg)5047{5048/*5049* if focus owner is null, but focused window isn't5050* we will send key event to focused window5051*/5052HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow());50535054if (hwndTarget == GetHWnd()) {5055SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg);5056} else {5057AwtComponent *target = NULL;5058if (hwndTarget != NULL) {5059target = AwtComponent::GetComponent(hwndTarget);5060if (target == NULL) {5061target = this;5062}5063}5064if (target != NULL) {5065target->SendKeyEvent(id, when, raw, cooked, modifiers,5066keyLocation, nativeCode, msg);5067}5068}5069}50705071void AwtComponent::SetDragCapture(UINT flags)5072{5073// don't want to interfere with other controls5074if (::GetCapture() == NULL) {5075::SetCapture(GetHWnd());5076}5077}50785079void AwtComponent::ReleaseDragCapture(UINT flags)5080{5081if ((::GetCapture() == GetHWnd()) && ((flags & ALL_MK_BUTTONS) == 0)) {5082// user has released all buttons, so release the capture5083::ReleaseCapture();5084}5085}50865087void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y,5088jint modifiers, jint clickCount,5089jboolean popupTrigger, jint button,5090MSG *pMsg, BOOL causedByTouchEvent)5091{5092JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);5093CriticalSection::Lock l(GetLock());5094if (GetPeer(env) == NULL) {5095/* event received during termination. */5096return;5097}50985099static jclass mouseEventCls;5100if (mouseEventCls == NULL) {5101jclass mouseEventClsLocal =5102env->FindClass("java/awt/event/MouseEvent");5103CHECK_NULL(mouseEventClsLocal);5104mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal);5105env->DeleteLocalRef(mouseEventClsLocal);5106}5107RECT insets;5108GetInsets(&insets);51095110static jmethodID mouseEventConst;5111if (mouseEventConst == NULL) {5112mouseEventConst =5113env->GetMethodID(mouseEventCls, "<init>",5114"(Ljava/awt/Component;IJIIIIIIZI)V");5115DASSERT(mouseEventConst);5116CHECK_NULL(mouseEventConst);5117}5118if (env->EnsureLocalCapacity(2) < 0) {5119return;5120}5121jobject target = GetTarget(env);5122DWORD curMousePos = ::GetMessagePos();5123int xAbs = GET_X_LPARAM(curMousePos);5124int yAbs = GET_Y_LPARAM(curMousePos);5125jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst,5126target,5127id, when, modifiers,5128ScaleDownX(x + insets.left),5129ScaleDownY(y + insets.top),5130ScaleDownAbsX(xAbs), ScaleDownAbsY(yAbs),5131clickCount, popupTrigger, button);51325133if (safe_ExceptionOccurred(env)) {5134env->ExceptionDescribe();5135env->ExceptionClear();5136}51375138DASSERT(mouseEvent != NULL);5139CHECK_NULL(mouseEvent);5140if (causedByTouchEvent) {5141env->SetBooleanField(mouseEvent, AwtMouseEvent::causedByTouchEventID,5142JNI_TRUE);5143}5144if (pMsg != 0) {5145AwtAWTEvent::saveMSG(env, pMsg, mouseEvent);5146}5147SendEvent(mouseEvent);51485149env->DeleteLocalRef(mouseEvent);5150env->DeleteLocalRef(target);5151}51525153void5154AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,5155jint modifiers, jint clickCount,5156jboolean popupTrigger, jint scrollType,5157jint scrollAmount, jint roundedWheelRotation,5158jdouble preciseWheelRotation, MSG *pMsg)5159{5160/* Code based not so loosely on AwtComponent::SendMouseEvent */5161JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);5162CriticalSection::Lock l(GetLock());5163if (GetPeer(env) == NULL) {5164/* event received during termination. */5165return;5166}51675168static jclass mouseWheelEventCls;5169if (mouseWheelEventCls == NULL) {5170jclass mouseWheelEventClsLocal =5171env->FindClass("java/awt/event/MouseWheelEvent");5172CHECK_NULL(mouseWheelEventClsLocal);5173mouseWheelEventCls = (jclass)env->NewGlobalRef(mouseWheelEventClsLocal);5174env->DeleteLocalRef(mouseWheelEventClsLocal);5175}5176RECT insets;5177GetInsets(&insets);51785179static jmethodID mouseWheelEventConst;5180if (mouseWheelEventConst == NULL) {5181mouseWheelEventConst =5182env->GetMethodID(mouseWheelEventCls, "<init>",5183"(Ljava/awt/Component;IJIIIIIIZIIID)V");5184DASSERT(mouseWheelEventConst);5185CHECK_NULL(mouseWheelEventConst);5186}5187if (env->EnsureLocalCapacity(2) < 0) {5188return;5189}5190jobject target = GetTarget(env);5191DWORD curMousePos = ::GetMessagePos();5192int xAbs = GET_X_LPARAM(curMousePos);5193int yAbs = GET_Y_LPARAM(curMousePos);51945195DTRACE_PRINTLN("creating MWE in JNI");51965197jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,5198mouseWheelEventConst,5199target,5200id, when, modifiers,5201ScaleDownX(x + insets.left),5202ScaleDownY(y + insets.top),5203ScaleDownAbsX(xAbs),5204ScaleDownAbsY(yAbs),5205clickCount, popupTrigger,5206scrollType, scrollAmount,5207roundedWheelRotation, preciseWheelRotation);52085209DASSERT(mouseWheelEvent != NULL);5210if (mouseWheelEvent == NULL || safe_ExceptionOccurred(env)) {5211env->ExceptionDescribe();5212env->ExceptionClear();5213env->DeleteLocalRef(target);5214return;5215}5216if (pMsg != NULL) {5217AwtAWTEvent::saveMSG(env, pMsg, mouseWheelEvent);5218}5219SendEvent(mouseWheelEvent);52205221env->DeleteLocalRef(mouseWheelEvent);5222env->DeleteLocalRef(target);5223}52245225void AwtComponent::SendFocusEvent(jint id, HWND opposite)5226{5227JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);52285229CriticalSection::Lock l(GetLock());5230if (GetPeer(env) == NULL) {5231/* event received during termination. */5232return;5233}52345235static jclass focusEventCls;5236if (focusEventCls == NULL) {5237jclass focusEventClsLocal5238= env->FindClass("java/awt/event/FocusEvent");5239DASSERT(focusEventClsLocal);5240CHECK_NULL(focusEventClsLocal);5241focusEventCls = (jclass)env->NewGlobalRef(focusEventClsLocal);5242env->DeleteLocalRef(focusEventClsLocal);5243}52445245static jmethodID focusEventConst;5246if (focusEventConst == NULL) {5247focusEventConst =5248env->GetMethodID(focusEventCls, "<init>",5249"(Ljava/awt/Component;IZLjava/awt/Component;)V");5250DASSERT(focusEventConst);5251CHECK_NULL(focusEventConst);5252}52535254static jclass sequencedEventCls;5255if (sequencedEventCls == NULL) {5256jclass sequencedEventClsLocal =5257env->FindClass("java/awt/SequencedEvent");5258DASSERT(sequencedEventClsLocal);5259CHECK_NULL(sequencedEventClsLocal);5260sequencedEventCls =5261(jclass)env->NewGlobalRef(sequencedEventClsLocal);5262env->DeleteLocalRef(sequencedEventClsLocal);5263}52645265static jmethodID sequencedEventConst;5266if (sequencedEventConst == NULL) {5267sequencedEventConst =5268env->GetMethodID(sequencedEventCls, "<init>",5269"(Ljava/awt/AWTEvent;)V");5270DASSERT(sequencedEventConst);5271CHECK_NULL(sequencedEventConst);5272}52735274if (env->EnsureLocalCapacity(3) < 0) {5275return;5276}52775278jobject target = GetTarget(env);5279jobject jOpposite = NULL;5280if (opposite != NULL) {5281AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);5282if (awtOpposite != NULL) {5283jOpposite = awtOpposite->GetTarget(env);5284}5285}5286jobject focusEvent = env->NewObject(focusEventCls, focusEventConst,5287target, id, JNI_FALSE, jOpposite);5288DASSERT(!safe_ExceptionOccurred(env));5289DASSERT(focusEvent != NULL);5290if (jOpposite != NULL) {5291env->DeleteLocalRef(jOpposite); jOpposite = NULL;5292}5293env->DeleteLocalRef(target); target = NULL;5294CHECK_NULL(focusEvent);52955296jobject sequencedEvent = env->NewObject(sequencedEventCls,5297sequencedEventConst,5298focusEvent);5299DASSERT(!safe_ExceptionOccurred(env));5300DASSERT(sequencedEvent != NULL);5301env->DeleteLocalRef(focusEvent); focusEvent = NULL;5302CHECK_NULL(sequencedEvent);5303SendEvent(sequencedEvent);53045305env->DeleteLocalRef(sequencedEvent);5306}53075308/*5309* Forward a filtered event directly to the subclassed window.5310* This method is needed so that DefWindowProc is invoked on the5311* component's owning thread.5312*/5313MsgRouting AwtComponent::HandleEvent(MSG *msg, BOOL)5314{5315DefWindowProc(msg->message, msg->wParam, msg->lParam);5316delete msg;5317return mrConsume;5318}53195320/* Post a WM_AWT_HANDLE_EVENT message which invokes HandleEvent5321on the toolkit thread. This method may pre-filter the messages. */5322BOOL AwtComponent::PostHandleEventMessage(MSG *msg, BOOL synthetic)5323{5324JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);5325// We should cut off keyboard events to disabled components5326// to avoid the components responding visually to keystrokes when disabled.5327// we shouldn't cut off WM_SYS* messages as they aren't used for normal activity5328// but to activate menus, close windows, etc5329switch(msg->message) {5330case WM_KEYDOWN:5331case WM_KEYUP:5332case WM_CHAR:5333case WM_DEADCHAR:5334{5335if (!isRecursivelyEnabled()) {5336goto quit;5337}5338break;5339}5340}5341if (PostMessage(GetHWnd(), WM_AWT_HANDLE_EVENT,5342(WPARAM) synthetic, (LPARAM) msg)) {5343return TRUE;5344} else {5345JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");5346}5347quit:5348delete msg;5349return FALSE;5350}53515352void AwtComponent::SynthesizeKeyMessage(JNIEnv *env, jobject keyEvent)5353{5354jint id = (env)->GetIntField(keyEvent, AwtAWTEvent::idID);5355UINT message;5356switch (id) {5357case java_awt_event_KeyEvent_KEY_PRESSED:5358message = WM_KEYDOWN;5359break;5360case java_awt_event_KeyEvent_KEY_RELEASED:5361message = WM_KEYUP;5362break;5363case java_awt_event_KeyEvent_KEY_TYPED:5364message = WM_CHAR;5365break;5366default:5367return;5368}53695370/*5371* KeyEvent.modifiers aren't supported -- the Java apppwd must send separate5372* KEY_PRESSED and KEY_RELEASED events for the modifier virtual keys.5373*/5374if (id == java_awt_event_KeyEvent_KEY_TYPED) {5375// WM_CHAR message must be posted using WM_AWT_FORWARD_CHAR5376// (for Edit control)5377jchar keyChar = (jchar)5378(env)->GetCharField(keyEvent, AwtKeyEvent::keyCharID);53795380// Bugid 4724007. If it is a Delete character, don't send the fake5381// KEY_TYPED we created back to the native window: Windows doesn't5382// expect a WM_CHAR for Delete in TextFields, so it tries to enter a5383// character after deleting.5384if (keyChar == '\177') { // the Delete character5385return;5386}53875388// Disable forwarding WM_CHAR messages to disabled components5389if (isRecursivelyEnabled()) {5390if (!::PostMessage(GetHWnd(), WM_AWT_FORWARD_CHAR,5391MAKEWPARAM(keyChar, TRUE), 0)) {5392JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");5393}5394}5395} else {5396jint keyCode =5397(env)->GetIntField(keyEvent, AwtKeyEvent::keyCodeID);5398UINT key, modifiers;5399AwtComponent::JavaKeyToWindowsKey(keyCode, &key, &modifiers);5400MSG* msg = CreateMessage(message, key, 0);5401PostHandleEventMessage(msg, TRUE);5402}5403}54045405void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent)5406{5407/* DebugBreak(); */5408jint button = (env)->GetIntField(mouseEvent, AwtMouseEvent::buttonID);5409jint modifiers = (env)->GetIntField(mouseEvent, AwtInputEvent::modifiersID);54105411WPARAM wParam = 0;5412WORD wLow = 0;5413jint wheelAmt = 0;5414jint id = (env)->GetIntField(mouseEvent, AwtAWTEvent::idID);5415UINT message;5416switch (id) {5417case java_awt_event_MouseEvent_MOUSE_PRESSED: {5418switch (button) {5419case java_awt_event_MouseEvent_BUTTON1:5420message = WM_LBUTTONDOWN; break;5421case java_awt_event_MouseEvent_BUTTON3:5422message = WM_MBUTTONDOWN; break;5423case java_awt_event_MouseEvent_BUTTON2:5424message = WM_RBUTTONDOWN; break;5425default:5426return;5427}5428break;5429}5430case java_awt_event_MouseEvent_MOUSE_RELEASED: {5431switch (button) {5432case java_awt_event_MouseEvent_BUTTON1:5433message = WM_LBUTTONUP; break;5434case java_awt_event_MouseEvent_BUTTON3:5435message = WM_MBUTTONUP; break;5436case java_awt_event_MouseEvent_BUTTON2:5437message = WM_RBUTTONUP; break;5438default:5439return;5440}5441break;5442}5443case java_awt_event_MouseEvent_MOUSE_MOVED:5444/* MOUSE_DRAGGED events must first have sent a MOUSE_PRESSED event. */5445case java_awt_event_MouseEvent_MOUSE_DRAGGED:5446message = WM_MOUSEMOVE;5447break;5448case java_awt_event_MouseEvent_MOUSE_WHEEL:5449if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) {5450wLow |= MK_CONTROL;5451}5452if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) {5453wLow |= MK_SHIFT;5454}5455if (modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) {5456wLow |= MK_LBUTTON;5457}5458if (modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) {5459wLow |= MK_RBUTTON;5460}5461if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) {5462wLow |= MK_MBUTTON;5463}5464if (modifiers & X1_BUTTON) {5465wLow |= GetButtonMK(X1_BUTTON);5466}5467if (modifiers & X2_BUTTON) {5468wLow |= GetButtonMK(X2_BUTTON);5469}54705471wheelAmt = (jint)JNU_CallMethodByName(env,5472NULL,5473mouseEvent,5474"getWheelRotation",5475"()I").i;5476DASSERT(!safe_ExceptionOccurred(env));5477JNU_CHECK_EXCEPTION(env);5478DTRACE_PRINTLN1("wheelAmt = %i\n", wheelAmt);54795480// convert Java wheel amount value to Win325481wheelAmt *= -1 * WHEEL_DELTA;54825483message = WM_MOUSEWHEEL;5484wParam = MAKEWPARAM(wLow, wheelAmt);54855486break;5487default:5488return;5489}5490jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID);5491jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID);5492MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y);5493PostHandleEventMessage(msg, TRUE);5494}54955496BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;}54975498void AwtComponent::Invalidate(RECT* r)5499{5500::InvalidateRect(GetHWnd(), r, FALSE);5501}55025503void AwtComponent::BeginValidate()5504{5505DASSERT(m_validationNestCount >= 0 &&5506m_validationNestCount < 1000); // sanity check55075508if (m_validationNestCount == 0) {5509// begin deferred window positioning if we're not inside5510// another Begin/EndValidate pair5511DASSERT(m_hdwp == NULL);5512m_hdwp = ::BeginDeferWindowPos(32);5513}55145515m_validationNestCount++;5516}55175518void AwtComponent::EndValidate()5519{5520DASSERT(m_validationNestCount > 0 &&5521m_validationNestCount < 1000); // sanity check5522DASSERT(m_hdwp != NULL);55235524m_validationNestCount--;5525if (m_validationNestCount == 0) {5526// if this call to EndValidate is not nested inside another5527// Begin/EndValidate pair, end deferred window positioning5528::EndDeferWindowPos(m_hdwp);5529m_hdwp = NULL;5530}5531}55325533/**5534* HWND, AwtComponent and Java Peer interaction5535*/55365537/*5538*Link the C++, Java peer, and HWNDs together.5539*/5540void AwtComponent::LinkObjects(JNIEnv *env, jobject peer)5541{5542/*5543* Bind all three objects together thru this C++ object, two-way to each:5544* JavaPeer <-> C++ <-> HWND5545*5546* C++ -> JavaPeer5547*/5548if (m_peerObject == NULL) {5549// This may have already been set up by CreateHWnd5550// And we don't want to create two references so we5551// will leave the prior one alone5552m_peerObject = env->NewGlobalRef(peer);5553}5554/* JavaPeer -> HWND */5555env->SetLongField(peer, AwtComponent::hwndID, reinterpret_cast<jlong>(m_hwnd));55565557/* JavaPeer -> C++ */5558JNI_SET_PDATA(peer, this);55595560/* HWND -> C++ */5561SetComponentInHWND();5562}55635564/* Cleanup above linking */5565void AwtComponent::UnlinkObjects()5566{5567JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);5568if (m_peerObject) {5569env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);5570JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));5571JNI_SET_DESTROYED(m_peerObject);5572env->DeleteGlobalRef(m_peerObject);5573m_peerObject = NULL;5574}5575}55765577void AwtComponent::Enable(BOOL bEnable)5578{5579if (bEnable && IsTopLevel()) {5580// we should not enable blocked toplevels5581bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));5582}5583// Shouldn't trigger native focus change5584// (only the proxy may be the native focus owner).5585::EnableWindow(GetHWnd(), bEnable);55865587CriticalSection::Lock l(GetLock());5588VerifyState();5589}55905591/*5592* associate an AwtDropTarget with this AwtComponent5593*/55945595AwtDropTarget* AwtComponent::CreateDropTarget(JNIEnv* env) {5596m_dropTarget = new AwtDropTarget(env, this);5597m_dropTarget->RegisterTarget(TRUE);5598return m_dropTarget;5599}56005601/*5602* disassociate an AwtDropTarget with this AwtComponent5603*/56045605void AwtComponent::DestroyDropTarget() {5606if (m_dropTarget != NULL) {5607m_dropTarget->RegisterTarget(FALSE);5608m_dropTarget->Release();5609m_dropTarget = NULL;5610}5611}56125613BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) {5614return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK;5615}56165617BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) {5618return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE;5619}56205621void AwtComponent::_Show(void *param)5622{5623JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);56245625jobject self = (jobject)param;56265627AwtComponent *p;56285629PDATA pData;5630JNI_CHECK_PEER_GOTO(self, ret);5631p = (AwtComponent *)pData;5632if (::IsWindow(p->GetHWnd()))5633{5634p->SendMessage(WM_AWT_COMPONENT_SHOW);5635}5636ret:5637env->DeleteGlobalRef(self);5638}56395640void AwtComponent::_Hide(void *param)5641{5642JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);56435644jobject self = (jobject)param;56455646AwtComponent *p;56475648PDATA pData;5649JNI_CHECK_PEER_GOTO(self, ret);5650p = (AwtComponent *)pData;5651if (::IsWindow(p->GetHWnd()))5652{5653p->SendMessage(WM_AWT_COMPONENT_HIDE);5654}5655ret:5656env->DeleteGlobalRef(self);5657}56585659void AwtComponent::_Enable(void *param)5660{5661JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);56625663jobject self = (jobject)param;56645665AwtComponent *p;56665667PDATA pData;5668JNI_CHECK_PEER_GOTO(self, ret);5669p = (AwtComponent *)pData;5670if (::IsWindow(p->GetHWnd()))5671{5672p->Enable(TRUE);5673}5674ret:5675env->DeleteGlobalRef(self);5676}56775678void AwtComponent::_Disable(void *param)5679{5680JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);56815682jobject self = (jobject)param;56835684AwtComponent *p;56855686PDATA pData;5687JNI_CHECK_PEER_GOTO(self, ret);5688p = (AwtComponent *)pData;5689if (::IsWindow(p->GetHWnd()))5690{5691p->Enable(FALSE);5692}5693ret:5694env->DeleteGlobalRef(self);5695}56965697jobject AwtComponent::_GetLocationOnScreen(void *param)5698{5699JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);57005701jobject self = (jobject)param;57025703jobject result = NULL;5704AwtComponent *p;57055706PDATA pData;5707JNI_CHECK_PEER_GOTO(self, ret);5708p = (AwtComponent *)pData;5709if (::IsWindow(p->GetHWnd()))5710{5711RECT rect;5712VERIFY(::GetWindowRect(p->GetHWnd(),&rect));5713result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V",5714p->ScaleDownAbsX(rect.left),5715p->ScaleDownAbsY(rect.top));5716}5717ret:5718env->DeleteGlobalRef(self);57195720if (result != NULL)5721{5722jobject resultGlobalRef = env->NewGlobalRef(result);5723env->DeleteLocalRef(result);5724return resultGlobalRef;5725}5726else5727{5728return NULL;5729}5730}57315732void AwtComponent::_Reshape(void *param)5733{5734JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);57355736ReshapeStruct *rs = (ReshapeStruct*)param;5737jobject self = rs->component;5738jint x = rs->x;5739jint y = rs->y;5740jint w = rs->w;5741jint h = rs->h;57425743AwtComponent *p;57445745PDATA pData;5746JNI_CHECK_PEER_GOTO(self, ret);5747p = (AwtComponent *)pData;5748if (::IsWindow(p->GetHWnd()))5749{5750RECT* r = new RECT;5751::SetRect(r, x, y, x + w, y + h);5752p->SendMessage(WM_AWT_RESHAPE_COMPONENT, CHECK_EMBEDDED, (LPARAM)r);5753}5754ret:5755env->DeleteGlobalRef(self);57565757delete rs;5758}57595760void AwtComponent::_ReshapeNoCheck(void *param)5761{5762JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);57635764ReshapeStruct *rs = (ReshapeStruct*)param;5765jobject self = rs->component;5766jint x = rs->x;5767jint y = rs->y;5768jint w = rs->w;5769jint h = rs->h;57705771AwtComponent *p;57725773PDATA pData;5774JNI_CHECK_PEER_GOTO(self, ret);5775p = (AwtComponent *)pData;5776if (::IsWindow(p->GetHWnd()))5777{5778RECT* r = new RECT;5779::SetRect(r, x, y, x + w, y + h);5780p->SendMessage(WM_AWT_RESHAPE_COMPONENT, DONT_CHECK_EMBEDDED, (LPARAM)r);5781}5782ret:5783env->DeleteGlobalRef(self);57845785delete rs;5786}57875788void AwtComponent::_NativeHandleEvent(void *param)5789{5790JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);57915792NativeHandleEventStruct *nhes = (NativeHandleEventStruct *)param;5793jobject self = nhes->component;5794jobject event = nhes->event;57955796AwtComponent *p;57975798PDATA pData;5799JNI_CHECK_NULL_GOTO(self, "peer", ret);5800pData = JNI_GET_PDATA(self);5801if (pData == NULL) {5802env->DeleteGlobalRef(self);5803if (event != NULL) {5804env->DeleteGlobalRef(event);5805}5806delete nhes;5807return;5808}5809JNI_CHECK_NULL_GOTO(event, "null AWTEvent", ret);58105811p = (AwtComponent *)pData;5812if (::IsWindow(p->GetHWnd()))5813{5814if (env->EnsureLocalCapacity(1) < 0) {5815env->DeleteGlobalRef(self);5816env->DeleteGlobalRef(event);5817delete nhes;5818return;5819}5820jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID);5821int id = (env)->GetIntField(event, AwtAWTEvent::idID);5822DASSERT(!safe_ExceptionOccurred(env));5823if (bdata != 0) {5824MSG msg;5825(env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg);5826(env)->DeleteLocalRef(bdata);5827static BOOL keyDownConsumed = FALSE;5828static BOOL bCharChanged = FALSE;5829static WCHAR modifiedChar;5830WCHAR unicodeChar;58315832/* Remember if a KEY_PRESSED event is consumed, as an old model5833* program won't consume a subsequent KEY_TYPED event.5834*/5835jboolean consumed =5836(env)->GetBooleanField(event, AwtAWTEvent::consumedID);5837DASSERT(!safe_ExceptionOccurred(env));58385839if (consumed) {5840keyDownConsumed = (id == java_awt_event_KeyEvent_KEY_PRESSED);5841env->DeleteGlobalRef(self);5842env->DeleteGlobalRef(event);5843delete nhes;5844return;58455846} else if (id == java_awt_event_KeyEvent_KEY_PRESSED) {5847// Fix for 6637607: reset consuming5848keyDownConsumed = FALSE;5849}58505851/* Consume a KEY_TYPED event if a KEY_PRESSED had been, to support5852* the old model.5853*/5854if ((id == java_awt_event_KeyEvent_KEY_TYPED) && keyDownConsumed) {5855keyDownConsumed = FALSE;5856env->DeleteGlobalRef(self);5857env->DeleteGlobalRef(event);5858delete nhes;5859return;5860}58615862/* Modify any event parameters, if necessary. */5863if (self && pData &&5864id >= java_awt_event_KeyEvent_KEY_FIRST &&5865id <= java_awt_event_KeyEvent_KEY_LAST) {58665867AwtComponent* p = (AwtComponent*)pData;58685869jint keyCode =5870(env)->GetIntField(event, AwtKeyEvent::keyCodeID);5871jchar keyChar =5872(env)->GetCharField(event, AwtKeyEvent::keyCharID);5873jint modifiers =5874(env)->GetIntField(event, AwtInputEvent::modifiersID);58755876DASSERT(!safe_ExceptionOccurred(env));58775878/* Check to see whether the keyCode or modifiers were changed5879on the keyPressed event, and tweak the following keyTyped5880event (if any) accodingly. */5881switch (id) {5882case java_awt_event_KeyEvent_KEY_PRESSED:5883{5884UINT winKey = (UINT)msg.wParam;5885bCharChanged = FALSE;58865887if (winKey == VK_PROCESSKEY) {5888// Leave it up to IME5889break;5890}58915892if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) {5893UINT newWinKey, ignored;5894p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey);5895if (newWinKey != 0) {5896winKey = newWinKey;5897}5898}58995900BOOL isDeadKey = FALSE;5901modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey);5902bCharChanged = (keyChar != modifiedChar);5903}5904break;59055906case java_awt_event_KeyEvent_KEY_RELEASED:5907{5908keyDownConsumed = FALSE;5909bCharChanged = FALSE;5910}5911break;59125913case java_awt_event_KeyEvent_KEY_TYPED:5914{5915if (bCharChanged)5916{5917unicodeChar = modifiedChar;5918}5919else5920{5921unicodeChar = keyChar;5922}5923bCharChanged = FALSE;59245925// Disable forwarding KEY_TYPED messages to peers of5926// disabled components5927if (p->isRecursivelyEnabled()) {5928// send the character back to the native window for5929// processing. The WM_AWT_FORWARD_CHAR handler will send5930// this character to DefWindowProc5931if (!::PostMessage(p->GetHWnd(), WM_AWT_FORWARD_CHAR,5932MAKEWPARAM(unicodeChar, FALSE), msg.lParam)) {5933JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");5934}5935}5936env->DeleteGlobalRef(self);5937env->DeleteGlobalRef(event);5938delete nhes;5939return;5940}5941break;59425943default:5944break;5945}5946}59475948// ignore all InputMethodEvents5949if (self && (pData = JNI_GET_PDATA(self)) &&5950id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST &&5951id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) {5952env->DeleteGlobalRef(self);5953env->DeleteGlobalRef(event);5954delete nhes;5955return;5956}59575958// Create copy for local msg5959MSG* pCopiedMsg = new MSG;5960memmove(pCopiedMsg, &msg, sizeof(MSG));5961// Event handler deletes msg5962p->PostHandleEventMessage(pCopiedMsg, FALSE);59635964env->DeleteGlobalRef(self);5965env->DeleteGlobalRef(event);5966delete nhes;5967return;5968}59695970/* Forward any valid synthesized events. Currently only mouse and5971* key events are supported.5972*/5973if (self == NULL || (pData = JNI_GET_PDATA(self)) == NULL) {5974env->DeleteGlobalRef(self);5975env->DeleteGlobalRef(event);5976delete nhes;5977return;5978}59795980AwtComponent* p = (AwtComponent*)pData;5981if (id >= java_awt_event_KeyEvent_KEY_FIRST &&5982id <= java_awt_event_KeyEvent_KEY_LAST) {5983p->SynthesizeKeyMessage(env, event);5984} else if (id >= java_awt_event_MouseEvent_MOUSE_FIRST &&5985id <= java_awt_event_MouseEvent_MOUSE_LAST) {5986p->SynthesizeMouseMessage(env, event);5987}5988}59895990ret:5991if (self != NULL) {5992env->DeleteGlobalRef(self);5993}5994if (event != NULL) {5995env->DeleteGlobalRef(event);5996}59975998delete nhes;5999}60006001void AwtComponent::_SetForeground(void *param)6002{6003JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);60046005SetColorStruct *scs = (SetColorStruct *)param;6006jobject self = scs->component;6007jint rgb = scs->rgb;60086009AwtComponent *c = NULL;60106011PDATA pData;6012JNI_CHECK_PEER_GOTO(self, ret);6013c = (AwtComponent *)pData;6014if (::IsWindow(c->GetHWnd()))6015{6016c->SetColor(PALETTERGB((rgb>>16)&0xff,6017(rgb>>8)&0xff,6018(rgb)&0xff));6019c->VerifyState();6020}6021ret:6022env->DeleteGlobalRef(self);60236024delete scs;6025}60266027void AwtComponent::_SetBackground(void *param)6028{6029JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);60306031SetColorStruct *scs = (SetColorStruct *)param;6032jobject self = scs->component;6033jint rgb = scs->rgb;60346035AwtComponent *c = NULL;60366037PDATA pData;6038JNI_CHECK_PEER_GOTO(self, ret);6039c = (AwtComponent *)pData;6040if (::IsWindow(c->GetHWnd()))6041{6042c->SetBackgroundColor(PALETTERGB((rgb>>16)&0xff,6043(rgb>>8)&0xff,6044(rgb)&0xff));6045c->VerifyState();6046}6047ret:6048env->DeleteGlobalRef(self);60496050delete scs;6051}60526053void AwtComponent::_SetFont(void *param)6054{6055JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);60566057SetFontStruct *sfs = (SetFontStruct *)param;6058jobject self = sfs->component;6059jobject font = sfs->font;60606061AwtComponent *c = NULL;60626063PDATA pData;6064JNI_CHECK_PEER_GOTO(self, ret);6065JNI_CHECK_NULL_GOTO(font, "null font", ret);6066c = (AwtComponent *)pData;6067if (::IsWindow(c->GetHWnd()))6068{6069AwtFont *awtFont = (AwtFont *)env->GetLongField(font, AwtFont::pDataID);6070if (awtFont == NULL) {6071/*arguments of AwtFont::Create are changed for multifont component */6072awtFont = AwtFont::Create(env, font);6073}6074env->SetLongField(font, AwtFont::pDataID, (jlong)awtFont);60756076c->SetFont(awtFont);6077}6078ret:6079env->DeleteGlobalRef(self);6080env->DeleteGlobalRef(font);60816082delete sfs;6083}60846085// Sets or kills focus for a component.6086void AwtComponent::_SetFocus(void *param)6087{6088JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);60896090SetFocusStruct *sfs = (SetFocusStruct *)param;6091jobject self = sfs->component;6092jboolean doSetFocus = sfs->doSetFocus;60936094AwtComponent *c = NULL;60956096PDATA pData;6097JNI_CHECK_NULL_GOTO(self, "peer", ret);6098pData = JNI_GET_PDATA(self);6099if (pData == NULL) {6100// do nothing just return false6101goto ret;6102}61036104c = (AwtComponent *)pData;6105if (::IsWindow(c->GetHWnd())) {6106c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0);6107}6108ret:6109env->DeleteGlobalRef(self);61106111delete sfs;6112}61136114void AwtComponent::_Start(void *param)6115{6116JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);61176118jobject self = (jobject)param;61196120AwtComponent *c = NULL;61216122PDATA pData;6123JNI_CHECK_PEER_GOTO(self, ret);6124c = (AwtComponent *)pData;6125if (::IsWindow(c->GetHWnd()))6126{6127jobject target = c->GetTarget(env);61286129/* Disable window if specified -- windows are enabled by default. */6130jboolean enabled = (jboolean)env->GetBooleanField(target,6131AwtComponent::enabledID);6132if (!enabled) {6133::EnableWindow(c->GetHWnd(), FALSE);6134}61356136/* The peer is now ready for callbacks, since this is the last6137* initialization call6138*/6139c->EnableCallbacks(TRUE);61406141// Fix 4745222: we need to invalidate region since we validated it before initialization.6142::InvalidateRgn(c->GetHWnd(), NULL, FALSE);61436144// Fix 4530093: WM_PAINT after EnableCallbacks6145::UpdateWindow(c->GetHWnd());61466147env->DeleteLocalRef(target);6148}6149ret:6150env->DeleteGlobalRef(self);6151}61526153void AwtComponent::_BeginValidate(void *param)6154{6155JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);6156if (AwtToolkit::IsMainThread()) {6157jobject self = (jobject)param;6158if (self != NULL) {6159PDATA pData = JNI_GET_PDATA(self);6160if (pData) {6161AwtComponent *c = (AwtComponent *)pData;6162if (::IsWindow(c->GetHWnd())) {6163c->SendMessage(WM_AWT_BEGIN_VALIDATE);6164}6165}6166env->DeleteGlobalRef(self);6167}6168} else {6169AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_BeginValidate, param);6170}6171}61726173void AwtComponent::_EndValidate(void *param)6174{6175if (AwtToolkit::IsMainThread()) {6176JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);6177jobject self = (jobject)param;6178if (self != NULL) {6179PDATA pData = JNI_GET_PDATA(self);6180if (pData) {6181AwtComponent *c = (AwtComponent *)pData;6182if (::IsWindow(c->GetHWnd())) {6183c->SendMessage(WM_AWT_END_VALIDATE);6184}6185}6186env->DeleteGlobalRef(self);6187}6188} else {6189AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_EndValidate, param);6190}6191}61926193void AwtComponent::_UpdateWindow(void *param)6194{6195JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);6196if (AwtToolkit::IsMainThread()) {6197jobject self = (jobject)param;6198AwtComponent *c = NULL;6199PDATA pData;6200JNI_CHECK_PEER_GOTO(self, ret);6201c = (AwtComponent *)pData;6202if (::IsWindow(c->GetHWnd())) {6203::UpdateWindow(c->GetHWnd());6204}6205ret:6206env->DeleteGlobalRef(self);6207} else {6208AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_UpdateWindow, param);6209}6210}62116212jlong AwtComponent::_AddNativeDropTarget(void *param)6213{6214JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);62156216jobject self = (jobject)param;62176218jlong result = 0;6219AwtComponent *c = NULL;62206221PDATA pData;6222JNI_CHECK_PEER_GOTO(self, ret);6223c = (AwtComponent *)pData;6224if (::IsWindow(c->GetHWnd()))6225{6226result = (jlong)(c->CreateDropTarget(env));6227}6228ret:6229env->DeleteGlobalRef(self);62306231return result;6232}62336234void AwtComponent::_RemoveNativeDropTarget(void *param)6235{6236JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);62376238jobject self = (jobject)param;62396240AwtComponent *c = NULL;62416242PDATA pData;6243JNI_CHECK_PEER_GOTO(self, ret);6244c = (AwtComponent *)pData;6245if (::IsWindow(c->GetHWnd()))6246{6247c->DestroyDropTarget();6248}6249ret:6250env->DeleteGlobalRef(self);6251}62526253jintArray AwtComponent::_CreatePrintedPixels(void *param)6254{6255JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);62566257CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param;6258jobject self = cpps->component;62596260jintArray result = NULL;6261AwtComponent *c = NULL;62626263PDATA pData;6264JNI_CHECK_PEER_GOTO(self, ret);6265c = (AwtComponent *)pData;6266if (::IsWindow(c->GetHWnd()))6267{6268result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0);6269}6270ret:6271env->DeleteGlobalRef(self);62726273delete cpps;6274return result; // this reference is global6275}62766277jboolean AwtComponent::_IsObscured(void *param)6278{6279JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);62806281jobject self = (jobject)param;62826283jboolean result = JNI_FALSE;6284AwtComponent *c = NULL;62856286PDATA pData;6287JNI_CHECK_PEER_GOTO(self, ret);62886289c = (AwtComponent *)pData;62906291if (::IsWindow(c->GetHWnd()))6292{6293HWND hWnd = c->GetHWnd();6294HDC hDC = ::GetDC(hWnd);6295RECT clipbox;6296int callresult = ::GetClipBox(hDC, &clipbox);6297switch(callresult) {6298case NULLREGION :6299result = JNI_FALSE;6300break;6301case SIMPLEREGION : {6302RECT windowRect;6303if (!::GetClientRect(hWnd, &windowRect)) {6304result = JNI_TRUE;6305} else {6306result = (jboolean)((clipbox.bottom != windowRect.bottom)6307|| (clipbox.left != windowRect.left)6308|| (clipbox.right != windowRect.right)6309|| (clipbox.top != windowRect.top));6310}6311break;6312}6313case COMPLEXREGION :6314default :6315result = JNI_TRUE;6316break;6317}6318::ReleaseDC(hWnd, hDC);6319}6320ret:6321env->DeleteGlobalRef(self);63226323return result;6324}63256326jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param)6327{6328JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);63296330jobject self = (jobject)param;63316332jboolean result = JNI_FALSE;6333AwtComponent *c = NULL;63346335PDATA pData;6336JNI_CHECK_PEER_GOTO(self, ret);6337c = (AwtComponent *)pData;6338if (::IsWindow(c->GetHWnd()))6339{6340result = JNI_IS_TRUE(c->InheritsNativeMouseWheelBehavior());6341}6342ret:6343env->DeleteGlobalRef(self);63446345return result;6346}63476348void AwtComponent::_SetParent(void * param)6349{6350if (AwtToolkit::IsMainThread()) {6351JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);6352SetParentStruct *data = (SetParentStruct*) param;6353jobject self = data->component;6354jobject parent = data->parentComp;63556356AwtComponent *awtComponent = NULL;6357AwtComponent *awtParent = NULL;63586359PDATA pData;6360JNI_CHECK_PEER_GOTO(self, ret);6361awtComponent = (AwtComponent *)pData;6362JNI_CHECK_PEER_GOTO(parent, ret);6363awtParent = (AwtComponent *)pData;63646365HWND selfWnd = awtComponent->GetHWnd();6366HWND parentWnd = awtParent->GetHWnd();6367if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) {6368// Shouldn't trigger native focus change6369// (only the proxy may be the native focus owner).6370::SetParent(selfWnd, parentWnd);6371}6372ret:6373env->DeleteGlobalRef(self);6374env->DeleteGlobalRef(parent);6375delete data;6376} else {6377AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetParent, param);6378}6379}63806381void AwtComponent::_SetRectangularShape(void *param)6382{6383if (!AwtToolkit::IsMainThread()) {6384AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param);6385} else {6386JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);63876388SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param;6389jobject self = data->component;6390jint x1 = data->x1;6391jint x2 = data->x2;6392jint y1 = data->y1;6393jint y2 = data->y2;6394jobject region = data->region;63956396AwtComponent *c = NULL;63976398PDATA pData;6399JNI_CHECK_PEER_GOTO(self, ret);64006401c = (AwtComponent *)pData;6402if (::IsWindow(c->GetHWnd())) {6403HRGN hRgn = NULL;64046405// If all the params are zeros, the shape must be simply reset.6406// Otherwise, convert it into a region.6407if (region || x1 || x2 || y1 || y2) {6408RECT_T rects[256];6409RECT_T *pRect = rects;64106411const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2,6412region, &pRect, sizeof(rects)/sizeof(rects[0]));6413if (!pRect) {6414// RegionToYXBandedRectangles doesn't use safe_Malloc(),6415// so throw the exception explicitly6416throw std::bad_alloc();6417}64186419RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc,6420sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects);6421memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects);6422if (pRect != rects) {6423free(pRect);6424}6425pRect = NULL;64266427RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData;6428pRgnHdr->dwSize = sizeof(RGNDATAHEADER);6429pRgnHdr->iType = RDH_RECTANGLES;6430pRgnHdr->nRgnSize = 0;6431pRgnHdr->rcBound.top = 0;6432pRgnHdr->rcBound.left = 0;6433pRgnHdr->rcBound.bottom = LONG(y2 - y1);6434pRgnHdr->rcBound.right = LONG(x2 - x1);6435pRgnHdr->nCount = numrects;64366437hRgn = ::ExtCreateRegion(NULL,6438sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData);64396440free(pRgnData);6441}64426443::SetWindowRgn(c->GetHWnd(), hRgn, TRUE);6444}64456446ret:6447env->DeleteGlobalRef(self);6448if (region) {6449env->DeleteGlobalRef(region);6450}64516452delete data;6453}6454}64556456void AwtComponent::_SetZOrder(void *param) {6457JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);64586459SetZOrderStruct *data = (SetZOrderStruct *)param;6460jobject self = data->component;6461HWND above = HWND_TOP;6462if (data->above != 0) {6463above = reinterpret_cast<HWND>(data->above);6464}64656466AwtComponent *c = NULL;64676468PDATA pData;6469JNI_CHECK_PEER_GOTO(self, ret);64706471c = (AwtComponent *)pData;6472if (::IsWindow(c->GetHWnd())) {6473::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0,6474SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS);6475}64766477ret:6478env->DeleteGlobalRef(self);64796480delete data;6481}64826483void AwtComponent::PostUngrabEvent() {6484JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);6485jobject target = GetTarget(env);6486jobject event = JNU_NewObjectByName(env, "sun/awt/UngrabEvent", "(Ljava/awt/Component;)V",6487target);6488if (safe_ExceptionOccurred(env)) {6489env->ExceptionDescribe();6490env->ExceptionClear();6491}6492env->DeleteLocalRef(target);6493if (event != NULL) {6494SendEvent(event);6495env->DeleteLocalRef(event);6496}6497}64986499void AwtComponent::SetFocusedWindow(HWND window)6500{6501HWND old = sm_focusedWindow;6502sm_focusedWindow = window;65036504AwtWindow::FocusedWindowChanged(old, window);6505}65066507/************************************************************************6508* Component native methods6509*/65106511extern "C" {65126513/**6514* This method is called from the WGL pipeline when it needs to retrieve6515* the HWND associated with a ComponentPeer's C++ level object.6516*/6517HWND6518AwtComponent_GetHWnd(JNIEnv *env, jlong pData)6519{6520AwtComponent *p = (AwtComponent *)jlong_to_ptr(pData);6521if (p == NULL) {6522return (HWND)0;6523}6524return p->GetHWnd();6525}65266527static void _GetInsets(void* param)6528{6529JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);65306531GetInsetsStruct *gis = (GetInsetsStruct *)param;6532jobject self = gis->window;65336534gis->insets->left = gis->insets->top =6535gis->insets->right = gis->insets->bottom = 0;65366537PDATA pData;6538JNI_CHECK_PEER_GOTO(self, ret);6539AwtComponent *component = (AwtComponent *)pData;65406541component->GetInsets(gis->insets);65426543ret:6544env->DeleteGlobalRef(self);6545delete gis;6546}65476548/**6549* This method is called from the WGL pipeline when it needs to retrieve6550* the insets associated with a ComponentPeer's C++ level object.6551*/6552void AwtComponent_GetInsets(JNIEnv *env, jobject peer, RECT *insets)6553{6554TRY;65556556GetInsetsStruct *gis = new GetInsetsStruct;6557gis->window = env->NewGlobalRef(peer);6558gis->insets = insets;65596560AwtToolkit::GetInstance().InvokeFunction(_GetInsets, gis);6561// global refs and mds are deleted in _UpdateWindow65626563CATCH_BAD_ALLOC;65646565}65666567JNIEXPORT void JNICALL6568Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)6569{6570TRY;6571jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent");6572CHECK_NULL(inputEventClazz);6573jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I");6574CHECK_NULL(getButtonDownMasksID);6575jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID);6576jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE);6577CHECK_NULL(tmp);6578jsize len = env->GetArrayLength(obj);6579AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len);6580for (int i = 0; i < len; i++) {6581AwtComponent::masks[i] = tmp[i];6582}6583env->ReleaseIntArrayElements(obj, tmp, 0);6584env->DeleteLocalRef(obj);65856586/* class ids */6587jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer");65886589DASSERT(peerCls);6590CHECK_NULL(peerCls);65916592/* field ids */6593AwtComponent::peerID =6594env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;");6595DASSERT(AwtComponent::peerID);6596CHECK_NULL(AwtComponent::peerID);65976598AwtComponent::xID = env->GetFieldID(cls, "x", "I");6599DASSERT(AwtComponent::xID);6600CHECK_NULL(AwtComponent::xID);66016602AwtComponent::yID = env->GetFieldID(cls, "y", "I");6603DASSERT(AwtComponent::yID);6604CHECK_NULL(AwtComponent::yID);66056606AwtComponent::heightID = env->GetFieldID(cls, "height", "I");6607DASSERT(AwtComponent::heightID);6608CHECK_NULL(AwtComponent::heightID);66096610AwtComponent::widthID = env->GetFieldID(cls, "width", "I");6611DASSERT(AwtComponent::widthID);6612CHECK_NULL(AwtComponent::widthID);66136614AwtComponent::visibleID = env->GetFieldID(cls, "visible", "Z");6615DASSERT(AwtComponent::visibleID);6616CHECK_NULL(AwtComponent::visibleID);66176618AwtComponent::backgroundID =6619env->GetFieldID(cls, "background", "Ljava/awt/Color;");6620DASSERT(AwtComponent::backgroundID);6621CHECK_NULL(AwtComponent::backgroundID);66226623AwtComponent::foregroundID =6624env->GetFieldID(cls, "foreground", "Ljava/awt/Color;");6625DASSERT(AwtComponent::foregroundID);6626CHECK_NULL(AwtComponent::foregroundID);66276628AwtComponent::enabledID = env->GetFieldID(cls, "enabled", "Z");6629DASSERT(AwtComponent::enabledID);6630CHECK_NULL(AwtComponent::enabledID);66316632AwtComponent::parentID = env->GetFieldID(cls, "parent", "Ljava/awt/Container;");6633DASSERT(AwtComponent::parentID);6634CHECK_NULL(AwtComponent::parentID);66356636AwtComponent::graphicsConfigID =6637env->GetFieldID(cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;");6638DASSERT(AwtComponent::graphicsConfigID);6639CHECK_NULL(AwtComponent::graphicsConfigID);66406641AwtComponent::focusableID = env->GetFieldID(cls, "focusable", "Z");6642DASSERT(AwtComponent::focusableID);6643CHECK_NULL(AwtComponent::focusableID);66446645AwtComponent::appContextID = env->GetFieldID(cls, "appContext",6646"Lsun/awt/AppContext;");6647DASSERT(AwtComponent::appContextID);6648CHECK_NULL(AwtComponent::appContextID);66496650AwtComponent::peerGCID = env->GetFieldID(peerCls, "winGraphicsConfig",6651"Lsun/awt/Win32GraphicsConfig;");6652DASSERT(AwtComponent::peerGCID);6653CHECK_NULL(AwtComponent::peerGCID);66546655AwtComponent::hwndID = env->GetFieldID(peerCls, "hwnd", "J");6656DASSERT(AwtComponent::hwndID);6657CHECK_NULL(AwtComponent::hwndID);66586659AwtComponent::cursorID = env->GetFieldID(cls, "cursor", "Ljava/awt/Cursor;");6660DASSERT(AwtComponent::cursorID);6661CHECK_NULL(AwtComponent::cursorID);66626663/* method ids */6664AwtComponent::getFontMID =6665env->GetMethodID(cls, "getFont_NoClientCode", "()Ljava/awt/Font;");6666DASSERT(AwtComponent::getFontMID);6667CHECK_NULL(AwtComponent::getFontMID);66686669AwtComponent::getToolkitMID =6670env->GetMethodID(cls, "getToolkitImpl", "()Ljava/awt/Toolkit;");6671DASSERT(AwtComponent::getToolkitMID);6672CHECK_NULL(AwtComponent::getToolkitMID);66736674AwtComponent::isEnabledMID = env->GetMethodID(cls, "isEnabledImpl", "()Z");6675DASSERT(AwtComponent::isEnabledMID);6676CHECK_NULL(AwtComponent::isEnabledMID);66776678AwtComponent::getLocationOnScreenMID =6679env->GetMethodID(cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;");6680DASSERT(AwtComponent::getLocationOnScreenMID);6681CHECK_NULL(AwtComponent::getLocationOnScreenMID);66826683AwtComponent::replaceSurfaceDataMID =6684env->GetMethodID(peerCls, "replaceSurfaceData", "()V");6685DASSERT(AwtComponent::replaceSurfaceDataMID);6686CHECK_NULL(AwtComponent::replaceSurfaceDataMID);66876688AwtComponent::replaceSurfaceDataLaterMID =6689env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V");6690DASSERT(AwtComponent::replaceSurfaceDataLaterMID);6691CHECK_NULL(AwtComponent::replaceSurfaceDataLaterMID);66926693AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V");6694DASSERT(AwtComponent::disposeLaterMID);6695CHECK_NULL(AwtComponent::disposeLaterMID);66966697CATCH_BAD_ALLOC;6698}66996700} /* extern "C" */670167026703/************************************************************************6704* ComponentPeer native methods6705*/67066707extern "C" {67086709/*6710* Class: sun_awt_windows_WComponentPeer6711* Method: pShow6712* Signature: ()V6713*/6714JNIEXPORT void JNICALL6715Java_sun_awt_windows_WComponentPeer_pShow(JNIEnv *env, jobject self)6716{6717TRY;67186719jobject selfGlobalRef = env->NewGlobalRef(self);67206721AwtToolkit::GetInstance().SyncCall(AwtComponent::_Show, (void *)selfGlobalRef);6722// selfGlobalRef is deleted in _Show67236724CATCH_BAD_ALLOC;6725}67266727/*6728* Class: sun_awt_windows_WComponentPeer6729* Method: hide6730* Signature: ()V6731*/6732JNIEXPORT void JNICALL6733Java_sun_awt_windows_WComponentPeer_hide(JNIEnv *env, jobject self)6734{6735TRY;67366737jobject selfGlobalRef = env->NewGlobalRef(self);67386739AwtToolkit::GetInstance().SyncCall(AwtComponent::_Hide, (void *)selfGlobalRef);6740// selfGlobalRef is deleted in _Hide67416742CATCH_BAD_ALLOC;6743}67446745/*6746* Class: sun_awt_windows_WComponentPeer6747* Method: enable6748* Signature: ()V6749*/6750JNIEXPORT void JNICALL6751Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self)6752{6753TRY;67546755jobject selfGlobalRef = env->NewGlobalRef(self);67566757AwtToolkit::GetInstance().SyncCall(AwtComponent::_Enable, (void *)selfGlobalRef);6758// selfGlobalRef is deleted in _Enable67596760CATCH_BAD_ALLOC;6761}67626763/*6764* Class: sun_awt_windows_WComponentPeer6765* Method: disable6766* Signature: ()V6767*/6768JNIEXPORT void JNICALL6769Java_sun_awt_windows_WComponentPeer_disable(JNIEnv *env, jobject self)6770{6771TRY;67726773jobject selfGlobalRef = env->NewGlobalRef(self);67746775AwtToolkit::GetInstance().SyncCall(AwtComponent::_Disable, (void *)selfGlobalRef);6776// selfGlobalRef is deleted in _Disable67776778CATCH_BAD_ALLOC;6779}67806781/*6782* Class: sun_awt_windows_WComponentPeer6783* Method: getLocationOnScreen6784* Signature: ()Ljava/awt/Point;6785*/6786JNIEXPORT jobject JNICALL6787Java_sun_awt_windows_WComponentPeer_getLocationOnScreen(JNIEnv *env, jobject self)6788{6789TRY;67906791jobject selfGlobalRef = env->NewGlobalRef(self);67926793jobject resultGlobalRef = (jobject)AwtToolkit::GetInstance().SyncCall(6794(void*(*)(void*))AwtComponent::_GetLocationOnScreen, (void *)selfGlobalRef);6795// selfGlobalRef is deleted in _GetLocationOnScreen6796if (resultGlobalRef != NULL)6797{6798jobject resultLocalRef = env->NewLocalRef(resultGlobalRef);6799env->DeleteGlobalRef(resultGlobalRef);6800return resultLocalRef;6801}68026803return NULL;68046805CATCH_BAD_ALLOC_RET(NULL);6806}68076808/*6809* Class: sun_awt_windows_WComponentPeer6810* Method: reshape6811* Signature: (IIII)V6812*/6813JNIEXPORT void JNICALL6814Java_sun_awt_windows_WComponentPeer_reshape(JNIEnv *env, jobject self,6815jint x, jint y, jint w, jint h)6816{6817TRY;68186819ReshapeStruct *rs = new ReshapeStruct;6820rs->component = env->NewGlobalRef(self);6821rs->x = x;6822rs->y = y;6823rs->w = w;6824rs->h = h;68256826AwtToolkit::GetInstance().SyncCall(AwtComponent::_Reshape, rs);6827// global ref and rs are deleted in _Reshape68286829CATCH_BAD_ALLOC;6830}68316832/*6833* Class: sun_awt_windows_WComponentPeer6834* Method: reshape6835* Signature: (IIII)V6836*/6837JNIEXPORT void JNICALL6838Java_sun_awt_windows_WComponentPeer_reshapeNoCheck(JNIEnv *env, jobject self,6839jint x, jint y, jint w, jint h)6840{6841TRY;68426843ReshapeStruct *rs = new ReshapeStruct;6844rs->component = env->NewGlobalRef(self);6845rs->x = x;6846rs->y = y;6847rs->w = w;6848rs->h = h;68496850AwtToolkit::GetInstance().SyncCall(AwtComponent::_ReshapeNoCheck, rs);6851// global ref and rs are deleted in _ReshapeNoCheck68526853CATCH_BAD_ALLOC;6854}685568566857/*6858* Class: sun_awt_windows_WComponentPeer6859* Method: nativeHandleEvent6860* Signature: (Ljava/awt/AWTEvent;)V6861*/6862JNIEXPORT void JNICALL6863Java_sun_awt_windows_WComponentPeer_nativeHandleEvent(JNIEnv *env,6864jobject self,6865jobject event)6866{6867TRY;68686869jobject selfGlobalRef = env->NewGlobalRef(self);6870jobject eventGlobalRef = env->NewGlobalRef(event);68716872NativeHandleEventStruct *nhes = new NativeHandleEventStruct;6873nhes->component = selfGlobalRef;6874nhes->event = eventGlobalRef;68756876AwtToolkit::GetInstance().SyncCall(AwtComponent::_NativeHandleEvent, nhes);6877// global refs and nhes are deleted in _NativeHandleEvent68786879CATCH_BAD_ALLOC;6880}68816882/*6883* Class: sun_awt_windows_WComponentPeer6884* Method: _dispose6885* Signature: ()V6886*/6887JNIEXPORT void JNICALL6888Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self)6889{6890TRY_NO_HANG;68916892AwtObject::_Dispose(self);68936894CATCH_BAD_ALLOC;6895}68966897/*6898* Class: sun_awt_windows_WComponentPeer6899* Method: _setForeground6900* Signature: (I)V6901*/6902JNIEXPORT void JNICALL6903Java_sun_awt_windows_WComponentPeer__1setForeground(JNIEnv *env, jobject self,6904jint rgb)6905{6906TRY;69076908jobject selfGlobalRef = env->NewGlobalRef(self);69096910SetColorStruct *scs = new SetColorStruct;6911scs->component = selfGlobalRef;6912scs->rgb = rgb;69136914AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetForeground, scs);6915// selfGlobalRef and scs are deleted in _SetForeground()69166917CATCH_BAD_ALLOC;6918}69196920/*6921* Class: sun_awt_windows_WComponentPeer6922* Method: _setBackground6923* Signature: (I)V6924*/6925JNIEXPORT void JNICALL6926Java_sun_awt_windows_WComponentPeer__1setBackground(JNIEnv *env, jobject self,6927jint rgb)6928{6929TRY;69306931jobject selfGlobalRef = env->NewGlobalRef(self);69326933SetColorStruct *scs = new SetColorStruct;6934scs->component = selfGlobalRef;6935scs->rgb = rgb;69366937AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetBackground, scs);6938// selfGlobalRef and scs are deleted in _SetBackground()69396940CATCH_BAD_ALLOC;6941}69426943/*6944* Class: sun_awt_windows_WComponentPeer6945* Method: _setFont6946* Signature: (Ljava/awt/Font;)V6947*/6948JNIEXPORT void JNICALL6949Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self,6950jobject font)6951{6952TRY;69536954jobject selfGlobalRef = env->NewGlobalRef(self);6955jobject fontGlobalRef = env->NewGlobalRef(font);69566957SetFontStruct *sfs = new SetFontStruct;6958sfs->component = selfGlobalRef;6959sfs->font = fontGlobalRef;69606961AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetFont, sfs);6962// global refs and sfs are deleted in _SetFont()69636964CATCH_BAD_ALLOC;6965}69666967/*6968* Class: sun_awt_windows_WComponentPeer6969* Method: focusGained6970* Signature: (Z)6971*/6972JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus6973(JNIEnv *env, jobject self, jboolean doSetFocus)6974{6975TRY;69766977jobject selfGlobalRef = env->NewGlobalRef(self);69786979SetFocusStruct *sfs = new SetFocusStruct;6980sfs->component = selfGlobalRef;6981sfs->doSetFocus = doSetFocus;69826983AwtToolkit::GetInstance().SyncCall(6984(void*(*)(void*))AwtComponent::_SetFocus, sfs);6985// global refs and self are deleted in _SetFocus69866987CATCH_BAD_ALLOC;6988}69896990/*6991* Class: sun_awt_windows_WComponentPeer6992* Method: start6993* Signature: ()V6994*/6995JNIEXPORT void JNICALL6996Java_sun_awt_windows_WComponentPeer_start(JNIEnv *env, jobject self)6997{6998TRY;69997000jobject selfGlobalRef = env->NewGlobalRef(self);70017002AwtToolkit::GetInstance().SyncCall(AwtComponent::_Start, (void *)selfGlobalRef);7003// selfGlobalRef is deleted in _Start70047005CATCH_BAD_ALLOC;7006}70077008/*7009* Class: sun_awt_windows_WComponentPeer7010* Method: beginValidate7011* Signature: ()V7012*/7013JNIEXPORT void JNICALL7014Java_sun_awt_windows_WComponentPeer_beginValidate(JNIEnv *env, jobject self)7015{7016TRY;70177018jobject selfGlobalRef = env->NewGlobalRef(self);70197020AwtToolkit::GetInstance().SyncCall(AwtComponent::_BeginValidate, (void *)selfGlobalRef);7021// selfGlobalRef is deleted in _BeginValidate70227023CATCH_BAD_ALLOC;7024}70257026/*7027* Class: sun_awt_windows_WComponentPeer7028* Method: endValidate7029* Signature: ()V7030*/7031JNIEXPORT void JNICALL7032Java_sun_awt_windows_WComponentPeer_endValidate(JNIEnv *env, jobject self)7033{7034TRY;70357036jobject selfGlobalRef = env->NewGlobalRef(self);70377038AwtToolkit::GetInstance().SyncCall(AwtComponent::_EndValidate, (void *)selfGlobalRef);7039// selfGlobalRef is deleted in _EndValidate70407041CATCH_BAD_ALLOC;7042}70437044JNIEXPORT void JNICALL7045Java_sun_awt_windows_WComponentPeer_updateWindow(JNIEnv *env, jobject self)7046{7047TRY;70487049jobject selfGlobalRef = env->NewGlobalRef(self);70507051AwtToolkit::GetInstance().SyncCall(AwtComponent::_UpdateWindow, (void *)selfGlobalRef);7052// selfGlobalRef is deleted in _UpdateWindow70537054CATCH_BAD_ALLOC;7055}70567057/*7058* Class: sun_awt_windows_WComponentPeer7059* Method: addNativeDropTarget7060* Signature: ()L7061*/70627063JNIEXPORT jlong JNICALL7064Java_sun_awt_windows_WComponentPeer_addNativeDropTarget(JNIEnv *env,7065jobject self)7066{7067TRY;70687069jobject selfGlobalRef = env->NewGlobalRef(self);70707071return ptr_to_jlong(AwtToolkit::GetInstance().SyncCall(7072(void*(*)(void*))AwtComponent::_AddNativeDropTarget,7073(void *)selfGlobalRef));7074// selfGlobalRef is deleted in _AddNativeDropTarget70757076CATCH_BAD_ALLOC_RET(0);7077}70787079/*7080* Class: sun_awt_windows_WComponentPeer7081* Method: removeNativeDropTarget7082* Signature: ()V7083*/70847085JNIEXPORT void JNICALL7086Java_sun_awt_windows_WComponentPeer_removeNativeDropTarget(JNIEnv *env,7087jobject self)7088{7089TRY;70907091jobject selfGlobalRef = env->NewGlobalRef(self);70927093AwtToolkit::GetInstance().SyncCall(7094AwtComponent::_RemoveNativeDropTarget, (void *)selfGlobalRef);7095// selfGlobalRef is deleted in _RemoveNativeDropTarget70967097CATCH_BAD_ALLOC;7098}70997100/*7101* Class: sun_awt_windows_WComponentPeer7102* Method: getTargetGC7103* Signature: ()Ljava/awt/GraphicsConfiguration;7104*/7105JNIEXPORT jobject JNICALL7106Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis)7107{7108TRY;71097110jobject targetObj;7111jobject gc = 0;71127113targetObj = env->GetObjectField(theThis, AwtObject::targetID);7114DASSERT(targetObj);71157116gc = env->GetObjectField(targetObj, AwtComponent::graphicsConfigID);7117return gc;71187119CATCH_BAD_ALLOC_RET(NULL);7120}71217122/*7123* Class: sun_awt_windows_WComponentPeer7124* Method: createPrintedPixels7125* Signature: (IIIIII)I[7126*/7127JNIEXPORT jintArray JNICALL7128Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env,7129jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha)7130{7131TRY;71327133jobject selfGlobalRef = env->NewGlobalRef(self);71347135CreatePrintedPixelsStruct *cpps = new CreatePrintedPixelsStruct;7136cpps->component = selfGlobalRef;7137cpps->srcx = srcX;7138cpps->srcy = srcY;7139cpps->srcw = srcW;7140cpps->srch = srcH;7141cpps->alpha = alpha;71427143jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall(7144(void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps);7145// selfGlobalRef and cpps are deleted in _CreatePrintedPixels7146if (globalRef != NULL)7147{7148jintArray localRef = (jintArray)env->NewLocalRef(globalRef);7149env->DeleteGlobalRef(globalRef);7150return localRef;7151}7152else7153{7154return NULL;7155}71567157CATCH_BAD_ALLOC_RET(NULL);7158}71597160/*7161* Class: sun_awt_windows_WComponentPeer7162* Method: nativeHandlesWheelScrolling7163* Signature: ()Z7164*/7165JNIEXPORT jboolean JNICALL7166Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env,7167jobject self)7168{7169TRY;71707171return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(7172(void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling,7173env->NewGlobalRef(self)));7174// global ref is deleted in _NativeHandlesWheelScrolling71757176CATCH_BAD_ALLOC_RET(NULL);7177}71787179/*7180* Class: sun_awt_windows_WComponentPeer7181* Method: isObscured7182* Signature: ()Z7183*/7184JNIEXPORT jboolean JNICALL7185Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env,7186jobject self)7187{7188TRY;71897190jobject selfGlobalRef = env->NewGlobalRef(self);71917192return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(7193(void*(*)(void*))AwtComponent::_IsObscured,7194(void *)selfGlobalRef));7195// selfGlobalRef is deleted in _IsObscured71967197CATCH_BAD_ALLOC_RET(NULL);7198}71997200JNIEXPORT void JNICALL7201Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) {7202TRY;72037204SetParentStruct * data = new SetParentStruct;7205data->component = env->NewGlobalRef(self);7206data->parentComp = env->NewGlobalRef(parent);72077208AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetParent, data);7209// global refs and data are deleted in SetParent72107211CATCH_BAD_ALLOC;7212}72137214JNIEXPORT void JNICALL7215Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject self,7216jint x1, jint y1, jint x2, jint y2, jobject region)7217{7218TRY;72197220SetRectangularShapeStruct * data = new SetRectangularShapeStruct;7221data->component = env->NewGlobalRef(self);7222data->x1 = x1;7223data->x2 = x2;7224data->y1 = y1;7225data->y2 = y2;7226if (region) {7227data->region = env->NewGlobalRef(region);7228} else {7229data->region = NULL;7230}72317232AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetRectangularShape, data);7233// global refs and data are deleted in _SetRectangularShape72347235CATCH_BAD_ALLOC;7236}72377238JNIEXPORT void JNICALL7239Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above)7240{7241TRY;72427243SetZOrderStruct * data = new SetZOrderStruct;7244data->component = env->NewGlobalRef(self);7245data->above = above;72467247AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data);7248// global refs and data are deleted in _SetLower72497250CATCH_BAD_ALLOC;7251}72527253} /* extern "C" */725472557256/************************************************************************7257* Diagnostic routines7258*/72597260#ifdef DEBUG72617262void AwtComponent::VerifyState()7263{7264if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) {7265return;7266}72677268if (m_callbacksEnabled == FALSE) {7269/* Component is not fully setup yet. */7270return;7271}72727273/* Get target bounds. */7274JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);7275if (env->PushLocalFrame(10) < 0)7276return;72777278jobject target = GetTarget(env);72797280jint x = env->GetIntField(target, AwtComponent::xID);7281jint y = env->GetIntField(target, AwtComponent::yID);7282jint width = env->GetIntField(target, AwtComponent::widthID);7283jint height = env->GetIntField(target, AwtComponent::heightID);72847285/* Convert target origin to absolute coordinates */7286while (TRUE) {72877288jobject parent = env->GetObjectField(target, AwtComponent::parentID);7289if (parent == NULL) {7290break;7291}7292x += env->GetIntField(parent, AwtComponent::xID);7293y += env->GetIntField(parent, AwtComponent::yID);72947295/* If this component has insets, factor them in, but ignore7296* top-level windows.7297*/7298jobject parent2 = env->GetObjectField(parent, AwtComponent::parentID);7299if (parent2 != NULL) {7300jobject peer = GetPeerForTarget(env, parent);7301if (peer != NULL &&7302JNU_IsInstanceOfByName(env, peer,7303"sun/awt/windows/WPanelPeer") > 0) {7304jobject insets =7305JNU_CallMethodByName(env, NULL, peer,"insets",7306"()Ljava/awt/Insets;").l;7307x += (env)->GetIntField(insets, AwtInsets::leftID);7308y += (env)->GetIntField(insets, AwtInsets::topID);7309}7310}7311env->DeleteLocalRef(target);7312target = parent;7313}73147315x = ScaleUpX(x);7316y = ScaleUpY(y);7317width = ScaleUpX(width);7318height = ScaleUpY(height);73197320// Test whether component's bounds match the native window's7321RECT rect;7322VERIFY(::GetWindowRect(GetHWnd(), &rect));7323#if 07324DASSERT( (x == rect.left) &&7325(y == rect.top) &&7326(width == (rect.right-rect.left)) &&7327(height == (rect.bottom-rect.top)) );7328#else7329BOOL fSizeValid = ( (x == rect.left) &&7330(y == rect.top) &&7331(width == (rect.right-rect.left)) &&7332(height == (rect.bottom-rect.top)) );7333#endif73347335// See if visible state matches7336BOOL wndVisible = ::IsWindowVisible(GetHWnd());7337jboolean targetVisible;7338// To avoid possibly running client code on the toolkit thread, don't7339// do the following check if we're running on the toolkit thread.7340if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) {7341targetVisible = JNU_CallMethodByName(env, NULL, GetTarget(env),7342"isShowing", "()Z").z;7343DASSERT(!safe_ExceptionOccurred(env));7344} else {7345targetVisible = wndVisible ? 1 : 0;7346}7347#if 07348DASSERT( (targetVisible && wndVisible) ||7349(!targetVisible && !wndVisible) );7350#else7351BOOL fVisibleValid = ( (targetVisible && wndVisible) ||7352(!targetVisible && !wndVisible) );7353#endif73547355// Check enabled state7356BOOL wndEnabled = ::IsWindowEnabled(GetHWnd());7357jboolean enabled = (jboolean)env->GetBooleanField(target,7358AwtComponent::enabledID);7359#if 07360DASSERT( (enabled && wndEnabled) ||7361(!enabled && !wndEnabled) );7362#else7363BOOL fEnabledValid = ((enabled && wndEnabled) ||7364(!(enabled && !wndEnabled) ));73657366if (!fSizeValid || !fVisibleValid || !fEnabledValid) {7367printf("AwtComponent::ValidateState() failed:\n");7368// To avoid possibly running client code on the toolkit thread, don't7369// do the following call if we're running on the toolkit thread.7370if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) {7371jstring targetStr =7372(jstring)JNU_CallMethodByName(env, NULL, GetTarget(env),7373"getName",7374"()Ljava/lang/String;").l;7375DASSERT(!safe_ExceptionOccurred(env));7376LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL);7377printf("\t%S\n", targetStrW);7378JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW);7379}7380printf("\twas: [%d,%d,%dx%d]\n", x, y, width, height);7381if (!fSizeValid) {7382printf("\tshould be: [%d,%d,%dx%d]\n", rect.left, rect.top,7383rect.right-rect.left, rect.bottom-rect.top);7384}7385if (!fVisibleValid) {7386printf("\tshould be: %s\n",7387(targetVisible) ? "visible" : "hidden");7388}7389if (!fEnabledValid) {7390printf("\tshould be: %s\n",7391enabled ? "enabled" : "disabled");7392}7393}7394#endif7395env->PopLocalFrame(0);7396}7397#endif //DEBUG73987399// Methods for globally managed DC list74007401/**7402* Add a new DC to the DC list for this component.7403*/7404void DCList::AddDC(HDC hDC, HWND hWnd)7405{7406DCItem *newItem = new DCItem;7407newItem->hDC = hDC;7408newItem->hWnd = hWnd;7409AddDCItem(newItem);7410}74117412void DCList::AddDCItem(DCItem *newItem)7413{7414listLock.Enter();7415newItem->next = head;7416head = newItem;7417listLock.Leave();7418}74197420/**7421* Given a DC and window handle, remove the DC from the DC list7422* and return TRUE if it exists on the current list. Otherwise7423* return FALSE.7424* A DC may not exist on the list because it has already7425* been released elsewhere (for example, the window7426* destruction process may release a DC while a rendering7427* thread may also want to release a DC when it notices that7428* its DC is obsolete for the current window).7429*/7430DCItem *DCList::RemoveDC(HDC hDC, HWND hWnd)7431{7432listLock.Enter();7433DCItem **prevPtrPtr = &head;7434DCItem *listPtr = head;7435while (listPtr) {7436DCItem *nextPtr = listPtr->next;7437if (listPtr->hDC == hDC && listPtr->hWnd == hWnd) {7438*prevPtrPtr = nextPtr;7439break;7440}7441prevPtrPtr = &listPtr->next;7442listPtr = nextPtr;7443}7444listLock.Leave();7445return listPtr;7446}74477448/**7449* Remove all DCs from the DC list which are associated with7450* the same window as hWnd. Return the list of those7451* DC's to the caller (which will then probably want to7452* call ReleaseDC() for the returned DCs).7453*/7454DCItem *DCList::RemoveAllDCs(HWND hWnd)7455{7456listLock.Enter();7457DCItem **prevPtrPtr = &head;7458DCItem *listPtr = head;7459DCItem *newListPtr = NULL;7460BOOL ret = FALSE;7461while (listPtr) {7462DCItem *nextPtr = listPtr->next;7463if (listPtr->hWnd == hWnd) {7464*prevPtrPtr = nextPtr;7465listPtr->next = newListPtr;7466newListPtr = listPtr;7467} else {7468prevPtrPtr = &listPtr->next;7469}7470listPtr = nextPtr;7471}7472listLock.Leave();7473return newListPtr;7474}74757476/**7477* Remove all DCs from the DC list. Return the list of those7478* DC's to the caller (which will then probably want to7479* call ReleaseDC() for the returned DCs).7480*/7481DCItem *DCList::RemoveAllDCs()7482{7483listLock.Enter();7484DCItem *newListPtr = head;7485head = NULL;7486listLock.Leave();7487return newListPtr;7488}74897490/**7491* Realize palettes of all existing HDC objects7492*/7493void DCList::RealizePalettes(int screen)7494{7495listLock.Enter();7496DCItem *listPtr = head;7497while (listPtr) {7498AwtWin32GraphicsDevice::RealizePalette(listPtr->hDC, screen);7499listPtr = listPtr->next;7500}7501listLock.Leave();7502}75037504void MoveDCToPassiveList(HDC hDC, HWND hWnd) {7505DCItem *removedDC;7506if ((removedDC = activeDCList.RemoveDC(hDC, hWnd)) != NULL) {7507passiveDCList.AddDCItem(removedDC);7508}7509}75107511static void ReleaseDCList(DCItem *removedDCs) {7512while (removedDCs) {7513DCItem *tmpDCList = removedDCs;7514DASSERT(::GetObjectType(tmpDCList->hDC) == OBJ_DC);7515int retValue = ::ReleaseDC(tmpDCList->hWnd, tmpDCList->hDC);7516VERIFY(retValue != 0);7517if (retValue != 0) {7518// Valid ReleaseDC call; need to decrement GDI object counter7519AwtGDIObject::Decrement();7520}7521removedDCs = removedDCs->next;7522delete tmpDCList;7523}7524}75257526void ReleaseDCList(HWND hwnd, DCList &list) {7527ReleaseDCList(list.RemoveAllDCs(hwnd));7528}75297530void ReleaseDCList(DCList &list) {7531ReleaseDCList(list.RemoveAllDCs());7532}753375347535