diff --git a/api/graphics2_unix.cpp b/api/graphics2_unix.cpp index e500bad3940..ff64dbe4188 100644 --- a/api/graphics2_unix.cpp +++ b/api/graphics2_unix.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2020 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -237,15 +237,19 @@ void boinc_graphics_loop(int argc, char** argv, const char* title) { boinc_init_graphics_diagnostics(BOINC_DIAG_DEFAULTS); } -#ifdef __APPLE__ - char dir [MAXPATHLEN]; - getcwd(dir, MAXPATHLEN); -#endif for (int i=1; imajor_version = BOINC_MAJOR_VERSION; + ss_shmem->minor_version = BOINC_MINOR_VERSION; + ss_shmem->release = BOINC_RELEASE; + } +} + #endif diff --git a/api/macglutfix.m b/api/macglutfix.m index 2953b10c1b9..b4a27c1cf45 100644 --- a/api/macglutfix.m +++ b/api/macglutfix.m @@ -1,6 +1,6 @@ // Berkeley Open Infrastructure for Network Computing // http://boinc.berkeley.edu -// Copyright (C) 2020 University of California +// Copyright (C) 2024 University of California // // This is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -190,14 +190,12 @@ void HideThisApp() { @interface ServerController : NSObject { NSMachPort *serverPort; - NSMachPort *localPort; - - uint32_t serverPortName; - uint32_t localPortName; NSMachPort *clientPort[16]; uint32_t clientPortNames[16]; uint32_t clientPortCount; + + bool mach_bootstrap_unavailable_to_screensavers; } - (ServerController *)init; - (kern_return_t)checkInClient:(mach_port_t)client_port index:(int32_t *)client_index; @@ -220,30 +218,42 @@ @implementation ServerController - (ServerController *)init { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(portDied:) name:NSPortDidBecomeInvalidNotification object:nil]; - mach_port_t servicePortNum = MACH_PORT_NULL; kern_return_t machErr; - char *portName = "edu.berkeley.boincsaver"; + char *portNameV1 = "edu.berkeley.boincsaver"; + char *portNameV2 = "edu.berkeley.boincsaver-v2"; + + mach_bootstrap_unavailable_to_screensavers = false; // NSMachBootstrapServer is deprecated in OS 10.13, so use bootstrap_look_up -// serverPort = [(NSMachPort *)([[NSMachBootstrapServer sharedInstance] servicePortWithName:@"edu.berkeley.boincsaver"]) retain]; - machErr = bootstrap_check_in(bootstrap_port, portName, &servicePortNum); - if (machErr != KERN_SUCCESS) { - [NSApp terminate:self]; +// serverPort = [(NSMachPort *)([[NSMachBootstrapServer sharedInstance] portForName:@"edu.berkeley.boincsaver"]) retain]; + machErr = bootstrap_look_up(bootstrap_port, portNameV2, &servicePortNum); + if (machErr == KERN_SUCCESS) { + // As of MacOS 14.0, the legacyScreenSave sandbox prevents using + // bootstrap_look_up. I have filed bug report FB13300491 with + // Apple and hope they will change this in a future MacOS. + mach_bootstrap_unavailable_to_screensavers = true; + + int32_t dummy_index; + [self checkInClient:servicePortNum index:&dummy_index]; + } else { +// NSMachBootstrapServer is deprecated in OS 10.13, so use bootstrap_check_in +// serverPort = [(NSMachPort *)([[NSMachBootstrapServer sharedInstance] servicePortWithName:@"edu.berkeley.boincsaver"]) retain]; + machErr = bootstrap_check_in(bootstrap_port, portNameV1, &servicePortNum); + if (machErr != KERN_SUCCESS) { // maybe BOOTSTRAP_UNKNOWN_SERVICE + [NSApp terminate:self]; + } } - serverPort = (NSMachPort*)[NSMachPort portWithMachPort:servicePortNum]; - // Create a local dummy reply port to use with the mig reply stuff - localPort = [[NSMachPort alloc] init]; - - // Retrieve raw mach port names. - serverPortName = [serverPort machPort]; - localPortName = [localPort machPort]; + serverPort = (NSMachPort*)[NSMachPort portWithMachPort:servicePortNum]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(portDied:) name:NSPortDidBecomeInvalidNotification object:nil]; - [serverPort setDelegate:self]; - [serverPort scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + if (!mach_bootstrap_unavailable_to_screensavers) { + // Register server port with the current runloop. + [serverPort setDelegate:self]; // CAF STD + [serverPort scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; // CAF STD + } // NOT USED: See comments in animateOneFrame in Mac_Saver_ModuleView.m #if 0 diff --git a/api/x_opengl.h b/api/x_opengl.h index eecbf05fff5..36c4db16deb 100644 --- a/api/x_opengl.h +++ b/api/x_opengl.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2020 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -32,6 +32,7 @@ extern void BringAppToFront(void); extern void HideThisApp(void); extern bool UseSharedOffscreenBuffer(void); extern bool debugSharedOffscreenBuffer; +void pass_BOINC_gfx_lib_version_to_ss(void); extern void print_to_log_file(const char *format, ...); diff --git a/clientscr/Mac_Saver_Module.h b/clientscr/Mac_Saver_Module.h index 7b8c27ce63e..4145636fb9e 100644 --- a/clientscr/Mac_Saver_Module.h +++ b/clientscr/Mac_Saver_Module.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -47,14 +47,15 @@ bool getShow_default_ss_first(); double getGFXDefaultPeriod(); double getGFXSciencePeriod(); double getGGFXChangePeriod(); -void incompatibleGfxApp(char * appPath, pid_t pid, int slot); +void incompatibleGfxApp(char * appPath, char * wuName, pid_t pid, int slot); void setShow_default_ss_first(bool value); void setGFXDefaultPeriod(double value); void setGFXSciencePeriod(double value); void setGGFXChangePeriod(double value); double getDTime(); void doBoinc_Sleep(double seconds); -void launchedGfxApp(char * appPath, pid_t thePID, int slot); +void launchedGfxApp(char * appPath, char * wuName, pid_t thePID, int slot); +int compareBOINCLibVersionTo(int toMajor, int toMinor, int toRelease); void print_to_log_file(const char *format, ...); void strip_cr(char *buf); void PrintBacktrace(void); @@ -63,7 +64,8 @@ extern bool gIsMojave; extern bool gIsCatalina; extern bool gIsHighSierra; extern bool gIsSonoma; -extern bool gCant_Use_Shared_Offscreen_Buffer; +extern bool gMach_bootstrap_unavailable_to_screensavers; +extern mach_port_name_t commsPort; #ifdef __cplusplus } // extern "C" diff --git a/clientscr/Mac_Saver_ModuleView.h b/clientscr/Mac_Saver_ModuleView.h index 08a2b64eb02..ed858af0cc3 100644 --- a/clientscr/Mac_Saver_ModuleView.h +++ b/clientscr/Mac_Saver_ModuleView.h @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -51,8 +51,9 @@ @property (NS_NONATOMIC_IOSONLY, readonly) GLuint currentTextureName; - (void)init:(NSView*)saverView; -- (void)portDied:(NSNotification *)notification; - (void)testConnection; +- (void)portDied:(NSNotification *)notification; +- (void)cleanUpOpenGL; @end @@ -84,14 +85,15 @@ bool getShow_default_ss_first(); double getGFXDefaultPeriod(); double getGFXSciencePeriod(); double getGGFXChangePeriod(); -void incompatibleGfxApp(char * appPath, pid_t pid, int slot); +void incompatibleGfxApp(char * appPath, char * wuName, pid_t pid, int slot); void setShow_default_ss_first(bool value); void setGFXDefaultPeriod(double value); void setGFXSciencePeriod(double value); void setGGFXChangePeriod(double value); double getDTime(); void doBoinc_Sleep(double seconds); -void launchedGfxApp(char * appPath, pid_t thePID, int slot); +void launchedGfxApp(char * appPath, char * wuName, pid_t thePID, int slot); +int compareBOINCLibVersionTo(int toMajor, int toMinor, int toRelease); void print_to_log_file(const char *format, ...); void strip_cr(char *buf); void PrintBacktrace(void); @@ -100,7 +102,9 @@ extern bool gIsCatalina; extern bool gIsHighSierra; extern bool gIsMojave; extern bool gIsSonoma; -extern bool gCant_Use_Shared_Offscreen_Buffer; +extern bool gMach_bootstrap_unavailable_to_screensavers; +extern mach_port_name_t commsPort; + #ifdef __cplusplus } // extern "C" diff --git a/clientscr/Mac_Saver_ModuleView.m b/clientscr/Mac_Saver_ModuleView.m index a92c1c120e0..746d7583f7f 100644 --- a/clientscr/Mac_Saver_ModuleView.m +++ b/clientscr/Mac_Saver_ModuleView.m @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -150,6 +150,7 @@ static int gfxAppWindowNum; static NSView *imageView; static char gfxAppPath[MAXPATHLEN]; +static char gfxWuName[MAXPATHLEN]; static int taskSlot; static NSRunningApplication *childApp; static double gfxAppStartTime; @@ -175,12 +176,17 @@ #define MAXWAITFORCONNECTIONCATALINA 12.0 #define MAX_CGWINDOWLIST_TRIES 3 +#define MAJORBOINCGFXLIBNEEDEDFORSONOMA 7 +#define MINORBOINCGFXLIBNEEDEDFORSONOMA 24 +#define RELEASEBOINCGFXLIBNEEDEDFORSONOMA 4 + int signof(float x) { return (x > 0.0 ? 1 : -1); } -void launchedGfxApp(char * appPath, pid_t thePID, int slot) { +void launchedGfxApp(char * appPath, char * wuName, pid_t thePID, int slot) { strlcpy(gfxAppPath, appPath, sizeof(gfxAppPath)); + strlcpy(gfxWuName, wuName, sizeof(gfxWuName)); childPid = thePID; taskSlot = slot; gfxAppStartTime = getDTime(); @@ -188,16 +194,24 @@ void launchedGfxApp(char * appPath, pid_t thePID, int slot) { if (thePID == 0) { useCGWindowList = false; gfxAppStartTime = 0.0; + gfxWuName[0] = '\0'; + if (mySharedGraphicsController) { + [ mySharedGraphicsController cleanUpOpenGL ]; + } if (imageView) { // removeFromSuperview must be called from main thread - if (pthread_equal(mainThreadID, pthread_self())) { + if (NSThread.isMainThread) { [imageView removeFromSuperview]; // Releases imageView - imageView = nil; + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + [imageView removeFromSuperview]; // Releases imageView + }); } + imageView = nil; } - } else { - if (gCant_Use_Shared_Offscreen_Buffer) { - stopAllGFXApps(); + } else { // thePID != 0 + if (childPid) { + childApp = [NSRunningApplication runningApplicationWithProcessIdentifier:childPid]; } } } @@ -408,7 +422,13 @@ - (void)stopAnimation { if (imageView) { useCGWindowList = false; // removeFromSuperview must be called from main thread - [imageView removeFromSuperview]; // Releases imageView + if (NSThread.isMainThread) { + [imageView removeFromSuperview]; // Releases imageView + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + [imageView removeFromSuperview]; // Releases imageView + }); + } imageView = nil; } @@ -563,7 +583,7 @@ - (void)doPeriodicTasks { // if (childApp) { if (![ childApp activateWithOptions:NSApplicationActivateIgnoringOtherApps ]) { - launchedGfxApp("", 0, -1); // Graphics app is no longer running + launchedGfxApp("", "", 0, -1); // Graphics app is no longer running } else if (useCGWindowList) { // As a safety precaution, prevent terminating gfx app while copying its window pthread_mutex_lock(&saver_mutex); @@ -611,7 +631,13 @@ - (void)doPeriodicTasks { if (imageView && !useCGWindowList) { // removeFromSuperview must be called from main thread - [imageView removeFromSuperview]; // Releases imageView + if (NSThread.isMainThread) { + [imageView removeFromSuperview]; // Releases imageView + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + [imageView removeFromSuperview]; // Releases imageView + }); + } imageView = nil; } @@ -631,16 +657,26 @@ - (void)doPeriodicTasks { maxWaitTime = gIsCatalina ? MAXWAITFORCONNECTIONCATALINA : MAXWAITFORCONNECTION; if ((getDTime() - gfxAppStartTime) > maxWaitTime) { if (gIsCatalina) { + if (gMach_bootstrap_unavailable_to_screensavers) { + // Is the gfx app built with a new enough BOINC graphics library version? + if (compareBOINCLibVersionTo(MAJORBOINCGFXLIBNEEDEDFORSONOMA, MINORBOINCGFXLIBNEEDEDFORSONOMA, RELEASEBOINCGFXLIBNEEDEDFORSONOMA) >= 0) { + runningSharedGraphics = true; + if (childPid) { + gfxAppStartTime = 0.0; + childApp = [NSRunningApplication runningApplicationWithProcessIdentifier:childPid]; + } + } + } // CGWindowListCopyWindowInfo and CGWindowListCreateImage can copy // windows between user boinc_project and the user running the // screensaver only if OS < 10.15 (before Catalina) - incompatibleGfxApp(gfxAppPath, childPid, taskSlot); + incompatibleGfxApp(gfxAppPath, gfxWuName, childPid, taskSlot); } else { if (++CGWindowListTries > MAX_CGWINDOWLIST_TRIES) { // After displaying message for 5 seconds, incompatibleGfxApp // will call launchedGfxApp("", 0, -1) which will clear // gfxAppStartTime and CGWindowListTries - incompatibleGfxApp(gfxAppPath, childPid, taskSlot); + incompatibleGfxApp(gfxAppPath, gfxWuName, childPid, taskSlot); } else { if ([self setUpToUseCGWindowList]) { CGWindowListTries = 0; @@ -1088,12 +1124,14 @@ - (void)init:(NSView*)saverView { [[NSNotificationCenter defaultCenter] removeObserver:self name:NSPortDidBecomeInvalidNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(portDied:) name:NSPortDidBecomeInvalidNotification object:nil]; - openGLView = nil; [self testConnection]; + + if (! gMach_bootstrap_unavailable_to_screensavers) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(portDied:) name:NSPortDidBecomeInvalidNotification object:nil]; + } } @@ -1101,60 +1139,129 @@ - (void) testConnection { mach_port_t servicePortNum = MACH_PORT_NULL; kern_return_t machErr; - char *portName = "edu.berkeley.boincsaver"; + char *portNameV1 = "edu.berkeley.boincsaver"; + char *portNameV2 = "edu.berkeley.boincsaver-v2"; - // Try to check in with master. + if ((!gMach_bootstrap_unavailable_to_screensavers) || (serverPort == MACH_PORT_NULL)) { + // Try to check in with master. // NSMachBootstrapServer is deprecated in OS 10.13, so use bootstrap_look_up // serverPort = [(NSMachPort *)([[NSMachBootstrapServer sharedInstance] portForName:@"edu.berkeley.boincsaver"]) retain]; - machErr = bootstrap_look_up(bootstrap_port, portName, &servicePortNum); - if (machErr == KERN_SUCCESS) { - serverPort = (NSMachPort*)[NSMachPort portWithMachPort:servicePortNum]; - } else { - if (machErr == BOOTSTRAP_NOT_PRIVILEGED) { - // As of MacOS 14.0, the legacyScreenSave sandbox prevents using - // IOSurfaceLookupFromMachPort. I have filed bug report FB13300491 - // with Apple and hope they will change this in future MacOS. - gCant_Use_Shared_Offscreen_Buffer = true; - stopAllGFXApps(); + machErr = bootstrap_look_up(bootstrap_port, portNameV1, &servicePortNum); + if (machErr != KERN_SUCCESS) { + if (machErr != BOOTSTRAP_NOT_PRIVILEGED) { + // bootstrap_look_up() returned error other than BOOTSTRAP_NOT_PRIVILEGED + // machErr is probably BOOTSTRAP_UNKNOWN_SERVICE because no gfx app is running + // Keep trying bootstrap_look_up() until we get a connection from gfx app + serverPort = MACH_PORT_NULL; + } else { // bootstrap_look_up() returned error BOOTSTRAP_NOT_PRIVILEGED + // As of MacOS 14.0, the legacyScreenSave sandbox prevents using + // bootstrap_look_up. I have filed bug report FB13300491 with + // Apple and hope they will change this in a future MacOS. + machErr = bootstrap_check_in(bootstrap_port, portNameV2, &servicePortNum); + if (machErr != KERN_SUCCESS) { + [NSApp terminate:nil]; + } + gMach_bootstrap_unavailable_to_screensavers = true; + } // bootstrap_look_up() returned error BOOTSTRAP_NOT_PRIVILEGED + } // bootstrap_look_up() did not return KERN_SUCCESS + + if (machErr == KERN_SUCCESS) { + serverPort = (NSMachPort*)[NSMachPort portWithMachPort:servicePortNum]; } - serverPort = MACH_PORT_NULL; - } - if ((serverPort != MACH_PORT_NULL) && (localPort == MACH_PORT_NULL)) - { - // Create our own local port. - localPort = [[NSMachPort alloc] init]; + if ((serverPort != MACH_PORT_NULL) && (localPort == MACH_PORT_NULL)) { + // Retrieve raw mach port names. + serverPortName = [serverPort machPort]; + + if (gMach_bootstrap_unavailable_to_screensavers) { + // Register server port with the current runloop. + [serverPort setDelegate:self]; + [serverPort scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + } else { // (! gMach_bootstrap_unavailable_to_screensavers) + // Create our own local port. + localPort = [[NSMachPort alloc] init]; + localPortName = [localPort machPort]; + // Register our local port with the current runloop. + [localPort setDelegate:self]; + [localPort scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + + // Check in with server. + int kr; + kr = _MGCCheckinClient(serverPortName, localPortName, &clientIndex); + if(kr != 0) { + [NSApp terminate:nil]; + } - // Retrieve raw mach port names. - serverPortName = [serverPort machPort]; - localPortName = [localPort machPort]; + runningSharedGraphics = true; - // Register our local port with the current runloop. - [localPort setDelegate:self]; - [localPort scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + if (childPid) { + gfxAppStartTime = 0.0; + childApp = [NSRunningApplication runningApplicationWithProcessIdentifier:childPid]; + } + } // (! gMach_bootstrap_unavailable_to_screensavers) + } // ((serverPort != MACH_PORT_NULL) && (localPort == MACH_PORT_NULL)) + } // ((!gMach_bootstrap_unavailable_to_screensavers) || (serverPort == MACH_PORT_NULL)) +} - // Check in with server. - int kr; - kr = _MGCCheckinClient(serverPortName, localPortName, &clientIndex); - if(kr != 0) - [NSApp terminate:nil]; - runningSharedGraphics = true; +- (void)cleanUpOpenGL +{ + if (gMach_bootstrap_unavailable_to_screensavers) { + [serverPort removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + } + childPid=0; + childApp = nil; + + if (gMach_bootstrap_unavailable_to_screensavers || + ((serverPort == MACH_PORT_NULL) && (localPort == MACH_PORT_NULL)) + ) { + if (openGLView) { + if (NSThread.isMainThread) { + [openGLView removeFromSuperview]; // Releases openGLView + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + [openGLView removeFromSuperview]; // Releases openGLView + }); + } + openGLView = nil; + } - if (childPid) { - gfxAppStartTime = 0.0; - childApp = [NSRunningApplication runningApplicationWithProcessIdentifier:childPid]; + int i; + for(i = 0; i < NUM_IOSURFACE_BUFFERS; i++) { + if (_ioSurfaceBuffers[i]) { + CFRelease(_ioSurfaceBuffers[i]); + _ioSurfaceBuffers[i] = nil; + } + + // if (glIsTexture(_textureNames[i])) { + // glDeleteTextures(1, _textureNames[i]); + // } + _textureNames[i] = 0; + + if (_ioSurfaceMachPorts[i] != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), _ioSurfaceMachPorts[i]); + _ioSurfaceMachPorts[i] = MACH_PORT_NULL; + } + } + + runningSharedGraphics = false; // Do this last!! + if (gMach_bootstrap_unavailable_to_screensavers) { + [serverPort scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; } } } - (void)portDied:(NSNotification *)notification { + if (gMach_bootstrap_unavailable_to_screensavers) { + return; // This should never be called if using MacOS 14 workaround + } NSPort *port = [notification object]; if(port == serverPort) { childApp = nil; gfxAppStartTime = 0.0; gfxAppPath[0] = '\0'; + gfxWuName[0] = '\0'; if ([serverPort isValid]) { [serverPort invalidate]; @@ -1169,29 +1276,7 @@ - (void)portDied:(NSNotification *)notification // [localPort release]; localPort = MACH_PORT_NULL; - int i; - for(i = 0; i < NUM_IOSURFACE_BUFFERS; i++) { - if (_ioSurfaceBuffers[i]) { - CFRelease(_ioSurfaceBuffers[i]); - _ioSurfaceBuffers[i] = nil; - } - - // if (glIsTexture(_textureNames[i])) { - // glDeleteTextures(1, _textureNames[i]); - // } - _textureNames[i] = 0; - - if (_ioSurfaceMachPorts[i] != MACH_PORT_NULL) { - mach_port_deallocate(mach_task_self(), _ioSurfaceMachPorts[i]); - _ioSurfaceMachPorts[i] = MACH_PORT_NULL; - } - } - - if ((serverPort == MACH_PORT_NULL) && (localPort == MACH_PORT_NULL)) { - runningSharedGraphics = false; - [openGLView removeFromSuperview]; // Releases openGLView - openGLView = nil; - } + [ self cleanUpOpenGL ]; } } @@ -1206,13 +1291,16 @@ - (void)handleMachMessage:(void *)msg { kr = mach_msg(reply_header, MACH_SEND_MSG, reply_header->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL); - if(kr != 0) + if(kr != 0) { [NSApp terminate:nil]; + } } } - (kern_return_t)displayFrame:(int32_t)frameIndex surfacemachport:(mach_port_t)iosurface_port { + if (!childPid) return 0; + nextFrameIndex = frameIndex; if(!_ioSurfaceBuffers[frameIndex]) @@ -1239,11 +1327,21 @@ - (kern_return_t)displayFrame:(int32_t)frameIndex surfacemachport:(mach_port_t)i _textureNames[frameIndex] = [openGLView setupIOSurfaceTexture:_ioSurfaceBuffers[frameIndex]]; } - okToDraw = true; // Tell drawRect that we have real data to display + if (openGLView) { + okToDraw = true; // Tell drawRect that we have real data to display - [openGLView setNeedsDisplay:YES]; - [openGLView display]; + [openGLView setNeedsDisplay:YES]; + [openGLView display]; + } + if (gMach_bootstrap_unavailable_to_screensavers && (runningSharedGraphics == false)) { + // We have now heard from gfx app so connection has been established + runningSharedGraphics = true; + if (childPid) { + gfxAppStartTime = 0.0; + childApp = [NSRunningApplication runningApplicationWithProcessIdentifier:childPid]; + } + } return 0; } @@ -1283,8 +1381,9 @@ - (instancetype)initWithFrame:(NSRect)frame { NSOpenGLPixelFormat *pix_fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; - if(!pix_fmt) + if(!pix_fmt) { [ NSApp terminate:nil]; + } self = [super initWithFrame:frame pixelFormat:pix_fmt]; @@ -1431,12 +1530,6 @@ static bool UseSharedOffscreenBuffer() { static bool needSharedGfxBuffer = false; //return true; // FOR TESTING ONLY - // As of MacOS 14.0, the legacyScreenSaver sandbox prevents using - // IOSurfaceLookupFromMachPort. I have filed bug report FB13300491 - // with Apple and hope they will change this in future MacOS. - if (gCant_Use_Shared_Offscreen_Buffer) { - return false; - } if (alreadyTested) { return needSharedGfxBuffer; } diff --git a/clientscr/gfx_cleanup.mm b/clientscr/gfx_cleanup.mm index 9ed64559619..214506e18fd 100644 --- a/clientscr/gfx_cleanup.mm +++ b/clientscr/gfx_cleanup.mm @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -51,9 +51,17 @@ pthread_t MonitorParentThread = 0; bool quit_MonitorParentThread = false; +// struct ss_shmem_data must be kept in sync in these files: +// screensaver.cpp +// gfx_switcher.cpp +// gfx_cleanup.mm +// graphics2_unix.cpp struct ss_shmem_data { pid_t gfx_pid; int gfx_slot; + int major_version; + int minor_version; + int release; }; static struct ss_shmem_data* ss_shmem = NULL; @@ -122,6 +130,9 @@ void killGfxApp(pid_t thePID) { if (ss_shmem) { rpc->run_graphics_app("stop", ss_shmem->gfx_slot, ""); ss_shmem->gfx_slot = -1; + ss_shmem->major_version = 0; + ss_shmem->minor_version = 0; + ss_shmem->release = 0; } rpc->close(); diff --git a/clientscr/gfx_switcher.cpp b/clientscr/gfx_switcher.cpp index c0b4efdb733..1e18cc62e01 100644 --- a/clientscr/gfx_switcher.cpp +++ b/clientscr/gfx_switcher.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -82,9 +82,17 @@ static void strip_cr(char *buf); void * MonitorScreenSaverEngine(void* param); +// struct ss_shmem_data must be kept in sync in these files: +// screensaver.cpp +// gfx_switcher.cpp +// gfx_cleanup.mm +// graphics2_unix.cpp struct ss_shmem_data { pid_t gfx_pid; int gfx_slot; + int major_version; + int minor_version; + int release; }; static struct ss_shmem_data* ss_shmem = NULL; @@ -222,6 +230,9 @@ int main(int argc, char** argv) { pthread_cancel(monitorScreenSaverEngineThread); if (ss_shmem != 0) { ss_shmem->gfx_pid = 0; + ss_shmem->major_version = 0; + ss_shmem->minor_version = 0; + ss_shmem->release = 0; } return 0; } @@ -287,6 +298,9 @@ int main(int argc, char** argv) { pthread_cancel(monitorScreenSaverEngineThread); if (ss_shmem != 0) { ss_shmem ->gfx_pid = 0; + ss_shmem->major_version = 0; + ss_shmem->minor_version = 0; + ss_shmem->release = 0; } return 0; } diff --git a/clientscr/mac_saver_module.cpp b/clientscr/mac_saver_module.cpp index 283effcd352..b67cc92ac32 100644 --- a/clientscr/mac_saver_module.cpp +++ b/clientscr/mac_saver_module.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -112,8 +112,8 @@ bool gIsCatalina = false; // OS 10.15 or later bool gIsSonoma = false; // OS 14.0 or later // As of MacOS 14.0, the legacyScreenSave sandbox -// prevents using IOSurfaceLookupFromMachPort. -bool gCant_Use_Shared_Offscreen_Buffer = false; +// prevents using bootstrap_look_up. +bool gMach_bootstrap_unavailable_to_screensavers = false; const char * CantLaunchCCMsg = "Unable to launch BOINC application."; const char * LaunchingCCMsg = "Launching BOINC application."; @@ -128,7 +128,6 @@ const char * DefaultGFXAppCrashedMsg = "Default screensaver module had an unrec const char * RunningOnBatteryMsg = "Computing and screensaver disabled while running on battery power."; const char * IncompatibleMsg = "Could not connect to screensaver "; const char * CCNotRunningMsg = "BOINC is not running."; -const char * NoScreenSaverGraphicsThisMacOS = "BOINC can't show screensaver graphics on this version of MacOS"; //const char * BOINCExitedSaverMode = "BOINC is no longer in screensaver mode."; @@ -207,7 +206,7 @@ void closeBOINCSaver() { } -void incompatibleGfxApp(char * appPath, pid_t pid, int slot){ +void incompatibleGfxApp(char * appPath, char * wuName, pid_t pid, int slot){ char *p; static char buf[1024]; static double msgstartTime = 0.0; @@ -253,8 +252,8 @@ void incompatibleGfxApp(char * appPath, pid_t pid, int slot){ } // End if (msgstartTime == 0.0) if (msgstartTime && (getDTime() - msgstartTime > 5.0)) { - gspScreensaver->markAsIncompatible(appPath); - launchedGfxApp("", 0, -1); + gspScreensaver->markAsIncompatible(wuName); + launchedGfxApp("", "", 0, -1); msgstartTime = 0.0; gspScreensaver->terminate_v6_screensaver(pid); } @@ -356,7 +355,6 @@ CScreensaver::CScreensaver() { GetDefaultDisplayPeriods(periods); m_bShow_default_ss_first = periods.Show_default_ss_first; - m_fGFXDefaultPeriod = periods.GFXDefaultPeriod; m_fGFXSciencePeriod = periods.GFXSciencePeriod; m_fGFXChangePeriod = periods.GFXChangePeriod; @@ -479,11 +477,6 @@ int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) { return NOTEXTLOGOFREQUENCY; } - if (gCant_Use_Shared_Offscreen_Buffer) { - gspScreensaver->setSSMessageText(NoScreenSaverGraphicsThisMacOS); - goto msgIsSet; - } - CheckDualGPUPowerSource(); switch (saverState) { @@ -654,7 +647,6 @@ int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) { } } -msgIsSet: if (m_MessageText[0]) { newFrequency = TEXTLOGOFREQUENCY; } else { diff --git a/clientscr/screensaver.cpp b/clientscr/screensaver.cpp index 6a5a750d440..06c55e10156 100644 --- a/clientscr/screensaver.cpp +++ b/clientscr/screensaver.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -102,13 +102,23 @@ extern pthread_mutex_t saver_mutex; RESULT* graphics_app_result_ptr = NULL; #ifdef __APPLE__ +// struct ss_shmem_data must be kept in sync in these files: +// screensaver.cpp +// gfx_switcher.cpp +// gfx_cleanup.mm +// graphics2_unix.cpp struct ss_shmem_data { pid_t gfx_pid; int gfx_slot; + int major_version; + int minor_version; + int release; }; static struct ss_shmem_data* ss_shmem = NULL; bool canAccessProjectGFXApps = true; +static double graphicsAppStartTime; + #endif bool CScreensaver::is_same_task(RESULT* taska, RESULT* taskb) { @@ -136,10 +146,10 @@ int CScreensaver::count_active_graphic_apps(RESULTS& res, RESULT* exclude) { if (is_same_task(res.results[i], exclude)) continue; #ifdef __APPLE__ // Remove it from the vector if incompatible with current version of OS X - if (isIncompatible(res.results[i]->graphics_exec_path)) { + if (isIncompatible(res.results[i]->wu_name)) { BOINCTRACE( _T("count_active_graphic_apps -- removing incompatible name = '%s', path = '%s'\n"), - res.results[i]->name, res.results[i]->graphics_exec_path + res.results[i]->wu_name, res.results[i]->graphics_exec_path ); RESULT *rp = res.results[i]; res.results.erase(res.results.begin()+i); @@ -211,23 +221,23 @@ RESULT* CScreensaver::get_random_graphics_app( #ifdef __APPLE__ -void CScreensaver::markAsIncompatible(char *gfxAppPath) { - char *buf = (char *)malloc(strlen(gfxAppPath)+1); +void CScreensaver::markAsIncompatible(char *wuName) { + char *buf = (char *)malloc(strlen(wuName)+1); if (buf) { - strlcpy(buf, gfxAppPath, malloc_size(buf)); + strlcpy(buf, wuName, malloc_size(buf)); m_vIncompatibleGfxApps.push_back(buf); - BOINCTRACE(_T("markAsIncompatible -- path = '%s'\n"), gfxAppPath); + BOINCTRACE(_T("markAsIncompatible -- wuName = '%s'\n"), wuName); } } -bool CScreensaver::isIncompatible(char *appPath) { +bool CScreensaver::isIncompatible(char *wuName) { unsigned int i = 0; for (i = 0; i < m_vIncompatibleGfxApps.size(); i++) { BOINCTRACE( _T("isIncompatible -- comparing incompatible path '%s' to candidate path %s\n"), - m_vIncompatibleGfxApps[i], appPath + m_vIncompatibleGfxApps[i], wuName ); - if (strcmp(m_vIncompatibleGfxApps[i], appPath) == 0) { + if (strcmp(m_vIncompatibleGfxApps[i], wuName) == 0) { return true; } } @@ -266,7 +276,7 @@ int CScreensaver::launch_screensaver(RESULT* rp, PROCESS_REF& graphics_applicati // V6 Graphics #ifdef __APPLE__ graphics_application = 0; - + graphicsAppStartTime = 0; // As of OS 10.15 (Catalina) screensavers can no longer: // - launch apps that run setuid or setgid // - launch apps downloaded from the Internet which have not been @@ -300,7 +310,8 @@ int CScreensaver::launch_screensaver(RESULT* rp, PROCESS_REF& graphics_applicati fflush(m_gfx_Cleanup_IPC); if (graphics_application) { - launchedGfxApp(rp->graphics_exec_path, graphics_application, rp->slot); + graphicsAppStartTime = getDTime(); + launchedGfxApp(rp->graphics_exec_path, rp->wu_name, graphics_application, rp->slot); } #else char* argv[3]; @@ -324,6 +335,7 @@ int CScreensaver::launch_screensaver(RESULT* rp, PROCESS_REF& graphics_applicati // int CScreensaver::terminate_v6_screensaver(PROCESS_REF graphics_application) { #ifdef __APPLE__ + static bool in_terminate_v6_screensaver = false; pid_t thePID; // As of OS 10.15 (Catalina) screensavers can no longer launch apps @@ -338,31 +350,41 @@ int CScreensaver::terminate_v6_screensaver(PROCESS_REF graphics_application) { // able to just call kill_program(graphics_application). // int ignore; - - if (graphics_application == 0) return 0; - + graphicsAppStartTime = 0; // Prevent triggering markAsIncompatible in HasProcessExited() // MUTEX may help prevent crashes when terminating an older gfx app which // we were displaying using CGWindowListCreateImage under OS X >= 10.13 // Also prevents reentry when called from our other thread pthread_mutex_lock(&saver_mutex); thePID = graphics_application; - // fprintf(stderr, "stopping pid %d\n", thePID); + if (in_terminate_v6_screensaver) { + pthread_mutex_unlock(&saver_mutex); + return 0; + } + + in_terminate_v6_screensaver = true; + // print_to_log_file( "stopping pid %d\n", thePID); rpc->run_graphics_app("stop", thePID, gUserName); // Inform our helper app that we have stopped current graphics app fprintf(m_gfx_Cleanup_IPC, "0\n"); fflush(m_gfx_Cleanup_IPC); - launchedGfxApp("", 0, -1); - for (int i=0; i<200; i++) { boinc_sleep(0.01); // Wait 2 seconds max if (HasProcessExited(graphics_application, ignore)) { break; } } + // For safety, call kill_process() even under Apple sandbox security + if (graphics_application) { + kill_process(graphics_application); + } + + launchedGfxApp("", "", 0, -1); + pthread_mutex_unlock(&saver_mutex); + in_terminate_v6_screensaver = false; #endif #ifdef _WIN32 @@ -377,10 +399,10 @@ int CScreensaver::terminate_v6_screensaver(PROCESS_REF graphics_application) { kill_process(graphics_application); } } -#endif // For safety, call kill_process() even under Apple sandbox security kill_process(graphics_application); +#endif return 0; } @@ -436,7 +458,7 @@ int CScreensaver::launch_default_screensaver(char *dir_path, PROCESS_REF& graphi fflush(m_gfx_Cleanup_IPC); if (graphics_application) { - launchedGfxApp("boincscr", graphics_application, -1); + launchedGfxApp("boincscr", "", graphics_application, -1); } BOINCTRACE(_T("launch_default_screensaver returned %d\n"), retval); @@ -540,6 +562,11 @@ DataMgmtProcType CScreensaver::DataManagementProc() { graphics_app_result_ptr = NULL; #ifdef __APPLE__ + for (int i = 0; i < m_vIncompatibleGfxApps.size(); i++) { + if (m_vIncompatibleGfxApps[i]) { + free(m_vIncompatibleGfxApps[i]); + } + } m_vIncompatibleGfxApps.clear(); default_ss_dir_path = "/Library/Application Support/BOINC Data"; char shmem_name[MAXPATHLEN]; @@ -551,6 +578,9 @@ DataMgmtProcType CScreensaver::DataManagementProc() { chmod(shmem_name, 0666); ss_shmem->gfx_pid = 0; ss_shmem->gfx_slot = -1; + ss_shmem->major_version = 0; + ss_shmem->minor_version = 0; + ss_shmem->release = 0; } if (!IsUserMemberOfGroup(gUserName, "boinc_master")) canAccessProjectGFXApps = false; @@ -680,11 +710,19 @@ DataMgmtProcType CScreensaver::DataManagementProc() { // BOINCTRACE(_T("CScreensaver::Ending Default phase: now=%f, default_phase_start_time=%f, default_saver_duration_in_science_phase=%f\n"), // dtime(), default_phase_start_time, default_saver_duration_in_science_phase); ss_phase = SCIENCE_SS_PHASE; - default_phase_start_time = 0; + default_phase_start_time = 0; default_saver_duration_in_science_phase = 0; science_phase_start_time = dtime(); if (m_bDefault_gfx_running) { default_saver_start_time_in_science_phase = science_phase_start_time; +#ifdef __APPLE__ + for (int i = 0; i < m_vIncompatibleGfxApps.size(); i++) { + if (m_vIncompatibleGfxApps[i]) { + free(m_vIncompatibleGfxApps[i]); + } + } + m_vIncompatibleGfxApps.clear(); +#endif } switch_to_default_gfx = false; } @@ -945,7 +983,7 @@ DataMgmtProcType CScreensaver::DataManagementProc() { m_bDefault_gfx_running = false; m_bScience_gfx_running = false; #ifdef __APPLE__ - launchedGfxApp("", 0, -1); + launchedGfxApp("", "", 0, -1); #endif continue; } @@ -976,6 +1014,12 @@ bool CScreensaver::HasProcessExited(pid_t pid, int &exitCode) { if (ss_shmem) { if (ss_shmem->gfx_pid != 0) return false; if (ss_shmem->gfx_slot > -1) { // -1 means Default GFX, which has no slot number + if (graphicsAppStartTime && ((getDTime() - graphicsAppStartTime) < 2)) { + if (graphics_app_result_ptr && graphics_app_result_ptr->graphics_exec_path) { + markAsIncompatible(graphics_app_result_ptr->wu_name); + + } + } // Graphics apps called by screensaver or Manager (via Show // Graphics button) now write files in their slot directory as // the logged in user, not boinc_master. This ugly hack tells @@ -983,6 +1027,9 @@ bool CScreensaver::HasProcessExited(pid_t pid, int &exitCode) { rpc->run_graphics_app("stop", ss_shmem->gfx_slot, ""); ss_shmem->gfx_pid = 0; ss_shmem->gfx_slot = -1; + ss_shmem->major_version = 0; + ss_shmem->minor_version = 0; + ss_shmem->release = 0; } } @@ -1034,3 +1081,22 @@ void CScreensaver::GetDefaultDisplayPeriods(struct ss_periods &periods) { periods.GFXChangePeriod ); } + + +#ifdef __APPLE__ +// compareBOINCLibVersionTo(x, y) returns: +// -1 if the library version is less than x.y.z +// 0 if the library version is equal to x.y.z +// +1 if the library version is lgreater than x.y +int compareBOINCLibVersionTo(int toMajor, int toMinor, int toRelease) { + if (ss_shmem->major_version < toMajor) return -1; + if (ss_shmem->major_version > toMajor) return 1; + // if (major == toMajor) compare minor version numbers + if (ss_shmem->minor_version < toMinor) return -1; + if (ss_shmem->minor_version > toMinor) return 1; + // if (minor == toMinor) compare release version numbers + if (ss_shmem->release < toRelease) return -1; + if (ss_shmem->release > toRelease) return 1; + return 0; +} +#endif diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/AddRemoveUser.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/AddRemoveUser.xcscheme new file mode 100644 index 00000000000..d036f154e94 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/AddRemoveUser.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/BOINC_Client.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/BOINC_Client.xcscheme new file mode 100644 index 00000000000..f91199fe1bc --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/BOINC_Client.xcscheme @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Build_All.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Build_All.xcscheme new file mode 100644 index 00000000000..45aa40fa2bf --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Build_All.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Install_BOINC.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Install_BOINC.xcscheme new file mode 100644 index 00000000000..1b193085990 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Install_BOINC.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/PostInstall.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/PostInstall.xcscheme new file mode 100644 index 00000000000..42d9fb35155 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/PostInstall.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/ScreenSaver.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/ScreenSaver.xcscheme new file mode 100644 index 00000000000..e6da73d4a9e --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/ScreenSaver.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/SetUpSecurity.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/SetUpSecurity.xcscheme new file mode 100644 index 00000000000..6eb989c2f18 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/SetUpSecurity.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/SetVersion.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/SetVersion.xcscheme new file mode 100644 index 00000000000..27f192ef3fa --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/SetVersion.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Uninstaller.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Uninstaller.xcscheme new file mode 100644 index 00000000000..98748230639 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/Uninstaller.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/api_libboinc.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/api_libboinc.xcscheme new file mode 100644 index 00000000000..9a60ce4e2ea --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/api_libboinc.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/boinc_finish_install.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/boinc_finish_install.xcscheme new file mode 100644 index 00000000000..1ded2fbec38 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/boinc_finish_install.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/boinc_opencl.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/boinc_opencl.xcscheme new file mode 100644 index 00000000000..9eca50f3362 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/boinc_opencl.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/cmd_boinc.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/cmd_boinc.xcscheme new file mode 100644 index 00000000000..331abb32ed1 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/cmd_boinc.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/detect_rosetta_cpu.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/detect_rosetta_cpu.xcscheme new file mode 100644 index 00000000000..3a079662001 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/detect_rosetta_cpu.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx2libboinc.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx2libboinc.xcscheme new file mode 100644 index 00000000000..c4055a6a4c7 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx2libboinc.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx_cleanup.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx_cleanup.xcscheme new file mode 100644 index 00000000000..ee41b731ea0 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx_cleanup.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx_switcher.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx_switcher.xcscheme new file mode 100644 index 00000000000..f8c17ab2e19 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/gfx_switcher.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/jpeg.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/jpeg.xcscheme new file mode 100644 index 00000000000..99a30bdf2b2 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/jpeg.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/libboinc.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/libboinc.xcscheme new file mode 100644 index 00000000000..f38c668051f --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/libboinc.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/mgr_boinc.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/mgr_boinc.xcscheme new file mode 100644 index 00000000000..8ea3f6be114 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/mgr_boinc.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/setprojectgrp.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/setprojectgrp.xcscheme new file mode 100644 index 00000000000..f0d48bef214 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/setprojectgrp.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/ss_app.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/ss_app.xcscheme new file mode 100644 index 00000000000..3b241c6ebc9 --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/ss_app.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/switcher.xcscheme b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/switcher.xcscheme new file mode 100644 index 00000000000..5364af9da8c --- /dev/null +++ b/mac_build/boinc.xcodeproj/xcshareddata/xcschemes/switcher.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mac_installer/PostInstall.cpp b/mac_installer/PostInstall.cpp index 131444f59ac..e9e058e4774 100644 --- a/mac_installer/PostInstall.cpp +++ b/mac_installer/PostInstall.cpp @@ -1,6 +1,6 @@ // This file is part of BOINC. // http://boinc.berkeley.edu -// Copyright (C) 2023 University of California +// Copyright (C) 2024 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License @@ -1678,12 +1678,11 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID) } } - // As of MacOS 14.0, the legacyScreenSaver sandbox prevents using - // IOSurfaceLookupFromMachPort. I have filed bug report FB13300491 - // with Apple and hope they will change this in a future MacOS. - // Also as of MacOS 14.0 Sonoma, we can't set the screensaver + // As of MacOS 14.0 Sonoma, we can't set the screensaver //automatically. I have filed bug report FB13270885 about this. - // See a;so the comment at top of SetScreenSaverSelection(). + // The response to my bug report is that it will be fixed in a + // future rlease of MacOS. + // See also the comment at top of SetScreenSaverSelection(). if (compareOSVersionTo(14, 0) < 0) { if (! saverAlreadySetForAll) { if (gCommandLineInstall) { @@ -2018,6 +2017,9 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID) // As of MacOS 14.0 Sonoma, this code no longer will detect the current screensaver, // and will need to be rewritten. See the comment at top of SetScreenSaverSelection(). +// It is unclear whether this will be fixed in a uture rlease of MacOS. +// This Applescript stoll works: +// tell application "System Events" to set mysaver to name of current screen saver OSErr GetCurrentScreenSaverSelection(passwd *pw, char *moduleName, size_t maxLen) { char buf[1024]; FILE *f;