diff options
| author | Joel Klinghed <the_jk@yahoo.com> | 2017-09-27 19:38:44 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@yahoo.com> | 2017-09-27 19:38:44 +0200 |
| commit | 36ab6defac59d289a513e74c28e21f437adead98 (patch) | |
| tree | a578cf109f7a5da6973937c68fc00f9846032494 /src | |
| parent | 62546e2a0fbd6d0e4730873480466dd1fef07d96 (diff) | |
Add some rather quirky X fixes
So, from the xserver code, if you don't specify a border pixel
you must match the parent window depth.
Also, if you don't specify a colormap you need to match the
parent visual
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cc | 25 | ||||
| -rw-r--r-- | src/x.cc | 15 | ||||
| -rw-r--r-- | src/x.hh | 29 |
3 files changed, 60 insertions, 9 deletions
diff --git a/src/main.cc b/src/main.cc index 50fe463..a00d4c7 100644 --- a/src/main.cc +++ b/src/main.cc @@ -104,18 +104,32 @@ public: wnd_.reset(conn); pixmap_.reset(conn); gcontext_.reset(conn); + cmap_.reset(); - uint32_t values[2]; - values[0] = screen->black_pixel; - values[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_EXPOSURE + uint32_t values[4]; + size_t i = 0; + uint32_t mask = XCB_CW_BACK_PIXEL; + values[i++] = screen->black_pixel; + if (format.need_border()) { + mask |= XCB_CW_BORDER_PIXEL; + values[i++] = screen->black_pixel; + } + mask |= XCB_CW_EVENT_MASK; + values[i++] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; + if (format.need_colormap()) { + mask |= XCB_CW_COLORMAP; + cmap_.reset(conn); + xcb_create_colormap(cmap_.conn(), XCB_COLORMAP_ALLOC_NONE, cmap_.get(), + screen->root, format.visual->visual_id); + values[i++] = cmap_.get(); + } xcb_create_window(wnd_.conn(), format.depth, wnd_.get(), screen->root, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, format.visual->visual_id, - XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, - values); + mask, values); if (!normal) { if (atoms->get("_MOTIF_WM_INFO", false) != XCB_ATOM_NONE) { auto atom = atoms->get("_MOTIF_WM_HINTS"); @@ -779,6 +793,7 @@ private: std::shared_ptr<x::Atoms> atoms_; x::unique_window wnd_; x::unique_gcontext gcontext_; + x::unique_colormap cmap_; uint8_t depth_; uint32_t black_pixel_; xcb_screen_t const* screen_; @@ -177,6 +177,7 @@ Format get_best_format(xcb_connection_t* conn, xcb_screen_t const* screen, xcb_render_pictforminfo_t* render = nullptr; xcb_render_pictforminfo_t* render_alpha = nullptr; xcb_render_query_pict_formats_reply_t* render_formats = nullptr; + uint8_t flags = 0; PixelFormat format; auto render_reply = xcb_get_extension_data(conn, &xcb_render_id); @@ -265,6 +266,15 @@ Format get_best_format(xcb_connection_t* conn, xcb_screen_t const* screen, free(render_formats); return Format(); } + + if (depth != screen->root_depth) { + flags |= Format::FLAG_NEED_BORDER; + } + if (visual->visual_id != screen->root_visual + || screen->default_colormap == XCB_NONE) { + flags |= Format::FLAG_NEED_COLORMAP; + } + if (render && render_formats) { auto info = xcb_render_query_pict_formats_formats(render_formats); auto count = xcb_render_query_pict_formats_formats_length(render_formats); @@ -313,7 +323,10 @@ Format get_best_format(xcb_connection_t* conn, xcb_screen_t const* screen, // as xcb_render_pictforminfo_t pointers // free(render_formats); - return Format(depth, visual, render, render_alpha); + return Format(depth, visual, render, render_alpha, flags); } +const uint8_t Format::FLAG_NEED_BORDER = 1 << 0; +const uint8_t Format::FLAG_NEED_COLORMAP = 1 << 1; + } // namespace x @@ -41,6 +41,12 @@ struct XcbRenderPictureDelete { } }; +struct XcbColormapDelete { + void operator()(xcb_connection_t* conn, xcb_colormap_t id) const { + xcb_free_colormap(conn, id); + } +}; + } // priv class shared_connection { @@ -194,24 +200,41 @@ typedef unique_resource<xcb_gcontext_t, priv::XcbGContextDelete> unique_gcontext; typedef unique_resource<xcb_render_picture_t, priv::XcbRenderPictureDelete> unique_picture; +typedef unique_resource<xcb_colormap_t, + priv::XcbColormapDelete> unique_colormap; struct Format { + static uint8_t const FLAG_NEED_BORDER; + static uint8_t const FLAG_NEED_COLORMAP; + uint8_t depth; xcb_visualtype_t* visual; xcb_render_pictforminfo_t* render; xcb_render_pictforminfo_t* render_alpha; + uint8_t flags; bool good() const { return depth > 0 && visual; } + bool need_border() const { + return flags & FLAG_NEED_BORDER; + } + + bool need_colormap() const { + return flags & FLAG_NEED_COLORMAP; + } + Format(uint8_t depth, xcb_visualtype_t* visual, xcb_render_pictforminfo_t* render, - xcb_render_pictforminfo_t* render_alpha) - : depth(depth), visual(visual), render(render), render_alpha(render_alpha) { + xcb_render_pictforminfo_t* render_alpha, + uint8_t flags) + : depth(depth), visual(visual), render(render), render_alpha(render_alpha), + flags(flags) { } Format() - : depth(0), visual(nullptr), render(nullptr), render_alpha(nullptr) { + : depth(0), visual(nullptr), render(nullptr), render_alpha(nullptr), + flags(0) { } }; |
