Mercurial > dwindows
comparison ios/dw.m @ 2407:6336244aa895
iOS: Fix timers and implement dw_beep().
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sun, 28 Mar 2021 20:51:44 +0000 |
parents | 38c17a19e00d |
children | 795056df9efd |
comparison
equal
deleted
inserted
replaced
2406:716f38f69073 | 2407:6336244aa895 |
---|---|
9 * clang -g -o dwtest -D__IOS__ -I. dwtest.c ios/dw.m -framework UIKit -framework WebKit -framework Foundation -framework UserNotifications | 9 * clang -g -o dwtest -D__IOS__ -I. dwtest.c ios/dw.m -framework UIKit -framework WebKit -framework Foundation -framework UserNotifications |
10 */ | 10 */ |
11 #import <Foundation/Foundation.h> | 11 #import <Foundation/Foundation.h> |
12 #import <UIKit/UIKit.h> | 12 #import <UIKit/UIKit.h> |
13 #import <WebKit/WebKit.h> | 13 #import <WebKit/WebKit.h> |
14 #import <AudioToolbox/AudioToolbox.h> | |
14 #import <UserNotifications/UserNotifications.h> | 15 #import <UserNotifications/UserNotifications.h> |
15 #include "dw.h" | 16 #include "dw.h" |
16 #include <sys/utsname.h> | 17 #include <sys/utsname.h> |
17 #include <sys/socket.h> | 18 #include <sys/socket.h> |
18 #include <sys/un.h> | 19 #include <sys/un.h> |
3515 * id: An ID to be used with dw_window_from_id() or 0L. | 3516 * id: An ID to be used with dw_window_from_id() or 0L. |
3516 * filename: Name of the file, omit extention to have | 3517 * filename: Name of the file, omit extention to have |
3517 * DW pick the appropriate file extension. | 3518 * DW pick the appropriate file extension. |
3518 * (BMP on OS/2 or Windows, XPM on Unix) | 3519 * (BMP on OS/2 or Windows, XPM on Unix) |
3519 */ | 3520 */ |
3520 DW_FUNCTION_DEFINITION(dw_bitmapbutton_new_from_file, HWND, const char *text, ULONG cid, const char *filename) | 3521 DW_FUNCTION_DEFINITION(dw_bitmapbutton_new_from_file, HWND, DW_UNUSED(const char *text), ULONG cid, const char *filename) |
3521 DW_FUNCTION_ADD_PARAM3(text, cid, filename) | 3522 DW_FUNCTION_ADD_PARAM3(text, cid, filename) |
3522 DW_FUNCTION_RETURN(dw_bitmapbutton_new_from_file, HWND) | 3523 DW_FUNCTION_RETURN(dw_bitmapbutton_new_from_file, HWND) |
3523 DW_FUNCTION_RESTORE_PARAM3(text, const char *, cid, ULONG, filename, const char *) | 3524 DW_FUNCTION_RESTORE_PARAM3(DW_UNUSED(text), const char *, cid, ULONG, filename, const char *) |
3524 { | 3525 { |
3525 char *ext = _dw_get_image_extension(filename); | 3526 char *ext = _dw_get_image_extension(filename); |
3526 | 3527 |
3527 NSString *nstr = [ NSString stringWithUTF8String:filename ]; | 3528 NSString *nstr = [ NSString stringWithUTF8String:filename ]; |
3528 UIImage *image = [[UIImage alloc] initWithContentsOfFile:nstr]; | 3529 UIImage *image = [[UIImage alloc] initWithContentsOfFile:nstr]; |
3667 * Parameters: | 3668 * Parameters: |
3668 * vertical: TRUE or FALSE if slider is vertical. | 3669 * vertical: TRUE or FALSE if slider is vertical. |
3669 * increments: Number of increments available. | 3670 * increments: Number of increments available. |
3670 * id: An ID to be used with dw_window_from_id() or 0L. | 3671 * id: An ID to be used with dw_window_from_id() or 0L. |
3671 */ | 3672 */ |
3672 DW_FUNCTION_DEFINITION(dw_slider_new, HWND, int vertical, int increments, ULONG cid) | 3673 DW_FUNCTION_DEFINITION(dw_slider_new, HWND, int DW_UNUSED(vertical), int increments, ULONG cid) |
3673 DW_FUNCTION_ADD_PARAM3(vertical, increments, cid) | 3674 DW_FUNCTION_ADD_PARAM3(vertical, increments, cid) |
3674 DW_FUNCTION_RETURN(dw_slider_new, HWND) | 3675 DW_FUNCTION_RETURN(dw_slider_new, HWND) |
3675 DW_FUNCTION_RESTORE_PARAM3(vertical, int, increments, int, cid, ULONG) | 3676 DW_FUNCTION_RESTORE_PARAM3(DW_UNUSED(vertical), int, increments, int, cid, ULONG) |
3676 { | 3677 { |
3677 DWSlider *slider = [[[DWSlider alloc] init] retain]; | 3678 DWSlider *slider = [[[DWSlider alloc] init] retain]; |
3678 [slider setMaximumValue:(double)increments]; | 3679 [slider setMaximumValue:(double)increments]; |
3679 [slider setMinimumValue:0]; | 3680 [slider setMinimumValue:0]; |
3680 [slider setContinuous:YES]; | 3681 [slider setContinuous:YES]; |
5860 * handle: Handle to the window (widget) to be scrolled. | 5861 * handle: Handle to the window (widget) to be scrolled. |
5861 * direction: DW_SCROLL_UP, DW_SCROLL_DOWN, DW_SCROLL_TOP or | 5862 * direction: DW_SCROLL_UP, DW_SCROLL_DOWN, DW_SCROLL_TOP or |
5862 * DW_SCROLL_BOTTOM. (rows is ignored for last two) | 5863 * DW_SCROLL_BOTTOM. (rows is ignored for last two) |
5863 * rows: The number of rows to be scrolled. | 5864 * rows: The number of rows to be scrolled. |
5864 */ | 5865 */ |
5865 DW_FUNCTION_DEFINITION(dw_container_scroll, void, HWND handle, int direction, long rows) | 5866 DW_FUNCTION_DEFINITION(dw_container_scroll, void, HWND handle, int direction, DW_UNUSED(long rows)) |
5866 DW_FUNCTION_ADD_PARAM3(handle, direction, rows) | 5867 DW_FUNCTION_ADD_PARAM3(handle, direction, rows) |
5867 DW_FUNCTION_NO_RETURN(dw_container_scroll) | 5868 DW_FUNCTION_NO_RETURN(dw_container_scroll) |
5868 DW_FUNCTION_RESTORE_PARAM3(handle, HWND, direction, int, rows, long) | 5869 DW_FUNCTION_RESTORE_PARAM3(handle, HWND, direction, int, DW_UNUSED(rows), long) |
5869 { | 5870 { |
5870 DW_FUNCTION_INIT; | 5871 DW_FUNCTION_INIT; |
5871 DWContainer *cont = handle; | 5872 DWContainer *cont = handle; |
5872 UIScrollView *sv = [cont scrollview]; | 5873 UIScrollView *sv = [cont scrollview]; |
5873 int rowcount = (int)[cont numberOfRowsInSection:0]; | 5874 int rowcount = (int)[cont numberOfRowsInSection:0]; |
5889 case DW_SCROLL_BOTTOM: | 5890 case DW_SCROLL_BOTTOM: |
5890 { | 5891 { |
5891 offset.y = [sv contentSize].height - [sv visibleSize].height; | 5892 offset.y = [sv contentSize].height - [sv visibleSize].height; |
5892 break; | 5893 break; |
5893 } | 5894 } |
5895 /* TODO: Currently scrolling a full page, need to use row parameter instead */ | |
5894 case DW_SCROLL_UP: | 5896 case DW_SCROLL_UP: |
5895 { | 5897 { |
5896 offset.y = offset.y - [sv visibleSize].height; | 5898 offset.y -= [sv visibleSize].height; |
5897 break; | 5899 break; |
5898 } | 5900 } |
5899 case DW_SCROLL_DOWN: | 5901 case DW_SCROLL_DOWN: |
5900 { | 5902 { |
5901 offset.y = offset.y + [sv visibleSize].height; | 5903 offset.y += [sv visibleSize].height; |
5902 break; | 5904 break; |
5903 } | 5905 } |
5904 } | 5906 } |
5905 if(offset.y < 0) | 5907 if(offset.y < 0) |
5906 offset.y = 0; | 5908 offset.y = 0; |
7190 * Create a notebook object to be packed. | 7192 * Create a notebook object to be packed. |
7191 * Parameters: | 7193 * Parameters: |
7192 * id: An ID to be used for getting the resource from the | 7194 * id: An ID to be used for getting the resource from the |
7193 * resource file. | 7195 * resource file. |
7194 */ | 7196 */ |
7195 DW_FUNCTION_DEFINITION(dw_notebook_new, HWND, ULONG cid, int top) | 7197 DW_FUNCTION_DEFINITION(dw_notebook_new, HWND, ULONG cid, DW_UNUSED(int top)) |
7196 DW_FUNCTION_ADD_PARAM2(cid, top) | 7198 DW_FUNCTION_ADD_PARAM2(cid, top) |
7197 DW_FUNCTION_RETURN(dw_notebook_new, HWND) | 7199 DW_FUNCTION_RETURN(dw_notebook_new, HWND) |
7198 DW_FUNCTION_RESTORE_PARAM2(cid, ULONG, top, int) | 7200 DW_FUNCTION_RESTORE_PARAM2(cid, ULONG, DW_UNUSED(top), int) |
7199 { | 7201 { |
7200 DWNotebook *notebook = [[[DWNotebook alloc] init] retain]; | 7202 DWNotebook *notebook = [[[DWNotebook alloc] init] retain]; |
7201 [notebook addTarget:notebook | 7203 [notebook addTarget:notebook |
7202 action:@selector(pageChanged:) | 7204 action:@selector(pageChanged:) |
7203 forControlEvents:UIControlEventValueChanged]; | 7205 forControlEvents:UIControlEventValueChanged]; |
8521 * freq: Frequency. | 8523 * freq: Frequency. |
8522 * dur: Duration. | 8524 * dur: Duration. |
8523 */ | 8525 */ |
8524 void API dw_beep(int freq, int dur) | 8526 void API dw_beep(int freq, int dur) |
8525 { | 8527 { |
8526 /* TODO: Don't see a simple way to do this without bundling sounds */ | 8528 AudioServicesPlayAlertSound((SystemSoundID)1104); |
8527 } | 8529 } |
8528 | 8530 |
8529 /* Call this after drawing to the screen to make sure | 8531 /* Call this after drawing to the screen to make sure |
8530 * anything you have drawn is visible. | 8532 * anything you have drawn is visible. |
8531 */ | 8533 */ |
8632 * Parameters: | 8634 * Parameters: |
8633 * window: Window handle of signal to be called back. | 8635 * window: Window handle of signal to be called back. |
8634 * dataname: A string pointer identifying which signal to be hooked. | 8636 * dataname: A string pointer identifying which signal to be hooked. |
8635 * data: User data to be passed to the handler function. | 8637 * data: User data to be passed to the handler function. |
8636 */ | 8638 */ |
8637 void dw_window_set_data(HWND window, const char *dataname, void *data) | 8639 DW_FUNCTION_DEFINITION(dw_window_set_data, void, HWND window, const char *dataname, void *data) |
8640 DW_FUNCTION_ADD_PARAM3(window, dataname, data) | |
8641 DW_FUNCTION_NO_RETURN(dw_window_set_data) | |
8642 DW_FUNCTION_RESTORE_PARAM3(window, HWND, dataname, const char *, data, void *) | |
8638 { | 8643 { |
8639 id object = window; | 8644 id object = window; |
8640 if([object isMemberOfClass:[DWWindow class]]) | 8645 if([object isMemberOfClass:[DWWindow class]]) |
8641 { | 8646 { |
8642 UIWindow *win = window; | 8647 UIWindow *win = window; |
8667 if(dataname) | 8672 if(dataname) |
8668 _dw_remove_userdata(&(blah->root), dataname, FALSE); | 8673 _dw_remove_userdata(&(blah->root), dataname, FALSE); |
8669 else | 8674 else |
8670 _dw_remove_userdata(&(blah->root), NULL, TRUE); | 8675 _dw_remove_userdata(&(blah->root), NULL, TRUE); |
8671 } | 8676 } |
8677 DW_FUNCTION_RETURN_NOTHING; | |
8672 } | 8678 } |
8673 | 8679 |
8674 /* | 8680 /* |
8675 * Gets a named user data item to a window handle. | 8681 * Gets a named user data item to a window handle. |
8676 * Parameters: | 8682 * Parameters: |
8677 * window: Window handle of signal to be called back. | 8683 * window: Window handle of signal to be called back. |
8678 * dataname: A string pointer identifying which signal to be hooked. | 8684 * dataname: A string pointer identifying which signal to be hooked. |
8679 * data: User data to be passed to the handler function. | 8685 * data: User data to be passed to the handler function. |
8680 */ | 8686 */ |
8681 void *dw_window_get_data(HWND window, const char *dataname) | 8687 DW_FUNCTION_DEFINITION(dw_window_get_data, void *, HWND window, const char *dataname) |
8688 DW_FUNCTION_ADD_PARAM2(window, dataname) | |
8689 DW_FUNCTION_RETURN(dw_window_get_data, void *) | |
8690 DW_FUNCTION_RESTORE_PARAM2(window, HWND, dataname, const char *) | |
8682 { | 8691 { |
8683 id object = window; | 8692 id object = window; |
8693 void *retval = NULL; | |
8694 | |
8684 if([object isMemberOfClass:[DWWindow class]]) | 8695 if([object isMemberOfClass:[DWWindow class]]) |
8685 { | 8696 { |
8686 UIWindow *win = window; | 8697 UIWindow *win = window; |
8687 NSArray *subviews = [win subviews]; | 8698 NSArray *subviews = [win subviews]; |
8688 object = [subviews firstObject]; | 8699 object = [subviews firstObject]; |
8697 | 8708 |
8698 if(blah && blah->root && dataname) | 8709 if(blah && blah->root && dataname) |
8699 { | 8710 { |
8700 UserData *ud = _dw_find_userdata(&(blah->root), dataname); | 8711 UserData *ud = _dw_find_userdata(&(blah->root), dataname); |
8701 if(ud) | 8712 if(ud) |
8702 return ud->data; | 8713 retval = ud->data; |
8703 } | 8714 } |
8704 return NULL; | 8715 DW_FUNCTION_RETURN_THIS(retval); |
8705 } | 8716 } |
8706 | 8717 |
8707 #define DW_TIMER_MAX 64 | 8718 #define DW_TIMER_MAX 64 |
8708 static NSTimer *DWTimers[DW_TIMER_MAX]; | 8719 static NSTimer *DWTimers[DW_TIMER_MAX]; |
8709 | 8720 |
8714 * sigfunc: The pointer to the function to be used as the callback. | 8725 * sigfunc: The pointer to the function to be used as the callback. |
8715 * data: User data to be passed to the handler function. | 8726 * data: User data to be passed to the handler function. |
8716 * Returns: | 8727 * Returns: |
8717 * Timer ID for use with dw_timer_disconnect(), 0 on error. | 8728 * Timer ID for use with dw_timer_disconnect(), 0 on error. |
8718 */ | 8729 */ |
8719 int API dw_timer_connect(int interval, void *sigfunc, void *data) | 8730 DW_FUNCTION_DEFINITION(dw_timer_connect, int, int interval, void *sigfunc, void *data) |
8720 { | 8731 DW_FUNCTION_ADD_PARAM3(interval, sigfunc, data) |
8721 int z; | 8732 DW_FUNCTION_RETURN(dw_timer_connect, int) |
8733 DW_FUNCTION_RESTORE_PARAM3(interval, int, sigfunc, void *, data, void *) | |
8734 { | |
8735 int z, retval = 0; | |
8722 | 8736 |
8723 for(z=0;z<DW_TIMER_MAX;z++) | 8737 for(z=0;z<DW_TIMER_MAX;z++) |
8724 { | 8738 { |
8725 if(!DWTimers[z]) | 8739 if(!DWTimers[z]) |
8726 { | 8740 { |
8731 if(sigfunc && !DWTimers[z]) | 8745 if(sigfunc && !DWTimers[z]) |
8732 { | 8746 { |
8733 NSTimeInterval seconds = (double)interval / 1000.0; | 8747 NSTimeInterval seconds = (double)interval / 1000.0; |
8734 NSTimer *thistimer = DWTimers[z] = [NSTimer scheduledTimerWithTimeInterval:seconds target:DWHandler selector:@selector(runTimer:) userInfo:nil repeats:YES]; | 8748 NSTimer *thistimer = DWTimers[z] = [NSTimer scheduledTimerWithTimeInterval:seconds target:DWHandler selector:@selector(runTimer:) userInfo:nil repeats:YES]; |
8735 _dw_new_signal(0, thistimer, z+1, sigfunc, NULL, data); | 8749 _dw_new_signal(0, thistimer, z+1, sigfunc, NULL, data); |
8736 return z+1; | 8750 retval = z+1; |
8737 } | 8751 } |
8738 return 0; | 8752 DW_FUNCTION_RETURN_THIS(retval); |
8739 } | 8753 } |
8740 | 8754 |
8741 /* | 8755 /* |
8742 * Removes timer callback. | 8756 * Removes timer callback. |
8743 * Parameters: | 8757 * Parameters: |
8744 * id: Timer ID returned by dw_timer_connect(). | 8758 * id: Timer ID returned by dw_timer_connect(). |
8745 */ | 8759 */ |
8746 void API dw_timer_disconnect(int timerid) | 8760 DW_FUNCTION_DEFINITION(dw_timer_disconnect, void, int timerid) |
8761 DW_FUNCTION_ADD_PARAM1(timerid) | |
8762 DW_FUNCTION_NO_RETURN(dw_timer_disconnect) | |
8763 DW_FUNCTION_RESTORE_PARAM1(timerid, int) | |
8747 { | 8764 { |
8748 SignalHandler *prev = NULL, *tmp = DWRoot; | 8765 SignalHandler *prev = NULL, *tmp = DWRoot; |
8749 NSTimer *thistimer; | 8766 NSTimer *thistimer; |
8750 | 8767 |
8751 /* 0 is an invalid timer ID */ | 8768 /* 0 is an invalid timer ID */ |
8752 if(timerid < 1 || !DWTimers[timerid-1]) | 8769 if(timerid > 0 && timerid < DW_TIMER_MAX && DWTimers[timerid-1]) |
8753 return; | 8770 { |
8754 | 8771 thistimer = DWTimers[timerid-1]; |
8755 thistimer = DWTimers[timerid-1]; | 8772 DWTimers[timerid-1] = nil; |
8756 DWTimers[timerid-1] = nil; | 8773 |
8757 | 8774 [thistimer invalidate]; |
8758 [thistimer invalidate]; | 8775 |
8759 | 8776 while(tmp) |
8760 while(tmp) | 8777 { |
8761 { | 8778 if(tmp->id == timerid && tmp->window == thistimer) |
8762 if(tmp->id == timerid && tmp->window == thistimer) | |
8763 { | |
8764 if(prev) | |
8765 { | 8779 { |
8766 prev->next = tmp->next; | 8780 if(prev) |
8767 free(tmp); | 8781 { |
8768 tmp = prev->next; | 8782 prev->next = tmp->next; |
8783 free(tmp); | |
8784 tmp = prev->next; | |
8785 } | |
8786 else | |
8787 { | |
8788 DWRoot = tmp->next; | |
8789 free(tmp); | |
8790 tmp = DWRoot; | |
8791 } | |
8769 } | 8792 } |
8770 else | 8793 else |
8771 { | 8794 { |
8772 DWRoot = tmp->next; | 8795 prev = tmp; |
8773 free(tmp); | 8796 tmp = tmp->next; |
8774 tmp = DWRoot; | |
8775 } | 8797 } |
8776 } | 8798 } |
8777 else | 8799 } |
8778 { | 8800 DW_FUNCTION_RETURN_NOTHING; |
8779 prev = tmp; | |
8780 tmp = tmp->next; | |
8781 } | |
8782 } | |
8783 } | 8801 } |
8784 | 8802 |
8785 /* | 8803 /* |
8786 * Add a callback to a window event. | 8804 * Add a callback to a window event. |
8787 * Parameters: | 8805 * Parameters: |
9691 dw_event_reset(DWMainEvent); | 9709 dw_event_reset(DWMainEvent); |
9692 /* We wait for the dw_init() in the user's main function */ | 9710 /* We wait for the dw_init() in the user's main function */ |
9693 dw_event_wait(DWMainEvent, DW_TIMEOUT_INFINITE); | 9711 dw_event_wait(DWMainEvent, DW_TIMEOUT_INFINITE); |
9694 DWThread = dw_thread_id(); | 9712 DWThread = dw_thread_id(); |
9695 DWObj = [[DWObject alloc] init]; | 9713 DWObj = [[DWObject alloc] init]; |
9714 /* Create object for handling timers */ | |
9715 DWHandler = [[DWTimerHandler alloc] init]; | |
9696 UIApplicationMain(argc, argv, nil, NSStringFromClass([DWAppDel class])); | 9716 UIApplicationMain(argc, argv, nil, NSStringFromClass([DWAppDel class])); |
9697 /* Shouldn't get here, but ... just in case */ | 9717 /* Shouldn't get here, but ... just in case */ |
9698 DWThread = (DWTID)-1; | 9718 DWThread = (DWTID)-1; |
9699 } | 9719 } |
9700 | 9720 |
9790 * directly, otherwise specify UTF-8 explicitly. | 9810 * directly, otherwise specify UTF-8 explicitly. |
9791 */ | 9811 */ |
9792 setlocale(LC_ALL, lang && strstr(lang, ".UTF-8") ? lang : "UTF-8"); | 9812 setlocale(LC_ALL, lang && strstr(lang, ".UTF-8") ? lang : "UTF-8"); |
9793 /* Create the application object */ | 9813 /* Create the application object */ |
9794 _dw_app_init(); | 9814 _dw_app_init(); |
9795 /* Create object for handling timers */ | |
9796 DWHandler = [[DWTimerHandler alloc] init]; | |
9797 pthread_key_create(&_dw_pool_key, NULL); | 9815 pthread_key_create(&_dw_pool_key, NULL); |
9798 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | 9816 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
9799 pthread_setspecific(_dw_pool_key, pool); | 9817 pthread_setspecific(_dw_pool_key, pool); |
9800 pthread_key_create(&_dw_fg_color_key, NULL); | 9818 pthread_key_create(&_dw_fg_color_key, NULL); |
9801 pthread_key_create(&_dw_bg_color_key, NULL); | 9819 pthread_key_create(&_dw_bg_color_key, NULL); |