C/C# Mono в Unix/Linux, взаимодействующий с X11: как я могу переопределить, чтобы XEvent.send_event всегда было ложным при использовании XSendEvent?

Как видно из заголовка, я хотел бы использовать функцию Xlib XSendEvent для имитации "реального" ввода с помощью мыши (вход IE не помечен как send_event = true). Мое приложение написано на C#, но я не боюсь писать библиотеку C и взаимодействовать с ней в моем оригинальном приложении.

Вот что я не ищу:

  1. XTestFakeButtonEvent
  2. xdotool
  3. Пишу /dev/psaux " или же " /dev/input/mice " или же " /dev/input/eventX "

Вот почему я не ищу вышеупомянутые "решения":

  1. XTestFakeButtonEvent не позволяет мне указывать координаты X/Y или заголовок окна. Последнее не является для меня проблемой, так как я могу это компенсировать, проверив окно с фокусом ввода перед отправкой ввода мышью. Первое, однако, представляет собой еще большую проблему. Я знаю о XTestFakeMotionEvent и XTestFakeRelativeMotionEvent, но проблема возникает, когда они должны быть отправлены отдельно от исходного XButtonEvent, когда бывают случаи, когда я предпочитаю, чтобы они отправлялись как одно, а не как два отдельных события. Обычно мне было бы все равно, если бы они были отправлены как два отдельных события, но я боюсь, что некоторые приложения делают. Плюс есть дополнительное преимущество более чистой реализации.
  2. xdotool не страдает от тех же проблем, что и XTestFakeButtonEvent но все же есть две проблемы:

    1. Мне не нравится запускать внешние программы командной строки из моего приложения, потому что это неуклюжая реализация.

    2. Я не люблю полагаться на предустановленную такую ​​программу. "Подожди, что? Но разве ты не полагаешься на предустановленный пакет расширения XTest?" Ну да, но вы также должны принять во внимание тот факт, что мне также требуется " libX11-dev "Пакет должен быть установлен до того, как приложение будет запущено из-за того, что я взаимодействую с"libX11.so ". Я думаю, что для меня более разумно потребовать два" официальных "пакета Xlib, чем один странный инструмент Xlib.

  3. Запись необработанного ввода с помощью мыши на одно из вышеупомянутых устройств не подойдет, как вы уже догадались, еще две причины.;)

    1. Боюсь, что запись на устройство вызовет у меня проблемы из-за одной очень специфической функциональности в моем приложении. Иногда мне нужно проверять текущее глобальное состояние мыши перед отправкой ввода мышью. Теперь это создает немного загадки. Если я отправлю какой-либо ввод через XSendEvent, то мне нужно будет использовать какую-то библиотеку, которая взаимодействует на более низком уровне, чем Xlib, чтобы получить глобальное состояние мыши, чтобы я не обнаружил ввод, который я уже отправлено, поэтому создается бесконечно повторяющаяся петля обратной связи. Если я напишу на устройство, конечно, оно создаст "реальный" ввод, но это также будет означать, что я не могу легко расшифровать свой ввод от ввода мыши, создавая бесконечный цикл обратной связи. В действительности эта ситуация намного сложнее, чем я могу реально реально объяснить, но это лучший способ, который я знаю, без публикации всего моего частного источника.

    2. Иногда запись на устройство требует sudo разрешения. Я не хочу, чтобы мое приложение запускалось как sudoer.

Если вы все еще читаете это, вот что я попробовал:

  1. Практически все вышеперечисленные вещи, которые я не искал.
  2. Оборачивание функции 'XSendEvent' в разделяемой библиотеке C с использованием следующих методов: http://samanbarghi.com/blog/2014/09/05/how-to-wrap-a-system-call-libc-function-in-linux/. Причина, по которой это не сработало, заключается в том, что метод 1("LD_PRELOAD") требует от вас использования "LD_PRELOAD" перед запуском моего приложения, которое на самом деле не жизнеспособно (что я собираюсь сделать, попросите всех запустить мое приложение с помощью команды параметр -line?) Метод 2('ld --wrap=symbol'), если я правильно понимаю, потребовал бы от меня связать мою программу с общей библиотекой C, которую я написал, что невозможно увидеть как мой Основным приложением является все C#. Даже если бы я мог заставить их работать, это все равно не имело бы значения, поскольку, кажется, это не работает, когда я сначала вызываю реальную функцию, а затем устанавливаю: send_event = False; прежде чем вернуться из упакованной функции. Так что этот был глупым.
  3. Оборачивая XNextEvent в разделяемой библиотеке C ( http://www.semicomplete.com/blog/tags/xsendevent), вызывая реальную функцию, затем выполните: 'send_event = False;' прежде чем вернуться из функции упаковки. Но, так как это LD_PRELOAD Решение требует, чтобы любое приложение, которое я собирался отправлять мышью, запускалось с установленной переменной окружения. Предположительно это работает, но я думаю, что это последнее средство. Что если кто-то запустит мое приложение в первый раз, ожидая, что оно будет работать с любым открытым приложением, но это не так, потому что я установил переменную среды при первом запуске и не вступит в силу, пока все приложения не будут сброшены? Что произойдет, если кто-то удалит переменную окружения из конфигурации bash? Что если они не используют конфиги bash? Что если они используют другой терминал? Я должен поддержать их всех? Это кажется неуклюжим, как весь ад.
  4. Возможно, моя лучшая и единственная надежда еще, писать свой собственный новый XSendEvent функция в C, которая напрямую взаимодействует с Xlib для ручной настройки send_event = False; и завернуть его в общую библиотеку, чтобы я мог дальше взаимодействовать с ним через C#. Я пытался несколько раз переписать XSendEvent используя следующий источник в качестве моей ссылки: https://github.com/mirror/libX11/blob/master/src/SendEvent.c. Но даже после поиска по всему исходному коду Xlib я даже не могу понять, что именно устанавливает " send_event переменная или как я могу остановить это от моего модифицированного XSendEvent функция. Поверьте мне, я попытался просто установить его внутри функции. Неважно, где я его разместил, это не имело значения. Я могу только заключить, что это устанавливается где-то еще полностью после XSendEvent выполнен. Я могу ошибаться в этом, и я бы хотел быть. Я искал весь источник и нашел кусочки, где send_event был установлен, но он даже не был вызван XSendEvent непосредственно.

Послушайте, если вы не сошли с ума, читая это, тогда я аплодирую вам, потому что чуть не сошел с ума, пытаясь найти решение. На самом деле я никогда не задаю вопрос о Stackru, если не чувствую, что больше некуда обратиться. Я искал, искал и искал. Я старался изо всех сил, чтобы проявить должную осмотрительность, но, очевидно, потерпел неудачу Может быть, есть кто-то, кто прочитал все это и нашел какое-то оригинальное решение. Если нет, я буду продолжать искать. Я надеюсь, что это было наглядно и максимально полезно. Большое спасибо за ваше время.

0 ответов

Другие вопросы по тегам