볼랜드포럼에서 무대뽀님이 남겨준 팁 공유합니다.(작업한 내용 공유해주셔서 감사합니다^^)
무대뽀님께서 맥용 애플리케이션 개잘 중 맥의 스크린 세이버를 비활성화 시키는 질문을 볼랜드포럼에 올려서 간단히 댓글을 드렸더니 멋지게 기능을 완성하셨네요.(http://firemonkey.borlandforum.com/impboard/impboard.dll?action=read&db=firemonkey_qna&no=146)
제가 작성한 답변입니다.
맥 개발자 라이브러리에 아래와 같은 샘플이 있습니다.
https://developer.apple.com/library/mac/samplecode/SceneKitWWDC2014/Listings/Scene_Kit_Session_WWDC_2014_AAPLAppDelegate_m.html
그 중 아래 코드를 호출하면 됩니다.
IOPMAssertionID _assertionID;
- (void)disableDisplaySleeping {
CFStringRef reasonForActivity = CFSTR("Scene Kit Presentation");
IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &_assertionID);
}
- (void)enableDisplaySleeping {
if (_assertionID)
IOPMAssertionRelease(_assertionID);
}
위가 잠자는걸 막는 거고 아래는 막은걸 해지하는 겁니다.
위 메소드 들은 Macapi 중 IOKit에 구현되어 있습니다.(즉 맥의 라이브러리를 이용해야 한다는 거죠.)
아쉽게도 파이어몽키에 구현된 IOKit을 보면 구현된 API가 몇가지 안됩니다.
(C:\Program Files (x86)\Embarcadero\Studio\17.0\source\rtl\osx\Macapi.IOKit.pas)
위 문서와 애플 기술문서를 참고하셔서 필요한 API를 추가하시고 호출하는 코드를 작성해 보시기 바랍니다.
아래 애플 기술문서가 도움이 될것입니다.
https://developer.apple.com/library/mac/documentation/IOKit/Reference/IOPMLib_header_reference/#//apple_ref/c/econst/kIOPMAssertionLevelOn
위 내용을 참고로 Macapi.IOKit.pas에 필요한 메소드를 추가/확장했습니다.
기존의 유닛(C:\Program Files (x86)\Embarcadero\Studio\17.0\source\rtl\osx\Macapi.IOKit.pas)을 확장하기 위해서는 유닛파일(*.pas)를 복사 해 프로젝트 파일(*.dpr)과 같은 경로에 복사후 수정하면 프로젝트 파일과 같은 경로의 유닛을 먼저 참조합니다.
unit Macapi.IOKit ... const kIOMasterPortDefault: mach_port_t = 0; kIOPlatformUUIDKey = 'IOPlatformUUID'; // add kIOPMAssertionLevelOff = 0; kIOPMAssertionLevelOn = 255; kIOPMAssertionTypeNoDisplaySleep = 'NoDisplaySleepAssertion'; ... type ... function ... ... function IOObjectRelease(anObject: io_object_t): kern_return_t; cdecl; external libIOKit name _PU + 'IOObjectRelease'; // add // AssertionID는 Uint32의 포인터형 function IOPMAssertionCreateWithName(AssertionType : CFStringRef; AssertLevel : uint32_t; AssertionName : CFStringRef; AssertionID : uint32_t) : uint32_t; cdecl; external libIOKit name _PU + 'IOPMAssertionCreateWithName'; function IOPMAssertionRelease(AssertionID : uint32_t) : uint32_t; cdecl; external libIOKit name _PU + 'IOPMAssertionRelease';
추가한 API를 사용하는 코드는 아래와 같습니다. 버튼을 눌러 비활성화/활성화 시킵니다.
TForm1 = class(TForm) procedure BtnDisableClick(Sender: TObject); procedure BtnEnableClick(Sender: TObject); private FSleepAssert : UInt32; public end; implementation uses Macapi.IOKit, Macapi.CoreFoundation; ............ procedure TForm1.BtnDisableClick(Sender: TObject); begin FSleepAssert := 0; IOPMAssertionCreateWithName(CFSTR(kIOPMAssertionTypeNoDisplaySleep), kIOPMAssertionLevelOn, CFSTR('MyProject is Good'), FSleepAssert); if FSleepAssert = 0 then ShowMessage('Disable Failed!!'); end; procedure TForm1.BtnEnableClick(Sender: TObject); begin if FSleepAssert > 0 then IOPMAssertionRelease(@FSleepAssert); end;
다시한번 좋은 자료 공유해 주신 무대뽀님에게 감사인사를 전합니다.