diff options
-rw-r--r-- | unsaver.1 | 10 | ||||
-rw-r--r-- | unsaver.c | 48 | ||||
-rw-r--r-- | unsaver.html | 13 | ||||
-rw-r--r-- | unsaver.rst | 10 |
4 files changed, 54 insertions, 27 deletions
@@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH UNSAVER 1 "2020-05-20" "0.3.0" "Urchlay" +.TH UNSAVER 1 "2020-05-23" "0.4.0" "Urchlay" .SH NAME unsaver \- deactivate screensaver on joystick activity . @@ -102,6 +102,7 @@ Only one of \fB\-k\fP/\fB\-b\fP/\fB\-m\fP/\fB\-c\fP/\fB\-x\fP is accepted. .TP .BI \-k \ <keycode> Send this keycode when activity is detected. Default +(with no \fB\-k\fP/\fB\-b\fP/\fB\-m\fP/\fB\-c\fP/\fB\-x\fP options) is to search the keymap for an unused code. If you set this manually, it should be a keycode that \fIdoesn\(aqt\fP map to a keysym in your usual keymapping (use "xmodmap \-pk" to find one). @@ -202,15 +203,12 @@ numbers (it\(aqs better to autodetect). .sp Normally once daemonized, unsaver is very robust. However, if something does go wrong, there\(aqs no way to find out what. Probably there should -be a log file, or use syslog (or is that overkill?). +be a log file, or use syslog (or is that overkill?). The best you can +do for now is run it with \-d and maybe redirect stderr to a log file. .sp It should be (but currently isn\(aqt) possible to at least work in mouse\-motion mode even without the XTest extension, via XWarpPointer(). .sp -I \fIreally\fP need to use the XKB extension rather than the old & deprecated -Xlib keyboard API. This mainly affects the default "find an unused -keycode" mode. -.sp unsaver isn\(aqt portable. It only works on Linux, at least for now, for three reasons: .INDENT 0.0 @@ -17,6 +17,7 @@ #include <X11/X.h> #include <X11/Xlib.h> +#include <X11/XKBlib.h> #include <X11/extensions/XTest.h> #include <linux/joystick.h> @@ -661,31 +662,62 @@ void connect_to_x(void) { } } -/* XXX: XKeycodeToKeysym() is deprecated. I must learn XKB. */ +/* XKeycodeToKeysym() is deprecated, hence the pragma fugliness. + Deprecated or not, the xmodmap command still uses it, and it + still works. However, XKB is the new hotness, we'll use that if + it's available. */ +KeySym keycode_is_mapped(XkbDescPtr xkbd, int i) { + if(xkbd) { + return XkbKeyNumGroups(xkbd, i) > 0; + } else { + /* if xkbd is NULL, the caller failed to init XKB. */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -KeySym get_keysym(int i) { - return XKeycodeToKeysym(xdisp, i, 0); -} + return XKeycodeToKeysym(xdisp, i, 0) != NoSymbol; #pragma GCC diagnostic pop + } +} -/* the goggles, they do nothing! */ +/* The goggles, they do nothing! + Find an unused keycode in the keymap. From the shell, this would + be something like: xmodmap -pke|grep '= *$'|head -1 */ void find_keycode() { - int i, min_code = 0, max_code = 0; - + int i, ignoreme, min_code = 0, max_code = 0; + int major = XkbMajorVersion, minor = XkbMinorVersion; + XkbDescPtr xkbd = NULL; + + /* not sure any X server still running on planet Earth will lack + the XKB extension, but in case I'm wrong... */ + if(XkbQueryExtension( + xdisp, + &ignoreme, + &ignoreme, + &ignoreme, + &major, + &minor)) + { + xkbd = XkbGetMap(xdisp, XkbAllClientInfoMask, XkbUseCoreKbd); + fprintf(stderr, "using XKB extension major %d, minor %d\n", major, minor); + } else { + fprintf(stderr, "XKB extension not supported, fall back to XKeycodeToKeysym\n"); + } + /* man page doesn't document the return value */ (void)XDisplayKeycodes(xdisp, &min_code, &max_code); if(debug) fprintf(stderr, "XDisplayKeycodes min %d, max %d\n", min_code, max_code); for(i = min_code; i <= max_code; i++) { - if(get_keysym(i) == NoSymbol) { + if(!keycode_is_mapped(xkbd, i)) { keycode = i; if(debug) fprintf(stderr, "using keycode %d\n", keycode); break; } } + if(xkbd) + XkbFreeKeyboard(xkbd, XkbAllClientInfoMask, 1); + if(keycode < 0) { fprintf(stderr, "%s: can't find a free keycode in the keymap, using %d\n", diff --git a/unsaver.html b/unsaver.html index 17188e3..e64c712 100644 --- a/unsaver.html +++ b/unsaver.html @@ -5,7 +5,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" /> <title>unsaver</title> -<meta name="date" content="2020-05-20" /> +<meta name="date" content="2020-05-23" /> <style type="text/css"> /* @@ -373,9 +373,9 @@ ul.auto-toc { <tr class="manual-group field"><th class="docinfo-name">Manual group:</th><td class="field-body">Urchlay</td> </tr> <tr><th class="docinfo-name">Date:</th> -<td>2020-05-20</td></tr> +<td>2020-05-23</td></tr> <tr><th class="docinfo-name">Version:</th> -<td>0.3.0</td></tr> +<td>0.4.0</td></tr> </tbody> </table> <!-- RST source for unsaver(1) man page. Convert with: --> @@ -461,6 +461,7 @@ as milliseconds. Default: 250m.</td></tr> <tr><td class="option-group"> <kbd><span class="option">-k <var><keycode></var></span></kbd></td> <td>Send this keycode when activity is detected. Default +(with no <strong>-k</strong>/<strong>-b</strong>/<strong>-m</strong>/<strong>-c</strong>/<strong>-x</strong> options) is to search the keymap for an unused code. If you set this manually, it should be a keycode that <em>doesn't</em> map to a keysym in your usual keymapping (use "xmodmap -pk" to find one).</td></tr> @@ -556,12 +557,10 @@ been plugged in yet. Try to avoid typos, if you really have to use device numbers (it's better to autodetect).</p> <p>Normally once daemonized, unsaver is very robust. However, if something does go wrong, there's no way to find out what. Probably there should -be a log file, or use syslog (or is that overkill?).</p> +be a log file, or use syslog (or is that overkill?). The best you can +do for now is run it with -d and maybe redirect stderr to a log file.</p> <p>It should be (but currently isn't) possible to at least work in mouse-motion mode even without the XTest extension, via XWarpPointer().</p> -<p>I <em>really</em> need to use the XKB extension rather than the old & deprecated -Xlib keyboard API. This mainly affects the default "find an unused -keycode" mode.</p> <p>unsaver isn't portable. It only works on Linux, at least for now, for three reasons:</p> <blockquote> diff --git a/unsaver.rst b/unsaver.rst index 734d828..dc05f44 100644 --- a/unsaver.rst +++ b/unsaver.rst @@ -1,7 +1,7 @@ .. RST source for unsaver(1) man page. Convert with: .. rst2man.py unsaver.rst > unsaver.1 -.. |version| replace:: 0.3.0 +.. |version| replace:: 0.4.0 .. |date| date:: ======= @@ -85,6 +85,7 @@ Deactivation mode options Only one of **-k**/**-b**/**-m**/**-c**/**-x** is accepted. -k <keycode> Send this keycode when activity is detected. Default + (with no **-k**/**-b**/**-m**/**-c**/**-x** options) is to search the keymap for an unused code. If you set this manually, it should be a keycode that *doesn't* map to a keysym in your usual keymapping (use "xmodmap -pk" to find one). @@ -188,15 +189,12 @@ numbers (it's better to autodetect). Normally once daemonized, unsaver is very robust. However, if something does go wrong, there's no way to find out what. Probably there should -be a log file, or use syslog (or is that overkill?). +be a log file, or use syslog (or is that overkill?). The best you can +do for now is run it with -d and maybe redirect stderr to a log file. It should be (but currently isn't) possible to at least work in mouse-motion mode even without the XTest extension, via XWarpPointer(). -I *really* need to use the XKB extension rather than the old & deprecated -Xlib keyboard API. This mainly affects the default "find an unused -keycode" mode. - unsaver isn't portable. It only works on Linux, at least for now, for three reasons: |