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