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