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