File 0001-Port-ffmvforce-to-SDL2-some-bugfixes.patch of Package linuxconsoletools
From 3aa2d246550f506850d53d9f6914c3371adf0474 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
Date: Thu, 1 Aug 2019 18:00:02 +0200
Subject: [PATCH] Port ffmvforce to SDL2, some bugfixes
This also adds some features and does some minor bugfixes:
- Mouse clicks are honored: a click without movement only generates
a BUTTONDOWN, but no MOTION event.
- The last position is always forwarded to the FF device, previously
all events after the last generated event were dropped if they fell
into the same update period.
- The four quadrants are shown in the window, and a line from the center
to the last event position drawn.
---
utils/Makefile | 4 +-
utils/ffmvforce.c | 100 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 79 insertions(+), 25 deletions(-)
diff --git a/utils/Makefile b/utils/Makefile
index 864b017d..b565cf97 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -51,10 +51,10 @@ ffcfstress: ffcfstress.c
$(CC) $(CFLAGS) $(CPPFLAGS) -funsigned-char $^ $(LDFLAGS) -lm -o $@
ffmvforce.o: ffmvforce.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -c $^ -o $@ `sdl-config --cflags`
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c $^ -o $@ `sdl2-config --cflags`
ffmvforce: ffmvforce.o
- $(CC) $^ -o $@ $(LDFLAGS) -g -lm `sdl-config --libs`
+ $(CC) $^ -o $@ $(LDFLAGS) -g -lm `sdl2-config --libs`
axbtnmap.o: axbtnmap.c axbtnmap.h
diff --git a/utils/ffmvforce.c b/utils/ffmvforce.c
index efe0511c..a4bb6353 100644
--- a/utils/ffmvforce.c
+++ b/utils/ffmvforce.c
@@ -43,9 +43,12 @@
#define max(a,b) ((a)>(b)?(a):(b))
/* File descriptor of the force feedback /dev entry */
-static int ff_fd;
+static int ff_fd = -1;
static struct ff_effect effect;
+static SDL_Window* window = NULL;
+static SDL_Renderer* renderer = NULL;
+
static void welcome()
{
const char* txt[] = {
@@ -112,18 +115,29 @@ printf("level: %04x direction: %04x\n", (unsigned int)effect.u.constant.level, (
first = 0;
}
+static void shutdown()
+{
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+
+ SDL_Quit();
+ if (ff_fd >= 0) {
+ close(ff_fd);
+ }
+}
+
int main(int argc, char** argv)
{
- SDL_Surface* screen;
const char * dev_name = "/dev/input/event0";
- int i;
- Uint32 ticks, period = 200;
+ Uint32 ticks, timeout, period = 200;
+ Sint32 x = WIN_W / 2, y = WIN_H / 2;
+ Uint32 state = 0;
welcome();
if (argc <= 1) return 0;
/* Parse parameters */
- for (i=1; i<argc; ++i) {
+ for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--help") == 0) {
printf("Usage: %s /dev/input/eventXX [-u update frequency in HZ]\n", argv[0]);
printf("Generates constant force effects depending on the position of the mouse\n");
@@ -142,14 +156,21 @@ int main(int argc, char** argv)
}
/* Initialize SDL */
- if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) {
fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
exit(1);
}
- atexit(SDL_Quit);
- screen = SDL_SetVideoMode(WIN_W, WIN_H, 0, SDL_SWSURFACE);
- if (screen == NULL) {
- fprintf(stderr, "Could not set video mode: %s\n", SDL_GetError());
+ atexit(&shutdown);
+
+ window = SDL_CreateWindow("ffmvforce", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIN_W, WIN_H, 0);
+ if (!window) {
+ fprintf(stderr, "Could not create window: %s\n", SDL_GetError());
+ exit(1);
+ }
+
+ renderer = SDL_CreateRenderer(window, -1, 0);
+ if (!renderer) {
+ fprintf(stderr, "Could not create renderer: %s\n", SDL_GetError());
exit(1);
}
@@ -161,25 +182,58 @@ int main(int argc, char** argv)
}
ticks = SDL_GetTicks();
+ timeout = ticks + period;
+
/* Main loop */
for (;;) {
SDL_Event event;
- SDL_WaitEvent(&event);
- switch (event.type) {
- case SDL_QUIT:
- exit(0);
- break;
-
- case SDL_MOUSEMOTION:
- if (event.motion.state && SDL_GetTicks()-ticks > period) {
- ticks = SDL_GetTicks();
- generate_force(event.motion.x, event.motion.y);
+ if (state) {
+ SDL_WaitEventTimeout(&event, period);
+ } else {
+ SDL_WaitEvent(&event);
+ }
+
+ do {
+ if (event.type == SDL_QUIT) {
+ exit(0);
+
+ } else if (event.type == SDL_KEYDOWN) {
+ switch(event.key.keysym.sym) {
+ case SDLK_ESCAPE:
+ case SDLK_q:
+ exit(0);
+ default:
+ break;
+ }
+
+ } else if (event.type == SDL_MOUSEBUTTONDOWN) {
+ state = event.button.state;
+ x = event.button.x;
+ y = event.button.y;
+
+ } else if (event.type == SDL_MOUSEMOTION && event.motion.state) {
+ state = event.motion.state;
+ x = event.motion.x;
+ y = event.motion.y;
}
-
- break;
+ } while(SDL_PollEvent(&event));
+
+ ticks = SDL_GetTicks();
+ if (state && SDL_TICKS_PASSED(ticks, timeout)) {
+ timeout = ticks + period;
+ generate_force(x, y);
+ state = 0;
}
+
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
+ SDL_RenderClear(renderer);
+ SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
+ SDL_RenderDrawLine(renderer, 0, WIN_H / 2, WIN_W, WIN_H / 2);
+ SDL_RenderDrawLine(renderer, WIN_W / 2, 0, WIN_W / 2, WIN_H);
+ SDL_RenderDrawLine(renderer, WIN_W / 2, WIN_H / 2, x, y);
+ SDL_RenderPresent(renderer);
}
- return 0;
+ exit(0);
}
--
2.22.0