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