aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--unsaver.110
-rw-r--r--unsaver.c48
-rw-r--r--unsaver.html13
-rw-r--r--unsaver.rst10
4 files changed, 54 insertions, 27 deletions
diff --git a/unsaver.1 b/unsaver.1
index 5fcf97a..623a291 100644
--- a/unsaver.1
+++ b/unsaver.1
@@ -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
diff --git a/unsaver.c b/unsaver.c
index ec502df..2cba2dc 100644
--- a/unsaver.c
+++ b/unsaver.c
@@ -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>&lt;keycode&gt;</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 &quot;xmodmap -pk&quot; 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 &amp; deprecated
-Xlib keyboard API. This mainly affects the default &quot;find an unused
-keycode&quot; 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: