1 /* 2 * Copyright (c) 1996, 2010, 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 transfering 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 env->SetObjectField(peer, AwtComponent::peerGCID, compGC); 471 } 472 } 473 474 void 475 AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title, 476 DWORD windowStyle, 477 DWORD windowExStyle, 478 int x, int y, int w, int h, 479 HWND hWndParent, HMENU hMenu, 480 COLORREF colorForeground, 481 COLORREF colorBackground, 482 jobject peer) 483 { 484 if (env->EnsureLocalCapacity(2) < 0) { 485 return; 486 } 487 488 /* 489 * The window class of multifont label must be "BUTTON" because 490 * "STATIC" class can't get WM_DRAWITEM message, and m_peerObject 491 * member is referred in the GetClassName method of AwtLabel class. 492 * So m_peerObject member must be set here. 493 */ 494 m_peerObject = env->NewGlobalRef(peer); 495 RegisterClass(); 496 497 jobject target = env->GetObjectField(peer, AwtObject::targetID); 498 jboolean visible = env->GetBooleanField(target, AwtComponent::visibleID); 499 m_visible = visible; 500 501 if (visible) { 502 windowStyle |= WS_VISIBLE; 503 } else { 504 windowStyle &= ~WS_VISIBLE; 505 } 506 507 InitPeerGraphicsConfig(env, peer); 508 509 SetLastError(0); 510 HWND hwnd = ::CreateWindowEx(windowExStyle, 511 GetClassName(), 512 title, 513 windowStyle, 514 x, y, w, h, 515 hWndParent, 516 hMenu, 517 AwtToolkit::GetInstance().GetModuleHandle(), 518 NULL); 519 520 // fix for 5088782 521 // check if CreateWindowsEx() returns not null value and if it does - 522 // create an InternalError or OutOfMemoryError based on GetLastError(). 523 // This error is set to createError field of WObjectPeer and then 524 // checked and thrown in WComponentPeer constructor. We can't throw an 525 // error here because this code is invoked on Toolkit thread 526 if (hwnd == NULL) 527 { 528 DWORD dw = ::GetLastError(); 529 jobject createError = NULL; 530 if (dw == ERROR_OUTOFMEMORY) 531 { 532 jstring errorMsg = JNU_NewStringPlatform(env, L"too many window handles"); 533 createError = JNU_NewObjectByName(env, "java/lang/OutOfMemoryError", 534 "(Ljava/lang/String;)V", 535 errorMsg); 536 env->DeleteLocalRef(errorMsg); 537 } 538 else 539 { 540 TCHAR *buf; 541 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 542 NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 543 (LPTSTR)&buf, 0, NULL); 544 jstring s = JNU_NewStringPlatform(env, buf); 545 createError = JNU_NewObjectByName(env, "java/lang/InternalError", 546 "(Ljava/lang/String;)V", s); 547 LocalFree(buf); 548 env->DeleteLocalRef(s); 549 } 550 env->SetObjectField(peer, AwtObject::createErrorID, createError); 551 if (createError != NULL) 552 { 553 env->DeleteLocalRef(createError); 554 } 555 env->DeleteLocalRef(target); 556 return; 557 } 558 559 m_hwnd = hwnd; 560 561 ::ImmAssociateContext(m_hwnd, NULL); 562 563 SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | 564 (jint)JAWT_LOCK_BOUNDS_CHANGED | 565 (jint)JAWT_LOCK_CLIP_CHANGED); 566 567 LinkObjects(env, peer); 568 569 /* Subclass the window now so that we can snoop on its messages */ 570 SubclassHWND(); 571 572 /* 573 * Fix for 4046446. 574 */ 575 SetWindowPos(GetHWnd(), 0, x, y, w, h, SWP_NOZORDER | SWP_NOCOPYBITS | SWP_NOACTIVATE); 576 577 /* Set default colors. */ 578 m_colorForeground = colorForeground; 579 m_colorBackground = colorBackground; 580 581 /* 582 * Only set background color if the color is actually set on the 583 * target -- this avoids inheriting a parent's color unnecessarily, 584 * and has to be done here because there isn't an API to get the 585 * real background color from outside the AWT package. 586 */ 587 jobject bkgrd = env->GetObjectField(target, AwtComponent::backgroundID) ; 588 if (bkgrd != NULL) { 589 JNU_CallMethodByName(env, NULL, peer, "setBackground", 590 "(Ljava/awt/Color;)V", bkgrd); 591 DASSERT(!safe_ExceptionOccurred(env)); 592 } 593 env->DeleteLocalRef(target); 594 env->DeleteLocalRef(bkgrd); 595 } 596 597 /* 598 * Destroy this window's HWND 599 */ 600 void AwtComponent::DestroyHWnd() { 601 if (m_hwnd != NULL) { 602 AwtToolkit::DestroyComponentHWND(m_hwnd); 603 //AwtToolkit::DestroyComponent(this); 604 m_hwnd = NULL; 605 } 606 } 607 608 /* 609 * Returns hwnd for target on non Toolkit thread 610 */ 611 HWND 612 AwtComponent::GetHWnd(JNIEnv* env, jobject target) { 613 if (JNU_IsNull(env, target)) { 614 return 0; 615 } 616 jobject peer = env->GetObjectField(target, AwtComponent::peerID); 617 if (JNU_IsNull(env, peer)) { 618 return 0; 619 } 620 HWND hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR> ( 621 env->GetLongField(peer, AwtComponent::hwndID))); 622 env->DeleteLocalRef(peer); 623 return hwnd; 624 } 625 // 626 // Propagate the background color to synchronize Java field and peer's field. 627 // This is needed to fix 4148334 628 // 629 void AwtComponent::UpdateBackground(JNIEnv *env, jobject target) 630 { 631 if (env->EnsureLocalCapacity(1) < 0) { 632 return; 633 } 634 635 jobject bkgrnd = env->GetObjectField(target, AwtComponent::backgroundID); 636 637 if (bkgrnd == NULL) { 638 bkgrnd = JNU_NewObjectByName(env, "java/awt/Color", "(III)V", 639 GetRValue(m_colorBackground), 640 GetGValue(m_colorBackground), 641 GetBValue(m_colorBackground)); 642 if (bkgrnd != NULL) { 643 env->SetObjectField(target, AwtComponent::backgroundID, bkgrnd); 644 } 645 } 646 env->DeleteLocalRef(bkgrnd); 647 } 648 649 /* 650 * Install our window proc as the proc for our HWND, and save off the 651 * previous proc as the default 652 */ 653 void AwtComponent::SubclassHWND() 654 { 655 if (m_bSubclassed) { 656 return; 657 } 658 const WNDPROC wndproc = WndProc; // let compiler type check WndProc 659 m_DefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc); 660 m_bSubclassed = TRUE; 661 } 662 663 /* 664 * Reinstall the original window proc as the proc for our HWND 665 */ 666 void AwtComponent::UnsubclassHWND() 667 { 668 if (!m_bSubclassed) { 669 return; 670 } 671 ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc, m_DefWindowProc); 672 m_bSubclassed = FALSE; 673 } 674 675 ///////////////////////////////////// 676 // (static method) 677 // Determines the top-level ancestor for a given window. If the given 678 // window is a top-level window, return itself. 679 // 680 // 'Top-level' includes dialogs as well. 681 // 682 HWND AwtComponent::GetTopLevelParentForWindow(HWND hwndDescendant) { 683 if (hwndDescendant == NULL) { 684 return NULL; 685 } 686 687 DASSERT(IsWindow(hwndDescendant)); 688 HWND hwnd = hwndDescendant; 689 for(;;) { 690 DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); 691 // a) found a non-child window so terminate 692 // b) found real toplevel window (e.g. EmbeddedFrame 693 // that is child though) 694 if ( (style & WS_CHILD) == 0 || 695 AwtComponent::IsTopLevelHWnd(hwnd) ) 696 { 697 break; 698 } 699 hwnd = ::GetParent(hwnd); 700 } 701 702 return hwnd; 703 } 704 //////////////////// 705 706 jobject AwtComponent::FindHeavyweightUnderCursor(BOOL useCache) { 707 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 708 if (env->EnsureLocalCapacity(1) < 0) { 709 return NULL; 710 } 711 712 HWND hit = NULL; 713 POINT p = { 0, 0 }; 714 AwtComponent *comp = NULL; 715 716 if (useCache) { 717 if (sm_cursorOn == NULL) { 718 return NULL; 719 } 720 721 722 DASSERT(::IsWindow(sm_cursorOn)); 723 VERIFY(::GetCursorPos(&p)); 724 /* 725 * Fix for BugTraq ID 4304024. 726 * Allow a non-default cursor only for the client area. 727 */ 728 comp = AwtComponent::GetComponent(sm_cursorOn); 729 if (comp != NULL && 730 ::SendMessage(sm_cursorOn, WM_NCHITTEST, 0, 731 MAKELPARAM(p.x, p.y)) == HTCLIENT) { 732 goto found; 733 } 734 } 735 736 ::GetCursorPos(&p); 737 hit = ::WindowFromPoint(p); 738 while (hit != NULL) { 739 comp = AwtComponent::GetComponent(hit); 740 741 if (comp != NULL) { 742 INT nHittest = (INT)::SendMessage(hit, WM_NCHITTEST, 743 0, MAKELPARAM(p.x, p.y)); 744 /* 745 * Fix for BugTraq ID 4304024. 746 * Allow a non-default cursor only for the client area. 747 */ 748 if (nHittest != HTCLIENT) { 749 /* 750 * When over the non-client area, send WM_SETCURSOR 751 * to revert the cursor to an arrow. 752 */ 753 ::SendMessage(hit, WM_SETCURSOR, (WPARAM)hit, 754 MAKELPARAM(nHittest, WM_MOUSEMOVE)); 755 return NULL; 756 } else { 757 sm_cursorOn = hit; 758 goto found; 759 } 760 } 761 762 if ((::GetWindowLong(hit, GWL_STYLE) & WS_CHILD) == 0) { 763 return NULL; 764 } 765 hit = ::GetParent(hit); 766 } 767 768 return NULL; 769 770 found: 771 jobject localRef = comp->GetTarget(env); 772 jobject globalRef = env->NewGlobalRef(localRef); 773 env->DeleteLocalRef(localRef); 774 return globalRef; 775 } 776 777 void AwtComponent::SetColor(COLORREF c) 778 { 779 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 780 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 781 if (grayscale != GS_NOTGRAY) { 782 int g; 783 784 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 785 .114 * ((c >> 16) & 0xFF) + 0.5); 786 // c = g | (g << 8) | (g << 16); 787 c = PALETTERGB(g, g, g); 788 } 789 790 if (m_colorForeground == c) { 791 return; 792 } 793 794 m_colorForeground = c; 795 if (m_penForeground != NULL) { 796 m_penForeground->Release(); 797 m_penForeground = NULL; 798 } 799 VERIFY(::InvalidateRect(GetHWnd(), NULL, FALSE)); 800 } 801 802 void AwtComponent::SetBackgroundColor(COLORREF c) 803 { 804 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 805 int grayscale = AwtWin32GraphicsDevice::GetGrayness(screen); 806 if (grayscale != GS_NOTGRAY) { 807 int g; 808 809 g = (int) (.299 * (c & 0xFF) + .587 * ((c >> 8) & 0xFF) + 810 .114 * ((c >> 16) & 0xFF) + 0.5); 811 // c = g | (g << 8) | (g << 16); 812 c = PALETTERGB(g, g, g); 813 } 814 815 if (m_colorBackground == c) { 816 return; 817 } 818 m_colorBackground = c; 819 m_backgroundColorSet = TRUE; 820 if (m_brushBackground != NULL) { 821 m_brushBackground->Release(); 822 m_brushBackground = NULL; 823 } 824 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 825 } 826 827 HPEN AwtComponent::GetForegroundPen() 828 { 829 if (m_penForeground == NULL) { 830 m_penForeground = AwtPen::Get(m_colorForeground); 831 } 832 return (HPEN)m_penForeground->GetHandle(); 833 } 834 835 COLORREF AwtComponent::GetBackgroundColor() 836 { 837 if (m_backgroundColorSet == FALSE) { 838 AwtComponent* c = this; 839 while ((c = c->GetParent()) != NULL) { 840 if (c->IsBackgroundColorSet()) { 841 return c->GetBackgroundColor(); 842 } 843 } 844 } 845 return m_colorBackground; 846 } 847 848 HBRUSH AwtComponent::GetBackgroundBrush() 849 { 850 if (m_backgroundColorSet == FALSE) { 851 if (m_brushBackground != NULL) { 852 m_brushBackground->Release(); 853 m_brushBackground = NULL; 854 } 855 AwtComponent* c = this; 856 while ((c = c->GetParent()) != NULL) { 857 if (c->IsBackgroundColorSet()) { 858 m_brushBackground = 859 AwtBrush::Get(c->GetBackgroundColor()); 860 break; 861 } 862 } 863 } 864 if (m_brushBackground == NULL) { 865 m_brushBackground = AwtBrush::Get(m_colorBackground); 866 } 867 return (HBRUSH)m_brushBackground->GetHandle(); 868 } 869 870 void AwtComponent::SetFont(AwtFont* font) 871 { 872 DASSERT(font != NULL); 873 if (font->GetAscent() < 0) { 874 AwtFont::SetupAscent(font); 875 } 876 SendMessage(WM_SETFONT, (WPARAM)font->GetHFont(), MAKELPARAM(FALSE, 0)); 877 VERIFY(::InvalidateRect(GetHWnd(), NULL, TRUE)); 878 } 879 880 AwtComponent* AwtComponent::GetParent() 881 { 882 HWND hwnd = ::GetParent(GetHWnd()); 883 if (hwnd == NULL) { 884 return NULL; 885 } 886 return GetComponent(hwnd); 887 } 888 889 AwtWindow* AwtComponent::GetContainer() 890 { 891 AwtComponent* comp = this; 892 while (comp != NULL) { 893 if (comp->IsContainer()) { 894 return (AwtWindow*)comp; 895 } 896 comp = comp->GetParent(); 897 } 898 return NULL; 899 } 900 901 void AwtComponent::Show() 902 { 903 m_visible = true; 904 ::ShowWindow(GetHWnd(), SW_SHOWNA); 905 } 906 907 void AwtComponent::Hide() 908 { 909 m_visible = false; 910 ::ShowWindow(GetHWnd(), SW_HIDE); 911 } 912 913 BOOL 914 AwtComponent::SetWindowPos(HWND wnd, HWND after, 915 int x, int y, int w, int h, UINT flags) 916 { 917 // Conditions we shouldn't handle: 918 // z-order changes, correct window dimensions 919 if (after != NULL || (w < 32767 && h < 32767) 920 || ((::GetWindowLong(wnd, GWL_STYLE) & WS_CHILD) == 0)) 921 { 922 return ::SetWindowPos(wnd, after, x, y, w, h, flags); 923 } 924 WINDOWPLACEMENT wp; 925 ::ZeroMemory(&wp, sizeof(wp)); 926 927 wp.length = sizeof(wp); 928 ::GetWindowPlacement(wnd, &wp); 929 wp.rcNormalPosition.left = x; 930 wp.rcNormalPosition.top = y; 931 wp.rcNormalPosition.right = x + w; 932 wp.rcNormalPosition.bottom = y + h; 933 if ( flags & SWP_NOACTIVATE ) { 934 wp.showCmd = SW_SHOWNOACTIVATE; 935 } 936 ::SetWindowPlacement(wnd, &wp); 937 return 1; 938 } 939 940 941 void AwtComponent::Reshape(int x, int y, int w, int h) 942 { 943 #if defined(DEBUG) 944 RECT rc; 945 ::GetWindowRect(GetHWnd(), &rc); 946 ::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2); 947 DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top); 948 #endif 949 AwtWindow* container = GetContainer(); 950 AwtComponent* parent = GetParent(); 951 if (container != NULL && container == parent) { 952 container->SubtractInsetPoint(x, y); 953 } 954 DTRACE_PRINTLN4("AwtComponent::Reshape to %d, %d, %d, %d", x, y, w, h); 955 UINT flags = SWP_NOACTIVATE | SWP_NOZORDER; 956 957 RECT r; 958 959 ::GetWindowRect(GetHWnd(), &r); 960 // if the component size is changing , don't copy window bits 961 if (r.right - r.left != w || r.bottom - r.top != h) { 962 flags |= SWP_NOCOPYBITS; 963 } 964 965 if (parent && _tcscmp(parent->GetClassName(), TEXT("SunAwtScrollPane")) == 0) { 966 if (x > 0) { 967 x = 0; 968 } 969 if (y > 0) { 970 y = 0; 971 } 972 } 973 if (m_hdwp != NULL) { 974 m_hdwp = ::DeferWindowPos(m_hdwp, GetHWnd(), 0, x, y, w, h, flags); 975 DASSERT(m_hdwp != NULL); 976 } else { 977 /* 978 * Fox for 4046446 979 * If window has dimensions above the short int limit, ::SetWindowPos doesn't work. 980 * We should use SetWindowPlacement instead. 981 */ 982 SetWindowPos(GetHWnd(), 0, x, y, w, h, flags); 983 } 984 } 985 986 void AwtComponent::SetScrollValues(UINT bar, int min, int value, int max) 987 { 988 int minTmp, maxTmp; 989 990 ::GetScrollRange(GetHWnd(), bar, &minTmp, &maxTmp); 991 if (min == INT_MAX) { 992 min = minTmp; 993 } 994 if (value == INT_MAX) { 995 value = ::GetScrollPos(GetHWnd(), bar); 996 } 997 if (max == INT_MAX) { 998 max = maxTmp; 999 } 1000 if (min == max) { 1001 max++; 1002 } 1003 ::SetScrollRange(GetHWnd(), bar, min, max, FALSE); 1004 ::SetScrollPos(GetHWnd(), bar, value, TRUE); 1005 } 1006 1007 /* 1008 * Save Global Reference of sun.awt.windows.WInputMethod object 1009 */ 1010 void AwtComponent::SetInputMethod(jobject im, BOOL useNativeCompWindow) 1011 { 1012 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1013 1014 if (m_InputMethod!=NULL) 1015 env->DeleteGlobalRef(m_InputMethod); 1016 1017 if (im!=NULL){ 1018 m_InputMethod = env->NewGlobalRef(im); 1019 m_useNativeCompWindow = useNativeCompWindow; 1020 } else { 1021 m_InputMethod = NULL; 1022 m_useNativeCompWindow = TRUE; 1023 } 1024 1025 } 1026 1027 /* 1028 * Opportunity to process and/or eat a message before it is dispatched 1029 */ 1030 MsgRouting AwtComponent::PreProcessMsg(MSG& msg) 1031 { 1032 return mrPassAlong; 1033 } 1034 1035 static UINT lastMessage = WM_NULL; 1036 1037 #ifndef SPY_MESSAGES 1038 #define SpyWinMessage(hwin,msg,str) 1039 #else 1040 1041 #define FMT_MSG(x,y) case x: _stprintf(szBuf, \ 1042 "0x%8.8x(%s):%s\n", hwnd, szComment, y); break; 1043 #define WIN_MSG(x) FMT_MSG(x,#x) 1044 1045 void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { 1046 1047 TCHAR szBuf[256]; 1048 1049 switch (message) { 1050 WIN_MSG(WM_NULL) 1051 WIN_MSG(WM_CREATE) 1052 WIN_MSG(WM_DESTROY) 1053 WIN_MSG(WM_MOVE) 1054 WIN_MSG(WM_SIZE) 1055 WIN_MSG(WM_ACTIVATE) 1056 WIN_MSG(WM_SETFOCUS) 1057 WIN_MSG(WM_KILLFOCUS) 1058 WIN_MSG(WM_ENABLE) 1059 WIN_MSG(WM_SETREDRAW) 1060 WIN_MSG(WM_SETTEXT) 1061 WIN_MSG(WM_GETTEXT) 1062 WIN_MSG(WM_GETTEXTLENGTH) 1063 WIN_MSG(WM_PAINT) 1064 WIN_MSG(WM_CLOSE) 1065 WIN_MSG(WM_QUERYENDSESSION) 1066 WIN_MSG(WM_QUIT) 1067 WIN_MSG(WM_QUERYOPEN) 1068 WIN_MSG(WM_ERASEBKGND) 1069 WIN_MSG(WM_SYSCOLORCHANGE) 1070 WIN_MSG(WM_ENDSESSION) 1071 WIN_MSG(WM_SHOWWINDOW) 1072 FMT_MSG(WM_WININICHANGE,"WM_WININICHANGE/WM_SETTINGCHANGE") 1073 WIN_MSG(WM_DEVMODECHANGE) 1074 WIN_MSG(WM_ACTIVATEAPP) 1075 WIN_MSG(WM_FONTCHANGE) 1076 WIN_MSG(WM_TIMECHANGE) 1077 WIN_MSG(WM_CANCELMODE) 1078 WIN_MSG(WM_SETCURSOR) 1079 WIN_MSG(WM_MOUSEACTIVATE) 1080 WIN_MSG(WM_CHILDACTIVATE) 1081 WIN_MSG(WM_QUEUESYNC) 1082 WIN_MSG(WM_GETMINMAXINFO) 1083 WIN_MSG(WM_PAINTICON) 1084 WIN_MSG(WM_ICONERASEBKGND) 1085 WIN_MSG(WM_NEXTDLGCTL) 1086 WIN_MSG(WM_SPOOLERSTATUS) 1087 WIN_MSG(WM_DRAWITEM) 1088 WIN_MSG(WM_MEASUREITEM) 1089 WIN_MSG(WM_DELETEITEM) 1090 WIN_MSG(WM_VKEYTOITEM) 1091 WIN_MSG(WM_CHARTOITEM) 1092 WIN_MSG(WM_SETFONT) 1093 WIN_MSG(WM_GETFONT) 1094 WIN_MSG(WM_SETHOTKEY) 1095 WIN_MSG(WM_GETHOTKEY) 1096 WIN_MSG(WM_QUERYDRAGICON) 1097 WIN_MSG(WM_COMPAREITEM) 1098 FMT_MSG(0x003D, "WM_GETOBJECT") 1099 WIN_MSG(WM_COMPACTING) 1100 WIN_MSG(WM_COMMNOTIFY) 1101 WIN_MSG(WM_WINDOWPOSCHANGING) 1102 WIN_MSG(WM_WINDOWPOSCHANGED) 1103 WIN_MSG(WM_POWER) 1104 WIN_MSG(WM_COPYDATA) 1105 WIN_MSG(WM_CANCELJOURNAL) 1106 WIN_MSG(WM_NOTIFY) 1107 WIN_MSG(WM_INPUTLANGCHANGEREQUEST) 1108 WIN_MSG(WM_INPUTLANGCHANGE) 1109 WIN_MSG(WM_TCARD) 1110 WIN_MSG(WM_HELP) 1111 WIN_MSG(WM_USERCHANGED) 1112 WIN_MSG(WM_NOTIFYFORMAT) 1113 WIN_MSG(WM_CONTEXTMENU) 1114 WIN_MSG(WM_STYLECHANGING) 1115 WIN_MSG(WM_STYLECHANGED) 1116 WIN_MSG(WM_DISPLAYCHANGE) 1117 WIN_MSG(WM_GETICON) 1118 WIN_MSG(WM_SETICON) 1119 WIN_MSG(WM_NCCREATE) 1120 WIN_MSG(WM_NCDESTROY) 1121 WIN_MSG(WM_NCCALCSIZE) 1122 WIN_MSG(WM_NCHITTEST) 1123 WIN_MSG(WM_NCPAINT) 1124 WIN_MSG(WM_NCACTIVATE) 1125 WIN_MSG(WM_GETDLGCODE) 1126 WIN_MSG(WM_SYNCPAINT) 1127 WIN_MSG(WM_NCMOUSEMOVE) 1128 WIN_MSG(WM_NCLBUTTONDOWN) 1129 WIN_MSG(WM_NCLBUTTONUP) 1130 WIN_MSG(WM_NCLBUTTONDBLCLK) 1131 WIN_MSG(WM_NCRBUTTONDOWN) 1132 WIN_MSG(WM_NCRBUTTONUP) 1133 WIN_MSG(WM_NCRBUTTONDBLCLK) 1134 WIN_MSG(WM_NCMBUTTONDOWN) 1135 WIN_MSG(WM_NCMBUTTONUP) 1136 WIN_MSG(WM_NCMBUTTONDBLCLK) 1137 WIN_MSG(WM_KEYDOWN) 1138 WIN_MSG(WM_KEYUP) 1139 WIN_MSG(WM_CHAR) 1140 WIN_MSG(WM_DEADCHAR) 1141 WIN_MSG(WM_SYSKEYDOWN) 1142 WIN_MSG(WM_SYSKEYUP) 1143 WIN_MSG(WM_SYSCHAR) 1144 WIN_MSG(WM_SYSDEADCHAR) 1145 WIN_MSG(WM_IME_STARTCOMPOSITION) 1146 WIN_MSG(WM_IME_ENDCOMPOSITION) 1147 WIN_MSG(WM_IME_COMPOSITION) 1148 WIN_MSG(WM_INITDIALOG) 1149 WIN_MSG(WM_COMMAND) 1150 WIN_MSG(WM_SYSCOMMAND) 1151 WIN_MSG(WM_TIMER) 1152 WIN_MSG(WM_HSCROLL) 1153 WIN_MSG(WM_VSCROLL) 1154 WIN_MSG(WM_INITMENU) 1155 WIN_MSG(WM_INITMENUPOPUP) 1156 WIN_MSG(WM_MENUSELECT) 1157 WIN_MSG(WM_MENUCHAR) 1158 WIN_MSG(WM_ENTERIDLE) 1159 FMT_MSG(0x0122, "WM_MENURBUTTONUP") 1160 FMT_MSG(0x0123, "WM_MENUDRAG") 1161 FMT_MSG(0x0124, "WM_MENUGETOBJECT") 1162 FMT_MSG(0x0125, "WM_UNINITMENUPOPUP") 1163 FMT_MSG(0x0126, "WM_MENUCOMMAND") 1164 WIN_MSG(WM_CTLCOLORMSGBOX) 1165 WIN_MSG(WM_CTLCOLOREDIT) 1166 WIN_MSG(WM_CTLCOLORLISTBOX) 1167 WIN_MSG(WM_CTLCOLORBTN) 1168 WIN_MSG(WM_CTLCOLORDLG) 1169 WIN_MSG(WM_CTLCOLORSCROLLBAR) 1170 WIN_MSG(WM_CTLCOLORSTATIC) 1171 WIN_MSG(WM_MOUSEMOVE) 1172 WIN_MSG(WM_LBUTTONDOWN) 1173 WIN_MSG(WM_LBUTTONUP) 1174 WIN_MSG(WM_LBUTTONDBLCLK) 1175 WIN_MSG(WM_RBUTTONDOWN) 1176 WIN_MSG(WM_RBUTTONUP) 1177 WIN_MSG(WM_RBUTTONDBLCLK) 1178 WIN_MSG(WM_MBUTTONDOWN) 1179 WIN_MSG(WM_MBUTTONUP) 1180 WIN_MSG(WM_MBUTTONDBLCLK) 1181 WIN_MSG(WM_XBUTTONDBLCLK) 1182 WIN_MSG(WM_XBUTTONDOWN) 1183 WIN_MSG(WM_XBUTTONUP) 1184 WIN_MSG(WM_MOUSEWHEEL) 1185 WIN_MSG(WM_PARENTNOTIFY) 1186 WIN_MSG(WM_ENTERMENULOOP) 1187 WIN_MSG(WM_EXITMENULOOP) 1188 WIN_MSG(WM_NEXTMENU) 1189 WIN_MSG(WM_SIZING) 1190 WIN_MSG(WM_CAPTURECHANGED) 1191 WIN_MSG(WM_MOVING) 1192 WIN_MSG(WM_POWERBROADCAST) 1193 WIN_MSG(WM_DEVICECHANGE) 1194 WIN_MSG(WM_MDICREATE) 1195 WIN_MSG(WM_MDIDESTROY) 1196 WIN_MSG(WM_MDIACTIVATE) 1197 WIN_MSG(WM_MDIRESTORE) 1198 WIN_MSG(WM_MDINEXT) 1199 WIN_MSG(WM_MDIMAXIMIZE) 1200 WIN_MSG(WM_MDITILE) 1201 WIN_MSG(WM_MDICASCADE) 1202 WIN_MSG(WM_MDIICONARRANGE) 1203 WIN_MSG(WM_MDIGETACTIVE) 1204 WIN_MSG(WM_MDISETMENU) 1205 WIN_MSG(WM_ENTERSIZEMOVE) 1206 WIN_MSG(WM_EXITSIZEMOVE) 1207 WIN_MSG(WM_DROPFILES) 1208 WIN_MSG(WM_MDIREFRESHMENU) 1209 WIN_MSG(WM_IME_SETCONTEXT) 1210 WIN_MSG(WM_IME_NOTIFY) 1211 WIN_MSG(WM_IME_CONTROL) 1212 WIN_MSG(WM_IME_COMPOSITIONFULL) 1213 WIN_MSG(WM_IME_SELECT) 1214 WIN_MSG(WM_IME_CHAR) 1215 FMT_MSG(WM_IME_REQUEST) 1216 WIN_MSG(WM_IME_KEYDOWN) 1217 WIN_MSG(WM_IME_KEYUP) 1218 FMT_MSG(0x02A1, "WM_MOUSEHOVER") 1219 FMT_MSG(0x02A3, "WM_MOUSELEAVE") 1220 WIN_MSG(WM_CUT) 1221 WIN_MSG(WM_COPY) 1222 WIN_MSG(WM_PASTE) 1223 WIN_MSG(WM_CLEAR) 1224 WIN_MSG(WM_UNDO) 1225 WIN_MSG(WM_RENDERFORMAT) 1226 WIN_MSG(WM_RENDERALLFORMATS) 1227 WIN_MSG(WM_DESTROYCLIPBOARD) 1228 WIN_MSG(WM_DRAWCLIPBOARD) 1229 WIN_MSG(WM_PAINTCLIPBOARD) 1230 WIN_MSG(WM_VSCROLLCLIPBOARD) 1231 WIN_MSG(WM_SIZECLIPBOARD) 1232 WIN_MSG(WM_ASKCBFORMATNAME) 1233 WIN_MSG(WM_CHANGECBCHAIN) 1234 WIN_MSG(WM_HSCROLLCLIPBOARD) 1235 WIN_MSG(WM_QUERYNEWPALETTE) 1236 WIN_MSG(WM_PALETTEISCHANGING) 1237 WIN_MSG(WM_PALETTECHANGED) 1238 WIN_MSG(WM_HOTKEY) 1239 WIN_MSG(WM_PRINT) 1240 WIN_MSG(WM_PRINTCLIENT) 1241 WIN_MSG(WM_HANDHELDFIRST) 1242 WIN_MSG(WM_HANDHELDLAST) 1243 WIN_MSG(WM_AFXFIRST) 1244 WIN_MSG(WM_AFXLAST) 1245 WIN_MSG(WM_PENWINFIRST) 1246 WIN_MSG(WM_PENWINLAST) 1247 WIN_MSG(WM_AWT_COMPONENT_CREATE) 1248 WIN_MSG(WM_AWT_DESTROY_WINDOW) 1249 WIN_MSG(WM_AWT_MOUSEENTER) 1250 WIN_MSG(WM_AWT_MOUSEEXIT) 1251 WIN_MSG(WM_AWT_COMPONENT_SHOW) 1252 WIN_MSG(WM_AWT_COMPONENT_HIDE) 1253 WIN_MSG(WM_AWT_COMPONENT_SETFOCUS) 1254 WIN_MSG(WM_AWT_WINDOW_SETACTIVE) 1255 WIN_MSG(WM_AWT_LIST_SETMULTISELECT) 1256 WIN_MSG(WM_AWT_HANDLE_EVENT) 1257 WIN_MSG(WM_AWT_PRINT_COMPONENT) 1258 WIN_MSG(WM_AWT_RESHAPE_COMPONENT) 1259 WIN_MSG(WM_AWT_SETALWAYSONTOP) 1260 WIN_MSG(WM_AWT_BEGIN_VALIDATE) 1261 WIN_MSG(WM_AWT_END_VALIDATE) 1262 WIN_MSG(WM_AWT_FORWARD_CHAR) 1263 WIN_MSG(WM_AWT_FORWARD_BYTE) 1264 WIN_MSG(WM_AWT_SET_SCROLL_INFO) 1265 WIN_MSG(WM_AWT_CREATECONTEXT) 1266 WIN_MSG(WM_AWT_DESTROYCONTEXT) 1267 WIN_MSG(WM_AWT_ASSOCIATECONTEXT) 1268 WIN_MSG(WM_AWT_GET_DEFAULT_IME_HANDLER) 1269 WIN_MSG(WM_AWT_HANDLE_NATIVE_IME_EVENT) 1270 WIN_MSG(WM_AWT_PRE_KEYDOWN) 1271 WIN_MSG(WM_AWT_PRE_KEYUP) 1272 WIN_MSG(WM_AWT_PRE_SYSKEYDOWN) 1273 WIN_MSG(WM_AWT_PRE_SYSKEYUP) 1274 WIN_MSG(WM_AWT_ENDCOMPOSITION,) 1275 WIN_MSG(WM_AWT_DISPOSE,) 1276 WIN_MSG(WM_AWT_DELETEOBJECT,) 1277 WIN_MSG(WM_AWT_SETCONVERSIONSTATUS,) 1278 WIN_MSG(WM_AWT_GETCONVERSIONSTATUS,) 1279 WIN_MSG(WM_AWT_SETOPENSTATUS,) 1280 WIN_MSG(WM_AWT_GETOPENSTATUS) 1281 WIN_MSG(WM_AWT_ACTIVATEKEYBOARDLAYOUT) 1282 WIN_MSG(WM_AWT_OPENCANDIDATEWINDOW) 1283 WIN_MSG(WM_AWT_DLG_SHOWMODAL,) 1284 WIN_MSG(WM_AWT_DLG_ENDMODAL,) 1285 WIN_MSG(WM_AWT_SETCURSOR,) 1286 WIN_MSG(WM_AWT_WAIT_FOR_SINGLE_OBJECT,) 1287 WIN_MSG(WM_AWT_INVOKE_METHOD,) 1288 WIN_MSG(WM_AWT_INVOKE_VOID_METHOD,) 1289 WIN_MSG(WM_AWT_EXECUTE_SYNC,) 1290 WIN_MSG(WM_AWT_CURSOR_SYNC) 1291 WIN_MSG(WM_AWT_GETDC) 1292 WIN_MSG(WM_AWT_RELEASEDC) 1293 WIN_MSG(WM_AWT_RELEASE_ALL_DCS) 1294 WIN_MSG(WM_AWT_SHOWCURSOR) 1295 WIN_MSG(WM_AWT_HIDECURSOR) 1296 WIN_MSG(WM_AWT_CREATE_PRINTED_PIXELS) 1297 WIN_MSG(WM_AWT_OBJECTLISTCLEANUP) 1298 default: 1299 sprintf(szBuf, "0x%8.8x(%s):Unknown message 0x%8.8x\n", 1300 hwnd, szComment, message); 1301 break; 1302 } 1303 printf(szBuf); 1304 } 1305 1306 #endif /* SPY_MESSAGES */ 1307 1308 /* 1309 * Dispatch messages for this window class--general component 1310 */ 1311 LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 1312 { 1313 CounterHelper ch(&m_MessagesProcessing); 1314 1315 JNILocalFrame lframe(AwtToolkit::GetEnv(), 10); 1316 SpyWinMessage(GetHWnd(), message, 1317 (message == WM_AWT_RELEASE_ALL_DCS) ? TEXT("Disposed Component") : GetClassName()); 1318 1319 LRESULT retValue = 0; 1320 MsgRouting mr = mrDoDefault; 1321 AwtToolkit::GetInstance().eventNumber++; 1322 1323 static BOOL ignoreNextLBTNUP = FALSE; //Ignore next LBUTTONUP msg? 1324 1325 lastMessage = message; 1326 1327 if (message == WmAwtIsComponent) { 1328 // special message to identify AWT HWND's without using 1329 // resource hogging ::SetProp 1330 return (LRESULT)TRUE; 1331 } 1332 1333 DWORD curPos = 0; 1334 1335 UINT switchMessage = message; 1336 switch (switchMessage) { 1337 case WM_AWT_GETDC: 1338 { 1339 HDC hDC; 1340 // First, release the DCs scheduled for deletion 1341 ReleaseDCList(GetHWnd(), passiveDCList); 1342 1343 GetDCReturnStruct *returnStruct = new GetDCReturnStruct; 1344 returnStruct->gdiLimitReached = FALSE; 1345 if (AwtGDIObject::IncrementIfAvailable()) { 1346 hDC = ::GetDCEx(GetHWnd(), NULL, 1347 DCX_CACHE | DCX_CLIPCHILDREN | 1348 DCX_CLIPSIBLINGS); 1349 if (hDC != NULL) { 1350 // Add new DC to list of DC's associated with this Component 1351 activeDCList.AddDC(hDC, GetHWnd()); 1352 } else { 1353 // Creation failed; decrement counter in AwtGDIObject 1354 AwtGDIObject::Decrement(); 1355 } 1356 } else { 1357 hDC = NULL; 1358 returnStruct->gdiLimitReached = TRUE; 1359 } 1360 returnStruct->hDC = hDC; 1361 retValue = (LRESULT)returnStruct; 1362 mr = mrConsume; 1363 break; 1364 } 1365 case WM_AWT_RELEASEDC: 1366 { 1367 HDC hDC = (HDC)wParam; 1368 MoveDCToPassiveList(hDC); 1369 ReleaseDCList(GetHWnd(), passiveDCList); 1370 mr = mrConsume; 1371 break; 1372 } 1373 case WM_AWT_RELEASE_ALL_DCS: 1374 { 1375 // Called during Component destruction. Gets current list of 1376 // DC's associated with Component and releases each DC. 1377 ReleaseDCList(GetHWnd(), activeDCList); 1378 ReleaseDCList(GetHWnd(), passiveDCList); 1379 mr = mrConsume; 1380 break; 1381 } 1382 case WM_AWT_SHOWCURSOR: 1383 ::ShowCursor(TRUE); 1384 break; 1385 case WM_AWT_HIDECURSOR: 1386 ::ShowCursor(FALSE); 1387 break; 1388 case WM_CREATE: mr = WmCreate(); break; 1389 case WM_CLOSE: mr = WmClose(); break; 1390 case WM_DESTROY: mr = WmDestroy(); break; 1391 case WM_NCDESTROY: mr = WmNcDestroy(); break; 1392 1393 case WM_ERASEBKGND: 1394 mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break; 1395 case WM_PAINT: 1396 CheckFontSmoothingSettings(GetHWnd()); 1397 /* Set draw state */ 1398 SetDrawState(GetDrawState() | JAWT_LOCK_CLIP_CHANGED); 1399 mr = WmPaint((HDC)wParam); 1400 break; 1401 1402 case WM_GETMINMAXINFO: 1403 mr = WmGetMinMaxInfo((LPMINMAXINFO)lParam); 1404 break; 1405 1406 case WM_WINDOWPOSCHANGING: 1407 { 1408 // We process this message so that we can synchronize access to 1409 // a moving window. The Scale/Blt functions in Win32BlitLoops 1410 // take the same windowMoveLock to ensure that a window is not 1411 // moving while we are trying to copy pixels into it. 1412 WINDOWPOS *lpPosInfo = (WINDOWPOS *)lParam; 1413 if ((lpPosInfo->flags & (SWP_NOMOVE | SWP_NOSIZE)) != 1414 (SWP_NOMOVE | SWP_NOSIZE)) 1415 { 1416 // Move or Size command. 1417 // Windows tends to send erroneous events that the window 1418 // is about to move when the coordinates are exactly the 1419 // same as the last time. This can cause problems with 1420 // our windowMoveLock CriticalSection because we enter it 1421 // here and never get to WM_WINDOWPOSCHANGED to release it. 1422 // So make sure this is a real move/size event before bothering 1423 // to grab the critical section. 1424 BOOL takeLock = FALSE; 1425 if (!(lpPosInfo->flags & SWP_NOMOVE) && 1426 ((windowMoveLockPosX != lpPosInfo->x) || 1427 (windowMoveLockPosY != lpPosInfo->y))) 1428 { 1429 // Real move event 1430 takeLock = TRUE; 1431 windowMoveLockPosX = lpPosInfo->x; 1432 windowMoveLockPosY = lpPosInfo->y; 1433 } 1434 if (!(lpPosInfo->flags & SWP_NOSIZE) && 1435 ((windowMoveLockPosCX != lpPosInfo->cx) || 1436 (windowMoveLockPosCY != lpPosInfo->cy))) 1437 { 1438 // Real size event 1439 takeLock = TRUE; 1440 windowMoveLockPosCX = lpPosInfo->cx; 1441 windowMoveLockPosCY = lpPosInfo->cy; 1442 } 1443 if (takeLock) { 1444 if (!windowMoveLockHeld) { 1445 windowMoveLock.Enter(); 1446 windowMoveLockHeld = TRUE; 1447 } 1448 } 1449 } 1450 mr = WmWindowPosChanging(lParam); 1451 break; 1452 } 1453 case WM_WINDOWPOSCHANGED: 1454 { 1455 // Release lock grabbed in the POSCHANGING message 1456 if (windowMoveLockHeld) { 1457 windowMoveLockHeld = FALSE; 1458 windowMoveLock.Leave(); 1459 } 1460 mr = WmWindowPosChanged(lParam); 1461 break; 1462 } 1463 case WM_MOVE: { 1464 RECT r; 1465 ::GetWindowRect(GetHWnd(), &r); 1466 mr = WmMove(r.left, r.top); 1467 break; 1468 } 1469 case WM_SIZE: 1470 { 1471 RECT r; 1472 // fix 4128317 : use GetClientRect for full 32-bit int precision and 1473 // to avoid negative client area dimensions overflowing 16-bit params - robi 1474 ::GetClientRect( GetHWnd(), &r ); 1475 mr = WmSize(static_cast<UINT>(wParam), r.right - r.left, r.bottom - r.top); 1476 //mr = WmSize(wParam, LOWORD(lParam), HIWORD(lParam)); 1477 SetCompositionWindow(r); 1478 break; 1479 } 1480 case WM_SIZING: 1481 mr = WmSizing(); 1482 break; 1483 case WM_SHOWWINDOW: 1484 mr = WmShowWindow(static_cast<BOOL>(wParam), 1485 static_cast<UINT>(lParam)); break; 1486 case WM_SYSCOMMAND: 1487 mr = WmSysCommand(static_cast<UINT>(wParam & 0xFFF0), 1488 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1489 break; 1490 case WM_EXITSIZEMOVE: 1491 mr = WmExitSizeMove(); 1492 break; 1493 // Bug #4039858 (Selecting menu item causes bogus mouse click event) 1494 case WM_ENTERMENULOOP: 1495 mr = WmEnterMenuLoop((BOOL)wParam); 1496 sm_bMenuLoop = TRUE; 1497 // we need to release grab if menu is shown 1498 if (AwtWindow::GetGrabbedWindow() != NULL) { 1499 AwtWindow::GetGrabbedWindow()->Ungrab(); 1500 } 1501 break; 1502 case WM_EXITMENULOOP: 1503 mr = WmExitMenuLoop((BOOL)wParam); 1504 sm_bMenuLoop = FALSE; 1505 break; 1506 1507 // We don't expect any focus messages on non-proxy component, 1508 // except those that came from Java. 1509 case WM_SETFOCUS: 1510 if (sm_inSynthesizeFocus) { 1511 mr = WmSetFocus((HWND)wParam); 1512 } else { 1513 mr = mrConsume; 1514 } 1515 break; 1516 case WM_KILLFOCUS: 1517 if (sm_inSynthesizeFocus) { 1518 mr = WmKillFocus((HWND)wParam); 1519 } else { 1520 mr = mrConsume; 1521 } 1522 break; 1523 case WM_ACTIVATE: { 1524 UINT nState = LOWORD(wParam); 1525 BOOL fMinimized = (BOOL)HIWORD(wParam); 1526 mr = mrConsume; 1527 1528 if (!sm_suppressFocusAndActivation && 1529 (!fMinimized || (nState == WA_INACTIVE))) 1530 { 1531 mr = WmActivate(nState, fMinimized, (HWND)lParam); 1532 1533 // When the window is deactivated, send WM_IME_ENDCOMPOSITION 1534 // message to deactivate the composition window so that 1535 // it won't receive keyboard input focus. 1536 HIMC hIMC; 1537 HWND hwnd = ImmGetHWnd(); 1538 if ((hIMC = ImmGetContext(hwnd)) != NULL) { 1539 ImmReleaseContext(hwnd, hIMC); 1540 DefWindowProc(WM_IME_ENDCOMPOSITION, 0, 0); 1541 } 1542 } 1543 break; 1544 } 1545 case WM_MOUSEACTIVATE: { 1546 AwtWindow *window = GetContainer(); 1547 if (window && window->IsFocusableWindow()) { 1548 // AWT/Swing will later request focus to a proper component 1549 // on handling the Java mouse event. Anyway, we have to 1550 // activate the window here as it works both for AWT & Swing. 1551 // Do it in our own fassion, 1552 window->AwtSetActiveWindow(TRUE, LOWORD(lParam)/*hittest*/); 1553 } 1554 mr = mrConsume; 1555 retValue = MA_NOACTIVATE; 1556 break; 1557 } 1558 case WM_CTLCOLORMSGBOX: 1559 case WM_CTLCOLOREDIT: 1560 case WM_CTLCOLORLISTBOX: 1561 case WM_CTLCOLORBTN: 1562 case WM_CTLCOLORDLG: 1563 case WM_CTLCOLORSCROLLBAR: 1564 case WM_CTLCOLORSTATIC: 1565 mr = WmCtlColor((HDC)wParam, (HWND)lParam, 1566 message-WM_CTLCOLORMSGBOX+CTLCOLOR_MSGBOX, 1567 *(HBRUSH*)&retValue); 1568 break; 1569 case WM_HSCROLL: 1570 mr = WmHScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1571 break; 1572 case WM_VSCROLL: 1573 mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); 1574 break; 1575 // 4664415: We're seeing a WM_LBUTTONUP when the user releases the 1576 // mouse button after a WM_NCLBUTTONDBLCLK. We want to ignore this 1577 // WM_LBUTTONUP, so we set a flag in WM_NCLBUTTONDBLCLK and look for the 1578 // flag on a WM_LBUTTONUP. -bchristi 1579 case WM_NCLBUTTONDBLCLK: 1580 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON | DBL_CLICK); 1581 if (mr == mrDoDefault) { 1582 ignoreNextLBTNUP = TRUE; 1583 } 1584 break; 1585 case WM_NCLBUTTONDOWN: 1586 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1587 ignoreNextLBTNUP = FALSE; 1588 break; 1589 case WM_NCLBUTTONUP: 1590 mr = WmNcMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), LEFT_BUTTON); 1591 break; 1592 case WM_NCRBUTTONDOWN: 1593 mr = WmNcMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), RIGHT_BUTTON); 1594 break; 1595 case WM_LBUTTONUP: 1596 if (ignoreNextLBTNUP) { 1597 ignoreNextLBTNUP = FALSE; 1598 return mrDoDefault; 1599 } 1600 //fall-through 1601 case WM_LBUTTONDOWN: 1602 ignoreNextLBTNUP = FALSE; 1603 //fall-through 1604 case WM_LBUTTONDBLCLK: 1605 case WM_RBUTTONDOWN: 1606 case WM_RBUTTONDBLCLK: 1607 case WM_RBUTTONUP: 1608 case WM_MBUTTONDOWN: 1609 case WM_MBUTTONDBLCLK: 1610 case WM_MBUTTONUP: 1611 case WM_XBUTTONDBLCLK: 1612 case WM_XBUTTONDOWN: 1613 case WM_XBUTTONUP: 1614 case WM_MOUSEMOVE: 1615 case WM_MOUSEWHEEL: 1616 case WM_AWT_MOUSEENTER: 1617 case WM_AWT_MOUSEEXIT: 1618 curPos = ::GetMessagePos(); 1619 POINT myPos; 1620 myPos.x = GET_X_LPARAM(curPos); 1621 myPos.y = GET_Y_LPARAM(curPos); 1622 ::ScreenToClient(GetHWnd(), &myPos); 1623 switch(switchMessage) { 1624 case WM_AWT_MOUSEENTER: 1625 mr = WmMouseEnter(static_cast<UINT>(wParam), myPos.x, myPos.y); 1626 break; 1627 case WM_LBUTTONDOWN: 1628 case WM_LBUTTONDBLCLK: 1629 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1630 LEFT_BUTTON); 1631 break; 1632 case WM_LBUTTONUP: 1633 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1634 LEFT_BUTTON); 1635 break; 1636 case WM_MOUSEMOVE: 1637 mr = WmMouseMove(static_cast<UINT>(wParam), myPos.x, myPos.y); 1638 break; 1639 case WM_MBUTTONDOWN: 1640 case WM_MBUTTONDBLCLK: 1641 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1642 MIDDLE_BUTTON); 1643 break; 1644 case WM_XBUTTONDOWN: 1645 case WM_XBUTTONDBLCLK: 1646 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1647 if (HIWORD(wParam) == 1) { 1648 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1649 X1_BUTTON); 1650 } 1651 if (HIWORD(wParam) == 2) { 1652 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1653 X2_BUTTON); 1654 } 1655 } 1656 break; 1657 case WM_XBUTTONUP: 1658 if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) { 1659 if (HIWORD(wParam) == 1) { 1660 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1661 X1_BUTTON); 1662 } 1663 if (HIWORD(wParam) == 2) { 1664 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1665 X2_BUTTON); 1666 } 1667 } 1668 break; 1669 case WM_RBUTTONDOWN: 1670 case WM_RBUTTONDBLCLK: 1671 mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y, 1672 RIGHT_BUTTON); 1673 break; 1674 case WM_RBUTTONUP: 1675 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1676 RIGHT_BUTTON); 1677 break; 1678 case WM_MBUTTONUP: 1679 mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y, 1680 MIDDLE_BUTTON); 1681 break; 1682 case WM_AWT_MOUSEEXIT: 1683 mr = WmMouseExit(static_cast<UINT>(wParam), myPos.x, myPos.y); 1684 break; 1685 case WM_MOUSEWHEEL: 1686 mr = WmMouseWheel(GET_KEYSTATE_WPARAM(wParam), 1687 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1688 GET_WHEEL_DELTA_WPARAM(wParam)); 1689 break; 1690 } 1691 break; 1692 case WM_SETCURSOR: 1693 mr = mrDoDefault; 1694 if (LOWORD(lParam) == HTCLIENT) { 1695 if (AwtComponent* comp = 1696 AwtComponent::GetComponent((HWND)wParam)) { 1697 AwtCursor::UpdateCursor(comp); 1698 mr = mrConsume; 1699 } 1700 } 1701 break; 1702 1703 case WM_KEYDOWN: 1704 mr = WmKeyDown(static_cast<UINT>(wParam), 1705 LOWORD(lParam), HIWORD(lParam), FALSE); 1706 break; 1707 case WM_KEYUP: 1708 mr = WmKeyUp(static_cast<UINT>(wParam), 1709 LOWORD(lParam), HIWORD(lParam), FALSE); 1710 break; 1711 case WM_SYSKEYDOWN: 1712 mr = WmKeyDown(static_cast<UINT>(wParam), 1713 LOWORD(lParam), HIWORD(lParam), TRUE); 1714 break; 1715 case WM_SYSKEYUP: 1716 mr = WmKeyUp(static_cast<UINT>(wParam), 1717 LOWORD(lParam), HIWORD(lParam), TRUE); 1718 break; 1719 case WM_IME_SETCONTEXT: 1720 // lParam is passed as pointer and it can be modified. 1721 mr = WmImeSetContext(static_cast<BOOL>(wParam), &lParam); 1722 break; 1723 case WM_IME_NOTIFY: 1724 mr = WmImeNotify(wParam, lParam); 1725 break; 1726 case WM_IME_STARTCOMPOSITION: 1727 mr = WmImeStartComposition(); 1728 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1729 break; 1730 case WM_IME_ENDCOMPOSITION: 1731 mr = WmImeEndComposition(); 1732 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1733 break; 1734 case WM_IME_COMPOSITION: { 1735 WORD dbcschar = static_cast<WORD>(wParam); 1736 mr = WmImeComposition(dbcschar, lParam); 1737 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1738 break; 1739 } 1740 case WM_IME_CONTROL: 1741 case WM_IME_COMPOSITIONFULL: 1742 case WM_IME_SELECT: 1743 case WM_IME_KEYUP: 1744 case WM_IME_KEYDOWN: 1745 case WM_IME_REQUEST: 1746 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1747 break; 1748 case WM_CHAR: 1749 mr = WmChar(static_cast<UINT>(wParam), 1750 LOWORD(lParam), HIWORD(lParam), FALSE); 1751 break; 1752 case WM_SYSCHAR: 1753 mr = WmChar(static_cast<UINT>(wParam), 1754 LOWORD(lParam), HIWORD(lParam), TRUE); 1755 break; 1756 case WM_IME_CHAR: 1757 mr = WmIMEChar(static_cast<UINT>(wParam), 1758 LOWORD(lParam), HIWORD(lParam), FALSE); 1759 break; 1760 1761 case WM_INPUTLANGCHANGEREQUEST: { 1762 DTRACE_PRINTLN4("WM_INPUTLANGCHANGEREQUEST: hwnd = 0x%X (%s);"// 1763 "0x%08X -> 0x%08X", 1764 GetHWnd(), GetClassName(), 1765 (UINT_PTR)GetKeyboardLayout(), (UINT_PTR)lParam); 1766 // 4267428: make sure keyboard layout is turned undead. 1767 static BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 1768 AwtToolkit::GetKeyboardState(keyboardState); 1769 WORD ignored; 1770 ::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0), 1771 keyboardState, &ignored, 0, GetKeyboardLayout()); 1772 1773 // Set this flag to block ActivateKeyboardLayout from 1774 // WInputMethod.activate() 1775 g_bUserHasChangedInputLang = TRUE; 1776 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1777 break; 1778 } 1779 case WM_INPUTLANGCHANGE: 1780 DTRACE_PRINTLN3("WM_INPUTLANGCHANGE: hwnd = 0x%X (%s);"// 1781 "new = 0x%08X", 1782 GetHWnd(), GetClassName(), (UINT)lParam); 1783 mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam)); 1784 CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); 1785 // should return non-zero if we process this message 1786 retValue = 1; 1787 break; 1788 1789 case WM_AWT_FORWARD_CHAR: 1790 mr = WmForwardChar(LOWORD(wParam), lParam, HIWORD(wParam)); 1791 break; 1792 1793 case WM_AWT_FORWARD_BYTE: 1794 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1795 break; 1796 1797 case WM_PASTE: 1798 mr = WmPaste(); 1799 break; 1800 case WM_TIMER: 1801 mr = WmTimer(wParam); 1802 break; 1803 1804 case WM_COMMAND: 1805 mr = WmCommand(LOWORD(wParam), (HWND)lParam, HIWORD(wParam)); 1806 break; 1807 case WM_COMPAREITEM: 1808 mr = WmCompareItem(static_cast<UINT>(wParam), 1809 *(COMPAREITEMSTRUCT*)lParam, retValue); 1810 break; 1811 case WM_DELETEITEM: 1812 mr = WmDeleteItem(static_cast<UINT>(wParam), 1813 *(DELETEITEMSTRUCT*)lParam); 1814 break; 1815 case WM_DRAWITEM: 1816 mr = WmDrawItem(static_cast<UINT>(wParam), 1817 *(DRAWITEMSTRUCT*)lParam); 1818 break; 1819 case WM_MEASUREITEM: 1820 mr = WmMeasureItem(static_cast<UINT>(wParam), 1821 *(MEASUREITEMSTRUCT*)lParam); 1822 break; 1823 1824 case WM_AWT_HANDLE_EVENT: 1825 mr = HandleEvent( (MSG *) lParam, (BOOL) wParam); 1826 break; 1827 1828 case WM_PRINT: 1829 mr = WmPrint((HDC)wParam, lParam); 1830 break; 1831 case WM_PRINTCLIENT: 1832 mr = WmPrintClient((HDC)wParam, lParam); 1833 break; 1834 1835 case WM_NCCALCSIZE: 1836 mr = WmNcCalcSize((BOOL)wParam, (LPNCCALCSIZE_PARAMS)lParam, 1837 retValue); 1838 break; 1839 case WM_NCPAINT: 1840 mr = WmNcPaint((HRGN)wParam); 1841 break; 1842 case WM_NCHITTEST: 1843 mr = WmNcHitTest(LOWORD(lParam), HIWORD(lParam), retValue); 1844 break; 1845 1846 case WM_AWT_RESHAPE_COMPONENT: { 1847 RECT* r = (RECT*)lParam; 1848 WPARAM checkEmbedded = wParam; 1849 if (checkEmbedded == CHECK_EMBEDDED && IsEmbeddedFrame()) { 1850 ::OffsetRect(r, -r->left, -r->top); 1851 } 1852 Reshape(r->left, r->top, r->right - r->left, r->bottom - r->top); 1853 delete r; 1854 mr = mrConsume; 1855 break; 1856 } 1857 1858 case WM_AWT_SETALWAYSONTOP: { 1859 AwtWindow* w = (AwtWindow*)lParam; 1860 BOOL value = (BOOL)wParam; 1861 UINT flags = SWP_NOMOVE | SWP_NOSIZE; 1862 // transient windows shouldn't change the owner window's position in the z-order 1863 if (w->IsRetainingHierarchyZOrder()) { 1864 flags |= SWP_NOOWNERZORDER; 1865 } 1866 ::SetWindowPos(w->GetHWnd(), (value != 0 ? HWND_TOPMOST : HWND_NOTOPMOST), 1867 0,0,0,0, flags); 1868 break; 1869 } 1870 1871 case WM_AWT_BEGIN_VALIDATE: 1872 BeginValidate(); 1873 mr = mrConsume; 1874 break; 1875 case WM_AWT_END_VALIDATE: 1876 EndValidate(); 1877 mr = mrConsume; 1878 break; 1879 1880 case WM_PALETTEISCHANGING: 1881 mr = WmPaletteIsChanging((HWND)wParam); 1882 mr = mrDoDefault; 1883 break; 1884 case WM_QUERYNEWPALETTE: 1885 mr = WmQueryNewPalette(retValue); 1886 break; 1887 case WM_PALETTECHANGED: 1888 mr = WmPaletteChanged((HWND)wParam); 1889 break; 1890 case WM_STYLECHANGED: 1891 mr = WmStyleChanged(static_cast<int>(wParam), (LPSTYLESTRUCT)lParam); 1892 break; 1893 case WM_SETTINGCHANGE: 1894 CheckFontSmoothingSettings(NULL); 1895 mr = WmSettingChange(static_cast<UINT>(wParam), (LPCTSTR)lParam); 1896 break; 1897 case WM_CONTEXTMENU: 1898 mr = WmContextMenu((HWND)wParam, 1899 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); 1900 break; 1901 1902 /* 1903 * These messages are used to route Win32 calls to the 1904 * creating thread, since these calls fail unless executed 1905 * there. 1906 */ 1907 case WM_AWT_COMPONENT_SHOW: 1908 Show(); 1909 mr = mrConsume; 1910 break; 1911 case WM_AWT_COMPONENT_HIDE: 1912 Hide(); 1913 mr = mrConsume; 1914 break; 1915 1916 case WM_AWT_COMPONENT_SETFOCUS: 1917 if ((BOOL)wParam) { 1918 retValue = SynthesizeWmSetFocus(GetHWnd(), NULL); 1919 } else { 1920 retValue = SynthesizeWmKillFocus(GetHWnd(), NULL); 1921 } 1922 mr = mrConsume; 1923 break; 1924 case WM_AWT_WINDOW_SETACTIVE: 1925 retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam); 1926 mr = mrConsume; 1927 break; 1928 1929 case WM_AWT_SET_SCROLL_INFO: { 1930 SCROLLINFO *si = (SCROLLINFO *) lParam; 1931 ::SetScrollInfo(GetHWnd(), (int) wParam, si, TRUE); 1932 delete si; 1933 mr = mrConsume; 1934 break; 1935 } 1936 case WM_AWT_CREATE_PRINTED_PIXELS: { 1937 CreatePrintedPixelsStruct* cpps = (CreatePrintedPixelsStruct*)wParam; 1938 SIZE loc = { cpps->srcx, cpps->srcy }; 1939 SIZE size = { cpps->srcw, cpps->srch }; 1940 retValue = (LRESULT)CreatePrintedPixels(loc, size, cpps->alpha); 1941 mr = mrConsume; 1942 break; 1943 } 1944 case WM_UNDOCUMENTED_CLICKMENUBAR: 1945 { 1946 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { 1947 mr = mrConsume; 1948 } 1949 } 1950 } 1951 1952 /* 1953 * If not a specific Consume, it was a specific DoDefault, or a 1954 * PassAlong (since the default is the next in chain), then call the 1955 * default proc. 1956 */ 1957 if (mr != mrConsume) { 1958 retValue = DefWindowProc(message, wParam, lParam); 1959 } 1960 1961 return retValue; 1962 } 1963 /* 1964 * Call this instance's default window proc, or if none set, call the stock 1965 * Window's one. 1966 */ 1967 LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) 1968 { 1969 return ComCtl32Util::GetInstance().DefWindowProc(m_DefWindowProc, GetHWnd(), msg, wParam, lParam); 1970 } 1971 1972 /* 1973 * This message should only be received when a window is destroyed by 1974 * Windows, and not Java. Window termination has been reworked so 1975 * this method should never be called during termination. 1976 */ 1977 MsgRouting AwtComponent::WmDestroy() 1978 { 1979 return mrConsume; 1980 } 1981 1982 /* 1983 * This message should only be received when a window is destroyed by 1984 * Windows, and not Java. It is sent only after child windows were destroyed. 1985 */ 1986 MsgRouting AwtComponent::WmNcDestroy() 1987 { 1988 if (m_peerObject != NULL) { // is not being terminating 1989 // Stay in this handler until AwtComponent::Dispose is called. 1990 m_bPauseDestroy = TRUE; 1991 1992 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1993 // Post invocation event for WObjectPeer.dispose to EDT 1994 env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID); 1995 // Wait until AwtComponent::Dispose is called 1996 AwtToolkit::GetInstance().PumpToDestroy(this); 1997 } 1998 1999 return mrConsume; 2000 } 2001 2002 MsgRouting AwtComponent::WmGetMinMaxInfo(LPMINMAXINFO lpmmi) 2003 { 2004 return mrDoDefault; 2005 } 2006 2007 MsgRouting AwtComponent::WmMove(int x, int y) 2008 { 2009 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2010 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2011 return mrDoDefault; 2012 } 2013 2014 MsgRouting AwtComponent::WmSize(UINT type, int w, int h) 2015 { 2016 SetDrawState(GetDrawState() | static_cast<jint>(JAWT_LOCK_BOUNDS_CHANGED) 2017 | static_cast<jint>(JAWT_LOCK_CLIP_CHANGED)); 2018 return mrDoDefault; 2019 } 2020 2021 MsgRouting AwtComponent::WmSizing() 2022 { 2023 return mrDoDefault; 2024 } 2025 2026 MsgRouting AwtComponent::WmSysCommand(UINT uCmdType, int xPos, int yPos) 2027 { 2028 return mrDoDefault; 2029 } 2030 2031 MsgRouting AwtComponent::WmExitSizeMove() 2032 { 2033 return mrDoDefault; 2034 } 2035 2036 MsgRouting AwtComponent::WmEnterMenuLoop(BOOL isTrackPopupMenu) 2037 { 2038 return mrDoDefault; 2039 } 2040 2041 MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu) 2042 { 2043 return mrDoDefault; 2044 } 2045 2046 MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status) 2047 { 2048 return mrDoDefault; 2049 } 2050 2051 MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus) 2052 { 2053 m_wheelRotationAmount = 0; 2054 return mrDoDefault; 2055 } 2056 2057 MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus) 2058 { 2059 m_wheelRotationAmount = 0; 2060 return mrDoDefault; 2061 } 2062 2063 MsgRouting AwtComponent::WmCtlColor(HDC hDC, HWND hCtrl, 2064 UINT ctlColor, HBRUSH& retBrush) 2065 { 2066 AwtComponent* child = AwtComponent::GetComponent(hCtrl); 2067 if (child) { 2068 ::SetBkColor(hDC, child->GetBackgroundColor()); 2069 ::SetTextColor(hDC, child->GetColor()); 2070 retBrush = child->GetBackgroundBrush(); 2071 return mrConsume; 2072 } 2073 return mrDoDefault; 2074 /* 2075 switch (ctlColor) { 2076 case CTLCOLOR_MSGBOX: 2077 case CTLCOLOR_EDIT: 2078 case CTLCOLOR_LISTBOX: 2079 case CTLCOLOR_BTN: 2080 case CTLCOLOR_DLG: 2081 case CTLCOLOR_SCROLLBAR: 2082 case CTLCOLOR_STATIC: 2083 } 2084 */ 2085 } 2086 2087 MsgRouting AwtComponent::WmHScroll(UINT scrollCode, UINT pos, 2088 HWND hScrollbar) { 2089 if (hScrollbar && hScrollbar != GetHWnd()) { 2090 /* the last test should never happen */ 2091 AwtComponent* sb = GetComponent(hScrollbar); 2092 if (sb) { 2093 sb->WmHScroll(scrollCode, pos, hScrollbar); 2094 } 2095 } 2096 return mrDoDefault; 2097 } 2098 2099 MsgRouting AwtComponent::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar) 2100 { 2101 if (hScrollbar && hScrollbar != GetHWnd()) { 2102 /* the last test should never happen */ 2103 AwtComponent* sb = GetComponent(hScrollbar); 2104 if (sb) { 2105 sb->WmVScroll(scrollCode, pos, hScrollbar); 2106 } 2107 } 2108 return mrDoDefault; 2109 } 2110 2111 namespace TimeHelper { 2112 // Sometimes the message belongs to another event queue and 2113 // GetMessageTime() may return wrong non-zero value (the case is 2114 // the TrayIcon peer). Using TimeHelper::windowsToUTC(::GetTickCount()) 2115 // could help there. 2116 static DWORD getMessageTimeWindows(){ 2117 DWORD time = ::GetMessageTime(); 2118 // The following 'if' seems to be a unneeded hack. 2119 // Consider removing it. 2120 if (time == 0) { 2121 time = ::GetTickCount(); 2122 } 2123 return time; 2124 } 2125 2126 jlong getMessageTimeUTC() { 2127 return windowsToUTC(getMessageTimeWindows()); 2128 } 2129 2130 // If calling order of GetTickCount and JVM_CurrentTimeMillis 2131 // is swapped, it would sometimes give different result. 2132 // Anyway, we would not always have determinism 2133 // and sortedness of time conversion here (due to Windows's 2134 // timers peculiarities). Having some euristic algorithm might 2135 // help here. 2136 jlong windowsToUTC(DWORD windowsTime) { 2137 jlong offset = ::GetTickCount() - windowsTime; 2138 jlong jvm_time = ::JVM_CurrentTimeMillis(NULL, 0); 2139 return jvm_time - offset; 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 dont 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 if (extKeyCodesClsLocal == NULL) { 3313 /* exception already thrown */ 3314 return; 3315 } 3316 extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal); 3317 env->DeleteLocalRef(extKeyCodesClsLocal); 3318 } 3319 static jmethodID getExtendedKeyCodeForChar; 3320 if (getExtendedKeyCodeForChar == NULL) { 3321 getExtendedKeyCodeForChar = 3322 env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I"); 3323 DASSERT(getExtendedKeyCodeForChar); 3324 } 3325 jint extJKC; //extended Java key code 3326 3327 for (UINT i = 0; i < 256; i++) { 3328 dynPrimaryKeymap[i].wkey = i; 3329 dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED; 3330 dynPrimaryKeymap[i].unicode = 0; 3331 3332 if ((sc = MapVirtualKey (i, 0)) == 0) { 3333 dynPrimaryKeymap[i].scancode = 0; 3334 continue; 3335 } 3336 dynPrimaryKeymap[i].scancode = sc; 3337 3338 // XXX process cases like VK_SHIFT etc. 3339 kbdState[i] = 0x80; // "key pressed". 3340 WCHAR wc[16]; 3341 int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl); 3342 if (k == 1) { 3343 // unicode 3344 dynPrimaryKeymap[i].unicode = wc[0]; 3345 if (dynPrimaryKeymap[i].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3346 // Convert unicode to java keycode. 3347 //dynPrimaryKeymap[i].jkey = ((UINT)(wc[0]) + 0x01000000); 3348 // 3349 //XXX If this key in on the keypad, we should force a special value equal to 3350 //XXX an old java keycode: but how to say if it is a keypad key? 3351 //XXX We'll do it in WmKeyUp/Down. 3352 extJKC = env->CallStaticIntMethod(extKeyCodesCls, 3353 getExtendedKeyCodeForChar, (jint)(wc[0])); 3354 dynPrimaryKeymap[i].jkey = extJKC; 3355 } 3356 }else if (k == -1) { 3357 // dead key: use charToDeadVKTable 3358 dynPrimaryKeymap[i].unicode = wc[0]; 3359 resetKbdState( kbdState ); 3360 for (const CharToVKEntry *map = charToDeadVKTable; map->c != 0; ++map) { 3361 if (wc[0] == map->c) { 3362 dynPrimaryKeymap[i].jkey = map->javaKey; 3363 break; 3364 } 3365 } 3366 } else if (k == 0) { 3367 // reset 3368 resetKbdState( kbdState ); 3369 }else { 3370 // k > 1: this key does generate multiple characters. Ignore it. 3371 // An example: Arabic Lam and Alef ligature. 3372 // There will be no extended keycode and thus shortcuts for this key. 3373 // XXX shouldn't we reset the kbd state? 3374 #ifdef DEBUG 3375 DTRACE_PRINTLN2("wkey 0x%02X (%d)", i,i); 3376 #endif 3377 } 3378 kbdState[i] = 0; // "key unpressed" 3379 } 3380 } 3381 void 3382 AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers) 3383 { 3384 if( wkey && wkey < 256 ) { 3385 if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) { 3386 // At the creation time, 3387 // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /" 3388 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3389 } 3390 if(dynPrimaryKeymap[wkey].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) { 3391 // E.g. it is non-unicode key 3392 dynPrimaryKeymap[wkey].jkey = jkeyLegacy; 3393 } 3394 } 3395 } 3396 3397 UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey) 3398 { 3399 static Hashtable transTable("VKEY translations"); 3400 static Hashtable deadKeyFlagTable("Dead Key Flags"); 3401 isDeadKey = FALSE; 3402 3403 // Try to translate using last saved translation 3404 if (ops == LOAD) { 3405 void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3406 void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3407 if (value != NULL) { 3408 isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag)); 3409 return static_cast<UINT>(reinterpret_cast<INT_PTR>(value)); 3410 } 3411 } 3412 3413 // If the windows key is a return, wkey will equal 13 ('\r') 3414 // In this case, we want to return 10 ('\n') 3415 // Since ToAscii would convert VK_RETURN to '\r', we need 3416 // to have a special case here. 3417 if (wkey == VK_RETURN) 3418 return '\n'; 3419 3420 // high order bit in keyboardState indicates whether the key is down 3421 static const BYTE KEY_STATE_DOWN = 0x80; 3422 BYTE keyboardState[AwtToolkit::KB_STATE_SIZE]; 3423 AwtToolkit::GetKeyboardState(keyboardState); 3424 3425 // apply modifiers to keyboard state if necessary 3426 if (modifiers) { 3427 BOOL shiftIsDown = modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK; 3428 BOOL altIsDown = modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK; 3429 BOOL ctrlIsDown = modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK; 3430 3431 // Windows treats AltGr as Ctrl+Alt 3432 if (modifiers & java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK) { 3433 altIsDown = TRUE; 3434 ctrlIsDown = TRUE; 3435 } 3436 3437 if (shiftIsDown) { 3438 keyboardState[VK_SHIFT] |= KEY_STATE_DOWN; 3439 } 3440 3441 // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715) 3442 // Here we try to resolve a conflict with ::ToAsciiEx's translating 3443 // ALT+number key combinations. kdm@sarc.spb.su 3444 // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail. 3445 if( IsNavigationKey(wkey) ) { 3446 keyboardState[VK_MENU] &= ~KEY_STATE_DOWN; 3447 } 3448 3449 if (ctrlIsDown) 3450 { 3451 if (altIsDown) { 3452 // bugid 4215009: don't mess with AltGr == Ctrl + Alt 3453 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3454 } 3455 else { 3456 // bugid 4098210: old event model doesn't have KEY_TYPED 3457 // events, so try to provide a meaningful character for 3458 // Ctrl+<key>. Take Ctrl into account only when we know 3459 // that Ctrl+<key> will be an ASCII control. Ignore by 3460 // default. 3461 keyboardState[VK_CONTROL] &= ~KEY_STATE_DOWN; 3462 3463 // Letters have Ctrl+<letter> counterparts. According to 3464 // <winuser.h> VK_A through VK_Z are the same as ASCII 3465 // 'A' through 'Z'. 3466 if (wkey >= 'A' && wkey <= 'Z') { 3467 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3468 } 3469 else { 3470 // Non-letter controls 033 to 037 are: 3471 // ^[ (ESC), ^\ (FS), ^] (GS), ^^ (RS), and ^_ (US) 3472 3473 // Shift state bits returned by ::VkKeyScan in HIBYTE 3474 static const UINT _VKS_SHIFT_MASK = 0x01; 3475 static const UINT _VKS_CTRL_MASK = 0x02; 3476 static const UINT _VKS_ALT_MASK = 0x04; 3477 3478 // Check to see whether there is a meaningful translation 3479 TCHAR ch; 3480 short vk; 3481 for (ch = _T('\033'); ch < _T('\040'); ch++) { 3482 vk = ::VkKeyScan(ch); 3483 if (wkey == LOBYTE(vk)) { 3484 UINT shiftState = HIBYTE(vk); 3485 if ((shiftState & _VKS_CTRL_MASK) || 3486 (!(shiftState & _VKS_SHIFT_MASK) 3487 == !shiftIsDown)) 3488 { 3489 keyboardState[VK_CONTROL] |= KEY_STATE_DOWN; 3490 } 3491 break; 3492 } 3493 } 3494 } 3495 } // ctrlIsDown && altIsDown 3496 } // ctrlIsDown 3497 } // modifiers 3498 3499 // instead of creating our own conversion tables, I'll let Win32 3500 // convert the character for me. 3501 WORD wChar[2]; 3502 UINT scancode = ::MapVirtualKey(wkey, 0); 3503 int converted = ::ToUnicodeEx(wkey, scancode, keyboardState, 3504 wChar, 2, 0, GetKeyboardLayout()); 3505 3506 UINT translation; 3507 BOOL deadKeyFlag = (converted == 2); 3508 3509 // Dead Key 3510 if (converted < 0) { 3511 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3512 } else 3513 // No translation available -- try known conversions or else punt. 3514 if (converted == 0) { 3515 if (wkey == VK_DELETE) { 3516 translation = '\177'; 3517 } else 3518 if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) { 3519 translation = '0' + wkey - VK_NUMPAD0; 3520 } else { 3521 translation = java_awt_event_KeyEvent_CHAR_UNDEFINED; 3522 } 3523 } else 3524 // the caller expects a Unicode character. 3525 if (converted > 0) { 3526 translation = wChar[0]; 3527 } 3528 if (ops == SAVE) { 3529 transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3530 reinterpret_cast<void*>(static_cast<INT_PTR>(translation))); 3531 if (deadKeyFlag) { 3532 deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)), 3533 reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag))); 3534 } else { 3535 deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey))); 3536 } 3537 } 3538 3539 isDeadKey = deadKeyFlag; 3540 return translation; 3541 } 3542 3543 MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, 3544 UINT flags, BOOL system) 3545 { 3546 // VK_PROCESSKEY is a special value which means 3547 // "Current IME wants to consume this KeyEvent" 3548 // Real key code is saved by IMM32.DLL and can be retrieved by 3549 // calling ImmGetVirtualKey(); 3550 if (wkey == VK_PROCESSKEY) { 3551 return mrDoDefault; 3552 } 3553 MSG msg; 3554 InitMessage(&msg, (system ? WM_SYSKEYDOWN : WM_KEYDOWN), 3555 wkey, MAKELPARAM(repCnt, flags)); 3556 3557 UINT modifiers = GetJavaModifiers(); 3558 jint keyLocation = GetKeyLocation(wkey, flags); 3559 BOOL isDeadKey = FALSE; 3560 UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey); 3561 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3562 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3563 3564 3565 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED, 3566 TimeHelper::windowsToUTC(msg.time), jkey, character, 3567 modifiers, keyLocation, (jlong)wkey, &msg); 3568 3569 // bugid 4724007: Windows does not create a WM_CHAR for the Del key 3570 // for some reason, so we need to create the KEY_TYPED event on the 3571 // WM_KEYDOWN. Use null msg so the character doesn't get sent back 3572 // to the native window for processing (this event is synthesized 3573 // for Java - we don't want Windows trying to process it). 3574 if (jkey == java_awt_event_KeyEvent_VK_DELETE) { 3575 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3576 TimeHelper::windowsToUTC(msg.time), 3577 java_awt_event_KeyEvent_VK_UNDEFINED, 3578 character, modifiers, 3579 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0); 3580 } 3581 3582 return mrConsume; 3583 } 3584 3585 MsgRouting AwtComponent::WmKeyUp(UINT wkey, UINT repCnt, 3586 UINT flags, BOOL system) 3587 { 3588 3589 // VK_PROCESSKEY is a special value which means 3590 // "Current IME wants to consume this KeyEvent" 3591 // Real key code is saved by IMM32.DLL and can be retrieved by 3592 // calling ImmGetVirtualKey(); 3593 if (wkey == VK_PROCESSKEY) { 3594 return mrDoDefault; 3595 } 3596 MSG msg; 3597 InitMessage(&msg, (system ? WM_SYSKEYUP : WM_KEYUP), 3598 wkey, MAKELPARAM(repCnt, flags)); 3599 3600 UINT modifiers = GetJavaModifiers(); 3601 jint keyLocation = GetKeyLocation(wkey, flags); 3602 BOOL isDeadKey = FALSE; 3603 UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey); 3604 UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey); 3605 UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers); 3606 3607 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED, 3608 TimeHelper::windowsToUTC(msg.time), jkey, character, 3609 modifiers, keyLocation, (jlong)wkey, &msg); 3610 return mrConsume; 3611 } 3612 3613 MsgRouting AwtComponent::WmInputLangChange(UINT charset, HKL hKeyboardLayout) 3614 { 3615 // Normally we would be able to use charset and TranslateCharSetInfo 3616 // to get a code page that should be associated with this keyboard 3617 // layout change. However, there seems to be an NT 4.0 bug associated 3618 // with the WM_INPUTLANGCHANGE message, which makes the charset parameter 3619 // unreliable, especially on Asian systems. Our workaround uses the 3620 // keyboard layout handle instead. 3621 m_hkl = hKeyboardLayout; 3622 m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID 3623 m_CodePage = LangToCodePage(m_idLang); 3624 BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM 3625 BuildPrimaryDynamicTable(); 3626 return mrConsume; // do not propagate to children 3627 } 3628 3629 // Convert Language ID to CodePage 3630 UINT AwtComponent::LangToCodePage(LANGID idLang) 3631 { 3632 TCHAR strCodePage[MAX_ACP_STR_LEN]; 3633 // use the LANGID to create a LCID 3634 LCID idLocale = MAKELCID(idLang, SORT_DEFAULT); 3635 // get the ANSI code page associated with this locale 3636 if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE, strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 ) 3637 return _ttoi(strCodePage); 3638 else 3639 return GetACP(); 3640 } 3641 3642 3643 MsgRouting AwtComponent::WmIMEChar(UINT character, UINT repCnt, UINT flags, BOOL system) 3644 { 3645 // We will simply create Java events here. 3646 WCHAR unicodeChar = character; 3647 MSG msg; 3648 InitMessage(&msg, WM_IME_CHAR, character, 3649 MAKELPARAM(repCnt, flags)); 3650 3651 jint modifiers = GetJavaModifiers(); 3652 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3653 TimeHelper::windowsToUTC(msg.time), 3654 java_awt_event_KeyEvent_VK_UNDEFINED, 3655 unicodeChar, modifiers, 3656 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3657 &msg); 3658 return mrConsume; 3659 } 3660 3661 MsgRouting AwtComponent::WmChar(UINT character, UINT repCnt, UINT flags, 3662 BOOL system) 3663 { 3664 // Will only get WmChar messages with DBCS if we create them for 3665 // an Edit class in the WmForwardChar method. These synthesized 3666 // DBCS chars are ok to pass on directly to the default window 3667 // procedure. They've already been filtered through the Java key 3668 // event queue. We will never get the trail byte since the edit 3669 // class will PeekMessage(&msg, hwnd, WM_CHAR, WM_CHAR, 3670 // PM_REMOVE). I would like to be able to pass this character off 3671 // via WM_AWT_FORWARD_BYTE, but the Edit classes don't seem to 3672 // like that. 3673 3674 // We will simply create Java events here. 3675 UINT message = system ? WM_SYSCHAR : WM_CHAR; 3676 3677 // The Alt modifier is reported in the 29th bit of the lParam, 3678 // i.e., it is the 13th bit of `flags' (which is HIWORD(lParam)). 3679 bool alt_is_down = (flags & (1<<13)) != 0; 3680 3681 // Fix for bug 4141621, corrected by fix for bug 6223726: Alt+space doesn't invoke system menu 3682 // We should not pass this particular combination to Java. 3683 3684 if (system && alt_is_down) { 3685 if (character == VK_SPACE) { 3686 return mrDoDefault; 3687 } 3688 } 3689 3690 // If this is a WM_CHAR (non-system) message, then the Alt flag 3691 // indicates that the character was typed using an AltGr key 3692 // (which Windows treats as Ctrl+Alt), so in this case we do NOT 3693 // pass the Ctrl and Alt modifiers to Java, but instead we 3694 // replace them with Java's AltGraph modifier. Note: the AltGraph 3695 // modifier does not exist in 1.1.x releases. 3696 jint modifiers = GetJavaModifiers(); 3697 if (!system && alt_is_down) { 3698 // character typed with AltGraph 3699 modifiers &= ~(java_awt_event_InputEvent_ALT_DOWN_MASK 3700 | java_awt_event_InputEvent_CTRL_DOWN_MASK); 3701 modifiers |= java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK; 3702 } 3703 3704 WCHAR unicodeChar = character; 3705 3706 // Kludge: Combine pending single byte with this char for some Chinese IMEs 3707 if (m_PendingLeadByte != 0) { 3708 character = (m_PendingLeadByte & 0x00ff) | (character << 8); 3709 m_PendingLeadByte = 0; 3710 ::MultiByteToWideChar(GetCodePage(), 0, (CHAR*)&character, 2, 3711 &unicodeChar, 1); 3712 } 3713 3714 if (unicodeChar == VK_RETURN) { 3715 // Enter key generates \r in windows, but \n is required in java 3716 unicodeChar = java_awt_event_KeyEvent_VK_ENTER; 3717 } 3718 MSG msg; 3719 InitMessage(&msg, message, character, 3720 MAKELPARAM(repCnt, flags)); 3721 SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_TYPED, 3722 TimeHelper::windowsToUTC(msg.time), 3723 java_awt_event_KeyEvent_VK_UNDEFINED, 3724 unicodeChar, modifiers, 3725 java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0, 3726 &msg); 3727 return mrConsume; 3728 } 3729 3730 MsgRouting AwtComponent::WmForwardChar(WCHAR character, LPARAM lParam, 3731 BOOL synthetic) 3732 { 3733 // just post WM_CHAR with unicode key value 3734 DefWindowProc(WM_CHAR, (WPARAM)character, lParam); 3735 return mrConsume; 3736 } 3737 3738 MsgRouting AwtComponent::WmPaste() 3739 { 3740 return mrDoDefault; 3741 } 3742 3743 // support IME Composition messages 3744 void AwtComponent::SetCompositionWindow(RECT& r) 3745 { 3746 HWND hwnd = ImmGetHWnd(); 3747 HIMC hIMC = ImmGetContext(hwnd); 3748 if (hIMC == NULL) { 3749 return; 3750 } 3751 COMPOSITIONFORM cf = {CFS_DEFAULT, {0, 0}, {0, 0, 0, 0}}; 3752 ImmSetCompositionWindow(hIMC, &cf); 3753 ImmReleaseContext(hwnd, hIMC); 3754 } 3755 3756 void AwtComponent::OpenCandidateWindow(int x, int y) 3757 { 3758 UINT bits = 1; 3759 RECT rc; 3760 GetWindowRect(GetHWnd(), &rc); 3761 3762 for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) { 3763 if ( m_bitsCandType & bits ) 3764 SetCandidateWindow(iCandType, x-rc.left, y-rc.top); 3765 } 3766 if (m_bitsCandType != 0) { 3767 // REMIND: is there any chance GetProxyFocusOwner() returns NULL here? 3768 ::DefWindowProc(ImmGetHWnd(), 3769 WM_IME_NOTIFY, IMN_OPENCANDIDATE, m_bitsCandType); 3770 } 3771 } 3772 3773 void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) 3774 { 3775 HWND hwnd = ImmGetHWnd(); 3776 HIMC hIMC = ImmGetContext(hwnd); 3777 CANDIDATEFORM cf; 3778 cf.dwIndex = iCandType; 3779 cf.dwStyle = CFS_CANDIDATEPOS; 3780 cf.ptCurrentPos.x = x; 3781 cf.ptCurrentPos.y = y; 3782 3783 ImmSetCandidateWindow(hIMC, &cf); 3784 ImmReleaseContext(hwnd, hIMC); 3785 } 3786 3787 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam) 3788 { 3789 // If the Windows input context is disabled, do not let Windows 3790 // display any UIs. 3791 HWND hwnd = ImmGetHWnd(); 3792 HIMC hIMC = ImmGetContext(hwnd); 3793 if (hIMC == NULL) { 3794 *lplParam = 0; 3795 return mrDoDefault; 3796 } 3797 ImmReleaseContext(hwnd, hIMC); 3798 3799 if (fSet) { 3800 LPARAM lParam = *lplParam; 3801 if (!m_useNativeCompWindow) { 3802 // stop to draw native composing window. 3803 *lplParam &= ~ISC_SHOWUICOMPOSITIONWINDOW; 3804 } 3805 } 3806 return mrDoDefault; 3807 } 3808 3809 MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType) 3810 { 3811 if (!m_useNativeCompWindow && subMsg == IMN_OPENCANDIDATE) { 3812 m_bitsCandType = bitsCandType; 3813 InquireCandidatePosition(); 3814 return mrConsume; 3815 } 3816 return mrDoDefault; 3817 } 3818 3819 MsgRouting AwtComponent::WmImeStartComposition() 3820 { 3821 if (m_useNativeCompWindow) { 3822 RECT rc; 3823 ::GetClientRect(GetHWnd(), &rc); 3824 SetCompositionWindow(rc); 3825 return mrDoDefault; 3826 } else 3827 return mrConsume; 3828 } 3829 3830 MsgRouting AwtComponent::WmImeEndComposition() 3831 { 3832 if (m_useNativeCompWindow) return mrDoDefault; 3833 3834 SendInputMethodEvent( 3835 java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3836 NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0 ); 3837 return mrConsume; 3838 } 3839 3840 MsgRouting AwtComponent::WmImeComposition(WORD wChar, LPARAM flags) 3841 { 3842 if (m_useNativeCompWindow) return mrDoDefault; 3843 3844 int* bndClauseW = NULL; 3845 jstring* readingClauseW = NULL; 3846 int* bndAttrW = NULL; 3847 BYTE* valAttrW = NULL; 3848 int cClauseW = 0; 3849 AwtInputTextInfor* textInfor = NULL; 3850 3851 try { 3852 HWND hwnd = ImmGetHWnd(); 3853 HIMC hIMC = ImmGetContext(hwnd); 3854 DASSERT(hIMC!=0); 3855 3856 textInfor = new AwtInputTextInfor; 3857 textInfor->GetContextData(hIMC, flags); 3858 ImmReleaseContext(hwnd, hIMC); 3859 3860 jstring jtextString = textInfor->GetText(); 3861 /* The conditions to send the input method event to AWT EDT are: 3862 1. Whenever there is a composition message sent regarding whether 3863 the composition text is NULL or not. See details at bug 6222692. 3864 2. When there is a committed message sent, in which case, we have to 3865 check whether the committed string is NULL or not. If the committed string 3866 is NULL, there is no need to send any input method event. 3867 (Minor note: 'jtextString' returned is the merged string in the case of 3868 partial commit.) 3869 */ 3870 if ((flags & GCS_RESULTSTR && jtextString != NULL) || 3871 (flags & GCS_COMPSTR)) { 3872 int cursorPosW = textInfor->GetCursorPosition(); 3873 // In order not to delete the readingClauseW in the catch clause, 3874 // calling GetAttributeInfor before GetClauseInfor. 3875 int cAttrW = textInfor->GetAttributeInfor(bndAttrW, valAttrW); 3876 cClauseW = textInfor->GetClauseInfor(bndClauseW, readingClauseW); 3877 3878 /* Send INPUT_METHOD_TEXT_CHANGED event to the WInputMethod which in turn sends 3879 the event to AWT EDT. 3880 3881 The last two paremeters are set to equal since we don't have recommendations for 3882 the visible position within the current composed text. See details at 3883 java.awt.event.InputMethodEvent. 3884 */ 3885 SendInputMethodEvent(java_awt_event_InputMethodEvent_INPUT_METHOD_TEXT_CHANGED, 3886 jtextString, 3887 cClauseW, bndClauseW, readingClauseW, 3888 cAttrW, bndAttrW, valAttrW, 3889 textInfor->GetCommittedTextLength(), 3890 cursorPosW, cursorPosW); 3891 } 3892 } catch (...) { 3893 // since GetClauseInfor and GetAttributeInfor could throw exception, we have to release 3894 // the pointer here. 3895 delete [] bndClauseW; 3896 delete [] readingClauseW; 3897 delete [] bndAttrW; 3898 delete [] valAttrW; 3899 throw; 3900 } 3901 3902 /* Free the storage allocated. Since jtextString won't be passed from threads 3903 * to threads, we just use the local ref and it will be deleted within the destructor 3904 * of AwtInputTextInfor object. 3905 */ 3906 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3907 if (cClauseW && readingClauseW) { 3908 for (int i = 0; i < cClauseW; i ++) { 3909 if (readingClauseW[i]) { 3910 env->DeleteLocalRef(readingClauseW[i]); 3911 } 3912 } 3913 } 3914 delete [] bndClauseW; 3915 delete [] readingClauseW; 3916 delete [] bndAttrW; 3917 delete [] valAttrW; 3918 delete textInfor; 3919 3920 return mrConsume; 3921 } 3922 3923 // 3924 // generate and post InputMethodEvent 3925 // 3926 void AwtComponent::SendInputMethodEvent(jint id, jstring text, 3927 int cClause, int* rgClauseBoundary, jstring* rgClauseReading, 3928 int cAttrBlock, int* rgAttrBoundary, BYTE *rgAttrValue, 3929 int commitedTextLength, int caretPos, int visiblePos) 3930 { 3931 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 3932 3933 // assumption for array type casting 3934 DASSERT(sizeof(int)==sizeof(jint)); 3935 DASSERT(sizeof(BYTE)==sizeof(jbyte)); 3936 3937 // caluse information 3938 jintArray clauseBoundary = NULL; 3939 jobjectArray clauseReading = NULL; 3940 if (cClause && rgClauseBoundary && rgClauseReading) { 3941 // convert clause boundary offset array to java array 3942 clauseBoundary = env->NewIntArray(cClause+1); 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 clauseReading = env->NewObjectArray(cClause, JNU_ClassString(env), NULL); 3948 for (int i=0; i<cClause; i++) env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]); 3949 DASSERT(!safe_ExceptionOccurred(env)); 3950 } 3951 3952 3953 // attrubute value definition in WInputMethod.java must be equal to that in IMM.H 3954 DASSERT(ATTR_INPUT==sun_awt_windows_WInputMethod_ATTR_INPUT); 3955 DASSERT(ATTR_TARGET_CONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_CONVERTED); 3956 DASSERT(ATTR_CONVERTED==sun_awt_windows_WInputMethod_ATTR_CONVERTED); 3957 DASSERT(ATTR_TARGET_NOTCONVERTED==sun_awt_windows_WInputMethod_ATTR_TARGET_NOTCONVERTED); 3958 DASSERT(ATTR_INPUT_ERROR==sun_awt_windows_WInputMethod_ATTR_INPUT_ERROR); 3959 3960 // attribute information 3961 jintArray attrBoundary = NULL; 3962 jbyteArray attrValue = NULL; 3963 if (cAttrBlock && rgAttrBoundary && rgAttrValue) { 3964 // convert attribute boundary offset array to java array 3965 attrBoundary = env->NewIntArray(cAttrBlock+1); 3966 env->SetIntArrayRegion(attrBoundary, 0, cAttrBlock+1, (jint *)rgAttrBoundary); 3967 DASSERT(!safe_ExceptionOccurred(env)); 3968 3969 // convert attribute value byte array to java array 3970 attrValue = env->NewByteArray(cAttrBlock); 3971 env->SetByteArrayRegion(attrValue, 0, cAttrBlock, (jbyte *)rgAttrValue); 3972 DASSERT(!safe_ExceptionOccurred(env)); 3973 } 3974 3975 3976 // get global reference of WInputMethod class (run only once) 3977 static jclass wInputMethodCls = NULL; 3978 if (wInputMethodCls == NULL) { 3979 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 3980 DASSERT(wInputMethodClsLocal); 3981 if (wInputMethodClsLocal == NULL) { 3982 /* exception already thrown */ 3983 return; 3984 } 3985 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 3986 env->DeleteLocalRef(wInputMethodClsLocal); 3987 } 3988 3989 // get method ID of sendInputMethodEvent() (run only once) 3990 static jmethodID sendIMEventMid = 0; 3991 if (sendIMEventMid == 0) { 3992 sendIMEventMid = env->GetMethodID(wInputMethodCls, "sendInputMethodEvent", 3993 "(IJLjava/lang/String;[I[Ljava/lang/String;[I[BIII)V"); 3994 DASSERT(sendIMEventMid); 3995 } 3996 3997 // call m_InputMethod.sendInputMethod() 3998 env->CallVoidMethod(m_InputMethod, sendIMEventMid, id, TimeHelper::getMessageTimeUTC(), 3999 text, clauseBoundary, clauseReading, attrBoundary, 4000 attrValue, commitedTextLength, caretPos, visiblePos); 4001 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4002 DASSERT(!safe_ExceptionOccurred(env)); 4003 4004 } 4005 4006 4007 4008 // 4009 // Inquires candidate position according to the composed text 4010 // 4011 void AwtComponent::InquireCandidatePosition() 4012 { 4013 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4014 4015 // get global reference of WInputMethod class (run only once) 4016 static jclass wInputMethodCls = NULL; 4017 if (wInputMethodCls == NULL) { 4018 jclass wInputMethodClsLocal = env->FindClass("sun/awt/windows/WInputMethod"); 4019 DASSERT(wInputMethodClsLocal); 4020 if (wInputMethodClsLocal == NULL) { 4021 /* exception already thrown */ 4022 return; 4023 } 4024 wInputMethodCls = (jclass)env->NewGlobalRef(wInputMethodClsLocal); 4025 env->DeleteLocalRef(wInputMethodClsLocal); 4026 } 4027 4028 // get method ID of sendInputMethodEvent() (run only once) 4029 static jmethodID inqCandPosMid = 0; 4030 if (inqCandPosMid == 0) { 4031 inqCandPosMid = env->GetMethodID(wInputMethodCls, "inquireCandidatePosition", 4032 "()V"); 4033 DASSERT(!safe_ExceptionOccurred(env)); 4034 DASSERT(inqCandPosMid); 4035 } 4036 4037 // call m_InputMethod.sendInputMethod() 4038 jobject candPos = env->CallObjectMethod(m_InputMethod, inqCandPosMid); 4039 DASSERT(!safe_ExceptionOccurred(env)); 4040 } 4041 4042 HWND AwtComponent::ImmGetHWnd() 4043 { 4044 HWND proxy = GetProxyFocusOwner(); 4045 return (proxy != NULL) ? proxy : GetHWnd(); 4046 } 4047 4048 HIMC AwtComponent::ImmAssociateContext(HIMC himc) 4049 { 4050 return ::ImmAssociateContext(ImmGetHWnd(), himc); 4051 } 4052 4053 HWND AwtComponent::GetProxyFocusOwner() 4054 { 4055 AwtWindow *window = GetContainer(); 4056 if (window != 0) { 4057 AwtFrame *owner = window->GetOwningFrameOrDialog(); 4058 if (owner != 0) { 4059 return owner->GetProxyFocusOwner(); 4060 } else if (!window->IsSimpleWindow()) { // isn't an owned simple window 4061 return ((AwtFrame*)window)->GetProxyFocusOwner(); 4062 } 4063 } 4064 return (HWND)NULL; 4065 } 4066 4067 /* Call DefWindowProc for the focus proxy, if any */ 4068 void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam, 4069 LPARAM lParam, LRESULT &retVal, MsgRouting &mr) 4070 { 4071 if (mr != mrConsume) { 4072 HWND proxy = GetProxyFocusOwner(); 4073 if (proxy != NULL) { 4074 retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam); 4075 mr = mrConsume; 4076 } 4077 } 4078 } 4079 4080 MsgRouting AwtComponent::WmCommand(UINT id, HWND hWndChild, UINT notifyCode) 4081 { 4082 /* Menu/Accelerator */ 4083 if (hWndChild == 0) { 4084 AwtObject* obj = AwtToolkit::GetInstance().LookupCmdID(id); 4085 if (obj == NULL) { 4086 return mrConsume; 4087 } 4088 DASSERT(((AwtMenuItem*)obj)->GetID() == id); 4089 obj->DoCommand(); 4090 return mrConsume; 4091 } 4092 /* Child id notification */ 4093 else { 4094 AwtComponent* child = AwtComponent::GetComponent(hWndChild); 4095 if (child) { 4096 child->WmNotify(notifyCode); 4097 } 4098 } 4099 return mrDoDefault; 4100 } 4101 4102 MsgRouting AwtComponent::WmNotify(UINT notifyCode) 4103 { 4104 return mrDoDefault; 4105 } 4106 4107 MsgRouting AwtComponent::WmCompareItem(UINT ctrlId, 4108 COMPAREITEMSTRUCT &compareInfo, 4109 LRESULT &result) 4110 { 4111 AwtComponent* child = AwtComponent::GetComponent(compareInfo.hwndItem); 4112 if (child == this) { 4113 /* DoCallback("handleItemDelete", */ 4114 } 4115 else if (child) { 4116 return child->WmCompareItem(ctrlId, compareInfo, result); 4117 } 4118 return mrConsume; 4119 } 4120 4121 MsgRouting AwtComponent::WmDeleteItem(UINT ctrlId, 4122 DELETEITEMSTRUCT &deleteInfo) 4123 { 4124 /* 4125 * Workaround for NT 4.0 bug -- if SetWindowPos is called on a AwtList 4126 * window, a WM_DELETEITEM message is sent to its parent with a window 4127 * handle of one of the list's child windows. The property lookup 4128 * succeeds, but the HWNDs don't match. 4129 */ 4130 if (deleteInfo.hwndItem == NULL) { 4131 return mrConsume; 4132 } 4133 AwtComponent* child = (AwtComponent *)AwtComponent::GetComponent(deleteInfo.hwndItem); 4134 4135 if (child && child->GetHWnd() != deleteInfo.hwndItem) { 4136 return mrConsume; 4137 } 4138 4139 if (child == this) { 4140 /*DoCallback("handleItemDelete", */ 4141 } 4142 else if (child) { 4143 return child->WmDeleteItem(ctrlId, deleteInfo); 4144 } 4145 return mrConsume; 4146 } 4147 4148 MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo) 4149 { 4150 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4151 4152 if (drawInfo.CtlType == ODT_MENU) { 4153 if (drawInfo.itemData != 0) { 4154 AwtMenu* menu = (AwtMenu*)(drawInfo.itemData); 4155 menu->DrawItem(drawInfo); 4156 } 4157 } else { 4158 return OwnerDrawItem(ctrlId, drawInfo); 4159 } 4160 return mrConsume; 4161 } 4162 4163 MsgRouting AwtComponent::WmMeasureItem(UINT ctrlId, 4164 MEASUREITEMSTRUCT &measureInfo) 4165 { 4166 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4167 4168 if (measureInfo.CtlType == ODT_MENU) { 4169 if (measureInfo.itemData != 0) { 4170 AwtMenu* menu = (AwtMenu*)(measureInfo.itemData); 4171 HDC hDC = ::GetDC(GetHWnd()); 4172 /* menu->MeasureItem(env, hDC, measureInfo); */ 4173 menu->MeasureItem(hDC, measureInfo); 4174 ::ReleaseDC(GetHWnd(), hDC); 4175 } 4176 } else { 4177 return OwnerMeasureItem(ctrlId, measureInfo); 4178 } 4179 return mrConsume; 4180 } 4181 4182 MsgRouting AwtComponent::OwnerDrawItem(UINT ctrlId, 4183 DRAWITEMSTRUCT &drawInfo) 4184 { 4185 AwtComponent* child = AwtComponent::GetComponent(drawInfo.hwndItem); 4186 if (child == this) { 4187 /* DoCallback("handleItemDelete", */ 4188 } else if (child != NULL) { 4189 return child->WmDrawItem(ctrlId, drawInfo); 4190 } 4191 return mrConsume; 4192 } 4193 4194 MsgRouting AwtComponent::OwnerMeasureItem(UINT ctrlId, 4195 MEASUREITEMSTRUCT &measureInfo) 4196 { 4197 HWND hChild = ::GetDlgItem(GetHWnd(), measureInfo.CtlID); 4198 AwtComponent* child = AwtComponent::GetComponent(hChild); 4199 /* 4200 * If the parent cannot find the child's instance from its handle, 4201 * maybe the child is in its creation. So the child must be searched 4202 * from the list linked before the child's creation. 4203 */ 4204 if (child == NULL) { 4205 child = SearchChild((UINT)ctrlId); 4206 } 4207 4208 if (child == this) { 4209 /* DoCallback("handleItemDelete", */ 4210 } 4211 else if (child) { 4212 return child->WmMeasureItem(ctrlId, measureInfo); 4213 } 4214 return mrConsume; 4215 } 4216 4217 /* for WmDrawItem method of Label, Button and Checkbox */ 4218 void AwtComponent::DrawWindowText(HDC hDC, jobject font, jstring text, 4219 int x, int y) 4220 { 4221 int nOldBkMode = ::SetBkMode(hDC,TRANSPARENT); 4222 DASSERT(nOldBkMode != 0); 4223 AwtFont::drawMFString(hDC, font, text, x, y, GetCodePage()); 4224 VERIFY(::SetBkMode(hDC,nOldBkMode)); 4225 } 4226 4227 /* 4228 * Draw text in gray (the color being set to COLOR_GRAYTEXT) when the 4229 * component is disabled. Used only for label, checkbox and button in 4230 * OWNER_DRAW. It draws the text in emboss. 4231 */ 4232 void AwtComponent::DrawGrayText(HDC hDC, jobject font, jstring text, 4233 int x, int y) 4234 { 4235 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNHILIGHT)); 4236 AwtComponent::DrawWindowText(hDC, font, text, x+1, y+1); 4237 ::SetTextColor(hDC, ::GetSysColor(COLOR_BTNSHADOW)); 4238 AwtComponent::DrawWindowText(hDC, font, text, x, y); 4239 } 4240 4241 /* for WmMeasureItem method of List and Choice */ 4242 jstring AwtComponent::GetItemString(JNIEnv *env, jobject target, jint index) 4243 { 4244 jstring str = (jstring)JNU_CallMethodByName(env, NULL, target, "getItemImpl", 4245 "(I)Ljava/lang/String;", 4246 index).l; 4247 DASSERT(!safe_ExceptionOccurred(env)); 4248 return str; 4249 } 4250 4251 /* for WmMeasureItem method of List and Choice */ 4252 void AwtComponent::MeasureListItem(JNIEnv *env, 4253 MEASUREITEMSTRUCT &measureInfo) 4254 { 4255 if (env->EnsureLocalCapacity(1) < 0) { 4256 return; 4257 } 4258 jobject dimension = PreferredItemSize(env); 4259 DASSERT(dimension); 4260 measureInfo.itemWidth = 4261 env->GetIntField(dimension, AwtDimension::widthID); 4262 measureInfo.itemHeight = 4263 env->GetIntField(dimension, AwtDimension::heightID); 4264 env->DeleteLocalRef(dimension); 4265 } 4266 4267 /* for WmDrawItem method of List and Choice */ 4268 void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) 4269 { 4270 if (env->EnsureLocalCapacity(3) < 0) { 4271 return; 4272 } 4273 jobject peer = GetPeer(env); 4274 jobject target = env->GetObjectField(peer, AwtObject::targetID); 4275 4276 HDC hDC = drawInfo.hDC; 4277 RECT rect = drawInfo.rcItem; 4278 4279 BOOL bEnabled = isEnabled(); 4280 BOOL unfocusableChoice = (drawInfo.itemState & ODS_COMBOBOXEDIT) && !IsFocusable(); 4281 DWORD crBack, crText; 4282 if (drawInfo.itemState & ODS_SELECTED){ 4283 /* Set background and text colors for selected item */ 4284 crBack = ::GetSysColor (COLOR_HIGHLIGHT); 4285 crText = ::GetSysColor (COLOR_HIGHLIGHTTEXT); 4286 } else { 4287 /* Set background and text colors for unselected item */ 4288 crBack = GetBackgroundColor(); 4289 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4290 } 4291 if (unfocusableChoice) { 4292 //6190728. Shouldn't draw selection field (edit control) of an owner-drawn combo box. 4293 crBack = GetBackgroundColor(); 4294 crText = bEnabled ? GetColor() : ::GetSysColor(COLOR_GRAYTEXT); 4295 } 4296 4297 /* Fill item rectangle with background color */ 4298 HBRUSH hbrBack = ::CreateSolidBrush (crBack); 4299 DASSERT(hbrBack); 4300 /* 6190728. Shouldn't draw any kind of rectangle around selection field 4301 * (edit control) of an owner-drawn combo box while unfocusable 4302 */ 4303 if (!unfocusableChoice){ 4304 VERIFY(::FillRect (hDC, &rect, hbrBack)); 4305 } 4306 VERIFY(::DeleteObject (hbrBack)); 4307 4308 /* Set current background and text colors */ 4309 ::SetBkColor (hDC, crBack); 4310 ::SetTextColor (hDC, crText); 4311 4312 /*draw string (with left margin of 1 point) */ 4313 if ((int) (drawInfo.itemID) >= 0) { 4314 jobject font = GET_FONT(target, peer); 4315 jstring text = GetItemString(env, target, drawInfo.itemID); 4316 SIZE size = AwtFont::getMFStringSize(hDC, font, text); 4317 AwtFont::drawMFString(hDC, font, text, 4318 (GetRTL()) ? rect.right - size.cx - 1 4319 : rect.left + 1, 4320 (rect.top + rect.bottom - size.cy) / 2, 4321 GetCodePage()); 4322 env->DeleteLocalRef(font); 4323 env->DeleteLocalRef(text); 4324 } 4325 if ((drawInfo.itemState & ODS_FOCUS) && 4326 (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { 4327 if (!unfocusableChoice){ 4328 VERIFY(::DrawFocusRect(hDC, &rect)); 4329 } 4330 } 4331 env->DeleteLocalRef(target); 4332 } 4333 4334 /* for MeasureListItem method and WmDrawItem method of Checkbox */ 4335 jint AwtComponent::GetFontHeight(JNIEnv *env) 4336 { 4337 if (env->EnsureLocalCapacity(4) < 0) { 4338 return NULL; 4339 } 4340 jobject self = GetPeer(env); 4341 jobject target = env->GetObjectField(self, AwtObject::targetID); 4342 4343 jobject font = GET_FONT(target, self); 4344 jobject toolkit = env->CallObjectMethod(target, 4345 AwtComponent::getToolkitMID); 4346 4347 DASSERT(!safe_ExceptionOccurred(env)); 4348 4349 jobject fontMetrics = 4350 env->CallObjectMethod(toolkit, AwtToolkit::getFontMetricsMID, font); 4351 4352 DASSERT(!safe_ExceptionOccurred(env)); 4353 4354 jint height = env->CallIntMethod(fontMetrics, AwtFont::getHeightMID); 4355 DASSERT(!safe_ExceptionOccurred(env)); 4356 4357 env->DeleteLocalRef(target); 4358 env->DeleteLocalRef(font); 4359 env->DeleteLocalRef(toolkit); 4360 env->DeleteLocalRef(fontMetrics); 4361 4362 return height; 4363 } 4364 4365 // If you override WmPrint, make sure to save a copy of the DC on the GDI 4366 // stack to be restored in WmPrintClient. Windows mangles the DC in 4367 // ::DefWindowProc. 4368 MsgRouting AwtComponent::WmPrint(HDC hDC, LPARAM flags) 4369 { 4370 /* 4371 * DefWindowProc for WM_PRINT changes DC parameters, so we have 4372 * to restore it ourselves. Otherwise it will cause problems 4373 * when several components are printed to the same DC. 4374 */ 4375 int nOriginalDC = ::SaveDC(hDC); 4376 DASSERT(nOriginalDC != 0); 4377 4378 if (flags & PRF_NONCLIENT) { 4379 4380 VERIFY(::SaveDC(hDC)); 4381 4382 DefWindowProc(WM_PRINT, (WPARAM)hDC, 4383 (flags & (PRF_NONCLIENT 4384 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4385 4386 VERIFY(::RestoreDC(hDC, -1)); 4387 4388 // Special case for components with a sunken border. Windows does not 4389 // print the border correctly on PCL printers, so we have to do it ourselves. 4390 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4391 RECT r; 4392 VERIFY(::GetWindowRect(GetHWnd(), &r)); 4393 VERIFY(::OffsetRect(&r, -r.left, -r.top)); 4394 VERIFY(::DrawEdge(hDC, &r, EDGE_SUNKEN, BF_RECT)); 4395 } 4396 } 4397 4398 if (flags & PRF_CLIENT) { 4399 4400 /* 4401 * Special case for components with a sunken border. 4402 * Windows prints a client area without offset to a border width. 4403 * We will first print the non-client area with the original offset, 4404 * then the client area with a corrected offset. 4405 */ 4406 if (GetStyleEx() & WS_EX_CLIENTEDGE) { 4407 4408 int nEdgeWidth = ::GetSystemMetrics(SM_CXEDGE); 4409 int nEdgeHeight = ::GetSystemMetrics(SM_CYEDGE); 4410 4411 VERIFY(::OffsetWindowOrgEx(hDC, -nEdgeWidth, -nEdgeHeight, NULL)); 4412 4413 // Save a copy of the DC for WmPrintClient 4414 VERIFY(::SaveDC(hDC)); 4415 4416 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4417 (flags & (PRF_CLIENT 4418 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4419 4420 VERIFY(::OffsetWindowOrgEx(hDC, nEdgeWidth, nEdgeHeight, NULL)); 4421 4422 } else { 4423 4424 // Save a copy of the DC for WmPrintClient 4425 VERIFY(::SaveDC(hDC)); 4426 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4427 (flags & (PRF_CLIENT 4428 | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); 4429 } 4430 } 4431 4432 if (flags & (PRF_CHILDREN | PRF_OWNED)) { 4433 DefWindowProc(WM_PRINT, (WPARAM) hDC, 4434 (flags & ~PRF_CLIENT & ~PRF_NONCLIENT)); 4435 } 4436 4437 VERIFY(::RestoreDC(hDC, nOriginalDC)); 4438 4439 return mrConsume; 4440 } 4441 4442 // If you override WmPrintClient, make sure to obtain a valid copy of 4443 // the DC from the GDI stack. The copy of the DC should have been placed 4444 // there by WmPrint. Windows mangles the DC in ::DefWindowProc. 4445 MsgRouting AwtComponent::WmPrintClient(HDC hDC, LPARAM) 4446 { 4447 // obtain valid DC from GDI stack 4448 ::RestoreDC(hDC, -1); 4449 4450 return mrDoDefault; 4451 } 4452 4453 MsgRouting AwtComponent::WmNcCalcSize(BOOL fCalcValidRects, 4454 LPNCCALCSIZE_PARAMS lpncsp, 4455 LRESULT &retVal) 4456 { 4457 return mrDoDefault; 4458 } 4459 4460 MsgRouting AwtComponent::WmNcPaint(HRGN hrgn) 4461 { 4462 return mrDoDefault; 4463 } 4464 4465 MsgRouting AwtComponent::WmNcHitTest(UINT x, UINT y, LRESULT &retVal) 4466 { 4467 return mrDoDefault; 4468 } 4469 4470 /** 4471 * WmQueryNewPalette is called whenever our component is coming to 4472 * the foreground; this gives us an opportunity to install our 4473 * custom palette. If this install actually changes entries in 4474 * the system palette, then we get a further call to WmPaletteChanged 4475 * (but note that we only need to realize our palette once). 4476 */ 4477 MsgRouting AwtComponent::WmQueryNewPalette(LRESULT &retVal) 4478 { 4479 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4480 m_QueryNewPaletteCalled = TRUE; 4481 HDC hDC = ::GetDC(GetHWnd()); 4482 DASSERT(hDC); 4483 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4484 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4485 ::ReleaseDC(GetHWnd(), hDC); 4486 // We must realize the palettes of all of our DC's 4487 // There is sometimes a problem where the realization of 4488 // our temporary hDC here does not actually do what 4489 // we want. Not clear why, but presumably fallout from 4490 // our use of several simultaneous hDC's. 4491 activeDCList.RealizePalettes(screen); 4492 // Do not invalidate here; if the palette 4493 // has not changed we will get an extra repaint 4494 retVal = TRUE; 4495 4496 return mrDoDefault; 4497 } 4498 4499 /** 4500 * We should not need to track this event since we handle our 4501 * palette management effectively in the WmQueryNewPalette and 4502 * WmPaletteChanged methods. However, there seems to be a bug 4503 * on some win32 systems (e.g., NT4) whereby the palette 4504 * immediately after a displayChange is not yet updated to its 4505 * final post-display-change values (hence we adjust our palette 4506 * using the wrong system palette entries), then the palette is 4507 * updated, but a WM_PALETTECHANGED message is never sent. 4508 * By tracking the ISCHANGING message as well (and by tracking 4509 * displayChange events in the AwtToolkit object), we can account 4510 * for this error by forcing our WmPaletteChanged method to be 4511 * called and thereby realizing our logical palette and updating 4512 * our dynamic colorModel object. 4513 */ 4514 MsgRouting AwtComponent::WmPaletteIsChanging(HWND hwndPalChg) 4515 { 4516 if (AwtToolkit::GetInstance().HasDisplayChanged()) { 4517 WmPaletteChanged(hwndPalChg); 4518 AwtToolkit::GetInstance().ResetDisplayChanged(); 4519 } 4520 return mrDoDefault; 4521 } 4522 4523 MsgRouting AwtComponent::WmPaletteChanged(HWND hwndPalChg) 4524 { 4525 // We need to re-realize our palette here (unless we're the one 4526 // that was realizing it in the first place). That will let us match the 4527 // remaining colors in the system palette as best we can. We always 4528 // invalidate because the palette will have changed when we receive this 4529 // message. 4530 4531 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 4532 if (hwndPalChg != GetHWnd()) { 4533 HDC hDC = ::GetDC(GetHWnd()); 4534 DASSERT(hDC); 4535 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 4536 AwtWin32GraphicsDevice::RealizePalette(hDC, screen); 4537 ::ReleaseDC(GetHWnd(), hDC); 4538 // We must realize the palettes of all of our DC's 4539 activeDCList.RealizePalettes(screen); 4540 } 4541 if (AwtWin32GraphicsDevice::UpdateSystemPalette(screen)) { 4542 AwtWin32GraphicsDevice::UpdateDynamicColorModel(screen); 4543 } 4544 Invalidate(NULL); 4545 return mrDoDefault; 4546 } 4547 4548 MsgRouting AwtComponent::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 4549 { 4550 DASSERT(!IsBadReadPtr(lpss, sizeof(STYLESTRUCT))); 4551 return mrDoDefault; 4552 } 4553 4554 MsgRouting AwtComponent::WmSettingChange(UINT wFlag, LPCTSTR pszSection) 4555 { 4556 DASSERT(!IsBadStringPtr(pszSection, 20)); 4557 DTRACE_PRINTLN2("WM_SETTINGCHANGE: wFlag=%d pszSection=%s", (int)wFlag, pszSection); 4558 return mrDoDefault; 4559 } 4560 4561 HDC AwtComponent::GetDCFromComponent() 4562 { 4563 GetDCReturnStruct *hdcStruct = 4564 (GetDCReturnStruct*)SendMessage(WM_AWT_GETDC); 4565 HDC hdc; 4566 if (hdcStruct) { 4567 if (hdcStruct->gdiLimitReached) { 4568 if (jvm != NULL) { 4569 JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4570 if (env != NULL && !safe_ExceptionOccurred(env)) { 4571 JNU_ThrowByName(env, "java/awt/AWTError", 4572 "HDC creation failure - " \ 4573 "exceeded maximum GDI resources"); 4574 } 4575 } 4576 } 4577 hdc = hdcStruct->hDC; 4578 delete hdcStruct; 4579 } else { 4580 hdc = NULL; 4581 } 4582 return hdc; 4583 } 4584 4585 void AwtComponent::FillBackground(HDC hMemoryDC, SIZE &size) 4586 { 4587 RECT eraseR = { 0, 0, size.cx, size.cy }; 4588 VERIFY(::FillRect(hMemoryDC, &eraseR, GetBackgroundBrush())); 4589 } 4590 4591 void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha) 4592 { 4593 if (!bitmapBits) { 4594 return; 4595 } 4596 4597 DWORD* dest = (DWORD*)bitmapBits; 4598 //XXX: might be optimized to use one loop (cy*cx -> 0) 4599 for (int i = 0; i < size.cy; i++ ) { 4600 for (int j = 0; j < size.cx; j++ ) { 4601 ((BYTE*)(dest++))[3] = alpha; 4602 } 4603 } 4604 } 4605 4606 jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) { 4607 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4608 4609 if (!::IsWindowVisible(GetHWnd())) { 4610 return NULL; 4611 } 4612 4613 HDC hdc = GetDCFromComponent(); 4614 if (!hdc) { 4615 return NULL; 4616 } 4617 HDC hMemoryDC = ::CreateCompatibleDC(hdc); 4618 void *bitmapBits = NULL; 4619 HBITMAP hBitmap = BitmapUtil::CreateARGBBitmap(size.cx, size.cy, &bitmapBits); 4620 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemoryDC, hBitmap); 4621 SendMessage(WM_AWT_RELEASEDC, (WPARAM)hdc); 4622 4623 FillBackground(hMemoryDC, size); 4624 4625 VERIFY(::SetWindowOrgEx(hMemoryDC, loc.cx, loc.cy, NULL)); 4626 4627 // Don't bother with PRF_CHECKVISIBLE because we called IsWindowVisible 4628 // above. 4629 SendMessage(WM_PRINT, (WPARAM)hMemoryDC, PRF_CLIENT | PRF_NONCLIENT); 4630 4631 // First make sure the system completed any drawing to the bitmap. 4632 ::GdiFlush(); 4633 4634 // WM_PRINT does not fill the alpha-channel of the ARGB bitmap 4635 // leaving it equal to zero. Hence we need to fill it manually. Otherwise 4636 // the pixels will be considered transparent when interpreting the data. 4637 FillAlpha(bitmapBits, size, alpha); 4638 4639 ::SelectObject(hMemoryDC, hOldBitmap); 4640 4641 BITMAPINFO bmi; 4642 memset(&bmi, 0, sizeof(BITMAPINFO)); 4643 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 4644 bmi.bmiHeader.biWidth = size.cx; 4645 bmi.bmiHeader.biHeight = -size.cy; 4646 bmi.bmiHeader.biPlanes = 1; 4647 bmi.bmiHeader.biBitCount = 32; 4648 bmi.bmiHeader.biCompression = BI_RGB; 4649 4650 jobject localPixelArray = env->NewIntArray(size.cx * size.cy); 4651 jintArray pixelArray = NULL; 4652 if (localPixelArray != NULL) { 4653 pixelArray = (jintArray)env->NewGlobalRef(localPixelArray); 4654 env->DeleteLocalRef(localPixelArray); localPixelArray = NULL; 4655 4656 jboolean isCopy; 4657 jint *pixels = env->GetIntArrayElements(pixelArray, &isCopy); 4658 4659 ::GetDIBits(hMemoryDC, hBitmap, 0, size.cy, (LPVOID)pixels, &bmi, 4660 DIB_RGB_COLORS); 4661 4662 env->ReleaseIntArrayElements(pixelArray, pixels, 0); 4663 } 4664 4665 VERIFY(::DeleteObject(hBitmap)); 4666 VERIFY(::DeleteDC(hMemoryDC)); 4667 4668 return pixelArray; 4669 } 4670 4671 void* AwtComponent::SetNativeFocusOwner(void *self) { 4672 if (self == NULL) { 4673 // It means that the KFM wants to set focus to null 4674 sm_focusOwner = NULL; 4675 return NULL; 4676 } 4677 4678 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4679 4680 AwtComponent *c = NULL; 4681 jobject peer = (jobject)self; 4682 4683 PDATA pData; 4684 JNI_CHECK_NULL_GOTO(peer, "peer", ret); 4685 pData = JNI_GET_PDATA(peer); 4686 if (pData == NULL) { 4687 goto ret; 4688 } 4689 c = (AwtComponent *)pData; 4690 4691 ret: 4692 if (c && ::IsWindow(c->GetHWnd())) { 4693 sm_focusOwner = c->GetHWnd(); 4694 } else { 4695 sm_focusOwner = NULL; 4696 } 4697 env->DeleteGlobalRef(peer); 4698 return NULL; 4699 } 4700 4701 void* AwtComponent::GetNativeFocusedWindow() { 4702 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4703 AwtComponent *comp = 4704 AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 4705 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4706 } 4707 4708 void* AwtComponent::GetNativeFocusOwner() { 4709 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4710 AwtComponent *comp = 4711 AwtComponent::GetComponent(AwtComponent::sm_focusOwner); 4712 return (comp != NULL) ? comp->GetTargetAsGlobalRef(env) : NULL; 4713 } 4714 4715 AwtComponent* AwtComponent::SearchChild(UINT id) { 4716 ChildListItem* child; 4717 for (child = m_childList; child != NULL;child = child->m_next) { 4718 if (child->m_ID == id) 4719 return child->m_Component; 4720 } 4721 /* 4722 * DASSERT(FALSE); 4723 * This should not be happend if all children are recorded 4724 */ 4725 return NULL; /* make compiler happy */ 4726 } 4727 4728 void AwtComponent::RemoveChild(UINT id) { 4729 ChildListItem* child = m_childList; 4730 ChildListItem* lastChild = NULL; 4731 while (child != NULL) { 4732 if (child->m_ID == id) { 4733 if (lastChild == NULL) { 4734 m_childList = child->m_next; 4735 } else { 4736 lastChild->m_next = child->m_next; 4737 } 4738 child->m_next = NULL; 4739 DASSERT(child != NULL); 4740 delete child; 4741 return; 4742 } 4743 lastChild = child; 4744 child = child->m_next; 4745 } 4746 } 4747 4748 void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked, 4749 jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg) 4750 { 4751 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4752 CriticalSection::Lock l(GetLock()); 4753 if (GetPeer(env) == NULL) { 4754 /* event received during termination. */ 4755 return; 4756 } 4757 4758 static jclass keyEventCls; 4759 if (keyEventCls == NULL) { 4760 jclass keyEventClsLocal = env->FindClass("java/awt/event/KeyEvent"); 4761 DASSERT(keyEventClsLocal); 4762 if (keyEventClsLocal == NULL) { 4763 /* exception already thrown */ 4764 return; 4765 } 4766 keyEventCls = (jclass)env->NewGlobalRef(keyEventClsLocal); 4767 env->DeleteLocalRef(keyEventClsLocal); 4768 } 4769 4770 static jmethodID keyEventConst; 4771 if (keyEventConst == NULL) { 4772 keyEventConst = env->GetMethodID(keyEventCls, "<init>", 4773 "(Ljava/awt/Component;IJIICI)V"); 4774 DASSERT(keyEventConst); 4775 } 4776 if (env->EnsureLocalCapacity(2) < 0) { 4777 return; 4778 } 4779 jobject target = GetTarget(env); 4780 jobject keyEvent = env->NewObject(keyEventCls, keyEventConst, target, 4781 id, when, modifiers, raw, cooked, 4782 keyLocation); 4783 if (safe_ExceptionOccurred(env)) env->ExceptionDescribe(); 4784 DASSERT(!safe_ExceptionOccurred(env)); 4785 DASSERT(keyEvent != NULL); 4786 env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode); 4787 if( nativeCode && nativeCode < 256 ) { 4788 env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode)); 4789 env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey)); 4790 if( nativeCode < 255 ) { 4791 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode)); 4792 }else if( pMsg != NULL ) { 4793 // unknown key with virtual keycode 0xFF. 4794 // Its scancode is not in the table, pickup it from the message. 4795 env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF)); 4796 } 4797 } 4798 if (pMsg != NULL) { 4799 AwtAWTEvent::saveMSG(env, pMsg, keyEvent); 4800 } 4801 SendEvent(keyEvent); 4802 4803 env->DeleteLocalRef(keyEvent); 4804 env->DeleteLocalRef(target); 4805 } 4806 4807 void 4808 AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when, 4809 jint raw, jint cooked, 4810 jint modifiers, jint keyLocation, 4811 jlong nativeCode, 4812 MSG *msg) 4813 { 4814 /* 4815 * if focus owner is null, but focused window isn't 4816 * we will send key event to focused window 4817 */ 4818 HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow()); 4819 4820 if (hwndTarget == GetHWnd()) { 4821 SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg); 4822 } else { 4823 AwtComponent *target = NULL; 4824 if (hwndTarget != NULL) { 4825 target = AwtComponent::GetComponent(hwndTarget); 4826 if (target == NULL) { 4827 target = this; 4828 } 4829 } 4830 if (target != NULL) { 4831 target->SendKeyEvent(id, when, raw, cooked, modifiers, 4832 keyLocation, nativeCode, msg); 4833 } 4834 } 4835 } 4836 4837 void AwtComponent::SetDragCapture(UINT flags) 4838 { 4839 // don't want to interfere with other controls 4840 if (::GetCapture() == NULL) { 4841 ::SetCapture(GetHWnd()); 4842 } 4843 } 4844 4845 void AwtComponent::ReleaseDragCapture(UINT flags) 4846 { 4847 if ((::GetCapture() == GetHWnd()) && ((flags & ALL_MK_BUTTONS) == 0)) { 4848 // user has released all buttons, so release the capture 4849 ::ReleaseCapture(); 4850 } 4851 } 4852 4853 void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y, 4854 jint modifiers, jint clickCount, 4855 jboolean popupTrigger, jint button, 4856 MSG *pMsg) 4857 { 4858 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4859 CriticalSection::Lock l(GetLock()); 4860 if (GetPeer(env) == NULL) { 4861 /* event received during termination. */ 4862 return; 4863 } 4864 4865 static jclass mouseEventCls; 4866 if (mouseEventCls == NULL) { 4867 jclass mouseEventClsLocal = 4868 env->FindClass("java/awt/event/MouseEvent"); 4869 if (!mouseEventClsLocal) { 4870 /* exception already thrown */ 4871 return; 4872 } 4873 mouseEventCls = (jclass)env->NewGlobalRef(mouseEventClsLocal); 4874 env->DeleteLocalRef(mouseEventClsLocal); 4875 } 4876 RECT insets; 4877 GetInsets(&insets); 4878 4879 static jmethodID mouseEventConst; 4880 if (mouseEventConst == NULL) { 4881 mouseEventConst = 4882 env->GetMethodID(mouseEventCls, "<init>", 4883 "(Ljava/awt/Component;IJIIIIIIZI)V"); 4884 DASSERT(mouseEventConst); 4885 } 4886 if (env->EnsureLocalCapacity(2) < 0) { 4887 return; 4888 } 4889 jobject target = GetTarget(env); 4890 DWORD curMousePos = ::GetMessagePos(); 4891 int xAbs = GET_X_LPARAM(curMousePos); 4892 int yAbs = GET_Y_LPARAM(curMousePos); 4893 jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst, 4894 target, 4895 id, when, modifiers, 4896 x+insets.left, y+insets.top, 4897 xAbs, yAbs, 4898 clickCount, popupTrigger, button); 4899 4900 if (safe_ExceptionOccurred(env)) { 4901 env->ExceptionDescribe(); 4902 env->ExceptionClear(); 4903 } 4904 4905 DASSERT(mouseEvent != NULL); 4906 if (pMsg != 0) { 4907 AwtAWTEvent::saveMSG(env, pMsg, mouseEvent); 4908 } 4909 SendEvent(mouseEvent); 4910 4911 env->DeleteLocalRef(mouseEvent); 4912 env->DeleteLocalRef(target); 4913 } 4914 4915 void 4916 AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, 4917 jint modifiers, jint clickCount, 4918 jboolean popupTrigger, jint scrollType, 4919 jint scrollAmount, jint roundedWheelRotation, 4920 jdouble preciseWheelRotation, MSG *pMsg) 4921 { 4922 /* Code based not so loosely on AwtComponent::SendMouseEvent */ 4923 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4924 CriticalSection::Lock l(GetLock()); 4925 if (GetPeer(env) == NULL) { 4926 /* event received during termination. */ 4927 return; 4928 } 4929 4930 static jclass mouseWheelEventCls; 4931 if (mouseWheelEventCls == NULL) { 4932 jclass mouseWheelEventClsLocal = 4933 env->FindClass("java/awt/event/MouseWheelEvent"); 4934 if (!mouseWheelEventClsLocal) { 4935 /* exception already thrown */ 4936 return; 4937 } 4938 mouseWheelEventCls = (jclass)env->NewGlobalRef(mouseWheelEventClsLocal); 4939 env->DeleteLocalRef(mouseWheelEventClsLocal); 4940 } 4941 RECT insets; 4942 GetInsets(&insets); 4943 4944 static jmethodID mouseWheelEventConst; 4945 if (mouseWheelEventConst == NULL) { 4946 mouseWheelEventConst = 4947 env->GetMethodID(mouseWheelEventCls, "<init>", 4948 "(Ljava/awt/Component;IJIIIIIIZIIID)V"); 4949 DASSERT(mouseWheelEventConst); 4950 } 4951 if (env->EnsureLocalCapacity(2) < 0) { 4952 return; 4953 } 4954 jobject target = GetTarget(env); 4955 DTRACE_PRINTLN("creating MWE in JNI"); 4956 4957 jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls, 4958 mouseWheelEventConst, 4959 target, 4960 id, when, modifiers, 4961 x+insets.left, y+insets.top, 4962 0, 0, 4963 clickCount, popupTrigger, 4964 scrollType, scrollAmount, 4965 roundedWheelRotation, preciseWheelRotation); 4966 if (safe_ExceptionOccurred(env)) { 4967 env->ExceptionDescribe(); 4968 env->ExceptionClear(); 4969 } 4970 DASSERT(mouseWheelEvent != NULL); 4971 if (pMsg != NULL) { 4972 AwtAWTEvent::saveMSG(env, pMsg, mouseWheelEvent); 4973 } 4974 SendEvent(mouseWheelEvent); 4975 4976 env->DeleteLocalRef(mouseWheelEvent); 4977 env->DeleteLocalRef(target); 4978 } 4979 4980 void AwtComponent::SendFocusEvent(jint id, HWND opposite) 4981 { 4982 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 4983 4984 CriticalSection::Lock l(GetLock()); 4985 if (GetPeer(env) == NULL) { 4986 /* event received during termination. */ 4987 return; 4988 } 4989 4990 static jclass focusEventCls; 4991 if (focusEventCls == NULL) { 4992 jclass focusEventClsLocal 4993 = env->FindClass("java/awt/event/FocusEvent"); 4994 DASSERT(focusEventClsLocal); 4995 if (focusEventClsLocal == NULL) { 4996 /* exception already thrown */ 4997 return; 4998 } 4999 focusEventCls = (jclass)env->NewGlobalRef(focusEventClsLocal); 5000 env->DeleteLocalRef(focusEventClsLocal); 5001 } 5002 5003 static jmethodID focusEventConst; 5004 if (focusEventConst == NULL) { 5005 focusEventConst = 5006 env->GetMethodID(focusEventCls, "<init>", 5007 "(Ljava/awt/Component;IZLjava/awt/Component;)V"); 5008 DASSERT(focusEventConst); 5009 } 5010 5011 static jclass sequencedEventCls; 5012 if (sequencedEventCls == NULL) { 5013 jclass sequencedEventClsLocal = 5014 env->FindClass("java/awt/SequencedEvent"); 5015 DASSERT(sequencedEventClsLocal); 5016 if (sequencedEventClsLocal == NULL) { 5017 /* exception already thrown */ 5018 return; 5019 } 5020 sequencedEventCls = 5021 (jclass)env->NewGlobalRef(sequencedEventClsLocal); 5022 env->DeleteLocalRef(sequencedEventClsLocal); 5023 } 5024 5025 static jmethodID sequencedEventConst; 5026 if (sequencedEventConst == NULL) { 5027 sequencedEventConst = 5028 env->GetMethodID(sequencedEventCls, "<init>", 5029 "(Ljava/awt/AWTEvent;)V"); 5030 } 5031 5032 if (env->EnsureLocalCapacity(3) < 0) { 5033 return; 5034 } 5035 5036 jobject target = GetTarget(env); 5037 jobject jOpposite = NULL; 5038 if (opposite != NULL) { 5039 AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite); 5040 if (awtOpposite != NULL) { 5041 jOpposite = awtOpposite->GetTarget(env); 5042 } 5043 } 5044 jobject focusEvent = env->NewObject(focusEventCls, focusEventConst, 5045 target, id, JNI_FALSE, jOpposite); 5046 DASSERT(!safe_ExceptionOccurred(env)); 5047 DASSERT(focusEvent != NULL); 5048 if (jOpposite != NULL) { 5049 env->DeleteLocalRef(jOpposite); jOpposite = NULL; 5050 } 5051 env->DeleteLocalRef(target); target = NULL; 5052 5053 jobject sequencedEvent = env->NewObject(sequencedEventCls, 5054 sequencedEventConst, 5055 focusEvent); 5056 DASSERT(!safe_ExceptionOccurred(env)); 5057 DASSERT(sequencedEvent != NULL); 5058 env->DeleteLocalRef(focusEvent); focusEvent = NULL; 5059 5060 SendEvent(sequencedEvent); 5061 5062 env->DeleteLocalRef(sequencedEvent); 5063 } 5064 5065 /* 5066 * Forward a filtered event directly to the subclassed window. 5067 * This method is needed so that DefWindowProc is invoked on the 5068 * component's owning thread. 5069 */ 5070 MsgRouting AwtComponent::HandleEvent(MSG *msg, BOOL) 5071 { 5072 DefWindowProc(msg->message, msg->wParam, msg->lParam); 5073 delete msg; 5074 return mrConsume; 5075 } 5076 5077 /* Post a WM_AWT_HANDLE_EVENT message which invokes HandleEvent 5078 on the toolkit thread. This method may pre-filter the messages. */ 5079 BOOL AwtComponent::PostHandleEventMessage(MSG *msg, BOOL synthetic) 5080 { 5081 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5082 // We should cut off keyboard events to disabled components 5083 // to avoid the components responding visually to keystrokes when disabled. 5084 // we shouldn't cut off WM_SYS* messages as they aren't used for normal activity 5085 // but to activate menus, close windows, etc 5086 switch(msg->message) { 5087 case WM_KEYDOWN: 5088 case WM_KEYUP: 5089 case WM_CHAR: 5090 case WM_DEADCHAR: 5091 { 5092 if (!isRecursivelyEnabled()) { 5093 goto quit; 5094 } 5095 break; 5096 } 5097 } 5098 if (PostMessage(GetHWnd(), WM_AWT_HANDLE_EVENT, 5099 (WPARAM) synthetic, (LPARAM) msg)) { 5100 return TRUE; 5101 } else { 5102 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5103 } 5104 quit: 5105 delete msg; 5106 return FALSE; 5107 } 5108 5109 void AwtComponent::SynthesizeKeyMessage(JNIEnv *env, jobject keyEvent) 5110 { 5111 jint id = (env)->GetIntField(keyEvent, AwtAWTEvent::idID); 5112 UINT message; 5113 switch (id) { 5114 case java_awt_event_KeyEvent_KEY_PRESSED: 5115 message = WM_KEYDOWN; 5116 break; 5117 case java_awt_event_KeyEvent_KEY_RELEASED: 5118 message = WM_KEYUP; 5119 break; 5120 case java_awt_event_KeyEvent_KEY_TYPED: 5121 message = WM_CHAR; 5122 break; 5123 default: 5124 return; 5125 } 5126 5127 /* 5128 * KeyEvent.modifiers aren't supported -- the Java apppwd must send separate 5129 * KEY_PRESSED and KEY_RELEASED events for the modifier virtual keys. 5130 */ 5131 if (id == java_awt_event_KeyEvent_KEY_TYPED) { 5132 // WM_CHAR message must be posted using WM_AWT_FORWARD_CHAR 5133 // (for Edit control) 5134 jchar keyChar = (jchar) 5135 (env)->GetCharField(keyEvent, AwtKeyEvent::keyCharID); 5136 5137 // Bugid 4724007. If it is a Delete character, don't send the fake 5138 // KEY_TYPED we created back to the native window: Windows doesn't 5139 // expect a WM_CHAR for Delete in TextFields, so it tries to enter a 5140 // character after deleting. 5141 if (keyChar == '\177') { // the Delete character 5142 return; 5143 } 5144 5145 // Disable forwarding WM_CHAR messages to disabled components 5146 if (isRecursivelyEnabled()) { 5147 if (!::PostMessage(GetHWnd(), WM_AWT_FORWARD_CHAR, 5148 MAKEWPARAM(keyChar, TRUE), 0)) { 5149 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5150 } 5151 } 5152 } else { 5153 jint keyCode = 5154 (env)->GetIntField(keyEvent, AwtKeyEvent::keyCodeID); 5155 UINT key, modifiers; 5156 AwtComponent::JavaKeyToWindowsKey(keyCode, &key, &modifiers); 5157 MSG* msg = CreateMessage(message, key, 0); 5158 PostHandleEventMessage(msg, TRUE); 5159 } 5160 } 5161 5162 void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent) 5163 { 5164 /* DebugBreak(); */ 5165 jint button = (env)->GetIntField(mouseEvent, AwtMouseEvent::buttonID); 5166 jint modifiers = (env)->GetIntField(mouseEvent, AwtInputEvent::modifiersID); 5167 5168 WPARAM wParam = 0; 5169 WORD wLow = 0; 5170 jint wheelAmt = 0; 5171 jint id = (env)->GetIntField(mouseEvent, AwtAWTEvent::idID); 5172 UINT message; 5173 switch (id) { 5174 case java_awt_event_MouseEvent_MOUSE_PRESSED: { 5175 switch (button) { 5176 case java_awt_event_MouseEvent_BUTTON1: 5177 message = WM_LBUTTONDOWN; break; 5178 case java_awt_event_MouseEvent_BUTTON3: 5179 message = WM_MBUTTONDOWN; break; 5180 case java_awt_event_MouseEvent_BUTTON2: 5181 message = WM_RBUTTONDOWN; break; 5182 } 5183 break; 5184 } 5185 case java_awt_event_MouseEvent_MOUSE_RELEASED: { 5186 switch (button) { 5187 case java_awt_event_MouseEvent_BUTTON1: 5188 message = WM_LBUTTONUP; break; 5189 case java_awt_event_MouseEvent_BUTTON3: 5190 message = WM_MBUTTONUP; break; 5191 case java_awt_event_MouseEvent_BUTTON2: 5192 message = WM_RBUTTONUP; break; 5193 } 5194 break; 5195 } 5196 case java_awt_event_MouseEvent_MOUSE_MOVED: 5197 /* MOUSE_DRAGGED events must first have sent a MOUSE_PRESSED event. */ 5198 case java_awt_event_MouseEvent_MOUSE_DRAGGED: 5199 message = WM_MOUSEMOVE; 5200 break; 5201 case java_awt_event_MouseEvent_MOUSE_WHEEL: 5202 if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) { 5203 wLow |= MK_CONTROL; 5204 } 5205 if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) { 5206 wLow |= MK_SHIFT; 5207 } 5208 if (modifiers & java_awt_event_InputEvent_BUTTON1_DOWN_MASK) { 5209 wLow |= MK_LBUTTON; 5210 } 5211 if (modifiers & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) { 5212 wLow |= MK_RBUTTON; 5213 } 5214 if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) { 5215 wLow |= MK_MBUTTON; 5216 } 5217 if (modifiers & X1_BUTTON) { 5218 wLow |= GetButtonMK(X1_BUTTON); 5219 } 5220 if (modifiers & X2_BUTTON) { 5221 wLow |= GetButtonMK(X2_BUTTON); 5222 } 5223 5224 wheelAmt = (jint)JNU_CallMethodByName(env, 5225 NULL, 5226 mouseEvent, 5227 "getWheelRotation", 5228 "()I").i; 5229 DASSERT(!safe_ExceptionOccurred(env)); 5230 //DASSERT(wheelAmt); 5231 DTRACE_PRINTLN1("wheelAmt = %i\n", wheelAmt); 5232 5233 // convert Java wheel amount value to Win32 5234 wheelAmt *= -1 * WHEEL_DELTA; 5235 5236 message = WM_MOUSEWHEEL; 5237 wParam = MAKEWPARAM(wLow, wheelAmt); 5238 5239 break; 5240 default: 5241 return; 5242 } 5243 jint x = (env)->GetIntField(mouseEvent, AwtMouseEvent::xID); 5244 jint y = (env)->GetIntField(mouseEvent, AwtMouseEvent::yID); 5245 MSG* msg = CreateMessage(message, wParam, MAKELPARAM(x, y), x, y); 5246 PostHandleEventMessage(msg, TRUE); 5247 } 5248 5249 BOOL AwtComponent::InheritsNativeMouseWheelBehavior() {return false;} 5250 5251 void AwtComponent::Invalidate(RECT* r) 5252 { 5253 ::InvalidateRect(GetHWnd(), r, FALSE); 5254 } 5255 5256 void AwtComponent::BeginValidate() 5257 { 5258 DASSERT(m_validationNestCount >= 0 && 5259 m_validationNestCount < 1000); // sanity check 5260 5261 if (m_validationNestCount == 0) { 5262 // begin deferred window positioning if we're not inside 5263 // another Begin/EndValidate pair 5264 DASSERT(m_hdwp == NULL); 5265 m_hdwp = ::BeginDeferWindowPos(32); 5266 } 5267 5268 m_validationNestCount++; 5269 } 5270 5271 void AwtComponent::EndValidate() 5272 { 5273 DASSERT(m_validationNestCount > 0 && 5274 m_validationNestCount < 1000); // sanity check 5275 DASSERT(m_hdwp != NULL); 5276 5277 m_validationNestCount--; 5278 if (m_validationNestCount == 0) { 5279 // if this call to EndValidate is not nested inside another 5280 // Begin/EndValidate pair, end deferred window positioning 5281 ::EndDeferWindowPos(m_hdwp); 5282 m_hdwp = NULL; 5283 } 5284 } 5285 5286 /** 5287 * HWND, AwtComponent and Java Peer interaction 5288 */ 5289 5290 /* 5291 *Link the C++, Java peer, and HWNDs together. 5292 */ 5293 void AwtComponent::LinkObjects(JNIEnv *env, jobject peer) 5294 { 5295 /* 5296 * Bind all three objects together thru this C++ object, two-way to each: 5297 * JavaPeer <-> C++ <-> HWND 5298 * 5299 * C++ -> JavaPeer 5300 */ 5301 if (m_peerObject == NULL) { 5302 // This may have already been set up by CreateHWnd 5303 // And we don't want to create two references so we 5304 // will leave the prior one alone 5305 m_peerObject = env->NewGlobalRef(peer); 5306 } 5307 /* JavaPeer -> HWND */ 5308 env->SetLongField(peer, AwtComponent::hwndID, reinterpret_cast<jlong>(m_hwnd)); 5309 5310 /* JavaPeer -> C++ */ 5311 JNI_SET_PDATA(peer, this); 5312 5313 /* HWND -> C++ */ 5314 SetComponentInHWND(); 5315 } 5316 5317 /* Cleanup above linking */ 5318 void AwtComponent::UnlinkObjects() 5319 { 5320 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5321 if (m_peerObject) { 5322 env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); 5323 JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL)); 5324 JNI_SET_DESTROYED(m_peerObject); 5325 env->DeleteGlobalRef(m_peerObject); 5326 m_peerObject = NULL; 5327 } 5328 } 5329 5330 void AwtComponent::Enable(BOOL bEnable) 5331 { 5332 if (bEnable && IsTopLevel()) { 5333 // we should not enable blocked toplevels 5334 bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); 5335 } 5336 // Shouldn't trigger native focus change 5337 // (only the proxy may be the native focus owner). 5338 ::EnableWindow(GetHWnd(), bEnable); 5339 5340 CriticalSection::Lock l(GetLock()); 5341 VerifyState(); 5342 } 5343 5344 /* 5345 * associate an AwtDropTarget with this AwtComponent 5346 */ 5347 5348 AwtDropTarget* AwtComponent::CreateDropTarget(JNIEnv* env) { 5349 m_dropTarget = new AwtDropTarget(env, this); 5350 m_dropTarget->RegisterTarget(TRUE); 5351 return m_dropTarget; 5352 } 5353 5354 /* 5355 * disassociate an AwtDropTarget with this AwtComponent 5356 */ 5357 5358 void AwtComponent::DestroyDropTarget() { 5359 if (m_dropTarget != NULL) { 5360 m_dropTarget->RegisterTarget(FALSE); 5361 m_dropTarget->Release(); 5362 m_dropTarget = NULL; 5363 } 5364 } 5365 5366 BOOL AwtComponent::IsFocusingMouseMessage(MSG *pMsg) { 5367 return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK; 5368 } 5369 5370 BOOL AwtComponent::IsFocusingKeyMessage(MSG *pMsg) { 5371 return pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE; 5372 } 5373 5374 void AwtComponent::_Show(void *param) 5375 { 5376 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5377 5378 jobject self = (jobject)param; 5379 5380 AwtComponent *p; 5381 5382 PDATA pData; 5383 JNI_CHECK_PEER_GOTO(self, ret); 5384 p = (AwtComponent *)pData; 5385 if (::IsWindow(p->GetHWnd())) 5386 { 5387 p->SendMessage(WM_AWT_COMPONENT_SHOW); 5388 } 5389 ret: 5390 env->DeleteGlobalRef(self); 5391 } 5392 5393 void AwtComponent::_Hide(void *param) 5394 { 5395 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5396 5397 jobject self = (jobject)param; 5398 5399 AwtComponent *p; 5400 5401 PDATA pData; 5402 JNI_CHECK_PEER_GOTO(self, ret); 5403 p = (AwtComponent *)pData; 5404 if (::IsWindow(p->GetHWnd())) 5405 { 5406 p->SendMessage(WM_AWT_COMPONENT_HIDE); 5407 } 5408 ret: 5409 env->DeleteGlobalRef(self); 5410 } 5411 5412 void AwtComponent::_Enable(void *param) 5413 { 5414 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5415 5416 jobject self = (jobject)param; 5417 5418 AwtComponent *p; 5419 5420 PDATA pData; 5421 JNI_CHECK_PEER_GOTO(self, ret); 5422 p = (AwtComponent *)pData; 5423 if (::IsWindow(p->GetHWnd())) 5424 { 5425 p->Enable(TRUE); 5426 } 5427 ret: 5428 env->DeleteGlobalRef(self); 5429 } 5430 5431 void AwtComponent::_Disable(void *param) 5432 { 5433 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5434 5435 jobject self = (jobject)param; 5436 5437 AwtComponent *p; 5438 5439 PDATA pData; 5440 JNI_CHECK_PEER_GOTO(self, ret); 5441 p = (AwtComponent *)pData; 5442 if (::IsWindow(p->GetHWnd())) 5443 { 5444 p->Enable(FALSE); 5445 } 5446 ret: 5447 env->DeleteGlobalRef(self); 5448 } 5449 5450 jobject AwtComponent::_GetLocationOnScreen(void *param) 5451 { 5452 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5453 5454 jobject self = (jobject)param; 5455 5456 jobject result = NULL; 5457 AwtComponent *p; 5458 5459 PDATA pData; 5460 JNI_CHECK_PEER_GOTO(self, ret); 5461 p = (AwtComponent *)pData; 5462 if (::IsWindow(p->GetHWnd())) 5463 { 5464 RECT rect; 5465 VERIFY(::GetWindowRect(p->GetHWnd(),&rect)); 5466 result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", 5467 rect.left, rect.top); 5468 } 5469 ret: 5470 env->DeleteGlobalRef(self); 5471 5472 if (result != NULL) 5473 { 5474 jobject resultGlobalRef = env->NewGlobalRef(result); 5475 env->DeleteLocalRef(result); 5476 return resultGlobalRef; 5477 } 5478 else 5479 { 5480 return NULL; 5481 } 5482 } 5483 5484 void AwtComponent::_Reshape(void *param) 5485 { 5486 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5487 5488 ReshapeStruct *rs = (ReshapeStruct*)param; 5489 jobject self = rs->component; 5490 jint x = rs->x; 5491 jint y = rs->y; 5492 jint w = rs->w; 5493 jint h = rs->h; 5494 5495 AwtComponent *p; 5496 5497 PDATA pData; 5498 JNI_CHECK_PEER_GOTO(self, ret); 5499 p = (AwtComponent *)pData; 5500 if (::IsWindow(p->GetHWnd())) 5501 { 5502 RECT* r = new RECT; 5503 ::SetRect(r, x, y, x + w, y + h); 5504 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, CHECK_EMBEDDED, (LPARAM)r); 5505 } 5506 ret: 5507 env->DeleteGlobalRef(self); 5508 5509 delete rs; 5510 } 5511 5512 void AwtComponent::_ReshapeNoCheck(void *param) 5513 { 5514 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5515 5516 ReshapeStruct *rs = (ReshapeStruct*)param; 5517 jobject self = rs->component; 5518 jint x = rs->x; 5519 jint y = rs->y; 5520 jint w = rs->w; 5521 jint h = rs->h; 5522 5523 AwtComponent *p; 5524 5525 PDATA pData; 5526 JNI_CHECK_PEER_GOTO(self, ret); 5527 p = (AwtComponent *)pData; 5528 if (::IsWindow(p->GetHWnd())) 5529 { 5530 RECT* r = new RECT; 5531 ::SetRect(r, x, y, x + w, y + h); 5532 p->SendMessage(WM_AWT_RESHAPE_COMPONENT, DONT_CHECK_EMBEDDED, (LPARAM)r); 5533 } 5534 ret: 5535 env->DeleteGlobalRef(self); 5536 5537 delete rs; 5538 } 5539 5540 void AwtComponent::_NativeHandleEvent(void *param) 5541 { 5542 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5543 5544 NativeHandleEventStruct *nhes = (NativeHandleEventStruct *)param; 5545 jobject self = nhes->component; 5546 jobject event = nhes->event; 5547 5548 AwtComponent *p; 5549 5550 PDATA pData; 5551 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5552 pData = JNI_GET_PDATA(self); 5553 if (pData == NULL) { 5554 env->DeleteGlobalRef(self); 5555 if (event != NULL) { 5556 env->DeleteGlobalRef(event); 5557 } 5558 delete nhes; 5559 return; 5560 } 5561 JNI_CHECK_NULL_GOTO(event, "null AWTEvent", ret); 5562 5563 p = (AwtComponent *)pData; 5564 if (::IsWindow(p->GetHWnd())) 5565 { 5566 if (env->EnsureLocalCapacity(1) < 0) { 5567 env->DeleteGlobalRef(self); 5568 env->DeleteGlobalRef(event); 5569 delete nhes; 5570 return; 5571 } 5572 jbyteArray bdata = (jbyteArray)(env)->GetObjectField(event, AwtAWTEvent::bdataID); 5573 int id = (env)->GetIntField(event, AwtAWTEvent::idID); 5574 DASSERT(!safe_ExceptionOccurred(env)); 5575 if (bdata != 0) { 5576 MSG msg; 5577 (env)->GetByteArrayRegion(bdata, 0, sizeof(MSG), (jbyte *)&msg); 5578 (env)->DeleteLocalRef(bdata); 5579 static BOOL keyDownConsumed = FALSE; 5580 static BOOL bCharChanged = FALSE; 5581 static WCHAR modifiedChar; 5582 WCHAR unicodeChar; 5583 5584 /* Remember if a KEY_PRESSED event is consumed, as an old model 5585 * program won't consume a subsequent KEY_TYPED event. 5586 */ 5587 jboolean consumed = 5588 (env)->GetBooleanField(event, AwtAWTEvent::consumedID); 5589 DASSERT(!safe_ExceptionOccurred(env)); 5590 5591 if (consumed) { 5592 keyDownConsumed = (id == java_awt_event_KeyEvent_KEY_PRESSED); 5593 env->DeleteGlobalRef(self); 5594 env->DeleteGlobalRef(event); 5595 delete nhes; 5596 return; 5597 5598 } else if (id == java_awt_event_KeyEvent_KEY_PRESSED) { 5599 // Fix for 6637607: reset consuming 5600 keyDownConsumed = FALSE; 5601 } 5602 5603 /* Consume a KEY_TYPED event if a KEY_PRESSED had been, to support 5604 * the old model. 5605 */ 5606 if ((id == java_awt_event_KeyEvent_KEY_TYPED) && keyDownConsumed) { 5607 keyDownConsumed = FALSE; 5608 env->DeleteGlobalRef(self); 5609 env->DeleteGlobalRef(event); 5610 delete nhes; 5611 return; 5612 } 5613 5614 /* Modify any event parameters, if necessary. */ 5615 if (self && pData && 5616 id >= java_awt_event_KeyEvent_KEY_FIRST && 5617 id <= java_awt_event_KeyEvent_KEY_LAST) { 5618 5619 AwtComponent* p = (AwtComponent*)pData; 5620 5621 jint keyCode = 5622 (env)->GetIntField(event, AwtKeyEvent::keyCodeID); 5623 jchar keyChar = 5624 (env)->GetCharField(event, AwtKeyEvent::keyCharID); 5625 jint modifiers = 5626 (env)->GetIntField(event, AwtInputEvent::modifiersID); 5627 5628 DASSERT(!safe_ExceptionOccurred(env)); 5629 5630 /* Check to see whether the keyCode or modifiers were changed 5631 on the keyPressed event, and tweak the following keyTyped 5632 event (if any) accodingly. */ 5633 switch (id) { 5634 case java_awt_event_KeyEvent_KEY_PRESSED: 5635 { 5636 UINT winKey = (UINT)msg.wParam; 5637 bCharChanged = FALSE; 5638 5639 if (winKey == VK_PROCESSKEY) { 5640 // Leave it up to IME 5641 break; 5642 } 5643 5644 if (keyCode != java_awt_event_KeyEvent_VK_UNDEFINED) { 5645 UINT newWinKey, ignored; 5646 p->JavaKeyToWindowsKey(keyCode, &newWinKey, &ignored, winKey); 5647 if (newWinKey != 0) { 5648 winKey = newWinKey; 5649 } 5650 } 5651 5652 BOOL isDeadKey = FALSE; 5653 modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey); 5654 bCharChanged = (keyChar != modifiedChar); 5655 } 5656 break; 5657 5658 case java_awt_event_KeyEvent_KEY_RELEASED: 5659 { 5660 keyDownConsumed = FALSE; 5661 bCharChanged = FALSE; 5662 } 5663 break; 5664 5665 case java_awt_event_KeyEvent_KEY_TYPED: 5666 { 5667 if (bCharChanged) 5668 { 5669 unicodeChar = modifiedChar; 5670 } 5671 else 5672 { 5673 unicodeChar = keyChar; 5674 } 5675 bCharChanged = FALSE; 5676 5677 // Disable forwarding KEY_TYPED messages to peers of 5678 // disabled components 5679 if (p->isRecursivelyEnabled()) { 5680 // send the character back to the native window for 5681 // processing. The WM_AWT_FORWARD_CHAR handler will send 5682 // this character to DefWindowProc 5683 if (!::PostMessage(p->GetHWnd(), WM_AWT_FORWARD_CHAR, 5684 MAKEWPARAM(unicodeChar, FALSE), msg.lParam)) { 5685 JNU_ThrowInternalError(env, "Message not posted, native event queue may be full."); 5686 } 5687 } 5688 env->DeleteGlobalRef(self); 5689 env->DeleteGlobalRef(event); 5690 delete nhes; 5691 return; 5692 } 5693 break; 5694 5695 default: 5696 break; 5697 } 5698 } 5699 5700 // ignore all InputMethodEvents 5701 if (self && (pData = JNI_GET_PDATA(self)) && 5702 id >= java_awt_event_InputMethodEvent_INPUT_METHOD_FIRST && 5703 id <= java_awt_event_InputMethodEvent_INPUT_METHOD_LAST) { 5704 env->DeleteGlobalRef(self); 5705 env->DeleteGlobalRef(event); 5706 delete nhes; 5707 return; 5708 } 5709 5710 // Create copy for local msg 5711 MSG* pCopiedMsg = new MSG; 5712 memmove(pCopiedMsg, &msg, sizeof(MSG)); 5713 // Event handler deletes msg 5714 p->PostHandleEventMessage(pCopiedMsg, FALSE); 5715 5716 env->DeleteGlobalRef(self); 5717 env->DeleteGlobalRef(event); 5718 delete nhes; 5719 return; 5720 } 5721 5722 /* Forward any valid synthesized events. Currently only mouse and 5723 * key events are supported. 5724 */ 5725 if (self == NULL || (pData = JNI_GET_PDATA(self)) == NULL) { 5726 env->DeleteGlobalRef(self); 5727 env->DeleteGlobalRef(event); 5728 delete nhes; 5729 return; 5730 } 5731 5732 AwtComponent* p = (AwtComponent*)pData; 5733 if (id >= java_awt_event_KeyEvent_KEY_FIRST && 5734 id <= java_awt_event_KeyEvent_KEY_LAST) { 5735 p->SynthesizeKeyMessage(env, event); 5736 } else if (id >= java_awt_event_MouseEvent_MOUSE_FIRST && 5737 id <= java_awt_event_MouseEvent_MOUSE_LAST) { 5738 p->SynthesizeMouseMessage(env, event); 5739 } 5740 } 5741 5742 ret: 5743 if (self != NULL) { 5744 env->DeleteGlobalRef(self); 5745 } 5746 if (event != NULL) { 5747 env->DeleteGlobalRef(event); 5748 } 5749 5750 delete nhes; 5751 } 5752 5753 void AwtComponent::_SetForeground(void *param) 5754 { 5755 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5756 5757 SetColorStruct *scs = (SetColorStruct *)param; 5758 jobject self = scs->component; 5759 jint rgb = scs->rgb; 5760 5761 AwtComponent *c = NULL; 5762 5763 PDATA pData; 5764 JNI_CHECK_PEER_GOTO(self, ret); 5765 c = (AwtComponent *)pData; 5766 if (::IsWindow(c->GetHWnd())) 5767 { 5768 c->SetColor(PALETTERGB((rgb>>16)&0xff, 5769 (rgb>>8)&0xff, 5770 (rgb)&0xff)); 5771 c->VerifyState(); 5772 } 5773 ret: 5774 env->DeleteGlobalRef(self); 5775 5776 delete scs; 5777 } 5778 5779 void AwtComponent::_SetBackground(void *param) 5780 { 5781 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5782 5783 SetColorStruct *scs = (SetColorStruct *)param; 5784 jobject self = scs->component; 5785 jint rgb = scs->rgb; 5786 5787 AwtComponent *c = NULL; 5788 5789 PDATA pData; 5790 JNI_CHECK_PEER_GOTO(self, ret); 5791 c = (AwtComponent *)pData; 5792 if (::IsWindow(c->GetHWnd())) 5793 { 5794 c->SetBackgroundColor(PALETTERGB((rgb>>16)&0xff, 5795 (rgb>>8)&0xff, 5796 (rgb)&0xff)); 5797 c->VerifyState(); 5798 } 5799 ret: 5800 env->DeleteGlobalRef(self); 5801 5802 delete scs; 5803 } 5804 5805 void AwtComponent::_SetFont(void *param) 5806 { 5807 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5808 5809 SetFontStruct *sfs = (SetFontStruct *)param; 5810 jobject self = sfs->component; 5811 jobject font = sfs->font; 5812 5813 AwtComponent *c = NULL; 5814 5815 PDATA pData; 5816 JNI_CHECK_PEER_GOTO(self, ret); 5817 JNI_CHECK_NULL_GOTO(font, "null font", ret); 5818 c = (AwtComponent *)pData; 5819 if (::IsWindow(c->GetHWnd())) 5820 { 5821 AwtFont *awtFont = (AwtFont *)env->GetLongField(font, AwtFont::pDataID); 5822 if (awtFont == NULL) { 5823 /*arguments of AwtFont::Create are changed for multifont component */ 5824 awtFont = AwtFont::Create(env, font); 5825 } 5826 env->SetLongField(font, AwtFont::pDataID, (jlong)awtFont); 5827 5828 c->SetFont(awtFont); 5829 } 5830 ret: 5831 env->DeleteGlobalRef(self); 5832 env->DeleteGlobalRef(font); 5833 5834 delete sfs; 5835 } 5836 5837 // Sets or kills focus for a component. 5838 void AwtComponent::_SetFocus(void *param) 5839 { 5840 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5841 5842 SetFocusStruct *sfs = (SetFocusStruct *)param; 5843 jobject self = sfs->component; 5844 jboolean doSetFocus = sfs->doSetFocus; 5845 5846 AwtComponent *c = NULL; 5847 5848 PDATA pData; 5849 JNI_CHECK_NULL_GOTO(self, "peer", ret); 5850 pData = JNI_GET_PDATA(self); 5851 if (pData == NULL) { 5852 // do nothing just return false 5853 goto ret; 5854 } 5855 5856 c = (AwtComponent *)pData; 5857 if (::IsWindow(c->GetHWnd())) { 5858 c->SendMessage(WM_AWT_COMPONENT_SETFOCUS, (WPARAM)doSetFocus, 0); 5859 } 5860 ret: 5861 env->DeleteGlobalRef(self); 5862 5863 delete sfs; 5864 } 5865 5866 void AwtComponent::_Start(void *param) 5867 { 5868 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5869 5870 jobject self = (jobject)param; 5871 5872 AwtComponent *c = NULL; 5873 5874 PDATA pData; 5875 JNI_CHECK_PEER_GOTO(self, ret); 5876 c = (AwtComponent *)pData; 5877 if (::IsWindow(c->GetHWnd())) 5878 { 5879 jobject target = c->GetTarget(env); 5880 5881 /* Disable window if specified -- windows are enabled by default. */ 5882 jboolean enabled = (jboolean)env->GetBooleanField(target, 5883 AwtComponent::enabledID); 5884 if (!enabled) { 5885 ::EnableWindow(c->GetHWnd(), FALSE); 5886 } 5887 5888 /* The peer is now ready for callbacks, since this is the last 5889 * initialization call 5890 */ 5891 c->EnableCallbacks(TRUE); 5892 5893 // Fix 4745222: we need to invalidate region since we validated it before initialization. 5894 ::InvalidateRgn(c->GetHWnd(), NULL, FALSE); 5895 5896 // Fix 4530093: WM_PAINT after EnableCallbacks 5897 ::UpdateWindow(c->GetHWnd()); 5898 5899 env->DeleteLocalRef(target); 5900 } 5901 ret: 5902 env->DeleteGlobalRef(self); 5903 } 5904 5905 void AwtComponent::_BeginValidate(void *param) 5906 { 5907 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5908 if (AwtToolkit::IsMainThread()) { 5909 jobject self = (jobject)param; 5910 if (self != NULL) { 5911 PDATA pData = JNI_GET_PDATA(self); 5912 if (pData) { 5913 AwtComponent *c = (AwtComponent *)pData; 5914 if (::IsWindow(c->GetHWnd())) { 5915 c->SendMessage(WM_AWT_BEGIN_VALIDATE); 5916 } 5917 } 5918 env->DeleteGlobalRef(self); 5919 } 5920 } else { 5921 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_BeginValidate, param); 5922 } 5923 } 5924 5925 void AwtComponent::_EndValidate(void *param) 5926 { 5927 if (AwtToolkit::IsMainThread()) { 5928 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5929 jobject self = (jobject)param; 5930 if (self != NULL) { 5931 PDATA pData = JNI_GET_PDATA(self); 5932 if (pData) { 5933 AwtComponent *c = (AwtComponent *)pData; 5934 if (::IsWindow(c->GetHWnd())) { 5935 c->SendMessage(WM_AWT_END_VALIDATE); 5936 } 5937 } 5938 env->DeleteGlobalRef(self); 5939 } 5940 } else { 5941 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_EndValidate, param); 5942 } 5943 } 5944 5945 void AwtComponent::_UpdateWindow(void *param) 5946 { 5947 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5948 if (AwtToolkit::IsMainThread()) { 5949 jobject self = (jobject)param; 5950 AwtComponent *c = NULL; 5951 PDATA pData; 5952 JNI_CHECK_PEER_GOTO(self, ret); 5953 c = (AwtComponent *)pData; 5954 if (::IsWindow(c->GetHWnd())) { 5955 ::UpdateWindow(c->GetHWnd()); 5956 } 5957 ret: 5958 env->DeleteGlobalRef(self); 5959 } else { 5960 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_UpdateWindow, param); 5961 } 5962 } 5963 5964 jlong AwtComponent::_AddNativeDropTarget(void *param) 5965 { 5966 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5967 5968 jobject self = (jobject)param; 5969 5970 jlong result = 0; 5971 AwtComponent *c = NULL; 5972 5973 PDATA pData; 5974 JNI_CHECK_PEER_GOTO(self, ret); 5975 c = (AwtComponent *)pData; 5976 if (::IsWindow(c->GetHWnd())) 5977 { 5978 result = (jlong)(c->CreateDropTarget(env)); 5979 } 5980 ret: 5981 env->DeleteGlobalRef(self); 5982 5983 return result; 5984 } 5985 5986 void AwtComponent::_RemoveNativeDropTarget(void *param) 5987 { 5988 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 5989 5990 jobject self = (jobject)param; 5991 5992 AwtComponent *c = NULL; 5993 5994 PDATA pData; 5995 JNI_CHECK_PEER_GOTO(self, ret); 5996 c = (AwtComponent *)pData; 5997 if (::IsWindow(c->GetHWnd())) 5998 { 5999 c->DestroyDropTarget(); 6000 } 6001 ret: 6002 env->DeleteGlobalRef(self); 6003 } 6004 6005 jintArray AwtComponent::_CreatePrintedPixels(void *param) 6006 { 6007 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6008 6009 CreatePrintedPixelsStruct *cpps = (CreatePrintedPixelsStruct *)param; 6010 jobject self = cpps->component; 6011 6012 jintArray result = NULL; 6013 AwtComponent *c = NULL; 6014 6015 PDATA pData; 6016 JNI_CHECK_PEER_GOTO(self, ret); 6017 c = (AwtComponent *)pData; 6018 if (::IsWindow(c->GetHWnd())) 6019 { 6020 result = (jintArray)c->SendMessage(WM_AWT_CREATE_PRINTED_PIXELS, (WPARAM)cpps, 0); 6021 } 6022 ret: 6023 env->DeleteGlobalRef(self); 6024 6025 delete cpps; 6026 return result; // this reference is global 6027 } 6028 6029 jboolean AwtComponent::_IsObscured(void *param) 6030 { 6031 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6032 6033 jobject self = (jobject)param; 6034 6035 jboolean result = JNI_FALSE; 6036 AwtComponent *c = NULL; 6037 6038 PDATA pData; 6039 JNI_CHECK_PEER_GOTO(self, ret); 6040 6041 c = (AwtComponent *)pData; 6042 6043 if (::IsWindow(c->GetHWnd())) 6044 { 6045 HWND hWnd = c->GetHWnd(); 6046 HDC hDC = ::GetDC(hWnd); 6047 RECT clipbox; 6048 int callresult = ::GetClipBox(hDC, &clipbox); 6049 switch(callresult) { 6050 case NULLREGION : 6051 result = JNI_FALSE; 6052 break; 6053 case SIMPLEREGION : { 6054 RECT windowRect; 6055 if (!::GetClientRect(hWnd, &windowRect)) { 6056 result = JNI_TRUE; 6057 } else { 6058 result = (jboolean)((clipbox.bottom != windowRect.bottom) 6059 || (clipbox.left != windowRect.left) 6060 || (clipbox.right != windowRect.right) 6061 || (clipbox.top != windowRect.top)); 6062 } 6063 break; 6064 } 6065 case COMPLEXREGION : 6066 default : 6067 result = JNI_TRUE; 6068 break; 6069 } 6070 ::ReleaseDC(hWnd, hDC); 6071 } 6072 ret: 6073 env->DeleteGlobalRef(self); 6074 6075 return result; 6076 } 6077 6078 jboolean AwtComponent::_NativeHandlesWheelScrolling(void *param) 6079 { 6080 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6081 6082 jobject self = (jobject)param; 6083 6084 jboolean result = JNI_FALSE; 6085 AwtComponent *c = NULL; 6086 6087 PDATA pData; 6088 JNI_CHECK_PEER_GOTO(self, ret); 6089 c = (AwtComponent *)pData; 6090 if (::IsWindow(c->GetHWnd())) 6091 { 6092 result = (jboolean)c->InheritsNativeMouseWheelBehavior(); 6093 } 6094 ret: 6095 env->DeleteGlobalRef(self); 6096 6097 return result; 6098 } 6099 6100 void AwtComponent::SetParent(void * param) { 6101 if (AwtToolkit::IsMainThread()) { 6102 AwtComponent** comps = (AwtComponent**)param; 6103 if ((comps[0] != NULL) && (comps[1] != NULL)) { 6104 HWND selfWnd = comps[0]->GetHWnd(); 6105 HWND parentWnd = comps[1]->GetHWnd(); 6106 if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) { 6107 // Shouldn't trigger native focus change 6108 // (only the proxy may be the native focus owner). 6109 ::SetParent(selfWnd, parentWnd); 6110 } 6111 } 6112 delete[] comps; 6113 } else { 6114 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::SetParent, param); 6115 } 6116 } 6117 6118 void AwtComponent::_SetRectangularShape(void *param) 6119 { 6120 if (!AwtToolkit::IsMainThread()) { 6121 AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param); 6122 } else { 6123 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6124 6125 SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param; 6126 jobject self = data->component; 6127 jint x1 = data->x1; 6128 jint x2 = data->x2; 6129 jint y1 = data->y1; 6130 jint y2 = data->y2; 6131 jobject region = data->region; 6132 6133 AwtComponent *c = NULL; 6134 6135 PDATA pData; 6136 JNI_CHECK_PEER_GOTO(self, ret); 6137 6138 c = (AwtComponent *)pData; 6139 if (::IsWindow(c->GetHWnd())) { 6140 HRGN hRgn = NULL; 6141 6142 // If all the params are zeros, the shape must be simply reset. 6143 // Otherwise, convert it into a region. 6144 if (region || x1 || x2 || y1 || y2) { 6145 RECT_T rects[256]; 6146 RECT_T *pRect = rects; 6147 6148 const int numrects = RegionToYXBandedRectangles(env, x1, y1, x2, y2, 6149 region, &pRect, sizeof(rects)/sizeof(rects[0])); 6150 if (!pRect) { 6151 // RegionToYXBandedRectangles doesn't use safe_Malloc(), 6152 // so throw the exception explicitly 6153 throw std::bad_alloc(); 6154 } 6155 6156 RGNDATA *pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(safe_Malloc, 6157 sizeof(RGNDATAHEADER), sizeof(RECT_T), numrects); 6158 memcpy((BYTE*)pRgnData + sizeof(RGNDATAHEADER), pRect, sizeof(RECT_T) * numrects); 6159 if (pRect != rects) { 6160 free(pRect); 6161 } 6162 pRect = NULL; 6163 6164 RGNDATAHEADER *pRgnHdr = (RGNDATAHEADER *) pRgnData; 6165 pRgnHdr->dwSize = sizeof(RGNDATAHEADER); 6166 pRgnHdr->iType = RDH_RECTANGLES; 6167 pRgnHdr->nRgnSize = 0; 6168 pRgnHdr->rcBound.top = 0; 6169 pRgnHdr->rcBound.left = 0; 6170 pRgnHdr->rcBound.bottom = LONG(y2 - y1); 6171 pRgnHdr->rcBound.right = LONG(x2 - x1); 6172 pRgnHdr->nCount = numrects; 6173 6174 hRgn = ::ExtCreateRegion(NULL, 6175 sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData); 6176 6177 free(pRgnData); 6178 } 6179 6180 ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE); 6181 } 6182 6183 ret: 6184 env->DeleteGlobalRef(self); 6185 if (region) { 6186 env->DeleteGlobalRef(region); 6187 } 6188 6189 delete data; 6190 } 6191 } 6192 6193 void AwtComponent::_SetZOrder(void *param) { 6194 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6195 6196 SetZOrderStruct *data = (SetZOrderStruct *)param; 6197 jobject self = data->component; 6198 HWND above = HWND_TOP; 6199 if (data->above != 0) { 6200 above = reinterpret_cast<HWND>(data->above); 6201 } 6202 6203 AwtComponent *c = NULL; 6204 6205 PDATA pData; 6206 JNI_CHECK_PEER_GOTO(self, ret); 6207 6208 c = (AwtComponent *)pData; 6209 if (::IsWindow(c->GetHWnd())) { 6210 ::SetWindowPos(c->GetHWnd(), above, 0, 0, 0, 0, 6211 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS); 6212 } 6213 6214 ret: 6215 env->DeleteGlobalRef(self); 6216 6217 delete data; 6218 } 6219 6220 void AwtComponent::PostUngrabEvent() { 6221 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6222 jobject target = GetTarget(env); 6223 jobject event = JNU_NewObjectByName(env, "sun/awt/UngrabEvent", "(Ljava/awt/Component;)V", 6224 target); 6225 if (safe_ExceptionOccurred(env)) { 6226 env->ExceptionDescribe(); 6227 env->ExceptionClear(); 6228 } 6229 env->DeleteLocalRef(target); 6230 if (event != NULL) { 6231 SendEvent(event); 6232 env->DeleteLocalRef(event); 6233 } 6234 } 6235 6236 void AwtComponent::SetFocusedWindow(HWND window) 6237 { 6238 HWND old = sm_focusedWindow; 6239 sm_focusedWindow = window; 6240 6241 AwtWindow::FocusedWindowChanged(old, window); 6242 } 6243 6244 /************************************************************************ 6245 * Component native methods 6246 */ 6247 6248 extern "C" { 6249 6250 /** 6251 * This method is called from the WGL pipeline when it needs to retrieve 6252 * the HWND associated with a ComponentPeer's C++ level object. 6253 */ 6254 HWND 6255 AwtComponent_GetHWnd(JNIEnv *env, jlong pData) 6256 { 6257 AwtComponent *p = (AwtComponent *)jlong_to_ptr(pData); 6258 if (p == NULL) { 6259 return (HWND)0; 6260 } 6261 return p->GetHWnd(); 6262 } 6263 6264 static void _GetInsets(void* param) 6265 { 6266 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6267 6268 GetInsetsStruct *gis = (GetInsetsStruct *)param; 6269 jobject self = gis->window; 6270 6271 gis->insets->left = gis->insets->top = 6272 gis->insets->right = gis->insets->bottom = 0; 6273 6274 PDATA pData; 6275 JNI_CHECK_PEER_GOTO(self, ret); 6276 AwtComponent *component = (AwtComponent *)pData; 6277 6278 component->GetInsets(gis->insets); 6279 6280 ret: 6281 env->DeleteGlobalRef(self); 6282 delete gis; 6283 } 6284 6285 /** 6286 * This method is called from the WGL pipeline when it needs to retrieve 6287 * the insets associated with a ComponentPeer's C++ level object. 6288 */ 6289 void AwtComponent_GetInsets(JNIEnv *env, jobject peer, RECT *insets) 6290 { 6291 TRY; 6292 6293 GetInsetsStruct *gis = new GetInsetsStruct; 6294 gis->window = env->NewGlobalRef(peer); 6295 gis->insets = insets; 6296 6297 AwtToolkit::GetInstance().InvokeFunction(_GetInsets, gis); 6298 // global refs and mds are deleted in _UpdateWindow 6299 6300 CATCH_BAD_ALLOC; 6301 6302 } 6303 6304 JNIEXPORT void JNICALL 6305 Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) 6306 { 6307 TRY; 6308 jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent"); 6309 jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I"); 6310 jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID); 6311 jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE); 6312 6313 jsize len = env->GetArrayLength(obj); 6314 AwtComponent::masks = SAFE_SIZE_NEW_ARRAY(jint, len); 6315 for (int i = 0; i < len; i++) { 6316 AwtComponent::masks[i] = tmp[i]; 6317 } 6318 env->ReleaseIntArrayElements(obj, tmp, 0); 6319 env->DeleteLocalRef(obj); 6320 6321 /* class ids */ 6322 jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer"); 6323 6324 DASSERT(peerCls); 6325 6326 /* field ids */ 6327 AwtComponent::peerID = 6328 env->GetFieldID(cls, "peer", "Ljava/awt/peer/ComponentPeer;"); 6329 AwtComponent::xID = env->GetFieldID(cls, "x", "I"); 6330 AwtComponent::yID = env->GetFieldID(cls, "y", "I"); 6331 AwtComponent::heightID = env->GetFieldID(cls, "height", "I"); 6332 AwtComponent::widthID = env->GetFieldID(cls, "width", "I"); 6333 AwtComponent::visibleID = env->GetFieldID(cls, "visible", "Z"); 6334 AwtComponent::backgroundID = 6335 env->GetFieldID(cls, "background", "Ljava/awt/Color;"); 6336 AwtComponent::foregroundID = 6337 env->GetFieldID(cls, "foreground", "Ljava/awt/Color;"); 6338 AwtComponent::enabledID = env->GetFieldID(cls, "enabled", "Z"); 6339 AwtComponent::parentID = env->GetFieldID(cls, "parent", "Ljava/awt/Container;"); 6340 AwtComponent::graphicsConfigID = 6341 env->GetFieldID(cls, "graphicsConfig", "Ljava/awt/GraphicsConfiguration;"); 6342 AwtComponent::focusableID = env->GetFieldID(cls, "focusable", "Z"); 6343 6344 AwtComponent::appContextID = env->GetFieldID(cls, "appContext", 6345 "Lsun/awt/AppContext;"); 6346 6347 AwtComponent::peerGCID = env->GetFieldID(peerCls, "winGraphicsConfig", 6348 "Lsun/awt/Win32GraphicsConfig;"); 6349 6350 AwtComponent::hwndID = env->GetFieldID(peerCls, "hwnd", "J"); 6351 6352 AwtComponent::cursorID = env->GetFieldID(cls, "cursor", "Ljava/awt/Cursor;"); 6353 6354 /* method ids */ 6355 AwtComponent::getFontMID = 6356 env->GetMethodID(cls, "getFont_NoClientCode", "()Ljava/awt/Font;"); 6357 AwtComponent::getToolkitMID = 6358 env->GetMethodID(cls, "getToolkitImpl", "()Ljava/awt/Toolkit;"); 6359 AwtComponent::isEnabledMID = env->GetMethodID(cls, "isEnabledImpl", "()Z"); 6360 AwtComponent::getLocationOnScreenMID = 6361 env->GetMethodID(cls, "getLocationOnScreen_NoTreeLock", "()Ljava/awt/Point;"); 6362 AwtComponent::replaceSurfaceDataMID = 6363 env->GetMethodID(peerCls, "replaceSurfaceData", "()V"); 6364 AwtComponent::replaceSurfaceDataLaterMID = 6365 env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V"); 6366 AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V"); 6367 6368 DASSERT(AwtComponent::xID); 6369 DASSERT(AwtComponent::yID); 6370 DASSERT(AwtComponent::heightID); 6371 DASSERT(AwtComponent::widthID); 6372 DASSERT(AwtComponent::visibleID); 6373 DASSERT(AwtComponent::backgroundID); 6374 DASSERT(AwtComponent::foregroundID); 6375 DASSERT(AwtComponent::enabledID); 6376 DASSERT(AwtComponent::parentID); 6377 DASSERT(AwtComponent::hwndID); 6378 6379 DASSERT(AwtComponent::getFontMID); 6380 DASSERT(AwtComponent::getToolkitMID); 6381 DASSERT(AwtComponent::isEnabledMID); 6382 DASSERT(AwtComponent::getLocationOnScreenMID); 6383 DASSERT(AwtComponent::replaceSurfaceDataMID); 6384 DASSERT(AwtComponent::replaceSurfaceDataLaterMID); 6385 DASSERT(AwtComponent::disposeLaterMID); 6386 6387 6388 CATCH_BAD_ALLOC; 6389 } 6390 6391 } /* extern "C" */ 6392 6393 6394 /************************************************************************ 6395 * ComponentPeer native methods 6396 */ 6397 6398 extern "C" { 6399 6400 /* 6401 * Class: sun_awt_windows_WComponentPeer 6402 * Method: pShow 6403 * Signature: ()V 6404 */ 6405 JNIEXPORT void JNICALL 6406 Java_sun_awt_windows_WComponentPeer_pShow(JNIEnv *env, jobject self) 6407 { 6408 TRY; 6409 6410 jobject selfGlobalRef = env->NewGlobalRef(self); 6411 6412 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Show, (void *)selfGlobalRef); 6413 // selfGlobalRef is deleted in _Show 6414 6415 CATCH_BAD_ALLOC; 6416 } 6417 6418 /* 6419 * Class: sun_awt_windows_WComponentPeer 6420 * Method: hide 6421 * Signature: ()V 6422 */ 6423 JNIEXPORT void JNICALL 6424 Java_sun_awt_windows_WComponentPeer_hide(JNIEnv *env, jobject self) 6425 { 6426 TRY; 6427 6428 jobject selfGlobalRef = env->NewGlobalRef(self); 6429 6430 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Hide, (void *)selfGlobalRef); 6431 // selfGlobalRef is deleted in _Hide 6432 6433 CATCH_BAD_ALLOC; 6434 } 6435 6436 /* 6437 * Class: sun_awt_windows_WComponentPeer 6438 * Method: enable 6439 * Signature: ()V 6440 */ 6441 JNIEXPORT void JNICALL 6442 Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self) 6443 { 6444 TRY; 6445 6446 jobject selfGlobalRef = env->NewGlobalRef(self); 6447 6448 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Enable, (void *)selfGlobalRef); 6449 // selfGlobalRef is deleted in _Enable 6450 6451 CATCH_BAD_ALLOC; 6452 } 6453 6454 /* 6455 * Class: sun_awt_windows_WComponentPeer 6456 * Method: disable 6457 * Signature: ()V 6458 */ 6459 JNIEXPORT void JNICALL 6460 Java_sun_awt_windows_WComponentPeer_disable(JNIEnv *env, jobject self) 6461 { 6462 TRY; 6463 6464 jobject selfGlobalRef = env->NewGlobalRef(self); 6465 6466 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Disable, (void *)selfGlobalRef); 6467 // selfGlobalRef is deleted in _Disable 6468 6469 CATCH_BAD_ALLOC; 6470 } 6471 6472 /* 6473 * Class: sun_awt_windows_WComponentPeer 6474 * Method: getLocationOnScreen 6475 * Signature: ()Ljava/awt/Point; 6476 */ 6477 JNIEXPORT jobject JNICALL 6478 Java_sun_awt_windows_WComponentPeer_getLocationOnScreen(JNIEnv *env, jobject self) 6479 { 6480 TRY; 6481 6482 jobject selfGlobalRef = env->NewGlobalRef(self); 6483 6484 jobject resultGlobalRef = (jobject)AwtToolkit::GetInstance().SyncCall( 6485 (void*(*)(void*))AwtComponent::_GetLocationOnScreen, (void *)selfGlobalRef); 6486 // selfGlobalRef is deleted in _GetLocationOnScreen 6487 if (resultGlobalRef != NULL) 6488 { 6489 jobject resultLocalRef = env->NewLocalRef(resultGlobalRef); 6490 env->DeleteGlobalRef(resultGlobalRef); 6491 return resultLocalRef; 6492 } 6493 6494 return NULL; 6495 6496 CATCH_BAD_ALLOC_RET(NULL); 6497 } 6498 6499 /* 6500 * Class: sun_awt_windows_WComponentPeer 6501 * Method: reshape 6502 * Signature: (IIII)V 6503 */ 6504 JNIEXPORT void JNICALL 6505 Java_sun_awt_windows_WComponentPeer_reshape(JNIEnv *env, jobject self, 6506 jint x, jint y, jint w, jint h) 6507 { 6508 TRY; 6509 6510 ReshapeStruct *rs = new ReshapeStruct; 6511 rs->component = env->NewGlobalRef(self); 6512 rs->x = x; 6513 rs->y = y; 6514 rs->w = w; 6515 rs->h = h; 6516 6517 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Reshape, rs); 6518 // global ref and rs are deleted in _Reshape 6519 6520 CATCH_BAD_ALLOC; 6521 } 6522 6523 /* 6524 * Class: sun_awt_windows_WComponentPeer 6525 * Method: reshape 6526 * Signature: (IIII)V 6527 */ 6528 JNIEXPORT void JNICALL 6529 Java_sun_awt_windows_WComponentPeer_reshapeNoCheck(JNIEnv *env, jobject self, 6530 jint x, jint y, jint w, jint h) 6531 { 6532 TRY; 6533 6534 ReshapeStruct *rs = new ReshapeStruct; 6535 rs->component = env->NewGlobalRef(self); 6536 rs->x = x; 6537 rs->y = y; 6538 rs->w = w; 6539 rs->h = h; 6540 6541 AwtToolkit::GetInstance().SyncCall(AwtComponent::_ReshapeNoCheck, rs); 6542 // global ref and rs are deleted in _ReshapeNoCheck 6543 6544 CATCH_BAD_ALLOC; 6545 } 6546 6547 6548 /* 6549 * Class: sun_awt_windows_WComponentPeer 6550 * Method: nativeHandleEvent 6551 * Signature: (Ljava/awt/AWTEvent;)V 6552 */ 6553 JNIEXPORT void JNICALL 6554 Java_sun_awt_windows_WComponentPeer_nativeHandleEvent(JNIEnv *env, 6555 jobject self, 6556 jobject event) 6557 { 6558 TRY; 6559 6560 jobject selfGlobalRef = env->NewGlobalRef(self); 6561 jobject eventGlobalRef = env->NewGlobalRef(event); 6562 6563 NativeHandleEventStruct *nhes = new NativeHandleEventStruct; 6564 nhes->component = selfGlobalRef; 6565 nhes->event = eventGlobalRef; 6566 6567 AwtToolkit::GetInstance().SyncCall(AwtComponent::_NativeHandleEvent, nhes); 6568 // global refs and nhes are deleted in _NativeHandleEvent 6569 6570 CATCH_BAD_ALLOC; 6571 } 6572 6573 /* 6574 * Class: sun_awt_windows_WComponentPeer 6575 * Method: _dispose 6576 * Signature: ()V 6577 */ 6578 JNIEXPORT void JNICALL 6579 Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) 6580 { 6581 TRY_NO_HANG; 6582 6583 AwtObject::_Dispose(self); 6584 6585 CATCH_BAD_ALLOC; 6586 } 6587 6588 /* 6589 * Class: sun_awt_windows_WComponentPeer 6590 * Method: _setForeground 6591 * Signature: (I)V 6592 */ 6593 JNIEXPORT void JNICALL 6594 Java_sun_awt_windows_WComponentPeer__1setForeground(JNIEnv *env, jobject self, 6595 jint rgb) 6596 { 6597 TRY; 6598 6599 jobject selfGlobalRef = env->NewGlobalRef(self); 6600 6601 SetColorStruct *scs = new SetColorStruct; 6602 scs->component = selfGlobalRef; 6603 scs->rgb = rgb; 6604 6605 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetForeground, scs); 6606 // selfGlobalRef and scs are deleted in _SetForeground() 6607 6608 CATCH_BAD_ALLOC; 6609 } 6610 6611 /* 6612 * Class: sun_awt_windows_WComponentPeer 6613 * Method: _setBackground 6614 * Signature: (I)V 6615 */ 6616 JNIEXPORT void JNICALL 6617 Java_sun_awt_windows_WComponentPeer__1setBackground(JNIEnv *env, jobject self, 6618 jint rgb) 6619 { 6620 TRY; 6621 6622 jobject selfGlobalRef = env->NewGlobalRef(self); 6623 6624 SetColorStruct *scs = new SetColorStruct; 6625 scs->component = selfGlobalRef; 6626 scs->rgb = rgb; 6627 6628 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetBackground, scs); 6629 // selfGlobalRef and scs are deleted in _SetBackground() 6630 6631 CATCH_BAD_ALLOC; 6632 } 6633 6634 /* 6635 * Class: sun_awt_windows_WComponentPeer 6636 * Method: _setFont 6637 * Signature: (Ljava/awt/Font;)V 6638 */ 6639 JNIEXPORT void JNICALL 6640 Java_sun_awt_windows_WComponentPeer__1setFont(JNIEnv *env, jobject self, 6641 jobject font) 6642 { 6643 TRY; 6644 6645 jobject selfGlobalRef = env->NewGlobalRef(self); 6646 jobject fontGlobalRef = env->NewGlobalRef(font); 6647 6648 SetFontStruct *sfs = new SetFontStruct; 6649 sfs->component = selfGlobalRef; 6650 sfs->font = fontGlobalRef; 6651 6652 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetFont, sfs); 6653 // global refs and sfs are deleted in _SetFont() 6654 6655 CATCH_BAD_ALLOC; 6656 } 6657 6658 /* 6659 * Class: sun_awt_windows_WComponentPeer 6660 * Method: focusGained 6661 * Signature: (Z) 6662 */ 6663 JNIEXPORT void JNICALL Java_sun_awt_windows_WComponentPeer_setFocus 6664 (JNIEnv *env, jobject self, jboolean doSetFocus) 6665 { 6666 TRY; 6667 6668 jobject selfGlobalRef = env->NewGlobalRef(self); 6669 6670 SetFocusStruct *sfs = new SetFocusStruct; 6671 sfs->component = selfGlobalRef; 6672 sfs->doSetFocus = doSetFocus; 6673 6674 AwtToolkit::GetInstance().SyncCall( 6675 (void*(*)(void*))AwtComponent::_SetFocus, sfs); 6676 // global refs and self are deleted in _SetFocus 6677 6678 CATCH_BAD_ALLOC; 6679 } 6680 6681 /* 6682 * Class: sun_awt_windows_WComponentPeer 6683 * Method: start 6684 * Signature: ()V 6685 */ 6686 JNIEXPORT void JNICALL 6687 Java_sun_awt_windows_WComponentPeer_start(JNIEnv *env, jobject self) 6688 { 6689 TRY; 6690 6691 jobject selfGlobalRef = env->NewGlobalRef(self); 6692 6693 AwtToolkit::GetInstance().SyncCall(AwtComponent::_Start, (void *)selfGlobalRef); 6694 // selfGlobalRef is deleted in _Start 6695 6696 CATCH_BAD_ALLOC; 6697 } 6698 6699 /* 6700 * Class: sun_awt_windows_WComponentPeer 6701 * Method: beginValidate 6702 * Signature: ()V 6703 */ 6704 JNIEXPORT void JNICALL 6705 Java_sun_awt_windows_WComponentPeer_beginValidate(JNIEnv *env, jobject self) 6706 { 6707 TRY; 6708 6709 jobject selfGlobalRef = env->NewGlobalRef(self); 6710 6711 AwtToolkit::GetInstance().SyncCall(AwtComponent::_BeginValidate, (void *)selfGlobalRef); 6712 // selfGlobalRef is deleted in _BeginValidate 6713 6714 CATCH_BAD_ALLOC; 6715 } 6716 6717 /* 6718 * Class: sun_awt_windows_WComponentPeer 6719 * Method: endValidate 6720 * Signature: ()V 6721 */ 6722 JNIEXPORT void JNICALL 6723 Java_sun_awt_windows_WComponentPeer_endValidate(JNIEnv *env, jobject self) 6724 { 6725 TRY; 6726 6727 jobject selfGlobalRef = env->NewGlobalRef(self); 6728 6729 AwtToolkit::GetInstance().SyncCall(AwtComponent::_EndValidate, (void *)selfGlobalRef); 6730 // selfGlobalRef is deleted in _EndValidate 6731 6732 CATCH_BAD_ALLOC; 6733 } 6734 6735 JNIEXPORT void JNICALL 6736 Java_sun_awt_windows_WComponentPeer_updateWindow(JNIEnv *env, jobject self) 6737 { 6738 TRY; 6739 6740 jobject selfGlobalRef = env->NewGlobalRef(self); 6741 6742 AwtToolkit::GetInstance().SyncCall(AwtComponent::_UpdateWindow, (void *)selfGlobalRef); 6743 // selfGlobalRef is deleted in _UpdateWindow 6744 6745 CATCH_BAD_ALLOC; 6746 } 6747 6748 /* 6749 * Class: sun_awt_windows_WComponentPeer 6750 * Method: addNativeDropTarget 6751 * Signature: ()L 6752 */ 6753 6754 JNIEXPORT jlong JNICALL 6755 Java_sun_awt_windows_WComponentPeer_addNativeDropTarget(JNIEnv *env, 6756 jobject self) 6757 { 6758 TRY; 6759 6760 jobject selfGlobalRef = env->NewGlobalRef(self); 6761 6762 return ptr_to_jlong(AwtToolkit::GetInstance().SyncCall( 6763 (void*(*)(void*))AwtComponent::_AddNativeDropTarget, 6764 (void *)selfGlobalRef)); 6765 // selfGlobalRef is deleted in _AddNativeDropTarget 6766 6767 CATCH_BAD_ALLOC_RET(0); 6768 } 6769 6770 /* 6771 * Class: sun_awt_windows_WComponentPeer 6772 * Method: removeNativeDropTarget 6773 * Signature: ()V 6774 */ 6775 6776 JNIEXPORT void JNICALL 6777 Java_sun_awt_windows_WComponentPeer_removeNativeDropTarget(JNIEnv *env, 6778 jobject self) 6779 { 6780 TRY; 6781 6782 jobject selfGlobalRef = env->NewGlobalRef(self); 6783 6784 AwtToolkit::GetInstance().SyncCall( 6785 AwtComponent::_RemoveNativeDropTarget, (void *)selfGlobalRef); 6786 // selfGlobalRef is deleted in _RemoveNativeDropTarget 6787 6788 CATCH_BAD_ALLOC; 6789 } 6790 6791 /* 6792 * Class: sun_awt_windows_WComponentPeer 6793 * Method: getTargetGC 6794 * Signature: ()Ljava/awt/GraphicsConfiguration; 6795 */ 6796 JNIEXPORT jobject JNICALL 6797 Java_sun_awt_windows_WComponentPeer_getTargetGC(JNIEnv* env, jobject theThis) 6798 { 6799 TRY; 6800 6801 jobject targetObj; 6802 jobject gc = 0; 6803 6804 targetObj = env->GetObjectField(theThis, AwtObject::targetID); 6805 DASSERT(targetObj); 6806 6807 gc = env->GetObjectField(targetObj, AwtComponent::graphicsConfigID); 6808 return gc; 6809 6810 CATCH_BAD_ALLOC_RET(NULL); 6811 } 6812 6813 /* 6814 * Class: sun_awt_windows_WComponentPeer 6815 * Method: createPrintedPixels 6816 * Signature: (IIIIII)I[ 6817 */ 6818 JNIEXPORT jintArray JNICALL 6819 Java_sun_awt_windows_WComponentPeer_createPrintedPixels(JNIEnv* env, 6820 jobject self, jint srcX, jint srcY, jint srcW, jint srcH, jint alpha) 6821 { 6822 TRY; 6823 6824 jobject selfGlobalRef = env->NewGlobalRef(self); 6825 6826 CreatePrintedPixelsStruct *cpps = new CreatePrintedPixelsStruct; 6827 cpps->component = selfGlobalRef; 6828 cpps->srcx = srcX; 6829 cpps->srcy = srcY; 6830 cpps->srcw = srcW; 6831 cpps->srch = srcH; 6832 cpps->alpha = alpha; 6833 6834 jintArray globalRef = (jintArray)AwtToolkit::GetInstance().SyncCall( 6835 (void*(*)(void*))AwtComponent::_CreatePrintedPixels, cpps); 6836 // selfGlobalRef and cpps are deleted in _CreatePrintedPixels 6837 if (globalRef != NULL) 6838 { 6839 jintArray localRef = (jintArray)env->NewLocalRef(globalRef); 6840 env->DeleteGlobalRef(globalRef); 6841 return localRef; 6842 } 6843 else 6844 { 6845 return NULL; 6846 } 6847 6848 CATCH_BAD_ALLOC_RET(NULL); 6849 } 6850 6851 /* 6852 * Class: sun_awt_windows_WComponentPeer 6853 * Method: nativeHandlesWheelScrolling 6854 * Signature: ()Z 6855 */ 6856 JNIEXPORT jboolean JNICALL 6857 Java_sun_awt_windows_WComponentPeer_nativeHandlesWheelScrolling (JNIEnv* env, 6858 jobject self) 6859 { 6860 TRY; 6861 6862 return (jboolean)AwtToolkit::GetInstance().SyncCall( 6863 (void *(*)(void *))AwtComponent::_NativeHandlesWheelScrolling, 6864 env->NewGlobalRef(self)); 6865 // global ref is deleted in _NativeHandlesWheelScrolling 6866 6867 CATCH_BAD_ALLOC_RET(NULL); 6868 } 6869 6870 /* 6871 * Class: sun_awt_windows_WComponentPeer 6872 * Method: isObscured 6873 * Signature: ()Z 6874 */ 6875 JNIEXPORT jboolean JNICALL 6876 Java_sun_awt_windows_WComponentPeer_isObscured(JNIEnv* env, 6877 jobject self) 6878 { 6879 TRY; 6880 6881 jobject selfGlobalRef = env->NewGlobalRef(self); 6882 6883 return (jboolean)AwtToolkit::GetInstance().SyncCall( 6884 (void*(*)(void*))AwtComponent::_IsObscured, 6885 (void *)selfGlobalRef); 6886 // selfGlobalRef is deleted in _IsObscured 6887 6888 CATCH_BAD_ALLOC_RET(NULL); 6889 } 6890 6891 JNIEXPORT void JNICALL 6892 Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) { 6893 TRY; 6894 6895 typedef AwtComponent* PComponent; 6896 AwtComponent** comps = new PComponent[2]; 6897 AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(self); 6898 AwtComponent* parentComp = (AwtComponent*)JNI_GET_PDATA(parent); 6899 comps[0] = comp; 6900 comps[1] = parentComp; 6901 6902 AwtToolkit::GetInstance().SyncCall(AwtComponent::SetParent, comps); 6903 // comps is deleted in SetParent 6904 6905 CATCH_BAD_ALLOC; 6906 } 6907 6908 JNIEXPORT void JNICALL 6909 Java_sun_awt_windows_WComponentPeer_setRectangularShape(JNIEnv* env, jobject self, 6910 jint x1, jint y1, jint x2, jint y2, jobject region) 6911 { 6912 TRY; 6913 6914 SetRectangularShapeStruct * data = new SetRectangularShapeStruct; 6915 data->component = env->NewGlobalRef(self); 6916 data->x1 = x1; 6917 data->x2 = x2; 6918 data->y1 = y1; 6919 data->y2 = y2; 6920 if (region) { 6921 data->region = env->NewGlobalRef(region); 6922 } else { 6923 data->region = NULL; 6924 } 6925 6926 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetRectangularShape, data); 6927 // global refs and data are deleted in _SetRectangularShape 6928 6929 CATCH_BAD_ALLOC; 6930 } 6931 6932 JNIEXPORT void JNICALL 6933 Java_sun_awt_windows_WComponentPeer_setZOrder(JNIEnv* env, jobject self, jlong above) 6934 { 6935 TRY; 6936 6937 SetZOrderStruct * data = new SetZOrderStruct; 6938 data->component = env->NewGlobalRef(self); 6939 data->above = above; 6940 6941 AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetZOrder, data); 6942 // global refs and data are deleted in _SetLower 6943 6944 CATCH_BAD_ALLOC; 6945 } 6946 6947 } /* extern "C" */ 6948 6949 6950 /************************************************************************ 6951 * Diagnostic routines 6952 */ 6953 6954 #ifdef DEBUG 6955 6956 void AwtComponent::VerifyState() 6957 { 6958 if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) { 6959 return; 6960 } 6961 6962 if (m_callbacksEnabled == FALSE) { 6963 /* Component is not fully setup yet. */ 6964 return; 6965 } 6966 6967 /* Get target bounds. */ 6968 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 6969 if (env->PushLocalFrame(10) < 0) 6970 return; 6971 6972 jobject target = GetTarget(env); 6973 6974 jint x = env->GetIntField(target, AwtComponent::xID); 6975 jint y = env->GetIntField(target, AwtComponent::yID); 6976 jint width = env->GetIntField(target, AwtComponent::widthID); 6977 jint height = env->GetIntField(target, AwtComponent::heightID); 6978 6979 /* Convert target origin to absolute coordinates */ 6980 while (TRUE) { 6981 6982 jobject parent = env->GetObjectField(target, AwtComponent::parentID); 6983 if (parent == NULL) { 6984 break; 6985 } 6986 x += env->GetIntField(parent, AwtComponent::xID); 6987 y += env->GetIntField(parent, AwtComponent::yID); 6988 6989 /* If this component has insets, factor them in, but ignore 6990 * top-level windows. 6991 */ 6992 jobject parent2 = env->GetObjectField(parent, AwtComponent::parentID); 6993 if (parent2 != NULL) { 6994 jobject peer = GetPeerForTarget(env, parent); 6995 if (peer != NULL && 6996 JNU_IsInstanceOfByName(env, peer, 6997 "sun/awt/windows/WPanelPeer") > 0) { 6998 jobject insets = 6999 JNU_CallMethodByName(env, NULL, peer,"insets", 7000 "()Ljava/awt/Insets;").l; 7001 x += (env)->GetIntField(insets, AwtInsets::leftID); 7002 y += (env)->GetIntField(insets, AwtInsets::topID); 7003 } 7004 } 7005 env->DeleteLocalRef(target); 7006 target = parent; 7007 } 7008 7009 // Test whether component's bounds match the native window's 7010 RECT rect; 7011 VERIFY(::GetWindowRect(GetHWnd(), &rect)); 7012 #if 0 7013 DASSERT( (x == rect.left) && 7014 (y == rect.top) && 7015 (width == (rect.right-rect.left)) && 7016 (height == (rect.bottom-rect.top)) ); 7017 #else 7018 BOOL fSizeValid = ( (x == rect.left) && 7019 (y == rect.top) && 7020 (width == (rect.right-rect.left)) && 7021 (height == (rect.bottom-rect.top)) ); 7022 #endif 7023 7024 // See if visible state matches 7025 BOOL wndVisible = ::IsWindowVisible(GetHWnd()); 7026 jboolean targetVisible; 7027 // To avoid possibly running client code on the toolkit thread, don't 7028 // do the following check if we're running on the toolkit thread. 7029 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7030 targetVisible = JNU_CallMethodByName(env, NULL, GetTarget(env), 7031 "isShowing", "()Z").z; 7032 DASSERT(!safe_ExceptionOccurred(env)); 7033 } else { 7034 targetVisible = wndVisible ? 1 : 0; 7035 } 7036 #if 0 7037 DASSERT( (targetVisible && wndVisible) || 7038 (!targetVisible && !wndVisible) ); 7039 #else 7040 BOOL fVisibleValid = ( (targetVisible && wndVisible) || 7041 (!targetVisible && !wndVisible) ); 7042 #endif 7043 7044 // Check enabled state 7045 BOOL wndEnabled = ::IsWindowEnabled(GetHWnd()); 7046 jboolean enabled = (jboolean)env->GetBooleanField(target, 7047 AwtComponent::enabledID); 7048 #if 0 7049 DASSERT( (enabled && wndEnabled) || 7050 (!enabled && !wndEnabled) ); 7051 #else 7052 BOOL fEnabledValid = ((enabled && wndEnabled) || 7053 (!(enabled && !wndEnabled) )); 7054 7055 if (!fSizeValid || !fVisibleValid || !fEnabledValid) { 7056 printf("AwtComponent::ValidateState() failed:\n"); 7057 // To avoid possibly running client code on the toolkit thread, don't 7058 // do the following call if we're running on the toolkit thread. 7059 if (AwtToolkit::MainThread() != ::GetCurrentThreadId()) { 7060 jstring targetStr = 7061 (jstring)JNU_CallMethodByName(env, NULL, GetTarget(env), 7062 "getName", 7063 "()Ljava/lang/String;").l; 7064 DASSERT(!safe_ExceptionOccurred(env)); 7065 LPCWSTR targetStrW = JNU_GetStringPlatformChars(env, targetStr, NULL); 7066 printf("\t%S\n", targetStrW); 7067 JNU_ReleaseStringPlatformChars(env, targetStr, targetStrW); 7068 } 7069 printf("\twas: [%d,%d,%dx%d]\n", x, y, width, height); 7070 if (!fSizeValid) { 7071 printf("\tshould be: [%d,%d,%dx%d]\n", rect.left, rect.top, 7072 rect.right-rect.left, rect.bottom-rect.top); 7073 } 7074 if (!fVisibleValid) { 7075 printf("\tshould be: %s\n", 7076 (targetVisible) ? "visible" : "hidden"); 7077 } 7078 if (!fEnabledValid) { 7079 printf("\tshould be: %s\n", 7080 enabled ? "enabled" : "disabled"); 7081 } 7082 } 7083 #endif 7084 env->PopLocalFrame(0); 7085 } 7086 #endif //DEBUG 7087 7088 // Methods for globally managed DC list 7089 7090 /** 7091 * Add a new DC to the DC list for this component. 7092 */ 7093 void DCList::AddDC(HDC hDC, HWND hWnd) 7094 { 7095 DCItem *newItem = new DCItem; 7096 newItem->hDC = hDC; 7097 newItem->hWnd = hWnd; 7098 AddDCItem(newItem); 7099 } 7100 7101 void DCList::AddDCItem(DCItem *newItem) 7102 { 7103 listLock.Enter(); 7104 newItem->next = head; 7105 head = newItem; 7106 listLock.Leave(); 7107 } 7108 7109 /** 7110 * Given a DC, remove it from the DC list and return 7111 * TRUE if it exists on the current list. Otherwise 7112 * return FALSE. 7113 * A DC may not exist on the list because it has already 7114 * been released elsewhere (for example, the window 7115 * destruction process may release a DC while a rendering 7116 * thread may also want to release a DC when it notices that 7117 * its DC is obsolete for the current window). 7118 */ 7119 DCItem *DCList::RemoveDC(HDC hDC) 7120 { 7121 listLock.Enter(); 7122 DCItem **prevPtrPtr = &head; 7123 DCItem *listPtr = head; 7124 while (listPtr) { 7125 DCItem *nextPtr = listPtr->next; 7126 if (listPtr->hDC == hDC) { 7127 *prevPtrPtr = nextPtr; 7128 break; 7129 } 7130 prevPtrPtr = &listPtr->next; 7131 listPtr = nextPtr; 7132 } 7133 listLock.Leave(); 7134 return listPtr; 7135 } 7136 7137 /** 7138 * Remove all DCs from the DC list which are associated with 7139 * the same window as hWnd. Return the list of those 7140 * DC's to the caller (which will then probably want to 7141 * call ReleaseDC() for the returned DCs). 7142 */ 7143 DCItem *DCList::RemoveAllDCs(HWND hWnd) 7144 { 7145 listLock.Enter(); 7146 DCItem **prevPtrPtr = &head; 7147 DCItem *listPtr = head; 7148 DCItem *newListPtr = NULL; 7149 BOOL ret = FALSE; 7150 while (listPtr) { 7151 DCItem *nextPtr = listPtr->next; 7152 if (listPtr->hWnd == hWnd) { 7153 *prevPtrPtr = nextPtr; 7154 listPtr->next = newListPtr; 7155 newListPtr = listPtr; 7156 } else { 7157 prevPtrPtr = &listPtr->next; 7158 } 7159 listPtr = nextPtr; 7160 } 7161 listLock.Leave(); 7162 return newListPtr; 7163 } 7164 7165 7166 /** 7167 * Realize palettes of all existing HDC objects 7168 */ 7169 void DCList::RealizePalettes(int screen) 7170 { 7171 listLock.Enter(); 7172 DCItem *listPtr = head; 7173 while (listPtr) { 7174 AwtWin32GraphicsDevice::RealizePalette(listPtr->hDC, screen); 7175 listPtr = listPtr->next; 7176 } 7177 listLock.Leave(); 7178 } 7179 7180 void MoveDCToPassiveList(HDC hDC) { 7181 DCItem *removedDC; 7182 if ((removedDC = activeDCList.RemoveDC(hDC)) != NULL) { 7183 passiveDCList.AddDCItem(removedDC); 7184 } 7185 } 7186 7187 void ReleaseDCList(HWND hwnd, DCList &list) { 7188 DCItem *removedDCs = list.RemoveAllDCs(hwnd); 7189 while (removedDCs) { 7190 DCItem *tmpDCList = removedDCs; 7191 DASSERT(::GetObjectType(tmpDCList->hDC) == OBJ_DC); 7192 int retValue = ::ReleaseDC(tmpDCList->hWnd, tmpDCList->hDC); 7193 VERIFY(retValue != 0); 7194 if (retValue != 0) { 7195 // Valid ReleaseDC call; need to decrement GDI object counter 7196 AwtGDIObject::Decrement(); 7197 } 7198 removedDCs = removedDCs->next; 7199 delete tmpDCList; 7200 } 7201 } 7202