comparison mac/dw.m @ 2994:8311be624877

Mac/iOS: Implement DW_FEATURE_RENDER_SAFE. iOS always operates in safe render mode. Mac defaults to disabled, enabling will enforce expose event restrictions on drawing to render widgets.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 03 May 2023 23:29:17 +0000
parents 81f9399b11c8
children a74b30a9d744
comparison
equal deleted inserted replaced
2993:392f0b3dd502 2994:8311be624877
519 pthread_key_t _dw_fg_color_key; 519 pthread_key_t _dw_fg_color_key;
520 pthread_key_t _dw_bg_color_key; 520 pthread_key_t _dw_bg_color_key;
521 static int DWOSMajor, DWOSMinor, DWOSBuild; 521 static int DWOSMajor, DWOSMinor, DWOSBuild;
522 static char _dw_bundle_path[PATH_MAX+1] = { 0 }; 522 static char _dw_bundle_path[PATH_MAX+1] = { 0 };
523 static char _dw_app_id[_DW_APP_ID_SIZE+1]= {0}; 523 static char _dw_app_id[_DW_APP_ID_SIZE+1]= {0};
524 static int _dw_render_safe_mode = DW_FEATURE_DISABLED;
525 static id _dw_render_expose = nil;
526
527 /* Return TRUE if it is safe to draw on the window handle.
528 * Either we are in unsafe mode, or we are in an EXPOSE
529 * event for the requested render window handle.
530 */
531 int _dw_render_safe_check(id handle)
532 {
533 if(_dw_render_safe_mode == DW_FEATURE_DISABLED ||
534 (handle && _dw_render_expose == handle))
535 return TRUE;
536 return FALSE;
537 }
538
539 int _dw_is_render(id handle);
524 540
525 /* Create a default colors for a thread */ 541 /* Create a default colors for a thread */
526 void _dw_init_colors(void) 542 void _dw_init_colors(void)
527 { 543 {
528 NSColor *fgcolor = [[NSColor grayColor] retain]; 544 NSColor *fgcolor = [[NSColor grayColor] retain];
730 case _DW_EVENT_EXPOSE: 746 case _DW_EVENT_EXPOSE:
731 { 747 {
732 DWExpose exp; 748 DWExpose exp;
733 int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))handler->signalfunction; 749 int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))handler->signalfunction;
734 NSRect rect = [object frame]; 750 NSRect rect = [object frame];
751 id oldrender = _dw_render_expose;
735 752
736 exp.x = rect.origin.x; 753 exp.x = rect.origin.x;
737 exp.y = rect.origin.y; 754 exp.y = rect.origin.y;
738 exp.width = rect.size.width; 755 exp.width = rect.size.width;
739 exp.height = rect.size.height; 756 exp.height = rect.size.height;
757 /* The render expose is only valid for render class windows */
758 if(_dw_is_render(object))
759 _dw_render_expose = object;
740 int result = exposefunc(object, &exp, handler->data); 760 int result = exposefunc(object, &exp, handler->data);
761 _dw_render_expose = oldrender;
741 #ifndef BUILDING_FOR_MOJAVE 762 #ifndef BUILDING_FOR_MOJAVE
742 [[object window] flushWindow]; 763 [[object window] flushWindow];
743 #endif 764 #endif
744 return result; 765 return result;
745 } 766 }
1260 #endif 1281 #endif
1261 [super dealloc]; 1282 [super dealloc];
1262 } 1283 }
1263 -(BOOL)acceptsFirstResponder { return YES; } 1284 -(BOOL)acceptsFirstResponder { return YES; }
1264 @end 1285 @end
1286
1287 /* So we can check before DWRender is declared */
1288 int _dw_is_render(id handle)
1289 {
1290 if([handle isMemberOfClass:[DWRender class]])
1291 return TRUE;
1292 return FALSE;
1293 }
1265 1294
1266 @implementation DWObject 1295 @implementation DWObject
1267 -(void)uselessThread:(id)sender { /* Thread only to initialize threading */ } 1296 -(void)uselessThread:(id)sender { /* Thread only to initialize threading */ }
1268 #ifndef BUILDING_FOR_MOJAVE 1297 #ifndef BUILDING_FOR_MOJAVE
1269 -(void)synchronizeThread:(id)param 1298 -(void)synchronizeThread:(id)param
7002 7031
7003 if(pixmap) 7032 if(pixmap)
7004 bi = (id)pixmap->image; 7033 bi = (id)pixmap->image;
7005 else 7034 else
7006 { 7035 {
7036 if(_dw_render_safe_check(handle))
7037 {
7007 #ifdef BUILDING_FOR_MOJAVE 7038 #ifdef BUILDING_FOR_MOJAVE
7008 if([image isMemberOfClass:[DWRender class]]) 7039 if([image isMemberOfClass:[DWRender class]])
7009 { 7040 {
7010 DWRender *render = image; 7041 DWRender *render = image;
7011 7042
7012 bi = [render cachedDrawingRep]; 7043 bi = [render cachedDrawingRep];
7013 } 7044 }
7014 #else 7045 #else
7015 if((bCanDraw = [image lockFocusIfCanDraw]) == YES) 7046 if((bCanDraw = [image lockFocusIfCanDraw]) == YES)
7016 _DWLastDrawable = handle; 7047 _DWLastDrawable = handle;
7017 #endif 7048 #endif
7049 }
7050 else
7051 bCanDraw = NO;
7018 } 7052 }
7019 if(bi) 7053 if(bi)
7020 { 7054 {
7021 [NSGraphicsContext saveGraphicsState]; 7055 [NSGraphicsContext saveGraphicsState];
7022 [NSGraphicsContext setCurrentContext:_dw_draw_context(bi)]; 7056 [NSGraphicsContext setCurrentContext:_dw_draw_context(bi)];
7066 7100
7067 if(pixmap) 7101 if(pixmap)
7068 bi = (id)pixmap->image; 7102 bi = (id)pixmap->image;
7069 else 7103 else
7070 { 7104 {
7105 if(_dw_render_safe_check(handle))
7106 {
7071 #ifdef BUILDING_FOR_MOJAVE 7107 #ifdef BUILDING_FOR_MOJAVE
7072 if([image isMemberOfClass:[DWRender class]]) 7108 if([image isMemberOfClass:[DWRender class]])
7073 { 7109 {
7074 DWRender *render = image; 7110 DWRender *render = image;
7075 7111
7076 bi = [render cachedDrawingRep]; 7112 bi = [render cachedDrawingRep];
7077 } 7113 }
7078 #else 7114 #else
7079 if((bCanDraw = [image lockFocusIfCanDraw]) == YES) 7115 if((bCanDraw = [image lockFocusIfCanDraw]) == YES)
7080 _DWLastDrawable = handle; 7116 _DWLastDrawable = handle;
7081 #endif 7117 #endif
7118 }
7119 else
7120 bCanDraw = NO;
7082 } 7121 }
7083 if(bi) 7122 if(bi)
7084 { 7123 {
7085 [NSGraphicsContext saveGraphicsState]; 7124 [NSGraphicsContext saveGraphicsState];
7086 [NSGraphicsContext setCurrentContext:_dw_draw_context(bi)]; 7125 [NSGraphicsContext setCurrentContext:_dw_draw_context(bi)];
7141 font = [render font]; 7180 font = [render font];
7142 } 7181 }
7143 } 7182 }
7144 else if(image && [image isMemberOfClass:[DWRender class]]) 7183 else if(image && [image isMemberOfClass:[DWRender class]])
7145 { 7184 {
7146 render = image; 7185 if(_dw_render_safe_check(handle))
7147 font = [render font]; 7186 {
7187 render = image;
7188 font = [render font];
7148 #ifdef BUILDING_FOR_MOJAVE 7189 #ifdef BUILDING_FOR_MOJAVE
7149 bi = [render cachedDrawingRep]; 7190 bi = [render cachedDrawingRep];
7150 #else 7191 #else
7151 if((bCanDraw = [image lockFocusIfCanDraw]) == YES) 7192 if((bCanDraw = [image lockFocusIfCanDraw]) == YES)
7152 _DWLastDrawable = handle; 7193 _DWLastDrawable = handle;
7153 #endif 7194 #endif
7195 }
7196 else
7197 bCanDraw = NO;
7154 } 7198 }
7155 if(bi) 7199 if(bi)
7156 { 7200 {
7157 [NSGraphicsContext saveGraphicsState]; 7201 [NSGraphicsContext saveGraphicsState];
7158 [NSGraphicsContext setCurrentContext:_dw_draw_context(bi)]; 7202 [NSGraphicsContext setCurrentContext:_dw_draw_context(bi)];
7273 7317
7274 if(pixmap) 7318 if(pixmap)
7275 bi = (id)pixmap->image; 7319 bi = (id)pixmap->image;
7276 else 7320 else
7277 { 7321 {
7322 if(_dw_render_safe_check(handle))
7323 {
7278 #ifdef BUILDING_FOR_MOJAVE 7324 #ifdef BUILDING_FOR_MOJAVE
7279 if([image isMemberOfClass:[DWRender class]]) 7325 if([image isMemberOfClass:[DWRender class]])
7280 { 7326 {
7281 DWRender *render = image; 7327 DWRender *render = image;
7282 7328
7283 bi = [render cachedDrawingRep]; 7329 bi = [render cachedDrawingRep];
7284 } 7330 }
7285 #else 7331 #else
7286 if((bCanDraw = [image lockFocusIfCanDraw]) == YES) 7332 if((bCanDraw = [image lockFocusIfCanDraw]) == YES)
7287 { 7333 {
7288 _DWLastDrawable = handle; 7334 _DWLastDrawable = handle;
7289 [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)]; 7335 [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)];
7290 } 7336 }
7291 #endif 7337 #endif
7338 }
7339 else
7340 bCanDraw = NO;
7292 } 7341 }
7293 if(bi) 7342 if(bi)
7294 { 7343 {
7295 id gc = _dw_create_gc(bi, flags & DW_DRAW_NOAA ? NO : YES); 7344 id gc = _dw_create_gc(bi, flags & DW_DRAW_NOAA ? NO : YES);
7296 [NSGraphicsContext saveGraphicsState]; 7345 [NSGraphicsContext saveGraphicsState];
7352 7401
7353 if(pixmap) 7402 if(pixmap)
7354 bi = (id)pixmap->image; 7403 bi = (id)pixmap->image;
7355 else 7404 else
7356 { 7405 {
7406 if(_dw_render_safe_check(handle))
7407 {
7357 #ifdef BUILDING_FOR_MOJAVE 7408 #ifdef BUILDING_FOR_MOJAVE
7358 if([image isMemberOfClass:[DWRender class]]) 7409 if([image isMemberOfClass:[DWRender class]])
7359 { 7410 {
7360 DWRender *render = image; 7411 DWRender *render = image;
7361 7412
7362 bi = [render cachedDrawingRep]; 7413 bi = [render cachedDrawingRep];
7363 } 7414 }
7364 #else 7415 #else
7365 if((bCanDraw = [image lockFocusIfCanDraw]) == YES) 7416 if((bCanDraw = [image lockFocusIfCanDraw]) == YES)
7366 { 7417 {
7367 _DWLastDrawable = handle; 7418 _DWLastDrawable = handle;
7368 [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)]; 7419 [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)];
7369 } 7420 }
7370 #endif 7421 #endif
7422 }
7423 else
7424 bCanDraw = NO;
7371 } 7425 }
7372 if(bi) 7426 if(bi)
7373 { 7427 {
7374 id gc = _dw_create_gc(bi, flags & DW_DRAW_NOAA ? NO : YES); 7428 id gc = _dw_create_gc(bi, flags & DW_DRAW_NOAA ? NO : YES);
7375 [NSGraphicsContext saveGraphicsState]; 7429 [NSGraphicsContext saveGraphicsState];
7426 7480
7427 if(pixmap) 7481 if(pixmap)
7428 bi = (id)pixmap->image; 7482 bi = (id)pixmap->image;
7429 else 7483 else
7430 { 7484 {
7485 if(_dw_render_safe_check(handle))
7486 {
7431 #ifdef BUILDING_FOR_MOJAVE 7487 #ifdef BUILDING_FOR_MOJAVE
7432 if([image isMemberOfClass:[DWRender class]]) 7488 if([image isMemberOfClass:[DWRender class]])
7433 { 7489 {
7434 DWRender *render = image; 7490 DWRender *render = image;
7435 7491
7436 bi = [render cachedDrawingRep]; 7492 bi = [render cachedDrawingRep];
7437 } 7493 }
7438 #else 7494 #else
7439 if((bCanDraw = [image lockFocusIfCanDraw]) == YES) 7495 if((bCanDraw = [image lockFocusIfCanDraw]) == YES)
7440 { 7496 {
7441 _DWLastDrawable = handle; 7497 _DWLastDrawable = handle;
7442 [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)]; 7498 [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)];
7443 } 7499 }
7444 #endif 7500 #endif
7501 }
7502 else
7503 bCanDraw = NO;
7445 } 7504 }
7446 if(bi) 7505 if(bi)
7447 { 7506 {
7448 id gc = _dw_create_gc(bi, flags & DW_DRAW_NOAA ? NO : YES); 7507 id gc = _dw_create_gc(bi, flags & DW_DRAW_NOAA ? NO : YES);
7449 [NSGraphicsContext saveGraphicsState]; 7508 [NSGraphicsContext saveGraphicsState];
9282 NSValue* bi; 9341 NSValue* bi;
9283 DW_LOCAL_POOL_IN; 9342 DW_LOCAL_POOL_IN;
9284 9343
9285 /* Sanity checks */ 9344 /* Sanity checks */
9286 if((!dest && !destp) || (!src && !srcp) || 9345 if((!dest && !destp) || (!src && !srcp) ||
9287 ((srcwidth == -1 || srcheight == -1) && srcwidth != srcheight)) 9346 ((srcwidth == -1 || srcheight == -1) && srcwidth != srcheight) ||
9347 (dest && !_dw_render_safe_check(dest)))
9288 { 9348 {
9289 DW_LOCAL_POOL_OUT; 9349 DW_LOCAL_POOL_OUT;
9290 return DW_ERROR_GENERAL; 9350 return DW_ERROR_GENERAL;
9291 } 9351 }
9292 9352
13475 case DW_FEATURE_MLE_WORD_WRAP: 13535 case DW_FEATURE_MLE_WORD_WRAP:
13476 case DW_FEATURE_UTF8_UNICODE: 13536 case DW_FEATURE_UTF8_UNICODE:
13477 case DW_FEATURE_TREE: 13537 case DW_FEATURE_TREE:
13478 case DW_FEATURE_WINDOW_PLACEMENT: 13538 case DW_FEATURE_WINDOW_PLACEMENT:
13479 return DW_FEATURE_ENABLED; 13539 return DW_FEATURE_ENABLED;
13540 case DW_FEATURE_RENDER_SAFE:
13541 return _dw_render_safe_mode;
13480 #ifdef BUILDING_FOR_MOJAVE 13542 #ifdef BUILDING_FOR_MOJAVE
13481 case DW_FEATURE_DARK_MODE: 13543 case DW_FEATURE_DARK_MODE:
13482 { 13544 {
13483 if(@available(macOS 10.14, *)) 13545 if(@available(macOS 10.14, *))
13484 { 13546 {
13560 case DW_FEATURE_UTF8_UNICODE: 13622 case DW_FEATURE_UTF8_UNICODE:
13561 case DW_FEATURE_TREE: 13623 case DW_FEATURE_TREE:
13562 case DW_FEATURE_WINDOW_PLACEMENT: 13624 case DW_FEATURE_WINDOW_PLACEMENT:
13563 return DW_ERROR_GENERAL; 13625 return DW_ERROR_GENERAL;
13564 /* These features are supported and configurable */ 13626 /* These features are supported and configurable */
13627 case DW_FEATURE_RENDER_SAFE:
13628 {
13629 if (state == DW_FEATURE_ENABLED || state == DW_FEATURE_DISABLED)
13630 {
13631 _dw_render_safe_mode = state;
13632 return DW_ERROR_NONE;
13633 }
13634 return DW_ERROR_GENERAL;
13635 }
13565 #ifdef BUILDING_FOR_MOJAVE 13636 #ifdef BUILDING_FOR_MOJAVE
13566 case DW_FEATURE_DARK_MODE: 13637 case DW_FEATURE_DARK_MODE:
13567 { 13638 {
13568 if(@available(macOS 10.14, *)) 13639 if(@available(macOS 10.14, *))
13569 { 13640 {