// std #include #include #include #include #include #include // X #include #include #include #include #include // #include // #include // #include // local #include "types.h" #include "config.h" #include "scapx.h" #include "x.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); } int main(int argc, char **argv) { // TODO: parse flags (void)argc; (void)argv; Server_context_t *info; if (!(info = init_XCB_server())) FATAL_ERROR("Couldn't make a connection to the x server. %s", ""); xcb_drawable_t win = create_win(info); xcb_key_symbols_t *ksymbols = xcb_key_symbols_alloc(info->con); 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 ) SLOG("Error reported by the x server.\n"); switch (event->response_type & ~0x80) { { // mouse 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"); } if (((xcb_button_press_event_t *)event)->detail == M_BTN_2) { printf("right clicked.\n"); rmbtn = 1; } break; case XCB_BUTTON_RELEASE: cursor_die(info->con, win, mptr); if (((xcb_button_press_event_t *)event)->detail == M_BTN_1) { lmbtn = 0; } if (((xcb_button_press_event_t *)event)->detail == M_BTN_2) { rmbtn = 0; } break; case XCB_MOTION_NOTIFY: if (lmbtn || rmbtn) { 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; // 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); 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; case XCB_KEY_RELEASE: break; } free(event); } xcb_free_cursor(info->con, mptr); die(ksymbols, info, win); return 0; }