diff --git a/client/hostinfo_unix.C b/client/hostinfo_unix.C index 7313974e2b..d5a6cdf3d0 100644 --- a/client/hostinfo_unix.C +++ b/client/hostinfo_unix.C @@ -71,6 +71,10 @@ using std::string; +#ifdef __APPLE__ +NXEventHandle gEventHandle; +#endif // __APPLE__ + // anyone know how to see if this host has physical network connection? // int get_connected_state() { @@ -580,6 +584,10 @@ bool HOST_INFO::users_idle(bool check_all_logins, double idle_time_to_run) { #ifdef HAVE__DEV_TTY1 && (check_all_logins || all_tty_idle(idle_time, device_tty, '1', 7)) #endif +#ifdef __APPLE__ + && (NXIdleTime(gEventHandle) > (60 * idle_time_to_run)) +#endif // __APPLE__ + ; } diff --git a/client/main.C b/client/main.C index 5264bcd62a..cfdacb3c83 100644 --- a/client/main.C +++ b/client/main.C @@ -140,6 +140,9 @@ void show_message(PROJECT *p, char* msg, int priority) { // and create an account file // int add_new_project() { +#if defined(__WXMAC__) // If we have a GUI BOINC Manager + return 0; +#else PROJECT project; printf("Enter the URL of the project: "); @@ -158,6 +161,7 @@ int add_new_project() { project.tentative = true; return project.write_account_file(); +#endif } #ifdef WIN32 @@ -418,6 +422,12 @@ int main(int argc, char** argv) { retval = boinc_main_loop(); } #else + +#ifdef __APPLE__ + // Initialize Mac OS X idle time measurement / idle detection + gEventHandle = NXOpenEventStatus(); +#endif // __APPLE__ + retval = boinc_main_loop(); #endif diff --git a/client/net_xfer.C b/client/net_xfer.C index 7a7e95da74..aa7cf56912 100644 --- a/client/net_xfer.C +++ b/client/net_xfer.C @@ -68,6 +68,26 @@ using std::vector; // in this many seconds, error out #define NET_XFER_TIMEOUT 600 +static void boinc_close_socket(int sock) { +#ifdef _WIN32 + closesocket(sock); +#else + close(sock); +#endif +} + +int get_socket_error(int fd) { + socklen_t intsize = sizeof(int); + int n; +#ifdef WIN32 + getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&n, &intsize); +#elif __APPLE__ + getsockopt(fd, SOL_SOCKET, SO_ERROR, &n, (int *)&intsize); +#else + getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&n, &intsize); +#endif + return n; +} int NET_XFER::get_ip_addr(int &ip_addr) { diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp index bb8ad5ef41..4d8435aae8 100644 --- a/clientgui/BOINCGUIApp.cpp +++ b/clientgui/BOINCGUIApp.cpp @@ -34,6 +34,9 @@ typedef void (CALLBACK* IdleTrackerTerm)(); typedef DWORD (CALLBACK* IdleTrackerGetIdleTickCount)(); #endif +#ifdef __WXMAC__ +#include +#endif IMPLEMENT_APP(CBOINCGUIApp) IMPLEMENT_DYNAMIC_CLASS(CBOINCGUIApp, wxApp) @@ -304,6 +307,43 @@ void CBOINCGUIApp::StartupBOINCCore() #endif +#ifdef __WXMAC__ + + { + wxChar buf[1024]; + bool success; + ProcessSerialNumber ourPSN; + FSRef ourFSRef; + OSErr err; + + // Set the current directory ahead of the application launch so the core + // client can find its files + wxExpandPath(buf, "~/Library/Application Support"); + strDirectory = wxT(buf); + success = ::wxSetWorkingDirectory( strDirectory ); + if (success) // If SetWD failed, don't create a directory in wrong place + success = wxMkdir( wxT("BOINC Data"), 0777); // Does nothing if dir exists + strDirectory += wxT("/BOINC Data"); + success = ::wxSetWorkingDirectory( strDirectory ); +// wxChar *wd = wxGetWorkingDirectory(buf, 1000); // For debugging + // Get the full path to core client inside this application's bundle + err = GetCurrentProcess (&ourPSN); + if (err == noErr) + err = GetProcessBundleLocation(&ourPSN, &ourFSRef); + if (err == noErr) + err = FSRefMakePath (&ourFSRef, (UInt8*)buf, sizeof(buf)); + if (err == noErr) + { + strExecute = wxT("\""); + strExecute += wxT(buf); + strExecute += wxT("/Contents/Resources/boinc_client\" -redirectio"); + } + else + buf[0] = '\0'; + } + +#else // ! __WXMAC__ + // We are only interested in the path component of the fully qualified path. wxFileName::SplitPath( szExecutableDirectory, &strDirectory, NULL, NULL ); @@ -311,6 +351,8 @@ void CBOINCGUIApp::StartupBOINCCore() // client can find its files ::wxSetWorkingDirectory( strDirectory ); +#endif // ! __WXMAC__ + #ifdef __WXMSW__ // Append boinc.exe to the end of the strExecute string and get ready to rock @@ -347,11 +389,16 @@ void CBOINCGUIApp::StartupBOINCCore() #else +#ifndef __WXMAC__ + // Append boinc.exe to the end of the strExecute string and get ready to rock strExecute += wxT("/boinc"); + +#endif // ! __WXMAC__ + m_lBOINCCoreProcessId = ::wxExecute( strExecute ); -#endif +#endif // ! __WXMSW__ if ( 0 != m_lBOINCCoreProcessId ) m_bBOINCStartedByManager = true; diff --git a/lib/hostinfo.h b/lib/hostinfo.h index d8b0186df3..8aacd4d665 100644 --- a/lib/hostinfo.h +++ b/lib/hostinfo.h @@ -74,4 +74,19 @@ struct HOST_INFO { extern HINSTANCE g_hIdleDetectionDll; // handle to DLL for user idle #endif +#ifdef __APPLE__ +#ifdef __cplusplus +extern "C" { +#endif +#include +typedef mach_port_t NXEventHandle; +NXEventHandle NXOpenEventStatus(void); +extern double NXIdleTime(NXEventHandle handle); +#ifdef __cplusplus +} // extern "C" +#endif + +extern NXEventHandle gEventHandle; +#endif + #endif diff --git a/mac_build/boinc.pbproj.zip b/mac_build/boinc.pbproj.zip new file mode 100644 index 0000000000..95fcf744fe Binary files /dev/null and b/mac_build/boinc.pbproj.zip differ