Win32: Added methods to lock device context in place
Added #dcLockForGC: and #dcUnlockForGC: to "lock" device context
in place. After a call to #dcLockForGC: it's guaranteed that the
device context is not destroyed - until corresponding #dcUnlockForGC:
is called.
This facility is to be used by alternative drawing libraries,
e.g. Cairo.
--- a/WinWorkstation.st Fri Mar 25 06:41:01 2016 +0000
+++ b/WinWorkstation.st Mon Mar 28 00:38:27 2016 +0100
@@ -8079,6 +8079,58 @@
self removeKnownView:aView withId:aWindowId
!
+dcLockForGC:gcId
+ "Locks and return a device context for given GC.
+ Returned DeviceContext is associated with given GC and it's
+ guaranteed not to be destroyed (by ReleaseDC()) until
+ #dcUnlockForGC: is called.
+
+ NOTE: The DC __is__ destroyed, however, when the whole
+ GC is destroyed."
+
+ | error |
+%{
+ if (__isExternalAddress(gcId)) {
+ struct gcData *gc = _GCDATA(gcId);
+ HDC hDC;
+ if (! gc->_hDC) {
+ hDC = _getDC(gc);
+ gc->_hDC = hDC;
+ } else {
+ hDC = gc->_hDC;
+ }
+ gc->doNotCacheOrRelease = 1;
+ RETURN ( __MKEXTERNALADDRESS ( hDC ) );
+ }
+ error = @symbol(BadArg1);
+ err:;
+%}.
+ ^ self primitiveFailed: error
+!
+
+dcUnlockForGC:gcId
+ "Unlocks and __destroy__ a device context for given GC previously
+ locked by #dcLockForGC:. If the GC was not locked,
+ calling this method is no-op."
+
+ | error |
+%{
+ if (__isExternalAddress(gcId)) {
+ struct gcData *gc = _GCDATA(gcId);
+ if (gc->hWnd) {
+ gc->doNotCacheOrRelease = 0;
+ if (gc->_hDC) {
+ _releaseDC(gc);
+ }
+ }
+ RETURN ( nil );
+ }
+ error = @symbol(BadArg1);
+ err:;
+%}.
+ ^ self primitiveFailed: error
+!
+
gcFor:aDrawableId
%{ /* NOCONTEXT */
@@ -8179,19 +8231,6 @@
%}
!
-hdcForGC: gcId
- "Private. Return a HDC (as ExternalAddress) associated with
- given GC"
-%{
- if (__isExternalAddressLike(gcId)) {
- HDC dc = _getDC ( _GCDATA(gcId) );
- _GCDATA(gcId)->doNotCacheOrRelease = 1;
- RETURN ( __MKEXTERNALADDRESS ( dc ) );
- }
-%}.
- self primitiveFailed.
-!
-
primCreateBitmapFromArray:anArray width:w height:h
%{