From 1225425e66013646cd68d02009b7bec6136e5006 Mon Sep 17 00:00:00 2001 From: KIM Hyeok Date: Tue, 26 May 2020 11:24:54 +0900 Subject: [PATCH 01/16] Add support of right side modifier keys. --- common.c | 26 ++++++++++++++++++++++++++ common.h | 4 ++++ footswitch.c | 22 +++++++++++++++++----- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/common.c b/common.c index 0043721..2853fa4 100644 --- a/common.c +++ b/common.c @@ -184,7 +184,9 @@ static const keymap_entry keymap[] = {"XF86AudioRaiseVolume", 0x80}, {"XF86AudioLowerVolume", 0x81}, {"<82>", 0x82}, + {"Hangul", 0x82}, {"<83>", 0x83}, + {"Hangul_Hanja",0x83}, {"A", 0x84}, {"B", 0x85}, {"C", 0x86}, @@ -326,6 +328,30 @@ Bool parse_modifier(const char *arg, enum modifier *mod) { } else if (strcasecmp("shift", arg) == 0) { *mod = SHIFT; return 1; + } else if (strcasecmp("l_ctrl", arg) == 0) { + *mod = CTRL; + return 1; + } else if (strcasecmp("l_alt", arg) == 0) { + *mod = ALT; + return 1; + } else if (strcasecmp("l_win", arg) == 0) { + *mod = WIN; + return 1; + } else if (strcasecmp("l_shift", arg) == 0) { + *mod = SHIFT; + return 1; + } else if (strcasecmp("r_ctrl", arg) == 0) { + *mod = R_CTRL; + return 1; + } else if (strcasecmp("r_alt", arg) == 0) { + *mod = R_ALT; + return 1; + } else if (strcasecmp("r_win", arg) == 0) { + *mod = R_WIN; + return 1; + } else if (strcasecmp("r_shift", arg) == 0) { + *mod = R_SHIFT; + return 1; } return 0; } diff --git a/common.h b/common.h index f399be3..b36958c 100644 --- a/common.h +++ b/common.h @@ -27,6 +27,10 @@ enum modifier { SHIFT = 2, ALT = 4, WIN = 8, + R_CTRL = 16, + R_SHIFT = 32, + R_ALT = 64, + R_WIN = 128, }; enum mouse_button { diff --git a/footswitch.c b/footswitch.c index a9401f1..c78b2de 100644 --- a/footswitch.c +++ b/footswitch.c @@ -63,7 +63,7 @@ void usage() { " -S rstring - append the specified raw string (hex numbers delimited with spaces)\n" " -a key - append the specified key\n" " -k key - write the specified key\n" - " -m modifier - ctrl|shift|alt|win\n" + " -m modifier - (l_,r_)ctrl|shift|alt|win\n" " -b button - mouse_left|mouse_middle|mouse_right\n" " -x X - move the mouse cursor horizontally by X pixels\n" " -y Y - move the mouse cursor vertically by Y pixels\n" @@ -168,16 +168,28 @@ void print_mouse(unsigned char data[]) { void print_key(unsigned char data[]) { char combo[128] = {0}; if ((data[2] & CTRL) != 0) { - strcat(combo, "ctrl+"); + strcat(combo, "l_ctrl+"); } if ((data[2] & SHIFT) != 0) { - strcat(combo, "shift+"); + strcat(combo, "l_shift+"); } if ((data[2] & ALT) != 0) { - strcat(combo, "alt+"); + strcat(combo, "l_alt+"); } if ((data[2] & WIN) != 0) { - strcat(combo, "win+"); + strcat(combo, "l_win+"); + } + if ((data[2] & R_CTRL) != 0) { + strcat(combo, "r_ctrl+"); + } + if ((data[2] & R_SHIFT) != 0) { + strcat(combo, "r_shift+"); + } + if ((data[2] & R_ALT) != 0) { + strcat(combo, "r_alt+"); + } + if ((data[2] & R_WIN) != 0) { + strcat(combo, "r_win+"); } if (data[3] != 0) { const char *key = decode_byte(data[3]); From 10bee91b18a5ec78e14d8ecf56f78786640118bf Mon Sep 17 00:00:00 2001 From: Max Ignatenko Date: Sun, 14 Feb 2021 21:03:35 +0000 Subject: [PATCH 02/16] Make this repo also a homebrew tap --- HomebrewFormula/footswitch.rb | 13 +++++++++++++ README.md | 7 ++----- 2 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 HomebrewFormula/footswitch.rb diff --git a/HomebrewFormula/footswitch.rb b/HomebrewFormula/footswitch.rb new file mode 100644 index 0000000..2897d50 --- /dev/null +++ b/HomebrewFormula/footswitch.rb @@ -0,0 +1,13 @@ +class Footswitch < Formula + desc "Command-line utility for PCsensor foot switch" + homepage "https://github.com/rgerganov/footswitch" + license "MIT" + head "https://github.com/rgerganov/footswitch.git" + + depends_on "hidapi" + + def install + system "mkdir", "#{prefix}/bin" + system "make", "install", "PREFIX=#{prefix}" + end +end diff --git a/README.md b/README.md index 905ed02..55d5b5e 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,8 @@ The programs are using the [hidapi][3] library and should work on Linux and OSX. To build on OSX: - brew install hidapi - git clone https://github.com/rgerganov/footswitch.git - cd footswitch - make - sudo make install + brew tap rgerganov/footswitch https://github.com/rgerganov/footswitch.git + brew install --HEAD footswitch Usage ----- From e1470fe4f01b2ef4819c3a9d8f34ffbd5120fea2 Mon Sep 17 00:00:00 2001 From: Radoslav Gerganov Date: Wed, 17 Mar 2021 09:15:49 +0200 Subject: [PATCH 03/16] Update supported devices in the README Issue #65 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 55d5b5e..2a9e716 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Command line utlities for programming [PCsensor][1] and Scythe foot switches. Th * `0c45:7403` * `0c45:7404` * `413d:2107` + * `1a86:e026` Scythe switches with `vendorId:productId`=`0426:3011` can be programmed with the `scythe` binary. You can find the `vendorId` and `productId` of your device using the `lsusb` command on Linux. From aa0b10f00d3e76dac27b55b88c8d44c0c406f7f0 Mon Sep 17 00:00:00 2001 From: Radoslav Gerganov Date: Mon, 15 Feb 2021 21:37:20 +0200 Subject: [PATCH 04/16] Update travis build --- .travis.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 07ca13e..58a84c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,14 +13,12 @@ os: compiler: - gcc -before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install hidapi; fi - script: - make addons: apt: - packages: - - libhidapi-dev + packages: libhidapi-dev + homebrew: + packages: hidapi + update: true From d2eb3d8f23a128c51ff1c1c373e81e63e10cd3fd Mon Sep 17 00:00:00 2001 From: aureliocarlucci Date: Thu, 25 Nov 2021 11:29:16 +0000 Subject: [PATCH 05/16] Modified Makefile to allow staged install and packaging for linux distros (#69) --- Makefile | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 159193b..60c14be 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ PREFIX = /usr/local +UDEVPREFIX = /etc/udev + INSTALL = /usr/bin/install -c INSTALLDATA = /usr/bin/install -c -m 644 CFLAGS = -Wall @@ -21,17 +23,19 @@ footswitch: footswitch.c common.c debug.c scythe: scythe.c common.c debug.c install: all - $(INSTALL) footswitch $(PREFIX)/bin - $(INSTALL) scythe $(PREFIX)/bin + $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin + $(INSTALL) footswitch $(DESTDIR)$(PREFIX)/bin + $(INSTALL) scythe $(DESTDIR)$(PREFIX)/bin ifeq ($(UNAME), Linux) - $(INSTALLDATA) 19-footswitch.rules /etc/udev/rules.d + $(INSTALL) -d $(DESTDIR)$(UDEVPREFIX)/rules.d + $(INSTALLDATA) 19-footswitch.rules $(DESTDIR)$(UDEVPREFIX)/rules.d endif -uninstall: - rm -f $(PREFIX)/bin/footswitch - rm -f $(PREFIX)/bin/scythe +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/footswitch + rm -f $(DESTDIR)$(PREFIX)/bin/scythe ifeq ($(UNAME), Linux) - rm -f /etc/udev/rules.d/19-footswitch.rules + rm -f $(DESTDIR)$(UDEVPREFIX)/rules.d/19-footswitch.rules endif clean: From 26e507c853cbb3065055ed1b86be8e3f056e35ba Mon Sep 17 00:00:00 2001 From: Radoslav Gerganov Date: Mon, 21 Mar 2022 15:59:15 +0200 Subject: [PATCH 06/16] Add github action --- .github/workflows/build.yml | 34 ++++++++++++++++++++++++++++++++++ .travis.yml | 24 ------------------------ README.md | 2 +- 3 files changed, 35 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..917db4a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + ubuntu-build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Dependencies + run: | + sudo apt update + sudo apt install libhidapi-dev + - name: Build + run: make + + osx-build: + + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + - name: Dependencies + run: | + brew update + brew install hidapi + - name: Build + run: make diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 58a84c5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: c - -cache: apt - -dist: trusty - -sudo: false - -os: - - linux - - osx - -compiler: - - gcc - -script: - - make - -addons: - apt: - packages: libhidapi-dev - homebrew: - packages: hidapi - update: true diff --git a/README.md b/README.md index 2a9e716..6e80444 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/rgerganov/footswitch.svg?branch=master)](https://travis-ci.org/rgerganov/footswitch) +[![Build Status](https://github.com/rgerganov/footswitch/workflows/CI/badge.svg)](https://github.com/rgerganov/footswitch/actions) Footswitch ---------- From 1cf63643e18e688e4ebe96451db24edf52338cc0 Mon Sep 17 00:00:00 2001 From: Radoslav Gerganov Date: Tue, 12 Apr 2022 10:02:57 +0300 Subject: [PATCH 07/16] Add note in the README about the usage of sudo Closes #73 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 6e80444..685f9a3 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,9 @@ The programs are using the [hidapi][3] library and should work on Linux and OSX. make sudo make install +The `install` target installs udev rules on Linux which allow running the programs without root. +You may need to use `sudo` otherwise. + To build on OSX: brew tap rgerganov/footswitch https://github.com/rgerganov/footswitch.git From 87f1a4f8783aaba0d39c22d32072274818381bc7 Mon Sep 17 00:00:00 2001 From: nameless Date: Tue, 14 Jun 2022 14:11:02 -0500 Subject: [PATCH 08/16] Changes to be committed: modified: common.c modified: common.h --- Makefile | 18 +- common.c | 26 ++ common.h | 4 + footswitch | Bin 0 -> 43304 bytes footswitch.c | 63 +++-- footswitch.c.devices | 576 +++++++++++++++++++++++++++++++++++++++++++ scythe | Bin 0 -> 38472 bytes 7 files changed, 666 insertions(+), 21 deletions(-) create mode 100755 footswitch create mode 100644 footswitch.c.devices create mode 100755 scythe diff --git a/Makefile b/Makefile index 159193b..ec92ac7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ PREFIX = /usr/local +UDEVPREFIX = /etc/udev + INSTALL = /usr/bin/install -c INSTALLDATA = /usr/bin/install -c -m 644 CFLAGS = -Wall @@ -21,19 +23,21 @@ footswitch: footswitch.c common.c debug.c scythe: scythe.c common.c debug.c install: all - $(INSTALL) footswitch $(PREFIX)/bin - $(INSTALL) scythe $(PREFIX)/bin + $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin + $(INSTALL) footswitch $(DESTDIR)$(PREFIX)/bin + $(INSTALL) scythe $(DESTDIR)$(PREFIX)/bin ifeq ($(UNAME), Linux) - $(INSTALLDATA) 19-footswitch.rules /etc/udev/rules.d + $(INSTALL) -d $(DESTDIR)$(UDEVPREFIX)/rules.d + $(INSTALLDATA) 19-footswitch.rules $(DESTDIR)$(UDEVPREFIX)/rules.d endif uninstall: - rm -f $(PREFIX)/bin/footswitch - rm -f $(PREFIX)/bin/scythe + rm -f $(DESTDIR)$(PREFIX)/bin/footswitch + rm -f $(DESTDIR)$(PREFIX)/bin/scythe ifeq ($(UNAME), Linux) - rm -f /etc/udev/rules.d/19-footswitch.rules + rm -f $(DESTDIR)$(UDEVPREFIX)/rules.d/19-footswitch.rules endif + clean: rm -f scythe footswitch *.o - diff --git a/common.c b/common.c index 0043721..2853fa4 100644 --- a/common.c +++ b/common.c @@ -184,7 +184,9 @@ static const keymap_entry keymap[] = {"XF86AudioRaiseVolume", 0x80}, {"XF86AudioLowerVolume", 0x81}, {"<82>", 0x82}, + {"Hangul", 0x82}, {"<83>", 0x83}, + {"Hangul_Hanja",0x83}, {"A", 0x84}, {"B", 0x85}, {"C", 0x86}, @@ -326,6 +328,30 @@ Bool parse_modifier(const char *arg, enum modifier *mod) { } else if (strcasecmp("shift", arg) == 0) { *mod = SHIFT; return 1; + } else if (strcasecmp("l_ctrl", arg) == 0) { + *mod = CTRL; + return 1; + } else if (strcasecmp("l_alt", arg) == 0) { + *mod = ALT; + return 1; + } else if (strcasecmp("l_win", arg) == 0) { + *mod = WIN; + return 1; + } else if (strcasecmp("l_shift", arg) == 0) { + *mod = SHIFT; + return 1; + } else if (strcasecmp("r_ctrl", arg) == 0) { + *mod = R_CTRL; + return 1; + } else if (strcasecmp("r_alt", arg) == 0) { + *mod = R_ALT; + return 1; + } else if (strcasecmp("r_win", arg) == 0) { + *mod = R_WIN; + return 1; + } else if (strcasecmp("r_shift", arg) == 0) { + *mod = R_SHIFT; + return 1; } return 0; } diff --git a/common.h b/common.h index f399be3..b36958c 100644 --- a/common.h +++ b/common.h @@ -27,6 +27,10 @@ enum modifier { SHIFT = 2, ALT = 4, WIN = 8, + R_CTRL = 16, + R_SHIFT = 32, + R_ALT = 64, + R_WIN = 128, }; enum mouse_button { diff --git a/footswitch b/footswitch new file mode 100755 index 0000000000000000000000000000000000000000..df83df8cd36571aa0c2367d73933a9c5e5214026 GIT binary patch literal 43304 zcmeI53wTu3x%XEBK|mq#f-=`*Jhg;mn7?rFdh>Gk|-7!Ae{yA-NPU+tGfy2@zKn7@6Ybk+;yu zwtMr*hKrjXPv=+8@htcCqYW1~Js!19^A;1{d_$%iImXB(#~N4SQFBqejwZu9zL)9t za6^bI?MY>%&unf_+buE4r255$RQ_(+ z`8RD1j3*tc2c=0mbP%JD95h}Wd`L&Pj~?VhbBUdd&rk39?5H^(HOe#s$vn$2#7oQ3bt!vB(mPt20;7!pW`vTEuII1-& zqk(`Yz-qy8jfTM*jvtN$YCI8dyh`I}!0Shme6?OrWw6E@3SJdZiC8EQh=5`l^Kn6| zy}=q4i${Ic5mgz925aJ#${P;{)%rj@9EnpTJ)Y9e47B2Ekn|e;lS2QE#?e|UZ_fDHSlX^B6e>qrHvHs#O z7i*;MoWONbIc1YzK6ME@x9CoE&c-Y5{tjYywu_^GcUJzJM)OeUt?Zp z@zZvH07})s3d%hjaVC!@R)a?=g2Q z-pRbs;(ujcV)6aVOD+CB^Ky&#FppULBj$A$Kft`%;-4~4TD+Hei^acS-fHoK%-b#g z59S>fS3%RTJr>Vpu5QX~|DntaEIy36WAWk43oSmHd5OixFfXpt?l6y7{7mL` z7N5$z+2V!FlNO)Fyv5?PnYUVeF7tMa7c=j$_X%e&+2KU(dY5 z;#V;5v3NCeb+c)BY5xfG0*l9)I~K2HUTE|I~L!|ywKvW zFfXzA>�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] [-S ] [-ak ] [-m ] [-b