X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fxset.c;h=46607977ada484781ecd9b82b74bb471bb309fd1;hb=50be9bb40dc60130c99ffa568e6677779904ff70;hp=305ce846367944d2d8d4dfb2e4e3ca50a630c59f;hpb=481b95e2617b69e6fd4444432747d7e1e0c3dc85;p=xscreensaver diff --git a/driver/xset.c b/driver/xset.c index 305ce846..46607977 100644 --- a/driver/xset.c +++ b/driver/xset.c @@ -1,5 +1,5 @@ /* xset.c --- interacting with server extensions and the builtin screensaver. - * xscreensaver, Copyright (c) 1991-1998 Jamie Zawinski + * xscreensaver, Copyright (c) 1991-2008 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -30,6 +30,10 @@ #include "xscreensaver.h" +#ifdef _VROOT_H_ +ERROR! You must not include vroot.h in this file. +#endif + /* MIT SCREEN-SAVER server extension hackery. */ @@ -38,14 +42,6 @@ # include -Bool -query_mit_saver_extension (saver_info *si) -{ - return XScreenSaverQueryExtension (si->dpy, - &si->mit_saver_ext_event_number, - &si->mit_saver_ext_error_number); -} - static int ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) { @@ -89,6 +85,180 @@ init_mit_saver_extension (saver_info *si) } #endif /* HAVE_MIT_SAVER_EXTENSION */ + +#ifdef HAVE_XINPUT +/* XInputExtension device support */ +#include + +struct xinput_dev_info { + XDevice *device; + XEventClass press, release, valuator; +}; + +Bool +query_xinput_extension (saver_info *si) +{ + XExtCodes codes; + + if (!XQueryExtension (si->dpy, INAME, &codes.major_opcode, + &codes.first_event, &codes.first_error)) + { + if (si->prefs.verbose_p) + fprintf (stderr, "\t XInputExtension is not present!\n"); + return False; + } + else + { + if (si->prefs.verbose_p) + fprintf (stderr, "\t XInputExtension is present!\n"); + return True; + } +} + +void +init_xinput_extension (saver_info *si) +{ + int i, ndevices; + int class; + XDeviceInfo *list; + XDevice *dev; + XAnyClassPtr pClass; + XEventClass *event_list; + int nevents = 0; + + /* skip if already initialized */ + if (si->num_xinput_devices && si->xinput_devices) + return; + + si->num_xinput_devices = 0; + + list = XListInputDevices (si->dpy, &ndevices); + if (list == NULL) + { + si->xinput_devices = NULL; + return; + } + + /* We only care about 3 event types per device (DeviceButtonPress, + DeviceButtonRelease, and DeviceMotionNotify), hence the "* 3" + for the event count. */ + event_list = calloc(ndevices * 3, sizeof(XEventClass)); + if (event_list == NULL) + return; + + si->xinput_devices = calloc(ndevices, sizeof(struct xinput_dev_info)); + if (si->xinput_devices == NULL) + { + free(event_list); + return; + } + + for (i = 0; i < ndevices; i++) + { + if ((list[i].use == IsXExtensionDevice) +#ifdef IsXExtensionPointer + || (list[i].use == IsXExtensionPointer) +#endif + ) + { + struct xinput_dev_info *dev_info = + &si->xinput_devices[si->num_xinput_devices]; + Bool device_we_want = False; + + if (si->prefs.debug_p) + fprintf(stderr, + "Extension device #%2d: XID=%2d type=%3d name=\"%s\"\n", + i, (int) list[i].id, (int) list[i].type, list[i].name); + + dev = XOpenDevice (si->dpy, list[i].id); + if (!dev) + continue; + dev_info->device = dev; + + pClass = list[i].inputclassinfo; + for (class = 0; class < list[i].num_classes; class++) + { + switch (pClass->class) + { + case ButtonClass: + if (((XButtonInfo *) pClass)->num_buttons > 0) + { + /* Macros set values in the second & third arguments */ + DeviceButtonPress (dev, si->xinput_DeviceButtonPress, + dev_info->press); + event_list[nevents++] = dev_info->press; + + DeviceButtonRelease (dev, si->xinput_DeviceButtonRelease, + dev_info->release); + event_list[nevents++] = dev_info->release; + device_we_want = True; + } + break; + + case ValuatorClass: + if (((XValuatorInfo *) pClass)->num_axes > 0) + { + DeviceMotionNotify (dev, si->xinput_DeviceMotionNotify, + dev_info->valuator); + event_list[nevents++] = dev_info->valuator; + device_we_want = True; + } + break; + + default: + /* ignore other classes of devices/events */ + break; + } + + pClass = (XAnyClassPtr) & ((char *) pClass)[pClass->length]; + } + + if (device_we_want) + si->num_xinput_devices++; + else + XCloseDevice (si->dpy, dev); + } + } + + if (list) + XFreeDeviceList (list); + + if ((nevents == 0) || (si->num_xinput_devices == 0)) + { + free(event_list); + free(si->xinput_devices); + si->xinput_devices = NULL; + si->num_xinput_devices = 0; + return; + } + + for (i = 0; i < si->nscreens; i++) + { + saver_screen_info *ssi = &si->screens[i]; + Window root = RootWindowOfScreen (ssi->screen); + XSelectExtensionEvent (si->dpy, root, event_list, nevents); + } + + free(event_list); +} + +#if 0 +/* not used */ +static void +close_xinput_extension (saver_info *si) +{ + int i; + + for (i = 0; i < si->num_xinput_devices; i++) + XCloseDevice (si->dpy, si->xinput_devices[i].device); + + free(si->xinput_devices); + si->xinput_devices = NULL; + si->num_xinput_devices = 0; +} +#endif +#endif /* HAVE_XINPUT */ + /* SGI SCREEN_SAVER server extension hackery. */ @@ -97,14 +267,6 @@ init_mit_saver_extension (saver_info *si) # include -Bool -query_sgi_saver_extension (saver_info *si) -{ - return XScreenSaverQueryExtension (si->dpy, - &si->sgi_saver_ext_event_number, - &si->sgi_saver_ext_error_number); -} - static void init_sgi_saver_extension (saver_info *si) { @@ -125,7 +287,7 @@ init_sgi_saver_extension (saver_info *si) "%s: SGI SCREEN_SAVER extension exists, but can't be initialized;\n\ perhaps some other screensaver program is already running?\n", blurb()); - p->use_sgi_saver_extension = False; + si->using_sgi_saver_extension = False; return; } } @@ -133,13 +295,14 @@ init_sgi_saver_extension (saver_info *si) #endif /* HAVE_SGI_SAVER_EXTENSION */ + /* Figuring out what the appropriate XSetScreenSaver() parameters are (one wouldn't expect this to be rocket science.) */ void -disable_builtin_screensaver (saver_info *si, Bool turn_off_p) +disable_builtin_screensaver (saver_info *si, Bool unblank_screen_p) { saver_preferences *p = &si->prefs; int current_server_timeout, current_server_interval; @@ -169,43 +332,51 @@ disable_builtin_screensaver (saver_info *si, Bool turn_off_p) desired_server_interval = 0; /* I suspect (but am not sure) that DontAllowExposures might have - something to do with powering off the monitor as well. */ + something to do with powering off the monitor as well, at least + on some systems that don't support XDPMS? Who knows... */ desired_allow_exp = AllowExposures; -#if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION) - if (p->use_mit_saver_extension || p->use_sgi_saver_extension) + if (si->using_mit_saver_extension || si->using_sgi_saver_extension) { desired_server_timeout = (p->timeout / 1000); /* The SGI extension won't give us events unless blanking is on. I think (unsure right now) that the MIT extension is the opposite. */ - if (p->use_sgi_saver_extension) + if (si->using_sgi_saver_extension) desired_prefer_blank = PreferBlanking; else desired_prefer_blank = DontPreferBlanking; } else -#endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */ { + /* When we're not using an extension, set the server-side timeout to 0, + so that the server never gets involved with screen blanking, and we + do it all ourselves. (However, when we *are* using an extension, + we tell the server when to notify us, and rather than blanking the + screen, the server will send us an X event telling us to blank.) + */ desired_server_timeout = 0; } + /* XSetScreenSaver() generates BadValue if either timeout parameter + exceeds 15 bits (signed short.) That is 09:06:07. + */ + if (desired_server_timeout > 0x7FFF) desired_server_timeout = 0x7FFF; + if (desired_server_interval > 0x7FFF) desired_server_interval = 0x7FFF; + if (desired_server_timeout != current_server_timeout || desired_server_interval != current_server_interval || desired_prefer_blank != current_prefer_blank || desired_allow_exp != current_allow_exp) { - if (desired_server_timeout == 0) - printf ("%s%sisabling server builtin screensaver.\n\ - You can re-enable it with \"xset s on\".\n", - (p->verbose_p ? "" : blurb()), - (p->verbose_p ? "\n\tD" : ": d")); - if (p->verbose_p) - fprintf (stderr, "%s: (xset s %d %d %s %s)\n", blurb(), + fprintf (stderr, + "%s: disabling server builtin screensaver:\n" + "%s: (xset s %d %d; xset s %s; xset s %s)\n", + blurb(), blurb(), desired_server_timeout, desired_server_interval, (desired_prefer_blank ? "blank" : "noblank"), - (desired_allow_exp ? "noexpose" : "expose")); + (desired_allow_exp ? "expose" : "noexpose")); XSetScreenSaver (si->dpy, desired_server_timeout, desired_server_interval, @@ -221,134 +392,16 @@ disable_builtin_screensaver (saver_info *si, Bool turn_off_p) { extension_initted = True; # ifdef HAVE_MIT_SAVER_EXTENSION - if (p->use_mit_saver_extension) init_mit_saver_extension(si); + if (si->using_mit_saver_extension) init_mit_saver_extension(si); # endif # ifdef HAVE_SGI_SAVER_EXTENSION - if (p->use_sgi_saver_extension) init_sgi_saver_extension(si); + if (si->using_sgi_saver_extension) init_sgi_saver_extension(si); # endif } } #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */ - if (turn_off_p) + if (unblank_screen_p) /* Turn off the server builtin saver if it is now running. */ XForceScreenSaver (si->dpy, ScreenSaverReset); } - - -/* Display Power Management System (DPMS.) - - On XFree86 systems, "man xset" reports: - - -dpms The -dpms option disables DPMS (Energy Star) features. - +dpms The +dpms option enables DPMS (Energy Star) features. - - dpms flags... - The dpms option allows the DPMS (Energy Star) - parameters to be set. The option can take up to three - numerical values, or the `force' flag followed by a - DPMS state. The `force' flags forces the server to - immediately switch to the DPMS state specified. The - DPMS state can be one of `standby', `suspend', or - `off'. When numerical values are given, they set the - inactivity period before the three modes are activated. - The first value given is for the `standby' mode, the - second is for the `suspend' mode, and the third is for - the `off' mode. Setting these values implicitly - enables the DPMS features. A value of zero disables a - particular mode. - - However, note that the implementation is more than a little bogus, - in that there is code in /usr/X11R6/lib/libXdpms.a to implement all - the usual server-extension-querying utilities -- but there are no - prototypes in any header file! Thus, the prototypes here. (The - stuff in X11/extensions/dpms.h and X11/extensions/dpmsstr.h define - the raw X protcol, they don't define the API to libXdpms.a.) - */ - -#ifdef HAVE_DPMS_EXTENSION - -#include /* for CARD16 */ -#include -#include - -extern Bool DPMSQueryExtension (Display *dpy, int *event_ret, int *error_ret); -extern Bool DPMSCapable (Display *dpy); -extern Status DPMSForceLevel (Display *dpy, CARD16 level); -extern Status DPMSInfo (Display *dpy, CARD16 *power_level, BOOL *state); - -#if 0 /* others we don't use */ -extern Status DPMSGetVersion (Display *dpy, int *major_ret, int *minor_ret); -extern Status DPMSSetTimeouts (Display *dpy, - CARD16 standby, CARD16 suspend, CARD16 off); -extern Bool DPMSGetTimeouts (Display *dpy, - CARD16 *standby, CARD16 *suspend, CARD16 *off); -extern Status DPMSEnable (Display *dpy); -extern Status DPMSDisable (Display *dpy); -#endif /* 0 */ - - -Bool -monitor_powered_on_p (saver_info *si) -{ - Bool result; - int event_number, error_number; - BOOL onoff = False; - CARD16 state; - - if (!DPMSQueryExtension(si->dpy, &event_number, &error_number)) - /* Server doesn't know -- assume the monitor is on. */ - result = True; - - else if (!DPMSCapable(si->dpy)) - /* Server says the monitor doesn't do power management -- so it's on. */ - result = True; - - else - { - DPMSInfo(si->dpy, &state, &onoff); - if (!onoff) - /* Server says DPMS is disabled -- so the monitor is on. */ - result = True; - else - switch (state) { - case DPMSModeOn: result = True; break; /* really on */ - case DPMSModeStandby: result = False; break; /* kinda off */ - case DPMSModeSuspend: result = False; break; /* pretty off */ - case DPMSModeOff: result = False; break; /* really off */ - default: result = True; break; /* protocol error? */ - } - } - - return result; -} - -void -monitor_power_on (saver_info *si) -{ - if (!monitor_powered_on_p (si)) - { - DPMSForceLevel(si->dpy, DPMSModeOn); - XSync(si->dpy, False); - if (!monitor_powered_on_p (si)) - fprintf (stderr, - "%s: DPMSForceLevel(dpy, DPMSModeOn) did not power the monitor on?\n", - blurb()); - } -} - -#else /* !HAVE_DPMS_EXTENSION */ - -Bool -monitor_powered_on_p (saver_info *si) -{ - return True; -} - -void -monitor_power_on (saver_info *si) -{ - return; -} - -#endif /* !HAVE_DPMS_EXTENSION */