4949 */
5050public final class Cursor extends Resource {
5151
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 ;
6452 /**
6553 * Attribute to cache current native zoom level
6654 */
@@ -70,6 +58,8 @@ public final class Cursor extends Resource {
7058
7159 private final CursorHandleProvider cursorHandleProvider ;
7260
61+ private boolean isDestroyed ;
62+
7363/**
7464 * Constructs a new cursor given a device and a style
7565 * constant describing the desired cursor appearance.
@@ -119,7 +109,6 @@ public final class Cursor extends Resource {
119109public Cursor (Device device , int style ) {
120110 super (device );
121111 this .cursorHandleProvider = new StyleCursorHandleProvider (style );
122- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
123112 init ();
124113 this .device .registerResourceWithZoomSupport (this );
125114}
@@ -160,28 +149,11 @@ public Cursor(Device device, int style) {
160149public Cursor (Device device , ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
161150 super (device );
162151 this .cursorHandleProvider = new ImageDataWithMaskCursorHandleProvider (source , mask , hotspotX , hotspotY );
163- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
164152 init ();
165153 this .device .registerResourceWithZoomSupport (this );
166154}
167155
168156private static CursorHandle setupCursorFromImageData (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
169- if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
170- if (mask == null ) {
171- if (source .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
172- SWT .error (SWT .ERROR_NULL_ARGUMENT );
173- }
174- mask = source .getTransparencyMask ();
175- }
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- }
185157 /* Convert depth to 1 */
186158 mask = ImageData .convertMask (mask );
187159 source = ImageData .convertMask (source );
@@ -229,18 +201,12 @@ private static CursorHandle setupCursorFromImageData(ImageData source, ImageData
229201public Cursor (Device device , ImageData source , int hotspotX , int hotspotY ) {
230202 super (device );
231203 this .cursorHandleProvider = new ImageDataCursorHandleProvider (source , hotspotX , hotspotY );
232- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
233204 init ();
234205 this .device .registerResourceWithZoomSupport (this );
235206}
236207
237208private static CursorHandle setupCursorFromImageData (Device device , ImageData source , int hotspotX , int hotspotY ) {
238209 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- }
244210 long hBitmap = 0 ;
245211 long hMask = 0 ;
246212 if (source .maskData == null && source .transparentPixel == -1 && (source .alpha != -1 || source .alphaData != null )) {
@@ -341,7 +307,6 @@ public Cursor(Device device, ImageDataProvider imageDataProvider, int hotspotX,
341307 super (device );
342308 if (imageDataProvider == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
343309 this .cursorHandleProvider = new ImageDataProviderCursorHandleProvider (imageDataProvider , hotspotX , hotspotY );
344- this .handle = this .cursorHandleProvider .createHandle (this .device , DEFAULT_ZOOM ).getHandle ();
345310 init ();
346311 this .device .registerResourceWithZoomSupport (this );
347312}
@@ -363,7 +328,7 @@ public Cursor(Device device, ImageDataProvider imageDataProvider, int hotspotX,
363328 */
364329public static Long win32_getHandle (Cursor cursor , int zoom ) {
365330 if (cursor .isDisposed ()) {
366- return cursor . handle ;
331+ return 0L ;
367332 }
368333 if (cursor .zoomLevelToHandle .get (zoom ) != null ) {
369334 return cursor .zoomLevelToHandle .get (zoom ).getHandle ();
@@ -376,38 +341,19 @@ public static Long win32_getHandle (Cursor cursor, int zoom) {
376341}
377342
378343private void setHandleForZoomLevel (CursorHandle handle , Integer zoom ) {
379- if (this .handle == 0 ) {
380- this .handle = handle .getHandle (); // Set handle for default zoom level
381- }
382344 if (zoom != null && !zoomLevelToHandle .containsKey (zoom )) {
383345 zoomLevelToHandle .put (zoom , handle );
384346 }
385347}
386348
387349@ Override
388350void 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- // }
401351 device .deregisterResourceWithZoomSupport (this );
402- destroyHandle ();
403- }
404-
405- private void destroyHandle () {
406352 for (CursorHandle handle : zoomLevelToHandle .values ()) {
407353 handle .destroy ();
408354 }
409355 zoomLevelToHandle .clear ();
410- handle = 0 ;
356+ this . isDestroyed = true ;
411357}
412358
413359/**
@@ -425,7 +371,7 @@ public boolean equals (Object object) {
425371 if (object == this ) return true ;
426372 if (!(object instanceof Cursor )) return false ;
427373 Cursor cursor = (Cursor ) object ;
428- return device == cursor .device && handle == cursor . handle ;
374+ return device == cursor .device && win32_getHandle ( this , DEFAULT_ZOOM ) == win32_getHandle ( cursor , DEFAULT_ZOOM ) ;
429375}
430376
431377/**
@@ -440,7 +386,7 @@ public boolean equals (Object object) {
440386 */
441387@ Override
442388public int hashCode () {
443- return ( int ) handle ;
389+ return win32_getHandle ( this , DEFAULT_ZOOM ). intValue () ;
444390}
445391
446392/**
@@ -455,7 +401,7 @@ public int hashCode () {
455401 */
456402@ Override
457403public boolean isDisposed () {
458- return handle == 0 ;
404+ return isDestroyed ;
459405}
460406
461407/**
@@ -467,7 +413,7 @@ public boolean isDisposed() {
467413@ Override
468414public String toString () {
469415 if (isDisposed ()) return "Cursor {*DISPOSED*}" ;
470- return "Cursor {" + handle + "}" ;
416+ return "Cursor {" + zoomLevelToHandle + "}" ;
471417}
472418
473419@ Override
@@ -531,19 +477,23 @@ private static interface CursorHandleProvider {
531477}
532478
533479private static class StyleCursorHandleProvider implements CursorHandleProvider {
534- private final int style ;
480+ private final long lpCursorName ;
535481
536482 public StyleCursorHandleProvider (int style ) {
537- this .style = style ;
483+ this .lpCursorName = getOSCursorIdFromStyle ( style ) ;
538484 }
539485
540486 @ Override
541487 public CursorHandle createHandle (Device device , int zoom ) {
542488 // zoom ignored, LoadCursor handles scaling internally
543- return setupCursorFromStyle (this .style );
489+ long handle = OS .LoadCursor (0 , lpCursorName );
490+ if (handle == 0 ) {
491+ SWT .error (SWT .ERROR_NO_HANDLES );
492+ }
493+ return new CustomCursorHandle (handle );
544494 }
545495
546- private static final CursorHandle setupCursorFromStyle (int style ) {
496+ private static final long getOSCursorIdFromStyle (int style ) {
547497 long lpCursorName = 0 ;
548498 switch (style ) {
549499 case SWT .CURSOR_HAND :
@@ -615,11 +565,7 @@ private static final CursorHandle setupCursorFromStyle(int style) {
615565 default :
616566 SWT .error (SWT .ERROR_INVALID_ARGUMENT );
617567 }
618- long handle = OS .LoadCursor (0 , lpCursorName );
619- if (handle == 0 ) {
620- SWT .error (SWT .ERROR_NO_HANDLES );
621- }
622- return new CustomCursorHandle (handle );
568+ return lpCursorName ;
623569 }
624570}
625571
@@ -646,6 +592,13 @@ private static class ImageDataProviderCursorHandleProvider extends HotspotAwareC
646592
647593 public ImageDataProviderCursorHandleProvider (ImageDataProvider provider , int hotspotX , int hotspotY ) {
648594 super (hotspotX , hotspotY );
595+ ImageData source = provider .getImageData (DEFAULT_ZOOM );
596+ if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
597+ /* Check the hotspots */
598+ if (hotspotX >= source .width || hotspotX < 0 ||
599+ hotspotY >= source .height || hotspotY < 0 ) {
600+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
601+ }
649602 this .provider = provider ;
650603 }
651604
@@ -668,6 +621,12 @@ private static class ImageDataCursorHandleProvider extends HotspotAwareCursorHan
668621
669622 public ImageDataCursorHandleProvider (ImageData source , int hotspotX , int hotspotY ) {
670623 super (hotspotX , hotspotY );
624+ if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
625+ /* Check the hotspots */
626+ if (hotspotX >= source .width || hotspotX < 0 ||
627+ hotspotY >= source .height || hotspotY < 0 ) {
628+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
629+ }
671630 this .source = source ;
672631 }
673632
@@ -685,6 +644,21 @@ private static class ImageDataWithMaskCursorHandleProvider extends ImageDataCurs
685644 public ImageDataWithMaskCursorHandleProvider (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
686645 super (source , hotspotX , hotspotY );
687646 this .mask = mask ;
647+ validateMask (source , mask );
648+ }
649+
650+ private void validateMask (ImageData source , ImageData mask ) {
651+ ImageData testMask = mask == null ? null : (ImageData ) mask .clone ();
652+ if (testMask == null ) {
653+ if (source .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
654+ SWT .error (SWT .ERROR_NULL_ARGUMENT );
655+ }
656+ testMask = source .getTransparencyMask ();
657+ }
658+ /* Check the bounds. Mask must be the same size as source */
659+ if (testMask .width != source .width || testMask .height != source .height ) {
660+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
661+ }
688662 }
689663
690664 @ Override
0 commit comments