       1 /*
       2  * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
       3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       4  *
       5  * This code is free software; you can redistribute it and/or modify it
       6  * under the terms of the GNU General Public License version 2 only, as
       7  * published by the Free Software Foundation.  Oracle designates this
       8  * particular file as subject to the "Classpath" exception as provided
       9  * by Oracle in the LICENSE file that accompanied this code.
      10  *
      11  * This code is distributed in the hope that it will be useful, but WITHOUT
      12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14  * version 2 for more details (a copy is included in the LICENSE file that
      15  * accompanied this code).
      16  *
      17  * You should have received a copy of the GNU General Public License version
      18  * 2 along with this work; if not, write to the Free Software Foundation,
      19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
      20  *
      21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
      22  * or visit www.oracle.com if you need additional information or have any
      23  * questions.
      24  */
      25
      26 #include "awt.h"
      27
      28 #include <windowsx.h>
      29 #include <zmouse.h>
      30
      31 #include "jlong.h"
      32 #include "awt_AWTEvent.h"
      33 #include "awt_BitmapUtil.h"
      34 #include "awt_Component.h"
      35 #include "awt_Cursor.h"
      36 #include "awt_Dimension.h"
      37 #include "awt_Frame.h"
      38 #include "awt_InputEvent.h"
      39 #include "awt_InputTextInfor.h"
      40 #include "awt_Insets.h"
      41 #include "awt_KeyEvent.h"
      42 #include "awt_MenuItem.h"
      43 #include "awt_MouseEvent.h"
      44 #include "awt_Palette.h"
      45 #include "awt_Toolkit.h"
      46 #include "awt_Window.h"
      47 #include "awt_Win32GraphicsDevice.h"
      48 #include "Hashtable.h"
      49 #include "ComCtl32Util.h"
      50
      51 #include <Region.h>
      52
      53 #include <jawt.h>
      54
      55 #include <java_awt_Toolkit.h>
      56 #include <java_awt_FontMetrics.h>
      57 #include <java_awt_Color.h>
      58 #include <java_awt_Event.h>
      59 #include <java_awt_event_KeyEvent.h>
      60 #include <java_awt_Insets.h>
      61 #include <sun_awt_windows_WPanelPeer.h>
      62 #include <java_awt_event_InputEvent.h>
      63 #include <java_awt_event_ActionEvent.h>
      64 #include <java_awt_event_InputMethodEvent.h>
      65 #include <sun_awt_windows_WInputMethod.h>
      66 #include <java_awt_event_MouseEvent.h>
      67 #include <java_awt_event_MouseWheelEvent.h>
      68
      69 // Begin -- Win32 SDK include files
      70 #include <imm.h>
      71 #include <ime.h>
      72 // End -- Win32 SDK include files
      73
      74 #include <awt_DnDDT.h>
      75
      76 LPCTSTR szAwtComponentClassName = TEXT("SunAwtComponent");
      77 // register a message that no other window in the process (even in a plugin
      78 // scenario) will be using
      79 const UINT AwtComponent::WmAwtIsComponent =
      80     ::RegisterWindowMessage(szAwtComponentClassName);
      81
      82 static HWND g_hwndDown = NULL;
      83 static DCList activeDCList;
      84 static DCList passiveDCList;
      85
      86 extern void CheckFontSmoothingSettings(HWND);
      87
      88 extern "C" {
      89     // Remember the input language has changed by some user's action
      90     // (Alt+Shift or through the language icon on the Taskbar) to control the
      91     // race condition between the toolkit thread and the AWT event thread.
      92     // This flag remains TRUE until the next WInputMethod.getNativeLocale() is
      93     // issued.
      94     BOOL g_bUserHasChangedInputLang = FALSE;
      95 }
      96
      97 BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE;
      98 BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE;
      99 HWND AwtComponent::sm_focusOwner = NULL;
     100 HWND AwtComponent::sm_focusedWindow = NULL;
     101 BOOL AwtComponent::sm_bMenuLoop = FALSE;
     102 BOOL AwtComponent::sm_inSynthesizeFocus = FALSE;
     103
     104 /************************************************************************/
     105 // Struct for _Reshape() and ReshapeNoCheck() methods
     106 struct ReshapeStruct {
     107     jobject component;
     108     jint x, y;
     109     jint w, h;
     110 };
     111 // Struct for _NativeHandleEvent() method
     112 struct NativeHandleEventStruct {
     113     jobject component;
     114     jobject event;
     115 };
     116 // Struct for _SetForeground() and _SetBackground() methods
     117 struct SetColorStruct {
     118     jobject component;
     119     jint rgb;
     120 };
     121 // Struct for _SetFont() method
     122 struct SetFontStruct {
     123     jobject component;
     124     jobject font;
     125 };
     126 // Struct for _CreatePrintedPixels() method
     127 struct CreatePrintedPixelsStruct {
     128     jobject component;
     129     int srcx, srcy;
     130     int srcw, srch;
     131     jint alpha;
     132 };
     133 // Struct for _SetRectangularShape() method
     134 struct SetRectangularShapeStruct {
     135     jobject component;
     136     jint x1, x2, y1, y2;
     137     jobject region;
     138 };
     139 // Struct for _GetInsets function
     140 struct GetInsetsStruct {
     141     jobject window;
     142     RECT *insets;
     143 };
     144 // Struct for _SetZOrder function
     145 struct SetZOrderStruct {
     146     jobject component;
     147     jlong above;
     148 };
     149 // Struct for _SetFocus function
     150 struct SetFocusStruct {
     151     jobject component;
     152     jboolean doSetFocus;
     153 };
     154 // Struct for _SetParent function
     155 struct SetParentStruct {
     156     jobject component;
     157     jobject parentComp;
     158 };
     159 /************************************************************************/
     160
     161 //////////////////////////////////////////////////////////////////////////
     162
     163 /*************************************************************************
     164  * AwtComponent fields
     165  */
     166
     167
     168 jfieldID AwtComponent::peerID;
     169 jfieldID AwtComponent::xID;
     170 jfieldID AwtComponent::yID;
     171 jfieldID AwtComponent::widthID;
     172 jfieldID AwtComponent::heightID;
     173 jfieldID AwtComponent::visibleID;
     174 jfieldID AwtComponent::backgroundID;
     175 jfieldID AwtComponent::foregroundID;
     176 jfieldID AwtComponent::enabledID;
     177 jfieldID AwtComponent::parentID;
     178 jfieldID AwtComponent::graphicsConfigID;
     179 jfieldID AwtComponent::peerGCID;
     180 jfieldID AwtComponent::focusableID;
     181 jfieldID AwtComponent::appContextID;
     182 jfieldID AwtComponent::cursorID;
     183 jfieldID AwtComponent::hwndID;
     184
     185 jmethodID AwtComponent::getFontMID;
     186 jmethodID AwtComponent::getToolkitMID;
     187 jmethodID AwtComponent::isEnabledMID;
     188 jmethodID AwtComponent::getLocationOnScreenMID;
     189 jmethodID AwtComponent::replaceSurfaceDataMID;
     190 jmethodID AwtComponent::replaceSurfaceDataLaterMID;
     191 jmethodID AwtComponent::disposeLaterMID;
     192
     193 HKL    AwtComponent::m_hkl = ::GetKeyboardLayout(0);
     194 LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0));
     195 UINT   AwtComponent::m_CodePage
     196                        = AwtComponent::LangToCodePage(m_idLang);
     197
     198 jint *AwtComponent::masks;
     199
     200 static BOOL bLeftShiftIsDown = false;
     201 static BOOL bRightShiftIsDown = false;
     202 static UINT lastShiftKeyPressed = 0; // init to safe value
     203
     204 // Added by waleed to initialize the RTL Flags
     205 BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC ||
     206                             PRIMARYLANGID(GetInputLanguage()) == LANG_HEBREW;
     207 BOOL AwtComponent::sm_rtlReadingOrder =
     208     PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC;
     209
     210 BOOL AwtComponent::sm_PrimaryDynamicTableBuilt = FALSE;
     211
     212 HWND AwtComponent::sm_cursorOn;
     213 BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;
     214
     215 CriticalSection windowMoveLock;
     216 BOOL windowMoveLockHeld = FALSE;
     217
     218 /************************************************************************
     219  * AwtComponent methods
     220  */
     221
     222 AwtComponent::AwtComponent()
     223 {
     224     m_mouseButtonClickAllowed = 0;
     225     m_touchDownOccurred = FALSE;
     226     m_touchUpOccurred = FALSE;
     227     m_touchDownPoint.x = m_touchDownPoint.y = 0;
     228     m_touchUpPoint.x = m_touchUpPoint.y = 0;
     229     m_callbacksEnabled = FALSE;
     230     m_hwnd = NULL;
     231
     232     m_colorForeground = 0;
     233     m_colorBackground = 0;
     234     m_backgroundColorSet = FALSE;
     235     m_penForeground = NULL;
     236     m_brushBackground = NULL;
     237     m_DefWindowProc = NULL;
     238     m_nextControlID = 1;
     239     m_childList = NULL;
     240     m_myControlID = 0;
     241     m_hdwp = NULL;
     242     m_validationNestCount = 0;
     243
     244     m_dropTarget = NULL;
     245
     246     m_InputMethod = NULL;
     247     m_useNativeCompWindow = TRUE;
     248     m_PendingLeadByte = 0;
     249     m_bitsCandType = 0;
     250
     251     windowMoveLockPosX = 0;
     252     windowMoveLockPosY = 0;
     253     windowMoveLockPosCX = 0;
     254     windowMoveLockPosCY = 0;
     255
     256     m_hCursorCache = NULL;
     257
     258     m_bSubclassed = FALSE;
     259     m_bPauseDestroy = FALSE;
     260
     261     m_MessagesProcessing = 0;
     262     m_wheelRotationAmountX = 0;
     263     m_wheelRotationAmountY = 0;
     264     if (!sm_PrimaryDynamicTableBuilt) {
     265         // do it once.
     266         AwtComponent::BuildPrimaryDynamicTable();
     267         sm_PrimaryDynamicTableBuilt = TRUE;
     268     }
     269
     270     deadKeyActive = FALSE;
     271 }
     272
     273 AwtComponent::~AwtComponent()
     274 {
     275     DASSERT(AwtToolkit::IsMainThread());
     276
     277     /*
     278      * All the messages for this component are processed, native
     279      * resources are freed, and Java object is not connected to
     280      * the native one anymore. So we can safely destroy component's
     281      * handle.
     282      */
     283     DestroyHWnd();
     284 }
     285
     286 void AwtComponent::Dispose()
     287 {
     288     DASSERT(AwtToolkit::IsMainThread());
     289
     290     // NOTE: in case the component/toplevel was focused, Java should
     291     // have already taken care of proper transferring it or clearing.
     292
     293     if (m_hdwp != NULL) {
     294     // end any deferred window positioning, regardless
     295     // of m_validationNestCount
     296         ::EndDeferWindowPos(m_hdwp);
     297     }
     298
     299     // Send final message to release all DCs associated with this component
     300     SendMessage(WM_AWT_RELEASE_ALL_DCS);
     301
     302     /* Stop message filtering. */
     303     UnsubclassHWND();
     304
     305     /* Release global ref to input method */
     306     SetInputMethod(NULL, TRUE);
     307
     308     if (m_childList != NULL) {
     309         delete m_childList;
     310         m_childList = NULL;
     311     }
     312
     313     DestroyDropTarget();
     314     ReleaseDragCapture(0);
     315
     316     if (m_myControlID != 0) {
     317         AwtComponent* parent = GetParent();
     318         if (parent != NULL)
     319             parent->RemoveChild(m_myControlID);
     320     }
     321
     322     ::RemoveProp(GetHWnd(), DrawingStateProp);
     323
     324     /* Release any allocated resources. */
     325     if (m_penForeground != NULL) {
     326         m_penForeground->Release();
     327         m_penForeground = NULL;
     328     }
     329     if (m_brushBackground != NULL) {
     330         m_brushBackground->Release();
     331         m_brushBackground = NULL;
     332     }
     333
     334     /* Disconnect all links. */
     335     UnlinkObjects();
     336
     337     if (m_bPauseDestroy) {
     338         // AwtComponent::WmNcDestroy could be released now
     339         m_bPauseDestroy = FALSE;
     340         m_hwnd = NULL;
     341     }
     342
     343     // The component instance is deleted using AwtObject::Dispose() method
     344     AwtObject::Dispose();
     345 }
     346
     347 /* store component pointer in window extra bytes */
     348 void AwtComponent::SetComponentInHWND() {
     349     DASSERT(::GetWindowLongPtr(GetHWnd(), GWLP_USERDATA) == NULL);
     350     ::SetWindowLongPtr(GetHWnd(), GWLP_USERDATA, (LONG_PTR)this);
     351 }
     352
     353 /*
     354  * static function to get AwtComponent pointer from hWnd --
     355  * you don't want to call this from inside a wndproc to avoid
     356  * infinite recursion
     357  */
     358 AwtComponent* AwtComponent::GetComponent(HWND hWnd) {
     359     // Requests for Toolkit hwnd resolution happen pretty often. Check first.
     360     if (hWnd == AwtToolkit::GetInstance().GetHWnd()) {
     361         return NULL;
     362     }
     363
     364     // check that it's an AWT component from the same toolkit as the caller
     365     if (::IsWindow(hWnd) &&
     366         AwtToolkit::MainThread() == ::GetWindowThreadProcessId(hWnd, NULL))
     367     {
     368         DASSERT(WmAwtIsComponent != 0);
     369         if (::SendMessage(hWnd, WmAwtIsComponent, 0, 0L)) {
     370             return GetComponentImpl(hWnd);
     371         }
     372     }
     373     return NULL;
     374 }
     375
     376 /*
     377  * static function to get AwtComponent pointer from hWnd--
     378  * different from GetComponent because caller knows the
     379  * hwnd is an AWT component hwnd
     380  */
     381 AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) {
     382     AwtComponent *component =
     383         (AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
     384     DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) );
     385     DASSERT(!component || component->GetHWnd() == hWnd );
     386     return component;
     387 }
     388
     389 /*
     390  * Single window proc for all the components. Delegates real work to
     391  * the component's WindowProc() member function.
     392  */
     393 LRESULT CALLBACK AwtComponent::WndProc(HWND hWnd, UINT message,
     394                                        WPARAM wParam, LPARAM lParam)
     395 {
     396     TRY;
     397
     398     AwtComponent * self = AwtComponent::GetComponentImpl(hWnd);
     399     if (self == NULL || self->GetHWnd() != hWnd ||
     400         message == WM_UNDOCUMENTED_CLIENTSHUTDOWN) // handle log-off gracefully
     401     {
     402         return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam);
     403     } else {
     404         return self->WindowProc(message, wParam, lParam);
     405     }
     406
     407     CATCH_BAD_ALLOC_RET(0);
     408 }
     409
     410 BOOL AwtComponent::IsFocusable() {
     411     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
     412     jobject peer = GetPeer(env);
     413     jobject target = env->GetObjectField(peer, AwtObject::targetID);
     414     BOOL res = env->GetBooleanField(target, focusableID);
     415     AwtWindow *pCont = GetContainer();
     416     if (pCont) {
     417         res &= pCont->IsFocusableWindow();
     418     }
     419     env->DeleteLocalRef(target);
     420     return res;
     421 }
     422
     423 /************************************************************************
     424  * AwtComponent dynamic methods
     425  *
     426  * Window class registration routines
     427  */
     428
     429 /*
     430  * Fix for 4964237: Win XP: Changing theme changes java dialogs title icon
     431  */
     432 void AwtComponent::FillClassInfo(WNDCLASSEX *lpwc)
     433 {
     434     lpwc->cbSize        = sizeof(WNDCLASSEX);
     435     lpwc->style         = 0L;//CS_OWNDC;
     436     lpwc->lpfnWndProc   = (WNDPROC)::DefWindowProc;
     437     lpwc->cbClsExtra    = 0;
     438     lpwc->cbWndExtra    = 0;
     439     lpwc->hInstance     = AwtToolkit::GetInstance().GetModuleHandle(),
     440     lpwc->hIcon         = AwtToolkit::GetInstance().GetAwtIcon();
     441     lpwc->hCursor       = NULL;
     442     lpwc->hbrBackground = NULL;
     443     lpwc->lpszMenuName  = NULL;
     444     lpwc->lpszClassName = GetClassName();
     445     //Fixed 6233560: PIT: Java Cup Logo on the title bar of top-level windows look blurred, Win32
     446     lpwc->hIconSm       = AwtToolkit::GetInstance().GetAwtIconSm();
     447 }
     448
     449 void AwtComponent::RegisterClass()
     450 {
     451     WNDCLASSEX wc;
     452     if (!::GetClassInfoEx(AwtToolkit::GetInstance().GetModuleHandle(), GetClassName(), &wc)) {
     453         FillClassInfo(&wc);
     454         ATOM ret = ::RegisterClassEx(&wc);
     455         DASSERT(ret != 0);
     456     }
     457 }
     458
     459 void AwtComponent::UnregisterClass()
     460 {
     461     ::UnregisterClass(GetClassName(), AwtToolkit::GetInstance().GetModuleHandle());
     462 }
     463
     464 /*
     465  * Copy the graphicsConfig reference from Component into WComponentPeer
     466  */
     467 void AwtComponent::InitPeerGraphicsConfig(JNIEnv *env, jobject peer)
     468 {
     469     jobject target = env->GetObjectField(peer, AwtObject::targetID);
     470     //Get graphicsConfig object ref from Component
     471     jobject compGC = env->GetObjectField(target,
     472                       AwtComponent::graphicsConfigID);
     473
     474     //Set peer's graphicsConfig to Component's graphicsConfig
     475     if (compGC != NULL) {
     476         jclass win32GCCls = env->FindClass("sun/awt/Win32GraphicsConfig");
     477         DASSERT(win32GCCls != NULL);
     478         DASSERT(env->IsInstanceOf(compGC, win32GCCls));
     479         if (win32GCCls == NULL) {
     480             throw std::bad_alloc();
     481         }
     482         env->SetObjectField(peer, AwtComponent::peerGCID, compGC);
     483     }
     484 }
     485
     486 void
     487 AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title,
     488                          DWORD windowStyle,
     489                          DWORD windowExStyle,
     490                          int x, int y, int w, int h,
     491                          HWND hWndParent, HMENU hMenu,
     492                          COLORREF colorForeground,
     493                          COLORREF colorBackground,
     494                          jobject peer)
     495 {
     496     if (env->EnsureLocalCapacity(2) < 0) {
     497         return;
     498     }
     499
     500     /*
     501      * The window class of multifont label must be "BUTTON" because
     502      * "STATIC" class can't get WM_DRAWITEM message, and m_peerObject
     503      * member is referred in the GetClassName method of AwtLabel class.
     504      * So m_peerObject member must be set here.
     505      */
     506     if (m_peerObject == NULL) {
     507         m_peerObject = env->NewGlobalRef(peer);
     508     } else {
     509         assert(env->IsSameObject(m_peerObject, peer));
     510     }
     511
     512     RegisterClass();
     513
     514     jobject target = env->GetObjectField(peer, AwtObject::targetID);
     515     jboolean visible = env->GetBooleanField(target, AwtComponent::visibleID);
     516     m_visible = visible;
     517
     518     if (visible) {
     519         windowStyle |= WS_VISIBLE;
     520     } else {
     521         windowStyle &= ~WS_VISIBLE;
     522     }
     523
     524     InitPeerGraphicsConfig(env, peer);
     525
     526     SetLastError(0);
     527     HWND hwnd = ::CreateWindowEx(windowExStyle,
     528                                  GetClassName(),
     529                                  title,
     530                                  windowStyle,
     531                                  x, y, w, h,
     532                                  hWndParent,
     533                                  hMenu,
     534                                  AwtToolkit::GetInstance().GetModuleHandle(),
     535                                  NULL);
     536
     537     // fix for 5088782
     538     // check if CreateWindowsEx() returns not null value and if it does -
     539     //   create an InternalError or OutOfMemoryError based on GetLastError().
     540     //   This error is set to createError field of WObjectPeer and then
     541     //   checked and thrown in WComponentPeer constructor. We can't throw an
     542     //   error here because this code is invoked on Toolkit thread
     543     if (hwnd == NULL)
     544     {
     545         DWORD dw = ::GetLastError();
     546         jobject createError = NULL;
     547         if (dw == ERROR_OUTOFMEMORY)
     548         {
     549             jstring errorMsg = JNU_NewStringPlatform(env, L"too many window handles");
     550             if (errorMsg == NULL || env->ExceptionCheck()) {
     551                 env->ExceptionClear();
     552                 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", "()V");
     553             } else {
     554                 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError",
     555                                                       "(Ljava/lang/String;)V",
     556                                                       errorMsg);
     557                 env->DeleteLocalRef(errorMsg);
     558             }
     559         }
     560         else
     561         {
     562             TCHAR *buf;
     563             FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
     564                 NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
     565                 (LPTSTR)&buf, 0, NULL);
     566             jstring s = JNU_NewStringPlatform(env, buf);
     567             if (s == NULL || env->ExceptionCheck()) {
     568                 env->ExceptionClear();
     569                 createError = JNU_NewObjectByName(env, "java/lang/InternalError", "()V");
     570             } else {
     571                 createError = JNU_NewObjectByName(env, "java/lang/InternalError",
     572                                                                   "(Ljava/lang/String;)V", s);
     573                 env->DeleteLocalRef(s);
     574             }
     575             LocalFree(buf);
     576         }
     577         if (createError != NULL) {
     578             env->SetObjectField(peer, AwtObject::createErrorID, createError);
     579             env->DeleteLocalRef(createError);
     580         }
     581         env->DeleteLocalRef(target);
     582         return;
     583     }
     584
     585     m_hwnd = hwnd;
     586
     587     ::ImmAssociateContext(m_hwnd, NULL);
     588
     589     SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED |
     590         (jint)JAWT_LOCK_BOUNDS_CHANGED |
     591         (jint)JAWT_LOCK_CLIP_CHANGED);
     592
     593     LinkObjects(env, peer);
     594
     595     /* Subclass the window now so that we can snoop on its messages */
     596     SubclassHWND();
     597
     598     AwtToolkit& tk = AwtToolkit::GetInstance();
     599     if (tk.IsWin8OrLater() && tk.IsTouchKeyboardAutoShowEnabled()) {
     600         tk.TIRegisterTouchWindow(GetHWnd(), TWF_WANTPALM);
     601     }
     602
     603     /*
     604       * Fix for 4046446.
     605       */
     606     SetWindowPos(GetHWnd(), 0, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE);
     607
     608     /* Set default colors. */
     609     m_colorForeground = colorForeground;
     610     m_colorBackground = colorBackground;
     611
     612     /*
     613      * Only set background color if the color is actually set on the
     614      * target -- this avoids inheriting a parent's color unnecessarily,
     615      * and has to be done here because there isn't an API to get the
     616      * real background color from outside the AWT package.
     617      */
     618     jobject bkgrd = env->GetObjectField(target, AwtComponent::backgroundID) ;
     619     if (bkgrd != NULL) {
     620         JNU_CallMethodByName(env, NULL, peer, "setBackground",
     621                              "(Ljava/awt/Color;)V", bkgrd);
     622         DASSERT(!safe_ExceptionOccurred(env));
     623     }
     624     env->DeleteLocalRef(target);
     625     env->DeleteLocalRef(bkgrd);
     626 }
     627
     628 /*
     629  * Destroy this window's HWND
     630  */
     631 void AwtComponent::DestroyHWnd() {
     632     if (m_hwnd != NULL) {
     633         AwtToolkit::DestroyComponentHWND(m_hwnd);
     634         //AwtToolkit::DestroyComponent(this);
     635         m_hwnd = NULL;
     636     }
     637 }
     638
     639 /*
     640  * Returns hwnd for target on non Toolkit thread
     641  */
     642 HWND
     643 AwtComponent::GetHWnd(JNIEnv* env, jobject target) {
     644     if (JNU_IsNull(env, target)) {
     645         return 0;
     646     }
     647     jobject peer = env->GetObjectField(target, AwtComponent::peerID);
     648     if (JNU_IsNull(env, peer)) {
     649         return 0;
     650     }
     651     HWND hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR> (
     652         env->GetLongField(peer, AwtComponent::hwndID)));
     653     env->DeleteLocalRef(peer);
     654     return hwnd;
     655 }
     656 //
     657 // Propagate the background color to synchronize Java field and peer's field.
     658 // This is needed to fix 4148334
     659 //
     660 void AwtComponent::UpdateBackground(JNIEnv *env, jobject target)
     661 {
     662     if (env->EnsureLocalCapacity(1) < 0) {
     663         return;
     664     }
     665
     666     jobject bkgrnd = env->GetObjectField(target, AwtComponent::backgroundID);
     667
     668     if (bkgrnd == NULL) {
     669         bkgrnd = JNU_NewObjectByName(env, "java/awt/Color", "(III)V",
     670                                      GetRValue(m_colorBackground),
     671                                      GetGValue(m_colorBackground),
     672                                      GetBValue(m_colorBackground));
     673         if (bkgrnd != NULL) {
     674             env->SetObjectField(target, AwtComponent::backgroundID, bkgrnd);
     675         }
     676     }
     677     env->DeleteLocalRef(bkgrnd);
     678 }
     679
     680 /*
     681  * Install our window proc as the proc for our HWND, and save off the
     682  * previous proc as the default
     683  */
     684 void AwtComponent::SubclassHWND()
     685 {
     686     if (m_bSubclassed) {
     687         return;
     688     }
     689     const WNDPROC wndproc = WndProc; // let compiler type check WndProc
     690     m_DefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc);
     691     m_bSubclassed = TRUE;
     692 }
     693
     694 /*
     695  * Reinstall the original window proc as the proc for our HWND
     696  */
     697 void AwtComponent::UnsubclassHWND()
     698 {
     699     if (!m_bSubclassed) {
     700         return;
     701     }
     702     ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc, m_DefWindowProc);
     703     m_bSubclassed = FALSE;
     704 }
     705
     706 /////////////////////////////////////
     707 // (static method)
     708 // Determines the top-level ancestor for a given window. If the given
     709 // window is a top-level window, return itself.
     710 //
     711 // 'Top-level' includes dialogs as well.
     712 //
     713 HWND AwtComponent::GetTopLevelParentForWindow(HWND hwndDescendant) {
     714     if (hwndDescendant == NULL) {
     715         return NULL;
     716     }
     717
     718     DASSERT(IsWindow(hwndDescendant));
     719     HWND hwnd = hwndDescendant;
     720     for(;;) {
     721         DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
     722         // a) found a non-child window so terminate
     723         // b) found real toplevel window (e.g. EmbeddedFrame
     724         //    that is child though)
     725         if ( (style & WS_CHILD) == 0 ||
     726              AwtComponent::IsTopLevelHWnd(hwnd) )
     727         {
     728             break;
     729         }
     730         hwnd = ::GetParent(hwnd);
     731     }
     732
     733     return hwnd;
     734 }
     735 ////////////////////
     736
     737 jobject AwtComponent::FindHeavyweightUnderCursor(BOOL useCache) {
     738     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
     739     if (env->EnsureLocalCapacity(1) < 0) {
     740         return NULL;
     741     }
     742
     743     HWND hit = NULL;
     744     POINT p = { 0, 0 };
     745     AwtComponent *comp = NULL;
     746
     747     if (useCache) {
     748         if (sm_cursorOn == NULL) {
     749             return NULL;
     750         }
     751
     752
     753         DASSERT(::IsWindow(sm_cursorOn));
     754         VERIFY(::GetCursorPos(&p));
     755         /*
     756          * Fix for BugTraq ID 4304024.
     757          * Allow a non-default cursor only for the client area.
     758          */
     759         comp = AwtComponent::GetComponent(sm_cursorOn);
     760         if (comp != NULL &&
     761             ::SendMessage(sm_cursorOn, WM_NCHITTEST, 0,
     762                           MAKELPARAM(p.x, p.y)) == HTCLIENT) {
     763             goto found;
     764         }
     765     }
     766
     767     ::GetCursorPos(&p);
     768     hit = ::WindowFromPoint(p);
     769     while (hit != NULL) {
     770         comp = AwtComponent::GetComponent(hit);
     771
     772         if (comp != NULL) {
     773             INT nHittest = (INT)::SendMessage(hit, WM_NCHITTEST,
     774                                           0, MAKELPARAM(p.x, p.y));
     775             /*
     776              * Fix for BugTraq ID 4304024.
     777              * Allow a non-default cursor only for the client area.
     778              */
     779             if (nHittest != HTCLIENT) {
     780                 /*
     781                  * When over the non-client area, send WM_SETCURSOR
     782                  * to revert the cursor to an arrow.
     783                  */
     784                 ::SendMessage(hit, WM_SETCURSOR, (WPARAM)hit,
     785                               MAKELPARAM(nHittest, WM_MOUSEMOVE));
     786                 return NULL;
     787             } else {
     788               sm_cursorOn = hit;
     789               goto found;
     790             }
     791         }
     792
     793         if ((::GetWindowLong(hit, GWL_STYLE) & WS_CHILD) == 0) {
     794             return NULL;
     795         }
     796         hit = ::GetParent(hit);
     797     }
     798
     799     return NULL;
     800
     801 found:
     802     jobject localRef = comp->GetTarget(env);
     803     jobject globalRef = env->NewGlobalRef(localRef);
     804     env->DeleteLocalRef(localRef);
     805     return globalRef;
     806 }
     807
     808 void AwtComponent::SetColor(COLORREF c)
     809 {
     810     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
     811     int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen);
     812     if (grayscale != GS_NOTGRAY) {
     813         int g;
     814
     815         g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) +
     816             .114 * ((c >> 16) & 0xFF) + 0.5);
     817         // c = g | (g << 8) | (g << 16);
     818         c = PALETTERGB(g, g, g);
     819     }
     820
     821     if (m_colorForeground == c) {
     822         return;
     823     }
     824
     825     m_colorForeground = c;
     826     if (m_penForeground != NULL) {
     827         m_penForeground->Release();
     828         m_penForeground = NULL;
     829     }
     830     VERIFY(::InvalidateRect(GetHWnd(), NULL, FALSE));
     831 }
     832
     833 void AwtComponent::SetBackgroundColor(COLORREF c)
     834 {
     835     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
     836     int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen);
     837     if (grayscale != GS_NOTGRAY) {
     838         int g;
     839
     840         g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) +
     841             .114 * ((c >> 16) & 0xFF) + 0.5);
     842         // c = g | (g << 8) | (g << 16);
     843         c = PALETTERGB(g, g, g);
     844     }
     845
     846     if (m_colorBackground == c) {
     847         return;
     848     }
     849     m_colorBackground = c;
     850     m_backgroundColorSet = TRUE;
     851     if (m_brushBackground != NULL) {
     852         m_brushBackground->Release();
     853         m_brushBackground = NULL;
     854     }
     855     VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE));
     856 }
     857
     858 HPEN AwtComponent::GetForegroundPen()
     859 {
     860     if (m_penForeground == NULL) {
     861         m_penForeground = AwtPen::Get(m_colorForeground);
     862     }
     863     return (HPEN)m_penForeground->GetHandle();
     864 }
     865
     866 COLORREF AwtComponent::GetBackgroundColor()
     867 {
     868     if (m_backgroundColorSet == FALSE) {
     869         AwtComponent* c = this;
     870         while ((c = c->GetParent()) != NULL) {
     871             if (c->IsBackgroundColorSet()) {
     872                 return c->GetBackgroundColor();
     873             }
     874         }
     875     }
     876     return m_colorBackground;
     877 }
     878
     879 HBRUSH AwtComponent::GetBackgroundBrush()
     880 {
     881     if (m_backgroundColorSet == FALSE) {
     882         if (m_brushBackground != NULL) {
     883             m_brushBackground->Release();
     884             m_brushBackground = NULL;
     885         }
     886           AwtComponent* c = this;
     887           while ((c = c->GetParent()) != NULL) {
     888               if (c->IsBackgroundColorSet()) {
     889                   m_brushBackground =
     890                       AwtBrush::Get(c->GetBackgroundColor());
     891                   break;
     892               }
     893           }
     894     }
     895     if (m_brushBackground == NULL) {
     896         m_brushBackground = AwtBrush::Get(m_colorBackground);
     897     }
     898     return (HBRUSH)m_brushBackground->GetHandle();
     899 }
     900
     901 void AwtComponent::SetFont(AwtFont* font)
     902 {
     903     DASSERT(font != NULL);
     904     if (font->GetAscent() < 0) {
     905         AwtFont::SetupAscent(font);
     906     }
     907     SendMessage(WM_SETFONT, (WPARAM)font->GetHFont(), MAKELPARAM(FALSE, 0));
     908     VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE));
     909 }
     910
     911 AwtComponent* AwtComponent::GetParent()
     912 {
     913     HWND hwnd = ::GetParent(GetHWnd());
     914     if (hwnd == NULL) {
     915         return NULL;
     916     }
     917     return GetComponent(hwnd);
     918 }
     919
     920 AwtWindow* AwtComponent::GetContainer()
     921 {
     922     AwtComponent* comp = this;
     923     while (comp != NULL) {
     924         if (comp->IsContainer()) {
     925             return (AwtWindow*)comp;
     926         }
     927         comp = comp->GetParent();
     928     }
     929     return NULL;
     930 }
     931
     932 void AwtComponent::Show()
     933 {
     934     m_visible = true;
     935     ::ShowWindow(GetHWnd(), SW_SHOWNA);
     936 }
     937
     938 void AwtComponent::Hide()
     939 {
     940     m_visible = false;
     941     ::ShowWindow(GetHWnd(), SW_HIDE);
     942 }
     943
     944 BOOL
     945 AwtComponent::SetWindowPos(HWND wnd, HWND after,
     946                            int x, int y, int w, int h, UINT flags)
     947 {
     948     // Conditions we shouldn't handle:
     949     // z-order changes, correct window dimensions
     950     if (after != NULL || (w < 32767 && h < 32767)
     951         || ((::GetWindowLong(wnd, GWL_STYLE) & WS_CHILD) == 0))
     952     {
     953         return ::SetWindowPos(wnd, after, x, y, w, h, flags);
     954     }
     955     WINDOWPLACEMENT wp;
     956     ::ZeroMemory(&wp, sizeof(wp));
     957
     958     wp.length = sizeof(wp);
     959     ::GetWindowPlacement(wnd, &wp);
     960     wp.rcNormalPosition.left = x;
     961     wp.rcNormalPosition.top = y;
     962     wp.rcNormalPosition.right = x + w;
     963     wp.rcNormalPosition.bottom = y + h;
     964     if ( flags & SWP_NOACTIVATE ) {
     965         wp.showCmd = SW_SHOWNOACTIVATE;
     966     }
     967     ::SetWindowPlacement(wnd, &wp);
     968     return 1;
     969 }
     970
     971 void AwtComponent::Reshape(int x, int y, int w, int h) {
     972     ReshapeNoScale(ScaleUpX(x), ScaleUpY(y), ScaleUpX(w), ScaleUpY(h));
     973 }
     974
     975 void AwtComponent::ReshapeNoScale(int x, int y, int w, int h)
     976 {
     977 #if defined(DEBUG)
     978     RECT        rc;
     979     ::GetWindowRect(GetHWnd(), &rc);
     980     ::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2);
     981     DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
     982 #endif
     983
     984     AwtWindow* container = GetContainer();
     985     AwtComponent* parent = GetParent();
     986     if (container != NULL && container == parent) {
     987         container->SubtractInsetPoint(x, y);
     988     }
     989     DTRACE_PRINTLN4("AwtComponent::Reshape to %d, %d, %d, %d", x, y, w, h);
     990     UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
     991
     992     RECT        r;
     993
     994     ::GetWindowRect(GetHWnd(), &r);
     995     // if the component size is changing , don't copy window bits
     996     if (r.right - r.left != w || r.bottom - r.top != h) {
     997         flags |= SWP_NOCOPYBITS;
     998     }
     999
    1000     if (parent && _tcscmp(parent->GetClassName(), TEXT("SunAwtScrollPane")) == 0) {
    1001         if (x > 0) {
    1002             x = 0;
    1003         }
    1004         if (y > 0) {
    1005             y = 0;
    1006         }
    1007     }
    1008     if (m_hdwp != NULL) {
    1009         m_hdwp = ::DeferWindowPos(m_hdwp, GetHWnd(), 0, x, y, w, h, flags);
    1010         DASSERT(m_hdwp != NULL);
    1011     } else {
    1012         /*
    1013          * Fox for 4046446
    1014          * If window has dimensions above the short int limit, ::SetWindowPos doesn't work.
    1015          * We should use SetWindowPlacement instead.
    1016          */
    1017         SetWindowPos(GetHWnd(), 0, x, y, w, h, flags);
    1018     }
    1019 }
    1020
    1021 void AwtComponent::SetScrollValues(UINT bar, int min, int value, int max)
    1022 {
    1023     int minTmp, maxTmp;
    1024
    1025     ::GetScrollRange(GetHWnd(), bar, &minTmp, &maxTmp);
    1026     if (min == INT_MAX) {
    1027         min = minTmp;
    1028     }
    1029     if (value == INT_MAX) {
    1030         value = ::GetScrollPos(GetHWnd(), bar);
    1031     }
    1032     if (max == INT_MAX) {
    1033         max = maxTmp;
    1034     }
    1035     if (min == max) {
    1036         max++;
    1037     }
    1038     ::SetScrollRange(GetHWnd(), bar, min, max, FALSE);
    1039     ::SetScrollPos(GetHWnd(), bar, value, TRUE);
    1040 }
    1041
    1042 /*
    1043  * Save Global Reference of sun.awt.windows.WInputMethod object
    1044  */
    1045 void AwtComponent::SetInputMethod(jobject im, BOOL useNativeCompWindow)
    1046 {
    1047     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    1048
    1049     if (m_InputMethod!=NULL)
    1050         env->DeleteGlobalRef(m_InputMethod);
    1051
    1052     if (im!=NULL){
    1053         m_InputMethod = env->NewGlobalRef(im);
    1054         m_useNativeCompWindow = useNativeCompWindow;
    1055     } else {
    1056         m_InputMethod = NULL;
    1057         m_useNativeCompWindow = TRUE;
    1058     }
    1059
    1060 }
    1061
    1062 /*
    1063  * Opportunity to process and/or eat a message before it is dispatched
    1064  */
    1065 MsgRouting AwtComponent::PreProcessMsg(MSG& msg)
    1066 {
    1067     return mrPassAlong;
    1068 }
    1069
    1070 static UINT lastMessage = WM_NULL;
    1071
    1072 #ifndef SPY_MESSAGES
    1073 #define SpyWinMessage(hwin,msg,str)
    1074 #else
    1075
    1076 #define FMT_MSG(x,y) case x: _stprintf(szBuf, \
    1077     "0x%8.8x(%s):%s\n", hwnd, szComment, y); break;
    1078 #define WIN_MSG(x) FMT_MSG(x,#x)
    1079
    1080 void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) {
    1081
    1082     TCHAR szBuf[256];
    1083
    1084     switch (message) {
    1085         WIN_MSG(WM_NULL)
    1086         WIN_MSG(WM_CREATE)
    1087         WIN_MSG(WM_DESTROY)
    1088         WIN_MSG(WM_MOVE)
    1089         WIN_MSG(WM_SIZE)
    1090         WIN_MSG(WM_ACTIVATE)
    1091         WIN_MSG(WM_SETFOCUS)
    1092         WIN_MSG(WM_KILLFOCUS)
    1093         WIN_MSG(WM_ENABLE)
    1094         WIN_MSG(WM_SETREDRAW)
    1095         WIN_MSG(WM_SETTEXT)
    1096         WIN_MSG(WM_GETTEXT)
    1097         WIN_MSG(WM_GETTEXTLENGTH)
    1098         WIN_MSG(WM_PAINT)
    1099         WIN_MSG(WM_CLOSE)
    1100         WIN_MSG(WM_QUERYENDSESSION)
    1101         WIN_MSG(WM_QUIT)
    1102         WIN_MSG(WM_QUERYOPEN)
    1103         WIN_MSG(WM_ERASEBKGND)
    1104         WIN_MSG(WM_SYSCOLORCHANGE)
    1105         WIN_MSG(WM_ENDSESSION)
    1106         WIN_MSG(WM_SHOWWINDOW)
    1107         FMT_MSG(WM_WININICHANGE,"WM_WININICHANGE/WM_SETTINGCHANGE")
    1108         WIN_MSG(WM_DEVMODECHANGE)
    1109         WIN_MSG(WM_ACTIVATEAPP)
    1110         WIN_MSG(WM_FONTCHANGE)
    1111         WIN_MSG(WM_TIMECHANGE)
    1112         WIN_MSG(WM_CANCELMODE)
    1113         WIN_MSG(WM_SETCURSOR)
    1114         WIN_MSG(WM_MOUSEACTIVATE)
    1115         WIN_MSG(WM_CHILDACTIVATE)
    1116         WIN_MSG(WM_QUEUESYNC)
    1117         WIN_MSG(WM_GETMINMAXINFO)
    1118         WIN_MSG(WM_PAINTICON)
    1119         WIN_MSG(WM_ICONERASEBKGND)
    1120         WIN_MSG(WM_NEXTDLGCTL)
    1121         WIN_MSG(WM_SPOOLERSTATUS)
    1122         WIN_MSG(WM_DRAWITEM)
    1123         WIN_MSG(WM_MEASUREITEM)
    1124         WIN_MSG(WM_DELETEITEM)
    1125         WIN_MSG(WM_VKEYTOITEM)
    1126         WIN_MSG(WM_CHARTOITEM)
    1127         WIN_MSG(WM_SETFONT)
    1128         WIN_MSG(WM_GETFONT)
    1129         WIN_MSG(WM_SETHOTKEY)
    1130         WIN_MSG(WM_GETHOTKEY)
    1131         WIN_MSG(WM_QUERYDRAGICON)
    1132         WIN_MSG(WM_COMPAREITEM)
    1133         FMT_MSG(0x003D, "WM_GETOBJECT")
    1134         WIN_MSG(WM_COMPACTING)
    1135         WIN_MSG(WM_COMMNOTIFY)
    1136         WIN_MSG(WM_WINDOWPOSCHANGING)
    1137         WIN_MSG(WM_WINDOWPOSCHANGED)
    1138         WIN_MSG(WM_POWER)
    1139         WIN_MSG(WM_COPYDATA)
    1140         WIN_MSG(WM_CANCELJOURNAL)
    1141         WIN_MSG(WM_NOTIFY)
    1142         WIN_MSG(WM_INPUTLANGCHANGEREQUEST)
    1143         WIN_MSG(WM_INPUTLANGCHANGE)
    1144         WIN_MSG(WM_TCARD)
    1145         WIN_MSG(WM_HELP)
    1146         WIN_MSG(WM_USERCHANGED)
    1147         WIN_MSG(WM_NOTIFYFORMAT)
    1148         WIN_MSG(WM_CONTEXTMENU)
    1149         WIN_MSG(WM_STYLECHANGING)
    1150         WIN_MSG(WM_STYLECHANGED)
    1151         WIN_MSG(WM_DISPLAYCHANGE)
    1152         WIN_MSG(WM_GETICON)
    1153         WIN_MSG(WM_SETICON)
    1154         WIN_MSG(WM_NCCREATE)
    1155         WIN_MSG(WM_NCDESTROY)
    1156         WIN_MSG(WM_NCCALCSIZE)
    1157         WIN_MSG(WM_NCHITTEST)
    1158         WIN_MSG(WM_NCPAINT)
    1159         WIN_MSG(WM_NCACTIVATE)
    1160         WIN_MSG(WM_GETDLGCODE)
    1161         WIN_MSG(WM_SYNCPAINT)
    1162         WIN_MSG(WM_NCMOUSEMOVE)
    1163         WIN_MSG(WM_NCLBUTTONDOWN)
    1164         WIN_MSG(WM_NCLBUTTONUP)
    1165         WIN_MSG(WM_NCLBUTTONDBLCLK)
    1166         WIN_MSG(WM_NCRBUTTONDOWN)
    1167         WIN_MSG(WM_NCRBUTTONUP)
    1168         WIN_MSG(WM_NCRBUTTONDBLCLK)
    1169         WIN_MSG(WM_NCMBUTTONDOWN)
    1170         WIN_MSG(WM_NCMBUTTONUP)
    1171         WIN_MSG(WM_NCMBUTTONDBLCLK)
    1172         WIN_MSG(WM_KEYDOWN)
    1173         WIN_MSG(WM_KEYUP)
    1174         WIN_MSG(WM_CHAR)
    1175         WIN_MSG(WM_DEADCHAR)
    1176         WIN_MSG(WM_SYSKEYDOWN)
    1177         WIN_MSG(WM_SYSKEYUP)
    1178         WIN_MSG(WM_SYSCHAR)
    1179         WIN_MSG(WM_SYSDEADCHAR)
    1180         WIN_MSG(WM_IME_STARTCOMPOSITION)
    1181         WIN_MSG(WM_IME_ENDCOMPOSITION)
    1182         WIN_MSG(WM_IME_COMPOSITION)
    1183         WIN_MSG(WM_INITDIALOG)
    1184         WIN_MSG(WM_COMMAND)
    1185         WIN_MSG(WM_SYSCOMMAND)
    1186         WIN_MSG(WM_TIMER)
    1187         WIN_MSG(WM_HSCROLL)
    1188         WIN_MSG(WM_VSCROLL)
    1189         WIN_MSG(WM_INITMENU)
    1190         WIN_MSG(WM_INITMENUPOPUP)
    1191         WIN_MSG(WM_MENUSELECT)
    1192         WIN_MSG(WM_MENUCHAR)
    1193         WIN_MSG(WM_ENTERIDLE)
    1194         FMT_MSG(0x0122, "WM_MENURBUTTONUP")
    1195         FMT_MSG(0x0123, "WM_MENUDRAG")
    1196         FMT_MSG(0x0124, "WM_MENUGETOBJECT")
    1197         FMT_MSG(0x0125, "WM_UNINITMENUPOPUP")
    1198         FMT_MSG(0x0126, "WM_MENUCOMMAND")
    1199         WIN_MSG(WM_CTLCOLORMSGBOX)
    1200         WIN_MSG(WM_CTLCOLOREDIT)
    1201         WIN_MSG(WM_CTLCOLORLISTBOX)
    1202         WIN_MSG(WM_CTLCOLORBTN)
    1203         WIN_MSG(WM_CTLCOLORDLG)
    1204         WIN_MSG(WM_CTLCOLORSCROLLBAR)
    1205         WIN_MSG(WM_CTLCOLORSTATIC)
    1206         WIN_MSG(WM_MOUSEMOVE)
    1207         WIN_MSG(WM_LBUTTONDOWN)
    1208         WIN_MSG(WM_LBUTTONUP)
    1209         WIN_MSG(WM_LBUTTONDBLCLK)
    1210         WIN_MSG(WM_RBUTTONDOWN)
    1211         WIN_MSG(WM_RBUTTONUP)
    1212         WIN_MSG(WM_RBUTTONDBLCLK)
    1213         WIN_MSG(WM_MBUTTONDOWN)
    1214         WIN_MSG(WM_MBUTTONUP)
    1215         WIN_MSG(WM_MBUTTONDBLCLK)
    1216         WIN_MSG(WM_XBUTTONDBLCLK)
    1217         WIN_MSG(WM_XBUTTONDOWN)
    1218         WIN_MSG(WM_XBUTTONUP)
    1219         WIN_MSG(WM_MOUSEWHEEL)
    1220         WIN_MSG(WM_MOUSEHWHEEL)
    1221         WIN_MSG(WM_PARENTNOTIFY)
    1222         WIN_MSG(WM_ENTERMENULOOP)
    1223         WIN_MSG(WM_EXITMENULOOP)
    1224         WIN_MSG(WM_NEXTMENU)
    1225         WIN_MSG(WM_SIZING)
    1226         WIN_MSG(WM_CAPTURECHANGED)
    1227         WIN_MSG(WM_MOVING)
    1228         WIN_MSG(WM_POWERBROADCAST)
    1229         WIN_MSG(WM_DEVICECHANGE)
    1230         WIN_MSG(WM_MDICREATE)
    1231         WIN_MSG(WM_MDIDESTROY)
    1232         WIN_MSG(WM_MDIACTIVATE)
    1233         WIN_MSG(WM_MDIRESTORE)
    1234         WIN_MSG(WM_MDINEXT)
    1235         WIN_MSG(WM_MDIMAXIMIZE)
    1236         WIN_MSG(WM_MDITILE)
    1237         WIN_MSG(WM_MDICASCADE)
    1238         WIN_MSG(WM_MDIICONARRANGE)
    1239         WIN_MSG(WM_MDIGETACTIVE)
    1240         WIN_MSG(WM_MDISETMENU)
    1241         WIN_MSG(WM_ENTERSIZEMOVE)
    1242         WIN_MSG(WM_EXITSIZEMOVE)
    1243         WIN_MSG(WM_DROPFILES)
    1244         WIN_MSG(WM_MDIREFRESHMENU)
    1245         WIN_MSG(WM_IME_SETCONTEXT)
    1246         WIN_MSG(WM_IME_NOTIFY)
    1247         WIN_MSG(WM_IME_CONTROL)
    1248         WIN_MSG(WM_IME_COMPOSITIONFULL)
    1249         WIN_MSG(WM_IME_SELECT)
    1250         WIN_MSG(WM_IME_CHAR)
    1251         FMT_MSG(WM_IME_REQUEST)
    1252         WIN_MSG(WM_IME_KEYDOWN)
    1253         WIN_MSG(WM_IME_KEYUP)
    1254         FMT_MSG(0x02A1, "WM_MOUSEHOVER")
    1255         FMT_MSG(0x02A3, "WM_MOUSELEAVE")
    1256         WIN_MSG(WM_CUT)
    1257         WIN_MSG(WM_COPY)
    1258         WIN_MSG(WM_PASTE)
    1259         WIN_MSG(WM_CLEAR)
    1260         WIN_MSG(WM_UNDO)
    1261         WIN_MSG(WM_RENDERFORMAT)
    1262         WIN_MSG(WM_RENDERALLFORMATS)
    1263         WIN_MSG(WM_DESTROYCLIPBOARD)
    1264         WIN_MSG(WM_DRAWCLIPBOARD)
    1265         WIN_MSG(WM_PAINTCLIPBOARD)
    1266         WIN_MSG(WM_VSCROLLCLIPBOARD)
    1267         WIN_MSG(WM_SIZECLIPBOARD)
    1268         WIN_MSG(WM_ASKCBFORMATNAME)
    1269         WIN_MSG(WM_CHANGECBCHAIN)
    1270         WIN_MSG(WM_HSCROLLCLIPBOARD)
    1271         WIN_MSG(WM_QUERYNEWPALETTE)
    1272         WIN_MSG(WM_PALETTEISCHANGING)
    1273         WIN_MSG(WM_PALETTECHANGED)
    1274         WIN_MSG(WM_HOTKEY)
    1275         WIN_MSG(WM_PRINT)
    1276         WIN_MSG(WM_PRINTCLIENT)
    1277         WIN_MSG(WM_HANDHELDFIRST)
    1278         WIN_MSG(WM_HANDHELDLAST)
    1279         WIN_MSG(WM_AFXFIRST)
    1280         WIN_MSG(WM_AFXLAST)
    1281         WIN_MSG(WM_PENWINFIRST)
    1282         WIN_MSG(WM_PENWINLAST)
    1283         WIN_MSG(WM_AWT_COMPONENT_CREATE)
    1284         WIN_MSG(WM_AWT_DESTROY_WINDOW)
    1285         WIN_MSG(WM_AWT_MOUSEENTER)
    1286         WIN_MSG(WM_AWT_MOUSEEXIT)
    1287         WIN_MSG(WM_AWT_COMPONENT_SHOW)
    1288         WIN_MSG(WM_AWT_COMPONENT_HIDE)
    1289         WIN_MSG(WM_AWT_COMPONENT_SETFOCUS)
    1290         WIN_MSG(WM_AWT_WINDOW_SETACTIVE)
    1291         WIN_MSG(WM_AWT_LIST_SETMULTISELECT)
    1292         WIN_MSG(WM_AWT_HANDLE_EVENT)
    1293         WIN_MSG(WM_AWT_PRINT_COMPONENT)
    1294         WIN_MSG(WM_AWT_RESHAPE_COMPONENT)
    1295         WIN_MSG(WM_AWT_SETALWAYSONTOP)
    1296         WIN_MSG(WM_AWT_BEGIN_VALIDATE)
    1297         WIN_MSG(WM_AWT_END_VALIDATE)
    1298         WIN_MSG(WM_AWT_FORWARD_CHAR)
    1299         WIN_MSG(WM_AWT_FORWARD_BYTE)
    1300         WIN_MSG(WM_AWT_SET_SCROLL_INFO)
    1301         WIN_MSG(WM_AWT_CREATECONTEXT)
    1302         WIN_MSG(WM_AWT_DESTROYCONTEXT)
    1303         WIN_MSG(WM_AWT_ASSOCIATECONTEXT)
    1304         WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER)
    1305         WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT)
    1306         WIN_MSG(WM_AWT_PRE_KEYDOWN)
    1307         WIN_MSG(WM_AWT_PRE_KEYUP)
    1308         WIN_MSG(WM_AWT_PRE_SYSKEYDOWN)
    1309         WIN_MSG(WM_AWT_PRE_SYSKEYUP)
    1310         WIN_MSG(WM_AWT_ENDCOMPOSITION,)
    1311         WIN_MSG(WM_AWT_DISPOSE,)
    1312         WIN_MSG(WM_AWT_DELETEOBJECT,)
    1313         WIN_MSG(WM_AWT_SETCONVERSIONSTATUS,)
    1314         WIN_MSG(WM_AWT_GETCONVERSIONSTATUS,)
    1315         WIN_MSG(WM_AWT_SETOPENSTATUS,)
    1316         WIN_MSG(WM_AWT_GETOPENSTATUS)
    1317         WIN_MSG(WM_AWT_ACTIVATEKEYBOARDLAYOUT)
    1318         WIN_MSG(WM_AWT_OPENCANDIDATEWINDOW)
    1319         WIN_MSG(WM_AWT_DLG_SHOWMODAL,)
    1320         WIN_MSG(WM_AWT_DLG_ENDMODAL,)
    1321         WIN_MSG(WM_AWT_SETCURSOR,)
    1322         WIN_MSG(WM_AWT_WAIT_FOR_SINGLE_OBJECT,)
    1323         WIN_MSG(WM_AWT_INVOKE_METHOD,)
    1324         WIN_MSG(WM_AWT_INVOKE_VOID_METHOD,)
    1325         WIN_MSG(WM_AWT_EXECUTE_SYNC,)
    1326         WIN_MSG(WM_AWT_CURSOR_SYNC)
    1327         WIN_MSG(WM_AWT_GETDC)
    1328         WIN_MSG(WM_AWT_RELEASEDC)
    1329         WIN_MSG(WM_AWT_RELEASE_ALL_DCS)
    1330         WIN_MSG(WM_AWT_SHOWCURSOR)
    1331         WIN_MSG(WM_AWT_HIDECURSOR)
    1332         WIN_MSG(WM_AWT_CREATE_PRINTED_PIXELS)
    1333         WIN_MSG(WM_AWT_OBJECTLISTCLEANUP)
    1334         default:
    1335             sprintf(szBuf, "0x%8.8x(%s):Unknown message 0x%8.8x\n",
    1336                 hwnd, szComment, message);
    1337             break;
    1338     }
    1339     printf(szBuf);
    1340 }
    1341
    1342 #endif /* SPY_MESSAGES */
    1343
    1344 /*
    1345  * Dispatch messages for this window class--general component
    1346  */
    1347 LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    1348 {
    1349     CounterHelper ch(&m_MessagesProcessing);
    1350
    1351     JNILocalFrame lframe(AwtToolkit::GetEnv(), 10);
    1352     SpyWinMessage(GetHWnd(), message,
    1353         (message == WM_AWT_RELEASE_ALL_DCS) ? TEXT("Disposed Component") : GetClassName());
    1354
    1355     LRESULT retValue = 0;
    1356     MsgRouting mr = mrDoDefault;
    1357     AwtToolkit::GetInstance().eventNumber++;
    1358
    1359     static BOOL ignoreNextLBTNUP = FALSE; //Ignore next LBUTTONUP msg?
    1360
    1361     lastMessage = message;
    1362
    1363     if (message == WmAwtIsComponent) {
    1364     // special message to identify AWT HWND's without using
    1365     // resource hogging ::SetProp
    1366         return (LRESULT)TRUE;
    1367     }
    1368
    1369     DWORD curPos = 0;
    1370
    1371     UINT switchMessage = message;
    1372     switch (switchMessage) {
    1373       case WM_AWT_GETDC:
    1374       {
    1375             HDC hDC;
    1376             // First, release the DCs scheduled for deletion
    1377             ReleaseDCList(GetHWnd(), passiveDCList);
    1378
    1379             GetDCReturnStruct *returnStruct = new GetDCReturnStruct;
    1380             returnStruct->gdiLimitReached = FALSE;
    1381             if (AwtGDIObject::IncrementIfAvailable()) {
    1382                 hDC = ::GetDCEx(GetHWnd(), NULL,
    1383                                 DCX_CACHE | DCX_CLIPCHILDREN |
    1384                                 DCX_CLIPSIBLINGS);
    1385                 if (hDC != NULL) {
    1386                     // Add new DC to list of DC's associated with this Component
    1387                     activeDCList.AddDC(hDC, GetHWnd());
    1388                 } else {
    1389                     // Creation failed; decrement counter in AwtGDIObject
    1390                     AwtGDIObject::Decrement();
    1391                 }
    1392             } else {
    1393                 hDC = NULL;
    1394                 returnStruct->gdiLimitReached = TRUE;
    1395             }
    1396             returnStruct->hDC = hDC;
    1397             retValue = (LRESULT)returnStruct;
    1398             mr = mrConsume;
    1399             break;
    1400       }
    1401       case WM_AWT_RELEASEDC:
    1402       {
    1403             HDC hDC = (HDC)wParam;
    1404             MoveDCToPassiveList(hDC, GetHWnd());
    1405             ReleaseDCList(GetHWnd(), passiveDCList);
    1406             mr = mrConsume;
    1407             break;
    1408       }
    1409       case WM_AWT_RELEASE_ALL_DCS:
    1410       {
    1411             // Called during Component destruction.  Gets current list of
    1412             // DC's associated with Component and releases each DC.
    1413             ReleaseDCList(GetHWnd(), activeDCList);
    1414             ReleaseDCList(GetHWnd(), passiveDCList);
    1415             mr = mrConsume;
    1416             break;
    1417       }
    1418       case WM_AWT_SHOWCURSOR:
    1419           ::ShowCursor(TRUE);
    1420           break;
    1421       case WM_AWT_HIDECURSOR:
    1422           ::ShowCursor(FALSE);
    1423           break;
    1424       case WM_CREATE: mr = WmCreate(); break;
    1425       case WM_CLOSE:      mr = WmClose(); break;
    1426       case WM_DESTROY:    mr = WmDestroy(); break;
    1427       case WM_NCDESTROY:  mr = WmNcDestroy(); break;
    1428
    1429       case WM_ERASEBKGND:
    1430           mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break;
    1431       case WM_PAINT:
    1432           CheckFontSmoothingSettings(GetHWnd());
    1433           /* Set draw state */
    1434           SetDrawState(GetDrawState() | JAWT_LOCK_CLIP_CHANGED);
    1435           mr = WmPaint((HDC)wParam);
    1436           break;
    1437
    1438       case WM_GETMINMAXINFO:
    1439           mr = WmGetMinMaxInfo((LPMINMAXINFO)lParam);
    1440           break;
    1441
    1442       case WM_WINDOWPOSCHANGING:
    1443       {
    1444           // We process this message so that we can synchronize access to
    1445           // a moving window.  The Scale/Blt functions in Win32BlitLoops
    1446           // take the same windowMoveLock to ensure that a window is not
    1447           // moving while we are trying to copy pixels into it.
    1448           WINDOWPOS *lpPosInfo = (WINDOWPOS *)lParam;
    1449           if ((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 window
    1454               // is about to move when the coordinates are exactly the
    1455               // same as the last time.  This can cause problems with
    1456               // our windowMoveLock CriticalSection because we enter it
    1457               // here and never get to WM_WINDOWPOSCHANGED to release it.
    1458               // So make sure this is a real move/size event before bothering
    1459               // to grab the critical section.
    1460               BOOL takeLock = FALSE;
    1461               if (!(lpPosInfo->flags & SWP_NOMOVE) &&
    1462                   ((windowMoveLockPosX != lpPosInfo->x) ||
    1463                    (windowMoveLockPosY != lpPosInfo->y)))
    1464               {
    1465                   // Real move event
    1466                   takeLock = TRUE;
    1467                   windowMoveLockPosX = lpPosInfo->x;
    1468                   windowMoveLockPosY = lpPosInfo->y;
    1469               }
    1470               if (!(lpPosInfo->flags & SWP_NOSIZE) &&
    1471                   ((windowMoveLockPosCX != lpPosInfo->cx) ||
    1472                    (windowMoveLockPosCY != lpPosInfo->cy)))
    1473               {
    1474                   // Real size event
    1475                   takeLock = TRUE;
    1476                   windowMoveLockPosCX = lpPosInfo->cx;
    1477                   windowMoveLockPosCY = lpPosInfo->cy;
    1478               }
    1479               if (takeLock) {
    1480                   if (!windowMoveLockHeld) {
    1481                       windowMoveLock.Enter();
    1482                       windowMoveLockHeld = TRUE;
    1483                   }
    1484               }
    1485           }
    1486           mr = WmWindowPosChanging(lParam);
    1487           break;
    1488       }
    1489       case WM_WINDOWPOSCHANGED:
    1490       {
    1491           // Release lock grabbed in the POSCHANGING message
    1492           if (windowMoveLockHeld) {
    1493               windowMoveLockHeld = FALSE;
    1494               windowMoveLock.Leave();
    1495           }
    1496           mr = WmWindowPosChanged(lParam);
    1497           break;
    1498       }
    1499       case WM_MOVE: {
    1500           RECT r;
    1501           ::GetWindowRect(GetHWnd(), &r);
    1502           mr = WmMove(r.left, r.top);
    1503           break;
    1504       }
    1505       case WM_SIZE:
    1506       {
    1507           RECT r;
    1508           // fix 4128317 : use GetClientRect for full 32-bit int precision and
    1509           // to avoid negative client area dimensions overflowing 16-bit params - robi
    1510           ::GetClientRect( GetHWnd(), &r );
    1511           mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top);
    1512           //mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam));
    1513           SetCompositionWindow(r);
    1514           break;
    1515       }
    1516       case WM_SIZING:
    1517           mr = WmSizing();
    1518           break;
    1519       case WM_SHOWWINDOW:
    1520           mr = WmShowWindow(static_cast<BOOL>(wParam),
    1521                             static_cast<UINT>(lParam)); break;
    1522       case WM_SYSCOMMAND:
    1523           mr = WmSysCommand(static_cast<UINT>(wParam & 0xFFF0),
    1524                             GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
    1525           break;
    1526       case WM_ENTERSIZEMOVE:
    1527           mr = WmEnterSizeMove();
    1528           break;
    1529       case WM_EXITSIZEMOVE:
    1530           mr = WmExitSizeMove();
    1531           break;
    1532       // Bug #4039858 (Selecting menu item causes bogus mouse click event)
    1533       case WM_ENTERMENULOOP:
    1534           mr = WmEnterMenuLoop((BOOL)wParam);
    1535           sm_bMenuLoop = TRUE;
    1536           // we need to release grab if menu is shown
    1537           if (AwtWindow::GetGrabbedWindow() != NULL) {
    1538               AwtWindow::GetGrabbedWindow()->Ungrab();
    1539           }
    1540           break;
    1541       case WM_EXITMENULOOP:
    1542           mr = WmExitMenuLoop((BOOL)wParam);
    1543           sm_bMenuLoop = FALSE;
    1544           break;
    1545
    1546       // We don't expect any focus messages on non-proxy component,
    1547       // except those that came from Java.
    1548       case WM_SETFOCUS:
    1549           if (sm_inSynthesizeFocus) {
    1550               mr = WmSetFocus((HWND)wParam);
    1551           } else {
    1552               mr = mrConsume;
    1553           }
    1554           break;
    1555       case WM_KILLFOCUS:
    1556           if (sm_inSynthesizeFocus) {
    1557               mr = WmKillFocus((HWND)wParam);
    1558           } else {
    1559               mr = mrConsume;
    1560           }
    1561           break;
    1562       case WM_ACTIVATE: {
    1563           UINT nState = LOWORD(wParam);
    1564           BOOL fMinimized = (BOOL)HIWORD(wParam);
    1565           mr = mrConsume;
    1566
    1567           if (!sm_suppressFocusAndActivation &&
    1568               (!fMinimized || (nState == WA_INACTIVE)))
    1569           {
    1570               mr = WmActivate(nState, fMinimized, (HWND)lParam);
    1571
    1572               // When the window is deactivated, send WM_IME_ENDCOMPOSITION
    1573               // message to deactivate the composition window so that
    1574               // it won't receive keyboard input focus.
    1575               HIMC hIMC;
    1576               HWND hwnd = ImmGetHWnd();
    1577               if ((hIMC = ImmGetContext(hwnd)) != NULL) {
    1578                   ImmReleaseContext(hwnd, hIMC);
    1579                   DefWindowProc(WM_IME_ENDCOMPOSITION, 0, 0);
    1580               }
    1581           }
    1582           break;
    1583       }
    1584       case WM_MOUSEACTIVATE: {
    1585           AwtWindow *window = GetContainer();
    1586           if (window && window->IsFocusableWindow()) {
    1587               // AWT/Swing will later request focus to a proper component
    1588               // on handling the Java mouse event. Anyway, we have to
    1589               // activate the window here as it works both for AWT & Swing.
    1590               // Do it in our own fassion,
    1591               window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/);
    1592           }
    1593           mr = mrConsume;
    1594           retValue = MA_NOACTIVATE;
    1595           break;
    1596       }
    1597       case WM_CTLCOLORMSGBOX:
    1598       case WM_CTLCOLOREDIT:
    1599       case WM_CTLCOLORLISTBOX:
    1600       case WM_CTLCOLORBTN:
    1601       case WM_CTLCOLORDLG:
    1602       case WM_CTLCOLORSCROLLBAR:
    1603       case WM_CTLCOLORSTATIC:
    1604           mr = WmCtlColor((HDC)wParam, (HWND)lParam,
    1605                           message-WM_CTLCOLORMSGBOX+CTLCOLOR_MSGBOX,
    1606                           *(HBRUSH*)&retValue);
    1607           break;
    1608       case WM_HSCROLL:
    1609           mr = WmHScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
    1610           break;
    1611       case WM_VSCROLL:
    1612           mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
    1613           break;
    1614       // 4664415: We're seeing a WM_LBUTTONUP when the user releases the
    1615       // mouse button after a WM_NCLBUTTONDBLCLK.  We want to ignore this
    1616       // WM_LBUTTONUP, so we set a flag in WM_NCLBUTTONDBLCLK and look for the
    1617       // flag on a WM_LBUTTONUP.  -bchristi
    1618       case WM_NCLBUTTONDBLCLK:
    1619           mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON | DBL_CLICK);
    1620           if (mr == mrDoDefault) {
    1621               ignoreNextLBTNUP = TRUE;
    1622           }
    1623           break;
    1624       case WM_NCLBUTTONDOWN:
    1625           mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON);
    1626           ignoreNextLBTNUP = FALSE;
    1627           break;
    1628       case WM_NCLBUTTONUP:
    1629           mr = WmNcMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON);
    1630           break;
    1631       case WM_NCRBUTTONDOWN:
    1632            mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), RIGHT_BUTTON);
    1633            break;
    1634       case WM_LBUTTONUP:
    1635           if (ignoreNextLBTNUP) {
    1636               ignoreNextLBTNUP = FALSE;
    1637               return mrDoDefault;
    1638           }
    1639           //fall-through
    1640       case WM_LBUTTONDOWN:
    1641           ignoreNextLBTNUP = FALSE;
    1642           //fall-through
    1643       case WM_LBUTTONDBLCLK:
    1644       case WM_RBUTTONDOWN:
    1645       case WM_RBUTTONDBLCLK:
    1646       case WM_RBUTTONUP:
    1647       case WM_MBUTTONDOWN:
    1648       case WM_MBUTTONDBLCLK:
    1649       case WM_MBUTTONUP:
    1650       case WM_XBUTTONDBLCLK:
    1651       case WM_XBUTTONDOWN:
    1652       case WM_XBUTTONUP:
    1653       case WM_MOUSEMOVE:
    1654       case WM_MOUSEWHEEL:
    1655       case WM_MOUSEHWHEEL:
    1656       case WM_AWT_MOUSEENTER:
    1657       case WM_AWT_MOUSEEXIT:
    1658           curPos = ::GetMessagePos();
    1659           POINT myPos;
    1660           myPos.x = GET_X_LPARAM(curPos);
    1661           myPos.y = GET_Y_LPARAM(curPos);
    1662           ::ScreenToClient(GetHWnd(), &myPos);
    1663           switch(switchMessage) {
    1664           case WM_AWT_MOUSEENTER:
    1665               mr = WmMouseEnter(static_cast<UINT>(wParam), myPos.x, myPos.y);
    1666               break;
    1667           case WM_LBUTTONDOWN:
    1668           case WM_LBUTTONDBLCLK:
    1669               mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1670                                LEFT_BUTTON);
    1671               break;
    1672           case WM_LBUTTONUP:
    1673               mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1674                              LEFT_BUTTON);
    1675               break;
    1676           case WM_MOUSEMOVE:
    1677               mr = WmMouseMove(static_cast<UINT>(wParam), myPos.x, myPos.y);
    1678               break;
    1679           case WM_MBUTTONDOWN:
    1680           case WM_MBUTTONDBLCLK:
    1681               mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1682                                MIDDLE_BUTTON);
    1683               break;
    1684           case WM_XBUTTONDOWN:
    1685           case WM_XBUTTONDBLCLK:
    1686               if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {
    1687                   if (HIWORD(wParam) == 1) {
    1688                       mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1689                                        X1_BUTTON);
    1690                   }
    1691                   if (HIWORD(wParam) == 2) {
    1692                       mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1693                                        X2_BUTTON);
    1694                   }
    1695               }
    1696               break;
    1697           case WM_XBUTTONUP:
    1698               if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {
    1699                   if (HIWORD(wParam) == 1) {
    1700                       mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1701                                      X1_BUTTON);
    1702                   }
    1703                   if (HIWORD(wParam) == 2) {
    1704                       mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1705                                      X2_BUTTON);
    1706                   }
    1707               }
    1708               break;
    1709           case WM_RBUTTONDOWN:
    1710           case WM_RBUTTONDBLCLK:
    1711               mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1712                                RIGHT_BUTTON);
    1713               break;
    1714           case WM_RBUTTONUP:
    1715               mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1716                              RIGHT_BUTTON);
    1717               break;
    1718           case WM_MBUTTONUP:
    1719               mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
    1720                              MIDDLE_BUTTON);
    1721               break;
    1722           case WM_AWT_MOUSEEXIT:
    1723               mr = WmMouseExit(static_cast<UINT>(wParam), myPos.x, myPos.y);
    1724               break;
    1725           case WM_MOUSEWHEEL:
    1726           case WM_MOUSEHWHEEL:
    1727               mr = WmMouseWheel(GET_KEYSTATE_WPARAM(wParam),
    1728                                 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
    1729                                 GET_WHEEL_DELTA_WPARAM(wParam),
    1730                                 switchMessage == WM_MOUSEHWHEEL);
    1731               break;
    1732           }
    1733           break;
    1734       case WM_TOUCH:
    1735           WmTouch(wParam, lParam);
    1736           break;
    1737       case WM_SETCURSOR:
    1738           mr = mrDoDefault;
    1739           if (LOWORD(lParam) == HTCLIENT) {
    1740               if (AwtComponent* comp =
    1741                                     AwtComponent::GetComponent((HWND)wParam)) {
    1742                   AwtCursor::UpdateCursor(comp);
    1743                   mr = mrConsume;
    1744               }
    1745           }
    1746           break;
    1747
    1748       case WM_KEYDOWN:
    1749           mr = WmKeyDown(static_cast<UINT>(wParam),
    1750                          LOWORD(lParam), HIWORD(lParam), FALSE);
    1751           break;
    1752       case WM_KEYUP:
    1753           mr = WmKeyUp(static_cast<UINT>(wParam),
    1754                        LOWORD(lParam), HIWORD(lParam), FALSE);
    1755           break;
    1756       case WM_SYSKEYDOWN:
    1757           mr = WmKeyDown(static_cast<UINT>(wParam),
    1758                          LOWORD(lParam), HIWORD(lParam), TRUE);
    1759           break;
    1760       case WM_SYSKEYUP:
    1761           mr = WmKeyUp(static_cast<UINT>(wParam),
    1762                        LOWORD(lParam), HIWORD(lParam), TRUE);
    1763           break;
    1764       case WM_IME_SETCONTEXT:
    1765           // lParam is passed as pointer and it can be modified.
    1766           mr = WmImeSetContext(static_cast<BOOL>(wParam), &lParam);
    1767           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1768           break;
    1769       case WM_IME_NOTIFY:
    1770           mr = WmImeNotify(wParam, lParam);
    1771           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1772           break;
    1773       case WM_IME_STARTCOMPOSITION:
    1774           mr = WmImeStartComposition();
    1775           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1776           break;
    1777       case WM_IME_ENDCOMPOSITION:
    1778           mr = WmImeEndComposition();
    1779           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1780           break;
    1781       case WM_IME_COMPOSITION: {
    1782           WORD dbcschar = static_cast<WORD>(wParam);
    1783           mr = WmImeComposition(dbcschar, lParam);
    1784           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1785           break;
    1786       }
    1787       case WM_IME_CONTROL:
    1788       case WM_IME_COMPOSITIONFULL:
    1789       case WM_IME_SELECT:
    1790       case WM_IME_KEYUP:
    1791       case WM_IME_KEYDOWN:
    1792       case WM_IME_REQUEST:
    1793           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1794           break;
    1795       case WM_CHAR:
    1796           mr = WmChar(static_cast<UINT>(wParam),
    1797                       LOWORD(lParam), HIWORD(lParam), FALSE);
    1798           break;
    1799       case WM_SYSCHAR:
    1800           mr = WmChar(static_cast<UINT>(wParam),
    1801                       LOWORD(lParam), HIWORD(lParam), TRUE);
    1802           break;
    1803       case WM_IME_CHAR:
    1804           mr = WmIMEChar(static_cast<UINT>(wParam),
    1805                          LOWORD(lParam), HIWORD(lParam), FALSE);
    1806           break;
    1807
    1808       case WM_INPUTLANGCHANGEREQUEST: {
    1809           DTRACE_PRINTLN4("WM_INPUTLANGCHANGEREQUEST: hwnd = 0x%X (%s);"//
    1810                           "0x%08X -> 0x%08X",
    1811                           GetHWnd(), GetClassName(),
    1812                           (UINT_PTR)GetKeyboardLayout(), (UINT_PTR)lParam);
    1813           // 4267428: make sure keyboard layout is turned undead.
    1814           static BYTE keyboardState[AwtToolkit::KB_STATE_SIZE];
    1815           AwtToolkit::GetKeyboardState(keyboardState);
    1816           WORD ignored;
    1817           ::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0),
    1818                       keyboardState, &ignored, 0, GetKeyboardLayout());
    1819
    1820           // Set this flag to block ActivateKeyboardLayout from
    1821           // WInputMethod.activate()
    1822           g_bUserHasChangedInputLang = TRUE;
    1823           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1824           break;
    1825       }
    1826       case WM_INPUTLANGCHANGE:
    1827           DTRACE_PRINTLN3("WM_INPUTLANGCHANGE: hwnd = 0x%X (%s);"//
    1828                           "new = 0x%08X",
    1829                           GetHWnd(), GetClassName(), (UINT)lParam);
    1830           mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam));
    1831           g_bUserHasChangedInputLang = TRUE;
    1832           CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
    1833           // should return non-zero if we process this message
    1834           retValue = 1;
    1835           break;
    1836
    1837       case WM_AWT_FORWARD_CHAR:
    1838           mr = WmForwardChar(LOWORD(wParam), lParam, HIWORD(wParam));
    1839           break;
    1840
    1841       case WM_AWT_FORWARD_BYTE:
    1842           mr = HandleEvent( (MSG *) lParam, (BOOL) wParam);
    1843           break;
    1844
    1845       case WM_PASTE:
    1846           mr = WmPaste();
    1847           break;
    1848       case WM_TIMER:
    1849           mr = WmTimer(wParam);
    1850           break;
    1851
    1852       case WM_COMMAND:
    1853           mr = WmCommand(LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
    1854           break;
    1855       case WM_COMPAREITEM:
    1856           mr = WmCompareItem(static_cast<UINT>(wParam),
    1857                              *(COMPAREITEMSTRUCT*)lParam, retValue);
    1858           break;
    1859       case WM_DELETEITEM:
    1860           mr = WmDeleteItem(static_cast<UINT>(wParam),
    1861                             *(DELETEITEMSTRUCT*)lParam);
    1862           break;
    1863       case WM_DRAWITEM:
    1864           mr = WmDrawItem(static_cast<UINT>(wParam),
    1865                           *(DRAWITEMSTRUCT*)lParam);
    1866           break;
    1867       case WM_MEASUREITEM:
    1868           mr = WmMeasureItem(static_cast<UINT>(wParam),
    1869                              *(MEASUREITEMSTRUCT*)lParam);
    1870           break;
    1871
    1872       case WM_AWT_HANDLE_EVENT:
    1873           mr = HandleEvent( (MSG *) lParam, (BOOL) wParam);
    1874           break;
    1875
    1876       case WM_PRINT:
    1877           mr = WmPrint((HDC)wParam, lParam);
    1878           break;
    1879       case WM_PRINTCLIENT:
    1880           mr = WmPrintClient((HDC)wParam, lParam);
    1881           break;
    1882
    1883       case WM_NCCALCSIZE:
    1884           mr = WmNcCalcSize((BOOL)wParam, (LPNCCALCSIZE_PARAMS)lParam,
    1885                             retValue);
    1886           break;
    1887       case WM_NCPAINT:
    1888           mr = WmNcPaint((HRGN)wParam);
    1889           break;
    1890       case WM_NCHITTEST:
    1891           mr = WmNcHitTest(LOWORD(lParam), HIWORD(lParam), retValue);
    1892           break;
    1893
    1894       case WM_AWT_RESHAPE_COMPONENT: {
    1895           RECT* r = (RECT*)lParam;
    1896           WPARAM checkEmbedded = wParam;
    1897           if (checkEmbedded == CHECK_EMBEDDED && IsEmbeddedFrame()) {
    1898               ::OffsetRect(r, -r->left, -r->top);
    1899           }
    1900           Reshape(r->left, r->top, r->right - r->left, r->bottom - r->top);
    1901           delete r;
    1902           mr = mrConsume;
    1903           break;
    1904       }
    1905
    1906       case WM_AWT_SETALWAYSONTOP: {
    1907         AwtWindow* w = (AwtWindow*)lParam;
    1908         BOOL value = (BOOL)wParam;
    1909         UINT flags = SWP_NOMOVE | SWP_NOSIZE;
    1910         // transient windows shouldn't change the owner window's position in the z-order
    1911         if (w->IsRetainingHierarchyZOrder()) {
    1912             flags |= SWP_NOOWNERZORDER;
    1913         }
    1914         ::SetWindowPos(w->GetHWnd(), (value != 0 ? HWND_TOPMOST : HWND_NOTOPMOST),
    1915                        0,0,0,0, flags);
    1916         break;
    1917       }
    1918
    1919       case WM_AWT_BEGIN_VALIDATE:
    1920           BeginValidate();
    1921           mr = mrConsume;
    1922           break;
    1923       case WM_AWT_END_VALIDATE:
    1924           EndValidate();
    1925           mr = mrConsume;
    1926           break;
    1927
    1928       case WM_PALETTEISCHANGING:
    1929           mr = WmPaletteIsChanging((HWND)wParam);
    1930           mr = mrDoDefault;
    1931           break;
    1932       case WM_QUERYNEWPALETTE:
    1933           mr = WmQueryNewPalette(retValue);
    1934           break;
    1935       case WM_PALETTECHANGED:
    1936           mr = WmPaletteChanged((HWND)wParam);
    1937           break;
    1938       case WM_STYLECHANGED:
    1939           mr = WmStyleChanged(static_cast<int>(wParam), (LPSTYLESTRUCT)lParam);
    1940           break;
    1941       case WM_SETTINGCHANGE:
    1942           CheckFontSmoothingSettings(NULL);
    1943           mr = WmSettingChange(static_cast<UINT>(wParam), (LPCTSTR)lParam);
    1944           break;
    1945       case WM_CONTEXTMENU:
    1946           mr = WmContextMenu((HWND)wParam,
    1947                              GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
    1948           break;
    1949
    1950           /*
    1951            * These messages are used to route Win32 calls to the
    1952            * creating thread, since these calls fail unless executed
    1953            * there.
    1954            */
    1955       case WM_AWT_COMPONENT_SHOW:
    1956           Show();
    1957           mr = mrConsume;
    1958           break;
    1959       case WM_AWT_COMPONENT_HIDE:
    1960           Hide();
    1961           mr = mrConsume;
    1962           break;
    1963
    1964       case WM_AWT_COMPONENT_SETFOCUS:
    1965           if ((BOOL)wParam) {
    1966               retValue = SynthesizeWmSetFocus(GetHWnd(), NULL);
    1967           } else {
    1968               retValue = SynthesizeWmKillFocus(GetHWnd(), NULL);
    1969           }
    1970           mr = mrConsume;
    1971           break;
    1972       case WM_AWT_WINDOW_SETACTIVE:
    1973           retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam);
    1974           mr = mrConsume;
    1975           break;
    1976
    1977       case WM_AWT_SET_SCROLL_INFO: {
    1978           SCROLLINFO *si = (SCROLLINFO *) lParam;
    1979           ::SetScrollInfo(GetHWnd(), (int) wParam, si, TRUE);
    1980           delete si;
    1981           mr = mrConsume;
    1982           break;
    1983       }
    1984       case WM_AWT_CREATE_PRINTED_PIXELS: {
    1985           CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam;
    1986           SIZE loc = { cpps->srcx, cpps->srcy };
    1987           SIZE size = { cpps->srcw, cpps->srch };
    1988           retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha);
    1989           mr = mrConsume;
    1990           break;
    1991       }
    1992       case WM_UNDOCUMENTED_CLICKMENUBAR:
    1993       {
    1994           if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) {
    1995               mr = mrConsume;
    1996           }
    1997       }
    1998     }
    1999
    2000     /*
    2001      * If not a specific Consume, it was a specific DoDefault, or a
    2002      * PassAlong (since the default is the next in chain), then call the
    2003      * default proc.
    2004      */
    2005     if (mr != mrConsume) {
    2006         retValue = DefWindowProc(message, wParam, lParam);
    2007     }
    2008
    2009     return retValue;
    2010 }
    2011 /*
    2012  * Call this instance's default window proc, or if none set, call the stock
    2013  * Window's one.
    2014  */
    2015 LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
    2016 {
    2017     return ComCtl32Util::GetInstance().DefWindowProc(m_DefWindowProc, GetHWnd(), msg, wParam, lParam);
    2018 }
    2019
    2020 /*
    2021  * This message should only be received when a window is destroyed by
    2022  * Windows, and not Java.  Window termination has been reworked so
    2023  * this method should never be called during termination.
    2024  */
    2025 MsgRouting AwtComponent::WmDestroy()
    2026 {
    2027     return mrConsume;
    2028 }
    2029
    2030 /*
    2031  * This message should only be received when a window is destroyed by
    2032  * Windows, and not Java. It is sent only after child windows were destroyed.
    2033  */
    2034 MsgRouting AwtComponent::WmNcDestroy()
    2035 {
    2036     if (m_peerObject != NULL) { // is not being terminating
    2037         // Stay in this handler until AwtComponent::Dispose is called.
    2038         m_bPauseDestroy = TRUE;
    2039
    2040         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    2041         // Post invocation event for WObjectPeer.dispose to EDT
    2042         env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID);
    2043         // Wait until AwtComponent::Dispose is called
    2044         AwtToolkit::GetInstance().PumpToDestroy(this);
    2045     }
    2046
    2047     return mrConsume;
    2048 }
    2049
    2050 MsgRouting AwtComponent::WmGetMinMaxInfo(LPMINMAXINFO lpmmi)
    2051 {
    2052     return mrDoDefault;
    2053 }
    2054
    2055 MsgRouting AwtComponent::WmMove(int x, int y)
    2056 {
    2057     SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED)
    2058         | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED));
    2059     return mrDoDefault;
    2060 }
    2061
    2062 MsgRouting AwtComponent::WmSize(UINT type, int w, int h)
    2063 {
    2064     SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED)
    2065         | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED));
    2066     return mrDoDefault;
    2067 }
    2068
    2069 MsgRouting AwtComponent::WmSizing()
    2070 {
    2071     return mrDoDefault;
    2072 }
    2073
    2074 MsgRouting AwtComponent::WmSysCommand(UINT uCmdType, int xPos, int yPos)
    2075 {
    2076     return mrDoDefault;
    2077 }
    2078
    2079 MsgRouting AwtComponent::WmEnterSizeMove()
    2080 {
    2081     return mrDoDefault;
    2082 }
    2083
    2084 MsgRouting AwtComponent::WmExitSizeMove()
    2085 {
    2086     return mrDoDefault;
    2087 }
    2088
    2089 MsgRouting AwtComponent::WmEnterMenuLoop(BOOL isTrackPopupMenu)
    2090 {
    2091     return mrDoDefault;
    2092 }
    2093
    2094 MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu)
    2095 {
    2096     return mrDoDefault;
    2097 }
    2098
    2099 MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status)
    2100 {
    2101     return mrDoDefault;
    2102 }
    2103
    2104 MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus)
    2105 {
    2106     m_wheelRotationAmountX = 0;
    2107     m_wheelRotationAmountY = 0;
    2108     return mrDoDefault;
    2109 }
    2110
    2111 MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus)
    2112 {
    2113     m_wheelRotationAmountX = 0;
    2114     m_wheelRotationAmountY = 0;
    2115     return mrDoDefault;
    2116 }
    2117
    2118 MsgRouting AwtComponent::WmCtlColor(HDC hDC, HWND hCtrl,
    2119                                     UINT ctlColor, HBRUSH& retBrush)
    2120 {
    2121     AwtComponent* child = AwtComponent::GetComponent(hCtrl);
    2122     if (child) {
    2123         ::SetBkColor(hDC, child->GetBackgroundColor());
    2124         ::SetTextColor(hDC, child->GetColor());
    2125         retBrush = child->GetBackgroundBrush();
    2126         return mrConsume;
    2127     }
    2128     return mrDoDefault;
    2129 /*
    2130     switch (ctlColor) {
    2131         case CTLCOLOR_MSGBOX:
    2132         case CTLCOLOR_EDIT:
    2133         case CTLCOLOR_LISTBOX:
    2134         case CTLCOLOR_BTN:
    2135         case CTLCOLOR_DLG:
    2136         case CTLCOLOR_SCROLLBAR:
    2137         case CTLCOLOR_STATIC:
    2138     }
    2139 */
    2140 }
    2141
    2142 MsgRouting AwtComponent::WmHScroll(UINT scrollCode, UINT pos,
    2143                                    HWND hScrollbar) {
    2144     if (hScrollbar && hScrollbar != GetHWnd()) {
    2145         /* the last test should never happen */
    2146         AwtComponent* sb = GetComponent(hScrollbar);
    2147         if (sb) {
    2148             sb->WmHScroll(scrollCode, pos, hScrollbar);
    2149         }
    2150     }
    2151     return mrDoDefault;
    2152 }
    2153
    2154 MsgRouting AwtComponent::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar)
    2155 {
    2156     if (hScrollbar && hScrollbar != GetHWnd()) {
    2157         /* the last test should never happen */
    2158         AwtComponent* sb = GetComponent(hScrollbar);
    2159         if (sb) {
    2160             sb->WmVScroll(scrollCode, pos, hScrollbar);
    2161         }
    2162     }
    2163     return mrDoDefault;
    2164 }
    2165
    2166
    2167 MsgRouting AwtComponent::WmPaint(HDC)
    2168 {
    2169     /* Get the rectangle that covers all update regions, if any exist. */
    2170     RECT r;
    2171     if (::GetUpdateRect(GetHWnd(), &r, FALSE)) {
    2172         if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 &&
    2173             m_peerObject != NULL && m_callbacksEnabled) {
    2174             /*
    2175              * Always call handlePaint, because the underlying control
    2176              * will have painted itself (the "background") before any
    2177              * paint method is called.
    2178              */
    2179             DoCallback("handlePaint", "(IIII)V",
    2180                        r.left, r.top, r.right-r.left, r.bottom-r.top);
    2181         }
    2182     }
    2183     return mrDoDefault;
    2184 }
    2185
    2186 void AwtComponent::PaintUpdateRgn(const RECT *insets)
    2187 {
    2188     // Fix 4530093: Don't Validate if can't actually paint
    2189     if (m_peerObject == NULL || !m_callbacksEnabled) {
    2190
    2191         // Fix 4745222: If we don't ValidateRgn,  windows will keep sending
    2192         // WM_PAINT messages until we do. This causes java to go into
    2193         // a tight loop that increases CPU to 100% and starves main
    2194         // thread which needs to complete initialization, but cant.
    2195         ::ValidateRgn(GetHWnd(), NULL);
    2196
    2197         return;
    2198     }
    2199
    2200     HRGN rgn = ::CreateRectRgn(0,0,1,1);
    2201     int updated = ::GetUpdateRgn(GetHWnd(), rgn, FALSE);
    2202     /*
    2203      * Now remove all update regions from this window -- do it
    2204      * here instead of after the Java upcall, in case any new
    2205      * updating is requested.
    2206      */
    2207     ::ValidateRgn(GetHWnd(), NULL);
    2208
    2209     if (updated == COMPLEXREGION || updated == SIMPLEREGION) {
    2210         if (insets != NULL) {
    2211             ::OffsetRgn(rgn, insets->left, insets->top);
    2212         }
    2213         DWORD size = ::GetRegionData(rgn, 0, NULL);
    2214         if (size == 0) {
    2215             ::DeleteObject((HGDIOBJ)rgn);
    2216             return;
    2217         }
    2218         char* buffer = new char[size]; // safe because sizeof(char)==1
    2219         memset(buffer, 0, size);
    2220         LPRGNDATA rgndata = (LPRGNDATA)buffer;
    2221         rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
    2222         rgndata->rdh.iType = RDH_RECTANGLES;
    2223         int retCode = ::GetRegionData(rgn, size, rgndata);
    2224         VERIFY(retCode);
    2225         if (retCode == 0) {
    2226             delete [] buffer;
    2227             ::DeleteObject((HGDIOBJ)rgn);
    2228             return;
    2229         }
    2230         /*
    2231          * Updating rects are divided into mostly vertical and mostly horizontal
    2232          * Each group is united together and if not empty painted separately
    2233          */
    2234         RECT* r = (RECT*)(buffer + rgndata->rdh.dwSize);
    2235         RECT* un[2] = {0, 0};
    2236     DWORD i;
    2237     for (i = 0; i < rgndata->rdh.nCount; i++, r++) {
    2238             int width = r->right-r->left;
    2239             int height = r->bottom-r->top;
    2240             if (width > 0 && height > 0) {
    2241                 int toAdd = (width > height) ? 0: 1;
    2242                 if (un[toAdd] != 0) {
    2243                     ::UnionRect(un[toAdd], un[toAdd], r);
    2244                 } else {
    2245                     un[toAdd] = r;
    2246                 }
    2247             }
    2248         }
    2249         for(i = 0; i < 2; i++) {
    2250             if (un[i] != 0) {
    2251                 DoCallback("handleExpose", "(IIII)V",
    2252                            ScaleDownX(un[i]->left),
    2253                            ScaleDownY(un[i]->top),
    2254                            ScaleDownX(un[i]->right - un[i]->left),
    2255                            ScaleDownY(un[i]->bottom - un[i]->top));
    2256             }
    2257         }
    2258         delete [] buffer;
    2259     }
    2260     ::DeleteObject((HGDIOBJ)rgn);
    2261 }
    2262
    2263 MsgRouting AwtComponent::WmMouseEnter(UINT flags, int x, int y)
    2264 {
    2265     SendMouseEvent(java_awt_event_MouseEvent_MOUSE_ENTERED,
    2266                    ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(), 0, JNI_FALSE);
    2267     if ((flags & ALL_MK_BUTTONS) == 0) {
    2268         AwtCursor::UpdateCursor(this);
    2269     }
    2270     sm_cursorOn = GetHWnd();
    2271     return mrConsume;   /* Don't pass our synthetic event on! */
    2272 }
    2273
    2274 MSG*
    2275 AwtComponent::CreateMessage(UINT message, WPARAM wParam, LPARAM lParam,
    2276                             int x = 0, int y = 0)
    2277 {
    2278     MSG* pMsg = new MSG;
    2279     InitMessage(pMsg, message, wParam, lParam, x, y);
    2280     return pMsg;
    2281 }
    2282
    2283
    2284 jint
    2285 AwtComponent::GetDrawState(HWND hwnd) {
    2286     return (jint)(INT_PTR)(::GetProp(hwnd, DrawingStateProp));
    2287 }
    2288
    2289 void
    2290 AwtComponent::SetDrawState(HWND hwnd, jint state) {
    2291     ::SetProp(hwnd, DrawingStateProp, (HANDLE)(INT_PTR)state);
    2292 }
    2293
    2294 void
    2295 AwtComponent::InitMessage(MSG* msg, UINT message, WPARAM wParam, LPARAM lParam,
    2296                             int x = 0, int y = 0)
    2297 {
    2298     msg->message = message;
    2299     msg->wParam = wParam;
    2300     msg->lParam = lParam;
    2301     msg->time = ::GetMessageTime();
    2302     msg->pt.x = x;
    2303     msg->pt.y = y;
    2304 }
    2305
    2306 MsgRouting AwtComponent::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) {
    2307     return mrDoDefault;
    2308 }
    2309 MsgRouting AwtComponent::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) {
    2310     return mrDoDefault;
    2311 }
    2312
    2313 MsgRouting AwtComponent::WmWindowPosChanging(LPARAM windowPos) {
    2314     return mrDoDefault;
    2315 }
    2316 MsgRouting AwtComponent::WmWindowPosChanged(LPARAM windowPos) {
    2317     return mrDoDefault;
    2318 }
    2319
    2320 void AwtComponent::WmTouch(WPARAM wParam, LPARAM lParam) {
    2321     AwtToolkit& tk = AwtToolkit::GetInstance();
    2322     if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) {
    2323         return;
    2324     }
    2325
    2326     UINT inputsCount = LOWORD(wParam);
    2327     TOUCHINPUT* pInputs = new TOUCHINPUT[inputsCount];
    2328     if (pInputs != NULL) {
    2329         if (tk.TIGetTouchInputInfo((HTOUCHINPUT)lParam, inputsCount, pInputs,
    2330                 sizeof(TOUCHINPUT)) != 0) {
    2331             for (UINT i = 0; i < inputsCount; i++) {
    2332                 TOUCHINPUT ti = pInputs[i];
    2333                 if (ti.dwFlags & TOUCHEVENTF_PRIMARY) {
    2334                     if (ti.dwFlags & TOUCHEVENTF_DOWN) {
    2335                         m_touchDownPoint.x = ti.x / 100;
    2336                         m_touchDownPoint.y = ti.y / 100;
    2337                         ::ScreenToClient(GetHWnd(), &m_touchDownPoint);
    2338                         m_touchDownOccurred = TRUE;
    2339                     } else if (ti.dwFlags & TOUCHEVENTF_UP) {
    2340                         m_touchUpPoint.x = ti.x / 100;
    2341                         m_touchUpPoint.y = ti.y / 100;
    2342                         ::ScreenToClient(GetHWnd(), &m_touchUpPoint);
    2343                         m_touchUpOccurred = TRUE;
    2344                     }
    2345                 }
    2346             }
    2347         }
    2348         delete[] pInputs;
    2349     }
    2350 }
    2351
    2352 /* Double-click variables. */
    2353 static jlong multiClickTime = ::GetDoubleClickTime();
    2354 static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK);
    2355 static int multiClickMaxY = ::GetSystemMetrics(SM_CYDOUBLECLK);
    2356 static AwtComponent* lastClickWnd = NULL;
    2357 static jlong lastTime = 0;
    2358 static int lastClickX = 0;
    2359 static int lastClickY = 0;
    2360 static int lastButton = 0;
    2361 static int clickCount = 0;
    2362
    2363 // A static method that makes the clickCount available in the derived classes
    2364 // overriding WmMouseDown().
    2365 int AwtComponent::GetClickCount()
    2366 {
    2367     return clickCount;
    2368 }
    2369
    2370 MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button)
    2371 {
    2372     jlong now = ::JVM_CurrentTimeMillis(NULL, 0);
    2373
    2374     if (lastClickWnd == this &&
    2375         lastButton == button &&
    2376         (now - lastTime) <= multiClickTime &&
    2377         abs(x - lastClickX) <= multiClickMaxX &&
    2378         abs(y - lastClickY) <= multiClickMaxY)
    2379     {
    2380         clickCount++;
    2381     } else {
    2382         clickCount = 1;
    2383         lastClickWnd = this;
    2384         lastButton = button;
    2385         lastClickX = x;
    2386         lastClickY = y;
    2387     }
    2388     /*
    2389      *Set appropriate bit of the mask on WM_MOUSE_DOWN message.
    2390      */
    2391     m_mouseButtonClickAllowed |= GetButtonMK(button);
    2392     lastTime = now;
    2393
    2394     BOOL causedByTouchEvent = FALSE;
    2395     if (m_touchDownOccurred &&
    2396         (abs(m_touchDownPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) &&
    2397         (abs(m_touchDownPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) {
    2398         causedByTouchEvent = TRUE;
    2399         m_touchDownOccurred = FALSE;
    2400     }
    2401
    2402     MSG msg;
    2403     InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
    2404
    2405     AwtWindow *toplevel = GetContainer();
    2406     if (toplevel && !toplevel->IsSimpleWindow()) {
    2407         /*
    2408          * The frame should be focused by click in case it is
    2409          * the active window but not the focused window. See 6886678.
    2410          */
    2411         if (toplevel->GetHWnd() == ::GetActiveWindow() &&
    2412             toplevel->GetHWnd() != AwtComponent::GetFocusedWindow())
    2413         {
    2414             toplevel->AwtSetActiveWindow();
    2415         }
    2416     }
    2417
    2418     SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
    2419                    GetJavaModifiers(), clickCount, JNI_FALSE,
    2420                    GetButton(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 the
    2424      * latest retrieved message (see lastMessage in awt_Component.cpp)
    2425      * matches the mouse message being processed.
    2426      * SetCapture() sends WM_CAPTURECHANGED and breaks that
    2427      * assumption.
    2428      */
    2429     SetDragCapture(flags);
    2430
    2431     AwtWindow * owner = (AwtWindow*)GetComponent(GetTopLevelParentForWindow(GetHWnd()));
    2432     if (AwtWindow::GetGrabbedWindow() != NULL && owner != NULL) {
    2433         if (!AwtWindow::GetGrabbedWindow()->IsOneOfOwnersOf(owner)) {
    2434             AwtWindow::GetGrabbedWindow()->Ungrab();
    2435         }
    2436     }
    2437     return mrConsume;
    2438 }
    2439
    2440 MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button)
    2441 {
    2442     BOOL causedByTouchEvent = FALSE;
    2443     if (m_touchUpOccurred &&
    2444         (abs(m_touchUpPoint.x - x) <= TOUCH_MOUSE_COORDS_DELTA) &&
    2445         (abs(m_touchUpPoint.y - y) <= TOUCH_MOUSE_COORDS_DELTA)) {
    2446         causedByTouchEvent = TRUE;
    2447         m_touchUpOccurred = FALSE;
    2448     }
    2449
    2450     MSG msg;
    2451     InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
    2452
    2453     SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, ::JVM_CurrentTimeMillis(NULL, 0),
    2454                    x, y, GetJavaModifiers(), clickCount,
    2455                    (GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ?
    2456                     TRUE : 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      */
    2462     if ((m_mouseButtonClickAllowed & GetButtonMK(button)) != 0) { //CLICK allowed
    2463         SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED,
    2464                        ::JVM_CurrentTimeMillis(NULL, 0), x, y, GetJavaModifiers(),
    2465                        clickCount, JNI_FALSE, GetButton(button));
    2466     }
    2467     // Exclude button from allowed to generate CLICK messages
    2468     m_mouseButtonClickAllowed &= ~GetButtonMK(button);
    2469
    2470     if ((flags & ALL_MK_BUTTONS) == 0) {
    2471         // only update if all buttons have been released
    2472         AwtCursor::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 the
    2477      * latest retrieved message (see lastMessage in awt_Component.cpp)
    2478      * matches the mouse message being processed.
    2479      * ReleaseCapture() sends WM_CAPTURECHANGED and breaks that
    2480      * assumption.
    2481      */
    2482     ReleaseDragCapture(flags);
    2483
    2484     return mrConsume;
    2485 }
    2486
    2487 MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y)
    2488 {
    2489     static AwtComponent* lastComp = NULL;
    2490     static int lastX = 0;
    2491     static int lastY = 0;
    2492
    2493     /*
    2494      * Only report mouse move and drag events if a move or drag
    2495      * actually happened -- Windows sends a WM_MOUSEMOVE in case the
    2496      * app wants to modify the cursor.
    2497      */
    2498     if (lastComp != this || x != lastX || y != lastY) {
    2499         lastComp = this;
    2500         lastX = x;
    2501         lastY = y;
    2502         BOOL extraButtonsEnabled = AwtToolkit::GetInstance().areExtraMouseButtonsEnabled();
    2503         if (((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 fire
    2509             // Clicked event: m_firstDragSent set to TRUE.
    2510             // This is a partial backout of 5039416 fix.
    2511             MSG msg;
    2512             InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
    2513             SendMouseEvent(java_awt_event_MouseEvent_MOUSE_DRAGGED, ::JVM_CurrentTimeMillis(NULL, 0), x, y,
    2514                            GetJavaModifiers(), 0, JNI_FALSE,
    2515                            java_awt_event_MouseEvent_NOBUTTON, &msg);
    2516             //dragging means no more CLICKs until next WM_MOUSE_DOWN/WM_MOUSE_UP message sequence
    2517             m_mouseButtonClickAllowed = 0;
    2518         } else {
    2519             MSG msg;
    2520             InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
    2521             SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, ::JVM_CurrentTimeMillis(NULL, 0), x, y,
    2522                            GetJavaModifiers(), 0, JNI_FALSE,
    2523                            java_awt_event_MouseEvent_NOBUTTON, &msg);
    2524         }
    2525     }
    2526
    2527     return mrConsume;
    2528 }
    2529
    2530 MsgRouting AwtComponent::WmMouseExit(UINT flags, int x, int y)
    2531 {
    2532     SendMouseEvent(java_awt_event_MouseEvent_MOUSE_EXITED, ::JVM_CurrentTimeMillis(NULL, 0), x,
    2533                    y, GetJavaModifiers(), 0, JNI_FALSE);
    2534     sm_cursorOn = NULL;
    2535     return mrConsume;   /* Don't pass our synthetic event on! */
    2536 }
    2537
    2538 MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,
    2539                                       int wheelRotation, BOOL isHorizontal)
    2540 {
    2541     // convert coordinates to be Component-relative, not screen relative
    2542     // for wheeling when outside the window, this works similar to
    2543     // coordinates during a drag
    2544     POINT eventPt;
    2545     eventPt.x = x;
    2546     eventPt.y = y;
    2547     DTRACE_PRINT2("  original coords: %i,%i\n", x, y);
    2548     ::ScreenToClient(GetHWnd(), &eventPt);
    2549     DTRACE_PRINT2("  new coords: %i,%i\n\n", eventPt.x, eventPt.y);
    2550
    2551     // set some defaults
    2552     jint scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL;
    2553     jint scrollUnits = 3;
    2554
    2555     BOOL result;
    2556     UINT platformUnits;
    2557     jint roundedWheelRotation;
    2558     jdouble preciseWheelRotation;
    2559
    2560     // AWT interprets wheel rotation differently than win32, so we need to
    2561     // decode wheel amount.
    2562     jint modifiers = GetJavaModifiers();
    2563     if (isHorizontal) {
    2564         modifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK;
    2565         m_wheelRotationAmountX += wheelRotation;
    2566         roundedWheelRotation = m_wheelRotationAmountX / (WHEEL_DELTA);
    2567         preciseWheelRotation = (jdouble) wheelRotation / (WHEEL_DELTA);
    2568         result = ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0,
    2569                                         &platformUnits, 0);
    2570     } else {
    2571         m_wheelRotationAmountY += wheelRotation;
    2572         roundedWheelRotation = m_wheelRotationAmountY / (-1 * WHEEL_DELTA);
    2573         preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);
    2574         result = ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
    2575                                         &platformUnits, 0);
    2576     }
    2577
    2578     MSG msg;
    2579     InitMessage(&msg, lastMessage, MAKEWPARAM(flags, wheelRotation),
    2580                 MAKELPARAM(x, y));
    2581
    2582     if (result) {
    2583         if (platformUnits == WHEEL_PAGESCROLL) {
    2584             scrollType = java_awt_event_MouseWheelEvent_WHEEL_BLOCK_SCROLL;
    2585             scrollUnits = 1;
    2586         }
    2587         else {
    2588             scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL;
    2589             scrollUnits = platformUnits;
    2590         }
    2591     }
    2592
    2593     DTRACE_PRINTLN("calling SendMouseWheelEvent");
    2594
    2595     SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, ::JVM_CurrentTimeMillis(NULL, 0),
    2596                         eventPt.x, eventPt.y, modifiers, 0, 0, scrollType,
    2597                         scrollUnits, roundedWheelRotation, preciseWheelRotation, &msg);
    2598
    2599     m_wheelRotationAmountX %= WHEEL_DELTA;
    2600     m_wheelRotationAmountY %= WHEEL_DELTA;
    2601     // this message could be propagated up to the parent chain
    2602     // by the mouse message post processors
    2603     return mrConsume;
    2604 }
    2605
    2606 jint AwtComponent::GetKeyLocation(UINT wkey, UINT flags) {
    2607     // Rector+Newcomer page 413
    2608     // The extended keys are the Alt and Control on the right of
    2609     // the space bar, the non-Numpad arrow keys, the non-Numpad
    2610     // 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 keys
    2613     // (91 and 92) are extended keys, the Context Menu key
    2614     // (property key or application key - 93) is extended,
    2615     // and so is the NumLock key.
    2616
    2617     // wkey is the wParam, flags is the HIWORD of the lParam
    2618
    2619     // "Extended" bit is 24th in lParam, so it's 8th in flags = HIWORD(lParam)
    2620     BOOL extended = ((1<<8) & flags);
    2621
    2622     if (IsNumPadKey(wkey, extended)) {
    2623         return java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD;
    2624     }
    2625
    2626     switch (wkey) {
    2627       case VK_SHIFT:
    2628         return AwtComponent::GetShiftKeyLocation(wkey, flags);
    2629       case VK_CONTROL: // fall through
    2630       case VK_MENU:
    2631         if (extended) {
    2632             return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;
    2633         } else {
    2634             return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
    2635         }
    2636       case VK_LWIN:
    2637         return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
    2638       case VK_RWIN:
    2639         return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;
    2640       default:
    2641         break;
    2642     }
    2643
    2644     // REMIND: if we add keycodes for the windows keys, we'll have to
    2645     // include left/right discrimination code for them.
    2646
    2647     return java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
    2648 }
    2649
    2650 jint AwtComponent::GetShiftKeyLocation(UINT vkey, UINT flags)
    2651 {
    2652     // init scancodes to safe values
    2653     UINT leftShiftScancode = 0;
    2654     UINT rightShiftScancode = 0;
    2655
    2656     // First 8 bits of flags is the scancode
    2657     UINT keyScanCode = flags & 0xFF;
    2658
    2659     DTRACE_PRINTLN3(
    2660       "AwtComponent::GetShiftKeyLocation  vkey = %d = 0x%x  scan = %d",
    2661       vkey, vkey, keyScanCode);
    2662
    2663     leftShiftScancode = ::MapVirtualKey(VK_LSHIFT, 0);
    2664     rightShiftScancode = ::MapVirtualKey(VK_RSHIFT, 0);
    2665
    2666     if (keyScanCode == leftShiftScancode) {
    2667         return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
    2668     }
    2669     if (keyScanCode == rightShiftScancode) {
    2670         return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;
    2671     }
    2672
    2673     DASSERT(false);
    2674     // Note: the above should not fail on NT (or 2000)
    2675
    2676     // default value
    2677     return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
    2678 }
    2679
    2680 /* Returns Java ActionEvent modifieres.
    2681  * When creating ActionEvent, modifiers provided by ActionEvent
    2682  * class should be set.
    2683  */
    2684 jint
    2685 AwtComponent::GetActionModifiers()
    2686 {
    2687     jint modifiers = GetJavaModifiers();
    2688
    2689     if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) {
    2690         modifiers |= java_awt_event_ActionEvent_CTRL_MASK;
    2691     }
    2692     if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) {
    2693         modifiers |= java_awt_event_ActionEvent_SHIFT_MASK;
    2694     }
    2695     if (modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) {
    2696         modifiers |= java_awt_event_ActionEvent_ALT_MASK;
    2697     }
    2698     return modifiers;
    2699 }
    2700
    2701 /* Returns Java extended InputEvent modifieres.
    2702  * Since ::GetKeyState returns current state and Java modifiers represent
    2703  * state before event, modifier on changed key are inverted.
    2704  */
    2705 jint
    2706 AwtComponent::GetJavaModifiers()
    2707 {
    2708     jint modifiers = 0;
    2709
    2710     if (HIBYTE(::GetKeyState(VK_CONTROL)) != 0) {
    2711         modifiers |= java_awt_event_InputEvent_CTRL_DOWN_MASK;
    2712     }
    2713     if (HIBYTE(::GetKeyState(VK_SHIFT)) != 0) {
    2714         modifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK;
    2715     }
    2716     if (HIBYTE(::GetKeyState(VK_MENU)) != 0) {
    2717         modifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK;
    2718     }
    2719     if (HIBYTE(::GetKeyState(VK_RMENU)) != 0) {
    2720         modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK;
    2721     }
    2722     if (HIBYTE(::GetKeyState(VK_MBUTTON)) != 0) {
    2723        modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;
    2724     }
    2725     if (HIBYTE(::GetKeyState(VK_RBUTTON)) != 0) {
    2726         modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK;
    2727     }
    2728     if (HIBYTE(::GetKeyState(VK_LBUTTON)) != 0) {
    2729         modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK;
    2730     }
    2731
    2732     if (HIBYTE(::GetKeyState(VK_XBUTTON1)) != 0) {
    2733         modifiers |= masks[3];
    2734     }
    2735     if (HIBYTE(::GetKeyState(VK_XBUTTON2)) != 0) {
    2736         modifiers |= masks[4];
    2737     }
    2738     return modifiers;
    2739 }
    2740
    2741 jint
    2742 AwtComponent::GetButton(int mouseButton)
    2743 {
    2744     /* Mouse buttons are already set correctly for left/right handedness */
    2745     switch(mouseButton) {
    2746     case LEFT_BUTTON:
    2747         return java_awt_event_MouseEvent_BUTTON1;
    2748     case MIDDLE_BUTTON:
    2749         return java_awt_event_MouseEvent_BUTTON2;
    2750     case RIGHT_BUTTON:
    2751         return java_awt_event_MouseEvent_BUTTON3;
    2752     case X1_BUTTON: //16 :
    2753         //just assign 4 and 5 numbers because MouseEvent class doesn't contain const identifier for them now
    2754         return 4;
    2755     case X2_BUTTON: //32
    2756         return 5;
    2757     }
    2758     return java_awt_event_MouseEvent_NOBUTTON;
    2759 }
    2760
    2761 UINT
    2762 AwtComponent::GetButtonMK(int mouseButton)
    2763 {
    2764     switch(mouseButton) {
    2765     case LEFT_BUTTON:
    2766         return MK_LBUTTON;
    2767     case MIDDLE_BUTTON:
    2768         return MK_MBUTTON;
    2769     case RIGHT_BUTTON:
    2770         return MK_RBUTTON;
    2771     case X1_BUTTON:
    2772         return MK_XBUTTON1;
    2773     case X2_BUTTON:
    2774         return MK_XBUTTON2;
    2775     }
    2776     return 0;
    2777 }
    2778
    2779 // FIXME: Keyboard related stuff has grown so big and hairy that we
    2780 // really need to move it into a class of its own.  And, since
    2781 // keyboard is a shared resource, AwtComponent is a bad place for it.
    2782
    2783 // These constants are defined in the Japanese version of VC++5.0,
    2784 // but not the US version
    2785 #ifndef VK_CONVERT
    2786 #define VK_KANA           0x15
    2787 #define VK_KANJI          0x19
    2788 #define VK_CONVERT        0x1C
    2789 #define VK_NONCONVERT     0x1D
    2790 #endif
    2791
    2792 #ifndef VK_XBUTTON1
    2793 #define VK_XBUTTON1      0x05
    2794 #endif
    2795
    2796 #ifndef VK_XBUTTON2
    2797 #define VK_XBUTTON2      0x06
    2798 #endif
    2799
    2800 typedef struct {
    2801     UINT javaKey;
    2802     UINT windowsKey;
    2803 } KeyMapEntry;
    2804
    2805 // Static table, arranged more or less spatially.
    2806 KeyMapEntry keyMapTable[] = {
    2807     // Modifier keys
    2808     {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},
    2814
    2815     // Miscellaneous Windows keys
    2816     {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},
    2819
    2820     // Alphabet
    2821     {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'},
    2847
    2848     // Standard numeric row
    2849     {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'},
    2859
    2860     // Misc key from main block
    2861     {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},
    2866
    2867     // 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 5
    2875
    2876     // 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},
    2881
    2882     // NumPad with NumLock on: numbers
    2883     {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},
    2893
    2894     // NumPad with NumLock on
    2895     {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},
    2901
    2902     // Functional keys
    2903     {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},
    2927
    2928     {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},
    2933
    2934     // Japanese
    2935     {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},
    2944
    2945     {java_awt_event_KeyEvent_VK_UNDEFINED,        0}
    2946 };
    2947
    2948
    2949 // Dynamic mapping table for OEM VK codes.  This table is refilled
    2950 // by BuildDynamicKeyMapTable when keyboard layout is switched.
    2951 // (see NT4 DDK src/input/inc/vkoem.h for OEM VK_ values).
    2952 struct DynamicKeyMapEntry {
    2953     UINT windowsKey;            // OEM VK codes known in advance
    2954     UINT javaKey;               // depends on input langauge (kbd layout)
    2955 };
    2956
    2957 static DynamicKeyMapEntry dynamicKeyMapTable[] = {
    2958     {0x00BA,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_1
    2959     {0x00BB,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PLUS
    2960     {0x00BC,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_COMMA
    2961     {0x00BD,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_MINUS
    2962     {0x00BE,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PERIOD
    2963     {0x00BF,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_2
    2964     {0x00C0,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_3
    2965     {0x00DB,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_4
    2966     {0x00DC,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_5
    2967     {0x00DD,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_6
    2968     {0x00DE,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_7
    2969     {0x00DF,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_8
    2970     {0x00E2,  java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_102
    2971     {0, 0}
    2972 };
    2973
    2974
    2975
    2976 // Auxiliary tables used to fill the above dynamic table.  We first
    2977 // find the character for the OEM VK code using ::MapVirtualKey and
    2978 // then go through these auxiliary tables to map it to Java VK code.
    2979
    2980 struct CharToVKEntry {
    2981     WCHAR c;
    2982     UINT  javaKey;
    2983 };
    2984
    2985 static 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 };
    3018
    3019 // For dead accents some layouts return ASCII punctuation, while some
    3020 // return spacing accent chars, so both should be listed.  NB: MS docs
    3021 // say that conversion routings return spacing accent character, not
    3022 // combining.
    3023 static 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 hacek
    3038     {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 };
    3047
    3048 // The full map of the current keyboard state including
    3049 // windows virtual key, scancode, java virtual key, and unicode
    3050 // 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 code
    3053 struct DynPrimaryKeymapEntry {
    3054     UINT wkey;
    3055     UINT scancode;
    3056     UINT jkey;
    3057     WCHAR unicode;
    3058 };
    3059
    3060 static DynPrimaryKeymapEntry dynPrimaryKeymap[256];
    3061
    3062 void
    3063 AwtComponent::InitDynamicKeyMapTable()
    3064 {
    3065     static BOOL kbdinited = FALSE;
    3066
    3067     if (!kbdinited) {
    3068         AwtComponent::BuildDynamicKeyMapTable();
    3069         // We cannot build it here since JNI is not available yet:
    3070         //AwtComponent::BuildPrimaryDynamicTable();
    3071         kbdinited = TRUE;
    3072     }
    3073 }
    3074
    3075 void
    3076 AwtComponent::BuildDynamicKeyMapTable()
    3077 {
    3078     HKL hkl = GetKeyboardLayout();
    3079
    3080     DTRACE_PRINTLN2("Building dynamic VK mapping tables: HKL = %08X (CP%d)",
    3081                     hkl, AwtComponent::GetCodePage());
    3082
    3083     // Will need this to reset layout after dead keys.
    3084     UINT spaceScanCode = ::MapVirtualKeyEx(VK_SPACE, 0, hkl);
    3085
    3086     // Entries in dynamic table that maps between Java VK and Windows
    3087     // VK are built in three steps:
    3088     //   1. Map windows VK to ANSI character (cannot map to unicode
    3089     //      directly, since ::ToUnicode is not implemented on win9x)
    3090     //   2. Convert ANSI char to Unicode char
    3091     //   3. Map Unicode char to Java VK via two auxilary tables.
    3092
    3093     for (DynamicKeyMapEntry *dynamic = dynamicKeyMapTable;
    3094          dynamic->windowsKey != 0;
    3095          ++dynamic)
    3096     {
    3097         // Defaults to VK_UNDEFINED
    3098         dynamic->javaKey = java_awt_event_KeyEvent_VK_UNDEFINED;
    3099
    3100         BYTE kbdState[AwtToolkit::KB_STATE_SIZE];
    3101         AwtToolkit::GetKeyboardState(kbdState);
    3102
    3103         kbdState[dynamic->windowsKey] |=  0x80; // Press the key.
    3104
    3105         // Unpress modifiers, since they are most likely pressed as
    3106         // part of the keyboard switching shortcut.
    3107         kbdState[VK_CONTROL] &= ~0x80;
    3108         kbdState[VK_SHIFT]   &= ~0x80;
    3109         kbdState[VK_MENU]    &= ~0x80;
    3110
    3111         char cbuf[2] = { '\0', '\0'};
    3112         UINT scancode = ::MapVirtualKeyEx(dynamic->windowsKey, 0, hkl);
    3113         int nchars = ::ToAsciiEx(dynamic->windowsKey, scancode, kbdState,
    3114                                  (WORD*)cbuf, 0, hkl);
    3115
    3116         // Auxiliary table used to map Unicode character to Java VK.
    3117         // Will assign a different table for dead keys (below).
    3118         const CharToVKEntry *charMap = charToVKTable;
    3119
    3120         if (nchars < 0) { // Dead key
    3121             // Use a different table for dead chars since different layouts
    3122             // return different characters for the same dead key.
    3123             charMap = charToDeadVKTable;
    3124
    3125             // We also need to reset layout so that next translation
    3126             // is unaffected by the dead status.  We do this by
    3127             // translating <SPACE> key.
    3128             kbdState[dynamic->windowsKey] &= ~0x80;
    3129             kbdState[VK_SPACE] |= 0x80;
    3130
    3131             char junkbuf[2] = { '\0', '\0'};
    3132             ::ToAsciiEx(VK_SPACE, spaceScanCode, kbdState,
    3133                         (WORD*)junkbuf, 0, hkl);
    3134         }
    3135
    3136 #ifdef DEBUG
    3137         if (nchars == 0) {
    3138             DTRACE_PRINTLN1("VK 0x%02X -> cannot convert to ANSI char",
    3139                             dynamic->windowsKey);
    3140             continue;
    3141         }
    3142         else if (nchars > 1) {  // can't happen, see reset code below
    3143             DTRACE_PRINTLN3("VK 0x%02X -> converted to <0x%02X,0x%02X>",
    3144                             dynamic->windowsKey,
    3145                             (UCHAR)cbuf[0], (UCHAR)cbuf[1]);
    3146             continue;
    3147         }
    3148 #endif
    3149
    3150         WCHAR ucbuf[2] = { L'\0', L'\0' };
    3151         int nconverted = ::MultiByteToWideChar(AwtComponent::GetCodePage(), 0,
    3152                                                cbuf, 1, ucbuf, 2);
    3153 #ifdef DEBUG
    3154         if (nconverted < 0) {
    3155             DTRACE_PRINTLN3("VK 0x%02X -> ANSI 0x%02X -> MultiByteToWideChar failed (0x%X)",
    3156                             dynamic->windowsKey, (UCHAR)cbuf[0],
    3157                             ::GetLastError());
    3158             continue;
    3159         }
    3160 #endif
    3161
    3162         WCHAR uc = ucbuf[0];
    3163         for (const CharToVKEntry *map = charMap;  map->c != 0;  ++map) {
    3164             if (uc == map->c) {
    3165                 dynamic->javaKey = map->javaKey;
    3166                 break;
    3167             }
    3168         }
    3169
    3170         DTRACE_PRINTLN4("VK 0x%02X -> ANSI 0x%02X -> U+%04X -> Java VK 0x%X",
    3171                         dynamic->windowsKey, (UCHAR)cbuf[0], (UINT)ucbuf[0],
    3172                         dynamic->javaKey);
    3173     } // for each VK_OEM_*
    3174 }
    3175
    3176
    3177 static BOOL isKanaLockAvailable()
    3178 {
    3179     // This method is to determine whether the Kana Lock feature is
    3180     // available on the attached keyboard.  Kana Lock feature does not
    3181     // necessarily require that the real KANA keytop is available on
    3182     // 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).
    3187     return (LOWORD(GetKeyboardLayout(0)) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT))
    3188         && (GetKeyboardType(0) == 7);
    3189 }
    3190
    3191 void AwtComponent::JavaKeyToWindowsKey(UINT javaKey,
    3192                                        UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey)
    3193 {
    3194     // Handle the few cases where a Java VK code corresponds to a Windows
    3195     // key/modifier combination or applies only to specific keyboard layouts
    3196     switch (javaKey) {
    3197         case java_awt_event_KeyEvent_VK_ALL_CANDIDATES:
    3198             *windowsKey = VK_CONVERT;
    3199             *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK;
    3200             return;
    3201         case java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE:
    3202             *windowsKey = VK_CONVERT;
    3203             *modifiers = java_awt_event_InputEvent_SHIFT_DOWN_MASK;
    3204             return;
    3205         case java_awt_event_KeyEvent_VK_CODE_INPUT:
    3206             *windowsKey = VK_DBE_ALPHANUMERIC;
    3207             *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK;
    3208             return;
    3209         case java_awt_event_KeyEvent_VK_KANA_LOCK:
    3210             if (isKanaLockAvailable()) {
    3211                 *windowsKey = VK_KANA;
    3212                 *modifiers = java_awt_event_InputEvent_CTRL_DOWN_MASK;
    3213                 return;
    3214             }
    3215     }
    3216
    3217     // for the general case, use a bi-directional table
    3218     for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {
    3219         if (keyMapTable[i].javaKey == javaKey) {
    3220             *windowsKey = keyMapTable[i].windowsKey;
    3221             *modifiers = 0;
    3222             return;
    3223         }
    3224     }
    3225
    3226     // Bug 4766655
    3227     // Two Windows keys could map to the same Java key, so
    3228     // give preference to the originalWindowsKey if it is
    3229     // specified (not IGNORE_KEY).
    3230     if (originalWindowsKey == IGNORE_KEY) {
    3231         for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
    3232             if (dynamicKeyMapTable[j].javaKey == javaKey) {
    3233                 *windowsKey = dynamicKeyMapTable[j].windowsKey;
    3234                 *modifiers = 0;
    3235                 return;
    3236             }
    3237         }
    3238     } else {
    3239         BOOL found = false;
    3240         for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
    3241             if (dynamicKeyMapTable[j].javaKey == javaKey) {
    3242                 *windowsKey = dynamicKeyMapTable[j].windowsKey;
    3243                 *modifiers = 0;
    3244                 found = true;
    3245                 if (*windowsKey == originalWindowsKey) {
    3246                     return;   /* if ideal case found return, else keep looking */
    3247                 }
    3248             }
    3249         }
    3250         if (found) {
    3251             return;
    3252         }
    3253     }
    3254
    3255     *windowsKey = 0;
    3256     *modifiers = 0;
    3257     return;
    3258 }
    3259
    3260 UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey)
    3261
    3262 {
    3263     // Handle the few cases where we need to take the modifier into
    3264     // consideration for the Java VK code or where we have to take the keyboard
    3265     // layout into consideration so that function keys can get
    3266     // recognized in a platform-independent way.
    3267     switch (windowsKey) {
    3268         case VK_CONVERT:
    3269             if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {
    3270                 return java_awt_event_KeyEvent_VK_ALL_CANDIDATES;
    3271             }
    3272             if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0) {
    3273                 return java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE;
    3274             }
    3275             break;
    3276         case VK_DBE_ALPHANUMERIC:
    3277             if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) {
    3278                 return java_awt_event_KeyEvent_VK_CODE_INPUT;
    3279             }
    3280             break;
    3281         case VK_KANA:
    3282             if (isKanaLockAvailable()) {
    3283                 return java_awt_event_KeyEvent_VK_KANA_LOCK;
    3284             }
    3285             break;
    3286     };
    3287
    3288     // check dead key
    3289     if (isDeadKey) {
    3290       for (int i = 0; charToDeadVKTable[i].c != 0; i++) {
    3291         if (charToDeadVKTable[i].c == character) {
    3292             return charToDeadVKTable[i].javaKey;
    3293         }
    3294       }
    3295     }
    3296
    3297     // for the general case, use a bi-directional table
    3298     for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {
    3299         if (keyMapTable[i].windowsKey == windowsKey) {
    3300             return keyMapTable[i].javaKey;
    3301         }
    3302     }
    3303
    3304     for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
    3305         if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
    3306             if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) {
    3307                 return dynamicKeyMapTable[j].javaKey;
    3308             }else{
    3309                 break;
    3310             }
    3311         }
    3312     }
    3313
    3314     return java_awt_event_KeyEvent_VK_UNDEFINED;
    3315 }
    3316
    3317 BOOL AwtComponent::IsNavigationKey(UINT wkey) {
    3318     switch (wkey) {
    3319       case VK_END:
    3320       case VK_PRIOR:  // PageUp
    3321       case VK_NEXT:  // PageDown
    3322       case VK_HOME:
    3323       case VK_LEFT:
    3324       case VK_UP:
    3325       case VK_RIGHT:
    3326       case VK_DOWN:
    3327           return TRUE;
    3328     }
    3329     return FALSE;
    3330 }
    3331
    3332 // determine if a key is a numpad key (distinguishes the numpad
    3333 // arrow keys from the non-numpad arrow keys, for example).
    3334 BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended)
    3335 {
    3336     // Note: scancodes are the same for the numpad arrow keys and
    3337     // the non-numpad arrow keys (also for PageUp, etc.).
    3338     // The scancodes for the numpad divide and the non-numpad slash
    3339     // are the same, but the wparams are different
    3340
    3341     DTRACE_PRINTLN3("AwtComponent::IsNumPadKey  vkey = %d = 0x%x  extended = %d",
    3342       vkey, vkey, extended);
    3343
    3344     switch (vkey) {
    3345       case VK_CLEAR:  // numpad 5 with numlock off
    3346       case VK_NUMPAD0:
    3347       case VK_NUMPAD1:
    3348       case VK_NUMPAD2:
    3349       case VK_NUMPAD3:
    3350       case VK_NUMPAD4:
    3351       case VK_NUMPAD5:
    3352       case VK_NUMPAD6:
    3353       case VK_NUMPAD7:
    3354       case VK_NUMPAD8:
    3355       case VK_NUMPAD9:
    3356       case VK_MULTIPLY:
    3357       case VK_ADD:
    3358       case VK_SEPARATOR:  // numpad ,  not on US kbds
    3359       case VK_SUBTRACT:
    3360       case VK_DECIMAL:
    3361       case VK_DIVIDE:
    3362       case VK_NUMLOCK:
    3363         return TRUE;
    3364         break;
    3365       case VK_END:
    3366       case VK_PRIOR:  // PageUp
    3367       case VK_NEXT:  // PageDown
    3368       case VK_HOME:
    3369       case VK_LEFT:
    3370       case VK_UP:
    3371       case VK_RIGHT:
    3372       case VK_DOWN:
    3373       case VK_INSERT:
    3374       case VK_DELETE:
    3375         // extended if non-numpad
    3376         return (!extended);
    3377         break;
    3378       case VK_RETURN:  // extended if on numpad
    3379         return (extended);
    3380         break;
    3381       default:
    3382         break;
    3383     }
    3384
    3385     return FALSE;
    3386 }
    3387 static void
    3388 resetKbdState( BYTE kstate[256]) {
    3389     BYTE tmpState[256];
    3390     WCHAR wc[2];
    3391     memmove(tmpState, kstate, sizeof(kstate));
    3392     tmpState[VK_SHIFT] = 0;
    3393     tmpState[VK_CONTROL] = 0;
    3394     tmpState[VK_MENU] = 0;
    3395
    3396     ::ToUnicodeEx(VK_SPACE,::MapVirtualKey(VK_SPACE, 0), tmpState, wc, 2, 0,  GetKeyboardLayout(0));
    3397 }
    3398
    3399 // XXX in the update releases this is an addition to the unchanged existing code
    3400 // After the call, a table will have a unicode associated with a windows virtual keycode
    3401 // sans modifiers. With some further simplification, one can
    3402 // derive java keycode from it, and anyway we will pass this unicode value
    3403 // all the way up in a comment to a KeyEvent.
    3404 void
    3405 AwtComponent::BuildPrimaryDynamicTable() {
    3406     JNIEnv *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     //}
    3413
    3414     HKL hkl = GetKeyboardLayout();
    3415     UINT sc = 0;
    3416     BYTE kbdState[AwtToolkit::KB_STATE_SIZE];
    3417     memset(kbdState, 0, sizeof (kbdState));
    3418
    3419     // Use JNI call to obtain java key code. We should keep a list
    3420     // of currently available keycodes in a single place.
    3421     static jclass extKeyCodesCls;
    3422     if( extKeyCodesCls == NULL) {
    3423         jclass extKeyCodesClsLocal = env->FindClass("sun/awt/ExtendedKeyCodes");
    3424         DASSERT(extKeyCodesClsLocal);
    3425         CHECK_NULL(extKeyCodesClsLocal);
    3426         extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal);
    3427         env->DeleteLocalRef(extKeyCodesClsLocal);
    3428     }
    3429     static jmethodID getExtendedKeyCodeForChar;
    3430     if (getExtendedKeyCodeForChar == NULL) {
    3431         getExtendedKeyCodeForChar =
    3432                   env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I");
    3433         DASSERT(getExtendedKeyCodeForChar);
    3434         CHECK_NULL(getExtendedKeyCodeForChar);
    3435     }
    3436     jint extJKC; //extended Java key code
    3437
    3438     for (UINT i = 0; i < 256; i++) {
    3439         dynPrimaryKeymap[i].wkey = i;
    3440         dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED;
    3441         dynPrimaryKeymap[i].unicode = 0;
    3442
    3443         if ((sc = MapVirtualKey (i, 0)) == 0) {
    3444             dynPrimaryKeymap[i].scancode = 0;
    3445             continue;
    3446         }
    3447         dynPrimaryKeymap[i].scancode = sc;
    3448
    3449         // XXX process cases like VK_SHIFT etc.
    3450         kbdState[i] = 0x80; // "key pressed".
    3451         WCHAR wc[16];
    3452         int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl);
    3453         if (k == 1) {
    3454             // unicode
    3455             dynPrimaryKeymap[i].unicode = wc[0];
    3456             if (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 to
    3461                 //XXX an old java keycode: but how to say if it is a keypad key?
    3462                 //XXX We'll do it in WmKeyUp/Down.
    3463                 extJKC = env->CallStaticIntMethod(extKeyCodesCls,
    3464                                                   getExtendedKeyCodeForChar, (jint)(wc[0]));
    3465                 dynPrimaryKeymap[i].jkey = extJKC;
    3466             }
    3467         }else if (k == -1) {
    3468             // dead key: use charToDeadVKTable
    3469             dynPrimaryKeymap[i].unicode = wc[0];
    3470             resetKbdState( kbdState );
    3471             for (const CharToVKEntry *map = charToDeadVKTable;  map->c != 0;  ++map) {
    3472                 if (wc[0] == map->c) {
    3473                     dynPrimaryKeymap[i].jkey = map->javaKey;
    3474                     break;
    3475                 }
    3476             }
    3477         } else if (k == 0) {
    3478             // reset
    3479             resetKbdState( 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 DEBUG
    3486             DTRACE_PRINTLN2("wkey 0x%02X (%d)", i,i);
    3487 #endif
    3488         }
    3489         kbdState[i] = 0; // "key unpressed"
    3490     }
    3491 }
    3492 void
    3493 AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers)
    3494 {
    3495     if( wkey && wkey < 256 ) {
    3496         if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) {
    3497             // At the creation time,
    3498             // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /"
    3499             dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
    3500         }
    3501         if(dynPrimaryKeymap[wkey].jkey ==  java_awt_event_KeyEvent_VK_UNDEFINED) {
    3502             // E.g. it is non-unicode key
    3503             dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
    3504         }
    3505     }
    3506 }
    3507
    3508 UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey)
    3509 {
    3510     static Hashtable transTable("VKEY translations");
    3511     static Hashtable deadKeyFlagTable("Dead Key Flags");
    3512     isDeadKey = FALSE;
    3513
    3514     // Try to translate using last saved translation
    3515     if (ops == LOAD) {
    3516        void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
    3517        void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
    3518        if (value != NULL) {
    3519            isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));
    3520            return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
    3521        }
    3522     }
    3523
    3524     // 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 need
    3527     // to have a special case here.
    3528     if (wkey == VK_RETURN)
    3529         return '\n';
    3530
    3531     // high order bit in keyboardState indicates whether the key is down
    3532     static const BYTE KEY_STATE_DOWN = 0x80;
    3533     BYTE    keyboardState[AwtToolkit::KB_STATE_SIZE];
    3534     AwtToolkit::GetKeyboardState(keyboardState);
    3535
    3536     // apply modifiers to keyboard state if necessary
    3537     BOOL shiftIsDown = FALSE;
    3538     if (modifiers) {
    3539         shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK;
    3540         BOOL altIsDown = ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) ||
    3541                             (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK));
    3542         BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK;

    3543
    3544         if (shiftIsDown) {
    3545             keyboardState[VK_SHIFT] |= KEY_STATE_DOWN;
    3546         }
    3547
    3548         // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715)
    3549         // Here we try to resolve a conflict with ::ToAsciiEx's translating
    3550         // ALT+number key combinations. kdm@sarc.spb.su
    3551         // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail.
    3552         if( IsNavigationKey(wkey) ) {
    3553             keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
    3554         }
    3555
    3556         if (ctrlIsDown)
    3557         {
    3558             if (altIsDown) {
    3559                 // bugid 4215009: don't mess with AltGr == Ctrl + Alt
    3560                 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
    3561             }
    3562             else {
    3563                 // bugid 4098210: old event model doesn't have KEY_TYPED
    3564                 // events, so try to provide a meaningful character for
    3565                 // Ctrl+<key>.  Take Ctrl into account only when we know
    3566                 // that Ctrl+<key> will be an ASCII control.  Ignore by
    3567                 // default.
    3568                 keyboardState[VK_CONTROL] &= ~KEY_STATE_DOWN;
    3569
    3570                 // Letters have Ctrl+<letter> counterparts.  According to
    3571                 // <winuser.h> VK_A through VK_Z are the same as ASCII
    3572                 // 'A' through 'Z'.
    3573                 if (wkey >= 'A' && wkey <= 'Z') {
    3574                     keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
    3575                 }
    3576                 else {
    3577                     // Non-letter controls 033 to 037 are:
    3578                     // ^[ (ESC), ^\ (FS), ^] (GS), ^^ (RS), and ^_ (US)
    3579
    3580                     // Shift state bits returned by ::VkKeyScan in HIBYTE
    3581                     static const UINT _VKS_SHIFT_MASK = 0x01;
    3582                     static const UINT _VKS_CTRL_MASK = 0x02;
    3583                     static const UINT _VKS_ALT_MASK = 0x04;
    3584
    3585                     // Check to see whether there is a meaningful translation
    3586                     TCHAR ch;
    3587                     short vk;
    3588                     for (ch = _T('\033'); ch < _T('\040'); ch++) {
    3589                         vk = ::VkKeyScan(ch);
    3590                         if (wkey == LOBYTE(vk)) {
    3591                             UINT shiftState = HIBYTE(vk);
    3592                             if ((shiftState & _VKS_CTRL_MASK) ||
    3593                                 (!(shiftState & _VKS_SHIFT_MASK)
    3594                                 == !shiftIsDown))
    3595                             {
    3596                                 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN;
    3597                             }
    3598                             break;
    3599                         }
    3600                     }
    3601                 }
    3602             } // ctrlIsDown && altIsDown
    3603         } // ctrlIsDown
    3604     } // modifiers
    3605
    3606     WORD wChar[2];
    3607     int converted = 1;
    3608     UINT ch = ::MapVirtualKeyEx(wkey, 2, GetKeyboardLayout());
    3609     if (ch & 0x80000000) {
    3610         // Dead key which is handled as a normal key
    3611         isDeadKey = deadKeyActive = TRUE;
    3612     } else if (deadKeyActive) {
    3613         // We cannot use ::ToUnicodeEx if dead key is active because this will
    3614         // break dead key function
    3615         wChar[0] = shiftIsDown ? ch : tolower(ch);
    3616     } else {
    3617         UINT scancode = ::MapVirtualKey(wkey, 0);
    3618         converted = ::ToUnicodeEx(wkey, scancode, keyboardState,
    3619                                               wChar, 2, 0, GetKeyboardLayout());
    3620     }
    3621
    3622     UINT translation;
    3623     BOOL deadKeyFlag = (converted == 2);
    3624
    3625     // Dead Key
    3626     if (converted < 0 || isDeadKey) {
    3627         translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
    3628     } else
    3629     // No translation available -- try known conversions or else punt.
    3630     if (converted == 0) {
    3631         if (wkey == VK_DELETE) {
    3632             translation = '\177';
    3633         } else
    3634         if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
    3635             translation = '0' + wkey - VK_NUMPAD0;
    3636         } else {
    3637             translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
    3638         }
    3639     } else
    3640     // the caller expects a Unicode character.
    3641     if (converted > 0) {
    3642         translation = wChar[0];
    3643     }
    3644     if (ops == SAVE) {
    3645         transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
    3646                        reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));
    3647         if (deadKeyFlag) {
    3648             deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
    3649                          reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag)));
    3650         } else {
    3651             deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
    3652         }
    3653     }
    3654
    3655     isDeadKey = deadKeyFlag;
    3656     return translation;
    3657 }
    3658
    3659 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt,
    3660                                    UINT flags, BOOL system)
    3661 {
    3662     // VK_PROCESSKEY is a special value which means
    3663     //          "Current IME wants to consume this KeyEvent"
    3664     // Real key code is saved by IMM32.DLL and can be retrieved by
    3665     // calling ImmGetVirtualKey();
    3666     if (wkey == VK_PROCESSKEY) {
    3667         return mrDoDefault;
    3668     }
    3669     MSG msg;
    3670     InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN),
    3671                              wkey, MAKELPARAM(repCnt, flags));
    3672
    3673     UINT modifiers = GetJavaModifiers();
    3674     jint keyLocation = GetKeyLocation(wkey, flags);
    3675     BOOL isDeadKey = FALSE;
    3676     UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey);
    3677     UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
    3678     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
    3679
    3680
    3681     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
    3682                              ::JVM_CurrentTimeMillis(NULL, 0), jkey, character,
    3683                              modifiers, keyLocation, (jlong)wkey, &msg);
    3684
    3685     // bugid 4724007: Windows does not create a WM_CHAR for the Del key
    3686     // for some reason, so we need to create the KEY_TYPED event on the
    3687     // WM_KEYDOWN.  Use null msg so the character doesn't get sent back
    3688     // to the native window for processing (this event is synthesized
    3689     // for Java - we don't want Windows trying to process it).
    3690     if (jkey == java_awt_event_KeyEvent_VK_DELETE) {
    3691         SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
    3692                                  ::JVM_CurrentTimeMillis(NULL, 0),
    3693                                  java_awt_event_KeyEvent_VK_UNDEFINED,
    3694                                  character, modifiers,
    3695                                  java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);
    3696     }
    3697
    3698     return mrConsume;
    3699 }
    3700
    3701 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt,
    3702                                  UINT flags, BOOL system)
    3703 {
    3704
    3705     // VK_PROCESSKEY is a special value which means
    3706     //          "Current IME wants to consume this KeyEvent"
    3707     // Real key code is saved by IMM32.DLL and can be retrieved by
    3708     // calling ImmGetVirtualKey();
    3709     if (wkey == VK_PROCESSKEY) {
    3710         return mrDoDefault;
    3711     }
    3712     MSG msg;
    3713     InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP),
    3714                              wkey, MAKELPARAM(repCnt, flags));
    3715
    3716     UINT modifiers = GetJavaModifiers();
    3717     jint keyLocation = GetKeyLocation(wkey, flags);
    3718     BOOL isDeadKey = FALSE;
    3719     UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey);
    3720     UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
    3721     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
    3722
    3723     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
    3724                              ::JVM_CurrentTimeMillis(NULL, 0), jkey, character,
    3725                              modifiers, keyLocation, (jlong)wkey, &msg);
    3726     return mrConsume;
    3727 }
    3728
    3729 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout)
    3730 {
    3731     // Normally we would be able to use charset and TranslateCharSetInfo
    3732     // to get a code page that should be associated with this keyboard
    3733     // layout change. However, there seems to be an NT 4.0 bug associated
    3734     // with the WM_INPUTLANGCHANGE message, which makes the charset parameter
    3735     // unreliable, especially on Asian systems. Our workaround uses the
    3736     // keyboard layout handle instead.
    3737     m_hkl = hKeyboardLayout;
    3738     m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID
    3739     m_CodePage = LangToCodePage(m_idLang);
    3740     BuildDynamicKeyMapTable();  // compute new mappings for VK_OEM
    3741     BuildPrimaryDynamicTable();
    3742     return mrConsume;           // do not propagate to children
    3743 }
    3744
    3745 // Convert Language ID to CodePage
    3746 UINT AwtComponent::LangToCodePage(LANGID idLang)
    3747 {
    3748     TCHAR strCodePage[MAX_ACP_STR_LEN];
    3749     // use the LANGID to create a LCID
    3750     LCID idLocale = MAKELCID(idLang, SORT_DEFAULT);
    3751     // get the ANSI code page associated with this locale
    3752     if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE, strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 )
    3753         return _ttoi(strCodePage);
    3754     else
    3755         return GetACP();
    3756 }
    3757
    3758
    3759 MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL system)
    3760 {
    3761     // We will simply create Java events here.
    3762     WCHAR unicodeChar = character;
    3763     MSG msg;
    3764     InitMessage(&msg, WM_IME_CHAR, character,
    3765                               MAKELPARAM(repCnt, flags));
    3766
    3767     jint modifiers = GetJavaModifiers();
    3768     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
    3769                              ::JVM_CurrentTimeMillis(NULL, 0),
    3770                              java_awt_event_KeyEvent_VK_UNDEFINED,
    3771                              unicodeChar, modifiers,
    3772                              java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
    3773                              &msg);
    3774     return mrConsume;
    3775 }
    3776
    3777 MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags,
    3778                                 BOOL system)
    3779 {
    3780     deadKeyActive = FALSE;
    3781
    3782     // Will only get WmChar messages with DBCS if we create them for
    3783     // an Edit class in the WmForwardChar method. These synthesized
    3784     // DBCS chars are ok to pass on directly to the default window
    3785     // procedure. They've already been filtered through the Java key
    3786     // event queue. We will never get the trail byte since the edit
    3787     // class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR,
    3788     // PM_REMOVE).  I would like to be able to pass this character off
    3789     // via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to
    3790     // like that.
    3791
    3792     // We will simply create Java events here.
    3793     UINT message = system ? WM_SYSCHAR : WM_CHAR;
    3794
    3795     // 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)).
    3797     bool alt_is_down = (flags & (1<<13)) != 0;
    3798
    3799     // Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu
    3800     // We should not pass this particular combination to Java.
    3801
    3802     if (system && alt_is_down) {
    3803         if (character == VK_SPACE) {
    3804             return mrDoDefault;
    3805         }
    3806     }
    3807
    3808     // If this is a WM_CHAR (non-system) message, then the Alt flag
    3809     // indicates that the character was typed using an AltGr key
    3810     // (which Windows treats as Ctrl+Alt), so in this case we do NOT
    3811     // pass the Ctrl and Alt modifiers to Java, but instead we
    3812     // replace them with Java's AltGraph modifier.  Note: the AltGraph
    3813     // modifier does not exist in 1.1.x releases.
    3814     jint modifiers = GetJavaModifiers();
    3815     if (!system && alt_is_down) {
    3816         // character typed with AltGraph
    3817         modifiers &= ~(java_awt_event_InputEvent_ALT_DOWN_MASK
    3818                        | java_awt_event_InputEvent_CTRL_DOWN_MASK);
    3819         modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK;
    3820     }
    3821
    3822     WCHAR unicodeChar = character;
    3823
    3824     // Kludge: Combine pending single byte with this char for some Chinese IMEs
    3825     if (m_PendingLeadByte != 0) {
    3826         character = (m_PendingLeadByte & 0x00ff) | (character << 8);
    3827         m_PendingLeadByte = 0;
    3828         ::MultiByteToWideChar(GetCodePage(), 0, (CHAR*)&character, 2,
    3829                           &unicodeChar, 1);
    3830     }
    3831
    3832     if (unicodeChar == VK_RETURN) {
    3833         // Enter key generates \r in windows, but \n is required in java
    3834         unicodeChar = java_awt_event_KeyEvent_VK_ENTER;
    3835     }
    3836     MSG msg;
    3837     InitMessage(&msg, message, character,
    3838                               MAKELPARAM(repCnt, flags));
    3839     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED,
    3840                              ::JVM_CurrentTimeMillis(NULL, 0),
    3841                              java_awt_event_KeyEvent_VK_UNDEFINED,
    3842                              unicodeChar, modifiers,
    3843                              java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
    3844                              &msg);
    3845     return mrConsume;
    3846 }
    3847
    3848 MsgRouting AwtComponent::WmForwardChar(WCHAR character, LPARAM lParam,
    3849                                        BOOL synthetic)
    3850 {
    3851     // just post WM_CHAR with unicode key value
    3852     DefWindowProc(WM_CHAR, (WPARAM)character, lParam);
    3853     return mrConsume;
    3854 }
    3855
    3856 MsgRouting AwtComponent::WmPaste()
    3857 {
    3858     return mrDoDefault;
    3859 }
    3860
    3861 // support IME Composition messages
    3862 void AwtComponent::SetCompositionWindow(RECT& r)
    3863 {
    3864     HWND hwnd = ImmGetHWnd();
    3865     HIMC hIMC = ImmGetContext(hwnd);
    3866     if (hIMC == NULL) {
    3867         return;
    3868     }
    3869     COMPOSITIONFORM cf = {CFS_DEFAULT, {0, 0}, {0, 0, 0, 0}};
    3870     ImmSetCompositionWindow(hIMC, &cf);
    3871     ImmReleaseContext(hwnd, hIMC);
    3872 }
    3873
    3874 void AwtComponent::OpenCandidateWindow(int x, int y)
    3875 {
    3876     UINT bits = 1;
    3877     POINT p = {0, 0}; // upper left corner of the client area
    3878     HWND hWnd = GetHWnd();
    3879     if (!::IsWindowVisible(hWnd)) {
    3880         return;
    3881     }
    3882     HWND hTop = GetTopLevelParentForWindow(hWnd);
    3883     ::ClientToScreen(hTop, &p);
    3884     if (!m_bitsCandType) {
    3885         SetCandidateWindow(m_bitsCandType, x - p.x, y - p.y);
    3886         return;
    3887     }
    3888     for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) {
    3889         if ( m_bitsCandType & bits )
    3890             SetCandidateWindow(iCandType, x - p.x, y - p.y);
    3891     }
    3892 }
    3893
    3894 void AwtComponent::SetCandidateWindow(int iCandType, int x, int y)
    3895 {
    3896     HWND hwnd = ImmGetHWnd();
    3897     HIMC hIMC = ImmGetContext(hwnd);
    3898     if (hIMC) {
    3899         CANDIDATEFORM cf;
    3900         cf.dwStyle = CFS_POINT;
    3901         ImmGetCandidateWindow(hIMC, 0, &cf);
    3902         if (x != cf.ptCurrentPos.x || y != cf.ptCurrentPos.y) {
    3903             cf.dwIndex = iCandType;
    3904             cf.dwStyle = CFS_POINT;
    3905             cf.ptCurrentPos = {x, y};
    3906             cf.rcArea = {0, 0, 0, 0};
    3907             ImmSetCandidateWindow(hIMC, &cf);
    3908         }
    3909         COMPOSITIONFORM cfr;
    3910         cfr.dwStyle = CFS_POINT;
    3911         ImmGetCompositionWindow(hIMC, &cfr);
    3912         if (x != cfr.ptCurrentPos.x || y != cfr.ptCurrentPos.y) {
    3913             cfr.dwStyle = CFS_POINT;
    3914             cfr.ptCurrentPos = {x, y};
    3915             cfr.rcArea = {0, 0, 0, 0};
    3916             ImmSetCompositionWindow(hIMC, &cfr);
    3917         }
    3918         ImmReleaseContext(hwnd, hIMC);
    3919     }
    3920 }
    3921
    3922 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam)
    3923 {
    3924     // If the Windows input context is disabled, do not let Windows
    3925     // display any UIs.
    3926     HWND hwnd = ImmGetHWnd();
    3927     HIMC hIMC = ImmGetContext(hwnd);
    3928     if (hIMC == NULL) {
    3929         *lplParam = 0;
    3930         return mrDoDefault;
    3931     }
    3932     ImmReleaseContext(hwnd, hIMC);
    3933
    3934     if (fSet) {
    3935         LPARAM lParam = *lplParam;
    3936         if (!m_useNativeCompWindow) {
    3937             // stop to draw native composing window.
    3938             *lplParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
    3939         }
    3940     }
    3941     return mrDoDefault;
    3942 }
    3943
    3944 MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType)
    3945 {
    3946     if (!m_useNativeCompWindow) {
    3947         if (subMsg == IMN_OPENCANDIDATE || subMsg == IMN_CHANGECANDIDATE) {
    3948             m_bitsCandType = bitsCandType;
    3949             InquireCandidatePosition();
    3950         } else if (subMsg == IMN_OPENSTATUSWINDOW ||
    3951                    subMsg == WM_IME_STARTCOMPOSITION ||
    3952                    subMsg == IMN_SETCANDIDATEPOS) {
    3953             InquireCandidatePosition();
    3954         }
    3955     }
    3956     return mrDoDefault;
    3957 }
    3958
    3959 MsgRouting AwtComponent::WmImeStartComposition()
    3960 {
    3961     if (m_useNativeCompWindow) {
    3962         RECT rc;
    3963         ::GetClientRect(GetHWnd(), &rc);
    3964         SetCompositionWindow(rc);
    3965         return mrDoDefault;
    3966     } else
    3967         return mrConsume;
    3968 }
    3969
    3970 MsgRouting AwtComponent::WmImeEndComposition()
    3971 {
    3972     if (m_useNativeCompWindow)   return mrDoDefault;
    3973
    3974     SendInputMethodEvent(
    3975         java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED,
    3976         NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0 );
    3977     return mrConsume;
    3978 }
    3979
    3980 MsgRouting AwtComponent::WmImeComposition(WORD wChar, LPARAM flags)
    3981 {
    3982     if (m_useNativeCompWindow)   return mrDoDefault;
    3983
    3984     int*      bndClauseW = NULL;
    3985     jstring*  readingClauseW = NULL;
    3986     int*      bndAttrW = NULL;
    3987     BYTE*     valAttrW = NULL;
    3988     int       cClauseW = 0;
    3989     AwtInputTextInfor* textInfor = NULL;
    3990
    3991     try {
    3992         HWND hwnd = ImmGetHWnd();
    3993         HIMC hIMC = ImmGetContext(hwnd);
    3994         DASSERT(hIMC!=0);
    3995
    3996         textInfor = new AwtInputTextInfor;
    3997         textInfor->GetContextData(hIMC, flags);
    3998         ImmReleaseContext(hwnd, hIMC);
    3999
    4000         jstring jtextString = textInfor->GetText();
    4001         /* The conditions to send the input method event to AWT EDT are:
    4002            1. Whenever there is a composition message sent regarding whether
    4003            the composition text is NULL or not. See details at bug 6222692.
    4004            2. When there is a committed message sent, in which case, we have to
    4005            check whether the committed string is NULL or not. If the committed string
    4006            is NULL, there is no need to send any input method event.
    4007            (Minor note: 'jtextString' returned is the merged string in the case of
    4008            partial commit.)
    4009         */
    4010         if ((flags & GCS_RESULTSTR && jtextString != NULL) ||
    4011             (flags & GCS_COMPSTR)) {
    4012             int       cursorPosW = textInfor->GetCursorPosition();
    4013             // In order not to delete the readingClauseW in the catch clause,
    4014             // calling GetAttributeInfor before GetClauseInfor.
    4015             int       cAttrW = textInfor->GetAttributeInfor(bndAttrW, valAttrW);
    4016             cClauseW = textInfor->GetClauseInfor(bndClauseW, readingClauseW);
    4017
    4018             /* Send INPUT_METHOD_TEXT_CHANGED event to the WInputMethod which in turn sends
    4019                the event to AWT EDT.
    4020
    4021                The last two paremeters are set to equal since we don't have recommendations for
    4022                the visible position within the current composed text. See details at
    4023                java.awt.event.InputMethodEvent.
    4024             */
    4025             SendInputMethodEvent(java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED,
    4026                                  jtextString,
    4027                                  cClauseW, bndClauseW, readingClauseW,
    4028                                  cAttrW, bndAttrW, valAttrW,
    4029                                  textInfor->GetCommittedTextLength(),
    4030                                  cursorPosW, cursorPosW);
    4031         }
    4032     } catch (...) {
    4033         // since GetClauseInfor and GetAttributeInfor could throw exception, we have to release
    4034         // the pointer here.
    4035         delete [] bndClauseW;
    4036         delete [] readingClauseW;
    4037         delete [] bndAttrW;
    4038         delete [] valAttrW;
    4039         throw;
    4040     }
    4041
    4042     /* Free the storage allocated. Since jtextString won't be passed from threads
    4043      *  to threads, we just use the local ref and it will be deleted within the destructor
    4044      *  of AwtInputTextInfor object.
    4045      */
    4046     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4047     if (cClauseW && readingClauseW) {
    4048         for (int i = 0; i < cClauseW; i ++) {
    4049             if (readingClauseW[i]) {
    4050                 env->DeleteLocalRef(readingClauseW[i]);
    4051             }
    4052         }
    4053     }
    4054     delete [] bndClauseW;
    4055     delete [] readingClauseW;
    4056     delete [] bndAttrW;
    4057     delete [] valAttrW;
    4058     delete textInfor;
    4059
    4060     return mrConsume;
    4061 }
    4062
    4063 //
    4064 // generate and post InputMethodEvent
    4065 //
    4066 void AwtComponent::SendInputMethodEvent(jint id, jstring text,
    4067                                         int cClause, int* rgClauseBoundary, jstring* rgClauseReading,
    4068                                         int cAttrBlock, int* rgAttrBoundary, BYTE *rgAttrValue,
    4069                                         int commitedTextLength, int caretPos, int visiblePos)
    4070 {
    4071     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4072
    4073     // assumption for array type casting
    4074     DASSERT(sizeof(int)==sizeof(jint));
    4075     DASSERT(sizeof(BYTE)==sizeof(jbyte));
    4076
    4077     // caluse information
    4078     jintArray clauseBoundary = NULL;
    4079     jobjectArray clauseReading = NULL;
    4080     if (cClause && rgClauseBoundary && rgClauseReading) {
    4081         // convert clause boundary offset array to java array
    4082         clauseBoundary = env->NewIntArray(cClause+1);
    4083         DASSERT(clauseBoundary);
    4084         CHECK_NULL(clauseBoundary);
    4085         env->SetIntArrayRegion(clauseBoundary, 0, cClause+1, (jint *)rgClauseBoundary);
    4086         DASSERT(!safe_ExceptionOccurred(env));
    4087
    4088         // convert clause reading string array to java array
    4089         jclass stringCls = JNU_ClassString(env);
    4090         DASSERT(stringCls);
    4091         CHECK_NULL(stringCls);
    4092         clauseReading = env->NewObjectArray(cClause, stringCls, NULL);
    4093         DASSERT(clauseReading);
    4094         CHECK_NULL(clauseReading);
    4095         for (int i=0; i<cClause; i++)   env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]);
    4096         DASSERT(!safe_ExceptionOccurred(env));
    4097     }
    4098
    4099
    4100     // attrubute value definition in WInputMethod.java must be equal to that in IMM.H
    4101     DASSERT(ATTR_INPUT==sun_awt_windows_WInputMethod_ATTR_INPUT);
    4102     DASSERT(ATTR_TARGET_CONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_CONVERTED);
    4103     DASSERT(ATTR_CONVERTED==sun_awt_windows_WInputMethod_ATTR_CONVERTED);
    4104     DASSERT(ATTR_TARGET_NOTCONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_NOTCONVERTED);
    4105     DASSERT(ATTR_INPUT_ERROR==sun_awt_windows_WInputMethod_ATTR_INPUT_ERROR);
    4106
    4107     // attribute information
    4108     jintArray attrBoundary = NULL;
    4109     jbyteArray attrValue = NULL;
    4110     if (cAttrBlock && rgAttrBoundary && rgAttrValue) {
    4111         // convert attribute boundary offset array to java array
    4112         attrBoundary = env->NewIntArray(cAttrBlock+1);
    4113         DASSERT(attrBoundary);
    4114         CHECK_NULL(attrBoundary);
    4115         env->SetIntArrayRegion(attrBoundary, 0, cAttrBlock+1, (jint *)rgAttrBoundary);
    4116         DASSERT(!safe_ExceptionOccurred(env));
    4117
    4118         // convert attribute value byte array to java array
    4119         attrValue = env->NewByteArray(cAttrBlock);
    4120         DASSERT(attrValue);
    4121         CHECK_NULL(attrValue);
    4122         env->SetByteArrayRegion(attrValue, 0, cAttrBlock, (jbyte *)rgAttrValue);
    4123         DASSERT(!safe_ExceptionOccurred(env));
    4124     }
    4125
    4126
    4127     // get global reference of WInputMethod class (run only once)
    4128     static jclass wInputMethodCls = NULL;
    4129     if (wInputMethodCls == NULL) {
    4130         jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod");
    4131         DASSERT(wInputMethodClsLocal);
    4132         CHECK_NULL(wInputMethodClsLocal);
    4133         wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal);
    4134         env->DeleteLocalRef(wInputMethodClsLocal);
    4135     }
    4136
    4137     // get method ID of sendInputMethodEvent() (run only once)
    4138     static jmethodID sendIMEventMid = 0;
    4139     if (sendIMEventMid == 0) {
    4140         sendIMEventMid =  env->GetMethodID(wInputMethodCls, "sendInputMethodEvent",
    4141                                            "(IJLjava/lang/String;[I[Ljava/lang/String;[I[BIII)V");
    4142         DASSERT(sendIMEventMid);
    4143         CHECK_NULL(sendIMEventMid);
    4144     }
    4145
    4146     // call m_InputMethod.sendInputMethod()
    4147     env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, ::JVM_CurrentTimeMillis(NULL, 0),
    4148                         text, clauseBoundary, clauseReading, attrBoundary,
    4149                         attrValue, commitedTextLength, caretPos, visiblePos);
    4150     if (safe_ExceptionOccurred(env))   env->ExceptionDescribe();
    4151     DASSERT(!safe_ExceptionOccurred(env));
    4152
    4153 }
    4154
    4155
    4156
    4157 //
    4158 // Inquires candidate position according to the composed text
    4159 //
    4160 void AwtComponent::InquireCandidatePosition()
    4161 {
    4162     if (!::IsWindowVisible(GetHWnd())) {
    4163         return;
    4164     }
    4165     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4166
    4167     // get global reference of WInputMethod class (run only once)
    4168     static jclass wInputMethodCls = NULL;
    4169     if (wInputMethodCls == NULL) {
    4170         jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod");
    4171         DASSERT(wInputMethodClsLocal);
    4172         CHECK_NULL(wInputMethodClsLocal);
    4173         wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal);
    4174         env->DeleteLocalRef(wInputMethodClsLocal);
    4175     }
    4176
    4177     // get method ID of sendInputMethodEvent() (run only once)
    4178     static jmethodID inqCandPosMid = 0;
    4179     if (inqCandPosMid == 0) {
    4180         inqCandPosMid =  env->GetMethodID(wInputMethodCls, "inquireCandidatePosition", "()V");
    4181         DASSERT(!safe_ExceptionOccurred(env));
    4182         DASSERT(inqCandPosMid);
    4183         CHECK_NULL(inqCandPosMid);
    4184     }
    4185
    4186     // call m_InputMethod.sendInputMethod()
    4187     jobject candPos = env->CallObjectMethod(m_InputMethod, inqCandPosMid);
    4188     DASSERT(!safe_ExceptionOccurred(env));
    4189 }
    4190
    4191 HWND AwtComponent::ImmGetHWnd()
    4192 {
    4193     HWND proxy = GetProxyFocusOwner();
    4194     return (proxy != NULL) ? proxy : GetHWnd();
    4195 }
    4196
    4197 HIMC AwtComponent::ImmAssociateContext(HIMC himc)
    4198 {
    4199     return ::ImmAssociateContext(ImmGetHWnd(), himc);
    4200 }
    4201
    4202 HWND AwtComponent::GetProxyFocusOwner()
    4203 {
    4204     AwtWindow *window = GetContainer();
    4205     if (window != 0) {
    4206         AwtFrame *owner = window->GetOwningFrameOrDialog();
    4207         if (owner != 0) {
    4208             return owner->GetProxyFocusOwner();
    4209         } else if (!window->IsSimpleWindow()) { // isn't an owned simple window
    4210             return ((AwtFrame*)window)->GetProxyFocusOwner();
    4211         }
    4212     }
    4213     return (HWND)NULL;
    4214 }
    4215
    4216 /* Redirects message to the focus proxy, if any */
    4217 void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam,
    4218     LPARAM lParam, LRESULT &retVal, MsgRouting &mr)
    4219 {
    4220     if (mr != mrConsume)  {
    4221         HWND proxy = GetProxyFocusOwner();
    4222         if (proxy != NULL && ::IsWindowEnabled(proxy)) {
    4223             retVal = ::DefWindowProc(proxy, message, wParam, lParam);
    4224             mr = mrConsume;
    4225         }
    4226     }
    4227 }
    4228
    4229 MsgRouting AwtComponent::WmCommand(UINT id, HWND hWndChild, UINT notifyCode)
    4230 {
    4231     /* Menu/Accelerator */
    4232     if (hWndChild == 0) {
    4233         AwtObject* obj = AwtToolkit::GetInstance().LookupCmdID(id);
    4234         if (obj == NULL) {
    4235             return mrConsume;
    4236         }
    4237         DASSERT(((AwtMenuItem*)obj)->GetID() == id);
    4238         obj->DoCommand();
    4239         return mrConsume;
    4240     }
    4241     /* Child id notification */
    4242     else {
    4243         AwtComponent* child = AwtComponent::GetComponent(hWndChild);
    4244         if (child) {
    4245             child->WmNotify(notifyCode);
    4246         }
    4247     }
    4248     return mrDoDefault;
    4249 }
    4250
    4251 MsgRouting AwtComponent::WmNotify(UINT notifyCode)
    4252 {
    4253     return mrDoDefault;
    4254 }
    4255
    4256 MsgRouting AwtComponent::WmCompareItem(UINT ctrlId,
    4257                                        COMPAREITEMSTRUCT &compareInfo,
    4258                                        LRESULT &result)
    4259 {
    4260     AwtComponent* child = AwtComponent::GetComponent(compareInfo.hwndItem);
    4261     if (child == this) {
    4262         /* DoCallback("handleItemDelete", */
    4263     }
    4264     else if (child) {
    4265         return child->WmCompareItem(ctrlId, compareInfo, result);
    4266     }
    4267     return mrConsume;
    4268 }
    4269
    4270 MsgRouting AwtComponent::WmDeleteItem(UINT ctrlId,
    4271                                       DELETEITEMSTRUCT &deleteInfo)
    4272 {
    4273     /*
    4274      * Workaround for NT 4.0 bug -- if SetWindowPos is called on a AwtList
    4275      * window, a WM_DELETEITEM message is sent to its parent with a window
    4276      * handle of one of the list's child windows.  The property lookup
    4277      * succeeds, but the HWNDs don't match.
    4278      */
    4279     if (deleteInfo.hwndItem == NULL) {
    4280         return mrConsume;
    4281     }
    4282     AwtComponent* child = (AwtComponent *)AwtComponent::GetComponent(deleteInfo.hwndItem);
    4283
    4284     if (child && child->GetHWnd() != deleteInfo.hwndItem) {
    4285         return mrConsume;
    4286     }
    4287
    4288     if (child == this) {
    4289         /*DoCallback("handleItemDelete", */
    4290     }
    4291     else if (child) {
    4292         return child->WmDeleteItem(ctrlId, deleteInfo);
    4293     }
    4294     return mrConsume;
    4295 }
    4296
    4297 MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo)
    4298 {
    4299     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4300
    4301     if (drawInfo.CtlType == ODT_MENU) {
    4302         if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) {
    4303             AwtMenu* menu = (AwtMenu*)(drawInfo.itemData);
    4304             menu->DrawItem(drawInfo);
    4305         }
    4306     } else {
    4307         return OwnerDrawItem(ctrlId, drawInfo);
    4308     }
    4309     return mrConsume;
    4310 }
    4311
    4312 MsgRouting AwtComponent::WmMeasureItem(UINT ctrlId,
    4313                                        MEASUREITEMSTRUCT &measureInfo)
    4314 {
    4315     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4316
    4317     if (measureInfo.CtlType == ODT_MENU) {
    4318         if (measureInfo.itemData != 0) {
    4319             AwtMenu* menu = (AwtMenu*)(measureInfo.itemData);
    4320             HDC hDC = ::GetDC(GetHWnd());
    4321             /* menu->MeasureItem(env, hDC, measureInfo); */
    4322             menu->MeasureItem(hDC, measureInfo);
    4323             ::ReleaseDC(GetHWnd(), hDC);
    4324         }
    4325     } else {
    4326         return OwnerMeasureItem(ctrlId, measureInfo);
    4327     }
    4328     return mrConsume;
    4329 }
    4330
    4331 MsgRouting AwtComponent::OwnerDrawItem(UINT ctrlId,
    4332     DRAWITEMSTRUCT &drawInfo)
    4333 {
    4334     AwtComponent* child = AwtComponent::GetComponent(drawInfo.hwndItem);
    4335     if (child == this) {
    4336         /* DoCallback("handleItemDelete", */
    4337     } else if (child != NULL) {
    4338         return child->WmDrawItem(ctrlId, drawInfo);
    4339     }
    4340     return mrConsume;
    4341 }
    4342
    4343 MsgRouting AwtComponent::OwnerMeasureItem(UINT ctrlId,
    4344     MEASUREITEMSTRUCT &measureInfo)
    4345 {
    4346     HWND  hChild = ::GetDlgItem(GetHWnd(), measureInfo.CtlID);
    4347     AwtComponent* child = AwtComponent::GetComponent(hChild);
    4348     /*
    4349      * If the parent cannot find the child's instance from its handle,
    4350      * maybe the child is in its creation.  So the child must be searched
    4351      * from the list linked before the child's creation.
    4352      */
    4353     if (child == NULL) {
    4354         child = SearchChild((UINT)ctrlId);
    4355     }
    4356
    4357     if (child == this) {
    4358     /* DoCallback("handleItemDelete",  */
    4359     }
    4360     else if (child) {
    4361         return child->WmMeasureItem(ctrlId, measureInfo);
    4362     }
    4363     return mrConsume;
    4364 }
    4365
    4366 /* for WmDrawItem method of Label, Button and Checkbox */
    4367 void AwtComponent::DrawWindowText(HDC hDC, jobject font, jstring text,
    4368                                   int x, int y)
    4369 {
    4370     int nOldBkMode = ::SetBkMode(hDC,TRANSPARENT);
    4371     DASSERT(nOldBkMode != 0);
    4372     AwtFont::drawMFString(hDC, font, text, x, y, GetCodePage());
    4373     VERIFY(::SetBkMode(hDC,nOldBkMode));
    4374 }
    4375
    4376 /*
    4377  * Draw text in gray (the color being set to COLOR_GRAYTEXT) when the
    4378  * component is disabled.  Used only for label, checkbox and button in
    4379  * OWNER_DRAW.  It draws the text in emboss.
    4380  */
    4381 void AwtComponent::DrawGrayText(HDC hDC, jobject font, jstring text,
    4382                                 int x, int y)
    4383 {
    4384     ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT));
    4385     AwtComponent::DrawWindowText(hDC, font, text, x+1, y+1);
    4386     ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW));
    4387     AwtComponent::DrawWindowText(hDC, font, text, x, y);
    4388 }
    4389
    4390 /* for WmMeasureItem method of List and Choice */
    4391 jstring AwtComponent::GetItemString(JNIEnv *env, jobject target, jint index)
    4392 {
    4393     jstring str = (jstring)JNU_CallMethodByName(env, NULL, target, "getItemImpl",
    4394                                                 "(I)Ljava/lang/String;",
    4395                                                 index).l;
    4396     DASSERT(!safe_ExceptionOccurred(env));
    4397     return str;
    4398 }
    4399
    4400 /* for WmMeasureItem method of List and Choice */
    4401 void AwtComponent::MeasureListItem(JNIEnv *env,
    4402                                    MEASUREITEMSTRUCT &measureInfo)
    4403 {
    4404     if (env->EnsureLocalCapacity(1) < 0) {
    4405         return;
    4406     }
    4407     jobject dimension = PreferredItemSize(env);
    4408     DASSERT(dimension);
    4409     measureInfo.itemWidth =
    4410       env->GetIntField(dimension, AwtDimension::widthID);
    4411     measureInfo.itemHeight =
    4412       env->GetIntField(dimension, AwtDimension::heightID);
    4413     env->DeleteLocalRef(dimension);
    4414 }
    4415
    4416 /* for WmDrawItem method of List and Choice */
    4417 void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo)
    4418 {
    4419     if (env->EnsureLocalCapacity(3) < 0) {
    4420         return;
    4421     }
    4422     jobject peer = GetPeer(env);
    4423     jobject target = env->GetObjectField(peer, AwtObject::targetID);
    4424
    4425     HDC hDC = drawInfo.hDC;
    4426     RECT rect = drawInfo.rcItem;
    4427
    4428     BOOL bEnabled = isEnabled();
    4429     BOOL unfocusableChoice = (drawInfo.itemState & ODS_COMBOBOXEDIT) && !IsFocusable();
    4430     DWORD crBack, crText;
    4431     if (drawInfo.itemState & ODS_SELECTED){
    4432         /* Set background and text colors for selected item */
    4433         crBack = ::GetSysColor (COLOR_HIGHLIGHT);
    4434         crText = ::GetSysColor (COLOR_HIGHLIGHTTEXT);
    4435     } else {
    4436         /* Set background and text colors for unselected item */
    4437         crBack = GetBackgroundColor();
    4438         crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT);
    4439     }
    4440     if (unfocusableChoice) {
    4441         //6190728. Shouldn't draw selection field (edit control) of an owner-drawn combo box.
    4442         crBack = GetBackgroundColor();
    4443         crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT);
    4444     }
    4445
    4446     /* Fill item rectangle with background color */
    4447     HBRUSH hbrBack = ::CreateSolidBrush (crBack);
    4448     DASSERT(hbrBack);
    4449     /* 6190728. Shouldn't draw any kind of rectangle around selection field
    4450      * (edit control) of an owner-drawn combo box while unfocusable
    4451      */
    4452     if (!unfocusableChoice){
    4453         VERIFY(::FillRect (hDC, &rect, hbrBack));
    4454     }
    4455     VERIFY(::DeleteObject (hbrBack));
    4456
    4457     /* Set current background and text colors */
    4458     ::SetBkColor (hDC, crBack);
    4459     ::SetTextColor (hDC, crText);
    4460
    4461     /*draw string (with left margin of 1 point) */
    4462     if ((int) (drawInfo.itemID) >= 0) {
    4463             jobject font = GET_FONT(target, peer);
    4464             jstring text = GetItemString(env, target, drawInfo.itemID);
    4465             if (env->ExceptionCheck()) {
    4466                 env->DeleteLocalRef(font);
    4467                 env->DeleteLocalRef(target);
    4468                 return;
    4469             }
    4470             SIZE size = AwtFont::getMFStringSize(hDC, font, text);
    4471             AwtFont::drawMFString(hDC, font, text,
    4472                                   (GetRTL()) ? rect.right - size.cx - 1
    4473                                              : rect.left + 1,
    4474                                   (rect.top + rect.bottom - size.cy) / 2,
    4475                                   GetCodePage());
    4476             env->DeleteLocalRef(font);
    4477             env->DeleteLocalRef(text);
    4478     }
    4479     if ((drawInfo.itemState & ODS_FOCUS)  &&
    4480         (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) {
    4481       if (!unfocusableChoice){
    4482           if(::DrawFocusRect(hDC, &rect) == 0)
    4483               VERIFY(::GetLastError() == 0);
    4484       }
    4485     }
    4486     env->DeleteLocalRef(target);
    4487 }
    4488
    4489 /* for MeasureListItem method and WmDrawItem method of Checkbox */
    4490 jint AwtComponent::GetFontHeight(JNIEnv *env)
    4491 {
    4492     if (env->EnsureLocalCapacity(4) < 0) {
    4493         return NULL;
    4494     }
    4495     jobject self = GetPeer(env);
    4496     jobject target = env->GetObjectField(self, AwtObject::targetID);
    4497
    4498     jobject font = GET_FONT(target, self);
    4499     jobject toolkit = env->CallObjectMethod(target,
    4500                                             AwtComponent::getToolkitMID);
    4501
    4502     DASSERT(!safe_ExceptionOccurred(env));
    4503
    4504     jobject fontMetrics =
    4505         env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font);
    4506
    4507     DASSERT(!safe_ExceptionOccurred(env));
    4508
    4509     jint height = env->CallIntMethod(fontMetrics, AwtFont::getHeightMID);
    4510     DASSERT(!safe_ExceptionOccurred(env));
    4511
    4512     env->DeleteLocalRef(target);
    4513     env->DeleteLocalRef(font);
    4514     env->DeleteLocalRef(toolkit);
    4515     env->DeleteLocalRef(fontMetrics);
    4516
    4517     return height;
    4518 }
    4519
    4520 // If you override WmPrint, make sure to save a copy of the DC on the GDI
    4521 // stack to be restored in WmPrintClient. Windows mangles the DC in
    4522 // ::DefWindowProc.
    4523 MsgRouting AwtComponent::WmPrint(HDC hDC, LPARAM flags)
    4524 {
    4525     /*
    4526      * DefWindowProc for WM_PRINT changes DC parameters, so we have
    4527      * to restore it ourselves. Otherwise it will cause problems
    4528      * when several components are printed to the same DC.
    4529      */
    4530     int nOriginalDC = ::SaveDC(hDC);
    4531     DASSERT(nOriginalDC != 0);
    4532
    4533     if (flags & PRF_NONCLIENT) {
    4534
    4535         VERIFY(::SaveDC(hDC));
    4536
    4537         DefWindowProc(WM_PRINT, (WPARAM)hDC,
    4538                       (flags & (PRF_NONCLIENT
    4539                                 | PRF_CHECKVISIBLE | PRF_ERASEBKGND)));
    4540
    4541         VERIFY(::RestoreDC(hDC, -1));
    4542
    4543         // Special case for components with a sunken border. Windows does not
    4544         // print the border correctly on PCL printers, so we have to do it ourselves.
    4545         if (GetStyleEx() & WS_EX_CLIENTEDGE) {
    4546             RECT r;
    4547             VERIFY(::GetWindowRect(GetHWnd(), &r));
    4548             VERIFY(::OffsetRect(&r, -r.left, -r.top));
    4549             VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT));
    4550         }
    4551     }
    4552
    4553     if (flags & PRF_CLIENT) {
    4554
    4555         /*
    4556          * Special case for components with a sunken border.
    4557          * Windows prints a client area without offset to a border width.
    4558          * We will first print the non-client area with the original offset,
    4559          * then the client area with a corrected offset.
    4560          */
    4561         if (GetStyleEx() & WS_EX_CLIENTEDGE) {
    4562
    4563             int nEdgeWidth = ::GetSystemMetrics(SM_CXEDGE);
    4564             int nEdgeHeight = ::GetSystemMetrics(SM_CYEDGE);
    4565
    4566             VERIFY(::OffsetWindowOrgEx(hDC, -nEdgeWidth, -nEdgeHeight, NULL));
    4567
    4568             // Save a copy of the DC for WmPrintClient
    4569             VERIFY(::SaveDC(hDC));
    4570
    4571             DefWindowProc(WM_PRINT, (WPARAM) hDC,
    4572                           (flags & (PRF_CLIENT
    4573                                     | PRF_CHECKVISIBLE | PRF_ERASEBKGND)));
    4574
    4575             VERIFY(::OffsetWindowOrgEx(hDC, nEdgeWidth, nEdgeHeight, NULL));
    4576
    4577         } else {
    4578
    4579             // Save a copy of the DC for WmPrintClient
    4580             VERIFY(::SaveDC(hDC));
    4581             DefWindowProc(WM_PRINT, (WPARAM) hDC,
    4582                           (flags & (PRF_CLIENT
    4583                                     | PRF_CHECKVISIBLE | PRF_ERASEBKGND)));
    4584         }
    4585     }
    4586
    4587     if (flags & (PRF_CHILDREN | PRF_OWNED)) {
    4588         DefWindowProc(WM_PRINT, (WPARAM) hDC,
    4589                       (flags & ~PRF_CLIENT & ~PRF_NONCLIENT));
    4590     }
    4591
    4592     VERIFY(::RestoreDC(hDC, nOriginalDC));
    4593
    4594     return mrConsume;
    4595 }
    4596
    4597 // If you override WmPrintClient, make sure to obtain a valid copy of
    4598 // the DC from the GDI stack. The copy of the DC should have been placed
    4599 // there by WmPrint. Windows mangles the DC in ::DefWindowProc.
    4600 MsgRouting AwtComponent::WmPrintClient(HDC hDC, LPARAM)
    4601 {
    4602     // obtain valid DC from GDI stack
    4603     ::RestoreDC(hDC, -1);
    4604
    4605     return mrDoDefault;
    4606 }
    4607
    4608 MsgRouting AwtComponent::WmNcCalcSize(BOOL fCalcValidRects,
    4609                                       LPNCCALCSIZE_PARAMS lpncsp,
    4610                                       LRESULT &retVal)
    4611 {
    4612     return mrDoDefault;
    4613 }
    4614
    4615 MsgRouting AwtComponent::WmNcPaint(HRGN hrgn)
    4616 {
    4617     return mrDoDefault;
    4618 }
    4619
    4620 MsgRouting AwtComponent::WmNcHitTest(UINT x, UINT y, LRESULT &retVal)
    4621 {
    4622     return mrDoDefault;
    4623 }
    4624
    4625 /**
    4626  * WmQueryNewPalette is called whenever our component is coming to
    4627  * the foreground; this gives us an opportunity to install our
    4628  * custom palette.  If this install actually changes entries in
    4629  * the system palette, then we get a further call to WmPaletteChanged
    4630  * (but note that we only need to realize our palette once).
    4631  */
    4632 MsgRouting AwtComponent::WmQueryNewPalette(LRESULT &retVal)
    4633 {
    4634     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
    4635     m_QueryNewPaletteCalled = TRUE;
    4636     HDC hDC = ::GetDC(GetHWnd());
    4637     DASSERT(hDC);
    4638     AwtWin32GraphicsDevice::SelectPalette(hDC, screen);
    4639     AwtWin32GraphicsDevice::RealizePalette(hDC, screen);
    4640     ::ReleaseDC(GetHWnd(), hDC);
    4641     // We must realize the palettes of all of our DC's
    4642     // There is sometimes a problem where the realization of
    4643     // our temporary hDC here does not actually do what
    4644     // we want.  Not clear why, but presumably fallout from
    4645     // our use of several simultaneous hDC's.
    4646     activeDCList.RealizePalettes(screen);
    4647     // Do not invalidate here; if the palette
    4648     // has not changed we will get an extra repaint
    4649     retVal = TRUE;
    4650
    4651     return mrDoDefault;
    4652 }
    4653
    4654 /**
    4655  * We should not need to track this event since we handle our
    4656  * palette management effectively in the WmQueryNewPalette and
    4657  * WmPaletteChanged methods.  However, there seems to be a bug
    4658  * on some win32 systems (e.g., NT4) whereby the palette
    4659  * immediately after a displayChange is not yet updated to its
    4660  * final post-display-change values (hence we adjust our palette
    4661  * using the wrong system palette entries), then the palette is
    4662  * updated, but a WM_PALETTECHANGED message is never sent.
    4663  * By tracking the ISCHANGING message as well (and by tracking
    4664  * displayChange events in the AwtToolkit object), we can account
    4665  * for this error by forcing our WmPaletteChanged method to be
    4666  * called and thereby realizing our logical palette and updating
    4667  * our dynamic colorModel object.
    4668  */
    4669 MsgRouting AwtComponent::WmPaletteIsChanging(HWND hwndPalChg)
    4670 {
    4671     if (AwtToolkit::GetInstance().HasDisplayChanged()) {
    4672         WmPaletteChanged(hwndPalChg);
    4673         AwtToolkit::GetInstance().ResetDisplayChanged();
    4674     }
    4675     return mrDoDefault;
    4676 }
    4677
    4678 MsgRouting AwtComponent::WmPaletteChanged(HWND hwndPalChg)
    4679 {
    4680     // We need to re-realize our palette here (unless we're the one
    4681     // that was realizing it in the first place).  That will let us match the
    4682     // remaining colors in the system palette as best we can.  We always
    4683     // invalidate because the palette will have changed when we receive this
    4684     // message.
    4685
    4686     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
    4687     if (hwndPalChg != GetHWnd()) {
    4688         HDC hDC = ::GetDC(GetHWnd());
    4689         DASSERT(hDC);
    4690         AwtWin32GraphicsDevice::SelectPalette(hDC, screen);
    4691         AwtWin32GraphicsDevice::RealizePalette(hDC, screen);
    4692         ::ReleaseDC(GetHWnd(), hDC);
    4693         // We must realize the palettes of all of our DC's
    4694         activeDCList.RealizePalettes(screen);
    4695     }
    4696     if (AwtWin32GraphicsDevice::UpdateSystemPalette(screen)) {
    4697         AwtWin32GraphicsDevice::UpdateDynamicColorModel(screen);
    4698     }
    4699     Invalidate(NULL);
    4700     return mrDoDefault;
    4701 }
    4702
    4703 MsgRouting AwtComponent::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss)
    4704 {
    4705     DASSERT(!IsBadReadPtr(lpss, sizeof(STYLESTRUCT)));
    4706     return mrDoDefault;
    4707 }
    4708
    4709 MsgRouting AwtComponent::WmSettingChange(UINT wFlag, LPCTSTR pszSection)
    4710 {
    4711     DASSERT(!IsBadStringPtr(pszSection, 20));
    4712     DTRACE_PRINTLN2("WM_SETTINGCHANGE: wFlag=%d pszSection=%s", (int)wFlag, pszSection);
    4713     return mrDoDefault;
    4714 }
    4715
    4716 HDC AwtComponent::GetDCFromComponent()
    4717 {
    4718     GetDCReturnStruct *hdcStruct =
    4719         (GetDCReturnStruct*)SendMessage(WM_AWT_GETDC);
    4720     HDC hdc;
    4721     if (hdcStruct) {
    4722         if (hdcStruct->gdiLimitReached) {
    4723             if (jvm != NULL) {
    4724                 JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4725                 if (env != NULL && !safe_ExceptionOccurred(env)) {
    4726                     JNU_ThrowByName(env, "java/awt/AWTError",
    4727                         "HDC creation failure - " \
    4728                         "exceeded maximum GDI resources");
    4729                 }
    4730             }
    4731         }
    4732         hdc = hdcStruct->hDC;
    4733         delete hdcStruct;
    4734     } else {
    4735         hdc = NULL;
    4736     }
    4737     return hdc;
    4738 }
    4739
    4740 void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size)
    4741 {
    4742     RECT eraseR = { 0, 0, size.cx, size.cy };
    4743     VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush()));
    4744 }
    4745
    4746 void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
    4747 {
    4748     if (!bitmapBits) {
    4749         return;
    4750     }
    4751
    4752     DWORD* dest = (DWORD*)bitmapBits;
    4753     //XXX: might be optimized to use one loop (cy*cx -> 0)
    4754     for (int i = 0; i < size.cy; i++ ) {
    4755         for (int j = 0; j < size.cx; j++ ) {
    4756             ((BYTE*)(dest++))[3] = alpha;
    4757         }
    4758     }
    4759 }
    4760
    4761 int AwtComponent::ScaleUpX(int x) {
    4762     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
    4763     Devices::InstanceAccess devices;
    4764     AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
    4765     return device == NULL ? x : device->ScaleUpX(x);
    4766 }
    4767
    4768 int AwtComponent::ScaleUpY(int y) {
    4769     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
    4770     Devices::InstanceAccess devices;
    4771     AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
    4772     return device == NULL ? y : device->ScaleUpY(y);
    4773 }
    4774
    4775 int AwtComponent::ScaleDownX(int x) {
    4776     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
    4777     Devices::InstanceAccess devices;
    4778     AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
    4779     return device == NULL ? x : device->ScaleDownX(x);
    4780 }
    4781
    4782 int AwtComponent::ScaleDownY(int y) {
    4783     int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
    4784     Devices::InstanceAccess devices;
    4785     AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
    4786     return device == NULL ? y : device->ScaleDownY(y);
    4787 }
    4788
    4789 jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) {
    4790     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4791
    4792     if (!::IsWindowVisible(GetHWnd())) {
    4793         return NULL;
    4794     }
    4795
    4796     HDC hdc = GetDCFromComponent();
    4797     if (!hdc) {
    4798         return NULL;
    4799     }
    4800     HDC hMemoryDC = ::CreateCompatibleDC(hdc);
    4801     void *bitmapBits = NULL;
    4802     HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits);
    4803     HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap);
    4804     SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc);
    4805
    4806     FillBackground(hMemoryDC, size);
    4807
    4808     VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL));
    4809
    4810     // Don't bother with PRF_CHECKVISIBLE because we called IsWindowVisible
    4811     // above.
    4812     SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT);
    4813
    4814     // First make sure the system completed any drawing to the bitmap.
    4815     ::GdiFlush();
    4816
    4817     // WM_PRINT does not fill the alpha-channel of the ARGB bitmap
    4818     // leaving it equal to zero. Hence we need to fill it manually. Otherwise
    4819     // the pixels will be considered transparent when interpreting the data.
    4820     FillAlpha(bitmapBits, size, alpha);
    4821
    4822     ::SelectObject(hMemoryDC, hOldBitmap);
    4823
    4824     BITMAPINFO bmi;
    4825     memset(&bmi, 0, sizeof(BITMAPINFO));
    4826     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    4827     bmi.bmiHeader.biWidth = size.cx;
    4828     bmi.bmiHeader.biHeight = -size.cy;
    4829     bmi.bmiHeader.biPlanes = 1;
    4830     bmi.bmiHeader.biBitCount = 32;
    4831     bmi.bmiHeader.biCompression = BI_RGB;
    4832
    4833     jobject localPixelArray = env->NewIntArray(size.cx * size.cy);
    4834     jintArray pixelArray = NULL;
    4835     if (localPixelArray != NULL) {
    4836         pixelArray = (jintArray)env->NewGlobalRef(localPixelArray);
    4837         env->DeleteLocalRef(localPixelArray); localPixelArray = NULL;
    4838
    4839         jboolean isCopy;
    4840         jint *pixels = env->GetIntArrayElements(pixelArray, &isCopy);
    4841
    4842         ::GetDIBits(hMemoryDC, hBitmap, 0, size.cy, (LPVOID)pixels, &bmi,
    4843                     DIB_RGB_COLORS);
    4844
    4845         env->ReleaseIntArrayElements(pixelArray, pixels, 0);
    4846     }
    4847
    4848     VERIFY(::DeleteObject(hBitmap));
    4849     VERIFY(::DeleteDC(hMemoryDC));
    4850
    4851     return pixelArray;
    4852 }
    4853
    4854 void* AwtComponent::SetNativeFocusOwner(void *self) {
    4855     if (self == NULL) {
    4856         // It means that the KFM wants to set focus to null
    4857         sm_focusOwner = NULL;
    4858         return NULL;
    4859     }
    4860
    4861     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4862
    4863     AwtComponent *c = NULL;
    4864     jobject peer = (jobject)self;
    4865
    4866     PDATA pData;
    4867     JNI_CHECK_NULL_GOTO(peer, "peer", ret);
    4868     pData = JNI_GET_PDATA(peer);
    4869     if (pData == NULL) {
    4870         goto ret;
    4871     }
    4872     c = (AwtComponent *)pData;
    4873
    4874 ret:
    4875     if (c && ::IsWindow(c->GetHWnd())) {
    4876         sm_focusOwner = c->GetHWnd();
    4877     } else {
    4878         sm_focusOwner = NULL;
    4879     }
    4880     env->DeleteGlobalRef(peer);
    4881     return NULL;
    4882 }
    4883
    4884 void* AwtComponent::GetNativeFocusedWindow() {
    4885     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4886     AwtComponent *comp =
    4887         AwtComponent::GetComponent(AwtComponent::GetFocusedWindow());
    4888     return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL;
    4889 }
    4890
    4891 void* AwtComponent::GetNativeFocusOwner() {
    4892     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4893     AwtComponent *comp =
    4894         AwtComponent::GetComponent(AwtComponent::sm_focusOwner);
    4895     return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL;
    4896 }
    4897
    4898 AwtComponent* AwtComponent::SearchChild(UINT id) {
    4899     ChildListItem* child;
    4900     for (child = m_childList; child != NULL;child = child->m_next) {
    4901         if (child->m_ID == id)
    4902             return child->m_Component;
    4903     }
    4904     /*
    4905      * DASSERT(FALSE);
    4906      * This should not be happend if all children are recorded
    4907      */
    4908     return NULL;        /* make compiler happy */
    4909 }
    4910
    4911 void AwtComponent::RemoveChild(UINT id) {
    4912     ChildListItem* child = m_childList;
    4913     ChildListItem* lastChild = NULL;
    4914     while (child != NULL) {
    4915         if (child->m_ID == id) {
    4916             if (lastChild == NULL) {
    4917                 m_childList = child->m_next;
    4918             } else {
    4919                 lastChild->m_next = child->m_next;
    4920             }
    4921             child->m_next = NULL;
    4922             DASSERT(child != NULL);
    4923             delete child;
    4924             return;
    4925         }
    4926         lastChild = child;
    4927         child = child->m_next;
    4928     }
    4929 }
    4930
    4931 void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked,
    4932                                 jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg)
    4933 {
    4934     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    4935     CriticalSection::Lock l(GetLock());
    4936     if (GetPeer(env) == NULL) {
    4937         /* event received during termination. */
    4938         return;
    4939     }
    4940
    4941     static jclass keyEventCls;
    4942     if (keyEventCls == NULL) {
    4943         jclass keyEventClsLocal = env->FindClass("java/awt/event/KeyEvent");
    4944         DASSERT(keyEventClsLocal);
    4945         if (keyEventClsLocal == NULL) {
    4946             /* exception already thrown */
    4947             return;
    4948         }
    4949         keyEventCls = (jclass)env->NewGlobalRef(keyEventClsLocal);
    4950         env->DeleteLocalRef(keyEventClsLocal);
    4951     }
    4952
    4953     static jmethodID keyEventConst;
    4954     if (keyEventConst == NULL) {
    4955         keyEventConst =  env->GetMethodID(keyEventCls, "<init>",
    4956                                           "(Ljava/awt/Component;IJIICI)V");
    4957         DASSERT(keyEventConst);
    4958         CHECK_NULL(keyEventConst);
    4959     }
    4960     if (env->EnsureLocalCapacity(2) < 0) {
    4961         return;
    4962     }
    4963     jobject target = GetTarget(env);
    4964     jobject keyEvent = env->NewObject(keyEventCls, keyEventConst, target,
    4965                                       id, when, modifiers, raw, cooked,
    4966                                       keyLocation);
    4967     if (safe_ExceptionOccurred(env)) env->ExceptionDescribe();
    4968     DASSERT(!safe_ExceptionOccurred(env));
    4969     DASSERT(keyEvent != NULL);
    4970     if (keyEvent == NULL) {
    4971         env->DeleteLocalRef(target);
    4972         return;
    4973     }
    4974     env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode);
    4975     if( nativeCode && nativeCode < 256 ) {
    4976         env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode));
    4977         env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey));
    4978         if( nativeCode < 255 ) {
    4979             env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode));
    4980         }else if( pMsg != NULL ) {
    4981             // unknown key with virtual keycode 0xFF.
    4982             // Its scancode is not in the table, pickup it from the message.
    4983             env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF));
    4984         }
    4985     }
    4986     if (pMsg != NULL) {
    4987         AwtAWTEvent::saveMSG(env, pMsg, keyEvent);
    4988     }
    4989     SendEvent(keyEvent);
    4990
    4991     env->DeleteLocalRef(keyEvent);
    4992     env->DeleteLocalRef(target);
    4993 }
    4994
    4995 void
    4996 AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when,
    4997                                        jint raw, jint cooked,
    4998                                        jint modifiers, jint keyLocation,
    4999                                        jlong nativeCode,
    5000                                        MSG *msg)
    5001 {
    5002     /*
    5003      * if focus owner is null, but focused window isn't
    5004      * we will send key event to focused window
    5005      */
    5006     HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow());
    5007
    5008     if (hwndTarget == GetHWnd()) {
    5009         SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg);
    5010     } else {
    5011         AwtComponent *target = NULL;
    5012         if (hwndTarget != NULL) {
    5013             target = AwtComponent::GetComponent(hwndTarget);
    5014             if (target == NULL) {
    5015                 target = this;
    5016             }
    5017         }
    5018         if (target != NULL) {
    5019             target->SendKeyEvent(id, when, raw, cooked, modifiers,
    5020               keyLocation, nativeCode, msg);
    5021         }
    5022     }
    5023 }
    5024
    5025 void AwtComponent::SetDragCapture(UINT flags)
    5026 {
    5027     // don't want to interfere with other controls
    5028     if (::GetCapture() == NULL) {
    5029         ::SetCapture(GetHWnd());
    5030     }
    5031 }
    5032
    5033 void AwtComponent::ReleaseDragCapture(UINT flags)
    5034 {
    5035     if ((::GetCapture() == GetHWnd()) && ((flags & ALL_MK_BUTTONS) == 0)) {
    5036         // user has released all buttons, so release the capture
    5037         ::ReleaseCapture();
    5038     }
    5039 }
    5040
    5041 void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y,
    5042                                   jint modifiers, jint clickCount,
    5043                                   jboolean popupTrigger, jint button,
    5044                                   MSG *pMsg, BOOL causedByTouchEvent)
    5045 {
    5046     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5047     CriticalSection::Lock l(GetLock());
    5048     if (GetPeer(env) == NULL) {
    5049         /* event received during termination. */
    5050         return;
    5051     }
    5052
    5053     static jclass mouseEventCls;
    5054     if (mouseEventCls == NULL) {
    5055         jclass mouseEventClsLocal =
    5056             env->FindClass("java/awt/event/MouseEvent");
    5057         CHECK_NULL(mouseEventClsLocal);
    5058         mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal);
    5059         env->DeleteLocalRef(mouseEventClsLocal);
    5060     }
    5061     RECT insets;
    5062     GetInsets(&insets);
    5063
    5064     static jmethodID mouseEventConst;
    5065     if (mouseEventConst == NULL) {
    5066         mouseEventConst =
    5067             env->GetMethodID(mouseEventCls, "<init>",
    5068                  "(Ljava/awt/Component;IJIIIIIIZI)V");
    5069         DASSERT(mouseEventConst);
    5070         CHECK_NULL(mouseEventConst);
    5071     }
    5072     if (env->EnsureLocalCapacity(2) < 0) {
    5073         return;
    5074     }
    5075     jobject target = GetTarget(env);
    5076     DWORD curMousePos = ::GetMessagePos();
    5077     int xAbs = GET_X_LPARAM(curMousePos);
    5078     int yAbs = GET_Y_LPARAM(curMousePos);
    5079     jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst,
    5080                                         target,
    5081                                         id, when, modifiers,
    5082                                         ScaleDownX(x + insets.left),
    5083                                         ScaleDownY(y + insets.top),
    5084                                         ScaleDownX(xAbs), ScaleDownY(yAbs),
    5085                                         clickCount, popupTrigger, button);
    5086
    5087     if (safe_ExceptionOccurred(env)) {
    5088         env->ExceptionDescribe();
    5089         env->ExceptionClear();
    5090     }
    5091
    5092     DASSERT(mouseEvent != NULL);
    5093     CHECK_NULL(mouseEvent);
    5094     if (causedByTouchEvent) {
    5095         env->SetBooleanField(mouseEvent, AwtMouseEvent::causedByTouchEventID,
    5096             JNI_TRUE);
    5097     }
    5098     if (pMsg != 0) {
    5099         AwtAWTEvent::saveMSG(env, pMsg, mouseEvent);
    5100     }
    5101     SendEvent(mouseEvent);
    5102
    5103     env->DeleteLocalRef(mouseEvent);
    5104     env->DeleteLocalRef(target);
    5105 }
    5106
    5107 void
    5108 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
    5109                                   jint modifiers, jint clickCount,
    5110                                   jboolean popupTrigger, jint scrollType,
    5111                                   jint scrollAmount, jint roundedWheelRotation,
    5112                                   jdouble preciseWheelRotation, MSG *pMsg)
    5113 {
    5114     /* Code based not so loosely on AwtComponent::SendMouseEvent */
    5115     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5116     CriticalSection::Lock l(GetLock());
    5117     if (GetPeer(env) == NULL) {
    5118         /* event received during termination. */
    5119         return;
    5120     }
    5121
    5122     static jclass mouseWheelEventCls;
    5123     if (mouseWheelEventCls == NULL) {
    5124         jclass mouseWheelEventClsLocal =
    5125             env->FindClass("java/awt/event/MouseWheelEvent");
    5126         CHECK_NULL(mouseWheelEventClsLocal);
    5127         mouseWheelEventCls = (jclass)env->NewGlobalRef(mouseWheelEventClsLocal);
    5128         env->DeleteLocalRef(mouseWheelEventClsLocal);
    5129     }
    5130     RECT insets;
    5131     GetInsets(&insets);
    5132
    5133     static jmethodID mouseWheelEventConst;
    5134     if (mouseWheelEventConst == NULL) {
    5135         mouseWheelEventConst =
    5136             env->GetMethodID(mouseWheelEventCls, "<init>",
    5137                            "(Ljava/awt/Component;IJIIIIIIZIIID)V");
    5138         DASSERT(mouseWheelEventConst);
    5139         CHECK_NULL(mouseWheelEventConst);
    5140     }
    5141     if (env->EnsureLocalCapacity(2) < 0) {
    5142         return;
    5143     }
    5144     jobject target = GetTarget(env);
    5145     DWORD curMousePos = ::GetMessagePos();
    5146     int xAbs = GET_X_LPARAM(curMousePos);
    5147     int yAbs = GET_Y_LPARAM(curMousePos);
    5148
    5149     DTRACE_PRINTLN("creating MWE in JNI");
    5150
    5151     jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
    5152                                              mouseWheelEventConst,
    5153                                              target,
    5154                                              id, when, modifiers,
    5155                                              ScaleDownX(x + insets.left),
    5156                                              ScaleDownY(y + insets.top),
    5157                                              ScaleDownX(xAbs),
    5158                                              ScaleDownY(yAbs),
    5159                                              clickCount, popupTrigger,
    5160                                              scrollType, scrollAmount,
    5161                                              roundedWheelRotation, preciseWheelRotation);
    5162
    5163     DASSERT(mouseWheelEvent != NULL);
    5164     if (mouseWheelEvent == NULL || safe_ExceptionOccurred(env)) {
    5165         env->ExceptionDescribe();
    5166         env->ExceptionClear();
    5167         env->DeleteLocalRef(target);
    5168         return;
    5169     }
    5170     if (pMsg != NULL) {
    5171         AwtAWTEvent::saveMSG(env, pMsg, mouseWheelEvent);
    5172     }
    5173     SendEvent(mouseWheelEvent);
    5174
    5175     env->DeleteLocalRef(mouseWheelEvent);
    5176     env->DeleteLocalRef(target);
    5177 }
    5178
    5179 void AwtComponent::SendFocusEvent(jint id, HWND opposite)
    5180 {
    5181     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5182
    5183     CriticalSection::Lock l(GetLock());
    5184     if (GetPeer(env) == NULL) {
    5185         /* event received during termination. */
    5186         return;
    5187     }
    5188
    5189     static jclass focusEventCls;
    5190     if (focusEventCls == NULL) {
    5191         jclass focusEventClsLocal
    5192             = env->FindClass("java/awt/event/FocusEvent");
    5193         DASSERT(focusEventClsLocal);
    5194         CHECK_NULL(focusEventClsLocal);
    5195         focusEventCls = (jclass)env->NewGlobalRef(focusEventClsLocal);
    5196         env->DeleteLocalRef(focusEventClsLocal);
    5197     }
    5198
    5199     static jmethodID focusEventConst;
    5200     if (focusEventConst == NULL) {
    5201         focusEventConst =
    5202             env->GetMethodID(focusEventCls, "<init>",
    5203                              "(Ljava/awt/Component;IZLjava/awt/Component;)V");
    5204         DASSERT(focusEventConst);
    5205         CHECK_NULL(focusEventConst);
    5206     }
    5207
    5208     static jclass sequencedEventCls;
    5209     if (sequencedEventCls == NULL) {
    5210         jclass sequencedEventClsLocal =
    5211             env->FindClass("java/awt/SequencedEvent");
    5212         DASSERT(sequencedEventClsLocal);
    5213         CHECK_NULL(sequencedEventClsLocal);
    5214         sequencedEventCls =
    5215             (jclass)env->NewGlobalRef(sequencedEventClsLocal);
    5216         env->DeleteLocalRef(sequencedEventClsLocal);
    5217     }
    5218
    5219     static jmethodID sequencedEventConst;
    5220     if (sequencedEventConst == NULL) {
    5221         sequencedEventConst =
    5222             env->GetMethodID(sequencedEventCls, "<init>",
    5223                              "(Ljava/awt/AWTEvent;)V");
    5224         DASSERT(sequencedEventConst);
    5225         CHECK_NULL(sequencedEventConst);
    5226     }
    5227
    5228     if (env->EnsureLocalCapacity(3) < 0) {
    5229         return;
    5230     }
    5231
    5232     jobject target = GetTarget(env);
    5233     jobject jOpposite = NULL;
    5234     if (opposite != NULL) {
    5235         AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);
    5236         if (awtOpposite != NULL) {
    5237             jOpposite = awtOpposite->GetTarget(env);
    5238         }
    5239     }
    5240     jobject focusEvent = env->NewObject(focusEventCls, focusEventConst,
    5241                                         target, id, JNI_FALSE, jOpposite);
    5242     DASSERT(!safe_ExceptionOccurred(env));
    5243     DASSERT(focusEvent != NULL);
    5244     if (jOpposite != NULL) {
    5245         env->DeleteLocalRef(jOpposite); jOpposite = NULL;
    5246     }
    5247     env->DeleteLocalRef(target); target = NULL;
    5248     CHECK_NULL(focusEvent);
    5249
    5250     jobject sequencedEvent = env->NewObject(sequencedEventCls,
    5251                                             sequencedEventConst,
    5252                                             focusEvent);
    5253     DASSERT(!safe_ExceptionOccurred(env));
    5254     DASSERT(sequencedEvent != NULL);
    5255     env->DeleteLocalRef(focusEvent); focusEvent = NULL;
    5256     CHECK_NULL(sequencedEvent);
    5257     SendEvent(sequencedEvent);
    5258
    5259     env->DeleteLocalRef(sequencedEvent);
    5260 }
    5261
    5262 /*
    5263  * Forward a filtered event directly to the subclassed window.
    5264  * This method is needed so that DefWindowProc is invoked on the
    5265  * component's owning thread.
    5266  */
    5267 MsgRouting AwtComponent::HandleEvent(MSG *msg, BOOL)
    5268 {
    5269     DefWindowProc(msg->message, msg->wParam, msg->lParam);
    5270     delete msg;
    5271     return mrConsume;
    5272 }
    5273
    5274 /* Post a WM_AWT_HANDLE_EVENT message which invokes HandleEvent
    5275    on the toolkit thread. This method may pre-filter the messages. */
    5276 BOOL AwtComponent::PostHandleEventMessage(MSG *msg, BOOL synthetic)
    5277 {
    5278     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5279     // We should cut off keyboard events to disabled components
    5280     // to avoid the components responding visually to keystrokes when disabled.
    5281     // we shouldn't cut off WM_SYS* messages as they aren't used for normal activity
    5282     // but to activate menus, close windows, etc
    5283     switch(msg->message) {
    5284         case WM_KEYDOWN:
    5285         case WM_KEYUP:
    5286         case WM_CHAR:
    5287         case WM_DEADCHAR:
    5288             {
    5289                 if (!isRecursivelyEnabled()) {
    5290                     goto quit;
    5291                 }
    5292                 break;
    5293             }
    5294     }
    5295     if (PostMessage(GetHWnd(), WM_AWT_HANDLE_EVENT,
    5296         (WPARAM) synthetic, (LPARAM) msg)) {
    5297             return TRUE;
    5298     } else {
    5299         JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
    5300     }
    5301 quit:
    5302     delete msg;
    5303     return FALSE;
    5304 }
    5305
    5306 void AwtComponent::SynthesizeKeyMessage(JNIEnv *env, jobject keyEvent)
    5307 {
    5308     jint id = (env)->GetIntField(keyEvent, AwtAWTEvent::idID);
    5309     UINT message;
    5310     switch (id) {
    5311       case java_awt_event_KeyEvent_KEY_PRESSED:
    5312           message = WM_KEYDOWN;
    5313           break;
    5314       case java_awt_event_KeyEvent_KEY_RELEASED:
    5315           message = WM_KEYUP;
    5316           break;
    5317       case java_awt_event_KeyEvent_KEY_TYPED:
    5318           message = WM_CHAR;
    5319           break;
    5320       default:
    5321           return;
    5322     }
    5323
    5324     /*
    5325      * KeyEvent.modifiers aren't supported -- the Java apppwd must send separate
    5326      * KEY_PRESSED and KEY_RELEASED events for the modifier virtual keys.
    5327      */
    5328     if (id == java_awt_event_KeyEvent_KEY_TYPED) {
    5329         // WM_CHAR message must be posted using WM_AWT_FORWARD_CHAR
    5330         // (for Edit control)
    5331         jchar keyChar = (jchar)
    5332           (env)->GetCharField(keyEvent, AwtKeyEvent::keyCharID);
    5333
    5334         // Bugid 4724007.  If it is a Delete character, don't send the fake
    5335         // KEY_TYPED we created back to the native window: Windows doesn't
    5336         // expect a WM_CHAR for Delete in TextFields, so it tries to enter a
    5337         // character after deleting.
    5338         if (keyChar == '\177') { // the Delete character
    5339             return;
    5340         }
    5341
    5342         // Disable forwarding WM_CHAR messages to disabled components
    5343         if (isRecursivelyEnabled()) {
    5344             if (!::PostMessage(GetHWnd(), WM_AWT_FORWARD_CHAR,
    5345                 MAKEWPARAM(keyChar, TRUE), 0)) {
    5346                 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
    5347             }
    5348         }
    5349     } else {
    5350         jint keyCode =
    5351           (env)->GetIntField(keyEvent, AwtKeyEvent::keyCodeID);
    5352         UINT key, modifiers;
    5353         AwtComponent::JavaKeyToWindowsKey(keyCode, &key, &modifiers);
    5354         MSG* msg = CreateMessage(message, key, 0);
    5355         PostHandleEventMessage(msg, TRUE);
    5356     }
    5357 }
    5358
    5359 void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent)
    5360 {
    5361     /*    DebugBreak(); */
    5362     jint button = (env)->GetIntField(mouseEvent, AwtMouseEvent::buttonID);
    5363     jint modifiers = (env)->GetIntField(mouseEvent, AwtInputEvent::modifiersID);
    5364
    5365     WPARAM wParam = 0;
    5366     WORD wLow = 0;
    5367     jint wheelAmt = 0;
    5368     jint id = (env)->GetIntField(mouseEvent, AwtAWTEvent::idID);
    5369     UINT message;
    5370     switch (id) {
    5371       case java_awt_event_MouseEvent_MOUSE_PRESSED: {
    5372           switch (button) {
    5373             case java_awt_event_MouseEvent_BUTTON1:
    5374                 message = WM_LBUTTONDOWN; break;
    5375             case java_awt_event_MouseEvent_BUTTON3:
    5376                 message = WM_MBUTTONDOWN; break;
    5377             case java_awt_event_MouseEvent_BUTTON2:
    5378                 message = WM_RBUTTONDOWN; break;
    5379             default:
    5380                 return;
    5381           }
    5382           break;
    5383       }
    5384       case java_awt_event_MouseEvent_MOUSE_RELEASED: {
    5385           switch (button) {
    5386             case java_awt_event_MouseEvent_BUTTON1:
    5387                 message = WM_LBUTTONUP; break;
    5388             case java_awt_event_MouseEvent_BUTTON3:
    5389                 message = WM_MBUTTONUP; break;
    5390             case java_awt_event_MouseEvent_BUTTON2:
    5391                 message = WM_RBUTTONUP; break;
    5392             default:
    5393                 return;
    5394           }
    5395           break;
    5396       }
    5397       case java_awt_event_MouseEvent_MOUSE_MOVED:
    5398           /* MOUSE_DRAGGED events must first have sent a MOUSE_PRESSED event. */
    5399       case java_awt_event_MouseEvent_MOUSE_DRAGGED:
    5400           message = WM_MOUSEMOVE;
    5401           break;
    5402       case java_awt_event_MouseEvent_MOUSE_WHEEL:
    5403           if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) {
    5404               wLow |= MK_CONTROL;
    5405           }
    5406           if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) {
    5407               wLow |= MK_SHIFT;
    5408           }
    5409           if (modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) {
    5410               wLow |= MK_LBUTTON;
    5411           }
    5412           if (modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) {
    5413               wLow |= MK_RBUTTON;
    5414           }
    5415           if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) {
    5416               wLow |= MK_MBUTTON;
    5417           }
    5418           if (modifiers & X1_BUTTON) {
    5419               wLow |= GetButtonMK(X1_BUTTON);
    5420           }
    5421           if (modifiers & X2_BUTTON) {
    5422               wLow |= GetButtonMK(X2_BUTTON);
    5423           }
    5424
    5425           wheelAmt = (jint)JNU_CallMethodByName(env,
    5426                                                NULL,
    5427                                                mouseEvent,
    5428                                                "getWheelRotation",
    5429                                                "()I").i;
    5430           DASSERT(!safe_ExceptionOccurred(env));
    5431           JNU_CHECK_EXCEPTION(env);
    5432           DTRACE_PRINTLN1("wheelAmt = %i\n", wheelAmt);
    5433
    5434           // convert Java wheel amount value to Win32
    5435           wheelAmt *= -1 * WHEEL_DELTA;
    5436
    5437           message = WM_MOUSEWHEEL;
    5438           wParam = MAKEWPARAM(wLow, wheelAmt);
    5439
    5440           break;
    5441       default:
    5442           return;
    5443     }
    5444     jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID);
    5445     jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID);
    5446     MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y);
    5447     PostHandleEventMessage(msg, TRUE);
    5448 }
    5449
    5450 BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;}
    5451
    5452 void AwtComponent::Invalidate(RECT* r)
    5453 {
    5454     ::InvalidateRect(GetHWnd(), r, FALSE);
    5455 }
    5456
    5457 void AwtComponent::BeginValidate()
    5458 {
    5459     DASSERT(m_validationNestCount >= 0 &&
    5460            m_validationNestCount < 1000); // sanity check
    5461
    5462     if (m_validationNestCount == 0) {
    5463     // begin deferred window positioning if we're not inside
    5464     // another Begin/EndValidate pair
    5465         DASSERT(m_hdwp == NULL);
    5466         m_hdwp = ::BeginDeferWindowPos(32);
    5467     }
    5468
    5469     m_validationNestCount++;
    5470 }
    5471
    5472 void AwtComponent::EndValidate()
    5473 {
    5474     DASSERT(m_validationNestCount > 0 &&
    5475            m_validationNestCount < 1000); // sanity check
    5476     DASSERT(m_hdwp != NULL);
    5477
    5478     m_validationNestCount--;
    5479     if (m_validationNestCount == 0) {
    5480     // if this call to EndValidate is not nested inside another
    5481     // Begin/EndValidate pair, end deferred window positioning
    5482         ::EndDeferWindowPos(m_hdwp);
    5483         m_hdwp = NULL;
    5484     }
    5485 }
    5486
    5487 /**
    5488  * HWND, AwtComponent and Java Peer interaction
    5489  */
    5490
    5491 /*
    5492  *Link the C++, Java peer, and HWNDs together.
    5493  */
    5494 void AwtComponent::LinkObjects(JNIEnv *env, jobject peer)
    5495 {
    5496     /*
    5497      * Bind all three objects together thru this C++ object, two-way to each:
    5498      *     JavaPeer <-> C++ <-> HWND
    5499      *
    5500      * C++ -> JavaPeer
    5501      */
    5502     if (m_peerObject == NULL) {
    5503         // This may have already been set up by CreateHWnd
    5504         // And we don't want to create two references so we
    5505         // will leave the prior one alone
    5506         m_peerObject = env->NewGlobalRef(peer);
    5507     }
    5508     /* JavaPeer -> HWND */
    5509     env->SetLongField(peer, AwtComponent::hwndID, reinterpret_cast<jlong>(m_hwnd));
    5510
    5511     /* JavaPeer -> C++ */
    5512     JNI_SET_PDATA(peer, this);
    5513
    5514     /* HWND -> C++ */
    5515     SetComponentInHWND();
    5516 }
    5517
    5518 /* Cleanup above linking */
    5519 void AwtComponent::UnlinkObjects()
    5520 {
    5521     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5522     if (m_peerObject) {
    5523         env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
    5524         JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
    5525         JNI_SET_DESTROYED(m_peerObject);
    5526         env->DeleteGlobalRef(m_peerObject);
    5527         m_peerObject = NULL;
    5528     }
    5529 }
    5530
    5531 void AwtComponent::Enable(BOOL bEnable)
    5532 {
    5533     if (bEnable && IsTopLevel()) {
    5534         // we should not enable blocked toplevels
    5535         bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
    5536     }
    5537     // Shouldn't trigger native focus change
    5538     // (only the proxy may be the native focus owner).
    5539     ::EnableWindow(GetHWnd(), bEnable);
    5540
    5541     CriticalSection::Lock l(GetLock());
    5542     VerifyState();
    5543 }
    5544
    5545 /*
    5546  * associate an AwtDropTarget with this AwtComponent
    5547  */
    5548
    5549 AwtDropTarget* AwtComponent::CreateDropTarget(JNIEnv* env) {
    5550     m_dropTarget = new AwtDropTarget(env, this);
    5551     m_dropTarget->RegisterTarget(TRUE);
    5552     return m_dropTarget;
    5553 }
    5554
    5555 /*
    5556  * disassociate an AwtDropTarget with this AwtComponent
    5557  */
    5558
    5559 void AwtComponent::DestroyDropTarget() {
    5560     if (m_dropTarget != NULL) {
    5561         m_dropTarget->RegisterTarget(FALSE);
    5562         m_dropTarget->Release();
    5563         m_dropTarget = NULL;
    5564     }
    5565 }
    5566
    5567 BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) {
    5568     return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK;
    5569 }
    5570
    5571 BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) {
    5572     return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE;
    5573 }
    5574
    5575 void AwtComponent::_Show(void *param)
    5576 {
    5577     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5578
    5579     jobject self = (jobject)param;
    5580
    5581     AwtComponent *p;
    5582
    5583     PDATA pData;
    5584     JNI_CHECK_PEER_GOTO(self, ret);
    5585     p = (AwtComponent *)pData;
    5586     if (::IsWindow(p->GetHWnd()))
    5587     {
    5588         p->SendMessage(WM_AWT_COMPONENT_SHOW);
    5589     }
    5590 ret:
    5591     env->DeleteGlobalRef(self);
    5592 }
    5593
    5594 void AwtComponent::_Hide(void *param)
    5595 {
    5596     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5597
    5598     jobject self = (jobject)param;
    5599
    5600     AwtComponent *p;
    5601
    5602     PDATA pData;
    5603     JNI_CHECK_PEER_GOTO(self, ret);
    5604     p = (AwtComponent *)pData;
    5605     if (::IsWindow(p->GetHWnd()))
    5606     {
    5607         p->SendMessage(WM_AWT_COMPONENT_HIDE);
    5608     }
    5609 ret:
    5610     env->DeleteGlobalRef(self);
    5611 }
    5612
    5613 void AwtComponent::_Enable(void *param)
    5614 {
    5615     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5616
    5617     jobject self = (jobject)param;
    5618
    5619     AwtComponent *p;
    5620
    5621     PDATA pData;
    5622     JNI_CHECK_PEER_GOTO(self, ret);
    5623     p = (AwtComponent *)pData;
    5624     if (::IsWindow(p->GetHWnd()))
    5625     {
    5626         p->Enable(TRUE);
    5627     }
    5628 ret:
    5629     env->DeleteGlobalRef(self);
    5630 }
    5631
    5632 void AwtComponent::_Disable(void *param)
    5633 {
    5634     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5635
    5636     jobject self = (jobject)param;
    5637
    5638     AwtComponent *p;
    5639
    5640     PDATA pData;
    5641     JNI_CHECK_PEER_GOTO(self, ret);
    5642     p = (AwtComponent *)pData;
    5643     if (::IsWindow(p->GetHWnd()))
    5644     {
    5645         p->Enable(FALSE);
    5646     }
    5647 ret:
    5648     env->DeleteGlobalRef(self);
    5649 }
    5650
    5651 jobject AwtComponent::_GetLocationOnScreen(void *param)
    5652 {
    5653     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5654
    5655     jobject self = (jobject)param;
    5656
    5657     jobject result = NULL;
    5658     AwtComponent *p;
    5659
    5660     PDATA pData;
    5661     JNI_CHECK_PEER_GOTO(self, ret);
    5662     p = (AwtComponent *)pData;
    5663     if (::IsWindow(p->GetHWnd()))
    5664     {
    5665         RECT rect;
    5666         VERIFY(::GetWindowRect(p->GetHWnd(),&rect));
    5667         result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V",
    5668                                      p->ScaleDownX(rect.left),
    5669                                      p->ScaleDownY(rect.top));
    5670     }
    5671 ret:
    5672     env->DeleteGlobalRef(self);
    5673
    5674     if (result != NULL)
    5675     {
    5676         jobject resultGlobalRef = env->NewGlobalRef(result);
    5677         env->DeleteLocalRef(result);
    5678         return resultGlobalRef;
    5679     }
    5680     else
    5681     {
    5682         return NULL;
    5683     }
    5684 }
    5685
    5686 void AwtComponent::_Reshape(void *param)
    5687 {
    5688     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5689
    5690     ReshapeStruct *rs = (ReshapeStruct*)param;
    5691     jobject self = rs->component;
    5692     jint x = rs->x;
    5693     jint y = rs->y;
    5694     jint w = rs->w;
    5695     jint h = rs->h;
    5696
    5697     AwtComponent *p;
    5698
    5699     PDATA pData;
    5700     JNI_CHECK_PEER_GOTO(self, ret);
    5701     p = (AwtComponent *)pData;
    5702     if (::IsWindow(p->GetHWnd()))
    5703     {
    5704         RECT* r = new RECT;
    5705         ::SetRect(r, x, y, x + w, y + h);
    5706         p->SendMessage(WM_AWT_RESHAPE_COMPONENT, CHECK_EMBEDDED, (LPARAM)r);
    5707     }
    5708 ret:
    5709     env->DeleteGlobalRef(self);
    5710
    5711     delete rs;
    5712 }
    5713
    5714 void AwtComponent::_ReshapeNoCheck(void *param)
    5715 {
    5716     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5717
    5718     ReshapeStruct *rs = (ReshapeStruct*)param;
    5719     jobject self = rs->component;
    5720     jint x = rs->x;
    5721     jint y = rs->y;
    5722     jint w = rs->w;
    5723     jint h = rs->h;
    5724
    5725     AwtComponent *p;
    5726
    5727     PDATA pData;
    5728     JNI_CHECK_PEER_GOTO(self, ret);
    5729     p = (AwtComponent *)pData;
    5730     if (::IsWindow(p->GetHWnd()))
    5731     {
    5732         RECT* r = new RECT;
    5733         ::SetRect(r, x, y, x + w, y + h);
    5734         p->SendMessage(WM_AWT_RESHAPE_COMPONENT, DONT_CHECK_EMBEDDED, (LPARAM)r);
    5735     }
    5736 ret:
    5737     env->DeleteGlobalRef(self);
    5738
    5739     delete rs;
    5740 }
    5741
    5742 void AwtComponent::_NativeHandleEvent(void *param)
    5743 {
    5744     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5745
    5746     NativeHandleEventStruct *nhes = (NativeHandleEventStruct *)param;
    5747     jobject self = nhes->component;
    5748     jobject event = nhes->event;
    5749
    5750     AwtComponent *p;
    5751
    5752     PDATA pData;
    5753     JNI_CHECK_NULL_GOTO(self, "peer", ret);
    5754     pData = JNI_GET_PDATA(self);
    5755     if (pData == NULL) {
    5756         env->DeleteGlobalRef(self);
    5757         if (event != NULL) {
    5758             env->DeleteGlobalRef(event);
    5759         }
    5760         delete nhes;
    5761         return;
    5762     }
    5763     JNI_CHECK_NULL_GOTO(event, "null AWTEvent", ret);
    5764
    5765     p = (AwtComponent *)pData;
    5766     if (::IsWindow(p->GetHWnd()))
    5767     {
    5768         if (env->EnsureLocalCapacity(1) < 0) {
    5769             env->DeleteGlobalRef(self);
    5770             env->DeleteGlobalRef(event);
    5771             delete nhes;
    5772             return;
    5773         }
    5774         jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID);
    5775         int id = (env)->GetIntField(event, AwtAWTEvent::idID);
    5776         DASSERT(!safe_ExceptionOccurred(env));
    5777         if (bdata != 0) {
    5778             MSG msg;
    5779             (env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg);
    5780             (env)->DeleteLocalRef(bdata);
    5781             static BOOL keyDownConsumed = FALSE;
    5782             static BOOL bCharChanged = FALSE;
    5783             static WCHAR modifiedChar;
    5784             WCHAR unicodeChar;
    5785
    5786             /* Remember if a KEY_PRESSED event is consumed, as an old model
    5787              * program won't consume a subsequent KEY_TYPED event.
    5788              */
    5789             jboolean consumed =
    5790                 (env)->GetBooleanField(event, AwtAWTEvent::consumedID);
    5791             DASSERT(!safe_ExceptionOccurred(env));
    5792
    5793             if (consumed) {
    5794                 keyDownConsumed = (id == java_awt_event_KeyEvent_KEY_PRESSED);
    5795                 env->DeleteGlobalRef(self);
    5796                 env->DeleteGlobalRef(event);
    5797                 delete nhes;
    5798                 return;
    5799
    5800             } else if (id == java_awt_event_KeyEvent_KEY_PRESSED) {
    5801                 // Fix for 6637607: reset consuming
    5802                 keyDownConsumed = FALSE;
    5803             }
    5804
    5805             /* Consume a KEY_TYPED event if a KEY_PRESSED had been, to support
    5806              * the old model.
    5807              */
    5808             if ((id == java_awt_event_KeyEvent_KEY_TYPED) && keyDownConsumed) {
    5809                 keyDownConsumed = FALSE;
    5810                 env->DeleteGlobalRef(self);
    5811                 env->DeleteGlobalRef(event);
    5812                 delete nhes;
    5813                 return;
    5814             }
    5815
    5816             /* Modify any event parameters, if necessary. */
    5817             if (self && pData &&
    5818                 id >= java_awt_event_KeyEvent_KEY_FIRST &&
    5819                 id <= java_awt_event_KeyEvent_KEY_LAST) {
    5820
    5821                     AwtComponent* p = (AwtComponent*)pData;
    5822
    5823                     jint keyCode =
    5824                       (env)->GetIntField(event, AwtKeyEvent::keyCodeID);
    5825                     jchar keyChar =
    5826                       (env)->GetCharField(event, AwtKeyEvent::keyCharID);
    5827                     jint modifiers =
    5828                       (env)->GetIntField(event, AwtInputEvent::modifiersID);
    5829
    5830                     DASSERT(!safe_ExceptionOccurred(env));
    5831
    5832                 /* Check to see whether the keyCode or modifiers were changed
    5833                    on the keyPressed event, and tweak the following keyTyped
    5834                    event (if any) accodingly.  */
    5835                 switch (id) {
    5836                 case java_awt_event_KeyEvent_KEY_PRESSED:
    5837                 {
    5838                     UINT winKey = (UINT)msg.wParam;
    5839                     bCharChanged = FALSE;
    5840
    5841                     if (winKey == VK_PROCESSKEY) {
    5842                         // Leave it up to IME
    5843                         break;
    5844                     }
    5845
    5846                     if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) {
    5847                         UINT newWinKey, ignored;
    5848                         p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey);
    5849                         if (newWinKey != 0) {
    5850                             winKey = newWinKey;
    5851                         }
    5852                     }
    5853
    5854                     BOOL isDeadKey = FALSE;
    5855                     modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey);
    5856                     bCharChanged = (keyChar != modifiedChar);
    5857                 }
    5858                 break;
    5859
    5860                 case java_awt_event_KeyEvent_KEY_RELEASED:
    5861                 {
    5862                     keyDownConsumed = FALSE;
    5863                     bCharChanged = FALSE;
    5864                 }
    5865                 break;
    5866
    5867                 case java_awt_event_KeyEvent_KEY_TYPED:
    5868                 {
    5869                     if (bCharChanged)
    5870                     {
    5871                         unicodeChar = modifiedChar;
    5872                     }
    5873                     else
    5874                     {
    5875                         unicodeChar = keyChar;
    5876                     }
    5877                     bCharChanged = FALSE;
    5878
    5879                     // Disable forwarding KEY_TYPED messages to peers of
    5880                     // disabled components
    5881                     if (p->isRecursivelyEnabled()) {
    5882                         // send the character back to the native window for
    5883                         // processing. The WM_AWT_FORWARD_CHAR handler will send
    5884                         // this character to DefWindowProc
    5885                         if (!::PostMessage(p->GetHWnd(), WM_AWT_FORWARD_CHAR,
    5886                             MAKEWPARAM(unicodeChar, FALSE), msg.lParam)) {
    5887                             JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
    5888                         }
    5889                     }
    5890                     env->DeleteGlobalRef(self);
    5891                     env->DeleteGlobalRef(event);
    5892                     delete nhes;
    5893                     return;
    5894                 }
    5895                 break;
    5896
    5897                 default:
    5898                     break;
    5899                 }
    5900             }
    5901
    5902             // ignore all InputMethodEvents
    5903             if (self && (pData = JNI_GET_PDATA(self)) &&
    5904                 id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST &&
    5905                 id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) {
    5906                 env->DeleteGlobalRef(self);
    5907                 env->DeleteGlobalRef(event);
    5908                 delete nhes;
    5909                 return;
    5910             }
    5911
    5912             // Create copy for local msg
    5913             MSG* pCopiedMsg = new MSG;
    5914             memmove(pCopiedMsg, &msg, sizeof(MSG));
    5915             // Event handler deletes msg
    5916             p->PostHandleEventMessage(pCopiedMsg, FALSE);
    5917
    5918             env->DeleteGlobalRef(self);
    5919             env->DeleteGlobalRef(event);
    5920             delete nhes;
    5921             return;
    5922         }
    5923
    5924         /* Forward any valid synthesized events.  Currently only mouse and
    5925          * key events are supported.
    5926          */
    5927         if (self == NULL || (pData = JNI_GET_PDATA(self)) == NULL) {
    5928             env->DeleteGlobalRef(self);
    5929             env->DeleteGlobalRef(event);
    5930             delete nhes;
    5931             return;
    5932         }
    5933
    5934         AwtComponent* p = (AwtComponent*)pData;
    5935         if (id >= java_awt_event_KeyEvent_KEY_FIRST &&
    5936             id <= java_awt_event_KeyEvent_KEY_LAST) {
    5937             p->SynthesizeKeyMessage(env, event);
    5938         } else if (id >= java_awt_event_MouseEvent_MOUSE_FIRST &&
    5939                    id <= java_awt_event_MouseEvent_MOUSE_LAST) {
    5940             p->SynthesizeMouseMessage(env, event);
    5941         }
    5942     }
    5943
    5944 ret:
    5945     if (self != NULL) {
    5946         env->DeleteGlobalRef(self);
    5947     }
    5948     if (event != NULL) {
    5949         env->DeleteGlobalRef(event);
    5950     }
    5951
    5952     delete nhes;
    5953 }
    5954
    5955 void AwtComponent::_SetForeground(void *param)
    5956 {
    5957     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5958
    5959     SetColorStruct *scs = (SetColorStruct *)param;
    5960     jobject self = scs->component;
    5961     jint rgb = scs->rgb;
    5962
    5963     AwtComponent *c = NULL;
    5964
    5965     PDATA pData;
    5966     JNI_CHECK_PEER_GOTO(self, ret);
    5967     c = (AwtComponent *)pData;
    5968     if (::IsWindow(c->GetHWnd()))
    5969     {
    5970         c->SetColor(PALETTERGB((rgb>>16)&0xff,
    5971                                (rgb>>8)&0xff,
    5972                                (rgb)&0xff));
    5973         c->VerifyState();
    5974     }
    5975 ret:
    5976     env->DeleteGlobalRef(self);
    5977
    5978     delete scs;
    5979 }
    5980
    5981 void AwtComponent::_SetBackground(void *param)
    5982 {
    5983     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    5984
    5985     SetColorStruct *scs = (SetColorStruct *)param;
    5986     jobject self = scs->component;
    5987     jint rgb = scs->rgb;
    5988
    5989     AwtComponent *c = NULL;
    5990
    5991     PDATA pData;
    5992     JNI_CHECK_PEER_GOTO(self, ret);
    5993     c = (AwtComponent *)pData;
    5994     if (::IsWindow(c->GetHWnd()))
    5995     {
    5996         c->SetBackgroundColor(PALETTERGB((rgb>>16)&0xff,
    5997                                          (rgb>>8)&0xff,
    5998                                          (rgb)&0xff));
    5999         c->VerifyState();
    6000     }
    6001 ret:
    6002     env->DeleteGlobalRef(self);
    6003
    6004     delete scs;
    6005 }
    6006
    6007 void AwtComponent::_SetFont(void *param)
    6008 {
    6009     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6010
    6011     SetFontStruct *sfs = (SetFontStruct *)param;
    6012     jobject self = sfs->component;
    6013     jobject font = sfs->font;
    6014
    6015     AwtComponent *c = NULL;
    6016
    6017     PDATA pData;
    6018     JNI_CHECK_PEER_GOTO(self, ret);
    6019     JNI_CHECK_NULL_GOTO(font, "null font", ret);
    6020     c = (AwtComponent *)pData;
    6021     if (::IsWindow(c->GetHWnd()))
    6022     {
    6023         AwtFont *awtFont = (AwtFont *)env->GetLongField(font, AwtFont::pDataID);
    6024         if (awtFont == NULL) {
    6025             /*arguments of AwtFont::Create are changed for multifont component */
    6026             awtFont = AwtFont::Create(env, font);
    6027         }
    6028         env->SetLongField(font, AwtFont::pDataID, (jlong)awtFont);
    6029
    6030         c->SetFont(awtFont);
    6031     }
    6032 ret:
    6033     env->DeleteGlobalRef(self);
    6034     env->DeleteGlobalRef(font);
    6035
    6036     delete sfs;
    6037 }
    6038
    6039 // Sets or kills focus for a component.
    6040 void AwtComponent::_SetFocus(void *param)
    6041 {
    6042     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6043
    6044     SetFocusStruct *sfs = (SetFocusStruct *)param;
    6045     jobject self = sfs->component;
    6046     jboolean doSetFocus = sfs->doSetFocus;
    6047
    6048     AwtComponent *c = NULL;
    6049
    6050     PDATA pData;
    6051     JNI_CHECK_NULL_GOTO(self, "peer", ret);
    6052     pData = JNI_GET_PDATA(self);
    6053     if (pData == NULL) {
    6054         // do nothing just return false
    6055         goto ret;
    6056     }
    6057
    6058     c = (AwtComponent *)pData;
    6059     if (::IsWindow(c->GetHWnd())) {
    6060         c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0);
    6061     }
    6062 ret:
    6063     env->DeleteGlobalRef(self);
    6064
    6065     delete sfs;
    6066 }
    6067
    6068 void AwtComponent::_Start(void *param)
    6069 {
    6070     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6071
    6072     jobject self = (jobject)param;
    6073
    6074     AwtComponent *c = NULL;
    6075
    6076     PDATA pData;
    6077     JNI_CHECK_PEER_GOTO(self, ret);
    6078     c = (AwtComponent *)pData;
    6079     if (::IsWindow(c->GetHWnd()))
    6080     {
    6081         jobject target = c->GetTarget(env);
    6082
    6083         /* Disable window if specified -- windows are enabled by default. */
    6084         jboolean enabled = (jboolean)env->GetBooleanField(target,
    6085                                                           AwtComponent::enabledID);
    6086         if (!enabled) {
    6087             ::EnableWindow(c->GetHWnd(), FALSE);
    6088         }
    6089
    6090         /* The peer is now ready for callbacks, since this is the last
    6091          * initialization call
    6092          */
    6093         c->EnableCallbacks(TRUE);
    6094
    6095         // Fix 4745222: we need to invalidate region since we validated it before initialization.
    6096         ::InvalidateRgn(c->GetHWnd(), NULL, FALSE);
    6097
    6098         // Fix 4530093: WM_PAINT after EnableCallbacks
    6099         ::UpdateWindow(c->GetHWnd());
    6100
    6101         env->DeleteLocalRef(target);
    6102     }
    6103 ret:
    6104     env->DeleteGlobalRef(self);
    6105 }
    6106
    6107 void AwtComponent::_BeginValidate(void *param)
    6108 {
    6109     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6110     if (AwtToolkit::IsMainThread()) {
    6111         jobject self = (jobject)param;
    6112         if (self != NULL) {
    6113             PDATA pData = JNI_GET_PDATA(self);
    6114             if (pData) {
    6115                 AwtComponent *c = (AwtComponent *)pData;
    6116                 if (::IsWindow(c->GetHWnd())) {
    6117                     c->SendMessage(WM_AWT_BEGIN_VALIDATE);
    6118                 }
    6119             }
    6120             env->DeleteGlobalRef(self);
    6121         }
    6122     } else {
    6123         AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_BeginValidate, param);
    6124     }
    6125 }
    6126
    6127 void AwtComponent::_EndValidate(void *param)
    6128 {
    6129     if (AwtToolkit::IsMainThread()) {
    6130         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6131         jobject self = (jobject)param;
    6132         if (self != NULL) {
    6133             PDATA pData = JNI_GET_PDATA(self);
    6134             if (pData) {
    6135                 AwtComponent *c = (AwtComponent *)pData;
    6136                 if (::IsWindow(c->GetHWnd())) {
    6137                     c->SendMessage(WM_AWT_END_VALIDATE);
    6138                 }
    6139             }
    6140             env->DeleteGlobalRef(self);
    6141         }
    6142     } else {
    6143         AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_EndValidate, param);
    6144     }
    6145 }
    6146
    6147 void AwtComponent::_UpdateWindow(void *param)
    6148 {
    6149     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6150     if (AwtToolkit::IsMainThread()) {
    6151         jobject self = (jobject)param;
    6152         AwtComponent *c = NULL;
    6153         PDATA pData;
    6154         JNI_CHECK_PEER_GOTO(self, ret);
    6155         c = (AwtComponent *)pData;
    6156         if (::IsWindow(c->GetHWnd())) {
    6157             ::UpdateWindow(c->GetHWnd());
    6158         }
    6159 ret:
    6160         env->DeleteGlobalRef(self);
    6161     } else {
    6162         AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_UpdateWindow, param);
    6163     }
    6164 }
    6165
    6166 jlong AwtComponent::_AddNativeDropTarget(void *param)
    6167 {
    6168     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6169
    6170     jobject self = (jobject)param;
    6171
    6172     jlong result = 0;
    6173     AwtComponent *c = NULL;
    6174
    6175     PDATA pData;
    6176     JNI_CHECK_PEER_GOTO(self, ret);
    6177     c = (AwtComponent *)pData;
    6178     if (::IsWindow(c->GetHWnd()))
    6179     {
    6180         result = (jlong)(c->CreateDropTarget(env));
    6181     }
    6182 ret:
    6183     env->DeleteGlobalRef(self);
    6184
    6185     return result;
    6186 }
    6187
    6188 void AwtComponent::_RemoveNativeDropTarget(void *param)
    6189 {
    6190     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6191
    6192     jobject self = (jobject)param;
    6193
    6194     AwtComponent *c = NULL;
    6195
    6196     PDATA pData;
    6197     JNI_CHECK_PEER_GOTO(self, ret);
    6198     c = (AwtComponent *)pData;
    6199     if (::IsWindow(c->GetHWnd()))
    6200     {
    6201         c->DestroyDropTarget();
    6202     }
    6203 ret:
    6204     env->DeleteGlobalRef(self);
    6205 }
    6206
    6207 jintArray AwtComponent::_CreatePrintedPixels(void *param)
    6208 {
    6209     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6210
    6211     CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param;
    6212     jobject self = cpps->component;
    6213
    6214     jintArray result = NULL;
    6215     AwtComponent *c = NULL;
    6216
    6217     PDATA pData;
    6218     JNI_CHECK_PEER_GOTO(self, ret);
    6219     c = (AwtComponent *)pData;
    6220     if (::IsWindow(c->GetHWnd()))
    6221     {
    6222         result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0);
    6223     }
    6224 ret:
    6225     env->DeleteGlobalRef(self);
    6226
    6227     delete cpps;
    6228     return result; // this reference is global
    6229 }
    6230
    6231 jboolean AwtComponent::_IsObscured(void *param)
    6232 {
    6233     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6234
    6235     jobject self = (jobject)param;
    6236
    6237     jboolean result = JNI_FALSE;
    6238     AwtComponent *c = NULL;
    6239
    6240     PDATA pData;
    6241     JNI_CHECK_PEER_GOTO(self, ret);
    6242
    6243     c = (AwtComponent *)pData;
    6244
    6245     if (::IsWindow(c->GetHWnd()))
    6246     {
    6247         HWND hWnd = c->GetHWnd();
    6248         HDC hDC = ::GetDC(hWnd);
    6249         RECT clipbox;
    6250         int callresult = ::GetClipBox(hDC, &clipbox);
    6251         switch(callresult) {
    6252             case NULLREGION :
    6253                 result = JNI_FALSE;
    6254                 break;
    6255             case SIMPLEREGION : {
    6256                 RECT windowRect;
    6257                 if (!::GetClientRect(hWnd, &windowRect)) {
    6258                     result = JNI_TRUE;
    6259                 } else {
    6260                     result  = (jboolean)((clipbox.bottom != windowRect.bottom)
    6261                         || (clipbox.left != windowRect.left)
    6262                         || (clipbox.right != windowRect.right)
    6263                         || (clipbox.top != windowRect.top));
    6264                 }
    6265                 break;
    6266             }
    6267             case COMPLEXREGION :
    6268             default :
    6269                 result = JNI_TRUE;
    6270                 break;
    6271         }
    6272         ::ReleaseDC(hWnd, hDC);
    6273     }
    6274 ret:
    6275     env->DeleteGlobalRef(self);
    6276
    6277     return result;
    6278 }
    6279
    6280 jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param)
    6281 {
    6282     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6283
    6284     jobject self = (jobject)param;
    6285
    6286     jboolean result = JNI_FALSE;
    6287     AwtComponent *c = NULL;
    6288
    6289     PDATA pData;
    6290     JNI_CHECK_PEER_GOTO(self, ret);
    6291     c = (AwtComponent *)pData;
    6292     if (::IsWindow(c->GetHWnd()))
    6293     {
    6294         result = JNI_IS_TRUE(c->InheritsNativeMouseWheelBehavior());
    6295     }
    6296 ret:
    6297     env->DeleteGlobalRef(self);
    6298
    6299     return result;
    6300 }
    6301
    6302 void AwtComponent::_SetParent(void * param)
    6303 {
    6304     if (AwtToolkit::IsMainThread()) {
    6305         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6306         SetParentStruct *data = (SetParentStruct*) param;
    6307         jobject self = data->component;
    6308         jobject parent = data->parentComp;
    6309
    6310         AwtComponent *awtComponent = NULL;
    6311         AwtComponent *awtParent = NULL;
    6312
    6313         PDATA pData;
    6314         JNI_CHECK_PEER_GOTO(self, ret);
    6315         awtComponent = (AwtComponent *)pData;
    6316         JNI_CHECK_PEER_GOTO(parent, ret);
    6317         awtParent = (AwtComponent *)pData;
    6318
    6319         HWND selfWnd = awtComponent->GetHWnd();
    6320         HWND parentWnd = awtParent->GetHWnd();
    6321         if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) {
    6322             // Shouldn't trigger native focus change
    6323             // (only the proxy may be the native focus owner).
    6324             ::SetParent(selfWnd, parentWnd);
    6325         }
    6326 ret:
    6327         env->DeleteGlobalRef(self);
    6328         env->DeleteGlobalRef(parent);
    6329         delete data;
    6330     } else {
    6331         AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetParent, param);
    6332     }
    6333 }
    6334
    6335 void AwtComponent::_SetRectangularShape(void *param)
    6336 {
    6337     if (!AwtToolkit::IsMainThread()) {
    6338         AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param);
    6339     } else {
    6340         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6341
    6342         SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param;
    6343         jobject self = data->component;
    6344         jint x1 = data->x1;
    6345         jint x2 = data->x2;
    6346         jint y1 = data->y1;
    6347         jint y2 = data->y2;
    6348         jobject region = data->region;
    6349
    6350         AwtComponent *c = NULL;
    6351
    6352         PDATA pData;
    6353         JNI_CHECK_PEER_GOTO(self, ret);
    6354
    6355         c = (AwtComponent *)pData;
    6356         if (::IsWindow(c->GetHWnd())) {
    6357             HRGN hRgn = NULL;
    6358
    6359             // If all the params are zeros, the shape must be simply reset.
    6360             // Otherwise, convert it into a region.
    6361             if (region || x1 || x2 || y1 || y2) {
    6362                 RECT_T rects[256];
    6363                 RECT_T *pRect = rects;
    6364
    6365                 const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2,
    6366                         region, &pRect, sizeof(rects)/sizeof(rects[0]));
    6367                 if (!pRect) {
    6368                     // RegionToYXBandedRectangles doesn't use safe_Malloc(),
    6369                     // so throw the exception explicitly
    6370                     throw std::bad_alloc();
    6371                 }
    6372
    6373                 RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc,
    6374                         sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects);
    6375                 memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects);
    6376                 if (pRect != rects) {
    6377                     free(pRect);
    6378                 }
    6379                 pRect = NULL;
    6380
    6381                 RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData;
    6382                 pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
    6383                 pRgnHdr->iType = RDH_RECTANGLES;
    6384                 pRgnHdr->nRgnSize = 0;
    6385                 pRgnHdr->rcBound.top = 0;
    6386                 pRgnHdr->rcBound.left = 0;
    6387                 pRgnHdr->rcBound.bottom = LONG(y2 - y1);
    6388                 pRgnHdr->rcBound.right = LONG(x2 - x1);
    6389                 pRgnHdr->nCount = numrects;
    6390
    6391                 hRgn = ::ExtCreateRegion(NULL,
    6392                         sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData);
    6393
    6394                 free(pRgnData);
    6395             }
    6396
    6397             ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE);
    6398         }
    6399
    6400 ret:
    6401         env->DeleteGlobalRef(self);
    6402         if (region) {
    6403             env->DeleteGlobalRef(region);
    6404         }
    6405
    6406         delete data;
    6407     }
    6408 }
    6409
    6410 void AwtComponent::_SetZOrder(void *param) {
    6411     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6412
    6413     SetZOrderStruct *data = (SetZOrderStruct *)param;
    6414     jobject self = data->component;
    6415     HWND above = HWND_TOP;
    6416     if (data->above != 0) {
    6417         above = reinterpret_cast<HWND>(data->above);
    6418     }
    6419
    6420     AwtComponent *c = NULL;
    6421
    6422     PDATA pData;
    6423     JNI_CHECK_PEER_GOTO(self, ret);
    6424
    6425     c = (AwtComponent *)pData;
    6426     if (::IsWindow(c->GetHWnd())) {
    6427         ::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0,
    6428                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS);
    6429     }
    6430
    6431 ret:
    6432     env->DeleteGlobalRef(self);
    6433
    6434     delete data;
    6435 }
    6436
    6437 void AwtComponent::PostUngrabEvent() {
    6438     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6439     jobject target = GetTarget(env);
    6440     jobject event = JNU_NewObjectByName(env, "sun/awt/UngrabEvent", "(Ljava/awt/Component;)V",
    6441                                         target);
    6442     if (safe_ExceptionOccurred(env)) {
    6443         env->ExceptionDescribe();
    6444         env->ExceptionClear();
    6445     }
    6446     env->DeleteLocalRef(target);
    6447     if (event != NULL) {
    6448         SendEvent(event);
    6449         env->DeleteLocalRef(event);
    6450     }
    6451 }
    6452
    6453 void AwtComponent::SetFocusedWindow(HWND window)
    6454 {
    6455     HWND old = sm_focusedWindow;
    6456     sm_focusedWindow = window;
    6457
    6458     AwtWindow::FocusedWindowChanged(old, window);
    6459 }
    6460
    6461 /************************************************************************
    6462  * Component native methods
    6463  */
    6464
    6465 extern "C" {
    6466
    6467 /**
    6468  * This method is called from the WGL pipeline when it needs to retrieve
    6469  * the HWND associated with a ComponentPeer's C++ level object.
    6470  */
    6471 HWND
    6472 AwtComponent_GetHWnd(JNIEnv *env, jlong pData)
    6473 {
    6474     AwtComponent *p = (AwtComponent *)jlong_to_ptr(pData);
    6475     if (p == NULL) {
    6476         return (HWND)0;
    6477     }
    6478     return p->GetHWnd();
    6479 }
    6480
    6481 static void _GetInsets(void* param)
    6482 {
    6483     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    6484
    6485     GetInsetsStruct *gis = (GetInsetsStruct *)param;
    6486     jobject self = gis->window;
    6487
    6488     gis->insets->left = gis->insets->top =
    6489         gis->insets->right = gis->insets->bottom = 0;
    6490
    6491     PDATA pData;
    6492     JNI_CHECK_PEER_GOTO(self, ret);
    6493     AwtComponent *component = (AwtComponent *)pData;
    6494
    6495     component->GetInsets(gis->insets);
    6496
    6497   ret:
    6498     env->DeleteGlobalRef(self);
    6499     delete gis;
    6500 }
    6501
    6502 /**
    6503  * This method is called from the WGL pipeline when it needs to retrieve
    6504  * the insets associated with a ComponentPeer's C++ level object.
    6505  */
    6506 void AwtComponent_GetInsets(JNIEnv *env, jobject peer, RECT *insets)
    6507 {
    6508     TRY;
    6509
    6510     GetInsetsStruct *gis = new GetInsetsStruct;
    6511     gis->window = env->NewGlobalRef(peer);
    6512     gis->insets = insets;
    6513
    6514     AwtToolkit::GetInstance().InvokeFunction(_GetInsets, gis);
    6515     // global refs and mds are deleted in _UpdateWindow
    6516
    6517     CATCH_BAD_ALLOC;
    6518
    6519 }
    6520
    6521 JNIEXPORT void JNICALL
    6522 Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
    6523 {
    6524     TRY;
    6525     jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent");
    6526     CHECK_NULL(inputEventClazz);
    6527     jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I");
    6528     CHECK_NULL(getButtonDownMasksID);
    6529     jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID);
    6530     jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE);
    6531     CHECK_NULL(tmp);
    6532     jsize len = env->GetArrayLength(obj);
    6533     AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len);
    6534     for (int i = 0; i < len; i++) {
    6535         AwtComponent::masks[i] = tmp[i];
    6536     }
    6537     env->ReleaseIntArrayElements(obj, tmp, 0);
    6538     env->DeleteLocalRef(obj);
    6539
    6540     /* class ids */
    6541     jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer");
    6542
    6543     DASSERT(peerCls);
    6544     CHECK_NULL(peerCls);
    6545
    6546     /* field ids */
    6547     AwtComponent::peerID =
    6548       env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;");
    6549     DASSERT(AwtComponent::peerID);
    6550     CHECK_NULL(AwtComponent::peerID);
    6551
    6552     AwtComponent::xID = env->GetFieldID(cls, "x", "I");
    6553     DASSERT(AwtComponent::xID);
    6554     CHECK_NULL(AwtComponent::xID);
    6555
    6556     AwtComponent::yID = env->GetFieldID(cls, "y", "I");
    6557     DASSERT(AwtComponent::yID);
    6558     CHECK_NULL(AwtComponent::yID);
    6559
    6560     AwtComponent::heightID = env->GetFieldID(cls, "height", "I");
    6561     DASSERT(AwtComponent::heightID);
    6562     CHECK_NULL(AwtComponent::heightID);
    6563
    6564     AwtComponent::widthID = env->GetFieldID(cls, "width", "I");
    6565     DASSERT(AwtComponent::widthID);
    6566     CHECK_NULL(AwtComponent::widthID);
    6567
    6568     AwtComponent::visibleID = env->GetFieldID(cls, "visible", "Z");
    6569     DASSERT(AwtComponent::visibleID);
    6570     CHECK_NULL(AwtComponent::visibleID);
    6571
    6572     AwtComponent::backgroundID =
    6573         env->GetFieldID(cls, "background", "Ljava/awt/Color;");
    6574     DASSERT(AwtComponent::backgroundID);
    6575     CHECK_NULL(AwtComponent::backgroundID);
    6576
    6577     AwtComponent::foregroundID =
    6578         env->GetFieldID(cls, "foreground", "Ljava/awt/Color;");
    6579     DASSERT(AwtComponent::foregroundID);
    6580     CHECK_NULL(AwtComponent::foregroundID);
    6581
    6582     AwtComponent::enabledID = env->GetFieldID(cls, "enabled", "Z");
    6583     DASSERT(AwtComponent::enabledID);
    6584     CHECK_NULL(AwtComponent::enabledID);
    6585
    6586     AwtComponent::parentID = env->GetFieldID(cls, "parent", "Ljava/awt/Container;");
    6587     DASSERT(AwtComponent::parentID);
    6588     CHECK_NULL(AwtComponent::parentID);
    6589
    6590     AwtComponent::graphicsConfigID =
    6591      env->GetFieldID(cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;");
    6592     DASSERT(AwtComponent::graphicsConfigID);
    6593     CHECK_NULL(AwtComponent::graphicsConfigID);
    6594
    6595     AwtComponent::focusableID = env->GetFieldID(cls, "focusable", "Z");
    6596     DASSERT(AwtComponent::focusableID);
    6597     CHECK_NULL(AwtComponent::focusableID);
    6598
    6599     AwtComponent::appContextID = env->GetFieldID(cls, "appContext",
    6600                                                  "Lsun/awt/AppContext;");
    6601     DASSERT(AwtComponent::appContextID);
    6602     CHECK_NULL(AwtComponent::appContextID);
    6603
    6604     AwtComponent::peerGCID = env->GetFieldID(peerCls, "winGraphicsConfig",
    6605                                         "Lsun/awt/Win32GraphicsConfig;");
    6606     DASSERT(AwtComponent::peerGCID);
    6607     CHECK_NULL(AwtComponent::peerGCID);
    6608
    6609     AwtComponent::hwndID = env->GetFieldID(peerCls, "hwnd", "J");
    6610     DASSERT(AwtComponent::hwndID);
    6611     CHECK_NULL(AwtComponent::hwndID);
    6612
    6613     AwtComponent::cursorID = env->GetFieldID(cls, "cursor", "Ljava/awt/Cursor;");
    6614     DASSERT(AwtComponent::cursorID);
    6615     CHECK_NULL(AwtComponent::cursorID);
    6616
    6617     /* method ids */
    6618     AwtComponent::getFontMID =
    6619         env->GetMethodID(cls, "getFont_NoClientCode", "()Ljava/awt/Font;");
    6620     DASSERT(AwtComponent::getFontMID);
    6621     CHECK_NULL(AwtComponent::getFontMID);
    6622
    6623     AwtComponent::getToolkitMID =
    6624         env->GetMethodID(cls, "getToolkitImpl", "()Ljava/awt/Toolkit;");
    6625     DASSERT(AwtComponent::getToolkitMID);
    6626     CHECK_NULL(AwtComponent::getToolkitMID);
    6627
    6628     AwtComponent::isEnabledMID = env->GetMethodID(cls, "isEnabledImpl", "()Z");
    6629     DASSERT(AwtComponent::isEnabledMID);
    6630     CHECK_NULL(AwtComponent::isEnabledMID);
    6631
    6632     AwtComponent::getLocationOnScreenMID =
    6633         env->GetMethodID(cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;");
    6634     DASSERT(AwtComponent::getLocationOnScreenMID);
    6635     CHECK_NULL(AwtComponent::getLocationOnScreenMID);
    6636
    6637     AwtComponent::replaceSurfaceDataMID =
    6638         env->GetMethodID(peerCls, "replaceSurfaceData", "()V");
    6639     DASSERT(AwtComponent::replaceSurfaceDataMID);
    6640     CHECK_NULL(AwtComponent::replaceSurfaceDataMID);
    6641
    6642     AwtComponent::replaceSurfaceDataLaterMID =
    6643         env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V");
    6644     DASSERT(AwtComponent::replaceSurfaceDataLaterMID);
    6645     CHECK_NULL(AwtComponent::replaceSurfaceDataLaterMID);
    6646
    6647     AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V");
    6648     DASSERT(AwtComponent::disposeLaterMID);
    6649     CHECK_NULL(AwtComponent::disposeLaterMID);
    6650
    6651     CATCH_BAD_ALLOC;
    6652 }
    6653
    6654 } /* extern "C" */
    6655
    6656
    6657 /************************************************************************
    6658  * ComponentPeer native methods
    6659  */
    6660
    6661 extern "C" {
    6662
    6663 /*
    6664  * Class:     sun_awt_windows_WComponentPeer
    6665  * Method:    pShow
    6666  * Signature: ()V
    6667  */
    6668 JNIEXPORT void JNICALL
    6669 Java_sun_awt_windows_WComponentPeer_pShow(JNIEnv *env, jobject self)
    6670 {
    6671     TRY;
    6672
    6673     jobject selfGlobalRef = env->NewGlobalRef(self);
    6674
    6675     AwtToolkit::GetInstance().SyncCall(AwtComponent::_Show, (void *)selfGlobalRef);
    6676     // selfGlobalRef is deleted in _Show
    6677
    6678     CATCH_BAD_ALLOC;
    6679 }
    6680
    6681 /*
    6682  * Class:     sun_awt_windows_WComponentPeer
    6683  * Method:    hide
    6684  * Signature: ()V
    6685  */
    6686 JNIEXPORT void JNICALL
    6687 Java_sun_awt_windows_WComponentPeer_hide(JNIEnv *env, jobject self)
    6688 {
    6689     TRY;
    6690
    6691     jobject selfGlobalRef = env->NewGlobalRef(self);
    6692
    6693     AwtToolkit::GetInstance().SyncCall(AwtComponent::_Hide, (void *)selfGlobalRef);
    6694     // selfGlobalRef is deleted in _Hide
    6695
    6696     CATCH_BAD_ALLOC;
    6697 }
    6698
    6699 /*
    6700  * Class:     sun_awt_windows_WComponentPeer
    6701  * Method:    enable
    6702  * Signature: ()V
    6703  */
    6704 JNIEXPORT void JNICALL
    6705 Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self)
    6706 {
    6707     TRY;
    6708
    6709     jobject selfGlobalRef = env->NewGlobalRef(self);
    6710
    6711     AwtToolkit::GetInstance().SyncCall(AwtComponent::_Enable, (void *)selfGlobalRef);
    6712     // selfGlobalRef is deleted in _Enable
    6713
    6714     CATCH_BAD_ALLOC;
    6715 }
    6716
    6717 /*
    6718  * Class:     sun_awt_windows_WComponentPeer
    6719  * Method:    disable
    6720  * Signature: ()V
    6721  */
    6722 JNIEXPORT void JNICALL
    6723 Java_sun_awt_windows_WComponentPeer_disable(JNIEnv *env, jobject self)
    6724 {
    6725     TRY;
    6726
    6727     jobject selfGlobalRef = env->NewGlobalRef(self);
    6728
    6729     AwtToolkit::GetInstance().SyncCall(AwtComponent::_Disable, (void *)selfGlobalRef);
    6730     // selfGlobalRef is deleted in _Disable
    6731
    6732     CATCH_BAD_ALLOC;
    6733 }
    6734
    6735 /*
    6736  * Class:     sun_awt_windows_WComponentPeer
    6737  * Method:    getLocationOnScreen
    6738  * Signature: ()Ljava/awt/Point;
    6739  */
    6740 JNIEXPORT jobject JNICALL
    6741 Java_sun_awt_windows_WComponentPeer_getLocationOnScreen(JNIEnv *env, jobject self)
    6742 {
    6743     TRY;
    6744
    6745     jobject selfGlobalRef = env->NewGlobalRef(self);
    6746
    6747     jobject resultGlobalRef = (jobject)AwtToolkit::GetInstance().SyncCall(
    6748         (void*(*)(void*))AwtComponent::_GetLocationOnScreen, (void *)selfGlobalRef);
    6749     // selfGlobalRef is deleted in _GetLocationOnScreen
    6750     if (resultGlobalRef != NULL)
    6751     {
    6752         jobject resultLocalRef = env->NewLocalRef(resultGlobalRef);
    6753         env->DeleteGlobalRef(resultGlobalRef);
    6754         return resultLocalRef;
    6755     }
    6756
    6757     return NULL;
    6758
    6759     CATCH_BAD_ALLOC_RET(NULL);
    6760 }
    6761
    6762 /*
    6763  * Class:     sun_awt_windows_WComponentPeer
    6764  * Method:    reshape
    6765  * Signature: (IIII)V
    6766  */
    6767 JNIEXPORT void JNICALL
    6768 Java_sun_awt_windows_WComponentPeer_reshape(JNIEnv *env, jobject self,
    6769                                             jint x, jint y, jint w, jint h)
    6770 {
    6771     TRY;
    6772
    6773     ReshapeStruct *rs = new ReshapeStruct;
    6774     rs->component = env->NewGlobalRef(self);
    6775     rs->x = x;
    6776     rs->y = y;
    6777     rs->w = w;
    6778     rs->h = h;
    6779
    6780     AwtToolkit::GetInstance().SyncCall(AwtComponent::_Reshape, rs);
    6781     // global ref and rs are deleted in _Reshape
    6782
    6783     CATCH_BAD_ALLOC;
    6784 }
    6785
    6786 /*
    6787  * Class:     sun_awt_windows_WComponentPeer
    6788  * Method:    reshape
    6789  * Signature: (IIII)V
    6790  */
    6791 JNIEXPORT void JNICALL
    6792 Java_sun_awt_windows_WComponentPeer_reshapeNoCheck(JNIEnv *env, jobject self,
    6793                                             jint x, jint y, jint w, jint h)
    6794 {
    6795     TRY;
    6796
    6797     ReshapeStruct *rs = new ReshapeStruct;
    6798     rs->component = env->NewGlobalRef(self);
    6799     rs->x = x;
    6800     rs->y = y;
    6801     rs->w = w;
    6802     rs->h = h;
    6803
    6804     AwtToolkit::GetInstance().SyncCall(AwtComponent::_ReshapeNoCheck, rs);
    6805     // global ref and rs are deleted in _ReshapeNoCheck
    6806
    6807     CATCH_BAD_ALLOC;
    6808 }
    6809
    6810
    6811 /*
    6812  * Class:     sun_awt_windows_WComponentPeer
    6813  * Method:    nativeHandleEvent
    6814  * Signature: (Ljava/awt/AWTEvent;)V
    6815  */
    6816 JNIEXPORT void JNICALL
    6817 Java_sun_awt_windows_WComponentPeer_nativeHandleEvent(JNIEnv *env,
    6818                                                       jobject self,
    6819                                                       jobject event)
    6820 {
    6821     TRY;
    6822
    6823     jobject selfGlobalRef = env->NewGlobalRef(self);
    6824     jobject eventGlobalRef = env->NewGlobalRef(event);
    6825
    6826     NativeHandleEventStruct *nhes = new NativeHandleEventStruct;
    6827     nhes->component = selfGlobalRef;
    6828     nhes->event = eventGlobalRef;
    6829
    6830     AwtToolkit::GetInstance().SyncCall(AwtComponent::_NativeHandleEvent, nhes);
    6831     // global refs and nhes are deleted in _NativeHandleEvent
    6832
    6833     CATCH_BAD_ALLOC;
    6834 }
    6835
    6836 /*
    6837  * Class:     sun_awt_windows_WComponentPeer
    6838  * Method:    _dispose
    6839  * Signature: ()V
    6840  */
    6841 JNIEXPORT void JNICALL
    6842 Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self)
    6843 {
    6844     TRY_NO_HANG;
    6845
    6846     AwtObject::_Dispose(self);
    6847
    6848     CATCH_BAD_ALLOC;
    6849 }
    6850
    6851 /*
    6852  * Class:     sun_awt_windows_WComponentPeer
    6853  * Method:    _setForeground
    6854  * Signature: (I)V
    6855  */
    6856 JNIEXPORT void JNICALL
    6857 Java_sun_awt_windows_WComponentPeer__1setForeground(JNIEnv *env, jobject self,
    6858                                                     jint rgb)
    6859 {
    6860     TRY;
    6861
    6862     jobject selfGlobalRef = env->NewGlobalRef(self);
    6863
    6864     SetColorStruct *scs = new SetColorStruct;
    6865     scs->component = selfGlobalRef;
    6866     scs->rgb = rgb;
    6867
    6868     AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetForeground, scs);
    6869     // selfGlobalRef and scs are deleted in _SetForeground()
    6870
    6871     CATCH_BAD_ALLOC;
    6872 }
    6873
    6874 /*
    6875  * Class:     sun_awt_windows_WComponentPeer
    6876  * Method:    _setBackground
    6877  * Signature: (I)V
    6878  */
    6879 JNIEXPORT void JNICALL
    6880 Java_sun_awt_windows_WComponentPeer__1setBackground(JNIEnv *env, jobject self,
    6881                                                     jint rgb)
    6882 {
    6883     TRY;
    6884
    6885     jobject selfGlobalRef = env->NewGlobalRef(self);
    6886
    6887     SetColorStruct *scs = new SetColorStruct;
    6888     scs->component = selfGlobalRef;
    6889     scs->rgb = rgb;
    6890
    6891     AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetBackground, scs);
    6892     // selfGlobalRef and scs are deleted in _SetBackground()
    6893
    6894     CATCH_BAD_ALLOC;
    6895 }
    6896
    6897 /*
    6898  * Class:     sun_awt_windows_WComponentPeer
    6899  * Method:    _setFont
    6900  * Signature: (Ljava/awt/Font;)V
    6901  */
    6902 JNIEXPORT void JNICALL
    6903 Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self,
    6904                         jobject font)
    6905 {
    6906     TRY;
    6907
    6908     jobject selfGlobalRef = env->NewGlobalRef(self);
    6909     jobject fontGlobalRef = env->NewGlobalRef(font);
    6910
    6911     SetFontStruct *sfs = new SetFontStruct;
    6912     sfs->component = selfGlobalRef;
    6913     sfs->font = fontGlobalRef;
    6914
    6915     AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetFont, sfs);
    6916     // global refs and sfs are deleted in _SetFont()
    6917
    6918     CATCH_BAD_ALLOC;
    6919 }
    6920
    6921 /*
    6922  * Class:     sun_awt_windows_WComponentPeer
    6923  * Method:    focusGained
    6924  * Signature: (Z)
    6925  */
    6926 JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus
    6927     (JNIEnv *env, jobject self, jboolean doSetFocus)
    6928 {
    6929     TRY;
    6930
    6931     jobject selfGlobalRef = env->NewGlobalRef(self);
    6932
    6933     SetFocusStruct *sfs = new SetFocusStruct;
    6934     sfs->component = selfGlobalRef;
    6935     sfs->doSetFocus = doSetFocus;
    6936
    6937     AwtToolkit::GetInstance().SyncCall(
    6938         (void*(*)(void*))AwtComponent::_SetFocus, sfs);
    6939     // global refs and self are deleted in _SetFocus
    6940
    6941     CATCH_BAD_ALLOC;
    6942 }
    6943
    6944 /*
    6945  * Class:     sun_awt_windows_WComponentPeer
    6946  * Method:    start
    6947  * Signature: ()V
    6948  */
    6949 JNIEXPORT void JNICALL
    6950 Java_sun_awt_windows_WComponentPeer_start(JNIEnv *env, jobject self)
    6951 {
    6952     TRY;
    6953
    6954     jobject selfGlobalRef = env->NewGlobalRef(self);
    6955
    6956     AwtToolkit::GetInstance().SyncCall(AwtComponent::_Start, (void *)selfGlobalRef);
    6957     // selfGlobalRef is deleted in _Start
    6958
    6959     CATCH_BAD_ALLOC;
    6960 }
    6961
    6962 /*
    6963  * Class:     sun_awt_windows_WComponentPeer
    6964  * Method:    beginValidate
    6965  * Signature: ()V
    6966  */
    6967 JNIEXPORT void JNICALL
    6968 Java_sun_awt_windows_WComponentPeer_beginValidate(JNIEnv *env, jobject self)
    6969 {
    6970     TRY;
    6971
    6972     jobject selfGlobalRef = env->NewGlobalRef(self);
    6973
    6974     AwtToolkit::GetInstance().SyncCall(AwtComponent::_BeginValidate, (void *)selfGlobalRef);
    6975     // selfGlobalRef is deleted in _BeginValidate
    6976
    6977     CATCH_BAD_ALLOC;
    6978 }
    6979
    6980 /*
    6981  * Class:     sun_awt_windows_WComponentPeer
    6982  * Method:    endValidate
    6983  * Signature: ()V
    6984  */
    6985 JNIEXPORT void JNICALL
    6986 Java_sun_awt_windows_WComponentPeer_endValidate(JNIEnv *env, jobject self)
    6987 {
    6988     TRY;
    6989
    6990     jobject selfGlobalRef = env->NewGlobalRef(self);
    6991
    6992     AwtToolkit::GetInstance().SyncCall(AwtComponent::_EndValidate, (void *)selfGlobalRef);
    6993     // selfGlobalRef is deleted in _EndValidate
    6994
    6995     CATCH_BAD_ALLOC;
    6996 }
    6997
    6998 JNIEXPORT void JNICALL
    6999 Java_sun_awt_windows_WComponentPeer_updateWindow(JNIEnv *env, jobject self)
    7000 {
    7001     TRY;
    7002
    7003     jobject selfGlobalRef = env->NewGlobalRef(self);
    7004
    7005     AwtToolkit::GetInstance().SyncCall(AwtComponent::_UpdateWindow, (void *)selfGlobalRef);
    7006     // selfGlobalRef is deleted in _UpdateWindow
    7007
    7008     CATCH_BAD_ALLOC;
    7009 }
    7010
    7011 /*
    7012  * Class:     sun_awt_windows_WComponentPeer
    7013  * Method:    addNativeDropTarget
    7014  * Signature: ()L
    7015  */
    7016
    7017 JNIEXPORT jlong JNICALL
    7018 Java_sun_awt_windows_WComponentPeer_addNativeDropTarget(JNIEnv *env,
    7019                                                         jobject self)
    7020 {
    7021     TRY;
    7022
    7023     jobject selfGlobalRef = env->NewGlobalRef(self);
    7024
    7025     return ptr_to_jlong(AwtToolkit::GetInstance().SyncCall(
    7026         (void*(*)(void*))AwtComponent::_AddNativeDropTarget,
    7027         (void *)selfGlobalRef));
    7028     // selfGlobalRef is deleted in _AddNativeDropTarget
    7029
    7030     CATCH_BAD_ALLOC_RET(0);
    7031 }
    7032
    7033 /*
    7034  * Class:     sun_awt_windows_WComponentPeer
    7035  * Method:    removeNativeDropTarget
    7036  * Signature: ()V
    7037  */
    7038
    7039 JNIEXPORT void JNICALL
    7040 Java_sun_awt_windows_WComponentPeer_removeNativeDropTarget(JNIEnv *env,
    7041                                                            jobject self)
    7042 {
    7043     TRY;
    7044
    7045     jobject selfGlobalRef = env->NewGlobalRef(self);
    7046
    7047     AwtToolkit::GetInstance().SyncCall(
    7048         AwtComponent::_RemoveNativeDropTarget, (void *)selfGlobalRef);
    7049     // selfGlobalRef is deleted in _RemoveNativeDropTarget
    7050
    7051     CATCH_BAD_ALLOC;
    7052 }
    7053
    7054 /*
    7055  * Class:     sun_awt_windows_WComponentPeer
    7056  * Method:    getTargetGC
    7057  * Signature: ()Ljava/awt/GraphicsConfiguration;
    7058  */
    7059 JNIEXPORT jobject JNICALL
    7060 Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis)
    7061 {
    7062     TRY;
    7063
    7064     jobject targetObj;
    7065     jobject gc = 0;
    7066
    7067     targetObj = env->GetObjectField(theThis, AwtObject::targetID);
    7068     DASSERT(targetObj);
    7069
    7070     gc = env->GetObjectField(targetObj, AwtComponent::graphicsConfigID);
    7071     return gc;
    7072
    7073     CATCH_BAD_ALLOC_RET(NULL);
    7074 }
    7075
    7076 /*
    7077  * Class:     sun_awt_windows_WComponentPeer
    7078  * Method:    createPrintedPixels
    7079  * Signature: (IIIIII)I[
    7080  */
    7081 JNIEXPORT jintArray JNICALL
    7082 Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env,
    7083     jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha)
    7084 {
    7085     TRY;
    7086
    7087     jobject selfGlobalRef = env->NewGlobalRef(self);
    7088
    7089     CreatePrintedPixelsStruct *cpps = new CreatePrintedPixelsStruct;
    7090     cpps->component = selfGlobalRef;
    7091     cpps->srcx = srcX;
    7092     cpps->srcy = srcY;
    7093     cpps->srcw = srcW;
    7094     cpps->srch = srcH;
    7095     cpps->alpha = alpha;
    7096
    7097     jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall(
    7098         (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps);
    7099     // selfGlobalRef and cpps are deleted in _CreatePrintedPixels
    7100     if (globalRef != NULL)
    7101     {
    7102         jintArray localRef = (jintArray)env->NewLocalRef(globalRef);
    7103         env->DeleteGlobalRef(globalRef);
    7104         return localRef;
    7105     }
    7106     else
    7107     {
    7108         return NULL;
    7109     }
    7110
    7111     CATCH_BAD_ALLOC_RET(NULL);
    7112 }
    7113
    7114 /*
    7115  * Class:     sun_awt_windows_WComponentPeer
    7116  * Method:    nativeHandlesWheelScrolling
    7117  * Signature: ()Z
    7118  */
    7119 JNIEXPORT jboolean JNICALL
    7120 Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env,
    7121     jobject self)
    7122 {
    7123     TRY;
    7124
    7125     return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(
    7126         (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling,
    7127         env->NewGlobalRef(self)));
    7128     // global ref is deleted in _NativeHandlesWheelScrolling
    7129
    7130     CATCH_BAD_ALLOC_RET(NULL);
    7131 }
    7132
    7133 /*
    7134  * Class:     sun_awt_windows_WComponentPeer
    7135  * Method:    isObscured
    7136  * Signature: ()Z
    7137  */
    7138 JNIEXPORT jboolean JNICALL
    7139 Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env,
    7140     jobject self)
    7141 {
    7142     TRY;
    7143
    7144     jobject selfGlobalRef = env->NewGlobalRef(self);
    7145
    7146     return (jboolean)((intptr_t)AwtToolkit::GetInstance().SyncCall(
    7147         (void*(*)(void*))AwtComponent::_IsObscured,
    7148         (void *)selfGlobalRef));
    7149     // selfGlobalRef is deleted in _IsObscured
    7150
    7151     CATCH_BAD_ALLOC_RET(NULL);
    7152 }
    7153
    7154 JNIEXPORT void JNICALL
    7155 Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) {
    7156     TRY;
    7157
    7158     SetParentStruct * data = new SetParentStruct;
    7159     data->component = env->NewGlobalRef(self);
    7160     data->parentComp = env->NewGlobalRef(parent);
    7161
    7162     AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetParent, data);
    7163     // global refs and data are deleted in SetParent
    7164
    7165     CATCH_BAD_ALLOC;
    7166 }
    7167
    7168 JNIEXPORT void JNICALL
    7169 Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject self,
    7170         jint x1, jint y1, jint x2, jint y2, jobject region)
    7171 {
    7172     TRY;
    7173
    7174     SetRectangularShapeStruct * data = new SetRectangularShapeStruct;
    7175     data->component = env->NewGlobalRef(self);
    7176     data->x1 = x1;
    7177     data->x2 = x2;
    7178     data->y1 = y1;
    7179     data->y2 = y2;
    7180     if (region) {
    7181         data->region = env->NewGlobalRef(region);
    7182     } else {
    7183         data->region = NULL;
    7184     }
    7185
    7186     AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetRectangularShape, data);
    7187     // global refs and data are deleted in _SetRectangularShape
    7188
    7189     CATCH_BAD_ALLOC;
    7190 }
    7191
    7192 JNIEXPORT void JNICALL
    7193 Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above)
    7194 {
    7195     TRY;
    7196
    7197     SetZOrderStruct * data = new SetZOrderStruct;
    7198     data->component = env->NewGlobalRef(self);
    7199     data->above = above;
    7200
    7201     AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data);
    7202     // global refs and data are deleted in _SetLower
    7203
    7204     CATCH_BAD_ALLOC;
    7205 }
    7206
    7207 } /* extern "C" */
    7208
    7209
    7210 /************************************************************************
    7211  * Diagnostic routines
    7212  */
    7213
    7214 #ifdef DEBUG
    7215
    7216 void AwtComponent::VerifyState()
    7217 {
    7218     if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) {
    7219         return;
    7220     }
    7221
    7222     if (m_callbacksEnabled == FALSE) {
    7223         /* Component is not fully setup yet. */
    7224         return;
    7225     }
    7226
    7227     /* Get target bounds. */
    7228     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    7229     if (env->PushLocalFrame(10) < 0)
    7230         return;
    7231
    7232     jobject target = GetTarget(env);
    7233
    7234     jint x = env->GetIntField(target, AwtComponent::xID);
    7235     jint y = env->GetIntField(target, AwtComponent::yID);
    7236     jint width = env->GetIntField(target, AwtComponent::widthID);
    7237     jint height = env->GetIntField(target, AwtComponent::heightID);
    7238
    7239     /* Convert target origin to absolute coordinates */
    7240     while (TRUE) {
    7241
    7242         jobject parent = env->GetObjectField(target, AwtComponent::parentID);
    7243         if (parent == NULL) {
    7244             break;
    7245         }
    7246         x += env->GetIntField(parent, AwtComponent::xID);
    7247         y += env->GetIntField(parent, AwtComponent::yID);
    7248
    7249         /* If this component has insets, factor them in, but ignore
    7250          * top-level windows.
    7251          */
    7252         jobject parent2 = env->GetObjectField(parent, AwtComponent::parentID);
    7253         if (parent2 != NULL) {
    7254             jobject peer = GetPeerForTarget(env, parent);
    7255             if (peer != NULL &&
    7256                 JNU_IsInstanceOfByName(env, peer,
    7257                                        "sun/awt/windows/WPanelPeer") > 0) {
    7258                 jobject insets =
    7259                     JNU_CallMethodByName(env, NULL, peer,"insets",
    7260                                          "()Ljava/awt/Insets;").l;
    7261                 x += (env)->GetIntField(insets, AwtInsets::leftID);
    7262                 y += (env)->GetIntField(insets, AwtInsets::topID);
    7263             }
    7264         }
    7265         env->DeleteLocalRef(target);
    7266         target = parent;
    7267     }
    7268
    7269     x = ScaleUpX(x);
    7270     y = ScaleUpY(y);
    7271     width = ScaleUpX(width);
    7272     height = ScaleUpY(height);
    7273
    7274     // Test whether component's bounds match the native window's
    7275     RECT rect;
    7276     VERIFY(::GetWindowRect(GetHWnd(), &rect));
    7277 #if 0
    7278     DASSERT( (x == rect.left) &&
    7279             (y == rect.top) &&
    7280             (width == (rect.right-rect.left)) &&
    7281             (height == (rect.bottom-rect.top)) );
    7282 #else
    7283     BOOL fSizeValid = ( (x == rect.left) &&
    7284             (y == rect.top) &&
    7285             (width == (rect.right-rect.left)) &&
    7286             (height == (rect.bottom-rect.top)) );
    7287 #endif
    7288
    7289     // See if visible state matches
    7290     BOOL wndVisible = ::IsWindowVisible(GetHWnd());
    7291     jboolean targetVisible;
    7292     // To avoid possibly running client code on the toolkit thread, don't
    7293     // do the following check if we're running on the toolkit thread.
    7294     if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) {
    7295         targetVisible = JNU_CallMethodByName(env, NULL, GetTarget(env),
    7296                                                   "isShowing", "()Z").z;
    7297         DASSERT(!safe_ExceptionOccurred(env));
    7298     } else {
    7299         targetVisible = wndVisible ? 1 : 0;
    7300     }
    7301 #if 0
    7302     DASSERT( (targetVisible && wndVisible) ||
    7303             (!targetVisible && !wndVisible) );
    7304 #else
    7305     BOOL fVisibleValid = ( (targetVisible && wndVisible) ||
    7306             (!targetVisible && !wndVisible) );
    7307 #endif
    7308
    7309     // Check enabled state
    7310     BOOL wndEnabled = ::IsWindowEnabled(GetHWnd());
    7311     jboolean enabled = (jboolean)env->GetBooleanField(target,
    7312                                                       AwtComponent::enabledID);
    7313 #if 0
    7314     DASSERT( (enabled && wndEnabled) ||
    7315             (!enabled && !wndEnabled) );
    7316 #else
    7317     BOOL fEnabledValid = ((enabled && wndEnabled) ||
    7318                           (!(enabled && !wndEnabled) ));
    7319
    7320     if (!fSizeValid || !fVisibleValid || !fEnabledValid) {
    7321         printf("AwtComponent::ValidateState() failed:\n");
    7322         // To avoid possibly running client code on the toolkit thread, don't
    7323         // do the following call if we're running on the toolkit thread.
    7324         if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) {
    7325             jstring targetStr =
    7326                 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env),
    7327                                               "getName",
    7328                                               "()Ljava/lang/String;").l;
    7329             DASSERT(!safe_ExceptionOccurred(env));
    7330             LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL);
    7331             printf("\t%S\n", targetStrW);
    7332             JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW);
    7333         }
    7334         printf("\twas:       [%d,%d,%dx%d]\n", x, y, width, height);
    7335         if (!fSizeValid) {
    7336             printf("\tshould be: [%d,%d,%dx%d]\n", rect.left, rect.top,
    7337                    rect.right-rect.left, rect.bottom-rect.top);
    7338         }
    7339         if (!fVisibleValid) {
    7340             printf("\tshould be: %s\n",
    7341                    (targetVisible) ? "visible" : "hidden");
    7342         }
    7343         if (!fEnabledValid) {
    7344             printf("\tshould be: %s\n",
    7345                    enabled ? "enabled" : "disabled");
    7346         }
    7347     }
    7348 #endif
    7349     env->PopLocalFrame(0);
    7350 }
    7351 #endif //DEBUG
    7352
    7353 // Methods for globally managed DC list
    7354
    7355 /**
    7356  * Add a new DC to the DC list for this component.
    7357  */
    7358 void DCList::AddDC(HDC hDC, HWND hWnd)
    7359 {
    7360     DCItem *newItem = new DCItem;
    7361     newItem->hDC = hDC;
    7362     newItem->hWnd = hWnd;
    7363     AddDCItem(newItem);
    7364 }
    7365
    7366 void DCList::AddDCItem(DCItem *newItem)
    7367 {
    7368     listLock.Enter();
    7369     newItem->next = head;
    7370     head = newItem;
    7371     listLock.Leave();
    7372 }
    7373
    7374 /**
    7375  * Given a DC and window handle, remove the DC from the DC list
    7376  * and return TRUE if it exists on the current list.  Otherwise
    7377  * return FALSE.
    7378  * A DC may not exist on the list because it has already
    7379  * been released elsewhere (for example, the window
    7380  * destruction process may release a DC while a rendering
    7381  * thread may also want to release a DC when it notices that
    7382  * its DC is obsolete for the current window).
    7383  */
    7384 DCItem *DCList::RemoveDC(HDC hDC, HWND hWnd)
    7385 {
    7386     listLock.Enter();
    7387     DCItem **prevPtrPtr = &head;
    7388     DCItem *listPtr = head;
    7389     while (listPtr) {
    7390         DCItem *nextPtr = listPtr->next;
    7391         if (listPtr->hDC == hDC && listPtr->hWnd == hWnd) {
    7392             *prevPtrPtr = nextPtr;
    7393             break;
    7394         }
    7395         prevPtrPtr = &listPtr->next;
    7396         listPtr = nextPtr;
    7397     }
    7398     listLock.Leave();
    7399     return listPtr;
    7400 }
    7401
    7402 /**
    7403  * Remove all DCs from the DC list which are associated with
    7404  * the same window as hWnd.  Return the list of those
    7405  * DC's to the caller (which will then probably want to
    7406  * call ReleaseDC() for the returned DCs).
    7407  */
    7408 DCItem *DCList::RemoveAllDCs(HWND hWnd)
    7409 {
    7410     listLock.Enter();
    7411     DCItem **prevPtrPtr = &head;
    7412     DCItem *listPtr = head;
    7413     DCItem *newListPtr = NULL;
    7414     BOOL ret = FALSE;
    7415     while (listPtr) {
    7416         DCItem *nextPtr = listPtr->next;
    7417         if (listPtr->hWnd == hWnd) {
    7418             *prevPtrPtr = nextPtr;
    7419             listPtr->next = newListPtr;
    7420             newListPtr = listPtr;
    7421         } else {
    7422             prevPtrPtr = &listPtr->next;
    7423         }
    7424         listPtr = nextPtr;
    7425     }
    7426     listLock.Leave();
    7427     return newListPtr;
    7428 }
    7429
    7430
    7431 /**
    7432  * Realize palettes of all existing HDC objects
    7433  */
    7434 void DCList::RealizePalettes(int screen)
    7435 {
    7436     listLock.Enter();
    7437     DCItem *listPtr = head;
    7438     while (listPtr) {
    7439         AwtWin32GraphicsDevice::RealizePalette(listPtr->hDC, screen);
    7440         listPtr = listPtr->next;
    7441     }
    7442     listLock.Leave();
    7443 }
    7444
    7445 void MoveDCToPassiveList(HDC hDC, HWND hWnd) {
    7446     DCItem *removedDC;
    7447     if ((removedDC = activeDCList.RemoveDC(hDC, hWnd)) != NULL) {
    7448         passiveDCList.AddDCItem(removedDC);
    7449     }
    7450 }
    7451
    7452 void ReleaseDCList(HWND hwnd, DCList &list) {
    7453     DCItem *removedDCs = list.RemoveAllDCs(hwnd);
    7454     while (removedDCs) {
    7455         DCItem *tmpDCList = removedDCs;
    7456         DASSERT(::GetObjectType(tmpDCList->hDC) == OBJ_DC);
    7457         int retValue = ::ReleaseDC(tmpDCList->hWnd, tmpDCList->hDC);
    7458         VERIFY(retValue != 0);
    7459         if (retValue != 0) {
    7460             // Valid ReleaseDC call; need to decrement GDI object counter
    7461             AwtGDIObject::Decrement();
    7462         }
    7463         removedDCs = removedDCs->next;
    7464         delete tmpDCList;
    7465     }
    7466 }
    --- EOF ---