@@ -66,10 +66,9 @@ public final class Cursor extends Resource {
66
66
*/
67
67
private static final int DEFAULT_ZOOM = 100 ;
68
68
69
- private HashMap <Integer , Long > zoomLevelToHandle = new HashMap <>();
69
+ private HashMap <Integer , CursorHandle > zoomLevelToHandle = new HashMap <>();
70
70
71
71
private final CursorHandleProvider cursorHandleProvider ;
72
- boolean isIcon ;
73
72
74
73
/**
75
74
* Constructs a new cursor given a device and a style
@@ -120,7 +119,7 @@ public final class Cursor extends Resource {
120
119
public Cursor (Device device , int style ) {
121
120
super (device );
122
121
this .cursorHandleProvider = new StyleCursorHandleProvider (style );
123
- this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM );
122
+ this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM ). getHandle () ;
124
123
init ();
125
124
this .device .registerResourceWithZoomSupport (this );
126
125
}
@@ -161,12 +160,12 @@ public Cursor(Device device, int style) {
161
160
public Cursor (Device device , ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
162
161
super (device );
163
162
this .cursorHandleProvider = new ImageDataWithMaskCursorHandleProvider (source , mask , hotspotX , hotspotY );
164
- this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM );
163
+ this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM ). getHandle () ;
165
164
init ();
166
165
this .device .registerResourceWithZoomSupport (this );
167
166
}
168
167
169
- private static long setupCursorFromImageData (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
168
+ private static CursorHandle setupCursorFromImageData (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
170
169
if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
171
170
if (mask == null ) {
172
171
if (source .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
@@ -195,7 +194,7 @@ private static long setupCursorFromImageData(ImageData source, ImageData mask, i
195
194
long hInst = OS .GetModuleHandle (null );
196
195
long handle = OS .CreateCursor (hInst , hotspotX , hotspotY , source .width , source .height , sourceData , maskData );
197
196
if (handle == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
198
- return handle ;
197
+ return new CustomCursorHandle ( handle ) ;
199
198
}
200
199
201
200
/**
@@ -230,13 +229,12 @@ private static long setupCursorFromImageData(ImageData source, ImageData mask, i
230
229
public Cursor (Device device , ImageData source , int hotspotX , int hotspotY ) {
231
230
super (device );
232
231
this .cursorHandleProvider = new ImageDataCursorHandleProvider (source , hotspotX , hotspotY );
233
- isIcon = true ;
234
- this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM );
232
+ this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM ).getHandle ();
235
233
init ();
236
234
this .device .registerResourceWithZoomSupport (this );
237
235
}
238
236
239
- private static long setupCursorFromImageData (Device device , ImageData source , int hotspotX , int hotspotY ) {
237
+ private static CursorHandle setupCursorFromImageData (Device device , ImageData source , int hotspotX , int hotspotY ) {
240
238
if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
241
239
/* Check the hotspots */
242
240
if (hotspotX >= source .width || hotspotX < 0 ||
@@ -307,7 +305,7 @@ private static long setupCursorFromImageData(Device device, ImageData source, in
307
305
OS .DeleteObject (hMask );
308
306
if (handle == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
309
307
310
- return handle ;
308
+ return new IconCursorHandle ( handle ) ;
311
309
}
312
310
313
311
/**
@@ -343,8 +341,7 @@ public Cursor(Device device, ImageDataProvider imageDataProvider, int hotspotX,
343
341
super (device );
344
342
if (imageDataProvider == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
345
343
this .cursorHandleProvider = new ImageDataProviderCursorHandleProvider (imageDataProvider , hotspotX , hotspotY );
346
- isIcon = true ;
347
- this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM );
344
+ this .handle = this .cursorHandleProvider .createHandle (device , DEFAULT_ZOOM ).getHandle ();
348
345
init ();
349
346
this .device .registerResourceWithZoomSupport (this );
350
347
}
@@ -369,18 +366,18 @@ public static Long win32_getHandle (Cursor cursor, int zoom) {
369
366
return cursor .handle ;
370
367
}
371
368
if (cursor .zoomLevelToHandle .get (zoom ) != null ) {
372
- return cursor .zoomLevelToHandle .get (zoom );
369
+ return cursor .zoomLevelToHandle .get (zoom ). getHandle () ;
373
370
}
374
371
375
- long handle = cursor .cursorHandleProvider .createHandle (cursor .device , zoom );
372
+ CursorHandle handle = cursor .cursorHandleProvider .createHandle (cursor .device , zoom );
376
373
cursor .setHandleForZoomLevel (handle , zoom );
377
374
378
- return cursor .zoomLevelToHandle .get (zoom );
375
+ return cursor .zoomLevelToHandle .get (zoom ). getHandle () ;
379
376
}
380
377
381
- private void setHandleForZoomLevel (long handle , Integer zoom ) {
378
+ private void setHandleForZoomLevel (CursorHandle handle , Integer zoom ) {
382
379
if (this .handle == 0 ) {
383
- this .handle = handle ; // Set handle for default zoom level
380
+ this .handle = handle . getHandle () ; // Set handle for default zoom level
384
381
}
385
382
if (zoom != null && !zoomLevelToHandle .containsKey (zoom )) {
386
383
zoomLevelToHandle .put (zoom , handle );
@@ -406,29 +403,13 @@ void destroy () {
406
403
}
407
404
408
405
private void destroyHandle () {
409
- for (Long handle : zoomLevelToHandle .values ()) {
410
- destroyHandle ( handle );
406
+ for (CursorHandle handle : zoomLevelToHandle .values ()) {
407
+ handle . destroy ( );
411
408
}
412
409
zoomLevelToHandle .clear ();
413
410
handle = 0 ;
414
411
}
415
412
416
- private void destroyHandle (long handle ) {
417
- if (isIcon ) {
418
- OS .DestroyIcon (handle );
419
- } else {
420
- /*
421
- * The MSDN states that one should not destroy a shared
422
- * cursor, that is, one obtained from LoadCursor.
423
- * However, it does not appear to do any harm, so rather
424
- * than keep track of how a cursor was created, we just
425
- * destroy them all. If this causes problems in the future,
426
- * put the flag back in.
427
- */
428
- OS .DestroyCursor (handle );
429
- }
430
- }
431
-
432
413
/**
433
414
* Compares the argument to the receiver, and returns true
434
415
* if they represent the <em>same</em> object using a class
@@ -494,15 +475,59 @@ void destroyHandlesExcept(Set<Integer> zoomLevels) {
494
475
zoomLevelToHandle .entrySet ().removeIf (entry -> {
495
476
final Integer zoom = entry .getKey ();
496
477
if (!zoomLevels .contains (zoom ) && zoom != DPIUtil .getZoomForAutoscaleProperty (DEFAULT_ZOOM )) {
497
- destroyHandle ( entry .getValue ());
478
+ entry .getValue (). destroy ( );
498
479
return true ;
499
480
}
500
481
return false ;
501
482
});
502
483
}
503
484
485
+ private static abstract class CursorHandle {
486
+ private final long handle ;
487
+
488
+ public CursorHandle (long handle ) {
489
+ this .handle = handle ;
490
+ }
491
+
492
+ long getHandle () {
493
+ return handle ;
494
+ }
495
+
496
+ abstract void destroy ();
497
+ }
498
+
499
+ private static class IconCursorHandle extends CursorHandle {
500
+ public IconCursorHandle (long handle ) {
501
+ super (handle );
502
+ }
503
+
504
+ @ Override
505
+ void destroy () {
506
+ OS .DestroyIcon (getHandle ());
507
+ }
508
+ }
509
+
510
+ private static class CustomCursorHandle extends CursorHandle {
511
+ public CustomCursorHandle (long handle ) {
512
+ super (handle );
513
+ }
514
+
515
+ @ Override
516
+ void destroy () {
517
+ /*
518
+ * The MSDN states that one should not destroy a shared
519
+ * cursor, that is, one obtained from LoadCursor.
520
+ * However, it does not appear to do any harm, so rather
521
+ * than keep track of how a cursor was created, we just
522
+ * destroy them all. If this causes problems in the future,
523
+ * put the flag back in.
524
+ */
525
+ OS .DestroyCursor (getHandle ());
526
+ }
527
+ }
528
+
504
529
private static interface CursorHandleProvider {
505
- long createHandle (Device device , int zoom );
530
+ CursorHandle createHandle (Device device , int zoom );
506
531
}
507
532
508
533
private static class StyleCursorHandleProvider implements CursorHandleProvider {
@@ -513,12 +538,12 @@ public StyleCursorHandleProvider(int style) {
513
538
}
514
539
515
540
@ Override
516
- public long createHandle (Device device , int zoom ) {
541
+ public CursorHandle createHandle (Device device , int zoom ) {
517
542
// zoom ignored, LoadCursor handles scaling internally
518
543
return setupCursorFromStyle (this .style );
519
544
}
520
545
521
- private static final long setupCursorFromStyle (int style ) {
546
+ private static final CursorHandle setupCursorFromStyle (int style ) {
522
547
long lpCursorName = 0 ;
523
548
switch (style ) {
524
549
case SWT .CURSOR_HAND :
@@ -594,7 +619,7 @@ private static final long setupCursorFromStyle(int style) {
594
619
if (handle == 0 ) {
595
620
SWT .error (SWT .ERROR_NO_HANDLES );
596
621
}
597
- return handle ;
622
+ return new CustomCursorHandle ( handle ) ;
598
623
}
599
624
}
600
625
@@ -625,7 +650,7 @@ public ImageDataProviderCursorHandleProvider(ImageDataProvider provider, int hot
625
650
}
626
651
627
652
@ Override
628
- public long createHandle (Device device , int zoom ) {
653
+ public CursorHandle createHandle (Device device , int zoom ) {
629
654
ImageData source ;
630
655
if (zoom == DEFAULT_ZOOM ) {
631
656
source = this .provider .getImageData (DEFAULT_ZOOM );
@@ -647,7 +672,7 @@ public ImageDataCursorHandleProvider(ImageData source, int hotspotX, int hotspot
647
672
}
648
673
649
674
@ Override
650
- public long createHandle (Device device , int zoom ) {
675
+ public CursorHandle createHandle (Device device , int zoom ) {
651
676
ImageData scaledSource = DPIUtil .scaleImageData (device , this .source , zoom , DEFAULT_ZOOM );
652
677
return setupCursorFromImageData (device , scaledSource , getHotpotXInPixels (zoom ),
653
678
getHotpotYInPixels (zoom ));
@@ -663,7 +688,7 @@ public ImageDataWithMaskCursorHandleProvider(ImageData source, ImageData mask, i
663
688
}
664
689
665
690
@ Override
666
- public long createHandle (Device device , int zoom ) {
691
+ public CursorHandle createHandle (Device device , int zoom ) {
667
692
ImageData scaledSource = DPIUtil .scaleImageData (device , this .source , zoom , DEFAULT_ZOOM );
668
693
ImageData scaledMask = this .mask != null ? DPIUtil .scaleImageData (device , mask , zoom , DEFAULT_ZOOM )
669
694
: null ;
0 commit comments