comparison mac/dw.m @ 660:2784e7ee8bcb

Fixes for pixmaps and drawing to the screen. Running into some deadlock issues with multithreaded applications that draw from multiple threads.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 24 Feb 2011 22:42:29 +0000
parents 756015085da7
children eee90a788876
comparison
equal deleted inserted replaced
659:756015085da7 660:2784e7ee8bcb
96 96
97 if(!timerfunc(handler->data)) 97 if(!timerfunc(handler->data))
98 dw_timer_disconnect(handler->id); 98 dw_timer_disconnect(handler->id);
99 return 0; 99 return 0;
100 } 100 }
101 case 1:
102 {
103 int (*sizefunc)(HWND, int, int, void *) = handler->signalfunction;
104 NSSize size;
105
106 if([object isMemberOfClass:[NSWindow class]])
107 {
108 NSWindow *window = object;
109 size = [[window contentView] frame].size;
110 }
111 else
112 {
113 NSView *view = object;
114 size = [view frame].size;
115 }
116
117 return sizefunc(object, size.width, size.height, handler->data);
118 }
101 case 3: 119 case 3:
102 case 4: 120 case 4:
103 { 121 {
104 int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))handler->signalfunction; 122 int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))handler->signalfunction;
105 int flags = [object pressedMouseButtons]; 123 int flags = [object pressedMouseButtons];
142 160
143 exp.x = rect.origin.x; 161 exp.x = rect.origin.x;
144 exp.y = rect.origin.y; 162 exp.y = rect.origin.y;
145 exp.width = rect.size.width; 163 exp.width = rect.size.width;
146 exp.height = rect.size.height; 164 exp.height = rect.size.height;
147 return exposefunc(object, &exp, handler->data); 165 int result = exposefunc(object, &exp, handler->data);
166 NSGraphicsContext *gc = [[object window] graphicsContext];
167 [gc flushGraphics];
168 return result;
148 } 169 }
149 case 8: 170 case 8:
150 { 171 {
151 int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))handler->signalfunction; 172 int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))handler->signalfunction;
152 173
277 [[NSNotificationCenter defaultCenter] removeObserver:self]; 298 [[NSNotificationCenter defaultCenter] removeObserver:self];
278 [super dealloc]; 299 [super dealloc];
279 } 300 }
280 - (void)windowResized:(NSNotification *)notification; 301 - (void)windowResized:(NSNotification *)notification;
281 { 302 {
282 NSSize size = [self frame].size; 303 NSSize size = [self frame].size;
283 _do_resize(&box, size.width, size.height); 304 _do_resize(&box, size.width, size.height);
305 _event_handler([self window], nil, 1);
284 } 306 }
285 -(void)windowDidBecomeMain:(id)sender 307 -(void)windowDidBecomeMain:(id)sender
286 { 308 {
287 if(windowmenu) 309 if(windowmenu)
288 { 310 {
493 } 515 }
494 -(void *)userdata; 516 -(void *)userdata;
495 -(void)setUserdata:(void *)input; 517 -(void)setUserdata:(void *)input;
496 -(void)drawRect:(NSRect)rect; 518 -(void)drawRect:(NSRect)rect;
497 -(BOOL)isFlipped; 519 -(BOOL)isFlipped;
520 -(void)mouseDown:(NSEvent *)theEvent;
521 -(void)mouseUp:(NSEvent *)theEvent;
498 @end 522 @end
499 523
500 @implementation DWRender 524 @implementation DWRender
501 -(void *)userdata { return userdata; } 525 -(void *)userdata { return userdata; }
502 -(void)setUserdata:(void *)input { userdata = input; } 526 -(void)setUserdata:(void *)input { userdata = input; }
503 -(void)drawRect:(NSRect)rect { _event_handler(self, nil, 7); } 527 -(void)drawRect:(NSRect)rect { _event_handler(self, nil, 7); }
504 -(BOOL)isFlipped { return YES; } 528 -(BOOL)isFlipped { return YES; }
529 -(void)mouseDown:(NSEvent *)theEvent { _event_handler(self, theEvent, 3); }
530 -(void)mouseUp:(NSEvent *)theEvent { _event_handler(self, theEvent, 4); }
505 @end 531 @end
506 532
507 /* Subclass for a MLE type */ 533 /* Subclass for a MLE type */
508 @interface DWMLE : NSTextView 534 @interface DWMLE : NSTextView
509 { 535 {
690 @end 716 @end
691 717
692 @implementation DWComboBox 718 @implementation DWComboBox
693 -(void *)userdata { return userdata; } 719 -(void *)userdata { return userdata; }
694 -(void)setUserdata:(void *)input { userdata = input; } 720 -(void)setUserdata:(void *)input { userdata = input; }
721 @end
722
723 /* Subclass for a test object type */
724 @interface DWObject : NSObject {}
725 -(void)uselessThread:(id)sender;
726 @end
727
728 @implementation DWObject
729 -(void)uselessThread:(id)sender { /* Thread only to initialize threading */ }
695 @end 730 @end
696 731
697 typedef struct 732 typedef struct
698 { 733 {
699 ULONG message; 734 ULONG message;
1167 Box box = [view box]; 1202 Box box = [view box];
1168 NSSize size = [view frame].size; 1203 NSSize size = [view frame].size;
1169 _do_resize(&box, size.width, size.height); 1204 _do_resize(&box, size.width, size.height);
1170 } 1205 }
1171 } 1206 }
1207 else if([handle isMemberOfClass:[DWRender class]])
1208 {
1209 _event_handler(handle, nil, 1);
1210 }
1211
1172 if(thisbox->type == DW_HORZ) 1212 if(thisbox->type == DW_HORZ)
1173 currentx += width + vectorx + (pad * 2); 1213 currentx += width + vectorx + (pad * 2);
1174 if(thisbox->type == DW_VERT) 1214 if(thisbox->type == DW_VERT)
1175 currenty += height + vectory + (pad * 2); 1215 currenty += height + vectory + (pad * 2);
1176 } 1216 }
1317 #if !defined(GARBAGE_COLLECT) 1357 #if !defined(GARBAGE_COLLECT)
1318 pool = [[NSAutoreleasePool alloc] init]; 1358 pool = [[NSAutoreleasePool alloc] init];
1319 #endif 1359 #endif
1320 DWMainMenu = _generate_main_menu(); 1360 DWMainMenu = _generate_main_menu();
1321 [DWApp setMainMenu:DWMainMenu]; 1361 [DWApp setMainMenu:DWMainMenu];
1322 1362 DWObject *test = [[DWObject alloc] init];
1363 NSThread *thread = [[ NSThread alloc] initWithTarget:test selector:@selector(uselessThread:) object:nil];
1364 [thread start];
1323 return 0; 1365 return 0;
1324 } 1366 }
1325 1367
1326 /* 1368 /*
1327 * Runs a message loop for Dynamic Windows. 1369 * Runs a message loop for Dynamic Windows.
2671 void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) 2713 void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
2672 { 2714 {
2673 id image = handle; 2715 id image = handle;
2674 if(pixmap) 2716 if(pixmap)
2675 { 2717 {
2676 image = (id)pixmap; 2718 image = (id)pixmap->handle;
2677 } 2719 [image lockFocus];
2678 [image lockFocus]; 2720 }
2721 else
2722 {
2723 [image lockFocusIfCanDraw];
2724 }
2679 NSRect rect = NSMakeRect(x, y, x, y); 2725 NSRect rect = NSMakeRect(x, y, x, y);
2680 [[NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1] set]; 2726 [[NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1] set];
2681 NSRectFill(rect); 2727 NSRectFill(rect);
2682 [image unlockFocus]; 2728 [image unlockFocus];
2683 } 2729 }
2694 void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) 2740 void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
2695 { 2741 {
2696 id image = handle; 2742 id image = handle;
2697 if(pixmap) 2743 if(pixmap)
2698 { 2744 {
2699 image = (id)pixmap; 2745 image = (id)pixmap->handle;
2700 } 2746 [image lockFocus];
2701 [image lockFocus]; 2747 }
2748 else
2749 {
2750 [image lockFocusIfCanDraw];
2751 }
2702 NSBezierPath* aPath = [NSBezierPath bezierPath]; 2752 NSBezierPath* aPath = [NSBezierPath bezierPath];
2753 [aPath setLineWidth: 1.0];
2703 2754
2704 [aPath moveToPoint:NSMakePoint(x1, y1)]; 2755 [aPath moveToPoint:NSMakePoint(x1, y1)];
2705 [aPath lineToPoint:NSMakePoint(x2, y2)]; 2756 [aPath lineToPoint:NSMakePoint(x2, y2)];
2757 [aPath stroke];
2706 2758
2707 [image unlockFocus]; 2759 [image unlockFocus];
2708 } 2760 }
2709 2761
2710 /* Draw text on a window (preferably a render window). 2762 /* Draw text on a window (preferably a render window).
2721 NSString *nstr = [ NSString stringWithUTF8String:text ]; 2773 NSString *nstr = [ NSString stringWithUTF8String:text ];
2722 if(image) 2774 if(image)
2723 { 2775 {
2724 if([image isMemberOfClass:[NSView class]]) 2776 if([image isMemberOfClass:[NSView class]])
2725 { 2777 {
2726 [image lockFocus]; 2778 [image lockFocusIfCanDraw];
2727 NSDictionary *dict = [[NSDictionary alloc] init]; 2779 NSDictionary *dict = [[NSDictionary alloc] init];
2728 [nstr drawAtPoint:NSMakePoint(x, y) withAttributes:dict]; 2780 [nstr drawAtPoint:NSMakePoint(x, y) withAttributes:dict];
2729 [image unlockFocus]; 2781 [image unlockFocus];
2730 } 2782 }
2731 } 2783 }
2732 if(pixmap) 2784 if(pixmap)
2733 { 2785 {
2734 image = (id)pixmap; 2786 image = (id)pixmap->handle;
2735 /* TODO: Figure out how to write here */ 2787 [image lockFocus];
2788 NSDictionary *dict = [[NSDictionary alloc] init];
2789 [nstr drawAtPoint:NSMakePoint(x, y) withAttributes:dict];
2790 [image unlockFocus];
2736 } 2791 }
2737 } 2792 }
2738 2793
2739 /* Query the width and height of a text string. 2794 /* Query the width and height of a text string.
2740 * Parameters: 2795 * Parameters:
2747 void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height) 2802 void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height)
2748 { 2803 {
2749 id image = handle; 2804 id image = handle;
2750 if(pixmap) 2805 if(pixmap)
2751 { 2806 {
2752 image = (id)pixmap; 2807 image = (id)pixmap->handle;
2753 } 2808 }
2754 NSLog(@"dw_font_text_extents_get() unimplemented\n"); 2809 NSLog(@"dw_font_text_extents_get() unimplemented\n");
2755 } 2810 }
2756 2811
2757 /* Draw a polygon on a window (preferably a render window). 2812 /* Draw a polygon on a window (preferably a render window).
2768 { 2823 {
2769 id image = handle; 2824 id image = handle;
2770 int z; 2825 int z;
2771 if(pixmap) 2826 if(pixmap)
2772 { 2827 {
2773 image = (id)pixmap; 2828 image = (id)pixmap->handle;
2774 } 2829 [image lockFocus];
2775 [image lockFocus]; 2830 }
2831 else
2832 {
2833 [image lockFocusIfCanDraw];
2834 }
2776 NSBezierPath* aPath = [NSBezierPath bezierPath]; 2835 NSBezierPath* aPath = [NSBezierPath bezierPath];
2836 [aPath setLineWidth: 1.0];
2777 2837
2778 [aPath moveToPoint:NSMakePoint(*x, *y)]; 2838 [aPath moveToPoint:NSMakePoint(*x, *y)];
2779 for(z=1;z<npoints;z++) 2839 for(z=1;z<npoints;z++)
2780 { 2840 {
2781 [aPath lineToPoint:NSMakePoint(x[z], y[z])]; 2841 [aPath lineToPoint:NSMakePoint(x[z], y[z])];
2783 [aPath closePath]; 2843 [aPath closePath];
2784 if(fill) 2844 if(fill)
2785 { 2845 {
2786 [aPath fill]; 2846 [aPath fill];
2787 } 2847 }
2848 [aPath stroke];
2788 [image unlockFocus]; 2849 [image unlockFocus];
2789 } 2850 }
2790 2851
2791 /* Draw a rectangle on a window (preferably a render window). 2852 /* Draw a rectangle on a window (preferably a render window).
2792 * Parameters: 2853 * Parameters:
2801 void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height) 2862 void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height)
2802 { 2863 {
2803 id image = handle; 2864 id image = handle;
2804 if(pixmap) 2865 if(pixmap)
2805 { 2866 {
2806 image = (id)pixmap; 2867 image = (id)pixmap->handle;
2807 } 2868 [image lockFocus];
2808 [image lockFocus]; 2869 }
2870 else
2871 {
2872 [image lockFocusIfCanDraw];
2873 }
2809 NSRect rect = NSMakeRect(x, y, x + width, y + height); 2874 NSRect rect = NSMakeRect(x, y, x + width, y + height);
2810 [[NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1] set]; 2875 [[NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1] set];
2811 NSRectFill(rect); 2876 NSRectFill(rect);
2812 [image unlockFocus]; 2877 [image unlockFocus];
2813 } 2878 }
3501 * A handle to a pixmap or NULL on failure. 3566 * A handle to a pixmap or NULL on failure.
3502 */ 3567 */
3503 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) 3568 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
3504 { 3569 {
3505 NSSize size = { (float)width, (float)height }; 3570 NSSize size = { (float)width, (float)height };
3506 NSImage *pixmap = [[NSImage alloc] initWithSize:size]; 3571 HPIXMAP pixmap;
3507 return (HPIXMAP)pixmap; 3572
3573 if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
3574 return NULL;
3575 pixmap->width = width;
3576 pixmap->height = height;
3577 pixmap->handle = [[NSImage alloc] initWithSize:size];
3578 return pixmap;
3508 } 3579 }
3509 3580
3510 /* 3581 /*
3511 * Creates a pixmap from a file. 3582 * Creates a pixmap from a file.
3512 * Parameters: 3583 * Parameters:
3517 * Returns: 3588 * Returns:
3518 * A handle to a pixmap or NULL on failure. 3589 * A handle to a pixmap or NULL on failure.
3519 */ 3590 */
3520 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename) 3591 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
3521 { 3592 {
3522 NSImage *pixmap = [[NSImage alloc] initWithContentsOfFile:[ NSString stringWithUTF8String:filename ]]; 3593 HPIXMAP pixmap;
3523 return (HPIXMAP)pixmap; 3594
3595 if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
3596 return NULL;
3597 NSImage *image = [[NSImage alloc] initWithContentsOfFile:[ NSString stringWithUTF8String:filename ]];
3598 NSSize size = [image size];
3599 pixmap->width = size.width;
3600 pixmap->height = size.height;
3601 pixmap->handle = image;
3602 return pixmap;
3524 } 3603 }
3525 3604
3526 /* 3605 /*
3527 * Creates a pixmap from memory. 3606 * Creates a pixmap from memory.
3528 * Parameters: 3607 * Parameters:
3533 * Returns: 3612 * Returns:
3534 * A handle to a pixmap or NULL on failure. 3613 * A handle to a pixmap or NULL on failure.
3535 */ 3614 */
3536 HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len) 3615 HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len)
3537 { 3616 {
3617 HPIXMAP pixmap;
3618
3619 if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
3620 return NULL;
3538 NSData *thisdata = [[NSData alloc] dataWithBytes:data length:len]; 3621 NSData *thisdata = [[NSData alloc] dataWithBytes:data length:len];
3539 NSImage *pixmap = [[NSImage alloc] initWithData:thisdata]; 3622 NSImage *image = [[NSImage alloc] initWithData:thisdata];
3540 return (HPIXMAP)pixmap; 3623 NSSize size = [image size];
3624 pixmap->width = size.width;
3625 pixmap->height = size.height;
3626 pixmap->handle = image;
3627 return pixmap;
3541 } 3628 }
3542 3629
3543 /* 3630 /*
3544 * Creates a bitmap mask for rendering bitmaps with transparent backgrounds 3631 * Creates a bitmap mask for rendering bitmaps with transparent backgrounds
3545 */ 3632 */
3568 * pixmap: Handle to a pixmap returned by 3655 * pixmap: Handle to a pixmap returned by
3569 * dw_pixmap_new.. 3656 * dw_pixmap_new..
3570 */ 3657 */
3571 void API dw_pixmap_destroy(HPIXMAP pixmap) 3658 void API dw_pixmap_destroy(HPIXMAP pixmap)
3572 { 3659 {
3573 NSImage *image = (NSImage *)pixmap; 3660 NSImage *image = (NSImage *)pixmap->handle;
3574 [image dealloc]; 3661 [image dealloc];
3662 free(pixmap);
3575 } 3663 }
3576 3664
3577 /* 3665 /*
3578 * Copies from one item to another. 3666 * Copies from one item to another.
3579 * Parameters: 3667 * Parameters:
3592 { 3680 {
3593 id bltdest = dest; 3681 id bltdest = dest;
3594 id bltsrc = src; 3682 id bltsrc = src;
3595 if(destp) 3683 if(destp)
3596 { 3684 {
3597 bltdest = (id)destp; 3685 bltdest = (id)destp->handle;
3598 } 3686 [bltdest lockFocus];
3599 [bltdest lockFocus]; 3687 }
3688 else
3689 {
3690 [bltdest lockFocusIfCanDraw];
3691 }
3600 if(srcp) 3692 if(srcp)
3601 { 3693 {
3602 bltsrc = (id)srcp; 3694 bltsrc = (id)srcp->handle;
3603 NSImage *image = bltsrc; 3695 NSImage *image = bltsrc;
3604 [image drawAtPoint:NSMakePoint(xdest, ydest) fromRect:NSMakeRect(xsrc, ysrc, width, height) operation:NSCompositeCopy fraction:1.0]; 3696 [image drawAtPoint:NSMakePoint(xdest, ydest) fromRect:NSMakeRect(xsrc, ysrc, width, height) operation:NSCompositeCopy fraction:1.0];
3605 } 3697 }
3606 [bltdest unlockFocus]; 3698 [bltdest unlockFocus];
3607 } 3699 }
5697 */ 5789 */
5698 void _dwthreadstart(void *data) 5790 void _dwthreadstart(void *data)
5699 { 5791 {
5700 void (*threadfunc)(void *) = NULL; 5792 void (*threadfunc)(void *) = NULL;
5701 void **tmp = (void **)data; 5793 void **tmp = (void **)data;
5702 5794 #if !defined(GARBAGE_COLLECT)
5795 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
5796 #endif
5797
5703 threadfunc = (void (*)(void *))tmp[0]; 5798 threadfunc = (void (*)(void *))tmp[0];
5704 5799
5705 threadfunc(tmp[1]); 5800 threadfunc(tmp[1]);
5706 free(tmp); 5801 free(tmp);
5707 } 5802 }
5817 * data: Parameter(s) passed to the function. 5912 * data: Parameter(s) passed to the function.
5818 * stack: Stack size of new thread (OS/2 and Windows only). 5913 * stack: Stack size of new thread (OS/2 and Windows only).
5819 */ 5914 */
5820 DWTID dw_thread_new(void *func, void *data, int stack) 5915 DWTID dw_thread_new(void *func, void *data, int stack)
5821 { 5916 {
5822 DWTID thread; 5917 DWTID thread;
5823 void **tmp = malloc(sizeof(void *) * 2); 5918 void **tmp = malloc(sizeof(void *) * 2);
5824 int rc; 5919 int rc;
5825 5920
5826 tmp[0] = func; 5921 tmp[0] = func;
5827 tmp[1] = data; 5922 tmp[1] = data;
5828 5923
5829 rc = pthread_create(&thread, NULL, (void *)_dwthreadstart, (void *)tmp); 5924 rc = pthread_create(&thread, NULL, (void *)_dwthreadstart, (void *)tmp);