J'essaie de faire un script de capture d'écran bash simple. Je veux obtenir les coordonnées de sélection d'écran en traçant un rectangle rouge avec la souris. Je peux utiliser xdotools pour obtenir les coordonnées, mais comment puis-je dessiner un rectangle à l'écran?
Je viens de trouver https://www.opengl.org/discussion_boards/showthread.php/157014-Compiling-with-gcc , et j'ai modifié le code afin de supprimer le problème du 100% CPU; cela semble fonctionner correctement sur Ubuntu 14.04 - exécutez-le simplement à partir d’un terminal, tracez votre rectangle et le programme se fermera, en affichant les coordonnées dans le terminal:
xrectsel.c
:
_#include<stdio.h>
#include<stdlib.h>
#include<X11/Xlib.h>
#include<X11/cursorfont.h>
#include<unistd.h> // added for sleep/usleep
// original from [https://bbs.archlinux.org/viewtopic.php?id=85378 Select a screen area with mouse and return the geometry of this area? / Programming & Scripting / Arch Linux Forums]
// build with (Ubuntu 14.04):
// gcc -Wall xrectsel.c -o xrectsel -lX11
int main(void)
{
int rx = 0, ry = 0, rw = 0, rh = 0;
int rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0;
int btn_pressed = 0, done = 0;
XEvent ev;
Display *disp = XOpenDisplay(NULL);
if(!disp)
return EXIT_FAILURE;
Screen *scr = NULL;
scr = ScreenOfDisplay(disp, DefaultScreen(disp));
Window root = 0;
root = RootWindow(disp, XScreenNumberOfScreen(scr));
Cursor cursor, cursor2;
cursor = XCreateFontCursor(disp, XC_left_ptr);
cursor2 = XCreateFontCursor(disp, XC_lr_angle);
XGCValues gcval;
gcval.foreground = XWhitePixel(disp, 0);
gcval.function = GXxor;
gcval.background = XBlackPixel(disp, 0);
gcval.plane_mask = gcval.background ^ gcval.foreground;
gcval.subwindow_mode = IncludeInferiors;
GC gc;
gc = XCreateGC(disp, root,
GCFunction | GCForeground | GCBackground | GCSubwindowMode,
&gcval);
/* this XGrab* stuff makes XPending true ? */
if ((XGrabPointer
(disp, root, False,
ButtonMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync,
GrabModeAsync, root, cursor, CurrentTime) != GrabSuccess))
printf("couldn't grab pointer:");
if ((XGrabKeyboard
(disp, root, False, GrabModeAsync, GrabModeAsync,
CurrentTime) != GrabSuccess))
printf("couldn't grab keyboard:");
// see also: http://stackoverflow.com/questions/19659486/xpending-cycle-is-making-cpu-100
while (!done) {
//~ while (!done && XPending(disp)) {
//~ XNextEvent(disp, &ev);
if (!XPending(disp)) { usleep(1000); continue; } // fixes the 100% CPU hog issue in original code
if ( (XNextEvent(disp, &ev) >= 0) ) {
switch (ev.type) {
case MotionNotify:
/* this case is purely for drawing rect on screen */
if (btn_pressed) {
if (rect_w) {
/* re-draw the last rect to clear it */
XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
} else {
/* Change the cursor to show we're selecting a region */
XChangeActivePointerGrab(disp,
ButtonMotionMask | ButtonReleaseMask,
cursor2, CurrentTime);
}
rect_x = rx;
rect_y = ry;
rect_w = ev.xmotion.x - rect_x;
rect_h = ev.xmotion.y - rect_y;
if (rect_w < 0) {
rect_x += rect_w;
rect_w = 0 - rect_w;
}
if (rect_h < 0) {
rect_y += rect_h;
rect_h = 0 - rect_h;
}
/* draw rectangle */
XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
XFlush(disp);
}
break;
case ButtonPress:
btn_pressed = 1;
rx = ev.xbutton.x;
ry = ev.xbutton.y;
break;
case ButtonRelease:
done = 1;
break;
}
}
}
/* clear the drawn rectangle */
if (rect_w) {
XDrawRectangle(disp, root, gc, rect_x, rect_y, rect_w, rect_h);
XFlush(disp);
}
rw = ev.xbutton.x - rx;
rh = ev.xbutton.y - ry;
/* cursor moves backwards */
if (rw < 0) {
rx += rw;
rw = 0 - rw;
}
if (rh < 0) {
ry += rh;
rh = 0 - rh;
}
XCloseDisplay(disp);
printf("%dx%d+%d+%d\n",rw,rh,rx,ry);
return EXIT_SUCCESS;
}
_
vous pouvez installer le package python cli
pip3 install python-xrectsel
Vérifier les options de format
xrectsel --help