commit 31a752142adf44620fcdc04646fe3e4ba6fcf42c
parent 99a09a6927fd0030a70f8b5963bba985c68bbca6
Author: quantumish <freifeld.david@gmail.com>
Date: Mon, 27 Feb 2023 00:23:14 +0000
Add wheel parameter support
Diffstat:
| M | todo.org | | | 13 | ++++++++----- |
| A | wheeldaemon.c | | | 59 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | wheelmacs.cpp | | | 90 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
| A | wheelmesg.h | | | 27 | +++++++++++++++++++++++++++ |
4 files changed, 170 insertions(+), 19 deletions(-)
diff --git a/todo.org b/todo.org
@@ -1,11 +1,14 @@
* todos
-- [ ] settings before worker init
-- [X] bind wheel keys to unused emacs-recognized keys
+- [-] bind wheel keys to unused emacs-recognized keys
+ - [X] function keys
- [ ] dynamically choose unused keys
-- [ ] enabling autocenter
-- [ ] changing range
+- [X] enabling autocenter
+- [X] changing range/gain/force
- [ ] ffb settings
- [ ] send wheel shifts as keypresses
- [ ] emulated (emacs)
- [ ] emulated (c++/X11)
-
+- [ ] curate some fun examples
+ - [ ] "roll back" changes
+ - [ ] exert force to force push
+ - [ ] wheel for warning level
diff --git a/wheeldaemon.c b/wheeldaemon.c
@@ -0,0 +1,59 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "wheelmesg.h"
+
+#define PORT 8070
+#define PATH "/sys/devices/pci0000:00/0000:00:14.0/usb1/1-6"
+#define BUFSIZE 512
+
+int main() {
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ struct sockaddr_in addr;
+ memset((char *)&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET; // Specify address family.
+ addr.sin_addr.s_addr = htonl(INADDR_ANY); // INADDR_ANY just 0.0.0.0, machine IP address
+ addr.sin_port = htons(PORT); // Specify port.
+ bind(s, (struct sockaddr *)&addr, sizeof(addr));
+ struct sockaddr_in remaddr;
+ socklen_t addrlen = sizeof(remaddr);
+ int recvlen;
+ unsigned char buf[BUFSIZE];
+
+ while (1 == 1) {
+ recvlen = recvfrom(s, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
+ struct wheel_cmd cmd = *(struct wheel_cmd*)buf;
+ int fd;
+ char val[5] = {0};
+ switch (cmd.type) {
+ case AUTOCENTER:
+ fd = open(PATH "/enable_autocenter", O_WRONLY);
+ write(fd, cmd.value.autocenter ? "y" : "n", 1);
+ break;
+ case AUTOCENTER_FORCE:
+ fd = open(PATH "/autocenter", O_WRONLY);
+ sprintf(val, "%d", cmd.value.autocenter_force);
+ write(fd, val, 3);
+ break;
+ case GAIN:
+ fd = open(PATH "/gain", O_WRONLY);
+ sprintf(val, "%d", cmd.value.gain);
+ write(fd, val, 3);
+ break;
+ case RANGE:
+ fd = open(PATH "/range", O_WRONLY);
+ sprintf(val, "%d", cmd.value.range);
+ write(fd, val, 4);
+ break;
+ }
+ }
+
+}
diff --git a/wheelmacs.cpp b/wheelmacs.cpp
@@ -1,4 +1,5 @@
#include <cstdint>
+#include <stdint.h>
#include <thread>
#include <memory>
#include <vector>
@@ -8,12 +9,19 @@
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <mutex>
#include "linux/joystick.h"
#include "emacs-module.h"
extern "C" {
#include "xdo.h"
+ #include "wheelmesg.h"
}
#define VERSION 0.1
@@ -21,18 +29,11 @@ int plugin_is_GPL_compatible;
#define S(s) (env->intern(env, s))
+// Set the function cell of the symbol named NAME to SFUN using the 'fset' function.
static void bind_function (emacs_env *env, const char *name, emacs_value Sfun) {
- /* Set the function cell of the symbol named NAME to SFUN using
- the 'fset' function. */
-
- /* Convert the strings to symbols by interning them */
emacs_value Qfset = env->intern (env, "fset");
emacs_value Qsym = env->intern (env, name);
-
- /* Prepare the arguments array */
emacs_value args[] = { Qsym, Sfun };
-
- /* Make the call (2 == nb of arguments) */
env->funcall (env, Qfset, 2, args);
}
@@ -47,15 +48,26 @@ static void provide (emacs_env *env, const char *feature) {
env->funcall (env, Qprovide, 1, args);
}
-
std::shared_ptr<std::vector<bool>> buttons;
std::shared_ptr<std::vector<int16_t>> axes;
std::thread worker;
std::atomic_bool stop_worker;
+std::mutex cmd_mutex;
+struct wheel_cmd cmd;
void grab_values() {
xdo_t* x = xdo_new(NULL);
int fd = open("/dev/input/js0", O_RDONLY | O_NONBLOCK);
+
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ struct sockaddr_in addr;
+ memset((char *)&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET; // Specify address family.
+ addr.sin_addr.s_addr = htonl(INADDR_ANY); // INADDR_ANY just 0.0.0.0, machine IP address
+ addr.sin_port = htons(8070); // Specify port.
+
+ connect(s, (struct sockaddr *)&addr, sizeof(addr));
+
while (true) {
struct js_event e;
int r = read(fd, &e, sizeof(e));
@@ -67,15 +79,20 @@ void grab_values() {
} else if (e.type & JS_EVENT_AXIS) {
(*axes)[e.number] = e.value;
}
+ if (cmd.type != NONE) {
+ sendto(s, (void*)&cmd, sizeof(struct wheel_cmd), 0, NULL, sizeof(addr));
+ cmd.type = NONE;
+ cmd_mutex.unlock();
+ }
if (stop_worker) return;
}
}
static emacs_value wheel_init (emacs_env *env, ptrdiff_t nargs, emacs_value* args, void* data) noexcept {
- std::vector<bool> tmp_buttons =
- {{false,false,false,false,false,false,false,false,false,false,false,false}};
- std::vector<int16_t> tmp_axes = {{0,0,0,0,0}};
-
+ std::vector<bool> tmp_buttons(12);
+ std::vector<int16_t> tmp_axes(5);
+ std::fill(tmp_buttons.begin(), tmp_buttons.end(), false);
+ std::fill(tmp_axes.begin(), tmp_axes.end(), 0);
buttons = std::make_unique<std::vector<bool>>(tmp_buttons);
axes = std::make_unique<std::vector<int16_t>>(tmp_axes);
@@ -90,6 +107,47 @@ static emacs_value wheel_stop (emacs_env *env, ptrdiff_t nargs, emacs_value* arg
return S("nil");
}
+static emacs_value wheel_set_autocenter (emacs_env *env, ptrdiff_t nargs, emacs_value* args, void* data) noexcept {
+ bool val = env->is_not_nil(env, args[0]);
+ // cmd_mutex.lock();
+ cmd = {
+ .type = AUTOCENTER,
+ .value = {.autocenter = val}
+ };
+ // cmd_mutex.unlock();
+ return S("nil");
+}
+
+static emacs_value wheel_set_range (emacs_env *env, ptrdiff_t nargs, emacs_value* args, void* data) noexcept {
+ int val = env->extract_integer(env, args[0]);
+ if (val < 270 || val > 1080) return S("nil");
+ cmd = {
+ .type = RANGE,
+ .value = {.range = val}
+ };
+ return S("nil");
+}
+
+static emacs_value wheel_set_gain (emacs_env *env, ptrdiff_t nargs, emacs_value* args, void* data) noexcept {
+ int val = env->extract_integer(env, args[0]);
+ if (val < 0 || val > 100) return S("nil");
+ cmd = {
+ .type = GAIN,
+ .value = {.gain = val}
+ };
+ return S("nil");
+}
+
+static emacs_value wheel_set_autocenter_force (emacs_env *env, ptrdiff_t nargs, emacs_value* args, void* data) noexcept {
+ int val = env->extract_integer(env, args[0]);
+ if (val < 0 || val > 100) return S("nil");
+ cmd = {
+ .type = AUTOCENTER_FORCE,
+ .value = {.autocenter_force = val}
+ };
+ return S("nil");
+}
+
static emacs_value wheel_button (emacs_env *env, ptrdiff_t nargs, emacs_value* args, void* data) noexcept {
auto index = env->extract_integer(env, args[0]);
if (index >= (*buttons).size() || stop_worker) return S("nil");
@@ -108,7 +166,11 @@ extern int emacs_module_init (struct emacs_runtime *ert) noexcept {
emacs_env *env = ert->get_environment (ert);
DEFUN("wheel-init", wheel_init, 0, 0, "Set up whe.el worker thread", NULL);
DEFUN("wheel-stop", wheel_stop, 0, 0, "Stop whe.el worker thread", NULL);
- DEFUN("wheel-button", wheel_button, 1, 1, "Check if button is pressed.", NULL);
+ DEFUN("wheel-button", wheel_button, 1, 1, "Check if button is pressed.", NULL);
+ DEFUN("wheel-set-autocenter", wheel_set_autocenter, 1, 1, "Enable/disable autocentering.", NULL);
+ DEFUN("wheel-set-autocenter-force", wheel_set_autocenter_force, 1, 1, "", NULL);
+ DEFUN("wheel-set-range", wheel_set_range, 1, 1, "", NULL);
+ DEFUN("wheel-set-gain", wheel_set_gain, 1, 1, "", NULL);
DEFUN("wheel-axis", wheel_axis, 1, 1, "Get axis value.", NULL);
provide(env, "wheel");
return 0;
diff --git a/wheelmesg.h b/wheelmesg.h
@@ -0,0 +1,27 @@
+#pragma once
+#include <stdbool.h>
+
+enum wheel_cmd_type {
+ AUTOCENTER,
+ AUTOCENTER_FORCE,
+ GAIN,
+ RANGE,
+ NONE,
+};
+
+// tagged union
+struct wheel_cmd {
+ enum wheel_cmd_type type;
+ union {
+ bool autocenter;
+ int autocenter_force;
+ int gain;
+ int range;
+ } value;
+};
+
+
+/* struct wheel_cmd a = { */
+/* .type = AUTOCENTER, */
+/* .value = { .autocenter = true } */
+/* }; */