Russian Qt Forum

Программирование => Общий => Тема начата: funstep от Ноябрь 08, 2011, 18:04



Название: Как отловить запуск скринсейвера или отключение дисплея при простое?
Отправлено: funstep от Ноябрь 08, 2011, 18:04
Доброго времени суток!

Подскажите, пожалуйста, как можно узнать о запуске скринсейвера или отключение дисплея при простое, средствами Qt или же другими способами и отменить их запуск? Конкретно интересуют платформы Linux и Mac OS.


Название: Re: Как отловить запуск скринсейвера или отключение дисплея при простое?
Отправлено: Blackwanderer от Ноябрь 09, 2011, 10:17
Средствами Qt скорее всего не получится. Нужно искать платформозависимое решение (под тот же Linux существует как минимум три популярных скринсейвера). Можете попробовать покопаться в исходниках какого-нибудь видеоплеера. Если мне не изменяет память, MPlayer умеет блокировать запуск скринсейвера.


Название: Re: Как отловить запуск скринсейвера или отключение дисплея при простое?
Отправлено: sendevent от Ноябрь 09, 2011, 11:08
Отсутствие действий:
Код
C++ (Qt)
int CommonUtils::getUserIdle()
{
#if defined(Q_WS_X11)
   XScreenSaverInfo *info = XScreenSaverAllocInfo();
   if(!info)
   {
return 0;
   }
 
   Display *display = QX11Info::display();
   XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
   int idle = info->idle;
   XFree(info);
   return idle;
#elif defined(Q_WS_WIN)
   LASTINPUTINFO lif;
   lif.cbSize = sizeof(LASTINPUTINFO);
 
   if(!GetLastInputInfo(&lif))
   {
return 0;
   }
 
   return GetTickCount() - lif.dwTime;
#elif defined(Q_WS_MAC)
   int64_t idlesecs = 0;
   io_iterator_t iter = 0;
   if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS)
   {
io_registry_entry_t entry = IOIteratorNext(iter);
if (entry)
{
   CFMutableDictionaryRef dict = NULL;
   if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS)
   {
CFNumberRef obj = (CFNumberRef)CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
if (obj)
{
   int64_t nanoseconds = 0;
   if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds))
   {
idlesecs = (nanoseconds * 1000000); // Divide by 10^9 to convert from nanoseconds to seconds.
   }
}
CFRelease(dict);
   }
   IOObjectRelease(entry);
}
IOObjectRelease(iter);
   }
 
   return idlesecs;
#endif
}

Хранитель экрана:
Код
C++ (Qt)
static QString getProcessesOutput
(
   const QString& strUtility0,
   const QStringList argsList0,
   const QString& strUtility1,
   const QStringList argsList1
)
{
   QProcess process0, process1;
 
   process0.setStandardOutputProcess( &process1 );
 
   process0.start( strUtility0, argsList0 );
   process1.start( strUtility1, argsList1 );
 
   QString strRes;
   if( process0.waitForStarted() )
   {
if( process1.waitForStarted() && process1.waitForReadyRead() )
{
   strRes = QString( process1.readAllStandardOutput().trimmed() );
   process1.waitForFinished();
}
process0.waitForFinished();
   }
 
//    qDebug( "getProcessesOutput: 0: %d", process0.exitCode() );
//    qDebug( "getProcessesOutput: 1: %d", process1.exitCode() );
//    qDebug( "getProcessesOutput: res: [%s]", qPrintable( strRes ) );
 
   return strRes;
}
 
bool CommonUtils::isScreenSaverActive()
{
   bool bRes = false;
#if defined(Q_WS_X11)
   XScreenSaverInfo *info = XScreenSaverAllocInfo();
   if(info)
   {
Display *display = QX11Info::display();
XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
bRes = info->state == ScreenSaverOn;
XFree(info);
   }
#elif defined(Q_WS_WIN)
   BOOL isOn;
   BOOL cmdResult =SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, NULL, &isOn, FALSE);
   bRes = isOn && cmdResult;
#elif defined(Q_WS_MAC)
   static const QString path2ps = "ps";
   static const QString psArg = "ax";
 
   static const QString path2grep = "grep";
   static const QString grepArg = "[S]creenSaverEngine";
 
   QString output = getProcessesOutput
   (
path2ps,
QStringList() << psArg,
path2grep,
QStringList() << grepArg
   );
   bRes = !output.isEmpty();
#endif
 
   return bRes;
}


Название: Re: Как отловить запуск скринсейвера или отключение дисплея при простое?
Отправлено: GreatSnake от Ноябрь 09, 2011, 11:34
См. DisableXScreenSaver() в vlc исходниках (http://git.videolan.org/?p=vlc/vlc-1.0.git;a=blob;f=modules/video_output/x11/xcommon.c;h=700d9a04dcf971499d581d870923b65625c269a3;hb=HEAD).


Название: Re: Как отловить запуск скринсейвера или отключение дисплея при простое?
Отправлено: funstep от Ноябрь 10, 2011, 11:31
Большое спасибо.


Название: Re: Как отловить запуск скринсейвера или отключение дисплея при простое?
Отправлено: Alex Custov от Ноябрь 10, 2011, 22:55
Доброго времени суток!

Подскажите, пожалуйста, как можно узнать о запуске скринсейвера или отключение дисплея при простое, средствами Qt или же другими способами и отменить их запуск? Конкретно интересуют платформы Linux и Mac OS.

В X11 такого сигнала нет. Нужно по таймеру, скажем, раз в секунду, проверять состояние монитора через DPMS функции, и отслеживать когда это состояние поменялось. В Linux man DPMSInfo и далее по ссылкам.