From 2497c1392b81e093f4de2541a98746aebd449a7f Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 26 Sep 2012 15:04:18 +0200 Subject: Initial commit --- xcbviewfs.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 xcbviewfs.c (limited to 'xcbviewfs.c') 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 + * Date: 2012-09-24 + * gcc -o xcbviewfs xcbviewfs.c -lxcb-image -lxcb-shm -lxcb + */ + +#include +//#include +#include +#include +#include +#include + +#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; +} -- cgit v1.2.1