Xinput

I wanted a simple way of turning off the built in keyboard and the touchpad on my laptop while using a USB keyboard and a trackball.

This is sort of the skeleton for this.

#!/usr/bin/env ruby
# frozen_string_literal: true

%w(io/console timeout optimist_xl hash_dot).each {|¡t| require ¡t }

class Array; alias in? include?; end

def ignore(&bl) = ( nil )

class Xin
  attr_reader :dev

  def initialize = ( @dev = Hash[sc('id').zip(sc('name'))] )
  
  def id?(rex)
    @dev.each {|k,v| return k[/(\d+)/] if v[rex.tr('_', ' ')] }
    nil
  end

  def method_missing(n, id) =
      ( %i(enable disable).in?(n) ?
        (system 'xinput %s %s' % [n, id]) : super )
  
  def toggle(id) = ( enabled?(id) ? disable(id) : enable(id) )
  
  def enabled?(id) =
    ( `xinput list #{id}`[/device is disabled/] ? false : true )
  
  def disabled?(id) = ( !enabled?(id) )
  
  def confirm_disable(id, sec=5)
    disable(id)
    puts 'Disabled.. will revert in 5 seconds unless you press a key.'
    Timeout.timeout(sec) { STDIN.getch } rescue enable(id)
  end
  
  private
  def sc(s) = ( `xinput list --#{s}-only`.split(/\n/) )

end

=begin
        Example usage
        =============

          > xin --disable 'Optical Mouse'
          
          > xin --list
            2 => Virtual core pointer
            4 => Virtual core XTEST pointer
            3 => Virtual core keyboard
            5 => Virtual core XTEST keyboard
            6 => Power Button
            7 => Power Button
            8 => Sleep Button
            10 => AT Translated Set 2 keyboard
            ∼ 9 => ∼ USB Optical Mouse

          > xin --id 'AT Translated'
            ID => 10

          > xin --toggle 10

          > xin --enable 9

          > xin --disable 'AT Translated' --confirm
            Disabled.. will revert in 5 seconds unless you press a key.


        short
        =====

          > xin -d Mouse
          > xin -l
          > xin -t 10
          > xin -i Set_2    Underscore translates to Space
          > xin -e 8 -c

=end

xin = Xin.new

paq     = ->(s) { puts s; exit }
do_list = ->{ xin.dev.each {|k,v| puts '%s => %s' % [k, v]}; exit }
do_id   = ->(id) { xin.id? id }

do_cmd  = ->(cmd, arg) {
  arg = xin.id?(arg) unless arg[/^\d+$/]
  xin.send(cmd.to_s, arg); exit
}


op = OptimistXL.options do
  opt :enable,  'enable device',        type: String
  opt :disable, 'disable device',       type: String
  opt :toggle,  'toggle device',        type: String
  opt :id,      'fetch id from regex',  type: String
  
  opt :list,    'list devices'
  opt :confirm, 'confirmed disable'
end.to_dot

do_list[]                             if op.list
paq['ID => %s' % do_id[op.id]]        if op.id
do_cmd[:confirm_disable, op.disable]  if op.confirm && op.disable
%i(enable disable toggle).each { do_cmd[_1, op[_1]] if op[_1] }