changeset 906:16e51fb5908e trunk

[svn] - aosd: beta4, ghosd source was rewritten to support argb visual (x composite extension) as an option, this allows to have real transparency in the OSD
author giacomo
date Sat, 31 Mar 2007 17:44:23 -0700
parents 987eebc33408
children f20ca9b8cd7d
files ChangeLog src/aosd/aosd.c src/aosd/aosd_cfg.c src/aosd/aosd_cfg.h src/aosd/aosd_common.h src/aosd/aosd_osd.c src/aosd/aosd_osd.h src/aosd/aosd_ui.c src/aosd/ghosd-internal.h src/aosd/ghosd-main.c src/aosd/ghosd.c src/aosd/ghosd.h
diffstat 12 files changed, 269 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Mar 31 06:40:00 2007 -0700
+++ b/ChangeLog	Sat Mar 31 17:44:23 2007 -0700
@@ -1,3 +1,11 @@
+2007-03-31 13:40:00 +0000  William Pitcock <nenolod@sacredspiral.co.uk>
+  revision [1910]
+  - for security reasons, do not try all of the players (only check extension)
+  
+  trunk/src/adplug/core/adplug.cxx |    2 ++
+  1 file changed, 2 insertions(+)
+
+
 2007-03-30 13:37:26 +0000  Michael Farber <01mf02@gmail.com>
   revision [1908]
   - Added option to save output files to original file directory
--- a/src/aosd/aosd.c	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/aosd.c	Sat Mar 31 17:44:23 2007 -0700
@@ -48,7 +48,7 @@
   global_config = aosd_cfg_new();
   aosd_cfg_load( global_config );
 
-  aosd_osd_init();
+  aosd_osd_init( global_config->osd->misc.transparency_mode );
 
   aosd_trigger_start( &global_config->osd->trigger );
 
--- a/src/aosd/aosd_cfg.c	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/aosd_cfg.c	Sat Mar 31 17:44:23 2007 -0700
@@ -160,6 +160,7 @@
     gint trigger_id = g_array_index( cfg_osd->trigger.active , gint , i );
     g_array_insert_val( cfg_osd_copy->trigger.active , i , trigger_id );
   }
+  cfg_osd_copy->misc.transparency_mode = cfg_osd->misc.transparency_mode;
   return cfg_osd_copy;
 }
 
@@ -351,6 +352,11 @@
     g_strfreev( trig_active_strv );
   }
 
+  /* miscellanous */
+  if ( !bmp_cfg_db_get_int( cfgfile , "aosd" ,
+       "transparency_mode" , &(cfg->osd->misc.transparency_mode) ) )
+    cfg->osd->misc.transparency_mode = AOSD_MISC_TRANSPARENCY_FAKE;
+
   bmp_cfg_db_close( cfgfile );
 
   /* the config object has been filled with information */
@@ -460,6 +466,10 @@
   bmp_cfg_db_set_string( cfgfile , "aosd" , "trigger_active" , string->str );
   g_string_free( string , TRUE );
 
+  /* miscellaneous */
+  bmp_cfg_db_set_int( cfgfile , "aosd" ,
+    "transparency_mode" , cfg->osd->misc.transparency_mode );
+
   bmp_cfg_db_close( cfgfile );
 
   return 0;
--- a/src/aosd/aosd_cfg.h	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/aosd_cfg.h	Sat Mar 31 17:44:23 2007 -0700
@@ -27,6 +27,11 @@
 /* in this release only one user font is supported */
 #define AOSD_TEXT_FONTS_NUM 1
 
+/* transparency mode values */
+#define AOSD_MISC_TRANSPARENCY_FAKE 0
+#define AOSD_MISC_TRANSPARENCY_REAL 1
+
+
 enum
 {
   AOSD_POSITION_PLACEMENT_TOPLEFT = 1,
@@ -103,6 +108,14 @@
 aosd_cfg_osd_trigger_t;
 
 
+/* config portion containing osd miscellaneous information */
+typedef struct
+{
+  gint transparency_mode;
+}
+aosd_cfg_osd_misc_t;
+
+
 /* config portion containing all information */
 typedef struct
 {
@@ -111,6 +124,7 @@
   aosd_cfg_osd_text_t text;
   aosd_cfg_osd_decoration_t decoration;
   aosd_cfg_osd_trigger_t trigger;
+  aosd_cfg_osd_misc_t misc;
 }
 aosd_cfg_osd_t;
 
--- a/src/aosd/aosd_common.h	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/aosd_common.h	Sat Mar 31 17:44:23 2007 -0700
@@ -30,6 +30,6 @@
 
 #include "../../config.h"
 
-#define AOSD_VERSION_PLUGIN "0.1beta3"
+#define AOSD_VERSION_PLUGIN "0.1beta4"
 
 #endif /* !_I_AOSD_COMMON_H */
--- a/src/aosd/aosd_osd.c	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/aosd_osd.c	Sat Mar 31 17:44:23 2007 -0700
@@ -409,7 +409,7 @@
 void
 aosd_osd_shutdown ( void )
 {
-  if ( osd_status != AOSD_STATUS_HIDDEN ) /* osd is being displayed */
+  if (( osd != NULL ) && ( osd_status != AOSD_STATUS_HIDDEN )) /* osd is being displayed */
   {
     g_source_remove( osd_source_id ); /* remove timer */
     osd_source_id = 0;
@@ -422,12 +422,15 @@
 
 
 void
-aosd_osd_init ( void )
+aosd_osd_init ( gint transparency_mode )
 {
   if ( osd == NULL )
   {
     /* create Ghosd object */
-    osd = ghosd_new();
+    if ( transparency_mode == AOSD_MISC_TRANSPARENCY_FAKE )
+      osd = ghosd_new();
+    else
+      osd = ghosd_new_with_argbvisual();
   }
   return;
 }
--- a/src/aosd/aosd_osd.h	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/aosd_osd.h	Sat Mar 31 17:44:23 2007 -0700
@@ -28,7 +28,7 @@
 
 gint aosd_osd_display ( gchar * markup_string , aosd_cfg_osd_t * cfg_osd , gboolean copy_cfg );
 void aosd_osd_shutdown ( void );
-void aosd_osd_init ( void ); /* to be called before any OSD usage */
+void aosd_osd_init ( gint transparency_mode ); /* to be called before any OSD usage */
 void aosd_osd_cleanup ( void ); /* to be called when done with OSD usage */
 
 #endif /* !_I_AOSD_OSD_H */
--- a/src/aosd/aosd_ui.c	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/aosd_ui.c	Sat Mar 31 17:44:23 2007 -0700
@@ -784,6 +784,59 @@
 
 
 static void
+aosd_cb_configure_misc_transp_commit ( GtkWidget * mis_transp_vbox , aosd_cfg_t * cfg )
+{
+  GList *child_list = gtk_container_get_children( GTK_CONTAINER(mis_transp_vbox) );
+  while (child_list != NULL)
+  {
+    if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(child_list->data) ) )
+    {
+      cfg->osd->misc.transparency_mode = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(child_list->data),"val"));
+      break;
+    }
+    child_list = g_list_next(child_list);
+  }
+  return;
+}
+
+
+static GtkWidget *
+aosd_ui_configure_misc ( aosd_cfg_t * cfg , GList ** cb_list )
+{
+  GtkWidget *mis_vbox;
+  GtkWidget *mis_transp_frame, *mis_transp_vbox;
+  GtkWidget *mis_transp_fake_rbt, *mis_transp_real_rbt;
+
+  mis_vbox = gtk_vbox_new( FALSE , 0 );
+  gtk_container_set_border_width( GTK_CONTAINER(mis_vbox) , 6 );
+
+  mis_transp_vbox = gtk_vbox_new( FALSE , 0 );
+  mis_transp_frame = gtk_frame_new( _("Transparency") );
+  gtk_container_set_border_width( GTK_CONTAINER(mis_transp_vbox) , 6 );
+  gtk_container_add( GTK_CONTAINER(mis_transp_frame) , mis_transp_vbox );
+  gtk_box_pack_start( GTK_BOX(mis_vbox) , mis_transp_frame , FALSE , FALSE , 0 );
+
+  mis_transp_fake_rbt = gtk_radio_button_new_with_label( NULL ,
+                          _("Fake transparency") );
+  mis_transp_real_rbt = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(mis_transp_fake_rbt) ,
+                          _("Real transparency (requires X Composite Ext.)") );
+  g_object_set_data( G_OBJECT(mis_transp_fake_rbt) , "val" ,
+                     GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_FAKE) );
+  g_object_set_data( G_OBJECT(mis_transp_real_rbt) , "val" ,
+                     GINT_TO_POINTER(AOSD_MISC_TRANSPARENCY_REAL) );
+  if ( cfg->osd->misc.transparency_mode == AOSD_MISC_TRANSPARENCY_FAKE )
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_fake_rbt) , TRUE );
+  else
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mis_transp_real_rbt) , TRUE );
+  gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_fake_rbt , TRUE , TRUE , 0 );
+  gtk_box_pack_start( GTK_BOX(mis_transp_vbox) , mis_transp_real_rbt , TRUE , TRUE , 0 );
+  aosd_callback_list_add( cb_list , mis_transp_vbox , aosd_cb_configure_misc_transp_commit );
+
+  return mis_vbox;
+}
+
+
+static void
 aosd_cb_configure_test ( gpointer cfg_win )
 {
   gchar *markup_message = NULL;
@@ -796,8 +849,9 @@
 #endif
   markup_message = g_markup_printf_escaped(
     "<span font_desc='%s'>Audacious OSD</span>" , cfg->osd->text.fonts_name[0] );
-  if ( plugin_is_active != TRUE )
-    aosd_osd_init();
+  aosd_osd_shutdown(); /* stop any displayed osd */
+  aosd_osd_cleanup(); /* just in case it's active */
+  aosd_osd_init( cfg->osd->misc.transparency_mode );
   aosd_osd_display( markup_message , cfg->osd , TRUE );
   g_free( markup_message );
   aosd_cfg_delete( cfg );
@@ -811,8 +865,9 @@
   GList *cb_list = g_object_get_data( G_OBJECT(cfg_win) , "cblist" );
   aosd_callback_list_free( cb_list );
   aosd_osd_shutdown(); /* stop any displayed osd */
-  if ( plugin_is_active != TRUE )
-    aosd_osd_cleanup();
+  aosd_osd_cleanup(); /* just in case it's active */
+  if ( plugin_is_active == TRUE )
+    aosd_osd_init( global_config->osd->misc.transparency_mode );
   gtk_widget_destroy( GTK_WIDGET(cfg_win) );
   return;
 }
@@ -827,8 +882,7 @@
   aosd_callback_list_run( cb_list , cfg );
   cfg->set = TRUE;
   aosd_osd_shutdown(); /* stop any displayed osd */
-  if ( plugin_is_active != TRUE )
-    aosd_osd_cleanup();
+  aosd_osd_cleanup(); /* just in case it's active */
 
   if ( global_config != NULL )
   {
@@ -837,6 +891,7 @@
     aosd_cfg_delete( global_config ); /* delete old global_config */
     global_config = cfg; /* put the new one */
     aosd_cfg_save( cfg ); /* save the new configuration on config file */
+    aosd_osd_init( cfg->osd->misc.transparency_mode ); /* restart osd */
     aosd_trigger_start( &cfg->osd->trigger ); /* restart triggers */
   }
   else
@@ -932,6 +987,11 @@
   gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
     cfg_trigger_widget , gtk_label_new( _("Trigger") ) );
 
+  /* add MISC page */
+  cfg_trigger_widget = aosd_ui_configure_misc( cfg , &cb_list );
+  gtk_notebook_append_page( GTK_NOTEBOOK(cfg_nb) ,
+    cfg_trigger_widget , gtk_label_new( _("Misc") ) );
+
   g_object_set_data( G_OBJECT(cfg_win) , "cblist" , cb_list );
 
   g_signal_connect_swapped( G_OBJECT(cfg_bbar_bt_test) , "clicked" ,
--- a/src/aosd/ghosd-internal.h	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/ghosd-internal.h	Sat Mar 31 17:44:23 2007 -0700
@@ -3,6 +3,9 @@
  *
  * With further development by Giacomo Lozito <james@develia.org>
  * for the ghosd-based Audacious OSD
+ * - added real transparency with X Composite Extension
+ * - added mouse event handling on OSD window
+ * - added/changed some other stuff
  */
 
 #include <X11/Xlib.h>
@@ -28,7 +31,13 @@
 struct _Ghosd {
   Display *dpy;
   Window win;
+  Window root_win;
+  Visual *visual;
+  Colormap colormap;
+  int screen_num;
+  unsigned int depth;
   int transparent;
+  int composite;
   int x, y, width, height;
 
   GhosdBackground background;
--- a/src/aosd/ghosd-main.c	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/ghosd-main.c	Sat Mar 31 17:44:23 2007 -0700
@@ -3,6 +3,9 @@
  *
  * With further development by Giacomo Lozito <james@develia.org>
  * for the ghosd-based Audacious OSD
+ * - added real transparency with X Composite Extension
+ * - added mouse event handling on OSD window
+ * - added/changed some other stuff
  */
 
 #include "config.h"
--- a/src/aosd/ghosd.c	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/ghosd.c	Sat Mar 31 17:44:23 2007 -0700
@@ -3,6 +3,9 @@
  *
  * With further development by Giacomo Lozito <james@develia.org>
  * for the ghosd-based Audacious OSD
+ * - added real transparency with X Composite Extension
+ * - added mouse event handling on OSD window
+ * - added/changed some other stuff
  */
 
 #include "config.h"
@@ -39,6 +42,39 @@
   return 0;
 }
 
+Visual *
+find_argb_visual (Display *dpy, int scr)
+{
+  XVisualInfo	*xvi;
+  XVisualInfo	template;
+  int nvi, i;
+  XRenderPictFormat *format;
+  Visual *visual;
+
+  template.screen = scr;
+  template.depth = 32;
+  template.class = TrueColor;
+  xvi = XGetVisualInfo (dpy, 
+          VisualScreenMask | VisualDepthMask | VisualClassMask,
+          &template, &nvi);
+  if (xvi == NULL)
+    return NULL;
+
+  visual = NULL;
+  for (i = 0; i < nvi; i++)
+  {
+    format = XRenderFindVisualFormat (dpy, xvi[i].visual);
+    if (format->type == PictTypeDirect && format->direct.alphaMask)
+    {
+      visual = xvi[i].visual;
+      break;
+    }
+  }
+  XFree (xvi);
+  
+  return visual;
+}
+
 static Pixmap
 take_snapshot(Ghosd *ghosd) {
   Pixmap pixmap;
@@ -66,33 +102,48 @@
   Pixmap pixmap;
   GC gc;
 
-  /* make our own copy of the background pixmap as the initial surface. */
-  pixmap = XCreatePixmap(ghosd->dpy, ghosd->win, ghosd->width, ghosd->height,
-                         DefaultDepth(ghosd->dpy, DefaultScreen(ghosd->dpy)));
-
-  gc = XCreateGC(ghosd->dpy, pixmap, 0, NULL);
-  if (ghosd->transparent) {
-    XCopyArea(ghosd->dpy, ghosd->background.pixmap, pixmap, gc,
-              0, 0, ghosd->width, ghosd->height, 0, 0);
-  } else {
+  if (ghosd->composite)
+  {
+    pixmap = XCreatePixmap(ghosd->dpy, ghosd->win, ghosd->width, ghosd->height, 32);
+    gc = XCreateGC(ghosd->dpy, pixmap, 0, NULL);
     XFillRectangle(ghosd->dpy, pixmap, gc,
-                  0, 0, ghosd->width, ghosd->height);
+      0, 0, ghosd->width, ghosd->height);
+  }
+  else
+  {
+    pixmap = XCreatePixmap(ghosd->dpy, ghosd->win, ghosd->width, ghosd->height,
+      DefaultDepth(ghosd->dpy, DefaultScreen(ghosd->dpy)));
+    gc = XCreateGC(ghosd->dpy, pixmap, 0, NULL);
+    if (ghosd->transparent) {
+      /* make our own copy of the background pixmap as the initial surface. */
+      XCopyArea(ghosd->dpy, ghosd->background.pixmap, pixmap, gc,
+        0, 0, ghosd->width, ghosd->height, 0, 0);
+    } else {
+      XFillRectangle(ghosd->dpy, pixmap, gc,
+        0, 0, ghosd->width, ghosd->height);
+    }
   }
   XFreeGC(ghosd->dpy, gc);
 
   /* render with cairo. */
   if (ghosd->render.func) {
     /* create cairo surface using the pixmap. */
-    XRenderPictFormat *xrformat = 
-      XRenderFindVisualFormat(ghosd->dpy,
-                              DefaultVisual(ghosd->dpy,
-                                            DefaultScreen(ghosd->dpy)));
-    cairo_surface_t *surf =
-      cairo_xlib_surface_create_with_xrender_format(
-        ghosd->dpy, pixmap,
-        ScreenOfDisplay(ghosd->dpy, DefaultScreen(ghosd->dpy)),
-        xrformat,
-        ghosd->width, ghosd->height);
+    XRenderPictFormat *xrformat;
+    cairo_surface_t *surf;
+    if (ghosd->composite) {
+      xrformat = XRenderFindVisualFormat(ghosd->dpy, ghosd->visual);
+      surf = cairo_xlib_surface_create_with_xrender_format(
+               ghosd->dpy, pixmap,
+               ScreenOfDisplay(ghosd->dpy, ghosd->screen_num),
+               xrformat, ghosd->width, ghosd->height);
+    } else {
+      xrformat = XRenderFindVisualFormat(ghosd->dpy,
+                   DefaultVisual(ghosd->dpy, DefaultScreen(ghosd->dpy)));
+      surf = cairo_xlib_surface_create_with_xrender_format(
+               ghosd->dpy, pixmap,
+               ScreenOfDisplay(ghosd->dpy, DefaultScreen(ghosd->dpy)),
+               xrformat, ghosd->width, ghosd->height);
+    }
 
     /* draw some stuff. */
     cairo_t *cr = cairo_create(surf);
@@ -166,24 +217,33 @@
 }
 
 static Window
-make_window(Display *dpy) {
+make_window(Display *dpy, Window root_win, Visual *visual, Colormap colormap, Bool use_argbvisual) {
   Window win;
   XSetWindowAttributes att;
 
   att.backing_store = WhenMapped;
-  att.background_pixel = None;
+  att.background_pixel = 0x0;
   att.border_pixel = 0;
   att.background_pixmap = None;
   att.save_under = True;
   att.event_mask = ExposureMask | StructureNotifyMask | ButtonPressMask;
   att.override_redirect = True;
 
-  win = XCreateWindow(dpy, DefaultRootWindow(dpy),
-                      -1, -1, 1, 1, 0,
-                      CopyFromParent, InputOutput, CopyFromParent,
-                      CWBackingStore | CWBackPixel | CWBackPixmap |
+  if ( use_argbvisual )
+  {
+    att.colormap = colormap;
+    win = XCreateWindow(dpy, root_win,
+                      -1, -1, 1, 1, 0, 32, InputOutput, visual,
+                      CWBackingStore | CWBackPixel | CWBackPixmap | CWBorderPixel |
+                      CWColormap | CWEventMask | CWSaveUnder | CWOverrideRedirect,
+                      &att);
+  } else {
+    win = XCreateWindow(dpy, root_win,
+                      -1, -1, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent,
+                      CWBackingStore | CWBackPixel | CWBackPixmap | CWBorderPixel |
                       CWEventMask | CWSaveUnder | CWOverrideRedirect,
                       &att);
+  }
 
   set_hints(dpy, win);
 
@@ -192,7 +252,7 @@
 
 void
 ghosd_show(Ghosd *ghosd) {
-  if (ghosd->transparent) {
+  if ((!ghosd->composite) && (ghosd->transparent)) {
     if (ghosd->background.set)
     {
       XFreePixmap(ghosd->dpy, ghosd->background.pixmap);
@@ -203,7 +263,6 @@
   }
 
   ghosd_render(ghosd);
-
   XMapRaised(ghosd->dpy, ghosd->win);
 }
 
@@ -272,20 +331,72 @@
 ghosd_new(void) {
   Ghosd *ghosd;
   Display *dpy;
-  Window win;
+  Window win, root_win;
+  int screen_num;
+  Visual *visual;
+  Colormap colormap;
+  Bool use_argbvisual = False;
 
   dpy = XOpenDisplay(NULL);
   if (dpy == NULL) {
     fprintf(stderr, "Couldn't open display: (XXX FIXME)\n");
     return NULL;
   }
+  
+  screen_num = DefaultScreen(dpy);
+  root_win = RootWindow(dpy, screen_num);
+  visual = NULL; /* unused */
+  colormap = None; /* unused */
 
-  win = make_window(dpy);
+  win = make_window(dpy, root_win, visual, colormap, use_argbvisual);
   
   ghosd = calloc(1, sizeof(Ghosd));
   ghosd->dpy = dpy;
+  ghosd->visual = visual;
+  ghosd->colormap = colormap;
   ghosd->win = win;
+  ghosd->root_win = root_win;
+  ghosd->screen_num = screen_num;
   ghosd->transparent = 1;
+  ghosd->composite = 0;
+  ghosd->eventbutton.func = NULL;
+  ghosd->background.set = 0;
+
+  return ghosd;
+}
+
+Ghosd *
+ghosd_new_with_argbvisual(void) {
+  Ghosd *ghosd;
+  Display *dpy;
+  Window win, root_win;
+  int screen_num;
+  Visual *visual;
+  Colormap colormap;
+  Bool use_argbvisual = True;
+
+  dpy = XOpenDisplay(NULL);
+  if (dpy == NULL) {
+    fprintf(stderr, "Couldn't open display: (XXX FIXME)\n");
+    return NULL;
+  }
+  
+  screen_num = DefaultScreen(dpy);
+  root_win = RootWindow(dpy, screen_num);
+  visual = find_argb_visual(dpy, screen_num);
+  colormap = XCreateColormap(dpy, root_win, visual, AllocNone);
+
+  win = make_window(dpy, root_win, visual, colormap, use_argbvisual);
+  
+  ghosd = calloc(1, sizeof(Ghosd));
+  ghosd->dpy = dpy;
+  ghosd->visual = visual;
+  ghosd->colormap = colormap;
+  ghosd->win = win;
+  ghosd->root_win = root_win;
+  ghosd->screen_num = screen_num;
+  ghosd->transparent = 1;
+  ghosd->composite = 1;
   ghosd->eventbutton.func = NULL;
   ghosd->background.set = 0;
 
@@ -299,7 +410,12 @@
     XFreePixmap(ghosd->dpy, ghosd->background.pixmap);
     ghosd->background.set = 0;
   }
+  if (ghosd->composite)
+  {
+    XFreeColormap(ghosd->dpy, ghosd->colormap);
+  }
   XDestroyWindow(ghosd->dpy, ghosd->win);
+  XCloseDisplay(ghosd->dpy);
 }
 
 int
--- a/src/aosd/ghosd.h	Sat Mar 31 06:40:00 2007 -0700
+++ b/src/aosd/ghosd.h	Sat Mar 31 17:44:23 2007 -0700
@@ -3,6 +3,9 @@
  *
  * With further development by Giacomo Lozito <james@develia.org>
  * for the ghosd-based Audacious OSD
+ * - added real transparency with X Composite Extension
+ * - added mouse event handling on OSD window
+ * - added/changed some other stuff
  */
 
 #ifndef __GHOSD_H__
@@ -30,6 +33,7 @@
 typedef void (*GhosdEventButtonCb)(Ghosd *ghosd, GhosdEventButton *event, void *user_data);
 
 Ghosd *ghosd_new(void);
+Ghosd *ghosd_new_with_argbvisual(void);
 void   ghosd_destroy(Ghosd* ghosd);
 
 #define GHOSD_COORD_CENTER INT_MAX