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