49
49
*/
50
50
public final class Cursor extends Resource {
51
51
52
- /**
53
- * the handle to the OS cursor resource
54
- * (Warning: This field is platform dependent)
55
- * <p>
56
- * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
57
- * public API. It is marked public only so that it can be shared
58
- * within the packages provided by SWT. It is not available on all
59
- * platforms and should never be accessed from application code.
60
- * </p>
61
- *
62
- */
63
- private long handle ;
64
52
/**
65
53
* Attribute to cache current native zoom level
66
54
*/
@@ -70,6 +58,8 @@ public final class Cursor extends Resource {
70
58
71
59
private final CursorHandleProvider cursorHandleProvider ;
72
60
61
+ private boolean isDestroyed ;
62
+
73
63
/**
74
64
* Constructs a new cursor given a device and a style
75
65
* constant describing the desired cursor appearance.
@@ -119,7 +109,6 @@ public final class Cursor extends Resource {
119
109
public Cursor (Device device , int style ) {
120
110
super (device );
121
111
this .cursorHandleProvider = new StyleCursorHandleProvider (style );
122
- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
123
112
init ();
124
113
this .device .registerResourceWithZoomSupport (this );
125
114
}
@@ -160,28 +149,14 @@ public Cursor(Device device, int style) {
160
149
public Cursor (Device device , ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
161
150
super (device );
162
151
this .cursorHandleProvider = new ImageDataWithMaskCursorHandleProvider (source , mask , hotspotX , hotspotY );
163
- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
164
152
init ();
165
153
this .device .registerResourceWithZoomSupport (this );
166
154
}
167
155
168
156
private static CursorHandle setupCursorFromImageData (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
169
- if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
170
157
if (mask == null ) {
171
- if (source .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
172
- SWT .error (SWT .ERROR_NULL_ARGUMENT );
173
- }
174
158
mask = source .getTransparencyMask ();
175
159
}
176
- /* Check the bounds. Mask must be the same size as source */
177
- if (mask .width != source .width || mask .height != source .height ) {
178
- SWT .error (SWT .ERROR_INVALID_ARGUMENT );
179
- }
180
- /* Check the hotspots */
181
- if (hotspotX >= source .width || hotspotX < 0 ||
182
- hotspotY >= source .height || hotspotY < 0 ) {
183
- SWT .error (SWT .ERROR_INVALID_ARGUMENT );
184
- }
185
160
/* Convert depth to 1 */
186
161
mask = ImageData .convertMask (mask );
187
162
source = ImageData .convertMask (source );
@@ -229,18 +204,12 @@ private static CursorHandle setupCursorFromImageData(ImageData source, ImageData
229
204
public Cursor (Device device , ImageData source , int hotspotX , int hotspotY ) {
230
205
super (device );
231
206
this .cursorHandleProvider = new ImageDataCursorHandleProvider (source , hotspotX , hotspotY );
232
- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
233
207
init ();
234
208
this .device .registerResourceWithZoomSupport (this );
235
209
}
236
210
237
211
private static CursorHandle setupCursorFromImageData (Device device , ImageData source , int hotspotX , int hotspotY ) {
238
212
if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
239
- /* Check the hotspots */
240
- if (hotspotX >= source .width || hotspotX < 0 ||
241
- hotspotY >= source .height || hotspotY < 0 ) {
242
- SWT .error (SWT .ERROR_INVALID_ARGUMENT );
243
- }
244
213
long hBitmap = 0 ;
245
214
long hMask = 0 ;
246
215
if (source .maskData == null && source .transparentPixel == -1 && (source .alpha != -1 || source .alphaData != null )) {
@@ -341,7 +310,6 @@ public Cursor(Device device, ImageDataProvider imageDataProvider, int hotspotX,
341
310
super (device );
342
311
if (imageDataProvider == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
343
312
this .cursorHandleProvider = new ImageDataProviderCursorHandleProvider (imageDataProvider , hotspotX , hotspotY );
344
- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
345
313
init ();
346
314
this .device .registerResourceWithZoomSupport (this );
347
315
}
@@ -363,7 +331,7 @@ public Cursor(Device device, ImageDataProvider imageDataProvider, int hotspotX,
363
331
*/
364
332
public static Long win32_getHandle (Cursor cursor , int zoom ) {
365
333
if (cursor .isDisposed ()) {
366
- return cursor . handle ;
334
+ return 0L ;
367
335
}
368
336
if (cursor .zoomLevelToHandle .get (zoom ) != null ) {
369
337
return cursor .zoomLevelToHandle .get (zoom ).getHandle ();
@@ -376,38 +344,19 @@ public static Long win32_getHandle (Cursor cursor, int zoom) {
376
344
}
377
345
378
346
private void setHandleForZoomLevel (CursorHandle handle , Integer zoom ) {
379
- if (this .handle == 0 ) {
380
- this .handle = handle .getHandle (); // Set handle for default zoom level
381
- }
382
347
if (zoom != null && !zoomLevelToHandle .containsKey (zoom )) {
383
348
zoomLevelToHandle .put (zoom , handle );
384
349
}
385
350
}
386
351
387
352
@ Override
388
353
void destroy () {
389
- /*
390
- * It is an error in Windows to destroy the current
391
- * cursor. Check that the cursor that is about to
392
- * be destroyed is the current cursor. If so, set
393
- * the current cursor to be IDC_ARROW. Note that
394
- * Windows shares predefined cursors so the call to
395
- * LoadCursor() does not leak.
396
- */
397
- // TEMPORARY CODE
398
- // if (OS.GetCursor() == handle) {
399
- // OS.SetCursor(OS.LoadCursor(0, OS.IDC_ARROW));
400
- // }
401
354
device .deregisterResourceWithZoomSupport (this );
402
- destroyHandle ();
403
- }
404
-
405
- private void destroyHandle () {
406
355
for (CursorHandle handle : zoomLevelToHandle .values ()) {
407
356
handle .destroy ();
408
357
}
409
358
zoomLevelToHandle .clear ();
410
- handle = 0 ;
359
+ this . isDestroyed = true ;
411
360
}
412
361
413
362
/**
@@ -425,7 +374,7 @@ public boolean equals (Object object) {
425
374
if (object == this ) return true ;
426
375
if (!(object instanceof Cursor )) return false ;
427
376
Cursor cursor = (Cursor ) object ;
428
- return device == cursor .device && handle == cursor . handle ;
377
+ return device == cursor .device && win32_getHandle ( this , DEFAULT_ZOOM ) == win32_getHandle ( cursor , DEFAULT_ZOOM ) ;
429
378
}
430
379
431
380
/**
@@ -440,7 +389,7 @@ public boolean equals (Object object) {
440
389
*/
441
390
@ Override
442
391
public int hashCode () {
443
- return ( int ) handle ;
392
+ return win32_getHandle ( this , DEFAULT_ZOOM ). intValue () ;
444
393
}
445
394
446
395
/**
@@ -455,7 +404,7 @@ public int hashCode () {
455
404
*/
456
405
@ Override
457
406
public boolean isDisposed () {
458
- return handle == 0 ;
407
+ return isDestroyed ;
459
408
}
460
409
461
410
/**
@@ -467,7 +416,7 @@ public boolean isDisposed() {
467
416
@ Override
468
417
public String toString () {
469
418
if (isDisposed ()) return "Cursor {*DISPOSED*}" ;
470
- return "Cursor {" + handle + "}" ;
419
+ return "Cursor {" + zoomLevelToHandle + "}" ;
471
420
}
472
421
473
422
@ Override
@@ -531,19 +480,23 @@ private static interface CursorHandleProvider {
531
480
}
532
481
533
482
private static class StyleCursorHandleProvider implements CursorHandleProvider {
534
- private final int style ;
483
+ private final long lpCursorName ;
535
484
536
485
public StyleCursorHandleProvider (int style ) {
537
- this .style = style ;
486
+ this .lpCursorName = getOSCursorIdFromStyle ( style ) ;
538
487
}
539
488
540
489
@ Override
541
490
public CursorHandle createHandle (Device device , int zoom ) {
542
491
// zoom ignored, LoadCursor handles scaling internally
543
- return setupCursorFromStyle (this .style );
492
+ long handle = OS .LoadCursor (0 , lpCursorName );
493
+ if (handle == 0 ) {
494
+ SWT .error (SWT .ERROR_NO_HANDLES );
495
+ }
496
+ return new CustomCursorHandle (handle );
544
497
}
545
498
546
- private static final CursorHandle setupCursorFromStyle (int style ) {
499
+ private static final long getOSCursorIdFromStyle (int style ) {
547
500
long lpCursorName = 0 ;
548
501
switch (style ) {
549
502
case SWT .CURSOR_HAND :
@@ -615,11 +568,7 @@ private static final CursorHandle setupCursorFromStyle(int style) {
615
568
default :
616
569
SWT .error (SWT .ERROR_INVALID_ARGUMENT );
617
570
}
618
- long handle = OS .LoadCursor (0 , lpCursorName );
619
- if (handle == 0 ) {
620
- SWT .error (SWT .ERROR_NO_HANDLES );
621
- }
622
- return new CustomCursorHandle (handle );
571
+ return lpCursorName ;
623
572
}
624
573
}
625
574
@@ -639,13 +588,24 @@ protected final int getHotpotXInPixels(int zoom) {
639
588
protected final int getHotpotYInPixels (int zoom ) {
640
589
return Win32DPIUtils .pointToPixel (hotspotY , zoom );
641
590
}
591
+
592
+ protected static final void validateHotspotInsideImage (ImageData source , int hotspotX , int hotspotY ) {
593
+ /* Check the hotspots */
594
+ if (hotspotX >= source .width || hotspotX < 0 ||
595
+ hotspotY >= source .height || hotspotY < 0 ) {
596
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
597
+ }
598
+ }
642
599
}
643
600
644
601
private static class ImageDataProviderCursorHandleProvider extends HotspotAwareCursorHandleProvider {
645
602
private final ImageDataProvider provider ;
646
603
647
604
public ImageDataProviderCursorHandleProvider (ImageDataProvider provider , int hotspotX , int hotspotY ) {
648
605
super (hotspotX , hotspotY );
606
+ ImageData source = provider .getImageData (DEFAULT_ZOOM );
607
+ if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
608
+ validateHotspotInsideImage (source , hotspotX , hotspotY );
649
609
this .provider = provider ;
650
610
}
651
611
@@ -668,6 +628,8 @@ private static class ImageDataCursorHandleProvider extends HotspotAwareCursorHan
668
628
669
629
public ImageDataCursorHandleProvider (ImageData source , int hotspotX , int hotspotY ) {
670
630
super (hotspotX , hotspotY );
631
+ if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
632
+ validateHotspotInsideImage (source , hotspotX , hotspotY );
671
633
this .source = source ;
672
634
}
673
635
@@ -685,6 +647,21 @@ private static class ImageDataWithMaskCursorHandleProvider extends ImageDataCurs
685
647
public ImageDataWithMaskCursorHandleProvider (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
686
648
super (source , hotspotX , hotspotY );
687
649
this .mask = mask ;
650
+ validateMask (source , mask );
651
+ }
652
+
653
+ private void validateMask (ImageData source , ImageData mask ) {
654
+ ImageData testMask = mask == null ? null : (ImageData ) mask .clone ();
655
+ if (testMask == null ) {
656
+ if (source .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
657
+ SWT .error (SWT .ERROR_NULL_ARGUMENT );
658
+ }
659
+ testMask = source .getTransparencyMask ();
660
+ }
661
+ /* Check the bounds. Mask must be the same size as source */
662
+ if (testMask .width != source .width || testMask .height != source .height ) {
663
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
664
+ }
688
665
}
689
666
690
667
@ Override
0 commit comments