Coder Social home page Coder Social logo

nirenjan / libx52 Goto Github PK

View Code? Open in Web Editor NEW
113.0 7.0 13.0 1.32 MB

Saitek X52/X52pro drivers & controller mapping software for Linux

Home Page: https://nirenjan.github.io/libx52

License: GNU General Public License v2.0

C 71.22% Makefile 4.69% Shell 0.17% M4 20.41% Python 3.51%
saitek linux joystick driver x52pro x52

libx52's People

Contributors

gitter-badger avatar nirenjan avatar ryandrake08 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

libx52's Issues

Typo in install instructions, causes rules to be written to /rules.d

Describe the bug

The pkg-config invocation should be:

pkg-config --variable=udevdir udev

Otherwise, at least on my openSUSE system, I get

pkg-config --variable=udev
Please specify at least one package name on the command line.

This causes the udev rules to be written to /rules.d because the subprocess does not return any output.

To Reproduce
Steps to reproduce the behavior:

  1. Execute the configure call in INSTALL.md

Compiling for macOS

Excellent library! Despite having -linux in its name, I found this software to work beautifully on macOS as well with a single change: Apple does not have ELIBACC, so you need to ./configure with -DELIBACC=EINVAL (or whatever error code you want to use that macOS supports). Other than that, it works! Feel free to conditionalize the use of ELIBACC on Linux or don't bother since the workaround is trivial.

Axis input does not get reported correctly by kernel module

The Saitek X52 has a total of 7 physical axes, although the kernel module reports 11. The following axes are not reported properly by the input interface:

Stick X
Stick Y
Stick twist (Rz)
Throttle Rx
Throttle Ry
Mouse stick X
Mouse stick Y

The Hat (HAT0X, HAT0Y), throttle and slider axes are all reported correctly (more or less).

error: cannot install 'libx52util.la' to a directory not ending in /usr/local/lib

This is a new "git clone/pull". Because of the substantial changes, I had to remove/wipe previous "git clone/pull". (ie. Wasn't sure "make clean" was going to work properly anymore, etc etc.)

./autogen && ./configure --prefix=/home/roger/src/x52pro-linux/install && make && make install

I get the following errors during "make install"

libtool: warning: remember to run 'libtool --finish /usr/local/lib'
libtool: warning: '../libx52/libx52.la' has not been installed in '/usr/local/lib'
libtool: warning: '../libx52/libx52.la' has not been installed in '/usr/local/lib'
libtool: error: error: cannot install 'libx52util.la' to a directory not ending in /usr/local/lib

Looks like the previous is defined within:
./libx52/libx52.la:libdir='/usr/local/lib'
./util/libx52util.la:libdir='/usr/local/lib'

Clock offset calculation is incorrect if local time is summer/daylight time.

With libx52_set_clock, the automatic clock offset calculation is incorrect if the local time is currently in daylight savings time.

E.g., my system is currently set to Pacific Daylight Time (UTC-07:00). However, standard time (Pacific Standard Time, UTC-08:00) is used instead to calculate the offset.

Testcase

Use x52cli to set the system clock to local time (when your system is in local daylight time). E.g. x52cli clock local 12hr ddmmyy. This should reset the offsets for the secondary and tertiary clocks back to GMT, which should display the issue.

With the previous example, if my primary clock shows 06:00pm, I expect the secondary and tertiary clocks to show 01:00am, but they show 02:00am instead.

Root Cause Analysis

This appears to be due to the use of the timezone variable, which, according to the manual, is set to the local standard time offset in seconds west of GMT, not the current local time offset. This means that timezone will always be 28800, regardless of whether it is currently daylight savings or not.

Workaround

Set primary clock to GMT and use offsets to set secondary and tertiary clock.

journal flooded with usb IO errors

Describe the bug
when plugging in the X52 the Journal is flooded with
ERROR: x52d_device.c:179 Error 8 when updating X52 device: USB input/output error
ERROR: x52d_device.c:179 Error 15 when updating X52 device: Pipe error
and a occasional ERROR: x52d_io.c:75 Error 5 reading from X52 I/O device: I/O error

To Reproduce
Steps to reproduce the behavior:

  1. plug in X52 pro HOTAS

Expected behavior
It not screaming errors left and right and able to set LED's

Screenshots/Logs
image
x52d Journal log

Environment (please complete the following information):

  • Output of x52bugreport
> sudo x52bugreport
libx52 bugreport
================
Package version: 0.3.0
Build version: v0.3.0
Built on: 2023-01-03T16:56:02+0100
version-info $Id: 9ff692993dd94efda1a444da79e175cf111e631b $

Built against:
==============
libusb API version: 0x01000109
hidapi version: 0.12.0

System versions:
================
libusb: 1.0.26.11724 (http://libusb.info)
hidapi: 0.13.1

System info:
============
Linux 6.1.5-zen2-1-zen x86_64 (#1 ZEN SMP PREEMPT_DYNAMIC Thu, 12 Jan 2023 22:42:30 +0000)

Device info:
============
Device ID: vendor 0x06a3 product 0x0762 version 0x2000
Device name: 'Logitech' 'X52 Professional H.O.T.A.S.'
Serial number: '(null)'

Additional context
Add any other context about the problem here.

0.2.2. --- erratic behavior

Describe the bug
After daemon is started and X52Pro connected, on display, mode status (1,2, 3) starts rapidly blinking. Also in game X52Pro is erratic ( it feels like it is repeating inputs, rather then holding constant value).

To Reproduce
Steps to reproduce the behavior:

  1. Just start x52d 0.2.2
  2. take a look at LCD display
  3. Blinking mode status number
  4. Soon as x52d is stopped, hotas is working normally.

Expected behavior
Normal behavior

Screenshots
If applicable, add screenshots to
x52evtest-output.txt
help explain your problem.

Environment (please complete the following information):

  • OS: Debian Sid
  • libusb version: libusb-1.0
  • X52 type: Bus 001 Device 004: ID 06a3:0762 Saitek PLC Saitek X52 Pro Flight Control System

Additional context
In attachment x52evtest output,without touching hotas. It starts soon as hotas is connected.

Configure Error on OSX Catalina

Hi,

At the configure stage I'm having an error. Here is what I have in the config.log :
configure:3851: checking for ar configure:3867: found /opt/local/bin/ar configure:3878: result: ar configure:3904: checking the archiver (ar) interface configure:3920: gcc -c -g -O2 conftest.c >&5 configure:3920: $? = 0 configure:3922: ar cru libconftest.a conftest.o >&5 /opt/local/bin/ranlib: object: libconftest.a(conftest.o) malformed object (unknown load command 1) ar: internal ranlib command failed configure:3925: $? = 1 configure:3931: ar -NOLOGO -OUT:conftest.lib conftest.o >&5 ar: illegal option -- N usage: ar -d [-TLsv] archive file ... ar -m [-TLsv] archive file ... ar -m [-abiTLsv] position archive file ... ar -p [-TLsv] archive [file ...] ar -q [-cTLsv] archive file ... ar -r [-cuTLsv] archive file ... ar -r [-abciuTLsv] position archive file ... ar -t [-TLsv] archive [file ...] ar -x [-ouTLsv] archive [file ...] configure:3934: $? = 1 configure:3953: result: unknown configure:3969: error: could not determine ar interface

I'm running OSX Catalina 10.15.4
uname -m = x86_64
uname -r = 19.4.0
uname -s = Darwin
uname -v = Darwin Kernel Version 19.4.0: Wed Mar 4 22:28:40 PST 2020; root:xnu-6153.101.6~15/RELEASE_X86_64

x52d: a single scroll event may result in multiple REL_WHEEL reports

Observed behavior
With some hardware, the joystick may report multiple events with the wheel button selected. As a result, x52d receives multiple events where the scroll button is on, but with different values in the axis reports. The following log reported by @VorpalBlade in #45 has some sample events: scrolling.log.

x52d currently only looks at the current state of the scroll buttons, therefore, faulty hardware could result in several virtual wheel events sent to the uinput node for a single scroll event on the joystick wheel.

Expected behavior
Each scroll event from the joystick should result in only 1 scroll event on the virtual mouse.

Mouse mini-stick as additional axes?

Hi,
One quick question.

Is it possible to define mini-stick as additional axes?
I'm playing Elite Dangerous and it would be great to be able to define mini-stick as analogue lateral thrust control.

build error in kernel make (gcc 4.8.3)

make

make -C /lib/modules/3.11.10-21-desktop/build M=/home/moozaad/Documents/dev/x52pro-linux/kernel_module modules
make[1]: Entering directory /usr/src/linux-3.11.10-21-obj/x86_64/desktop' CC [M] /home/moozaad/Documents/dev/x52pro-linux/kernel_module/x52joy.o /home/moozaad/Documents/dev/x52pro-linux/kernel_module/x52joy.c: In function ‘x52_init’: /home/moozaad/Documents/dev/x52pro-linux/kernel_module/x52joy.c:581:9: error: implicit declaration of function ‘err’ [-Werror=implicit-function-declaration] err("usb_register failed (errno=%d)\n", retval); ^ cc1: some warnings being treated as errors make[4]: *** [/home/moozaad/Documents/dev/x52pro-linux/kernel_module/x52joy.o] Error 1 make[3]: *** [_module_/home/moozaad/Documents/dev/x52pro-linux/kernel_module] Error 2 make[2]: *** [sub-make] Error 2 make[1]: *** [all] Error 2 make[1]: Leaving directory/usr/src/linux-3.11.10-21-obj/x86_64/desktop'
make: *** [all] Error 2

gcc (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064]
GNU Make 3.82

possible fixing kernel module for mouse?

on kernel 6.4.15-100 when using the kernel module to fix the mouse cursor it breaks the slider on the throttle

(when loaded)
S is mapped to mouse vertical
Rs is mapped to mouse horizontal
Slider now sends random buttons like the mouse vertical axis before

(when not loaded)
S is mapped to Slider
Rs is mapped to mouse vertical axis
mouse horizontal axis is broken and pushes buttons

2023-09-27.11-08-19.mp4

this is a slightly modified version that fixes the button layout to how it is originally (

/*
 * HID driver for Saitek X52 HOTAS
 *
 * Supported devices:
 *  - Saitek X52
 *  - Saitek X52 Pro
 *
 * Copyright (c) 2020 Nirenjan Krishnan
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

#include <linux/module.h>
#include <linux/hid.h>
#include <linux/bits.h>

#define VENDOR_SAITEK 0x06a3
#define DEV_X52_1 0x0255
#define DEV_X52_2 0x075c
#define DEV_X52_PRO 0x0762


static void _parse_axis_report(struct input_dev *input_dev,
                               int is_pro, u8 *data, int len)
{
    static const s32 hat_to_axis[16][2] = {
        {0, 0},
        {0, -1},
        {1, -1},
        {1, 0},
        {1, 1},
        {0, 1},
        {-1, 1},
        {-1, 0},
        {-1, -1},
    };

    u8 hat = (data[len - 2]) >> 4;

    u32 axis = (data[3] << 24) |
               (data[2] << 16) |
               (data[1] <<  8) |
               data[0];

    if (is_pro) {
        input_report_abs(input_dev, ABS_X, (axis & 0x3ff));
        input_report_abs(input_dev, ABS_Y, ((axis >> 10) & 0x3ff));
    } else {
        input_report_abs(input_dev, ABS_X, (axis & 0x7ff));
        input_report_abs(input_dev, ABS_Y, ((axis >> 11) & 0x7ff));
    }

    input_report_abs(input_dev, ABS_RZ, ((axis >> 22) & 0x3ff));
    input_report_abs(input_dev, ABS_Z, data[4]);
    input_report_abs(input_dev, ABS_RX, data[5]);
    input_report_abs(input_dev, ABS_RY, data[6]);
    input_report_abs(input_dev, ABS_MISC, data[7]);

    /* Mouse stick is always the last byte of the report */
    input_report_abs(input_dev, ABS_TILT_X, data[len-1] & 0xf);
    input_report_abs(input_dev, ABS_TILT_Y, data[len-1] >> 4);

    /* Hat is always the upper nibble of the penultimate byte of the report */
    input_report_abs(input_dev, ABS_HAT0X, hat_to_axis[hat][0]);
    input_report_abs(input_dev, ABS_HAT0Y, hat_to_axis[hat][1]);
}

/**********************************************************************
 * Mapping buttons
 * ===============
 *
 * The X52 and X52 Pro report the buttons in different orders. In order
 * to let a userspace application handle them in a generic fashion, we
 * define a map for buttons to BTN_* defines, so that one button (eg. clutch)
 * will send the same ID on both X52 and X52 Pro
 *
 * The map is defined below.
 **********************************************************************
 */
#define X52_TRIGGER_1       BTN_TRIGGER_HAPPY1
#define X52_BTN_FIRE        BTN_TRIGGER_HAPPY2
#define X52_BTN_A           BTN_TRIGGER_HAPPY3
#define X52_BTN_B           BTN_TRIGGER_HAPPY4
#define X52_BTN_C           BTN_TRIGGER_HAPPY5
#define X52_BTN_PINKIE      BTN_TRIGGER_HAPPY6
#define X52_BTN_D           BTN_TRIGGER_HAPPY7
#define X52_BTN_E           BTN_TRIGGER_HAPPY8
#define X52_BTN_T1_UP       BTN_TRIGGER_HAPPY9
#define X52_BTN_T1_DN       BTN_TRIGGER_HAPPY10
#define X52_BTN_T2_UP       BTN_TRIGGER_HAPPY11
#define X52_BTN_T2_DN       BTN_TRIGGER_HAPPY12
#define X52_BTN_T3_UP       BTN_TRIGGER_HAPPY13
#define X52_BTN_T3_DN       BTN_TRIGGER_HAPPY14
#define X52_TRIGGER_2       BTN_TRIGGER_HAPPY15
#define X52_MOUSE_LEFT      BTN_TRIGGER_HAPPY16
#define X52_MOUSE_FORWARD   BTN_TRIGGER_HAPPY17
#define X52_MOUSE_BACKWARD  BTN_TRIGGER_HAPPY18
#define X52_MOUSE_RIGHT     BTN_TRIGGER_HAPPY19
#define X52_STICK_POV_N     BTN_TRIGGER_HAPPY20
#define X52_STICK_POV_E     BTN_TRIGGER_HAPPY21
#define X52_STICK_POV_S     BTN_TRIGGER_HAPPY22
#define X52_STICK_POV_W     BTN_TRIGGER_HAPPY23
#define X52_THROT_POV_N     BTN_TRIGGER_HAPPY24
#define X52_THROT_POV_E     BTN_TRIGGER_HAPPY25
#define X52_THROT_POV_S     BTN_TRIGGER_HAPPY26
#define X52_THROT_POV_W     BTN_TRIGGER_HAPPY27
#define X52_MODE_1          BTN_TRIGGER_HAPPY28
#define X52_MODE_2          BTN_TRIGGER_HAPPY29
#define X52_MODE_3          BTN_TRIGGER_HAPPY30
#define X52_BTN_CLUTCH      BTN_TRIGGER_HAPPY31
#define X52_BTN_FUNCTION    BTN_TRIGGER_HAPPY32
#define X52_BTN_START_STOP  BTN_TRIGGER_HAPPY33
#define X52_BTN_RESET       BTN_TRIGGER_HAPPY34
#define X52_BTN_PG_UP       BTN_TRIGGER_HAPPY35
#define X52_BTN_PG_DN       BTN_TRIGGER_HAPPY36
#define X52_BTN_UP          BTN_TRIGGER_HAPPY37
#define X52_BTN_DN          BTN_TRIGGER_HAPPY38
#define X52_BTN_MFD_SELECT  BTN_TRIGGER_HAPPY39

static void _parse_button_report(struct input_dev *input_dev,
                                 int is_pro, u8 *data, int num_buttons)
{
    int i;
    int idx;
    int btn;

    // Map X52 buttons from report to fixed button ID
    // This should be defined in the order provided in the report.
    static const int x52_buttons[] = {
        X52_TRIGGER_1,
        X52_BTN_FIRE,
        X52_BTN_A,
        X52_BTN_B,
        X52_BTN_C,
        X52_BTN_PINKIE,
        X52_BTN_D,
        X52_BTN_E,
        X52_BTN_T1_UP,
        X52_BTN_T1_DN,
        X52_BTN_T2_UP,
        X52_BTN_T2_DN,
        X52_BTN_T3_UP,
        X52_BTN_T3_DN,
        X52_TRIGGER_2,
        X52_STICK_POV_N,
        X52_STICK_POV_E,
        X52_STICK_POV_S,
        X52_STICK_POV_W,
        X52_THROT_POV_N,
        X52_THROT_POV_E,
        X52_THROT_POV_S,
        X52_THROT_POV_W,
        X52_MODE_1,
        X52_MODE_2,
        X52_MODE_3,
        X52_BTN_FUNCTION,
        X52_BTN_START_STOP,
        X52_BTN_RESET,
        X52_BTN_CLUTCH,
        X52_MOUSE_LEFT,
        X52_MOUSE_RIGHT,
        X52_MOUSE_FORWARD,
        X52_MOUSE_BACKWARD,
    };

    static const int pro_buttons[] = {
        X52_TRIGGER_1,
        X52_BTN_FIRE,
        X52_BTN_A,
        X52_BTN_B,
        X52_BTN_C,
        X52_BTN_PINKIE,
        X52_BTN_D,
        X52_BTN_E,
        X52_BTN_T1_UP,
        X52_BTN_T1_DN,
        X52_BTN_T2_UP,
        X52_BTN_T2_DN,
        X52_BTN_T3_UP,
        X52_BTN_T3_DN,
        X52_TRIGGER_2,
        X52_MOUSE_LEFT,
        X52_MOUSE_FORWARD,
        X52_MOUSE_BACKWARD,
        X52_MOUSE_RIGHT,
        X52_STICK_POV_N,
        X52_STICK_POV_E,
        X52_STICK_POV_S,
        X52_STICK_POV_W,
        X52_THROT_POV_N,
        X52_THROT_POV_E,
        X52_THROT_POV_S,
        X52_THROT_POV_W,
        X52_MODE_1,
        X52_MODE_2,
        X52_MODE_3,
        X52_BTN_CLUTCH,
        X52_BTN_FUNCTION,
        X52_BTN_START_STOP,
        X52_BTN_RESET,
        X52_BTN_PG_UP,
        X52_BTN_PG_DN,
        X52_BTN_UP,
        X52_BTN_DN,
        X52_BTN_MFD_SELECT,
    };

    const int *btn_map = is_pro ? pro_buttons : x52_buttons ;

    for (i = 0; i < num_buttons; i++) {
        idx = 8 + (i / BITS_PER_BYTE);
        btn = !!(data[idx] & (1 << (i % BITS_PER_BYTE)));
        input_report_key(input_dev, btn_map[i], btn);
    }
}

static int _parse_x52_report(struct input_dev *input_dev,
                             u8 *data, int len)
{
    if (len != 14) {
        return -1;
    }

    _parse_axis_report(input_dev, 0, data, len);
    _parse_button_report(input_dev, 0, data, 34);
    return 0;
}

static int _parse_x52pro_report(struct input_dev *input_dev,
                             u8 *data, int len)
{
    if (len != 15) {
        return -1;
    }

    _parse_axis_report(input_dev, 1, data, len);
    _parse_button_report(input_dev, 1, data, 39);
    return 0;
}

static int x52_raw_event(struct hid_device *dev,
                         struct hid_report *report, u8 *data, int len)
{
    struct input_dev *input_dev = hid_get_drvdata(dev);
    int is_pro = (dev->product == DEV_X52_PRO);
    int ret;

    if (is_pro) {
        ret = _parse_x52pro_report(input_dev, data, len);
    } else {
        ret = _parse_x52_report(input_dev, data, len);
    }
    input_sync(input_dev);
    return ret;
}

static int x52_input_configured(struct hid_device *dev,
                                struct hid_input *input)
{
    struct input_dev *input_dev = input->input;
    int i;
    int max_btn;
    int is_pro = (dev->product == DEV_X52_PRO);
    int max_stick;

    hid_set_drvdata(dev, input_dev);

    set_bit(EV_KEY, input_dev->evbit);
    set_bit(EV_ABS, input_dev->evbit);

    /*
     * X52 has only 34 buttons, X52 Pro has 39. The first 34 buttons are common
     * although the button order differs between the two.
     */
    max_btn = is_pro ? 39 : 34 ;

    for (i = 0; i < max_btn; i++) {
        set_bit(BTN_TRIGGER_HAPPY1 + i, input_dev->keybit);
    }

    /* Both X52 and X52 Pro have the same number of axes, only the ranges vary */

    set_bit(ABS_X, input_dev->absbit);
    set_bit(ABS_Y, input_dev->absbit);
    set_bit(ABS_Z, input_dev->absbit);
    set_bit(ABS_RX, input_dev->absbit);
    set_bit(ABS_RY, input_dev->absbit);
    set_bit(ABS_RZ, input_dev->absbit);
    set_bit(ABS_RZ, input_dev->absbit);
    set_bit(ABS_HAT0X, input_dev->absbit);
    set_bit(ABS_HAT0Y, input_dev->absbit);
    set_bit(ABS_TILT_X, input_dev->absbit);
    set_bit(ABS_TILT_Y, input_dev->absbit);
    set_bit(ABS_MISC, input_dev->absbit);

    max_stick = is_pro ? 1023 : 2047;
    input_set_abs_params(input_dev, ABS_X, 0, max_stick, max_stick >> 8, max_stick >> 4);
    input_set_abs_params(input_dev, ABS_Y, 0, max_stick, max_stick >> 8, max_stick >> 4);
    input_set_abs_params(input_dev, ABS_RZ, 0, 1023, 3, 63);
    input_set_abs_params(input_dev, ABS_RX, 0, 255, 0, 15);
    input_set_abs_params(input_dev, ABS_RY, 0, 255, 0, 15);
    input_set_abs_params(input_dev, ABS_Z, 0, 255, 0, 15);
    input_set_abs_params(input_dev, ABS_MISC, 0, 255, 0, 15);
    input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
    input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0);
    input_set_abs_params(input_dev, ABS_TILT_X, 0, 15, 0, 0);
    input_set_abs_params(input_dev, ABS_TILT_Y, 0, 15, 0, 0);

    return 0;
}

static int x52_input_mapping(struct hid_device *dev,
                             struct hid_input *input,
                             struct hid_field *field,
                             struct hid_usage *usage,
                             unsigned long **bit,
                             int *max)
{
    /*
     * We are reporting the events in x52_raw_event.
     * Skip the hid-input processing.
     */
    return -1;
}

static const struct hid_device_id x52_devices[] = {
    { HID_USB_DEVICE(VENDOR_SAITEK, DEV_X52_1) },
    { HID_USB_DEVICE(VENDOR_SAITEK, DEV_X52_2) },
    { HID_USB_DEVICE(VENDOR_SAITEK, DEV_X52_PRO) },
    {}
};

MODULE_DEVICE_TABLE(hid, x52_devices);

static struct hid_driver x52_driver = {
    .name = "saitek-x52",
    .id_table = x52_devices,
    .input_mapping = x52_input_mapping,
    .input_configured = x52_input_configured,
    .raw_event = x52_raw_event,
};

module_hid_driver(x52_driver);


MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Nirenjan Krishnan");
MODULE_DESCRIPTION("HID driver for Saitek X52 HOTAS devices");

Option to disable use of pid file

x52d should have an option to disable use of pid file - this is requied if the daemon is controlled by systemd. Use of pid file often leads to false positive daemon running check. Or pid file on-exit cleanup should be implemented.

Failure example:

journalctl -xu x52d

...
May 15 16:37:06 flatbox.home x52d[1728]: FATAL: x52d_main.c:122 Daemon is already running as PID 1684
May 15 16:37:06 flatbox.home systemd[1]: x52d.service: Main process exited, code=exited, status=1/FAILURE
...

ps axu | grep 1684

root 1684 0.0 0.0 229568 4536 ? SLsl 16:37 0:00 /usr/libexec/low-memory-monitor

Support for x52 (non pro)

Hi, Does this driver work on the x52 (non pro)?

I just need a way to turn off those annoying leds

Default log is too verbose

Describe the bug
When I don't have my X52 connected, the journalctl logs are spammed with

ott 01 22:57:58 leon.lan x52d[910]: TRACE: x52d_device.c:37 Attempting to connect to X52 device
ott 01 22:57:58 leon.lan x52d[910]: TRACE: x52d_device.c:44 No compatible X52 device found
ott 01 22:57:58 leon.lan x52d[910]: TRACE: x52d_device.c:46 Sleeping for 5 seconds before trying to acquire device again
ott 01 22:57:58 leon.lan x52d[910]: TRACE: x52d_io.c:58 Device disconnected, trying to connect
ott 01 22:57:58 leon.lan x52d[910]: TRACE: x52d_io.c:65 No compatible X52 I/O device found. Sleeping 5 seconds before trying again.

I haven't found a way to disable this logging.

To Reproduce
Steps to reproduce the behavior:

  1. Run the daemon without a joystick attached

Expected behavior
No TRACE logs unless explicitly enabled.

X52Pro Second POV hat (metal one) LED

Is your feature request related to a problem? Please describe.
Unable to change LED color on second POV hat (metal one)

Describe the solution you'd like
To be able to change second POV hat LED color

Describe alternatives you've considered

Additional context

12 hour clock display broken for 12 AM

When the user sets the clock to a time that represents 12:00:00 AM to 12:59:59 AM in the chosen location (local/GMT), and the clock is set to display in 12 Hour mode, the MFD displays 00 AM, i.e. the hour is displayed as 0.

This appears to be a known hardware issue, at least with my unit. Setting the hour value to 12 corresponds to 12 PM, so that won't fix the problem.

build failed with doxygen enabled: missing docs/Makefile.am

make[2]: Entering directory '/home/maxb/src/x52pro-linux'
doxygen Doxyfile
warning: Tag 'TCL_SUBST' at line 270 of file 'Doxyfile' has become obsolete.
To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
warning: Tag 'COLS_IN_ALPHA_INDEX' at line 1123 of file 'Doxyfile' has become obsolete.
To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
Warning: Cannot open file tab_a.png for writing
Warning: Cannot open file tab_b.png for writing
Warning: Cannot open file tab_h.png for writing
Warning: Cannot open file tab_s.png for writing
Warning: Cannot open file nav_h.png for writing
Warning: Cannot open file nav_f.png for writing
Warning: Cannot open file bc_s.png for writing
Warning: Cannot open file closed.png for writing
Warning: Cannot open file open.png for writing
Warning: Cannot open file bdwn.png for writing
Warning: Cannot open file sync_on.png for writing
Warning: Cannot open file sync_off.png for writing
error: Could not open file /home/maxb/src/x52pro-linux/docs/html/doxygen.css for writing
make[2]: *** [Makefile:3654: docs/.stamp] Error 1
make[2]: Leaving directory '/home/maxb/src/x52pro-linux'
make[1]: *** [Makefile:2805: all-recursive] Error 1
make[1]: Leaving directory '/home/maxb/src/x52pro-linux'
make: *** [Makefile:1286: all] Error 2

x52d mouse diagonal cursor speed

Is your feature request related to a problem? Please describe.

  1. Run x52d with mouse support enabled and speed in config set to 15
  2. Connect Saitek X52 Pro
  3. Notice that horizontal and vertical movements are much slower than diagonal movements (45 degrees diagonal shows this most clearly).

Describe the solution you'd like

It feels like the speed is handled per axis. To me (given how the mouse joystick feels) I think it should be handled as "max total speed". As it is now it is very awkward to use.

It may be worth investigating how trackpoints on Thinkpads (and similar laptops) handle this, as those feel way more natural in their diagonal movements, and they are essentially also small mouse joysticks.

Describe alternatives you've considered

I considered implementing this myself and making a PR, but I want to discuss this first. I would also need to do research on how this works with track points (and if that is handled in software or hardware in that case).

Additional context

If it matters, my X52 Pro is really old, probably from the first or second year they were manufactured.

Build Instructions

How about listing some build instructions within the documentation? (Granted, I'll figure out the incantation quickly, but may stall others.)

Got compilation error after make (ini.h missing)

Hi there, when trying to compile, I get this error:

gabo@skylake ~/github/x52pro-linux $ make
make  all-recursive
.......
gcc -DHAVE_CONFIG_H -I.    -I . -I ./libx52io -I ./libx52 -I ./libx52util -I ./lib/pinelog -DSYSCONFDIR=\"/usr/etc\" -DLOCALEDIR=\"/usr/share/locale\" -DLOGDIR=\"/usr/var/log\" -DRUNDIR=\"/usr/var/run\" -pthread -fno-strict-aliasing -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes -Wdeclaration-after-statement -Wimplicit-function-declaration -Wold-style-definition -Wjump-misses-init -Wall -Wextra -Wundef -Wwrite-strings -Wpointer-arith -Wmissing-declarations -Wredundant-decls -Wno-unused-parameter -Wno-missing-field-initializers -Wformat=2 -Wcast-align -Wformat-nonliteral -Wformat-security -Wsign-compare -Wstrict-aliasing -Wshadow -Winline -Wmissing-format-attribute -Wmissing-noreturn -Winit-self -Wmissing-include-dirs -Wunused-but-set-variable -Warray-bounds -Wreturn-type -Wswitch-enum -Wswitch-default -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wrestrict -Wnull-dereference -Wdouble-promotion -Werror -Wno-suggest-attribute=format -Wno-error=unused-parameter -Wno-error=missing-field-initializers -g -O2 -MT daemon/x52d-x52d_config_parser.o -MD -MP -MF daemon/.deps/x52d-x52d_config_parser.Tpo -c -o daemon/x52d-x52d_config_parser.o `test -f 'daemon/x52d_config_parser.c' || echo './'`daemon/x52d_config_parser.c
daemon/x52d_config_parser.c:17:10: fatal error: ini.h: File o directory non esistente
   17 | #include "ini.h"
      |          ^~~~~~~
compilation terminated.
make[2]: *** [Makefile:2082: daemon/x52d-x52d_config_parser.o] Errore 1
make[2]: uscita dalla directory «/home/gabo/github/x52pro-linux»
make[1]: *** [Makefile:2485: all-recursive] Errore 1
make[1]: uscita dalla directory «/home/gabo/github/x52pro-linux»

It's probably my fault, for instance I may have some missing *-dev package, but ./configure --prefix=/usr gave me no errors, and I don't know what packages ini.h header come from...
Suggestions? Thanks in advance.

Gabriele

daemon crash on subsequent joystick reconnections

x52d daemon coredumps on subsequent physical joystick reconnections
Diagnostics below:

journalctl -xu x52d

May 22 17:07:31 flatbox.home x52d[1703]: INFO: x52d_device.c:73 Initializing libx52
May 22 17:07:31 flatbox.home x52d[1703]: INFO: x52d_device.c:35 Starting X52 device manager thread
May 22 17:07:31 flatbox.home x52d[1703]: INFO: x52d_clock.c:170 Starting X52 clock manager thread
May 22 17:31:46 flatbox.home x52d[1703]: libusb: error [udev_hotplug_event] ignoring udev action change
May 22 17:31:51 flatbox.home x52d[1703]: INFO: x52d_device.c:51 Device connected, writing configuration
May 22 21:59:45 flatbox.home x52d[1703]: libusb: error [udev_hotplug_event] ignoring udev action change
May 22 21:59:51 flatbox.home x52d[1703]: INFO: x52d_device.c:51 Device connected, writing configuration
May 22 21:59:51 flatbox.home x52d[1703]: libusb: error [do_close] Device handle closed while transfer was still being processed, but the device is still connected as far as we know
May 22 21:59:51 flatbox.home x52d[1703]: libusb: error [do_close] A cancellation hasn't even been scheduled on the transfer for which the device is closing
May 22 21:59:51 flatbox.home systemd[1]: x52d.service: Main process exited, code=dumped, status=11/SEGV

coredumpctl debug

       PID: 1703 (x52d)
       UID: 0 (root)
       GID: 0 (root)
    Signal: 11 (SEGV)
 Timestamp: Sun 2022-05-22 21:59:51 EEST (1h 53min ago)

Command Line: /usr/local/bin/x52d -f -v
Executable: /usr/local/bin/x52d
Control Group: /system.slice/x52d.service
Unit: x52d.service
Slice: system.slice
Boot ID: 5b95a2343be14ea8bc1da55cd88710b7
Machine ID: e33d9124cc344be3a8d2422f1d6be8ba
Hostname: flatbox.home
Storage: /var/lib/systemd/coredump/core.x52d.0.5b95a2343be14ea8bc1da55cd88710b7.1703.1653245991000000.zst (present)
Disk Size: 67.6K
Message: Process 1703 (x52d) of user 0 dumped core.

            Found module linux-vdso.so.1 with build-id: 250ccfeac05063b6aec6b9e764aab14fe7a350ad
            Found module libgcc_s.so.1 with build-id: b6870691657424bce223a2e63e40a74a86865cd4
            Found module ld-linux-x86-64.so.2 with build-id: 1c439781d708688791a444ca9fb2d427e77e0711
            Found module libudev.so.1 with build-id: 349aae4b9b0f8015c69d8c61f20191b6400e6903
            Found module libc.so.6 with build-id: cd3fe5b329409691a824712f6b1335893c5ca7e7
            Found module libusb-1.0.so.0 with build-id: 87775348a4f4614d71a366d83c79d9f9498e72a2
            Found module libx52.so.2 with build-id: 20444272d1da9d5a3c47f64739587c4d6b83d70e
            Found module x52d with build-id: d7abb6073b8c460ac41f0b44bf5a2ccef284f9bd
            Stack trace of thread 1736:
            #0  0x00007f98b6820015 libusb_control_transfer.cold (libusb-1.0.so.0 + 0x5015)
            #1  0x00007f98b683c2f0 libx52_vendor_command (libx52.so.2 + 0x22f0)
            #2  0x00007f98b683c64c libx52_update (libx52.so.2 + 0x264c)
            #3  0x000000000040879d x52d_dev_update (x52d + 0x879d)
            #4  0x0000000000408978 x52_dev_thr (x52d + 0x8978)
            #5  0x00007f98b66b28ca start_thread (libc.so.6 + 0xa08ca)
            #6  0x00007f98b6652500 __clone3 (libc.so.6 + 0x40500)
            
            Stack trace of thread 1703:
            #0  0x00007f98b675596f __poll (libc.so.6 + 0x14396f)
            #1  0x0000000000409d6d poll_clients (x52d + 0x9d6d)
            #2  0x00000000004029b0 main (x52d + 0x29b0)
            #3  0x00007f98b6652f60 __libc_start_call_main (libc.so.6 + 0x40f60)
            #4  0x00007f98b6653010 __libc_start_main@@GLIBC_2.34 (libc.so.6 + 0x41010)
            #5  0x00000000004031d5 _start (x52d + 0x31d5)
            
            Stack trace of thread 1737:
            #0  0x00007f98b6726ce5 clock_nanosleep@GLIBC_2.2.5 (libc.so.6 + 0x114ce5)
            #1  0x00007f98b672b887 __nanosleep (libc.so.6 + 0x119887)
            #2  0x00007f98b672b7be sleep (libc.so.6 + 0x1197be)
            #3  0x0000000000408aea x52_clock_thr (x52d + 0x8aea)
            #4  0x00007f98b66b28ca start_thread (libc.so.6 + 0xa08ca)
            #5  0x00007f98b6652500 __clone3 (libc.so.6 + 0x40500)
            
            Stack trace of thread 1717:
            #0  0x00007f98b675596f __poll (libc.so.6 + 0x14396f)
            #1  0x00007f98b68278d2 linux_udev_event_thread_main (libusb-1.0.so.0 + 0xc8d2)
            #2  0x00007f98b66b28ca start_thread (libc.so.6 + 0xa08ca)
            #3  0x00007f98b6652500 __clone3 (libc.so.6 + 0x40500)

GNU gdb (GDB) Fedora 11.2-2.fc35
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
https://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
http://www.gnu.org/software/gdb/documentation/.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/local/bin/x52d...
[New LWP 1736]
[New LWP 1703]
[New LWP 1737]
[New LWP 1717]

warning: Section `.reg-xstate/1736' in core file too small.

This GDB supports auto-downloading debuginfo from the following URLs:
https://debuginfod.fedoraproject.org/
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `/usr/local/bin/x52d -f -v'.
Program terminated with signal SIGSEGV, Segmentation fault.

warning: Section `.reg-xstate/1736' in core file too small.
#0 usbi_handling_events (ctx=) at /usr/src/debug/libusb1-1.0.25-8.fc35.x86_64/libusb/libusbi.h:484
484 return usbi_tls_key_get(ctx->event_handling_key) != NULL;
[Current thread is 1 (Thread 0x7f98a8897640 (LWP 1736))]

Debian Bullseye compile error

Hi,
I'm having trouble compiling X52pro.

I'm receiving this error after "make":

In file included from libx52/x52_common.h:14, from libx52/x52_control.c:18: /usr/include/libusb-1.0/libusb.h:934:1: error: packed attribute is unnecessary for 'libusb_control_setup' [-Werror=packed] 934 | } LIBUSB_PACKED; | ^ cc1: all warnings being treated as errors make[2]: *** [Makefile:1650: libx52/la-x52_control.lo] Error 1 make[2]: Leaving directory '/home/xxx/Downloads/x52pro-linux-master' make[1]: *** [Makefile:2390: all-recursive] Error 1 make[1]: Leaving directory '/home/xxx/Downloads/x52pro-linux-master' make: *** [Makefile:1147: all] Error 2

If you have some time, can you assist me?
Ideally, if you can make new deb file with daemon support that would be great.

hotas for dumb

🇬🇧 Hello here,
I just followed your installation procedure.

sudo apt install automake autoconf gettext autopoint libhidapi-dev libtool libusb-1.0-0-dev pkg-config python3 git libx52pro0

as well as antimicroX via the deb package

in antimicroX all buttons and axis are recognized.

but I expected a graphical interface (even simplistic) to manage the leds and text (MFD) through your program.

can you give me the instructions that I miss to arrive at a similar result as the official program saitek

Thanks in advance

===============================================================================

🇫🇷 Bonjour ici,
je viens de suivre votre procédure d'installation.
sudo apt install automake autoconf gettext autopoint libhidapi-dev libtool libusb-1.0-0-dev pkg-config python3 git libx52pro0
ainsi que antimicroX via le paquet deb

dans antimicrox l'ensemble des bouton et axe sont bien reconnu.
mais je m'attendais a une interface graphique (même simpliste) pour géré les led et texte via votre programme.

pourrez vous me donnez les instruction qu'il me manque pour arrivé a un résultat similaire que le programme officiel saitek

D'avance merci

kernel module repeatedly resets after some time

Describe the bug
after inserting the saitek_x52.ko module to fix the mouse axis showing in proton
it causes the controller to randomly reset on button inputs (afaik only from the joystick) after a good while, its not a fix time after adding sadly.

To Reproduce
Steps to reproduce the behavior:

  1. insert saitek_x52.ko module
  2. keep the controller connected (havent been able to determine the time)
  3. pressing (ringed) hat Up or for me also the pinky trigger + main trigger causes reset

Expected behavior
it not to reset

Screenshots/Logs

Environment (please complete the following information):

  • Output of x52bugreport
> sudo !!
sudo x52bugreport
libx52 bugreport
================
Package version: 0.3.0
Build version: v0.3.0
Built on: 2023-01-03T16:56:02+0100
version-info $Id: 9ff692993dd94efda1a444da79e175cf111e631b $

Built against:
==============
libusb API version: 0x01000109
hidapi version: 0.12.0

System versions:
================
libusb: 1.0.26.11724 (http://libusb.info)
hidapi: 0.13.0

System info:
============
Linux 6.1.3-zen1-1-zen x86_64 (#1 ZEN SMP PREEMPT_DYNAMIC Wed, 04 Jan 2023 16:28:17 +0000)

Device info:
============
Device ID: vendor 0x06a3 product 0x0762 version 0x2000
Device name: 'Logitech' 'X52 Professional H.O.T.A.S.'
Serial number: '(null)'
~/github/libx52/kernel_module master !2 ?4 >   

Additional context

without the kernel module it works fine, the only issue is the system seeing axis 7 & 8 which are the mouse X & Y and causing proton to go nuts

MFD time doesn't advance

Hello, I'm not sure if this is a bug, or if I missed the instructions for setting the time or if the controller has no internal clock and needs to be constantly updated (e.g. by a background process).

When I set time and date with x52cli, for example at 10:00am, the clock remains at 10:00 forever.

Am I doing anything wrong?

GPL Linking exception

@ryandrake08, I'd like to add an exception to the GPL license in order to allow proprietary applications to link with the library. Because you contributed some changes, you also own copyright on those pieces of code, and I'd like to get your OK before I change the license terms.

Any objections?

how to fix: error while loading shared libraries: libx52.so.2

So I am running Ubuntu 18.04. I followed the installation instructions in the readme but whenever I try to execute anything such as x52test or x52cli, it gives me an error saying "x52test: error while loading shared libraries: libx52.so.2: cannot open shared object file: No such file or directory"

Is there a way to fix this? Where do I get "libx52.so.2" and where do I put it?

./configure --prefix=/usr tries to install logs in /usr/var/log, fails installation ("missing operand")

Describe the bug
When configuring with --prefix=/usr, the Makefile is set up in a way that will try to create the log directory in /usr/var/log rather than /var/log. It will also fail (see output).

To Reproduce
Steps to reproduce the behavior:

  1. ./configure --prefix=/usr
  2. make
  3. sudo make install

Expected behavior
Installation should finish and not try to create bogus directories.

Environment (please complete the following information):

  • openSUSE Tumbleweed

Additional context

# sudo make install
[...]
 /usr/bin/mkdir -p '/usr/bin'
  /bin/sh ./libtool   --mode=install /usr/bin/install -c x52cli x52test x52evtest x52d '/usr/bin'
libtool: install: /usr/bin/install -c .libs/x52cli /usr/bin/x52cli
libtool: install: /usr/bin/install -c .libs/x52test /usr/bin/x52test
libtool: install: /usr/bin/install -c .libs/x52evtest /usr/bin/x52evtest
libtool: install: /usr/bin/install -c .libs/x52d /usr/bin/x52d
make  install-exec-hook
make[3]: Entering directory '/home/lb/Download/Sources/x52pro-linux'
/usr/bin/mkdir -p /usr/var/log
/usr/bin/mkdir -p 
/usr/bin/mkdir: missing operand
Try '/usr/bin/mkdir --help' for more information.

X52 Feature Report

I'm looking to get the USB interface descriptor for the Saitek X52 (VID 06a3, PID 075c or PID 0255).

On Ubuntu, you can get this info by running usbhid-dump -d 06a3, which will dump the HID report descriptor for all the Saitek devices that are connected.

Pinging the users I know have X52's - @winiciuscota, @KishCom

Add API to convert Unicode string to X52 code page

A nice to have is an API to convert any Unicode or UTF8 string to the code page supported by the X52 Pro - the display character map is shown below

X52 Pro MFD character map

However, I'm having trouble deciphering the Kana characters in the above map - I think I have something, based on comparing the glyphs with that on the Wikipedia Katakana page, but since I don't read Japanese, I'm sure whatever I've come up with is wrong.

Error: Unknown error -4

This library is exactly what I was looking for - thank you so much for developing it!

I've compiled and installed things OK, x52test successfully runs the LED brightness and MFD brightness tests (which, interestingly, seems to only dim the LEDs on the throttle/left side) -- but then cuts out with:

Testing LED FIRE
LED FIRE - OFF

led_state(LIBX52_LED_FIRE, LIBX52_LED_STATE_OFF) failed with 4
Received Illegal instruction signal, quitting...

Trying to toggle LEDs on/off does not seem to work x52cli led B amber :

Error: Unknown error -4

Other relevant details:

  • Ubuntu 20.04
  • 06a3:075c Saitek PLC X52 Flight Controller
  • Replacement ps/2 cable between throttle-side/stick-side (thought it might be pertinent to mention since I noticed the LEDs on the flight-stick/right side didn't dim with the test)
  • Added a custom udev rule that allows write access to USB without need for sudo

x52d reverse scroll wheel direction

Is your feature request related to a problem? Please describe.

The scroll wheel on the X52 Pro is mounted on the backside of the throttle. When using x52d pulling my finger back (as I would on a normal mouse wheel to scroll down) for some reason scrolls up, and vice versa.

I cannot see an option in x52d to reverse the scroll direction.

Describe the solution you'd like
An option in the config file to select scrolling direction.

Describe alternatives you've considered
I tried changing the scrolling direction in KDE settings, but that only affects my real mouse, not the X52.

Additional context
Add any other context or screenshots about the feature request here.

Allow to specify the group used in udev rules

Is your feature request related to a problem? Please describe.
Not all Linux distributions use plugdev for groups allowed to access input devices. openSUSE, for example, has an input group.

Describe the solution you'd like
Keep plugdev as default, but allow changing this in a configure call.

Describe alternatives you've considered
Replacing the group manually before installing, but for any distribution doing packaging that would be probably extra effort, and potentially error prone.

FATAL: x52d_main.c:117 Daemon is already running as PID 23488

whenever i run any commands it will throw a fatal message (FATAL: x52d_main.c:117 Daemon is already running as PID 22828)

when running anything other than x52d -h it throws a permission error

when using sudo x52d running any command after that (other than x52d -h) it will give the "FATAL" error
image

support for setting multiple leds at once

having the ability to set multiple led's at once would be a great feature (idk how else to put it)
example:

x52cli led A B D E I amber

EDIT: i found a workaround for my needs

function LEDcolor(){
    for(var i=0; i<arguments.length-1;i++)//dont loop over last one... thats the color
    {
    msg.payload= "led ".concat(arguments[i]," ",arguments[arguments.length-1])
    node.send(msg);
    }
}

im using node-red to read the game's status and depending on it change the led's... that code snippet just takes X variables as long as the last one is a state (on,off,red,amber,green)

Incorrect link to Arch Linux AUR package in README.

Describe the bug

The link in the README.md here on github to the Arch Linux AUR package for libx52 is broken (404). The correct link these days appears to be https://aur.archlinux.org/packages/libx52/

To Reproduce
Steps to reproduce the behavior:

  1. Click link to AUR at https://github.com/nirenjan/libx52

Expected behavior
Link should take me to the package page for this package at AUR.

Screenshots/Logs
Not applicable.

Environment (please complete the following information):

  • OS: Arch Linux
  • libusb 1.0.24-2 (but not relevant to this bug)
  • X52 Pro

Installation and config

Hello.
First I would like to thank you for your effort programming this plugin. I would like to know if you can make a step by step how to install this on Ubuntu 18.04 and how to configure all the settings. In fact my x52pro works great by default but I would like to know how to turn off the led lights.

Thank you in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.