*/
#include <xcb/xcb.h>
#include <xcb/xcb_keysyms.h>
+#include <xcb/xcb_image.h>
#include <xcb/dpms.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <unistd.h>
#include <assert.h>
#include <err.h>
+#include "cursors.h"
+
+#define curs_invisible_width 8
+#define curs_invisible_height 8
+
+static unsigned char curs_invisible_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+#define curs_windows_width 11
+#define curs_windows_height 19
+
+static unsigned char curs_windows_bits[] = {
+ 0xfe, 0x07, 0xfc, 0x07, 0xfa, 0x07, 0xf6, 0x07, 0xee, 0x07, 0xde, 0x07,
+ 0xbe, 0x07, 0x7e, 0x07, 0xfe, 0x06, 0xfe, 0x05, 0x3e, 0x00, 0xb6, 0x07,
+ 0x6a, 0x07, 0x6c, 0x07, 0xde, 0x06, 0xdf, 0x06, 0xbf, 0x05, 0xbf, 0x05,
+ 0x7f, 0x06 };
+
+#define mask_windows_width 11
+#define mask_windows_height 19
+
+static unsigned char mask_windows_bits[] = {
+ 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00,
+ 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x07, 0x7f, 0x00,
+ 0xf7, 0x00, 0xf3, 0x00, 0xe1, 0x01, 0xe0, 0x01, 0xc0, 0x03, 0xc0, 0x03,
+ 0x80, 0x01 };
+
static uint32_t get_colorpixel(char *hex) {
char strgroups[3][3] = {{hex[0], hex[1], '\0'},
{hex[2], hex[3], '\0'},
values[1] = 1;
mask |= XCB_CW_EVENT_MASK;
- values[2] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE;
+ values[2] = XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_KEY_PRESS |
+ XCB_EVENT_MASK_KEY_RELEASE |
+ XCB_EVENT_MASK_VISIBILITY_CHANGE;
xcb_create_window(conn,
24,
* Repeatedly tries to grab pointer and keyboard (up to 1000 times).
*
*/
-void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen) {
+void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor) {
xcb_grab_pointer_cookie_t pcookie;
xcb_grab_pointer_reply_t *preply;
xcb_grab_keyboard_cookie_t kcookie;
xcb_grab_keyboard_reply_t *kreply;
- int tries = 1000;
+ int tries = 10000;
while (tries-- > 0) {
pcookie = xcb_grab_pointer(
XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
XCB_GRAB_MODE_ASYNC, /* keyboard mode */
XCB_NONE, /* confine_to = in which window should the cursor stay */
- XCB_NONE, /* don’t display a special cursor */
+ cursor, /* we change the cursor to whatever the user wanted */
XCB_CURRENT_TIME
);
free(preply);
break;
}
+
+ /* Make this quite a bit slower */
+ usleep(50);
}
+ if (cursor != XCB_NONE)
+ xcb_free_cursor(conn, cursor);
+
while (tries-- > 0) {
kcookie = xcb_grab_keyboard(
conn,
free(kreply);
break;
}
+
+ /* Make this quite a bit slower */
+ usleep(50);
}
- if (tries == 0)
+ if (tries <= 0)
errx(EXIT_FAILURE, "Cannot grab pointer/keyboard");
}
+
+xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice) {
+ xcb_pixmap_t bitmap;
+ xcb_pixmap_t mask;
+ xcb_cursor_t cursor;
+
+ unsigned char* curs_bits;
+ unsigned char* mask_bits;
+ int curs_w, curs_h;
+
+ switch (choice) {
+ case CURS_NONE:
+ curs_bits = curs_invisible_bits;
+ mask_bits = curs_invisible_bits;
+ curs_w = curs_invisible_width;
+ curs_h = curs_invisible_height;
+ break;
+ case CURS_WIN:
+ curs_bits = curs_windows_bits;
+ mask_bits = mask_windows_bits;
+ curs_w = curs_windows_width;
+ curs_h = curs_windows_height;
+ break;
+ case CURS_DEFAULT:
+ default:
+ return XCB_NONE; /* XCB_NONE is xcb's way of saying "don't change the cursor" */
+ }
+
+ bitmap = xcb_create_pixmap_from_bitmap_data(conn,
+ win,
+ curs_bits,
+ curs_w,
+ curs_h,
+ 1,
+ screen->white_pixel,
+ screen->black_pixel,
+ NULL);
+
+ mask = xcb_create_pixmap_from_bitmap_data(conn,
+ win,
+ mask_bits,
+ curs_w,
+ curs_h,
+ 1,
+ screen->white_pixel,
+ screen->black_pixel,
+ NULL);
+
+ cursor = xcb_generate_id(conn);
+
+ xcb_create_cursor(conn,
+ cursor,
+ bitmap,
+ mask,
+ 65535,65535,65535,
+ 0,0,0,
+ 0,0);
+
+ xcb_free_pixmap(conn, bitmap);
+ xcb_free_pixmap(conn, mask);
+
+ return cursor;
+}