LINUX.ORG.RU

Перехват событий от мышки


0

1

Здравствуйте. Необходимо перехватывать нажатие и отпускание кнопки мыши. Написал следующий код в лазарусе:

program project1;

{$mode objfpc}{$H+}

uses
  xlib, x, ctypes, sysutils;

procedure run;
var
  d: PDisplay;
  w,root: TWindow;
  e: TXEvent;
  msg: PChar;
  s: cint;
  mx , my : integer;
  t : string;
begin
  t := 'gg';
  msg := PChar(t);

  d := XOpenDisplay(nil);
  if (d = nil) then
  begin
    WriteLn('[ModalShowX11Window] Cannot open display');
    exit;
  end;

  s := DefaultScreen(d);

  w := XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 200, 1,
                           BlackPixel(d, s), WhitePixel(d, s));

  XSelectInput(d, w, ExposureMask or KeyPressMask or pointermotionmask or
                  buttonpressmask or buttonreleasemask);

  XMapWindow(d, w);


  root := DefaultRootWindow(d);

  XGrabPointer(d, root, False, ButtonPressMask or ButtonReleaseMask or
               PointerMotionMask, GrabModeAsync, GrabModeAsync, None,
               None, CurrentTime);

  while (True) do
  begin
    XNextEvent(d, @e);
    case e._type of
      expose:
       begin
         XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
         XDrawString(d, w, DefaultGC(d, s), 50, 50, msg, strlen(msg));
       end;
      KeyPress:
       begin
         break;
       end;

      motionnotify:
        begin
          mx := e.xmotion.x;
          my := e.xmotion.y;
          t := inttostr(mx)+','+inttostr(my);
          XDrawstring(d, w, DefaultGC(d, s), 50, 50, pchar(t), strlen(pchar(t)));

         end;

      buttonpress:
       begin
          mx := e.xmotion.x;
          my := e.xmotion.y;
        case e.xbutton.button of
          button1:
            t := 'left';
        end;
      end;
    end;
  end;

  xungrabpointer( d,currenttime);
  XCloseDisplay(d);
end;

begin
  run;
end.
События приходят, но все окна перестают реагировать на действия мыши. Пробовал писать этот же код в QT Creator - результат тот же самый. Помогите, почему не работает?

Что-то непонимаю, если ты пишешь код именно в лазарусе а не в других редакторах, то почему не хочешь использовать событие OnMouseUp на форме? Там же всё это уже есть в кроссплатформенном варианте.

Napilnik ★★★★★
()
Ответ на: комментарий от TuxLinuxMan

Не просто же так я XGrabPointer() вызываю

man XGrabPointer

Further pointer events are reported *only* to the grabbing client.

Возможно ты хочешь вместо XGrubPointer читать события напрямую из устройств, как в коде evtest? Или после каждого пойманного события делать Ungrub и посылать перехваченное тобой событие его оригинальному адресату?

kim-roader ★★
()
Ответ на: комментарий от kim-roader

Я же все объяснил. Что непонятного? Нужно перехватывать нажатия и отпускания левой кнопки мыши за пределами моего окна и чтобы другие окна не прекращали реагировать на мышь.

TuxLinuxMan
() автор топика
Ответ на: комментарий от TuxLinuxMan

Правильно — читать напрямую из /dev/input/mouse0. Как это делается можешь посмотреть в коде evtest.

Ещё гугл говорит, что может сработать использование «X Record Extension Library», но он также намекает, что её работу в иксах не так давно ломали.

kim-roader ★★
()
Ответ на: комментарий от kim-roader

Большое спасибо! Скачал исходник evtest, собрал - перехват работает. Только я нуб в С. В каком IDE можно его редактировать и собирать на лету, а не через консоль sudo gcc -o evtest evtest.c? И как сделать, чтобы он по умолчанию с правами sudo запускался?

TuxLinuxMan
() автор топика
Ответ на: комментарий от TuxLinuxMan

1. В любой IDE поддерживающей C. 2. Либо какой-нибудь обёрткой, запускающей бинарник от рута, либо при помощи setuid бита в правах доступа (man chmod)

kim-roader ★★
()
Ответ на: комментарий от kim-roader

Я открыл файл «evtest.c» в QT Creator'е, но там он не хочет собираться. Опции сборки и запуска просто недоступны. А если собирать из консоли, то он ругается на добавленный мной код:

evtest.c:(.text+0x10cb): undefined reference to `XOpenDisplay'
evtest.c:(.text+0x11ed): undefined reference to `XQueryPointer'
evtest.c:(.text+0x1223): undefined reference to `XSendEvent'
evtest.c:(.text+0x1232): undefined reference to `XCloseDisplay'
Нагуглил, что надо собирать с ключом -lx11, но не понял, куда в консоли его прописывать?

TuxLinuxMan
() автор топика
Ответ на: комментарий от TuxLinuxMan

Я открыл файл «evtest.c» в QT Creator'е, но там он не хочет собираться

http://qt-project.org/doc/qtcreator-2.5/creator-project-creating.html http://qt-project.org/doc/qtcreator-2.5/creator-project-qmake-libraries.html

Нагуглил, что надо собирать с ключом -lx11, но не понял, куда в консоли его прописывать?

В качестве ключа к линкеру, конечно же.

Но вообще с такими вопросами, возможно, тебе стоит начать с описания того что такое компилятор и компановщик, а не с написания программ.

kim-roader ★★
()
Ответ на: комментарий от kim-roader

я не спорю - начинать надо с начала. я бы так и сделал, но очень нужно написать одну довольно несложную программу, так как не могу ее нигде найти. Итак, ключ -lx11. Как его прописать?

gcc -o evtest evtest.c -lx11
gcc -lx11 -o evtest evtest.c
gcc -o -lx11 evtest evtest.c
gcc -o evtest -lx11 evtest.c
Или .pro-файл нужно создать и туда вписать?

TuxLinuxMan
() автор топика
Ответ на: комментарий от TuxLinuxMan

Как его прописать?

Что тебе мешает попробовать и так и так? В данном случае будет работать в любом порядке, кроме третьего варианта, который является синтаксической ошибкой вызванной тем, что ты не понимаешь значение ключа "-o". Наиболее корректен первый вариант.

Или .pro-файл нужно создать и туда вписать?

Ну если ты хочешь собирать qmake'ом, то можешь и в .pro файле написать что-то вроде

LIBS += -lX11
SOURCES += evtest.c

kim-roader ★★
()
Ответ на: комментарий от kim-roader

чорт! надо просто Х большой ставить! тогда через GCC собирается. всем спасибо!

TuxLinuxMan
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.