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().