[gnome-devel-docs] Updated Spanish translation



commit 4836ab6e9e71572bc6fe470f022b96d03dac63dc
Author: Daniel Mustieles <daniel mustieles gmail com>
Date:   Tue Feb 24 19:21:22 2015 +0100

    Updated Spanish translation

 platform-demos/es/es.po |  827 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 818 insertions(+), 9 deletions(-)
---
diff --git a/platform-demos/es/es.po b/platform-demos/es/es.po
index a25be0e..b46ac2b 100644
--- a/platform-demos/es/es.po
+++ b/platform-demos/es/es.po
@@ -9,8 +9,8 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: gnome-devel-docs.platform-demos.master\n"
-"POT-Creation-Date: 2015-02-17 07:37+0000\n"
-"PO-Revision-Date: 2015-02-17 18:30+0100\n"
+"POT-Creation-Date: 2015-02-24 07:38+0000\n"
+"PO-Revision-Date: 2015-02-24 18:57+0100\n"
 "Last-Translator: Daniel Mustieles <daniel mustieles gmail com>\n"
 "Language-Team: Español; Castellano <gnome-es-list gnome org>\n"
 "Language: \n"
@@ -26529,18 +26529,11 @@ msgstr ""
 
 #. (itstool) path: p/link
 #: C/legal.xml:3
-#| msgid ""
-#| "This work is distributed under a CreativeCommons Attribution-Share Alike "
-#| "3.0 Unported license."
 msgid "Creative Commons Attribution-ShareAlike 3.0 Unported License"
 msgstr "Creative Commons de Atribución-Compartir Igual 3.0 sin soporte"
 
 #. (itstool) path: license/p
 #: C/legal.xml:3
-#| msgid ""
-#| "As a special exception, the copyright holders give you permission to "
-#| "copy, modify, and distribute the example code contained in this "
-#| "documentation under the terms of your choosing, without restriction."
 msgid ""
 "This work is licensed under a <_:link-1/>. As a special exception, the "
 "copyright holders give you permission to copy, modify, and distribute the "
@@ -59410,6 +59403,822 @@ msgstr ""
 "<link href=\"http://www.valadoc.org/gtk+-3.0/Gtk.Window.window_position.html";
 "\">window_position</link>"
 
+#. (itstool) path: credit/name
+#: C/custom-gsource.c.page:11
+#| msgid "Philip Chimento"
+msgid "Philip Withnall"
+msgstr "Philip Withnall"
+
+#. (itstool) path: credit/years
+#: C/custom-gsource.c.page:13
+msgid "2015"
+msgstr "2015"
+
+#. (itstool) path: info/desc
+#: C/custom-gsource.c.page:18
+msgid "Tutorial for writing a custom <code>GSource</code> implementation"
+msgstr ""
+
+#. (itstool) path: page/title
+#: C/custom-gsource.c.page:23
+msgid "Custom GSources"
+msgstr ""
+
+#. (itstool) path: synopsis/title
+#: C/custom-gsource.c.page:26
+msgid "Summary"
+msgstr "Resumen"
+
+#. (itstool) path: synopsis/p
+#: C/custom-gsource.c.page:28
+msgid ""
+"This article is a tutorial on creating a custom <code>GSource</code>. For "
+"the reference documentation, see the <link href=\"https://developer.gnome.";
+"org/glib/stable/glib-The-Main-Event-Loop.html#GSource\">GLib API reference</"
+"link>."
+msgstr ""
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:37
+msgid "What is <code>GSource</code>?"
+msgstr "¿qué es <code>GSource</code>?"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:39
+msgid ""
+"A <link href=\"https://developer.gnome.org/glib/stable/glib-The-Main-Event-";
+"Loop.html#GSource\"><code>GSource</code></link> is an expected event with an "
+"associated callback function which will be invoked when that event is "
+"received. An event could be a timeout or data being received on a socket, "
+"for example."
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:46
+msgid ""
+"GLib contains various types of <code>GSource</code>, but also allows "
+"applications to define their own, allowing custom events to be integrated "
+"into the main loop."
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:52
+#, fuzzy
+#| msgid ""
+#| "You can find signal definitions for any object in the <link href="
+#| "\"https://developer.gnome.org/gtk3/stable/gtkobjects.html\";>GTK class "
+#| "reference</link>."
+msgid ""
+"The structure of a <code>GSource</code> and its virtual functions are "
+"documented in detail in the <link href=\"https://developer.gnome.org/glib/";
+"stable/glib-The-Main-Event-Loop.html#GSourceFuncs\">GLib API reference</"
+"link>."
+msgstr ""
+"Puede encontrar definiciones de señales para cualquier objeto en la <link "
+"href=\"https://developer.gnome.org/gtk3/stable/gtkobjects.html\";>referencia "
+"de clases de GTK+</link>."
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:61
+msgid "A Message Queue Source"
+msgstr "Una fuente de cola de mensajes"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:63
+msgid ""
+"As a running example, a message queue source will be used which dispatches "
+"its callback whenever a message is enqueued to a queue internal to the "
+"source (potentially from another thread)."
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:69
+msgid ""
+"This type of source is useful for efficiently transferring large numbers of "
+"messages between main contexts. The alternative is transferring each message "
+"as a separate idle <code>GSource</code> using <code>g_source_attach()</"
+"code>. For large numbers of messages, this means a lot of allocations and "
+"frees of <code>GSource</code>s."
+msgstr ""
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:78
+#| msgid "Program Structure"
+msgid "Structure"
+msgstr "Estructura"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:80
+msgid ""
+"Firstly, a structure for the source needs to be declared. This must contain "
+"a <code>GSource</code> as its parent, followed by the private fields for the "
+"source: the queue and a function to call to free each message once finished "
+"with."
+msgstr ""
+
+#. (itstool) path: section/code
+#: C/custom-gsource.c.page:86
+#, no-wrap
+msgid ""
+"\n"
+"typedef struct {\n"
+"  GSource         parent;\n"
+"  GAsyncQueue    *queue;  /* owned */\n"
+"  GDestroyNotify  destroy_message;\n"
+"} MessageQueueSource;"
+msgstr ""
+"\n"
+"typedef struct {\n"
+"  GSource         parent;\n"
+"  GAsyncQueue    *queue;  /* owned */\n"
+"  GDestroyNotify  destroy_message;\n"
+"} MessageQueueSource;"
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:95
+msgid "Prepare Function"
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:97
+msgid ""
+"Next, the prepare function for the source must be defined. This determines "
+"whether the source is ready to be dispatched. As this source is using an in-"
+"memory queue, this can be determined by checking the queue’s length: if "
+"there are elements in the queue, the source can be dispatched to handle them."
+msgstr ""
+
+#. (itstool) path: section/code
+#: C/custom-gsource.c.page:104
+#, no-wrap
+msgid ""
+"\n"
+"return (g_async_queue_length (message_queue_source-&gt;queue) &gt; 0);"
+msgstr ""
+"\n"
+"return (g_async_queue_length (message_queue_source-&gt;queue) &gt; 0);"
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:109
+#, fuzzy
+#| msgid "CheckButton"
+msgid "Check Function"
+msgstr "CheckButton"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:111
+msgid ""
+"As this source has no file descriptors, the prepare and check functions "
+"essentially have the same job, so a check function is not needed. Setting "
+"the field to <code>NULL</code> in <code>GSourceFuncs</code> bypasses the "
+"check function for this source type."
+msgstr ""
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:120
+msgid "Dispatch Function"
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:122
+msgid ""
+"For this source, the dispatch function is where the complexity lies. It "
+"needs to dequeue a message from the queue, then pass that message to the "
+"<code>GSource</code>’s callback function. No messages may be queued: even "
+"through the prepare function returned true, another source wrapping the same "
+"queue may have been dispatched in the mean time and taken the final message "
+"from the queue. Further, if no callback has been set for the <code>GSource</"
+"code> (which is allowed), the message must be destroyed and silently dropped."
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:133
+msgid ""
+"If both a message and callback are set, the callback can be invoked on the "
+"message and its return value propagated as the return value of the dispatch "
+"function. This is <code>FALSE</code> to destroy the <code>GSource</code> and "
+"<code>TRUE</code> to keep it alive, just as for <code>GSourceFunc</code> — "
+"these semantics are the same for all dispatch function implementations."
+msgstr ""
+
+#. (itstool) path: section/code
+#: C/custom-gsource.c.page:141
+#, no-wrap
+msgid ""
+"\n"
+"/* Pop a message off the queue. */\n"
+"message = g_async_queue_try_pop (message_queue_source-&gt;queue);\n"
+"\n"
+"/* If there was no message, bail. */\n"
+"if (message == NULL)\n"
+"  {\n"
+"    /* Keep the source around to handle the next message. */\n"
+"    return TRUE;\n"
+"  }\n"
+"\n"
+"/* @func may be %NULL if no callback was specified.\n"
+" * If so, drop the message. */\n"
+"if (func == NULL)\n"
+"  {\n"
+"    if (message_queue_source-&gt;destroy_message != NULL)\n"
+"      {\n"
+"        message_queue_source-&gt;destroy_message (message);\n"
+"      }\n"
+"\n"
+"    /* Keep the source around to consume the next message. */\n"
+"    return TRUE;\n"
+"  }\n"
+"\n"
+"return func (message, user_data);"
+msgstr ""
+"\n"
+"/* Pop a message off the queue. */\n"
+"message = g_async_queue_try_pop (message_queue_source-&gt;queue);\n"
+"\n"
+"/* If there was no message, bail. */\n"
+"if (message == NULL)\n"
+"  {\n"
+"    /* Keep the source around to handle the next message. */\n"
+"    return TRUE;\n"
+"  }\n"
+"\n"
+"/* @func may be %NULL if no callback was specified.\n"
+" * If so, drop the message. */\n"
+"if (func == NULL)\n"
+"  {\n"
+"    if (message_queue_source-&gt;destroy_message != NULL)\n"
+"      {\n"
+"        message_queue_source-&gt;destroy_message (message);\n"
+"      }\n"
+"\n"
+"    /* Keep the source around to consume the next message. */\n"
+"    return TRUE;\n"
+"  }\n"
+"\n"
+"return func (message, user_data);"
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:169
+msgid "Callback Functions"
+msgstr "Funciones de retorno de llamada"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:171
+msgid ""
+"The callback from a <code>GSource</code> does not have to have type "
+"<code>GSourceFunc</code>. It can be whatever function type is called in the "
+"source’s dispatch function, as long as that type is sufficiently documented."
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:178
+msgid ""
+"Normally, <code>g_source_set_callback()</code> is used to set the callback "
+"function for a source instance. With its <code>GDestroyNotify</code>, a "
+"strong reference can be held to keep an object alive while the source is "
+"still alive:"
+msgstr ""
+
+#. (itstool) path: section/code
+#: C/custom-gsource.c.page:184
+#, no-wrap
+msgid ""
+"\n"
+"g_source_set_callback (source, callback_func,\n"
+"                       g_object_ref (object_to_strong_ref),\n"
+"                       (GDestroyNotify) g_object_unref);"
+msgstr ""
+"\n"
+"g_source_set_callback (source, callback_func,\n"
+"                       g_object_ref (object_to_strong_ref),\n"
+"                       (GDestroyNotify) g_object_unref);"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:189
+msgid ""
+"However, <code>GSource</code> has a layer of indirection for retrieving this "
+"callback, exposed as <code>g_source_set_callback_indirect()</code>. This "
+"allows GObject to set a <code>GClosure</code> as the callback for a source, "
+"which allows for sources which are automatically destroyed when an object is "
+"finalized — a <em>weak</em> reference, in contrast to the <em>strong</em> "
+"reference above:"
+msgstr ""
+
+#. (itstool) path: section/code
+#: C/custom-gsource.c.page:197
+#, no-wrap
+msgid ""
+"\n"
+"g_source_set_closure (source,\n"
+"                      g_cclosure_new_object (callback_func,\n"
+"                                             object_to_weak_ref));"
+msgstr ""
+"\n"
+"g_source_set_closure (source,\n"
+"                      g_cclosure_new_object (callback_func,\n"
+"                                             object_to_weak_ref));"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:202
+msgid ""
+"It also allows for a generic, closure-based ‘dummy’ callback, which can be "
+"used when a source needs to exist but no action needs to be performed in its "
+"callback:"
+msgstr ""
+
+#. (itstool) path: section/code
+#: C/custom-gsource.c.page:207
+#, no-wrap
+msgid ""
+"\n"
+"g_source_set_dummy_callback (source);"
+msgstr ""
+"\n"
+"g_source_set_dummy_callback (source);"
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:212
+msgid "Constructor"
+msgstr "Constructor"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:214
+msgid ""
+"Finally, the <code>GSourceFuncs</code> definition of the <code>GSource</"
+"code> can be written, alongside a construction function. It is typical "
+"practice to expose new source types simply as <code>GSource</code>s, not as "
+"the subtype structure; so the constructor returns a <code>GSource*</code>."
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:222
+msgid ""
+"The example constructor here also demonstrates use of a child source to "
+"support cancellation conveniently. If the <code>GCancellable</code> is "
+"cancelled, the applicationj’s callback will be dispatched and can check for "
+"cancellation. (The application code will need to make a pointer to the "
+"<code>GCancellable</code> available to its callback, as a field of the "
+"callback’s user data set in <code>g_source_set_callback()</code>.)"
+msgstr ""
+
+#. (itstool) path: section/code
+#: C/custom-gsource.c.page:230
+#, no-wrap
+msgid ""
+"\n"
+"GSource *\n"
+"message_queue_source_new (GAsyncQueue    *queue,\n"
+"                          GDestroyNotify  destroy_message,\n"
+"                          GCancellable   *cancellable)\n"
+"{\n"
+"  GSource *source;  /* alias of @message_queue_source */\n"
+"  MessageQueueSource *message_queue_source;  /* alias of @source */\n"
+"\n"
+"  g_return_val_if_fail (queue != NULL, NULL);\n"
+"  g_return_val_if_fail (cancellable == NULL ||\n"
+"                        G_IS_CANCELLABLE (cancellable), NULL);\n"
+"\n"
+"  source = g_source_new (&amp;message_queue_source_funcs,\n"
+"                         sizeof (MessageQueueSource));\n"
+"  message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  /* The caller can overwrite this name with something more useful later. */\n"
+"  g_source_set_name (source, \"MessageQueueSource\");\n"
+"\n"
+"  message_queue_source-&gt;queue = g_async_queue_ref (queue);\n"
+"  message_queue_source-&gt;destroy_message = destroy_message;\n"
+"\n"
+"  /* Add a cancellable source. */\n"
+"  if (cancellable != NULL)\n"
+"    {\n"
+"      GSource *cancellable_source;\n"
+"\n"
+"      cancellable_source = g_cancellable_source_new (cancellable);\n"
+"      g_source_set_dummy_callback (cancellable_source);\n"
+"      g_source_add_child_source (source, cancellable_source);\n"
+"      g_source_unref (cancellable_source);\n"
+"    }\n"
+"\n"
+"  return source;\n"
+"}"
+msgstr ""
+"\n"
+"GSource *\n"
+"message_queue_source_new (GAsyncQueue    *queue,\n"
+"                          GDestroyNotify  destroy_message,\n"
+"                          GCancellable   *cancellable)\n"
+"{\n"
+"  GSource *source;  /* alias of @message_queue_source */\n"
+"  MessageQueueSource *message_queue_source;  /* alias of @source */\n"
+"\n"
+"  g_return_val_if_fail (queue != NULL, NULL);\n"
+"  g_return_val_if_fail (cancellable == NULL ||\n"
+"                        G_IS_CANCELLABLE (cancellable), NULL);\n"
+"\n"
+"  source = g_source_new (&amp;message_queue_source_funcs,\n"
+"                         sizeof (MessageQueueSource));\n"
+"  message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  /* The caller can overwrite this name with something more useful later. */\n"
+"  g_source_set_name (source, \"MessageQueueSource\");\n"
+"\n"
+"  message_queue_source-&gt;queue = g_async_queue_ref (queue);\n"
+"  message_queue_source-&gt;destroy_message = destroy_message;\n"
+"\n"
+"  /* Add a cancellable source. */\n"
+"  if (cancellable != NULL)\n"
+"    {\n"
+"      GSource *cancellable_source;\n"
+"\n"
+"      cancellable_source = g_cancellable_source_new (cancellable);\n"
+"      g_source_set_dummy_callback (cancellable_source);\n"
+"      g_source_add_child_source (source, cancellable_source);\n"
+"      g_source_unref (cancellable_source);\n"
+"    }\n"
+"\n"
+"  return source;\n"
+"}"
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:270
+#| msgid "Complete code sample"
+msgid "Complete Example"
+msgstr "Ejemplo completo"
+
+#. (itstool) path: listing/title
+#: C/custom-gsource.c.page:273
+#| msgid "Complete code sample"
+msgid "Complete Example Code"
+msgstr "Código de ejemplo completo"
+
+#. (itstool) path: listing/code
+#: C/custom-gsource.c.page:275
+#, no-wrap
+msgid ""
+"/**\n"
+" * MessageQueueSource:\n"
+" *\n"
+" * This is a #GSource which wraps a #GAsyncQueue and is dispatched whenever a\n"
+" * message can be pulled off the queue. Messages can be enqueued from any\n"
+" * thread.\n"
+" *\n"
+" * The callbacks dispatched by a #MessageQueueSource have type\n"
+" * #MessageQueueSourceFunc.\n"
+" *\n"
+" * #MessageQueueSource supports adding a #GCancellable child source which will\n"
+" * additionally dispatch if a provided #GCancellable is cancelled.\n"
+" */\n"
+"typedef struct {\n"
+"  GSource         parent;\n"
+"  GAsyncQueue    *queue;  /* owned */\n"
+"  GDestroyNotify  destroy_message;\n"
+"} MessageQueueSource;\n"
+"\n"
+"/**\n"
+" * MessageQueueSourceFunc:\n"
+" * @message: (transfer full) (nullable): message pulled off the queue\n"
+" * @user_data: user data provided to g_source_set_callback()\n"
+" *\n"
+" * Callback function type for #MessageQueueSource.\n"
+" */\n"
+"typedef gboolean (*MessageQueueSourceFunc) (gpointer message,\n"
+"                                            gpointer user_data);\n"
+"\n"
+"static gboolean\n"
+"message_queue_source_prepare (GSource *source,\n"
+"                              gint    *timeout_)\n"
+"{\n"
+"  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  return (g_async_queue_length (message_queue_source-&gt;queue) &gt; 0);\n"
+"}\n"
+"\n"
+"static gboolean\n"
+"message_queue_source_dispatch (GSource     *source,\n"
+"                               GSourceFunc  callback,\n"
+"                               gpointer     user_data)\n"
+"{\n"
+"  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;\n"
+"  gpointer message;\n"
+"  MessageQueueSourceFunc func = (MessageQueueSourceFunc) callback;\n"
+"\n"
+"  /* Pop a message off the queue. */\n"
+"  message = g_async_queue_try_pop (message_queue_source-&gt;queue);\n"
+"\n"
+"  /* If there was no message, bail. */\n"
+"  if (message == NULL)\n"
+"    {\n"
+"      /* Keep the source around to handle the next message. */\n"
+"      return TRUE;\n"
+"    }\n"
+"\n"
+"  /* @func may be %NULL if no callback was specified.\n"
+"   * If so, drop the message. */\n"
+"  if (func == NULL)\n"
+"    {\n"
+"      if (message_queue_source-&gt;destroy_message != NULL)\n"
+"        {\n"
+"          message_queue_source-&gt;destroy_message (message);\n"
+"        }\n"
+"\n"
+"      /* Keep the source around to consume the next message. */\n"
+"      return TRUE;\n"
+"    }\n"
+"\n"
+"  return func (message, user_data);\n"
+"}\n"
+"\n"
+"static void\n"
+"message_queue_source_finalize (GSource *source)\n"
+"{\n"
+"  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  g_async_queue_unref (message_queue_source-&gt;queue);\n"
+"}\n"
+"\n"
+"static gboolean\n"
+"message_queue_source_closure_callback (gpointer message,\n"
+"                                       gpointer user_data)\n"
+"{\n"
+"  GClosure *closure = user_data;\n"
+"  GValue param_value = G_VALUE_INIT;\n"
+"  GValue result_value = G_VALUE_INIT;\n"
+"  gboolean retval;\n"
+"\n"
+"  /* The invoked function is responsible for freeing @message. */\n"
+"  g_value_init (&amp;result_value, G_TYPE_BOOLEAN);\n"
+"  g_value_init (&amp;param_value, G_TYPE_POINTER);\n"
+"  g_value_set_pointer (&amp;param_value, message);\n"
+"\n"
+"  g_closure_invoke (closure, &amp;result_value, 1, &amp;param_value, NULL);\n"
+"  retval = g_value_get_boolean (&amp;result_value);\n"
+"\n"
+"  g_value_unset (&amp;param_value);\n"
+"  g_value_unset (&amp;result_value);\n"
+"\n"
+"  return retval;\n"
+"}\n"
+"\n"
+"static GSourceFuncs message_queue_source_funcs =\n"
+"  {\n"
+"    message_queue_source_prepare,\n"
+"    NULL,  /* check */\n"
+"    message_queue_source_dispatch,\n"
+"    message_queue_source_finalize,\n"
+"    (GSourceFunc) message_queue_source_closure_callback,\n"
+"    NULL,\n"
+"  };\n"
+"\n"
+"/**\n"
+" * message_queue_source_new:\n"
+" * @queue: the queue to check\n"
+" * @destroy_message: (nullable): function to free a message, or %NULL\n"
+" * @cancellable: (nullable): a #GCancellable, or %NULL\n"
+" *\n"
+" * Create a new #MessageQueueSource, a type of #GSource which dispatches for\n"
+" * each message queued to it.\n"
+" *\n"
+" * If a callback function of type #MessageQueueSourceFunc is connected to the\n"
+" * returned #GSource using g_source_set_callback(), it will be invoked for each\n"
+" * message, with the message passed as its first argument. It is responsible for\n"
+" * freeing the message. If no callback is set, messages are automatically freed\n"
+" * as they are queued.\n"
+" *\n"
+" * Returns: (transfer full): a new #MessageQueueSource\n"
+" */\n"
+"GSource *\n"
+"message_queue_source_new (GAsyncQueue    *queue,\n"
+"                          GDestroyNotify  destroy_message,\n"
+"                          GCancellable   *cancellable)\n"
+"{\n"
+"  GSource *source;  /* alias of @message_queue_source */\n"
+"  MessageQueueSource *message_queue_source;  /* alias of @source */\n"
+"\n"
+"  g_return_val_if_fail (queue != NULL, NULL);\n"
+"  g_return_val_if_fail (cancellable == NULL ||\n"
+"                        G_IS_CANCELLABLE (cancellable), NULL);\n"
+"\n"
+"  source = g_source_new (&amp;message_queue_source_funcs,\n"
+"                         sizeof (MessageQueueSource));\n"
+"  message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  /* The caller can overwrite this name with something more useful later. */\n"
+"  g_source_set_name (source, \"MessageQueueSource\");\n"
+"\n"
+"  message_queue_source-&gt;queue = g_async_queue_ref (queue);\n"
+"  message_queue_source-&gt;destroy_message = destroy_message;\n"
+"\n"
+"  /* Add a cancellable source. */\n"
+"  if (cancellable != NULL)\n"
+"    {\n"
+"      GSource *cancellable_source;\n"
+"\n"
+"      cancellable_source = g_cancellable_source_new (cancellable);\n"
+"      g_source_set_dummy_callback (cancellable_source);\n"
+"      g_source_add_child_source (source, cancellable_source);\n"
+"      g_source_unref (cancellable_source);\n"
+"    }\n"
+"\n"
+"  return source;\n"
+"}\n"
+msgstr ""
+"/**\n"
+" * MessageQueueSource:\n"
+" *\n"
+" * This is a #GSource which wraps a #GAsyncQueue and is dispatched whenever a\n"
+" * message can be pulled off the queue. Messages can be enqueued from any\n"
+" * thread.\n"
+" *\n"
+" * The callbacks dispatched by a #MessageQueueSource have type\n"
+" * #MessageQueueSourceFunc.\n"
+" *\n"
+" * #MessageQueueSource supports adding a #GCancellable child source which will\n"
+" * additionally dispatch if a provided #GCancellable is cancelled.\n"
+" */\n"
+"typedef struct {\n"
+"  GSource         parent;\n"
+"  GAsyncQueue    *queue;  /* owned */\n"
+"  GDestroyNotify  destroy_message;\n"
+"} MessageQueueSource;\n"
+"\n"
+"/**\n"
+" * MessageQueueSourceFunc:\n"
+" * @message: (transfer full) (nullable): message pulled off the queue\n"
+" * @user_data: user data provided to g_source_set_callback()\n"
+" *\n"
+" * Callback function type for #MessageQueueSource.\n"
+" */\n"
+"typedef gboolean (*MessageQueueSourceFunc) (gpointer message,\n"
+"                                            gpointer user_data);\n"
+"\n"
+"static gboolean\n"
+"message_queue_source_prepare (GSource *source,\n"
+"                              gint    *timeout_)\n"
+"{\n"
+"  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  return (g_async_queue_length (message_queue_source-&gt;queue) &gt; 0);\n"
+"}\n"
+"\n"
+"static gboolean\n"
+"message_queue_source_dispatch (GSource     *source,\n"
+"                               GSourceFunc  callback,\n"
+"                               gpointer     user_data)\n"
+"{\n"
+"  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;\n"
+"  gpointer message;\n"
+"  MessageQueueSourceFunc func = (MessageQueueSourceFunc) callback;\n"
+"\n"
+"  /* Pop a message off the queue. */\n"
+"  message = g_async_queue_try_pop (message_queue_source-&gt;queue);\n"
+"\n"
+"  /* If there was no message, bail. */\n"
+"  if (message == NULL)\n"
+"    {\n"
+"      /* Keep the source around to handle the next message. */\n"
+"      return TRUE;\n"
+"    }\n"
+"\n"
+"  /* @func may be %NULL if no callback was specified.\n"
+"   * If so, drop the message. */\n"
+"  if (func == NULL)\n"
+"    {\n"
+"      if (message_queue_source-&gt;destroy_message != NULL)\n"
+"        {\n"
+"          message_queue_source-&gt;destroy_message (message);\n"
+"        }\n"
+"\n"
+"      /* Keep the source around to consume the next message. */\n"
+"      return TRUE;\n"
+"    }\n"
+"\n"
+"  return func (message, user_data);\n"
+"}\n"
+"\n"
+"static void\n"
+"message_queue_source_finalize (GSource *source)\n"
+"{\n"
+"  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  g_async_queue_unref (message_queue_source-&gt;queue);\n"
+"}\n"
+"\n"
+"static gboolean\n"
+"message_queue_source_closure_callback (gpointer message,\n"
+"                                       gpointer user_data)\n"
+"{\n"
+"  GClosure *closure = user_data;\n"
+"  GValue param_value = G_VALUE_INIT;\n"
+"  GValue result_value = G_VALUE_INIT;\n"
+"  gboolean retval;\n"
+"\n"
+"  /* The invoked function is responsible for freeing @message. */\n"
+"  g_value_init (&amp;result_value, G_TYPE_BOOLEAN);\n"
+"  g_value_init (&amp;param_value, G_TYPE_POINTER);\n"
+"  g_value_set_pointer (&amp;param_value, message);\n"
+"\n"
+"  g_closure_invoke (closure, &amp;result_value, 1, &amp;param_value, NULL);\n"
+"  retval = g_value_get_boolean (&amp;result_value);\n"
+"\n"
+"  g_value_unset (&amp;param_value);\n"
+"  g_value_unset (&amp;result_value);\n"
+"\n"
+"  return retval;\n"
+"}\n"
+"\n"
+"static GSourceFuncs message_queue_source_funcs =\n"
+"  {\n"
+"    message_queue_source_prepare,\n"
+"    NULL,  /* check */\n"
+"    message_queue_source_dispatch,\n"
+"    message_queue_source_finalize,\n"
+"    (GSourceFunc) message_queue_source_closure_callback,\n"
+"    NULL,\n"
+"  };\n"
+"\n"
+"/**\n"
+" * message_queue_source_new:\n"
+" * @queue: the queue to check\n"
+" * @destroy_message: (nullable): function to free a message, or %NULL\n"
+" * @cancellable: (nullable): a #GCancellable, or %NULL\n"
+" *\n"
+" * Create a new #MessageQueueSource, a type of #GSource which dispatches for\n"
+" * each message queued to it.\n"
+" *\n"
+" * If a callback function of type #MessageQueueSourceFunc is connected to the\n"
+" * returned #GSource using g_source_set_callback(), it will be invoked for each\n"
+" * message, with the message passed as its first argument. It is responsible for\n"
+" * freeing the message. If no callback is set, messages are automatically freed\n"
+" * as they are queued.\n"
+" *\n"
+" * Returns: (transfer full): a new #MessageQueueSource\n"
+" */\n"
+"GSource *\n"
+"message_queue_source_new (GAsyncQueue    *queue,\n"
+"                          GDestroyNotify  destroy_message,\n"
+"                          GCancellable   *cancellable)\n"
+"{\n"
+"  GSource *source;  /* alias of @message_queue_source */\n"
+"  MessageQueueSource *message_queue_source;  /* alias of @source */\n"
+"\n"
+"  g_return_val_if_fail (queue != NULL, NULL);\n"
+"  g_return_val_if_fail (cancellable == NULL ||\n"
+"                        G_IS_CANCELLABLE (cancellable), NULL);\n"
+"\n"
+"  source = g_source_new (&amp;message_queue_source_funcs,\n"
+"                         sizeof (MessageQueueSource));\n"
+"  message_queue_source = (MessageQueueSource *) source;\n"
+"\n"
+"  /* The caller can overwrite this name with something more useful later. */\n"
+"  g_source_set_name (source, \"MessageQueueSource\");\n"
+"\n"
+"  message_queue_source-&gt;queue = g_async_queue_ref (queue);\n"
+"  message_queue_source-&gt;destroy_message = destroy_message;\n"
+"\n"
+"  /* Add a cancellable source. */\n"
+"  if (cancellable != NULL)\n"
+"    {\n"
+"      GSource *cancellable_source;\n"
+"\n"
+"      cancellable_source = g_cancellable_source_new (cancellable);\n"
+"      g_source_set_dummy_callback (cancellable_source);\n"
+"      g_source_add_child_source (source, cancellable_source);\n"
+"      g_source_unref (cancellable_source);\n"
+"    }\n"
+"\n"
+"  return source;\n"
+"}\n"
+
+#. (itstool) path: section/title
+#: C/custom-gsource.c.page:282
+#, fuzzy
+#| msgid "Furthermore:"
+msgid "Further Examples"
+msgstr "Además:"
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:284
+msgid ""
+"Sources can be more complex than the example given above. In <link href="
+"\"http://nice.freedesktop.org/\";>libnice</link>, a custom <code>GSource</"
+"code> is needed to poll a set of sockets which changes dynamically. The "
+"implementation is given as <code>ComponentSource</code> in <link href="
+"\"http://cgit.freedesktop.org/libnice/libnice/tree/agent/component.";
+"c#n941\">component.c</link> and demonstrates a more complex use of the "
+"prepare function."
+msgstr ""
+
+#. (itstool) path: section/p
+#: C/custom-gsource.c.page:293
+msgid ""
+"Another example is a custom source to interface GnuTLS with GLib in its "
+"<code>GTlsConnection</code> implementation. <link href=\"https://git.gnome.";
+"org/browse/glib-networking/tree/tls/gnutls/gtlsconnection-gnutls."
+"c#n871\"><code>GTlsConnectionGnutlsSource</code></link> synchronizes the "
+"main thread and a TLS worker thread which performs the blocking TLS "
+"operations."
+msgstr ""
+
 #~ msgctxt "text"
 #~ msgid "Tutorial for beginners (C)"
 #~ msgstr "Tutorial para principiantes (C)"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]