Skip to content

Getting Started

Izzatbek Mukhanov edited this page Dec 11, 2016 · 12 revisions

Main concepts of libpointing toolkit

Introduction to URIs

A Uniform Resource Identifier (URI) is a string of characters used to identify a name of a resource. In libpointing objects of the principal classes are created using URIs. For example, in order to specify a transfer function, the create method of the the TransferFunction class is used. The TransferFunction class initializes a platform-specific subclass with the provided URI:

TransferFunction *tf = TransferFunction::create("osx:mouse?setting=0.6875", pointingDevice, displayDevice);

In this case for the specified pointingDevice and dispayDevice, the transfer function corresponding to OS X system will be instantiated with the acceleration setting=0.6875.

URI parameters

URIs consist of a few parts. In libpointing a URI may look as follows:

scheme:opaque?paramname=paramvalue

scheme is dedicated to detail the main object, opaque is used to define the object version or to detail it further. For each entity in libpointing, the possible options are given. The part of URI (?paramname=paramvalue) following ? is a query string. Parameters defined in query string are usually optional and are used to detail the members of the queried entity.

Main classes

Using URIs objects can be specified for the following classes:

  • PointingDevice
  • DisplayDevice
  • TransferFunction

To create an object the Factory method design pattern is used. The use of URIs simplify the cross-platform development of the project and allows to re(define) specific instances at runtime. Each of these 3 classes have method create(uri, ...) which constructs an object depending on the specified URI.

expanded

Those classes also have the method getURI(expanded) which outputs the URI for an object. Set the parameter expanded to true, if all available URI parameters need to be output.

PointingDevice

debugLevel

The debug level defines the level of information output by devices or transfer functions. This may be the list of devices available, their names and descriptors. By default, it is 0, but it can be changed using the method setDebugLevel(debugLevel) or directly in in the query part of the URI with debugLevel parameter.

Pointing Devices

Pointing Devices are specified using PointingDevice class. To create an object of PointingDevice, simply call its create method.

PointingDevice *input = PointingDevice::create("any:");

The toolkit provides direct access to any connected HID pointing device through platform-specific subclasses and URIs such as osxhid:/USB/4600000/AppleUSBTCButtons, winhid:/65591 or input:/dev/input/event0 depending on the system.

any:

The special URI any: matches any supported device and will list the available ones in the console if a debugLevel=1 option is passed on the query string. vendor and/or product query arguments may specify vendor id or product id of a device. In this case, the first match will be returned.

All HID PointingDevice objects support hot (re)plugging of the corresponding device. This means that a device can be used without reinitializing when it is connected or disconnected.

Note: If you specified any: and there are no reports coming from your device when you move it, this is most probably that any: was matched against another pointing device. Make sure you list all devices with any:?debugLevel=1 and choose the correct one.

crossplatform

By default, getURI(expanded) returns platform-specific URI for pointing devices. However, the same device can be used on any of the platforms with the URI specifying vendor and product identifiers. To specify this and obtain cross-platform URI, crossplatform option must be set to true in getURI(expanded, crossplatform). For example the line:

URI uri = input->getURI(false, true); // expanded=false and crossplatform=true

may return URI with a string like that: any:?vendor=0x46d&product=0xc52b which corresponds to the Logitech Optical Mouse (M325). Now, you can work with the same device specifying this URI.

dummy:

The toolkit also includes two pseudo-device subclasses for debugging and testing that can be instantiated with URIs such as dummy:?cpi=800&hz=125. This device will return the specified values when queried for its resolution and update frequency.

PointingDeviceManager

The list of pointing devices can be seen using PointingDeviceManager class. It provides the name of a device and unique URI that can be used to obtain an object of PointingDevice.

PointingDeviceManager *manager = PointingDeviceManager::get();
for (PointingDescriptorIterator it = manager->begin(); it != manager->end(); it++)
{
    PointingDeviceDescriptor desc = *it;
    std::cout << "Device name: " << desc.vendor << " - " << desc.product << std::endl;
    PointingDevice *device = PointingDevice::create(desc.devURI);
    // Work with device ...
    // ...
    delete device;
}

To detect plug-in and plug-out of pointing devices add DeviceUpdateCallback as follows:

void updateCallback(void *context, const PointingDeviceDescriptor &desc, bool wasAdded)
{
    if (wasAdded)
        std::cout << "New device was added" << std::endl;
    else
        std::cout << "Device was removed" << std::end;

    std::cout << "Device URI: " << desc.devURI
              << " vendor: " << desc.vendor
              << " product: " << desc.product << std::endl;
}

// ...

// Somewhere in your code:
manager->addDeviceUpdateCallback(updateCallback, anyContext);

PointingDevice URI query parameters

Parameters osx linux windows description default
cpi* x x x Number of counts per inch 400
hz* x x x Mouse update frequency (Hz) 125
debugLevel x x x The level of information [0, 2] 0
vendor x   x x Vendor Id of the device 0x0
product x x x Product Id of the device 0x0
seize x x Seize the given device in the system [0, 1]. This option gives an exclusive access for the device preventing other programs from receiving input from this device (This may be useful, if you want to create your own cursor replacing the original one). 0

* In many cases the resolution and update frequency of the pointing device are not present in the descriptors, thus, default or estimated values are returned.

In addition, one can specify their default values in the corresponding methods getResolution(defval) and getUpdateFrequency(defval). Those methods will return a given value only if the corresponding value was not found in the descriptor or could not be estimated from the input.

Moreover, sometimes manufacturers put wrong values in the descriptor. To force another update frequency or number of inches one can put another value for cpi or hz in the URI for PointingDevice (like any:?vendor=0x46d&product=0xc05a&cpi=1600&hz=500).

Display Devices

DisplayDevice is another entity class which can be created as follows:

DisplayDevice *output = DisplayDevice::create("any:");

Display devices play an important role while computing transfer functions. According to their resolution, a transfer function computes the gain for a given input. Depending on system, display devices may have different URIs:

  • OS X - osxdisplay:/<ID> - The specified CoreGraphics display or any if the path is omitted.
  • Linux - xorgdisplay:<display name> - The specified X11 display of the form [hostname]:displaynumber[.screennumber].
  • Windows - windisplay:/<display name> - The specified name as provided by the EDID.

Pseudodisplay may be created with specified parameters using URI like dummy:?ppi=96&hz=60&bx=0&by=0&bw=0&bh=0&w=0&h=0, where:

  • ppi- resolution (pixels per inch)
  • hz - refresh rate in Hz
  • bx, by, bw, bh - horizontal and vertical bounds (in pixels)
  • w, h- width and height (in mm)

Transfer Functions

A transfer function represents the mapping between the actions in motor space and the resulting output in display space. Typically it represents the relationship between the velocity of a pointing device in motor space and the cursor velocity in display space. Libpointing provides a variety of transfer functions all of which can be used simply by calling the create method in the TransferFunction class. In the current version (0.92) the following transfer functions are supported by all three operating systems:

osx

Mac OS X transfer function which uses the named hard-wired table or the one loaded from the specified file. URI to use this function is osx:?setting=0.6875.

Note that, in the current version echomouse-based interpolated transfer function is used, because the original transfer function can not be distributed with GPL license.

Mac OS X acceleration

Possible settings of the acceleration slider:

[0, 0.125, 0.3125, 0.5, 0.6875, 0.875, 1, 1.5, 2, 2.5, 3]

windows

URI to use it: windows:?slider=0&epp=true.

Note that, in the current version echomouse-based interpolated transfer function is used, because the original transfer function can not be distributed with GPL license.

Windows acceleration

slider defines the position of the acceleration slider, which can take values from [-5, 5]. epp uses non-linear transfer functions. When it is disabled, linear functions are used.

xorg

Xorg transfer function. Possible URIs:

  • xorg:noop - Xorg acceleration disabled using the NoOp scheme.
  • xorg:lightweight?num=2&den=1&thr=4 - Xorg acceleration using the lightweight scheme, where num and den represent the numerator and denominator of the acceleration and thr represents the threshold defining the minimum velocity that needs to be achieved to switch from the low gain to the high one.
  • xorg:<profile>?num=2&den=1&thr=4&cm=10&ca=1&ma=1, where Xorg acceleration using the specified profile of the predictable scheme. The active profile specifies how the estimated velocity will be used to determine the actual CD gain. Profile must be none, classic (default), devicespecific, polynomial, smoothlinear, simple, power, linear or smoothlimited. ca, ma correspond to constant acceleration and minimum acceleration.

system

Replicates the current system function (osx, windows or xorg). Query string options are also applied on the system pointer.

normalize

In URIs for system transfer functions (osx:, windows:, xorg: or system:) you can specify a query argument normalize which will take into account the resolution of pointing and display devices. Since operating systems do not take into account the input and output resolutions, so if you have a high-resolution mouse, you may get very fast movements. Provided normalize=true, the gain applied by a transfer function will be normalized with respect to the standard resolutions (Usually 400 CPI for mice and 96 PPI for displays).

Custom transfer functions

Tune your own transfer function or build it from scratch.