Skip to content

Instantly share code, notes, and snippets.

@jasonwhite
Last active June 24, 2025 13:01
Show Gist options
  • Save jasonwhite/c5b2048c15993d285130 to your computer and use it in GitHub Desktop.
Save jasonwhite/c5b2048c15993d285130 to your computer and use it in GitHub Desktop.

Revisions

  1. jasonwhite revised this gist Oct 19, 2019. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions joystick.c
    Original file line number Diff line number Diff line change
    @@ -128,6 +128,8 @@ int main(int argc, char *argv[])
    /* Ignore init events. */
    break;
    }

    fflush(stdout);
    }

    close(js);
  2. jasonwhite revised this gist Oct 17, 2019. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions joystick.c
    Original file line number Diff line number Diff line change
    @@ -15,6 +15,7 @@
    */
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <linux/joystick.h>


  3. jasonwhite revised this gist Jun 10, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion joystick.c
    Original file line number Diff line number Diff line change
    @@ -121,7 +121,7 @@ int main(int argc, char *argv[])
    case JS_EVENT_AXIS:
    axis = get_axis_state(&event, axes);
    if (axis < 3)
    printf("Axis %u at (%6d, %6d)\n", axis, axes[axis].x, axes[axis].y);
    printf("Axis %zu at (%6d, %6d)\n", axis, axes[axis].x, axes[axis].y);
    break;
    default:
    /* Ignore init events. */
  4. jasonwhite revised this gist Dec 20, 2014. 1 changed file with 26 additions and 1 deletion.
    27 changes: 26 additions & 1 deletion joystick.c
    Original file line number Diff line number Diff line change
    @@ -36,6 +36,31 @@ int read_event(int fd, struct js_event *event)
    return -1;
    }

    /**
    * Returns the number of axes on the controller or 0 if an error occurs.
    */
    size_t get_axis_count(int fd)
    {
    __u8 axes;

    if (ioctl(fd, JSIOCGAXES, &axes) == -1)
    return 0;

    return axes;
    }

    /**
    * Returns the number of buttons on the controller or 0 if an error occurs.
    */
    size_t get_button_count(int fd)
    {
    __u8 buttons;
    if (ioctl(fd, JSIOCGBUTTONS, &buttons) == -1)
    return 0;

    return buttons;
    }

    /**
    * Current state of an axis.
    */
    @@ -106,4 +131,4 @@ int main(int argc, char *argv[])

    close(js);
    return 0;
    }
    }
  5. jasonwhite created this gist Dec 16, 2014.
    109 changes: 109 additions & 0 deletions joystick.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,109 @@
    /**
    * Author: Jason White
    *
    * Description:
    * Reads joystick/gamepad events and displays them.
    *
    * Compile:
    * gcc joystick.c -o joystick
    *
    * Run:
    * ./joystick [/dev/input/jsX]
    *
    * See also:
    * https://www.kernel.org/doc/Documentation/input/joystick-api.txt
    */
    #include <fcntl.h>
    #include <stdio.h>
    #include <linux/joystick.h>


    /**
    * Reads a joystick event from the joystick device.
    *
    * Returns 0 on success. Otherwise -1 is returned.
    */
    int read_event(int fd, struct js_event *event)
    {
    ssize_t bytes;

    bytes = read(fd, event, sizeof(*event));

    if (bytes == sizeof(*event))
    return 0;

    /* Error, could not read full event. */
    return -1;
    }

    /**
    * Current state of an axis.
    */
    struct axis_state {
    short x, y;
    };

    /**
    * Keeps track of the current axis state.
    *
    * NOTE: This function assumes that axes are numbered starting from 0, and that
    * the X axis is an even number, and the Y axis is an odd number. However, this
    * is usually a safe assumption.
    *
    * Returns the axis that the event indicated.
    */
    size_t get_axis_state(struct js_event *event, struct axis_state axes[3])
    {
    size_t axis = event->number / 2;

    if (axis < 3)
    {
    if (event->number % 2 == 0)
    axes[axis].x = event->value;
    else
    axes[axis].y = event->value;
    }

    return axis;
    }

    int main(int argc, char *argv[])
    {
    const char *device;
    int js;
    struct js_event event;
    struct axis_state axes[3] = {0};
    size_t axis;

    if (argc > 1)
    device = argv[1];
    else
    device = "/dev/input/js0";

    js = open(device, O_RDONLY);

    if (js == -1)
    perror("Could not open joystick");

    /* This loop will exit if the controller is unplugged. */
    while (read_event(js, &event) == 0)
    {
    switch (event.type)
    {
    case JS_EVENT_BUTTON:
    printf("Button %u %s\n", event.number, event.value ? "pressed" : "released");
    break;
    case JS_EVENT_AXIS:
    axis = get_axis_state(&event, axes);
    if (axis < 3)
    printf("Axis %u at (%6d, %6d)\n", axis, axes[axis].x, axes[axis].y);
    break;
    default:
    /* Ignore init events. */
    break;
    }
    }

    close(js);
    return 0;
    }