Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/awt/Cursor.java
38829 views
1
/*
2
* Copyright (c) 1996, 2013, 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
package java.awt;
26
27
import java.io.File;
28
import java.io.FileInputStream;
29
30
import java.beans.ConstructorProperties;
31
import java.util.Hashtable;
32
import java.util.Properties;
33
import java.util.StringTokenizer;
34
35
import java.security.AccessController;
36
37
import sun.util.logging.PlatformLogger;
38
import sun.awt.AWTAccessor;
39
40
/**
41
* A class to encapsulate the bitmap representation of the mouse cursor.
42
*
43
* @see Component#setCursor
44
* @author Amy Fowler
45
*/
46
public class Cursor implements java.io.Serializable {
47
48
/**
49
* The default cursor type (gets set if no cursor is defined).
50
*/
51
public static final int DEFAULT_CURSOR = 0;
52
53
/**
54
* The crosshair cursor type.
55
*/
56
public static final int CROSSHAIR_CURSOR = 1;
57
58
/**
59
* The text cursor type.
60
*/
61
public static final int TEXT_CURSOR = 2;
62
63
/**
64
* The wait cursor type.
65
*/
66
public static final int WAIT_CURSOR = 3;
67
68
/**
69
* The south-west-resize cursor type.
70
*/
71
public static final int SW_RESIZE_CURSOR = 4;
72
73
/**
74
* The south-east-resize cursor type.
75
*/
76
public static final int SE_RESIZE_CURSOR = 5;
77
78
/**
79
* The north-west-resize cursor type.
80
*/
81
public static final int NW_RESIZE_CURSOR = 6;
82
83
/**
84
* The north-east-resize cursor type.
85
*/
86
public static final int NE_RESIZE_CURSOR = 7;
87
88
/**
89
* The north-resize cursor type.
90
*/
91
public static final int N_RESIZE_CURSOR = 8;
92
93
/**
94
* The south-resize cursor type.
95
*/
96
public static final int S_RESIZE_CURSOR = 9;
97
98
/**
99
* The west-resize cursor type.
100
*/
101
public static final int W_RESIZE_CURSOR = 10;
102
103
/**
104
* The east-resize cursor type.
105
*/
106
public static final int E_RESIZE_CURSOR = 11;
107
108
/**
109
* The hand cursor type.
110
*/
111
public static final int HAND_CURSOR = 12;
112
113
/**
114
* The move cursor type.
115
*/
116
public static final int MOVE_CURSOR = 13;
117
118
/**
119
* @deprecated As of JDK version 1.7, the {@link #getPredefinedCursor(int)}
120
* method should be used instead.
121
*/
122
@Deprecated
123
protected static Cursor predefined[] = new Cursor[14];
124
125
/**
126
* This field is a private replacement for 'predefined' array.
127
*/
128
private final static Cursor[] predefinedPrivate = new Cursor[14];
129
130
/* Localization names and default values */
131
static final String[][] cursorProperties = {
132
{ "AWT.DefaultCursor", "Default Cursor" },
133
{ "AWT.CrosshairCursor", "Crosshair Cursor" },
134
{ "AWT.TextCursor", "Text Cursor" },
135
{ "AWT.WaitCursor", "Wait Cursor" },
136
{ "AWT.SWResizeCursor", "Southwest Resize Cursor" },
137
{ "AWT.SEResizeCursor", "Southeast Resize Cursor" },
138
{ "AWT.NWResizeCursor", "Northwest Resize Cursor" },
139
{ "AWT.NEResizeCursor", "Northeast Resize Cursor" },
140
{ "AWT.NResizeCursor", "North Resize Cursor" },
141
{ "AWT.SResizeCursor", "South Resize Cursor" },
142
{ "AWT.WResizeCursor", "West Resize Cursor" },
143
{ "AWT.EResizeCursor", "East Resize Cursor" },
144
{ "AWT.HandCursor", "Hand Cursor" },
145
{ "AWT.MoveCursor", "Move Cursor" },
146
};
147
148
/**
149
* The chosen cursor type initially set to
150
* the <code>DEFAULT_CURSOR</code>.
151
*
152
* @serial
153
* @see #getType()
154
*/
155
int type = DEFAULT_CURSOR;
156
157
/**
158
* The type associated with all custom cursors.
159
*/
160
public static final int CUSTOM_CURSOR = -1;
161
162
/*
163
* hashtable, filesystem dir prefix, filename, and properties for custom cursors support
164
*/
165
166
private static final Hashtable<String,Cursor> systemCustomCursors = new Hashtable<>(1);
167
private static final String systemCustomCursorDirPrefix = initCursorDir();
168
169
private static String initCursorDir() {
170
String jhome = java.security.AccessController.doPrivileged(
171
new sun.security.action.GetPropertyAction("java.home"));
172
return jhome +
173
File.separator + "lib" + File.separator + "images" +
174
File.separator + "cursors" + File.separator;
175
}
176
177
private static final String systemCustomCursorPropertiesFile = systemCustomCursorDirPrefix + "cursors.properties";
178
179
private static Properties systemCustomCursorProperties = null;
180
181
private static final String CursorDotPrefix = "Cursor.";
182
private static final String DotFileSuffix = ".File";
183
private static final String DotHotspotSuffix = ".HotSpot";
184
private static final String DotNameSuffix = ".Name";
185
186
/*
187
* JDK 1.1 serialVersionUID
188
*/
189
private static final long serialVersionUID = 8028237497568985504L;
190
191
private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Cursor");
192
193
static {
194
/* ensure that the necessary native libraries are loaded */
195
Toolkit.loadLibraries();
196
if (!GraphicsEnvironment.isHeadless()) {
197
initIDs();
198
}
199
200
AWTAccessor.setCursorAccessor(
201
new AWTAccessor.CursorAccessor() {
202
public long getPData(Cursor cursor) {
203
return cursor.pData;
204
}
205
206
public void setPData(Cursor cursor, long pData) {
207
cursor.pData = pData;
208
}
209
210
public int getType(Cursor cursor) {
211
return cursor.type;
212
}
213
});
214
}
215
216
/**
217
* Initialize JNI field and method IDs for fields that may be
218
* accessed from C.
219
*/
220
private static native void initIDs();
221
222
/**
223
* Hook into native data.
224
*/
225
private transient long pData;
226
227
private transient Object anchor = new Object();
228
229
static class CursorDisposer implements sun.java2d.DisposerRecord {
230
volatile long pData;
231
public CursorDisposer(long pData) {
232
this.pData = pData;
233
}
234
public void dispose() {
235
if (pData != 0) {
236
finalizeImpl(pData);
237
}
238
}
239
}
240
transient CursorDisposer disposer;
241
private void setPData(long pData) {
242
this.pData = pData;
243
if (GraphicsEnvironment.isHeadless()) {
244
return;
245
}
246
if (disposer == null) {
247
disposer = new CursorDisposer(pData);
248
// anchor is null after deserialization
249
if (anchor == null) {
250
anchor = new Object();
251
}
252
sun.java2d.Disposer.addRecord(anchor, disposer);
253
} else {
254
disposer.pData = pData;
255
}
256
}
257
258
/**
259
* The user-visible name of the cursor.
260
*
261
* @serial
262
* @see #getName()
263
*/
264
protected String name;
265
266
/**
267
* Returns a cursor object with the specified predefined type.
268
*
269
* @param type the type of predefined cursor
270
* @return the specified predefined cursor
271
* @throws IllegalArgumentException if the specified cursor type is
272
* invalid
273
*/
274
static public Cursor getPredefinedCursor(int type) {
275
if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
276
throw new IllegalArgumentException("illegal cursor type");
277
}
278
Cursor c = predefinedPrivate[type];
279
if (c == null) {
280
predefinedPrivate[type] = c = new Cursor(type);
281
}
282
// fill 'predefined' array for backwards compatibility.
283
if (predefined[type] == null) {
284
predefined[type] = c;
285
}
286
return c;
287
}
288
289
/**
290
* Returns a system-specific custom cursor object matching the
291
* specified name. Cursor names are, for example: "Invalid.16x16"
292
*
293
* @param name a string describing the desired system-specific custom cursor
294
* @return the system specific custom cursor named
295
* @exception HeadlessException if
296
* <code>GraphicsEnvironment.isHeadless</code> returns true
297
*/
298
static public Cursor getSystemCustomCursor(final String name)
299
throws AWTException, HeadlessException {
300
GraphicsEnvironment.checkHeadless();
301
Cursor cursor = systemCustomCursors.get(name);
302
303
if (cursor == null) {
304
synchronized(systemCustomCursors) {
305
if (systemCustomCursorProperties == null)
306
loadSystemCustomCursorProperties();
307
}
308
309
String prefix = CursorDotPrefix + name;
310
String key = prefix + DotFileSuffix;
311
312
if (!systemCustomCursorProperties.containsKey(key)) {
313
if (log.isLoggable(PlatformLogger.Level.FINER)) {
314
log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
315
}
316
return null;
317
}
318
319
final String fileName =
320
systemCustomCursorProperties.getProperty(key);
321
322
String localized = systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
323
324
if (localized == null) localized = name;
325
326
String hotspot = systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
327
328
if (hotspot == null)
329
throw new AWTException("no hotspot property defined for cursor: " + name);
330
331
StringTokenizer st = new StringTokenizer(hotspot, ",");
332
333
if (st.countTokens() != 2)
334
throw new AWTException("failed to parse hotspot property for cursor: " + name);
335
336
int x = 0;
337
int y = 0;
338
339
try {
340
x = Integer.parseInt(st.nextToken());
341
y = Integer.parseInt(st.nextToken());
342
} catch (NumberFormatException nfe) {
343
throw new AWTException("failed to parse hotspot property for cursor: " + name);
344
}
345
346
try {
347
final int fx = x;
348
final int fy = y;
349
final String flocalized = localized;
350
351
cursor = java.security.AccessController.<Cursor>doPrivileged(
352
new java.security.PrivilegedExceptionAction<Cursor>() {
353
public Cursor run() throws Exception {
354
Toolkit toolkit = Toolkit.getDefaultToolkit();
355
Image image = toolkit.getImage(
356
systemCustomCursorDirPrefix + fileName);
357
return toolkit.createCustomCursor(
358
image, new Point(fx,fy), flocalized);
359
}
360
});
361
} catch (Exception e) {
362
throw new AWTException(
363
"Exception: " + e.getClass() + " " + e.getMessage() +
364
" occurred while creating cursor " + name);
365
}
366
367
if (cursor == null) {
368
if (log.isLoggable(PlatformLogger.Level.FINER)) {
369
log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
370
}
371
} else {
372
systemCustomCursors.put(name, cursor);
373
}
374
}
375
376
return cursor;
377
}
378
379
/**
380
* Return the system default cursor.
381
*/
382
static public Cursor getDefaultCursor() {
383
return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
384
}
385
386
/**
387
* Creates a new cursor object with the specified type.
388
* @param type the type of cursor
389
* @throws IllegalArgumentException if the specified cursor type
390
* is invalid
391
*/
392
@ConstructorProperties({"type"})
393
public Cursor(int type) {
394
if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
395
throw new IllegalArgumentException("illegal cursor type");
396
}
397
this.type = type;
398
399
// Lookup localized name.
400
name = Toolkit.getProperty(cursorProperties[type][0],
401
cursorProperties[type][1]);
402
}
403
404
/**
405
* Creates a new custom cursor object with the specified name.<p>
406
* Note: this constructor should only be used by AWT implementations
407
* as part of their support for custom cursors. Applications should
408
* use Toolkit.createCustomCursor().
409
* @param name the user-visible name of the cursor.
410
* @see java.awt.Toolkit#createCustomCursor
411
*/
412
protected Cursor(String name) {
413
this.type = Cursor.CUSTOM_CURSOR;
414
this.name = name;
415
}
416
417
/**
418
* Returns the type for this cursor.
419
*/
420
public int getType() {
421
return type;
422
}
423
424
/**
425
* Returns the name of this cursor.
426
* @return a localized description of this cursor.
427
* @since 1.2
428
*/
429
public String getName() {
430
return name;
431
}
432
433
/**
434
* Returns a string representation of this cursor.
435
* @return a string representation of this cursor.
436
* @since 1.2
437
*/
438
public String toString() {
439
return getClass().getName() + "[" + getName() + "]";
440
}
441
442
/*
443
* load the cursor.properties file
444
*/
445
private static void loadSystemCustomCursorProperties() throws AWTException {
446
synchronized(systemCustomCursors) {
447
systemCustomCursorProperties = new Properties();
448
449
try {
450
AccessController.<Object>doPrivileged(
451
new java.security.PrivilegedExceptionAction<Object>() {
452
public Object run() throws Exception {
453
FileInputStream fis = null;
454
try {
455
fis = new FileInputStream(
456
systemCustomCursorPropertiesFile);
457
systemCustomCursorProperties.load(fis);
458
} finally {
459
if (fis != null)
460
fis.close();
461
}
462
return null;
463
}
464
});
465
} catch (Exception e) {
466
systemCustomCursorProperties = null;
467
throw new AWTException("Exception: " + e.getClass() + " " +
468
e.getMessage() + " occurred while loading: " +
469
systemCustomCursorPropertiesFile);
470
}
471
}
472
}
473
474
private native static void finalizeImpl(long pData);
475
}
476
477