]> git.sur5r.net Git - i3/i3lock/commitdiff
Port the pointer-code to xcb
authorAxel Wagner <mail@merovius.de>
Mon, 19 Jul 2010 21:15:50 +0000 (23:15 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Tue, 20 Jul 2010 20:56:47 +0000 (22:56 +0200)
Makefile
cursors.h
debian/control
i3lock.c
xcb.c
xcb.h

index 9d3fb50bec4c3a12254f4e7c18cee611fcec2c50..7cb505258f8d2b9858648857d7191010f93cbd89 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ CFLAGS += -pipe
 CFLAGS += -Wall
 CFLAGS += -D_GNU_SOURCE
 CFLAGS += $(shell pkg-config --cflags cairo xcb-keysyms xcb-dpms)
-LDFLAGS += $(shell pkg-config --libs cairo xcb-keysyms xcb-dpms)
+LDFLAGS += $(shell pkg-config --libs cairo xcb-keysyms xcb-dpms xcb-image)
 LDFLAGS += -lpam
 
 FILES:=$(wildcard *.c)
index 6a0b1f8f1311bed7a8e6ddb7276091087e0f6110..23fd30f41021dccec64935614605b9aedc88cb08 100644 (file)
--- a/cursors.h
+++ b/cursors.h
@@ -1,3 +1,7 @@
+#define CURS_NONE    0
+#define CURS_WIN     1
+#define CURS_DEFAULT 2
+
 #define curs_invisible_width 8
 #define curs_invisible_height 8
 
index 204b75033e6515f22cff90dbbf3fb34d2ce583f3..436124d8bf9c9c2dacfec1e4d0766f4a6591f6e7 100644 (file)
@@ -3,7 +3,7 @@ Section: utils
 Priority: extra
 Maintainer: Michael Stapelberg <michael@stapelberg.de>
 DM-Upload-Allowed: yes
-Build-Depends: debhelper (>= 5), libx11-dev, libpam0g-dev, libcairo2-dev, libxcb1-dev, libxcb-dpms0-dev, libxcb-keysyms1-dev
+Build-Depends: debhelper (>= 5), libx11-dev, libpam0g-dev, libcairo2-dev, libxcb1-dev, libxcb-dpms0-dev, libxcb-keysyms1-dev, libxcb-image0-dev
 Standards-Version: 3.8.2
 Homepage: http://i3.zekjur.net/i3lock/
 
index 22317fc9e363e4741d3e7f52b5ff3e0b409dd044..5df9f268beb5c46f7542e97d7c69a146da69747a 100644 (file)
--- a/i3lock.c
+++ b/i3lock.c
@@ -27,6 +27,7 @@
 #include "keysym2ucs.h"
 #include "ucs2_to_utf8.h"
 #include "xcb.h"
+#include "cursors.h"
 
 static xcb_connection_t *conn;
 static xcb_key_symbols_t *symbols;
@@ -230,6 +231,8 @@ int main(int argc, char *argv[]) {
     xcb_generic_event_t *event;
     xcb_screen_t *scr;
     xcb_window_t win;
+    xcb_cursor_t cursor;
+    int curs_choice = CURS_NONE;
     char o;
     int optind = 0;
     struct option longopts[] = {
@@ -279,7 +282,12 @@ int main(int argc, char *argv[]) {
             /* TODO: tile image */
             break;
         case 'p':
-            /* TODO: cursor */
+            if (!strcmp(optarg, "win")) {
+                curs_choice = CURS_WIN;
+            }
+            if (!strcmp(optarg, "default")) {
+                curs_choice = CURS_DEFAULT;
+            }
             break;
         default:
             errx(1, "i3lock: Unknown option. Syntax: i3lock [-v] [-n] [-b] [-d] [-i image.png] [-c color] [-t] [-p win|default]\n");
@@ -319,7 +327,9 @@ int main(int argc, char *argv[]) {
      * ready to handle the expose event immediately afterwards) */
     win = open_fullscreen_window(conn, scr, color);
 
-    grab_pointer_and_keyboard(conn, scr);
+    cursor = create_cursor(conn, scr, win, curs_choice);
+
+    grab_pointer_and_keyboard(conn, scr, cursor);
 
     if (image_path)
         img = cairo_image_surface_create_from_png(image_path);
diff --git a/xcb.c b/xcb.c
index 41b007a3435b411e6ed1b8df7c2446f0b50d2b2f..70f1374008a5529d9ca4f4a7014c12f6d0bf6931 100644 (file)
--- a/xcb.c
+++ b/xcb.c
@@ -9,6 +9,7 @@
  */
 #include <xcb/xcb.h>
 #include <xcb/xcb_keysyms.h>
+#include <xcb/xcb_image.h>
 #include <xcb/dpms.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -17,6 +18,8 @@
 #include <assert.h>
 #include <err.h>
 
+#include "cursors.h"
+
 static uint32_t get_colorpixel(char *hex) {
     char strgroups[3][3] = {{hex[0], hex[1], '\0'},
                             {hex[2], hex[3], '\0'},
@@ -132,7 +135,7 @@ void dpms_turn_off_screen(xcb_connection_t *conn) {
  * 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;
 
@@ -150,7 +153,7 @@ void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen) {
             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
         );
 
@@ -164,6 +167,9 @@ void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen) {
         usleep(50);
     }
 
+    if (cursor != XCB_NONE)
+        xcb_free_cursor(conn, cursor);
+
     while (tries-- > 0) {
         kcookie = xcb_grab_keyboard(
             conn,
@@ -187,3 +193,66 @@ void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen) {
     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;
+}
diff --git a/xcb.h b/xcb.h
index 66590246ac0b1b5c8ce88a3ef79ae122234fe67e..bae51b212714dd65fd79b0514a8732c1c6c396ad 100644 (file)
--- a/xcb.h
+++ b/xcb.h
@@ -5,8 +5,9 @@
 
 xcb_visualtype_t *get_root_visual_type(xcb_screen_t *s);
 xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color);
-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);
 uint32_t get_mod_mask(xcb_connection_t *conn, xcb_key_symbols_t *symbols, uint32_t keycode);
 void dpms_turn_off_screen(xcb_connection_t *conn);
+xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice);
 
 #endif