comparison ios/dw.m @ 2396:5bb3491ceba2

iOS: Get iOS basic funcionality working by creating dwmain() macros. This allows us to fork the main() entry point into the main thread to essentially just call UIApplicationMain() and a secondary thread to call the user's main() function. This is an experimental change... but required for iOS functionality... May be changed further going forward. Move more DW functions into thread safety since the user entry point is now a secondary thread.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 25 Mar 2021 20:39:52 +0000
parents 2618277de356
children 1cbc316292c1
comparison
equal deleted inserted replaced
2395:2618277de356 2396:5bb3491ceba2
577 static UIApplication *DWApp = nil; 577 static UIApplication *DWApp = nil;
578 static UIFont *DWDefaultFont; 578 static UIFont *DWDefaultFont;
579 static DWTimerHandler *DWHandler; 579 static DWTimerHandler *DWHandler;
580 static NSMutableArray *_DWDirtyDrawables; 580 static NSMutableArray *_DWDirtyDrawables;
581 static DWTID DWThread = (DWTID)-1; 581 static DWTID DWThread = (DWTID)-1;
582 static HEV DWMainEvent;
582 583
583 /* Used for doing bitblts from the main thread */ 584 /* Used for doing bitblts from the main thread */
584 typedef struct _bitbltinfo 585 typedef struct _bitbltinfo
585 { 586 {
586 id src; 587 id src;
2407 _dw_resize_box(thisbox, &depth, x, y, 2); 2408 _dw_resize_box(thisbox, &depth, x, y, 2);
2408 } 2409 }
2409 } 2410 }
2410 } 2411 }
2411 2412
2412 static int _dw_argc = 0;
2413 static char **_dw_argv = NULL;
2414
2415 /* 2413 /*
2416 * Runs a message loop for Dynamic Windows. 2414 * Runs a message loop for Dynamic Windows.
2417 */ 2415 */
2418 void API dw_main(void) 2416 void API dw_main(void)
2419 { 2417 {
2420 DWThread = dw_thread_id(); 2418 /* We don't actually run a loop here,
2421 /* Make sure any queued redraws are handled */ 2419 * we launched a new thread to run the loop there.
2422 _dw_redraw(0, FALSE); 2420 * Just wait for dw_main_quit() on the DWMainEvent.
2423 UIApplicationMain(_dw_argc, _dw_argv, nil, NSStringFromClass([DWAppDel class])); 2421 */
2424 DWThread = (DWTID)-1; 2422 dw_event_wait(DWMainEvent, DW_TIMEOUT_INFINITE);
2425 } 2423 }
2426 2424
2427 /* 2425 /*
2428 * Causes running dw_main() to return. 2426 * Causes running dw_main() to return.
2429 */ 2427 */
2430 void API dw_main_quit(void) 2428 void API dw_main_quit(void)
2431 { 2429 {
2432 /* TODO: Make this work 2430 dw_event_post(DWMainEvent);
2433 [[NSRunLoop mainRunLoop] ]; */
2434 } 2431 }
2435 2432
2436 /* 2433 /*
2437 * Runs a message loop for Dynamic Windows, for a period of milliseconds. 2434 * Runs a message loop for Dynamic Windows, for a period of milliseconds.
2438 * Parameters: 2435 * Parameters:
3341 * height: Height in pixels of the item or -1 to be self determined. 3338 * height: Height in pixels of the item or -1 to be self determined.
3342 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. 3339 * hsize: TRUE if the window (widget) should expand horizontally to fill space given.
3343 * vsize: TRUE if the window (widget) should expand vertically to fill space given. 3340 * vsize: TRUE if the window (widget) should expand vertically to fill space given.
3344 * pad: Number of pixels of padding around the item. 3341 * pad: Number of pixels of padding around the item.
3345 */ 3342 */
3346 void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 3343 DW_FUNCTION_DEFINITION(dw_box_pack_start, void, HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
3344 DW_FUNCTION_ADD_PARAM7(box, item, width, height, hsize, vsize, pad)
3345 DW_FUNCTION_NO_RETURN(dw_box_pack_start)
3346 DW_FUNCTION_RESTORE_PARAM7(box, HWND, item, HWND, width, int, height, int, hsize, int, vsize, int, pad, int)
3347 { 3347 {
3348 /* 65536 is the table limit on GTK... 3348 /* 65536 is the table limit on GTK...
3349 * seems like a high enough value we will never hit it here either. 3349 * seems like a high enough value we will never hit it here either.
3350 */ 3350 */
3351 _dw_box_pack(box, item, 65536, width, height, hsize, vsize, pad, "dw_box_pack_start()"); 3351 _dw_box_pack(box, item, 65536, width, height, hsize, vsize, pad, "dw_box_pack_start()");
3352 DW_FUNCTION_RETURN_NOTHING;
3352 } 3353 }
3353 3354
3354 /* 3355 /*
3355 * Pack windows (widgets) into a box from the end (or bottom). 3356 * Pack windows (widgets) into a box from the end (or bottom).
3356 * Parameters: 3357 * Parameters:
3360 * height: Height in pixels of the item or -1 to be self determined. 3361 * height: Height in pixels of the item or -1 to be self determined.
3361 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. 3362 * hsize: TRUE if the window (widget) should expand horizontally to fill space given.
3362 * vsize: TRUE if the window (widget) should expand vertically to fill space given. 3363 * vsize: TRUE if the window (widget) should expand vertically to fill space given.
3363 * pad: Number of pixels of padding around the item. 3364 * pad: Number of pixels of padding around the item.
3364 */ 3365 */
3365 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) 3366 DW_FUNCTION_DEFINITION(dw_box_pack_end, void, HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
3367 DW_FUNCTION_ADD_PARAM7(box, item, width, height, hsize, vsize, pad)
3368 DW_FUNCTION_NO_RETURN(dw_box_pack_end)
3369 DW_FUNCTION_RESTORE_PARAM7(box, HWND, item, HWND, width, int, height, int, hsize, int, vsize, int, pad, int)
3366 { 3370 {
3367 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()"); 3371 _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()");
3372 DW_FUNCTION_RETURN_NOTHING;
3368 } 3373 }
3369 3374
3370 /* Internal function to create a basic button, used by all button types */ 3375 /* Internal function to create a basic button, used by all button types */
3371 HWND _dw_button_new(const char *text, ULONG cid) 3376 HWND _dw_button_new(const char *text, ULONG cid)
3372 { 3377 {
7292 /* 7297 /*
7293 * Makes the window visible. 7298 * Makes the window visible.
7294 * Parameters: 7299 * Parameters:
7295 * handle: The window handle to make visible. 7300 * handle: The window handle to make visible.
7296 */ 7301 */
7297 int API dw_window_show(HWND handle) 7302 DW_FUNCTION_DEFINITION(dw_window_show, int, HWND handle)
7303 DW_FUNCTION_ADD_PARAM1(handle)
7304 DW_FUNCTION_RETURN(dw_window_show, int)
7305 DW_FUNCTION_RESTORE_PARAM1(handle, HWND)
7298 { 7306 {
7299 NSObject *object = handle; 7307 NSObject *object = handle;
7308 int retval = DW_ERROR_NONE;
7300 7309
7301 if([ object isMemberOfClass:[ DWWindow class ] ]) 7310 if([ object isMemberOfClass:[ DWWindow class ] ])
7302 { 7311 {
7303 DWWindow *window = handle; 7312 DWWindow *window = handle;
7304 CGRect rect = [window frame]; 7313 CGRect rect = [window frame];
7315 [window setShown:YES]; 7324 [window setShown:YES];
7316 } 7325 }
7317 else 7326 else
7318 [window setHidden:NO]; 7327 [window setHidden:NO];
7319 } 7328 }
7320 return 0; 7329 DW_FUNCTION_RETURN_THIS(retval);
7321 } 7330 }
7322 7331
7323 /* 7332 /*
7324 * Makes the window invisible. 7333 * Makes the window invisible.
7325 * Parameters: 7334 * Parameters:
7326 * handle: The window handle to make visible. 7335 * handle: The window handle to make visible.
7327 */ 7336 */
7328 int API dw_window_hide(HWND handle) 7337 DW_FUNCTION_DEFINITION(dw_window_hide, int, HWND handle)
7338 DW_FUNCTION_ADD_PARAM1(handle)
7339 DW_FUNCTION_RETURN(dw_window_hide, int)
7340 DW_FUNCTION_RESTORE_PARAM1(handle, HWND)
7329 { 7341 {
7330 NSObject *object = handle; 7342 NSObject *object = handle;
7343 int retval = DW_ERROR_NONE;
7331 7344
7332 if([ object isKindOfClass:[ UIWindow class ] ]) 7345 if([ object isKindOfClass:[ UIWindow class ] ])
7333 { 7346 {
7334 UIWindow *window = handle; 7347 UIWindow *window = handle;
7335 7348
7336 [window setHidden:YES]; 7349 [window setHidden:YES];
7337 } 7350 }
7338 return 0; 7351 DW_FUNCTION_RETURN_THIS(retval);
7339 } 7352 }
7340 7353
7341 /* 7354 /*
7342 * Sets the colors used by a specified window (widget) handle. 7355 * Sets the colors used by a specified window (widget) handle.
7343 * Parameters: 7356 * Parameters:
9516 [DWDefaultFont retain]; 9529 [DWDefaultFont retain];
9517 } 9530 }
9518 [oldfont release]; 9531 [oldfont release];
9519 } 9532 }
9520 9533
9534 /* Thread start stub to launch our main */
9535 void _dw_main_launch(void **data)
9536 {
9537 int (*_dwmain)(int argc, char **argv) = (int (*)(int, char **))data[0];
9538 int argc = DW_POINTER_TO_INT(data[1]);
9539 char **argv = (char **)data[2];
9540
9541 _dwmain(argc, argv);
9542 free(data);
9543 }
9544
9545 /* The iOS main thread... all this does is handle messages */
9546 void _dw_main_thread(int argc, char *argv[])
9547 {
9548 DWMainEvent = dw_event_new();
9549 dw_event_reset(DWMainEvent);
9550 /* We wait for the dw_init() in the user's main function */
9551 dw_event_wait(DWMainEvent, DW_TIMEOUT_INFINITE);
9552 DWThread = dw_thread_id();
9553 DWObj = [[DWObject alloc] init];
9554 UIApplicationMain(argc, argv, nil, NSStringFromClass([DWAppDel class]));
9555 /* Shouldn't get here, but ... just in case */
9556 DWThread = (DWTID)-1;
9557 }
9558
9521 /* If DWApp is uninitialized, initialize it */ 9559 /* If DWApp is uninitialized, initialize it */
9522 void _dw_app_init(void) 9560 void _dw_app_init(void)
9523 { 9561 {
9524 if(!DWApp) 9562 /* The UIApplication singleton won't be created until we call
9563 * UIApplicationMain() which blocks indefinitely.. so we have
9564 * a thread to just run UIApplicationMain() .. and wait until
9565 * we get a non-nil sharedApplication result.
9566 */
9567 while(!DWApp)
9568 {
9569 static int posted = FALSE;
9570
9571 if(DWMainEvent && !posted)
9572 {
9573 /* Post the DWMainEvent so the main thread
9574 * will call UIApplicationMain() creating
9575 * the UIApplication sharedApplication.
9576 */
9577 posted = TRUE;
9578 dw_event_post(DWMainEvent);
9579 }
9580 pthread_yield_np();
9525 DWApp = [UIApplication sharedApplication]; 9581 DWApp = [UIApplication sharedApplication];
9582 }
9583 dw_event_reset(DWMainEvent);
9584 dw_debug("SharedApplication is valid!\n");
9526 } 9585 }
9527 9586
9528 /* 9587 /*
9529 * Initializes the Dynamic Windows engine. 9588 * Initializes the Dynamic Windows engine.
9530 * Parameters: 9589 * Parameters:
9532 * False if there is already a message loop running. 9591 * False if there is already a message loop running.
9533 */ 9592 */
9534 int API dw_init(int newthread, int argc, char *argv[]) 9593 int API dw_init(int newthread, int argc, char *argv[])
9535 { 9594 {
9536 char *lang = getenv("LANG"); 9595 char *lang = getenv("LANG");
9537
9538 _dw_argc = argc;
9539 _dw_argv = argv;
9540 9596
9541 /* Correct the startup path if run from a bundle */ 9597 /* Correct the startup path if run from a bundle */
9542 if(argc > 0 && argv[0]) 9598 if(argc > 0 && argv[0])
9543 { 9599 {
9544 char *pathcopy = strdup(argv[0]); 9600 char *pathcopy = strdup(argv[0]);
9600 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 9656 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
9601 pthread_setspecific(_dw_pool_key, pool); 9657 pthread_setspecific(_dw_pool_key, pool);
9602 pthread_key_create(&_dw_fg_color_key, NULL); 9658 pthread_key_create(&_dw_fg_color_key, NULL);
9603 pthread_key_create(&_dw_bg_color_key, NULL); 9659 pthread_key_create(&_dw_bg_color_key, NULL);
9604 _dw_init_colors(); 9660 _dw_init_colors();
9605 DWObj = [[DWObject alloc] init];
9606 DWDefaultFont = nil; 9661 DWDefaultFont = nil;
9607 if (@available(iOS 10.0, *)) 9662 if (@available(iOS 10.0, *))
9608 { 9663 {
9609 if([[NSBundle mainBundle] bundleIdentifier] != nil) 9664 if([[NSBundle mainBundle] bundleIdentifier] != nil)
9610 { 9665 {