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