Skip to content

Commit

Permalink
Added command line arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
Vftdan committed Jan 1, 2020
1 parent a6e4e6c commit 0f57ea9
Showing 1 changed file with 181 additions and 3 deletions.
184 changes: 181 additions & 3 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <limits.h>
#include <string.h>
#include <xcb/xcb.h>

const long MS_SLEEP_MAX = (UINT_MAX + 1L) * 1000 - 1;

xcb_connection_t *conn = NULL;
char running;
char grabk = 1;
char grabp = 1;
char grabk = 0;
char grabp = 0;

void sig_handler(int sig)
{
Expand Down Expand Up @@ -111,8 +115,178 @@ void check_pointer(xcb_screen_t* screen)
);
}

void sleep_ms(long ms)
{
sleep((unsigned int)(ms / 1000));
usleep((unsigned int)((ms % 1000) * 1000));
}

char try_parse_long(char * str, long * result)
{
char * endptr = NULL;
*result = strtol(str, &endptr, 10);
if (*endptr != '\0')
return 1;
return 0;
}

int set_max_iters(char * str, long * max_iters_ptr)
{
long int val = 0;
if (try_parse_long(str, &val) != 0)
{
fprintf(stderr, "Invalid number: \"%s\"\n", str);
return 4;
}
if (val < -1)
{
fprintf(stderr, "Iterations number out of range: %s\n", str);
return 5;
}
*max_iters_ptr = val;
return 0;
}

int set_delay_ms(char * str, long * delay_ms_ptr)
{
long int val = 0;
if (try_parse_long(str, &val) != 0)
{
fprintf(stderr, "Invalid number: \"%s\"\n", str);
return 4;
}
if (val < 1 || val > MS_SLEEP_MAX)
{
fprintf(stderr, "Delay duration out of range: %s\n", str);
return 5;
}
*delay_ms_ptr = val;
return 0;
}

int main(int argc, char ** argv)
{
long max_iters = -1;
long delay_ms = 150;

char show_usage = 0;

int argi;
for (argi = 1; argi < argc; argi++)
{
char * arg = argv[argi];
if (arg[0] == '-')
{
if (arg[1] == '-')
{
arg += 2;
if (!strcmp(arg, "pointer"))
{
grabp = 1;
}
else if (!strcmp(arg, "keyboard"))
{
grabk = 1;
}
else if (!strcmp(arg, "number"))
{
if (++argi >= argc)
{
fprintf(stderr, "Argument expected after: \"%s\"\n", arg - 2);
return 3;
}
int status = set_max_iters(argv[argi], &max_iters);
if (status)
return status;
}
else if (!strcmp(arg, "delay"))
{
if (++argi >= argc)
{
fprintf(stderr, "Argument expected after: \"%s\"\n", arg - 2);
return 3;
}
int status = set_delay_ms(argv[argi], &delay_ms);
if (status)
return status;
}
else if (!strcmp(arg, "help"))
{
show_usage = 1;
}
else
{
fprintf(stderr, "Unknown option: \"%s\"\n", arg - 2);
return 2;
}
}
else
{
while (arg[1] != 0)
{
++arg;
switch(*arg)
{
case 'p': grabp = 1; break;
case 'k': grabk = 1; break;
case 'n':
if (++argi >= argc)
{
fprintf(stderr, "Argument expected after: \"%s\"\n", arg - 2);
return 3;
}
int status = set_max_iters(argv[argi], &max_iters);
if (status)
return status;
break;
case 'd':
if (++argi >= argc)
{
fprintf(stderr, "Argument expected after: \"%s\"\n", arg - 2);
return 3;
}
status = set_delay_ms(argv[argi], &delay_ms);
if (status)
return status;
break;
case 'h': show_usage = 1; break;
default:
fprintf(stderr, "Unknown option: \"-%c\"\n", *arg);
return 2;
}
}
}
}
else
{
fprintf(stderr, "Option expected: \"%s\"\n", arg);
return 2;
}
}

if (show_usage)
{
printf("Usage: %s <OPTIONS...>\n"\
"Options:\n"\
" -p, --pointer Detect pointer grabbing\n"\
" -k, --keyboard Detect keyboard grabbing\n"\
" -n <N>, --number <N> Iterations number, -1 for infinity\n"\
" -d <N>, --delay <N> Delay duration (ms)\n"\
" -h, --help Show this message\n"\
"Limits:\n"\
" -1 <= iterations number <= %li\n"\
" 1 <= delay duration <= %li\n"\
, argv[0], LONG_MAX, MS_SLEEP_MAX);
return 0;
}

if (!grabk && !grabp)
{
fprintf(stderr, "--keyboard and/or --pointer should be passed\n"\
"Pass --help for usage\n");
return 6;
}

conn = xcb_connect(NULL, NULL);
if (xcb_connection_has_error(conn))
{
Expand All @@ -133,14 +307,18 @@ int main(int argc, char ** argv)
signal(SIGUSR2, sig_handler);

running = 1;
unsigned long i = 0;
while (running)
{
if (max_iters != -1 && i++ >= max_iters)
break;
if (grabk)
check_keyboard(screen);
if (grabp)
check_pointer(screen);
xcb_flush(conn);
usleep(150000);
if (running)
sleep_ms(delay_ms);
}
return 0;
}

0 comments on commit 0f57ea9

Please sign in to comment.