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