Friday, May 3, 2024
 Popular · Latest · Hot · Upcoming
4
rated 0 times [  4] [ 0]  / answers: 1 / hits: 4336  / 3 Years ago, wed, october 20, 2021, 8:31:08

I am trying to make a simple screencasting bash script. I want to get screen selection coordinates by drawing a red rectangle with mouse. I can use xdotools to get coordinates but how can I draw rectangle on screen?


More From » bash

 Answers
3

I just found https://www.opengl.org/discussion_boards/showthread.php/157014-Compiling-with-gcc, and I modified the code to get rid of the 100% CPU hog; it seems to work fine on Ubuntu 14.04 - simply run it from a terminal, draw your rectangle area, and the program will exit, printing the coordinates in the 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
",rw,rh,rx,ry);

return EXIT_SUCCESS;
}

[#24450] Wednesday, October 20, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
rtbrbab

Total Points: 461
Total Questions: 126
Total Answers: 117

Location: Saudi Arabia
Member since Fri, Jul 1, 2022
2 Years ago
;