Mercurial > dwindows
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); |