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