summaryrefslogtreecommitdiff
path: root/xcbviewfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'xcbviewfs.c')
-rw-r--r--xcbviewfs.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/xcbviewfs.c b/xcbviewfs.c
new file mode 100644
index 0000000..79386dd
--- /dev/null
+++ b/xcbviewfs.c
@@ -0,0 +1,139 @@
+/*
+ * Attempt to implement picture viewer XCB with kbd and pointer grabbing, fullscreen
+ *
+ * Author: Peter Wu <lekensteyn@gmail.com>
+ * Date: 2012-09-24
+ * gcc -o xcbviewfs xcbviewfs.c -lxcb-image -lxcb-shm -lxcb
+ */
+
+#include <xcb/xcb.h>
+//#include <X11/Xlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#define die(msg) do { \
+ fprintf(stderr, msg); \
+ exit(EXIT_FAILURE); \
+} while (0)
+
+#define bail(lbl, msg) do { \
+ fprintf(stderr, msg); \
+ goto lbl; \
+} while (0)
+
+static const char empty_cursor_data[32];
+
+int main(int argc, char **argv) {
+ xcb_connection_t *c;
+ xcb_screen_t *screen;
+ xcb_window_t win;
+ xcb_cursor_t cursor;
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s filename\n", *argv);
+ return 1;
+ }
+ c = xcb_connect(NULL, NULL);
+ if (!c) {
+ fprintf(stderr, "Cannot open display\n");
+ return 1;
+ }
+ screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
+ win = xcb_generate_id(c);
+ xcb_create_window(c, 0, win, /* conn, depth, WinID */
+ screen->root, /* parent */
+ 0, 0, /* x y */
+ 100, 100, /* width height */
+ 0, /* border_width */
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
+ screen->root_visual,
+ 0, NULL);
+ xcb_map_window(c, win);
+ xcb_flush(c);
+
+ /* options */
+ int grab_pointer = 0;
+ int hide_cursor = 0;
+ int grab_kbd = 0;
+ int fullscreen = 0;
+ grab_kbd = !(fullscreen = grab_pointer = hide_cursor = 0 );
+
+ if (grab_pointer) {
+ xcb_grab_pointer_cookie_t cookie;
+ xcb_grab_pointer_reply_t *reply;
+ cookie = xcb_grab_pointer(c, 1, screen->root, XCB_NONE,
+ XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
+ XCB_NONE, XCB_NONE,
+ XCB_CURRENT_TIME);
+ if (!(reply = xcb_grab_pointer_reply(c, cookie, NULL))) {
+ bail(disconnect, "No pointer grab reply\n");
+ }
+ if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
+ bail(disconnect, "Grab pointer FAILED\n");
+ }
+ free(reply);
+ }
+ if (hide_cursor) {
+ xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(c, win,
+ empty_cursor_data, 16, 16, 1, 0, 0, 0);
+ xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(c, win,
+ empty_cursor_data, 16, 16, 1, 0, 0, 0);
+
+ cursor = xcb_generate_id(c);
+ xcb_create_cursor(c, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ xcb_free_pixmap(c, cp);
+ xcb_free_pixmap(c, mp);
+
+ xcb_change_window_attributes(c, win, XCB_CW_CURSOR, &cursor);
+ xcb_free_cursor(c, cursor);
+ xcb_flush(c);
+ }
+ if (grab_kbd) {
+ xcb_grab_keyboard_cookie_t cookie;
+ xcb_grab_keyboard_reply_t *reply;
+ cookie = xcb_grab_keyboard(c, 1, screen->root, XCB_CURRENT_TIME,
+ XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
+ if (!(reply = xcb_grab_keyboard_reply(c, cookie, NULL))) {
+ bail(ungrab_pointer, "No kbd grab reply\n");
+ }
+ if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
+ bail(ungrab_pointer, "Grab kbd FAILED\n");
+ }
+ free(reply);
+ }
+ if (fullscreen) {
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t *reply;
+ xcb_atom_t property, data;
+
+ cookie = xcb_intern_atom(c, 0, 13, "_NET_WM_STATE");
+ if (!(reply = xcb_intern_atom_reply(c, cookie, 0))) {
+ bail(ungrab_kbd, "Failed to get _NET_WM_STATE atom\n");
+ }
+ property = reply->atom;
+ free(reply);
+
+ cookie = xcb_intern_atom(c, 0, 24, "_NET_WM_STATE_FULLSCREEN");
+ if (!(reply = xcb_intern_atom_reply(c, cookie, 0))) {
+ bail(ungrab_kbd, "Failed to get _NET_WM_STATE_FULLSCREEN atom\n");
+ }
+ data = reply->atom;
+ free(reply);
+
+ xcb_change_property(c, XCB_PROP_MODE_REPLACE, win,
+ property, XCB_ATOM_ATOM, 32, 1, &data);
+ xcb_flush(c);
+ }
+ xcb_generic_event_t *e;
+ while ((e = xcb_wait_for_event(c))) {
+ free(e);
+ }
+ungrab_kbd:
+ xcb_ungrab_keyboard(c, XCB_CURRENT_TIME);
+ungrab_pointer:
+ xcb_ungrab_pointer(c, XCB_CURRENT_TIME);
+disconnect:
+ xcb_disconnect(c);
+ return 0;
+}