summaryrefslogtreecommitdiff
path: root/xnap.c
diff options
context:
space:
mode:
authoruint <abhinav.prsai@gmail.com>2025-12-14 15:54:33 +0000
committeruint <abhinav.prsai@gmail.com>2025-12-14 15:54:33 +0000
commit1203a54cf35b647adaa664a3201458780922b9dc (patch)
treef19523dca9eb1f2e0ed7b199b7eadc57f3d6067b /xnap.c
parent9fbf665da20c7ede821faf90811f8f7e51de8c1c (diff)
create screenshot rectangle with X
Diffstat (limited to 'xnap.c')
-rw-r--r--xnap.c87
1 files changed, 81 insertions, 6 deletions
diff --git a/xnap.c b/xnap.c
index 7a4f294..e95f137 100644
--- a/xnap.c
+++ b/xnap.c
@@ -1,37 +1,112 @@
#include <stdlib.h>
#include <stdio.h>
+#include <X11/X.h>
#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+#define MIN(x, y) (x < y ? x : y)
+#define MAX(x, y) (x > y ? x : y)
+
+struct pointer_t {
+ int ret;
+ Bool sel;
+ int x0;
+ int y0;
+ int x1;
+ int y1;
+};
+
+void compimg(void);
void die(const char* s);
-void quit(void);
-void xsetup(void);
+void quit(Bool ex);
+void run(void);
+void setup(void);
Display* dpy = NULL;
Window root = None;
int scr = -1;
+struct pointer_t p = {0};
+XImage* img = NULL;
void die(const char* s)
{
fprintf(stderr, "xnap: %s", s);
- exit(1);
+ exit(EXIT_FAILURE);
}
-void quit(void)
+void quit(Bool ex)
{
+ XUngrabPointer(dpy, CurrentTime);
XCloseDisplay(dpy);
+ if (ex)
+ exit(EXIT_SUCCESS);
+}
+
+void run(void)
+{
+ XEvent ev;
+ for (;;) {
+ XNextEvent(dpy, &ev);
+
+ if (ev.type == KeyPress) {
+ KeySym ks = XLookupKeysym(&ev.xkey, 0);
+ if (ks == XK_Escape || ks == XK_q)
+ quit(True);
+ }
+
+ unsigned int b = ev.xbutton.button;
+ if (ev.type == ButtonPress && b == Button1) { /* start selecting */
+ p.sel = True;
+ p.x0 = p.x1 = ev.xbutton.x_root;
+ p.y0 = p.y1 = ev.xbutton.y_root;
+ }
+ else if (ev.type == MotionNotify && p.sel) { /* dragging selection */
+ p.x1 = ev.xmotion.x_root;
+ p.y1 = ev.xmotion.y_root;
+ }
+ else if (ev.type == ButtonRelease && p.sel && b == Button1) { /* release selection */
+ p.sel = False;
+
+ /* creating selection rectangle */
+ int recx = MIN(p.x0, p.x1);
+ int recy = MIN(p.y0, p.y1);
+ int recw = MAX(p.x0, p.x1) - recx;
+ int rech = MAX(p.y0, p.y1) - recy;
+
+ quit(False);
+ compimg()
+ }
+ }
}
-void xsetup(void)
+void setup(void)
{
+ /* X surface */
if (!(dpy = XOpenDisplay(NULL)))
die ("failed to open display");
int scr = DefaultScreen(dpy);
root = RootWindow(dpy, scr);
+
+ /* pointer */
+ p.ret = XGrabPointer(
+ dpy, root, False,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask,
+ GrabModeAsync, GrabModeAsync, None, None, CurrentTime
+ );
+ if (p.ret != GrabSuccess)
+ die("XGrabPointer failed");
}
-int main(void)
+int main(int argc, char** argv)
{
+ (void) argc;
+ (void) argv;
+
+ setup();
+ quit(True); /* unreachable */
+
return EXIT_SUCCESS;
}