/* ---------------------------------------------------------------- *\ file : space_dapp.c author : m. gumz copyr : copyright (c) 2006 by m. gumz license : MIT - license start : Sun Sep 17 15:41:56 2006 \* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- *\ about : simplest way for a dockapp i could come up with. use it to go further if you want. if you want to make it look like completly transparent you need to -DSHAPE and -lXext, otherwise not. compile with: gcc -o space_dapp_xcb space_dapp_xcb.c -DSHAPE \ `pkg-config --libs xcb-shape xcb-icccm xcb-image` \* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- *\ includes \* ---------------------------------------------------------------- */ #include #include #include #include #include #include #include #ifdef SHAPE #include #endif /* SHAPE */ /* ---------------------------------------------------------------- *\ \* ---------------------------------------------------------------- */ char dock_name[] = "space_dapp_xcb"; void msg(const char* s) { write(1, s, strlen(s)); } void err(const char* s) { write(2, s, strlen(s)); } void usage() { msg(dock_name); msg(" [width] [height]\n"); } int main(int argc, char* argv[]) { int w = -1; int h = -1; xcb_connection_t* dpy = 0; xcb_screen_t* screen = 0; xcb_window_t dock_win; xcb_window_t root_win; { // parse cli int i; for (i = 1; i < argc; i++) { char* arg = argv[i]; if (strcmp(arg, "-h") == 0) { usage(); return 0; } else if (w < 0) { int t = atoi(arg); if (t <= 0) { err("error, width must be greater than 0.\n"); return EXIT_FAILURE; } w = t; } else if (h < 0) { int t = atoi(arg); if (t <= 0) { err("error, height must be greater than 0.\n"); return EXIT_FAILURE; } h = t; } } } // last checks if (w == -1) { w = 1; } if (h == -1) { h = 1; } dpy = xcb_connect(0, 0); if (xcb_connection_has_error(dpy)) { err("couldnt connect to display\n"); exit(-1); } screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; root_win = screen->root; // create the window { uint32_t mask; uint32_t values[2]; mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; values[0] = screen->white_pixel; values[1] = XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_KEY_PRESS; dock_win = xcb_generate_id(dpy); xcb_create_window(dpy, screen->root_depth, dock_win, root_win, 0, 0, w, h, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values); #ifdef SHAPE { const int bytes = ((w / 8) + 1) * h; char* mask = (char*)malloc(bytes); memset(mask, 0x00, bytes); { xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(dpy, dock_win, mask, w, h, 2, 0, 1, 0); xcb_shape_mask(dpy, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, dock_win, 0, 0, pm); // xcb_free_pixmap(dpy, pm); } } #endif /* SHAPE */ { xcb_size_hints_t* size_hints = xcb_alloc_size_hints(); xcb_size_hints_set_size(size_hints, 1, w, h); xcb_size_hints_set_position(size_hints, 1, 0, 0); xcb_size_hints_set_flags(size_hints, XCB_SIZE_US_POSITION_HINT|XCB_SIZE_US_SIZE_HINT); xcb_set_wm_normal_hints(dpy, dock_win, size_hints); xcb_free_size_hints(size_hints); } { xcb_wm_hints_t* wm_hints = xcb_alloc_wm_hints(); xcb_wm_hints_set_withdrawn(wm_hints); xcb_wm_hints_set_icon_window(wm_hints, 0); xcb_wm_hints_set_window_group(wm_hints, dock_win); xcb_wm_hints_set_flags(wm_hints, XCB_WM_WINDOW_GROUP_HINT|XCB_WM_STATE_HINT); xcb_set_wm_hints(dpy, dock_win, wm_hints); xcb_free_wm_hints(wm_hints); } xcb_map_window(dpy, dock_win); xcb_flush(dpy); } // eventloop { xcb_generic_event_t* event; int done = 0; for (; !done;) { if (event = xcb_wait_for_event(dpy)) { switch (event->response_type & ~0x80) { case XCB_DESTROY_NOTIFY: done = 1; break; } } free(event); poll(NULL, 0, 25); } } xcb_disconnect(dpy); return EXIT_SUCCESS; } /* ---------------------------------------------------------------- *\ \* ---------------------------------------------------------------- */