summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorben <ben.nagy@arachnida.blog>2024-10-21 12:04:09 -0700
committerben <ben.nagy@arachnida.blog>2024-10-21 12:04:09 -0700
commitefebf35181554c40dc633e53329617c2b3990c83 (patch)
tree9077ece08a3a2271fcd3d0731fce9fbb8c42aab7
parent639e8280cc4440f4162c3488f1b5c8ad36dec346 (diff)
get focused window and set window nameHEADmain
-rw-r--r--src/Makefile4
-rw-r--r--src/config.h9
-rwxr-xr-xsrc/scapxbin0 -> 26000 bytes
-rw-r--r--src/scapx.c142
-rw-r--r--src/scapx.h19
-rw-r--r--src/x.c53
-rw-r--r--src/x.h5
7 files changed, 187 insertions, 45 deletions
diff --git a/src/Makefile b/src/Makefile
index 3aeea52..1a95772 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,9 +1,9 @@
CC = gcc
CFLAGS = -Wall -Wextra -Wpedantic -std=c99 -Wunreachable-code -Werror-implicit-function-declaration
LD_CFLAGS = -lxcb -lxcb-keysyms
-BIN_DIR = ../bin
+BIN_DIR = $(PWD)#../bin
TARGET = $(BIN_DIR)/scapx
-SRC = scapx.c x.c #keysyms.c
+SRC = *.c # scapx.c x.c
#HEADERS = scapx.h
diff --git a/src/config.h b/src/config.h
index 5291767..d07c777 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,11 +1,16 @@
#ifndef CONFIG_H
#define CONFIG_H
-#define DEBUG 1
-
+#include <X11/cursorfont.h>
+// Debugging Mode
+#define DEBUG 1
+// Mouse buttons
#define M_BTN_1 1
#define M_BTN_2 3
+// Mouse Cursor
+#define M_CURSOR XC_cross
+
#endif
diff --git a/src/scapx b/src/scapx
new file mode 100755
index 0000000..61090cf
--- /dev/null
+++ b/src/scapx
Binary files differ
diff --git a/src/scapx.c b/src/scapx.c
index 50edc7f..1b37bf5 100644
--- a/src/scapx.c
+++ b/src/scapx.c
@@ -3,36 +3,64 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
// X
#include <X11/keysymdef.h>
#include <X11/keysym.h>
#include <xcb/xcb_keysyms.h>
-#include <X11/cursorfont.h>
-//#include <xcb/xcb_atom.h>
-// #include <xcb/xcb_util.h>
-// #include <X11/Xutil.h>
+#include <xcb/xcb_atom.h>
#include <xcb/xcb_cursor.h>
+// #include <X11/extensions/Xcomposite.h>
+// #include <X11/Xutil.h>
+// #include <xcb/xcb_util.h>
+
// local
#include "types.h"
+#include "config.h"
#include "scapx.h"
#include "x.h"
-#include "config.h"
+// Project TODO:
+/*
+
+Stages:
+
+ // 1. WINDOWS:
+ - 1. get rid of visible window
+ - 2. grab info on currently focused window from WM
+ - 3. if simply left click, grab that whole window and window only for image capture (notice in maim, this scr does not take background?)
+
+ // 2. DRAWING
+ - 4. draw rectangle selection
+ - 5. draw lasso selection
+
+ // 3. screen capture3
+ - 6. capture drawn polygon selection
+ - 7. capture drawn irregular (lasso) polygon selection
+ // _NET_WM_WINDOW_TYPE_DND // indicates win is being dragged
+
+ // 4. FILE I/O
+ - 8. image file I/O
+*/
void dbg_printf(const char *fmt, ...)
{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
}
+
int main(int argc, char **argv)
{
// TODO: parse flags
+ (void)argc;
+ (void)argv;
Server_context_t *info;
@@ -44,6 +72,10 @@ int main(int argc, char **argv)
xcb_generic_event_t *event;
xcb_cursor_t mptr;
+ xcb_set_win_name(info->con, win, "scapx");
+
+ // TODO: refactor
+
bool done = 0;
while (!done && (event = xcb_wait_for_event(info->con))) {
if (event->response_type == 0 )
@@ -51,9 +83,9 @@ int main(int argc, char **argv)
switch (event->response_type & ~0x80) {
{ // mouse
- static bool lmbtn = 0;
- static bool rmbtn = 0;
- case XCB_BUTTON_PRESS:
+ static bool lmbtn = 0;
+ static bool rmbtn = 0;
+ case XCB_BUTTON_PRESS:
if (((xcb_button_press_event_t *)event)->detail == M_BTN_1) {
lmbtn = 1;
printf("left clicked.\n");
@@ -64,7 +96,7 @@ int main(int argc, char **argv)
rmbtn = 1;
}
break;
- case XCB_BUTTON_RELEASE:
+ case XCB_BUTTON_RELEASE:
cursor_die(info->con, win, mptr);
if (((xcb_button_press_event_t *)event)->detail == M_BTN_1) {
lmbtn = 0;
@@ -73,35 +105,91 @@ int main(int argc, char **argv)
rmbtn = 0;
}
break;
- case XCB_MOTION_NOTIFY:
+ case XCB_MOTION_NOTIFY:
if (lmbtn || rmbtn) {
- mptr = cursor_set(info->con, info->scr, win, XC_cross);
+ mptr = cursor_set(info->con, win, M_CURSOR);
printf("%s drag.\n", lmbtn ? "left" : "right");
} else
printf("moving.\n");
break;
+ case XCB_LEAVE_NOTIFY:
+ printf("left window.\n");
+ { // get focused window
+ xcb_window_t focused_win = get_focused_win(info->con);
+ xcb_get_geometry_reply_t *geo_rep = xcb_get_geometry_reply(info->con, xcb_get_geometry(info->con, focused_win), NULL);
+
+ xcb_flush(info->con);
+ xcb_unmap_window(info->con, win);
+
+ // TODO: 1. put this on the top of the stack (fix the new window onto that which was focused)
+ // first: remove WM decoration
+ // TODO: instead of deleting the old window and creating a new, simply use xcb_configure_window to modify the existing window with focused win attr.
+
+ xcb_create_window(info->con,
+ geo_rep->depth,
+ focused_win,
+ geo_rep->root,
+ geo_rep->x, geo_rep->y,
+ geo_rep->width, geo_rep->height,
+ geo_rep->border_width,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ info->scr->root_visual,
+ XCB_CW_EVENT_MASK | XCB_CW_CURSOR | XCB_CW_OVERRIDE_REDIRECT,
+ (u32[]){
+ 0,
+ XCB_EVENT_MASK_BUTTON_1_MOTION |
+ XCB_EVENT_MASK_POINTER_MOTION |
+ XCB_MOTION_NOTIFY |
+ XCB_EVENT_MASK_BUTTON_MOTION |
+ XCB_EVENT_MASK_LEAVE_WINDOW, 1
+ }
+ );
+
+ xcb_change_window_attributes(info->con, focused_win, XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT, (u32[]){info->scr->black_pixel, 0});
+ xcb_map_window(info->con, focused_win);
+ xcb_flush(info->con);
+
+ // event loop for new window
+
+
+ while (xcb_wait_for_event(info->con)) {
+ switch (geo_rep->response_type & ~0x80) {
+ case XCB_MOTION_NOTIFY:
+ printf("motion received.\n");
+ break;
+ default:
+ printf("event received.\n");
+ break;
+ }
+
+ printf("focused window width %u height %u\n", geo_rep->width, geo_rep->height);
+ }
+
+ free(geo_rep);
+ }
+ break;
}
case XCB_KEY_PRESS:
- printf("\nKeyPress event received:\n");
- xcb_key_press_event_t *kevent = (xcb_key_press_event_t *)event;
+ printf("\nKeyPress event received:\n");
+ xcb_key_press_event_t *kevent = (xcb_key_press_event_t *)event;
- // NOTE: field is a mask of the buttons held down during the event
- printf("state %#x ", kevent->state);
- printf("keycode %u ", kevent->detail);
+ // NOTE: field is a mask of the buttons held down during the event
+ printf("state %#x ", kevent->state);
+ printf("keycode %u ", kevent->detail);
- xcb_keysym_t ksym = xcb_key_symbols_get_keysym(ksymbols, kevent->detail, kevent->state);
- const char *sym_str = ksym_to_str(&ksym);
+ xcb_keysym_t ksym = xcb_key_symbols_get_keysym(ksymbols, kevent->detail, kevent->state);
+ const char *sym_str = ksym_to_str(&ksym);
- if (ksym == XK_Escape || ksym == XK_q || ksym == XK_Q)
- die(ksymbols, info, win);
+ if (ksym == XK_Escape || ksym == XK_q || ksym == XK_Q)
+ die(ksymbols, info, win);
- printf("keysym [%#x %s]\n", ksym, sym_str ? sym_str : "");
- break;
+ printf("keysym [%#x %s]\n", ksym, sym_str ? sym_str : "");
+ break;
case XCB_KEY_RELEASE:
- break;
+ break;
}
free(event);
diff --git a/src/scapx.h b/src/scapx.h
index c232067..47427db 100644
--- a/src/scapx.h
+++ b/src/scapx.h
@@ -10,21 +10,22 @@
fprintf(stdout, "-h, --help\t\t print this menu and quit. Alternatively, man scapx\n"); \
fprintf(stdout, "-v, --version\t\t print program version and quit\n\n"); \
exit(EXIT_FAILURE); \
- } while (0)
-
+ } while (0)
-#define SLOG(...) (fprintf(stderr, __VA_ARGS__))
+// TODO: put in util.h
-#define DEBUG_INFO(FMT, ARGS...) do { \
- if (DEBUG) \
- fprintf(stderr, "%s:%d " FMT "\n", __FUNCTION__, __LINE__, ## ARGS); \
- } while (0)
+#ifdef DEBUG
+ #define SLOG(...) (fprintf(stderr, ##__VA_ARGS__))
+ #define DEBUG_INFO(FMT, ...) do { \
+ if (DEBUG) \
+ fprintf(stderr, "%s:%d " FMT "\n", __func__, __LINE__, ##__VA_ARGS__); \
+ } while (0)
+#endif
-#define FATAL_ERROR(errstr, ...) \
+#define FATAL_ERROR(errstr, ...) \
do { \
fprintf(stderr, (errstr), ##__VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (0)
-
#endif
diff --git a/src/x.c b/src/x.c
index 828445f..61a0fc0 100644
--- a/src/x.c
+++ b/src/x.c
@@ -4,8 +4,12 @@
#include <X11/keysym.h>
#include <xcb/xcb_keysyms.h>
+// #include <xcb/xcb_cursor.h> very versatile
+
#include "x.h"
#include "types.h"
+#include "config.h"
+#include "scapx.h"
Server_context_t *init_XCB_server();
xcb_window_t create_win(Server_context_t *info);
@@ -22,8 +26,7 @@ Server_context_t *init_XCB_server()
info->con = xcb_connect(NULL, &info->scr_nbr);
if (xcb_connection_has_error(info->con) > 0) {
fprintf(stderr, "Error opening display.\n");
- free(info);
- return NULL;
+ free(info); return NULL;
}
info->iter = xcb_setup_roots_iterator(xcb_get_setup(info->con));
@@ -68,6 +71,7 @@ xcb_window_t create_win(Server_context_t *info)
XCB_EVENT_MASK_POINTER_MOTION | // mouse is moving without clicking
XCB_MOTION_NOTIFY |
XCB_EVENT_MASK_BUTTON_MOTION |
+ XCB_EVENT_MASK_LEAVE_WINDOW |
/*
XCB_MOTION_NOTIFY |
XCB_EVENT_MASK_EXPOSURE |
@@ -98,7 +102,7 @@ xcb_window_t create_win(Server_context_t *info)
return win;
}
-xcb_cursor_t cursor_set(xcb_connection_t *c, xcb_screen_t *scr, xcb_window_t win, u32 cid)
+xcb_cursor_t cursor_set(xcb_connection_t *c, xcb_window_t win, u32 cid)
{
xcb_font_t font;
xcb_cursor_t ptr;
@@ -115,7 +119,6 @@ xcb_cursor_t cursor_set(xcb_connection_t *c, xcb_screen_t *scr, xcb_window_t win
0, 0, 0,
0, 0, 0);
-
mask = XCB_CW_CURSOR;
value_list = ptr;
xcb_change_window_attributes(c, win, mask, &value_list);
@@ -156,3 +159,45 @@ void die(xcb_key_symbols_t *sym, Server_context_t *s_info, xcb_drawable_t win)
free(s_info);
exit(0);
}
+
+xcb_window_t get_focused_win(xcb_connection_t *con)
+{
+ xcb_get_input_focus_reply_t *in_fo_reply = NULL;
+
+ in_fo_reply = xcb_get_input_focus_reply(con, xcb_get_input_focus(con), NULL);
+ if (!in_fo_reply) {
+ DEBUG_INFO("could not get input focus reply: %s\n", "");
+ return XCB_WINDOW_NONE;
+ }
+
+ xcb_window_t focused_win = in_fo_reply->focus;
+ free(in_fo_reply);
+
+ if (focused_win == XCB_WINDOW_NONE) {
+ DEBUG_INFO("could not retrieve focused window: %s\n", "");
+ return XCB_WINDOW_NONE;
+ }
+
+ return focused_win;
+}
+
+xcb_atom_t get_atom(xcb_connection_t *c, const char *atom_name)
+{
+ xcb_intern_atom_cookie_t cookie = xcb_intern_atom(c, 0, strlen(atom_name), atom_name);
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(c, cookie, NULL);
+ xcb_atom_t atom = reply->atom;
+ free(reply);
+
+ return atom;
+}
+
+void xcb_set_win_name(xcb_connection_t *c, xcb_window_t w, const char *title)
+{
+ xcb_atom_t WM_NAME = get_atom(c, "WM_NAME");
+ xcb_atom_t STRING = get_atom(c, "STRING");
+ xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, WM_NAME, STRING, 8,
+ strlen(title), title);
+
+ xcb_map_window (c, w);
+ xcb_flush (c);
+}
diff --git a/src/x.h b/src/x.h
index 632a7a4..f4b69bc 100644
--- a/src/x.h
+++ b/src/x.h
@@ -15,9 +15,12 @@ typedef struct {
Server_context_t *init_XCB_server();
xcb_window_t create_win(Server_context_t *info);
-xcb_cursor_t cursor_set(xcb_connection_t *c, xcb_screen_t *scr, xcb_window_t win, u32 cid);
+xcb_cursor_t cursor_set(xcb_connection_t *c, xcb_window_t win, u32 cid);
void cursor_die(xcb_connection_t *c, xcb_window_t win, u32 value_list);
const char *ksym_to_str(const xcb_keysym_t *ksym);
void die(xcb_key_symbols_t *sym, Server_context_t *s_info, xcb_drawable_t win);
+xcb_window_t get_focused_win(xcb_connection_t *con);
+xcb_atom_t get_atom(xcb_connection_t *c, const char *atom_name);
+void xcb_set_win_name(xcb_connection_t *c, xcb_window_t w, const char *title);
#endif