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: | 
