Add ARGB visual support.
authordanielb <danielb_86@users.sourceforge.net>
Fri, 1 Jan 2010 23:01:51 +0000 (15:01 -0800)
committerBrenden Matthews <brenden@diddyinc.com>
Fri, 1 Jan 2010 23:01:51 +0000 (15:01 -0800)
This patch adds the possibility to use a argb visual for the conky
window.  Adding a boolean configuration entry 'own_window_argb_visual'.
the 'set_transparent_background' method sets the alpha bytes of the argb
color for transparency, instead of pseudo transparency.  This patch
would close following feature request:
https://sourceforge.net/tracker/?func=detail&aid=1563931&group_id=143975&at
id=757311 and would be a workaround for some reported transparency bugs
(https://sourceforge.net/tracker/?func=detail&aid=1968923&group_id=143975&a
tid=757308 for example)

Signed-off-by: Brenden Matthews <brenden@diddyinc.com>

AUTHORS
configure.ac.in
doc/config_settings.xml
src/conky.c
src/fonts.c
src/x11.c
src/x11.h

diff --git a/AUTHORS b/AUTHORS
index 98917f9..8ff5463 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -346,3 +346,6 @@ zimba-tm <zimba-tm at users dot sourceforge dot net>
 
 zotrix <zotrix at users dot sourceforge dot net>
   FreeBSD patch for <10 procs
+
+Daniel Beßler <daniel@orgizm.net>
+  argb visual patch
index b3c84db..93243d2 100644 (file)
@@ -423,6 +423,17 @@ if test "x$want_x11" = "xyes"; then
 fi
 
 dnl
+dnl ARGB
+dnl
+
+AC_ARG_ENABLE([argb],
+              AC_HELP_STRING([--enable-argb], [enable if you want a argb visual [[default=no]]]),
+              [want_argb="$enableval"], [want_argb=no])
+if test x$want_argb = xyes; then
+       AC_DEFINE(USE_ARGB, 1, [Define if you want argb visual support])
+fi
+
+dnl
 dnl IMLIB2
 dnl
 
@@ -965,6 +976,7 @@ $PACKAGE $VERSION configured successfully:
   XDamage support:  $want_xdamage
   XDBE support:     $want_double_buffer
   Xft support:      $want_xft
+  ARGB support      $want_argb
 
  * Music detection:
   Audacious:        $want_audacious
index c9be564..70d67d6 100644 (file)
     <varlistentry>
         <term>
             <command>
+                <option>own_window_argb</option>
+            </command>
+        </term>
+        <listitem>Boolean, use ARGB visual? ARGB can be used for real transparency,
+       note that a composite manager is required for real transparency.
+        <para /></listitem>
+    </varlistentry>
+    <varlistentry>
+        <term>
+            <command>
                 <option>own_window_transparent</option>
             </command>
         </term>
-        <listitem>Boolean, set pseudo-transparency? 
+        <listitem>Boolean, set transparency? If argb visual is configured
+       true transparency is used, else pseudo transparency is used.
         <para /></listitem>
     </varlistentry>
     <varlistentry>
index bd592f3..e744897 100644 (file)
@@ -203,6 +203,9 @@ static void print_version(void)
 # ifdef XFT
                   "  * Xft\n"
 # endif /* XFT */
+# ifdef USE_ARGB
+                  "  * ARGB visual\n"
+# endif /* USE_ARGB */
 #endif /* X11 */
                   "\n Music detection:\n"
 #ifdef AUDACIOUS
@@ -2692,8 +2695,16 @@ static inline void set_foreground_color(long c)
 {
 #ifdef X11
        if (output_methods & TO_X) {
-               current_color = c;
-               XSetForeground(display, window.gc, c);
+#ifdef USE_ARGB
+               if (have_argb_visual) {
+                       current_color = c | (0xff << 24);
+               } else {
+#endif /* USE_ARGB */
+                       current_color = c;
+#ifdef USE_ARGB
+               }
+#endif /* USE_ARGB */
+               XSetForeground(display, window.gc, current_color);
        }
 #endif /* X11 */
 #ifdef NCURSES
@@ -2794,7 +2805,8 @@ static void draw_string(const char *s)
                        XftColor c2;
 
                        c.pixel = current_color;
-                       XQueryColor(display, DefaultColormap(display, screen), &c);
+                       // query color on custom colormap
+                       XQueryColor(display, window.colourmap, &c);
 
                        c2.pixel = c.pixel;
                        c2.color.red = c.red;
@@ -3655,7 +3667,7 @@ static void main_loop(void)
 
 #ifdef OWN_WINDOW
                                        case ReparentNotify:
-                                               /* set background to ParentRelative for all parents */
+                                               /* make background transparent */
                                                if (own_window) {
                                                        set_transparent_background(window.window);
                                                }
@@ -4234,6 +4246,9 @@ static void set_default_configurations(void)
        window.hints = 0;
        strcpy(window.class_name, PACKAGE_NAME);
        sprintf(window.title, PACKAGE_NAME" (%s)", info.uname_s.nodename);
+#ifdef USE_ARGB
+       use_argb_visual = 0;
+#endif
 #endif
        stippled_borders = 0;
        window.border_inner_margin = 3;
@@ -5006,6 +5021,11 @@ char load_config_file(const char *f)
                                CONF_ERR;
                        }
                }
+#ifdef USE_ARGB
+               CONF("own_window_argb_visual") {
+                       use_argb_visual = string_to_bool(value);
+               }
+#endif /* USE_ARGB */
 #endif
                CONF("stippled_borders") {
                        if (value) {
index b110d10..4215b15 100644 (file)
@@ -58,7 +58,7 @@ void setup_fonts(void)
                        window.xftdraw = 0;
                }
                window.xftdraw = XftDrawCreate(display, window.drawable,
-                               DefaultVisual(display, screen), DefaultColormap(display, screen));
+                               window.visual, window.colourmap);
        }
 #endif /* XFT */
        set_font();
index 36cc4e8..c81c2b4 100644 (file)
--- a/src/x11.c
+++ b/src/x11.c
@@ -51,6 +51,11 @@ int use_xft = 0;
 int use_xdbe;
 #endif
 
+#ifdef USE_ARGB
+int use_argb_visual;
+int have_argb_visual;
+#endif /* USE_ARGB */
+
 /* some basic X11 stuff */
 Display *display = NULL;
 int display_width;
@@ -171,11 +176,26 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop)
        return win;
 }
 
-/* sets background to ParentRelative for the Window and all parents */
+/* if no argb visual is configured sets background to ParentRelative for the Window and all parents,
+   else real transparency is used */
 void set_transparent_background(Window win)
 {
        static int colour_set = -1;
 
+#ifdef USE_ARGB
+       if (have_argb_visual) {
+               // real transparency
+               if (set_transparent) {
+                       XSetWindowBackground(display, win, 0x00);
+               } else if (colour_set != background_colour) {
+                       XSetWindowBackground(display, win,
+                               background_colour | (0xff << 24));
+                       colour_set = background_colour;
+               }
+       } else {
+#endif /* USE_ARGB */
+       // pseudo transparency
+       
        if (set_transparent) {
                Window parent = win;
                unsigned int i;
@@ -193,7 +213,35 @@ void set_transparent_background(Window win)
                XSetWindowBackground(display, win, background_colour);
                colour_set = background_colour;
        }
+#ifdef USE_ARGB
+       }
+#endif /* USE_ARGB */
+}
+
+#ifdef USE_ARGB
+static int get_argb_visual(Visual** visual, int *depth) {
+       /* code from gtk project, gdk_screen_get_rgba_visual */
+       XVisualInfo visual_template;
+       XVisualInfo *visual_list;
+       int nxvisuals = 0, i;
+       
+       visual_template.screen = screen;
+       visual_list = XGetVisualInfo (display, VisualScreenMask,
+                               &visual_template, &nxvisuals);
+       for (i = 0; i < nxvisuals; i++) {
+               if (visual_list[i].depth == 32 &&
+                        (visual_list[i].red_mask   == 0xff0000 &&
+                         visual_list[i].green_mask == 0x00ff00 &&
+                         visual_list[i].blue_mask  == 0x0000ff)) {
+                       *visual = visual_list[i].visual;
+                       *depth = visual_list[i].depth;
+                       return 1;
+               }
+       }
+       // no argb visual available
+       return 0;
 }
+#endif /* USE_ARGB */
 
 void destroy_window(void)
 {
@@ -220,9 +268,28 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
 
 #ifdef OWN_WINDOW
        if (own_window) {
+               int depth = 0, flags;
+               Visual *visual = NULL;
+               
                if (!find_desktop_window(&window.root, &window.desktop)) {
                        return;
                }
+               
+#ifdef USE_ARGB
+               if (use_argb_visual && get_argb_visual(&visual, &depth)) {
+                       have_argb_visual = 1;
+                       window.visual = visual;
+                       window.colourmap = XCreateColormap(display,
+                               DefaultRootWindow(display), window.visual, AllocNone);
+               } else {
+#endif /* USE_ARGB */
+                       window.visual = DefaultVisual(display, screen);
+                       window.colourmap = DefaultColormap(display, screen);
+                       depth = CopyFromParent;
+                       visual = CopyFromParent;
+#ifdef USE_ARGB
+               }
+#endif /* USE_ARGB */
 
                if (window.type == TYPE_OVERRIDE) {
 
@@ -231,11 +298,21 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
                        XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
                                Always, 0L, 0L, False, StructureNotifyMask | ExposureMask, 0L,
                                True, 0, 0 };
+#ifdef USE_ARGB
+                       if (have_argb_visual) {
+                               attrs.colormap = window.colourmap;
+                               flags = CWBorderPixel | CWColormap | CWOverrideRedirect;
+                       } else {
+#endif /* USE_ARGB */
+                               flags = CWBackPixel | CWOverrideRedirect;
+#ifdef USE_ARGB
+                       }
+#endif /* USE_ARGB */
 
                        /* Parent is desktop window (which might be a child of root) */
                        window.window = XCreateWindow(display, window.desktop, window.x,
-                                       window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent,
-                                       CWBackPixel | CWOverrideRedirect, &attrs);
+                                       window.y, w, h, 0, depth, InputOutput, visual,
+                                       flags, &attrs);
 
                        XLowerWindow(display, window.window);
 
@@ -252,14 +329,25 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
                        XClassHint classHint;
                        XWMHints wmHint;
                        Atom xa;
+                       
+#ifdef USE_ARGB
+                       if (have_argb_visual) {
+                               attrs.colormap = window.colourmap;
+                               flags = CWBorderPixel | CWColormap | CWOverrideRedirect;
+                       } else {
+#endif /* USE_ARGB */
+                               flags = CWBackPixel | CWOverrideRedirect;
+#ifdef USE_ARGB
+                       }
+#endif /* USE_ARGB */
 
                        if (window.type == TYPE_DOCK) {
                                window.x = window.y = 0;
                        }
                        /* Parent is root window so WM can take control */
                        window.window = XCreateWindow(display, window.root, window.x,
-                                       window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent,
-                                       CWBackPixel | CWOverrideRedirect, &attrs);
+                                       window.y, w, h, 0, depth, InputOutput, visual,
+                                       flags, &attrs);
 
                        classHint.res_name = window.class_name;
                        classHint.res_class = classHint.res_name;
@@ -472,8 +560,6 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
                fprintf(stderr, PACKAGE_NAME": drawing to single buffer\n");
        }
 #endif
-       window.visual = DefaultVisual(display, DefaultScreen(display));
-       window.colourmap = DefaultColormap(display, DefaultScreen(display));
 #ifdef IMLIB2
        {
                cimlib_init(display, window.drawable, window.visual, window.colourmap);
index a4b2a2a..0ceaabb 100644 (file)
--- a/src/x11.h
+++ b/src/x11.h
@@ -75,6 +75,13 @@ extern int use_xdbe;
 extern int use_xft;
 #endif
 
+#if defined(USE_ARGB) && defined(OWN_WINDOW)
+/* 1 if config var set to 1, otherwise 0 */
+extern int use_argb_visual;
+/* 1 if use_argb_visual=1 and argb visual was found, otherwise 0 */
+extern int have_argb_visual;
+#endif
+
 extern Display *display;
 extern int display_width;
 extern int display_height;