comparison ios/dw.m @ 2380:93424ad710de

iOS: Remove printing and file browsing... more conversion.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sat, 20 Mar 2021 01:04:51 +0000
parents e35887009bb5
children 3777ea1cccdb
comparison
equal deleted inserted replaced
2379:e35887009bb5 2380:93424ad710de
18 #include <sys/un.h> 18 #include <sys/un.h>
19 #include <sys/mman.h> 19 #include <sys/mman.h>
20 #include <sys/time.h> 20 #include <sys/time.h>
21 #include <sys/stat.h> 21 #include <sys/stat.h>
22 #include <math.h> 22 #include <math.h>
23
24 /* Macros to handle local auto-release pools */
25 #define DW_LOCAL_POOL_IN NSAutoreleasePool *localpool = nil; \
26 if(DWThread != (DWTID)-1 && pthread_self() != DWThread) \
27 localpool = [[NSAutoreleasePool alloc] init];
28 #define DW_LOCAL_POOL_OUT if(localpool) [localpool drain];
23 29
24 /* Macros to encapsulate running functions on the main thread */ 30 /* Macros to encapsulate running functions on the main thread */
25 #define DW_FUNCTION_INIT 31 #define DW_FUNCTION_INIT
26 #define DW_FUNCTION_DEFINITION(func, rettype, ...) void _##func(NSPointerArray *_args); \ 32 #define DW_FUNCTION_DEFINITION(func, rettype, ...) void _##func(NSPointerArray *_args); \
27 rettype API func(__VA_ARGS__) { \ 33 rettype API func(__VA_ARGS__) { \
758 -(void)setSize:(CGSize)input { 764 -(void)setSize:(CGSize)input {
759 size = input; 765 size = input;
760 if(cachedDrawingRep) 766 if(cachedDrawingRep)
761 { 767 {
762 UIImage *oldrep = cachedDrawingRep; 768 UIImage *oldrep = cachedDrawingRep;
763 cachedDrawingRep = [self bitmapImageRepForCachingDisplayInRect:self.bounds]; 769 UIGraphicsBeginImageContext(self.frame.size);
770 [[self layer] renderInContext:UIGraphicsGetCurrentContext()];
771 cachedDrawingRep = UIGraphicsGetImageFromCurrentImageContext();
772 UIGraphicsEndImageContext();
764 [cachedDrawingRep retain]; 773 [cachedDrawingRep retain];
765 [oldrep release]; 774 [oldrep release];
766 } 775 }
767 } 776 }
768 -(CGSize)size { return size; } 777 -(CGSize)size { return size; }
769 -(UIImage *)cachedDrawingRep { 778 -(UIImage *)cachedDrawingRep {
770 if(!cachedDrawingRep) 779 if(!cachedDrawingRep)
771 { 780 {
772 cachedDrawingRep = [self bitmapImageRepForCachingDisplayInRect:self.bounds]; 781 UIGraphicsBeginImageContext(self.frame.size);
782 [[self layer] renderInContext:UIGraphicsGetCurrentContext()];
783 cachedDrawingRep = UIGraphicsGetImageFromCurrentImageContext();
784 UIGraphicsEndImageContext();
773 [cachedDrawingRep retain]; 785 [cachedDrawingRep retain];
774 } 786 }
775 /* Mark this render dirty if something is requesting it to draw */ 787 /* Mark this render dirty if something is requesting it to draw */
776 if(![_DWDirtyDrawables containsObject:self]) 788 if(![_DWDirtyDrawables containsObject:self])
777 [_DWDirtyDrawables addObject:self]; 789 [_DWDirtyDrawables addObject:self];
829 UIAlertController* alert = [UIAlertController alertControllerWithTitle:[params objectAtIndex:0] 841 UIAlertController* alert = [UIAlertController alertControllerWithTitle:[params objectAtIndex:0]
830 message:[params objectAtIndex:1] 842 message:[params objectAtIndex:1]
831 preferredStyle:[[params objectAtIndex:2] integerValue]]; 843 preferredStyle:[[params objectAtIndex:2] integerValue]];
832 844
833 UIAlertAction* action = [UIAlertAction actionWithTitle:[params objectAtIndex:3] style:UIAlertActionStyleDefault 845 UIAlertAction* action = [UIAlertAction actionWithTitle:[params objectAtIndex:3] style:UIAlertActionStyleDefault
834 handler:^(UIAlertAction * action) { iResponse = 0; }]; 846 handler:^(UIAlertAction * action) { iResponse = 1; }];
835 [alert addAction:action]; 847 [alert addAction:action];
836 if([params count] > 4) 848 if([params count] > 4)
837 action = [UIAlertAction actionWithTitle:[params objectAtIndex:4] style:UIAlertActionStyleDefault 849 action = [UIAlertAction actionWithTitle:[params objectAtIndex:4] style:UIAlertActionStyleDefault
838 handler:^(UIAlertAction * action) { iResponse = 1; }]; 850 handler:^(UIAlertAction * action) { iResponse = 2; }];
839 if([params count] > 5) 851 if([params count] > 5)
840 action = [UIAlertAction actionWithTitle:[params objectAtIndex:5] style:UIAlertActionStyleDefault 852 action = [UIAlertAction actionWithTitle:[params objectAtIndex:5] style:UIAlertActionStyleDefault
841 handler:^(UIAlertAction * action) { iResponse = 2; }]; 853 handler:^(UIAlertAction * action) { iResponse = 3; }];
842 854
843 [alert presentViewController:alert animated:YES completion:nil]; 855 [alert presentViewController:alert animated:YES completion:nil];
844 [alert release]; 856 [alert release];
845 [params addObject:[NSNumber numberWithInteger:iResponse]]; 857 [params addObject:[NSNumber numberWithInteger:iResponse]];
846 } 858 }
974 } 986 }
975 -(BOOL)windowShouldClose:(id)sender; 987 -(BOOL)windowShouldClose:(id)sender;
976 -(void)setMenu:(UIMenu *)input; 988 -(void)setMenu:(UIMenu *)input;
977 -(void)windowDidBecomeMain:(id)sender; 989 -(void)windowDidBecomeMain:(id)sender;
978 -(void)menuHandler:(id)sender; 990 -(void)menuHandler:(id)sender;
979 -(void)mouseDragged:(UIEvent *)theEvent;
980 @end 991 @end
981 992
982 @implementation DWView 993 @implementation DWView
983 -(BOOL)windowShouldClose:(id)sender 994 -(BOOL)windowShouldClose:(id)sender
984 { 995 {
1368 int lastAddPoint, lastQueryPoint; 1379 int lastAddPoint, lastQueryPoint;
1369 id scrollview; 1380 id scrollview;
1370 int filesystem; 1381 int filesystem;
1371 } 1382 }
1372 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable; 1383 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable;
1384 #if 0 /* TODO: Switch to columnless versions */
1373 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow; 1385 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow;
1374 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; 1386 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
1387 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row;
1388 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
1389 #endif
1375 -(void *)userdata; 1390 -(void *)userdata;
1376 -(void)setUserdata:(void *)input; 1391 -(void)setUserdata:(void *)input;
1377 -(void)setFilesystem:(int)input; 1392 -(void)setFilesystem:(int)input;
1378 -(int)filesystem; 1393 -(int)filesystem;
1379 -(id)scrollview; 1394 -(id)scrollview;
1392 -(void)clear; 1407 -(void)clear;
1393 -(void)setup; 1408 -(void)setup;
1394 -(CGSize)getsize; 1409 -(CGSize)getsize;
1395 -(void)setForegroundColor:(UIColor *)input; 1410 -(void)setForegroundColor:(UIColor *)input;
1396 -(void)doubleClicked:(id)sender; 1411 -(void)doubleClicked:(id)sender;
1397 -(void)keyUp:(UIEvent *)theEvent;
1398 -(void)selectionChanged:(id)sender; 1412 -(void)selectionChanged:(id)sender;
1399 -(UIMenu *)menuForEvent:(UIEvent *)event; 1413 -(UIMenu *)menuForEvent:(UIEvent *)event;
1400 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row;
1401 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
1402 @end 1414 @end
1403 1415
1404 @implementation DWContainer 1416 @implementation DWContainer
1405 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable 1417 -(NSInteger)numberOfRowsInTableView:(UITableView *)aTable
1406 { 1418 {
1413 return total / cols; 1425 return total / cols;
1414 } 1426 }
1415 } 1427 }
1416 return 0; 1428 return 0;
1417 } 1429 }
1430 #if 0 /* TODO: Switch to columnless versions */
1418 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow 1431 -(id)tableView:(UITableView *)aTable objectValueForTableColumn:(NSTableColumn *)aCol row:(NSInteger)aRow
1419 { 1432 {
1420 if(tvcols && data) 1433 if(tvcols && data)
1421 { 1434 {
1422 int z, col = -1; 1435 int z, col = -1;
1441 } 1454 }
1442 } 1455 }
1443 return nil; 1456 return nil;
1444 } 1457 }
1445 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { return NO; } 1458 -(BOOL)tableView:(UITableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { return NO; }
1459 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row
1460 {
1461 /* Handle drawing alternating row colors if enabled */
1462 if ((row % 2) == 0)
1463 {
1464 if(evencolor)
1465 [rowView setBackgroundColor:evencolor];
1466 }
1467 else
1468 {
1469 if(oddcolor)
1470 [rowView setBackgroundColor:oddcolor];
1471 }
1472 }
1473 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
1474 {
1475 /* Not reusing cell views, so get the cell from our array */
1476 int index = (int)(row * [tvcols count]) + (int)[tvcols indexOfObject:tableColumn];
1477 id celldata = [data objectAtIndex:index];
1478
1479 /* The data is already a NSTableCellView so just return that */
1480 if([celldata isMemberOfClass:[UITableViewCell class]])
1481 {
1482 UITableViewCell *result = celldata;
1483
1484 /* Copy the alignment setting from the column,
1485 * and set the text color from the container.
1486 */
1487 if(@available(iOS 14.0, *))
1488 {
1489 UIListContentConfiguration *content = [result defaultContentConfiguration];
1490
1491 if(fgcolor)
1492 [[content textProperties] setColor:fgcolor];
1493 }
1494 else
1495 {
1496 if(fgcolor)
1497 [result setTextColor:fgcolor];
1498 }
1499 /* Return the result */
1500 return result;
1501 }
1502 return nil;
1503 }
1504 -(void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn
1505 {
1506 NSUInteger index = [tvcols indexOfObject:tableColumn];
1507
1508 /* Handler for column click class */
1509 _event_handler(self, (UIEvent *)index, 17);
1510 }
1511 #endif
1446 -(void *)userdata { return userdata; } 1512 -(void *)userdata { return userdata; }
1447 -(void)setUserdata:(void *)input { userdata = input; } 1513 -(void)setUserdata:(void *)input { userdata = input; }
1448 -(void)setFilesystem:(int)input { filesystem = input; } 1514 -(void)setFilesystem:(int)input { filesystem = input; }
1449 -(int)filesystem { return filesystem; } 1515 -(int)filesystem { return filesystem; }
1450 -(id)scrollview { return scrollview; } 1516 -(id)scrollview { return scrollview; }
1536 [rowdatas addPointer:NULL]; 1602 [rowdatas addPointer:NULL];
1537 } 1603 }
1538 return (int)[titles count]; 1604 return (int)[titles count];
1539 } 1605 }
1540 return 0; 1606 return 0;
1541 }
1542 -(void)tableView:(UITableView *)tableView didAddRowView:(UITableRowView *)rowView forRow:(NSInteger)row
1543 {
1544 /* Handle drawing alternating row colors if enabled */
1545 if ((row % 2) == 0)
1546 {
1547 if(evencolor)
1548 [rowView setBackgroundColor:evencolor];
1549 }
1550 else
1551 {
1552 if(oddcolor)
1553 [rowView setBackgroundColor:oddcolor];
1554 }
1555 }
1556 -(UIView *)tableView:(UITableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
1557 {
1558 /* Not reusing cell views, so get the cell from our array */
1559 int index = (int)(row * [tvcols count]) + (int)[tvcols indexOfObject:tableColumn];
1560 id celldata = [data objectAtIndex:index];
1561
1562 /* The data is already a NSTableCellView so just return that */
1563 if([celldata isMemberOfClass:[UITableViewCell class]])
1564 {
1565 UITableViewCell *result = celldata;
1566
1567 /* Copy the alignment setting from the column,
1568 * and set the text color from the container.
1569 */
1570 if(@available(iOS 14.0, *))
1571 {
1572 UIListContentConfiguration *content = [result defaultContentConfiguration];
1573
1574 if(fgcolor)
1575 [[content textProperties] setColor:fgcolor];
1576 }
1577 else
1578 {
1579 if(fgcolor)
1580 [result setTextColor:fgcolor];
1581 }
1582 /* Return the result */
1583 return result;
1584 }
1585 return nil;
1586 } 1607 }
1587 -(void)editCell:(id)input at:(int)row and:(int)col 1608 -(void)editCell:(id)input at:(int)row and:(int)col
1588 { 1609 {
1589 if(tvcols) 1610 if(tvcols)
1590 { 1611 {
1742 cheight += 16; 1763 cheight += 16;
1743 return CGSizeMake(cwidth, cheight); 1764 return CGSizeMake(cwidth, cheight);
1744 } 1765 }
1745 -(void)setForegroundColor:(UIColor *)input 1766 -(void)setForegroundColor:(UIColor *)input
1746 { 1767 {
1768 #if 0 /* TODO: Fix this without columns */
1747 int z, count = (int)[tvcols count]; 1769 int z, count = (int)[tvcols count];
1748 1770
1749 fgcolor = input; 1771 fgcolor = input;
1750 [fgcolor retain]; 1772 [fgcolor retain];
1751 1773
1753 { 1775 {
1754 NSTableColumn *tableColumn = [tvcols objectAtIndex:z]; 1776 NSTableColumn *tableColumn = [tvcols objectAtIndex:z];
1755 UITextFieldCell *cell = [tableColumn dataCell]; 1777 UITextFieldCell *cell = [tableColumn dataCell];
1756 [cell setTextColor:fgcolor]; 1778 [cell setTextColor:fgcolor];
1757 } 1779 }
1780 #endif
1758 } 1781 }
1759 -(void)doubleClicked:(id)sender 1782 -(void)doubleClicked:(id)sender
1760 { 1783 {
1761 void *params[2]; 1784 void *params[2];
1762 1785
1763 params[0] = (void *)[self getRowTitle:(int)[self selectedRow]]; 1786 params[0] = (void *)[self getRowTitle:(int)[self indexPathForSelectedRow].row];
1764 params[1] = (void *)[self getRowData:(int)[self selectedRow]]; 1787 params[1] = (void *)[self getRowData:(int)[self indexPathForSelectedRow].row];
1765 1788
1766 /* Handler for container class */ 1789 /* Handler for container class */
1767 _event_handler(self, (UIEvent *)params, 9); 1790 _event_handler(self, (UIEvent *)params, 9);
1768 } 1791 }
1769 -(void)keyUp:(UIEvent *)theEvent
1770 {
1771 if([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == VK_RETURN)
1772 {
1773 void *params[2];
1774
1775 params[0] = (void *)[self getRowTitle:(int)[self selectedRow]];
1776 params[1] = (void *)[self getRowData:(int)[self selectedRow]];
1777
1778 _event_handler(self, (UIEvent *)params, 9);
1779 }
1780 [super keyUp:theEvent];
1781 }
1782
1783 -(void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn
1784 {
1785 NSUInteger index = [tvcols indexOfObject:tableColumn];
1786
1787 /* Handler for column click class */
1788 _event_handler(self, (UIEvent *)index, 17);
1789 }
1790 -(void)selectionChanged:(id)sender 1792 -(void)selectionChanged:(id)sender
1791 { 1793 {
1792 void *params[2]; 1794 void *params[2];
1793 1795
1794 params[0] = (void *)[self getRowTitle:(int)[self selectedRow]]; 1796 params[0] = (void *)[self getRowTitle:(int)[self indexPathForSelectedRow].row];
1795 params[1] = (void *)[self getRowData:(int)[self selectedRow]]; 1797 params[1] = (void *)[self getRowData:(int)[self indexPathForSelectedRow].row];
1796 1798
1797 /* Handler for container class */ 1799 /* Handler for container class */
1798 _event_handler(self, (UIEvent *)params, 12); 1800 _event_handler(self, (UIEvent *)params, 12);
1799 /* Handler for listbox class */ 1801 /* Handler for listbox class */
1800 _event_handler(self, DW_INT_TO_POINTER((int)[self selectedRow]), 11); 1802 _event_handler(self, DW_INT_TO_POINTER((int)[self indexPathForSelectedRow].row), 11);
1801 } 1803 }
1802 -(UIMenu *)menuForEvent:(UIEvent *)event 1804 -(UIMenu *)menuForEvent:(UIEvent *)event
1803 { 1805 {
1806 #if 0 /* TODO: Fix this */
1804 int row; 1807 int row;
1805 CGPoint where = [self convertPoint:[event locationInWindow] fromView:nil]; 1808 CGPoint where = [self convertPoint:[event locationInWindow] fromView:nil];
1806 row = (int)[self rowAtPoint:where]; 1809 row = (int)[self rowAtPoint:where];
1807 _event_handler(self, (UIEvent *)[self getRowTitle:row], 10); 1810 _event_handler(self, (UIEvent *)[self getRowTitle:row], 10);
1811 #endif
1808 return nil; 1812 return nil;
1809 } 1813 }
1810 -(void)keyDown:(UIEvent *)theEvent
1811 {
1812 unichar vk = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
1813
1814 if(vk == NSTabCharacter || vk == NSBackTabCharacter)
1815 [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
1816 [super keyDown:theEvent];
1817 }
1818 -(void)insertTab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectNextKeyView:self]; }
1819 -(void)insertBacktab:(id)sender { if([[self window] firstResponder] == self) [[self window] selectPreviousKeyView:self]; }
1820 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1814 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1821 @end 1815 @end
1822 1816
1823 /* Dive into the tree freeing all desired child nodes */ 1817 /* Dive into the tree freeing all desired child nodes */
1824 void _free_tree_recurse(NSMutableArray *node, NSMutableArray *item) 1818 void _free_tree_recurse(NSMutableArray *node, NSMutableArray *item)
1946 long val = [[textfield text] intValue]; 1940 long val = [[textfield text] intValue];
1947 [stepper setValue:(float)val]; 1941 [stepper setValue:(float)val];
1948 _event_handler(self, DW_INT_TO_POINTER(val), 14); 1942 _event_handler(self, DW_INT_TO_POINTER(val), 14);
1949 } 1943 }
1950 -(void)setClickDefault:(id)input { clickDefault = input; } 1944 -(void)setClickDefault:(id)input { clickDefault = input; }
1951 -(void)keyUp:(UIEvent *)theEvent
1952 {
1953 if(clickDefault && [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == VK_RETURN)
1954 {
1955 [[self window] makeFirstResponder:clickDefault];
1956 }
1957 else
1958 {
1959 [super keyUp:theEvent];
1960 }
1961 }
1962 -(void)performClick:(id)sender { [textfield performClick:sender]; }
1963 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; } 1945 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); dw_signal_disconnect_by_window(self); [super dealloc]; }
1964 @end 1946 @end
1965 1947
1966 API_AVAILABLE(ios(10.0)) 1948 API_AVAILABLE(ios(10.0))
1967 @interface DWUserNotificationCenterDelegate : NSObject <UNUserNotificationCenterDelegate> 1949 @interface DWUserNotificationCenterDelegate : NSObject <UNUserNotificationCenterDelegate>
2323 */ 2305 */
2324 else if([handle isMemberOfClass:[DWScrollBox class]]) 2306 else if([handle isMemberOfClass:[DWScrollBox class]])
2325 { 2307 {
2326 int depth = 0; 2308 int depth = 0;
2327 DWScrollBox *scrollbox = (DWScrollBox *)handle; 2309 DWScrollBox *scrollbox = (DWScrollBox *)handle;
2328 DWBox *contentbox = [scrollbox documentView]; 2310 DWBox *contentbox = [scrollbox contentView];
2329 Box *thisbox = [contentbox box]; 2311 Box *thisbox = [contentbox box];
2330 CGSize contentsize = [scrollbox contentSize]; 2312 CGSize contentsize = [scrollbox contentSize];
2331 2313
2332 /* Get the required space for the box */ 2314 /* Get the required space for the box */
2333 _resize_box(thisbox, &depth, x, y, 1); 2315 _resize_box(thisbox, &depth, x, y, 1);
2350 else if([handle isMemberOfClass:[DWSpinButton class]]) 2332 else if([handle isMemberOfClass:[DWSpinButton class]])
2351 { 2333 {
2352 DWSpinButton *spinbutton = (DWSpinButton *)handle; 2334 DWSpinButton *spinbutton = (DWSpinButton *)handle;
2353 UITextField *textfield = [spinbutton textfield]; 2335 UITextField *textfield = [spinbutton textfield];
2354 UIStepper *stepper = [spinbutton stepper]; 2336 UIStepper *stepper = [spinbutton stepper];
2355 [textfield setFrameOrigin:NSMakePoint(0,0)]; 2337 [textfield setFrameOrigin:CGPointMake(0,0)];
2356 [textfield setFrameSize:NSMakeSize(size.width-20,size.height)]; 2338 [textfield setFrameSize:CGSizeMake(size.width-20,size.height)];
2357 [stepper setFrameOrigin:NSMakePoint(size.width-20,0)]; 2339 [stepper setFrameOrigin:CGPointMake(size.width-20,0)];
2358 [stepper setFrameSize:NSMakeSize(20,size.height)]; 2340 [stepper setFrameSize:CGSizeMake(20,size.height)];
2359 } 2341 }
2360 else if([handle isMemberOfClass:[DWSplitBar class]]) 2342 else if([handle isMemberOfClass:[DWSplitBar class]])
2361 { 2343 {
2362 DWSplitBar *split = (DWSplitBar *)handle; 2344 DWSplitBar *split = (DWSplitBar *)handle;
2363 DWWindow *window = (DWWindow *)[split window]; 2345 DWWindow *window = (DWWindow *)[split window];
2417 * Causes running dw_main() to return. 2399 * Causes running dw_main() to return.
2418 */ 2400 */
2419 void API dw_main_quit(void) 2401 void API dw_main_quit(void)
2420 { 2402 {
2421 [DWApp stop:nil]; 2403 [DWApp stop:nil];
2422 _dw_wakeup_app();
2423 } 2404 }
2424 2405
2425 /* 2406 /*
2426 * Runs a message loop for Dynamic Windows, for a period of milliseconds. 2407 * Runs a message loop for Dynamic Windows, for a period of milliseconds.
2427 * Parameters: 2408 * Parameters:
2457 } 2438 }
2458 2439
2459 /* Internal version that doesn't lock the run mutex */ 2440 /* Internal version that doesn't lock the run mutex */
2460 int _dw_main_iteration(NSDate *date) 2441 int _dw_main_iteration(NSDate *date)
2461 { 2442 {
2462 UIEvent *event = [DWApp nextEventMatchingMask:DWEventMaskAny 2443 UIEvent *event = [DWApp nextEventMatchingMask:UIEventMaskAny
2463 untilDate:date 2444 untilDate:date
2464 inMode:NSDefaultRunLoopMode 2445 inMode:NSDefaultRunLoopMode
2465 dequeue:YES]; 2446 dequeue:YES];
2466 if(event) 2447 if(event)
2467 { 2448 {
2468 [DWApp sendEvent:event]; 2449 [DWApp sendEvent:event];
2469 [DWApp updateWindows];
2470 return 1; 2450 return 1;
2471 } 2451 }
2472 return 0; 2452 return 0;
2473 } 2453 }
2474 2454
2606 NSString *button1 = @"OK"; 2586 NSString *button1 = @"OK";
2607 NSString *button2 = nil; 2587 NSString *button2 = nil;
2608 NSString *button3 = nil; 2588 NSString *button3 = nil;
2609 NSString *mtitle = [NSString stringWithUTF8String:title]; 2589 NSString *mtitle = [NSString stringWithUTF8String:title];
2610 NSString *mtext; 2590 NSString *mtext;
2611 NSAlertStyle mstyle = DWAlertStyleWarning; 2591 UIAlertControllerStyle mstyle = UIAlertControllerStyleAlert;
2612 NSArray *params; 2592 NSArray *params;
2613 va_list args; 2593 va_list args;
2614 2594
2615 if(flags & DW_MB_OKCANCEL) 2595 if(flags & DW_MB_OKCANCEL)
2616 { 2596 {
2630 2610
2631 va_start(args, format); 2611 va_start(args, format);
2632 mtext = [[[NSString alloc] initWithFormat:[NSString stringWithUTF8String:format] arguments:args] autorelease]; 2612 mtext = [[[NSString alloc] initWithFormat:[NSString stringWithUTF8String:format] arguments:args] autorelease];
2633 va_end(args); 2613 va_end(args);
2634 2614
2635 if(flags & DW_MB_ERROR) 2615 if(flags & DW_MB_INFORMATION)
2636 mstyle = DWAlertStyleCritical; 2616 mstyle = UIAlertControllerStyleActionSheet;
2637 else if(flags & DW_MB_INFORMATION)
2638 mstyle = DWAlertStyleInformational;
2639 2617
2640 params = [NSMutableArray arrayWithObjects:mtitle, mtext, [NSNumber numberWithInteger:mstyle], button1, button2, button3, nil]; 2618 params = [NSMutableArray arrayWithObjects:mtitle, mtext, [NSNumber numberWithInteger:mstyle], button1, button2, button3, nil];
2641 [DWObj safeCall:@selector(messageBox:) withObject:params]; 2619 [DWObj safeCall:@selector(messageBox:) withObject:params];
2642 iResponse = [[params lastObject] integerValue]; 2620 iResponse = [[params lastObject] integerValue];
2643 2621
2644 switch(iResponse) 2622 switch(iResponse)
2645 { 2623 {
2646 case NSAlertFirstButtonReturn: /* user pressed OK */ 2624 case 1: /* user pressed OK */
2647 if(flags & DW_MB_YESNO || flags & DW_MB_YESNOCANCEL) 2625 if(flags & DW_MB_YESNO || flags & DW_MB_YESNOCANCEL)
2648 { 2626 {
2649 return DW_MB_RETURN_YES; 2627 return DW_MB_RETURN_YES;
2650 } 2628 }
2651 return DW_MB_RETURN_OK; 2629 return DW_MB_RETURN_OK;
2652 case NSAlertSecondButtonReturn: /* user pressed Cancel */ 2630 case 2: /* user pressed Cancel */
2653 if(flags & DW_MB_OKCANCEL) 2631 if(flags & DW_MB_OKCANCEL)
2654 { 2632 {
2655 return DW_MB_RETURN_CANCEL; 2633 return DW_MB_RETURN_CANCEL;
2656 } 2634 }
2657 return DW_MB_RETURN_NO; 2635 return DW_MB_RETURN_NO;
2658 case NSAlertThirdButtonReturn: /* user pressed the third button */ 2636 case 3: /* user pressed the third button */
2659 return DW_MB_RETURN_CANCEL; 2637 return DW_MB_RETURN_CANCEL;
2660 } 2638 }
2661 return 0; 2639 return 0;
2662 } 2640 }
2663 2641
2673 * the file path on success. 2651 * the file path on success.
2674 * 2652 *
2675 */ 2653 */
2676 char * API dw_file_browse(const char *title, const char *defpath, const char *ext, int flags) 2654 char * API dw_file_browse(const char *title, const char *defpath, const char *ext, int flags)
2677 { 2655 {
2678 char temp[PATH_MAX+1];
2679 char *file = NULL, *path = NULL;
2680 DW_LOCAL_POOL_IN;
2681
2682 /* Figure out path information...
2683 * These functions are only support in Snow Leopard and later...
2684 */
2685 if(defpath && *defpath && (DWOSMinor > 5 || DWOSMajor > 10))
2686 {
2687 struct stat buf;
2688
2689 /* Get an absolute path */
2690 if(!realpath(defpath, temp))
2691 strcpy(temp, defpath);
2692
2693 /* Check if the defpath exists */
2694 if(stat(temp, &buf) == 0)
2695 {
2696 /* Can be a directory or file */
2697 if(buf.st_mode & S_IFDIR)
2698 path = temp;
2699 else
2700 file = temp;
2701 }
2702 /* If it wasn't a directory... check if there is a path */
2703 if(!path && strchr(temp, '/'))
2704 {
2705 unsigned long x = strlen(temp) - 1;
2706
2707 /* Trim off the filename */
2708 while(x > 0 && temp[x] != '/')
2709 {
2710 x--;
2711 }
2712 if(temp[x] == '/')
2713 {
2714 temp[x] = 0;
2715 /* Check to make sure the trimmed piece is a directory */
2716 if(stat(temp, &buf) == 0)
2717 {
2718 if(buf.st_mode & S_IFDIR)
2719 {
2720 /* We now have it split */
2721 path = temp;
2722 file = &temp[x+1];
2723 }
2724 }
2725 }
2726 }
2727 }
2728
2729 if(flags == DW_FILE_OPEN || flags == DW_DIRECTORY_OPEN)
2730 {
2731 /* Create the File Open Dialog class. */
2732 NSOpenPanel* openDlg = [NSOpenPanel openPanel];
2733
2734 if(path)
2735 {
2736 SEL ssdu = NSSelectorFromString(@"setDirectoryURL");
2737
2738 if([openDlg respondsToSelector:ssdu])
2739 {
2740 DWIMP isdu = (DWIMP)[openDlg methodForSelector:ssdu];
2741 isdu(openDlg, ssdu, [NSURL fileURLWithPath:[NSString stringWithUTF8String:path]]);
2742 }
2743 }
2744
2745 /* Enable the selection of files in the dialog. */
2746 if(flags == DW_FILE_OPEN)
2747 {
2748 [openDlg setCanChooseFiles:YES];
2749 [openDlg setCanChooseDirectories:NO];
2750 }
2751 else
2752 {
2753 [openDlg setCanChooseFiles:NO];
2754 [openDlg setCanChooseDirectories:YES];
2755 }
2756
2757 /* Handle file types */
2758 if(ext && *ext)
2759 {
2760 NSArray* fileTypes = [[[NSArray alloc] initWithObjects:[NSString stringWithUTF8String:ext], nil] autorelease];
2761 [openDlg setAllowedFileTypes:fileTypes];
2762 }
2763
2764 /* Disable multiple selection */
2765 [openDlg setAllowsMultipleSelection:NO];
2766
2767 /* Display the dialog. If the OK button was pressed,
2768 * process the files.
2769 */
2770 if([openDlg runModal] == DWModalResponseOK)
2771 {
2772 /* Get an array containing the full filenames of all
2773 * files and directories selected.
2774 */
2775 NSArray *files = [openDlg URLs];
2776 NSString *fileName = [[files objectAtIndex:0] path];
2777 if(fileName)
2778 {
2779 char *ret = strdup([ fileName UTF8String ]);
2780 DW_LOCAL_POOL_OUT;
2781 return ret;
2782 }
2783 }
2784 }
2785 else
2786 {
2787 /* Create the File Save Dialog class. */
2788 NSSavePanel* saveDlg = [NSSavePanel savePanel];
2789
2790 if(path)
2791 {
2792 SEL ssdu = NSSelectorFromString(@"setDirectoryURL");
2793
2794 if([saveDlg respondsToSelector:ssdu])
2795 {
2796 DWIMP isdu = (DWIMP)[saveDlg methodForSelector:ssdu];
2797 isdu(saveDlg, ssdu, [NSURL fileURLWithPath:[NSString stringWithUTF8String:path]]);
2798 }
2799 }
2800 if(file)
2801 {
2802 SEL ssnfsv = NSSelectorFromString(@"setNameFieldStringValue");
2803
2804 if([saveDlg respondsToSelector:ssnfsv])
2805 {
2806 DWIMP isnfsv = (DWIMP)[saveDlg methodForSelector:ssnfsv];
2807 isnfsv(saveDlg, ssnfsv, [NSString stringWithUTF8String:file]);
2808 }
2809 }
2810
2811 /* Enable the creation of directories in the dialog. */
2812 [saveDlg setCanCreateDirectories:YES];
2813
2814 /* Handle file types */
2815 if(ext && *ext)
2816 {
2817 NSArray* fileTypes = [[[NSArray alloc] initWithObjects:[NSString stringWithUTF8String:ext], nil] autorelease];
2818 [saveDlg setAllowedFileTypes:fileTypes];
2819 }
2820
2821 /* Display the dialog. If the OK button was pressed,
2822 * process the files.
2823 */
2824 if([saveDlg runModal] == DWModalResponseOK)
2825 {
2826 /* Get an array containing the full filenames of all
2827 * files and directories selected.
2828 */
2829 NSString* fileName = [[saveDlg URL] path];
2830 if(fileName)
2831 {
2832 char *ret = strdup([ fileName UTF8String ]);
2833 DW_LOCAL_POOL_OUT;
2834 return ret;
2835 }
2836 }
2837 }
2838 DW_LOCAL_POOL_OUT;
2839 return NULL; 2656 return NULL;
2840 } 2657 }
2841 2658
2842 /* 2659 /*
2843 * Gets the contents of the default clipboard as text. 2660 * Gets the contents of the default clipboard as text.
2847 * Pointer to an allocated string of text or NULL if clipboard empty or contents could not 2664 * Pointer to an allocated string of text or NULL if clipboard empty or contents could not
2848 * be converted to text. 2665 * be converted to text.
2849 */ 2666 */
2850 char *dw_clipboard_get_text() 2667 char *dw_clipboard_get_text()
2851 { 2668 {
2852 NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 2669 UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
2853 NSString *str = [pasteboard stringForType:DWPasteboardTypeString]; 2670 NSString *str = [pasteboard string];
2854 if(str != nil) 2671 if(str != nil)
2855 { 2672 return strdup([str UTF8String]);
2856 return strdup([ str UTF8String ]);
2857 }
2858 return NULL; 2673 return NULL;
2859 } 2674 }
2860 2675
2861 /* 2676 /*
2862 * Sets the contents of the default clipboard to the supplied text. 2677 * Sets the contents of the default clipboard to the supplied text.
2863 * Parameters: 2678 * Parameters:
2864 * Text. 2679 * Text.
2865 */ 2680 */
2866 void dw_clipboard_set_text(const char *str, int len) 2681 void dw_clipboard_set_text(const char *str, int len)
2867 { 2682 {
2868 NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 2683 UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
2869 SEL scc = NSSelectorFromString(@"clearContents"); 2684
2870 2685 [pasteboard setString:[NSString stringWithUTF8String:str]];
2871 if([pasteboard respondsToSelector:scc])
2872 {
2873 DWIMP icc = (DWIMP)[pasteboard methodForSelector:scc];
2874 icc(pasteboard, scc);
2875 }
2876
2877 [pasteboard setString:[ NSString stringWithUTF8String:str ] forType:DWPasteboardTypeString];
2878 } 2686 }
2879 2687
2880 2688
2881 /* 2689 /*
2882 * Allocates and initializes a dialog struct. 2690 * Allocates and initializes a dialog struct.
4315 int result = -1; 4123 int result = -1;
4316 4124
4317 if([object isMemberOfClass:[DWContainer class]]) 4125 if([object isMemberOfClass:[DWContainer class]])
4318 { 4126 {
4319 DWContainer *cont = handle; 4127 DWContainer *cont = handle;
4320 result = (int)[cont selectedRow]; 4128 result = (int)[cont indexPathForSelectedRow].row;
4321 } 4129 }
4322 DW_FUNCTION_RETURN_THIS(result); 4130 DW_FUNCTION_RETURN_THIS(result);
4323 } 4131 }
4324 4132
4325 /* 4133 /*
4339 4147
4340 if([object isMemberOfClass:[DWContainer class]]) 4148 if([object isMemberOfClass:[DWContainer class]])
4341 { 4149 {
4342 NSUInteger result; 4150 NSUInteger result;
4343 DWContainer *cont = handle; 4151 DWContainer *cont = handle;
4344 NSIndexSet *selected = [cont selectedRowIndexes]; 4152 NSArray *selected = [cont indexPathsForSelectedRows];
4345 if( where == -1 ) 4153 if(where == -1)
4346 result = [selected indexGreaterThanOrEqualToIndex:0]; 4154 result = [selected objectAtIndex:0];
4347 else 4155 else
4348 result = [selected indexGreaterThanIndex:where]; 4156 result = [selected objectAtIndex:where];
4349 4157
4350 if(result != NSNotFound) 4158 if(result)
4351 { 4159 {
4352 retval = (int)result; 4160 retval = (int)result;
4353 } 4161 }
4354 } 4162 }
4355 DW_FUNCTION_RETURN_THIS(retval) 4163 DW_FUNCTION_RETURN_THIS(retval)
6141 DW_FUNCTION_RETURN(dw_container_query_start, char *) 5949 DW_FUNCTION_RETURN(dw_container_query_start, char *)
6142 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long) 5950 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long)
6143 { 5951 {
6144 DW_FUNCTION_INIT; 5952 DW_FUNCTION_INIT;
6145 DWContainer *cont = handle; 5953 DWContainer *cont = handle;
6146 NSIndexSet *selected = [cont selectedRowIndexes]; 5954 NSArray *selected = [cont indexPathsForSelectedRows];
6147 NSUInteger result = [selected indexGreaterThanOrEqualToIndex:0]; 5955 NSIndexPath *result = [selected objectAtIndex:0];
6148 void *retval = NULL; 5956 void *retval = NULL;
6149 5957
6150 if(result != NSNotFound) 5958 if(result)
6151 { 5959 {
6152 if(flags & DW_CR_RETDATA) 5960 if(flags & DW_CR_RETDATA)
6153 retval = [cont getRowData:(int)result]; 5961 retval = [cont getRowData:(int)result.row];
6154 else 5962 else
6155 { 5963 {
6156 char *temp = [cont getRowTitle:(int)result]; 5964 char *temp = [cont getRowTitle:(int)result.row];
6157 if(temp) 5965 if(temp)
6158 retval = strdup(temp); 5966 retval = strdup(temp);
6159 } 5967 }
6160 [cont setLastQueryPoint:(int)result]; 5968 [cont setLastQueryPoint:1];
6161 } 5969 }
6162 DW_FUNCTION_RETURN_THIS(retval); 5970 DW_FUNCTION_RETURN_THIS(retval);
6163 } 5971 }
6164 5972
6165 /* 5973 /*
6176 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long) 5984 DW_FUNCTION_RESTORE_PARAM2(handle, HWND, flags, unsigned long)
6177 { 5985 {
6178 DW_FUNCTION_INIT; 5986 DW_FUNCTION_INIT;
6179 DWContainer *cont = handle; 5987 DWContainer *cont = handle;
6180 int lastQueryPoint = [cont lastQueryPoint]; 5988 int lastQueryPoint = [cont lastQueryPoint];
6181 NSIndexSet *selected = [cont selectedRowIndexes]; 5989 NSArray *selected = [cont indexPathsForSelectedRows];
6182 NSUInteger result = [selected indexGreaterThanIndex:lastQueryPoint]; 5990 NSIndexPath *result = [selected objectAtIndex:lastQueryPoint];
6183 void *retval = NULL; 5991 void *retval = NULL;
6184 5992
6185 if(result != NSNotFound) 5993 if(result)
6186 { 5994 {
6187 if(flags & DW_CR_RETDATA) 5995 if(flags & DW_CR_RETDATA)
6188 retval = [cont getRowData:(int)result]; 5996 retval = [cont getRowData:(int)result.row];
6189 else 5997 else
6190 { 5998 {
6191 char *temp = [cont getRowTitle:(int)result]; 5999 char *temp = [cont getRowTitle:(int)result.row];
6192 if(temp) 6000 if(temp)
6193 retval = strdup(temp); 6001 retval = strdup(temp);
6194 } 6002 }
6195 [cont setLastQueryPoint:(int)result]; 6003 [cont setLastQueryPoint:(int)lastQueryPoint+1];
6196 } 6004 }
6197 DW_FUNCTION_RETURN_THIS(retval); 6005 DW_FUNCTION_RETURN_THIS(retval);
6198 } 6006 }
6199 6007
6200 /* 6008 /*
10241 pool = [[NSAutoreleasePool alloc] init]; 10049 pool = [[NSAutoreleasePool alloc] init];
10242 pthread_setspecific(_dw_pool_key, pool); 10050 pthread_setspecific(_dw_pool_key, pool);
10243 pthread_key_create(&_dw_fg_color_key, NULL); 10051 pthread_key_create(&_dw_fg_color_key, NULL);
10244 pthread_key_create(&_dw_bg_color_key, NULL); 10052 pthread_key_create(&_dw_bg_color_key, NULL);
10245 _init_colors(); 10053 _init_colors();
10246 /* Create a default main menu, with just the application menu */
10247 DWMainMenu = _generate_main_menu();
10248 [DWMainMenu retain];
10249 [DWApp setMainMenu:DWMainMenu];
10250 DWObj = [[DWObject alloc] init]; 10054 DWObj = [[DWObject alloc] init];
10251 DWDefaultFont = nil; 10055 DWDefaultFont = nil;
10252 DWFontManager = [UIFontManager sharedFontManager];
10253 if (@available(iOS 10.0, *)) 10056 if (@available(iOS 10.0, *))
10254 { 10057 {
10255 if([[NSBundle mainBundle] bundleIdentifier] != nil) 10058 if([[NSBundle mainBundle] bundleIdentifier] != nil)
10256 { 10059 {
10257 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; 10060 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
10426 DWTID dw_thread_id(void) 10229 DWTID dw_thread_id(void)
10427 { 10230 {
10428 return (DWTID)pthread_self(); 10231 return (DWTID)pthread_self();
10429 } 10232 }
10430 10233
10431 NSURL *_dw_url_from_program(NSString *nsprogram, NSWorkspace *ws)
10432 {
10433 NSURL *retval = [ws URLForApplicationWithBundleIdentifier:nsprogram];
10434 return retval;
10435 }
10436
10437 /* 10234 /*
10438 * Execute and external program in a seperate session. 10235 * Execute and external program in a seperate session.
10439 * Parameters: 10236 * Parameters:
10440 * program: Program name with optional path. 10237 * program: Program name with optional path.
10441 * type: Either DW_EXEC_CON or DW_EXEC_GUI. 10238 * type: Either DW_EXEC_CON or DW_EXEC_GUI.
10445 */ 10242 */
10446 int dw_exec(const char *program, int type, char **params) 10243 int dw_exec(const char *program, int type, char **params)
10447 { 10244 {
10448 int ret = DW_ERROR_UNKNOWN; 10245 int ret = DW_ERROR_UNKNOWN;
10449 10246
10247 #if 0 /* TODO: Figure out how to do this on iOS */
10450 if(type == DW_EXEC_GUI) 10248 if(type == DW_EXEC_GUI)
10451 { 10249 {
10452 NSString *nsprogram = [NSString stringWithUTF8String:program]; 10250 NSString *nsprogram = [NSString stringWithUTF8String:program];
10453 NSWorkspace *ws = [NSWorkspace sharedWorkspace]; 10251 NSWorkspace *ws = [NSWorkspace sharedWorkspace];
10454 10252
10498 dw_dialog_dismiss(dialog, DW_INT_TO_POINTER(pid)); 10296 dw_dialog_dismiss(dialog, DW_INT_TO_POINTER(pid));
10499 }]; 10297 }];
10500 ret = DW_POINTER_TO_INT(dw_dialog_wait(dialog)); 10298 ret = DW_POINTER_TO_INT(dw_dialog_wait(dialog));
10501 } 10299 }
10502 } 10300 }
10301 #endif
10503 return ret; 10302 return ret;
10504 } 10303 }
10505 10304
10506 /* 10305 /*
10507 * Loads a web browser pointed at the given URL. 10306 * Loads a web browser pointed at the given URL.
10509 * url: Uniform resource locator. 10308 * url: Uniform resource locator.
10510 */ 10309 */
10511 int dw_browse(const char *url) 10310 int dw_browse(const char *url)
10512 { 10311 {
10513 NSURL *myurl = [NSURL URLWithString:[NSString stringWithUTF8String:url]]; 10312 NSURL *myurl = [NSURL URLWithString:[NSString stringWithUTF8String:url]];
10514 [[NSWorkspace sharedWorkspace] openURL:myurl]; 10313 [DWApp openURL:myurl options:@{}
10314 completionHandler:^(BOOL success) {}];
10515 return DW_ERROR_NONE; 10315 return DW_ERROR_NONE;
10516 } 10316 }
10517
10518 typedef struct _dwprint
10519 {
10520 NSPrintInfo *pi;
10521 int (*drawfunc)(HPRINT, HPIXMAP, int, void *);
10522 void *drawdata;
10523 unsigned long flags;
10524 } DWPrint;
10525 10317
10526 /* 10318 /*
10527 * Creates a new print object. 10319 * Creates a new print object.
10528 * Parameters: 10320 * Parameters:
10529 * jobname: Name of the print job to show in the queue. 10321 * jobname: Name of the print job to show in the queue.
10534 * Returns: 10326 * Returns:
10535 * A handle to the print object or NULL on failure. 10327 * A handle to the print object or NULL on failure.
10536 */ 10328 */
10537 HPRINT API dw_print_new(const char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata) 10329 HPRINT API dw_print_new(const char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata)
10538 { 10330 {
10539 DWPrint *print; 10331 return NULL;
10540 NSPrintPanel *panel;
10541 PMPrintSettings settings;
10542 NSPrintInfo *pi;
10543
10544 if(!drawfunc || !(print = calloc(1, sizeof(DWPrint))))
10545 {
10546 return NULL;
10547 }
10548
10549 if(!jobname)
10550 jobname = "Dynamic Windows Print Job";
10551
10552 print->drawfunc = drawfunc;
10553 print->drawdata = drawdata;
10554 print->flags = flags;
10555
10556 /* Get the page range */
10557 pi = [NSPrintInfo sharedPrintInfo];
10558 [pi setHorizontalPagination:DWPrintingPaginationModeFit];
10559 [pi setHorizontallyCentered:YES];
10560 [pi setVerticalPagination:DWPrintingPaginationModeFit];
10561 [pi setVerticallyCentered:YES];
10562 [pi setOrientation:DWPaperOrientationPortrait];
10563 [pi setLeftMargin:0.0];
10564 [pi setRightMargin:0.0];
10565 [pi setTopMargin:0.0];
10566 [pi setBottomMargin:0.0];
10567
10568 settings = [pi PMPrintSettings];
10569 PMSetPageRange(settings, 1, pages);
10570 PMSetFirstPage(settings, 1, true);
10571 PMSetLastPage(settings, pages, true);
10572 PMPrintSettingsSetJobName(settings, (CFStringRef)[NSString stringWithUTF8String:jobname]);
10573 [pi updateFromPMPrintSettings];
10574
10575 /* Create and show the print panel */
10576 panel = [NSPrintPanel printPanel];
10577 if(!panel || [panel runModalWithPrintInfo:pi] == DWModalResponseCancel)
10578 {
10579 free(print);
10580 return NULL;
10581 }
10582 /* Put the print info from the panel into the operation */
10583 print->pi = pi;
10584
10585 return print;
10586 } 10332 }
10587 10333
10588 /* 10334 /*
10589 * Runs the print job, causing the draw page callbacks to fire. 10335 * Runs the print job, causing the draw page callbacks to fire.
10590 * Parameters: 10336 * Parameters:
10593 * Returns: 10339 * Returns:
10594 * DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success. 10340 * DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success.
10595 */ 10341 */
10596 int API dw_print_run(HPRINT print, unsigned long flags) 10342 int API dw_print_run(HPRINT print, unsigned long flags)
10597 { 10343 {
10598 DWPrint *p = print; 10344 return DW_ERROR_UNKNOWN;
10599 UIImage *rep, *rep2;
10600 NSPrintInfo *pi;
10601 NSPrintOperation *po;
10602 HPIXMAP pixmap, pixmap2;
10603 UIImage *image, *flipped;
10604 UIImageView *iv;
10605 CGSize size;
10606 PMPrintSettings settings;
10607 int x, result = DW_ERROR_UNKNOWN;
10608 UInt32 start, end;
10609
10610 if(!p)
10611 return result;
10612
10613 DW_LOCAL_POOL_IN;
10614
10615 /* Figure out the printer/paper size */
10616 pi = p->pi;
10617 size = [pi paperSize];
10618
10619 /* Get the page range */
10620 settings = [pi PMPrintSettings];
10621 PMGetFirstPage(settings, &start);
10622 if(start > 0)
10623 start--;
10624 PMGetLastPage(settings, &end);
10625 PMSetPageRange(settings, 1, 1);
10626 PMSetFirstPage(settings, 1, true);
10627 PMSetLastPage(settings, 1, true);
10628 [pi updateFromPMPrintSettings];
10629
10630 /* Create an image view to print and a pixmap to draw into */
10631 iv = [[UIImageView alloc] init];
10632 pixmap = dw_pixmap_new(iv, (int)size.width, (int)size.height, 8);
10633 rep = pixmap->image;
10634 pixmap2 = dw_pixmap_new(iv, (int)size.width, (int)size.height, 8);
10635 rep2 = pixmap2->image;
10636
10637 /* Create an image with the data from the pixmap
10638 * to go into the image view.
10639 */
10640 image = [[UIImage alloc] initWithSize:[rep size]];
10641 flipped = [[UIImage alloc] initWithSize:[rep size]];
10642 [image addRepresentation:rep];
10643 [flipped addRepresentation:rep2];
10644 [iv setImage:flipped];
10645 [iv setImageScaling:UIImageScaleProportionallyDown];
10646 [iv setFrameOrigin:NSMakePoint(0,0)];
10647 [iv setFrameSize:size];
10648
10649 /* Create the print operation using the image view and
10650 * print info obtained from the panel in the last call.
10651 */
10652 po = [NSPrintOperation printOperationWithView:iv printInfo:pi];
10653 [po setShowsPrintPanel:NO];
10654
10655 /* Cycle through each page */
10656 for(x=start; x<end && p->drawfunc; x++)
10657 {
10658 /* Call the application's draw function */
10659 p->drawfunc(print, pixmap, x, p->drawdata);
10660 if(p->drawfunc)
10661 {
10662 /* Internal representation is flipped... so flip again so we can print */
10663 _flip_image(image, rep2, size);
10664 #ifdef DEBUG_PRINT
10665 /* Save it to file to see what we have */
10666 NSData *data = [rep2 representationUsingType: NSPNGFileType properties: nil];
10667 [data writeToFile: @"print.png" atomically: NO];
10668 #endif
10669 /* Print the image view */
10670 [po runOperation];
10671 /* Fill the pixmap with white in case we are printing more pages */
10672 dw_color_foreground_set(DW_CLR_WHITE);
10673 dw_draw_rect(0, pixmap, TRUE, 0, 0, (int)size.width, (int)size.height);
10674 }
10675 }
10676 if(p->drawfunc)
10677 result = DW_ERROR_NONE;
10678 /* Free memory */
10679 [image release];
10680 [flipped release];
10681 dw_pixmap_destroy(pixmap);
10682 dw_pixmap_destroy(pixmap2);
10683 free(p);
10684 [iv release];
10685 DW_LOCAL_POOL_OUT;
10686 return result;
10687 } 10345 }
10688 10346
10689 /* 10347 /*
10690 * Cancels the print job, typically called from a draw page callback. 10348 * Cancels the print job, typically called from a draw page callback.
10691 * Parameters: 10349 * Parameters:
10692 * print: Handle to the print object returned by dw_print_new(). 10350 * print: Handle to the print object returned by dw_print_new().
10693 */ 10351 */
10694 void API dw_print_cancel(HPRINT print) 10352 void API dw_print_cancel(HPRINT print)
10695 { 10353 {
10696 DWPrint *p = print;
10697
10698 if(p)
10699 p->drawfunc = NULL;
10700 } 10354 }
10701 10355
10702 /* 10356 /*
10703 * Converts a UTF-8 encoded string into a wide string. 10357 * Converts a UTF-8 encoded string into a wide string.
10704 * Parameters: 10358 * Parameters: