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