From 9cc63d494824dda325a3d8539a94d9d149d81757 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Wed, 21 Jan 2015 10:04:15 +0100 Subject: [PATCH] Updates fixing pango transparancy. --- include/textbox.h | 16 ++++++----- source/rofi.c | 65 ++++++++++++++++++++++++++------------------- source/textbox.c | 65 +++++++++++++++++++++++++-------------------- test/textbox-test.c | 36 ++++++++++++++++--------- 4 files changed, 107 insertions(+), 75 deletions(-) diff --git a/include/textbox.h b/include/textbox.h index 5f7d1bc5..457e629e 100644 --- a/include/textbox.h +++ b/include/textbox.h @@ -42,6 +42,8 @@ typedef enum } TextBoxFontType; textbox* textbox_create ( Window parent, + XVisualInfo *vinfo, + Colormap map, TextboxFlags flags, short x, short y, short w, short h, TextBoxFontType tbft, @@ -81,7 +83,7 @@ void textbox_show ( textbox *tb ); * * Render the textbox. */ -void textbox_draw ( textbox *tb ); +void textbox_draw ( textbox * tb ); /** * @param tb Handle to the textbox @@ -134,6 +136,8 @@ void textbox_insert ( textbox *tb, int pos, char *str ); void textbox_hide ( textbox *tb ); /** + * @param visual Information about the visual to target + * @param colormap The colormap to set the colors for. * @param bg The background color. * @param bg_alt The background color for alternating row. * @param fg The foreground color. @@ -144,15 +148,15 @@ void textbox_hide ( textbox *tb ); * before any of the textbox_ functions is called. * Clean with textbox_cleanup() */ -void textbox_setup ( - const char *bg, const char *bg_alt, const char *fg, - const char *hlbg, const char *hlfg - ); +void textbox_setup ( XVisualInfo *visual, Colormap colormap, + const char *bg, const char *bg_alt, const char *fg, + const char *hlbg, const char *hlfg + ); /** * Cleanup the allocated colors and fonts by textbox_setup(). */ -void textbox_cleanup (); +void textbox_cleanup ( ); /** * @param tb Handle to the textbox diff --git a/source/rofi.c b/source/rofi.c index c6793b41..e8144909 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -713,12 +713,12 @@ static void menu_set_arrow_text ( int filtered_lines, int selected, int max_elem if ( page != 0 && npages > 1 ) { textbox_show ( arrowbox_top ); textbox_font ( arrowbox_top, ( entry != 0 ) ? NORMAL : HIGHLIGHT ); - textbox_draw ( arrowbox_top ); + textbox_draw ( arrowbox_top ); } if ( ( npages - 1 ) != page && npages > 1 ) { textbox_show ( arrowbox_bottom ); textbox_font ( arrowbox_bottom, ( entry != ( max_elements - 1 ) ) ? NORMAL : HIGHLIGHT ); - textbox_draw ( arrowbox_bottom ); + textbox_draw ( arrowbox_bottom ); } } @@ -1525,7 +1525,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom // we need this at this point so we can get height. - state.case_indicator = textbox_create ( main_window, TB_AUTOHEIGHT | TB_AUTOWIDTH, + state.case_indicator = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT | TB_AUTOWIDTH, ( config.padding ), ( config.padding ), 0, 0, NORMAL, "*" ); @@ -1545,7 +1545,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom menu_calculate_window_and_element_width ( &state, &mon ); // Prompt box. - state.prompt_tb = textbox_create ( main_window, TB_AUTOHEIGHT | TB_AUTOWIDTH, + state.prompt_tb = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT | TB_AUTOWIDTH, ( config.padding ), ( config.padding ), 0, 0, NORMAL, prompt ); @@ -1555,7 +1555,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom - textbox_get_width ( state.prompt_tb ) - textbox_get_width ( state.case_indicator ); - state.text = textbox_create ( main_window, TB_AUTOHEIGHT | TB_EDITABLE, + state.text = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT | TB_EDITABLE, ( config.padding ) + textbox_get_width ( state.prompt_tb ), ( config.padding ), entrybox_width, 0, @@ -1590,20 +1590,20 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom int ex = col * ( state.element_width + LINE_MARGIN ); int ey = line * element_height + ( ( config.hmode == TRUE ) ? 0 : LINE_MARGIN ); - state.boxes[i] = textbox_create ( main_window, 0, + state.boxes[i] = textbox_create ( main_window, &vinfo, map, 0, ex + x_offset, ey + y_offset, state.element_width, element_height, NORMAL, "" ); textbox_show ( state.boxes[i] ); } // Arrows - state.arrowbox_top = textbox_create ( main_window, TB_AUTOHEIGHT | TB_AUTOWIDTH, + state.arrowbox_top = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT | TB_AUTOWIDTH, ( config.padding ), ( config.padding ), 0, 0, NORMAL, ( config.hmode == FALSE ) ? "↑" : "←" ); - state.arrowbox_bottom = textbox_create ( main_window, TB_AUTOHEIGHT | TB_AUTOWIDTH, + state.arrowbox_bottom = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT | TB_AUTOWIDTH, ( config.padding ), ( config.padding ), 0, 0, @@ -1657,7 +1657,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom int line_height = textbox_get_height ( state.text ); int width = ( state.w - ( 2 * ( config.padding ) ) ) / num_switchers; for ( int j = 0; j < num_switchers; j++ ) { - switchers[j].tb = textbox_create ( main_window, TB_CENTER, + switchers[j].tb = textbox_create ( main_window, &vinfo, map, TB_CENTER, config.padding + j * width, state.h - line_height - config.padding, width, line_height, ( j == curr_switcher ) ? HIGHLIGHT : NORMAL, switchers[j].name ); textbox_show ( switchers[j].tb ); @@ -1899,7 +1899,7 @@ void error_dialog ( char *msg ) menu_calculate_window_and_element_width ( &state, &mon ); state.max_elements = 0; - state.text = textbox_create ( main_window, TB_AUTOHEIGHT, + state.text = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT, ( config.padding ), ( config.padding ), ( state.w - ( 2 * ( config.padding ) ) ), @@ -2106,13 +2106,14 @@ SwitcherMode run_switcher_window ( char **input, G_GNUC_UNUSED void *data ) */ static int run_dmenu () { + // Request truecolor visual. XMatchVisualInfo ( display, DefaultScreen ( display ), 32, TrueColor, &vinfo ); map = XCreateColormap ( display, DefaultRootWindow ( display ), vinfo.visual, AllocNone ); int ret_state; - textbox_setup ( - config.menu_bg, config.menu_bg_alt, config.menu_fg, - config.menu_hlbg, - config.menu_hlfg ); + textbox_setup ( &vinfo, map, + config.menu_bg, config.menu_bg_alt, config.menu_fg, + config.menu_hlbg, + config.menu_hlfg ); char *input = NULL; // Dmenu modi has a return state. @@ -2121,7 +2122,11 @@ static int run_dmenu () g_free ( input ); // Cleanup font setup. - textbox_cleanup (); + textbox_cleanup ( ); + + if ( map != None ) { + XFreeColormap ( display, map ); + } return ret_state; } @@ -2146,10 +2151,10 @@ static void run_switcher ( int do_fork, SwitcherMode mode ) // Because of the above fork, we want to do this here. // Make sure this is isolated to its own thread. - textbox_setup ( - config.menu_bg, config.menu_bg_alt, config.menu_fg, - config.menu_hlbg, - config.menu_hlfg ); + textbox_setup ( &vinfo, map, + config.menu_bg, config.menu_bg_alt, config.menu_fg, + config.menu_hlbg, + config.menu_hlfg ); char *input = NULL; // Otherwise check if requested mode is enabled. if ( switchers[mode].cb != NULL ) { @@ -2182,7 +2187,10 @@ static void run_switcher ( int do_fork, SwitcherMode mode ) g_free ( input ); // Cleanup font setup. - textbox_cleanup (); + textbox_cleanup ( ); + if ( map != None ) { + XFreeColormap ( display, map ); + } if ( do_fork == TRUE ) { exit ( EXIT_SUCCESS ); @@ -2428,9 +2436,6 @@ static void cleanup () { // Cleanup if ( display != NULL ) { - if ( map != None ) { - XFreeColormap ( display, map ); - } if ( main_window != None ) { XFreeGC ( display, gc ); XDestroyWindow ( display, main_window ); @@ -2671,14 +2676,18 @@ int main ( int argc, char *argv[] ) char *msg = NULL; if ( find_arg_str ( argc, argv, "-e", &( msg ) ) ) { + // Request truecolor visual. XMatchVisualInfo ( display, DefaultScreen ( display ), 32, TrueColor, &vinfo ); map = XCreateColormap ( display, DefaultRootWindow ( display ), vinfo.visual, AllocNone ); - textbox_setup ( - config.menu_bg, config.menu_bg_alt, config.menu_fg, - config.menu_hlbg, - config.menu_hlfg ); + textbox_setup ( &vinfo, map, + config.menu_bg, config.menu_bg_alt, config.menu_fg, + config.menu_hlbg, + config.menu_hlfg ); error_dialog ( msg ); - textbox_cleanup (); + textbox_cleanup ( ); + if ( map != None ) { + XFreeColormap ( display, map ); + } exit ( EXIT_SUCCESS ); } diff --git a/source/textbox.c b/source/textbox.c index 828d50eb..b13cf6d6 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -43,9 +43,7 @@ #include #define SIDE_MARGIN 2 -extern Colormap map; -extern XVisualInfo vinfo; -extern Display *display; +extern Display *display; /** * Font + font color cache. @@ -56,6 +54,8 @@ XftColor color_bg; XftColor color_hlfg; XftColor color_hlbg; XftColor color_bg_alt; +XVisualInfo *visual_info; +Colormap target_colormap; PangoContext *p_context = NULL; @@ -64,6 +64,8 @@ void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ); // Xft text box, optionally editable textbox* textbox_create ( Window parent, + XVisualInfo *vinfo, + Colormap map, TextboxFlags flags, short x, short y, short w, short h, TextBoxFontType tbft, @@ -99,7 +101,12 @@ textbox* textbox_create ( Window parent, break; } - tb->window = XCreateSimpleWindow ( display, tb->parent, tb->x, tb->y, tb->w, tb->h, 0, None, cp ); + XSetWindowAttributes attr; + attr.colormap = map; + attr.border_pixel = cp; + attr.background_pixel = cp; + tb->window = XCreateWindow ( display, tb->parent, tb->x, tb->y, tb->w, tb->h, 0, vinfo->depth, + InputOutput, vinfo->visual, CWColormap | CWBorderPixel | CWBackPixel, &attr ); // need to preload the font to calc line height textbox_font ( tb, tbft ); @@ -237,8 +244,8 @@ void textbox_free ( textbox *tb ) void textbox_draw ( textbox *tb ) { GC context = XCreateGC ( display, tb->window, 0, 0 ); - Pixmap canvas = XCreatePixmap ( display, tb->window, tb->w, tb->h, vinfo.depth ); - XftDraw *draw = XftDrawCreate ( display, canvas, vinfo.visual, map ); + Pixmap canvas = XCreatePixmap ( display, tb->window, tb->w, tb->h, visual_info->depth ); + XftDraw *draw = XftDrawCreate ( display, canvas, visual_info->visual, target_colormap ); // clear canvas XftDrawRect ( draw, &tb->color_bg, 0, 0, tb->w, tb->h ); @@ -449,10 +456,9 @@ int textbox_keypress ( textbox *tb, XEvent *ev ) /*** * Font setup. */ -static void parse_color ( const char *bg, XftColor *color ) +static void parse_color ( Visual *visual, Colormap colormap, + const char *bg, XftColor *color ) { - Visual *visual = vinfo.visual; - Colormap colormap = map; if ( strncmp ( bg, "argb:", 5 ) == 0 ) { XRenderColor col; unsigned int val = strtoul ( &bg[5], NULL, 16 ); @@ -467,36 +473,37 @@ static void parse_color ( const char *bg, XftColor *color ) } } -void textbox_setup ( - const char *bg, const char *bg_alt, const char *fg, - const char *hlbg, const char *hlfg - ) +void textbox_setup ( XVisualInfo *visual, Colormap colormap, + const char *bg, const char *bg_alt, const char *fg, + const char *hlbg, const char *hlfg + ) { - parse_color ( bg, &color_bg ); - parse_color ( fg, &color_fg ); - parse_color ( bg_alt, &color_bg_alt ); - parse_color ( hlfg, &color_hlfg ); - parse_color ( hlbg, &color_hlbg ); + visual_info = visual; + target_colormap = colormap; + + parse_color ( visual_info->visual, target_colormap, bg, &color_bg ); + parse_color ( visual_info->visual, target_colormap, fg, &color_fg ); + parse_color ( visual_info->visual, target_colormap, bg_alt, &color_bg_alt ); + parse_color ( visual_info->visual, target_colormap, hlfg, &color_hlfg ); + parse_color ( visual_info->visual, target_colormap, hlbg, &color_hlbg ); PangoFontMap *font_map = pango_xft_get_font_map ( display, DefaultScreen ( display ) ); p_context = pango_font_map_create_context ( font_map ); } -void textbox_cleanup () +void textbox_cleanup ( ) { if ( p_context ) { - Visual *visual = vinfo.visual; - Colormap colormap = map; - - - XftColorFree ( display, visual, colormap, &color_fg ); - XftColorFree ( display, visual, colormap, &color_bg ); - XftColorFree ( display, visual, colormap, &color_bg_alt ); - XftColorFree ( display, visual, colormap, &color_hlfg ); - XftColorFree ( display, visual, colormap, &color_hlbg ); + XftColorFree ( display, visual_info->visual, target_colormap, &color_fg ); + XftColorFree ( display, visual_info->visual, target_colormap, &color_bg ); + XftColorFree ( display, visual_info->visual, target_colormap, &color_bg_alt ); + XftColorFree ( display, visual_info->visual, target_colormap, &color_hlfg ); + XftColorFree ( display, visual_info->visual, target_colormap, &color_hlbg ); g_object_unref ( p_context ); - p_context = NULL; + p_context = NULL; + visual_info = NULL; + target_colormap = None; } } diff --git a/test/textbox-test.c b/test/textbox-test.c index e230bf9c..c6b7d802 100644 --- a/test/textbox-test.c +++ b/test/textbox-test.c @@ -21,13 +21,20 @@ static int test = 0; } Display *display = NULL; +Colormap map = None; +XVisualInfo vinfo; static unsigned int color_get ( Display *display, const char *const name ) { - int screen_id = DefaultScreen ( display ); - XColor color; - Colormap map = DefaultColormap ( display, screen_id ); - return XAllocNamedColor ( display, map, name, &color, &color ) ? color.pixel : None; + int screen_id = DefaultScreen ( display ); + XColor color; + // Special format. + if ( strncmp ( name, "argb:", 5 ) == 0 ) { + return strtoul ( &name[5], NULL, 16 ); + } + else { + return XAllocNamedColor ( display, map, name, &color, &color ) ? color.pixel : None; + } } int main ( int argc, char **argv ) @@ -39,20 +46,25 @@ int main ( int argc, char **argv ) fprintf ( stderr, "cannot open display!\n" ); return EXIT_FAILURE; } + XMatchVisualInfo ( display, DefaultScreen ( display ), 32, TrueColor, &vinfo ); + map = XCreateColormap ( display, DefaultRootWindow ( display ), vinfo.visual, AllocNone ); TASSERT( display != NULL ); Screen *screen = DefaultScreenOfDisplay ( display ); Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) ); - Window mw = XCreateSimpleWindow ( display, root, 0, 0, 200, 100, - config.menu_bw, - color_get ( display, config.menu_bc ), - color_get ( display, config.menu_bg ) ); + XSetWindowAttributes attr; + attr.colormap = map; + attr.border_pixel = color_get ( display, config.menu_bc ); + attr.background_pixel = color_get ( display, config.menu_bg ); + Window mw = XCreateWindow ( display, DefaultRootWindow ( display ), + 0, 0, 200, 100, config.menu_bw, vinfo.depth, InputOutput, + vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr ); TASSERT( mw != None ); // Set alternate row to normal row. config.menu_bg_alt = config.menu_bg; - textbox_setup ( config.menu_bg, config.menu_bg_alt, config.menu_fg, + textbox_setup ( &vinfo, map, config.menu_bg, config.menu_bg_alt, config.menu_fg, config.menu_hlbg, config.menu_hlfg ); - textbox *box = textbox_create(mw , TB_EDITABLE|TB_AUTOWIDTH|TB_AUTOHEIGHT, 0,0, -1, -1, NORMAL, "test"); + textbox *box = textbox_create(mw , &vinfo, map, TB_EDITABLE|TB_AUTOWIDTH|TB_AUTOHEIGHT, 0,0, -1, -1, NORMAL, "test"); TASSERT( box != NULL ); textbox_cursor_end ( box ); @@ -122,7 +134,7 @@ int main ( int argc, char **argv ) textbox_font ( box, HIGHLIGHT ); - textbox_draw( box ); + textbox_draw( box); textbox_show( box ); textbox_move ( box, 12, 13); @@ -131,7 +143,7 @@ int main ( int argc, char **argv ) textbox_hide( box ); textbox_free(box); - textbox_cleanup(); + textbox_cleanup( ); XDestroyWindow ( display, mw); XCloseDisplay ( display ); }