簡體   English   中英

在Linux / Ubuntu中捕獲窗口事件(屏幕捕獲+鼠標/鍵盤事件)

[英]Capturing Window Events in Linux/Ubuntu (Screen-Capture + Mouse/Keyboard-Events)

我想為Linux開發C ++應用程序,該應用程序需要通過標准IO(鼠標+鍵盤)與其他程序進行交互。 它應該能夠將鼠標/鍵盤輸入發送到窗口,並捕獲該特定窗口的“屏幕快照”。

(1)現在,我已經進行了一些研究,並且我知道Linux使用“ X Window”系統。 是否建議從這一層開始進行編程,還是應該使用更高級別的框架(例如wxWidgets)?

(2)是否可以將輸入事件發送到/捕獲窗口的屏幕,即使它沒有聚焦?

(3)我不是要您提供代碼,而是希望閱讀一些有關該主題的文獻。 可悲的是,我找不到關於此主題的任何好的資料。

如果有人可以幫助我,那就太好了!

先感謝您!!

[注意:該程序應作為后端運行,並稍后從Java應用程序執行命令。 該計划是分別為Windows / Linux實施此后端C ++ App]

解決方案1我可以推薦一段用於發送鍵盤事件的代碼,這些代碼我自己用來模擬按鍵。 它基於XSendEvent。

#include <X11/Xlib.h>
#include <X11/keysym.h>

/** Modifier states */
#define MOD_ALT 0x8
#define MOD_CONTROL 0x4
#define MOD_CONTROL_ALT 0xc
#define MOD_SHIFT_CONTROL 0x5
#define MOD_SHIFT_ALT 0x9

XKeyEvent createKeyEvent(Display *display, Window &win,
                           Window &winRoot, bool press,
                           int keycode, int modifiers)
{
   XKeyEvent event;

   event.display     = display;
   event.window      = win;
   event.root        = winRoot;
   event.subwindow   = None;
   event.time        = CurrentTime;
   event.x           = 1;
   event.y           = 1;
   event.x_root      = 1;
   event.y_root      = 1;
   event.same_screen = True;
   event.keycode     = XKeysymToKeycode(display, keycode);
   event.state       = modifiers;

   if(press)
      event.type = KeyPress;
   else
      event.type = KeyRelease;

   return event;
}


void pressKey(Display* display, Window &win_focus, Window &win_root,
              KeySym key, int modifiers)
{
    // Send a fake key press event to the window.
    XKeyEvent event = createKeyEvent(display, win_focus, win_root, true, key, modifiers);
    XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);

    // Send a fake key release event to the window.
    event = createKeyEvent(display, win_focus, win_root, false, key, modifiers);
    XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
}

然后,您可以使用它來發送按鍵事件(在本例中為Alt + W),如下所示:

// Obtain the X11 display.
Display *display = XOpenDisplay(0);
if (display == NULL)
{
  printf("Null display!\n");
  return 1;
}

// Get the root window for the current display
Window win_root = XDefaultRootWindow(display);

// Find the window which has the current keyboard focus
Window win_focus;
int    revert;
XGetInputFocus(display, &win_focus, &revert);


pressKey(display, win_focus, win_root, XK_w, MOD_ALT);

if (display)
  XCloseDisplay(display);

解決方案2使用XTest庫可以實現類似的行為。 但是,它在“更高級別”上運行,例如,窗口管理器也將拾取這些按鍵。 XTest的pressKey函數如下所示(不是很干凈的代碼):

void pressKey(Display* display, KeySym modifier1, KeySym modifier2, KeySym key)
{
    // Release every other modifier
    KeyCode keycodec = XKeysymToKeycode(display, XK_Control_L);
    KeyCode keycodea = XKeysymToKeycode(display, XK_Alt_L);
    KeyCode keycodes = XKeysymToKeycode(display, XK_Shift_L);
    XTestFakeKeyEvent(display, keycodec, False, 0); // key release event
    XTestFakeKeyEvent(display, keycodea, False, 0); // key release event
    XTestFakeKeyEvent(display, keycodes, False, 0); // key release event
    XFlush(display);

    // Press the actual keys
    KeyCode keycode1 = XKeysymToKeycode(display, modifier1);
    KeyCode keycode2 = XKeysymToKeycode(display, modifier2);
    KeyCode keycode3 = XKeysymToKeycode(display, key);
    if (keycode1)
        XTestFakeKeyEvent(display, keycode1, True, 0); // key press event
    if (keycode2)
        XTestFakeKeyEvent(display, keycode2, True, 0); // key press event
    if (keycode3)
    {
        XTestFakeKeyEvent(display, keycode3, True, 0); // key press event
        XTestFakeKeyEvent(display, keycode3, False, 0); // key release event
    }
    if (keycode2)
        XTestFakeKeyEvent(display, keycode2, False, 0); // key release event
    if (keycode1)
        XTestFakeKeyEvent(display, keycode1, False, 0); // key release event
    XFlush(display);
}

解決方案3另一個解決方案是僅使用xdotool這樣的工具編寫腳本。 基本上,您描述的大部分內容都可以通過bash腳本來實現。 此外, xdotool源代碼還是有關如何實現所需功能的大量信息來源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM