Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java
41159 views
1
/*
2
* Copyright (c) 2003, 2018, 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
package sun.awt.X11;
27
28
import java.awt.*;
29
import sun.awt.*;
30
import java.util.*;
31
import sun.util.logging.PlatformLogger;
32
33
public class XBaseWindow {
34
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XBaseWindow");
35
private static final PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XBaseWindow");
36
private static final PlatformLogger eventLog = PlatformLogger.getLogger("sun.awt.X11.event.XBaseWindow");
37
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XBaseWindow");
38
private static final PlatformLogger grabLog = PlatformLogger.getLogger("sun.awt.X11.grab.XBaseWindow");
39
40
public static final String
41
PARENT_WINDOW = "parent window", // parent window, Long
42
BOUNDS = "bounds", // bounds of the window, Rectangle
43
OVERRIDE_REDIRECT = "overrideRedirect", // override_redirect setting, Boolean
44
EVENT_MASK = "event mask", // event mask, Integer
45
VALUE_MASK = "value mask", // value mask, Long
46
BORDER_PIXEL = "border pixel", // border pixel value, Integer
47
COLORMAP = "color map", // color map, Long
48
DEPTH = "visual depth", // depth, Integer
49
VISUAL_CLASS = "visual class", // visual class, Integer
50
VISUAL = "visual", // visual, Long
51
EMBEDDED = "embedded", // is embedded?, Boolean
52
DELAYED = "delayed", // is creation delayed?, Boolean
53
PARENT = "parent", // parent peer
54
BACKGROUND_PIXMAP = "pixmap", // background pixmap
55
VISIBLE = "visible", // whether it is visible by default
56
SAVE_UNDER = "save under", // save content under this window
57
BACKING_STORE = "backing store", // enables double buffering
58
BIT_GRAVITY = "bit gravity"; // copy old content on geometry change
59
private XCreateWindowParams delayedParams;
60
61
Set<Long> children = new HashSet<Long>();
62
long window;
63
boolean visible;
64
boolean mapped;
65
boolean embedded;
66
Rectangle maxBounds;
67
volatile XBaseWindow parentWindow;
68
69
private boolean disposed;
70
71
private long screen;
72
private XSizeHints hints;
73
private XWMHints wmHints;
74
75
static final int MIN_SIZE = 1;
76
static final int DEF_LOCATION = 1;
77
78
private static XAtom wm_client_leader;
79
80
static enum InitialiseState {
81
INITIALISING,
82
INITIALISED,
83
FAILED_INITIALISATION
84
};
85
86
private InitialiseState initialising;
87
88
int x;
89
int y;
90
int width;
91
int height;
92
93
void awtLock() {
94
XToolkit.awtLock();
95
}
96
97
void awtUnlock() {
98
XToolkit.awtUnlock();
99
}
100
101
void awtLockNotifyAll() {
102
XToolkit.awtLockNotifyAll();
103
}
104
105
void awtLockWait() throws InterruptedException {
106
XToolkit.awtLockWait();
107
}
108
109
// To prevent errors from overriding obsolete methods
110
protected final void init(long parentWindow, Rectangle bounds) {}
111
protected final void preInit() {}
112
protected final void postInit() {}
113
114
// internal lock for synchronizing state changes and paint calls, initialized in preInit.
115
// the order with other locks: AWTLock -> stateLock
116
static class StateLock { }
117
protected StateLock state_lock;
118
119
/**
120
* Called for delayed inits during construction
121
*/
122
void instantPreInit(XCreateWindowParams params) {
123
state_lock = new StateLock();
124
}
125
126
/**
127
* Called before window creation, descendants should override to initialize the data,
128
* initialize params.
129
*/
130
void preInit(XCreateWindowParams params) {
131
state_lock = new StateLock();
132
embedded = Boolean.TRUE.equals(params.get(EMBEDDED));
133
visible = Boolean.TRUE.equals(params.get(VISIBLE));
134
135
Object parent = params.get(PARENT);
136
if (parent instanceof XBaseWindow) {
137
parentWindow = (XBaseWindow)parent;
138
} else {
139
Long parentWindowID = (Long)params.get(PARENT_WINDOW);
140
if (parentWindowID != null) {
141
parentWindow = XToolkit.windowToXWindow(parentWindowID);
142
}
143
}
144
145
Long eventMask = (Long)params.get(EVENT_MASK);
146
if (eventMask != null) {
147
long mask = eventMask.longValue();
148
mask |= XConstants.SubstructureNotifyMask;
149
params.put(EVENT_MASK, mask);
150
}
151
152
screen = -1;
153
}
154
155
/**
156
* Called after window creation, descendants should override to initialize Window
157
* with class-specific values and perform post-initialization actions.
158
*/
159
void postInit(XCreateWindowParams params) {
160
if (log.isLoggable(PlatformLogger.Level.FINE)) {
161
log.fine("WM name is " + getWMName());
162
}
163
updateWMName();
164
165
// Set WM_CLIENT_LEADER property
166
initClientLeader();
167
}
168
169
/**
170
* Creates window using parameters {@code params}
171
* If params contain flag DELAYED doesn't do anything.
172
* Note: Descendants can call this method to create the window
173
* at the time different to instance construction.
174
*/
175
protected final void init(XCreateWindowParams params) {
176
awtLock();
177
initialising = InitialiseState.INITIALISING;
178
awtUnlock();
179
180
try {
181
if (!Boolean.TRUE.equals(params.get(DELAYED))) {
182
preInit(params);
183
create(params);
184
postInit(params);
185
} else {
186
instantPreInit(params);
187
delayedParams = params;
188
}
189
awtLock();
190
initialising = InitialiseState.INITIALISED;
191
awtLockNotifyAll();
192
awtUnlock();
193
} catch (RuntimeException re) {
194
awtLock();
195
initialising = InitialiseState.FAILED_INITIALISATION;
196
awtLockNotifyAll();
197
awtUnlock();
198
throw re;
199
} catch (Throwable t) {
200
log.warning("Exception during peer initialization", t);
201
awtLock();
202
initialising = InitialiseState.FAILED_INITIALISATION;
203
awtLockNotifyAll();
204
awtUnlock();
205
}
206
}
207
208
public boolean checkInitialised() {
209
awtLock();
210
try {
211
switch (initialising) {
212
case INITIALISED:
213
return true;
214
case INITIALISING:
215
try {
216
while (initialising != InitialiseState.INITIALISED) {
217
awtLockWait();
218
}
219
} catch (InterruptedException ie) {
220
return false;
221
}
222
return true;
223
case FAILED_INITIALISATION:
224
return false;
225
default:
226
return false;
227
}
228
} finally {
229
awtUnlock();
230
}
231
}
232
233
/*
234
* Creates an invisible InputOnly window without an associated Component.
235
*/
236
XBaseWindow() {
237
this(new XCreateWindowParams());
238
}
239
240
/**
241
* Creates normal child window
242
*/
243
XBaseWindow(long parentWindow, Rectangle bounds) {
244
this(new XCreateWindowParams(new Object[] {
245
BOUNDS, bounds,
246
PARENT_WINDOW, Long.valueOf(parentWindow)}));
247
}
248
249
/**
250
* Creates top-level window
251
*/
252
XBaseWindow(Rectangle bounds) {
253
this(new XCreateWindowParams(new Object[] {
254
BOUNDS, bounds
255
}));
256
}
257
258
public XBaseWindow (XCreateWindowParams params) {
259
init(params);
260
}
261
262
/* This create is used by the XEmbeddedFramePeer since it has to create the window
263
as a child of the netscape window. This netscape window is passed in as wid */
264
XBaseWindow(long parentWindow) {
265
this(new XCreateWindowParams(new Object[] {
266
PARENT_WINDOW, Long.valueOf(parentWindow),
267
EMBEDDED, Boolean.TRUE
268
}));
269
}
270
271
/**
272
* Verifies that all required parameters are set. If not, sets them to default values.
273
* Verifies values of critical parameters, adjust their values when needed.
274
* @throws IllegalArgumentException if params is null
275
*/
276
protected void checkParams(XCreateWindowParams params) {
277
if (params == null) {
278
throw new IllegalArgumentException("Window creation parameters are null");
279
}
280
params.putIfNull(PARENT_WINDOW, Long.valueOf(XToolkit.getDefaultRootWindow()));
281
params.putIfNull(BOUNDS, new Rectangle(DEF_LOCATION, DEF_LOCATION, MIN_SIZE, MIN_SIZE));
282
params.putIfNull(DEPTH, Integer.valueOf((int)XConstants.CopyFromParent));
283
params.putIfNull(VISUAL, Long.valueOf(XConstants.CopyFromParent));
284
params.putIfNull(VISUAL_CLASS, Integer.valueOf(XConstants.InputOnly));
285
params.putIfNull(VALUE_MASK, Long.valueOf(XConstants.CWEventMask));
286
Rectangle bounds = (Rectangle)params.get(BOUNDS);
287
bounds.width = Math.max(MIN_SIZE, bounds.width);
288
bounds.height = Math.max(MIN_SIZE, bounds.height);
289
290
Long eventMaskObj = (Long)params.get(EVENT_MASK);
291
long eventMask = eventMaskObj != null ? eventMaskObj.longValue() : 0;
292
// We use our own synthetic grab see XAwtState.getGrabWindow()
293
// (see X vol. 1, 8.3.3.2)
294
eventMask |= XConstants.PropertyChangeMask | XConstants.OwnerGrabButtonMask;
295
params.put(EVENT_MASK, Long.valueOf(eventMask));
296
}
297
298
/**
299
* Returns scale factor of the window. It is used to convert native
300
* coordinates to local and vice verse.
301
*/
302
protected int getScale() {
303
return 1;
304
}
305
306
protected int scaleUp(int x) {
307
return x;
308
}
309
310
protected int scaleDown(int x) {
311
return x;
312
}
313
314
/**
315
* Creates window with parameters specified by {@code params}
316
* @see #init
317
*/
318
private void create(XCreateWindowParams params) {
319
XToolkit.awtLock();
320
try {
321
XSetWindowAttributes xattr = new XSetWindowAttributes();
322
try {
323
checkParams(params);
324
325
long value_mask = ((Long)params.get(VALUE_MASK)).longValue();
326
327
Long eventMask = (Long)params.get(EVENT_MASK);
328
xattr.set_event_mask(eventMask.longValue());
329
value_mask |= XConstants.CWEventMask;
330
331
Long border_pixel = (Long)params.get(BORDER_PIXEL);
332
if (border_pixel != null) {
333
xattr.set_border_pixel(border_pixel.longValue());
334
value_mask |= XConstants.CWBorderPixel;
335
}
336
337
Long colormap = (Long)params.get(COLORMAP);
338
if (colormap != null) {
339
xattr.set_colormap(colormap.longValue());
340
value_mask |= XConstants.CWColormap;
341
}
342
Long background_pixmap = (Long)params.get(BACKGROUND_PIXMAP);
343
if (background_pixmap != null) {
344
xattr.set_background_pixmap(background_pixmap.longValue());
345
value_mask |= XConstants.CWBackPixmap;
346
}
347
348
Long parentWindow = (Long)params.get(PARENT_WINDOW);
349
Rectangle bounds = (Rectangle)params.get(BOUNDS);
350
Integer depth = (Integer)params.get(DEPTH);
351
Integer visual_class = (Integer)params.get(VISUAL_CLASS);
352
Long visual = (Long)params.get(VISUAL);
353
Boolean overrideRedirect = (Boolean)params.get(OVERRIDE_REDIRECT);
354
if (overrideRedirect != null) {
355
xattr.set_override_redirect(overrideRedirect.booleanValue());
356
value_mask |= XConstants.CWOverrideRedirect;
357
}
358
359
Boolean saveUnder = (Boolean)params.get(SAVE_UNDER);
360
if (saveUnder != null) {
361
xattr.set_save_under(saveUnder.booleanValue());
362
value_mask |= XConstants.CWSaveUnder;
363
}
364
365
Integer backingStore = (Integer)params.get(BACKING_STORE);
366
if (backingStore != null) {
367
xattr.set_backing_store(backingStore.intValue());
368
value_mask |= XConstants.CWBackingStore;
369
}
370
371
Integer bitGravity = (Integer)params.get(BIT_GRAVITY);
372
if (bitGravity != null) {
373
xattr.set_bit_gravity(bitGravity.intValue());
374
value_mask |= XConstants.CWBitGravity;
375
}
376
377
if (log.isLoggable(PlatformLogger.Level.FINE)) {
378
log.fine("Creating window for " + this + " with the following attributes: \n" + params);
379
}
380
window = XlibWrapper.XCreateWindow(XToolkit.getDisplay(),
381
parentWindow.longValue(),
382
scaleUp(bounds.x),
383
scaleUp(bounds.y),
384
scaleUp(bounds.width),
385
scaleUp(bounds.height),
386
0, // border
387
depth.intValue(), // depth
388
visual_class.intValue(), // class
389
visual.longValue(), // visual
390
value_mask, // value mask
391
xattr.pData); // attributes
392
393
if (window == 0) {
394
throw new IllegalStateException("Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");
395
}
396
XToolkit.addToWinMap(window, this);
397
} finally {
398
xattr.dispose();
399
}
400
} finally {
401
XToolkit.awtUnlock();
402
}
403
}
404
405
public XCreateWindowParams getDelayedParams() {
406
return delayedParams;
407
}
408
409
protected String getWMName() {
410
return XToolkit.getCorrectXIDString(getClass().getName());
411
}
412
413
protected void initClientLeader() {
414
XToolkit.awtLock();
415
try {
416
if (wm_client_leader == null) {
417
wm_client_leader = XAtom.get("WM_CLIENT_LEADER");
418
}
419
wm_client_leader.setWindowProperty(this, getXAWTRootWindow());
420
} finally {
421
XToolkit.awtUnlock();
422
}
423
}
424
425
static XRootWindow getXAWTRootWindow() {
426
return XRootWindow.getInstance();
427
}
428
429
void destroy() {
430
XToolkit.awtLock();
431
try {
432
if (hints != null) {
433
XlibWrapper.XFree(hints.pData);
434
hints = null;
435
}
436
XToolkit.removeFromWinMap(getWindow(), this);
437
XlibWrapper.XDestroyWindow(XToolkit.getDisplay(), getWindow());
438
if (XPropertyCache.isCachingSupported()) {
439
XPropertyCache.clearCache(window);
440
}
441
window = -1;
442
if( !isDisposed() ) {
443
setDisposed( true );
444
}
445
446
XAwtState.getGrabWindow(); // Magic - getGrabWindow clear state if grabbing window is disposed of.
447
} finally {
448
XToolkit.awtUnlock();
449
}
450
}
451
452
void flush() {
453
XToolkit.awtLock();
454
try {
455
XlibWrapper.XFlush(XToolkit.getDisplay());
456
} finally {
457
XToolkit.awtUnlock();
458
}
459
}
460
461
/**
462
* Helper function to set W
463
*/
464
public final void setWMHints(XWMHints hints) {
465
XToolkit.awtLock();
466
try {
467
XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
468
} finally {
469
XToolkit.awtUnlock();
470
}
471
}
472
473
public XWMHints getWMHints() {
474
if (wmHints == null) {
475
wmHints = new XWMHints(XlibWrapper.XAllocWMHints());
476
// XlibWrapper.XGetWMHints(XToolkit.getDisplay(),
477
// getWindow(),
478
// wmHints.pData);
479
}
480
return wmHints;
481
}
482
483
484
/*
485
* Call this method under AWTLock.
486
* The lock should be acquired untill all operations with XSizeHints are completed.
487
*/
488
public XSizeHints getHints() {
489
if (hints == null) {
490
long p_hints = XlibWrapper.XAllocSizeHints();
491
hints = new XSizeHints(p_hints);
492
// XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(), getWindow(), p_hints, XlibWrapper.larg1);
493
// TODO: Shouldn't we listen for WM updates on this property?
494
}
495
return hints;
496
}
497
498
public void setSizeHints(long flags, int x, int y, int width, int height) {
499
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
500
insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(flags));
501
}
502
XToolkit.awtLock();
503
try {
504
XSizeHints hints = getHints();
505
// Note: if PPosition is not set in flags this means that
506
// we want to reset PPosition in hints. This is necessary
507
// for locationByPlatform functionality
508
if ((flags & XUtilConstants.PPosition) != 0) {
509
hints.set_x(scaleUp(x));
510
hints.set_y(scaleUp(y));
511
}
512
if ((flags & XUtilConstants.PSize) != 0) {
513
hints.set_width(scaleUp(width));
514
hints.set_height(scaleUp(height));
515
} else if ((hints.get_flags() & XUtilConstants.PSize) != 0) {
516
flags |= XUtilConstants.PSize;
517
}
518
if ((flags & XUtilConstants.PMinSize) != 0) {
519
hints.set_min_width(scaleUp(width));
520
hints.set_min_height(scaleUp(height));
521
} else if ((hints.get_flags() & XUtilConstants.PMinSize) != 0) {
522
flags |= XUtilConstants.PMinSize;
523
//Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
524
//We don't need to reset minimum size if it's already set
525
}
526
if ((flags & XUtilConstants.PMaxSize) != 0) {
527
if (maxBounds != null) {
528
if (maxBounds.width != Integer.MAX_VALUE) {
529
hints.set_max_width(scaleUp(maxBounds.width));
530
} else {
531
hints.set_max_width(XToolkit.getMaxWindowWidthInPixels());
532
}
533
if (maxBounds.height != Integer.MAX_VALUE) {
534
hints.set_max_height(scaleUp(maxBounds.height));
535
} else {
536
hints.set_max_height(XToolkit.getMaxWindowHeightInPixels());
537
}
538
} else {
539
hints.set_max_width(scaleUp(width));
540
hints.set_max_height(scaleUp(height));
541
}
542
} else if ((hints.get_flags() & XUtilConstants.PMaxSize) != 0) {
543
flags |= XUtilConstants.PMaxSize;
544
if (maxBounds != null) {
545
if (maxBounds.width != Integer.MAX_VALUE) {
546
hints.set_max_width(scaleUp(maxBounds.width));
547
} else {
548
hints.set_max_width(XToolkit.getMaxWindowWidthInPixels());
549
}
550
if (maxBounds.height != Integer.MAX_VALUE) {
551
hints.set_max_height(scaleUp(maxBounds.height));
552
} else {
553
hints.set_max_height(XToolkit.getMaxWindowHeightInPixels());
554
}
555
} else {
556
// Leave intact
557
}
558
}
559
flags |= XUtilConstants.PWinGravity;
560
hints.set_flags(flags);
561
hints.set_win_gravity(XConstants.NorthWestGravity);
562
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
563
insLog.finer("Setting hints, resulted flags " + XlibWrapper.hintsToString(flags) +
564
", values " + hints);
565
}
566
XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), getWindow(), hints.pData);
567
} finally {
568
XToolkit.awtUnlock();
569
}
570
}
571
572
public boolean isMinSizeSet() {
573
XSizeHints hints = getHints();
574
long flags = hints.get_flags();
575
return ((flags & XUtilConstants.PMinSize) == XUtilConstants.PMinSize);
576
}
577
578
/**
579
* This lock object can be used to protect instance data from concurrent access
580
* by two threads. If both state lock and AWT lock are taken, AWT Lock should be taken first.
581
*/
582
Object getStateLock() {
583
return state_lock;
584
}
585
586
public long getWindow() {
587
return window;
588
}
589
public long getContentWindow() {
590
return window;
591
}
592
593
public XBaseWindow getContentXWindow() {
594
return XToolkit.windowToXWindow(getContentWindow());
595
}
596
597
public Rectangle getBounds() {
598
return new Rectangle(x, y, width, height);
599
}
600
public Dimension getSize() {
601
return new Dimension(width, height);
602
}
603
604
605
public void toFront() {
606
XToolkit.awtLock();
607
try {
608
XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());
609
} finally {
610
XToolkit.awtUnlock();
611
}
612
}
613
public void xRequestFocus(long time) {
614
XToolkit.awtLock();
615
try {
616
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
617
focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()) + " with time " + time);
618
}
619
XlibWrapper.XSetInputFocus2(XToolkit.getDisplay(), getWindow(), time);
620
} finally {
621
XToolkit.awtUnlock();
622
}
623
}
624
public void xRequestFocus() {
625
XToolkit.awtLock();
626
try {
627
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
628
focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()));
629
}
630
XlibWrapper.XSetInputFocus(XToolkit.getDisplay(), getWindow());
631
} finally {
632
XToolkit.awtUnlock();
633
}
634
}
635
636
public static long xGetInputFocus() {
637
XToolkit.awtLock();
638
try {
639
return XlibWrapper.XGetInputFocus(XToolkit.getDisplay());
640
} finally {
641
XToolkit.awtUnlock();
642
}
643
}
644
645
public void xSetVisible(boolean visible) {
646
if (log.isLoggable(PlatformLogger.Level.FINE)) {
647
log.fine("Setting visible on " + this + " to " + visible);
648
}
649
XToolkit.awtLock();
650
try {
651
this.visible = visible;
652
if (visible) {
653
XlibWrapper.XMapWindow(XToolkit.getDisplay(), getWindow());
654
}
655
else {
656
XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
657
}
658
XlibWrapper.XFlush(XToolkit.getDisplay());
659
} finally {
660
XToolkit.awtUnlock();
661
}
662
}
663
664
boolean isMapped() {
665
return mapped;
666
}
667
668
void updateWMName() {
669
String name = getWMName();
670
XToolkit.awtLock();
671
try {
672
if (name == null) {
673
name = " ";
674
}
675
XAtom nameAtom = XAtom.get(XAtom.XA_WM_NAME);
676
nameAtom.setProperty(getWindow(), name);
677
XAtom netNameAtom = XAtom.get("_NET_WM_NAME");
678
netNameAtom.setPropertyUTF8(getWindow(), name);
679
} finally {
680
XToolkit.awtUnlock();
681
}
682
}
683
void setWMClass(String[] cl) {
684
if (cl.length != 2) {
685
throw new IllegalArgumentException("WM_CLASS_NAME consists of exactly two strings");
686
}
687
XToolkit.awtLock();
688
try {
689
XAtom xa = XAtom.get(XAtom.XA_WM_CLASS);
690
xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1] + '\0');
691
} finally {
692
XToolkit.awtUnlock();
693
}
694
}
695
696
boolean isVisible() {
697
return visible;
698
}
699
700
static long getScreenOfWindow(long window) {
701
XToolkit.awtLock();
702
try {
703
return XlibWrapper.getScreenOfWindow(XToolkit.getDisplay(), window);
704
} finally {
705
XToolkit.awtUnlock();
706
}
707
}
708
long getScreenNumber() {
709
XToolkit.awtLock();
710
try {
711
return XlibWrapper.XScreenNumberOfScreen(getScreen());
712
} finally {
713
XToolkit.awtUnlock();
714
}
715
}
716
717
long getScreen() {
718
if (screen == -1) { // Not initialized
719
screen = getScreenOfWindow(window);
720
}
721
return screen;
722
}
723
724
public void xSetBounds(Rectangle bounds) {
725
xSetBounds(bounds.x, bounds.y, bounds.width, bounds.height);
726
}
727
728
public void xSetBounds(int x, int y, int width, int height) {
729
if (getWindow() == 0) {
730
insLog.warning("Attempt to resize uncreated window");
731
throw new IllegalStateException("Attempt to resize uncreated window");
732
}
733
if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
734
insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
735
}
736
width = Math.max(MIN_SIZE, width);
737
height = Math.max(MIN_SIZE, height);
738
XToolkit.awtLock();
739
try {
740
XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(),
741
scaleUp(x), scaleUp(y),
742
scaleUp(width), scaleUp(height));
743
} finally {
744
XToolkit.awtUnlock();
745
}
746
}
747
748
/**
749
* Translate coordinates from one window into another. Optimized
750
* for XAWT - uses cached data when possible. Preferable over
751
* pure XTranslateCoordinates.
752
* @return coordinates relative to dst, or null if error happened
753
*/
754
static Point toOtherWindow(long src, long dst, int x, int y) {
755
Point rpt = new Point(0, 0);
756
757
// Check if both windows belong to XAWT - then no X calls are necessary
758
759
XBaseWindow srcPeer = XToolkit.windowToXWindow(src);
760
XBaseWindow dstPeer = XToolkit.windowToXWindow(dst);
761
762
if (srcPeer != null && dstPeer != null) {
763
// (x, y) is relative to src
764
rpt.x = x + srcPeer.getAbsoluteX() - dstPeer.getAbsoluteX();
765
rpt.y = y + srcPeer.getAbsoluteY() - dstPeer.getAbsoluteY();
766
} else if (dstPeer != null && XlibUtil.isRoot(src, dstPeer.getScreenNumber())) {
767
// from root into peer
768
rpt.x = x - dstPeer.getAbsoluteX();
769
rpt.y = y - dstPeer.getAbsoluteY();
770
} else if (srcPeer != null && XlibUtil.isRoot(dst, srcPeer.getScreenNumber())) {
771
// from peer into root
772
rpt.x = x + srcPeer.getAbsoluteX();
773
rpt.y = y + srcPeer.getAbsoluteY();
774
} else {
775
int scale = srcPeer == null ? 1 : srcPeer.getScale();
776
rpt = XlibUtil.translateCoordinates(src, dst, new Point(x, y), scale);
777
}
778
return rpt;
779
}
780
781
/*
782
* Convert to global coordinates.
783
*/
784
Rectangle toGlobal(Rectangle rec) {
785
Point p = toGlobal(rec.getLocation());
786
Rectangle newRec = new Rectangle(rec);
787
if (p != null) {
788
newRec.setLocation(p);
789
}
790
return newRec;
791
}
792
793
Point toGlobal(Point pt) {
794
Point p = toGlobal(pt.x, pt.y);
795
if (p != null) {
796
return p;
797
} else {
798
return new Point(pt);
799
}
800
}
801
802
Point toGlobal(int x, int y) {
803
long root;
804
XToolkit.awtLock();
805
try {
806
root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
807
getScreenNumber());
808
} finally {
809
XToolkit.awtUnlock();
810
}
811
Point p = toOtherWindow(getContentWindow(), root, x, y);
812
if (p != null) {
813
return p;
814
} else {
815
return new Point(x, y);
816
}
817
}
818
819
/*
820
* Convert to local coordinates.
821
*/
822
Point toLocal(Point pt) {
823
Point p = toLocal(pt.x, pt.y);
824
if (p != null) {
825
return p;
826
} else {
827
return new Point(pt);
828
}
829
}
830
831
Point toLocal(int x, int y) {
832
long root;
833
XToolkit.awtLock();
834
try {
835
root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
836
getScreenNumber());
837
} finally {
838
XToolkit.awtUnlock();
839
}
840
Point p = toOtherWindow(root, getContentWindow(), x, y);
841
if (p != null) {
842
return p;
843
} else {
844
return new Point(x, y);
845
}
846
}
847
848
/**
849
* We should always grab both keyboard and pointer to control event flow
850
* on popups. This also simplifies synthetic grab implementation.
851
* The active grab overrides activated automatic grab.
852
*/
853
public boolean grabInput() {
854
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
855
grabLog.fine("Grab input on {0}", this);
856
}
857
858
XToolkit.awtLock();
859
try {
860
if (XAwtState.getGrabWindow() == this &&
861
XAwtState.isManualGrab())
862
{
863
grabLog.fine(" Already Grabbed");
864
return true;
865
}
866
//6273031: PIT. Choice drop down does not close once it is right clicked to show a popup menu
867
//remember previous window having grab and if it's not null ungrab it.
868
XBaseWindow prevGrabWindow = XAwtState.getGrabWindow();
869
final int eventMask = (int) (XConstants.ButtonPressMask | XConstants.ButtonReleaseMask
870
| XConstants.EnterWindowMask | XConstants.LeaveWindowMask | XConstants.PointerMotionMask
871
| XConstants.ButtonMotionMask);
872
final int ownerEvents = 1;
873
874
875
//6714678: IDE (Netbeans, Eclipse, JDeveloper) Debugger hangs
876
//process on Linux
877
//The user must pass the sun.awt.disablegrab property to disable
878
//taking grabs. This prevents hanging of the GUI when a breakpoint
879
//is hit while a popup window taking the grab is open.
880
if (!XToolkit.getSunAwtDisableGrab()) {
881
int ptrGrab = XlibWrapper.XGrabPointer(XToolkit.getDisplay(),
882
getContentWindow(), ownerEvents, eventMask, XConstants.GrabModeAsync,
883
XConstants.GrabModeAsync, XConstants.None, (XWM.isMotif() ? XToolkit.arrowCursor : XConstants.None),
884
XConstants.CurrentTime);
885
// Check grab results to be consistent with X server grab
886
if (ptrGrab != XConstants.GrabSuccess) {
887
XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
888
XAwtState.setGrabWindow(null);
889
grabLog.fine(" Grab Failure - mouse");
890
return false;
891
}
892
893
int keyGrab = XlibWrapper.XGrabKeyboard(XToolkit.getDisplay(),
894
getContentWindow(), ownerEvents, XConstants.GrabModeAsync, XConstants.GrabModeAsync,
895
XConstants.CurrentTime);
896
if (keyGrab != XConstants.GrabSuccess) {
897
XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
898
XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);
899
XAwtState.setGrabWindow(null);
900
grabLog.fine(" Grab Failure - keyboard");
901
return false;
902
}
903
}
904
if (prevGrabWindow != null) {
905
prevGrabWindow.ungrabInputImpl();
906
}
907
XAwtState.setGrabWindow(this);
908
grabLog.fine(" Grab - success");
909
return true;
910
} finally {
911
XToolkit.awtUnlock();
912
}
913
}
914
915
static void ungrabInput() {
916
XToolkit.awtLock();
917
try {
918
XBaseWindow grabWindow = XAwtState.getGrabWindow();
919
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
920
grabLog.fine("UnGrab input on {0}", grabWindow);
921
}
922
if (grabWindow != null) {
923
grabWindow.ungrabInputImpl();
924
if (!XToolkit.getSunAwtDisableGrab()) {
925
XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);
926
XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);
927
}
928
XAwtState.setGrabWindow(null);
929
// we need to call XFlush() here to force ungrab
930
// see 6384219 for details
931
XlibWrapper.XFlush(XToolkit.getDisplay());
932
}
933
} finally {
934
XToolkit.awtUnlock();
935
}
936
}
937
938
// called from ungrabInput, used in popup windows to hide theirselfs in ungrabbing
939
void ungrabInputImpl() {
940
}
941
942
static void checkSecurity() {
943
if (XToolkit.isSecurityWarningEnabled() && XToolkit.isToolkitThread()) {
944
StackTraceElement[] stack = (new Throwable()).getStackTrace();
945
log.warning(stack[1] + ": Security violation: calling user code on toolkit thread");
946
}
947
}
948
949
public Set<Long> getChildren() {
950
synchronized (getStateLock()) {
951
return new HashSet<Long>(children);
952
}
953
}
954
955
// -------------- Event handling ----------------
956
public void handleMapNotifyEvent(XEvent xev) {
957
mapped = true;
958
}
959
public void handleUnmapNotifyEvent(XEvent xev) {
960
mapped = false;
961
}
962
public void handleReparentNotifyEvent(XEvent xev) {
963
if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
964
XReparentEvent msg = xev.get_xreparent();
965
eventLog.finer(msg.toString());
966
}
967
}
968
public void handlePropertyNotify(XEvent xev) {
969
XPropertyEvent msg = xev.get_xproperty();
970
if (XPropertyCache.isCachingSupported()) {
971
XPropertyCache.clearCache(window, XAtom.get(msg.get_atom()));
972
}
973
if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
974
eventLog.finer("{0}", msg);
975
}
976
}
977
978
public void handleDestroyNotify(XEvent xev) {
979
XAnyEvent xany = xev.get_xany();
980
if (xany.get_window() == getWindow()) {
981
XToolkit.removeFromWinMap(getWindow(), this);
982
if (XPropertyCache.isCachingSupported()) {
983
XPropertyCache.clearCache(getWindow());
984
}
985
}
986
if (xany.get_window() != getWindow()) {
987
synchronized (getStateLock()) {
988
children.remove(xany.get_window());
989
}
990
}
991
}
992
993
public void handleCreateNotify(XEvent xev) {
994
XAnyEvent xany = xev.get_xany();
995
if (xany.get_window() != getWindow()) {
996
synchronized (getStateLock()) {
997
children.add(xany.get_window());
998
}
999
}
1000
}
1001
1002
public void handleClientMessage(XEvent xev) {
1003
if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
1004
XClientMessageEvent msg = xev.get_xclient();
1005
eventLog.finer(msg.toString());
1006
}
1007
}
1008
1009
public void handleVisibilityEvent(XEvent xev) {
1010
}
1011
public void handleKeyPress(XEvent xev) {
1012
}
1013
public void handleKeyRelease(XEvent xev) {
1014
}
1015
public void handleExposeEvent(XEvent xev) {
1016
}
1017
/**
1018
* Activate automatic grab on first ButtonPress,
1019
* deactivate on full mouse release
1020
*/
1021
public void handleButtonPressRelease(XEvent xev) {
1022
XButtonEvent xbe = xev.get_xbutton();
1023
/*
1024
* Ignore the buttons above 20 due to the bit limit for
1025
* InputEvent.BUTTON_DOWN_MASK.
1026
* One more bit is reserved for FIRST_HIGH_BIT.
1027
*/
1028
int theButton = xbe.get_button();
1029
if (theButton > SunToolkit.MAX_BUTTONS_SUPPORTED) {
1030
return;
1031
}
1032
int buttonState = 0;
1033
buttonState = xbe.get_state() & XConstants.ALL_BUTTONS_MASK;
1034
1035
boolean isWheel = (theButton == XConstants.MouseWheelUp ||
1036
theButton == XConstants.MouseWheelDown);
1037
1038
// don't give focus if it's just the mouse wheel turning
1039
if (!isWheel) {
1040
switch (xev.get_type()) {
1041
case XConstants.ButtonPress:
1042
if (buttonState == 0) {
1043
XWindowPeer parent = getToplevelXWindow();
1044
// See 6385277, 6981400.
1045
if (parent != null && parent.isFocusableWindow()) {
1046
// A click in a client area drops the actual focused window retaining.
1047
parent.setActualFocusedWindow(null);
1048
parent.requestWindowFocus(xbe.get_time(), true);
1049
}
1050
XAwtState.setAutoGrabWindow(this);
1051
}
1052
break;
1053
case XConstants.ButtonRelease:
1054
if (isFullRelease(buttonState, xbe.get_button())) {
1055
XAwtState.setAutoGrabWindow(null);
1056
}
1057
break;
1058
}
1059
}
1060
}
1061
public void handleMotionNotify(XEvent xev) {
1062
}
1063
public void handleXCrossingEvent(XEvent xev) {
1064
}
1065
public void handleConfigureNotifyEvent(XEvent xev) {
1066
XConfigureEvent xe = xev.get_xconfigure();
1067
if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
1068
insLog.finer("Configure, {0}", xe);
1069
}
1070
1071
x = scaleDown(xe.get_x());
1072
y = scaleDown(xe.get_y());
1073
width = scaleDown(xe.get_width());
1074
height = scaleDown(xe.get_height());
1075
}
1076
/**
1077
* Checks ButtonRelease released all Mouse buttons
1078
*/
1079
static boolean isFullRelease(int buttonState, int button) {
1080
final int buttonsNumber = XToolkit.getNumberOfButtonsForMask();
1081
1082
if (button < 0 || button > buttonsNumber) {
1083
return buttonState == 0;
1084
} else {
1085
return buttonState == XlibUtil.getButtonMask(button);
1086
}
1087
}
1088
1089
static boolean isGrabbedEvent(XEvent ev, XBaseWindow target) {
1090
switch (ev.get_type()) {
1091
case XConstants.ButtonPress:
1092
case XConstants.ButtonRelease:
1093
case XConstants.MotionNotify:
1094
case XConstants.KeyPress:
1095
case XConstants.KeyRelease:
1096
return true;
1097
case XConstants.LeaveNotify:
1098
case XConstants.EnterNotify:
1099
// We shouldn't dispatch this events to the grabbed components (see 6317481)
1100
// But this logic is important if the grabbed component is top-level (see realSync)
1101
return (target instanceof XWindowPeer);
1102
default:
1103
return false;
1104
}
1105
}
1106
/**
1107
* Dispatches event to the grab Window or event source window depending
1108
* on whether the grab is active and on the event type
1109
*/
1110
static void dispatchToWindow(XEvent ev) {
1111
XBaseWindow target = XAwtState.getGrabWindow();
1112
if (target == null || !isGrabbedEvent(ev, target)) {
1113
target = XToolkit.windowToXWindow(ev.get_xany().get_window());
1114
}
1115
if (target != null && target.checkInitialised()) {
1116
target.dispatchEvent(ev);
1117
}
1118
}
1119
1120
public void dispatchEvent(XEvent xev) {
1121
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
1122
eventLog.finest(xev.toString());
1123
}
1124
int type = xev.get_type();
1125
1126
if (isDisposed()) {
1127
return;
1128
}
1129
1130
switch (type)
1131
{
1132
case XConstants.VisibilityNotify:
1133
handleVisibilityEvent(xev);
1134
break;
1135
case XConstants.ClientMessage:
1136
handleClientMessage(xev);
1137
break;
1138
case XConstants.Expose :
1139
case XConstants.GraphicsExpose :
1140
handleExposeEvent(xev);
1141
break;
1142
case XConstants.ButtonPress:
1143
case XConstants.ButtonRelease:
1144
handleButtonPressRelease(xev);
1145
break;
1146
1147
case XConstants.MotionNotify:
1148
handleMotionNotify(xev);
1149
break;
1150
case XConstants.KeyPress:
1151
handleKeyPress(xev);
1152
break;
1153
case XConstants.KeyRelease:
1154
handleKeyRelease(xev);
1155
break;
1156
case XConstants.EnterNotify:
1157
case XConstants.LeaveNotify:
1158
handleXCrossingEvent(xev);
1159
break;
1160
case XConstants.ConfigureNotify:
1161
handleConfigureNotifyEvent(xev);
1162
break;
1163
case XConstants.MapNotify:
1164
handleMapNotifyEvent(xev);
1165
break;
1166
case XConstants.UnmapNotify:
1167
handleUnmapNotifyEvent(xev);
1168
break;
1169
case XConstants.ReparentNotify:
1170
handleReparentNotifyEvent(xev);
1171
break;
1172
case XConstants.PropertyNotify:
1173
handlePropertyNotify(xev);
1174
break;
1175
case XConstants.DestroyNotify:
1176
handleDestroyNotify(xev);
1177
break;
1178
case XConstants.CreateNotify:
1179
handleCreateNotify(xev);
1180
break;
1181
}
1182
}
1183
protected boolean isEventDisabled(XEvent e) {
1184
return false;
1185
}
1186
1187
int getX() {
1188
return x;
1189
}
1190
1191
int getY() {
1192
return y;
1193
}
1194
1195
int getWidth() {
1196
return width;
1197
}
1198
1199
int getHeight() {
1200
return height;
1201
}
1202
1203
void setDisposed(boolean d) {
1204
disposed = d;
1205
}
1206
1207
boolean isDisposed() {
1208
return disposed;
1209
}
1210
1211
public int getAbsoluteX() {
1212
XBaseWindow pw = getParentWindow();
1213
if (pw != null) {
1214
return pw.getAbsoluteX() + getX();
1215
} else {
1216
// Overridden for top-levels as their (x,y) is Java (x, y), not native location
1217
return getX();
1218
}
1219
}
1220
1221
public int getAbsoluteY() {
1222
XBaseWindow pw = getParentWindow();
1223
if (pw != null) {
1224
return pw.getAbsoluteY() + getY();
1225
} else {
1226
return getY();
1227
}
1228
}
1229
1230
public XBaseWindow getParentWindow() {
1231
return parentWindow;
1232
}
1233
1234
public XWindowPeer getToplevelXWindow() {
1235
XBaseWindow bw = this;
1236
while (bw != null && !(bw instanceof XWindowPeer)) {
1237
bw = bw.getParentWindow();
1238
}
1239
return (XWindowPeer)bw;
1240
}
1241
public String toString() {
1242
return super.toString() + "(" + Long.toString(getWindow(), 16) + ")";
1243
}
1244
1245
/**
1246
* Returns whether the given point is inside of the window. Coordinates are local.
1247
*/
1248
public boolean contains(int x, int y) {
1249
return x >= 0 && y >= 0 && x < getWidth() && y < getHeight();
1250
}
1251
1252
/**
1253
* Returns whether the given point is inside of the window. Coordinates are global.
1254
*/
1255
public boolean containsGlobal(int x, int y) {
1256
return x >= getAbsoluteX() && y >= getAbsoluteY() && x < (getAbsoluteX()+getWidth()) && y < (getAbsoluteY()+getHeight());
1257
}
1258
1259
}
1260
1261