Поддержка мультитач-жестов в ноутбуках, оборудованных сенсорными панелями

Добавление трехпальцевого скольжения и щипков при помощи утилиты synclient и синтетических X-событий

Реализация поддержки жестов скольжения и щипков в Linux®-приложениях путем анализа вывода утилиты synclient для сенсорной панели Synaptics.

Натан Харрингтон, программист, IBM

Фото автораНатан Харингтон (Nathan Harrington) - программист в IBM, работающий в настоящее время с Linux и с технологиями поиска ресурсов.



11.05.2012

Мультитач-интерфейсы предоставляют множество преимуществ для интеграции новых режимов взаимодействия в приложения. Современные аппаратные платформы и драйверы для операционных систем Mac OS X и Microsoft® Windows® позволяют создавать в приложениях более эффективную навигацию с использованием более разнообразных жестов, чем простые касания. В статье рассматриваются инструментальные средства и код, необходимые для добавления поддержки этих новых движений в более старое аппаратное обеспечение на платформе Linux®. Представленный здесь Perl-код, анализирующий вывод утилиты synclient, позволяет назначить выполнение функций приложения жестам трехпальцевого скольжения и сведения/разведения пальцев (щипкам).

Требования

Аппаратное обеспечение

Представленный здесь код, предназначенный для использования на компьютерах, оборудованных сенсорными панелями Synaptics TouchPad, разрабатывался на IBM® ThinkPad T30. Панели Synaptics используются во многих ноутбуках, от Acer Aspire до Toshiba Tecra. В разделе Ресурсы приведена ссылка на список оборудования, совместимого с сенсорной панелью Synaptics.

Программное обеспечение

Необходимо современное ядро Linux с поддержкой evdev. К счастью, в большинстве современных дистрибутивов данная функциональность является встроенной. Многие дистрибутивы поставляются также с пакетом Synaptics, содержащим утилиту synclient, которая используется для мониторинга событий сенсорной панели. Fedora Core, например, содержит также подходящую конфигурацию X Window System, позволяющую использовать сенсорную панель с минимальными модификациями. Другие дистрибутивы (например, Ubuntu V7.10) могут потребовать определенной настройки для корректной работы пакета Synaptics, устанавливаемого при помощи команды sudo apt-get install tpconfig. Ссылки на дополнительную информацию по настройке базовой функциональности для сенсорной панели Synaptics под Linux приведены в разделе Ресурсы.

Понадобится также модуль Time::HiRes из CPAN, обеспечивающий точный контроль времени для обработки событий сенсорной панели. Кроме него понадобится модуль X11::GuiTest для отправки в приложения синтетических событий X Window. Ссылки на эти инструменты приведены в разделе Ресурсы.


Проверка базовой функциональности

Если управление посредством сенсорной панели разрешено, убедитесь, что она адекватно реагирует на касания пальцев. Выполните команду synclient -m 100 и попробуйте выполнить различные касательные движения на сенсорной панели. Должна отобразиться примерно следующая информация.

Листинг 1. Пример результатов работы synclient -m 100
    time     x    y   z f  w  l r u d m     multi  gl gm gr gdx gdy
  13.872  5680 4409   0 0  0  0 0 0 0 0  00000000   0  0  0   0   0
  14.891  1072 3945  28 1  4  0 0 0 0 0  00000000   0  0  0   0   0
  14.994  3529 2667 104 2  5  0 0 0 0 0  00000000   0  0  0   0   0
  15.605  3669 3667   0 0  0  0 0 0 0 0  00000000   0  0  0   0   0
  16.625  2628 2841 255 3  5  0 0 0 0 0  00000000   0  0  0   0   0
  17.951  3117 2843 255 3  5  0 0 0 0 0  00000000   0  0  0   0   0
  18.053  2902 3142   3 1 15  0 0 0 0 0  00000000   0  0  0   0   0
  18.155  2430 3062   0 0  0  0 0 0 0 0  00000000   0  0  0   0   0

Попробуйте выполнить одно-, двух- и трехпальцевые касания, чтобы проверить корректность обнаружения событий. Убедитесь, что сенсорная панель распознает касание трех пальцев, поскольку первым добавляемым нами жестом будет трехпальцевое скольжение. Обратите внимание на то, как сенсорная панель реагирует на отсутствие касаний, а также на то, как считываются координаты X и Y при касании двумя пальцами с меняющимся расстоянием между ними. Приведенный ниже сценарий использует некоторые из этих характеристик для обнаружения щипковых жестов. Нажмите комбинацию клавиш Ctrl+c для выхода из synclient


Общий подход

Использование вывода утилиты syclient для мониторинга состояния сенсорной панели является простым и эффективным способом добавить дополнительные варианты взаимодействия с пользователями в Linux-приложения. Представленная ниже программа gestureListener.pl открывает канал (pipe) для чтения данных из synclient и обрабатывает события сенсорной панели для обнаружения жестов. Эти жесты связываются с клавиатурными командами, отправляемыми в текущее активное приложение X Window System.


Жесты скольжения

Трехпальцевое скольжение – это относительно простой для обнаружения жест, поскольку он всего лишь требует перемещения на панели трех пальцев влево или вправо. В листинге 2 приведено начало программы gestureListener.pl, начинающей обработку данных, получаемых от synclient, для обнаружения жеста.

Листинг 2. Начало программы gestureListener.pl
#!/usr/bin/perl -w  
# gestureListener.pl прослушивает события щипка и скольжения
use strict;
use Time::HiRes();
use X11::GUITest qw( :ALL );

my @xHist = ();               # история координаты x
my @yHist = ();               # история координаты y
my @xHistThree = ();          # история координаты x (три пальца)

my $lastTime = 0;             # монитор времени для сброса события сенсорной панели
my $eventTime = 0;            # проверка времени между событиями
my $eventString = "default";  # выполняемое событие
my $centerTouchPad = 3000;    
my $openSt         = 1000;    # начало разведения пальцев
my $openEn         = 500;     # конец разведения пальцев
my $closeSt        = 1000;    # начало сведения пальцев
my $closeEn        = 1000;    # конец сведения пальцев

my $synCmd = qq{synclient TouchpadOff=1 -m 10};
my $currWind = GetInputFocus();
die "couldn't get input window" unless $currWind;
open(INFILE," $synCmd |") or die "can't read from synclient";

Отметим, что может потребоваться настройка переменной centerTouchPad и других параметров, зависящая от конкретного аппаратного устройства или уровня драйвера Synaptics. Параметр TouchPadOff=1 утилиты synclient отключает стандартные события сенсорной панели. При этом красный джойстик (на ThinkPad и других ноутбуках) остается доступным, так же как и поддержка PS2- и USB-мыши. Отключать сенсорную панель не обязательно, но это уменьшит проблемы идентификации событий мыши, не связанных с жестами щипков и скольжений.

Вызов GetInputFocus определяет идентификатор текущего активного окна. Он позволяет команде SendKeys (использующейся далее) отправлять синтетические события X Window текущему активному окну. В листинге 3 начинается основной цикл программы и считываются выходные данные synclient.

Листинг 3. Начало основного цикла программы
while( my $line  = <INFILE>)
{
  chomp($line);
  my(  $time, $x, $y, $z, $f ) = split " ", $line;
  next if( $time =~ /time/ ); #ignore header lines
  
  if( $time - $lastTime > 1 )
  { 
    @xHist = ();
    @yHist = ();
    @xHistThree = ();
  }#if time reset
  
  $lastTime = $time;

Сброс массивов истории обнаружения событий по прошествии определенного времени очень важен для устранения наложения жестов. В листинге 4 показано начало обнаружения трехпальцевых жестов в основном цикле программы.

Листинг 4. Обработка трехпальцевых жестов
  # обнаружение трехпальцевого скольжения
  if( $f eq "3" )
  {
    @xHist = ();
    @yHist = ();

    push @xHistThree, $x;
        
    if( @xHistThree > 10 )
    { 
      my @srt = sort @xHistThree;
      my @revSrt = reverse sort @xHistThree;

      if( "@srt" eq "@xHistThree" )
      { 
        # alt + стрелка вправо - вперед
        $eventString = "'%({RIG})";
      }elsif( "@revSrt" eq "@xHistThree" ) 
      {   
        # alt + стрелка влево - назад
        $eventString = "'%({LEF})";
      }#если вперед или назад

      @xHistThree= ();
        
    }#если более 10 точек в трех массивах finger

После получения 10 точек при трехпальцевом скольжении выполняется обработка координат X, чтобы определить порядок сортировки (по возрастанию или по убыванию). Если текущему значению координаты X соответствует сортировка по возрастанию, устанавливается состояние скольжения вправо. В противном случае, если текущему значению X соответствует сортировка по убыванию, устанавливается состояние скольжения влево. Это состояние хранится в переменной eventString: ниже будет показано, как ее использовать.

Листинг 5. Продолжение основной логики – выполнение события
  }else
  { 
    # сбросить все данные; да, вы можете иметь 0 пальцев в x,y
    @xHist = ();
    @yHist = ();  
    @xHistThree = ();
  }# если не один или два или три пальца
  
  # обрабатывать только одно событие в интервале времени
  if( $eventString ne "default" )
  { 
    if( abs(time - $eventTime) > 1 )
    { 
      $eventTime = time;
      SendKeys( "$eventString");
    }#если прошло достаточно времени
    $eventString = "default";
  }#если не событие по умолчанию

}#строка synclient

close(INFILE);

В этом месте каждая структура данных для скольжения и щипка сбрасывается, если касание трех пальцев не обнаружено. Если событие было установлено и прошло достаточно много времени с момента выполнения последнего события, выполняется новое событие. Подпрограмма SendKeys отправляет соответствующее событие (Alt+left или стрелку вправо) в текущее активное приложение. Как показано в демонстрационных видеоматериалах (см. раздел Ресурсы), эти трехпальцевые жесты используются для перемещения вперед и назад по истории просмотра в окне браузера.


Щипковые жесты

Щипковые жесты существенно сложнее обнаружить, особенно на старом оборудовании, которое использовалось при написании данной статьи. Удобным способом извлечения соответствующей информации из данных сенсорной панели является отслеживание сведения и разведения пальцев в режиме реального времени при помощи программы kst. Вставьте код, приведенный в листинге 6, в строку 65 (выше else), чтобы начать фрагмент обнаружения сведения пальцев.

Листинг 6. Определение сведения пальцев
  }elsif( $f eq "2" || $f eq "1" )
  {
    # принять данные о касании 1 или 2 пальцев как часть фрагмента pinch
    @xHistThree = ();
  
    push @xHist, $x;
    push @yHist, $y;
    
    if( @xHist > 50 )
    {
      if( (getStrAvg(\@xHist) > $closeSt && getStrAvg(\@yHist) > $closeSt) &&
          (getEndAvg(\@yHist) < $closeEn && getEndAvg(\@yHist) < $closeEn) )
      {
        # обнаружено сведение, теперь ищем отклонение

        my $tenX = 0; 
        my $tenY = 0;
        for my $each( @xHist[40..49] ){ $tenX += $each }
        for my $each( @yHist[40..49] ){ $tenY += $each }
        $tenX = $tenX / 10;
        $tenY = $tenY / 10;

        my $diffX = 0;
        my $diffY = 0;
        for my $each( @xHist[40..49] ){ $diffX += abs( $each - $tenX ) }
        for my $each( @yHist[40..49] ){ $diffY += abs( $each - $tenY ) }

        # ctrl + уменьшить размер шрифта
        if( ($diffX+$diffY) > 80 ){ $eventString = "^({-})" }
        
        @xHist = ();
        @yHist = ();
        @xHistThree = ();

      }#если x и y попадают в интервал

    }#если достаточно данных для 50 точек обнаружения сведения

При обнаружении щипка для улучшения общего отслеживания учитываются касания одним или двумя пальцами. Кратковременные касания и кратковременное движение одного пальца за пределы панели во время щипка проще обрабатывать, если учитывать одно или два касания как часть щипка.

После получения данных о 50 и более точках вычисляются средние положения начала и конца последних 50 точек. Третий оператор if выполняет четыре отдельные проверки положения начальной и конечной точек для обнаружения сведения – в частности, превышают ли средние значения X и Y начальных точек значения начальных точек сведения. Это означает, что начальные положения пальцев должны быть в углах, и, наоборот, конечные точки должны быть внутри конечных точек сведения. Функции getStrAvg и getEndAvg для надежности вычисляют средние значения трех начальных и конечных точек.

Настоящие мультисенсорные устройства позволяют считывать координаты X и Y для положения каждого пальца. Имеющееся у нас оборудование Synaptics не имеет этой функциональности, но обеспечивает аналогичное поведение, так как точки касания двух пальцев "усредняются" в одну для программы synclient. Анализ вывода synclient показывает, что когда два пальца касаются нижнего левого и верхнего правого углов, значения быстро меняются от углов к центру сенсорной панели. Если точки касания остаются в углах, вывод synclient показывает, что координаты X и Y находятся примерно в центре панели. При перемещении пальцев в направлении центра автоматическое усреднение показывает небольшие возмущения. Отклонение в данных, определенное в приведенном выше фрагменте кода, указывает на сведение, в отличие от усреднения данных в ситуации, когда пальцы находятся в углах без движения.

Десять последующих значений истории координат X и Y усредняются. Затем вычисляется разница между каждым из 10 этих значений и средним последних 10 значений. Если общая разница достаточно велика (больше 80 в нашем примере), обнаруживается достаточное отклонение, и в eventString устанавливается условие сведения пальцев.

Для обнаружения сведения добавьте код, приведенный в листинге 7, в строку 103 (после закрывающей скобки оператора if по 50 точкам сведения).

Листинг 7. Обнаружено сведение, теперь ищем достаточное отклонение
    #разведение требует существенно меньше данных
    if( @xHist > 10 )
    {
      if( (getStrAvg(\@xHist) < $openSt && getStrAvg(\@yHist) < $openSt) &&
          (getEndAvg(\@yHist) > $openEn && getEndAvg(\@yHist) > $openEn) )
      {
        # ctrl + увеличить размер шрифта
        $eventString = "^({+})"; 

        @xHist = ();
        @yHist = ();
        @xHistThree = ();
      }#если absx и absy

    }#если данных достаточно

Для надежного обнаружения разведения не только требуется существенно меньшее количество точек, но и не является обязательным этап обнаружения отклонений. При мониторинге в режиме реального времени с использованием программы kst вывод synclient дает значительно более широкий диапазон координат точек, собираемых для жеста разведения. Автоматическое усреднение позиций двух пальцев не оказывает большого влияния на координаты X и Y synclient при выполнении жеста разведения. Поэтому для точного обнаружения разведения нет необходимости распознавать отклонение. В листинге 8 показаны подпрограммы усреднения getStrAvg и getEndAvg.

Листинг 8. Две подпрограммы усреднения
sub getStrAvg
{     
  my $arrRef = $_[0];
  my $val = (@$arrRef[0] + @$arrRef[1] + @$arrRef[2]) / 3;
  $val = abs( $val - $centerTouchPad ); 
  return($val);
}#getStrAvg
        
sub getEndAvg
{       
  my $arrRef = $_[0];
  my $val = (@$arrRef[@$arrRef-3] + @$arrRef[@$arrRef-2] + 
               @$arrRef[@$arrRef-1]) / 3;
  $val = abs( $val - $centerTouchPad );
  return($val);
}#getEndAvg

Поместите код, приведенный в листинге 8, в строку 144 (конец файла) для завершения программы gestureListener.pl. getStrAvg и getEndAvg отвечают за возврат среднего значения первых трех и среднего значения последних трех элементов массива соответственно.

Использование

Для активизации программы просто выполните команду perl gestureListener.pl. Перейдите в окно браузера и пройдите по истории просмотренных адресов, выполняя скольжение вправо и влево. Необходимо отметить, что из-за небольших размеров сенсорной панели и ограниченных возможностей оборудования, возможно, нужно будет попрактиковаться в выполнении этих жестов. Примеры движений, работающих на ThinkPad автора, продемонстрированы в демонстрационных видеоматериалах (см. раздел Ресурсы). Опять включить функции мыши в сенсорной панели можно путем выполнения команды synclient TouchPadOff=0 после завершения программы gestureListener.pl.


Заключение и другие примеры

Связь между жестами и событиями

Помните, что команда SendKeys отправляет соответствующие команды (Alt+Left, Ctrl+/- и т.д.) в текущее активное приложение, независимо от функциональности этих переключателей. Можно внести относительно простые изменения в программу и указывать для отправки в приложение различные клавиатурные команды или события мыши в зависимости от названия окна.

Другие примеры и изменения

Представленные здесь анализ и обработка вывода программы synclient и создание синтетического X-события – это только один способ добавить функциональность к сенсорной панели Synaptics. Подумайте над добавлением дополнительных возможностей распознавания жестов, таких как вращение, посредством извлечения информации из вывода программы synclient. В качестве альтернативы измените исходный код драйвера Synaptics для поддержки дополнительных возможностей на уровне ядра и перепишите приложения для использования преимуществ этих новых каналов ввода.


Загрузка

ОписаниеИмяРазмер
Пример кодаos-touchpad.gestureListener_0.1.zip2 КБ

Ресурсы

Научиться

  • Оригинал статьи: Add multitouch gesture support to a TouchPad-equipped laptop (EN).
  • Демонстрационные материалы на YouTube.com.
  • Текущее состояние проекта Synaptics, посвященного драйверам сенсорной панели для Linux (в настоящее время интегрирован с проектом xorg на freedesktop.org.
  • TuxMobil и Ubuntu имеют ресурсы для настройки сенсорных панелей Synaptics.
  • Скачайте модуль Time::HiRes из CPAN.
  • В CPAN доступен замечательный модуль Денниса Поулсенса (Dennis Paulsens) X11::GuiTest.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source
ArticleID=814632
ArticleTitle=Поддержка мультитач-жестов в ноутбуках, оборудованных сенсорными панелями
publish-date=05112012