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_Checkbox.cpp
41153 views
1
/*
2
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include "awt.h"
27
#include "awt_Toolkit.h"
28
#include "awt_Checkbox.h"
29
#include "awt_Canvas.h"
30
#include "awt_Window.h"
31
32
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
33
*/
34
35
/***********************************************************************/
36
// Struct for _SetLabel() method
37
struct SetLabelStruct {
38
jobject checkbox;
39
jstring label;
40
};
41
// Struct for _SetState() method
42
struct SetStateStruct {
43
jobject checkbox;
44
jboolean state;
45
};
46
47
/************************************************************************
48
* AwtCheckbox fields
49
*/
50
51
/* java.awt.Checkbox field IDs */
52
jfieldID AwtCheckbox::labelID;
53
jfieldID AwtCheckbox::groupID;
54
jfieldID AwtCheckbox::stateID;
55
56
const int AwtCheckbox::CHECK_SIZE = 13;
57
58
/************************************************************************
59
* AwtCheckbox methods
60
*/
61
62
AwtCheckbox::AwtCheckbox() {
63
64
m_fLButtonDowned = FALSE;
65
}
66
67
LPCTSTR AwtCheckbox::GetClassName() {
68
return TEXT("BUTTON"); /* System provided checkbox class (a type of button) */
69
}
70
71
AwtCheckbox* AwtCheckbox::Create(jobject peer, jobject parent)
72
{
73
DASSERT(AwtToolkit::IsMainThread());
74
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
75
76
jstring label = NULL;
77
jobject target = NULL;
78
AwtCheckbox *checkbox = NULL;
79
80
try {
81
if (env->EnsureLocalCapacity(2) < 0) {
82
return NULL;
83
}
84
85
PDATA pData;
86
AwtComponent* awtParent;
87
JNI_CHECK_PEER_GOTO(parent, done);
88
awtParent = (AwtCanvas*)pData;
89
90
target = env->GetObjectField(peer, AwtObject::targetID);
91
JNI_CHECK_NULL_GOTO(target, "null target", done);
92
93
checkbox = new AwtCheckbox();
94
95
{
96
DWORD style = WS_CHILD | WS_CLIPSIBLINGS | BS_OWNERDRAW;
97
LPCWSTR defaultLabelStr = L"";
98
LPCWSTR labelStr = defaultLabelStr;
99
DWORD exStyle = 0;
100
101
if (GetRTL()) {
102
exStyle |= WS_EX_RIGHT;
103
if (GetRTLReadingOrder())
104
exStyle |= WS_EX_RTLREADING;
105
}
106
107
label = (jstring)env->GetObjectField(target, AwtCheckbox::labelID);
108
if (label != NULL) {
109
labelStr = JNU_GetStringPlatformChars(env, label, 0);
110
}
111
if (labelStr != 0) {
112
jint x = env->GetIntField(target, AwtComponent::xID);
113
jint y = env->GetIntField(target, AwtComponent::yID);
114
jint width = env->GetIntField(target, AwtComponent::widthID);
115
jint height = env->GetIntField(target, AwtComponent::heightID);
116
checkbox->CreateHWnd(env, labelStr, style, exStyle,
117
x, y, width, height,
118
awtParent->GetHWnd(),
119
reinterpret_cast<HMENU>(static_cast<INT_PTR>(
120
awtParent->CreateControlID())),
121
::GetSysColor(COLOR_WINDOWTEXT),
122
::GetSysColor(COLOR_BTNFACE),
123
peer);
124
125
if (labelStr != defaultLabelStr) {
126
JNU_ReleaseStringPlatformChars(env, label, labelStr);
127
}
128
} else {
129
throw std::bad_alloc();
130
}
131
}
132
} catch (...) {
133
env->DeleteLocalRef(label);
134
env->DeleteLocalRef(target);
135
throw;
136
}
137
138
done:
139
env->DeleteLocalRef(label);
140
env->DeleteLocalRef(target);
141
142
return checkbox;
143
}
144
145
MsgRouting
146
AwtCheckbox::WmMouseUp(UINT flags, int x, int y, int button)
147
{
148
MsgRouting mrResult = AwtComponent::WmMouseUp(flags, x, y, button);
149
150
if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd()))))
151
{
152
return mrConsume;
153
}
154
155
POINT p = {x, y};
156
RECT rect;
157
::GetClientRect(GetHWnd(), &rect);
158
159
if (::PtInRect(&rect, p) && button == LEFT_BUTTON && m_fLButtonDowned) {
160
WmNotify(BN_CLICKED);
161
}
162
m_fLButtonDowned = FALSE;
163
return mrResult;
164
}
165
166
MsgRouting
167
AwtCheckbox::WmMouseDown(UINT flags, int x, int y, int button)
168
{
169
m_fLButtonDowned = TRUE;
170
return AwtComponent::WmMouseDown(flags, x, y, button);
171
}
172
173
MsgRouting
174
AwtCheckbox::WmNotify(UINT notifyCode)
175
{
176
if (notifyCode == BN_CLICKED) {
177
BOOL fChecked = !GetState();
178
DoCallback("handleAction", "(Z)V", fChecked);
179
}
180
return mrDoDefault;
181
}
182
183
BOOL AwtCheckbox::GetState()
184
{
185
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
186
187
if (env->EnsureLocalCapacity(2) < 0) {
188
return NULL;
189
}
190
jobject target = GetTarget(env);
191
jboolean result = JNI_FALSE;
192
if (target != NULL) {
193
result = env->GetBooleanField(target, AwtCheckbox::stateID);
194
}
195
196
env->DeleteLocalRef(target);
197
198
return (BOOL)result;
199
}
200
201
int AwtCheckbox::GetCheckSize()
202
{
203
/* using height of small icon for check mark size */
204
return CHECK_SIZE;
205
}
206
207
MsgRouting
208
AwtCheckbox::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo)
209
{
210
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
211
212
if (env->EnsureLocalCapacity(4) < 0) {
213
return mrConsume;
214
}
215
216
jobject self = GetPeer(env);
217
jobject target = env->GetObjectField(self, AwtObject::targetID);
218
219
HDC hDC = drawInfo.hDC;
220
RECT rect = drawInfo.rcItem;
221
int checkSize;
222
UINT nState;
223
SIZE size;
224
225
jobject font = GET_FONT(target, self);
226
jstring str = (jstring)env->GetObjectField(target, AwtCheckbox::labelID);
227
size = AwtFont::getMFStringSize(hDC, font, str);
228
229
jobject group = env->GetObjectField(target, AwtCheckbox::groupID);
230
if (group != NULL)
231
nState = DFCS_BUTTONRADIO;
232
else
233
nState = DFCS_BUTTONCHECK;
234
235
if (GetState())
236
nState |= DFCS_CHECKED;
237
else
238
nState &= ~DFCS_CHECKED;
239
240
if (drawInfo.itemState & ODS_SELECTED)
241
nState |= DFCS_PUSHED;
242
243
if (drawInfo.itemAction & ODA_DRAWENTIRE) {
244
VERIFY(::FillRect (hDC, &rect, GetBackgroundBrush()));
245
}
246
247
/* draw check mark */
248
checkSize = GetCheckSize();
249
RECT boxRect;
250
251
boxRect.left = (GetRTL()) ? rect.right - checkSize : rect.left;
252
boxRect.top = (rect.bottom - rect.top - checkSize)/2;
253
boxRect.right = boxRect.left + checkSize;
254
boxRect.bottom = boxRect.top + checkSize;
255
::DrawFrameControl(hDC, &boxRect, DFC_BUTTON, nState);
256
257
/*
258
* draw string
259
*
260
* 4 is a heuristic number
261
*/
262
rect.left = rect.left + checkSize + checkSize/4;
263
if (drawInfo.itemAction & ODA_DRAWENTIRE) {
264
BOOL bEnabled = isEnabled();
265
266
int x = (GetRTL()) ? rect.right - (checkSize + checkSize / 4 + size.cx)
267
: rect.left;
268
int y = (rect.top + rect.bottom - size.cy) / 2;
269
if (bEnabled) {
270
AwtComponent::DrawWindowText(hDC, font, str, x, y);
271
} else {
272
AwtComponent::DrawGrayText(hDC, font, str, x, y);
273
}
274
}
275
276
/* Draw focus rect */
277
RECT focusRect;
278
const int margin = 2; /* 2 is a heuristic number */
279
280
focusRect.left = (GetRTL()) ? rect.right - checkSize - checkSize / 4 -
281
2 * margin - size.cx
282
: rect.left - margin;
283
focusRect.top = (rect.top+rect.bottom-size.cy)/2;
284
focusRect.right = (GetRTL()) ? rect.right - checkSize - checkSize / 4 +
285
margin
286
: focusRect.left + size.cx + 2 * margin;
287
focusRect.bottom = focusRect.top + size.cy;
288
289
/* draw focus rect */
290
if ((drawInfo.itemState & ODS_FOCUS) &&
291
((drawInfo.itemAction & ODA_FOCUS)||
292
(drawInfo.itemAction &ODA_DRAWENTIRE))) {
293
if(::DrawFocusRect(hDC, &focusRect) == 0)
294
VERIFY(::GetLastError() == 0);
295
}
296
/* erase focus rect */
297
else if (!(drawInfo.itemState & ODS_FOCUS) &&
298
(drawInfo.itemAction & ODA_FOCUS)) {
299
if(::DrawFocusRect(hDC, &focusRect) == 0)
300
VERIFY(::GetLastError() == 0);
301
}
302
303
/* Notify any subclasses */
304
rect = drawInfo.rcItem;
305
DoCallback("handlePaint", "(IIII)V", rect.left, rect.top,
306
rect.right-rect.left, rect.bottom-rect.top);
307
308
env->DeleteLocalRef(target);
309
env->DeleteLocalRef(font);
310
env->DeleteLocalRef(str);
311
env->DeleteLocalRef(group);
312
313
return mrConsume;
314
}
315
316
MsgRouting AwtCheckbox::WmPaint(HDC)
317
{
318
/* Suppress peer notification, because it's handled in WmDrawItem. */
319
return mrDoDefault;
320
}
321
322
BOOL AwtCheckbox::IsFocusingMouseMessage(MSG *pMsg) {
323
return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP;
324
}
325
326
BOOL AwtCheckbox::IsFocusingKeyMessage(MSG *pMsg) {
327
return (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) &&
328
pMsg->wParam == VK_SPACE;
329
}
330
331
MsgRouting AwtCheckbox::HandleEvent(MSG *msg, BOOL synthetic)
332
{
333
if (IsFocusingMouseMessage(msg)) {
334
SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_LBUTTONDOWN ? TRUE : FALSE));
335
delete msg;
336
return mrConsume;
337
}
338
if (IsFocusingKeyMessage(msg)) {
339
SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_KEYDOWN ? TRUE : FALSE));
340
if (msg->message == WM_KEYDOWN) {
341
m_fLButtonDowned = TRUE;
342
} else if (m_fLButtonDowned == TRUE) {
343
WmNotify(BN_CLICKED);
344
m_fLButtonDowned = TRUE;
345
}
346
delete msg;
347
return mrConsume;
348
}
349
return AwtComponent::HandleEvent(msg, synthetic);
350
}
351
352
void AwtCheckbox::_SetLabel(void *param)
353
{
354
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
355
356
SetLabelStruct *sls = (SetLabelStruct *)param;
357
jobject checkbox = sls->checkbox;
358
jstring label = sls->label;
359
360
int badAlloc = 0;
361
AwtCheckbox *c = NULL;
362
363
PDATA pData;
364
JNI_CHECK_PEER_GOTO(checkbox, done);
365
366
c = (AwtCheckbox *)pData;
367
if (::IsWindow(c->GetHWnd()))
368
{
369
LPCTSTR labelStr = NULL;
370
371
// By convension null label means empty string
372
if (label == NULL)
373
{
374
labelStr = TEXT("");
375
}
376
else
377
{
378
labelStr = JNU_GetStringPlatformChars(env, label, JNI_FALSE);
379
}
380
381
if (labelStr == NULL)
382
{
383
badAlloc = 1;
384
}
385
else
386
{
387
c->SetText(labelStr);
388
c->VerifyState();
389
if (label != NULL) {
390
JNU_ReleaseStringPlatformChars(env, label, labelStr);
391
}
392
}
393
}
394
395
done:
396
env->DeleteGlobalRef(checkbox);
397
if (label != NULL)
398
{
399
env->DeleteGlobalRef(label);
400
}
401
402
delete sls;
403
404
if (badAlloc) {
405
throw std::bad_alloc();
406
}
407
}
408
409
void AwtCheckbox::_SetCheckboxGroup(void *param)
410
{
411
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
412
413
jobject *jos = (jobject *)param;
414
jobject checkbox = jos[0];
415
jobject group = jos[1];
416
417
AwtCheckbox *c = NULL;
418
419
PDATA pData;
420
JNI_CHECK_PEER_GOTO(checkbox, done);
421
422
c = (AwtCheckbox *)pData;
423
if (::IsWindow(c->GetHWnd()))
424
{
425
/*
426
#ifdef DEBUG
427
if (group != NULL) {
428
DASSERT(IsInstanceOf((HObject*)group, "java/awt/CheckboxGroup"));
429
}
430
#endif
431
*/
432
long style = c->GetStyle();
433
if (group == NULL) {
434
style = style & ~BS_AUTORADIOBUTTON;
435
style = style | BS_AUTOCHECKBOX;
436
} else {
437
style = style & ~BS_AUTOCHECKBOX;
438
style = style | BS_AUTORADIOBUTTON;
439
}
440
c->SetStyle(style);
441
c->SendMessage(BM_SETSTYLE, (WPARAM)BS_OWNERDRAW, (LPARAM)TRUE);
442
c->VerifyState();
443
}
444
445
done:
446
env->DeleteGlobalRef(checkbox);
447
if (group != NULL) {
448
env->DeleteGlobalRef(group);
449
}
450
451
delete[] jos;
452
}
453
454
void AwtCheckbox::_SetState(void *param)
455
{
456
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
457
458
SetStateStruct *sss = (SetStateStruct *)param;
459
jobject checkbox = sss->checkbox;
460
jboolean state = sss->state;
461
462
AwtCheckbox *c = NULL;
463
464
PDATA pData;
465
JNI_CHECK_PEER_GOTO(checkbox, done);
466
467
c = (AwtCheckbox *)pData;
468
if (::IsWindow(c->GetHWnd()))
469
{
470
/*
471
* when multifont and group checkbox receive setState native
472
* method, it must be redraw to display correct check mark
473
*/
474
jobject target = env->GetObjectField(checkbox, AwtObject::targetID);
475
jobject group = env->GetObjectField(target, AwtCheckbox::groupID);
476
HWND hWnd = c->GetHWnd();
477
if (group != NULL) {
478
RECT rect;
479
VERIFY(::GetWindowRect(hWnd, &rect));
480
VERIFY(::ScreenToClient(hWnd, (LPPOINT)&rect));
481
VERIFY(::ScreenToClient(hWnd, ((LPPOINT)&rect) + 1));
482
VERIFY(::InvalidateRect(hWnd, &rect,TRUE));
483
VERIFY(::UpdateWindow(hWnd));
484
} else {
485
c->SendMessage(BM_SETCHECK, (WPARAM)(state ? BST_CHECKED : BST_UNCHECKED));
486
VERIFY(::InvalidateRect(hWnd, NULL, FALSE));
487
}
488
c->VerifyState();
489
env->DeleteLocalRef(target);
490
env->DeleteLocalRef(group);
491
}
492
493
done:
494
env->DeleteGlobalRef(checkbox);
495
496
delete sss;
497
}
498
499
#ifdef DEBUG
500
void AwtCheckbox::VerifyState()
501
{
502
if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) {
503
return;
504
}
505
506
if (m_callbacksEnabled == FALSE) {
507
/* Component is not fully setup yet. */
508
return;
509
}
510
511
AwtComponent::VerifyState();
512
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
513
514
if (env->EnsureLocalCapacity(2) < 0) {
515
return;
516
}
517
518
jobject target = GetTarget(env);
519
520
/* Check button style */
521
DWORD style = ::GetWindowLong(GetHWnd(), GWL_STYLE);
522
DASSERT(style & BS_OWNERDRAW);
523
524
/* Check label */
525
int len = ::GetWindowTextLength(GetHWnd());
526
LPTSTR peerStr;
527
try {
528
peerStr = new TCHAR[len+1];
529
} catch (std::bad_alloc&) {
530
env->DeleteLocalRef(target);
531
throw;
532
}
533
534
GetText(peerStr, len+1);
535
jstring label = (jstring)env->GetObjectField(target, AwtCheckbox::labelID);
536
DASSERT(_tcscmp(peerStr, JavaStringBuffer(env, label)) == 0);
537
delete [] peerStr;
538
539
env->DeleteLocalRef(target);
540
env->DeleteLocalRef(label);
541
}
542
#endif
543
544
545
/************************************************************************
546
* Checkbox native methods
547
*/
548
549
extern "C" {
550
551
/*
552
* Class: sun_awt_windows_WButtonPeer
553
* Method: initIDs
554
* Signature: ()V
555
*/
556
JNIEXPORT void JNICALL
557
Java_java_awt_Checkbox_initIDs(JNIEnv *env, jclass cls)
558
{
559
TRY;
560
561
AwtCheckbox::labelID =
562
env->GetFieldID(cls, "label", "Ljava/lang/String;");
563
DASSERT(AwtCheckbox::labelID != NULL);
564
CHECK_NULL(AwtCheckbox::labelID);
565
566
AwtCheckbox::groupID =
567
env->GetFieldID(cls, "group", "Ljava/awt/CheckboxGroup;");
568
DASSERT(AwtCheckbox::groupID != NULL);
569
CHECK_NULL(AwtCheckbox::groupID);
570
571
AwtCheckbox::stateID = env->GetFieldID(cls, "state", "Z");
572
DASSERT(AwtCheckbox::stateID != NULL);
573
574
CATCH_BAD_ALLOC;
575
}
576
577
} /* extern "C" */
578
579
580
/************************************************************************
581
* WCheckboxPeer native methods
582
*/
583
584
extern "C" {
585
586
/*
587
* Class: sun_awt_windows_WCheckboxPeer
588
* Method: getCheckMarkSize
589
* Signature: ()I
590
*/
591
JNIEXPORT jint JNICALL
592
Java_sun_awt_windows_WCheckboxPeer_getCheckMarkSize(JNIEnv *env,
593
jclass cls)
594
{
595
return (jint)AwtCheckbox::GetCheckSize();
596
}
597
598
/*
599
* Class: sun_awt_windows_WCheckboxPeer
600
* Method: setState
601
* Signature: (Z)V
602
*/
603
JNIEXPORT void JNICALL
604
Java_sun_awt_windows_WCheckboxPeer_setState(JNIEnv *env, jobject self,
605
jboolean state)
606
{
607
TRY;
608
609
SetStateStruct *sss = new SetStateStruct;
610
sss->checkbox = env->NewGlobalRef(self);
611
sss->state = state;
612
613
AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetState, sss);
614
// global refs and sss are deleted in _SetState()
615
616
CATCH_BAD_ALLOC;
617
}
618
619
/*
620
* Class: sun_awt_windows_WCheckboxPeer
621
* Method: setCheckboxGroup
622
* Signature: (Ljava/awt/CheckboxGroup;)V
623
*/
624
JNIEXPORT void JNICALL
625
Java_sun_awt_windows_WCheckboxPeer_setCheckboxGroup(JNIEnv *env, jobject self,
626
jobject group)
627
{
628
TRY;
629
630
jobject *jos = new jobject[2];
631
jos[0] = env->NewGlobalRef(self);
632
jos[1] = env->NewGlobalRef(group);
633
634
AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetCheckboxGroup, jos);
635
// global refs and jos are deleted in _SetLabel()
636
637
CATCH_BAD_ALLOC;
638
}
639
640
/*
641
* Class: sun_awt_windows_WCheckboxPeer
642
* Method: setLabel
643
* Signature: (Ljava/lang/String;)V
644
*/
645
JNIEXPORT void JNICALL
646
Java_sun_awt_windows_WCheckboxPeer_setLabel(JNIEnv *env, jobject self,
647
jstring label)
648
{
649
TRY;
650
651
SetLabelStruct *sls = new SetLabelStruct;
652
sls->checkbox = env->NewGlobalRef(self);
653
sls->label = (label != NULL) ? (jstring)env->NewGlobalRef(label) : NULL;
654
655
AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetLabel, sls);
656
// global refs and sls are deleted in _SetLabel()
657
658
CATCH_BAD_ALLOC;
659
}
660
661
/*
662
* Class: sun_awt_windows_WCheckboxPeer
663
* Method: create
664
* Signature: (Lsun/awt/windows/WComponentPeer;)V
665
*/
666
JNIEXPORT void JNICALL
667
Java_sun_awt_windows_WCheckboxPeer_create(JNIEnv *env, jobject self,
668
jobject parent)
669
{
670
TRY;
671
672
AwtToolkit::CreateComponent(self, parent,
673
(AwtToolkit::ComponentFactory)
674
AwtCheckbox::Create);
675
PDATA pData;
676
JNI_CHECK_PEER_CREATION_RETURN(self);
677
678
#ifdef DEBUG
679
((AwtComponent*)JNI_GET_PDATA(self))->VerifyState();
680
#endif
681
682
CATCH_BAD_ALLOC;
683
}
684
685
} /* extern "C" */
686
687