Skip to content

Commit 99fb36d

Browse files
committed
log indirection
1 parent 31ef475 commit 99fb36d

1 file changed

Lines changed: 90 additions & 42 deletions

File tree

main.c

Lines changed: 90 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,21 @@
1212
#include <stdint.h>
1313
#include <getopt.h>
1414
#include <sys/file.h>
15+
#include <stdarg.h>
1516
#include <X11/Xlib.h>
1617
#include <X11/extensions/XInput2.h>
1718
#include <X11/extensions/XTest.h>
1819
#include <X11/extensions/Xfixes.h>
1920

20-
static const char* PROGRAM_VERSION = "1.0";
21-
static int is_active = False;
22-
static int scrolls_since_active = 0;
23-
#define ALT_KEY_CODE 64
21+
enum LogLevel
22+
{
23+
LOG_OFF,
24+
LOG_FATAL,
25+
LOG_ERROR,
26+
LOG_WARN,
27+
LOG_INFO,
28+
LOG_DEBUG,
29+
};
2430

2531
enum ScrollDirection
2632
{
@@ -52,6 +58,27 @@ struct Config {
5258
int trigger_key_modifiers;
5359
};
5460

61+
static const char* PROGRAM_VERSION = "1.0";
62+
static int is_active = False;
63+
static int scrolls_since_active = 0;
64+
static enum LogLevel log_level = LOG_INFO;
65+
#define CAPSLOCK_KEY_CODE 66
66+
67+
void logg(enum LogLevel level, const char* fmt, ...)
68+
{
69+
va_list args;
70+
va_start(args, fmt);
71+
if ((level == LOG_ERROR && log_level >= LOG_ERROR) || (level == LOG_FATAL && log_level >= LOG_FATAL))
72+
{
73+
vfprintf(stderr, fmt, args);
74+
}
75+
else if (log_level >= level)
76+
{
77+
vfprintf(stdout, fmt, args);
78+
}
79+
va_end(args);
80+
}
81+
5582
struct Config create_default_config()
5683
{
5784
struct Config cfg =
@@ -62,12 +89,25 @@ struct Config create_default_config()
6289
.show_debug_output = False,
6390
.is_toggle_mode_on = False,
6491
.release_trigger_button = True,
65-
.trigger_key_code = ALT_KEY_CODE,
92+
.trigger_key_code = CAPSLOCK_KEY_CODE,
6693
.trigger_key_modifiers = 0,
6794
};
6895
return cfg;
6996
}
7097

98+
void print_cfg(struct Config* cfg)
99+
{
100+
printf("config:\n");
101+
printf("mouse_move_delta_to_scroll_threshold %i\n", cfg->mouse_move_delta_to_scroll_threshold);
102+
printf("allow_horizontal_scroll %i\n", cfg->allow_horizontal_scroll);
103+
printf("allow_triggering_of_repeated_scroll_event %i\n", cfg->allow_triggering_of_repeated_scroll_event);
104+
printf("show_debug_output %i\n", cfg->show_debug_output);
105+
printf("is_toggle_mode_on %i\n", cfg->is_toggle_mode_on);
106+
printf("release_trigger_button %i\n", cfg->release_trigger_button);
107+
printf("trigger_key_code %i\n", cfg->trigger_key_code);
108+
printf("trigger_key_modifiers %i\n", cfg->trigger_key_modifiers);
109+
}
110+
71111
void parse_args_into_config(int argc, char** argv, struct Config* cfg) {
72112
char *cvalue = NULL;
73113
int c;
@@ -81,7 +121,7 @@ void parse_args_into_config(int argc, char** argv, struct Config* cfg) {
81121
intmax_t num = strtoimax(optarg, NULL, 10);
82122
if (errno == ERANGE)
83123
{
84-
fprintf(stderr, "error parsing value for -%c. It must be a positive integer.",c);
124+
logg(LOG_FATAL, "error parsing value for -%c. It must be a positive integer.", c);
85125
exit(-1);
86126
}
87127
cfg->mouse_move_delta_to_scroll_threshold = (uint) labs(num);
@@ -93,22 +133,22 @@ void parse_args_into_config(int argc, char** argv, struct Config* cfg) {
93133
intmax_t num = strtoimax(optarg, NULL, 10);
94134
if (errno == ERANGE)
95135
{
96-
fprintf(stderr, "error parsing value for -%c. It must be an integer.", c);
136+
logg(LOG_FATAL, "error parsing value for -%c. It must be an integer.", c);
97137
exit(-1);
98138
}
99139
cfg->trigger_key_code = (int) num;
100140

101141
// look for optional modifier arg
102142
if (optind < argc && *argv[optind] != '-')
103143
{
104-
num = strtoimax(argv[optind], NULL, 0);
105-
optind++;
106-
if (errno == ERANGE)
107-
{
108-
fprintf(stderr, "error parsing optional second value for -%c. It must be an integer.", c);
109-
exit(-1);
110-
}
111-
cfg->trigger_key_modifiers = (int) num;
144+
num = strtoimax(argv[optind], NULL, 0);
145+
optind++;
146+
if (errno == ERANGE)
147+
{
148+
logg(LOG_FATAL, "error parsing optional second value for -%c. It must be an integer.", c);
149+
exit(-1);
150+
}
151+
cfg->trigger_key_modifiers = (int) num;
112152
}
113153
break;
114154
}
@@ -139,6 +179,7 @@ void parse_args_into_config(int argc, char** argv, struct Config* cfg) {
139179
break;
140180
case 'd':
141181
cfg->show_debug_output = True;
182+
log_level = LOG_DEBUG;
142183
break;
143184
case 'v':
144185
printf("%s\n", PROGRAM_VERSION);
@@ -167,8 +208,8 @@ static void request_to_receive_events(Display *dpy, Window win)
167208

168209
/* select for button and key events from all master devices */
169210
XISetMask(mask1, XI_RawMotion);
170-
// XISetMask(mask1, XI_ButtonPress);
171-
// XISetMask(mask1, XI_ButtonRelease);
211+
// XISetMask(mask1, XI_ButtonPress);
212+
// XISetMask(mask1, XI_ButtonRelease);
172213
XISetMask(mask1, XI_KeyPress);
173214
XISetMask(mask1, XI_KeyRelease);
174215

@@ -189,13 +230,15 @@ static int has_xi2(Display *dpy)
189230
int minor = 2;
190231

191232
int rc = XIQueryVersion(dpy, &major, &minor);
192-
if (rc == BadRequest) {
193-
fprintf(stderr, "No XI2 support. Server supports version %d.%d only.\n", major, minor);
233+
if (rc == BadRequest)
234+
{
235+
logg(LOG_FATAL, "No XI2 support. Server supports version %d.%d only.\n", major, minor);
194236
return 0;
195-
} else if (rc != Success) {
196-
fprintf(stderr, "Internal Error! This is a bug in Xlib.\n");
197237
}
198-
// printf("XI2 supported. Server provides version %d.%d.\n", major, minor);
238+
else if (rc != Success)
239+
{
240+
logg(LOG_WARN, "Internal Error! This is a bug in Xlib.\n");
241+
}
199242

200243
return 1;
201244
}
@@ -207,11 +250,10 @@ void trigger_scroll(Display* display, struct Config* cfg, enum ScrollDirection s
207250
{
208251
if (amount == 0) return;
209252

210-
if (cfg->show_debug_output)
211-
printf("scroll %s, %dx %s\n",
212-
scrollDirection == SCROLL_VERTICAL ? "v" : "h",
213-
cfg->allow_triggering_of_repeated_scroll_event ? abs(amount) : 1,
214-
amount < 0 ? "up" : "down");
253+
logg(LOG_INFO, "scroll %s, %dx %s\n",
254+
scrollDirection == SCROLL_VERTICAL ? "v" : "h",
255+
cfg->allow_triggering_of_repeated_scroll_event ? abs(amount) : 1,
256+
amount < 0 ? "up" : "down");
215257

216258
uint negative_scroll_amount_btn = scrollDirection == SCROLL_VERTICAL ? SCROLL_UP : SCROLL_LEFT;
217259
uint postitive_scroll_amount_btn = scrollDirection == SCROLL_VERTICAL ? SCROLL_DOWN : SCROLL_RIGHT;
@@ -248,7 +290,7 @@ int ensure_xinput2_or_exit(Display* display)
248290
{
249291
int xi_opcode, event, error;
250292
if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
251-
fprintf(stderr, "Error: X Input extension not available.");
293+
logg(LOG_FATAL, "Error: X Input extension not available.");
252294
exit(-3);
253295
}
254296

@@ -263,7 +305,7 @@ Display* open_display_or_exit()
263305
char* display_name = NULL;
264306
Display* display;
265307
if ((display = XOpenDisplay(display_name)) == NULL) {
266-
fprintf(stderr, "Failed to open display.\n");
308+
logg(LOG_FATAL, "Failed to open display.\n");
267309
exit(-1);
268310
}
269311
return display;
@@ -282,6 +324,8 @@ void set_is_active(Bool active, Display* display, Window window)
282324
{
283325
if (active == is_active) return;
284326

327+
logg(LOG_INFO, active ? "activating\n" : "deactivating\n");
328+
285329
is_active = active;
286330
scrolls_since_active = 0; // reset
287331

@@ -294,12 +338,11 @@ void set_is_active(Bool active, Display* display, Window window)
294338

295339
void check_for_scroll_trigger(enum ScrollDirection scroll_direction, double* total_movement_delta, double delta, struct Config* cfg, Display* display)
296340
{
297-
if (cfg->show_debug_output)
298-
printf ("check: dir: %s, total_movement_delta: %g, delta: %g, thres: %d\n",
299-
scroll_direction == SCROLL_VERTICAL ? "v" : "h",
300-
*total_movement_delta,
301-
delta,
302-
cfg->mouse_move_delta_to_scroll_threshold);
341+
logg(LOG_DEBUG, "check: dir: %s, total_movement_delta: %g, delta: %g, thres: %d\n",
342+
scroll_direction == SCROLL_VERTICAL ? "v" : "h",
343+
*total_movement_delta,
344+
delta,
345+
cfg->mouse_move_delta_to_scroll_threshold);
303346

304347
*total_movement_delta += delta;
305348
if (fabs(*total_movement_delta) > cfg->mouse_move_delta_to_scroll_threshold)
@@ -325,7 +368,7 @@ int find_input_device_id_by_name(Display* display, const char* device_name)
325368
XDeviceInfo* dd = XListInputDevices(display, &numDevices);
326369
for (int i = 0; i < numDevices; i++)
327370
{
328-
// printf("%s %ld %ld\n", dd[i].name, dd[i].id);
371+
// printf("%s %ld %ld\n", dd[i].name, dd[i].id);
329372
fflush(stdout);
330373
if (strcasecmp(dd[i].name, device_name) == 0)
331374
{
@@ -339,7 +382,7 @@ int find_input_device_id_by_name(Display* display, const char* device_name)
339382

340383
Bool is_trigger_shortcut(int key_code, int modifiers, struct Config* cfg)
341384
{
342-
// printf("k %d, mod %d", key_code, modifiers);
385+
// printf("k %d, mod %d", key_code, modifiers);
343386
if (cfg->trigger_key_modifiers > 0 // need to check modifiers?
344387
&& (modifiers & cfg->trigger_key_modifiers) != modifiers) // check modifiers
345388
{
@@ -366,18 +409,22 @@ void ensure_single_instance_or_exit()
366409
int main(int argc, char **argv)
367410
{
368411
ensure_single_instance_or_exit();
369-
Display* display = open_display_or_exit();
370-
int xi_opcode = ensure_xinput2_or_exit(display);
371412

372413
struct Config cfg = create_default_config();
373414
parse_args_into_config(argc, argv, &cfg);
374415

416+
if (cfg.show_debug_output)
417+
print_cfg(&cfg);
418+
419+
Display* display = open_display_or_exit();
420+
int xi_opcode = ensure_xinput2_or_exit(display);
421+
375422
Window window = DefaultRootWindow(display);
376423
request_to_receive_events(display, window);
377424

378425
int xtest_keyboard_device_id = find_input_device_id_by_name(display, "Virtual core XTEST keyboard");
379426
if (xtest_keyboard_device_id == -1)
380-
printf("warn: could not find 'Virtual core XTEST keyboard'. Things might not work well.");
427+
logg(LOG_WARN, "could not find 'Virtual core XTEST keyboard'. Things might not work well.");
381428

382429
struct ScreenPoint start_pointer_pos = get_pointer_position(display, window);
383430

@@ -403,7 +450,7 @@ int main(int argc, char **argv)
403450
int key_code = event->detail;
404451
Bool is_repeat = event->flags & XIKeyRepeat;
405452
if (cfg.show_debug_output)
406-
printf("KeyPress: key_code %d, mods %d, is_repeat %d\n", key_code, event->mods.base, is_repeat);
453+
logg(LOG_DEBUG, "KeyPress: key_code %d, mods %d, is_repeat %d\n", key_code, event->mods.base, is_repeat);
407454

408455
if (event->deviceid != xtest_keyboard_device_id
409456
&& is_trigger_shortcut(key_code, event->mods.base, &cfg)
@@ -425,11 +472,11 @@ int main(int argc, char **argv)
425472
}
426473
case XI_KeyRelease:
427474
{
428-
printf("KEY RELEASE");
429475
if (!cfg.is_toggle_mode_on)
430476
{
431477
XIDeviceEvent* event = (XIDeviceEvent*) cookie->data;
432478
int key_code = event->detail;
479+
logg(LOG_DEBUG, "KeyRelease: key_code %d, mods %d\n", key_code, event->mods.base);
433480
if (event->deviceid != xtest_keyboard_device_id
434481
&& is_active
435482
&& is_trigger_shortcut(key_code, 0, &cfg))
@@ -444,6 +491,7 @@ int main(int argc, char **argv)
444491
case XI_RawMotion:
445492
if (!is_active)
446493
break;
494+
447495
/// fixate pointer (set pointer to start pos): not the best solution (is wiggles a bit) but I've not found a bette one (maybe hide the cursor while scrolling to hide the wiggling)
448496
XWarpPointer(display, None, window, 0, 0, 0, 0,
449497
start_pointer_pos.x, start_pointer_pos.y);

0 commit comments

Comments
 (0)