2013-04-20 100 views
2

我想知道如何使用Xlib在屏幕上的任何位置獲得鼠標點擊的x和y座標。我發現這個職位它獲取當前指針位置獲取與Xlib的鼠標點擊座標

How can I get the current mouse (pointer) position co-ordinates in X

,但我不知道如何因此它的點擊鼠標時的X,Y座標進行修改。 我試過寫這段代碼,但它什麼也沒做。

#include <stdio.h> 
#include <stdlib.h> 
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 

int main(){ 
int x=-1,y=-1; 
XEvent event; 
int button; 
Display *display = XOpenDisplay(NULL); 
if (display == NULL) { 
    fprintf(stderr, "Cannot connect to X server!\n"); 
    exit (EXIT_FAILURE); 
} 
Window root= XDefaultRootWindow(display); 
XSelectInput(display, root, ButtonReleaseMask) ; 
while(1){ 
XNextEvent(display,&event); 
switch(event.type){ 
    case ButtonRelease: 
     switch(event.xbutton.button){ 
      case Button1: 
       x=event.xbutton.x; 
       y=event.xbutton.y; 
       button=Button1; 
       break; 

      case Button3: 
       x=event.xbutton.x; 
       y=event.xbutton.y; 
       button=Button3; 
       break; 
      default: 
       break; 

     } 
     break; 
    default: 
     break; 
} 
if(x>=0 && y>=0)break; 
} 
if(button==Button1)printf("leftclick at %d %d \n",x,y); 
else printf("rightclick at %d %d \n",x,y); 
XCloseDisplay(display); 
return 0; 
} 

事件可能發送到其他窗口,這就是它不工作的原因。另一個問題是,當我添加ButtonPressMask到XSelectInput功能我得到以下錯誤:

X Error of failed request: BadAccess (attempt to access private resource denied) 
Major opcode of failed request: 2 (X_ChangeWindowAttributes) 
Serial number of failed request: 7 
Current serial number in output stream: 7 

如果有更簡單的方法在C做到這一點,我很高興聽到這個消息。

回答

2

您可能需要抓住指針。

我不知道你是否想要按下按鈕的發佈。我把它改爲機,但你可以用兩種撿:

XSelectInput(display, root, ButtonPressMask|ButtonReleaseMask) ; 

,並添加ButtonRelease底蓋

#include <stdio.h> 
#include <stdlib.h> 
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 

int main(){ 
    int x=-1,y=-1; 
    XEvent event; 
    int button; 
    Display *display = XOpenDisplay(NULL); 
    if (display == NULL) { 
    fprintf(stderr, "Cannot connect to X server!\n"); 
    exit (EXIT_FAILURE); 
    } 
    Window root= XDefaultRootWindow(display); 
    XGrabPointer(display, root, False, ButtonPressMask, GrabModeAsync, 
     GrabModeAsync, None, None, CurrentTime); 

    XSelectInput(display, root, ButtonPressMask) ; 
    while(1){ 
    XNextEvent(display,&event); 
    switch(event.type){ 
    case ButtonPress: 
     switch(event.xbutton.button){ 
     case Button1: 
     x=event.xbutton.x; 
     y=event.xbutton.y; 
     button=Button1; 
     break; 

     case Button3: 
     x=event.xbutton.x; 
     y=event.xbutton.y; 
     button=Button3; 
     break; 
     default: 
     break; 

     } 
     break; 
    default: 
     break; 
    } 
    if(x>=0 && y>=0)break; 
    } 
    if(button==Button1)printf("leftclick at %d %d \n",x,y); 
    else printf("rightclick at %d %d \n",x,y); 
    XCloseDisplay(display); 
    return 0; 
} 
+0

謝謝,代碼對我來說工作正常,但我必須更改爲ButtonRelease,否則我會得到與上述相同的錯誤。你不知道爲什麼? – rex123 2013-04-21 15:51:01

+0

這兩個事件都爲我工作。你在使用哪個窗口管理器?我正在使用KDE窗口管理器。 – parkydr 2013-04-21 15:58:20

+0

我正在使用統一。 – rex123 2013-04-21 18:36:02

1

If there is simpler way to do this in C, I am happy to hear it.

完美!然後使用libxdo library,有些人已經爲你做了。

int x, y, scrn; 

xdo_t *hndl = xdo_new(NULL); 
xdo_mouselocation(hndl, &x, &y, &scrn); 
xdo_free(hndl); 

printf("Mouse coordinates: x = %4d, y = %4d\n", x, y); 
+0

謝謝。這個庫比xlib本身更容易使用,對我的項目來說是完美的。但是當鼠標點擊時,我還沒有看到任何返回座標的函數,因爲你的例子只是在被調用時返回座標。 – rex123 2013-04-20 16:47:34

1

我知道這是一對夫婦來了,所以這是信息對於其他人來說。首先,使用另一個庫並不符合我更容易的定義。我正在使用xlib和C編寫自己需要的東西,我想看看我可以如何簡單地編寫代碼。

基本上你只需要四行代碼就可以在現有程序的xlib中完成這些工作,其餘的全部都是你想要處理它的方式,printf/sprintf,grab_pixel_color(Display * display,XColor * color)等

/** gcc position.c -o position -lX11 **/ 
#include <X11/Xlib.h> 
#include <stdio.h> 

int main (int argc, char **argv) { 
    Window root_window; //<--one 
    int root_x, root_y; //<--two 
    unsigned int mask; //<--three 

    Display *display = XOpenDisplay(NULL); 

    /* 
    Bool XQueryPointer(display, w, root_return, child_return, root_x_return, root_y_return, 
         win_x_return, win_y_return, mask_return) 
      Display *display; 
      Window w; 
      Window *root_return, *child_return; 
      int *root_x_return, *root_y_return; 
      int *win_x_return, *win_y_return; 
      unsigned int *mask_return; 
    */ 

    XQueryPointer(display, DefaultRootWindow(display), &root_window, &root_window, &root_x, &root_y, &root_x, &root_y, &mask); //<--four 

    printf("Mouse coordinates (X: %d, Y: %d)\n", root_x, root_y); 

    XCloseDisplay(display); 
    return 0; 
} 

我希望這對其他人有用。