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