BoppreH
BoppreH

Reputation: 10193

Get mouse position on Linux, pure Python

I'm trying to get the global mouse position (x, y) in Linux with pure Python (+ctypes if necessary). I can get relative position changes by listening to /dev/input/mice, but I'm not receiving any event with absolute position to calibrate (EV_ABS).

I tried using ctypes to connect to X11, but everything after XOpenDisplay segfaults (yes, the XOpenDisplay worked and returned non-zero):

import ctypes
import ctypes.util
x11 = ctypes.cdll.LoadLibrary(ctypes.util.find_library('X11'))
display = x11.XOpenDisplay(None)
assert display
window = x11.XDefaultRootWindow(display) # segfault here

The equivalent code works well in C, but I'm looking for a solution without dependencies or compilation steps:

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

int main (){
    Display *display = XOpenDisplay(NULL);
    XEvent event;
    XQueryPointer(display, XDefaultRootWindow(display),
        &event.xbutton.root, &event.xbutton.window,
        &event.xbutton.x_root, &event.xbutton.y_root,
        &event.xbutton.x, &event.xbutton.y,
        &event.xbutton.state);
    printf("%d %d\n", event.xbutton.x_root, event.xbutton.y_root);
    XCloseDisplay(display);
    return 0;
}

This was tested on Fedora 23, 64 bits.

Upvotes: 3

Views: 3337

Answers (1)

Robᵩ
Robᵩ

Reputation: 168876

The following works for me with Python 2.7.6 on Ubuntu 14.04.3. It is almost entirely copied from https://unix.stackexchange.com/a/16157/4836

#! /usr/bin/env python
import sys
from ctypes import *
Xlib = CDLL("libX11.so.6")
display = Xlib.XOpenDisplay(None)
if display == 0: sys.exit(2)
w = Xlib.XRootWindow(display, c_int(0))
(root_id, child_id) = (c_uint32(), c_uint32())
(root_x, root_y, win_x, win_y) = (c_int(), c_int(), c_int(), c_int())
mask = c_uint()
ret = Xlib.XQueryPointer(display, c_uint32(w), byref(root_id), byref(child_id),
                         byref(root_x), byref(root_y),
                         byref(win_x), byref(win_y), byref(mask))
if ret == 0: sys.exit(1)
print child_id.value
print root_x, root_y

Edit: The following script, using python-xlib 0.12, prints the root window's mouse position:

from Xlib import display
qp = display.Display().screen().root.query_pointer()
print qp.root_x, qp.root_y

Upvotes: 6

Related Questions