1 /* 2 * Copyright (c) 1996, 2014, 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_InputMethodEvent.h> 64 #include <sun_awt_windows_WInputMethod.h> 65 #include <java_awt_event_MouseEvent.h> 66 #include <java_awt_event_MouseWheelEvent.h> 67 68 // Begin -- Win32 SDK include files 69 #include <imm.h> 70 #include <ime.h> 71 // End -- Win32 SDK include files 72 73 #include <awt_DnDDT.h> 74 75 LPCTSTR szAwtComponentClassName = TEXT("SunAwtComponent"); 76 // register a message that no other window in the process (even in a plugin 77 // scenario) will be using 78 const UINT AwtComponent::WmAwtIsComponent = 79 ::RegisterWindowMessage(szAwtComponentClassName); 80 81 static HWND g_hwndDown = NULL; 82 static DCList activeDCList; 83 static DCList passiveDCList; 84 85 extern void CheckFontSmoothingSettings(HWND); 86 87 extern "C" { 88 // Remember the input language has changed by some user's action 89 // (Alt+Shift or through the language icon on the Taskbar) to control the 90 // race condition between the toolkit thread and the AWT event thread. 91 // This flag remains TRUE until the next WInputMethod.getNativeLocale() is 92 // issued. 93 BOOL g_bUserHasChangedInputLang = FALSE; 94 } 95 96 BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE; 97 BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE; 98 HWND AwtComponent::sm_focusOwner = NULL; 99 HWND AwtComponent::sm_focusedWindow = NULL; 100 BOOL AwtComponent::sm_bMenuLoop = FALSE; 101 AwtComponent* AwtComponent::sm_getComponentCache = NULL; 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 /************************************************************************/ 155 156 ////////////////////////////////////////////////////////////////////////// 157 158 /************************************************************************* 159 * AwtComponent fields 160 */ 161 162 163 jfieldID AwtComponent::peerID; 164 jfieldID AwtComponent::xID; 165 jfieldID AwtComponent::yID; 166 jfieldID AwtComponent::widthID; 167 jfieldID AwtComponent::heightID; 168 jfieldID AwtComponent::visibleID; 169 jfieldID AwtComponent::backgroundID; 170 jfieldID AwtComponent::foregroundID; 171 jfieldID AwtComponent::enabledID; 172 jfieldID AwtComponent::parentID; 173 jfieldID AwtComponent::graphicsConfigID; 174 jfieldID AwtComponent::peerGCID; 175 jfieldID AwtComponent::focusableID; 176 jfieldID AwtComponent::appContextID; 177 jfieldID AwtComponent::cursorID; 178 jfieldID AwtComponent::hwndID; 179 180 jmethodID AwtComponent::getFontMID; 181 jmethodID AwtComponent::getToolkitMID; 182 jmethodID AwtComponent::isEnabledMID; 183 jmethodID AwtComponent::getLocationOnScreenMID; 184 jmethodID AwtComponent::replaceSurfaceDataMID; 185 jmethodID AwtComponent::replaceSurfaceDataLaterMID; 186 jmethodID AwtComponent::disposeLaterMID; 187 188 HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0); 189 LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0)); 190 UINT AwtComponent::m_CodePage 191 = AwtComponent::LangToCodePage(m_idLang); 192 193 jint *AwtComponent::masks; 194 195 static BOOL bLeftShiftIsDown = false; 196 static BOOL bRightShiftIsDown = false; 197 static UINT lastShiftKeyPressed = 0; // init to safe value 198 199 // Added by waleed to initialize the RTL Flags 200 BOOL AwtComponent::sm_rtl = PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC || 201 PRIMARYLANGID(GetInputLanguage()) == LANG_HEBREW; 202 BOOL AwtComponent::sm_rtlReadingOrder = 203 PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC; 204 205 BOOL AwtComponent::sm_PrimaryDynamicTableBuilt = FALSE; 206 207 HWND AwtComponent::sm_cursorOn; 208 BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE; 209 210 CriticalSection windowMoveLock; 211 BOOL windowMoveLockHeld = FALSE; 212 213 /************************************************************************ 214 * AwtComponent methods 215 */ 216 217 AwtComponent::AwtComponent() 218 { 219 m_mouseButtonClickAllowed = 0; 220 m_callbacksEnabled = FALSE; 221 m_hwnd = NULL; 222 223 m_colorForeground = 0; 224 m_colorBackground = 0; 225 m_backgroundColorSet = FALSE; 226 m_penForeground = NULL; 227 m_brushBackground = NULL; 228 m_DefWindowProc = NULL; 229 m_nextControlID = 1; 230 m_childList = NULL; 231 m_myControlID = 0; 232 m_hdwp = NULL; 233 m_validationNestCount = 0; 234 235 m_dropTarget = NULL; 236 237 m_InputMethod = NULL; 238 m_useNativeCompWindow = TRUE; 239 m_PendingLeadByte = 0; 240 m_bitsCandType = 0; 241 242 windowMoveLockPosX = 0; 243 windowMoveLockPosY = 0; 244 windowMoveLockPosCX = 0; 245 windowMoveLockPosCY = 0; 246 247 m_hCursorCache = NULL; 248 249 m_bSubclassed = FALSE; 250 m_bPauseDestroy = FALSE; 251 252 m_MessagesProcessing = 0; 253 m_wheelRotationAmount = 0; 254 if (!sm_PrimaryDynamicTableBuilt) { 255 // do it once. 256 AwtComponent::BuildPrimaryDynamicTable(); 257 sm_PrimaryDynamicTableBuilt = TRUE; 258 } 259 } 260 261 AwtComponent::~AwtComponent() 262 { 263 DASSERT(AwtToolkit::IsMainThread()); 264 265 /* Disconnect all links. */ 266 UnlinkObjects(); 267 268 /* 269 * All the messages for this component are processed, native 270 * resources are freed, and Java object is not connected to 271 * the native one anymore. So we can safely destroy component's 272 * handle. 273 */ 274 DestroyHWnd(); 275 276 if (sm_getComponentCache == this) { 277 sm_getComponentCache = NULL; 278 } 279 } 280 281 void AwtComponent::Dispose() 282 { 283 // NOTE: in case the component/toplevel was focused, Java should 284 // have already taken care of proper transferring it or clearing. 285 286 if (m_hdwp != NULL) { 287 // end any deferred window positioning, regardless 288 // of m_validationNestCount 289 ::EndDeferWindowPos(m_hdwp); 290 } 291 292 // Send final message to release all DCs associated with this component 293 SendMessage(WM_AWT_RELEASE_ALL_DCS); 294 295 /* Stop message filtering. */ 296 UnsubclassHWND(); 297 298 /* Release global ref to input method */ 299 SetInputMethod(NULL, TRUE); 300 301 if (m_childList != NULL) 302 delete m_childList; 303 304 DestroyDropTarget(); 305 ReleaseDragCapture(0); 306 307 if (m_myControlID != 0) { 308 AwtComponent* parent = GetParent(); 309 if (parent != NULL) 310 parent->RemoveChild(m_myControlID); 311 } 312 313 ::RemoveProp(GetHWnd(), DrawingStateProp); 314 315 /* Release any allocated resources. */ 316 if (m_penForeground != NULL) { 317 m_penForeground->Release(); 318 m_penForeground = NULL; 319 } 320 if (m_brushBackground != NULL) { 321 m_brushBackground->Release(); 322 m_brushBackground = NULL; 323 } 324 325 if (m_bPauseDestroy) { 326 // AwtComponent::WmNcDestroy could be released now 327 m_bPauseDestroy = FALSE; 328 m_hwnd = NULL; 329 } 330 331 // The component instance is deleted using AwtObject::Dispose() method 332 AwtObject::Dispose(); 333 } 334 335 /* store component pointer in window extra bytes */ 336 void AwtComponent::SetComponentInHWND() { 337 DASSERT(::GetWindowLongPtr(GetHWnd(), GWLP_USERDATA) == NULL); 338 ::SetWindowLongPtr(GetHWnd(), GWLP_USERDATA, (LONG_PTR)this); 339 } 340 341 /* 342 * static function to get AwtComponent pointer from hWnd -- 343 * you don't want to call this from inside a wndproc to avoid 344 * infinite recursion 345 */ 346 AwtComponent* AwtComponent::GetComponent(HWND hWnd) { 347 // Requests for Toolkit hwnd resolution happen pretty often. Check first. 348 if (hWnd == AwtToolkit::GetInstance().GetHWnd()) { 349 return NULL; 350 } 351 if (sm_getComponentCache && sm_getComponentCache->GetHWnd() == hWnd) { 352 return sm_getComponentCache; 353 } 354 355 // check that it's an AWT component from the same toolkit as the caller 356 if (::IsWindow(hWnd) && 357 AwtToolkit::MainThread() == ::GetWindowThreadProcessId(hWnd, NULL)) 358 { 359 DASSERT(WmAwtIsComponent != 0); 360 if (::SendMessage(hWnd, WmAwtIsComponent, 0, 0L)) { 361 return sm_getComponentCache = GetComponentImpl(hWnd); 362 } 363 } 364 return NULL; 365 } 366 367 /* 368 * static function to get AwtComponent pointer from hWnd-- 369 * different from GetComponent because caller knows the 370 * hwnd is an AWT component hwnd 371 */ 372 AwtComponent* AwtComponent::GetComponentImpl(HWND hWnd) { 373 AwtComponent *component = 374 (AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA); 375 DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) ); 376 DASSERT(!component || component->GetHWnd() == hWnd ); 377 return component; 378 } 379 380 /* 381 * Single window proc for all the components. Delegates real work to 382 * the component's WindowProc() member function. 383 */ 384 LRESULT CALLBACK AwtComponent::WndProc(HWND hWnd, UINT message, 385 WPARAM wParam, LPARAM lParam) 386 { 387 TRY; 388 389 AwtComponent * self = AwtComponent::GetComponentImpl(hWnd); 390 if (self == NULL || self->GetHWnd() != hWnd || 391 message == WM_UNDOCUMENTED_CLIENTSHUTDOWN) // handle log-off gracefully 392 { 393 return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam); 394 } else { 395 return self->WindowProc(message, wParam, lParam); 396 } 397 398 CATCH_BAD_ALLOC_RET(0); 399 } 400 401 BOOL AwtComponent::IsFocusable() { 402 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 403 jobject peer = GetPeer(env); 404 jobject target = env->GetObjectField(peer, AwtObject::targetID); 405 BOOL res = env->GetBooleanField(target, focusableID); 406 AwtWindow *pCont = GetContainer(); 407 if (pCont) { 408 res &= pCont->IsFocusableWindow(); 409 } 410 env->DeleteLocalRef(target); 411 return res; 412 } 413 414 /************************************************************************ 415 * AwtComponent dynamic methods 416 * 417 * Window class registration routines 418 */ 419 420 /* 421 * Fix for 4964237: Win XP: Changing theme changes java dialogs title icon 422 */ 423 void AwtComponent::FillClassInfo(WNDCLASSEX *lpwc) 424 { 425 lpwc->cbSize = sizeof(WNDCLASSEX); 426 lpwc->style = 0L;//CS_OWNDC; 427 lpwc->lpfnWndProc = (WNDPROC)::DefWindowProc; 428 lpwc->cbClsExtra = 0; 429 lpwc->cbWndExtra = 0; 430 lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(), 431 lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon(); 432 lpwc->hCursor = NULL; 433 lpwc->hbrBackground = NULL; 434 lpwc->lpszMenuName = NULL; 435 lpwc->lpszClassName = GetClassName(); 436 //Fixed 6233560: PIT: Java Cup Logo on the title bar of top-level windows look blurred, Win32 437 lpwc->hIconSm = AwtToolkit::GetInstance().GetAwtIconSm(); 438 } 439 440 void AwtComponent::RegisterClass() 441 { 442 WNDCLASSEX wc; 443 if (!::GetClassInfoEx(AwtToolkit::GetInstance().GetModuleHandle(), GetClassName(), &wc)) { 444 FillClassInfo(&wc); 445 ATOM ret = ::RegisterClassEx(&wc); 446 DASSERT(ret != 0); 447 } 448 } 449 450 void AwtComponent::UnregisterClass() 451 { 452 ::UnregisterClass(GetClassName(), AwtToolkit::GetInstance().GetModuleHandle()); 453 } 454 455 /* 456 * Copy the graphicsConfig reference from Component into WComponentPeer 457 */ 458 void AwtComponent::InitPeerGraphicsConfig(JNIEnv *env, jobject peer) 459 { 460 jobject target = env->GetObjectField(peer, AwtObject::targetID); 461 //Get graphicsConfig object ref from Component 462 jobject compGC = env->GetObjectField(target, 463 AwtComponent::graphicsConfigID); 464 465 //Set peer's graphicsConfig to Component's graphicsConfig 466 if (compGC != NULL) { 467 jclass win32GCCls = env->FindClass("sun/awt/Win32GraphicsConfig"); 468 DASSERT(win32GCCls != NULL); 469 DASSERT(env->IsInstanceOf(compGC, win32GCCls)); 470 CHECK_NULL(win32GCCls); 471 env->SetObjectField(peer, AwtComponent::peerGCID, compGC); 472 } 473 } 474 475 void 476 AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title, 477 DWORD windowStyle, 478 DWORD windowExStyle, 479 int x, int y, int w, int h, 480 HWND hWndParent, HMENU hMenu, 481 COLORREF colorForeground, 482 COLORREF colorBackground, 483 jobject peer) 484 { 485 if (env->EnsureLocalCapacity(2) < 0) { 486 return; 487 } 488 489 /* 490 * The window class of multifont label must be "BUTTON" because 491 * "STATIC" class can't get WM_DRAWITEM message, and m_peerObject 492 * member is referred in the GetClassName method of AwtLabel class. 493 * So m_peerObject member must be set here. 494 */ 495 if (m_peerObject == NULL) { 496 m_peerObject = env->NewGlobalRef(peer); 497 } 498 499 DASSERT (env->IsSameObject(m_peerObject, peer)); 500 501 RegisterClass(); 502 503 jobject target = env->GetObjectField(peer, AwtObject::targetID); 504 jboolean visible = env->GetBooleanField(target, AwtComponent::visibleID); 505 m_visible = visible; 506 507 if (visible) { 508 windowStyle |= WS_VISIBLE; 509 } else { 510 windowStyle &= ~WS_VISIBLE; 511 } 512 513 InitPeerGraphicsConfig(env, peer); 514 515 SetLastError(0); 516 HWND hwnd = ::CreateWindowEx(windowExStyle, 517 GetClassName(), 518 title, 519 windowStyle, 520 x, y, w, h, 521 hWndParent, 522 hMenu, 523 AwtToolkit::GetInstance().GetModuleHandle(), 524 NULL); 525 526 // fix for 5088782 527 // check if CreateWindowsEx() returns not null value and if it does - 528 // create an InternalError or OutOfMemoryError based on GetLastError(). 529 // This error is set to createError field of WObjectPeer and then 530 // checked and thrown in WComponentPeer constructor. We can't throw an 531 // error here because this code is invoked on Toolkit thread 532 if (hwnd == NULL) 533 { 534 DWORD dw = ::GetLastError(); 535 jobject createError = NULL; 536 if (dw == ERROR_OUTOFMEMORY) 537 { 538 jstring errorMsg = JNU_NewStringPlatform(env, L"too many window handles"); 539 if (errorMsg == NULL || env->ExceptionCheck()) { 540 env->ExceptionClear(); 541 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", "()V"); 542 } else { 543 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", 544 "(Ljava/lang/String;)V", 545 errorMsg); 546 env->DeleteLocalRef(errorMsg); 547 } 548 } 549 else 550 { 551 TCHAR *buf; 552 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 553 NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 554 (LPTSTR)&buf, 0, NULL); 555 jstring s = JNU_NewStringPlatform(env, buf); 556 if (s == NULL || env->ExceptionCheck()) { 557 env->ExceptionClear(); 558 createError = JNU_NewObjectByName(env, "java/lang/InternalError", "()V"); 559 } else { 560 createError = JNU_NewObjectByName(env, "java/lang/InternalError", 561 "(Ljava/lang/String;)V", s); 562 env->DeleteLocalRef(s); 563 } 564 LocalFree(buf); 565 } 566 if (createError != NULL) { 567 env->SetObjectField(peer, AwtObject::createErrorID, createError); 568 env->DeleteLocalRef(createError); 569 } 570 env->DeleteLocalRef(target); 571 return; 572 } 573 574 m_hwnd = hwnd; 575 576 ::ImmAssociateContext(m_hwnd, NULL); 577 578 SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | 579 (jint)JAWT_LOCK_BOUNDS_CHANGED | 580 (jint)JAWT_LOCK_CLIP_CHANGED); 581 582 LinkObjects(env, peer); 583 584 /* Subclass the window now so that we can snoop on its messages */ 585 SubclassHWND(); 586 587 /* 588 * Fix for 4046446. 589 */ 590 SetWindowPos(GetHWnd(), 0, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE); 591 592 /* Set default colors. */ 593 m_colorForeground = colorForeground; 594 m_colorBackground = colorBackground; 595 596 /* 597 * Only set background color if the color is actually set on the 598 * target -- this avoids inheriting a parent's color unnecessarily, 599 * and has to be done here because there isn't an API to get the 600 * real background color from outside the AWT package. 601 */ 602 jobject bkgrd = env->GetObjectField(target, AwtComponent::backgroundID) ; 603 if (bkgrd != NULL) { 604 JNU_CallMethodByName(env, NULL, peer, "setBackground", 605 "(Ljava/awt/Color;)V", bkgrd); 606 DASSERT(!safe_ExceptionOccurred(env)); 607 } 608 env->DeleteLocalRef(target); 609 env->DeleteLocalRef(bkgrd); 610 } 611 612 /* 613 * Destroy this window's HWND 614 */ 615 void AwtComponent::DestroyHWnd() { 616 if (m_hwnd != NULL) { 617 AwtToolkit::DestroyComponentHWND(m_hwnd); 618 //AwtToolkit::DestroyComponent(this); 619 m_hwnd = NULL; 620 } 621 } 622 623 /* 624 * Returns hwnd for target on non Toolkit thread 625 */ 626 HWND 627 AwtComponent::GetHWnd(JNIEnv* env, jobject target) { 628 if (JNU_IsNull(env, target)) { 629 return 0; 630 } 631 jobject peer = env->GetObjectField(target, AwtComponent::peerID); 632 if (JNU_IsNull(env, peer)) { 633 return 0; 634 } 635 HWND hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR> ( 636 env->GetLongField(peer, AwtComponent::hwndID))); 637 env->DeleteLocalRef(peer); 638 return hwnd; 639 } 640 // 641 // Propagate the background color to synchronize Java field and peer's field. 642 // This is needed to fix 4148334 643 // 644 void AwtComponent::UpdateBackground(JNIEnv *env, jobject target) 645 { 646 if (env->EnsureLocalCapacity(1) < 0) { 647 return; 648 } 649 650 jobject bkgrnd = env->GetObjectField(target, AwtComponent::backgroundID); 651 652 if (bkgrnd == NULL) { 653 bkgrnd = JNU_NewObjectByName(env, "java/awt/Color", "(III)V", 654 GetRValue(m_colorBackground), 655 GetGValue(m_colorBackground), 656 GetBValue(m_colorBackground)); 657 if (bkgrnd != NULL) { 658 env->SetObjectField(target, AwtComponent::backgroundID, bkgrnd); 659 } 660 } 661 env->DeleteLocalRef(bkgrnd); 662 } 663 664 /* 665 * Install our window proc as the proc for our HWND, and save off the 666 * previous proc as the default 667 */ 668 void AwtComponent::SubclassHWND() 669 { 670 if (m_bSubclassed) { 671 return; 672 } 673 const WNDPROC wndproc = WndProc; // let compiler type check WndProc 674 m_DefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc); 675 m_bSubclassed = TRUE; 676 } 677 678 /* 679 * Reinstall the original window proc as the proc for our HWND 680 */ 681 void AwtComponent::UnsubclassHWND() 682 { 683 if (!m_bSubclassed) { 684 return; 685 } 686 ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc, m_DefWindowProc); 687 m_bSubclassed = FALSE; 688 } 689 690 ///////////////////////////////////// 691 // (static method) 692 // Determines the top-level ancestor for a given window. If the given 693 // window is a top-level window, return itself. 694 // 695 // 'Top-level' includes dialogs as well. 696 // 697 HWND AwtComponent::GetTopLevelParentForWindow(HWND hwndDescendant) { 698 if (hwndDescendant == NULL) { 699 return NULL; 700 } 701 702 DASSERT(IsWindow(hwndDescendant)); 703 HWND hwnd = hwndDescendant; 704 for(;;) { 705 DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); 706 // a) found a non-child window so terminate 707 // b) found real toplevel window (e.g. EmbeddedFrame 708 // that is child though) 709 if ( (style & WS_CHILD) == 0 || 710 AwtComponent::IsTopLevelHWnd(hwnd) ) 711 { 712 break; 713 } 714 hwnd = ::GetParent(hwnd); 715 } 716 717 return hwnd; 718 } 719 //////////////////// 720 721 jobject AwtComponent::FindHeavyweightUnderCursor(BOOL useCache) { 722 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 723 if (env->EnsureLocalCapacity(1) < 0) { 724 return NULL; 725 } 726 727 HWND hit = NULL; 728 POINT p = { 0, 0 }; 729 AwtComponent *comp = NULL; 730 731 if (useCache) { 732 if (sm_cursorOn == NULL) { 733 return NULL; 734 } 735 736 737 DASSERT(::IsWindow(sm_cursorOn)); 738 VERIFY(::GetCursorPos(&p)); 739 /* 740 * Fix for BugTraq ID 4304024. 741 * Allow a non-default cursor only for the client area. 742 */ 743 comp = AwtComponent::GetComponent(sm_cursorOn); 744 if (comp != NULL && 745 ::SendMessage(sm_cursorOn, WM_NCHITTEST, 0, 746 MAKELPARAM(p.x, p.y)) == HTCLIENT) { 747 goto found; 748 } 749 } 750 751 ::GetCursorPos(&p); 752 hit = ::WindowFromPoint(p); 753 while (hit != NULL) { 754 comp = AwtComponent::GetComponent(hit); 755 756 if (comp != NULL) { 757 INT nHittest = (INT)::SendMessage(hit, WM_NCHITTEST, 758 0, MAKELPARAM(p.x, p.y)); 759 /* 760 * Fix for BugTraq ID 4304024. 761 * Allow a non-default cursor only for the client area. 762 */ 763 if (nHittest != HTCLIENT) { 764 /* 765 * When over the non-client area, send WM_SETCURSOR 766 * to revert the cursor to an arrow. 767 */ 768 ::SendMessage(hit, WM_SETCURSOR, (WPARAM)hit, 769 MAKELPARAM(nHittest, WM_MOUSEMOVE)); 770 return NULL; 771 } else { 772 sm_cursorOn = hit; 773 goto found; 774 } 775 } 776 777 if ((::GetWindowLong(hit, GWL_STYLE) & WS_CHILD) == 0) { 778 return NULL; 779 } 780 hit = ::GetParent(hit); 781 } 782 783 return NULL; 784 785 found: 786 jobject localRef = comp->GetTarget(env); 787 jobject globalRef = env->NewGlobalRef(localRef); 788 env->DeleteLocalRef(localRef); 789 return globalRef; 790 } 791 792 void AwtComponent::SetColor(COLORREF c) 793 { 794 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 795 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 796 if (grayscale != GS_NOTGRAY) { 797 int g; 798 799 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 800 .114 * ((c >> 16) & 0xFF) + 0.5); 801 // c = g | (g << 8) | (g << 16); 802 c = PALETTERGB(g, g, g); 803 } 804 805 if (m_colorForeground == c) { 806 return; 807 } 808 809 m_colorForeground = c; 810 if (m_penForeground != NULL) { 811 m_penForeground->Release(); 812 m_penForeground = NULL; 813 } 814 VERIFY(::InvalidateRect(GetHWnd(), NULL, FALSE)); 815 } 816 817 void AwtComponent::SetBackgroundColor(COLORREF c) 818 { 819 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 820 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 821 if (grayscale != GS_NOTGRAY) { 822 int g; 823 824 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 825 .114 * ((c >> 16) & 0xFF) + 0.5); 826 // c = g | (g << 8) | (g << 16); 827 c = PALETTERGB(g, g, g); 828 } 829 830 if (m_colorBackground == c) { 831 return; 832 } 833 m_colorBackground = c; 834 m_backgroundColorSet = TRUE; 835 if (m_brushBackground != NULL) { 836 m_brushBackground->Release(); 837 m_brushBackground = NULL; 838 } 839 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 840 } 841 842 HPEN AwtComponent::GetForegroundPen() 843 { 844 if (m_penForeground == NULL) { 845 m_penForeground = AwtPen::Get(m_colorForeground); 846 } 847 return (HPEN)m_penForeground->GetHandle(); 848 } 849 850 COLORREF AwtComponent::GetBackgroundColor() 851 { 852 if (m_backgroundColorSet == FALSE) { 853 AwtComponent* c = this; 854 while ((c = c->GetParent()) != NULL) { 855 if (c->IsBackgroundColorSet()) { 856 return c->GetBackgroundColor(); 857 } 858 } 859 } 860 return m_colorBackground; 861 } 862 863 HBRUSH AwtComponent::GetBackgroundBrush() 864 { 865 if (m_backgroundColorSet == FALSE) { 866 if (m_brushBackground != NULL) { 867 m_brushBackground->Release(); 868 m_brushBackground = NULL; 869 } 870 AwtComponent* c = this; 871 while ((c = c->GetParent()) != NULL) { 872 if (c->IsBackgroundColorSet()) { 873 m_brushBackground = 874 AwtBrush::Get(c->GetBackgroundColor()); 875 break; 876 } 877 } 878 } 879 if (m_brushBackground == NULL) { 880 m_brushBackground = AwtBrush::Get(m_colorBackground); 881 } 882 return (HBRUSH)m_brushBackground->GetHandle(); 883 } 884 885 void AwtComponent::SetFont(AwtFont* font) 886 { 887 DASSERT(font != NULL); 888 if (font->GetAscent() < 0) { 889 AwtFont::SetupAscent(font); 890 } 891 SendMessage(WM_SETFONT, (WPARAM)font->GetHFont(), MAKELPARAM(FALSE, 0)); 892 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 893 } 894 895 AwtComponent* AwtComponent::GetParent() 896 { 897 HWND hwnd = ::GetParent(GetHWnd()); 898 if (hwnd == NULL) { 899 return NULL; 900 } 901 return GetComponent(hwnd); 902 } 903 904 AwtWindow* AwtComponent::GetContainer() 905 { 906 AwtComponent* comp = this; 907 while (comp != NULL) { 908 if (comp->IsContainer()) { 909 return (AwtWindow*)comp; 910 } 911 comp = comp->GetParent(); 912 } 913 return NULL; 914 } 915 916 void AwtComponent::Show() 917 { 918 m_visible = true; 919 ::ShowWindow(GetHWnd(), SW_SHOWNA); 920 } 921 922 void AwtComponent::Hide() 923 { 924 m_visible = false; 925 ::ShowWindow(GetHWnd(), SW_HIDE); 926 } 927 928 BOOL 929 AwtComponent::SetWindowPos(HWND wnd, HWND after, 930 int x, int y, int w, int h, UINT flags) 931 { 932 // Conditions we shouldn't handle: 933 // z-order changes, correct window dimensions 934 if (after != NULL || (w < 32767 && h < 32767) 935 || ((::GetWindowLong(wnd, GWL_STYLE) & WS_CHILD) == 0)) 936 { 937 return ::SetWindowPos(wnd, after, x, y, w, h, flags); 938 } 939 WINDOWPLACEMENT wp; 940 ::ZeroMemory(&wp, sizeof(wp)); 941 942 wp.length = sizeof(wp); 943 ::GetWindowPlacement(wnd, &wp); 944 wp.rcNormalPosition.left = x; 945 wp.rcNormalPosition.top = y; 946 wp.rcNormalPosition.right = x + w; 947 wp.rcNormalPosition.bottom = y + h; 948 if ( flags & SWP_NOACTIVATE ) { 949 wp.showCmd = SW_SHOWNOACTIVATE; 950 } 951 ::SetWindowPlacement(wnd, &wp); 952 return 1; 953 } 954 955 956 void AwtComponent::Reshape(int x, int y, int w, int h) 957 { 958 #if defined(DEBUG) 959 RECT rc; 960 ::GetWindowRect(GetHWnd(), &rc); 961 ::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2); 962 DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top); 963 #endif 964 AwtWindow* container = GetContainer(); 965 AwtComponent* parent = GetParent(); 966 if (container != NULL && container == parent) { 967 container->SubtractInsetPoint(x, y); 968 } 969 DTRACE_PRINTLN4("AwtComponent::Reshape to %d, %d, %d, %d", x, y, w, h); 970 UINT flags = SWP_NOACTIVATE | SWP_NOZORDER; 971 972 RECT r; 973 974 ::GetWindowRect(GetHWnd(), &r); 975 // if the component size is changing , don't copy window bits 976 if (r.right - r.left != w || r.bottom - r.top != h) { 977 flags |= SWP_NOCOPYBITS; 978 } 979 980 if (parent && _tcscmp(parent->GetClassName(), TEXT("SunAwtScrollPane")) == 0) { 981 if (x > 0) { 982 x = 0; 983 } 984 if (y > 0) { 985 y = 0; 986 } 987 } 988 if (m_hdwp != NULL) { 989 m_hdwp = ::DeferWindowPos(m_hdwp, GetHWnd(), 0, x, y, w, h, flags); 990 DASSERT(m_hdwp != NULL); 991 } else { 992 /* 993 * Fox for 4046446 994 * If window has dimensions above the short int limit, ::SetWindowPos doesn't work. 995 * We should use SetWindowPlacement instead. 996 */ 997 SetWindowPos(GetHWnd(), 0, x, y, w, h, flags); 998 } 999 } 1000 1001 void AwtComponent::SetScrollValues(UINT bar, int min, int value, int max) 1002 { 1003 int minTmp, maxTmp; 1004 1005 ::GetScrollRange(GetHWnd(), bar, &minTmp, &maxTmp); 1006 if (min == INT_MAX) { 1007 min = minTmp; 1008 } 1009 if (value == INT_MAX) { 1010 value = ::GetScrollPos(GetHWnd(), bar); 1011 } 1012 if (max == INT_MAX) { 1013 max = maxTmp; 1014 } 1015 if (min == max) { 1016 max++; 1017 } 1018 ::SetScrollRange(GetHWnd(), bar, min, max, FALSE); 1019 ::SetScrollPos(GetHWnd(), bar, value, TRUE); 1020 } 1021 1022 /* 1023 * Save Global Reference of sun.awt.windows.WInputMethod object 1024 */ 1025 void AwtComponent::SetInputMethod(jobject im, BOOL useNativeCompWindow) 1026 { 1027 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1028 1029 if (m_InputMethod!=NULL) 1030 env->DeleteGlobalRef(m_InputMethod); 1031 1032 if (im!=NULL){ 1033 m_InputMethod = env->NewGlobalRef(im); 1034 m_useNativeCompWindow = useNativeCompWindow; 1035 } else { 1036 m_InputMethod = NULL; 1037 m_useNativeCompWindow = TRUE; 1038 } 1039 1040 } 1041 1042 /* 1043 * Opportunity to process and/or eat a message before it is dispatched 1044 */ 1045 MsgRouting AwtComponent::PreProcessMsg(MSG& msg) 1046 { 1047 return mrPassAlong; 1048 } 1049 1050 static UINT lastMessage = WM_NULL; 1051 1052 #ifndef SPY_MESSAGES 1053 #define SpyWinMessage(hwin,msg,str) 1054 #else 1055 1056 #define FMT_MSG(x,y) case x: _stprintf(szBuf, \ 1057 "0x%8.8x(%s):%s\n", hwnd, szComment, y); break; 1058 #define WIN_MSG(x) FMT_MSG(x,#x) 1059 1060 void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { 1061 1062 TCHAR szBuf[256]; 1063 1064 switch (message) { 1065 WIN_MSG(WM_NULL) 1066 WIN_MSG(WM_CREATE) 1067 WIN_MSG(WM_DESTROY) 1068 WIN_MSG(WM_MOVE) 1069 WIN_MSG(WM_SIZE) 1070 WIN_MSG(WM_ACTIVATE) 1071 WIN_MSG(WM_SETFOCUS) 1072 WIN_MSG(WM_KILLFOCUS) 1073 WIN_MSG(WM_ENABLE) 1074 WIN_MSG(WM_SETREDRAW) 1075 WIN_MSG(WM_SETTEXT) 1076 WIN_MSG(WM_GETTEXT) 1077 WIN_MSG(WM_GETTEXTLENGTH) 1078 WIN_MSG(WM_PAINT) 1079 WIN_MSG(WM_CLOSE) 1080 WIN_MSG(WM_QUERYENDSESSION) 1081 WIN_MSG(WM_QUIT) 1082 WIN_MSG(WM_QUERYOPEN) 1083 WIN_MSG(WM_ERASEBKGND) 1084 WIN_MSG(WM_SYSCOLORCHANGE) 1085 WIN_MSG(WM_ENDSESSION) 1086 WIN_MSG(WM_SHOWWINDOW) 1087 FMT_MSG(WM_WININICHANGE,"WM_WININICHANGE/WM_SETTINGCHANGE") 1088 WIN_MSG(WM_DEVMODECHANGE) 1089 WIN_MSG(WM_ACTIVATEAPP) 1090 WIN_MSG(WM_FONTCHANGE) 1091 WIN_MSG(WM_TIMECHANGE) 1092 WIN_MSG(WM_CANCELMODE) 1093 WIN_MSG(WM_SETCURSOR) 1094 WIN_MSG(WM_MOUSEACTIVATE) 1095 WIN_MSG(WM_CHILDACTIVATE) 1096 WIN_MSG(WM_QUEUESYNC) 1097 WIN_MSG(WM_GETMINMAXINFO) 1098 WIN_MSG(WM_PAINTICON) 1099 WIN_MSG(WM_ICONERASEBKGND) 1100 WIN_MSG(WM_NEXTDLGCTL) 1101 WIN_MSG(WM_SPOOLERSTATUS) 1102 WIN_MSG(WM_DRAWITEM) 1103 WIN_MSG(WM_MEASUREITEM) 1104 WIN_MSG(WM_DELETEITEM) 1105 WIN_MSG(WM_VKEYTOITEM) 1106 WIN_MSG(WM_CHARTOITEM) 1107 WIN_MSG(WM_SETFONT) 1108 WIN_MSG(WM_GETFONT) 1109 WIN_MSG(WM_SETHOTKEY) 1110 WIN_MSG(WM_GETHOTKEY) 1111 WIN_MSG(WM_QUERYDRAGICON) 1112 WIN_MSG(WM_COMPAREITEM) 1113 FMT_MSG(0x003D, "WM_GETOBJECT") 1114 WIN_MSG(WM_COMPACTING) 1115 WIN_MSG(WM_COMMNOTIFY) 1116 WIN_MSG(WM_WINDOWPOSCHANGING) 1117 WIN_MSG(WM_WINDOWPOSCHANGED) 1118 WIN_MSG(WM_POWER) 1119 WIN_MSG(WM_COPYDATA) 1120 WIN_MSG(WM_CANCELJOURNAL) 1121 WIN_MSG(WM_NOTIFY) 1122 WIN_MSG(WM_INPUTLANGCHANGEREQUEST) 1123 WIN_MSG(WM_INPUTLANGCHANGE) 1124 WIN_MSG(WM_TCARD) 1125 WIN_MSG(WM_HELP) 1126 WIN_MSG(WM_USERCHANGED) 1127 WIN_MSG(WM_NOTIFYFORMAT) 1128 WIN_MSG(WM_CONTEXTMENU) 1129 WIN_MSG(WM_STYLECHANGING) 1130 WIN_MSG(WM_STYLECHANGED) 1131 WIN_MSG(WM_DISPLAYCHANGE) 1132 WIN_MSG(WM_GETICON) 1133 WIN_MSG(WM_SETICON) 1134 WIN_MSG(WM_NCCREATE) 1135 WIN_MSG(WM_NCDESTROY) 1136 WIN_MSG(WM_NCCALCSIZE) 1137 WIN_MSG(WM_NCHITTEST) 1138 WIN_MSG(WM_NCPAINT) 1139 WIN_MSG(WM_NCACTIVATE) 1140 WIN_MSG(WM_GETDLGCODE) 1141 WIN_MSG(WM_SYNCPAINT) 1142 WIN_MSG(WM_NCMOUSEMOVE) 1143 WIN_MSG(WM_NCLBUTTONDOWN) 1144 WIN_MSG(WM_NCLBUTTONUP) 1145 WIN_MSG(WM_NCLBUTTONDBLCLK) 1146 WIN_MSG(WM_NCRBUTTONDOWN) 1147 WIN_MSG(WM_NCRBUTTONUP) 1148 WIN_MSG(WM_NCRBUTTONDBLCLK) 1149 WIN_MSG(WM_NCMBUTTONDOWN) 1150 WIN_MSG(WM_NCMBUTTONUP) 1151 WIN_MSG(WM_NCMBUTTONDBLCLK) 1152 WIN_MSG(WM_KEYDOWN) 1153 WIN_MSG(WM_KEYUP) 1154 WIN_MSG(WM_CHAR) 1155 WIN_MSG(WM_DEADCHAR) 1156 WIN_MSG(WM_SYSKEYDOWN) 1157 WIN_MSG(WM_SYSKEYUP) 1158 WIN_MSG(WM_SYSCHAR) 1159 WIN_MSG(WM_SYSDEADCHAR) 1160 WIN_MSG(WM_IME_STARTCOMPOSITION) 1161 WIN_MSG(WM_IME_ENDCOMPOSITION) 1162 WIN_MSG(WM_IME_COMPOSITION) 1163 WIN_MSG(WM_INITDIALOG) 1164 WIN_MSG(WM_COMMAND) 1165 WIN_MSG(WM_SYSCOMMAND) 1166 WIN_MSG(WM_TIMER) 1167 WIN_MSG(WM_HSCROLL) 1168 WIN_MSG(WM_VSCROLL) 1169 WIN_MSG(WM_INITMENU) 1170 WIN_MSG(WM_INITMENUPOPUP) 1171 WIN_MSG(WM_MENUSELECT) 1172 WIN_MSG(WM_MENUCHAR) 1173 WIN_MSG(WM_ENTERIDLE) 1174 FMT_MSG(0x0122, "WM_MENURBUTTONUP") 1175 FMT_MSG(0x0123, "WM_MENUDRAG") 1176 FMT_MSG(0x0124, "WM_MENUGETOBJECT") 1177 FMT_MSG(0x0125, "WM_UNINITMENUPOPUP") 1178 FMT_MSG(0x0126, "WM_MENUCOMMAND") 1179 WIN_MSG(WM_CTLCOLORMSGBOX) 1180 WIN_MSG(WM_CTLCOLOREDIT) 1181 WIN_MSG(WM_CTLCOLORLISTBOX) 1182 WIN_MSG(WM_CTLCOLORBTN) 1183 WIN_MSG(WM_CTLCOLORDLG) 1184 WIN_MSG(WM_CTLCOLORSCROLLBAR) 1185 WIN_MSG(WM_CTLCOLORSTATIC) 1186 WIN_MSG(WM_MOUSEMOVE) 1187 WIN_MSG(WM_LBUTTONDOWN) 1188 WIN_MSG(WM_LBUTTONUP) 1189 WIN_MSG(WM_LBUTTONDBLCLK) 1190 WIN_MSG(WM_RBUTTONDOWN) 1191 WIN_MSG(WM_RBUTTONUP) 1192 WIN_MSG(WM_RBUTTONDBLCLK) 1193 WIN_MSG(WM_MBUTTONDOWN) 1194 WIN_MSG(WM_MBUTTONUP) 1195 WIN_MSG(WM_MBUTTONDBLCLK) 1196 WIN_MSG(WM_XBUTTONDBLCLK) 1197 WIN_MSG(WM_XBUTTONDOWN) 1198 WIN_MSG(WM_XBUTTONUP) 1199 WIN_MSG(WM_MOUSEWHEEL) 1200 WIN_MSG(WM_PARENTNOTIFY) 1201 WIN_MSG(WM_ENTERMENULOOP) 1202 WIN_MSG(WM_EXITMENULOOP) 1203 WIN_MSG(WM_NEXTMENU) 1204 WIN_MSG(WM_SIZING) 1205 WIN_MSG(WM_CAPTURECHANGED) 1206 WIN_MSG(WM_MOVING) 1207 WIN_MSG(WM_POWERBROADCAST) 1208 WIN_MSG(WM_DEVICECHANGE) 1209 WIN_MSG(WM_MDICREATE) 1210 WIN_MSG(WM_MDIDESTROY) 1211 WIN_MSG(WM_MDIACTIVATE) 1212 WIN_MSG(WM_MDIRESTORE) 1213 WIN_MSG(WM_MDINEXT) 1214 WIN_MSG(WM_MDIMAXIMIZE) 1215 WIN_MSG(WM_MDITILE) 1216 WIN_MSG(WM_MDICASCADE) 1217 WIN_MSG(WM_MDIICONARRANGE) 1218 WIN_MSG(WM_MDIGETACTIVE) 1219 WIN_MSG(WM_MDISETMENU) 1220 WIN_MSG(WM_ENTERSIZEMOVE) 1221 WIN_MSG(WM_EXITSIZEMOVE) 1222 WIN_MSG(WM_DROPFILES) 1223 WIN_MSG(WM_MDIREFRESHMENU) 1224 WIN_MSG(WM_IME_SETCONTEXT) 1225 WIN_MSG(WM_IME_NOTIFY) 1226 WIN_MSG(WM_IME_CONTROL) 1227 WIN_MSG(WM_IME_COMPOSITIONFULL) 1228 WIN_MSG(WM_IME_SELECT) 1229 WIN_MSG(WM_IME_CHAR) 1230 FMT_MSG(WM_IME_REQUEST) 1231 WIN_MSG(WM_IME_KEYDOWN) 1232 WIN_MSG(WM_IME_KEYUP) 1233 FMT_MSG(0x02A1, "WM_MOUSEHOVER") 1234 FMT_MSG(0x02A3, "WM_MOUSELEAVE") 1235 WIN_MSG(WM_CUT) 1236 WIN_MSG(WM_COPY) 1237 WIN_MSG(WM_PASTE) 1238 WIN_MSG(WM_CLEAR) 1239 WIN_MSG(WM_UNDO) 1240 WIN_MSG(WM_RENDERFORMAT) 1241 WIN_MSG(WM_RENDERALLFORMATS) 1242 WIN_MSG(WM_DESTROYCLIPBOARD) 1243 WIN_MSG(WM_DRAWCLIPBOARD) 1244 WIN_MSG(WM_PAINTCLIPBOARD) 1245 WIN_MSG(WM_VSCROLLCLIPBOARD) 1246 WIN_MSG(WM_SIZECLIPBOARD) 1247 WIN_MSG(WM_ASKCBFORMATNAME) 1248 WIN_MSG(WM_CHANGECBCHAIN) 1249 WIN_MSG(WM_HSCROLLCLIPBOARD) 1250 WIN_MSG(WM_QUERYNEWPALETTE) 1251 WIN_MSG(WM_PALETTEISCHANGING) 1252 WIN_MSG(WM_PALETTECHANGED) 1253 WIN_MSG(WM_HOTKEY) 1254 WIN_MSG(WM_PRINT) 1255 WIN_MSG(WM_PRINTCLIENT) 1256 WIN_MSG(WM_HANDHELDFIRST) 1257 WIN_MSG(WM_HANDHELDLAST) 1258 WIN_MSG(WM_AFXFIRST) 1259 WIN_MSG(WM_AFXLAST) 1260 WIN_MSG(WM_PENWINFIRST) 1261 WIN_MSG(WM_PENWINLAST) 1262 WIN_MSG(WM_AWT_COMPONENT_CREATE) 1263 WIN_MSG(WM_AWT_DESTROY_WINDOW) 1264 WIN_MSG(WM_AWT_MOUSEENTER) 1265 WIN_MSG(WM_AWT_MOUSEEXIT) 1266 WIN_MSG(WM_AWT_COMPONENT_SHOW) 1267 WIN_MSG(WM_AWT_COMPONENT_HIDE) 1268 WIN_MSG(WM_AWT_COMPONENT_SETFOCUS) 1269 WIN_MSG(WM_AWT_WINDOW_SETACTIVE) 1270 WIN_MSG(WM_AWT_LIST_SETMULTISELECT) 1271 WIN_MSG(WM_AWT_HANDLE_EVENT) 1272 WIN_MSG(WM_AWT_PRINT_COMPONENT) 1273 WIN_MSG(WM_AWT_RESHAPE_COMPONENT) 1274 WIN_MSG(WM_AWT_SETALWAYSONTOP) 1275 WIN_MSG(WM_AWT_BEGIN_VALIDATE) 1276 WIN_MSG(WM_AWT_END_VALIDATE) 1277 WIN_MSG(WM_AWT_FORWARD_CHAR) 1278 WIN_MSG(WM_AWT_FORWARD_BYTE) 1279 WIN_MSG(WM_AWT_SET_SCROLL_INFO) 1280 WIN_MSG(WM_AWT_CREATECONTEXT) 1281 WIN_MSG(WM_AWT_DESTROYCONTEXT) 1282 WIN_MSG(WM_AWT_ASSOCIATECONTEXT) 1283 WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER) 1284 WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT) 1285 WIN_MSG(WM_AWT_PRE_KEYDOWN) 1286 WIN_MSG(WM_AWT_PRE_KEYUP) 1287 WIN_MSG(WM_AWT_PRE_SYSKEYDOWN) 1288 WIN_MSG(WM_AWT_PRE_SYSKEYUP) 1289 WIN_MSG(WM_AWT_ENDCOMPOSITION,) 1290 WIN_MSG(WM_AWT_DISPOSE,) 1291 WIN_MSG(WM_AWT_DELETEOBJECT,) 1292 WIN_MSG(WM_AWT_SETCONVERSIONSTATUS,) 1293 WIN_MSG(WM_AWT_GETCONVERSIONSTATUS,) 1294 WIN_MSG(WM_AWT_SETOPENSTATUS,) 1295 WIN_MSG(WM_AWT_GETOPENSTATUS) 1296 WIN_MSG(WM_AWT_ACTIVATEKEYBOARDLAYOUT) 1297 WIN_MSG(WM_AWT_OPENCANDIDATEWINDOW) 1298 WIN_MSG(WM_AWT_DLG_SHOWMODAL,) 1299 WIN_MSG(WM_AWT_DLG_ENDMODAL,) 1300 WIN_MSG(WM_AWT_SETCURSOR,) 1301 WIN_MSG(WM_AWT_WAIT_FOR_SINGLE_OBJECT,) 1302 WIN_MSG(WM_AWT_INVOKE_METHOD,) 1303 WIN_MSG(WM_AWT_INVOKE_VOID_METHOD,) 1304 WIN_MSG(WM_AWT_EXECUTE_SYNC,) 1305 WIN_MSG(WM_AWT_CURSOR_SYNC) 1306 WIN_MSG(WM_AWT_GETDC) 1307 WIN_MSG(WM_AWT_RELEASEDC) 1308 WIN_MSG(WM_AWT_RELEASE_ALL_DCS) 1309 WIN_MSG(WM_AWT_SHOWCURSOR) 1310 WIN_MSG(WM_AWT_HIDECURSOR) 1311 WIN_MSG(WM_AWT_CREATE_PRINTED_PIXELS) 1312 WIN_MSG(WM_AWT_OBJECTLISTCLEANUP) 1313 default: 1314 sprintf(szBuf, "0x%8.8x(%s):Unknown message 0x%8.8x\n", 1315 hwnd, szComment, message); 1316 break; 1317 } 1318 printf(szBuf); 1319 } 1320 1321 #endif /* SPY_MESSAGES */ 1322 1323 /* 1324 * Dispatch messages for this window class--general component 1325 */ 1326 LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 1327 { 1328 CounterHelper ch(&m_MessagesProcessing); 1329 1330 JNILocalFrame lframe(AwtToolkit::GetEnv(), 10); 1331 SpyWinMessage(GetHWnd(), message, 1332 (message == WM_AWT_RELEASE_ALL_DCS) ? TEXT("Disposed Component") : GetClassName()); 1333 1334 LRESULT retValue = 0; 1335 MsgRouting mr = mrDoDefault; 1336 AwtToolkit::GetInstance().eventNumber++; 1337 1338 static BOOL ignoreNextLBTNUP = FALSE; //Ignore next LBUTTONUP msg? 1339 1340 lastMessage = message; 1341 1342 if (message == WmAwtIsComponent) { 1343 // special message to identify AWT HWND's without using 1344 // resource hogging ::SetProp 1345 return (LRESULT)TRUE; 1346 } 1347 1348 DWORD curPos = 0; 1349 1350 UINT switchMessage = message; 1351 switch (switchMessage) { 1352 case WM_AWT_GETDC: 1353 { 1354 HDC hDC; 1355 // First, release the DCs scheduled for deletion 1356 ReleaseDCList(GetHWnd(), passiveDCList); 1357 1358 GetDCReturnStruct *returnStruct = new GetDCReturnStruct; 1359 returnStruct->gdiLimitReached = FALSE; 1360 if (AwtGDIObject::IncrementIfAvailable()) { 1361 hDC = ::GetDCEx(GetHWnd(), NULL, 1362 DCX_CACHE | DCX_CLIPCHILDREN | 1363 DCX_CLIPSIBLINGS); 1364 if (hDC != NULL) { 1365 // Add new DC to list of DC's associated with this Component 1366 activeDCList.AddDC(hDC, GetHWnd()); 1367 } else { 1368 // Creation failed; decrement counter in AwtGDIObject 1369 AwtGDIObject::Decrement(); 1370 } 1371 } else { 1372 hDC = NULL; 1373 returnStruct->gdiLimitReached = TRUE; 1374 } 1375 returnStruct->hDC = hDC; 1376 retValue = (LRESULT)returnStruct; 1377 mr = mrConsume; 1378 break; 1379 } 1380 case WM_AWT_RELEASEDC: 1381 { 1382 HDC hDC = (HDC)wParam; 1383 MoveDCToPassiveList(hDC); 1384 ReleaseDCList(GetHWnd(), passiveDCList); 1385 mr = mrConsume; 1386 break; 1387 } 1388 case WM_AWT_RELEASE_ALL_DCS: 1389 { 1390 // Called during Component destruction. Gets current list of 1391 // DC's associated with Component and releases each DC. 1392 ReleaseDCList(GetHWnd(), activeDCList); 1393 ReleaseDCList(GetHWnd(), passiveDCList); 1394 mr = mrConsume; 1395 break; 1396 } 1397 case WM_AWT_SHOWCURSOR: 1398 ::ShowCursor(TRUE); 1399 break; 1400 case WM_AWT_HIDECURSOR: 1401 ::ShowCursor(FALSE); 1402 break; 1403 case WM_CREATE: mr = WmCreate(); break; 1404 case WM_CLOSE: mr = WmClose(); break; 1405 case WM_DESTROY: mr = WmDestroy(); break; 1406 case WM_NCDESTROY: mr = WmNcDestroy(); break; 1407 1408 case WM_ERASEBKGND: 1409 mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break; 1410 case WM_PAINT: 1411 CheckFontSmoothingSettings(GetHWnd()); 1412 /* Set draw state */ 1413 SetDrawState(GetDrawState() | JAWT_LOCK_CLIP_CHANGED); 1414 mr = WmPaint((HDC)wParam); 1415 break; 1416 1417 case WM_GETMINMAXINFO: 1418 mr = WmGetMinMaxInfo((LPMINMAXINFO)lParam); 1419 break; 1420 1421 case WM_WINDOWPOSCHANGING: 1422 { 1423 // We process this message so that we can synchronize access to 1424 // a moving window. The Scale/Blt functions in Win32BlitLoops 1425 // take the same windowMoveLock to ensure that a window is not 1426 // moving while we are trying to copy pixels into it. 1427 WINDOWPOS *lpPosInfo = (WINDOWPOS *)lParam; 1428 if ((lpPosInfo->flags & (SWP_NOMOVE | SWP_NOSIZE)) != 1429 (SWP_NOMOVE | SWP_NOSIZE)) 1430 { 1431 // Move or Size command. 1432 // Windows tends to send erroneous events that the window 1433 // is about to move when the coordinates are exactly the 1434 // same as the last time. This can cause problems with 1435 // our windowMoveLock CriticalSection because we enter it 1436 // here and never get to WM_WINDOWPOSCHANGED to release it. 1437 // So make sure this is a real move/size event before bothering 1438 // to grab the critical section. 1439 BOOL takeLock = FALSE; 1440 if (!(lpPosInfo->flags & SWP_NOMOVE) && 1441 ((windowMoveLockPosX != lpPosInfo->x) || 1442 (windowMoveLockPosY != lpPosInfo->y))) 1443 { 1444 // Real move event 1445 takeLock = TRUE; 1446 windowMoveLockPosX = lpPosInfo->x; 1447 windowMoveLockPosY = lpPosInfo->y; 1448 } 1449 if (!(lpPosInfo->flags & SWP_NOSIZE) && 1450 ((windowMoveLockPosCX != lpPosInfo->cx) || 1451 (windowMoveLockPosCY != lpPosInfo->cy))) 1452 { 1453 // Real size event 1454 takeLock = TRUE; 1455 windowMoveLockPosCX = lpPosInfo->cx; 1456 windowMoveLockPosCY = lpPosInfo->cy; 1457 } 1458 if (takeLock) { 1459 if (!windowMoveLockHeld) { 1460 windowMoveLock.Enter(); 1461 windowMoveLockHeld = TRUE; 1462 } 1463 } 1464 } 1465 mr = WmWindowPosChanging(lParam); 1466 break; 1467 } 1468 case WM_WINDOWPOSCHANGED: 1469 { 1470 // Release lock grabbed in the POSCHANGING message 1471 if (windowMoveLockHeld) { 1472 windowMoveLockHeld = FALSE; 1473 windowMoveLock.Leave(); 1474 } 1475 mr = WmWindowPosChanged(lParam); 1476 break; 1477 } 1478 case WM_MOVE: { 1479 RECT r; 1480 ::GetWindowRect(GetHWnd(), &r); 1481 mr = WmMove(r.left, r.top); 1482 break; 1483 } 1484 case WM_SIZE: 1485 { 1486 RECT r; 1487 // fix 4128317 : use GetClientRect for full 32-bit int precision and 1488 // to avoid negative client area dimensions overflowing 16-bit params - robi 1489 ::GetClientRect( GetHWnd(), &r ); 1490 mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top); 1491 //mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam)); 1492 SetCompositionWindow(r); 1493 break; 1494 } 1495 case WM_SIZING: 1496 mr = WmSizing(); 1497 break; 1498 case WM_SHOWWINDOW: 1499 mr = WmShowWindow(static_cast<BOOL>(wParam), 1500 static_cast<UINT>(lParam)); break; 1501 case WM_SYSCOMMAND: 1502 mr = WmSysCommand(static_cast<UINT>(wParam & 0xFFF0), 1503 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1504 break; 1505 case WM_EXITSIZEMOVE: 1506 mr = WmExitSizeMove(); 1507 break; 1508 // Bug #4039858 (Selecting menu item causes bogus mouse click event) 1509 case WM_ENTERMENULOOP: 1510 mr = WmEnterMenuLoop((BOOL)wParam); 1511 sm_bMenuLoop = TRUE; 1512 // we need to release grab if menu is shown 1513 if (AwtWindow::GetGrabbedWindow() != NULL) { 1514 AwtWindow::GetGrabbedWindow()->Ungrab(); 1515 } 1516 break; 1517 case WM_EXITMENULOOP: 1518 mr = WmExitMenuLoop((BOOL)wParam); 1519 sm_bMenuLoop = FALSE; 1520 break; 1521 1522 // We don't expect any focus messages on non-proxy component, 1523 // except those that came from Java. 1524 case WM_SETFOCUS: 1525 if (sm_inSynthesizeFocus) { 1526 mr = WmSetFocus((HWND)wParam); 1527 } else { 1528 mr = mrConsume; 1529 } 1530 break; 1531 case WM_KILLFOCUS: 1532 if (sm_inSynthesizeFocus) { 1533 mr = WmKillFocus((HWND)wParam); 1534 } else { 1535 mr = mrConsume; 1536 } 1537 break; 1538 case WM_ACTIVATE: { 1539 UINT nState = LOWORD(wParam); 1540 BOOL fMinimized = (BOOL)HIWORD(wParam); 1541 mr = mrConsume; 1542 1543 if (!sm_suppressFocusAndActivation && 1544 (!fMinimized || (nState == WA_INACTIVE))) 1545 { 1546 mr = WmActivate(nState, fMinimized, (HWND)lParam); 1547 1548 // When the window is deactivated, send WM_IME_ENDCOMPOSITION 1549 // message to deactivate the composition window so that 1550 // it won't receive keyboard input focus. 1551 HIMC hIMC; 1552 HWND hwnd = ImmGetHWnd(); 1553 if ((hIMC = ImmGetContext(hwnd)) != NULL) { 1554 ImmReleaseContext(hwnd, hIMC); 1555 DefWindowProc(WM_IME_ENDCOMPOSITION, 0, 0); 1556 } 1557 } 1558 break; 1559 } 1560 case WM_MOUSEACTIVATE: { 1561 AwtWindow *window = GetContainer(); 1562 if (window && window->IsFocusableWindow()) { 1563 // AWT/Swing will later request focus to a proper component 1564 // on handling the Java mouse event. Anyway, we have to 1565 // activate the window here as it works both for AWT & Swing. 1566 // Do it in our own fassion, 1567 window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/); 1568 } 1569 mr = mrConsume; 1570 retValue = MA_NOACTIVATE; 1571 break; 1572 } 1573 case WM_CTLCOLORMSGBOX: 1574 case WM_CTLCOLOREDIT: 1575 case WM_CTLCOLORLISTBOX: 1576 case WM_CTLCOLORBTN: 1577 case WM_CTLCOLORDLG: 1578 case WM_CTLCOLORSCROLLBAR: 1579 case WM_CTLCOLORSTATIC: 1580 mr = WmCtlColor((HDC)wParam, (HWND)lParam, 1581 message-WM_CTLCOLORMSGBOX+CTLCOLOR_MSGBOX, 1582 *(HBRUSH*)&retValue); 1583 break; 1584 case WM_HSCROLL: 1585 mr = WmHScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1586 break; 1587 case WM_VSCROLL: 1588 mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1589 break; 1590 // 4664415: We're seeing a WM_LBUTTONUP when the user releases the 1591 // mouse button after a WM_NCLBUTTONDBLCLK. We want to ignore this 1592 // WM_LBUTTONUP, so we set a flag in WM_NCLBUTTONDBLCLK and look for the 1593 // flag on a WM_LBUTTONUP. -bchristi 1594 case WM_NCLBUTTONDBLCLK: 1595 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON | DBL_CLICK); 1596 if (mr == mrDoDefault) { 1597 ignoreNextLBTNUP = TRUE; 1598 } 1599 break; 1600 case WM_NCLBUTTONDOWN: 1601 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1602 ignoreNextLBTNUP = FALSE; 1603 break; 1604 case WM_NCLBUTTONUP: 1605 mr = WmNcMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1606 break; 1607 case WM_NCRBUTTONDOWN: 1608 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), RIGHT_BUTTON); 1609 break; 1610 case WM_LBUTTONUP: 1611 if (ignoreNextLBTNUP) { 1612 ignoreNextLBTNUP = FALSE; 1613 return mrDoDefault; 1614 } 1615 //fall-through 1616 case WM_LBUTTONDOWN: 1617 ignoreNextLBTNUP = FALSE; 1618 //fall-through 1619 case WM_LBUTTONDBLCLK: 1620 case WM_RBUTTONDOWN: 1621 case WM_RBUTTONDBLCLK: 1622 case WM_RBUTTONUP: 1623 case WM_MBUTTONDOWN: 1624 case WM_MBUTTONDBLCLK: 1625 case WM_MBUTTONUP: 1626 case WM_XBUTTONDBLCLK: 1627 case WM_XBUTTONDOWN: 1628 case WM_XBUTTONUP: 1629 case WM_MOUSEMOVE: 1630 case WM_MOUSEWHEEL: 1631 case WM_AWT_MOUSEENTER: 1632 case WM_AWT_MOUSEEXIT: 1633 curPos = ::GetMessagePos(); 1634 POINT myPos; 1635 myPos.x = GET_X_LPARAM(curPos); 1636 myPos.y = GET_Y_LPARAM(curPos); 1637 ::ScreenToClient(GetHWnd(), &myPos); 1638 switch(switchMessage) { 1639 case WM_AWT_MOUSEENTER: 1640 mr = WmMouseEnter(static_cast<UINT>(wParam), myPos.x, myPos.y); 1641 break; 1642 case WM_LBUTTONDOWN: 1643 case WM_LBUTTONDBLCLK: 1644 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1645 LEFT_BUTTON); 1646 break; 1647 case WM_LBUTTONUP: 1648 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1649 LEFT_BUTTON); 1650 break; 1651 case WM_MOUSEMOVE: 1652 mr = WmMouseMove(static_cast<UINT>(wParam), myPos.x, myPos.y); 1653 break; 1654 case WM_MBUTTONDOWN: 1655 case WM_MBUTTONDBLCLK: 1656 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1657 MIDDLE_BUTTON); 1658 break; 1659 case WM_XBUTTONDOWN: 1660 case WM_XBUTTONDBLCLK: 1661 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1662 if (HIWORD(wParam) == 1) { 1663 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1664 X1_BUTTON); 1665 } 1666 if (HIWORD(wParam) == 2) { 1667 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1668 X2_BUTTON); 1669 } 1670 } 1671 break; 1672 case WM_XBUTTONUP: 1673 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1674 if (HIWORD(wParam) == 1) { 1675 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1676 X1_BUTTON); 1677 } 1678 if (HIWORD(wParam) == 2) { 1679 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1680 X2_BUTTON); 1681 } 1682 } 1683 break; 1684 case WM_RBUTTONDOWN: 1685 case WM_RBUTTONDBLCLK: 1686 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1687 RIGHT_BUTTON); 1688 break; 1689 case WM_RBUTTONUP: 1690 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1691 RIGHT_BUTTON); 1692 break; 1693 case WM_MBUTTONUP: 1694 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1695 MIDDLE_BUTTON); 1696 break; 1697 case WM_AWT_MOUSEEXIT: 1698 mr = WmMouseExit(static_cast<UINT>(wParam), myPos.x, myPos.y); 1699 break; 1700 case WM_MOUSEWHEEL: 1701 mr = WmMouseWheel(GET_KEYSTATE_WPARAM(wParam), 1702 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1703 GET_WHEEL_DELTA_WPARAM(wParam)); 1704 break; 1705 } 1706 break; 1707 case WM_SETCURSOR: 1708 mr = mrDoDefault; 1709 if (LOWORD(lParam) == HTCLIENT) { 1710 if (AwtComponent* comp = 1711 AwtComponent::GetComponent((HWND)wParam)) { 1712 AwtCursor::UpdateCursor(comp); 1713 mr = mrConsume; 1714 } 1715 } 1716 break; 1717 1718 case WM_KEYDOWN: 1719 mr = WmKeyDown(static_cast<UINT>(wParam), 1720 LOWORD(lParam), HIWORD(lParam), FALSE); 1721 break; 1722 case WM_KEYUP: 1723 mr = WmKeyUp(static_cast<UINT>(wParam), 1724 LOWORD(lParam), HIWORD(lParam), FALSE); 1725 break; 1726 case WM_SYSKEYDOWN: 1727 mr = WmKeyDown(static_cast<UINT>(wParam), 1728 LOWORD(lParam), HIWORD(lParam), TRUE); 1729 break; 1730 case WM_SYSKEYUP: 1731 mr = WmKeyUp(static_cast<UINT>(wParam), 1732 LOWORD(lParam), HIWORD(lParam), TRUE); 1733 break; 1734 case WM_IME_SETCONTEXT: 1735 // lParam is passed as pointer and it can be modified. 1736 mr = WmImeSetContext(static_cast<BOOL>(wParam), &lParam); 1737 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1738 break; 1739 case WM_IME_NOTIFY: 1740 mr = WmImeNotify(wParam, lParam); 1741 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1742 break; 1743 case WM_IME_STARTCOMPOSITION: 1744 mr = WmImeStartComposition(); 1745 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1746 break; 1747 case WM_IME_ENDCOMPOSITION: 1748 mr = WmImeEndComposition(); 1749 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1750 break; 1751 case WM_IME_COMPOSITION: { 1752 WORD dbcschar = static_cast<WORD>(wParam); 1753 mr = WmImeComposition(dbcschar, lParam); 1754 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1755 break; 1756 } 1757 case WM_IME_CONTROL: 1758 case WM_IME_COMPOSITIONFULL: 1759 case WM_IME_SELECT: 1760 case WM_IME_KEYUP: 1761 case WM_IME_KEYDOWN: 1762 case WM_IME_REQUEST: 1763 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1764 break; 1765 case WM_CHAR: 1766 mr = WmChar(static_cast<UINT>(wParam), 1767 LOWORD(lParam), HIWORD(lParam), FALSE); 1768 break; 1769 case WM_SYSCHAR: 1770 mr = WmChar(static_cast<UINT>(wParam), 1771 LOWORD(lParam), HIWORD(lParam), TRUE); 1772 break; 1773 case WM_IME_CHAR: 1774 mr = WmIMEChar(static_cast<UINT>(wParam), 1775 LOWORD(lParam), HIWORD(lParam), FALSE); 1776 break; 1777 1778 case WM_INPUTLANGCHANGEREQUEST: { 1779 DTRACE_PRINTLN4("WM_INPUTLANGCHANGEREQUEST: hwnd = 0x%X (%s);"// 1780 "0x%08X -> 0x%08X", 1781 GetHWnd(), GetClassName(), 1782 (UINT_PTR)GetKeyboardLayout(), (UINT_PTR)lParam); 1783 // 4267428: make sure keyboard layout is turned undead. 1784 static BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 1785 AwtToolkit::GetKeyboardState(keyboardState); 1786 WORD ignored; 1787 ::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0), 1788 keyboardState, &ignored, 0, GetKeyboardLayout()); 1789 1790 // Set this flag to block ActivateKeyboardLayout from 1791 // WInputMethod.activate() 1792 g_bUserHasChangedInputLang = TRUE; 1793 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1794 break; 1795 } 1796 case WM_INPUTLANGCHANGE: 1797 DTRACE_PRINTLN3("WM_INPUTLANGCHANGE: hwnd = 0x%X (%s);"// 1798 "new = 0x%08X", 1799 GetHWnd(), GetClassName(), (UINT)lParam); 1800 mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam)); 1801 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1802 // should return non-zero if we process this message 1803 retValue = 1; 1804 break; 1805 1806 case WM_AWT_FORWARD_CHAR: 1807 mr = WmForwardChar(LOWORD(wParam), lParam, HIWORD(wParam)); 1808 break; 1809 1810 case WM_AWT_FORWARD_BYTE: 1811 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1812 break; 1813 1814 case WM_PASTE: 1815 mr = WmPaste(); 1816 break; 1817 case WM_TIMER: 1818 mr = WmTimer(wParam); 1819 break; 1820 1821 case WM_COMMAND: 1822 mr = WmCommand(LOWORD(wParam), (HWND)lParam, HIWORD(wParam)); 1823 break; 1824 case WM_COMPAREITEM: 1825 mr = WmCompareItem(static_cast<UINT>(wParam), 1826 *(COMPAREITEMSTRUCT*)lParam, retValue); 1827 break; 1828 case WM_DELETEITEM: 1829 mr = WmDeleteItem(static_cast<UINT>(wParam), 1830 *(DELETEITEMSTRUCT*)lParam); 1831 break; 1832 case WM_DRAWITEM: 1833 mr = WmDrawItem(static_cast<UINT>(wParam), 1834 *(DRAWITEMSTRUCT*)lParam); 1835 break; 1836 case WM_MEASUREITEM: 1837 mr = WmMeasureItem(static_cast<UINT>(wParam), 1838 *(MEASUREITEMSTRUCT*)lParam); 1839 break; 1840 1841 case WM_AWT_HANDLE_EVENT: 1842 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1843 break; 1844 1845 case WM_PRINT: 1846 mr = WmPrint((HDC)wParam, lParam); 1847 break; 1848 case WM_PRINTCLIENT: 1849 mr = WmPrintClient((HDC)wParam, lParam); 1850 break; 1851 1852 case WM_NCCALCSIZE: 1853 mr = WmNcCalcSize((BOOL)wParam, (LPNCCALCSIZE_PARAMS)lParam, 1854 retValue); 1855 break; 1856 case WM_NCPAINT: 1857 mr = WmNcPaint((HRGN)wParam); 1858 break; 1859 case WM_NCHITTEST: 1860 mr = WmNcHitTest(LOWORD(lParam), HIWORD(lParam), retValue); 1861 break; 1862 1863 case WM_AWT_RESHAPE_COMPONENT: { 1864 RECT* r = (RECT*)lParam; 1865 WPARAM checkEmbedded = wParam; 1866 if (checkEmbedded == CHECK_EMBEDDED && IsEmbeddedFrame()) { 1867 ::OffsetRect(r, -r->left, -r->top); 1868 } 1869 Reshape(r->left, r->top, r->right - r->left, r->bottom - r->top); 1870 delete r; 1871 mr = mrConsume; 1872 break; 1873 } 1874 1875 case WM_AWT_SETALWAYSONTOP: { 1876 AwtWindow* w = (AwtWindow*)lParam; 1877 BOOL value = (BOOL)wParam; 1878 UINT flags = SWP_NOMOVE | SWP_NOSIZE; 1879 // transient windows shouldn't change the owner window's position in the z-order 1880 if (w->IsRetainingHierarchyZOrder()) { 1881 flags |= SWP_NOOWNERZORDER; 1882 } 1883 ::SetWindowPos(w->GetHWnd(), (value != 0 ? HWND_TOPMOST : HWND_NOTOPMOST), 1884 0,0,0,0, flags); 1885 break; 1886 } 1887 1888 case WM_AWT_BEGIN_VALIDATE: 1889 BeginValidate(); 1890 mr = mrConsume; 1891 break; 1892 case WM_AWT_END_VALIDATE: 1893 EndValidate(); 1894 mr = mrConsume; 1895 break; 1896 1897 case WM_PALETTEISCHANGING: 1898 mr = WmPaletteIsChanging((HWND)wParam); 1899 mr = mrDoDefault; 1900 break; 1901 case WM_QUERYNEWPALETTE: 1902 mr = WmQueryNewPalette(retValue); 1903 break; 1904 case WM_PALETTECHANGED: 1905 mr = WmPaletteChanged((HWND)wParam); 1906 break; 1907 case WM_STYLECHANGED: 1908 mr = WmStyleChanged(static_cast<int>(wParam), (LPSTYLESTRUCT)lParam); 1909 break; 1910 case WM_SETTINGCHANGE: 1911 CheckFontSmoothingSettings(NULL); 1912 mr = WmSettingChange(static_cast<UINT>(wParam), (LPCTSTR)lParam); 1913 break; 1914 case WM_CONTEXTMENU: 1915 mr = WmContextMenu((HWND)wParam, 1916 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1917 break; 1918 1919 /* 1920 * These messages are used to route Win32 calls to the 1921 * creating thread, since these calls fail unless executed 1922 * there. 1923 */ 1924 case WM_AWT_COMPONENT_SHOW: 1925 Show(); 1926 mr = mrConsume; 1927 break; 1928 case WM_AWT_COMPONENT_HIDE: 1929 Hide(); 1930 mr = mrConsume; 1931 break; 1932 1933 case WM_AWT_COMPONENT_SETFOCUS: 1934 if ((BOOL)wParam) { 1935 retValue = SynthesizeWmSetFocus(GetHWnd(), NULL); 1936 } else { 1937 retValue = SynthesizeWmKillFocus(GetHWnd(), NULL); 1938 } 1939 mr = mrConsume; 1940 break; 1941 case WM_AWT_WINDOW_SETACTIVE: 1942 retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam); 1943 mr = mrConsume; 1944 break; 1945 1946 case WM_AWT_SET_SCROLL_INFO: { 1947 SCROLLINFO *si = (SCROLLINFO *) lParam; 1948 ::SetScrollInfo(GetHWnd(), (int) wParam, si, TRUE); 1949 delete si; 1950 mr = mrConsume; 1951 break; 1952 } 1953 case WM_AWT_CREATE_PRINTED_PIXELS: { 1954 CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam; 1955 SIZE loc = { cpps->srcx, cpps->srcy }; 1956 SIZE size = { cpps->srcw, cpps->srch }; 1957 retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha); 1958 mr = mrConsume; 1959 break; 1960 } 1961 case WM_UNDOCUMENTED_CLICKMENUBAR: 1962 { 1963 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { 1964 mr = mrConsume; 1965 } 1966 } 1967 } 1968 1969 /* 1970 * If not a specific Consume, it was a specific DoDefault, or a 1971 * PassAlong (since the default is the next in chain), then call the 1972 * default proc. 1973 */ 1974 if (mr != mrConsume) { 1975 retValue = DefWindowProc(message, wParam, lParam); 1976 } 1977 1978 return retValue; 1979 } 1980 /* 1981 * Call this instance's default window proc, or if none set, call the stock 1982 * Window's one. 1983 */ 1984 LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) 1985 { 1986 return ComCtl32Util::GetInstance().DefWindowProc(m_DefWindowProc, GetHWnd(), msg, wParam, lParam); 1987 } 1988 1989 /* 1990 * This message should only be received when a window is destroyed by 1991 * Windows, and not Java. Window termination has been reworked so 1992 * this method should never be called during termination. 1993 */ 1994 MsgRouting AwtComponent::WmDestroy() 1995 { 1996 return mrConsume; 1997 } 1998 1999 /* 2000 * This message should only be received when a window is destroyed by 2001 * Windows, and not Java. It is sent only after child windows were destroyed. 2002 */ 2003 MsgRouting AwtComponent::WmNcDestroy() 2004 { 2005 if (m_peerObject != NULL) { // is not being terminating 2006 // Stay in this handler until AwtComponent::Dispose is called. 2007 m_bPauseDestroy = TRUE; 2008 2009 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 2010 // Post invocation event for WObjectPeer.dispose to EDT 2011 env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID); 2012 // Wait until AwtComponent::Dispose is called 2013 AwtToolkit::GetInstance().PumpToDestroy(this); 2014 } 2015 2016 return mrConsume; 2017 } 2018 2019 MsgRouting AwtComponent::WmGetMinMaxInfo(LPMINMAXINFO lpmmi) 2020 { 2021 return mrDoDefault; 2022 } 2023 2024 MsgRouting AwtComponent::WmMove(int x, int y) 2025 { 2026 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2027 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2028 return mrDoDefault; 2029 } 2030 2031 MsgRouting AwtComponent::WmSize(UINT type, int w, int h) 2032 { 2033 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2034 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2035 return mrDoDefault; 2036 } 2037 2038 MsgRouting AwtComponent::WmSizing() 2039 { 2040 return mrDoDefault; 2041 } 2042 2043 MsgRouting AwtComponent::WmSysCommand(UINT uCmdType, int xPos, int yPos) 2044 { 2045 return mrDoDefault; 2046 } 2047 2048 MsgRouting AwtComponent::WmExitSizeMove() 2049 { 2050 return mrDoDefault; 2051 } 2052 2053 MsgRouting AwtComponent::WmEnterMenuLoop(BOOL isTrackPopupMenu) 2054 { 2055 return mrDoDefault; 2056 } 2057 2058 MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu) 2059 { 2060 return mrDoDefault; 2061 } 2062 2063 MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status) 2064 { 2065 return mrDoDefault; 2066 } 2067 2068 MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus) 2069 { 2070 m_wheelRotationAmount = 0; 2071 return mrDoDefault; 2072 } 2073 2074 MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus) 2075 { 2076 m_wheelRotationAmount = 0; 2077 return mrDoDefault; 2078 } 2079 2080 MsgRouting AwtComponent::WmCtlColor(HDC hDC, HWND hCtrl, 2081 UINT ctlColor, HBRUSH& retBrush) 2082 { 2083 AwtComponent* child = AwtComponent::GetComponent(hCtrl); 2084 if (child) { 2085 ::SetBkColor(hDC, child->GetBackgroundColor()); 2086 ::SetTextColor(hDC, child->GetColor()); 2087 retBrush = child->GetBackgroundBrush(); 2088 return mrConsume; 2089 } 2090 return mrDoDefault; 2091 /* 2092 switch (ctlColor) { 2093 case CTLCOLOR_MSGBOX: 2094 case CTLCOLOR_EDIT: 2095 case CTLCOLOR_LISTBOX: 2096 case CTLCOLOR_BTN: 2097 case CTLCOLOR_DLG: 2098 case CTLCOLOR_SCROLLBAR: 2099 case CTLCOLOR_STATIC: 2100 } 2101 */ 2102 } 2103 2104 MsgRouting AwtComponent::WmHScroll(UINT scrollCode, UINT pos, 2105 HWND hScrollbar) { 2106 if (hScrollbar && hScrollbar != GetHWnd()) { 2107 /* the last test should never happen */ 2108 AwtComponent* sb = GetComponent(hScrollbar); 2109 if (sb) { 2110 sb->WmHScroll(scrollCode, pos, hScrollbar); 2111 } 2112 } 2113 return mrDoDefault; 2114 } 2115 2116 MsgRouting AwtComponent::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar) 2117 { 2118 if (hScrollbar && hScrollbar != GetHWnd()) { 2119 /* the last test should never happen */ 2120 AwtComponent* sb = GetComponent(hScrollbar); 2121 if (sb) { 2122 sb->WmVScroll(scrollCode, pos, hScrollbar); 2123 } 2124 } 2125 return mrDoDefault; 2126 } 2127 2128 namespace TimeHelper { 2129 // Sometimes the message belongs to another event queue and 2130 // GetMessageTime() may return wrong non-zero value (the case is 2131 // the TrayIcon peer). Using TimeHelper::windowsToUTC(::GetTickCount()) 2132 // could help there. 2133 static DWORD getMessageTimeWindows(){ 2134 DWORD time = ::GetMessageTime(); 2135 // The following 'if' seems to be a unneeded hack. 2136 // Consider removing it. 2137 if (time == 0) { 2138 time = ::GetTickCount(); 2139 } 2140 return time; 2141 } 2142 2143 jlong getMessageTimeUTC() { 2144 return windowsToUTC(getMessageTimeWindows()); 2145 } 2146 2147 // If calling order of GetTickCount and JVM_CurrentTimeMillis 2148 // is swapped, it would sometimes give different result. 2149 // Anyway, we would not always have determinism 2150 // and sortedness of time conversion here (due to Windows's 2151 // timers peculiarities). Having some euristic algorithm might 2152 // help here. 2153 jlong windowsToUTC(DWORD windowsTime) { 2154 jlong offset = ::GetTickCount() - windowsTime; 2155 jlong jvm_time = ::JVM_CurrentTimeMillis(NULL, 0); 2156 return jvm_time - offset; 2157 } 2158 } //TimeHelper 2159 2160 MsgRouting AwtComponent::WmPaint(HDC) 2161 { 2162 /* Get the rectangle that covers all update regions, if any exist. */ 2163 RECT r; 2164 if (::GetUpdateRect(GetHWnd(), &r, FALSE)) { 2165 if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 && 2166 m_peerObject != NULL && m_callbacksEnabled) { 2167 /* 2168 * Always call handlePaint, because the underlying control 2169 * will have painted itself (the "background") before any 2170 * paint method is called. 2171 */ 2172 DoCallback("handlePaint", "(IIII)V", 2173 r.left, r.top, r.right-r.left, r.bottom-r.top); 2174 } 2175 } 2176 return mrDoDefault; 2177 } 2178 2179 void AwtComponent::PaintUpdateRgn(const RECT *insets) 2180 { 2181 // Fix 4530093: Don't Validate if can't actually paint 2182 if (m_peerObject == NULL || !m_callbacksEnabled) { 2183 2184 // Fix 4745222: If we don't ValidateRgn, windows will keep sending 2185 // WM_PAINT messages until we do. This causes java to go into 2186 // a tight loop that increases CPU to 100% and starves main 2187 // thread which needs to complete initialization, but cant. 2188 ::ValidateRgn(GetHWnd(), NULL); 2189 2190 return; 2191 } 2192 2193 HRGN rgn = ::CreateRectRgn(0,0,1,1); 2194 int updated = ::GetUpdateRgn(GetHWnd(), rgn, FALSE); 2195 /* 2196 * Now remove all update regions from this window -- do it 2197 * here instead of after the Java upcall, in case any new 2198 * updating is requested. 2199 */ 2200 ::ValidateRgn(GetHWnd(), NULL); 2201 2202 if (updated == COMPLEXREGION || updated == SIMPLEREGION) { 2203 if (insets != NULL) { 2204 ::OffsetRgn(rgn, insets->left, insets->top); 2205 } 2206 DWORD size = ::GetRegionData(rgn, 0, NULL); 2207 if (size == 0) { 2208 ::DeleteObject((HGDIOBJ)rgn); 2209 return; 2210 } 2211 char* buffer = new char[size]; // safe because sizeof(char)==1 2212 memset(buffer, 0, size); 2213 LPRGNDATA rgndata = (LPRGNDATA)buffer; 2214 rgndata->rdh.dwSize = sizeof(RGNDATAHEADER); 2215 rgndata->rdh.iType = RDH_RECTANGLES; 2216 int retCode = ::GetRegionData(rgn, size, rgndata); 2217 VERIFY(retCode); 2218 if (retCode == 0) { 2219 delete [] buffer; 2220 ::DeleteObject((HGDIOBJ)rgn); 2221 return; 2222 } 2223 /* 2224 * Updating rects are divided into mostly vertical and mostly horizontal 2225 * Each group is united together and if not empty painted separately 2226 */ 2227 RECT* r = (RECT*)(buffer + rgndata->rdh.dwSize); 2228 RECT* un[2] = {0, 0}; 2229 DWORD i; 2230 for (i = 0; i < rgndata->rdh.nCount; i++, r++) { 2231 int width = r->right-r->left; 2232 int height = r->bottom-r->top; 2233 if (width > 0 && height > 0) { 2234 int toAdd = (width > height) ? 0: 1; 2235 if (un[toAdd] != 0) { 2236 ::UnionRect(un[toAdd], un[toAdd], r); 2237 } else { 2238 un[toAdd] = r; 2239 } 2240 } 2241 } 2242 for(i = 0; i < 2; i++) { 2243 if (un[i] != 0) { 2244 DoCallback("handleExpose", "(IIII)V", un[i]->left, un[i]->top, 2245 un[i]->right-un[i]->left, un[i]->bottom-un[i]->top); 2246 } 2247 } 2248 delete [] buffer; 2249 } 2250 ::DeleteObject((HGDIOBJ)rgn); 2251 } 2252 2253 MsgRouting AwtComponent::WmMouseEnter(UINT flags, int x, int y) 2254 { 2255 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_ENTERED, 2256 TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), 0, JNI_FALSE); 2257 if ((flags & ALL_MK_BUTTONS) == 0) { 2258 AwtCursor::UpdateCursor(this); 2259 } 2260 sm_cursorOn = GetHWnd(); 2261 return mrConsume; /* Don't pass our synthetic event on! */ 2262 } 2263 2264 MSG* 2265 AwtComponent::CreateMessage(UINT message, WPARAM wParam, LPARAM lParam, 2266 int x = 0, int y = 0) 2267 { 2268 MSG* pMsg = new MSG; 2269 InitMessage(pMsg, message, wParam, lParam, x, y); 2270 return pMsg; 2271 } 2272 2273 2274 jint 2275 AwtComponent::GetDrawState(HWND hwnd) { 2276 return (jint)(INT_PTR)(::GetProp(hwnd, DrawingStateProp)); 2277 } 2278 2279 void 2280 AwtComponent::SetDrawState(HWND hwnd, jint state) { 2281 ::SetProp(hwnd, DrawingStateProp, (HANDLE)(INT_PTR)state); 2282 } 2283 2284 void 2285 AwtComponent::InitMessage(MSG* msg, UINT message, WPARAM wParam, LPARAM lParam, 2286 int x = 0, int y = 0) 2287 { 2288 msg->message = message; 2289 msg->wParam = wParam; 2290 msg->lParam = lParam; 2291 msg->time = TimeHelper::getMessageTimeWindows(); 2292 msg->pt.x = x; 2293 msg->pt.y = y; 2294 } 2295 2296 MsgRouting AwtComponent::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { 2297 return mrDoDefault; 2298 } 2299 MsgRouting AwtComponent::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) { 2300 return mrDoDefault; 2301 } 2302 2303 MsgRouting AwtComponent::WmWindowPosChanging(LPARAM windowPos) { 2304 return mrDoDefault; 2305 } 2306 MsgRouting AwtComponent::WmWindowPosChanged(LPARAM windowPos) { 2307 return mrDoDefault; 2308 } 2309 2310 /* Double-click variables. */ 2311 static jlong multiClickTime = ::GetDoubleClickTime(); 2312 static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK); 2313 static int multiClickMaxY = ::GetSystemMetrics(SM_CYDOUBLECLK); 2314 static AwtComponent* lastClickWnd = NULL; 2315 static jlong lastTime = 0; 2316 static int lastClickX = 0; 2317 static int lastClickY = 0; 2318 static int lastButton = 0; 2319 static int clickCount = 0; 2320 2321 // A static method that makes the clickCount available in the derived classes 2322 // overriding WmMouseDown(). 2323 int AwtComponent::GetClickCount() 2324 { 2325 return clickCount; 2326 } 2327 2328 MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button) 2329 { 2330 jlong now = TimeHelper::getMessageTimeUTC(); 2331 2332 if (lastClickWnd == this && 2333 lastButton == button && 2334 (now - lastTime) <= multiClickTime && 2335 abs(x - lastClickX) <= multiClickMaxX && 2336 abs(y - lastClickY) <= multiClickMaxY) 2337 { 2338 clickCount++; 2339 } else { 2340 clickCount = 1; 2341 lastClickWnd = this; 2342 lastButton = button; 2343 lastClickX = x; 2344 lastClickY = y; 2345 } 2346 /* 2347 *Set appropriate bit of the mask on WM_MOUSE_DOWN message. 2348 */ 2349 m_mouseButtonClickAllowed |= GetButtonMK(button); 2350 lastTime = now; 2351 2352 MSG msg; 2353 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2354 2355 AwtWindow *toplevel = GetContainer(); 2356 if (toplevel && !toplevel->IsSimpleWindow()) { 2357 /* 2358 * The frame should be focused by click in case it is 2359 * the active window but not the focused window. See 6886678. 2360 */ 2361 if (toplevel->GetHWnd() == ::GetActiveWindow() && 2362 toplevel->GetHWnd() != AwtComponent::GetFocusedWindow()) 2363 { 2364 toplevel->AwtSetActiveWindow(); 2365 } 2366 } 2367 2368 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y, 2369 GetJavaModifiers(), clickCount, JNI_FALSE, 2370 GetButton(button), &msg); 2371 /* 2372 * NOTE: this call is intentionally placed after all other code, 2373 * since AwtComponent::WmMouseDown() assumes that the cached id of the 2374 * latest retrieved message (see lastMessage in awt_Component.cpp) 2375 * matches the mouse message being processed. 2376 * SetCapture() sends WM_CAPTURECHANGED and breaks that 2377 * assumption. 2378 */ 2379 SetDragCapture(flags); 2380 2381 AwtWindow * owner = (AwtWindow*)GetComponent(GetTopLevelParentForWindow(GetHWnd())); 2382 if (AwtWindow::GetGrabbedWindow() != NULL && owner != NULL) { 2383 if (!AwtWindow::GetGrabbedWindow()->IsOneOfOwnersOf(owner)) { 2384 AwtWindow::GetGrabbedWindow()->Ungrab(); 2385 } 2386 } 2387 return mrConsume; 2388 } 2389 2390 MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button) 2391 { 2392 MSG msg; 2393 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2394 2395 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, TimeHelper::getMessageTimeUTC(), 2396 x, y, GetJavaModifiers(), clickCount, 2397 (GetButton(button) == java_awt_event_MouseEvent_BUTTON3 ? 2398 TRUE : FALSE), GetButton(button), &msg); 2399 /* 2400 * If no movement, then report a click following the button release. 2401 * When WM_MOUSEUP comes to a window without previous WM_MOUSEDOWN, 2402 * spurous MOUSE_CLICK is about to happen. See 6430553. 2403 */ 2404 if ((m_mouseButtonClickAllowed & GetButtonMK(button)) != 0) { //CLICK allowed 2405 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED, 2406 TimeHelper::getMessageTimeUTC(), x, y, GetJavaModifiers(), 2407 clickCount, JNI_FALSE, GetButton(button)); 2408 } 2409 // Exclude button from allowed to generate CLICK messages 2410 m_mouseButtonClickAllowed &= ~GetButtonMK(button); 2411 2412 if ((flags & ALL_MK_BUTTONS) == 0) { 2413 // only update if all buttons have been released 2414 AwtCursor::UpdateCursor(this); 2415 } 2416 /* 2417 * NOTE: this call is intentionally placed after all other code, 2418 * since AwtComponent::WmMouseUp() assumes that the cached id of the 2419 * latest retrieved message (see lastMessage in awt_Component.cpp) 2420 * matches the mouse message being processed. 2421 * ReleaseCapture() sends WM_CAPTURECHANGED and breaks that 2422 * assumption. 2423 */ 2424 ReleaseDragCapture(flags); 2425 2426 return mrConsume; 2427 } 2428 2429 MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y) 2430 { 2431 static AwtComponent* lastComp = NULL; 2432 static int lastX = 0; 2433 static int lastY = 0; 2434 2435 /* 2436 * Only report mouse move and drag events if a move or drag 2437 * actually happened -- Windows sends a WM_MOUSEMOVE in case the 2438 * app wants to modify the cursor. 2439 */ 2440 if (lastComp != this || x != lastX || y != lastY) { 2441 lastComp = this; 2442 lastX = x; 2443 lastY = y; 2444 BOOL extraButtonsEnabled = AwtToolkit::GetInstance().areExtraMouseButtonsEnabled(); 2445 if (((flags & (ALL_MK_BUTTONS)) != 0) || 2446 (extraButtonsEnabled && (flags & (X_BUTTONS)) != 0)) 2447 // if (( extraButtonsEnabled && ( (flags & (ALL_MK_BUTTONS | X_BUTTONS)) != 0 )) || 2448 // ( !extraButtonsEnabled && (((flags & (ALL_MK_BUTTONS)) != 0 )) && ((flags & (X_BUTTONS)) == 0) )) 2449 { 2450 // 6404008 : if Dragged event fired we shouldn't fire 2451 // Clicked event: m_firstDragSent set to TRUE. 2452 // This is a partial backout of 5039416 fix. 2453 MSG msg; 2454 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2455 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_DRAGGED, TimeHelper::getMessageTimeUTC(), x, y, 2456 GetJavaModifiers(), 0, JNI_FALSE, 2457 java_awt_event_MouseEvent_NOBUTTON, &msg); 2458 //dragging means no more CLICKs until next WM_MOUSE_DOWN/WM_MOUSE_UP message sequence 2459 m_mouseButtonClickAllowed = 0; 2460 } else { 2461 MSG msg; 2462 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); 2463 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::getMessageTimeUTC(), x, y, 2464 GetJavaModifiers(), 0, JNI_FALSE, 2465 java_awt_event_MouseEvent_NOBUTTON, &msg); 2466 } 2467 } 2468 2469 return mrConsume; 2470 } 2471 2472 MsgRouting AwtComponent::WmMouseExit(UINT flags, int x, int y) 2473 { 2474 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_EXITED, TimeHelper::getMessageTimeUTC(), x, 2475 y, GetJavaModifiers(), 0, JNI_FALSE); 2476 sm_cursorOn = NULL; 2477 return mrConsume; /* Don't pass our synthetic event on! */ 2478 } 2479 2480 MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, 2481 int wheelRotation) 2482 { 2483 // convert coordinates to be Component-relative, not screen relative 2484 // for wheeling when outside the window, this works similar to 2485 // coordinates during a drag 2486 POINT eventPt; 2487 eventPt.x = x; 2488 eventPt.y = y; 2489 DTRACE_PRINT2(" original coords: %i,%i\n", x, y); 2490 ::ScreenToClient(GetHWnd(), &eventPt); 2491 DTRACE_PRINT2(" new coords: %i,%i\n\n", eventPt.x, eventPt.y); 2492 2493 // set some defaults 2494 jint scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL; 2495 jint scrollLines = 3; 2496 2497 BOOL result; 2498 UINT platformLines; 2499 2500 m_wheelRotationAmount += wheelRotation; 2501 2502 // AWT interprets wheel rotation differently than win32, so we need to 2503 // decode wheel amount. 2504 jint roundedWheelRotation = m_wheelRotationAmount / (-1 * WHEEL_DELTA); 2505 jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA); 2506 2507 MSG msg; 2508 result = ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, 2509 &platformLines, 0); 2510 InitMessage(&msg, lastMessage, MAKEWPARAM(flags, wheelRotation), 2511 MAKELPARAM(x, y)); 2512 2513 if (result) { 2514 if (platformLines == WHEEL_PAGESCROLL) { 2515 scrollType = java_awt_event_MouseWheelEvent_WHEEL_BLOCK_SCROLL; 2516 scrollLines = 1; 2517 } 2518 else { 2519 scrollType = java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL; 2520 scrollLines = platformLines; 2521 } 2522 } 2523 2524 DTRACE_PRINTLN("calling SendMouseWheelEvent"); 2525 2526 SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(), 2527 eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType, 2528 scrollLines, roundedWheelRotation, preciseWheelRotation, &msg); 2529 2530 m_wheelRotationAmount %= WHEEL_DELTA; 2531 // this message could be propagated up to the parent chain 2532 // by the mouse message post processors 2533 return mrConsume; 2534 } 2535 2536 jint AwtComponent::GetKeyLocation(UINT wkey, UINT flags) { 2537 // Rector+Newcomer page 413 2538 // The extended keys are the Alt and Control on the right of 2539 // the space bar, the non-Numpad arrow keys, the non-Numpad 2540 // Insert, PageUp, etc. keys, and the Numpad Divide and Enter keys. 2541 // Note that neither Shift key is extended. 2542 // Although not listed in Rector+Newcomer, both Windows keys 2543 // (91 and 92) are extended keys, the Context Menu key 2544 // (property key or application key - 93) is extended, 2545 // and so is the NumLock key. 2546 2547 // wkey is the wParam, flags is the HIWORD of the lParam 2548 2549 // "Extended" bit is 24th in lParam, so it's 8th in flags = HIWORD(lParam) 2550 BOOL extended = ((1<<8) & flags); 2551 2552 if (IsNumPadKey(wkey, extended)) { 2553 return java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD; 2554 } 2555 2556 switch (wkey) { 2557 case VK_SHIFT: 2558 return AwtComponent::GetShiftKeyLocation(wkey, flags); 2559 case VK_CONTROL: // fall through 2560 case VK_MENU: 2561 if (extended) { 2562 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2563 } else { 2564 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2565 } 2566 case VK_LWIN: 2567 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2568 case VK_RWIN: 2569 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2570 default: 2571 break; 2572 } 2573 2574 // REMIND: if we add keycodes for the windows keys, we'll have to 2575 // include left/right discrimination code for them. 2576 2577 return java_awt_event_KeyEvent_KEY_LOCATION_STANDARD; 2578 } 2579 2580 jint AwtComponent::GetShiftKeyLocation(UINT vkey, UINT flags) 2581 { 2582 // init scancodes to safe values 2583 UINT leftShiftScancode = 0; 2584 UINT rightShiftScancode = 0; 2585 2586 // First 8 bits of flags is the scancode 2587 UINT keyScanCode = flags & 0xFF; 2588 2589 DTRACE_PRINTLN3( 2590 "AwtComponent::GetShiftKeyLocation vkey = %d = 0x%x scan = %d", 2591 vkey, vkey, keyScanCode); 2592 2593 leftShiftScancode = ::MapVirtualKey(VK_LSHIFT, 0); 2594 rightShiftScancode = ::MapVirtualKey(VK_RSHIFT, 0); 2595 2596 if (keyScanCode == leftShiftScancode) { 2597 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2598 } 2599 if (keyScanCode == rightShiftScancode) { 2600 return java_awt_event_KeyEvent_KEY_LOCATION_RIGHT; 2601 } 2602 2603 DASSERT(false); 2604 // Note: the above should not fail on NT (or 2000) 2605 2606 // default value 2607 return java_awt_event_KeyEvent_KEY_LOCATION_LEFT; 2608 } 2609 2610 /* Returns Java extended InputEvent modifieres. 2611 * Since ::GetKeyState returns current state and Java modifiers represent 2612 * state before event, modifier on changed key are inverted. 2613 */ 2614 jint 2615 AwtComponent::GetJavaModifiers() 2616 { 2617 jint modifiers = 0; 2618 2619 if (HIBYTE(::GetKeyState(VK_CONTROL)) != 0) { 2620 modifiers |= java_awt_event_InputEvent_CTRL_DOWN_MASK; 2621 } 2622 if (HIBYTE(::GetKeyState(VK_SHIFT)) != 0) { 2623 modifiers |= java_awt_event_InputEvent_SHIFT_DOWN_MASK; 2624 } 2625 if (HIBYTE(::GetKeyState(VK_MENU)) != 0) { 2626 modifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK; 2627 } 2628 if (HIBYTE(::GetKeyState(VK_MBUTTON)) != 0) { 2629 modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK; 2630 } 2631 if (HIBYTE(::GetKeyState(VK_RBUTTON)) != 0) { 2632 modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK; 2633 } 2634 if (HIBYTE(::GetKeyState(VK_LBUTTON)) != 0) { 2635 modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK; 2636 } 2637 2638 if (HIBYTE(::GetKeyState(VK_XBUTTON1)) != 0) { 2639 modifiers |= masks[3]; 2640 } 2641 if (HIBYTE(::GetKeyState(VK_XBUTTON2)) != 0) { 2642 modifiers |= masks[4]; 2643 } 2644 return modifiers; 2645 } 2646 2647 jint 2648 AwtComponent::GetButton(int mouseButton) 2649 { 2650 /* Mouse buttons are already set correctly for left/right handedness */ 2651 switch(mouseButton) { 2652 case LEFT_BUTTON: 2653 return java_awt_event_MouseEvent_BUTTON1; 2654 case MIDDLE_BUTTON: 2655 return java_awt_event_MouseEvent_BUTTON2; 2656 case RIGHT_BUTTON: 2657 return java_awt_event_MouseEvent_BUTTON3; 2658 case X1_BUTTON: //16 : 2659 //just assign 4 and 5 numbers because MouseEvent class doesn't contain const identifier for them now 2660 return 4; 2661 case X2_BUTTON: //32 2662 return 5; 2663 } 2664 return java_awt_event_MouseEvent_NOBUTTON; 2665 } 2666 2667 UINT 2668 AwtComponent::GetButtonMK(int mouseButton) 2669 { 2670 switch(mouseButton) { 2671 case LEFT_BUTTON: 2672 return MK_LBUTTON; 2673 case MIDDLE_BUTTON: 2674 return MK_MBUTTON; 2675 case RIGHT_BUTTON: 2676 return MK_RBUTTON; 2677 case X1_BUTTON: 2678 return MK_XBUTTON1; 2679 case X2_BUTTON: 2680 return MK_XBUTTON2; 2681 } 2682 return 0; 2683 } 2684 2685 // FIXME: Keyboard related stuff has grown so big and hairy that we 2686 // really need to move it into a class of its own. And, since 2687 // keyboard is a shared resource, AwtComponent is a bad place for it. 2688 2689 // These constants are defined in the Japanese version of VC++5.0, 2690 // but not the US version 2691 #ifndef VK_CONVERT 2692 #define VK_KANA 0x15 2693 #define VK_KANJI 0x19 2694 #define VK_CONVERT 0x1C 2695 #define VK_NONCONVERT 0x1D 2696 #endif 2697 2698 #ifndef VK_XBUTTON1 2699 #define VK_XBUTTON1 0x05 2700 #endif 2701 2702 #ifndef VK_XBUTTON2 2703 #define VK_XBUTTON2 0x06 2704 #endif 2705 2706 typedef struct { 2707 UINT javaKey; 2708 UINT windowsKey; 2709 } KeyMapEntry; 2710 2711 // Static table, arranged more or less spatially. 2712 KeyMapEntry keyMapTable[] = { 2713 // Modifier keys 2714 {java_awt_event_KeyEvent_VK_CAPS_LOCK, VK_CAPITAL}, 2715 {java_awt_event_KeyEvent_VK_SHIFT, VK_SHIFT}, 2716 {java_awt_event_KeyEvent_VK_CONTROL, VK_CONTROL}, 2717 {java_awt_event_KeyEvent_VK_ALT, VK_MENU}, 2718 {java_awt_event_KeyEvent_VK_NUM_LOCK, VK_NUMLOCK}, 2719 2720 // Miscellaneous Windows keys 2721 {java_awt_event_KeyEvent_VK_WINDOWS, VK_LWIN}, 2722 {java_awt_event_KeyEvent_VK_WINDOWS, VK_RWIN}, 2723 {java_awt_event_KeyEvent_VK_CONTEXT_MENU, VK_APPS}, 2724 2725 // Alphabet 2726 {java_awt_event_KeyEvent_VK_A, 'A'}, 2727 {java_awt_event_KeyEvent_VK_B, 'B'}, 2728 {java_awt_event_KeyEvent_VK_C, 'C'}, 2729 {java_awt_event_KeyEvent_VK_D, 'D'}, 2730 {java_awt_event_KeyEvent_VK_E, 'E'}, 2731 {java_awt_event_KeyEvent_VK_F, 'F'}, 2732 {java_awt_event_KeyEvent_VK_G, 'G'}, 2733 {java_awt_event_KeyEvent_VK_H, 'H'}, 2734 {java_awt_event_KeyEvent_VK_I, 'I'}, 2735 {java_awt_event_KeyEvent_VK_J, 'J'}, 2736 {java_awt_event_KeyEvent_VK_K, 'K'}, 2737 {java_awt_event_KeyEvent_VK_L, 'L'}, 2738 {java_awt_event_KeyEvent_VK_M, 'M'}, 2739 {java_awt_event_KeyEvent_VK_N, 'N'}, 2740 {java_awt_event_KeyEvent_VK_O, 'O'}, 2741 {java_awt_event_KeyEvent_VK_P, 'P'}, 2742 {java_awt_event_KeyEvent_VK_Q, 'Q'}, 2743 {java_awt_event_KeyEvent_VK_R, 'R'}, 2744 {java_awt_event_KeyEvent_VK_S, 'S'}, 2745 {java_awt_event_KeyEvent_VK_T, 'T'}, 2746 {java_awt_event_KeyEvent_VK_U, 'U'}, 2747 {java_awt_event_KeyEvent_VK_V, 'V'}, 2748 {java_awt_event_KeyEvent_VK_W, 'W'}, 2749 {java_awt_event_KeyEvent_VK_X, 'X'}, 2750 {java_awt_event_KeyEvent_VK_Y, 'Y'}, 2751 {java_awt_event_KeyEvent_VK_Z, 'Z'}, 2752 2753 // Standard numeric row 2754 {java_awt_event_KeyEvent_VK_0, '0'}, 2755 {java_awt_event_KeyEvent_VK_1, '1'}, 2756 {java_awt_event_KeyEvent_VK_2, '2'}, 2757 {java_awt_event_KeyEvent_VK_3, '3'}, 2758 {java_awt_event_KeyEvent_VK_4, '4'}, 2759 {java_awt_event_KeyEvent_VK_5, '5'}, 2760 {java_awt_event_KeyEvent_VK_6, '6'}, 2761 {java_awt_event_KeyEvent_VK_7, '7'}, 2762 {java_awt_event_KeyEvent_VK_8, '8'}, 2763 {java_awt_event_KeyEvent_VK_9, '9'}, 2764 2765 // Misc key from main block 2766 {java_awt_event_KeyEvent_VK_ENTER, VK_RETURN}, 2767 {java_awt_event_KeyEvent_VK_SPACE, VK_SPACE}, 2768 {java_awt_event_KeyEvent_VK_BACK_SPACE, VK_BACK}, 2769 {java_awt_event_KeyEvent_VK_TAB, VK_TAB}, 2770 {java_awt_event_KeyEvent_VK_ESCAPE, VK_ESCAPE}, 2771 2772 // NumPad with NumLock off & extended block (rectangular) 2773 {java_awt_event_KeyEvent_VK_INSERT, VK_INSERT}, 2774 {java_awt_event_KeyEvent_VK_DELETE, VK_DELETE}, 2775 {java_awt_event_KeyEvent_VK_HOME, VK_HOME}, 2776 {java_awt_event_KeyEvent_VK_END, VK_END}, 2777 {java_awt_event_KeyEvent_VK_PAGE_UP, VK_PRIOR}, 2778 {java_awt_event_KeyEvent_VK_PAGE_DOWN, VK_NEXT}, 2779 {java_awt_event_KeyEvent_VK_CLEAR, VK_CLEAR}, // NumPad 5 2780 2781 // NumPad with NumLock off & extended arrows block (triangular) 2782 {java_awt_event_KeyEvent_VK_LEFT, VK_LEFT}, 2783 {java_awt_event_KeyEvent_VK_RIGHT, VK_RIGHT}, 2784 {java_awt_event_KeyEvent_VK_UP, VK_UP}, 2785 {java_awt_event_KeyEvent_VK_DOWN, VK_DOWN}, 2786 2787 // NumPad with NumLock on: numbers 2788 {java_awt_event_KeyEvent_VK_NUMPAD0, VK_NUMPAD0}, 2789 {java_awt_event_KeyEvent_VK_NUMPAD1, VK_NUMPAD1}, 2790 {java_awt_event_KeyEvent_VK_NUMPAD2, VK_NUMPAD2}, 2791 {java_awt_event_KeyEvent_VK_NUMPAD3, VK_NUMPAD3}, 2792 {java_awt_event_KeyEvent_VK_NUMPAD4, VK_NUMPAD4}, 2793 {java_awt_event_KeyEvent_VK_NUMPAD5, VK_NUMPAD5}, 2794 {java_awt_event_KeyEvent_VK_NUMPAD6, VK_NUMPAD6}, 2795 {java_awt_event_KeyEvent_VK_NUMPAD7, VK_NUMPAD7}, 2796 {java_awt_event_KeyEvent_VK_NUMPAD8, VK_NUMPAD8}, 2797 {java_awt_event_KeyEvent_VK_NUMPAD9, VK_NUMPAD9}, 2798 2799 // NumPad with NumLock on 2800 {java_awt_event_KeyEvent_VK_MULTIPLY, VK_MULTIPLY}, 2801 {java_awt_event_KeyEvent_VK_ADD, VK_ADD}, 2802 {java_awt_event_KeyEvent_VK_SEPARATOR, VK_SEPARATOR}, 2803 {java_awt_event_KeyEvent_VK_SUBTRACT, VK_SUBTRACT}, 2804 {java_awt_event_KeyEvent_VK_DECIMAL, VK_DECIMAL}, 2805 {java_awt_event_KeyEvent_VK_DIVIDE, VK_DIVIDE}, 2806 2807 // Functional keys 2808 {java_awt_event_KeyEvent_VK_F1, VK_F1}, 2809 {java_awt_event_KeyEvent_VK_F2, VK_F2}, 2810 {java_awt_event_KeyEvent_VK_F3, VK_F3}, 2811 {java_awt_event_KeyEvent_VK_F4, VK_F4}, 2812 {java_awt_event_KeyEvent_VK_F5, VK_F5}, 2813 {java_awt_event_KeyEvent_VK_F6, VK_F6}, 2814 {java_awt_event_KeyEvent_VK_F7, VK_F7}, 2815 {java_awt_event_KeyEvent_VK_F8, VK_F8}, 2816 {java_awt_event_KeyEvent_VK_F9, VK_F9}, 2817 {java_awt_event_KeyEvent_VK_F10, VK_F10}, 2818 {java_awt_event_KeyEvent_VK_F11, VK_F11}, 2819 {java_awt_event_KeyEvent_VK_F12, VK_F12}, 2820 {java_awt_event_KeyEvent_VK_F13, VK_F13}, 2821 {java_awt_event_KeyEvent_VK_F14, VK_F14}, 2822 {java_awt_event_KeyEvent_VK_F15, VK_F15}, 2823 {java_awt_event_KeyEvent_VK_F16, VK_F16}, 2824 {java_awt_event_KeyEvent_VK_F17, VK_F17}, 2825 {java_awt_event_KeyEvent_VK_F18, VK_F18}, 2826 {java_awt_event_KeyEvent_VK_F19, VK_F19}, 2827 {java_awt_event_KeyEvent_VK_F20, VK_F20}, 2828 {java_awt_event_KeyEvent_VK_F21, VK_F21}, 2829 {java_awt_event_KeyEvent_VK_F22, VK_F22}, 2830 {java_awt_event_KeyEvent_VK_F23, VK_F23}, 2831 {java_awt_event_KeyEvent_VK_F24, VK_F24}, 2832 2833 {java_awt_event_KeyEvent_VK_PRINTSCREEN, VK_SNAPSHOT}, 2834 {java_awt_event_KeyEvent_VK_SCROLL_LOCK, VK_SCROLL}, 2835 {java_awt_event_KeyEvent_VK_PAUSE, VK_PAUSE}, 2836 {java_awt_event_KeyEvent_VK_CANCEL, VK_CANCEL}, 2837 {java_awt_event_KeyEvent_VK_HELP, VK_HELP}, 2838 2839 // Japanese 2840 {java_awt_event_KeyEvent_VK_CONVERT, VK_CONVERT}, 2841 {java_awt_event_KeyEvent_VK_NONCONVERT, VK_NONCONVERT}, 2842 {java_awt_event_KeyEvent_VK_INPUT_METHOD_ON_OFF, VK_KANJI}, 2843 {java_awt_event_KeyEvent_VK_ALPHANUMERIC, VK_DBE_ALPHANUMERIC}, 2844 {java_awt_event_KeyEvent_VK_KATAKANA, VK_DBE_KATAKANA}, 2845 {java_awt_event_KeyEvent_VK_HIRAGANA, VK_DBE_HIRAGANA}, 2846 {java_awt_event_KeyEvent_VK_FULL_WIDTH, VK_DBE_DBCSCHAR}, 2847 {java_awt_event_KeyEvent_VK_HALF_WIDTH, VK_DBE_SBCSCHAR}, 2848 {java_awt_event_KeyEvent_VK_ROMAN_CHARACTERS, VK_DBE_ROMAN}, 2849 2850 {java_awt_event_KeyEvent_VK_UNDEFINED, 0} 2851 }; 2852 2853 2854 // Dynamic mapping table for OEM VK codes. This table is refilled 2855 // by BuildDynamicKeyMapTable when keyboard layout is switched. 2856 // (see NT4 DDK src/input/inc/vkoem.h for OEM VK_ values). 2857 struct DynamicKeyMapEntry { 2858 UINT windowsKey; // OEM VK codes known in advance 2859 UINT javaKey; // depends on input langauge (kbd layout) 2860 }; 2861 2862 static DynamicKeyMapEntry dynamicKeyMapTable[] = { 2863 {0x00BA, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_1 2864 {0x00BB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PLUS 2865 {0x00BC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_COMMA 2866 {0x00BD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_MINUS 2867 {0x00BE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_PERIOD 2868 {0x00BF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_2 2869 {0x00C0, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_3 2870 {0x00DB, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_4 2871 {0x00DC, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_5 2872 {0x00DD, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_6 2873 {0x00DE, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_7 2874 {0x00DF, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_8 2875 {0x00E2, java_awt_event_KeyEvent_VK_UNDEFINED}, // VK_OEM_102 2876 {0, 0} 2877 }; 2878 2879 2880 2881 // Auxiliary tables used to fill the above dynamic table. We first 2882 // find the character for the OEM VK code using ::MapVirtualKey and 2883 // then go through these auxiliary tables to map it to Java VK code. 2884 2885 struct CharToVKEntry { 2886 WCHAR c; 2887 UINT javaKey; 2888 }; 2889 2890 static const CharToVKEntry charToVKTable[] = { 2891 {L'!', java_awt_event_KeyEvent_VK_EXCLAMATION_MARK}, 2892 {L'"', java_awt_event_KeyEvent_VK_QUOTEDBL}, 2893 {L'#', java_awt_event_KeyEvent_VK_NUMBER_SIGN}, 2894 {L'$', java_awt_event_KeyEvent_VK_DOLLAR}, 2895 {L'&', java_awt_event_KeyEvent_VK_AMPERSAND}, 2896 {L'\'', java_awt_event_KeyEvent_VK_QUOTE}, 2897 {L'(', java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS}, 2898 {L')', java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS}, 2899 {L'*', java_awt_event_KeyEvent_VK_ASTERISK}, 2900 {L'+', java_awt_event_KeyEvent_VK_PLUS}, 2901 {L',', java_awt_event_KeyEvent_VK_COMMA}, 2902 {L'-', java_awt_event_KeyEvent_VK_MINUS}, 2903 {L'.', java_awt_event_KeyEvent_VK_PERIOD}, 2904 {L'/', java_awt_event_KeyEvent_VK_SLASH}, 2905 {L':', java_awt_event_KeyEvent_VK_COLON}, 2906 {L';', java_awt_event_KeyEvent_VK_SEMICOLON}, 2907 {L'<', java_awt_event_KeyEvent_VK_LESS}, 2908 {L'=', java_awt_event_KeyEvent_VK_EQUALS}, 2909 {L'>', java_awt_event_KeyEvent_VK_GREATER}, 2910 {L'@', java_awt_event_KeyEvent_VK_AT}, 2911 {L'[', java_awt_event_KeyEvent_VK_OPEN_BRACKET}, 2912 {L'\\', java_awt_event_KeyEvent_VK_BACK_SLASH}, 2913 {L']', java_awt_event_KeyEvent_VK_CLOSE_BRACKET}, 2914 {L'^', java_awt_event_KeyEvent_VK_CIRCUMFLEX}, 2915 {L'_', java_awt_event_KeyEvent_VK_UNDERSCORE}, 2916 {L'`', java_awt_event_KeyEvent_VK_BACK_QUOTE}, 2917 {L'{', java_awt_event_KeyEvent_VK_BRACELEFT}, 2918 {L'}', java_awt_event_KeyEvent_VK_BRACERIGHT}, 2919 {0x00A1, java_awt_event_KeyEvent_VK_INVERTED_EXCLAMATION_MARK}, 2920 {0x20A0, java_awt_event_KeyEvent_VK_EURO_SIGN}, // ???? 2921 {0,0} 2922 }; 2923 2924 // For dead accents some layouts return ASCII punctuation, while some 2925 // return spacing accent chars, so both should be listed. NB: MS docs 2926 // say that conversion routings return spacing accent character, not 2927 // combining. 2928 static const CharToVKEntry charToDeadVKTable[] = { 2929 {L'`', java_awt_event_KeyEvent_VK_DEAD_GRAVE}, 2930 {L'\'', java_awt_event_KeyEvent_VK_DEAD_ACUTE}, 2931 {0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, 2932 {L'^', java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX}, 2933 {L'~', java_awt_event_KeyEvent_VK_DEAD_TILDE}, 2934 {0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE}, 2935 {0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON}, 2936 {0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE}, 2937 {0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT}, 2938 {L'"', java_awt_event_KeyEvent_VK_DEAD_DIAERESIS}, 2939 {0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS}, 2940 {0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING}, 2941 {0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE}, 2942 {0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON}, // aka hacek 2943 {L',', java_awt_event_KeyEvent_VK_DEAD_CEDILLA}, 2944 {0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA}, 2945 {0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK}, 2946 {0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA}, // ASCII ??? 2947 {0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND}, 2948 {0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND}, 2949 {0,0} 2950 }; 2951 2952 // The full map of the current keyboard state including 2953 // windows virtual key, scancode, java virtual key, and unicode 2954 // for this key sans modifiers. 2955 // All but first element may be 0. 2956 // XXX in the update releases this is an addition to the unchanged existing code 2957 struct DynPrimaryKeymapEntry { 2958 UINT wkey; 2959 UINT scancode; 2960 UINT jkey; 2961 WCHAR unicode; 2962 }; 2963 2964 static DynPrimaryKeymapEntry dynPrimaryKeymap[256]; 2965 2966 void 2967 AwtComponent::InitDynamicKeyMapTable() 2968 { 2969 static BOOL kbdinited = FALSE; 2970 2971 if (!kbdinited) { 2972 AwtComponent::BuildDynamicKeyMapTable(); 2973 // We cannot build it here since JNI is not available yet: 2974 //AwtComponent::BuildPrimaryDynamicTable(); 2975 kbdinited = TRUE; 2976 } 2977 } 2978 2979 void 2980 AwtComponent::BuildDynamicKeyMapTable() 2981 { 2982 HKL hkl = GetKeyboardLayout(); 2983 2984 DTRACE_PRINTLN2("Building dynamic VK mapping tables: HKL = %08X (CP%d)", 2985 hkl, AwtComponent::GetCodePage()); 2986 2987 // Will need this to reset layout after dead keys. 2988 UINT spaceScanCode = ::MapVirtualKeyEx(VK_SPACE, 0, hkl); 2989 2990 // Entries in dynamic table that maps between Java VK and Windows 2991 // VK are built in three steps: 2992 // 1. Map windows VK to ANSI character (cannot map to unicode 2993 // directly, since ::ToUnicode is not implemented on win9x) 2994 // 2. Convert ANSI char to Unicode char 2995 // 3. Map Unicode char to Java VK via two auxilary tables. 2996 2997 for (DynamicKeyMapEntry *dynamic = dynamicKeyMapTable; 2998 dynamic->windowsKey != 0; 2999 ++dynamic) 3000 { 3001 // Defaults to VK_UNDEFINED 3002 dynamic->javaKey = java_awt_event_KeyEvent_VK_UNDEFINED; 3003 3004 BYTE kbdState[AwtToolkit::KB_STATE_SIZE]; 3005 AwtToolkit::GetKeyboardState(kbdState); 3006 3007 kbdState[dynamic->windowsKey] |= 0x80; // Press the key. 3008 3009 // Unpress modifiers, since they are most likely pressed as 3010 // part of the keyboard switching shortcut. 3011 kbdState[VK_CONTROL] &= ~0x80; 3012 kbdState[VK_SHIFT] &= ~0x80; 3013 kbdState[VK_MENU] &= ~0x80; 3014 3015 char cbuf[2] = { '\0', '\0'}; 3016 UINT scancode = ::MapVirtualKeyEx(dynamic->windowsKey, 0, hkl); 3017 int nchars = ::ToAsciiEx(dynamic->windowsKey, scancode, kbdState, 3018 (WORD*)cbuf, 0, hkl); 3019 3020 // Auxiliary table used to map Unicode character to Java VK. 3021 // Will assign a different table for dead keys (below). 3022 const CharToVKEntry *charMap = charToVKTable; 3023 3024 if (nchars < 0) { // Dead key 3025 // Use a different table for dead chars since different layouts 3026 // return different characters for the same dead key. 3027 charMap = charToDeadVKTable; 3028 3029 // We also need to reset layout so that next translation 3030 // is unaffected by the dead status. We do this by 3031 // translating <SPACE> key. 3032 kbdState[dynamic->windowsKey] &= ~0x80; 3033 kbdState[VK_SPACE] |= 0x80; 3034 3035 char junkbuf[2] = { '\0', '\0'}; 3036 ::ToAsciiEx(VK_SPACE, spaceScanCode, kbdState, 3037 (WORD*)junkbuf, 0, hkl); 3038 } 3039 3040 #ifdef DEBUG 3041 if (nchars == 0) { 3042 DTRACE_PRINTLN1("VK 0x%02X -> cannot convert to ANSI char", 3043 dynamic->windowsKey); 3044 continue; 3045 } 3046 else if (nchars > 1) { // can't happen, see reset code below 3047 DTRACE_PRINTLN3("VK 0x%02X -> converted to <0x%02X,0x%02X>", 3048 dynamic->windowsKey, 3049 (UCHAR)cbuf[0], (UCHAR)cbuf[1]); 3050 continue; 3051 } 3052 #endif 3053 3054 WCHAR ucbuf[2] = { L'\0', L'\0' }; 3055 int nconverted = ::MultiByteToWideChar(AwtComponent::GetCodePage(), 0, 3056 cbuf, 1, ucbuf, 2); 3057 #ifdef DEBUG 3058 if (nconverted < 0) { 3059 DTRACE_PRINTLN3("VK 0x%02X -> ANSI 0x%02X -> MultiByteToWideChar failed (0x%X)", 3060 dynamic->windowsKey, (UCHAR)cbuf[0], 3061 ::GetLastError()); 3062 continue; 3063 } 3064 #endif 3065 3066 WCHAR uc = ucbuf[0]; 3067 for (const CharToVKEntry *map = charMap; map->c != 0; ++map) { 3068 if (uc == map->c) { 3069 dynamic->javaKey = map->javaKey; 3070 break; 3071 } 3072 } 3073 3074 DTRACE_PRINTLN4("VK 0x%02X -> ANSI 0x%02X -> U+%04X -> Java VK 0x%X", 3075 dynamic->windowsKey, (UCHAR)cbuf[0], (UINT)ucbuf[0], 3076 dynamic->javaKey); 3077 } // for each VK_OEM_* 3078 } 3079 3080 3081 static BOOL isKanaLockAvailable() 3082 { 3083 // This method is to determine whether the Kana Lock feature is 3084 // available on the attached keyboard. Kana Lock feature does not 3085 // necessarily require that the real KANA keytop is available on 3086 // keyboard, so using MapVirtualKey(VK_KANA) is not sufficient for testing. 3087 // Instead of that we regard it as Japanese keyboard (w/ Kana Lock) if :- 3088 // 3089 // - the keyboard layout is Japanese (VK_KANA has the same value as VK_HANGUL) 3090 // - the keyboard is Japanese keyboard (keyboard type == 7). 3091 return (LOWORD(GetKeyboardLayout(0)) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) 3092 && (GetKeyboardType(0) == 7); 3093 } 3094 3095 void AwtComponent::JavaKeyToWindowsKey(UINT javaKey, 3096 UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey) 3097 { 3098 // Handle the few cases where a Java VK code corresponds to a Windows 3099 // key/modifier combination or applies only to specific keyboard layouts 3100 switch (javaKey) { 3101 case java_awt_event_KeyEvent_VK_ALL_CANDIDATES: 3102 *windowsKey = VK_CONVERT; 3103 *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK; 3104 return; 3105 case java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE: 3106 *windowsKey = VK_CONVERT; 3107 *modifiers = java_awt_event_InputEvent_SHIFT_DOWN_MASK; 3108 return; 3109 case java_awt_event_KeyEvent_VK_CODE_INPUT: 3110 *windowsKey = VK_DBE_ALPHANUMERIC; 3111 *modifiers = java_awt_event_InputEvent_ALT_DOWN_MASK; 3112 return; 3113 case java_awt_event_KeyEvent_VK_KANA_LOCK: 3114 if (isKanaLockAvailable()) { 3115 *windowsKey = VK_KANA; 3116 *modifiers = java_awt_event_InputEvent_CTRL_DOWN_MASK; 3117 return; 3118 } 3119 } 3120 3121 // for the general case, use a bi-directional table 3122 for (int i = 0; keyMapTable[i].windowsKey != 0; i++) { 3123 if (keyMapTable[i].javaKey == javaKey) { 3124 *windowsKey = keyMapTable[i].windowsKey; 3125 *modifiers = 0; 3126 return; 3127 } 3128 } 3129 3130 // Bug 4766655 3131 // Two Windows keys could map to the same Java key, so 3132 // give preference to the originalWindowsKey if it is 3133 // specified (not IGNORE_KEY). 3134 if (originalWindowsKey == IGNORE_KEY) { 3135 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3136 if (dynamicKeyMapTable[j].javaKey == javaKey) { 3137 *windowsKey = dynamicKeyMapTable[j].windowsKey; 3138 *modifiers = 0; 3139 return; 3140 } 3141 } 3142 } else { 3143 BOOL found = false; 3144 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3145 if (dynamicKeyMapTable[j].javaKey == javaKey) { 3146 *windowsKey = dynamicKeyMapTable[j].windowsKey; 3147 *modifiers = 0; 3148 found = true; 3149 if (*windowsKey == originalWindowsKey) { 3150 return; /* if ideal case found return, else keep looking */ 3151 } 3152 } 3153 } 3154 if (found) { 3155 return; 3156 } 3157 } 3158 3159 *windowsKey = 0; 3160 *modifiers = 0; 3161 return; 3162 } 3163 3164 UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey) 3165 3166 { 3167 // Handle the few cases where we need to take the modifier into 3168 // consideration for the Java VK code or where we have to take the keyboard 3169 // layout into consideration so that function keys can get 3170 // recognized in a platform-independent way. 3171 switch (windowsKey) { 3172 case VK_CONVERT: 3173 if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) { 3174 return java_awt_event_KeyEvent_VK_ALL_CANDIDATES; 3175 } 3176 if ((modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) != 0) { 3177 return java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE; 3178 } 3179 break; 3180 case VK_DBE_ALPHANUMERIC: 3181 if ((modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) != 0) { 3182 return java_awt_event_KeyEvent_VK_CODE_INPUT; 3183 } 3184 break; 3185 case VK_KANA: 3186 if (isKanaLockAvailable()) { 3187 return java_awt_event_KeyEvent_VK_KANA_LOCK; 3188 } 3189 break; 3190 }; 3191 3192 // check dead key 3193 if (isDeadKey) { 3194 for (int i = 0; charToDeadVKTable[i].c != 0; i++) { 3195 if (charToDeadVKTable[i].c == character) { 3196 return charToDeadVKTable[i].javaKey; 3197 } 3198 } 3199 } 3200 3201 // for the general case, use a bi-directional table 3202 for (int i = 0; keyMapTable[i].windowsKey != 0; i++) { 3203 if (keyMapTable[i].windowsKey == windowsKey) { 3204 return keyMapTable[i].javaKey; 3205 } 3206 } 3207 3208 for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) { 3209 if (dynamicKeyMapTable[j].windowsKey == windowsKey) { 3210 if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) { 3211 return dynamicKeyMapTable[j].javaKey; 3212 }else{ 3213 break; 3214 } 3215 } 3216 } 3217 3218 return java_awt_event_KeyEvent_VK_UNDEFINED; 3219 } 3220 3221 BOOL AwtComponent::IsNavigationKey(UINT wkey) { 3222 switch (wkey) { 3223 case VK_END: 3224 case VK_PRIOR: // PageUp 3225 case VK_NEXT: // PageDown 3226 case VK_HOME: 3227 case VK_LEFT: 3228 case VK_UP: 3229 case VK_RIGHT: 3230 case VK_DOWN: 3231 return TRUE; 3232 } 3233 return FALSE; 3234 } 3235 3236 // determine if a key is a numpad key (distinguishes the numpad 3237 // arrow keys from the non-numpad arrow keys, for example). 3238 BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended) 3239 { 3240 // Note: scancodes are the same for the numpad arrow keys and 3241 // the non-numpad arrow keys (also for PageUp, etc.). 3242 // The scancodes for the numpad divide and the non-numpad slash 3243 // are the same, but the wparams are different 3244 3245 DTRACE_PRINTLN3("AwtComponent::IsNumPadKey vkey = %d = 0x%x extended = %d", 3246 vkey, vkey, extended); 3247 3248 switch (vkey) { 3249 case VK_CLEAR: // numpad 5 with numlock off 3250 case VK_NUMPAD0: 3251 case VK_NUMPAD1: 3252 case VK_NUMPAD2: 3253 case VK_NUMPAD3: 3254 case VK_NUMPAD4: 3255 case VK_NUMPAD5: 3256 case VK_NUMPAD6: 3257 case VK_NUMPAD7: 3258 case VK_NUMPAD8: 3259 case VK_NUMPAD9: 3260 case VK_MULTIPLY: 3261 case VK_ADD: 3262 case VK_SEPARATOR: // numpad , not on US kbds 3263 case VK_SUBTRACT: 3264 case VK_DECIMAL: 3265 case VK_DIVIDE: 3266 case VK_NUMLOCK: 3267 return TRUE; 3268 break; 3269 case VK_END: 3270 case VK_PRIOR: // PageUp 3271 case VK_NEXT: // PageDown 3272 case VK_HOME: 3273 case VK_LEFT: 3274 case VK_UP: 3275 case VK_RIGHT: 3276 case VK_DOWN: 3277 case VK_INSERT: 3278 case VK_DELETE: 3279 // extended if non-numpad 3280 return (!extended); 3281 break; 3282 case VK_RETURN: // extended if on numpad 3283 return (extended); 3284 break; 3285 default: 3286 break; 3287 } 3288 3289 return FALSE; 3290 } 3291 static void 3292 resetKbdState( BYTE kstate[256]) { 3293 BYTE tmpState[256]; 3294 WCHAR wc[2]; 3295 memmove(tmpState, kstate, sizeof(kstate)); 3296 tmpState[VK_SHIFT] = 0; 3297 tmpState[VK_CONTROL] = 0; 3298 tmpState[VK_MENU] = 0; 3299 3300 ::ToUnicodeEx(VK_SPACE,::MapVirtualKey(VK_SPACE, 0), tmpState, wc, 2, 0, GetKeyboardLayout(0)); 3301 } 3302 3303 // XXX in the update releases this is an addition to the unchanged existing code 3304 // After the call, a table will have a unicode associated with a windows virtual keycode 3305 // sans modifiers. With some further simplification, one can 3306 // derive java keycode from it, and anyway we will pass this unicode value 3307 // all the way up in a comment to a KeyEvent. 3308 void 3309 AwtComponent::BuildPrimaryDynamicTable() { 3310 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3311 // XXX: how about that? 3312 //CriticalSection::Lock l(GetLock()); 3313 //if (GetPeer(env) == NULL) { 3314 // /* event received during termination. */ 3315 // return; 3316 //} 3317 3318 HKL hkl = GetKeyboardLayout(); 3319 UINT sc = 0; 3320 BYTE kbdState[AwtToolkit::KB_STATE_SIZE]; 3321 memset(kbdState, 0, sizeof (kbdState)); 3322 3323 // Use JNI call to obtain java key code. We should keep a list 3324 // of currently available keycodes in a single place. 3325 static jclass extKeyCodesCls; 3326 if( extKeyCodesCls == NULL) { 3327 jclass extKeyCodesClsLocal = env->FindClass("sun/awt/ExtendedKeyCodes"); 3328 DASSERT(extKeyCodesClsLocal); 3329 CHECK_NULL(extKeyCodesClsLocal); 3330 extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal); 3331 env->DeleteLocalRef(extKeyCodesClsLocal); 3332 } 3333 static jmethodID getExtendedKeyCodeForChar; 3334 if (getExtendedKeyCodeForChar == NULL) { 3335 getExtendedKeyCodeForChar = 3336 env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I"); 3337 DASSERT(getExtendedKeyCodeForChar); 3338 CHECK_NULL(getExtendedKeyCodeForChar); 3339 } 3340 jint extJKC; //extended Java key code 3341 3342 for (UINT i = 0; i < 256; i++) { 3343 dynPrimaryKeymap[i].wkey = i; 3344 dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED; 3345 dynPrimaryKeymap[i].unicode = 0; 3346 3347 if ((sc = MapVirtualKey (i, 0)) == 0) { 3348 dynPrimaryKeymap[i].scancode = 0; 3349 continue; 3350 } 3351 dynPrimaryKeymap[i].scancode = sc; 3352 3353 // XXX process cases like VK_SHIFT etc. 3354 kbdState[i] = 0x80; // "key pressed". 3355 WCHAR wc[16]; 3356 int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl); 3357 if (k == 1) { 3358 // unicode 3359 dynPrimaryKeymap[i].unicode = wc[0]; 3360 if (dynPrimaryKeymap[i].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3361 // Convert unicode to java keycode. 3362 //dynPrimaryKeymap[i].jkey = ((UINT)(wc[0]) + 0x01000000); 3363 // 3364 //XXX If this key in on the keypad, we should force a special value equal to 3365 //XXX an old java keycode: but how to say if it is a keypad key? 3366 //XXX We'll do it in WmKeyUp/Down. 3367 extJKC = env->CallStaticIntMethod(extKeyCodesCls, 3368 getExtendedKeyCodeForChar, (jint)(wc[0])); 3369 dynPrimaryKeymap[i].jkey = extJKC; 3370 } 3371 }else if (k == -1) { 3372 // dead key: use charToDeadVKTable 3373 dynPrimaryKeymap[i].unicode = wc[0]; 3374 resetKbdState( kbdState ); 3375 for (const CharToVKEntry *map = charToDeadVKTable; map->c != 0; ++map) { 3376 if (wc[0] == map->c) { 3377 dynPrimaryKeymap[i].jkey = map->javaKey; 3378 break; 3379 } 3380 } 3381 } else if (k == 0) { 3382 // reset 3383 resetKbdState( kbdState ); 3384 }else { 3385 // k > 1: this key does generate multiple characters. Ignore it. 3386 // An example: Arabic Lam and Alef ligature. 3387 // There will be no extended keycode and thus shortcuts for this key. 3388 // XXX shouldn't we reset the kbd state? 3389 #ifdef DEBUG 3390 DTRACE_PRINTLN2("wkey 0x%02X (%d)", i,i); 3391 #endif 3392 } 3393 kbdState[i] = 0; // "key unpressed" 3394 } 3395 } 3396 void 3397 AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers) 3398 { 3399 if( wkey && wkey < 256 ) { 3400 if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) { 3401 // At the creation time, 3402 // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /" 3403 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3404 } 3405 if(dynPrimaryKeymap[wkey].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3406 // E.g. it is non-unicode key 3407 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3408 } 3409 } 3410 } 3411 3412 UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey) 3413 { 3414 static Hashtable transTable("VKEY translations"); 3415 static Hashtable deadKeyFlagTable("Dead Key Flags"); 3416 isDeadKey = FALSE; 3417 3418 // Try to translate using last saved translation 3419 if (ops == LOAD) { 3420 void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3421 void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3422 if (value != NULL) { 3423 isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag)); 3424 return static_cast<UINT>(reinterpret_cast<INT_PTR>(value)); 3425 } 3426 } 3427 3428 // If the windows key is a return, wkey will equal 13 ('\r') 3429 // In this case, we want to return 10 ('\n') 3430 // Since ToAscii would convert VK_RETURN to '\r', we need 3431 // to have a special case here. 3432 if (wkey == VK_RETURN) 3433 return '\n'; 3434 3435 // high order bit in keyboardState indicates whether the key is down 3436 static const BYTE KEY_STATE_DOWN = 0x80; 3437 BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 3438 AwtToolkit::GetKeyboardState(keyboardState); 3439 3440 // apply modifiers to keyboard state if necessary 3441 if (modifiers) { 3442 BOOL shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK; 3443 BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK; 3444 BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK; 3445 3446 // Windows treats AltGr as Ctrl+Alt 3447 if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) { 3448 altIsDown = TRUE; 3449 ctrlIsDown = TRUE; 3450 } 3451 3452 if (shiftIsDown) { 3453 keyboardState[VK_SHIFT] |= KEY_STATE_DOWN; 3454 } 3455 3456 // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715) 3457 // Here we try to resolve a conflict with ::ToAsciiEx's translating 3458 // ALT+number key combinations. kdm@sarc.spb.su 3459 // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail. 3460 if( IsNavigationKey(wkey) ) { 3461 keyboardState[VK_MENU] &= ~KEY_STATE_DOWN; 3462 } 3463 3464 if (ctrlIsDown) 3465 { 3466 if (altIsDown) { 3467 // bugid 4215009: don't mess with AltGr == Ctrl + Alt 3468 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3469 } 3470 else { 3471 // bugid 4098210: old event model doesn't have KEY_TYPED 3472 // events, so try to provide a meaningful character for 3473 // Ctrl+<key>. Take Ctrl into account only when we know 3474 // that Ctrl+<key> will be an ASCII control. Ignore by 3475 // default. 3476 keyboardState[VK_CONTROL] &= ~KEY_STATE_DOWN; 3477 3478 // Letters have Ctrl+<letter> counterparts. According to 3479 // <winuser.h> VK_A through VK_Z are the same as ASCII 3480 // 'A' through 'Z'. 3481 if (wkey >= 'A' && wkey <= 'Z') { 3482 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3483 } 3484 else { 3485 // Non-letter controls 033 to 037 are: 3486 // ^[ (ESC), ^\ (FS), ^] (GS), ^^ (RS), and ^_ (US) 3487 3488 // Shift state bits returned by ::VkKeyScan in HIBYTE 3489 static const UINT _VKS_SHIFT_MASK = 0x01; 3490 static const UINT _VKS_CTRL_MASK = 0x02; 3491 static const UINT _VKS_ALT_MASK = 0x04; 3492 3493 // Check to see whether there is a meaningful translation 3494 TCHAR ch; 3495 short vk; 3496 for (ch = _T('\033'); ch < _T('\040'); ch++) { 3497 vk = ::VkKeyScan(ch); 3498 if (wkey == LOBYTE(vk)) { 3499 UINT shiftState = HIBYTE(vk); 3500 if ((shiftState & _VKS_CTRL_MASK) || 3501 (!(shiftState & _VKS_SHIFT_MASK) 3502 == !shiftIsDown)) 3503 { 3504 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3505 } 3506 break; 3507 } 3508 } 3509 } 3510 } // ctrlIsDown && altIsDown 3511 } // ctrlIsDown 3512 } // modifiers 3513 3514 // instead of creating our own conversion tables, I'll let Win32 3515 // convert the character for me. 3516 WORD wChar[2]; 3517 UINT scancode = ::MapVirtualKey(wkey, 0); 3518 int converted = ::ToUnicodeEx(wkey, scancode, keyboardState, 3519 wChar, 2, 0, GetKeyboardLayout()); 3520 3521 UINT translation; 3522 BOOL deadKeyFlag = (converted == 2); 3523 3524 // Dead Key 3525 if (converted < 0) { 3526 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3527 } else 3528 // No translation available -- try known conversions or else punt. 3529 if (converted == 0) { 3530 if (wkey == VK_DELETE) { 3531 translation = '\177'; 3532 } else 3533 if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) { 3534 translation = '0' + wkey - VK_NUMPAD0; 3535 } else { 3536 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3537 } 3538 } else 3539 // the caller expects a Unicode character. 3540 if (converted > 0) { 3541 translation = wChar[0]; 3542 } 3543 if (ops == SAVE) { 3544 transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3545 reinterpret_cast<void*>(static_cast<INT_PTR>(translation))); 3546 if (deadKeyFlag) { 3547 deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3548 reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag))); 3549 } else { 3550 deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3551 } 3552 } 3553 3554 isDeadKey = deadKeyFlag; 3555 return translation; 3556 } 3557 3558 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, 3559 UINT flags, BOOL system) 3560 { 3561 // VK_PROCESSKEY is a special value which means 3562 // "Current IME wants to consume this KeyEvent" 3563 // Real key code is saved by IMM32.DLL and can be retrieved by 3564 // calling ImmGetVirtualKey(); 3565 if (wkey == VK_PROCESSKEY) { 3566 return mrDoDefault; 3567 } 3568 MSG msg; 3569 InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN), 3570 wkey, MAKELPARAM(repCnt, flags)); 3571 3572 UINT modifiers = GetJavaModifiers(); 3573 jint keyLocation = GetKeyLocation(wkey, flags); 3574 BOOL isDeadKey = FALSE; 3575 UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey); 3576 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3577 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3578 3579 3580 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED, 3581 TimeHelper::windowsToUTC(msg.time), jkey, character, 3582 modifiers, keyLocation, (jlong)wkey, &msg); 3583 3584 // bugid 4724007: Windows does not create a WM_CHAR for the Del key 3585 // for some reason, so we need to create the KEY_TYPED event on the 3586 // WM_KEYDOWN. Use null msg so the character doesn't get sent back 3587 // to the native window for processing (this event is synthesized 3588 // for Java - we don't want Windows trying to process it). 3589 if (jkey == java_awt_event_KeyEvent_VK_DELETE) { 3590 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3591 TimeHelper::windowsToUTC(msg.time), 3592 java_awt_event_KeyEvent_VK_UNDEFINED, 3593 character, modifiers, 3594 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0); 3595 } 3596 3597 return mrConsume; 3598 } 3599 3600 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt, 3601 UINT flags, BOOL system) 3602 { 3603 3604 // VK_PROCESSKEY is a special value which means 3605 // "Current IME wants to consume this KeyEvent" 3606 // Real key code is saved by IMM32.DLL and can be retrieved by 3607 // calling ImmGetVirtualKey(); 3608 if (wkey == VK_PROCESSKEY) { 3609 return mrDoDefault; 3610 } 3611 MSG msg; 3612 InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP), 3613 wkey, MAKELPARAM(repCnt, flags)); 3614 3615 UINT modifiers = GetJavaModifiers(); 3616 jint keyLocation = GetKeyLocation(wkey, flags); 3617 BOOL isDeadKey = FALSE; 3618 UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey); 3619 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3620 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3621 3622 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED, 3623 TimeHelper::windowsToUTC(msg.time), jkey, character, 3624 modifiers, keyLocation, (jlong)wkey, &msg); 3625 return mrConsume; 3626 } 3627 3628 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout) 3629 { 3630 // Normally we would be able to use charset and TranslateCharSetInfo 3631 // to get a code page that should be associated with this keyboard 3632 // layout change. However, there seems to be an NT 4.0 bug associated 3633 // with the WM_INPUTLANGCHANGE message, which makes the charset parameter 3634 // unreliable, especially on Asian systems. Our workaround uses the 3635 // keyboard layout handle instead. 3636 m_hkl = hKeyboardLayout; 3637 m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID 3638 m_CodePage = LangToCodePage(m_idLang); 3639 BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM 3640 BuildPrimaryDynamicTable(); 3641 return mrConsume; // do not propagate to children 3642 } 3643 3644 // Convert Language ID to CodePage 3645 UINT AwtComponent::LangToCodePage(LANGID idLang) 3646 { 3647 TCHAR strCodePage[MAX_ACP_STR_LEN]; 3648 // use the LANGID to create a LCID 3649 LCID idLocale = MAKELCID(idLang, SORT_DEFAULT); 3650 // get the ANSI code page associated with this locale 3651 if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE, strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 ) 3652 return _ttoi(strCodePage); 3653 else 3654 return GetACP(); 3655 } 3656 3657 3658 MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL system) 3659 { 3660 // We will simply create Java events here. 3661 WCHAR unicodeChar = character; 3662 MSG msg; 3663 InitMessage(&msg, WM_IME_CHAR, character, 3664 MAKELPARAM(repCnt, flags)); 3665 3666 jint modifiers = GetJavaModifiers(); 3667 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3668 TimeHelper::windowsToUTC(msg.time), 3669 java_awt_event_KeyEvent_VK_UNDEFINED, 3670 unicodeChar, modifiers, 3671 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3672 &msg); 3673 return mrConsume; 3674 } 3675 3676 MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags, 3677 BOOL system) 3678 { 3679 // Will only get WmChar messages with DBCS if we create them for 3680 // an Edit class in the WmForwardChar method. These synthesized 3681 // DBCS chars are ok to pass on directly to the default window 3682 // procedure. They've already been filtered through the Java key 3683 // event queue. We will never get the trail byte since the edit 3684 // class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR, 3685 // PM_REMOVE). I would like to be able to pass this character off 3686 // via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to 3687 // like that. 3688 3689 // We will simply create Java events here. 3690 UINT message = system ? WM_SYSCHAR : WM_CHAR; 3691 3692 // The Alt modifier is reported in the 29th bit of the lParam, 3693 // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)). 3694 bool alt_is_down = (flags & (1<<13)) != 0; 3695 3696 // Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu 3697 // We should not pass this particular combination to Java. 3698 3699 if (system && alt_is_down) { 3700 if (character == VK_SPACE) { 3701 return mrDoDefault; 3702 } 3703 } 3704 3705 // If this is a WM_CHAR (non-system) message, then the Alt flag 3706 // indicates that the character was typed using an AltGr key 3707 // (which Windows treats as Ctrl+Alt), so in this case we do NOT 3708 // pass the Ctrl and Alt modifiers to Java, but instead we 3709 // replace them with Java's AltGraph modifier. Note: the AltGraph 3710 // modifier does not exist in 1.1.x releases. 3711 jint modifiers = GetJavaModifiers(); 3712 if (!system && alt_is_down) { 3713 // character typed with AltGraph 3714 modifiers &= ~(java_awt_event_InputEvent_ALT_DOWN_MASK 3715 | java_awt_event_InputEvent_CTRL_DOWN_MASK); 3716 modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK; 3717 } 3718 3719 WCHAR unicodeChar = character; 3720 3721 // Kludge: Combine pending single byte with this char for some Chinese IMEs 3722 if (m_PendingLeadByte != 0) { 3723 character = (m_PendingLeadByte & 0x00ff) | (character << 8); 3724 m_PendingLeadByte = 0; 3725 ::MultiByteToWideChar(GetCodePage(), 0, (CHAR*)&character, 2, 3726 &unicodeChar, 1); 3727 } 3728 3729 if (unicodeChar == VK_RETURN) { 3730 // Enter key generates \r in windows, but \n is required in java 3731 unicodeChar = java_awt_event_KeyEvent_VK_ENTER; 3732 } 3733 MSG msg; 3734 InitMessage(&msg, message, character, 3735 MAKELPARAM(repCnt, flags)); 3736 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3737 TimeHelper::windowsToUTC(msg.time), 3738 java_awt_event_KeyEvent_VK_UNDEFINED, 3739 unicodeChar, modifiers, 3740 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3741 &msg); 3742 return mrConsume; 3743 } 3744 3745 MsgRouting AwtComponent::WmForwardChar(WCHAR character, LPARAM lParam, 3746 BOOL synthetic) 3747 { 3748 // just post WM_CHAR with unicode key value 3749 DefWindowProc(WM_CHAR, (WPARAM)character, lParam); 3750 return mrConsume; 3751 } 3752 3753 MsgRouting AwtComponent::WmPaste() 3754 { 3755 return mrDoDefault; 3756 } 3757 3758 // support IME Composition messages 3759 void AwtComponent::SetCompositionWindow(RECT& r) 3760 { 3761 HWND hwnd = ImmGetHWnd(); 3762 HIMC hIMC = ImmGetContext(hwnd); 3763 if (hIMC == NULL) { 3764 return; 3765 } 3766 COMPOSITIONFORM cf = {CFS_DEFAULT, {0, 0}, {0, 0, 0, 0}}; 3767 ImmSetCompositionWindow(hIMC, &cf); 3768 ImmReleaseContext(hwnd, hIMC); 3769 } 3770 3771 void AwtComponent::OpenCandidateWindow(int x, int y) 3772 { 3773 UINT bits = 1; 3774 RECT rc; 3775 GetWindowRect(GetHWnd(), &rc); 3776 3777 for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) { 3778 if ( m_bitsCandType & bits ) 3779 SetCandidateWindow(iCandType, x-rc.left, y-rc.top); 3780 } 3781 if (m_bitsCandType != 0) { 3782 // REMIND: is there any chance GetProxyFocusOwner() returns NULL here? 3783 ::DefWindowProc(ImmGetHWnd(), 3784 WM_IME_NOTIFY, IMN_OPENCANDIDATE, m_bitsCandType); 3785 } 3786 } 3787 3788 void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) 3789 { 3790 HWND hwnd = ImmGetHWnd(); 3791 HIMC hIMC = ImmGetContext(hwnd); 3792 CANDIDATEFORM cf; 3793 cf.dwIndex = iCandType; 3794 cf.dwStyle = CFS_CANDIDATEPOS; 3795 cf.ptCurrentPos.x = x; 3796 cf.ptCurrentPos.y = y; 3797 3798 ImmSetCandidateWindow(hIMC, &cf); 3799 ImmReleaseContext(hwnd, hIMC); 3800 } 3801 3802 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam) 3803 { 3804 // If the Windows input context is disabled, do not let Windows 3805 // display any UIs. 3806 HWND hwnd = ImmGetHWnd(); 3807 HIMC hIMC = ImmGetContext(hwnd); 3808 if (hIMC == NULL) { 3809 *lplParam = 0; 3810 return mrDoDefault; 3811 } 3812 ImmReleaseContext(hwnd, hIMC); 3813 3814 if (fSet) { 3815 LPARAM lParam = *lplParam; 3816 if (!m_useNativeCompWindow) { 3817 // stop to draw native composing window. 3818 *lplParam &= ~ISC_SHOWUICOMPOSITIONWINDOW; 3819 } 3820 } 3821 return mrDoDefault; 3822 } 3823 3824 MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType) 3825 { 3826 if (!m_useNativeCompWindow && subMsg == IMN_OPENCANDIDATE) { 3827 m_bitsCandType = bitsCandType; 3828 InquireCandidatePosition(); 3829 return mrConsume; 3830 } 3831 return mrDoDefault; 3832 } 3833 3834 MsgRouting AwtComponent::WmImeStartComposition() 3835 { 3836 if (m_useNativeCompWindow) { 3837 RECT rc; 3838 ::GetClientRect(GetHWnd(), &rc); 3839 SetCompositionWindow(rc); 3840 return mrDoDefault; 3841 } else 3842 return mrConsume; 3843 } 3844 3845 MsgRouting AwtComponent::WmImeEndComposition() 3846 { 3847 if (m_useNativeCompWindow) return mrDoDefault; 3848 3849 SendInputMethodEvent( 3850 java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3851 NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0 ); 3852 return mrConsume; 3853 } 3854 3855 MsgRouting AwtComponent::WmImeComposition(WORD wChar, LPARAM flags) 3856 { 3857 if (m_useNativeCompWindow) return mrDoDefault; 3858 3859 int* bndClauseW = NULL; 3860 jstring* readingClauseW = NULL; 3861 int* bndAttrW = NULL; 3862 BYTE* valAttrW = NULL; 3863 int cClauseW = 0; 3864 AwtInputTextInfor* textInfor = NULL; 3865 3866 try { 3867 HWND hwnd = ImmGetHWnd(); 3868 HIMC hIMC = ImmGetContext(hwnd); 3869 DASSERT(hIMC!=0); 3870 3871 textInfor = new AwtInputTextInfor; 3872 textInfor->GetContextData(hIMC, flags); 3873 ImmReleaseContext(hwnd, hIMC); 3874 3875 jstring jtextString = textInfor->GetText(); 3876 /* The conditions to send the input method event to AWT EDT are: 3877 1. Whenever there is a composition message sent regarding whether 3878 the composition text is NULL or not. See details at bug 6222692. 3879 2. When there is a committed message sent, in which case, we have to 3880 check whether the committed string is NULL or not. If the committed string 3881 is NULL, there is no need to send any input method event. 3882 (Minor note: 'jtextString' returned is the merged string in the case of 3883 partial commit.) 3884 */ 3885 if ((flags & GCS_RESULTSTR && jtextString != NULL) || 3886 (flags & GCS_COMPSTR)) { 3887 int cursorPosW = textInfor->GetCursorPosition(); 3888 // In order not to delete the readingClauseW in the catch clause, 3889 // calling GetAttributeInfor before GetClauseInfor. 3890 int cAttrW = textInfor->GetAttributeInfor(bndAttrW, valAttrW); 3891 cClauseW = textInfor->GetClauseInfor(bndClauseW, readingClauseW); 3892 3893 /* Send INPUT_METHOD_TEXT_CHANGED event to the WInputMethod which in turn sends 3894 the event to AWT EDT. 3895 3896 The last two paremeters are set to equal since we don't have recommendations for 3897 the visible position within the current composed text. See details at 3898 java.awt.event.InputMethodEvent. 3899 */ 3900 SendInputMethodEvent(java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3901 jtextString, 3902 cClauseW, bndClauseW, readingClauseW, 3903 cAttrW, bndAttrW, valAttrW, 3904 textInfor->GetCommittedTextLength(), 3905 cursorPosW, cursorPosW); 3906 } 3907 } catch (...) { 3908 // since GetClauseInfor and GetAttributeInfor could throw exception, we have to release 3909 // the pointer here. 3910 delete [] bndClauseW; 3911 delete [] readingClauseW; 3912 delete [] bndAttrW; 3913 delete [] valAttrW; 3914 throw; 3915 } 3916 3917 /* Free the storage allocated. Since jtextString won't be passed from threads 3918 * to threads, we just use the local ref and it will be deleted within the destructor 3919 * of AwtInputTextInfor object. 3920 */ 3921 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3922 if (cClauseW && readingClauseW) { 3923 for (int i = 0; i < cClauseW; i ++) { 3924 if (readingClauseW[i]) { 3925 env->DeleteLocalRef(readingClauseW[i]); 3926 } 3927 } 3928 } 3929 delete [] bndClauseW; 3930 delete [] readingClauseW; 3931 delete [] bndAttrW; 3932 delete [] valAttrW; 3933 delete textInfor; 3934 3935 return mrConsume; 3936 } 3937 3938 // 3939 // generate and post InputMethodEvent 3940 // 3941 void AwtComponent::SendInputMethodEvent(jint id, jstring text, 3942 int cClause, int* rgClauseBoundary, jstring* rgClauseReading, 3943 int cAttrBlock, int* rgAttrBoundary, BYTE *rgAttrValue, 3944 int commitedTextLength, int caretPos, int visiblePos) 3945 { 3946 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3947 3948 // assumption for array type casting 3949 DASSERT(sizeof(int)==sizeof(jint)); 3950 DASSERT(sizeof(BYTE)==sizeof(jbyte)); 3951 3952 // caluse information 3953 jintArray clauseBoundary = NULL; 3954 jobjectArray clauseReading = NULL; 3955 if (cClause && rgClauseBoundary && rgClauseReading) { 3956 // convert clause boundary offset array to java array 3957 clauseBoundary = env->NewIntArray(cClause+1); 3958 DASSERT(clauseBoundary); 3959 CHECK_NULL(clauseBoundary); 3960 env->SetIntArrayRegion(clauseBoundary, 0, cClause+1, (jint *)rgClauseBoundary); 3961 DASSERT(!safe_ExceptionOccurred(env)); 3962 3963 // convert clause reading string array to java array 3964 jclass stringCls = JNU_ClassString(env); 3965 DASSERT(stringCls); 3966 CHECK_NULL(stringCls); 3967 clauseReading = env->NewObjectArray(cClause, stringCls, NULL); 3968 env->DeleteLocalRef(stringCls); 3969 DASSERT(clauseReading); 3970 CHECK_NULL(clauseReading); 3971 for (int i=0; i<cClause; i++) env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]); 3972 DASSERT(!safe_ExceptionOccurred(env)); 3973 } 3974 3975 3976 // attrubute value definition in WInputMethod.java must be equal to that in IMM.H 3977 DASSERT(ATTR_INPUT==sun_awt_windows_WInputMethod_ATTR_INPUT); 3978 DASSERT(ATTR_TARGET_CONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_CONVERTED); 3979 DASSERT(ATTR_CONVERTED==sun_awt_windows_WInputMethod_ATTR_CONVERTED); 3980 DASSERT(ATTR_TARGET_NOTCONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_NOTCONVERTED); 3981 DASSERT(ATTR_INPUT_ERROR==sun_awt_windows_WInputMethod_ATTR_INPUT_ERROR); 3982 3983 // attribute information 3984 jintArray attrBoundary = NULL; 3985 jbyteArray attrValue = NULL; 3986 if (cAttrBlock && rgAttrBoundary && rgAttrValue) { 3987 // convert attribute boundary offset array to java array 3988 attrBoundary = env->NewIntArray(cAttrBlock+1); 3989 DASSERT(attrBoundary); 3990 CHECK_NULL(attrBoundary); 3991 env->SetIntArrayRegion(attrBoundary, 0, cAttrBlock+1, (jint *)rgAttrBoundary); 3992 DASSERT(!safe_ExceptionOccurred(env)); 3993 3994 // convert attribute value byte array to java array 3995 attrValue = env->NewByteArray(cAttrBlock); 3996 DASSERT(attrValue); 3997 CHECK_NULL(attrValue); 3998 env->SetByteArrayRegion(attrValue, 0, cAttrBlock, (jbyte *)rgAttrValue); 3999 DASSERT(!safe_ExceptionOccurred(env)); 4000 } 4001 4002 4003 // get global reference of WInputMethod class (run only once) 4004 static jclass wInputMethodCls = NULL; 4005 if (wInputMethodCls == NULL) { 4006 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4007 DASSERT(wInputMethodClsLocal); 4008 CHECK_NULL(wInputMethodClsLocal); 4009 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4010 env->DeleteLocalRef(wInputMethodClsLocal); 4011 } 4012 4013 // get method ID of sendInputMethodEvent() (run only once) 4014 static jmethodID sendIMEventMid = 0; 4015 if (sendIMEventMid == 0) { 4016 sendIMEventMid = env->GetMethodID(wInputMethodCls, "sendInputMethodEvent", 4017 "(IJLjava/lang/String;[I[Ljava/lang/String;[I[BIII)V"); 4018 DASSERT(sendIMEventMid); 4019 CHECK_NULL(sendIMEventMid); 4020 } 4021 4022 // call m_InputMethod.sendInputMethod() 4023 env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, TimeHelper::getMessageTimeUTC(), 4024 text, clauseBoundary, clauseReading, attrBoundary, 4025 attrValue, commitedTextLength, caretPos, visiblePos); 4026 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4027 DASSERT(!safe_ExceptionOccurred(env)); 4028 4029 } 4030 4031 4032 4033 // 4034 // Inquires candidate position according to the composed text 4035 // 4036 void AwtComponent::InquireCandidatePosition() 4037 { 4038 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4039 4040 // get global reference of WInputMethod class (run only once) 4041 static jclass wInputMethodCls = NULL; 4042 if (wInputMethodCls == NULL) { 4043 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4044 DASSERT(wInputMethodClsLocal); 4045 CHECK_NULL(wInputMethodClsLocal); 4046 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4047 env->DeleteLocalRef(wInputMethodClsLocal); 4048 } 4049 4050 // get method ID of sendInputMethodEvent() (run only once) 4051 static jmethodID inqCandPosMid = 0; 4052 if (inqCandPosMid == 0) { 4053 inqCandPosMid = env->GetMethodID(wInputMethodCls, "inquireCandidatePosition", "()V"); 4054 DASSERT(!safe_ExceptionOccurred(env)); 4055 DASSERT(inqCandPosMid); 4056 CHECK_NULL(inqCandPosMid); 4057 } 4058 4059 // call m_InputMethod.sendInputMethod() 4060 jobject candPos = env->CallObjectMethod(m_InputMethod, inqCandPosMid); 4061 DASSERT(!safe_ExceptionOccurred(env)); 4062 } 4063 4064 HWND AwtComponent::ImmGetHWnd() 4065 { 4066 HWND proxy = GetProxyFocusOwner(); 4067 return (proxy != NULL) ? proxy : GetHWnd(); 4068 } 4069 4070 HIMC AwtComponent::ImmAssociateContext(HIMC himc) 4071 { 4072 return ::ImmAssociateContext(ImmGetHWnd(), himc); 4073 } 4074 4075 HWND AwtComponent::GetProxyFocusOwner() 4076 { 4077 AwtWindow *window = GetContainer(); 4078 if (window != 0) { 4079 AwtFrame *owner = window->GetOwningFrameOrDialog(); 4080 if (owner != 0) { 4081 return owner->GetProxyFocusOwner(); 4082 } else if (!window->IsSimpleWindow()) { // isn't an owned simple window 4083 return ((AwtFrame*)window)->GetProxyFocusOwner(); 4084 } 4085 } 4086 return (HWND)NULL; 4087 } 4088 4089 /* Call DefWindowProc for the focus proxy, if any */ 4090 void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam, 4091 LPARAM lParam, LRESULT &retVal, MsgRouting &mr) 4092 { 4093 if (mr != mrConsume) { 4094 HWND proxy = GetProxyFocusOwner(); 4095 if (proxy != NULL && ::IsWindowEnabled(proxy)) { 4096 retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam); 4097 mr = mrConsume; 4098 } 4099 } 4100 } 4101 4102 MsgRouting AwtComponent::WmCommand(UINT id, HWND hWndChild, UINT notifyCode) 4103 { 4104 /* Menu/Accelerator */ 4105 if (hWndChild == 0) { 4106 AwtObject* obj = AwtToolkit::GetInstance().LookupCmdID(id); 4107 if (obj == NULL) { 4108 return mrConsume; 4109 } 4110 DASSERT(((AwtMenuItem*)obj)->GetID() == id); 4111 obj->DoCommand(); 4112 return mrConsume; 4113 } 4114 /* Child id notification */ 4115 else { 4116 AwtComponent* child = AwtComponent::GetComponent(hWndChild); 4117 if (child) { 4118 child->WmNotify(notifyCode); 4119 } 4120 } 4121 return mrDoDefault; 4122 } 4123 4124 MsgRouting AwtComponent::WmNotify(UINT notifyCode) 4125 { 4126 return mrDoDefault; 4127 } 4128 4129 MsgRouting AwtComponent::WmCompareItem(UINT ctrlId, 4130 COMPAREITEMSTRUCT &compareInfo, 4131 LRESULT &result) 4132 { 4133 AwtComponent* child = AwtComponent::GetComponent(compareInfo.hwndItem); 4134 if (child == this) { 4135 /* DoCallback("handleItemDelete", */ 4136 } 4137 else if (child) { 4138 return child->WmCompareItem(ctrlId, compareInfo, result); 4139 } 4140 return mrConsume; 4141 } 4142 4143 MsgRouting AwtComponent::WmDeleteItem(UINT ctrlId, 4144 DELETEITEMSTRUCT &deleteInfo) 4145 { 4146 /* 4147 * Workaround for NT 4.0 bug -- if SetWindowPos is called on a AwtList 4148 * window, a WM_DELETEITEM message is sent to its parent with a window 4149 * handle of one of the list's child windows. The property lookup 4150 * succeeds, but the HWNDs don't match. 4151 */ 4152 if (deleteInfo.hwndItem == NULL) { 4153 return mrConsume; 4154 } 4155 AwtComponent* child = (AwtComponent *)AwtComponent::GetComponent(deleteInfo.hwndItem); 4156 4157 if (child && child->GetHWnd() != deleteInfo.hwndItem) { 4158 return mrConsume; 4159 } 4160 4161 if (child == this) { 4162 /*DoCallback("handleItemDelete", */ 4163 } 4164 else if (child) { 4165 return child->WmDeleteItem(ctrlId, deleteInfo); 4166 } 4167 return mrConsume; 4168 } 4169 4170 MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo) 4171 { 4172 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4173 4174 if (drawInfo.CtlType == ODT_MENU) { 4175 if (drawInfo.itemData != 0) { 4176 AwtMenu* menu = (AwtMenu*)(drawInfo.itemData); 4177 menu->DrawItem(drawInfo); 4178 } 4179 } else { 4180 return OwnerDrawItem(ctrlId, drawInfo); 4181 } 4182 return mrConsume; 4183 } 4184 4185 MsgRouting AwtComponent::WmMeasureItem(UINT ctrlId, 4186 MEASUREITEMSTRUCT &measureInfo) 4187 { 4188 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4189 4190 if (measureInfo.CtlType == ODT_MENU) { 4191 if (measureInfo.itemData != 0) { 4192 AwtMenu* menu = (AwtMenu*)(measureInfo.itemData); 4193 HDC hDC = ::GetDC(GetHWnd()); 4194 /* menu->MeasureItem(env, hDC, measureInfo); */ 4195 menu->MeasureItem(hDC, measureInfo); 4196 ::ReleaseDC(GetHWnd(), hDC); 4197 } 4198 } else { 4199 return OwnerMeasureItem(ctrlId, measureInfo); 4200 } 4201 return mrConsume; 4202 } 4203 4204 MsgRouting AwtComponent::OwnerDrawItem(UINT ctrlId, 4205 DRAWITEMSTRUCT &drawInfo) 4206 { 4207 AwtComponent* child = AwtComponent::GetComponent(drawInfo.hwndItem); 4208 if (child == this) { 4209 /* DoCallback("handleItemDelete", */ 4210 } else if (child != NULL) { 4211 return child->WmDrawItem(ctrlId, drawInfo); 4212 } 4213 return mrConsume; 4214 } 4215 4216 MsgRouting AwtComponent::OwnerMeasureItem(UINT ctrlId, 4217 MEASUREITEMSTRUCT &measureInfo) 4218 { 4219 HWND hChild = ::GetDlgItem(GetHWnd(), measureInfo.CtlID); 4220 AwtComponent* child = AwtComponent::GetComponent(hChild); 4221 /* 4222 * If the parent cannot find the child's instance from its handle, 4223 * maybe the child is in its creation. So the child must be searched 4224 * from the list linked before the child's creation. 4225 */ 4226 if (child == NULL) { 4227 child = SearchChild((UINT)ctrlId); 4228 } 4229 4230 if (child == this) { 4231 /* DoCallback("handleItemDelete", */ 4232 } 4233 else if (child) { 4234 return child->WmMeasureItem(ctrlId, measureInfo); 4235 } 4236 return mrConsume; 4237 } 4238 4239 /* for WmDrawItem method of Label, Button and Checkbox */ 4240 void AwtComponent::DrawWindowText(HDC hDC, jobject font, jstring text, 4241 int x, int y) 4242 { 4243 int nOldBkMode = ::SetBkMode(hDC,TRANSPARENT); 4244 DASSERT(nOldBkMode != 0); 4245 AwtFont::drawMFString(hDC, font, text, x, y, GetCodePage()); 4246 VERIFY(::SetBkMode(hDC,nOldBkMode)); 4247 } 4248 4249 /* 4250 * Draw text in gray (the color being set to COLOR_GRAYTEXT) when the 4251 * component is disabled. Used only for label, checkbox and button in 4252 * OWNER_DRAW. It draws the text in emboss. 4253 */ 4254 void AwtComponent::DrawGrayText(HDC hDC, jobject font, jstring text, 4255 int x, int y) 4256 { 4257 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT)); 4258 AwtComponent::DrawWindowText(hDC, font, text, x+1, y+1); 4259 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); 4260 AwtComponent::DrawWindowText(hDC, font, text, x, y); 4261 } 4262 4263 /* for WmMeasureItem method of List and Choice */ 4264 jstring AwtComponent::GetItemString(JNIEnv *env, jobject target, jint index) 4265 { 4266 jstring str = (jstring)JNU_CallMethodByName(env, NULL, target, "getItemImpl", 4267 "(I)Ljava/lang/String;", 4268 index).l; 4269 DASSERT(!safe_ExceptionOccurred(env)); 4270 return str; 4271 } 4272 4273 /* for WmMeasureItem method of List and Choice */ 4274 void AwtComponent::MeasureListItem(JNIEnv *env, 4275 MEASUREITEMSTRUCT &measureInfo) 4276 { 4277 if (env->EnsureLocalCapacity(1) < 0) { 4278 return; 4279 } 4280 jobject dimension = PreferredItemSize(env); 4281 DASSERT(dimension); 4282 measureInfo.itemWidth = 4283 env->GetIntField(dimension, AwtDimension::widthID); 4284 measureInfo.itemHeight = 4285 env->GetIntField(dimension, AwtDimension::heightID); 4286 env->DeleteLocalRef(dimension); 4287 } 4288 4289 /* for WmDrawItem method of List and Choice */ 4290 void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) 4291 { 4292 if (env->EnsureLocalCapacity(3) < 0) { 4293 return; 4294 } 4295 jobject peer = GetPeer(env); 4296 jobject target = env->GetObjectField(peer, AwtObject::targetID); 4297 4298 HDC hDC = drawInfo.hDC; 4299 RECT rect = drawInfo.rcItem; 4300 4301 BOOL bEnabled = isEnabled(); 4302 BOOL unfocusableChoice = (drawInfo.itemState & ODS_COMBOBOXEDIT) && !IsFocusable(); 4303 DWORD crBack, crText; 4304 if (drawInfo.itemState & ODS_SELECTED){ 4305 /* Set background and text colors for selected item */ 4306 crBack = ::GetSysColor (COLOR_HIGHLIGHT); 4307 crText = ::GetSysColor (COLOR_HIGHLIGHTTEXT); 4308 } else { 4309 /* Set background and text colors for unselected item */ 4310 crBack = GetBackgroundColor(); 4311 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4312 } 4313 if (unfocusableChoice) { 4314 //6190728. Shouldn't draw selection field (edit control) of an owner-drawn combo box. 4315 crBack = GetBackgroundColor(); 4316 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4317 } 4318 4319 /* Fill item rectangle with background color */ 4320 HBRUSH hbrBack = ::CreateSolidBrush (crBack); 4321 DASSERT(hbrBack); 4322 /* 6190728. Shouldn't draw any kind of rectangle around selection field 4323 * (edit control) of an owner-drawn combo box while unfocusable 4324 */ 4325 if (!unfocusableChoice){ 4326 VERIFY(::FillRect (hDC, &rect, hbrBack)); 4327 } 4328 VERIFY(::DeleteObject (hbrBack)); 4329 4330 /* Set current background and text colors */ 4331 ::SetBkColor (hDC, crBack); 4332 ::SetTextColor (hDC, crText); 4333 4334 /*draw string (with left margin of 1 point) */ 4335 if ((int) (drawInfo.itemID) >= 0) { 4336 jobject font = GET_FONT(target, peer); 4337 jstring text = GetItemString(env, target, drawInfo.itemID); 4338 if (env->ExceptionCheck()) { 4339 env->DeleteLocalRef(font); 4340 env->DeleteLocalRef(target); 4341 return; 4342 } 4343 SIZE size = AwtFont::getMFStringSize(hDC, font, text); 4344 AwtFont::drawMFString(hDC, font, text, 4345 (GetRTL()) ? rect.right - size.cx - 1 4346 : rect.left + 1, 4347 (rect.top + rect.bottom - size.cy) / 2, 4348 GetCodePage()); 4349 env->DeleteLocalRef(font); 4350 env->DeleteLocalRef(text); 4351 } 4352 if ((drawInfo.itemState & ODS_FOCUS) && 4353 (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { 4354 if (!unfocusableChoice){ 4355 VERIFY(::DrawFocusRect(hDC, &rect)); 4356 } 4357 } 4358 env->DeleteLocalRef(target); 4359 } 4360 4361 /* for MeasureListItem method and WmDrawItem method of Checkbox */ 4362 jint AwtComponent::GetFontHeight(JNIEnv *env) 4363 { 4364 if (env->EnsureLocalCapacity(4) < 0) { 4365 return NULL; 4366 } 4367 jobject self = GetPeer(env); 4368 jobject target = env->GetObjectField(self, AwtObject::targetID); 4369 4370 jobject font = GET_FONT(target, self); 4371 jobject toolkit = env->CallObjectMethod(target, 4372 AwtComponent::getToolkitMID); 4373 4374 DASSERT(!safe_ExceptionOccurred(env)); 4375 4376 jobject fontMetrics = 4377 env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font); 4378 4379 DASSERT(!safe_ExceptionOccurred(env)); 4380 4381 jint height = env->CallIntMethod(fontMetrics, AwtFont::getHeightMID); 4382 DASSERT(!safe_ExceptionOccurred(env)); 4383 4384 env->DeleteLocalRef(target); 4385 env->DeleteLocalRef(font); 4386 env->DeleteLocalRef(toolkit); 4387 env->DeleteLocalRef(fontMetrics); 4388 4389 return height; 4390 } 4391 4392 // If you override WmPrint, make sure to save a copy of the DC on the GDI 4393 // stack to be restored in WmPrintClient. Windows mangles the DC in 4394 // ::DefWindowProc. 4395 MsgRouting AwtComponent::WmPrint(HDC hDC, LPARAM flags) 4396 { 4397 /* 4398 * DefWindowProc for WM_PRINT changes DC parameters, so we have 4399 * to restore it ourselves. Otherwise it will cause problems 4400 * when several components are printed to the same DC. 4401 */ 4402 int nOriginalDC = ::SaveDC(hDC); 4403 DASSERT(nOriginalDC != 0); 4404 4405 if (flags & PRF_NONCLIENT) { 4406 4407 VERIFY(::SaveDC(hDC)); 4408 4409 DefWindowProc(WM_PRINT, (WPARAM)hDC, 4410 (flags & (PRF_NONCLIENT 4411 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4412 4413 VERIFY(::RestoreDC(hDC, -1)); 4414 4415 // Special case for components with a sunken border. Windows does not 4416 // print the border correctly on PCL printers, so we have to do it ourselves. 4417 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4418 RECT r; 4419 VERIFY(::GetWindowRect(GetHWnd(), &r)); 4420 VERIFY(::OffsetRect(&r, -r.left, -r.top)); 4421 VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT)); 4422 } 4423 } 4424 4425 if (flags & PRF_CLIENT) { 4426 4427 /* 4428 * Special case for components with a sunken border. 4429 * Windows prints a client area without offset to a border width. 4430 * We will first print the non-client area with the original offset, 4431 * then the client area with a corrected offset. 4432 */ 4433 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4434 4435 int nEdgeWidth = ::GetSystemMetrics(SM_CXEDGE); 4436 int nEdgeHeight = ::GetSystemMetrics(SM_CYEDGE); 4437 4438 VERIFY(::OffsetWindowOrgEx(hDC, -nEdgeWidth, -nEdgeHeight, NULL)); 4439 4440 // Save a copy of the DC for WmPrintClient 4441 VERIFY(::SaveDC(hDC)); 4442 4443 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4444 (flags & (PRF_CLIENT 4445 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4446 4447 VERIFY(::OffsetWindowOrgEx(hDC, nEdgeWidth, nEdgeHeight, NULL)); 4448 4449 } else { 4450 4451 // Save a copy of the DC for WmPrintClient 4452 VERIFY(::SaveDC(hDC)); 4453 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4454 (flags & (PRF_CLIENT 4455 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4456 } 4457 } 4458 4459 if (flags & (PRF_CHILDREN | PRF_OWNED)) { 4460 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4461 (flags & ~PRF_CLIENT & ~PRF_NONCLIENT)); 4462 } 4463 4464 VERIFY(::RestoreDC(hDC, nOriginalDC)); 4465 4466 return mrConsume; 4467 } 4468 4469 // If you override WmPrintClient, make sure to obtain a valid copy of 4470 // the DC from the GDI stack. The copy of the DC should have been placed 4471 // there by WmPrint. Windows mangles the DC in ::DefWindowProc. 4472 MsgRouting AwtComponent::WmPrintClient(HDC hDC, LPARAM) 4473 { 4474 // obtain valid DC from GDI stack 4475 ::RestoreDC(hDC, -1); 4476 4477 return mrDoDefault; 4478 } 4479 4480 MsgRouting AwtComponent::WmNcCalcSize(BOOL fCalcValidRects, 4481 LPNCCALCSIZE_PARAMS lpncsp, 4482 LRESULT &retVal) 4483 { 4484 return mrDoDefault; 4485 } 4486 4487 MsgRouting AwtComponent::WmNcPaint(HRGN hrgn) 4488 { 4489 return mrDoDefault; 4490 } 4491 4492 MsgRouting AwtComponent::WmNcHitTest(UINT x, UINT y, LRESULT &retVal) 4493 { 4494 return mrDoDefault; 4495 } 4496 4497 /** 4498 * WmQueryNewPalette is called whenever our component is coming to 4499 * the foreground; this gives us an opportunity to install our 4500 * custom palette. If this install actually changes entries in 4501 * the system palette, then we get a further call to WmPaletteChanged 4502 * (but note that we only need to realize our palette once). 4503 */ 4504 MsgRouting AwtComponent::WmQueryNewPalette(LRESULT &retVal) 4505 { 4506 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4507 m_QueryNewPaletteCalled = TRUE; 4508 HDC hDC = ::GetDC(GetHWnd()); 4509 DASSERT(hDC); 4510 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4511 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4512 ::ReleaseDC(GetHWnd(), hDC); 4513 // We must realize the palettes of all of our DC's 4514 // There is sometimes a problem where the realization of 4515 // our temporary hDC here does not actually do what 4516 // we want. Not clear why, but presumably fallout from 4517 // our use of several simultaneous hDC's. 4518 activeDCList.RealizePalettes(screen); 4519 // Do not invalidate here; if the palette 4520 // has not changed we will get an extra repaint 4521 retVal = TRUE; 4522 4523 return mrDoDefault; 4524 } 4525 4526 /** 4527 * We should not need to track this event since we handle our 4528 * palette management effectively in the WmQueryNewPalette and 4529 * WmPaletteChanged methods. However, there seems to be a bug 4530 * on some win32 systems (e.g., NT4) whereby the palette 4531 * immediately after a displayChange is not yet updated to its 4532 * final post-display-change values (hence we adjust our palette 4533 * using the wrong system palette entries), then the palette is 4534 * updated, but a WM_PALETTECHANGED message is never sent. 4535 * By tracking the ISCHANGING message as well (and by tracking 4536 * displayChange events in the AwtToolkit object), we can account 4537 * for this error by forcing our WmPaletteChanged method to be 4538 * called and thereby realizing our logical palette and updating 4539 * our dynamic colorModel object. 4540 */ 4541 MsgRouting AwtComponent::WmPaletteIsChanging(HWND hwndPalChg) 4542 { 4543 if (AwtToolkit::GetInstance().HasDisplayChanged()) { 4544 WmPaletteChanged(hwndPalChg); 4545 AwtToolkit::GetInstance().ResetDisplayChanged(); 4546 } 4547 return mrDoDefault; 4548 } 4549 4550 MsgRouting AwtComponent::WmPaletteChanged(HWND hwndPalChg) 4551 { 4552 // We need to re-realize our palette here (unless we're the one 4553 // that was realizing it in the first place). That will let us match the 4554 // remaining colors in the system palette as best we can. We always 4555 // invalidate because the palette will have changed when we receive this 4556 // message. 4557 4558 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4559 if (hwndPalChg != GetHWnd()) { 4560 HDC hDC = ::GetDC(GetHWnd()); 4561 DASSERT(hDC); 4562 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4563 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4564 ::ReleaseDC(GetHWnd(), hDC); 4565 // We must realize the palettes of all of our DC's 4566 activeDCList.RealizePalettes(screen); 4567 } 4568 if (AwtWin32GraphicsDevice::UpdateSystemPalette(screen)) { 4569 AwtWin32GraphicsDevice::UpdateDynamicColorModel(screen); 4570 } 4571 Invalidate(NULL); 4572 return mrDoDefault; 4573 } 4574 4575 MsgRouting AwtComponent::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 4576 { 4577 DASSERT(!IsBadReadPtr(lpss, sizeof(STYLESTRUCT))); 4578 return mrDoDefault; 4579 } 4580 4581 MsgRouting AwtComponent::WmSettingChange(UINT wFlag, LPCTSTR pszSection) 4582 { 4583 DASSERT(!IsBadStringPtr(pszSection, 20)); 4584 DTRACE_PRINTLN2("WM_SETTINGCHANGE: wFlag=%d pszSection=%s", (int)wFlag, pszSection); 4585 return mrDoDefault; 4586 } 4587 4588 HDC AwtComponent::GetDCFromComponent() 4589 { 4590 GetDCReturnStruct *hdcStruct = 4591 (GetDCReturnStruct*)SendMessage(WM_AWT_GETDC); 4592 HDC hdc; 4593 if (hdcStruct) { 4594 if (hdcStruct->gdiLimitReached) { 4595 if (jvm != NULL) { 4596 JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4597 if (env != NULL && !safe_ExceptionOccurred(env)) { 4598 JNU_ThrowByName(env, "java/awt/AWTError", 4599 "HDC creation failure - " \ 4600 "exceeded maximum GDI resources"); 4601 } 4602 } 4603 } 4604 hdc = hdcStruct->hDC; 4605 delete hdcStruct; 4606 } else { 4607 hdc = NULL; 4608 } 4609 return hdc; 4610 } 4611 4612 void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size) 4613 { 4614 RECT eraseR = { 0, 0, size.cx, size.cy }; 4615 VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush())); 4616 } 4617 4618 void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) 4619 { 4620 if (!bitmapBits) { 4621 return; 4622 } 4623 4624 DWORD* dest = (DWORD*)bitmapBits; 4625 //XXX: might be optimized to use one loop (cy*cx -> 0) 4626 for (int i = 0; i < size.cy; i++ ) { 4627 for (int j = 0; j < size.cx; j++ ) { 4628 ((BYTE*)(dest++))[3] = alpha; 4629 } 4630 } 4631 } 4632 4633 jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) { 4634 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4635 4636 if (!::IsWindowVisible(GetHWnd())) { 4637 return NULL; 4638 } 4639 4640 HDC hdc = GetDCFromComponent(); 4641 if (!hdc) { 4642 return NULL; 4643 } 4644 HDC hMemoryDC = ::CreateCompatibleDC(hdc); 4645 void *bitmapBits = NULL; 4646 HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits); 4647 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap); 4648 SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc); 4649 4650 FillBackground(hMemoryDC, size); 4651 4652 VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL)); 4653 4654 // Don't bother with PRF_CHECKVISIBLE because we called IsWindowVisible 4655 // above. 4656 SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT); 4657 4658 // First make sure the system completed any drawing to the bitmap. 4659 ::GdiFlush(); 4660 4661 // WM_PRINT does not fill the alpha-channel of the ARGB bitmap 4662 // leaving it equal to zero. Hence we need to fill it manually. Otherwise 4663 // the pixels will be considered transparent when interpreting the data. 4664 FillAlpha(bitmapBits, size, alpha); 4665 4666 ::SelectObject(hMemoryDC, hOldBitmap); 4667 4668 BITMAPINFO bmi; 4669 memset(&bmi, 0, sizeof(BITMAPINFO)); 4670 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 4671 bmi.bmiHeader.biWidth = size.cx; 4672 bmi.bmiHeader.biHeight = -size.cy; 4673 bmi.bmiHeader.biPlanes = 1; 4674 bmi.bmiHeader.biBitCount = 32; 4675 bmi.bmiHeader.biCompression = BI_RGB; 4676 4677 jobject localPixelArray = env->NewIntArray(size.cx * size.cy); 4678 jintArray pixelArray = NULL; 4679 if (localPixelArray != NULL) { 4680 pixelArray = (jintArray)env->NewGlobalRef(localPixelArray); 4681 env->DeleteLocalRef(localPixelArray); localPixelArray = NULL; 4682 4683 jboolean isCopy; 4684 jint *pixels = env->GetIntArrayElements(pixelArray, &isCopy); 4685 4686 ::GetDIBits(hMemoryDC, hBitmap, 0, size.cy, (LPVOID)pixels, &bmi, 4687 DIB_RGB_COLORS); 4688 4689 env->ReleaseIntArrayElements(pixelArray, pixels, 0); 4690 } 4691 4692 VERIFY(::DeleteObject(hBitmap)); 4693 VERIFY(::DeleteDC(hMemoryDC)); 4694 4695 return pixelArray; 4696 } 4697 4698 void* AwtComponent::SetNativeFocusOwner(void *self) { 4699 if (self == NULL) { 4700 // It means that the KFM wants to set focus to null 4701 sm_focusOwner = NULL; 4702 return NULL; 4703 } 4704 4705 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4706 4707 AwtComponent *c = NULL; 4708 jobject peer = (jobject)self; 4709 4710 PDATA pData; 4711 JNI_CHECK_NULL_GOTO(peer, "peer", ret); 4712 pData = JNI_GET_PDATA(peer); 4713 if (pData == NULL) { 4714 goto ret; 4715 } 4716 c = (AwtComponent *)pData; 4717 4718 ret: 4719 if (c && ::IsWindow(c->GetHWnd())) { 4720 sm_focusOwner = c->GetHWnd(); 4721 } else { 4722 sm_focusOwner = NULL; 4723 } 4724 env->DeleteGlobalRef(peer); 4725 return NULL; 4726 } 4727 4728 void* AwtComponent::GetNativeFocusedWindow() { 4729 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4730 AwtComponent *comp = 4731 AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 4732 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4733 } 4734 4735 void* AwtComponent::GetNativeFocusOwner() { 4736 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4737 AwtComponent *comp = 4738 AwtComponent::GetComponent(AwtComponent::sm_focusOwner); 4739 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4740 } 4741 4742 AwtComponent* AwtComponent::SearchChild(UINT id) { 4743 ChildListItem* child; 4744 for (child = m_childList; child != NULL;child = child->m_next) { 4745 if (child->m_ID == id) 4746 return child->m_Component; 4747 } 4748 /* 4749 * DASSERT(FALSE); 4750 * This should not be happend if all children are recorded 4751 */ 4752 return NULL; /* make compiler happy */ 4753 } 4754 4755 void AwtComponent::RemoveChild(UINT id) { 4756 ChildListItem* child = m_childList; 4757 ChildListItem* lastChild = NULL; 4758 while (child != NULL) { 4759 if (child->m_ID == id) { 4760 if (lastChild == NULL) { 4761 m_childList = child->m_next; 4762 } else { 4763 lastChild->m_next = child->m_next; 4764 } 4765 child->m_next = NULL; 4766 DASSERT(child != NULL); 4767 delete child; 4768 return; 4769 } 4770 lastChild = child; 4771 child = child->m_next; 4772 } 4773 } 4774 4775 void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked, 4776 jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg) 4777 { 4778 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4779 CriticalSection::Lock l(GetLock()); 4780 if (GetPeer(env) == NULL) { 4781 /* event received during termination. */ 4782 return; 4783 } 4784 4785 static jclass keyEventCls; 4786 if (keyEventCls == NULL) { 4787 jclass keyEventClsLocal = env->FindClass("java/awt/event/KeyEvent"); 4788 DASSERT(keyEventClsLocal); 4789 if (keyEventClsLocal == NULL) { 4790 /* exception already thrown */ 4791 return; 4792 } 4793 keyEventCls = (jclass)env->NewGlobalRef(keyEventClsLocal); 4794 env->DeleteLocalRef(keyEventClsLocal); 4795 } 4796 4797 static jmethodID keyEventConst; 4798 if (keyEventConst == NULL) { 4799 keyEventConst = env->GetMethodID(keyEventCls, "<init>", 4800 "(Ljava/awt/Component;IJIICI)V"); 4801 DASSERT(keyEventConst); 4802 CHECK_NULL(keyEventConst); 4803 } 4804 if (env->EnsureLocalCapacity(2) < 0) { 4805 return; 4806 } 4807 jobject target = GetTarget(env); 4808 jobject keyEvent = env->NewObject(keyEventCls, keyEventConst, target, 4809 id, when, modifiers, raw, cooked, 4810 keyLocation); 4811 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4812 DASSERT(!safe_ExceptionOccurred(env)); 4813 DASSERT(keyEvent != NULL); 4814 if (keyEvent == NULL) { 4815 env->DeleteLocalRef(target); 4816 return; 4817 } 4818 env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode); 4819 if( nativeCode && nativeCode < 256 ) { 4820 env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode)); 4821 env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey)); 4822 if( nativeCode < 255 ) { 4823 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode)); 4824 }else if( pMsg != NULL ) { 4825 // unknown key with virtual keycode 0xFF. 4826 // Its scancode is not in the table, pickup it from the message. 4827 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF)); 4828 } 4829 } 4830 if (pMsg != NULL) { 4831 AwtAWTEvent::saveMSG(env, pMsg, keyEvent); 4832 } 4833 SendEvent(keyEvent); 4834 4835 env->DeleteLocalRef(keyEvent); 4836 env->DeleteLocalRef(target); 4837 } 4838 4839 void 4840 AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when, 4841 jint raw, jint cooked, 4842 jint modifiers, jint keyLocation, 4843 jlong nativeCode, 4844 MSG *msg) 4845 { 4846 /* 4847 * if focus owner is null, but focused window isn't 4848 * we will send key event to focused window 4849 */ 4850 HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow()); 4851 4852 if (hwndTarget == GetHWnd()) { 4853 SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg); 4854 } else { 4855 AwtComponent *target = NULL; 4856 if (hwndTarget != NULL) { 4857 target = AwtComponent::GetComponent(hwndTarget); 4858 if (target == NULL) { 4859 target = this; 4860 } 4861 } 4862 if (target != NULL) { 4863 target->SendKeyEvent(id, when, raw, cooked, modifiers, 4864 keyLocation, nativeCode, msg); 4865 } 4866 } 4867 } 4868 4869 void AwtComponent::SetDragCapture(UINT flags) 4870 { 4871 // don't want to interfere with other controls 4872 if (::GetCapture() == NULL) { 4873 ::SetCapture(GetHWnd()); 4874 } 4875 } 4876 4877 void AwtComponent::ReleaseDragCapture(UINT flags) 4878 { 4879 if ((::GetCapture() == GetHWnd()) && ((flags & ALL_MK_BUTTONS) == 0)) { 4880 // user has released all buttons, so release the capture 4881 ::ReleaseCapture(); 4882 } 4883 } 4884 4885 void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y, 4886 jint modifiers, jint clickCount, 4887 jboolean popupTrigger, jint button, 4888 MSG *pMsg) 4889 { 4890 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4891 CriticalSection::Lock l(GetLock()); 4892 if (GetPeer(env) == NULL) { 4893 /* event received during termination. */ 4894 return; 4895 } 4896 4897 static jclass mouseEventCls; 4898 if (mouseEventCls == NULL) { 4899 jclass mouseEventClsLocal = 4900 env->FindClass("java/awt/event/MouseEvent"); 4901 CHECK_NULL(mouseEventClsLocal); 4902 mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal); 4903 env->DeleteLocalRef(mouseEventClsLocal); 4904 } 4905 RECT insets; 4906 GetInsets(&insets); 4907 4908 static jmethodID mouseEventConst; 4909 if (mouseEventConst == NULL) { 4910 mouseEventConst = 4911 env->GetMethodID(mouseEventCls, "<init>", 4912 "(Ljava/awt/Component;IJIIIIIIZI)V"); 4913 DASSERT(mouseEventConst); 4914 CHECK_NULL(mouseEventConst); 4915 } 4916 if (env->EnsureLocalCapacity(2) < 0) { 4917 return; 4918 } 4919 jobject target = GetTarget(env); 4920 DWORD curMousePos = ::GetMessagePos(); 4921 int xAbs = GET_X_LPARAM(curMousePos); 4922 int yAbs = GET_Y_LPARAM(curMousePos); 4923 jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst, 4924 target, 4925 id, when, modifiers, 4926 x+insets.left, y+insets.top, 4927 xAbs, yAbs, 4928 clickCount, popupTrigger, button); 4929 4930 if (safe_ExceptionOccurred(env)) { 4931 env->ExceptionDescribe(); 4932 env->ExceptionClear(); 4933 } 4934 4935 DASSERT(mouseEvent != NULL); 4936 CHECK_NULL(mouseEvent); 4937 if (pMsg != 0) { 4938 AwtAWTEvent::saveMSG(env, pMsg, mouseEvent); 4939 } 4940 SendEvent(mouseEvent); 4941 4942 env->DeleteLocalRef(mouseEvent); 4943 env->DeleteLocalRef(target); 4944 } 4945 4946 void 4947 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, 4948 jint modifiers, jint clickCount, 4949 jboolean popupTrigger, jint scrollType, 4950 jint scrollAmount, jint roundedWheelRotation, 4951 jdouble preciseWheelRotation, MSG *pMsg) 4952 { 4953 /* Code based not so loosely on AwtComponent::SendMouseEvent */ 4954 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4955 CriticalSection::Lock l(GetLock()); 4956 if (GetPeer(env) == NULL) { 4957 /* event received during termination. */ 4958 return; 4959 } 4960 4961 static jclass mouseWheelEventCls; 4962 if (mouseWheelEventCls == NULL) { 4963 jclass mouseWheelEventClsLocal = 4964 env->FindClass("java/awt/event/MouseWheelEvent"); 4965 CHECK_NULL(mouseWheelEventClsLocal); 4966 mouseWheelEventCls = (jclass)env->NewGlobalRef(mouseWheelEventClsLocal); 4967 env->DeleteLocalRef(mouseWheelEventClsLocal); 4968 } 4969 RECT insets; 4970 GetInsets(&insets); 4971 4972 static jmethodID mouseWheelEventConst; 4973 if (mouseWheelEventConst == NULL) { 4974 mouseWheelEventConst = 4975 env->GetMethodID(mouseWheelEventCls, "<init>", 4976 "(Ljava/awt/Component;IJIIIIIIZIIID)V"); 4977 DASSERT(mouseWheelEventConst); 4978 CHECK_NULL(mouseWheelEventConst); 4979 } 4980 if (env->EnsureLocalCapacity(2) < 0) { 4981 return; 4982 } 4983 jobject target = GetTarget(env); 4984 DTRACE_PRINTLN("creating MWE in JNI"); 4985 4986 jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls, 4987 mouseWheelEventConst, 4988 target, 4989 id, when, modifiers, 4990 x+insets.left, y+insets.top, 4991 0, 0, 4992 clickCount, popupTrigger, 4993 scrollType, scrollAmount, 4994 roundedWheelRotation, preciseWheelRotation); 4995 4996 DASSERT(mouseWheelEvent != NULL); 4997 if (mouseWheelEvent == NULL || safe_ExceptionOccurred(env)) { 4998 env->ExceptionDescribe(); 4999 env->ExceptionClear(); 5000 env->DeleteLocalRef(target); 5001 return; 5002 } 5003 if (pMsg != NULL) { 5004 AwtAWTEvent::saveMSG(env, pMsg, mouseWheelEvent); 5005 } 5006 SendEvent(mouseWheelEvent); 5007 5008 env->DeleteLocalRef(mouseWheelEvent); 5009 env->DeleteLocalRef(target); 5010 } 5011 5012 void AwtComponent::SendFocusEvent(jint id, HWND opposite) 5013 { 5014 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5015 5016 CriticalSection::Lock l(GetLock()); 5017 if (GetPeer(env) == NULL) { 5018 /* event received during termination. */ 5019 return; 5020 } 5021 5022 static jclass focusEventCls; 5023 if (focusEventCls == NULL) { 5024 jclass focusEventClsLocal 5025 = env->FindClass("java/awt/event/FocusEvent"); 5026 DASSERT(focusEventClsLocal); 5027 CHECK_NULL(focusEventClsLocal); 5028 focusEventCls = (jclass)env->NewGlobalRef(focusEventClsLocal); 5029 env->DeleteLocalRef(focusEventClsLocal); 5030 } 5031 5032 static jmethodID focusEventConst; 5033 if (focusEventConst == NULL) { 5034 focusEventConst = 5035 env->GetMethodID(focusEventCls, "<init>", 5036 "(Ljava/awt/Component;IZLjava/awt/Component;)V"); 5037 DASSERT(focusEventConst); 5038 CHECK_NULL(focusEventConst); 5039 } 5040 5041 static jclass sequencedEventCls; 5042 if (sequencedEventCls == NULL) { 5043 jclass sequencedEventClsLocal = 5044 env->FindClass("java/awt/SequencedEvent"); 5045 DASSERT(sequencedEventClsLocal); 5046 CHECK_NULL(sequencedEventClsLocal); 5047 sequencedEventCls = 5048 (jclass)env->NewGlobalRef(sequencedEventClsLocal); 5049 env->DeleteLocalRef(sequencedEventClsLocal); 5050 } 5051 5052 static jmethodID sequencedEventConst; 5053 if (sequencedEventConst == NULL) { 5054 sequencedEventConst = 5055 env->GetMethodID(sequencedEventCls, "<init>", 5056 "(Ljava/awt/AWTEvent;)V"); 5057 DASSERT(sequencedEventConst); 5058 CHECK_NULL(sequencedEventConst); 5059 } 5060 5061 if (env->EnsureLocalCapacity(3) < 0) { 5062 return; 5063 } 5064 5065 jobject target = GetTarget(env); 5066 jobject jOpposite = NULL; 5067 if (opposite != NULL) { 5068 AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite); 5069 if (awtOpposite != NULL) { 5070 jOpposite = awtOpposite->GetTarget(env); 5071 } 5072 } 5073 jobject focusEvent = env->NewObject(focusEventCls, focusEventConst, 5074 target, id, JNI_FALSE, jOpposite); 5075 DASSERT(!safe_ExceptionOccurred(env)); 5076 DASSERT(focusEvent != NULL); 5077 if (jOpposite != NULL) { 5078 env->DeleteLocalRef(jOpposite); jOpposite = NULL; 5079 } 5080 env->DeleteLocalRef(target); target = NULL; 5081 CHECK_NULL(focusEvent); 5082 5083 jobject sequencedEvent = env->NewObject(sequencedEventCls, 5084 sequencedEventConst, 5085 focusEvent); 5086 DASSERT(!safe_ExceptionOccurred(env)); 5087 DASSERT(sequencedEvent != NULL); 5088 env->DeleteLocalRef(focusEvent); focusEvent = NULL; 5089 CHECK_NULL(sequencedEvent); 5090 SendEvent(sequencedEvent); 5091 5092 env->DeleteLocalRef(sequencedEvent); 5093 } 5094 5095 /* 5096 * Forward a filtered event directly to the subclassed window. 5097 * This method is needed so that DefWindowProc is invoked on the 5098 * component's owning thread. 5099 */ 5100 MsgRouting AwtComponent::HandleEvent(MSG *msg, BOOL) 5101 { 5102 DefWindowProc(msg->message, msg->wParam, msg->lParam); 5103 delete msg; 5104 return mrConsume; 5105 } 5106 5107 /* Post a WM_AWT_HANDLE_EVENT message which invokes HandleEvent 5108 on the toolkit thread. This method may pre-filter the messages. */ 5109 BOOL AwtComponent::PostHandleEventMessage(MSG *msg, BOOL synthetic) 5110 { 5111 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5112 // We should cut off keyboard events to disabled components 5113 // to avoid the components responding visually to keystrokes when disabled. 5114 // we shouldn't cut off WM_SYS* messages as they aren't used for normal activity 5115 // but to activate menus, close windows, etc 5116 switch(msg->message) { 5117 case WM_KEYDOWN: 5118 case WM_KEYUP: 5119 case WM_CHAR: 5120 case WM_DEADCHAR: 5121 { 5122 if (!isRecursivelyEnabled()) { 5123 goto quit; 5124 } 5125 break; 5126 } 5127 } 5128 if (PostMessage(GetHWnd(), WM_AWT_HANDLE_EVENT, 5129 (WPARAM) synthetic, (LPARAM) msg)) { 5130 return TRUE; 5131 } else { 5132 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5133 } 5134 quit: 5135 delete msg; 5136 return FALSE; 5137 } 5138 5139 void AwtComponent::SynthesizeKeyMessage(JNIEnv *env, jobject keyEvent) 5140 { 5141 jint id = (env)->GetIntField(keyEvent, AwtAWTEvent::idID); 5142 UINT message; 5143 switch (id) { 5144 case java_awt_event_KeyEvent_KEY_PRESSED: 5145 message = WM_KEYDOWN; 5146 break; 5147 case java_awt_event_KeyEvent_KEY_RELEASED: 5148 message = WM_KEYUP; 5149 break; 5150 case java_awt_event_KeyEvent_KEY_TYPED: 5151 message = WM_CHAR; 5152 break; 5153 default: 5154 return; 5155 } 5156 5157 /* 5158 * KeyEvent.modifiers aren't supported -- the Java apppwd must send separate 5159 * KEY_PRESSED and KEY_RELEASED events for the modifier virtual keys. 5160 */ 5161 if (id == java_awt_event_KeyEvent_KEY_TYPED) { 5162 // WM_CHAR message must be posted using WM_AWT_FORWARD_CHAR 5163 // (for Edit control) 5164 jchar keyChar = (jchar) 5165 (env)->GetCharField(keyEvent, AwtKeyEvent::keyCharID); 5166 5167 // Bugid 4724007. If it is a Delete character, don't send the fake 5168 // KEY_TYPED we created back to the native window: Windows doesn't 5169 // expect a WM_CHAR for Delete in TextFields, so it tries to enter a 5170 // character after deleting. 5171 if (keyChar == '\177') { // the Delete character 5172 return; 5173 } 5174 5175 // Disable forwarding WM_CHAR messages to disabled components 5176 if (isRecursivelyEnabled()) { 5177 if (!::PostMessage(GetHWnd(), WM_AWT_FORWARD_CHAR, 5178 MAKEWPARAM(keyChar, TRUE), 0)) { 5179 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5180 } 5181 } 5182 } else { 5183 jint keyCode = 5184 (env)->GetIntField(keyEvent, AwtKeyEvent::keyCodeID); 5185 UINT key, modifiers; 5186 AwtComponent::JavaKeyToWindowsKey(keyCode, &key, &modifiers); 5187 MSG* msg = CreateMessage(message, key, 0); 5188 PostHandleEventMessage(msg, TRUE); 5189 } 5190 } 5191 5192 void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent) 5193 { 5194 /* DebugBreak(); */ 5195 jint button = (env)->GetIntField(mouseEvent, AwtMouseEvent::buttonID); 5196 jint modifiers = (env)->GetIntField(mouseEvent, AwtInputEvent::modifiersID); 5197 5198 WPARAM wParam = 0; 5199 WORD wLow = 0; 5200 jint wheelAmt = 0; 5201 jint id = (env)->GetIntField(mouseEvent, AwtAWTEvent::idID); 5202 UINT message; 5203 switch (id) { 5204 case java_awt_event_MouseEvent_MOUSE_PRESSED: { 5205 switch (button) { 5206 case java_awt_event_MouseEvent_BUTTON1: 5207 message = WM_LBUTTONDOWN; break; 5208 case java_awt_event_MouseEvent_BUTTON3: 5209 message = WM_MBUTTONDOWN; break; 5210 case java_awt_event_MouseEvent_BUTTON2: 5211 message = WM_RBUTTONDOWN; break; 5212 } 5213 break; 5214 } 5215 case java_awt_event_MouseEvent_MOUSE_RELEASED: { 5216 switch (button) { 5217 case java_awt_event_MouseEvent_BUTTON1: 5218 message = WM_LBUTTONUP; break; 5219 case java_awt_event_MouseEvent_BUTTON3: 5220 message = WM_MBUTTONUP; break; 5221 case java_awt_event_MouseEvent_BUTTON2: 5222 message = WM_RBUTTONUP; break; 5223 } 5224 break; 5225 } 5226 case java_awt_event_MouseEvent_MOUSE_MOVED: 5227 /* MOUSE_DRAGGED events must first have sent a MOUSE_PRESSED event. */ 5228 case java_awt_event_MouseEvent_MOUSE_DRAGGED: 5229 message = WM_MOUSEMOVE; 5230 break; 5231 case java_awt_event_MouseEvent_MOUSE_WHEEL: 5232 if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) { 5233 wLow |= MK_CONTROL; 5234 } 5235 if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) { 5236 wLow |= MK_SHIFT; 5237 } 5238 if (modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) { 5239 wLow |= MK_LBUTTON; 5240 } 5241 if (modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) { 5242 wLow |= MK_RBUTTON; 5243 } 5244 if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) { 5245 wLow |= MK_MBUTTON; 5246 } 5247 if (modifiers & X1_BUTTON) { 5248 wLow |= GetButtonMK(X1_BUTTON); 5249 } 5250 if (modifiers & X2_BUTTON) { 5251 wLow |= GetButtonMK(X2_BUTTON); 5252 } 5253 5254 wheelAmt = (jint)JNU_CallMethodByName(env, 5255 NULL, 5256 mouseEvent, 5257 "getWheelRotation", 5258 "()I").i; 5259 DASSERT(!safe_ExceptionOccurred(env)); 5260 JNU_CHECK_EXCEPTION(env); 5261 DTRACE_PRINTLN1("wheelAmt = %i\n", wheelAmt); 5262 5263 // convert Java wheel amount value to Win32 5264 wheelAmt *= -1 * WHEEL_DELTA; 5265 5266 message = WM_MOUSEWHEEL; 5267 wParam = MAKEWPARAM(wLow, wheelAmt); 5268 5269 break; 5270 default: 5271 return; 5272 } 5273 jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID); 5274 jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID); 5275 MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y); 5276 PostHandleEventMessage(msg, TRUE); 5277 } 5278 5279 BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;} 5280 5281 void AwtComponent::Invalidate(RECT* r) 5282 { 5283 ::InvalidateRect(GetHWnd(), r, FALSE); 5284 } 5285 5286 void AwtComponent::BeginValidate() 5287 { 5288 DASSERT(m_validationNestCount >= 0 && 5289 m_validationNestCount < 1000); // sanity check 5290 5291 if (m_validationNestCount == 0) { 5292 // begin deferred window positioning if we're not inside 5293 // another Begin/EndValidate pair 5294 DASSERT(m_hdwp == NULL); 5295 m_hdwp = ::BeginDeferWindowPos(32); 5296 } 5297 5298 m_validationNestCount++; 5299 } 5300 5301 void AwtComponent::EndValidate() 5302 { 5303 DASSERT(m_validationNestCount > 0 && 5304 m_validationNestCount < 1000); // sanity check 5305 DASSERT(m_hdwp != NULL); 5306 5307 m_validationNestCount--; 5308 if (m_validationNestCount == 0) { 5309 // if this call to EndValidate is not nested inside another 5310 // Begin/EndValidate pair, end deferred window positioning 5311 ::EndDeferWindowPos(m_hdwp); 5312 m_hdwp = NULL; 5313 } 5314 } 5315 5316 /** 5317 * HWND, AwtComponent and Java Peer interaction 5318 */ 5319 5320 /* 5321 *Link the C++, Java peer, and HWNDs together. 5322 */ 5323 void AwtComponent::LinkObjects(JNIEnv *env, jobject peer) 5324 { 5325 /* 5326 * Bind all three objects together thru this C++ object, two-way to each: 5327 * JavaPeer <-> C++ <-> HWND 5328 * 5329 * C++ -> JavaPeer 5330 */ 5331 if (m_peerObject == NULL) { 5332 // This may have already been set up by CreateHWnd 5333 // And we don't want to create two references so we 5334 // will leave the prior one alone 5335 m_peerObject = env->NewGlobalRef(peer); 5336 } 5337 /* JavaPeer -> HWND */ 5338 env->SetLongField(peer, AwtComponent::hwndID, reinterpret_cast<jlong>(m_hwnd)); 5339 5340 /* JavaPeer -> C++ */ 5341 JNI_SET_PDATA(peer, this); 5342 5343 /* HWND -> C++ */ 5344 SetComponentInHWND(); 5345 } 5346 5347 /* Cleanup above linking */ 5348 void AwtComponent::UnlinkObjects() 5349 { 5350 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5351 if (m_peerObject) { 5352 env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); 5353 JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL)); 5354 JNI_SET_DESTROYED(m_peerObject); 5355 env->DeleteGlobalRef(m_peerObject); 5356 m_peerObject = NULL; 5357 } 5358 } 5359 5360 void AwtComponent::Enable(BOOL bEnable) 5361 { 5362 if (bEnable && IsTopLevel()) { 5363 // we should not enable blocked toplevels 5364 bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); 5365 } 5366 // Shouldn't trigger native focus change 5367 // (only the proxy may be the native focus owner). 5368 ::EnableWindow(GetHWnd(), bEnable); 5369 5370 CriticalSection::Lock l(GetLock()); 5371 VerifyState(); 5372 } 5373 5374 /* 5375 * associate an AwtDropTarget with this AwtComponent 5376 */ 5377 5378 AwtDropTarget* AwtComponent::CreateDropTarget(JNIEnv* env) { 5379 m_dropTarget = new AwtDropTarget(env, this); 5380 m_dropTarget->RegisterTarget(TRUE); 5381 return m_dropTarget; 5382 } 5383 5384 /* 5385 * disassociate an AwtDropTarget with this AwtComponent 5386 */ 5387 5388 void AwtComponent::DestroyDropTarget() { 5389 if (m_dropTarget != NULL) { 5390 m_dropTarget->RegisterTarget(FALSE); 5391 m_dropTarget->Release(); 5392 m_dropTarget = NULL; 5393 } 5394 } 5395 5396 BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) { 5397 return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK; 5398 } 5399 5400 BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) { 5401 return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE; 5402 } 5403 5404 void AwtComponent::_Show(void *param) 5405 { 5406 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5407 5408 jobject self = (jobject)param; 5409 5410 AwtComponent *p; 5411 5412 PDATA pData; 5413 JNI_CHECK_PEER_GOTO(self, ret); 5414 p = (AwtComponent *)pData; 5415 if (::IsWindow(p->GetHWnd())) 5416 { 5417 p->SendMessage(WM_AWT_COMPONENT_SHOW); 5418 } 5419 ret: 5420 env->DeleteGlobalRef(self); 5421 } 5422 5423 void AwtComponent::_Hide(void *param) 5424 { 5425 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5426 5427 jobject self = (jobject)param; 5428 5429 AwtComponent *p; 5430 5431 PDATA pData; 5432 JNI_CHECK_PEER_GOTO(self, ret); 5433 p = (AwtComponent *)pData; 5434 if (::IsWindow(p->GetHWnd())) 5435 { 5436 p->SendMessage(WM_AWT_COMPONENT_HIDE); 5437 } 5438 ret: 5439 env->DeleteGlobalRef(self); 5440 } 5441 5442 void AwtComponent::_Enable(void *param) 5443 { 5444 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5445 5446 jobject self = (jobject)param; 5447 5448 AwtComponent *p; 5449 5450 PDATA pData; 5451 JNI_CHECK_PEER_GOTO(self, ret); 5452 p = (AwtComponent *)pData; 5453 if (::IsWindow(p->GetHWnd())) 5454 { 5455 p->Enable(TRUE); 5456 } 5457 ret: 5458 env->DeleteGlobalRef(self); 5459 } 5460 5461 void AwtComponent::_Disable(void *param) 5462 { 5463 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5464 5465 jobject self = (jobject)param; 5466 5467 AwtComponent *p; 5468 5469 PDATA pData; 5470 JNI_CHECK_PEER_GOTO(self, ret); 5471 p = (AwtComponent *)pData; 5472 if (::IsWindow(p->GetHWnd())) 5473 { 5474 p->Enable(FALSE); 5475 } 5476 ret: 5477 env->DeleteGlobalRef(self); 5478 } 5479 5480 jobject AwtComponent::_GetLocationOnScreen(void *param) 5481 { 5482 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5483 5484 jobject self = (jobject)param; 5485 5486 jobject result = NULL; 5487 AwtComponent *p; 5488 5489 PDATA pData; 5490 JNI_CHECK_PEER_GOTO(self, ret); 5491 p = (AwtComponent *)pData; 5492 if (::IsWindow(p->GetHWnd())) 5493 { 5494 RECT rect; 5495 VERIFY(::GetWindowRect(p->GetHWnd(),&rect)); 5496 result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", 5497 rect.left, rect.top); 5498 } 5499 ret: 5500 env->DeleteGlobalRef(self); 5501 5502 if (result != NULL) 5503 { 5504 jobject resultGlobalRef = env->NewGlobalRef(result); 5505 env->DeleteLocalRef(result); 5506 return resultGlobalRef; 5507 } 5508 else 5509 { 5510 return NULL; 5511 } 5512 } 5513 5514 void AwtComponent::_Reshape(void *param) 5515 { 5516 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5517 5518 ReshapeStruct *rs = (ReshapeStruct*)param; 5519 jobject self = rs->component; 5520 jint x = rs->x; 5521 jint y = rs->y; 5522 jint w = rs->w; 5523 jint h = rs->h; 5524 5525 AwtComponent *p; 5526 5527 PDATA pData; 5528 JNI_CHECK_PEER_GOTO(self, ret); 5529 p = (AwtComponent *)pData; 5530 if (::IsWindow(p->GetHWnd())) 5531 { 5532 RECT* r = new RECT; 5533 ::SetRect(r, x, y, x + w, y + h); 5534 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, CHECK_EMBEDDED, (LPARAM)r); 5535 } 5536 ret: 5537 env->DeleteGlobalRef(self); 5538 5539 delete rs; 5540 } 5541 5542 void AwtComponent::_ReshapeNoCheck(void *param) 5543 { 5544 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5545 5546 ReshapeStruct *rs = (ReshapeStruct*)param; 5547 jobject self = rs->component; 5548 jint x = rs->x; 5549 jint y = rs->y; 5550 jint w = rs->w; 5551 jint h = rs->h; 5552 5553 AwtComponent *p; 5554 5555 PDATA pData; 5556 JNI_CHECK_PEER_GOTO(self, ret); 5557 p = (AwtComponent *)pData; 5558 if (::IsWindow(p->GetHWnd())) 5559 { 5560 RECT* r = new RECT; 5561 ::SetRect(r, x, y, x + w, y + h); 5562 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, DONT_CHECK_EMBEDDED, (LPARAM)r); 5563 } 5564 ret: 5565 env->DeleteGlobalRef(self); 5566 5567 delete rs; 5568 } 5569 5570 void AwtComponent::_NativeHandleEvent(void *param) 5571 { 5572 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5573 5574 NativeHandleEventStruct *nhes = (NativeHandleEventStruct *)param; 5575 jobject self = nhes->component; 5576 jobject event = nhes->event; 5577 5578 AwtComponent *p; 5579 5580 PDATA pData; 5581 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5582 pData = JNI_GET_PDATA(self); 5583 if (pData == NULL) { 5584 env->DeleteGlobalRef(self); 5585 if (event != NULL) { 5586 env->DeleteGlobalRef(event); 5587 } 5588 delete nhes; 5589 return; 5590 } 5591 JNI_CHECK_NULL_GOTO(event, "null AWTEvent", ret); 5592 5593 p = (AwtComponent *)pData; 5594 if (::IsWindow(p->GetHWnd())) 5595 { 5596 if (env->EnsureLocalCapacity(1) < 0) { 5597 env->DeleteGlobalRef(self); 5598 env->DeleteGlobalRef(event); 5599 delete nhes; 5600 return; 5601 } 5602 jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID); 5603 int id = (env)->GetIntField(event, AwtAWTEvent::idID); 5604 DASSERT(!safe_ExceptionOccurred(env)); 5605 if (bdata != 0) { 5606 MSG msg; 5607 (env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg); 5608 (env)->DeleteLocalRef(bdata); 5609 static BOOL keyDownConsumed = FALSE; 5610 static BOOL bCharChanged = FALSE; 5611 static WCHAR modifiedChar; 5612 WCHAR unicodeChar; 5613 5614 /* Remember if a KEY_PRESSED event is consumed, as an old model 5615 * program won't consume a subsequent KEY_TYPED event. 5616 */ 5617 jboolean consumed = 5618 (env)->GetBooleanField(event, AwtAWTEvent::consumedID); 5619 DASSERT(!safe_ExceptionOccurred(env)); 5620 5621 if (consumed) { 5622 keyDownConsumed = (id == java_awt_event_KeyEvent_KEY_PRESSED); 5623 env->DeleteGlobalRef(self); 5624 env->DeleteGlobalRef(event); 5625 delete nhes; 5626 return; 5627 5628 } else if (id == java_awt_event_KeyEvent_KEY_PRESSED) { 5629 // Fix for 6637607: reset consuming 5630 keyDownConsumed = FALSE; 5631 } 5632 5633 /* Consume a KEY_TYPED event if a KEY_PRESSED had been, to support 5634 * the old model. 5635 */ 5636 if ((id == java_awt_event_KeyEvent_KEY_TYPED) && keyDownConsumed) { 5637 keyDownConsumed = FALSE; 5638 env->DeleteGlobalRef(self); 5639 env->DeleteGlobalRef(event); 5640 delete nhes; 5641 return; 5642 } 5643 5644 /* Modify any event parameters, if necessary. */ 5645 if (self && pData && 5646 id >= java_awt_event_KeyEvent_KEY_FIRST && 5647 id <= java_awt_event_KeyEvent_KEY_LAST) { 5648 5649 AwtComponent* p = (AwtComponent*)pData; 5650 5651 jint keyCode = 5652 (env)->GetIntField(event, AwtKeyEvent::keyCodeID); 5653 jchar keyChar = 5654 (env)->GetCharField(event, AwtKeyEvent::keyCharID); 5655 jint modifiers = 5656 (env)->GetIntField(event, AwtInputEvent::modifiersID); 5657 5658 DASSERT(!safe_ExceptionOccurred(env)); 5659 5660 /* Check to see whether the keyCode or modifiers were changed 5661 on the keyPressed event, and tweak the following keyTyped 5662 event (if any) accodingly. */ 5663 switch (id) { 5664 case java_awt_event_KeyEvent_KEY_PRESSED: 5665 { 5666 UINT winKey = (UINT)msg.wParam; 5667 bCharChanged = FALSE; 5668 5669 if (winKey == VK_PROCESSKEY) { 5670 // Leave it up to IME 5671 break; 5672 } 5673 5674 if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) { 5675 UINT newWinKey, ignored; 5676 p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey); 5677 if (newWinKey != 0) { 5678 winKey = newWinKey; 5679 } 5680 } 5681 5682 BOOL isDeadKey = FALSE; 5683 modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey); 5684 bCharChanged = (keyChar != modifiedChar); 5685 } 5686 break; 5687 5688 case java_awt_event_KeyEvent_KEY_RELEASED: 5689 { 5690 keyDownConsumed = FALSE; 5691 bCharChanged = FALSE; 5692 } 5693 break; 5694 5695 case java_awt_event_KeyEvent_KEY_TYPED: 5696 { 5697 if (bCharChanged) 5698 { 5699 unicodeChar = modifiedChar; 5700 } 5701 else 5702 { 5703 unicodeChar = keyChar; 5704 } 5705 bCharChanged = FALSE; 5706 5707 // Disable forwarding KEY_TYPED messages to peers of 5708 // disabled components 5709 if (p->isRecursivelyEnabled()) { 5710 // send the character back to the native window for 5711 // processing. The WM_AWT_FORWARD_CHAR handler will send 5712 // this character to DefWindowProc 5713 if (!::PostMessage(p->GetHWnd(), WM_AWT_FORWARD_CHAR, 5714 MAKEWPARAM(unicodeChar, FALSE), msg.lParam)) { 5715 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5716 } 5717 } 5718 env->DeleteGlobalRef(self); 5719 env->DeleteGlobalRef(event); 5720 delete nhes; 5721 return; 5722 } 5723 break; 5724 5725 default: 5726 break; 5727 } 5728 } 5729 5730 // ignore all InputMethodEvents 5731 if (self && (pData = JNI_GET_PDATA(self)) && 5732 id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST && 5733 id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) { 5734 env->DeleteGlobalRef(self); 5735 env->DeleteGlobalRef(event); 5736 delete nhes; 5737 return; 5738 } 5739 5740 // Create copy for local msg 5741 MSG* pCopiedMsg = new MSG; 5742 memmove(pCopiedMsg, &msg, sizeof(MSG)); 5743 // Event handler deletes msg 5744 p->PostHandleEventMessage(pCopiedMsg, FALSE); 5745 5746 env->DeleteGlobalRef(self); 5747 env->DeleteGlobalRef(event); 5748 delete nhes; 5749 return; 5750 } 5751 5752 /* Forward any valid synthesized events. Currently only mouse and 5753 * key events are supported. 5754 */ 5755 if (self == NULL || (pData = JNI_GET_PDATA(self)) == NULL) { 5756 env->DeleteGlobalRef(self); 5757 env->DeleteGlobalRef(event); 5758 delete nhes; 5759 return; 5760 } 5761 5762 AwtComponent* p = (AwtComponent*)pData; 5763 if (id >= java_awt_event_KeyEvent_KEY_FIRST && 5764 id <= java_awt_event_KeyEvent_KEY_LAST) { 5765 p->SynthesizeKeyMessage(env, event); 5766 } else if (id >= java_awt_event_MouseEvent_MOUSE_FIRST && 5767 id <= java_awt_event_MouseEvent_MOUSE_LAST) { 5768 p->SynthesizeMouseMessage(env, event); 5769 } 5770 } 5771 5772 ret: 5773 if (self != NULL) { 5774 env->DeleteGlobalRef(self); 5775 } 5776 if (event != NULL) { 5777 env->DeleteGlobalRef(event); 5778 } 5779 5780 delete nhes; 5781 } 5782 5783 void AwtComponent::_SetForeground(void *param) 5784 { 5785 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5786 5787 SetColorStruct *scs = (SetColorStruct *)param; 5788 jobject self = scs->component; 5789 jint rgb = scs->rgb; 5790 5791 AwtComponent *c = NULL; 5792 5793 PDATA pData; 5794 JNI_CHECK_PEER_GOTO(self, ret); 5795 c = (AwtComponent *)pData; 5796 if (::IsWindow(c->GetHWnd())) 5797 { 5798 c->SetColor(PALETTERGB((rgb>>16)&0xff, 5799 (rgb>>8)&0xff, 5800 (rgb)&0xff)); 5801 c->VerifyState(); 5802 } 5803 ret: 5804 env->DeleteGlobalRef(self); 5805 5806 delete scs; 5807 } 5808 5809 void AwtComponent::_SetBackground(void *param) 5810 { 5811 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5812 5813 SetColorStruct *scs = (SetColorStruct *)param; 5814 jobject self = scs->component; 5815 jint rgb = scs->rgb; 5816 5817 AwtComponent *c = NULL; 5818 5819 PDATA pData; 5820 JNI_CHECK_PEER_GOTO(self, ret); 5821 c = (AwtComponent *)pData; 5822 if (::IsWindow(c->GetHWnd())) 5823 { 5824 c->SetBackgroundColor(PALETTERGB((rgb>>16)&0xff, 5825 (rgb>>8)&0xff, 5826 (rgb)&0xff)); 5827 c->VerifyState(); 5828 } 5829 ret: 5830 env->DeleteGlobalRef(self); 5831 5832 delete scs; 5833 } 5834 5835 void AwtComponent::_SetFont(void *param) 5836 { 5837 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5838 5839 SetFontStruct *sfs = (SetFontStruct *)param; 5840 jobject self = sfs->component; 5841 jobject font = sfs->font; 5842 5843 AwtComponent *c = NULL; 5844 5845 PDATA pData; 5846 JNI_CHECK_PEER_GOTO(self, ret); 5847 JNI_CHECK_NULL_GOTO(font, "null font", ret); 5848 c = (AwtComponent *)pData; 5849 if (::IsWindow(c->GetHWnd())) 5850 { 5851 AwtFont *awtFont = (AwtFont *)env->GetLongField(font, AwtFont::pDataID); 5852 if (awtFont == NULL) { 5853 /*arguments of AwtFont::Create are changed for multifont component */ 5854 awtFont = AwtFont::Create(env, font); 5855 } 5856 env->SetLongField(font, AwtFont::pDataID, (jlong)awtFont); 5857 5858 c->SetFont(awtFont); 5859 } 5860 ret: 5861 env->DeleteGlobalRef(self); 5862 env->DeleteGlobalRef(font); 5863 5864 delete sfs; 5865 } 5866 5867 // Sets or kills focus for a component. 5868 void AwtComponent::_SetFocus(void *param) 5869 { 5870 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5871 5872 SetFocusStruct *sfs = (SetFocusStruct *)param; 5873 jobject self = sfs->component; 5874 jboolean doSetFocus = sfs->doSetFocus; 5875 5876 AwtComponent *c = NULL; 5877 5878 PDATA pData; 5879 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5880 pData = JNI_GET_PDATA(self); 5881 if (pData == NULL) { 5882 // do nothing just return false 5883 goto ret; 5884 } 5885 5886 c = (AwtComponent *)pData; 5887 if (::IsWindow(c->GetHWnd())) { 5888 c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0); 5889 } 5890 ret: 5891 env->DeleteGlobalRef(self); 5892 5893 delete sfs; 5894 } 5895 5896 void AwtComponent::_Start(void *param) 5897 { 5898 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5899 5900 jobject self = (jobject)param; 5901 5902 AwtComponent *c = NULL; 5903 5904 PDATA pData; 5905 JNI_CHECK_PEER_GOTO(self, ret); 5906 c = (AwtComponent *)pData; 5907 if (::IsWindow(c->GetHWnd())) 5908 { 5909 jobject target = c->GetTarget(env); 5910 5911 /* Disable window if specified -- windows are enabled by default. */ 5912 jboolean enabled = (jboolean)env->GetBooleanField(target, 5913 AwtComponent::enabledID); 5914 if (!enabled) { 5915 ::EnableWindow(c->GetHWnd(), FALSE); 5916 } 5917 5918 /* The peer is now ready for callbacks, since this is the last 5919 * initialization call 5920 */ 5921 c->EnableCallbacks(TRUE); 5922 5923 // Fix 4745222: we need to invalidate region since we validated it before initialization. 5924 ::InvalidateRgn(c->GetHWnd(), NULL, FALSE); 5925 5926 // Fix 4530093: WM_PAINT after EnableCallbacks 5927 ::UpdateWindow(c->GetHWnd()); 5928 5929 env->DeleteLocalRef(target); 5930 } 5931 ret: 5932 env->DeleteGlobalRef(self); 5933 } 5934 5935 void AwtComponent::_BeginValidate(void *param) 5936 { 5937 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5938 if (AwtToolkit::IsMainThread()) { 5939 jobject self = (jobject)param; 5940 if (self != NULL) { 5941 PDATA pData = JNI_GET_PDATA(self); 5942 if (pData) { 5943 AwtComponent *c = (AwtComponent *)pData; 5944 if (::IsWindow(c->GetHWnd())) { 5945 c->SendMessage(WM_AWT_BEGIN_VALIDATE); 5946 } 5947 } 5948 env->DeleteGlobalRef(self); 5949 } 5950 } else { 5951 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_BeginValidate, param); 5952 } 5953 } 5954 5955 void AwtComponent::_EndValidate(void *param) 5956 { 5957 if (AwtToolkit::IsMainThread()) { 5958 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5959 jobject self = (jobject)param; 5960 if (self != NULL) { 5961 PDATA pData = JNI_GET_PDATA(self); 5962 if (pData) { 5963 AwtComponent *c = (AwtComponent *)pData; 5964 if (::IsWindow(c->GetHWnd())) { 5965 c->SendMessage(WM_AWT_END_VALIDATE); 5966 } 5967 } 5968 env->DeleteGlobalRef(self); 5969 } 5970 } else { 5971 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_EndValidate, param); 5972 } 5973 } 5974 5975 void AwtComponent::_UpdateWindow(void *param) 5976 { 5977 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5978 if (AwtToolkit::IsMainThread()) { 5979 jobject self = (jobject)param; 5980 AwtComponent *c = NULL; 5981 PDATA pData; 5982 JNI_CHECK_PEER_GOTO(self, ret); 5983 c = (AwtComponent *)pData; 5984 if (::IsWindow(c->GetHWnd())) { 5985 ::UpdateWindow(c->GetHWnd()); 5986 } 5987 ret: 5988 env->DeleteGlobalRef(self); 5989 } else { 5990 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_UpdateWindow, param); 5991 } 5992 } 5993 5994 jlong AwtComponent::_AddNativeDropTarget(void *param) 5995 { 5996 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5997 5998 jobject self = (jobject)param; 5999 6000 jlong result = 0; 6001 AwtComponent *c = NULL; 6002 6003 PDATA pData; 6004 JNI_CHECK_PEER_GOTO(self, ret); 6005 c = (AwtComponent *)pData; 6006 if (::IsWindow(c->GetHWnd())) 6007 { 6008 result = (jlong)(c->CreateDropTarget(env)); 6009 } 6010 ret: 6011 env->DeleteGlobalRef(self); 6012 6013 return result; 6014 } 6015 6016 void AwtComponent::_RemoveNativeDropTarget(void *param) 6017 { 6018 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6019 6020 jobject self = (jobject)param; 6021 6022 AwtComponent *c = NULL; 6023 6024 PDATA pData; 6025 JNI_CHECK_PEER_GOTO(self, ret); 6026 c = (AwtComponent *)pData; 6027 if (::IsWindow(c->GetHWnd())) 6028 { 6029 c->DestroyDropTarget(); 6030 } 6031 ret: 6032 env->DeleteGlobalRef(self); 6033 } 6034 6035 jintArray AwtComponent::_CreatePrintedPixels(void *param) 6036 { 6037 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6038 6039 CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param; 6040 jobject self = cpps->component; 6041 6042 jintArray result = NULL; 6043 AwtComponent *c = NULL; 6044 6045 PDATA pData; 6046 JNI_CHECK_PEER_GOTO(self, ret); 6047 c = (AwtComponent *)pData; 6048 if (::IsWindow(c->GetHWnd())) 6049 { 6050 result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0); 6051 } 6052 ret: 6053 env->DeleteGlobalRef(self); 6054 6055 delete cpps; 6056 return result; // this reference is global 6057 } 6058 6059 jboolean AwtComponent::_IsObscured(void *param) 6060 { 6061 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6062 6063 jobject self = (jobject)param; 6064 6065 jboolean result = JNI_FALSE; 6066 AwtComponent *c = NULL; 6067 6068 PDATA pData; 6069 JNI_CHECK_PEER_GOTO(self, ret); 6070 6071 c = (AwtComponent *)pData; 6072 6073 if (::IsWindow(c->GetHWnd())) 6074 { 6075 HWND hWnd = c->GetHWnd(); 6076 HDC hDC = ::GetDC(hWnd); 6077 RECT clipbox; 6078 int callresult = ::GetClipBox(hDC, &clipbox); 6079 switch(callresult) { 6080 case NULLREGION : 6081 result = JNI_FALSE; 6082 break; 6083 case SIMPLEREGION : { 6084 RECT windowRect; 6085 if (!::GetClientRect(hWnd, &windowRect)) { 6086 result = JNI_TRUE; 6087 } else { 6088 result = (jboolean)((clipbox.bottom != windowRect.bottom) 6089 || (clipbox.left != windowRect.left) 6090 || (clipbox.right != windowRect.right) 6091 || (clipbox.top != windowRect.top)); 6092 } 6093 break; 6094 } 6095 case COMPLEXREGION : 6096 default : 6097 result = JNI_TRUE; 6098 break; 6099 } 6100 ::ReleaseDC(hWnd, hDC); 6101 } 6102 ret: 6103 env->DeleteGlobalRef(self); 6104 6105 return result; 6106 } 6107 6108 jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param) 6109 { 6110 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6111 6112 jobject self = (jobject)param; 6113 6114 jboolean result = JNI_FALSE; 6115 AwtComponent *c = NULL; 6116 6117 PDATA pData; 6118 JNI_CHECK_PEER_GOTO(self, ret); 6119 c = (AwtComponent *)pData; 6120 if (::IsWindow(c->GetHWnd())) 6121 { 6122 result = JNI_IS_TRUE(c->InheritsNativeMouseWheelBehavior()); 6123 } 6124 ret: 6125 env->DeleteGlobalRef(self); 6126 6127 return result; 6128 } 6129 6130 void AwtComponent::SetParent(void * param) { 6131 if (AwtToolkit::IsMainThread()) { 6132 AwtComponent** comps = (AwtComponent**)param; 6133 if ((comps[0] != NULL) && (comps[1] != NULL)) { 6134 HWND selfWnd = comps[0]->GetHWnd(); 6135 HWND parentWnd = comps[1]->GetHWnd(); 6136 if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) { 6137 // Shouldn't trigger native focus change 6138 // (only the proxy may be the native focus owner). 6139 ::SetParent(selfWnd, parentWnd); 6140 } 6141 } 6142 delete[] comps; 6143 } else { 6144 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::SetParent, param); 6145 } 6146 } 6147 6148 void AwtComponent::_SetRectangularShape(void *param) 6149 { 6150 if (!AwtToolkit::IsMainThread()) { 6151 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param); 6152 } else { 6153 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6154 6155 SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param; 6156 jobject self = data->component; 6157 jint x1 = data->x1; 6158 jint x2 = data->x2; 6159 jint y1 = data->y1; 6160 jint y2 = data->y2; 6161 jobject region = data->region; 6162 6163 AwtComponent *c = NULL; 6164 6165 PDATA pData; 6166 JNI_CHECK_PEER_GOTO(self, ret); 6167 6168 c = (AwtComponent *)pData; 6169 if (::IsWindow(c->GetHWnd())) { 6170 HRGN hRgn = NULL; 6171 6172 // If all the params are zeros, the shape must be simply reset. 6173 // Otherwise, convert it into a region. 6174 if (region || x1 || x2 || y1 || y2) { 6175 RECT_T rects[256]; 6176 RECT_T *pRect = rects; 6177 6178 const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2, 6179 region, &pRect, sizeof(rects)/sizeof(rects[0])); 6180 if (!pRect) { 6181 // RegionToYXBandedRectangles doesn't use safe_Malloc(), 6182 // so throw the exception explicitly 6183 throw std::bad_alloc(); 6184 } 6185 6186 RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, 6187 sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects); 6188 memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects); 6189 if (pRect != rects) { 6190 free(pRect); 6191 } 6192 pRect = NULL; 6193 6194 RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData; 6195 pRgnHdr->dwSize = sizeof(RGNDATAHEADER); 6196 pRgnHdr->iType = RDH_RECTANGLES; 6197 pRgnHdr->nRgnSize = 0; 6198 pRgnHdr->rcBound.top = 0; 6199 pRgnHdr->rcBound.left = 0; 6200 pRgnHdr->rcBound.bottom = LONG(y2 - y1); 6201 pRgnHdr->rcBound.right = LONG(x2 - x1); 6202 pRgnHdr->nCount = numrects; 6203 6204 hRgn = ::ExtCreateRegion(NULL, 6205 sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData); 6206 6207 free(pRgnData); 6208 } 6209 6210 ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE); 6211 } 6212 6213 ret: 6214 env->DeleteGlobalRef(self); 6215 if (region) { 6216 env->DeleteGlobalRef(region); 6217 } 6218 6219 delete data; 6220 } 6221 } 6222 6223 void AwtComponent::_SetZOrder(void *param) { 6224 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6225 6226 SetZOrderStruct *data = (SetZOrderStruct *)param; 6227 jobject self = data->component; 6228 HWND above = HWND_TOP; 6229 if (data->above != 0) { 6230 above = reinterpret_cast<HWND>(data->above); 6231 } 6232 6233 AwtComponent *c = NULL; 6234 6235 PDATA pData; 6236 JNI_CHECK_PEER_GOTO(self, ret); 6237 6238 c = (AwtComponent *)pData; 6239 if (::IsWindow(c->GetHWnd())) { 6240 ::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0, 6241 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS); 6242 } 6243 6244 ret: 6245 env->DeleteGlobalRef(self); 6246 6247 delete data; 6248 } 6249 6250 void AwtComponent::PostUngrabEvent() { 6251 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6252 jobject target = GetTarget(env); 6253 jobject event = JNU_NewObjectByName(env, "sun/awt/UngrabEvent", "(Ljava/awt/Component;)V", 6254 target); 6255 if (safe_ExceptionOccurred(env)) { 6256 env->ExceptionDescribe(); 6257 env->ExceptionClear(); 6258 } 6259 env->DeleteLocalRef(target); 6260 if (event != NULL) { 6261 SendEvent(event); 6262 env->DeleteLocalRef(event); 6263 } 6264 } 6265 6266 void AwtComponent::SetFocusedWindow(HWND window) 6267 { 6268 HWND old = sm_focusedWindow; 6269 sm_focusedWindow = window; 6270 6271 AwtWindow::FocusedWindowChanged(old, window); 6272 } 6273 6274 /************************************************************************ 6275 * Component native methods 6276 */ 6277 6278 extern "C" { 6279 6280 /** 6281 * This method is called from the WGL pipeline when it needs to retrieve 6282 * the HWND associated with a ComponentPeer's C++ level object. 6283 */ 6284 HWND 6285 AwtComponent_GetHWnd(JNIEnv *env, jlong pData) 6286 { 6287 AwtComponent *p = (AwtComponent *)jlong_to_ptr(pData); 6288 if (p == NULL) { 6289 return (HWND)0; 6290 } 6291 return p->GetHWnd(); 6292 } 6293 6294 static void _GetInsets(void* param) 6295 { 6296 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6297 6298 GetInsetsStruct *gis = (GetInsetsStruct *)param; 6299 jobject self = gis->window; 6300 6301 gis->insets->left = gis->insets->top = 6302 gis->insets->right = gis->insets->bottom = 0; 6303 6304 PDATA pData; 6305 JNI_CHECK_PEER_GOTO(self, ret); 6306 AwtComponent *component = (AwtComponent *)pData; 6307 6308 component->GetInsets(gis->insets); 6309 6310 ret: 6311 env->DeleteGlobalRef(self); 6312 delete gis; 6313 } 6314 6315 /** 6316 * This method is called from the WGL pipeline when it needs to retrieve 6317 * the insets associated with a ComponentPeer's C++ level object. 6318 */ 6319 void AwtComponent_GetInsets(JNIEnv *env, jobject peer, RECT *insets) 6320 { 6321 TRY; 6322 6323 GetInsetsStruct *gis = new GetInsetsStruct; 6324 gis->window = env->NewGlobalRef(peer); 6325 gis->insets = insets; 6326 6327 AwtToolkit::GetInstance().InvokeFunction(_GetInsets, gis); 6328 // global refs and mds are deleted in _UpdateWindow 6329 6330 CATCH_BAD_ALLOC; 6331 6332 } 6333 6334 JNIEXPORT void JNICALL 6335 Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) 6336 { 6337 TRY; 6338 jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent"); 6339 CHECK_NULL(inputEventClazz); 6340 jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I"); 6341 CHECK_NULL(getButtonDownMasksID); 6342 jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID); 6343 jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE); 6344 CHECK_NULL(tmp); 6345 jsize len = env->GetArrayLength(obj); 6346 AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len); 6347 for (int i = 0; i < len; i++) { 6348 AwtComponent::masks[i] = tmp[i]; 6349 } 6350 env->ReleaseIntArrayElements(obj, tmp, 0); 6351 env->DeleteLocalRef(obj); 6352 6353 /* class ids */ 6354 jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer"); 6355 6356 DASSERT(peerCls); 6357 CHECK_NULL(peerCls); 6358 6359 /* field ids */ 6360 AwtComponent::peerID = 6361 env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;"); 6362 DASSERT(AwtComponent::peerID); 6363 CHECK_NULL(AwtComponent::peerID); 6364 6365 AwtComponent::xID = env->GetFieldID(cls, "x", "I"); 6366 DASSERT(AwtComponent::xID); 6367 CHECK_NULL(AwtComponent::xID); 6368 6369 AwtComponent::yID = env->GetFieldID(cls, "y", "I"); 6370 DASSERT(AwtComponent::yID); 6371 CHECK_NULL(AwtComponent::yID); 6372 6373 AwtComponent::heightID = env->GetFieldID(cls, "height", "I"); 6374 DASSERT(AwtComponent::heightID); 6375 CHECK_NULL(AwtComponent::heightID); 6376 6377 AwtComponent::widthID = env->GetFieldID(cls, "width", "I"); 6378 DASSERT(AwtComponent::widthID); 6379 CHECK_NULL(AwtComponent::widthID); 6380 6381 AwtComponent::visibleID = env->GetFieldID(cls, "visible", "Z"); 6382 DASSERT(AwtComponent::visibleID); 6383 CHECK_NULL(AwtComponent::visibleID); 6384 6385 AwtComponent::backgroundID = 6386 env->GetFieldID(cls, "background", "Ljava/awt/Color;"); 6387 DASSERT(AwtComponent::backgroundID); 6388 CHECK_NULL(AwtComponent::backgroundID); 6389 6390 AwtComponent::foregroundID = 6391 env->GetFieldID(cls, "foreground", "Ljava/awt/Color;"); 6392 DASSERT(AwtComponent::foregroundID); 6393 CHECK_NULL(AwtComponent::foregroundID); 6394 6395 AwtComponent::enabledID = env->GetFieldID(cls, "enabled", "Z"); 6396 DASSERT(AwtComponent::enabledID); 6397 CHECK_NULL(AwtComponent::enabledID); 6398 6399 AwtComponent::parentID = env->GetFieldID(cls, "parent", "Ljava/awt/Container;"); 6400 DASSERT(AwtComponent::parentID); 6401 CHECK_NULL(AwtComponent::parentID); 6402 6403 AwtComponent::graphicsConfigID = 6404 env->GetFieldID(cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;"); 6405 DASSERT(AwtComponent::graphicsConfigID); 6406 CHECK_NULL(AwtComponent::graphicsConfigID); 6407 6408 AwtComponent::focusableID = env->GetFieldID(cls, "focusable", "Z"); 6409 DASSERT(AwtComponent::focusableID); 6410 CHECK_NULL(AwtComponent::focusableID); 6411 6412 AwtComponent::appContextID = env->GetFieldID(cls, "appContext", 6413 "Lsun/awt/AppContext;"); 6414 DASSERT(AwtComponent::appContextID); 6415 CHECK_NULL(AwtComponent::appContextID); 6416 6417 AwtComponent::peerGCID = env->GetFieldID(peerCls, "winGraphicsConfig", 6418 "Lsun/awt/Win32GraphicsConfig;"); 6419 DASSERT(AwtComponent::peerGCID); 6420 CHECK_NULL(AwtComponent::peerGCID); 6421 6422 AwtComponent::hwndID = env->GetFieldID(peerCls, "hwnd", "J"); 6423 DASSERT(AwtComponent::hwndID); 6424 CHECK_NULL(AwtComponent::hwndID); 6425 6426 AwtComponent::cursorID = env->GetFieldID(cls, "cursor", "Ljava/awt/Cursor;"); 6427 DASSERT(AwtComponent::cursorID); 6428 CHECK_NULL(AwtComponent::cursorID); 6429 6430 /* method ids */ 6431 AwtComponent::getFontMID = 6432 env->GetMethodID(cls, "getFont_NoClientCode", "()Ljava/awt/Font;"); 6433 DASSERT(AwtComponent::getFontMID); 6434 CHECK_NULL(AwtComponent::getFontMID); 6435 6436 AwtComponent::getToolkitMID = 6437 env->GetMethodID(cls, "getToolkitImpl", "()Ljava/awt/Toolkit;"); 6438 DASSERT(AwtComponent::getToolkitMID); 6439 CHECK_NULL(AwtComponent::getToolkitMID); 6440 6441 AwtComponent::isEnabledMID = env->GetMethodID(cls, "isEnabledImpl", "()Z"); 6442 DASSERT(AwtComponent::isEnabledMID); 6443 CHECK_NULL(AwtComponent::isEnabledMID); 6444 6445 AwtComponent::getLocationOnScreenMID = 6446 env->GetMethodID(cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;"); 6447 DASSERT(AwtComponent::getLocationOnScreenMID); 6448 CHECK_NULL(AwtComponent::getLocationOnScreenMID); 6449 6450 AwtComponent::replaceSurfaceDataMID = 6451 env->GetMethodID(peerCls, "replaceSurfaceData", "()V"); 6452 DASSERT(AwtComponent::replaceSurfaceDataMID); 6453 CHECK_NULL(AwtComponent::replaceSurfaceDataMID); 6454 6455 AwtComponent::replaceSurfaceDataLaterMID = 6456 env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V"); 6457 DASSERT(AwtComponent::replaceSurfaceDataLaterMID); 6458 CHECK_NULL(AwtComponent::replaceSurfaceDataLaterMID); 6459 6460 AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V"); 6461 DASSERT(AwtComponent::disposeLaterMID); 6462 CHECK_NULL(AwtComponent::disposeLaterMID); 6463 6464 CATCH_BAD_ALLOC; 6465 } 6466 6467 } /* extern "C" */ 6468 6469 6470 /************************************************************************ 6471 * ComponentPeer native methods 6472 */ 6473 6474 extern "C" { 6475 6476 /* 6477 * Class: sun_awt_windows_WComponentPeer 6478 * Method: pShow 6479 * Signature: ()V 6480 */ 6481 JNIEXPORT void JNICALL 6482 Java_sun_awt_windows_WComponentPeer_pShow(JNIEnv *env, jobject self) 6483 { 6484 TRY; 6485 6486 jobject selfGlobalRef = env->NewGlobalRef(self); 6487 6488 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Show, (void *)selfGlobalRef); 6489 // selfGlobalRef is deleted in _Show 6490 6491 CATCH_BAD_ALLOC; 6492 } 6493 6494 /* 6495 * Class: sun_awt_windows_WComponentPeer 6496 * Method: hide 6497 * Signature: ()V 6498 */ 6499 JNIEXPORT void JNICALL 6500 Java_sun_awt_windows_WComponentPeer_hide(JNIEnv *env, jobject self) 6501 { 6502 TRY; 6503 6504 jobject selfGlobalRef = env->NewGlobalRef(self); 6505 6506 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Hide, (void *)selfGlobalRef); 6507 // selfGlobalRef is deleted in _Hide 6508 6509 CATCH_BAD_ALLOC; 6510 } 6511 6512 /* 6513 * Class: sun_awt_windows_WComponentPeer 6514 * Method: enable 6515 * Signature: ()V 6516 */ 6517 JNIEXPORT void JNICALL 6518 Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self) 6519 { 6520 TRY; 6521 6522 jobject selfGlobalRef = env->NewGlobalRef(self); 6523 6524 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Enable, (void *)selfGlobalRef); 6525 // selfGlobalRef is deleted in _Enable 6526 6527 CATCH_BAD_ALLOC; 6528 } 6529 6530 /* 6531 * Class: sun_awt_windows_WComponentPeer 6532 * Method: disable 6533 * Signature: ()V 6534 */ 6535 JNIEXPORT void JNICALL 6536 Java_sun_awt_windows_WComponentPeer_disable(JNIEnv *env, jobject self) 6537 { 6538 TRY; 6539 6540 jobject selfGlobalRef = env->NewGlobalRef(self); 6541 6542 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Disable, (void *)selfGlobalRef); 6543 // selfGlobalRef is deleted in _Disable 6544 6545 CATCH_BAD_ALLOC; 6546 } 6547 6548 /* 6549 * Class: sun_awt_windows_WComponentPeer 6550 * Method: getLocationOnScreen 6551 * Signature: ()Ljava/awt/Point; 6552 */ 6553 JNIEXPORT jobject JNICALL 6554 Java_sun_awt_windows_WComponentPeer_getLocationOnScreen(JNIEnv *env, jobject self) 6555 { 6556 TRY; 6557 6558 jobject selfGlobalRef = env->NewGlobalRef(self); 6559 6560 jobject resultGlobalRef = (jobject)AwtToolkit::GetInstance().SyncCall( 6561 (void*(*)(void*))AwtComponent::_GetLocationOnScreen, (void *)selfGlobalRef); 6562 // selfGlobalRef is deleted in _GetLocationOnScreen 6563 if (resultGlobalRef != NULL) 6564 { 6565 jobject resultLocalRef = env->NewLocalRef(resultGlobalRef); 6566 env->DeleteGlobalRef(resultGlobalRef); 6567 return resultLocalRef; 6568 } 6569 6570 return NULL; 6571 6572 CATCH_BAD_ALLOC_RET(NULL); 6573 } 6574 6575 /* 6576 * Class: sun_awt_windows_WComponentPeer 6577 * Method: reshape 6578 * Signature: (IIII)V 6579 */ 6580 JNIEXPORT void JNICALL 6581 Java_sun_awt_windows_WComponentPeer_reshape(JNIEnv *env, jobject self, 6582 jint x, jint y, jint w, jint h) 6583 { 6584 TRY; 6585 6586 ReshapeStruct *rs = new ReshapeStruct; 6587 rs->component = env->NewGlobalRef(self); 6588 rs->x = x; 6589 rs->y = y; 6590 rs->w = w; 6591 rs->h = h; 6592 6593 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Reshape, rs); 6594 // global ref and rs are deleted in _Reshape 6595 6596 CATCH_BAD_ALLOC; 6597 } 6598 6599 /* 6600 * Class: sun_awt_windows_WComponentPeer 6601 * Method: reshape 6602 * Signature: (IIII)V 6603 */ 6604 JNIEXPORT void JNICALL 6605 Java_sun_awt_windows_WComponentPeer_reshapeNoCheck(JNIEnv *env, jobject self, 6606 jint x, jint y, jint w, jint h) 6607 { 6608 TRY; 6609 6610 ReshapeStruct *rs = new ReshapeStruct; 6611 rs->component = env->NewGlobalRef(self); 6612 rs->x = x; 6613 rs->y = y; 6614 rs->w = w; 6615 rs->h = h; 6616 6617 AwtToolkit::GetInstance().SyncCall(AwtComponent::_ReshapeNoCheck, rs); 6618 // global ref and rs are deleted in _ReshapeNoCheck 6619 6620 CATCH_BAD_ALLOC; 6621 } 6622 6623 6624 /* 6625 * Class: sun_awt_windows_WComponentPeer 6626 * Method: nativeHandleEvent 6627 * Signature: (Ljava/awt/AWTEvent;)V 6628 */ 6629 JNIEXPORT void JNICALL 6630 Java_sun_awt_windows_WComponentPeer_nativeHandleEvent(JNIEnv *env, 6631 jobject self, 6632 jobject event) 6633 { 6634 TRY; 6635 6636 jobject selfGlobalRef = env->NewGlobalRef(self); 6637 jobject eventGlobalRef = env->NewGlobalRef(event); 6638 6639 NativeHandleEventStruct *nhes = new NativeHandleEventStruct; 6640 nhes->component = selfGlobalRef; 6641 nhes->event = eventGlobalRef; 6642 6643 AwtToolkit::GetInstance().SyncCall(AwtComponent::_NativeHandleEvent, nhes); 6644 // global refs and nhes are deleted in _NativeHandleEvent 6645 6646 CATCH_BAD_ALLOC; 6647 } 6648 6649 /* 6650 * Class: sun_awt_windows_WComponentPeer 6651 * Method: _dispose 6652 * Signature: ()V 6653 */ 6654 JNIEXPORT void JNICALL 6655 Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) 6656 { 6657 TRY_NO_HANG; 6658 6659 AwtObject::_Dispose(self); 6660 6661 CATCH_BAD_ALLOC; 6662 } 6663 6664 /* 6665 * Class: sun_awt_windows_WComponentPeer 6666 * Method: _setForeground 6667 * Signature: (I)V 6668 */ 6669 JNIEXPORT void JNICALL 6670 Java_sun_awt_windows_WComponentPeer__1setForeground(JNIEnv *env, jobject self, 6671 jint rgb) 6672 { 6673 TRY; 6674 6675 jobject selfGlobalRef = env->NewGlobalRef(self); 6676 6677 SetColorStruct *scs = new SetColorStruct; 6678 scs->component = selfGlobalRef; 6679 scs->rgb = rgb; 6680 6681 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetForeground, scs); 6682 // selfGlobalRef and scs are deleted in _SetForeground() 6683 6684 CATCH_BAD_ALLOC; 6685 } 6686 6687 /* 6688 * Class: sun_awt_windows_WComponentPeer 6689 * Method: _setBackground 6690 * Signature: (I)V 6691 */ 6692 JNIEXPORT void JNICALL 6693 Java_sun_awt_windows_WComponentPeer__1setBackground(JNIEnv *env, jobject self, 6694 jint rgb) 6695 { 6696 TRY; 6697 6698 jobject selfGlobalRef = env->NewGlobalRef(self); 6699 6700 SetColorStruct *scs = new SetColorStruct; 6701 scs->component = selfGlobalRef; 6702 scs->rgb = rgb; 6703 6704 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetBackground, scs); 6705 // selfGlobalRef and scs are deleted in _SetBackground() 6706 6707 CATCH_BAD_ALLOC; 6708 } 6709 6710 /* 6711 * Class: sun_awt_windows_WComponentPeer 6712 * Method: _setFont 6713 * Signature: (Ljava/awt/Font;)V 6714 */ 6715 JNIEXPORT void JNICALL 6716 Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self, 6717 jobject font) 6718 { 6719 TRY; 6720 6721 jobject selfGlobalRef = env->NewGlobalRef(self); 6722 jobject fontGlobalRef = env->NewGlobalRef(font); 6723 6724 SetFontStruct *sfs = new SetFontStruct; 6725 sfs->component = selfGlobalRef; 6726 sfs->font = fontGlobalRef; 6727 6728 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetFont, sfs); 6729 // global refs and sfs are deleted in _SetFont() 6730 6731 CATCH_BAD_ALLOC; 6732 } 6733 6734 /* 6735 * Class: sun_awt_windows_WComponentPeer 6736 * Method: focusGained 6737 * Signature: (Z) 6738 */ 6739 JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus 6740 (JNIEnv *env, jobject self, jboolean doSetFocus) 6741 { 6742 TRY; 6743 6744 jobject selfGlobalRef = env->NewGlobalRef(self); 6745 6746 SetFocusStruct *sfs = new SetFocusStruct; 6747 sfs->component = selfGlobalRef; 6748 sfs->doSetFocus = doSetFocus; 6749 6750 AwtToolkit::GetInstance().SyncCall( 6751 (void*(*)(void*))AwtComponent::_SetFocus, sfs); 6752 // global refs and self are deleted in _SetFocus 6753 6754 CATCH_BAD_ALLOC; 6755 } 6756 6757 /* 6758 * Class: sun_awt_windows_WComponentPeer 6759 * Method: start 6760 * Signature: ()V 6761 */ 6762 JNIEXPORT void JNICALL 6763 Java_sun_awt_windows_WComponentPeer_start(JNIEnv *env, jobject self) 6764 { 6765 TRY; 6766 6767 jobject selfGlobalRef = env->NewGlobalRef(self); 6768 6769 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Start, (void *)selfGlobalRef); 6770 // selfGlobalRef is deleted in _Start 6771 6772 CATCH_BAD_ALLOC; 6773 } 6774 6775 /* 6776 * Class: sun_awt_windows_WComponentPeer 6777 * Method: beginValidate 6778 * Signature: ()V 6779 */ 6780 JNIEXPORT void JNICALL 6781 Java_sun_awt_windows_WComponentPeer_beginValidate(JNIEnv *env, jobject self) 6782 { 6783 TRY; 6784 6785 jobject selfGlobalRef = env->NewGlobalRef(self); 6786 6787 AwtToolkit::GetInstance().SyncCall(AwtComponent::_BeginValidate, (void *)selfGlobalRef); 6788 // selfGlobalRef is deleted in _BeginValidate 6789 6790 CATCH_BAD_ALLOC; 6791 } 6792 6793 /* 6794 * Class: sun_awt_windows_WComponentPeer 6795 * Method: endValidate 6796 * Signature: ()V 6797 */ 6798 JNIEXPORT void JNICALL 6799 Java_sun_awt_windows_WComponentPeer_endValidate(JNIEnv *env, jobject self) 6800 { 6801 TRY; 6802 6803 jobject selfGlobalRef = env->NewGlobalRef(self); 6804 6805 AwtToolkit::GetInstance().SyncCall(AwtComponent::_EndValidate, (void *)selfGlobalRef); 6806 // selfGlobalRef is deleted in _EndValidate 6807 6808 CATCH_BAD_ALLOC; 6809 } 6810 6811 JNIEXPORT void JNICALL 6812 Java_sun_awt_windows_WComponentPeer_updateWindow(JNIEnv *env, jobject self) 6813 { 6814 TRY; 6815 6816 jobject selfGlobalRef = env->NewGlobalRef(self); 6817 6818 AwtToolkit::GetInstance().SyncCall(AwtComponent::_UpdateWindow, (void *)selfGlobalRef); 6819 // selfGlobalRef is deleted in _UpdateWindow 6820 6821 CATCH_BAD_ALLOC; 6822 } 6823 6824 /* 6825 * Class: sun_awt_windows_WComponentPeer 6826 * Method: addNativeDropTarget 6827 * Signature: ()L 6828 */ 6829 6830 JNIEXPORT jlong JNICALL 6831 Java_sun_awt_windows_WComponentPeer_addNativeDropTarget(JNIEnv *env, 6832 jobject self) 6833 { 6834 TRY; 6835 6836 jobject selfGlobalRef = env->NewGlobalRef(self); 6837 6838 return ptr_to_jlong(AwtToolkit::GetInstance().SyncCall( 6839 (void*(*)(void*))AwtComponent::_AddNativeDropTarget, 6840 (void *)selfGlobalRef)); 6841 // selfGlobalRef is deleted in _AddNativeDropTarget 6842 6843 CATCH_BAD_ALLOC_RET(0); 6844 } 6845 6846 /* 6847 * Class: sun_awt_windows_WComponentPeer 6848 * Method: removeNativeDropTarget 6849 * Signature: ()V 6850 */ 6851 6852 JNIEXPORT void JNICALL 6853 Java_sun_awt_windows_WComponentPeer_removeNativeDropTarget(JNIEnv *env, 6854 jobject self) 6855 { 6856 TRY; 6857 6858 jobject selfGlobalRef = env->NewGlobalRef(self); 6859 6860 AwtToolkit::GetInstance().SyncCall( 6861 AwtComponent::_RemoveNativeDropTarget, (void *)selfGlobalRef); 6862 // selfGlobalRef is deleted in _RemoveNativeDropTarget 6863 6864 CATCH_BAD_ALLOC; 6865 } 6866 6867 /* 6868 * Class: sun_awt_windows_WComponentPeer 6869 * Method: getTargetGC 6870 * Signature: ()Ljava/awt/GraphicsConfiguration; 6871 */ 6872 JNIEXPORT jobject JNICALL 6873 Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis) 6874 { 6875 TRY; 6876 6877 jobject targetObj; 6878 jobject gc = 0; 6879 6880 targetObj = env->GetObjectField(theThis, AwtObject::targetID); 6881 DASSERT(targetObj); 6882 6883 gc = env->GetObjectField(targetObj, AwtComponent::graphicsConfigID); 6884 return gc; 6885 6886 CATCH_BAD_ALLOC_RET(NULL); 6887 } 6888 6889 /* 6890 * Class: sun_awt_windows_WComponentPeer 6891 * Method: createPrintedPixels 6892 * Signature: (IIIIII)I[ 6893 */ 6894 JNIEXPORT jintArray JNICALL 6895 Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env, 6896 jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha) 6897 { 6898 TRY; 6899 6900 jobject selfGlobalRef = env->NewGlobalRef(self); 6901 6902 CreatePrintedPixelsStruct *cpps = new CreatePrintedPixelsStruct; 6903 cpps->component = selfGlobalRef; 6904 cpps->srcx = srcX; 6905 cpps->srcy = srcY; 6906 cpps->srcw = srcW; 6907 cpps->srch = srcH; 6908 cpps->alpha = alpha; 6909 6910 jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall( 6911 (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps); 6912 // selfGlobalRef and cpps are deleted in _CreatePrintedPixels 6913 if (globalRef != NULL) 6914 { 6915 jintArray localRef = (jintArray)env->NewLocalRef(globalRef); 6916 env->DeleteGlobalRef(globalRef); 6917 return localRef; 6918 } 6919 else 6920 { 6921 return NULL; 6922 } 6923 6924 CATCH_BAD_ALLOC_RET(NULL); 6925 } 6926 6927 /* 6928 * Class: sun_awt_windows_WComponentPeer 6929 * Method: nativeHandlesWheelScrolling 6930 * Signature: ()Z 6931 */ 6932 JNIEXPORT jboolean JNICALL 6933 Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env, 6934 jobject self) 6935 { 6936 TRY; 6937 6938 return JNI_IS_TRUE(AwtToolkit::GetInstance().SyncCall( 6939 (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling, 6940 env->NewGlobalRef(self))); 6941 // global ref is deleted in _NativeHandlesWheelScrolling 6942 6943 CATCH_BAD_ALLOC_RET(NULL); 6944 } 6945 6946 /* 6947 * Class: sun_awt_windows_WComponentPeer 6948 * Method: isObscured 6949 * Signature: ()Z 6950 */ 6951 JNIEXPORT jboolean JNICALL 6952 Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env, 6953 jobject self) 6954 { 6955 TRY; 6956 6957 jobject selfGlobalRef = env->NewGlobalRef(self); 6958 6959 return JNI_IS_TRUE(AwtToolkit::GetInstance().SyncCall( 6960 (void*(*)(void*))AwtComponent::_IsObscured, 6961 (void *)selfGlobalRef)); 6962 // selfGlobalRef is deleted in _IsObscured 6963 6964 CATCH_BAD_ALLOC_RET(NULL); 6965 } 6966 6967 JNIEXPORT void JNICALL 6968 Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) { 6969 TRY; 6970 6971 typedef AwtComponent* PComponent; 6972 AwtComponent** comps = new PComponent[2]; 6973 AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(self); 6974 AwtComponent* parentComp = (AwtComponent*)JNI_GET_PDATA(parent); 6975 comps[0] = comp; 6976 comps[1] = parentComp; 6977 6978 AwtToolkit::GetInstance().SyncCall(AwtComponent::SetParent, comps); 6979 // comps is deleted in SetParent 6980 6981 CATCH_BAD_ALLOC; 6982 } 6983 6984 JNIEXPORT void JNICALL 6985 Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject self, 6986 jint x1, jint y1, jint x2, jint y2, jobject region) 6987 { 6988 TRY; 6989 6990 SetRectangularShapeStruct * data = new SetRectangularShapeStruct; 6991 data->component = env->NewGlobalRef(self); 6992 data->x1 = x1; 6993 data->x2 = x2; 6994 data->y1 = y1; 6995 data->y2 = y2; 6996 if (region) { 6997 data->region = env->NewGlobalRef(region); 6998 } else { 6999 data->region = NULL; 7000 } 7001 7002 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetRectangularShape, data); 7003 // global refs and data are deleted in _SetRectangularShape 7004 7005 CATCH_BAD_ALLOC; 7006 } 7007 7008 JNIEXPORT void JNICALL 7009 Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above) 7010 { 7011 TRY; 7012 7013 SetZOrderStruct * data = new SetZOrderStruct; 7014 data->component = env->NewGlobalRef(self); 7015 data->above = above; 7016 7017 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data); 7018 // global refs and data are deleted in _SetLower 7019 7020 CATCH_BAD_ALLOC; 7021 } 7022 7023 } /* extern "C" */ 7024 7025 7026 /************************************************************************ 7027 * Diagnostic routines 7028 */ 7029 7030 #ifdef DEBUG 7031 7032 void AwtComponent::VerifyState() 7033 { 7034 if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) { 7035 return; 7036 } 7037 7038 if (m_callbacksEnabled == FALSE) { 7039 /* Component is not fully setup yet. */ 7040 return; 7041 } 7042 7043 /* Get target bounds. */ 7044 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 7045 if (env->PushLocalFrame(10) < 0) 7046 return; 7047 7048 jobject target = GetTarget(env); 7049 7050 jint x = env->GetIntField(target, AwtComponent::xID); 7051 jint y = env->GetIntField(target, AwtComponent::yID); 7052 jint width = env->GetIntField(target, AwtComponent::widthID); 7053 jint height = env->GetIntField(target, AwtComponent::heightID); 7054 7055 /* Convert target origin to absolute coordinates */ 7056 while (TRUE) { 7057 7058 jobject parent = env->GetObjectField(target, AwtComponent::parentID); 7059 if (parent == NULL) { 7060 break; 7061 } 7062 x += env->GetIntField(parent, AwtComponent::xID); 7063 y += env->GetIntField(parent, AwtComponent::yID); 7064 7065 /* If this component has insets, factor them in, but ignore 7066 * top-level windows. 7067 */ 7068 jobject parent2 = env->GetObjectField(parent, AwtComponent::parentID); 7069 if (parent2 != NULL) { 7070 jobject peer = GetPeerForTarget(env, parent); 7071 if (peer != NULL && 7072 JNU_IsInstanceOfByName(env, peer, 7073 "sun/awt/windows/WPanelPeer") > 0) { 7074 jobject insets = 7075 JNU_CallMethodByName(env, NULL, peer,"insets", 7076 "()Ljava/awt/Insets;").l; 7077 x += (env)->GetIntField(insets, AwtInsets::leftID); 7078 y += (env)->GetIntField(insets, AwtInsets::topID); 7079 } 7080 } 7081 env->DeleteLocalRef(target); 7082 target = parent; 7083 } 7084 7085 // Test whether component's bounds match the native window's 7086 RECT rect; 7087 VERIFY(::GetWindowRect(GetHWnd(), &rect)); 7088 #if 0 7089 DASSERT( (x == rect.left) && 7090 (y == rect.top) && 7091 (width == (rect.right-rect.left)) && 7092 (height == (rect.bottom-rect.top)) ); 7093 #else 7094 BOOL fSizeValid = ( (x == rect.left) && 7095 (y == rect.top) && 7096 (width == (rect.right-rect.left)) && 7097 (height == (rect.bottom-rect.top)) ); 7098 #endif 7099 7100 // See if visible state matches 7101 BOOL wndVisible = ::IsWindowVisible(GetHWnd()); 7102 jboolean targetVisible; 7103 // To avoid possibly running client code on the toolkit thread, don't 7104 // do the following check if we're running on the toolkit thread. 7105 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7106 targetVisible = JNU_CallMethodByName(env, NULL, GetTarget(env), 7107 "isShowing", "()Z").z; 7108 DASSERT(!safe_ExceptionOccurred(env)); 7109 } else { 7110 targetVisible = wndVisible ? 1 : 0; 7111 } 7112 #if 0 7113 DASSERT( (targetVisible && wndVisible) || 7114 (!targetVisible && !wndVisible) ); 7115 #else 7116 BOOL fVisibleValid = ( (targetVisible && wndVisible) || 7117 (!targetVisible && !wndVisible) ); 7118 #endif 7119 7120 // Check enabled state 7121 BOOL wndEnabled = ::IsWindowEnabled(GetHWnd()); 7122 jboolean enabled = (jboolean)env->GetBooleanField(target, 7123 AwtComponent::enabledID); 7124 #if 0 7125 DASSERT( (enabled && wndEnabled) || 7126 (!enabled && !wndEnabled) ); 7127 #else 7128 BOOL fEnabledValid = ((enabled && wndEnabled) || 7129 (!(enabled && !wndEnabled) )); 7130 7131 if (!fSizeValid || !fVisibleValid || !fEnabledValid) { 7132 printf("AwtComponent::ValidateState() failed:\n"); 7133 // To avoid possibly running client code on the toolkit thread, don't 7134 // do the following call if we're running on the toolkit thread. 7135 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7136 jstring targetStr = 7137 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env), 7138 "getName", 7139 "()Ljava/lang/String;").l; 7140 DASSERT(!safe_ExceptionOccurred(env)); 7141 LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL); 7142 printf("\t%S\n", targetStrW); 7143 JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW); 7144 } 7145 printf("\twas: [%d,%d,%dx%d]\n", x, y, width, height); 7146 if (!fSizeValid) { 7147 printf("\tshould be: [%d,%d,%dx%d]\n", rect.left, rect.top, 7148 rect.right-rect.left, rect.bottom-rect.top); 7149 } 7150 if (!fVisibleValid) { 7151 printf("\tshould be: %s\n", 7152 (targetVisible) ? "visible" : "hidden"); 7153 } 7154 if (!fEnabledValid) { 7155 printf("\tshould be: %s\n", 7156 enabled ? "enabled" : "disabled"); 7157 } 7158 } 7159 #endif 7160 env->PopLocalFrame(0); 7161 } 7162 #endif //DEBUG 7163 7164 // Methods for globally managed DC list 7165 7166 /** 7167 * Add a new DC to the DC list for this component. 7168 */ 7169 void DCList::AddDC(HDC hDC, HWND hWnd) 7170 { 7171 DCItem *newItem = new DCItem; 7172 newItem->hDC = hDC; 7173 newItem->hWnd = hWnd; 7174 AddDCItem(newItem); 7175 } 7176 7177 void DCList::AddDCItem(DCItem *newItem) 7178 { 7179 listLock.Enter(); 7180 newItem->next = head; 7181 head = newItem; 7182 listLock.Leave(); 7183 } 7184 7185 /** 7186 * Given a DC, remove it from the DC list and return 7187 * TRUE if it exists on the current list. Otherwise 7188 * return FALSE. 7189 * A DC may not exist on the list because it has already 7190 * been released elsewhere (for example, the window 7191 * destruction process may release a DC while a rendering 7192 * thread may also want to release a DC when it notices that 7193 * its DC is obsolete for the current window). 7194 */ 7195 DCItem *DCList::RemoveDC(HDC hDC) 7196 { 7197 listLock.Enter(); 7198 DCItem **prevPtrPtr = &head; 7199 DCItem *listPtr = head; 7200 while (listPtr) { 7201 DCItem *nextPtr = listPtr->next; 7202 if (listPtr->hDC == hDC) { 7203 *prevPtrPtr = nextPtr; 7204 break; 7205 } 7206 prevPtrPtr = &listPtr->next; 7207 listPtr = nextPtr; 7208 } 7209 listLock.Leave(); 7210 return listPtr; 7211 } 7212 7213 /** 7214 * Remove all DCs from the DC list which are associated with 7215 * the same window as hWnd. Return the list of those 7216 * DC's to the caller (which will then probably want to 7217 * call ReleaseDC() for the returned DCs). 7218 */ 7219 DCItem *DCList::RemoveAllDCs(HWND hWnd) 7220 { 7221 listLock.Enter(); 7222 DCItem **prevPtrPtr = &head; 7223 DCItem *listPtr = head; 7224 DCItem *newListPtr = NULL; 7225 BOOL ret = FALSE; 7226 while (listPtr) { 7227 DCItem *nextPtr = listPtr->next; 7228 if (listPtr->hWnd == hWnd) { 7229 *prevPtrPtr = nextPtr; 7230 listPtr->next = newListPtr; 7231 newListPtr = listPtr; 7232 } else { 7233 prevPtrPtr = &listPtr->next; 7234 } 7235 listPtr = nextPtr; 7236 } 7237 listLock.Leave(); 7238 return newListPtr; 7239 } 7240 7241 7242 /** 7243 * Realize palettes of all existing HDC objects 7244 */ 7245 void DCList::RealizePalettes(int screen) 7246 { 7247 listLock.Enter(); 7248 DCItem *listPtr = head; 7249 while (listPtr) { 7250 AwtWin32GraphicsDevice::RealizePalette(listPtr->hDC, screen); 7251 listPtr = listPtr->next; 7252 } 7253 listLock.Leave(); 7254 } 7255 7256 void MoveDCToPassiveList(HDC hDC) { 7257 DCItem *removedDC; 7258 if ((removedDC = activeDCList.RemoveDC(hDC)) != NULL) { 7259 passiveDCList.AddDCItem(removedDC); 7260 } 7261 } 7262 7263 void ReleaseDCList(HWND hwnd, DCList &list) { 7264 DCItem *removedDCs = list.RemoveAllDCs(hwnd); 7265 while (removedDCs) { 7266 DCItem *tmpDCList = removedDCs; 7267 DASSERT(::GetObjectType(tmpDCList->hDC) == OBJ_DC); 7268 int retValue = ::ReleaseDC(tmpDCList->hWnd, tmpDCList->hDC); 7269 VERIFY(retValue != 0); 7270 if (retValue != 0) { 7271 // Valid ReleaseDC call; need to decrement GDI object counter 7272 AwtGDIObject::Decrement(); 7273 } 7274 removedDCs = removedDCs->next; 7275 delete tmpDCList; 7276 } 7277 } 7278