diff options
author | Quentin Glidic <sardemff7+git@sardemff7.net> | 2016-02-21 19:42:32 +0100 |
---|---|---|
committer | Quentin Glidic <sardemff7+git@sardemff7.net> | 2016-02-23 17:37:25 +0100 |
commit | 2ef950eab96311d36bab7d70aabac5e6e37c2593 (patch) | |
tree | 70b9d9187da33fca1e7b9af48304c9715ab94d79 | |
parent | 6bb1d4b1a2b451ded41616ff56fdde94a5b46d5c (diff) |
WIP: Port window stuff to xcb
Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/i3-support.h | 2 | ||||
-rw-r--r-- | include/textbox.h | 2 | ||||
-rw-r--r-- | include/view.h | 2 | ||||
-rw-r--r-- | include/x11-helper.h | 22 | ||||
-rw-r--r-- | source/dialogs/window.c | 3 | ||||
-rw-r--r-- | source/i3-support.c | 11 | ||||
-rw-r--r-- | source/rofi.c | 4 | ||||
-rw-r--r-- | source/scrollbar.c | 2 | ||||
-rw-r--r-- | source/textbox.c | 58 | ||||
-rw-r--r-- | source/view.c | 119 | ||||
-rw-r--r-- | source/x11-helper.c | 142 |
12 files changed, 197 insertions, 172 deletions
diff --git a/configure.ac b/configure.ac index 63de6ae2..4df0b2b6 100644 --- a/configure.ac +++ b/configure.ac @@ -87,7 +87,7 @@ GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11]) PKG_CHECK_MODULES([x11], [x11 x11-xcb]) PKG_CHECK_MODULES([xinerama], [xinerama]) PKG_CHECK_MODULES([pango], [pango pangocairo]) -PKG_CHECK_MODULES([cairo], [cairo cairo-xlib]) +PKG_CHECK_MODULES([cairo], [cairo cairo-xcb]) PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0]) diff --git a/include/i3-support.h b/include/i3-support.h index 1e73fe73..e90dd315 100644 --- a/include/i3-support.h +++ b/include/i3-support.h @@ -28,7 +28,7 @@ void i3_support_focus_window ( Window id ); * @returns TRUE when i3 is running, FALSE when not. */ -int i3_support_initialize ( Display *display ); +int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection ); /** * Cleanup. diff --git a/include/textbox.h b/include/textbox.h index ea638ff0..80169c2d 100644 --- a/include/textbox.h +++ b/include/textbox.h @@ -142,7 +142,7 @@ void textbox_insert ( textbox *tb, int pos, char *str, int slen ); * before any of the textbox_ functions is called. * Clean with textbox_cleanup() */ -void textbox_setup ( Display *display ); +void textbox_setup ( void ); /** * Cleanup the allocated colors and fonts by textbox_setup(). diff --git a/include/view.h b/include/view.h index 79a2997b..758894ef 100644 --- a/include/view.h +++ b/include/view.h @@ -90,7 +90,7 @@ void rofi_view_update ( RofiViewState *state ); * * Enables fake transparancy on this view. */ -void rofi_view_setup_fake_transparency ( Display *display, RofiViewState *state ); +void rofi_view_setup_fake_transparency ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, RofiViewState *state ); /** * @param state The handle to the view diff --git a/include/x11-helper.h b/include/x11-helper.h index 6bcf62ae..02167248 100644 --- a/include/x11-helper.h +++ b/include/x11-helper.h @@ -1,6 +1,7 @@ #ifndef X11_ROFI_HELPER_H #define X11_ROFI_HELPER_H #include <cairo.h> +#include <xcb/xcb.h> #include "xkb.h" @@ -27,7 +28,7 @@ int window_get_prop ( Display *display, Window w, Atom prop, char* window_get_text_prop ( Display *display, Window w, Atom atom ); int window_get_atom_prop ( Display *display, Window w, Atom atom, Atom *list, int count ); -void window_set_atom_prop ( Display *display, Window w, Atom prop, Atom *atoms, int count ); +void window_set_atom_prop ( Display *display, Window w, Atom atom, Atom *atoms, int count ); int window_get_cardinal_prop ( Display *display, Window w, Atom atom, unsigned long *list, int count ); @@ -65,7 +66,7 @@ int window_get_cardinal_prop ( Display *display, Window w, Atom atom, unsigned l enum { EWMH_ATOMS ( ATOM_ENUM ), NUM_NETATOMS }; extern const char *netatom_names[]; -extern Atom netatoms[NUM_NETATOMS]; +extern Atom netatoms[NUM_NETATOMS]; typedef struct { int x, y, w, h; @@ -134,13 +135,16 @@ void x11_set_window_opacity ( Display *display, Window box, unsigned int opacity */ void x11_setup ( Display *display, xkb_stuff *xkb ); +extern xcb_depth_t *depth; +extern xcb_visualtype_t *visual; +extern xcb_colormap_t map; +extern xcb_depth_t *root_depth; +extern xcb_visualtype_t *root_visual; /** - * @param display Connection to the X server. - * * This function tries to create a 32bit TrueColor colormap. * If this fails, it falls back to the default for the connected display. */ -void create_visual_and_colormap ( Display *display ); +void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen ); typedef struct { @@ -153,11 +157,11 @@ typedef struct * * Allocate a pixel value for an X named color */ -Color color_get ( Display *display, const char *const name, const char * const defn ); +Color color_get ( const char *const name ); -void color_background ( Display *display, cairo_t *d ); -void color_border ( Display *display, cairo_t *d ); -void color_separator ( Display *display, cairo_t *d ); +void color_background ( cairo_t *d ); +void color_border ( cairo_t *d ); +void color_separator ( cairo_t *d ); void color_cache_reset ( void ); void x11_helper_set_cairo_rgba ( cairo_t *d, Color col ); diff --git a/source/dialogs/window.c b/source/dialogs/window.c index 9dec540e..f65bce13 100644 --- a/source/dialogs/window.c +++ b/source/dialogs/window.c @@ -74,6 +74,7 @@ typedef struct long hint_flags; } client; // TODO +extern xcb_connection_t *xcb_connection; extern Display *display; // window lists typedef struct @@ -387,7 +388,7 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd ) x11_cache_create (); // Check for i3 - pd->config_i3_mode = i3_support_initialize ( display ); + pd->config_i3_mode = i3_support_initialize ( display, xcb_connection ); // Get the active window so we can highlight this. if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) ) diff --git a/source/i3-support.c b/source/i3-support.c index 84396cfd..02ee548f 100644 --- a/source/i3-support.c +++ b/source/i3-support.c @@ -113,20 +113,21 @@ void i3_support_focus_window ( Window id ) close ( s ); } -int i3_support_initialize ( Display *display ) +int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection ) { // If we where initialized, clean this first. i3_support_free_internals (); - // Get atom for I3_SOCKET_PATH - Atom i3_sp_atom = XInternAtom ( display, "I3_SOCKET_PATH", False ); - if ( i3_sp_atom != None ) { + // Get atom for I3_SOCKET_PATH + xcb_intern_atom_cookie_t cookie = xcb_intern_atom ( xcb_connection, FALSE, strlen ( "I3_SOCKET_PATH" ), "I3_SOCKET_PATH" ); + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply ( xcb_connection, cookie, NULL ); + if ( reply != NULL ) { // Get the default screen. Screen *screen = DefaultScreenOfDisplay ( display ); // Find the root window (each X has one.). Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) ); // Get the i3 path property. - i3_socket_path = window_get_text_prop ( display, root, i3_sp_atom ); + i3_socket_path = window_get_text_prop ( display, root, reply->atom ); } // If we find it, go into i3 mode. return ( i3_socket_path != NULL ) ? TRUE : FALSE; diff --git a/source/rofi.c b/source/rofi.c index c5efab96..1bfc0387 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -139,8 +139,8 @@ static int setup () int pfd = create_pid_file ( pidfile ); if ( pfd >= 0 ) { // Request truecolor visual. - create_visual_and_colormap ( display ); - textbox_setup ( display ); + x11_create_visual_and_colormap ( xcb_connection, xcb_screen ); + textbox_setup (); } return pfd; } diff --git a/source/scrollbar.c b/source/scrollbar.c index 2f3eee63..26627daa 100644 --- a/source/scrollbar.c +++ b/source/scrollbar.c @@ -98,7 +98,7 @@ void scrollbar_draw ( scrollbar *sb, cairo_t *draw ) // Cap length; height = MIN ( bh - y + 1, ( height ) ); // Redraw base window - color_separator ( display, draw ); + color_separator ( draw ); cairo_rectangle ( draw, sb->widget.x + config.line_margin, sb->widget.y + y, sb->widget.w - config.line_margin, height ); cairo_fill ( draw ); diff --git a/source/textbox.c b/source/textbox.c index 32e20ab3..d6e8626e 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -621,11 +621,7 @@ int textbox_keypress ( textbox *tb, char *pad, int pad_len, unsigned int modstat /*** * Font setup. */ -static void parse_color ( Display *display, char *bg, Color *col ) -{ - *col = color_get ( display, bg, "white" ); -} -static void textbox_parse_string ( Display *display, const char *str, RowColor *color ) +static void textbox_parse_string ( const char *str, RowColor *color ) { if ( str == NULL ) { return; @@ -638,50 +634,50 @@ static void textbox_parse_string ( Display *display, const char *str, RowColor switch ( index ) { case 0: - parse_color ( display, g_strstrip ( token ), &( color->bg ) ); + color->bg = color_get ( g_strstrip ( token ) ); break; case 1: - parse_color ( display, g_strstrip ( token ), &( color->fg ) ); + color->fg = color_get ( g_strstrip ( token ) ); break; case 2: - parse_color ( display, g_strstrip ( token ), &( color->bgalt ) ); + color->bgalt = color_get ( g_strstrip ( token ) ); break; case 3: - parse_color ( display, g_strstrip ( token ), &( color->hlbg ) ); + color->hlbg = color_get ( g_strstrip ( token ) ); break; case 4: - parse_color ( display, g_strstrip ( token ), &( color->hlfg ) ); + color->hlfg = color_get ( g_strstrip ( token ) ); break; } index++; } g_free ( cstr ); } -void textbox_setup ( Display *display ) +void textbox_setup ( void ) { if ( config.color_enabled ) { - textbox_parse_string ( display, config.color_normal, &( colors[NORMAL] ) ); - textbox_parse_string ( display, config.color_urgent, &( colors[URGENT] ) ); - textbox_parse_string ( display, config.color_active, &( colors[ACTIVE] ) ); + textbox_parse_string ( config.color_normal, &( colors[NORMAL] ) ); + textbox_parse_string ( config.color_urgent, &( colors[URGENT] ) ); + textbox_parse_string ( config.color_active, &( colors[ACTIVE] ) ); } else { - parse_color ( display, config.menu_bg, &( colors[NORMAL].bg ) ); - parse_color ( display, config.menu_fg, &( colors[NORMAL].fg ) ); - parse_color ( display, config.menu_bg_alt, &( colors[NORMAL].bgalt ) ); - parse_color ( display, config.menu_hlfg, &( colors[NORMAL].hlfg ) ); - parse_color ( display, config.menu_hlbg, &( colors[NORMAL].hlbg ) ); - - parse_color ( display, config.menu_bg_urgent, &( colors[URGENT].bg ) ); - parse_color ( display, config.menu_fg_urgent, &( colors[URGENT].fg ) ); - parse_color ( display, config.menu_bg_alt, &( colors[URGENT].bgalt ) ); - parse_color ( display, config.menu_hlfg_urgent, &( colors[URGENT].hlfg ) ); - parse_color ( display, config.menu_hlbg_urgent, &( colors[URGENT].hlbg ) ); - - parse_color ( display, config.menu_bg_active, &( colors[ACTIVE].bg ) ); - parse_color ( display, config.menu_fg_active, &( colors[ACTIVE].fg ) ); - parse_color ( display, config.menu_bg_alt, &( colors[ACTIVE].bgalt ) ); - parse_color ( display, config.menu_hlfg_active, &( colors[ACTIVE].hlfg ) ); - parse_color ( display, config.menu_hlbg_active, &( colors[ACTIVE].hlbg ) ); + colors[NORMAL].bg = color_get ( config.menu_bg ); + colors[NORMAL].fg = color_get ( config.menu_fg ); + colors[NORMAL].bgalt = color_get ( config.menu_bg_alt ); + colors[NORMAL].hlfg = color_get ( config.menu_hlfg ); + colors[NORMAL].hlbg = color_get ( config.menu_hlbg ); + + colors[URGENT].bg = color_get ( config.menu_bg_urgent ); + colors[URGENT].fg = color_get ( config.menu_fg_urgent ); + colors[URGENT].bgalt = color_get ( config.menu_bg_alt ); + colors[URGENT].hlfg = color_get ( config.menu_hlfg_urgent ); + colors[URGENT].hlbg = color_get ( config.menu_hlbg_urgent ); + + colors[ACTIVE].bg = color_get ( config.menu_bg_active ); + colors[ACTIVE].fg = color_get ( config.menu_fg_active ); + colors[ACTIVE].bgalt = color_get ( config.menu_bg_alt ); + colors[ACTIVE].hlfg = color_get ( config.menu_hlfg_active ); + colors[ACTIVE].hlbg = color_get ( config.menu_hlbg_active ); } } diff --git a/source/view.c b/source/view.c index 61846b53..1f94885b 100644 --- a/source/view.c +++ b/source/view.c @@ -46,7 +46,7 @@ #include <sys/types.h> #include <cairo.h> -#include <cairo-xlib.h> +#include <cairo-xcb.h> #define SN_API_NOT_YET_FROZEN #include <libsn/sn.h> @@ -68,17 +68,17 @@ // What todo with these. extern Display *display; +extern xcb_connection_t *xcb_connection; +extern xcb_screen_t *xcb_screen; extern SnLauncheeContext *sncontext; GThreadPool *tpool = NULL; RofiViewState *current_active_menu = NULL; -Window main_window = None; +xcb_window_t main_window = XCB_WINDOW_NONE; cairo_surface_t *surface = NULL; cairo_surface_t *fake_bg = NULL; cairo_t *draw = NULL; -Colormap map = None; -XVisualInfo vinfo; static char * get_matching_state ( void ) { @@ -408,7 +408,7 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *event, xkb if ( state->w != xce->width || state->h != xce->height ) { state->w = xce->width; state->h = xce->height; - cairo_xlib_surface_set_size ( surface, state->w, state->h ); + cairo_xcb_surface_set_size ( surface, state->w, state->h ); rofi_view_resize ( state ); } } @@ -488,22 +488,31 @@ static void check_is_ascii ( thread_state *t, G_GNUC_UNUSED gpointer user_data ) g_mutex_unlock ( t->mutex ); } -static Window __create_window ( Display *display, MenuFlags menu_flags ) +static Window __create_window ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, MenuFlags menu_flags ) { - XSetWindowAttributes attr; - attr.colormap = map; - attr.border_pixel = 0; - attr.background_pixel = 0; - - Window box = XCreateWindow ( display, DefaultRootWindow ( display ), 0, 0, 200, 100, 0, vinfo.depth, InputOutput, - vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr ); - XSelectInput ( - display, - box, - KeyReleaseMask | KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask | FocusChangeMask | - Button1MotionMask ); - - surface = cairo_xlib_surface_create ( display, box, vinfo.visual, 200, 100 ); + uint32_t selmask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; + uint32_t selval[] = + { 0, + 0, + XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_KEY_PRESS | + XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_BUTTON_1_MOTION,map }; + + xcb_window_t box = xcb_generate_id ( xcb_connection ); + xcb_create_window ( xcb_connection, + depth->depth, + box, + xcb_screen->root, + 0, + 0, + 200, + 100, + 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + visual->visual_id, + selmask, + selval ); + + surface = cairo_xcb_surface_create ( xcb_connection, box, visual, 200, 100 ); // Create a drawable. draw = cairo_create ( surface ); g_assert ( draw != NULL ); @@ -894,17 +903,17 @@ void rofi_view_update ( RofiViewState *state ) -(double) ( state->y - state->mon.y ) ); cairo_paint ( d ); cairo_set_operator ( d, CAIRO_OPERATOR_OVER ); - color_background ( display, d ); + color_background ( d ); cairo_paint ( d ); } } else { // Paint the background. - color_background ( display, d ); + color_background ( d ); cairo_paint ( d ); } TICK_N ( "Background" ); - color_border ( display, d ); + color_border ( d ); if ( config.menu_bw > 0 ) { cairo_save ( d ); @@ -935,7 +944,7 @@ void rofi_view_update ( RofiViewState *state ) if ( state->message_tb ) { textbox_draw ( state->message_tb, d ); } - color_separator ( display, d ); + color_separator ( d ); if ( strcmp ( config.separator_style, "none" ) ) { if ( strcmp ( config.separator_style, "dash" ) == 0 ) { @@ -1243,16 +1252,14 @@ void rofi_view_finalize ( RofiViewState *state ) state->finalize ( state ); } } -void rofi_view_setup_fake_transparency ( Display *display, RofiViewState *state ) +void rofi_view_setup_fake_transparency ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, RofiViewState *state ) { if ( fake_bg == NULL ) { - Window root = DefaultRootWindow ( display ); - int screen = DefaultScreen ( display ); - cairo_surface_t *s = cairo_xlib_surface_create ( display, - root, - DefaultVisual ( display, screen ), - DisplayWidth ( display, screen ), - DisplayHeight ( display, screen ) ); + cairo_surface_t *s = cairo_xcb_surface_create ( xcb_connection, + xcb_screen->root, + root_visual, + xcb_screen->width_in_pixels, + xcb_screen->height_in_pixels ); fake_bg = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, state->mon.w, state->mon.h ); cairo_t *dr = cairo_create ( fake_bg ); @@ -1532,9 +1539,8 @@ RofiViewState *rofi_view_create ( Mode *sw, } TICK_N ( "Grab keyboard" ); // main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker - XWindowAttributes attr; - if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) { - main_window = __create_window ( display, menu_flags ); + if ( main_window == 0 ) { + main_window = __create_window ( xcb_connection, xcb_screen, menu_flags ); if ( sncontext != NULL ) { sn_launchee_context_setup_window ( sncontext, main_window ); } @@ -1544,7 +1550,7 @@ RofiViewState *rofi_view_create ( Mode *sw, monitor_active ( display, &( state->mon ) ); TICK_N ( "Get active monitor" ); if ( config.fake_transparency ) { - rofi_view_setup_fake_transparency ( display, state ); + rofi_view_setup_fake_transparency ( xcb_connection, xcb_screen, state ); } // we need this at this point so we can get height. @@ -1643,12 +1649,14 @@ RofiViewState *rofi_view_create ( Mode *sw, ( mode == state->sw ) ? HIGHLIGHT : NORMAL, mode_get_name ( mode ) ); } } + uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + uint32_t vals[] = { state->x, state->y, state->w, state->h }; // Display it. - XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h ); - cairo_xlib_surface_set_size ( surface, state->w, state->h ); - XMapRaised ( display, main_window ); - XFlush ( display ); + xcb_configure_window ( xcb_connection, main_window, mask, vals ); + cairo_xcb_surface_set_size ( surface, state->w, state->h ); + xcb_map_window ( xcb_connection, main_window ); + xcb_flush ( xcb_connection ); // if grabbing keyboard failed, fall through state->selected = 0; @@ -1695,12 +1703,11 @@ void rofi_view_error_dialog ( const char *msg, int markup ) // Get active monitor size. monitor_active ( display, &( state->mon ) ); if ( config.fake_transparency ) { - rofi_view_setup_fake_transparency ( display, state ); + rofi_view_setup_fake_transparency ( xcb_connection, xcb_screen, state ); } // main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker - XWindowAttributes attr; - if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) { - main_window = __create_window ( display, MENU_NORMAL ); + if ( main_window == 0 ) { + main_window = __create_window ( xcb_connection, xcb_screen, MENU_NORMAL ); } rofi_view_calculate_window_and_element_width ( state ); @@ -1715,11 +1722,14 @@ void rofi_view_error_dialog ( const char *msg, int markup ) state->h = state->line_height + ( state->border ) * 2; // Move the window to the correct x,y position. + uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + uint32_t vals[] = { state->x, state->y, state->w, state->h }; + + xcb_configure_window ( xcb_connection, main_window, mask, vals ); calculate_window_position ( state ); - XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h ); - cairo_xlib_surface_set_size ( surface, state->w, state->h ); + cairo_xcb_surface_set_size ( surface, state->w, state->h ); // Display it. - XMapRaised ( display, main_window ); + xcb_map_window ( xcb_connection, main_window ); if ( sncontext != NULL ) { sn_launchee_context_complete ( sncontext ); @@ -1741,15 +1751,14 @@ void rofi_view_cleanup () cairo_surface_destroy ( surface ); surface = NULL; } - if ( main_window != None ) { - XUnmapWindow ( display, main_window ); - XDestroyWindow ( display, main_window ); - main_window = None; + if ( main_window != XCB_WINDOW_NONE ) { + xcb_unmap_window ( xcb_connection, main_window ); + xcb_destroy_window ( xcb_connection, main_window ); + main_window = XCB_WINDOW_NONE; } - - if ( map != None ) { - XFreeColormap ( display, map ); - map = None; + if ( map != XCB_COLORMAP_NONE ) { + xcb_free_colormap ( xcb_connection, map ); + map = XCB_COLORMAP_NONE; } } void rofi_view_workers_initialize ( void ) diff --git a/source/x11-helper.c b/source/x11-helper.c index 43cfdddd..f5eb873f 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -34,6 +34,7 @@ #include <glib.h> #include <cairo.h> +#include <xcb/xcb.h> #include <X11/X.h> #include <X11/Xatom.h> #include <X11/Xlib.h> @@ -68,12 +69,15 @@ enum NUM_X11MOD }; +xcb_depth_t *depth = NULL; +xcb_visualtype_t *visual = NULL; +xcb_colormap_t map = XCB_COLORMAP_NONE; +xcb_depth_t *root_depth = NULL; +xcb_visualtype_t *root_visual = NULL; Atom netatoms[NUM_NETATOMS]; const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) }; static unsigned int x11_mod_masks[NUM_X11MOD]; -extern Colormap map; - // retrieve a property of any type from a window int window_get_prop ( Display *display, Window w, Atom prop, Atom *type, int *items, void *buffer, unsigned int bytes ) { @@ -523,71 +527,81 @@ void x11_setup ( Display *display, xkb_stuff *xkb ) x11_create_frequently_used_atoms ( display ); } -extern XVisualInfo vinfo; -int truecolor = FALSE; -void create_visual_and_colormap ( Display *display ) +void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen ) { - int screen = DefaultScreen ( display ); - // Try to create TrueColor map - if ( XMatchVisualInfo ( display, screen, 32, TrueColor, &vinfo ) ) { - // Visual found, lets try to create map. - map = XCreateColormap ( display, DefaultRootWindow ( display ), vinfo.visual, AllocNone ); - truecolor = TRUE; - } - // Failed to create map. - // Use the defaults then. - if ( map == None ) { - truecolor = FALSE; - // Two fields we use. - vinfo.visual = DefaultVisual ( display, screen ); - vinfo.depth = DefaultDepth ( display, screen ); - map = DefaultColormap ( display, screen ); + xcb_depth_iterator_t depth_iter; + for ( depth_iter = xcb_screen_allowed_depths_iterator ( xcb_screen ); depth_iter.rem; xcb_depth_next ( &depth_iter ) ) { + xcb_depth_t *d = depth_iter.data; + + xcb_visualtype_iterator_t visual_iter; + for ( visual_iter = xcb_depth_visuals_iterator ( d ); visual_iter.rem; xcb_visualtype_next ( &visual_iter ) ) { + xcb_visualtype_t *v = visual_iter.data; + if ( ( d->depth == 32 ) && ( v->_class == XCB_VISUAL_CLASS_TRUE_COLOR ) ) { + depth = d; + visual = v; + } + if ( xcb_screen->root_visual == v->visual_id ) { + root_depth = d; + root_visual = v; + } + } + } + if ( visual != NULL ) { + xcb_void_cookie_t c; + xcb_generic_error_t *e; + map = xcb_generate_id ( xcb_connection ); + c = xcb_create_colormap_checked ( xcb_connection, XCB_COLORMAP_ALLOC_NONE, map, xcb_screen->root, visual->visual_id ); + e = xcb_request_check ( xcb_connection, c ); + if ( e ) { + depth = NULL; + visual = NULL; + free ( e ); + } + } + + if ( visual == NULL ) { + depth = root_depth; + visual = root_visual; + map = xcb_screen->default_colormap; } } -Color color_get ( Display *display, const char *const name, const char * const defn ) +Color color_get ( const char *const name ) { - char *copy = g_strdup ( name ); - char *cname = g_strstrip ( copy ); - XColor color = { 0, 0, 0, 0, 0, 0 }; - XColor def; + char *copy = g_strdup ( name ); + char *cname = g_strstrip ( copy ); + + union + { + struct + { + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t a; + }; + uint32_t pixel; + } color = { + .r = 0xff, + .g = 0xff, + .b = 0xff, + .a = 0xff, + }; // Special format. if ( strncmp ( cname, "argb:", 5 ) == 0 ) { color.pixel = strtoul ( &cname[5], NULL, 16 ); - color.red = ( ( color.pixel & 0x00FF0000 ) >> 16 ) * 256; - color.green = ( ( color.pixel & 0x0000FF00 ) >> 8 ) * 256; - color.blue = ( ( color.pixel & 0x000000FF ) ) * 256; - if ( !truecolor ) { - // This will drop alpha part. - Status st = XAllocColor ( display, map, &color ); - if ( st == None ) { - fprintf ( stderr, "Failed to parse color: '%s'\n", cname ); - st = XAllocNamedColor ( display, map, defn, &color, &def ); - if ( st == None ) { - fprintf ( stderr, "Failed to allocate fallback color\n" ); - exit ( EXIT_FAILURE ); - } - } - } } - else { - Status st = XAllocNamedColor ( display, map, cname, &color, &def ); - if ( st == None ) { - fprintf ( stderr, "Failed to parse color: '%s'\n", cname ); - st = XAllocNamedColor ( display, map, defn, &color, &def ); - if ( st == None ) { - fprintf ( stderr, "Failed to allocate fallback color\n" ); - exit ( EXIT_FAILURE ); - } - } + else if ( strncmp ( cname, "#", 1 ) == 0 ) { + color.pixel = strtoul ( &cname[1], NULL, 16 ); + color.a = 0xff; } g_free ( copy ); Color ret = { - .red = color.red / 65535.0, - .green = color.green / 65535.0, - .blue = color.blue / 65535.0, - .alpha = ( ( color.pixel & 0xFF000000 ) >> 24 ) / 255.0, + .red = color.r / 255.0, + .green = color.g / 255.0, + .blue = color.b / 255.0, + .alpha = color.a / 255.0, }; return ret; } @@ -619,16 +633,16 @@ void color_cache_reset ( void ) color_cache[BORDER].set = FALSE; color_cache[SEPARATOR].set = FALSE; } -void color_background ( Display *display, cairo_t *d ) +void color_background ( cairo_t *d ) { if ( !color_cache[BACKGROUND].set ) { if ( !config.color_enabled ) { - color_cache[BACKGROUND].color = color_get ( display, config.menu_bg, "black" ); + color_cache[BACKGROUND].color = color_get ( config.menu_bg ); } else { gchar **vals = g_strsplit ( config.color_window, ",", 3 ); if ( vals != NULL && vals[0] != NULL ) { - color_cache[BACKGROUND].color = color_get ( display, vals[0], "black" ); + color_cache[BACKGROUND].color = color_get ( vals[0] ); } g_strfreev ( vals ); } @@ -638,16 +652,16 @@ void color_background ( Display *display, cairo_t *d ) x11_helper_set_cairo_rgba ( d, color_cache[BACKGROUND].color ); } -void color_border ( Display *display, cairo_t *d ) +void color_border ( cairo_t *d ) { if ( !color_cache[BORDER].set ) { if ( !config.color_enabled ) { - color_cache[BORDER].color = color_get ( display, config.menu_bc, "white" ); + color_cache[BORDER].color = color_get ( config.menu_bc ); } else { gchar **vals = g_strsplit ( config.color_window, ",", 3 ); if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) { - color_cache[BORDER].color = color_get ( display, vals[1], "white" ); + color_cache[BORDER].color = color_get ( vals[1] ); } g_strfreev ( vals ); } @@ -656,19 +670,19 @@ void color_border ( Display *display, cairo_t *d ) x11_helper_set_cairo_rgba ( d, color_cache[BORDER].color ); } -void color_separator ( Display *display, cairo_t *d ) +void color_separator ( cairo_t *d ) { if ( !color_cache[SEPARATOR].set ) { if ( !config.color_enabled ) { - color_cache[SEPARATOR].color = color_get ( display, config.menu_bc, "white" ); + color_cache[SEPARATOR].color = color_get ( config.menu_bc ); } else { gchar **vals = g_strsplit ( config.color_window, ",", 3 ); if ( vals != NULL && vals[0] != NULL && vals[1] != NULL && vals[2] != NULL ) { - color_cache[SEPARATOR].color = color_get ( display, vals[2], "white" ); + color_cache[SEPARATOR].color = color_get ( vals[2] ); } else if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) { - color_cache[SEPARATOR].color = color_get ( display, vals[1], "white" ); + color_cache[SEPARATOR].color = color_get ( vals[1] ); } g_strfreev ( vals ); } |