void wsScreenSaverOn(Display *mDisplay) { int nothing; #ifdef CONFIG_XDPMS if (dpms_disabled) { if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) { if (!DPMSEnable(mDisplay)) mp_msg(MSGT_GPLAYER, MSGL_ERR, MSGTR_WS_DpmsUnavailable); // restoring power saving settings else { // DPMS does not seem to be enabled unless we call DPMSInfo BOOL onoff; CARD16 state; DPMSInfo(mDisplay, &state, &onoff); if (onoff) mp_msg(MSGT_GPLAYER, MSGL_V, "Successfully enabled DPMS.\n"); else mp_msg(MSGT_GPLAYER, MSGL_STATUS, MSGTR_WS_DpmsNotEnabled); } } } #endif if (timeout_save) { int dummy, interval, prefer_blank, allow_exp; XGetScreenSaver(mDisplay, &dummy, &interval, &prefer_blank, &allow_exp); XSetScreenSaver(mDisplay, timeout_save, interval, prefer_blank, allow_exp); XGetScreenSaver(mDisplay, &timeout_save, &interval, &prefer_blank, &allow_exp); } }
void wsScreenSaverOff(Display *mDisplay) { int interval, prefer_blank, allow_exp, nothing; #ifdef CONFIG_XDPMS if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) { BOOL onoff; CARD16 state; DPMSInfo(mDisplay, &state, &onoff); if (onoff) { Status stat; mp_dbg(MSGT_GPLAYER, MSGL_DBG2, "Disabling DPMS.\n"); dpms_disabled = 1; stat = DPMSDisable(mDisplay); // monitor powersave off mp_dbg(MSGT_GPLAYER, MSGL_DBG2, "stat: %d.\n", stat); } } #endif XGetScreenSaver(mDisplay, &timeout_save, &interval, &prefer_blank, &allow_exp); if (timeout_save) XSetScreenSaver(mDisplay, 0, interval, prefer_blank, allow_exp); // turning off screensaver }
bool X11Helper::OpenXConnection() { DEBUG_ASSERT( Dpy == nullptr && Win == None ); Dpy = XOpenDisplay(0); if( Dpy == nullptr ) return false; XSetIOErrorHandler( FatalCallback ); XSetErrorHandler( ErrorCallback ); int event_base, error_base; display_supports_dpms_extension= DPMSQueryExtension(Dpy, &event_base, &error_base); if(display_supports_dpms_extension) { LOG->Trace("DPMSQueryExtension returned true. Stepmania will disable power management, and restore the original state on exit."); CARD16 power_level; BOOL state; if(DPMSInfo(Dpy, &power_level, &state)) { dpms_state_at_startup= state; DPMSDisable(Dpy); } else { LOG->Trace("DPMSInfo returned false. Stepmania will not be able to disable power management."); } } else { LOG->Trace("DPMSQueryExtension returned false, which means this display does not support the DPMS extension. Stepmania will not be able to disable power management."); } return true; }
/** * gpm_dpms_x11_set_mode: **/ static gboolean gpm_dpms_x11_set_mode (GpmDpms *dpms, GpmDpmsMode mode, GError **error) { GpmDpmsMode current_mode; CARD16 state; CARD16 current_state; BOOL current_enabled; if (!dpms->priv->dpms_capable) { egg_debug ("not DPMS capable"); g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL, "Display is not DPMS capable"); return FALSE; } if (!DPMSInfo (dpms->priv->display, ¤t_state, ¤t_enabled)) { egg_debug ("couldn't get DPMS info"); g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL, "Unable to get DPMS state"); return FALSE; } if (!current_enabled) { egg_debug ("DPMS not enabled"); g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL, "DPMS is not enabled"); return FALSE; } switch (mode) { case GPM_DPMS_MODE_ON: state = DPMSModeOn; break; case GPM_DPMS_MODE_STANDBY: state = DPMSModeStandby; break; case GPM_DPMS_MODE_SUSPEND: state = DPMSModeSuspend; break; case GPM_DPMS_MODE_OFF: state = DPMSModeOff; break; default: state = DPMSModeOn; break; } gpm_dpms_x11_get_mode (dpms, ¤t_mode, NULL); if (current_mode != mode) { if (! DPMSForceLevel (dpms->priv->display, state)) { g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL, "Could not change DPMS mode"); return FALSE; } XSync (dpms->priv->display, FALSE); } return TRUE; }
void set_dpms_mode(char *mode) { #if NO_X11 return; #else RAWFB_RET_VOID #if LIBVNCSERVER_HAVE_DPMS if (dpy && DPMSCapable(dpy)) { CARD16 level; CARD16 want; BOOL enabled; if (!strcmp(mode, "off")) { want = DPMSModeOff; } else if (!strcmp(mode, "on")) { want = DPMSModeOn; } else if (!strcmp(mode, "standby")) { want = DPMSModeStandby; } else if (!strcmp(mode, "suspend")) { want = DPMSModeSuspend; } else if (!strcmp(mode, "enable")) { DPMSEnable(dpy); return; } else if (!strcmp(mode, "disable")) { DPMSDisable(dpy); return; } else { return; } if (DPMSInfo(dpy, &level, &enabled)) { char *from = "unk"; if (enabled && level != want) { XErrorHandler old_handler = XSetErrorHandler(trap_xerror); trapped_xerror = 0; rfbLog("DPMSInfo level: %d enabled: %d\n", level, enabled); if (level == DPMSModeStandby) { from = "DPMSModeStandby"; } else if (level == DPMSModeSuspend) { from = "DPMSModeSuspend"; } else if (level == DPMSModeOff) { from = "DPMSModeOff"; } else if (level == DPMSModeOn) { from = "DPMSModeOn"; } rfbLog("switching DPMS state from %s to %s\n", from, mode); DPMSForceLevel(dpy, want); XSetErrorHandler(old_handler); trapped_xerror = 0; } } } #endif #endif }
/** * Actually this is a big mess. By default the libSDL disables the screen * saver during the SDL_InitSubSystem() call and restores the saved settings * during the SDL_QuitSubSystem() call. This mechanism can be disabled by * setting the environment variable SDL_VIDEO_ALLOW_SCREENSAVER to 1. However, * there is a known bug in the Debian libSDL: If this environment variable is * set, the screen saver is still disabled but the old state is not restored * during SDL_QuitSubSystem()! So the only solution to overcome this problem * is to save and restore the state prior and after each of these function * calls. */ void X11ScreenSaverSettingsSave() { int dummy; CARD16 dummy2; Display *display = QX11Info::display(); XGetScreenSaver(display, &gX11ScreenSaverTimeout, &dummy, &dummy, &dummy); if (gX11ScreenSaverDpmsAvailable) DPMSInfo(display, &dummy2, &gX11DpmsState); }
/** * Checks the DPMS state of the display. * @return @c 1 if DPMS is enabled, @c 0 otherwise. * @ingroup Ecore_X_DPMS_Group */ EAPI Eina_Bool ecore_x_dpms_enabled_get(void) { #ifdef ECORE_XDPMS unsigned char state; unsigned short power_lvl; LOGFN(__FILE__, __LINE__, __FUNCTION__); DPMSInfo(_ecore_x_disp, &power_lvl, &state); return state ? EINA_TRUE : EINA_FALSE; #else /* ifdef ECORE_XDPMS */ return EINA_FALSE; #endif /* ifdef ECORE_XDPMS */ }
bool ScreenSaverX11::Asleep(void) { if (!d->IsDPMSEnabled()) return false; if (d->DeactivatedDPMS()) return false; BOOL on; CARD16 power_level; DPMSInfo(qt_xdisplay(), &power_level, &on); return (power_level != DPMSModeOn); }
bool CXWindowsScreenSaver::isDPMSActivated() const { #if HAVE_X11_EXTENSIONS_DPMS_H if (m_dpms) { CARD16 level; BOOL state; DPMSInfo(m_display, &level, &state); return (level != DPMSModeOn); } else { return false; } #else return false; #endif }
void X11ScreenSaverSettingsSave() { /* Actually this is a big mess. By default the libSDL disables the screen saver * during the SDL_InitSubSystem() call and restores the saved settings during * the SDL_QuitSubSystem() call. This mechanism can be disabled by setting the * environment variable SDL_VIDEO_ALLOW_SCREENSAVER to 1. However, there is a * known bug in the Debian libSDL: If this environment variable is set, the * screen saver is still disabled but the old state is not restored during * SDL_QuitSubSystem()! So the only solution to overcome this problem is to * save and restore the state prior and after each of these function calls. */ int dummy; CARD16 dummy2; Display *display = QX11Info::display(); XGetScreenSaver(display, &gX11ScreenSaverTimeout, &dummy, &dummy, &dummy); if (gX11ScreenSaverDpmsAvailable) DPMSInfo(display, &dummy2, &gX11DpmsState); }
/** * gpm_dpms_x11_get_mode: **/ static gboolean gpm_dpms_x11_get_mode (GpmDpms *dpms, GpmDpmsMode *mode, GError **error) { GpmDpmsMode result; BOOL enabled = FALSE; CARD16 state; if (dpms->priv->dpms_capable == FALSE) { /* Server or monitor can't DPMS -- assume the monitor is on. */ result = GPM_DPMS_MODE_ON; goto out; } DPMSInfo (dpms->priv->display, &state, &enabled); if (!enabled) { /* Server says DPMS is disabled -- so the monitor is on. */ result = GPM_DPMS_MODE_ON; goto out; } switch (state) { case DPMSModeOn: result = GPM_DPMS_MODE_ON; break; case DPMSModeStandby: result = GPM_DPMS_MODE_STANDBY; break; case DPMSModeSuspend: result = GPM_DPMS_MODE_SUSPEND; break; case DPMSModeOff: result = GPM_DPMS_MODE_OFF; break; default: result = GPM_DPMS_MODE_ON; break; } out: if (mode) *mode = result; return TRUE; }
/*! * This function works around an XServer idleTime bug in the * XScreenSaverExtension if dpms is running. In this case the current * dpms-state time is always subtracted from the current idletime. * This means: XScreenSaverInfo->idle is not the time since the last * user activity, as descriped in the header file of the extension. * This result in SUSE bug # and sf.net bug #. The bug in the XServer itself * is reported at https://bugs.freedesktop.org/buglist.cgi?quicksearch=6439. * * Workaround: Check if if XServer is in a dpms state, check the * current timeout for this state and add this value to * the current idle time and return. * * \param _idleTime an unsigned long value with the current idletime from * XScreenSaverInfo->idle * \return an unsigned long with the corrected idletime */ static unsigned long workaroundX11(Display *dpy, unsigned long _idle) { int dummy; CARD16 standby, suspend, off; CARD16 state; BOOL onoff; if(DPMSQueryExtension(dpy, &dummy, &dummy)) { if(DPMSCapable(dpy)) { DPMSGetTimeouts(dpy, &standby, &suspend, &off); DPMSInfo(dpy, &state, &onoff); if(onoff) { switch(state) { case DPMSModeStandby: // this check is a little bit paranoid, but just to be sure if(_idle < (unsigned) (standby * 1000)) { _idle += (standby * 1000); } break; case DPMSModeSuspend: if(_idle < (unsigned) ((suspend + standby) * 1000)) { _idle += ((suspend + standby) * 1000); } break; case DPMSModeOff: if(_idle < (unsigned) ((off + suspend + standby) * 1000)) { _idle += ((off + suspend + standby) * 1000); } break; case DPMSModeOn: break; default: break; } } } } return _idle; }
ScreenSaverX11Private(ScreenSaverX11 *outer) : m_dpmsenabled(FALSE), m_dpmsdeactivated(false), m_timeoutInterval(-1), m_resetTimer(0) { m_xscreensaverRunning = myth_system("xscreensaver-command -version >&- 2>&-") == 0; m_gscreensaverRunning = myth_system("gnome-screensaver-command --help >&- 2>&-") == 0; if (IsScreenSaverRunning()) { m_resetTimer = new QTimer(outer); QObject::connect(m_resetTimer, SIGNAL(timeout()), outer, SLOT(resetSlot())); VERBOSE(VB_GENERAL, "XScreenSaver support enabled"); } int dummy; if ((m_dpmsaware = DPMSQueryExtension(qt_xdisplay(), &dummy, &dummy))) { CARD16 power_level; /* If someone runs into X server weirdness that goes away when * they externally disable DPMS, then the 'dpmsenabled' test should * be short circuited by a call to 'DPMSCapable()'. Be sure to * manually initialize dpmsenabled to false. */ DPMSInfo(qt_xdisplay(), &power_level, &m_dpmsenabled); if (m_dpmsenabled) VERBOSE(VB_GENERAL, "DPMS is active."); else VERBOSE(VB_GENERAL, "DPMS is disabled."); } else { VERBOSE(VB_GENERAL, "DPMS is not supported."); } }
/*! * This function works around an XServer idleTime bug in the * XScreenSaverExtension if dpms is running. In this case the current * dpms-state time is always subtracted from the current idletime. * This means: XScreenSaverInfo->idle is not the time since the last * user activity, as descriped in the header file of the extension. * This result in SUSE bug # and sf.net bug #. The bug in the XServer itself * is reported at https://bugs.freedesktop.org/buglist.cgi?quicksearch=6439. * * Workaround: Check if if XServer is in a dpms state, check the * current timeout for this state and add this value to * the current idle time and return. * * \param _idleTime a unsigned long value with the current idletime from * XScreenSaverInfo->idle * \return a unsigned long with the corrected idletime */ unsigned long workaroundCreepyXServer(Display *dpy, unsigned long _idleTime ){ int dummy; CARD16 standby, suspend, off; CARD16 state; BOOL onoff; if (DPMSQueryExtension(dpy, &dummy, &dummy)) { if (DPMSCapable(dpy)) { DPMSGetTimeouts(dpy, &standby, &suspend, &off); DPMSInfo(dpy, &state, &onoff); if (onoff) { switch (state) { case DPMSModeStandby: /* this check is a littlebit paranoid, but be sure */ if (_idleTime < (unsigned) (standby * 1000)) _idleTime += (standby * 1000); break; case DPMSModeSuspend: if (_idleTime < (unsigned) ((suspend + standby) * 1000)) _idleTime += ((suspend + standby) * 1000); break; case DPMSModeOff: if (_idleTime < (unsigned) ((off + suspend + standby) * 1000)) _idleTime += ((off + suspend + standby) * 1000); break; case DPMSModeOn: default: break; } } } } XCloseDisplay(dpy); return _idleTime; }
ScreenSaverX11Private(ScreenSaverX11 *outer) : m_dpmsaware(false), m_dpmsdeactivated(false), m_xscreensaverRunning(false), m_gscreensaverRunning(false), m_dpmsenabled(false), m_timeoutInterval(-1), m_resetTimer(NULL), m_display(NULL) { const uint flags = kMSDontBlockInputDevs | kMSDontDisableDrawing | kMSProcessEvents; m_xscreensaverRunning = myth_system("xscreensaver-command -version >&- 2>&-", flags) == 0; m_gscreensaverRunning = myth_system("gnome-screensaver-command --help >&- 2>&-", flags) == 0; if (IsScreenSaverRunning()) { m_resetTimer = new QTimer(outer); m_resetTimer->setSingleShot(false); QObject::connect(m_resetTimer, SIGNAL(timeout()), outer, SLOT(resetSlot())); if (m_xscreensaverRunning) LOG(VB_GENERAL, LOG_INFO, LOC + "XScreenSaver support enabled"); if (m_gscreensaverRunning) LOG(VB_GENERAL, LOG_INFO, LOC + "Gnome screen saver support enabled"); } m_display = OpenMythXDisplay(); if (m_display) { int dummy0, dummy1; m_dpmsaware = DPMSQueryExtension(m_display->GetDisplay(), &dummy0, &dummy1); } else { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open connection to X11 server"); } if (m_dpmsaware) { CARD16 power_level; /* If someone runs into X server weirdness that goes away when * they externally disable DPMS, then the 'dpmsenabled' test should * be short circuited by a call to 'DPMSCapable()'. Be sure to * manually initialize dpmsenabled to false. */ DPMSInfo(m_display->GetDisplay(), &power_level, &m_dpmsenabled); if (m_dpmsenabled) LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is active."); else LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is disabled."); } else { LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is not supported."); } }
uint32_t get_idle_milliseconds(Display *d) { XScreenSaverInfo *ssi; int evbase, errbase; if (!XScreenSaverQueryExtension(d, &evbase, &errbase)) { fprintf(stderr, "screen saver extension not supported\n"); return 1; } ssi = XScreenSaverAllocInfo(); if (ssi == NULL) { fprintf(stderr, "couldn't allocate screen saver info\n"); return 1; } if (!XScreenSaverQueryInfo(d, DefaultRootWindow(d), ssi)) { fprintf(stderr, "couldn't query screen saver info\n"); return 1; } uint32_t idle = (uint32_t) ssi->idle; XFree(ssi); // ugh. ssi->idle is wrong if DPMS is enabled, we have // to compensate. if (DPMSQueryExtension(d, &evbase, &errbase)) { if (DPMSCapable(d)) { CARD16 standby, suspend, off, state; BOOL onoff; DPMSGetTimeouts(d, &standby, &suspend, &off); DPMSInfo(d, &state, &onoff); if (onoff) { uint32_t offset = 0; switch (state) { case DPMSModeStandby: offset = (uint32_t) (standby * 1000); break; case DPMSModeSuspend: offset = (uint32_t) ((suspend + standby) * 1000); break; case DPMSModeOff: offset = (uint32_t) ((off + suspend + standby) * 1000); break; default: /*nothing*/; } if (offset != 0 && idle < offset) idle += offset; } } } return idle; }
int main(int argc, char **argv) { Display *dpy; int g15screen_fd; int event; int error; BOOL enabled = True; CARD16 power = 0; int dummy = 0, lights = True, change = 0; int i; struct sigaction new_action; char * enable_cmd = NULL; char * disable_cmd = NULL; int dpms_timeout = 0; for (i=0;i<argc;i++) { char argument[20]; memset(argument,0,20); strncpy(argument,argv[i],19); if (!strncmp(argument, "-a",2) || !strncmp(argument, "--activate",10)) { if(argv[i+1]!=NULL){ sscanf(argv[i+1],"%i",&dpms_timeout); i++; }else{ printf("%s --activate requires an argument <minutes to activation>\n",argv[0]); exit(1); } } if (!strncmp(argument, "-e",2) || !strncmp(argument, "--cmd-enable",12)) { if(argv[i+1]!=NULL){ enable_cmd = malloc(strlen(argv[i+1])+1); memcpy(enable_cmd, argv[i+1], strlen(argv[i+1])); i++; } } if (!strncmp(argument, "-d",2) || !strncmp(argument, "--cmd-disable",13)) { if(argv[i+1]!=NULL){ disable_cmd = malloc(strlen(argv[i+1])+1); memcpy(disable_cmd, argv[i+1], strlen(argv[i+1])); i++; } } if (!strncmp(argument, "-v",2) || !strncmp(argument, "--version",9)) { printf("%s version %s\n",argv[0],VERSION); exit(0); } if (!strncmp(argument, "-b",2) || !strncmp(argument, "--bright",13)) { bright=1; } if (!strncmp(argument, "-h",2) || !strncmp(argument, "--help",6)) { printf(" %s version %s\n (c)2007 Mike Lampard\n\n",argv[0],VERSION); printf(" -a or --activate <minutes> - cause DPMS to be activated in <minutes> if no activity.\n"); printf(" By default, %s will simply monitor DPMS status, and\n",argv[0]); printf(" requires a screensaver to activate. \n"); printf(" In this mode, no screensver is needed.\n"); printf(" %s will shut the monitor down on its own after <minutes>\n",argv[0]); printf(" with no keyboard or mouse activity.\n"); printf(" -e or --cmd-enable <cmd to run> - Run program <cmd> when DPMS is activated.\n\n"); printf(" -d or --cmd-disable <cmd to run> - Run program <cmd> when DPMS is de-activated.\n\n"); printf(" -b or --bright - When the keyboard is woken up, set the LEDs to bright.\n\n"); printf(" -v or --version - Show program version\n\n"); printf(" -h or --help - This page\n\n"); exit(0); } } dpy = XOpenDisplay(getenv("DISPLAY")); if (!dpy) { printf("Unable to open display %s - exiting\n",getenv("DISPLAY")); return 1; } do { if((g15screen_fd = new_g15_screen(G15_G15RBUF))<0){ printf("Sorry, cant connect to the G15daemon - retrying\n"); sleep(2); } }while(g15screen_fd<0); if (!DPMSQueryExtension (dpy, &event, &error)) { printf ("XDPMS extension not supported.\n"); return 1; } if (!DPMSCapable(dpy)) { printf("DPMS is not enabled... exiting\n"); return 1; } if (dpms_timeout>0) { DPMSEnable(dpy); DPMSSetTimeouts(dpy,dpms_timeout*60,dpms_timeout*60,0); } new_action.sa_handler = sighandler; new_action.sa_flags = 0; sigaction(SIGINT, &new_action, NULL); sigaction(SIGQUIT, &new_action, NULL); while(!leaving) { int fg_check = g15_send_cmd (g15screen_fd, G15DAEMON_IS_FOREGROUND, dummy); if (! DPMSInfo (dpy, &power, &enabled)) { printf ("unable to get DPMS state.\n"); return 1; } switch(power) { case DPMSModeOn: { if (lights == False) { change = 1; fork_child(enable_cmd); } lights = True; break; } case DPMSModeStandby: case DPMSModeSuspend: case DPMSModeOff: { if(lights == True){ change = 1; fork_child(disable_cmd); } lights = False; break; } } if (fg_check==1 && lights == True && change == 0) { // foreground g15_send_cmd (g15screen_fd, G15DAEMON_SWITCH_PRIORITIES, dummy); } if(change) { toggle_g15lights(g15screen_fd,lights,fg_check); change=0; } sleep (1); } close(g15screen_fd); if(enable_cmd!=NULL) free(enable_cmd); if(disable_cmd!=NULL) free(disable_cmd); XCloseDisplay(dpy); return 0; }
static void check_dpms(void) { static int init_dpms = 0; #if LIBVNCSERVER_HAVE_DPMS static int dpms_capable = 0; static time_t last_dpms = 0; int db = 0; CARD16 level; BOOL enabled; RAWFB_RET_VOID if (! init_dpms) { if (getenv("DPMS_DEBUG")) { db = atoi(getenv("DPMS_DEBUG")); } if (DPMSCapable(dpy)) { dpms_capable = 1; rfbLog("X display is capable of DPMS.\n"); if (watch_dpms) { rfbLog("Preventing low-power DPMS modes when" " clients are connected.\n"); } } else { if (! raw_fb_str) { rfbLog("X display is not capable of DPMS.\n"); } dpms_capable = 0; } init_dpms = 1; } if (force_dpms || (client_dpms && client_count)) { static int last_enable = 0; if (time(NULL) > last_enable) { set_dpms_mode("enable"); last_enable = time(NULL); } set_dpms_mode("off"); } if (! watch_dpms) { return; } if (! dpms_capable) { return; } if (! client_count) { return; } if (time(NULL) < last_dpms + 5) { return; } last_dpms = time(NULL); if (DPMSInfo(dpy, &level, &enabled)) { if (db) fprintf(stderr, "DPMSInfo level: %d enabled: %d\n", level, enabled); if (enabled && level != DPMSModeOn) { char *from = "unknown-dpms-state"; XErrorHandler old_handler = XSetErrorHandler(trap_xerror); trapped_xerror = 0; if (level == DPMSModeStandby) { from = "DPMSModeStandby"; } else if (level == DPMSModeSuspend) { from = "DPMSModeSuspend"; } else if (level == DPMSModeOff) { from = "DPMSModeOff"; } rfbLog("switching DPMS state from %s to DPMSModeOn\n", from); DPMSForceLevel(dpy, DPMSModeOn); XSetErrorHandler(old_handler); trapped_xerror = 0; } } else { if (db) fprintf(stderr, "DPMSInfo failed.\n"); } #else RAWFB_RET_VOID if (! init_dpms) { if (! raw_fb_str) { rfbLog("X DPMS extension not supported.\n"); } init_dpms = 1; } #endif }
int main(int argc, char** argv) { int verbose = 0, bg = 0; int i, ev, er; char *lock_cmd = "xlock"; char *flag_file = NULL; char estr[100], cmd[500]; struct stat sbuf; CARD16 power; CARD16 desired = DPMSModeOff; BOOL state; /* setup the lock command. it may be reset by -lock below. */ if (getenv("XLOCK_CMD")) { lock_cmd = (char *) getenv("XLOCK_CMD"); } /* process cmd line: */ for (i=1; i<argc; i++) { if (!strcmp(argv[i], "-display")) { sprintf(estr, "DISPLAY=%s", argv[++i]); putenv(strdup(estr)); } else if (!strcmp(argv[i], "-auth")) { sprintf(estr, "XAUTHORITY=%s", argv[++i]); putenv(strdup(estr)); } else if (!strcmp(argv[i], "-lock")) { lock_cmd = argv[++i]; } else if (!strcmp(argv[i], "-f")) { flag_file = argv[++i]; unlink(flag_file); } else if (!strcmp(argv[i], "-grab")) { grab = 1; } else if (!strcmp(argv[i], "-bg")) { bg = 1; } else if (!strcmp(argv[i], "-v")) { verbose = 1; } else if (!strcmp(argv[i], "-standby")) { desired = DPMSModeStandby; } else if (!strcmp(argv[i], "-suspend")) { desired = DPMSModeSuspend; } else if (!strcmp(argv[i], "-off")) { desired = DPMSModeOff; } } /* we want it to go into background to avoid blocking, so add '&'. */ strcpy(cmd, lock_cmd); strcat(cmd, " &"); lock_cmd = cmd; /* close any file descriptors we may have inherited (e.g. port 5900) */ for (i=3; i<=100; i++) { close(i); } /* open DISPLAY */ dpy = XOpenDisplay(NULL); if (! dpy) { fprintf(stderr, "XOpenDisplay failed.\n"); exit(1); } /* check for DPMS extension */ if (! DPMSQueryExtension(dpy, &ev, &er)) { fprintf(stderr, "DPMSQueryExtension failed.\n"); exit(1); } if (! DPMSCapable(dpy)) { fprintf(stderr, "DPMSCapable failed.\n"); exit(1); } /* make sure DPMS is enabled */ if (! DPMSEnable(dpy)) { fprintf(stderr, "DPMSEnable failed.\n"); exit(1); } /* retrieve the timeouts for later resetting */ if (! DPMSGetTimeouts(dpy, &standby, &suspend, &off)) { fprintf(stderr, "DPMSGetTimeouts failed.\n"); exit(1); } if (! standby || ! suspend || ! off) { /* if none, set to some reasonable values */ standby = 900; suspend = 1200; off = 1800; } if (verbose) { fprintf(stderr, "DPMS timeouts: %d %d %d\n", standby, suspend, off); } /* now set them to very small values */ if (desired == DPMSModeOff) { if (! DPMSSetTimeouts(dpy, 1, 1, 1)) { fprintf(stderr, "DPMSSetTimeouts failed.\n"); exit(1); } } else if (desired == DPMSModeSuspend) { if (! DPMSSetTimeouts(dpy, 1, 1, 0)) { fprintf(stderr, "DPMSSetTimeouts failed.\n"); exit(1); } } else if (desired == DPMSModeStandby) { if (! DPMSSetTimeouts(dpy, 1, 0, 0)) { fprintf(stderr, "DPMSSetTimeouts failed.\n"); exit(1); } } XFlush(dpy); /* set handlers for clean up in case we terminate via signal */ signal(SIGHUP, reset); signal(SIGINT, reset); signal(SIGQUIT, reset); signal(SIGABRT, reset); signal(SIGTERM, reset); /* force state into DPMS Off (lowest power) mode */ if (! DPMSForceLevel(dpy, desired)) { fprintf(stderr, "DPMSForceLevel failed.\n"); exit(1); } XFlush(dpy); /* read state */ msleep(500); if (! DPMSInfo(dpy, &power, &state)) { fprintf(stderr, "DPMSInfo failed.\n"); exit(1); } fprintf(stderr, "power: %d state: %d\n", power, state); /* grab display if desired. NOT WORKING */ if (grab) { if (verbose) { fprintf(stderr, "calling XGrabServer()\n"); } XGrabServer(dpy); } /* go into background if desired. */ if (bg) { pid_t p; if ((p = fork()) != 0) { if (p < 0) { fprintf(stderr, "problem forking.\n"); exit(1); } else { /* XXX no fd closing */ exit(0); } } } /* main loop: */ while (1) { /* reassert DPMSModeOff (desired) */ if (verbose) fprintf(stderr, "reasserting desired DPMSMode\n"); DPMSForceLevel(dpy, desired); XFlush(dpy); /* wait a bit */ msleep(200); /* check for flag file appearence */ if (flag_file && stat(flag_file, &sbuf) == 0) { if (verbose) { fprintf(stderr, "flag found: %s\n", flag_file); } unlink(flag_file); reset(0); exit(0); } /* check state and power level */ if (! DPMSInfo(dpy, &power, &state)) { fprintf(stderr, "DPMSInfo failed.\n"); reset(0); exit(1); } if (verbose) { fprintf(stderr, "power: %d state: %d\n", power, state); } if (!state || power != desired) { /* Someone (or maybe a cat) is evidently watching... */ fprintf(stderr, "DPMS CHANGE: power: %d state: %d\n", power, state); break; } } reset(0); fprintf(stderr, "locking screen with command: \"%s\"\n", lock_cmd); system(lock_cmd); exit(0); }