добавление поддержки xinputустройства ввода (например, графические планшеты), позволяющие рисовать удобнее и проще, чем мышью, последнее время стали намного дешевле . самый простой метод использования подобных устройств - замена мыши, но следует заметить, что также существуют другие преимущества :
для детальной информации о дополнительных возможностях xinput, смотрите xinput howto. анализируя, например, структуру gdkeventmotion мы видим, что она имеет поля для хранения информации об устройствах с дополнительными возможностями.
pressure определяет давление, задаваемое числом между 0 и 1. xtilt и ytilt могут иметь значения между -1 и 1, соответствующие углу наклона в каждом из направлений. source и deviceid указывают на устройство, связанное с событием. source предоставляет простую информацию об устройстве. она может иметь такие значения:
deviceid - уникальный id устройства. оно может быть использовано для выяснения дальнейшей информации об устройстве с помощью вызова gdk_input_list_devices() (см. ниже). специальное значение gdk_core_pointer чаще всего указывает простую мышь. расширение возможностей устройствадля того, чтобы дать gtk понять о нашем желании использовать дополнительную информацию устройства ввода, нужно всего-то добавить одну строку в программму:
используя значение gdk_extension_events_cursor мы указываем, что мы заинтересованы в дополнительных событиях устройства, но только если мы сами не должны рисовать свой собственный курсор. см. дальнейшие исследования для выяснения более подробной информации о рисовании курсора. также можно использовать gdk_extension_events_all при желании рисовать свои курсоры или gdk_extension_events_none для возврата к настройкам по умолчанию. но это ещё не всё. по умолчанию дополнительные возможности устройств не включены: мы должны пользователям предоставить некий механизм для конфигурирования устройств. для автоматизации этого процесса gtk предоставляет виджет inputdialog. предоставленный код демонстрирует работу с inputdialog:
(следует заметить, что после уничтожения диалога, мы не храним указатель на него. это гарантирует отсутствие ошибки сегментации.) inputdialog имеет две кнопки: "закрыть" и "сохранить", которые ничего в принципе не делают: "закрыть" прячет диалог, "сохранить" - спрятана. использование информации устройства с расширенными возможностямиустройство включено - можно начинать пользоваться дополнительными возможностями. в принципе, использование этой информации - вполне безопасное действие, т.к. полученные данные будут вполне вменяемы, даже если устройство не было включено. следует использовать gdk_input_window_get_pointer(), а не gdk_window_get_pointer, т.к. последний вызов не возвращает дополнительную информацию устройства.
при вызове функции следует указать id устройства и окно. обычно id берётся из поля deviceid структуры события. опять же, даже при наличии обычного устройства ввода (мышь) полученные данные будут корректными. просто event->deviceid будет иметь значение gdk_core_pointer. обработчики событий нажатия кнопки или движения особо не меняются - лишь добавляется обработка дополнительной информации.
так же следует как-нибудь использовать полученную информацию. скажем, функция draw_brush() рисует разными цветами в зависимости от event->source и меняет размер кисти в зависимости от давления.
выяснение дополнительной информации об устройствев качестве примера приведём код, который показывает имя устройства при нажатии на кнопку. для выяснения имени используется функция
, которая возвращает список (glist из библиотеки glib) структур gdkdeviceinfo. gdkdeviceinfo определена как:
скорее всего большинство полей этой структуры будет вами проигнорировано до тех пор, пока вам не нужно сохранение конфигурации xinput. в данный момент нас интересует поле name, которое представляет из себя имя, присвоенное устройству x'ми. в свою очередь, если has_cursor равен false, нам следует рисовать курсор самим, но т.к. мы указали gdk_extension_events_cursor нам не следует об этом беспокоится. функция print_button_press() просто итерирует по возвращённому списку до тех пор пока не найдёт совпадение.
описанное выше - последний шаг включения поддержки "xinput" в нашей программме. дальнейшие исследованияне смотря на то, что наша программма достаточно не плохо поддерживает xinput, не хватает того, что мы бы желали видеть в полноценной программме. во первых, пользователь скорее всего не захочет конфигурировать устройство ввода при каждом запуске программмы - мы должны позволить сохранить конфигурацию. это достигается итерированием по результату gdk_input_list_devices() и записью результата в файл. для восстановления состояния при загрузке программмы gdk предоставляет следующие функции:
(список, возвращённый gdk_input_list_devices() не должен изменяться на прямую.) пример подобной программмы - gsumi (доступна:http://www.msc.cornell.edu/~otaylor/gsumi/) конечно, было бы прекрасно иметь стандартный метод выполнения подобной процедуры, но, наверное, это задача библиотек более высокого уровня, скажем gnome. другой не малый недостаток - отсутствие курсоров. платформы, отличные от xfree86, на данный момент не позволяют одновременное использование устройства ввода как простую мышь и специальное устройство, используемое напрямую из приложения. подробнее: xinput-howto. это означает, что если автор приложения желает сделать своё приложение более универсальным, нужно курсоры рисовать самому. приложение, само желающее рисовать курсоры, должно сделать 2 вещи: определить требует ли устройство ввода прорисовки курсора и состояние устройства ввода (ведь приложение должно вести себя натурально: курсор пропадает, если стилус не дотрагивается до планшета, и появляется при контакте с планшетом). первое достигается поиском устройства в списке по имени. второе - используя событие "proximity_out". пример прорисовки собственных курсоров может быть найден в программме "testinput" из поставки gtk.
|