Confused about GDKPixBuf/Cairo interaction

2013-02-18 Thread Rena
Hi, just joined the mailing list, been using GTK and related projects
for a while now. Recently I've been developing a Game Boy emulator
that uses GtkDrawingArea and GdkPixbuf to display the game screen.

In addition to the game output I want to also be able to draw text and
shapes on the display window, and Cairo seems to be the ideal way to
draw shapes. I'm already using Cairo to copy the Pixbuf to the
GtkDrawingArea, so that seems like a good sign that Cairo and
GdkPixbuf should interact nicely.

However, it doesn't look like they should be able to interact at all,
as they don't seem to be able to agree on a pixel format:
http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new-from-data
Currently only RGB images with 8 bits per sample are supported.
http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-The-GdkPixbuf-Structure.html#image-data
p[0] = red; p[1] = green; p[2] = blue; p[3] = alpha;
That seems to suggest that GdkPixbuf supports only RGB (24-bit) and
RGBA (32-bit). But...

http://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t
CAIRO_FORMAT_ARGB32 is ARGB (each pixel is a 32-bit quantity, with
alpha in the upper 8 bits...). CAIRO_FORMAT_RGB24 is xRGB (each
pixel is a 32-bit quantity, with the upper 8 bits unused...). Neither
of those are RGB or RGBA. So, how can Cairo operate on a surface
provided by GdkPixbuf?

-- 
Sent from my Game Boy.
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Confused about GDKPixBuf/Cairo interaction

2013-02-18 Thread Colomban Wendling
Hi,

Le 18/02/2013 11:10, Rena a écrit :
 Hi, just joined the mailing list, been using GTK and related projects
 for a while now. Recently I've been developing a Game Boy emulator
 that uses GtkDrawingArea and GdkPixbuf to display the game screen.
 
 In addition to the game output I want to also be able to draw text and
 shapes on the display window, and Cairo seems to be the ideal way to
 draw shapes. I'm already using Cairo to copy the Pixbuf to the
 GtkDrawingArea, so that seems like a good sign that Cairo and
 GdkPixbuf should interact nicely.
 
 However, it doesn't look like they should be able to interact at all,
 as they don't seem to be able to agree on a pixel format:
 http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new-from-data
 Currently only RGB images with 8 bits per sample are supported.
 http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-The-GdkPixbuf-Structure.html#image-data
 p[0] = red; p[1] = green; p[2] = blue; p[3] = alpha;
 That seems to suggest that GdkPixbuf supports only RGB (24-bit) and
 RGBA (32-bit). But...
 
 http://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t
 CAIRO_FORMAT_ARGB32 is ARGB (each pixel is a 32-bit quantity, with
 alpha in the upper 8 bits...). CAIRO_FORMAT_RGB24 is xRGB (each
 pixel is a 32-bit quantity, with the upper 8 bits unused...). Neither
 of those are RGB or RGBA. So, how can Cairo operate on a surface
 provided by GdkPixbuf?

I don't really get it.  You say you already use Cairo to draw your
pixbuf, but also that you can't see how to use a GdkPixbuf with Cairo?
This seems contradictory to me.

Anyway, what you want is gdk_cairo_set_source_pixbuf()[1] that does the
appropriate conversions to create a Cairo pattern from a GdkPixbuf.
Then you can use this pattern like any other Cairo pattern (e.g.
cairo_paint()), and you're done.

Hope it helps.
Colomban

[1]
http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Confused about GDKPixBuf/Cairo interaction

2013-02-18 Thread Colomban Wendling
Le 18/02/2013 14:50, Rena a écrit :
 On Mon, Feb 18, 2013 at 8:35 AM, Colomban Wendling
 lists@herbesfolles.org wrote:
 Hi,

 Le 18/02/2013 11:10, Rena a écrit :
 Hi, just joined the mailing list, been using GTK and related projects
 for a while now. Recently I've been developing a Game Boy emulator
 that uses GtkDrawingArea and GdkPixbuf to display the game screen.

 In addition to the game output I want to also be able to draw text and
 shapes on the display window, and Cairo seems to be the ideal way to
 draw shapes. I'm already using Cairo to copy the Pixbuf to the
 GtkDrawingArea, so that seems like a good sign that Cairo and
 GdkPixbuf should interact nicely.

 [...]

 I don't really get it.  You say you already use Cairo to draw your
 pixbuf, but also that you can't see how to use a GdkPixbuf with Cairo?
 This seems contradictory to me.

 Anyway, what you want is gdk_cairo_set_source_pixbuf()[1] that does the
 appropriate conversions to create a Cairo pattern from a GdkPixbuf.
 Then you can use this pattern like any other Cairo pattern (e.g.
 cairo_paint()), and you're done.
 
 Well, in the GtkDrawingArea::draw signal, I receive a cairo_t* that
 Gdk has created for me, and draw my pixbuf to it:
 
 gboolean draw_callback(GtkWidget *widget, cairo_t *cairo) {
 gdk_cairo_set_source_pixbuf(cairo, pixbuf, 0, 0);
 cairo_paint(cairo);
 }
 
 but if I want to draw a shape on the pixbuf, I would need to create a
 cairo_t* of my own for that purpose, and I don't see how to create one
 that's compatible with the pixel format GdkPixbuf uses. i.e. I want
 the destination to be my pixbuf, not the source.

First, you could very well draw directly on the Cairo context straight
in the ::draw handler, give then you don't need caching for decent
performances.  E.g., just continue drawing stuff in the ::draw handler
after you painted the pixbuf.

But if you want to draw everything on your own surface and then paint
that surface in the ::draw handler, just create a surface with whatever
format you need, gdk_cairo_set_source_pixbuf() should be able to do the
conversion.

The other solution is to use cairo_surface_create_similar(), but this
requires a surface to be similar to -- but there is no much reason for
that other surface to have a format better suitable to your pixbuf.  The
Cairo context passed to the ::draw handler is appropriate to draw on the
screen, not particularly to draw your pixbuf.


But you can very well do this:

def prepare_suraface(pix):
  # use whatever format you need, e.g. ARGB32 or RGB24
  surface = Cairo.Surface(cairo.Format.ARGB32, pix.width, pix.height)
  cr = Cairo.Context(surface)
  Gdk.cairo_set_source_pixbuf(cr, pix, 0, 0)
  cr.pain()

  # and continue drawing stuff
  cr.move_to(0, 0)
  cr.line_to(pix.width, pix.height)
  cr.stroke()

  return surface

and then your simply paint the created surface in your ::draw handler.
Of course, doing this is only useful if you need caching the drawn
surface, otherwise it'd be faster do directly perform the draws on the
::draw handler.


Or maybe I got you wrong and you'd like to *draw* on your GdkPixbuf?
I'm afraid this just isn't possible directly.  If you really want to do
that, you'll probably have to manually do some pixel conversion.  You
can create a Cairo surface of the pixbuf's size, draw on that, and then
get the surface's pixels which you'd convert manually to the pixbuf
format, and push those pixels to the pixbuf.  But again, why would you
need to draw specifically on a GdkPixbuf?

Regards,
Colomban
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: How to prevent windows to be raised at the top of the stack when clicked?

2013-02-18 Thread Olivier Guillion - Myriad
Hi,

I made some more tests about the solutions that seem to be useable. It appears 
that they are not.

Reminder: the problem is to let the application manage window stacking (z-
order), instead of letting the Window manager do most of the job by itself.

- The gtk_windows_set_transient_for() function works but :

. It's not possible to change anything in the window stacking order 
without 
rebuilding the whole list from scratch

. When the list reaches 16 windows and more, this operation takes 
exponentially more and more time. With 20 windows, it takes several seconds. 
With 25, the whole system hangs.

- The gtk_window_restack() function works but :

. When a window is clicked, it seems that the WM automatically send it 
to the 
frontmost position in the stack, without letting the application avoid that.

. I couldn't find any way to prevent that behaviour from the WM by 
altering 
the .XDefault/.XResources file


Could it be possible to bypass GTK and to access the X structures and events 
directly? If yes, is it a way to prevent it to bring automatically the clicked 
window to front ?

Regards,
Olivier
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


parsing bibtex using gscanner

2013-02-18 Thread Rudra Banerjee
Dear Friends,
I am trying to parse a bibtex file using gscanner.
The problem is that, due to many formats accepted by bibtex, it seems
bit hard to parse it.
What I mean is as long as the bibtex is of the form key=some value,
then g_scanner_get_next_token can get the string.
But it fails if it is in the format key={value}.

I am attaching my code. Some help (outside using btparse/ bison )is
needed.
guint parse_entry (GScanner   *scanner,
GHashTable *table)
{
  int tokount;
  /* Entry starts with @ */
  g_scanner_get_next_token (scanner);
  if (scanner-token != '@')
return G_TOKEN_ERROR;

  /* Now get identifier */
  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_IDENTIFIER)
return G_TOKEN_ERROR;

  g_hash_table_insert (table, g_strdup (type),
  g_strdup (scanner-value.v_identifier));

  /* Brace */
  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_LEFT_CURLY){
return G_TOKEN_ERROR;}
  else
tokount += tokount;

  /* ID */
  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_IDENTIFIER)
return G_TOKEN_ERROR;

  g_hash_table_insert (table, g_strdup (id),
  g_strdup (scanner-value.v_identifier));

  while (TRUE)
  {
char *key, *val;

g_scanner_get_next_token (scanner);
if (scanner-token != G_TOKEN_COMMA)
  return G_TOKEN_ERROR;


g_scanner_get_next_token (scanner);
if (scanner-token != G_TOKEN_IDENTIFIER)
  return G_TOKEN_ERROR;

key = g_strdup (scanner-value.v_identifier);

/*g_scanner_peek_next_token (scanner);
if (scanner-token == G_TOKEN_LEFT_CURLY)
  tokount += tokount;*/

g_scanner_get_next_token (scanner);
if (scanner-token != '=')
{
  g_free (key);
  return G_TOKEN_ERROR;
}

g_scanner_get_next_token (scanner);
if (scanner-token != G_TOKEN_STRING)
{
  g_free (key);
  return G_TOKEN_ERROR;
}

val = g_strdup (scanner-value.v_string);
g_hash_table_insert(table, key, val);

g_scanner_peek_next_token (scanner);
if (scanner-next_token == G_TOKEN_RIGHT_CURLY)
  break;
  }

  g_scanner_get_next_token (scanner);
  return G_TOKEN_NONE;
}


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: parsing bibtex using gscanner

2013-02-18 Thread Rudra Banerjee
Below is a minimal example.
One  can check the problem with key={some value} by changing, say, 
author = \Chowdhury, D.\,\n
to 
author = {Chowdhury, D.},\n

This can be compiled as
gcc -Wall `pkg-config --cflags --libs gtk+-3.0` glex.c

/*glex.c*/
#include glib.h
#include string.h

/* Test data */
static const gchar *ttest = @phdthesis{chow1983thesis,\n
author = \Chowdhury, D.\,\n
institution = \Department of Physics, IIT,
Kanpur\,\n
location = \Kanpur\,\n
publisher = \Department of Physics, IIT,
Kanpur\,\n
school = \Department of Physics, IIT,
Kanpur\,\n
title = \{The Spin Glass Transition}\,\n
year = \1983\\n
};


static void
output_entry (GHashTable *table)
{
  GHashTableIter iter;
  char *key, *val;

  g_print (Citation entry:\n);
  g_hash_table_iter_init (iter, table);
  while (g_hash_table_iter_next (iter, (void **)key, (void **)val))
g_print (  %16s: %s\n, key, val);
  g_print (\n);
}

static guint
parse_entry (GScanner   *scanner,
 GHashTable *table)
{
  /* Entry starts with @ */
  g_scanner_get_next_token (scanner);
  if (scanner-token != '@')
return G_TOKEN_ERROR;

  /* Now get identifier */
  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_IDENTIFIER)
return G_TOKEN_ERROR;

  g_hash_table_insert (table, g_strdup (type),
   g_strdup (scanner-value.v_identifier));

  /* Brace */
  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_LEFT_CURLY)
return G_TOKEN_ERROR;

  /* ID */
  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_IDENTIFIER)
return G_TOKEN_ERROR;

  g_hash_table_insert (table, g_strdup (id),
   g_strdup (scanner-value.v_identifier));

  while (TRUE)
{
  char *key, *val;

  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_COMMA)
return G_TOKEN_ERROR;

  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_IDENTIFIER)
return G_TOKEN_ERROR;

  key = g_strdup (scanner-value.v_identifier);

  g_scanner_get_next_token (scanner);
  if (scanner-token != '=')
{
  g_free (key);
  return G_TOKEN_ERROR;
}

  g_scanner_get_next_token (scanner);
  if (scanner-token != G_TOKEN_STRING)
{
  g_free (key);
  return G_TOKEN_ERROR;
}

  val = g_strdup (scanner-value.v_string);
  g_hash_table_insert(table, key, val);

  g_scanner_peek_next_token (scanner);
  if (scanner-next_token == G_TOKEN_RIGHT_CURLY)
break;
}

  /* Eat last curly brace and return */
  g_scanner_get_next_token (scanner);
  return G_TOKEN_NONE;
}


int
main (intargc,
  char **argv)
{
  GScanner *scanner;
  GHashTable *table;
  guint ret;

  scanner = g_scanner_new (NULL);
  g_scanner_input_text (scanner, ttest, strlen (ttest));

  table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
g_free);
  do
{
  g_hash_table_remove_all (table);
  ret = parse_entry (scanner, table);

  if (ret == G_TOKEN_ERROR)
break;
  else
output_entry (table);

  g_scanner_peek_next_token (scanner);
}
  while (scanner-next_token != G_TOKEN_EOF 
 scanner-next_token != G_TOKEN_ERROR);

  /* finsish parsing */
  g_scanner_destroy (scanner);
  g_hash_table_destroy (table);

  return 0;
}




___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: parsing bibtex using gscanner

2013-02-18 Thread David Nečas
On Mon, Feb 18, 2013 at 05:15:56PM +, Rudra Banerjee wrote:
 I am trying to parse a bibtex file using gscanner.
 The problem is that, due to many formats accepted by bibtex, it seems
 bit hard to parse it.
 What I mean is as long as the bibtex is of the form key=some value,
 then g_scanner_get_next_token can get the string.
 But it fails if it is in the format key={value}.

And it fails even before escaping literal TeX code using braces within
entries or string macros have come to play...

 I am attaching my code. Some help (outside using btparse/ bison )is
 needed.

Don't do it this way.  GScanner is a lexical scanner, it just tokenizes
the input but it does not help with grammar.

The best approach to parse a grammar is, you know, using a parser.

If you insist on writing one manually realise that you need to formally
keep state, eg. the nesting level of braces at which you are now, etc.
Construct the parser similarly you would if you did if you just wrote
the BNF and let the parser be generared, e.g. write subroutines to parse
balanced braces, string, etc. possibly recusrively calling each other.

Attempting to write code for all the cases that can occur using
sequences of hardcoded ifs will only result in buggy mess.  You have
been warned.

Yeti

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: parsing bibtex using gscanner

2013-02-18 Thread Rudra Banerjee
I forget the acknowledgment:
http://www.gtkforums.com/viewtopic.php?f=3t=178159
On Mon, 2013-02-18 at 18:00 +, Rudra Banerjee wrote:
 Below is a minimal example.
 One  can check the problem with key={some value} by changing, say, 
 author = \Chowdhury, D.\,\n
 to 
 author = {Chowdhury, D.},\n
 
 This can be compiled as
 gcc -Wall `pkg-config --cflags --libs gtk+-3.0` glex.c
 
 /*glex.c*/
 #include glib.h
 #include string.h
 
 /* Test data */
 static const gchar *ttest = @phdthesis{chow1983thesis,\n
 author = \Chowdhury, D.\,\n
 institution = \Department of Physics, IIT,
 Kanpur\,\n
 location = \Kanpur\,\n
 publisher = \Department of Physics, IIT,
 Kanpur\,\n
 school = \Department of Physics, IIT,
 Kanpur\,\n
 title = \{The Spin Glass Transition}\,\n
 year = \1983\\n
 };
 
 
 static void
 output_entry (GHashTable *table)
 {
   GHashTableIter iter;
   char *key, *val;
 
   g_print (Citation entry:\n);
   g_hash_table_iter_init (iter, table);
   while (g_hash_table_iter_next (iter, (void **)key, (void **)val))
 g_print (  %16s: %s\n, key, val);
   g_print (\n);
 }
 
 static guint
 parse_entry (GScanner   *scanner,
  GHashTable *table)
 {
   /* Entry starts with @ */
   g_scanner_get_next_token (scanner);
   if (scanner-token != '@')
 return G_TOKEN_ERROR;
 
   /* Now get identifier */
   g_scanner_get_next_token (scanner);
   if (scanner-token != G_TOKEN_IDENTIFIER)
 return G_TOKEN_ERROR;
 
   g_hash_table_insert (table, g_strdup (type),
g_strdup (scanner-value.v_identifier));
 
   /* Brace */
   g_scanner_get_next_token (scanner);
   if (scanner-token != G_TOKEN_LEFT_CURLY)
 return G_TOKEN_ERROR;
 
   /* ID */
   g_scanner_get_next_token (scanner);
   if (scanner-token != G_TOKEN_IDENTIFIER)
 return G_TOKEN_ERROR;
 
   g_hash_table_insert (table, g_strdup (id),
g_strdup (scanner-value.v_identifier));
 
   while (TRUE)
 {
   char *key, *val;
 
   g_scanner_get_next_token (scanner);
   if (scanner-token != G_TOKEN_COMMA)
 return G_TOKEN_ERROR;
 
   g_scanner_get_next_token (scanner);
   if (scanner-token != G_TOKEN_IDENTIFIER)
 return G_TOKEN_ERROR;
 
   key = g_strdup (scanner-value.v_identifier);
 
   g_scanner_get_next_token (scanner);
   if (scanner-token != '=')
 {
   g_free (key);
   return G_TOKEN_ERROR;
 }
 
   g_scanner_get_next_token (scanner);
   if (scanner-token != G_TOKEN_STRING)
 {
   g_free (key);
   return G_TOKEN_ERROR;
 }
 
   val = g_strdup (scanner-value.v_string);
   g_hash_table_insert(table, key, val);
 
   g_scanner_peek_next_token (scanner);
   if (scanner-next_token == G_TOKEN_RIGHT_CURLY)
 break;
 }
 
   /* Eat last curly brace and return */
   g_scanner_get_next_token (scanner);
   return G_TOKEN_NONE;
 }
 
 
 int
 main (intargc,
   char **argv)
 {
   GScanner *scanner;
   GHashTable *table;
   guint ret;
 
   scanner = g_scanner_new (NULL);
   g_scanner_input_text (scanner, ttest, strlen (ttest));
 
   table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
 g_free);
   do
 {
   g_hash_table_remove_all (table);
   ret = parse_entry (scanner, table);
 
   if (ret == G_TOKEN_ERROR)
 break;
   else
 output_entry (table);
 
   g_scanner_peek_next_token (scanner);
 }
   while (scanner-next_token != G_TOKEN_EOF 
  scanner-next_token != G_TOKEN_ERROR);
 
   /* finsish parsing */
   g_scanner_destroy (scanner);
   g_hash_table_destroy (table);
 
   return 0;
 }
 
 
 
 
 ___
 gtk-app-devel-list mailing list
 gtk-app-devel-list@gnome.org
 https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: parsing bibtex using gscanner

2013-02-18 Thread Rudra Banerjee
On Mon, 2013-02-18 at 19:02 +0100, David Nečas wrote:
 The best approach to parse a grammar is, you know, using a parser.
So anything better then bison?

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: parsing bibtex using gscanner

2013-02-18 Thread Rudra Banerjee
On Mon, 2013-02-18 at 19:02 +0100, David Nečas wrote:
 The best approach to parse a grammar is, you know, using a parser.
So is there any better option then bison?

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: How to prevent windows to be raised at the top of the stack when clicked?

2013-02-18 Thread Sam Spilsbury
Hi,

On Thu, Feb 14, 2013 at 12:17 AM, Olivier Guillion - Myriad
oliv...@myriad-online.com wrote:
 Hi,

 I'm struggling with this problem for several days now, and can't find any
 solution.

 I'm writing an application for Ubuntu using GTK in C language.
 This application manages various windows (floating palettes, documents,
 toolbars, etc), with a complex stacking (Z-order) strategy.
 I would want to manage the stacking myself, by calling gtk_window_restack
 appropriately.

Warning, here be dragons. Applications don't have full control over
their stacking order or stacking policy, except if they are override
redirect and the window manager does not touch them at all.


 It works well, except for one thing : when a window is clicked, it seems to be
 automatically sent to front (top of the stack) by the system before my program
 receives any signal.
 For instance, if I put a breakpoint in the focus_in_event or
 button_press_event signal callback, the window has already been sent to top
 before the breakpoint is reached.

 Is there a way to prevent a clicked window from being automatically sent to 
 top
 of the stack ?
 Any help would be greatly appreciated.


There isn't really.

You can set _NET_WM_STATE_BELOW to make the window manager put it on
the same layer as all of the below windows [1]. The window manager
will still freely raise any window within this layer. Then you can use
WM_TRANSIENT_FOR in order to force ordering amongst your windows. That
ordering won't be exclusive though - it is entirely possible that
other windows can go in-between.

The reason why the window is automatically raised is because the
window manager has a passive grab on the parent window if its not on
the top of the stack. This grab activates and prevents your
application from receiving the first mouse click until the window
manager has done what its wants to do, namely, place the window at the
top of the stack. This is part of the reason why people want client
side decorations.

I'd suggest reconsidering the design of your application. There are
very good reasons why window managers needs to manage the stacking
order, allowing applications to override that behaviour generally
results in trouble.

[1] http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#STACKINGORDER

 Thank you,
 Olivier
 ___
 gtk-app-devel-list mailing list
 gtk-app-devel-list@gnome.org
 https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list



-- 
Sam Spilsbury
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list