summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cc25
-rw-r--r--src/x.cc15
-rw-r--r--src/x.hh29
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_;
diff --git a/src/x.cc b/src/x.cc
index 53b09d4..3749f81 100644
--- a/src/x.cc
+++ b/src/x.cc
@@ -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
diff --git a/src/x.hh b/src/x.hh
index ce4f812..00751c2 100644
--- a/src/x.hh
+++ b/src/x.hh
@@ -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) {
}
};