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