14#include <Cocoa/Cocoa.h>
31#ifdef MAC_OS_X_VERSION_10_12
63 NSEvent* stopEvent = [
NSEvent otherEventWithType : ROOT::MacOSX::Details::kApplicationDefined
64 location : NSMakePoint(0., 0.) modifierFlags : 0 timestamp : 0.
65 windowNumber : 0 context : nil subtype: 0 data1 : 0 data2 : 0];
66 [
NSApp postEvent : stopEvent atStart : true];
79# define HOWMANY(x, y) (((x)+((y)-1))/(y))
153 void SetFileDescriptor(
int fd, DescriptorType fdType);
171 const int nativeFD = CFFileDescriptorGetNativeDescriptor(fdref);
177 CFFileDescriptorInvalidate(fdref);
180 NSEvent *fdEvent = [
NSEvent otherEventWithType : kApplicationDefined
181 location : NSMakePoint(0, 0) modifierFlags : 0
182 timestamp: 0. windowNumber : 0 context : nil
183 subtype : 0 data1 : nativeFD data2 : 0];
184 [
NSApp postEvent : fdEvent atStart : NO];
191 const int nativeFD = CFFileDescriptorGetNativeDescriptor(fdref);
197 CFFileDescriptorInvalidate(fdref);
200 NSEvent *fdEvent = [
NSEvent otherEventWithType : kApplicationDefined
201 location : NSMakePoint(0, 0) modifierFlags : 0
202 timestamp: 0. windowNumber : 0 context : nil
203 subtype : 0 data1 : nativeFD data2 : 0];
204 [
NSApp postEvent : fdEvent atStart : NO];
214 assert(
fgInstance == 0 &&
"MacOSXSystem, fgInstance was initialized already");
228 assert(
fCocoaInitialized ==
false &&
"InitializeCocoa, Cocoa was initialized already");
243 assert(fileHandlers != 0 &&
"SetFileDescriptors, parameter 'fileHandlers' is null");
249 TIter next(fileHandlers);
251 assert(handler->GetFd() != -1 &&
"SetFileDescriptors, invalid file descriptor");
253 if (handler->HasReadInterest())
256 if (handler->HasWriteInterest())
259 }
catch (
const std::exception &) {
274 assert(fdIter !=
fCFFileDescriptors.end() &&
"InvalidateFileDescriptor, file descriptor was not found");
282 assert(
fCocoaInitialized ==
true &&
"CloseFileDescriptors, Cocoa was not initialized");
286 for (; fdIter != end; ++fdIter) {
287 CFFileDescriptorInvalidate(*fdIter);
298 assert(
fCocoaInitialized ==
true &&
"SetFileDescriptors, Cocoa was not initialized");
300 assert(fd != -1 &&
"SetFileDescriptor, invalid file descriptor");
302 const bool read = fdType ==
kDTRead;
303 CFFileDescriptorRef fdref = CFFileDescriptorCreate(kCFAllocatorDefault, fd,
false,
307 throw std::runtime_error(
"MacOSXSystem::SetFileDescriptors: CFFileDescriptorCreate failed");
309 CFFileDescriptorEnableCallBacks(fdref, read ? kCFFileDescriptorReadCallBack : kCFFileDescriptorWriteCallBack);
310 CFRunLoopSourceRef runLoopSource = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, fdref, 0);
312 if (!runLoopSource) {
314 throw std::runtime_error(
"MacOSXSystem::SetFileDescriptors: CFFileDescriptorCreateRunLoopSource failed");
317 CFRunLoopAddSource(CFRunLoopGetMain(), runLoopSource, kCFRunLoopDefaultMode);
318 CFRelease(runLoopSource);
359 Bool_t pollOnce = pendingOnly;
385 if (pendingOnly && !pollOnce)
391 if (!pendingOnly)
return;
446 fPimpl->InitializeCocoa();
460 [
stopper.
Get() performSelector : @selector(stopRun) withObject : nil afterDelay : 0.05];
469 assert(
fCocoaInitialized ==
true &&
"ProcessPendingEvents, called while Cocoa was not initialized");
471 bool processed =
false;
473 untilDate : nil inMode : NSDefaultRunLoopMode dequeue : YES]) {
474 [
NSApp sendEvent : event];
485 assert(
fCocoaInitialized ==
true &&
"WaitEvents, called while Cocoa was not initialized");
489 Fatal(
"WaitForAllEvents",
"SetFileDesciptors failed");
492 NSDate *untilDate = nil;
494 untilDate = [
NSDate dateWithTimeIntervalSinceNow : nextto / 1000.];
496 untilDate = [
NSDate distantFuture];
502 NSEvent *
event = [
NSApp nextEventMatchingMask : Private::kEventMaskAny
503 untilDate : untilDate inMode : NSDefaultRunLoopMode dequeue : YES];
508 [
NSApp sendEvent : event];
512 untilDate : nil inMode : NSDefaultRunLoopMode dequeue : YES]))
517 [
NSApp sendEvent : event];
520 fPimpl->CloseFileDescriptors();
530 if (fh->
GetFd() == -1)
531 Error(
"AddFileHandler",
"invalid file descriptor");
553 "ProcessApplicationDefinedEvent, called while Cocoa was not initialized");
556 assert(event != nil &&
557 "ProcessApplicationDefinedEvent, event parameter is nil");
559 "ProcessApplicationDefinedEvent, event parameter has wrong type");
561 bool descriptorFound =
false;
565 descriptorFound =
true;
570 descriptorFound =
true;
573 if (!descriptorFound) {
574 Error(
"ProcessApplicationDefinedEvent",
"file descriptor %d was not found",
int(event.data1));
int Int_t
Signed integer 4 bytes (int).
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
bool Bool_t
Boolean (0=false, 1=true) (bool).
@ kItimerResolution
interval-timer resolution in ms (used for TThread, TTimer, Emit, Connect, etc.)
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
externTFileHandler * gXDisplay
void SetFileDescriptor(int fd, DescriptorType fdType)
void UnregisterFileDescriptor(CFFileDescriptorRef fd)
std::set< CFFileDescriptorRef > fCFFileDescriptors
ROOT::MacOSX::Util::AutoreleasePool fPool
bool SetFileDescriptors(const TSeqCollection *fileHandlers)
void CloseFileDescriptors()
static MacOSXSystem * fgInstance
TFdSet & operator=(const TFdSet &rhs)
ULong_t fds_bits[(((kFDSETSIZE)+((kNFDBITS) -1))/(kNFDBITS))]
TFdSet(const TFdSet &org)
bool ProcessPendingEvents()
void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
void WaitEvents(Long_t nextto)
bool CocoaInitialized() const
void DispatchOneEvent(Bool_t pendingOnly)
Dispatch a single event.
TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
void ProcessApplicationDefinedEvent(void *event)
std::unique_ptr< ROOT::MacOSX::Details::MacOSXSystem > fPimpl
!
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Sequenceable collection abstract base class.
TSeqCollection * fFileHandler
TFdSet * fReadmask
!Files that should be checked for read events
virtual Long_t NextTimeOut(Bool_t mode)
Time when next timer of mode (synchronous=kTRUE or asynchronous=kFALSE) will time-out (in ms).
TFdSet * fWritemask
!Files that should be checked for write events
TFdSet * fSignals
!Signals that were trapped
TFdSet * fWriteready
!Files with writes waiting
TSeqCollection * fSignalHandler
TFdSet * fReadready
!Files with reads waiting
Bool_t CheckSignals(Bool_t sync)
Check if some signals were raised and call their Notify() member.
void DispatchOneEvent(Bool_t pendingOnly=kFALSE) override
Dispatch a single event.
Bool_t DispatchTimers(Bool_t mode)
Handle and dispatch timers.
TFileHandler * RemoveFileHandler(TFileHandler *fh) override
Remove a file handler from the list of file handlers.
void AddFileHandler(TFileHandler *fh) override
Add a file handler to the list of system file handlers.
Bool_t CheckDescriptors()
Check if there is activity on some file descriptors and call their Notify() member.
const NSEventType kApplicationDefined
void TMacOSXSystem_ReadCallback(CFFileDescriptorRef fdref, CFOptionFlags, void *)
const NSUInteger kEventMaskAny
void TMacOSXSystem_WriteCallback(CFFileDescriptorRef fdref, CFOptionFlags, void *)