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