Giter VIP home page Giter VIP logo

xrestrict's Introduction

xrestrict

A utility to modify the "Coordinate Transformation Matrix" of an XInput2 device.

Interactive Usage

Interactive mode is intended to be more user friendly than the "Basic Usage" explained below.

xrestrict -I [options]
  1. Ensure your input device is plugged in.
  2. Choose one of your computer monitors you wish to restrict your device to.
  3. Invoke xrestrict -I
  4. Use your device to click somewhere on the monitor you chose.

xrestrict will then modify your "Coordinate Transformation Matrix" to restrict your chosen device to your chosen monitor.

NOTE: In step 4 use device you wish to modify to click.

NOTE: To function properly, xrestrict -I temporarily resets some "Coordinate Transformation Matrix"s to the default value. However, if xrestrict -I terminates abnormally, it may not restore the correct "Coordinate Transformation Matrix"s. This is not likely to be a problem because most devices already use the default "Coordinate Transformation Matrix" to begin with, so xrestrict -I doesn't change it. In addition, xrestrict -I only modifies the "Coordinate Transformation Matrix" of devices with "Abs X" and "Abs Y" axes. Mice generally do not posess these and instead have "Rel X" and "Rel Y" axes. Typically, "Abs X" and "Abs Y" are only found on touchscreens and drawing tablets, and it is likely the only device like that is the one you are modifying.

Basic Usage

xrestrict -d $DEVICEID [-c $CRTCINDEX] [options]
  • DEVICEID is the XInput2 device XID, identical to that reported by xinput list
  • CRTCINDEX is the index in 0..N-1 of the N CRTCs to restrict the pointer device to. CRTCINDEX defaults to 0. For most multi-monitor setups, each non-mirrored CRTC corresponds to a different monitor. For most single-monitor setups, there will be only one CRTC which is equal to the size of the virtual screen.
  • options is a set of extra arguments which control things like alignment and fitting, for a complete list and description please look at xrestrict's usage output.

Results

Following successful invocation, the "Coordinate Transformation Matrix" of the pointer device will be modified. The pointer device should only be able to move within the given CRTC, or slightly more, as required to preserve the aspect ratio of the pointer device. To check the current "Coordinate Transformation Matrix" of a device, invoke xinput list-props $DEVICEID.

Dependencies

xrestrict uses Xlib, XInput2 support from Xlib, and XRandR

Ubuntu

On Ubuntu 14.04 the above dependencies correspond to the following packages:

libx11-dev libxi-dev libxrandr-dev

in addition to the basic packages required to build most software, and git to retrieve the source:

build-essential autoconf automake git-core pkg-config

From the console, a user may install all of these at once with the command:

sudo apt-get install build-essential autoconf automake pkg-config libx11-dev libxi-dev libxrandr-dev

openSUSE

On openSUSE 13.2 the above dependencies correspond to the following packages:

git automake autoconf gcc make libx11-devel libXrandr-devel xinput libXi-devel

From the console, a user may install all of these at once with the command:

sudo zypper install git automake autoconf gcc make libX11-devel libXrandr-devel xinput libXi-devel

Building

xrestrict uses a standard autotools configuration. To build xrestrict, first obtain the source code. If you do not have the xrestrict source code you may obtain it via git

From a console, change directories to where you wish to store the source code, then issue:

git clone https://github.com/ademan/xrestrict

After this, change into the directory of the source code you just retrieved:

cd xrestrict

At this point all you need to do is initialize the build system:

autoreconf -i
./configure

You are now ready to build xrestrict, which can be done by invoking Make:

make

Make will produce plenty of output, but when it's done, assuming there was no error, xrestrict should be built. You can invoke your newly built xrestrict with src/xrestrict.

License

xrestrict is provided without warrantee under the MIT license. See COPYING.

xrestrict's People

Contributors

ademan avatar

Stargazers

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

Watchers

 avatar  avatar

xrestrict's Issues

xrestrict uses both xlib and xcb

I started xrestrict with xcb, but xcb bindings for XInput2 were not ready for my use. As a result I'm mixing xlib and xcb calls. To reduce dependencies, and for uniformity, I want to eventually eliminate xcb code.

Build on Ubuntu 16.04

I'm trying to build xrestrict on Ubuntu 16.04 and getting this error:

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
./configure: line 3459: syntax error near unexpected token `X11,'
./configure: line 3459: `PKG_CHECK_MODULES(X11, x11)'

xrestrict ignores physical size of monitors

At present xrestrict does not attempt to use information about the physical size of monitors. On monitors with non-square pixels this could result in incorrect aspect ratios. I am unaware of practical cases where this would be a problem, however I'd prefer to be robust to this issue.

Allow users to affect all absolute pointer devices

Using xinput to discover the XID of the pointer device is not particularly user friendly. It might be desirable to allow xrestrict to affect all pointer devices with "Abs X" and "Abs Y" axes. This would not affect mice nor touchpads in their default configuration.

Cursor able to exceed desired area by one pixel

If I issue xrestrict -d 15 -c 0 to restrict my tablet to my left monitor, it can actually reach the first column of pixels on my right monitor. It may not be practical to address in all cases due to floating point inaccuracy but it should be addressed where possible.

How to best allow interactive session selection?

If a user uses xrestrict to confine their tablet to their left screen, and later wants to confine it to their right screen, they cannot do this. This is because interactive selection requires they be able to click on the right screen, but they've already confined themselves to their left screen.

To work around this, a user may unplug and replug their device but that is ugly.

xrestrict could reset all "Coordinate Transformation Matrix"s to identity prior to grabbing pointers, but that potentially munges state the user may wish to keep. In practice I believe this to be acceptable though, as tablets seem to be the most common type of device with absolute X and Y axes, and it seems unlikely a user would have two connected at once. Therefore the following procedure ought to be good enough:

  1. Find all devices with absolute X and Y axes with non-identity "Coordinate Transformation Matrix"s.
  2. Remember these matrices
  3. Reset all matrices to identity
  4. Perform grab
  5. Re-apply all matrices
  6. Apply xrestrict matrix

Clean up command line parsing(?)

Use a third party library? I don't particularly like getopt, but I think as soon as I add the remaining command line flags things are going to be pretty messy without some cleanup.

Allow users to specify alignment of tablet effective area.

rectangle_align() will align the left, right, top, or bottom edges of the reference and alignee rectangles. Top left is an Ok default, but I made it configurable with the intention that eventually users would be able to specify this alignment.

Allow users to select their monitor and/or tablet interactively

As mentioned in #6 , requiring the user to figure out the XID of their tablet before invoking xrestrict is not user friendly. A relatively user friendly user interaction is as follows:

  1. User invokes xrestrict --interactive or similar flag
  2. User is prompted to use their tablet to click on the monitor they wish to restrict the pointer to.
  3. User uses desired tablet device to click on the monitor they wish to use.
  4. xrestrict uses this information to discover both the monitor (output+crtc) and the tablet device id.

Open problems:
To support this interaction, each tablet device on the system must be able to reach every screen. This requires resetting the "Coordinate Transformation Matrix" for every tablet to the identity matrix. This might be undesirable, and in case of a bug (or if the user hard-kills xrestrict) could alter system state ("Coordinate Transformation Matrix" of all tablets) undesirably.

Allow users to interactively *switch* CRTCs

Because interactive selection uses the desired device to select the CRTC to use, it is not possible for the user to switch CRTCs in interactive mode. One must first allow the desired device to reach all CRTCs, which may be done any number of ways. A workaround is described in README.md. Another workaround is to simply unplug and replug the device which resets the Coordinate Transformation Matrix to identity, then invoke xrestrict.

Another alternative which might be more user friendly is during the cursor grab, any absolute pointers which move, have their Coordinate Transformation Matrix reset to identity. Drawbacks of this are: user may bump another device which would reset its coordinate Transformation Matrix against the users wishes (mitigation strategy: once the user has selected CRTC, re-set all other matrices). Another drawback is that the cursor jumps when altering its coordinate transformation matrix, perhaps the original proposal is best.

Current "best" proposal: When starting xrestrict in interactive mode, store the non-identity matrices for all devices with absolute X and Y axes. After selecting a screen in interactive mode, restore these matrices before finally calculating and applying the final matrix (Redundantly sets the matrix of the target device twice, but this can be easily mitigated).

Provide persistent device identifier to users

I would like to support something like the following user interaction:

  1. xrestrict --device-file=~/.config/xrestrict/mytablet -i
  2. User performs interactive selection of screen
  3. xrestrict saves persistent identifier to provided file
  4. xrestrict --device-file=~/.config/xrestrict/mytablet [OPTIONS] behaves the same as xrestrict -d $DEVICEID [OPTIONS] except $DEVICEID is discovered based on information in provided file

At present USB VID:PID:Interface numbers seem like the best choice for a persistent identifier.

On linux this "requires" retrieving the "Device Node" property from the XInput2 device, and then querying the device node via udev to discover the VID:PID:Interface numbers.

At least on FreeBSD the XInput2 devices do not appear to have a "Device Node" property so that may not work.

Alternatively, some combination of property values, available valuators and buttons, etc might be combined to create a "fingerprint" of a device, but that's a lot of work and seems like it would be brittle as well.

Finally, this might make sense to implement as a separate utility, the proposed user interaction could be emulated via something like:

  1. xfindusbdev $(xrestrict --verbose -i | grep XID | cut -f 2) > ~/.config/xrestrict/mytablet
  2. User performs interactive selection of screen
  3. xrestrict -d $(xfindusbdev --usbid-file ~/.config/xrestrict/mytablet) [OPTIONS]

The final problem with this is that VID:PID:Interface is not completely unique, two tablet devices of the same make and model may share this triple unfortunately. However, I feel that it's unique enough for the purposes of this utility and most of its potential users.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.