Пример #1
0
void
MySleepCallBack( void * refCon, io_service_t service, natural_t messageType, void * messageArgument )
{
    switch ( messageType )
    {
 
        case kIOMessageCanSystemSleep:
            IOAllowPowerChange( root_port, (long)messageArgument );
            break;
 
        case kIOMessageSystemWillSleep:
            IOAllowPowerChange( root_port, (long)messageArgument );
            break;
 
        case kIOMessageSystemWillPowerOn:
            break;
 
        case kIOMessageSystemHasPoweredOn:
            break;
 
        default:
            break;
 
    }
    callscripts( messageType);
}
void systemEventCallback(void* refCon,
                         io_service_t service,
                         natural_t messageType,
                         void* messageArgument) {
    Event event;
    switch (messageType) {
        case kIOMessageCanSystemSleep:
            event = SystemEventsManager::getEvent(SYSTEM_SLEEP);

			if (event.isPrevented()) {
				IOCancelPowerChange(rootPort, (long)messageArgument);
			} else {
				if (event.isRegistered())
					SystemEventsManager::executeCallback(event.getCallback());
				IOAllowPowerChange(rootPort, (long)messageArgument);
			}
            break;
        case kIOMessageSystemWillSleep:
            IOAllowPowerChange(rootPort, (long)messageArgument);
            break;
        case kIOMessageSystemWillPowerOn:
            break;
        case kIOMessageSystemHasPoweredOn:
            event = SystemEventsManager::getEvent(SYSTEM_WAKE);
            if (event.isRegistered())
                SystemEventsManager::executeCallback(event.getCallback());
            break;
        default:
            break;
    }
}
void sleepCallBack(void* systemWatch, io_service_t, natural_t messageType, void * messageArgument)
{
    //printf("messageType %08lx, arg %08lx\n",
    //  (long unsigned int)messageType, (long unsigned int)messageArgument);

    MacSystemWatch* macSystemWatch = static_cast<MacSystemWatch*>(systemWatch);
    switch (messageType) {
    case kIOMessageSystemWillSleep:
        // Sleep
        macSystemWatch->emitSleep();
        IOAllowPowerChange(root_port, (long)messageArgument);
        break;

    case kIOMessageCanSystemSleep:
        // Idle time sleep

        // TODO: Check if file transfers are running, and don't go to sleep
        // if there are.
        //IOCancelPowerChange(root_port, (long)messageArgument);

        macSystemWatch->emitIdleSleep();
        IOAllowPowerChange(root_port, (long)messageArgument);
        break;

    case kIOMessageSystemHasPoweredOn:
        // Wakeup
        macSystemWatch->emitWakeup();
        break;
    }
}
Пример #4
0
    void callback(io_service_t service, natural_t messageType, void *messageArgument)
    {
      switch (messageType)
	{
        case kIOMessageCanSystemSleep:
	  IOAllowPowerChange(root_port, (long)messageArgument);
	  break;
        case kIOMessageSystemWillSleep:
	  notify_sleep();
	  IOAllowPowerChange(root_port, (long)messageArgument);
	  break;
	case kIOMessageSystemHasPoweredOn:
	  notify_wakeup();
	  break;
	}
    }
Пример #5
0
void
COSXScreen::handlePowerChangeRequest(natural_t messageType, void* messageArg)
{
	// we've received a power change notification
	switch (messageType) {
	case kIOMessageSystemWillSleep:
		// COSXScreen has to handle this in the main thread so we have to
		// queue a confirm sleep event here.  we actually don't allow the
		// system to sleep until the event is handled.
		m_events->addEvent(CEvent(m_events->forCOSXScreen().confirmSleep(),
								getEventTarget(), messageArg,
								CEvent::kDontFreeData));
		return;
			
	case kIOMessageSystemHasPoweredOn:
		LOG((CLOG_DEBUG "system wakeup"));
		m_events->addEvent(CEvent(m_events->forIScreen().resume(),
								getEventTarget()));
		break;

	default:
		break;
	}

	CLock lock(m_pmMutex);
	if (m_pmRootPort != 0) {
		IOAllowPowerChange(m_pmRootPort, (long)messageArg);
	}
}
Пример #6
0
void powerCallback (void *rootPort, io_service_t y, natural_t msgType, void *msgArgument)
{
	int	result;
	char	*s;

/*
	fprintf (stderr, "powerCallback: message_type %08lx, arg %08lx\n",
		(long unsigned int) msgType, (long  unsigned int) msgArgument);
*/
	switch (msgType) {
	case kIOMessageCanSystemSleep :
		if (args.allowsleepcommand == NULL) {
			result = 0;
			message (LOG_INFO, "allow sleep\n");
		} else if (args.allowsleepcommand == DENY_SLEEP) {
			result = -1;
			message (LOG_INFO, "deny sleep\n");
		} else {
			result = system(args.allowsleepcommand);
			s = (! WIFEXITED(result) || WEXITSTATUS(result)) ? "deny" : "allow";
			message (LOG_INFO, "%s sleep: %s: exit=%s status=%d\n", s, args.allowsleepcommand,
				WIFEXITED(result) ? "ok" : "err", WEXITSTATUS(result));
			result = ! WIFEXITED(result) || WEXITSTATUS(result);
		}
		if (result)
			IOCancelPowerChange (* (io_connect_t *) rootPort, (long) msgArgument);
		else
			IOAllowPowerChange (* (io_connect_t *) rootPort, (long) msgArgument);
		break;
	case kIOMessageSystemWillSleep :
		if (args.sleepcommand)
			message (LOG_INFO, "sleep: %s: %d\n", args.sleepcommand, system(args.sleepcommand));
		IOAllowPowerChange (* (io_connect_t *) rootPort, (long) msgArgument);
		break;
	case kIOMessageSystemWillNotSleep :
		if (args.cantsleepcommand)
			message (LOG_INFO, "can't sleep: %s: %d\n", args.cantsleepcommand, system(args.cantsleepcommand));
		else
			message (LOG_INFO, "can't sleep\n");
		break;
	case kIOMessageSystemHasPoweredOn :
		setupIdleTimer ();
		if (args.wakeupcommand)
			message (LOG_INFO, "wakeup: %s: %d\n", args.wakeupcommand, system(args.wakeupcommand));
		break;
	}
}
Пример #7
0
void HostPowerServiceDarwin::powerChangeNotificationHandler(void *pvData, io_service_t /* service */, natural_t messageType, void *pMessageArgument)
{
    HostPowerServiceDarwin *pPowerObj = static_cast<HostPowerServiceDarwin *>(pvData);
    Log(( "powerChangeNotificationHandler: messageType %08lx, arg %08lx\n", (long unsigned int)messageType, (long unsigned int)pMessageArgument));

    switch (messageType)
    {
        case kIOMessageCanSystemSleep:
            {
                /* Idle sleep is about to kick in. This message will not be
                 * sent for forced sleep. Applications have a chance to prevent
                 * sleep by calling IOCancelPowerChange. Most applications
                 * should not prevent idle sleep. Power Management waits up to
                 * 30 seconds for you to either allow or deny idle sleep. If
                 * you don't acknowledge this power change by calling either
                 * IOAllowPowerChange or IOCancelPowerChange, the system will
                 * wait 30 seconds then go to sleep. */
                IOAllowPowerChange(pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument));
                break;
            }
        case kIOMessageSystemWillSleep:
            {
                /* The system will go for sleep. */
                pPowerObj->notify(Reason_HostSuspend);
                /* If you do not call IOAllowPowerChange or IOCancelPowerChange to
                 * acknowledge this message, sleep will be delayed by 30 seconds.
                 * NOTE: If you call IOCancelPowerChange to deny sleep it returns
                 * kIOReturnSuccess, however the system WILL still go to sleep. */
                IOAllowPowerChange(pPowerObj->mRootPort, reinterpret_cast<long>(pMessageArgument));
                break;
            }
        case kIOMessageSystemWillPowerOn:
            {
                /* System has started the wake up process. */
                break;
            }
        case kIOMessageSystemHasPoweredOn:
            {
                /* System has finished the wake up process. */
                pPowerObj->notify(Reason_HostResume);
                break;
            }
        default:
            break;
    }
}
Пример #8
0
void
cupsdAllowSleep(void)
{
  cupsdCleanDirty();

  IOAllowPowerChange(LastSysEvent.powerKernelPort,
		     LastSysEvent.powerNotificationID);
}
Пример #9
0
void SleepCallBack(void* refCon, io_service_t service, natural_t messageType, void* messageArgument)
{
    char* msg;

    switch (messageType) {

        case kIOMessageCanSystemSleep:
            /* Idle sleep is about to kick in. This message will not be sent for forced sleep.
                Applications have a chance to prevent sleep by calling IOCancelPowerChange.
                Most applications should not prevent idle sleep.

                Power Management waits up to 30 seconds for you to either allow or deny idle
                sleep. If you don't acknowledge this power change by calling either
                IOAllowPowerChange or IOCancelPowerChange, the system will wait 30
                seconds then go to sleep.
            */

            IOAllowPowerChange(root_port, (long)messageArgument);
            break;

        case kIOMessageSystemWillSleep:
            /* The system WILL go to sleep. If you do not call IOAllowPowerChange or
                IOCancelPowerChange to acknowledge this message, sleep will be
                delayed by 30 seconds.

                NOTE: If you call IOCancelPowerChange to deny sleep it returns
                kIOReturnSuccess, however the system WILL still go to sleep.
            */
            write(1, WEESLEEP_SUSPENDING, strlen(WEESLEEP_SUSPENDING));
            IOAllowPowerChange(root_port, (long)messageArgument);
            break;

        case kIOMessageSystemWillPowerOn:
            //System has started the wake up process...
            break;

        case kIOMessageSystemHasPoweredOn:
            write(1, WEESLEEP_WAKINGUP, strlen(WEESLEEP_WAKINGUP));
            //System has finished waking up...
        break;

        default:
            break;
    }
}
Пример #10
0
void
cupsdAllowSleep(void)
{
  cupsdCleanDirty();

  cupsdLogMessage(CUPSD_LOG_DEBUG, "Allowing system sleep.");
  IOAllowPowerChange(LastSysEvent.powerKernelPort,
		     LastSysEvent.powerNotificationID);
}
Пример #11
0
void CCocoaPowerSyscall::OSPowerCallBack(void *refcon, io_service_t service, natural_t msg_type, void *msg_arg)
{
#if !defined(TARGET_DARWIN_IOS)
  CCocoaAutoPool autopool;
  CCocoaPowerSyscall  *ctx;
  
  ctx = (CCocoaPowerSyscall*)refcon;

  switch (msg_type)
  {
    case kIOMessageCanSystemSleep:
      // System has been idle for sleeptime and will sleep soon.
      // we can either allow or cancel this notification.
      // if we don't respond, OS will sleep in 30 second.
      ctx->m_OnSuspend = true;
      IOAllowPowerChange(ctx->m_root_port, (long)msg_arg);
      //CLog::Log(LOGDEBUG, "%s - kIOMessageCanSystemSleep", __FUNCTION__);
    break;
    case kIOMessageSystemWillSleep:
      // System demanded sleep from:
      //   1) selecting sleep from the Apple menu.
      //   2) closing the lid of a laptop.
      //   3) running out of battery power.
      ctx->m_OnSuspend = true;
      // force processing of this power event. This callback runs
      // in main thread so we can do this.
      g_powerManager.ProcessEvents();
      IOAllowPowerChange(ctx->m_root_port, (long)msg_arg);
      //CLog::Log(LOGDEBUG, "%s - kIOMessageSystemWillSleep", __FUNCTION__);
      // let XBMC know system will sleep
      // TODO:
    break;
    case kIOMessageSystemHasPoweredOn:
      // System has awakened from sleep.
      // let XBMC know system has woke
      // TODO:
      ctx->m_OnResume = true;
      //CLog::Log(LOGDEBUG, "%s - kIOMessageSystemHasPoweredOn", __FUNCTION__);
    break;
	}
#endif
}
Пример #12
0
static void powerCallback (void *args, io_service_t y, natural_t msgType, void *msgArgument)
{
    PyGILState_STATE gstate;

    gstate = PyGILState_Ensure();

    switch (msgType)
    {
        case kIOMessageCanSystemSleep:
	    IOAllowPowerChange (((PyPowerObserver *)args)->rootPort, (long) msgArgument);
	    break;
        case kIOMessageSystemWillSleep:
	    PyObject_CallMethod((PyObject *)args, "PowerNotification", "i", POWEROFF);
	    IOAllowPowerChange (((PyPowerObserver *)args)->rootPort, (long) msgArgument);
	    break;
        case kIOMessageSystemHasPoweredOn:
	    PyObject_CallMethod((PyObject *)args, "PowerNotification", "i", POWERON);
	    break;
    }

    PyGILState_Release(gstate);
}
Пример #13
0
static void iokit_handle_notifications(void *opaque, io_service_t service,
                                       uint32_t message_type, void *message_argument) {
	io_connect_t *root_port = opaque;
	uint8_t byte = 0;

	(void)service;

	switch (message_type) {
	case kIOMessageCanSystemSleep:
		IOAllowPowerChange(*root_port, (long)message_argument);

		break;

	case kIOMessageSystemWillSleep:
		IOAllowPowerChange(*root_port, (long)message_argument);

		log_debug("Received IOKit sleep notification");

		break;

	case kIOMessageSystemWillPowerOn:
		break;

	case kIOMessageSystemHasPoweredOn:
		log_debug("Received IOKit wakeup notification");

		if (pipe_write(&_notification_pipe, &byte, sizeof(byte)) < 0) {
			log_error("Could not write to notification pipe: %s (%d)",
			          get_errno_name(errno), errno);
		}

		break;

	default:
		break;
	}
}
Пример #14
0
/* Callback function to power notifications */
void PowerCallBack(void* refCon, io_service_t service, natural_t messageType, void * messageArgument)
{
	/* printf( "messageType %08lx, arg %08lx\n",
            (long unsigned int)messageType,
            (long unsigned int)messageArgument ); */
			
	switch (messageType) {
		case kIOMessageSystemHasPoweredOn:                                                                                     /* System is waking up */
			CFRunLoopStop(CFRunLoopGetCurrent());                                                                                 /* Stop the loop in main() */
			break;
		case kIOMessageSystemWillSleep:                                                                                        /* System is going to sleep */
			if (!mute) printf("System is going down to sleep...\n");
			IOAllowPowerChange(root_power_port, (long)messageArgument);                                                           /* Allow the sleep operation */
			break;
	}                                                                         
}
Пример #15
0
void
COSXScreen::handleConfirmSleep(const CEvent& event, void*)
{
	long messageArg = (long)event.getData();
	if (messageArg != 0) {
		CLock lock(m_pmMutex);
		if (m_pmRootPort != 0) {
			// deliver suspend event immediately.
			m_events->addEvent(CEvent(m_events->forIScreen().suspend(),
									getEventTarget(), NULL, 
									CEvent::kDeliverImmediately));
	
			LOG((CLOG_DEBUG "system will sleep"));
			IOAllowPowerChange(m_pmRootPort, messageArg);
		}
	}
}
Пример #16
0
static void
sysEventPowerNotifier(
    void         *context,		/* I - Thread context data */
    io_service_t service,		/* I - Unused service info */
    natural_t    messageType,		/* I - Type of message */
    void         *messageArgument)	/* I - Message data */
{
  int			sendit = 1;	/* Send event to main thread?    *
					 * (0 = no, 1 = yes, 2 = delayed */
  cupsd_thread_data_t	*threadData;	/* Thread context data */


  threadData = (cupsd_thread_data_t *)context;

  (void)service;			/* anti-compiler-warning-code */

  switch (messageType)
  {
    case kIOMessageCanSystemPowerOff:
    case kIOMessageCanSystemSleep:
	threadData->sysevent.event |= SYSEVENT_CANSLEEP;
	break;

    case kIOMessageSystemWillRestart:
    case kIOMessageSystemWillPowerOff:
    case kIOMessageSystemWillSleep:
	threadData->sysevent.event |= SYSEVENT_WILLSLEEP;
	break;

    case kIOMessageSystemHasPoweredOn:
       /*
	* Because powered on is followed by a net-changed event, delay
	* before sending it.
	*/

        sendit = 2;
	threadData->sysevent.event |= SYSEVENT_WOKE;
	break;

    case kIOMessageSystemWillNotPowerOff:
    case kIOMessageSystemWillNotSleep:
#  ifdef kIOMessageSystemWillPowerOn
    case kIOMessageSystemWillPowerOn:
#  endif /* kIOMessageSystemWillPowerOn */
    default:
	sendit = 0;
	break;
  }

  if (sendit == 0)
    IOAllowPowerChange(threadData->sysevent.powerKernelPort,
                       (long)messageArgument);
  else
  {
    threadData->sysevent.powerNotificationID = (long)messageArgument;

    if (sendit == 1)
    {
     /*
      * Send the event to the main thread now.
      */

      write(SysEventPipes[1], &threadData->sysevent,
	    sizeof(threadData->sysevent));
      threadData->sysevent.event = 0;
    }
    else
    {
     /*
      * Send the event to the main thread after 1 to 2 seconds.
      */

      CFRunLoopTimerSetNextFireDate(threadData->timerRef,
                                    CFAbsoluteTimeGetCurrent() + 2);
    }
  }
}
Пример #17
0
//
// The callback dispatcher
//
void IOPowerWatcher::ioCallback(void *refCon, io_service_t service,
    natural_t messageType, void *argument)
{
    IOPowerWatcher *me = (IOPowerWatcher *)refCon;
    enum { allow, refuse, ignore } reaction;
    switch (messageType) {
    case kIOMessageSystemWillSleep:
        secdebug("powerwatch", "system will sleep");
        me->systemWillSleep();
        reaction = allow;
        break;
    case kIOMessageSystemHasPoweredOn:
        secdebug("powerwatch", "system has powered on");
        me->systemIsWaking();
        reaction = ignore;
        break;
    case kIOMessageSystemWillPowerOff:
        secdebug("powerwatch", "system will power off");
        me->systemWillPowerDown();
        reaction = allow;
        break;
    case kIOMessageSystemWillNotPowerOff:
        secdebug("powerwatch", "system will not power off");
        reaction = ignore;
        break;
    case kIOMessageCanSystemSleep:
        secdebug("powerwatch", "can system sleep");
        reaction = allow;
        break;
    case kIOMessageSystemWillNotSleep:
        secdebug("powerwatch", "system will not sleep");
        reaction = ignore;
        break;
    case kIOMessageCanSystemPowerOff:
        secdebug("powerwatch", "can system power off");
        reaction = allow;
        break;
	case kIOMessageSystemWillPowerOn:
        secdebug("powerwatch", "system will power on");
		me->systemWillPowerOn();
        reaction = ignore;
        break;
    default:
        secdebug("powerwatch",
            "type 0x%x message received (ignored)", messageType);
        reaction = ignore;
        break;
    }
    
    // handle acknowledgments
    switch (reaction) {
    case allow:
		secdebug("powerwatch", "calling IOAllowPowerChange");
        IOAllowPowerChange(me->mKernelPort, long(argument));
        break;
    case refuse:
		secdebug("powerwatch", "calling IOCancelPowerChange");
        IOCancelPowerChange(me->mKernelPort, long(argument));
        break;
    case ignore:
		secdebug("powerwatch", "sending no response");
        break;
    }
}
Пример #18
0
static void
sysUpdate(void)
{
  int			i;		/* Looping var */
  cupsd_sysevent_t	sysevent;	/* The system event */
  cupsd_printer_t	*p;		/* Printer information */


 /*
  * Drain the event pipe...
  */

  while (read((int)SysEventPipes[0], &sysevent, sizeof(sysevent))
             == sizeof(sysevent))
  {
    if (sysevent.event & SYSEVENT_CANSLEEP)
    {
     /*
      * If there are active printers that don't have the connecting-to-device
      * printer-state-reason then cancel the sleep request (i.e. this reason
      * indicates a job that is not yet connected to the printer)...
      */

      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
           p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
      {
        if (p->job)
        {
	  for (i = 0; i < p->num_reasons; i ++)
	    if (!strcmp(p->reasons[i], "connecting-to-device"))
	      break;

	  if (!p->num_reasons || i >= p->num_reasons)
	    break;
        }
      }

      if (p)
      {
        cupsdLogMessage(CUPSD_LOG_INFO,
	                "System sleep canceled because printer %s is active",
	                p->name);
        IOCancelPowerChange(sysevent.powerKernelPort,
	                    sysevent.powerNotificationID);
      }
      else
      {
	cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep");
        IOAllowPowerChange(sysevent.powerKernelPort,
	                   sysevent.powerNotificationID);
      }
    }

    if (sysevent.event & SYSEVENT_WILLSLEEP)
    {
      cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep");

      Sleeping = 1;

      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
           p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
      {
	if (p->type & CUPS_PRINTER_DISCOVERED)
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
	                  "Deleting remote destination \"%s\"", p->name);
	  cupsArraySave(Printers);
	  cupsdDeletePrinter(p, 0);
	  cupsArrayRestore(Printers);
	}
	else
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
	                  "Deregistering local printer \"%s\"", p->name);
	  cupsdDeregisterPrinter(p, 0);
	}
      }

      cupsdCleanDirty();

     /*
      * If we have no printing jobs, allow the power change immediately.
      * Otherwise set the SleepJobs time to 15 seconds in the future when
      * we'll take more drastic measures...
      */

      if (cupsArrayCount(PrintingJobs) == 0)
	IOAllowPowerChange(sysevent.powerKernelPort,
			   sysevent.powerNotificationID);
      else
      {
        LastSysEvent = sysevent;
        SleepJobs    = time(NULL) + 15;
      }
    }

    if (sysevent.event & SYSEVENT_WOKE)
    {
      cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep");
      IOAllowPowerChange(sysevent.powerKernelPort,
                         sysevent.powerNotificationID);
      Sleeping = 0;
      cupsdCheckJobs();
    }

    if (sysevent.event & SYSEVENT_NETCHANGED)
    {
      if (!Sleeping)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "System network configuration changed");

       /*
        * Resetting browse_time before calling cupsdSendBrowseList causes
	* browse packets to be sent for local shared printers.
        */

	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	     p;
	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
	  p->browse_time = 0;

        cupsdSendBrowseList();
	cupsdRestartPolling();
      }
      else
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "System network configuration changed; "
			"ignored while sleeping");
    }

    if (sysevent.event & SYSEVENT_NAMECHANGED)
    {
      if (!Sleeping)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Computer name or BTMM domains changed");

       /*
	* De-register the individual printers...
	*/

	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	     p;
	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
	  cupsdDeregisterPrinter(p, 1);

       /*
        * Update the computer name and BTMM domain list...
	*/

	cupsdUpdateDNSSDName();

       /*
	* Now re-register them...
	*/

	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	     p;
	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
	{
	  p->browse_time = 0;
	  cupsdRegisterPrinter(p);
	}
      }
      else
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Computer name or BTMM domains changed; ignored while "
			"sleeping");
    }
  }
}
Пример #19
0
static void
sysUpdate(void)
{
  int			i;		/* Looping var */
  cupsd_sysevent_t	sysevent;	/* The system event */
  cupsd_printer_t	*p;		/* Printer information */


 /*
  * Drain the event pipe...
  */

  while (read((int)SysEventPipes[0], &sysevent, sizeof(sysevent))
             == sizeof(sysevent))
  {
    if (sysevent.event & SYSEVENT_CANSLEEP)
    {
     /*
      * If there are active printers that don't have the connecting-to-device
      * printer-state-reason then cancel the sleep request (i.e. this reason
      * indicates a job that is not yet connected to the printer)...
      */

      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
           p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
      {
        if (p->job)
        {
	  for (i = 0; i < p->num_reasons; i ++)
	    if (!strcmp(p->reasons[i], "connecting-to-device"))
	      break;

	  if (!p->num_reasons || i >= p->num_reasons)
	    break;
        }
      }

      if (p)
      {
        cupsdLogMessage(CUPSD_LOG_INFO,
	                "System sleep canceled because printer %s is active",
	                p->name);
        IOCancelPowerChange(sysevent.powerKernelPort,
	                    sysevent.powerNotificationID);
      }
      else
      {
	cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep");
        IOAllowPowerChange(sysevent.powerKernelPort,
	                   sysevent.powerNotificationID);
      }
    }

    if (sysevent.event & SYSEVENT_WILLSLEEP)
    {
      cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep");

      Sleeping = 1;

      for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
           p;
	   p = (cupsd_printer_t *)cupsArrayNext(Printers))
      {
	cupsdLogMessage(CUPSD_LOG_DEBUG,
			"Deregistering local printer \"%s\"", p->name);
	cupsdDeregisterPrinter(p, 0);
      }

      cupsdCleanDirty();

#ifdef kIOPMAssertionTypeDenySystemSleep
     /*
      * Remove our assertion as needed since the user wants the system to
      * sleep (different than idle sleep)...
      */

      if (dark_wake)
      {
	cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing dark wake assertion.");
	IOPMAssertionRelease(dark_wake);
	dark_wake = 0;
      }
#endif /* kIOPMAssertionTypeDenySystemSleep */

     /*
      * If we have no printing jobs, allow the power change immediately.
      * Otherwise set the SleepJobs time to 15 seconds in the future when
      * we'll take more drastic measures...
      */

      if (cupsArrayCount(PrintingJobs) == 0)
	IOAllowPowerChange(sysevent.powerKernelPort,
			   sysevent.powerNotificationID);
      else
      {
       /*
	* If there are active printers that don't have the connecting-to-device
	* printer-state-reason then delay the sleep request (i.e. this reason
	* indicates a job that is not yet connected to the printer)...
	*/

	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	     p;
	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
	{
	  if (p->job)
	  {
	    for (i = 0; i < p->num_reasons; i ++)
	      if (!strcmp(p->reasons[i], "connecting-to-device"))
		break;

	    if (!p->num_reasons || i >= p->num_reasons)
	      break;
	  }
	}

	if (p)
	{
	  LastSysEvent = sysevent;
	  SleepJobs    = time(NULL) + 10;
	}
	else
	{
	  IOAllowPowerChange(sysevent.powerKernelPort,
			     sysevent.powerNotificationID);
	}
      }
    }

    if (sysevent.event & SYSEVENT_WOKE)
    {
      cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep");
      IOAllowPowerChange(sysevent.powerKernelPort,
                         sysevent.powerNotificationID);
      Sleeping = 0;

#ifdef kIOPMAssertionTypeDenySystemSleep
      if (cupsArrayCount(PrintingJobs) > 0 && !dark_wake)
      {
	cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting dark wake.");
	IOPMAssertionCreateWithName(kIOPMAssertionTypeDenySystemSleep,
				    kIOPMAssertionLevelOn,
				    CFSTR("org.cups.cupsd"), &dark_wake);
      }
#endif /* kIOPMAssertionTypeDenySystemSleep */

      cupsdCheckJobs();
    }

    if (sysevent.event & SYSEVENT_NETCHANGED)
    {
      if (!Sleeping)
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "System network configuration changed");
      else
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "System network configuration changed; "
			"ignored while sleeping");
    }

    if (sysevent.event & SYSEVENT_NAMECHANGED)
    {
      if (!Sleeping)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Computer name or BTMM domains changed");

       /*
	* De-register the individual printers...
	*/

	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	     p;
	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
	  cupsdDeregisterPrinter(p, 1);

#  if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
       /*
        * Update the computer name and BTMM domain list...
	*/

	cupsdUpdateDNSSDName();
#  endif /* HAVE_DNSSD || HAVE_AVAHI */

       /*
	* Now re-register them...
	*/

	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
	     p;
	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
	  cupsdRegisterPrinter(p);
      }
      else
        cupsdLogMessage(CUPSD_LOG_DEBUG,
	                "Computer name or BTMM domains changed; ignored while "
			"sleeping");
    }
  }
}