hidaping 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.clang-format +5 -0
 - data/.github/workflows/gem-push.yml +50 -0
 - data/.github/workflows/test.yml +53 -0
 - data/.ruby-version +1 -0
 - data/CHANGELOG.md +9 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +93 -0
 - data/Rakefile +18 -0
 - data/ext/hidaping/common.h +17 -0
 - data/ext/hidaping/extconf.rb +27 -0
 - data/ext/hidaping/hidaping.c +57 -0
 - data/ext/hidaping/hidaping.h +6 -0
 - data/ext/hidaping/hidaping_device.c +159 -0
 - data/ext/hidaping/hidaping_device.h +9 -0
 - data/ext/hidaping/hidaping_util.h +19 -0
 - data/lib/hidaping/version.rb +5 -0
 - data/lib/hidaping.rb +26 -0
 - data/sample/kbprog.rb +190 -0
 - data/sample/set_hsv.rb +21 -0
 - data/sig/myhidapi.rbs +4 -0
 - data/test/joycon.rb +16 -0
 - data/test/test.rb +14 -0
 - data/test/test_myhidapi.rb +33 -0
 - data/test/xbox360.rb +15 -0
 - metadata +74 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: c38b9b9d15828de26fea00975aa9744b1ab4351cc52bba779c3daf257b987efc
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: d65edf49a8fe4b072f3e68ad038d31d4a349c4a4331f2f38d24cfc20157780c4
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 7212e791d8fcc018e825b6ed54a2add5c8c2096e7aea2b8ce9375379a3710f25d8268d973e67b1fa691d928c5cd42e878580f40745fbeeac39890b07ddc8f5ea
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c8a7bf89640c6962fed10d48747cc3d024bc285889afe83fdfe2ea1221dd053265a4fdc70ba9b863eed961172cf557f2cb4e84e4ee7c900cb4b73e56b3076d90
         
     | 
    
        data/.clang-format
    ADDED
    
    
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            name: Ruby Gem
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            on:
         
     | 
| 
      
 4 
     | 
    
         
            +
              push:
         
     | 
| 
      
 5 
     | 
    
         
            +
                branches: [ "master" ]
         
     | 
| 
      
 6 
     | 
    
         
            +
              pull_request:
         
     | 
| 
      
 7 
     | 
    
         
            +
                branches: [ "master" ]
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            jobs:
         
     | 
| 
      
 10 
     | 
    
         
            +
              build:
         
     | 
| 
      
 11 
     | 
    
         
            +
                name: Build + Publish
         
     | 
| 
      
 12 
     | 
    
         
            +
                runs-on: ubuntu-latest
         
     | 
| 
      
 13 
     | 
    
         
            +
                permissions:
         
     | 
| 
      
 14 
     | 
    
         
            +
                  contents: read
         
     | 
| 
      
 15 
     | 
    
         
            +
                  pages: write
         
     | 
| 
      
 16 
     | 
    
         
            +
                  id-token: write
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 19 
     | 
    
         
            +
                  - name: Clone
         
     | 
| 
      
 20 
     | 
    
         
            +
                    uses: actions/checkout@v4
         
     | 
| 
      
 21 
     | 
    
         
            +
                  - name: Set up Ruby 3.4.5
         
     | 
| 
      
 22 
     | 
    
         
            +
                    uses: ruby/setup-ruby@v1
         
     | 
| 
      
 23 
     | 
    
         
            +
                    with:
         
     | 
| 
      
 24 
     | 
    
         
            +
                      ruby-version: 3.4.5
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - name: Build
         
     | 
| 
      
 26 
     | 
    
         
            +
                    run: |
         
     | 
| 
      
 27 
     | 
    
         
            +
                      bundle install
         
     | 
| 
      
 28 
     | 
    
         
            +
                      bundle exec rake gem
         
     | 
| 
      
 29 
     | 
    
         
            +
                      
         
     | 
| 
      
 30 
     | 
    
         
            +
                      mkdir -p ~/.gem
         
     | 
| 
      
 31 
     | 
    
         
            +
                      cat <<AAA > ~/.gem/.mirrorrc
         
     | 
| 
      
 32 
     | 
    
         
            +
                      ---
         
     | 
| 
      
 33 
     | 
    
         
            +
                      - from: https://repy.github.io/hidaping
         
     | 
| 
      
 34 
     | 
    
         
            +
                        to: /home/runner/gemrepos
         
     | 
| 
      
 35 
     | 
    
         
            +
                      AAA
         
     | 
| 
      
 36 
     | 
    
         
            +
                      mkdir -p /home/runner/gemrepos/gems
         
     | 
| 
      
 37 
     | 
    
         
            +
                      gem install rubygems-mirror
         
     | 
| 
      
 38 
     | 
    
         
            +
                      gem mirror
         
     | 
| 
      
 39 
     | 
    
         
            +
                      
         
     | 
| 
      
 40 
     | 
    
         
            +
                      cp ./pkg/hidaping-*.gem /home/runner/gemrepos/gems/
         
     | 
| 
      
 41 
     | 
    
         
            +
                      cd /home/runner/gemrepos
         
     | 
| 
      
 42 
     | 
    
         
            +
                      gem generate_index
         
     | 
| 
      
 43 
     | 
    
         
            +
                  - name: Setup Pages
         
     | 
| 
      
 44 
     | 
    
         
            +
                    uses: actions/configure-pages@v5
         
     | 
| 
      
 45 
     | 
    
         
            +
                  - name: Upload artifact
         
     | 
| 
      
 46 
     | 
    
         
            +
                    uses: actions/upload-pages-artifact@v3
         
     | 
| 
      
 47 
     | 
    
         
            +
                    with:
         
     | 
| 
      
 48 
     | 
    
         
            +
                      path: /home/runner/gemrepos
         
     | 
| 
      
 49 
     | 
    
         
            +
                  - name: Deploy to GitHub Pages
         
     | 
| 
      
 50 
     | 
    
         
            +
                    uses: actions/deploy-pages@v4
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            name: Test on All OS
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            on:
         
     | 
| 
      
 4 
     | 
    
         
            +
              push:
         
     | 
| 
      
 5 
     | 
    
         
            +
                branches: ["master"]
         
     | 
| 
      
 6 
     | 
    
         
            +
              pull_request:
         
     | 
| 
      
 7 
     | 
    
         
            +
                branches: ["master"]
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            jobs:
         
     | 
| 
      
 10 
     | 
    
         
            +
              test:
         
     | 
| 
      
 11 
     | 
    
         
            +
                runs-on: ${{ matrix.os }}
         
     | 
| 
      
 12 
     | 
    
         
            +
                strategy:
         
     | 
| 
      
 13 
     | 
    
         
            +
                  matrix:
         
     | 
| 
      
 14 
     | 
    
         
            +
                    os: 
         
     | 
| 
      
 15 
     | 
    
         
            +
                      - ubuntu-latest
         
     | 
| 
      
 16 
     | 
    
         
            +
                      - windows-latest
         
     | 
| 
      
 17 
     | 
    
         
            +
                      - macos-latest
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 20 
     | 
    
         
            +
                  - name: Clone
         
     | 
| 
      
 21 
     | 
    
         
            +
                    uses: actions/checkout@v4
         
     | 
| 
      
 22 
     | 
    
         
            +
                  - name: Set up Ruby 3.4.5
         
     | 
| 
      
 23 
     | 
    
         
            +
                    uses: ruby/setup-ruby@v1
         
     | 
| 
      
 24 
     | 
    
         
            +
                    with:
         
     | 
| 
      
 25 
     | 
    
         
            +
                      ruby-version: 3.4.5
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  - name: Run tests (Ubuntu)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    if: runner.os == 'Linux'
         
     | 
| 
      
 29 
     | 
    
         
            +
                    run: |
         
     | 
| 
      
 30 
     | 
    
         
            +
                      sudo apt-get update
         
     | 
| 
      
 31 
     | 
    
         
            +
                      sudo apt install -y libhidapi-dev
         
     | 
| 
      
 32 
     | 
    
         
            +
                      gem install bundler
         
     | 
| 
      
 33 
     | 
    
         
            +
                      bundle install
         
     | 
| 
      
 34 
     | 
    
         
            +
                      bundle exec rake compile
         
     | 
| 
      
 35 
     | 
    
         
            +
                      bundle exec ruby test/test.rb
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  - name: Run tests (Windows)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    if: runner.os == 'Windows'
         
     | 
| 
      
 39 
     | 
    
         
            +
                    run: |
         
     | 
| 
      
 40 
     | 
    
         
            +
                      pacman --noconfirm -S mingw-w64-ucrt-x86_64-hidapi
         
     | 
| 
      
 41 
     | 
    
         
            +
                      gem install bundler
         
     | 
| 
      
 42 
     | 
    
         
            +
                      bundle install
         
     | 
| 
      
 43 
     | 
    
         
            +
                      bundle exec rake compile
         
     | 
| 
      
 44 
     | 
    
         
            +
                      bundle exec ruby test/test.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  - name: Run tests (macOS)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    if: runner.os == 'macOS'
         
     | 
| 
      
 48 
     | 
    
         
            +
                    run: |
         
     | 
| 
      
 49 
     | 
    
         
            +
                      brew install hidapi
         
     | 
| 
      
 50 
     | 
    
         
            +
                      gem install bundler
         
     | 
| 
      
 51 
     | 
    
         
            +
                      bundle install
         
     | 
| 
      
 52 
     | 
    
         
            +
                      bundle exec rake compile
         
     | 
| 
      
 53 
     | 
    
         
            +
                      sudo bundle exec ruby test/test.rb
         
     | 
    
        data/.ruby-version
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            3.4.5
         
     | 
    
        data/CHANGELOG.md
    ADDED
    
    | 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            === 1.1.0 / 2024-05-24
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Forked from https://github.com/tenderlove/myhidapi and updated project metadata.
         
     | 
| 
      
 4 
     | 
    
         
            +
            * Improved the build process to use `pkg-config` for locating the `hidapi` library. This simplifies installation on systems where `hidapi` is installed via a package manager (e.g., Homebrew, apt).
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            === 1.0.0 / 2019-02-15
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            * 1 major enhancement
         
     | 
| 
      
 9 
     | 
    
         
            +
            * Birthday!
         
     | 
    
        data/LICENSE.txt
    ADDED
    
    | 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            MIT License
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright (c) 2024 Repy
         
     | 
| 
      
 4 
     | 
    
         
            +
            Copyright (c) 2019 Aaron Patterson
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 7 
     | 
    
         
            +
            of this software and associated documentation files (the “Software”), to deal
         
     | 
| 
      
 8 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 9 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 10 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 11 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 14 
     | 
    
         
            +
            all copies or substantial portions of the Software.
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 17 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 18 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 19 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 20 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 21 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 22 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,93 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # HIDAPING
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Next generation HIDAPI wrapper for Ruby
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## DESCRIPTION
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            This is a small wrapper around HIDAPI.
         
     | 
| 
      
 8 
     | 
    
         
            +
            I couldn't get other HIDAPI wrappers to work, so I wrote this one.
         
     | 
| 
      
 9 
     | 
    
         
            +
            I'm using it to communicate with my keyboard, so it really only supports enough of the HIDAPI to do that.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            ## DESCRIPTION
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            * https://github.com/Repy/hidaping
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            This gem is a fork from the original work by Aaron Patterson ([@tenderlove](https://github.com/tenderlove)).
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            * Original Repository: https://github.com/tenderlove/myhidapi
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ## SUPPORTS
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            This gem works on the following platforms, leveraging the capabilities of the underlying HIDAPI library.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            *   **Platforms**:
         
     | 
| 
      
 24 
     | 
    
         
            +
                *   Windows
         
     | 
| 
      
 25 
     | 
    
         
            +
                *   macOS
         
     | 
| 
      
 26 
     | 
    
         
            +
                *   Linux
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            *   **Device Types**:
         
     | 
| 
      
 29 
     | 
    
         
            +
                *   USB
         
     | 
| 
      
 30 
     | 
    
         
            +
                *   Bluetooth
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            ## FEATURES/PROBLEMS
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            * Incomplete
         
     | 
| 
      
 35 
     | 
    
         
            +
            * No tests
         
     | 
| 
      
 36 
     | 
    
         
            +
            * Seems to work (for me)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            ## SYNOPSIS
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 41 
     | 
    
         
            +
            require 'hidaping'
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            devices = HIDAPING.enumerate(0x0, 0x0)
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            for d in devices
         
     | 
| 
      
 46 
     | 
    
         
            +
                printf("0x%04x, 0x%04x, %s\n", d.vendor_id, d.product_id, d.product_string)
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            handle = HIDAPING.open(0x045e, 0x028e)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            while true
         
     | 
| 
      
 52 
     | 
    
         
            +
                report_raw = handle.read_timeout(64, 500)
         
     | 
| 
      
 53 
     | 
    
         
            +
                data = report_raw.unpack("vvvvvb*")
         
     | 
| 
      
 54 
     | 
    
         
            +
                p data
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
      
 56 
     | 
    
         
            +
            ```
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            ## REQUIREMENTS
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            This depends on **hidapi**.
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            ## INSTALL
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            First, install the **hidapi** library. Here are instructions for common platforms:
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            *   **Windows (using RubyInstaller with Devkit)**
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                ```sh
         
     | 
| 
      
 69 
     | 
    
         
            +
                ridk exec pacman -S mingw-w64-ucrt-x86_64-hidapi
         
     | 
| 
      
 70 
     | 
    
         
            +
                ```
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            *   **macOS (using Homebrew)**
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                ```sh
         
     | 
| 
      
 75 
     | 
    
         
            +
                brew install hidapi
         
     | 
| 
      
 76 
     | 
    
         
            +
                ```
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            *   **Ubuntu / Debian**
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                ```sh
         
     | 
| 
      
 81 
     | 
    
         
            +
                sudo apt update
         
     | 
| 
      
 82 
     | 
    
         
            +
                sudo apt install libhidapi-dev
         
     | 
| 
      
 83 
     | 
    
         
            +
                ```
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            Once `hidapi` is installed, you can install this gem:
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 88 
     | 
    
         
            +
            gem install hidaping
         
     | 
| 
      
 89 
     | 
    
         
            +
            ```
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            ## LICENSE
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            The gem is available as open source under the terms of the [MIT License](LICENSE.md).
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "bundler/gem_tasks"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "rake/extensiontask"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rake/packagetask'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            task build: :compile
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            GEMSPEC = Gem::Specification.load("hidaping.gemspec")
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Rake::ExtensionTask.new("hidaping", GEMSPEC) do |ext|
         
     | 
| 
      
 12 
     | 
    
         
            +
              ext.lib_dir = "lib/hidaping"
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            Gem::PackageTask.new(GEMSPEC) do |pkg|
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            task default: %i[clobber compile]
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #ifndef MY_HIDAPI_COMMON_H
         
     | 
| 
      
 2 
     | 
    
         
            +
            #define MY_HIDAPI_COMMON_H
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            #include "extconf.h"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            #if defined(HAVE_HIDAPI_H)
         
     | 
| 
      
 7 
     | 
    
         
            +
            #include <hidapi.h>
         
     | 
| 
      
 8 
     | 
    
         
            +
            #elif defined(HAVE_HIDAPI_HIDAPI_H)
         
     | 
| 
      
 9 
     | 
    
         
            +
            #include <hidapi/hidapi.h>
         
     | 
| 
      
 10 
     | 
    
         
            +
            #else
         
     | 
| 
      
 11 
     | 
    
         
            +
            #error "No suitable header found"
         
     | 
| 
      
 12 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            #include <ruby.h>
         
     | 
| 
      
 15 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            #endif // MY_HIDAPI_COMMON_H
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "mkmf"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            dir_config("hidapi")
         
     | 
| 
      
 6 
     | 
    
         
            +
            pkg_config('hidapi')
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            if have_library('hidapi')
         
     | 
| 
      
 9 
     | 
    
         
            +
                libname = 'hidapi'
         
     | 
| 
      
 10 
     | 
    
         
            +
            elsif have_library('hidapi-hidraw')
         
     | 
| 
      
 11 
     | 
    
         
            +
                libname = 'hidapi-hidraw'
         
     | 
| 
      
 12 
     | 
    
         
            +
            elsif have_library('hidapi-libusb')
         
     | 
| 
      
 13 
     | 
    
         
            +
                libname = 'hidapi-libusb'
         
     | 
| 
      
 14 
     | 
    
         
            +
            else
         
     | 
| 
      
 15 
     | 
    
         
            +
              abort 'you must have "libhidapi".'
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            if have_header('hidapi/hidapi.h')
         
     | 
| 
      
 19 
     | 
    
         
            +
                header = 'hidapi/hidapi.h'
         
     | 
| 
      
 20 
     | 
    
         
            +
            elsif have_header('hidapi.h')
         
     | 
| 
      
 21 
     | 
    
         
            +
                header = 'hidapi.h'
         
     | 
| 
      
 22 
     | 
    
         
            +
            else
         
     | 
| 
      
 23 
     | 
    
         
            +
              abort 'you must have "hidapi.h".'
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            create_header
         
     | 
| 
      
 27 
     | 
    
         
            +
            create_makefile("hidaping/hidaping")
         
     | 
| 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "hidaping.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include "hidaping_device.h"
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include "hidaping_util.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            VALUE mHIDAPING;
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            static VALUE enumerate(VALUE mod, VALUE vendor_id, VALUE product_id) {
         
     | 
| 
      
 8 
     | 
    
         
            +
                VALUE devices;
         
     | 
| 
      
 9 
     | 
    
         
            +
                struct hid_device_info *devs, *cur_dev;
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                VALUE device_info_class = rb_path2class("HIDAPING::DeviceInfo");
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                devices = rb_ary_new();
         
     | 
| 
      
 14 
     | 
    
         
            +
                devs = hid_enumerate(NUM2USHORT(vendor_id), NUM2USHORT(product_id));
         
     | 
| 
      
 15 
     | 
    
         
            +
                cur_dev = devs;
         
     | 
| 
      
 16 
     | 
    
         
            +
                while (cur_dev) {
         
     | 
| 
      
 17 
     | 
    
         
            +
                    VALUE args[] = {INT2NUM(cur_dev->vendor_id),
         
     | 
| 
      
 18 
     | 
    
         
            +
                                    INT2NUM(cur_dev->product_id),
         
     | 
| 
      
 19 
     | 
    
         
            +
                                    rb_str_new2(cur_dev->path),
         
     | 
| 
      
 20 
     | 
    
         
            +
                                    hidaping_wcstombs(cur_dev->serial_number),
         
     | 
| 
      
 21 
     | 
    
         
            +
                                    hidaping_wcstombs(cur_dev->manufacturer_string),
         
     | 
| 
      
 22 
     | 
    
         
            +
                                    hidaping_wcstombs(cur_dev->product_string),
         
     | 
| 
      
 23 
     | 
    
         
            +
                                    INT2NUM(cur_dev->usage),
         
     | 
| 
      
 24 
     | 
    
         
            +
                                    INT2NUM(cur_dev->interface_number)};
         
     | 
| 
      
 25 
     | 
    
         
            +
                    rb_ary_push(devices, rb_class_new_instance(8, args, device_info_class));
         
     | 
| 
      
 26 
     | 
    
         
            +
                    cur_dev = cur_dev->next;
         
     | 
| 
      
 27 
     | 
    
         
            +
                }
         
     | 
| 
      
 28 
     | 
    
         
            +
                hid_free_enumeration(devs);
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                return devices;
         
     | 
| 
      
 31 
     | 
    
         
            +
            }
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            static VALUE rb_hid_open(VALUE mod, VALUE vid, VALUE pid) {
         
     | 
| 
      
 34 
     | 
    
         
            +
                hid_device *handle = hid_open(NUM2USHORT(vid), NUM2USHORT(pid), NULL);
         
     | 
| 
      
 35 
     | 
    
         
            +
                if (handle) {
         
     | 
| 
      
 36 
     | 
    
         
            +
                    return create_hidaping_handle(handle);
         
     | 
| 
      
 37 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 38 
     | 
    
         
            +
                    return Qfalse;
         
     | 
| 
      
 39 
     | 
    
         
            +
                }
         
     | 
| 
      
 40 
     | 
    
         
            +
            }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            static VALUE rb_hid_open_path(VALUE mod, VALUE path) {
         
     | 
| 
      
 43 
     | 
    
         
            +
                hid_device *handle = hid_open_path(StringValueCStr(path));
         
     | 
| 
      
 44 
     | 
    
         
            +
                if (handle) {
         
     | 
| 
      
 45 
     | 
    
         
            +
                    return create_hidaping_handle(handle);
         
     | 
| 
      
 46 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 47 
     | 
    
         
            +
                    return Qfalse;
         
     | 
| 
      
 48 
     | 
    
         
            +
                }
         
     | 
| 
      
 49 
     | 
    
         
            +
            }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            extern void Init_hidaping(void) {
         
     | 
| 
      
 52 
     | 
    
         
            +
                mHIDAPING = rb_define_module("HIDAPING");
         
     | 
| 
      
 53 
     | 
    
         
            +
                rb_define_singleton_method(mHIDAPING, "enumerate", enumerate, 2);
         
     | 
| 
      
 54 
     | 
    
         
            +
                rb_define_singleton_method(mHIDAPING, "open", rb_hid_open, 2);
         
     | 
| 
      
 55 
     | 
    
         
            +
                rb_define_singleton_method(mHIDAPING, "open_path", rb_hid_open_path, 1);
         
     | 
| 
      
 56 
     | 
    
         
            +
                Init_hidaping_device(mHIDAPING);
         
     | 
| 
      
 57 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,159 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "hidaping_device.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include "hidaping.h"
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include "hidaping_util.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            #define BUF_SIZE 4096
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            VALUE cHIDAPINGHandle;
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            static void dealloc(void *ptr) {
         
     | 
| 
      
 10 
     | 
    
         
            +
                hid_device *handle = (hid_device *)ptr;
         
     | 
| 
      
 11 
     | 
    
         
            +
                hid_close(handle);
         
     | 
| 
      
 12 
     | 
    
         
            +
            }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            static const rb_data_type_t hidaping_handle_type = {
         
     | 
| 
      
 15 
     | 
    
         
            +
                "HIDAPING/Handle",
         
     | 
| 
      
 16 
     | 
    
         
            +
                {
         
     | 
| 
      
 17 
     | 
    
         
            +
                    0,
         
     | 
| 
      
 18 
     | 
    
         
            +
                    dealloc,
         
     | 
| 
      
 19 
     | 
    
         
            +
                    0,
         
     | 
| 
      
 20 
     | 
    
         
            +
                },
         
     | 
| 
      
 21 
     | 
    
         
            +
                0,
         
     | 
| 
      
 22 
     | 
    
         
            +
                0,
         
     | 
| 
      
 23 
     | 
    
         
            +
            #ifdef RUBY_TYPED_FREE_IMMEDIATELY
         
     | 
| 
      
 24 
     | 
    
         
            +
                RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
      
 25 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 26 
     | 
    
         
            +
            };
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            VALUE create_hidaping_handle(hid_device *handle) {
         
     | 
| 
      
 29 
     | 
    
         
            +
                return TypedData_Wrap_Struct(cHIDAPINGHandle, &hidaping_handle_type, handle);
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            static VALUE rb_hid_write(VALUE self, VALUE str) {
         
     | 
| 
      
 33 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 34 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                int written = hid_write(handle, (unsigned char *)StringValuePtr(str), RSTRING_LEN(str));
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                if (written >= 0) {
         
     | 
| 
      
 39 
     | 
    
         
            +
                    return INT2NUM(written);
         
     | 
| 
      
 40 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 41 
     | 
    
         
            +
                    return Qfalse;
         
     | 
| 
      
 42 
     | 
    
         
            +
                }
         
     | 
| 
      
 43 
     | 
    
         
            +
            }
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            static VALUE rb_hid_set_nonblocking(VALUE self, VALUE val) {
         
     | 
| 
      
 46 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 47 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                if (!hid_set_nonblocking(handle, NUM2INT(val))) {
         
     | 
| 
      
 50 
     | 
    
         
            +
                    return Qtrue;
         
     | 
| 
      
 51 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 52 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 53 
     | 
    
         
            +
                }
         
     | 
| 
      
 54 
     | 
    
         
            +
            }
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            static VALUE rb_hid_read(VALUE self, VALUE size) {
         
     | 
| 
      
 57 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 58 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                unsigned char *buf = xcalloc(NUM2SIZET(size), sizeof(unsigned char));
         
     | 
| 
      
 61 
     | 
    
         
            +
                int read = hid_read(handle, buf, NUM2SIZET(size));
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                VALUE ret;
         
     | 
| 
      
 64 
     | 
    
         
            +
                if (read > 0) {
         
     | 
| 
      
 65 
     | 
    
         
            +
                    ret = rb_str_new((char *)buf, read);
         
     | 
| 
      
 66 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 67 
     | 
    
         
            +
                    ret = Qnil;
         
     | 
| 
      
 68 
     | 
    
         
            +
                }
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                xfree(buf);
         
     | 
| 
      
 71 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 72 
     | 
    
         
            +
            }
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            static VALUE rb_hid_read_timeout(VALUE self, VALUE size, VALUE timeout_ms) {
         
     | 
| 
      
 75 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 76 
     | 
    
         
            +
                unsigned char *buf;
         
     | 
| 
      
 77 
     | 
    
         
            +
                int read;
         
     | 
| 
      
 78 
     | 
    
         
            +
                VALUE ret;
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                buf = xcalloc(NUM2SIZET(size), sizeof(unsigned char));
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                read = hid_read_timeout(handle, buf, NUM2SIZET(size), NUM2INT(timeout_ms));
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                if (read > 0) {
         
     | 
| 
      
 87 
     | 
    
         
            +
                    ret = rb_str_new((char *)buf, read);
         
     | 
| 
      
 88 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 89 
     | 
    
         
            +
                    ret = Qnil;
         
     | 
| 
      
 90 
     | 
    
         
            +
                }
         
     | 
| 
      
 91 
     | 
    
         
            +
                xfree(buf);
         
     | 
| 
      
 92 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 93 
     | 
    
         
            +
            }
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            static VALUE rb_hid_send_feature_report(VALUE self, VALUE str) {
         
     | 
| 
      
 96 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 97 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                int written =
         
     | 
| 
      
 100 
     | 
    
         
            +
                    hid_send_feature_report(handle, (unsigned char *)StringValuePtr(str), RSTRING_LEN(str));
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                if (written >= 0) {
         
     | 
| 
      
 103 
     | 
    
         
            +
                    return INT2NUM(written);
         
     | 
| 
      
 104 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 105 
     | 
    
         
            +
                    return Qfalse;
         
     | 
| 
      
 106 
     | 
    
         
            +
                }
         
     | 
| 
      
 107 
     | 
    
         
            +
            }
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            static VALUE rb_hid_get_feature_report(VALUE self, VALUE report_id, VALUE size) {
         
     | 
| 
      
 110 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 111 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                int buf_size = NUM2SIZET(size);
         
     | 
| 
      
 114 
     | 
    
         
            +
                unsigned char *buf = xcalloc(buf_size, sizeof(unsigned char));
         
     | 
| 
      
 115 
     | 
    
         
            +
                int read = hid_get_feature_report(handle, buf, buf_size);
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                VALUE ret;
         
     | 
| 
      
 118 
     | 
    
         
            +
                if (read > 0) {
         
     | 
| 
      
 119 
     | 
    
         
            +
                    ret = rb_str_new((char *)buf, read);
         
     | 
| 
      
 120 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 121 
     | 
    
         
            +
                    ret = Qnil;
         
     | 
| 
      
 122 
     | 
    
         
            +
                }
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                xfree(buf);
         
     | 
| 
      
 125 
     | 
    
         
            +
                return ret;
         
     | 
| 
      
 126 
     | 
    
         
            +
            }
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            static VALUE rb_manufacturer(VALUE self) {
         
     | 
| 
      
 129 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 130 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                wchar_t buffer[BUF_SIZE];
         
     | 
| 
      
 133 
     | 
    
         
            +
                hid_get_manufacturer_string(handle, buffer, BUF_SIZE);
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                return hidaping_wcstombs(buffer);
         
     | 
| 
      
 136 
     | 
    
         
            +
            }
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            static VALUE rb_product(VALUE self) {
         
     | 
| 
      
 139 
     | 
    
         
            +
                hid_device *handle;
         
     | 
| 
      
 140 
     | 
    
         
            +
                TypedData_Get_Struct(self, hid_device, &hidaping_handle_type, handle);
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                wchar_t buffer[BUF_SIZE];
         
     | 
| 
      
 143 
     | 
    
         
            +
                hid_get_product_string(handle, buffer, BUF_SIZE);
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                return hidaping_wcstombs(buffer);
         
     | 
| 
      
 146 
     | 
    
         
            +
            }
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            void Init_hidaping_device(VALUE mHIDAPING) {
         
     | 
| 
      
 149 
     | 
    
         
            +
                cHIDAPINGHandle = rb_define_class_under(mHIDAPING, "Handle", rb_cObject);
         
     | 
| 
      
 150 
     | 
    
         
            +
                rb_undef_alloc_func(cHIDAPINGHandle);
         
     | 
| 
      
 151 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "write", rb_hid_write, 1);
         
     | 
| 
      
 152 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "read", rb_hid_read, 1);
         
     | 
| 
      
 153 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "read_timeout", rb_hid_read_timeout, 2);
         
     | 
| 
      
 154 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "set_nonblocking", rb_hid_set_nonblocking, 1);
         
     | 
| 
      
 155 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "send_feature_report", rb_hid_send_feature_report, 1);
         
     | 
| 
      
 156 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "get_feature_report", rb_hid_get_feature_report, 2);
         
     | 
| 
      
 157 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "manufacturer", rb_manufacturer, 0);
         
     | 
| 
      
 158 
     | 
    
         
            +
                rb_define_method(cHIDAPINGHandle, "product", rb_product, 0);
         
     | 
| 
      
 159 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #ifndef MY_HIDAPI_UTIL_H
         
     | 
| 
      
 2 
     | 
    
         
            +
            #define MY_HIDAPI_UTIL_H
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            #include "common.h"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            #define BUF_SIZE 4096
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            static VALUE hidaping_wcstombs(wchar_t *str) {
         
     | 
| 
      
 9 
     | 
    
         
            +
                char buf[BUF_SIZE];
         
     | 
| 
      
 10 
     | 
    
         
            +
                int len;
         
     | 
| 
      
 11 
     | 
    
         
            +
                len = wcstombs(buf, str, BUF_SIZE);
         
     | 
| 
      
 12 
     | 
    
         
            +
                if (len > 0) {
         
     | 
| 
      
 13 
     | 
    
         
            +
                    return rb_str_new(buf, len);
         
     | 
| 
      
 14 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 15 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 16 
     | 
    
         
            +
                }
         
     | 
| 
      
 17 
     | 
    
         
            +
            }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            #endif // MY_HIDAPI_UTIL_H
         
     | 
    
        data/lib/hidaping.rb
    ADDED
    
    | 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "hidaping/hidaping.so"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module HIDAPING
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              class DeviceInfo
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :vendor_id, :product_id, :path, :serial_number, :manufacturer_string, :product_string, :usage, :interface_number
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def initialize vendor_id, product_id, path, serial_number, manufacturer_string, product_string, usage, interface_number
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @vendor_id           = vendor_id
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @product_id          = product_id
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @path                = path
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @serial_number       = serial_number
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @manufacturer_string = manufacturer_string
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @product_string      = product_string
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @usage               = usage
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @interface_number    = interface_number
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def open
         
     | 
| 
      
 22 
     | 
    
         
            +
                  HIDAPING.open vendor_id, product_id
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
    
        data/sample/kbprog.rb
    ADDED
    
    | 
         @@ -0,0 +1,190 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'hidaping'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'optparse'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class TeeloKB
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Error < StandardError; end
         
     | 
| 
      
 6 
     | 
    
         
            +
              class CouldNotReadError < Error; end
         
     | 
| 
      
 7 
     | 
    
         
            +
              class KeyboardNotFoundError < Error; end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              COMMAND_VERSIONS = { 1 => {} }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              %i{
         
     | 
| 
      
 12 
     | 
    
         
            +
                version
         
     | 
| 
      
 13 
     | 
    
         
            +
                rgblight_enable
         
     | 
| 
      
 14 
     | 
    
         
            +
                rgblight_disable
         
     | 
| 
      
 15 
     | 
    
         
            +
                rgblight_toggle
         
     | 
| 
      
 16 
     | 
    
         
            +
                rgblight_mode
         
     | 
| 
      
 17 
     | 
    
         
            +
                rgblight_sethsv
         
     | 
| 
      
 18 
     | 
    
         
            +
                rgblight_get_mode
         
     | 
| 
      
 19 
     | 
    
         
            +
                rgblight_get_hue
         
     | 
| 
      
 20 
     | 
    
         
            +
                rgblight_get_sat
         
     | 
| 
      
 21 
     | 
    
         
            +
                rgblight_get_val
         
     | 
| 
      
 22 
     | 
    
         
            +
              }.each_with_index do |command, index|
         
     | 
| 
      
 23 
     | 
    
         
            +
                COMMAND_VERSIONS[1][command] = index + 1
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def self.find
         
     | 
| 
      
 27 
     | 
    
         
            +
                HIDAPING.enumerate(0x0, 0x0).find { |dev| dev.product_string == "ErgoDox EZ" }
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def self.open
         
     | 
| 
      
 31 
     | 
    
         
            +
                dev = self.find
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                retries = 0
         
     | 
| 
      
 34 
     | 
    
         
            +
                handle = dev.open
         
     | 
| 
      
 35 
     | 
    
         
            +
                while !handle
         
     | 
| 
      
 36 
     | 
    
         
            +
                  retries += 1
         
     | 
| 
      
 37 
     | 
    
         
            +
                  raise KeyboardNotFoundError, "Couldn't find keyboard" if retries > 10
         
     | 
| 
      
 38 
     | 
    
         
            +
                  handle = dev.open
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                new handle
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              def initialize handle
         
     | 
| 
      
 45 
     | 
    
         
            +
                @handle = handle
         
     | 
| 
      
 46 
     | 
    
         
            +
                @version = protocol_version
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              def protocol_version
         
     | 
| 
      
 50 
     | 
    
         
            +
                write [0x0, 0x1]
         
     | 
| 
      
 51 
     | 
    
         
            +
                read(2).inject(:+)
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              def solid
         
     | 
| 
      
 55 
     | 
    
         
            +
                rgblight_mode 0x1
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
              def enable
         
     | 
| 
      
 59 
     | 
    
         
            +
                write [0x0, _(:rgblight_enable)]
         
     | 
| 
      
 60 
     | 
    
         
            +
                read 10
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              def disable
         
     | 
| 
      
 64 
     | 
    
         
            +
                write [0x0, _(:rgblight_disable)]
         
     | 
| 
      
 65 
     | 
    
         
            +
                read 10
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              def toggle
         
     | 
| 
      
 69 
     | 
    
         
            +
                write [0x0, _(:rgblight_toggle)]
         
     | 
| 
      
 70 
     | 
    
         
            +
                read 10
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              def mode
         
     | 
| 
      
 74 
     | 
    
         
            +
                write [0x0, _(:rgblight_get_mode)]
         
     | 
| 
      
 75 
     | 
    
         
            +
                read(2).last
         
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              def rainbow style = 0x6
         
     | 
| 
      
 79 
     | 
    
         
            +
                rgblight_mode style
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
              def rgblight_mode value
         
     | 
| 
      
 83 
     | 
    
         
            +
                write [0x0, _(:rgblight_mode), value & 0xFF]
         
     | 
| 
      
 84 
     | 
    
         
            +
                read 10
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
              alias :mode= :rgblight_mode
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              def rgblight_sethsv h, s, v
         
     | 
| 
      
 89 
     | 
    
         
            +
                write([0x0, _(:rgblight_sethsv)] + [(h >> 8) & 0xFF, h & 0xFF, s & 0xFF, v & 0xFF])
         
     | 
| 
      
 90 
     | 
    
         
            +
                read 10
         
     | 
| 
      
 91 
     | 
    
         
            +
              end
         
     | 
| 
      
 92 
     | 
    
         
            +
              alias :sethsv :rgblight_sethsv
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              def setrgb r, g, b
         
     | 
| 
      
 95 
     | 
    
         
            +
                sethsv *rgb2hsv(r, g, b)
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
              def hue
         
     | 
| 
      
 99 
     | 
    
         
            +
                write [0x0, _(:rgblight_get_hue)]
         
     | 
| 
      
 100 
     | 
    
         
            +
                _, upper, lower = read 3
         
     | 
| 
      
 101 
     | 
    
         
            +
                (upper << 8) | lower
         
     | 
| 
      
 102 
     | 
    
         
            +
              end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              def saturation
         
     | 
| 
      
 105 
     | 
    
         
            +
                write [0x0, _(:rgblight_get_sat)]
         
     | 
| 
      
 106 
     | 
    
         
            +
                read(2)[1]
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
              def value
         
     | 
| 
      
 110 
     | 
    
         
            +
                write [0x0, _(:rgblight_get_val)]
         
     | 
| 
      
 111 
     | 
    
         
            +
                read(2)[1]
         
     | 
| 
      
 112 
     | 
    
         
            +
              end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
              def hsv
         
     | 
| 
      
 115 
     | 
    
         
            +
                [hue, saturation, value]
         
     | 
| 
      
 116 
     | 
    
         
            +
              end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
              private
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
              def rgb2hsv r, g, b
         
     | 
| 
      
 121 
     | 
    
         
            +
                v     = [r, g, b].max
         
     | 
| 
      
 122 
     | 
    
         
            +
                delta = v - [r, g, b].min
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                s = v == 0 ? 0 : (delta / v.to_f)
         
     | 
| 
      
 125 
     | 
    
         
            +
                h = delta == 0 ? 0 : (case v
         
     | 
| 
      
 126 
     | 
    
         
            +
                when r then ((g - b) / delta) % 6
         
     | 
| 
      
 127 
     | 
    
         
            +
                when g then ((b - r) / delta) + 2
         
     | 
| 
      
 128 
     | 
    
         
            +
                when b then ((r - g) / delta) + 4
         
     | 
| 
      
 129 
     | 
    
         
            +
                end) * 60
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                [h.round, (s * 255).round, v]
         
     | 
| 
      
 132 
     | 
    
         
            +
              end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
              def write buf
         
     | 
| 
      
 135 
     | 
    
         
            +
                loop do
         
     | 
| 
      
 136 
     | 
    
         
            +
                  break if @handle.write buf.pack('C*')
         
     | 
| 
      
 137 
     | 
    
         
            +
                end
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
              def read size
         
     | 
| 
      
 141 
     | 
    
         
            +
                buf = @handle.read_timeout size, 300 # 300 ms timeout
         
     | 
| 
      
 142 
     | 
    
         
            +
                if buf
         
     | 
| 
      
 143 
     | 
    
         
            +
                  buf.unpack('C*')
         
     | 
| 
      
 144 
     | 
    
         
            +
                else
         
     | 
| 
      
 145 
     | 
    
         
            +
                  # Unfortunately, this seems to happen frequently.
         
     | 
| 
      
 146 
     | 
    
         
            +
                  raise CouldNotReadError, "could not read from device"
         
     | 
| 
      
 147 
     | 
    
         
            +
                end
         
     | 
| 
      
 148 
     | 
    
         
            +
              end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
              def _ command
         
     | 
| 
      
 151 
     | 
    
         
            +
                COMMAND_VERSIONS.fetch(@version).fetch(command)
         
     | 
| 
      
 152 
     | 
    
         
            +
              end
         
     | 
| 
      
 153 
     | 
    
         
            +
            end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            commands = []
         
     | 
| 
      
 156 
     | 
    
         
            +
            responses = []
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            OptionParser.new do |opts|
         
     | 
| 
      
 159 
     | 
    
         
            +
              opts.banner = "Usage: kbprog.rb [options]"
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
              opts.on("--hsv=[HSV]", "Set or get HSV (comma separated)") do |v|
         
     | 
| 
      
 162 
     | 
    
         
            +
                if v
         
     | 
| 
      
 163 
     | 
    
         
            +
                  commands << lambda { |kb| kb.sethsv(*v.split(",").map(&:to_i)) }
         
     | 
| 
      
 164 
     | 
    
         
            +
                else
         
     | 
| 
      
 165 
     | 
    
         
            +
                  commands << lambda { |kb| responses << { hsv: kb.hsv } }
         
     | 
| 
      
 166 
     | 
    
         
            +
                end
         
     | 
| 
      
 167 
     | 
    
         
            +
              end
         
     | 
| 
      
 168 
     | 
    
         
            +
              opts.on("--mode=[HSV]", "Set or get mode") do |v|
         
     | 
| 
      
 169 
     | 
    
         
            +
                if v
         
     | 
| 
      
 170 
     | 
    
         
            +
                  commands << lambda { |kb| kb.mode = v.to_i }
         
     | 
| 
      
 171 
     | 
    
         
            +
                else
         
     | 
| 
      
 172 
     | 
    
         
            +
                  commands << lambda { |kb| responses << { mode: kb.mode } }
         
     | 
| 
      
 173 
     | 
    
         
            +
                end
         
     | 
| 
      
 174 
     | 
    
         
            +
              end
         
     | 
| 
      
 175 
     | 
    
         
            +
            end.parse!
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
            kb = TeeloKB.open
         
     | 
| 
      
 178 
     | 
    
         
            +
            commands.each { |cmd| cmd.call kb }
         
     | 
| 
      
 179 
     | 
    
         
            +
            responses.each do |res|
         
     | 
| 
      
 180 
     | 
    
         
            +
              p res
         
     | 
| 
      
 181 
     | 
    
         
            +
            end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
            #p ez.mode
         
     | 
| 
      
 184 
     | 
    
         
            +
            #ez.mode = 5
         
     | 
| 
      
 185 
     | 
    
         
            +
            #ez.sethsv 300, 250, 255
         
     | 
| 
      
 186 
     | 
    
         
            +
            #p ez.hsv
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
            #rescue TeeloKB::Error => e
         
     | 
| 
      
 189 
     | 
    
         
            +
            #  exec "ruby --disable-gems -I lib:test #{__FILE__}"
         
     | 
| 
      
 190 
     | 
    
         
            +
            #end
         
     | 
    
        data/sample/set_hsv.rb
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'hidaping'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            def try_block times
         
     | 
| 
      
 4 
     | 
    
         
            +
              times.times { x = yield; return x if x }
         
     | 
| 
      
 5 
     | 
    
         
            +
              raise "Couldn't do it"
         
     | 
| 
      
 6 
     | 
    
         
            +
            end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            dev = HIDAPING.enumerate(0x0, 0x0).find { |dev| dev.product_string == "ErgoDox EZ" }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            handle = try_block(10) { dev.open }
         
     | 
| 
      
 11 
     | 
    
         
            +
            p handle
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            h = 0    # 0x0 to 0x168 (which is 360 base 10)
         
     | 
| 
      
 14 
     | 
    
         
            +
            s = 0xFF # 0x0 to 0xFF
         
     | 
| 
      
 15 
     | 
    
         
            +
            v = 0xFF # 0x0 to 0xFF
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            try_block(10) do
         
     | 
| 
      
 18 
     | 
    
         
            +
              handle.write [0x0, 0x6, (h >> 8) & 0xFF, h & 0xFF, s, v].pack('C*')
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            handle.read_timeout 10, 300 # 300 ms timeout
         
     | 
    
        data/sig/myhidapi.rbs
    ADDED
    
    
    
        data/test/joycon.rb
    ADDED
    
    | 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'hidaping'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            devices = HIDAPING.enumerate(0x0, 0x0)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            for d in devices
         
     | 
| 
      
 6 
     | 
    
         
            +
                printf("0x%04x, 0x%04x, %s\n", d.vendor_id, d.product_id, d.product_string)
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            handle = HIDAPING.open(0x057e, 0x2007)
         
     | 
| 
      
 10 
     | 
    
         
            +
            handle.send_feature_report("\x01\x48\x00\x01\x40\x40\x00\x01\x40\x40\x00")
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            while true
         
     | 
| 
      
 13 
     | 
    
         
            +
                report_raw = handle.read_timeout(64, 500)
         
     | 
| 
      
 14 
     | 
    
         
            +
                data = report_raw.unpack("a17va*")
         
     | 
| 
      
 15 
     | 
    
         
            +
                p data[1]
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
    
        data/test/test.rb
    ADDED
    
    | 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'hidaping'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            devices = HIDAPING.enumerate(0x0, 0x0)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            for d in devices
         
     | 
| 
      
 6 
     | 
    
         
            +
                printf("0x%04x, 0x%04x, %s\n", d.vendor_id, d.product_id, d.product_string)
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            if devices.length > 0
         
     | 
| 
      
 10 
     | 
    
         
            +
                handle = devices[0].open()
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                report_raw = handle.read_timeout(64, 500)
         
     | 
| 
      
 13 
     | 
    
         
            +
                p report_raw
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'minitest/autorun'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'hidaping'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class TestHIDAPING < MiniTest::Test
         
     | 
| 
      
 5 
     | 
    
         
            +
              def test_it_works
         
     | 
| 
      
 6 
     | 
    
         
            +
                devices = HIDAPING.enumerate 0x0, 0x0
         
     | 
| 
      
 7 
     | 
    
         
            +
                dev = devices.find { |dev| dev.product_string == "ErgoDox EZ" }
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                handle = dev.open
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                while !handle
         
     | 
| 
      
 12 
     | 
    
         
            +
                  p "retry"
         
     | 
| 
      
 13 
     | 
    
         
            +
                  handle = dev.open
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                p handle
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                buf = [0x0, 0x3, 35]
         
     | 
| 
      
 19 
     | 
    
         
            +
                loop do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  break if handle.write buf.pack('C*')
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                puts "done writing"
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                buf = handle.read_timeout 1, 500
         
     | 
| 
      
 25 
     | 
    
         
            +
                p buf
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              def test_can_enumerate_by_ids
         
     | 
| 
      
 29 
     | 
    
         
            +
                devices = HIDAPING.enumerate(0xfeed, 0x1307)
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                refute_predicate devices, :empty?
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
    
        data/test/xbox360.rb
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'hidaping'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            devices = HIDAPING.enumerate(0x0, 0x0)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            for d in devices
         
     | 
| 
      
 6 
     | 
    
         
            +
                printf("0x%04x, 0x%04x, %s\n", d.vendor_id, d.product_id, d.product_string)
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            handle = HIDAPING.open(0x045e, 0x028e)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            while true
         
     | 
| 
      
 12 
     | 
    
         
            +
                report_raw = handle.read_timeout(64, 500)
         
     | 
| 
      
 13 
     | 
    
         
            +
                data = report_raw.unpack("vvvvvSb*")
         
     | 
| 
      
 14 
     | 
    
         
            +
                p data
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: hidaping
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.1.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Repy
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Aaron Patterson
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: exe
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 1980-01-02 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 13 
     | 
    
         
            +
            description: |
         
     | 
| 
      
 14 
     | 
    
         
            +
              This is a small wrapper around HIDAPI.
         
     | 
| 
      
 15 
     | 
    
         
            +
              I couldn't get other HIDAPI wrappers to work, so I wrote this one.
         
     | 
| 
      
 16 
     | 
    
         
            +
              I'm using it to communicate with my keyboard, so it really only supports enough of the HIDAPI to do that.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              This gem is a fork from the original work by Aaron Patterson (@tenderlove).
         
     | 
| 
      
 19 
     | 
    
         
            +
            email:
         
     | 
| 
      
 20 
     | 
    
         
            +
            - gamecube02+git@gmail.com
         
     | 
| 
      
 21 
     | 
    
         
            +
            - tenderlove@ruby-lang.org
         
     | 
| 
      
 22 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 23 
     | 
    
         
            +
            extensions:
         
     | 
| 
      
 24 
     | 
    
         
            +
            - ext/hidaping/extconf.rb
         
     | 
| 
      
 25 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 26 
     | 
    
         
            +
            files:
         
     | 
| 
      
 27 
     | 
    
         
            +
            - ".clang-format"
         
     | 
| 
      
 28 
     | 
    
         
            +
            - ".github/workflows/gem-push.yml"
         
     | 
| 
      
 29 
     | 
    
         
            +
            - ".github/workflows/test.yml"
         
     | 
| 
      
 30 
     | 
    
         
            +
            - ".ruby-version"
         
     | 
| 
      
 31 
     | 
    
         
            +
            - CHANGELOG.md
         
     | 
| 
      
 32 
     | 
    
         
            +
            - LICENSE.txt
         
     | 
| 
      
 33 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 34 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 35 
     | 
    
         
            +
            - ext/hidaping/common.h
         
     | 
| 
      
 36 
     | 
    
         
            +
            - ext/hidaping/extconf.rb
         
     | 
| 
      
 37 
     | 
    
         
            +
            - ext/hidaping/hidaping.c
         
     | 
| 
      
 38 
     | 
    
         
            +
            - ext/hidaping/hidaping.h
         
     | 
| 
      
 39 
     | 
    
         
            +
            - ext/hidaping/hidaping_device.c
         
     | 
| 
      
 40 
     | 
    
         
            +
            - ext/hidaping/hidaping_device.h
         
     | 
| 
      
 41 
     | 
    
         
            +
            - ext/hidaping/hidaping_util.h
         
     | 
| 
      
 42 
     | 
    
         
            +
            - lib/hidaping.rb
         
     | 
| 
      
 43 
     | 
    
         
            +
            - lib/hidaping/version.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - sample/kbprog.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - sample/set_hsv.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - sig/myhidapi.rbs
         
     | 
| 
      
 47 
     | 
    
         
            +
            - test/joycon.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - test/test.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
            - test/test_myhidapi.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
            - test/xbox360.rb
         
     | 
| 
      
 51 
     | 
    
         
            +
            homepage: https://github.com/Repy/hidaping
         
     | 
| 
      
 52 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 53 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 54 
     | 
    
         
            +
            metadata:
         
     | 
| 
      
 55 
     | 
    
         
            +
              homepage_uri: https://github.com/Repy/hidaping
         
     | 
| 
      
 56 
     | 
    
         
            +
              source_code_uri: https://github.com/Repy/hidaping
         
     | 
| 
      
 57 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 58 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 59 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 60 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 61 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 62 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 63 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 64 
     | 
    
         
            +
                  version: 3.2.0
         
     | 
| 
      
 65 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 66 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 67 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 68 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 69 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 70 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 71 
     | 
    
         
            +
            rubygems_version: 3.7.1
         
     | 
| 
      
 72 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 73 
     | 
    
         
            +
            summary: A wrapper around hidapi for Ruby
         
     | 
| 
      
 74 
     | 
    
         
            +
            test_files: []
         
     |