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