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