Mercurial > dwindows
comparison mac/dw.m @ 699:b79300831495
Offload some drawing functions to the main thread to prevent focus deadlocks.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Fri, 11 Mar 2011 02:33:19 +0000 |
parents | e19f69a78f21 |
children | 7953f0471e4d |
comparison
equal
deleted
inserted
replaced
698:e19f69a78f21 | 699:b79300831495 |
---|---|
237 HMTX DWThreadMutex; | 237 HMTX DWThreadMutex; |
238 HMTX DWThreadMutex2; | 238 HMTX DWThreadMutex2; |
239 DWTID DWThread = (DWTID)-1; | 239 DWTID DWThread = (DWTID)-1; |
240 DWTID _dw_mutex_locked = (DWTID)-1; | 240 DWTID _dw_mutex_locked = (DWTID)-1; |
241 | 241 |
242 /* Used for doing bitblts from the main thread */ | |
243 typedef struct _bitbltinfo | |
244 { | |
245 id src; | |
246 id dest; | |
247 int xdest; | |
248 int ydest; | |
249 int width; | |
250 int height; | |
251 int xsrc; | |
252 int ysrc; | |
253 } DWBitBlt; | |
254 | |
242 /* Subclass for a test object type */ | 255 /* Subclass for a test object type */ |
243 @interface DWObject : NSObject {} | 256 @interface DWObject : NSObject {} |
244 -(void)uselessThread:(id)sender; | 257 -(void)uselessThread:(id)sender; |
245 -(void)synchronizeThread:(id)param; | 258 -(void)synchronizeThread:(id)param; |
259 -(void)doBitBlt:(id)param; | |
260 -(void)doFlush:(id)param; | |
246 @end | 261 @end |
247 | 262 |
248 @implementation DWObject | 263 @implementation DWObject |
249 -(void)uselessThread:(id)sender { /* Thread only to initialize threading */ } | 264 -(void)uselessThread:(id)sender { /* Thread only to initialize threading */ } |
250 -(void)synchronizeThread:(id)param | 265 -(void)synchronizeThread:(id)param |
253 //NSLog(@"Main thread releasing lock"); | 268 //NSLog(@"Main thread releasing lock"); |
254 pthread_mutex_lock(DWThreadMutex2); | 269 pthread_mutex_lock(DWThreadMutex2); |
255 pthread_mutex_unlock(DWThreadMutex2); | 270 pthread_mutex_unlock(DWThreadMutex2); |
256 pthread_mutex_lock(DWRunMutex); | 271 pthread_mutex_lock(DWRunMutex); |
257 //NSLog(@"Main thread reacquiring lock"); | 272 //NSLog(@"Main thread reacquiring lock"); |
273 } | |
274 -(void)doBitBlt:(id)param | |
275 { | |
276 NSValue *bi = (NSValue *)param; | |
277 DWBitBlt *bltinfo = (DWBitBlt *)[bi pointerValue]; | |
278 id bltdest = bltinfo->dest; | |
279 id bltsrc = bltinfo->src; | |
280 | |
281 if([bltdest isMemberOfClass:[NSImage class]]) | |
282 { | |
283 [bltdest lockFocus]; | |
284 } | |
285 else | |
286 { | |
287 [bltdest lockFocusIfCanDraw]; | |
288 _DWLastDrawable = bltinfo->dest; | |
289 } | |
290 if([bltsrc isMemberOfClass:[NSImage class]]) | |
291 { | |
292 NSImage *image = bltsrc; | |
293 [image drawAtPoint:NSMakePoint(bltinfo->xdest, bltinfo->ydest) fromRect:NSMakeRect(bltinfo->xsrc, bltinfo->ysrc, bltinfo->width, bltinfo->height) | |
294 operation:NSCompositeCopy fraction:1.0]; | |
295 [bltsrc release]; | |
296 } | |
297 [bltdest unlockFocus]; | |
298 free(bltinfo); | |
299 } | |
300 -(void)doFlush:(id)param | |
301 { | |
302 if(_DWLastDrawable) | |
303 { | |
304 id object = _DWLastDrawable; | |
305 NSWindow *window = [object window]; | |
306 [window flushWindow]; | |
307 } | |
258 } | 308 } |
259 @end | 309 @end |
260 | 310 |
261 DWObject *DWObj; | 311 DWObject *DWObj; |
262 | 312 |
4661 * xsrc: X coordinate of source. | 4711 * xsrc: X coordinate of source. |
4662 * ysrc: Y coordinate of source. | 4712 * ysrc: Y coordinate of source. |
4663 */ | 4713 */ |
4664 void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) | 4714 void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) |
4665 { | 4715 { |
4666 int _locked_by_me = FALSE; | 4716 DWBitBlt *bltinfo = calloc(1, sizeof(DWBitBlt)); |
4667 DW_MUTEX_LOCK; | 4717 NSValue* bi = [NSValue valueWithPointer:bltinfo]; |
4668 id bltdest = dest; | 4718 |
4669 id bltsrc = src; | 4719 /* Fill in the information */ |
4670 if(destp) | 4720 bltinfo->dest = dest; |
4671 { | 4721 bltinfo->src = src; |
4672 bltdest = (id)destp->handle; | 4722 bltinfo->xdest = xdest; |
4673 [bltdest lockFocus]; | 4723 bltinfo->ydest = ydest; |
4674 } | 4724 bltinfo->width = width; |
4675 else | 4725 bltinfo->height = height; |
4676 { | 4726 bltinfo->xsrc = xsrc; |
4677 [bltdest lockFocusIfCanDraw]; | 4727 bltinfo->ysrc = ysrc; |
4678 _DWLastDrawable = dest; | 4728 |
4679 } | 4729 if(destp) |
4680 if(srcp) | 4730 { |
4681 { | 4731 bltinfo->dest = (id)destp->handle; |
4682 bltsrc = (id)srcp->handle; | 4732 } |
4683 NSImage *image = bltsrc; | 4733 if(srcp) |
4684 [image drawAtPoint:NSMakePoint(xdest, ydest) fromRect:NSMakeRect(xsrc, ysrc, width, height) operation:NSCompositeCopy fraction:1.0]; | 4734 { |
4685 } | 4735 id object = bltinfo->src = (id)srcp->handle; |
4686 [bltdest unlockFocus]; | 4736 [object retain]; |
4687 DW_MUTEX_UNLOCK; | 4737 } |
4738 [DWObj performSelectorOnMainThread:@selector(doBitBlt:) withObject:bi waitUntilDone:YES]; | |
4688 } | 4739 } |
4689 | 4740 |
4690 /* | 4741 /* |
4691 * Create a new static text window (widget) to be packed. | 4742 * Create a new static text window (widget) to be packed. |
4692 * Not available under OS/2, eCS | 4743 * Not available under OS/2, eCS |
5958 * anything you have drawn is visible. | 6009 * anything you have drawn is visible. |
5959 */ | 6010 */ |
5960 void API dw_flush(void) | 6011 void API dw_flush(void) |
5961 { | 6012 { |
5962 /* This may need to be thread specific */ | 6013 /* This may need to be thread specific */ |
5963 if(_DWLastDrawable) | 6014 [DWObj performSelectorOnMainThread:@selector(doFlush:) withObject:nil waitUntilDone:NO]; |
5964 { | |
5965 int _locked_by_me = FALSE; | |
5966 DW_MUTEX_LOCK; | |
5967 id object = _DWLastDrawable; | |
5968 NSWindow *window = [object window]; | |
5969 [window flushWindow]; | |
5970 DW_MUTEX_UNLOCK; | |
5971 } | |
5972 } | 6015 } |
5973 | 6016 |
5974 /* Functions for managing the user data lists that are associated with | 6017 /* Functions for managing the user data lists that are associated with |
5975 * a given window handle. Used in dw_window_set_data() and | 6018 * a given window handle. Used in dw_window_set_data() and |
5976 * dw_window_get_data(). | 6019 * dw_window_get_data(). |