I'd say open a new thread and refer back to this one - but that should be done on the unbuntu forums as these are for archlinux only. There are many differences between the distros that might explain why this doesn't work for you.
Closing.
]]>Credits to HashBox
Cheers
Hmmm not sure why yours would do that, I guess mine would do the same thing as they both loop and use XNextEvent. I also noticed that I've obviously decided to use that program as a test bed for something, since I don't think the XMapWindow and stuff should be there :\ hmm.
Wait a sec I found another version which should at least compile. (With gcc -Wall -Wextra -o rootgrab main.c -lX11)
Edit: I've just modified it so it should do what you want, but it is untested
#include <X11/Xlib.h>
//#include <X11/Xresource.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
Display *dpy;
XEvent ev;
GC sel_gc;
XGCValues sel_gv;
int x, y, i;
int start_x, start_y, width, height;
if (!(dpy = XOpenDisplay(NULL))) {
fprintf(stderr, "Could not open display %s", getenv("DISPLAY"));
}
XGrabButton(dpy, 1, 0, DefaultRootWindow(dpy), True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);
sel_gv.function = GXinvert;
sel_gv.subwindow_mode = IncludeInferiors;
sel_gv.line_width = 1;
sel_gc = XCreateGC(dpy, DefaultRootWindow(dpy), GCFunction | GCSubwindowMode | GCLineWidth, &sel_gv);
for (;;) {
XNextEvent(dpy, &ev);
if (ev.type == ButtonPress) {
/* Grab pointer so we receive ButtonRelease */
XGrabPointer(dpy, DefaultRootWindow(dpy), True, PointerMotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
x = start_x = ev.xbutton.x_root;
y = start_y = ev.xbutton.y_root;
width = height = 0;
//XAllowEvents(dpy, ReplayPointer, CurrentTime); /* Allow other apps to process this message */
} else if (ev.type == MotionNotify) {
while (XCheckTypedEvent(dpy, MotionNotify, &ev));
XDrawRectangle(dpy, DefaultRootWindow(dpy), sel_gc, x, y, width, height); /* Clear Rectangle */
width = ev.xbutton.x_root - start_x;
height = ev.xbutton.y_root - start_y;
/* Ugliness to make width/height positive and put the start positions
* in the right place so we can draw backwards basically. */
if (width < 0) { width = abs(width); x = ev.xbutton.x_root; } else { x = start_x; }
if (height < 0) { height = abs(height); y = ev.xbutton.y_root; } else { y = start_y; }
XDrawRectangle(dpy, DefaultRootWindow(dpy), sel_gc, x, y, width, height); /* Draw Rectangle */
} else if (ev.type == ButtonRelease) {
XUngrabPointer(dpy, CurrentTime);
XDrawRectangle(dpy, DefaultRootWindow(dpy), sel_gc, x, y, width, height); /* Clear Rectangle */
XSync(dpy, 1); /* Needed to Ungrab Pointer NOW otherwise we continue receiving MotionNotify events and the previous line is useless */
printf("%i %i %i %i\n", x, y, width, height);
}
}
XFreeGC(dpy, sel_gc);
XCloseDisplay(dpy);
return 0;
}
I was pretty satisfied with my xrectsel.c, but not now.
The thing is it freaks my CPU out, one of 2 cores goes up to 100%, then the other.
Thoughts?
]]>I'm sorry I can't be a little more helpful right now, but this little utility I made a while back contains basically the functionality you need, but will need to be hacked a little and have some unnecessary stuff removed.
Basically this lets you drag a rectangle out on the root window which it can then pass to an external script or something. You will want to remove the stuff that deals with external scripts and just make it output the dimensions, and also you will probably need to modify it to allow dragging anywhere, rather than just the root window (should be just removing a line).
Actually now that I look at it most of the unneeded stuff has already been commented out for some reason
/*
* Run stuff on root window clicks
*/
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
Display *dpy;
XEvent ev;
XSetWindowAttributes wa;
GC gc;
/* XrmDatabase db;
XrmValue up;
XrmValue down;
XrmValue left;
XrmValue right;
char xdb_path[128];
char *type;*/
int x, y;
if (!(dpy = XOpenDisplay(NULL))) {
fprintf(stderr, "Could not open display %s", getenv("DISPLAY"));
}
int black = BlackPixel(dpy, DefaultScreen(dpy));
int white = WhitePixel(dpy, DefaultScreen(dpy));
wa.override_redirect = True;
Window w = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 100, 40, 0, DefaultDepth(dpy, DefaultScreen(dpy)), CopyFromParent, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect | CWEventMask, &wa);
gc = XCreateGC(dpy, w, 0, NULL);
XSelectInput(dpy, w, StructureNotifyMask);
// sprintf(xdb_path, "%s/.rootdragrc", getenv("HOME"));
/* XrmInitialize();
db = XrmGetFileDatabase(xdb_path);
XrmGetResource(db, "up", "up", &type, &up);
XrmGetResource(db, "down", "down", &type, &down);
XrmGetResource(db, "left", "left", &type, &left);
XrmGetResource(db, "right", "right", &type, &right);*/
XGrabButton(dpy, 2, 0, DefaultRootWindow(dpy), True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);
for (;;) {
XNextEvent(dpy, &ev);
if (ev.type == ButtonPress) {
if (ev.xbutton.subwindow == None) { /* Root Window */
/* Grab pointer so we receive ButtonRelease */
XGrabPointer(dpy, DefaultRootWindow(dpy), True, PointerMotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
x = ev.xbutton.x_root;
y = ev.xbutton.y_root;
// Open Window
XMapWindow(dpy, w);
XMoveWindow(dpy, w, ev.xbutton.x_root + 20, ev.xbutton.y_root + 20);
}
XAllowEvents(dpy, ReplayPointer, CurrentTime); /* Allow other apps to process this message */
} else if (ev.type == MotionNotify) {
while (XCheckTypedEvent(dpy, MotionNotify, &ev));
// Update Window Position
XMoveWindow(dpy, w, ev.xbutton.x_root + 20, ev.xbutton.y_root + 20);
} else if (ev.type == ButtonRelease) {
XUngrabPointer(dpy, CurrentTime);
XUnmapWindow(dpy, w);
XSync(dpy, 1);
/* char shell_buff[256];
sprintf(shell_buff, "%s &", button[ev.xbutton.button-1].addr);
system(shell_buff);*/
} else if (ev.type == Expose) {
while (XCheckTypedEvent(dpy, Expose, &ev));
// XSetForeground(dpy, gc, black);
// XDrawRectangle(dpy, w, gc, 1, 1, 100, 40);
}
}
XDestroyWindow(dpy, w);
XCloseDisplay(dpy);
return 0;
}
Hope this helps..
]]>#include<stdio.h>
#include<stdlib.h>
#include<X11/Xlib.h>
#include<X11/cursorfont.h>
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:");
while (!done) {
while (!done && XPending(disp)) {
XNextEvent(disp, &ev);
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;
}
It makes me excited, which may be, well, trivial to you.
I have to say, credit goes to main.c from src of scrot!
#include<stdio.h>
#include<stdlib.h>
#include<X11/Xlib.h>
#include<X11/cursorfont.h>
int main(void)
{
int rx = 0, ry = 0, rw = 0, rh = 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;
cursor = XCreateFontCursor(disp, XC_left_ptr);
/* 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:");
while (!done) {
while (!done && XPending(disp)) {
XNextEvent(disp, &ev);
switch (ev.type) {
case ButtonPress:
btn_pressed = 1;
rx = ev.xbutton.x;
ry = ev.xbutton.y;
break;
case ButtonRelease:
done = 1;
break;
}
}
}
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;
}
I was thinking about scrot -s... then I grabbed the sources of scrot... then, it's freaking done!
$ gcc -Wall -lX11 xrectsel.c -o xrectsel
$ ./xrectsel
492x538+552+54
Woot!
Any further suggestions?
say i put my mouse pointer at position (a,b), then i drag it to position (c,d), it will return something like "+a+b -x+y -c-d +m-n" or 'LxW+a+b' or just 'a,b c,d'
PS1: i think Xlib can easily do that, and i would have written it in C if i knew how..
PS2: i don't like the approach of resizing a window to that area and run xwininfo.
PS3: advertising:
this is for my new script ffcast :: thread :: AUR page
Regards
]]>