Mercurial > dwindows
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 { |