Index: Eclipse SWT/common/org/eclipse/swt/SWT.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java,v retrieving revision 1.101 diff -u -r1.101 SWT.java --- Eclipse SWT/common/org/eclipse/swt/SWT.java 14 Apr 2005 13:35:07 -0000 1.101 +++ Eclipse SWT/common/org/eclipse/swt/SWT.java 17 Jun 2005 23:08:39 -0000 @@ -2223,6 +2223,13 @@ */ public static final int ERROR_INVALID_FONT = 48; + /** + * SWT error constant indicating that an attempt was made to + * dispose an SWT graphics object while it was still in use + * (value is 49). + */ + public static final int ERROR_GRAPHIC_DISPOSED_EARLY = 49; + /** * Traversal event detail field value indicating that no * traversal action should be taken @@ -2784,9 +2791,10 @@ case ERROR_DEVICE_DISPOSED: return "Device is disposed"; //$NON-NLS-1$ case ERROR_FAILED_EXEC: return "Failed to execute runnable"; //$NON-NLS-1$ case ERROR_FAILED_LOAD_LIBRARY: return "Unable to load library"; //$NON-NLS-1$ - case ERROR_CANNOT_INVERT_MATRIX: return "Cannot invert matrix"; //$NON-NLS-1$ + case ERROR_CANNOT_INVERT_MATRIX: return "Cannot invert matrix"; //$NON-NLS-1$ case ERROR_NO_GRAPHICS_LIBRARY: return "Unable to load graphics library"; //$NON-NLS-1$ - case ERROR_INVALID_FONT: return "Font not valid"; //$NON-NLS-1$ + case ERROR_INVALID_FONT: return "Font not valid"; //$NON-NLS-1$ + case ERROR_GRAPHIC_DISPOSED_EARLY: return "Graphic was disposed while still in use"; //$NON-NLS-1$ } return "Unknown error"; //$NON-NLS-1$ } Index: Eclipse SWT/common/org/eclipse/swt/graphics/Resource.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Resource.java,v retrieving revision 1.4 diff -u -r1.4 Resource.java --- Eclipse SWT/common/org/eclipse/swt/graphics/Resource.java 31 Mar 2005 21:34:28 -0000 1.4 +++ Eclipse SWT/common/org/eclipse/swt/graphics/Resource.java 17 Jun 2005 23:08:39 -0000 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.swt.graphics; +import org.eclipse.swt.SWT; + /** * This class is the abstract superclass of all graphics resource objects. * Resources created by the application must be disposed. @@ -38,8 +40,53 @@ * the device where this resource was created */ Device device; + + int locks = 0; + +/** + * Locks this resource, preventing its dispose method from being used. + * This does not necessarily prevent the resource from being disposed + * by the OS, but it will cause an exception to be thrown if an + * attempt is made to explicitly call dispose. + * + *

+ * Locking the resource permits it to safely be exposed as public API + * without creating a risk that other objects will dispose the resource + * prematurely. + *

+ * + *

+ * Each call to lock must have a matching call to unlock with an identical + * key before the Resource may be disposed. + *

+ * + * @param key an integer chosen by the caller that will later be used + * to unlock the resource. + */ +public void lock(int key) { + locks += key; +} /** + * Unlocks a resource previously locked by a call to lock(...). A locked resource + * must be unlocked with the same keys before it can be disposed. Resources + * cannot be unlocked more than once unless they were locked the same number of + * times. + * + * @param key a key that had previously been used as an argument to lock(...). + */ +public void unlock(int key) { + locks -= key; +} + +/** + * Throws an exception if this resource is currently locked. + */ +protected void checkLocks() { + if (locks != 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED_EARLY); +} + +/** * Disposes of the operating system resources associated with * this resource. Applications must dispose of all resources * which they allocate. Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java,v retrieving revision 1.18 diff -u -r1.18 Color.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java 30 Mar 2005 23:17:53 -0000 1.18 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java 17 Jun 2005 23:08:40 -0000 @@ -118,6 +118,7 @@ public void dispose() { if (handle == -1) return; if (device.isDisposed()) return; + checkLocks(); /* * If this is a palette-based device, Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java,v retrieving revision 1.29 diff -u -r1.29 Cursor.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java 30 Mar 2005 23:17:53 -0000 1.29 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java 17 Jun 2005 23:08:40 -0000 @@ -361,6 +361,7 @@ public void dispose () { if (handle == 0) return; if (device.isDisposed()) return; + checkLocks(); /* * It is an error in Windows to destroy the current Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java,v retrieving revision 1.23 diff -u -r1.23 Font.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java 14 Apr 2005 14:27:10 -0000 1.23 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java 17 Jun 2005 23:08:40 -0000 @@ -146,6 +146,7 @@ public void dispose() { if (handle == 0) return; if (device.isDisposed()) return; + checkLocks(); OS.DeleteObject(handle); handle = 0; if (device.tracking) device.dispose_Object(this); Index: Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java,v retrieving revision 1.162 diff -u -r1.162 GC.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java 16 Jun 2005 22:13:05 -0000 1.162 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java 17 Jun 2005 23:08:40 -0000 @@ -427,6 +427,7 @@ public void dispose() { if (handle == 0) return; if (data.device.isDisposed()) return; + checkLocks(); if (data.gdipGraphics != 0) Gdip.Graphics_delete(data.gdipGraphics); if (data.gdipPen != 0) Gdip.Pen_delete(data.gdipPen); Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java,v retrieving revision 1.69 diff -u -r1.69 Image.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java 13 Jun 2005 20:32:03 -0000 1.69 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java 17 Jun 2005 23:08:40 -0000 @@ -960,6 +960,8 @@ public void dispose () { if (handle == 0) return; if (device.isDisposed()) return; + checkLocks(); + if (memGC != null) memGC.dispose(); if (type == SWT.ICON) { if (OS.IsWinCE) data = null; Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java,v retrieving revision 1.17 diff -u -r1.17 Path.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java 3 Jun 2005 21:01:18 -0000 1.17 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java 17 Jun 2005 23:08:40 -0000 @@ -287,6 +287,7 @@ public void dispose() { if (handle == 0) return; if (device.isDisposed()) return; + checkLocks(); Gdip.GraphicsPath_delete(handle); handle = 0; if (device.tracking) device.dispose_Object(this); Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Pattern.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Pattern.java,v retrieving revision 1.6 diff -u -r1.6 Pattern.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Pattern.java 17 May 2005 19:39:40 -0000 1.6 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Pattern.java 17 Jun 2005 23:08:40 -0000 @@ -138,6 +138,7 @@ public void dispose() { if (handle == 0) return; if (device.isDisposed()) return; + checkLocks(); int type = Gdip.Brush_GetType(handle); switch (type) { case Gdip.BrushTypeSolidColor: Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java,v retrieving revision 1.26 diff -u -r1.26 Region.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java 30 Mar 2005 23:17:53 -0000 1.26 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java 17 Jun 2005 23:08:40 -0000 @@ -229,6 +229,7 @@ public void dispose () { if (handle == 0) return; if (device.isDisposed()) return; + checkLocks(); OS.DeleteObject(handle); handle = 0; if (device.tracking) device.dispose_Object(this); Index: Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java,v retrieving revision 1.60 diff -u -r1.60 TextLayout.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java 18 May 2005 18:52:29 -0000 1.60 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java 17 Jun 2005 23:08:40 -0000 @@ -395,6 +395,7 @@ */ public void dispose () { if (device == null) return; + checkLocks(); freeRuns(); font = null; text = null; Index: Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java =================================================================== RCS file: /home/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java,v retrieving revision 1.10 diff -u -r1.10 Transform.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java 18 May 2005 16:13:30 -0000 1.10 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java 17 Jun 2005 23:08:40 -0000 @@ -122,6 +122,7 @@ public void dispose() { if (handle == 0) return; if (device.isDisposed()) return; + checkLocks(); Gdip.Matrix_delete(handle); handle = 0; if (device.tracking) device.dispose_Object(this);