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