From: Dana Jansens Date: Tue, 4 Mar 2008 19:19:04 +0000 (-0500) Subject: create a d_display_t type that encompasses a connection to a display X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=d0dbb7102f73431eedf37af92291835b6315e0dc;p=dana%2Fdcompmgr.git create a d_display_t type that encompasses a connection to a display --- diff --git a/dcompmgr.c b/dcompmgr.c index c024349..175b522 100644 --- a/dcompmgr.c +++ b/dcompmgr.c @@ -1,5 +1,6 @@ #include "screen.h" #include "window.h" +#include "display.h" #include "gettext.h" #include @@ -8,24 +9,28 @@ #include #include +typedef struct { + int foo; +} d_options_t; + static gint -all_screens(xcb_connection_t *conn, d_screen_t **list) +all_screens(d_display_t *dpy, d_screen_t **list) { static const xcb_setup_t *setup; xcb_screen_iterator_t it; int count, i; d_screen_t sc; - setup = xcb_get_setup(conn); + setup = xcb_get_setup(dpy->conn); count = i = 0; for (it = xcb_setup_roots_iterator(setup); it.rem; xcb_screen_next(&it)) { sc.super = *it.data; - sc.conn = conn; + sc.dpy = dpy; sc.num = i++; if (screen_register(&sc)) { ++count; - *list = g_renew(d_screen_t, *list, count); + *list = realloc(*list, sizeof(d_screen_t)*count); (*list)[count-1] = sc; printf(_("managing screen %d\n"), sc.num); } @@ -33,7 +38,7 @@ all_screens(xcb_connection_t *conn, d_screen_t **list) return count; } -d_screen_t* +static d_screen_t* screen_from_root(d_screen_t *list, int n, xcb_window_t root) { int i; @@ -43,32 +48,41 @@ screen_from_root(d_screen_t *list, int n, xcb_window_t root) return NULL; } +static +void read_options(int argc, char **argv, d_options_t *opts) +{ + opts->foo = argc && argv; +} + int main(int argc, char **argv) { - xcb_connection_t *conn; + d_display_t *dpy; d_screen_t *screens = NULL; int nscreens; xcb_generic_event_t *ev; + d_options_t opts; + + read_options(argc, argv, &opts); - conn = xcb_connect(NULL, NULL); - if (!conn) { + dpy = display_open(NULL); + if (!dpy) { printf(_("Unable to connect to display\n")); return 1; } - nscreens = all_screens(conn, &screens); + nscreens = all_screens(dpy, &screens); if (nscreens < 1) { printf(_("found no screens to run on\n")); - xcb_disconnect(conn); + display_unref(dpy); return 0; } - while ((ev = xcb_wait_for_event(conn))) { + while ((ev = xcb_wait_for_event(dpy->conn))) { printf("event %d\n", ev->response_type); if (!ev->response_type) { - error(conn, (xcb_generic_error_t*)ev); + display_error(dpy, (xcb_generic_error_t*)ev); free(ev); continue; } @@ -117,12 +131,38 @@ main(int argc, char **argv) } break; } + case XCB_MAP_NOTIFY: + { + xcb_map_notify_event_t *mev; + d_screen_t *sc; + d_window_t *w; + + mev = (xcb_map_notify_event_t*)ev; + sc = screen_from_root(screens, nscreens, mev->event); + if (!sc) break; + w = screen_find_window(sc, mev->window); + window_show(w); + break; + } + case XCB_UNMAP_NOTIFY: + { + xcb_unmap_notify_event_t *mev; + d_screen_t *sc; + d_window_t *w; + + mev = (xcb_unmap_notify_event_t*)ev; + sc = screen_from_root(screens, nscreens, mev->event); + if (!sc) break; + w = screen_find_window(sc, mev->window); + window_hide(w); + break; + } default: break; } free(ev); } - xcb_disconnect(conn); + display_unref(dpy); return 0; } diff --git a/display.c b/display.c new file mode 100644 index 0000000..ffca5e6 --- /dev/null +++ b/display.c @@ -0,0 +1,112 @@ +#include "display.h" +#include +#include + +#include +#include +#include + +d_display_t* +display_open(const char *name) +{ + d_display_t *dpy = NULL; + xcb_connection_t *conn; + + conn = xcb_connect(name, NULL); + if (conn) { + dpy = malloc(sizeof(d_display_t)); + dpy->conn = conn; + dpy->ref = 1; + } + return dpy; +} + +void +display_ref(d_display_t *dpy) +{ + ++dpy->ref; +} + +void +display_unref(d_display_t *dpy) +{ + if (dpy && --dpy->ref == 0) { + xcb_disconnect(dpy->conn); + free(dpy); + } +} + +void +display_error(d_display_t *dpy, xcb_generic_error_t *ev) +{ + const int major_opcode = ((xcb_request_error_t*)ev)->major_opcode; + const int minor_opcode = ((xcb_request_error_t*)ev)->minor_opcode; + const char *name, *req; + + /* XXX check if we should ignore it (ev->full_sequence) */ + + (void)dpy; + + name = NULL; + switch (ev->error_code) { + case XCB_REQUEST: name = "BadRequest"; break; + case XCB_VALUE: name = "BadValue"; break; + case XCB_WINDOW: name = "BadWindow"; break; + case XCB_PIXMAP: name = "BadPixmap"; break; + case XCB_MATCH: name = "BadMatch"; break; + case XCB_DRAWABLE: name = "BadDrawable"; break; + case XCB_G_CONTEXT: name = "BadGC"; break; + default: break; + } + if (!name) + switch (ev->error_code - dpy->fixes_error) { + case XCB_XFIXES_BAD_REGION: name = "BadRegion"; break; + default: break; + } + if (!name) + switch (ev->error_code - dpy->damage_error) { + case XCB_DAMAGE_BAD_DAMAGE: name = "BadDamage"; break; + default: break; + } + if (!name) + switch (ev->error_code - dpy->render_error) { + case XCB_RENDER_PICT_FORMAT: name = "BadPictFormat"; break; + case XCB_RENDER_PICT_OP: name = "BadPictOp"; break; + case XCB_RENDER_PICTURE: name = "BadPicture"; break; + case XCB_RENDER_GLYPH_SET: name = "BadGlyphSet"; break; + case XCB_RENDER_GLYPH: name = "BadGlyph"; break; + default: break; + } + + if (major_opcode <= 127) + switch (major_opcode) { + case 1: req = "CreateWindow"; break; + case 2: req = "ChangeWindowAttributes"; break; + case 3: req = "GetWindowAttributes"; break; + case 14: req = "GetGeometry"; break; + case 15: req = "QueryTree"; break; + case 18: req = "ChangeProperty"; break; + case 20: req = "GetProperty"; break; + case 22: req = "SetSelectionOwner"; break; + case 23: req = "GetSelectionOwner"; break; + case 53: req = "CreatePixmap"; break; + case 54: req = "FreePixmap"; break; + case 55: req = "CreateGC"; break; + case 56: req = "ChangeGC"; break; + case 60: req = "FreeGC"; break; + case 72: req = "PutImage"; break; + default: break; + } + + if (name && req) + printf("XError: %s %s!\n", + name, req); + else if (name) + printf("XError: %s major opcode %d minor opcode %d!\n", + name, major_opcode, minor_opcode); + else + printf("XError: code %d major opcode %d minor opcode %d!\n", + ev->error_code, major_opcode, minor_opcode); + + abort(); +} diff --git a/display.h b/display.h new file mode 100644 index 0000000..f46ed46 --- /dev/null +++ b/display.h @@ -0,0 +1,22 @@ +#ifndef dc__display_h +#define dc__display_h + +#include + +typedef struct d_display { + xcb_connection_t *conn; + int ref; + + int fixes_error; + int damage_error; + int render_error; +} d_display_t; + +d_display_t* display_open(const char *name); + +void display_ref(d_display_t *dpy); +void display_unref(d_display_t *dpy); + +void display_error(d_display_t *dpy, xcb_generic_error_t *ev); + +#endif diff --git a/error.c b/error.c deleted file mode 100644 index 918f95d..0000000 --- a/error.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "error.h" -#include -#include - -void -error(xcb_connection_t *conn, xcb_generic_error_t *ev) -{ - (void)conn; (void)ev; - printf("error!\n"); - abort(); -} diff --git a/error.h b/error.h deleted file mode 100644 index 3a8be4c..0000000 --- a/error.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef dc__error_h -#define dc__error_h - -#include - -void error(xcb_connection_t *conn, xcb_generic_error_t *ev); - -#endif diff --git a/screen.c b/screen.c index 873e96f..533f07f 100644 --- a/screen.c +++ b/screen.c @@ -1,5 +1,5 @@ #include "screen.h" -#include "error.h" +#include "display.h" #include "window.h" #include "gettext.h" #include @@ -28,19 +28,19 @@ screen_register(d_screen_t *sc) uint32_t event_mask; gboolean taken, ret; - w = xcb_generate_id(sc->conn); + w = xcb_generate_id(sc->dpy->conn); event_mask = SELECTION_MASK; - xcb_create_window(sc->conn, XCB_COPY_FROM_PARENT, w, sc->super.root, + xcb_create_window(sc->dpy->conn, XCB_COPY_FROM_PARENT, w, sc->super.root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, sc->super.root_visual, XCB_CW_EVENT_MASK, &event_mask); name = g_strdup_printf("_NET_WM_CM_S%d", sc->num); - ack = xcb_intern_atom(sc->conn, FALSE, strlen(name), name); - arep = xcb_intern_atom_reply(sc->conn, ack, NULL); + ack = xcb_intern_atom(sc->dpy->conn, FALSE, strlen(name), name); + arep = xcb_intern_atom_reply(sc->dpy->conn, ack, NULL); g_free(name); - sck = xcb_get_selection_owner(sc->conn, arep->atom); - srep = xcb_get_selection_owner_reply(sc->conn, sck, NULL); + sck = xcb_get_selection_owner(sc->dpy->conn, arep->atom); + srep = xcb_get_selection_owner_reply(sc->dpy->conn, sck, NULL); taken = !!srep->owner; free(srep); if (taken) { @@ -56,21 +56,21 @@ screen_register(d_screen_t *sc) time = screen_timestamp(sc); - xcb_grab_server(sc->conn); - xcb_set_selection_owner(sc->conn, w, arep->atom, time); - sck = xcb_get_selection_owner(sc->conn, arep->atom); - srep = xcb_get_selection_owner_reply(sc->conn, sck, NULL); + xcb_grab_server(sc->dpy->conn); + xcb_set_selection_owner(sc->dpy->conn, w, arep->atom, time); + sck = xcb_get_selection_owner(sc->dpy->conn, arep->atom); + srep = xcb_get_selection_owner_reply(sc->dpy->conn, sck, NULL); taken = srep->owner == w; if (taken) { screen_init(sc); ret = TRUE; } else { - xcb_destroy_window(sc->conn, w); + xcb_destroy_window(sc->dpy->conn, w); ret = FALSE; } - xcb_ungrab_server(sc->conn); - xcb_flush(sc->conn); + xcb_ungrab_server(sc->dpy->conn); + xcb_flush(sc->dpy->conn); } return ret; } @@ -89,14 +89,14 @@ screen_init(d_screen_t *sc) sc->winhash = g_hash_table_new((GHashFunc)window_hash, (GCompareFunc)window_compare); -// xcb_composite_redirect_subwindows(sc->conn, sc->super.root, +// xcb_composite_redirect_subwindows(sc->dpy->conn, sc->super.root, // XCB_COMPOSITE_REDIRECT_MANUAL); mask = SELECTION_MASK; - xcb_change_window_attributes(sc->conn, sc->selwin, + xcb_change_window_attributes(sc->dpy->conn, sc->selwin, XCB_CW_EVENT_MASK, &mask); mask = ROOT_MASK; - xcb_change_window_attributes(sc->conn, sc->super.root, + xcb_change_window_attributes(sc->dpy->conn, sc->super.root, XCB_CW_EVENT_MASK, &mask); } @@ -110,13 +110,13 @@ screen_add_window(d_screen_t *sc, xcb_window_t wid) w = window_new(wid, sc); g_hash_table_insert(sc->winhash, &w->id, w); - printf("added window 0x%x\n", w->id); + printf("screen added window 0x%x\n", w->id); } void screen_remove_window(d_screen_t *sc, struct d_window *w) { - printf("removed window 0x%x\n", w->id); + printf("screen removed window 0x%x\n", w->id); g_hash_table_remove(sc->winhash, &w->id); window_unref(w); @@ -134,13 +134,13 @@ screen_timestamp(d_screen_t *sc) xcb_void_cookie_t ck; xcb_timestamp_t time; - ck = xcb_change_property(sc->conn, XCB_PROP_MODE_REPLACE, sc->selwin, + ck = xcb_change_property(sc->dpy->conn, XCB_PROP_MODE_REPLACE, sc->selwin, sc->selatom, sc->selatom, 32, 0, NULL); - xcb_flush(sc->conn); + xcb_flush(sc->dpy->conn); while (1) { xcb_generic_event_t *ev; - ev = xcb_wait_for_event(sc->conn); + ev = xcb_wait_for_event(sc->dpy->conn); if (!ev) { printf(_("IO error\n")); exit(0); @@ -148,7 +148,7 @@ screen_timestamp(d_screen_t *sc) /* expect errors.. */ if (!ev->response_type) { - error(sc->conn, (xcb_generic_error_t*)ev); + display_error(sc->dpy, (xcb_generic_error_t*)ev); free(ev); continue; } diff --git a/screen.h b/screen.h index 4abfcb7..96b1ab1 100644 --- a/screen.h +++ b/screen.h @@ -5,11 +5,12 @@ #include struct d_window; +struct d_display; /* inherits from xcb_screen_t */ typedef struct d_screen { xcb_screen_t super; - xcb_connection_t *conn; + struct d_display *dpy; int num; xcb_window_t selwin; /* for the selection */ diff --git a/window.c b/window.c index 269b60d..4d9bb7b 100644 --- a/window.c +++ b/window.c @@ -1,23 +1,24 @@ #include "window.h" -#include - -static void window_show(d_window_t *w); -static void window_hide(d_window_t *w); +#include +#include d_window_t* window_new(xcb_window_t id, struct d_screen *sc) { d_window_t *w; - w = g_new(d_window_t, 1); + w = malloc(sizeof(d_window_t)); w->id = id; w->ref = 1; w->sc = sc; + w->mapped = FALSE; /* default functions */ w->show = window_show; w->hide = window_hide; + printf("new window 0x%x\n", w->id); + return w; } @@ -31,16 +32,26 @@ void window_unref(d_window_t *w) { if (w && --w->ref == 0) { - g_free(w); + free(w); } } -static void +void window_show(d_window_t *w) { + if (w->mapped) return; + + printf("show window 0x%x\n", w->id); + + w->mapped = TRUE; } -static void +void window_hide(d_window_t *w) { + if (!w->mapped) return; + + printf("hide window 0x%x\n", w->id); + + w->mapped = FALSE; } diff --git a/window.h b/window.h index e03623b..211fd8e 100644 --- a/window.h +++ b/window.h @@ -2,6 +2,7 @@ #define dc__window_h #include +#include struct d_screen; @@ -10,6 +11,8 @@ typedef struct d_window { int ref; struct d_screen *sc; + gboolean mapped; + void (*show)(struct d_window *w); void (*hide)(struct d_window *w); } d_window_t; @@ -19,5 +22,7 @@ d_window_t* window_new(xcb_window_t id, struct d_screen *sc); void window_ref(d_window_t *w); void window_unref(d_window_t *w); +void window_show(d_window_t *w); +void window_hide(d_window_t *w); #endif