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