archives/2009/03StyXman's globhttp://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/StyXman's globikiwiki2010-01-27T22:55:55Zman-and-batteryhttp://grulicueva.homelinux.net/~mdione/glob//posts/man-and-battery/2010-01-27T22:55:54Z2009-03-23T20:41:16Z
<p>When I arrived to pyCamp (I'm at
<a href="http://www.python.com.ar/moin/PyCamp/2009">pyCamp</a>!) I was fighting
with a battery applet bug. When the battery is almost full the applet
got 'confused' and thought the battery just finished charging, and if it
where showing the remaining time, it switched to charge percentage,
which actually showed that it wasn't fully charged, but somewhere near
96% or so (this is wrong assuming the battery can fully charge up to
100%, as my 6 month old Dell battery). The problem was really that my
code was checking if the remaining time were 0 or not. So I started from
there down.</p>
<p>Down was it indeed. Seems like from time to time, when the bettry is
filling up, one can't ask hal about the remaining time. Using <code>qdbus</code> to
ask <code>hal</code> directly we get this answer:</p>
<pre><code>Error: org.freedesktop.Hal.NoSuchProperty
No property battery.remaining_time on device
</code></pre>
<p>This situation is not stable; sometimes I get the value I want. Not only
that, when the battery is full, the values get horrobly wrong. Here's
some samples (values are seconds since epoch and remaining time in
seconds):</p>
<pre><code>1237677446 1134
1237677746 261
1237677806 235
1237677866 313
1237677927 190
# at some moment in this gap the battery is fully charged
1237678167 188836
1237678227 152509
1237678287 112581
</code></pre>
<p>So I changed the algorithm to a more correct one; that is, ask if the
battery is charging or discharging or none of those (in that case the
battery is full) and show the time or the percentage accordingly. This
works, except that it doesn't.</p>
<p>The problem has shifted to another place. Now I don't get the signal
when <code>is_chaging</code> goes false. With <code>lshal -m</code> I can see the event:</p>
<pre><code>11:48:46.823: computer_power_supply_battery_BAT0 property battery.rechargeable.is_charging = false
</code></pre>
<p>but I keep getting <code>"Charging"</code> from this code:</p>
<pre><code>battery_data.value()["State"].toString()
</code></pre>
<p>where <code>battery</code> is a powermanagement data engine. Interesting enough, if
I close the applet and load it again (as anyone debugging plasmoids,
I'm using <code>plasmoidviewer</code>), that line returns the correct value of
<code>"NoCharge"</code>, which is what's spected.</p>
<p>I will try to file a bug against the data engine, or maybe Solid, and
wait for the fix before comitting the fix to this bug.</p>
<hr />
<p>Update: it ended being <a href="https://bugs.kde.org/show_bug.cgi?id=187600">a bug in
Solid</a>, after all. I posted
a fix.</p>
<p><a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/kde/">kde</a></p>
chttp://grulicueva.homelinux.net/~mdione/glob//tags/c/2010-01-27T22:55:54Z2009-03-12T14:24:30Z
<div class="inlinepage">
<div class="inlineheader">
<span class="header">
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../posts/ctypes-and-buffers/">ctypes-and-buffers</a>
</span>
</div>
<div class="inlinecontent">
<p>I'm implementing a wrapper of a C library for Python. The obvious choice
is to write some C linked to <code>libpython</code>, and the not so obvious but
simpler one is to use <code>ctypes</code>. <code>ctypes</code> is really simple to use: it has
ways to declare structures and function types, with several classes that
represents the simple types: <code>c_int</code>, <code>c_char</code>, <code>c_char_p</code>, <code>c_void_p</code>,
etc.</p>
<p>Now, this library has a function, <code>write()</code>, that handles a buffer. In
this case, for buffer I mean a fixed size space in memory with data,
paired with an integer telling us how much of the space is really data.
So basically its declaration is like this:</p>
<pre><code>void (*write) (const char *buf, size_t size);
</code></pre>
<p>The void pointer is because this is the type of a struct member that has
to point to such a function. Looking at that declaration, one would
think that, assuming a <code>c_size_t</code> is already declared with the correct
type, the corresponding declaration in ctypes is:</p>
<pre><code>write_t = CFUNCTYPE(c_void_p, c_char_p, c_size_t)
</code></pre>
<p>This is what <a href="http://docs.python.org/library/ctypes.html#callback-functions">the <code>ctypes</code>
documentation</a>
calls a <em>callback function</em>.</p>
<p>The problem arises with the <code>c_char_p</code> there. With this class, <code>ctypes</code>
assumes that the parameter is a string, and not a buffer. Both strings
and buffers in C are fixed size space in memory. The difference between
them is that strings are <code>\x00</code> ended, so its size it's determined by
the first occurence of a <code>\x00</code> in the memory space, while a buffer has
to be accompanied by an integer, as I mentioned before. A <code>\x00</code> cannot
occur in a string (the trailing one is not always considered as part of
the string <em>per se</em>), while it can occur several times in a buffer. In
fact, a buffer can be entirely full of <code>\x00</code>'s.</p>
<p>So what <code>ctypes</code> does here is to convert our buffer into a string. Any
occurence of a <code>\x00</code> in the original data will make <code>c_char_p</code> end the
string and forget about the rest of the data, ignoring the real size of
the buffer. Even more, if the original data has no <code>\x00</code> in it,
<code>ctypes</code> might cause a segmentation fault trying to find one beyond the
process' memory space. This not only corrupts data, but might even crash
the app!</p>
<p>The solution is simple, luckly enough. You just neet to treat your
buffer as a <code>void *</code> instead of a <code>char *</code>. So the declaration ends up
being:</p>
<pre><code>write_t = CFUNCTYPE(c_void_p, c_void_p, c_size_t)
</code></pre>
<p>The later, in our callback, we can convert that buffer into a
<code>str()</code>[1] to manipulate it as such:</p>
<pre><code>def write(buf, size):
data = string_at(buf, size)
</code></pre>
<p>The <code>size</code> parameter is again important; if not, <code>string_at()</code> will
again think in terms of string and not of buffer. I think this has to be
improved a little. Maybe <a href="http://www.python.com.ar/moin/PyCamp/2009">next
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../posts/pycamp/">PyCamp</a></a> I'll file a bug and
develope a patch, either for the code or the documentation; maybe both.</p>
<hr />
<p>[1] This is Python 2.5</p>
<p><a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/python/">python</a> <a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/c/">c</a></p>
</div>
<div class="inlinefooter">
<span class="pagedate">
Posted <span class="date">Thu 12 Mar 2009 03:24:20 PM CET</span>
</span>
<span class="tags">
Tags:
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/c/" rel="tag">c</a>
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/python/" rel="tag">python</a>
</span>
</div>
</div>
ctypes-and-buffershttp://grulicueva.homelinux.net/~mdione/glob//posts/ctypes-and-buffers/2010-01-27T22:55:54Z2009-03-12T14:24:20Z
<p>I'm implementing a wrapper of a C library for Python. The obvious choice
is to write some C linked to <code>libpython</code>, and the not so obvious but
simpler one is to use <code>ctypes</code>. <code>ctypes</code> is really simple to use: it has
ways to declare structures and function types, with several classes that
represents the simple types: <code>c_int</code>, <code>c_char</code>, <code>c_char_p</code>, <code>c_void_p</code>,
etc.</p>
<p>Now, this library has a function, <code>write()</code>, that handles a buffer. In
this case, for buffer I mean a fixed size space in memory with data,
paired with an integer telling us how much of the space is really data.
So basically its declaration is like this:</p>
<pre><code>void (*write) (const char *buf, size_t size);
</code></pre>
<p>The void pointer is because this is the type of a struct member that has
to point to such a function. Looking at that declaration, one would
think that, assuming a <code>c_size_t</code> is already declared with the correct
type, the corresponding declaration in ctypes is:</p>
<pre><code>write_t = CFUNCTYPE(c_void_p, c_char_p, c_size_t)
</code></pre>
<p>This is what <a href="http://docs.python.org/library/ctypes.html#callback-functions">the <code>ctypes</code>
documentation</a>
calls a <em>callback function</em>.</p>
<p>The problem arises with the <code>c_char_p</code> there. With this class, <code>ctypes</code>
assumes that the parameter is a string, and not a buffer. Both strings
and buffers in C are fixed size space in memory. The difference between
them is that strings are <code>\x00</code> ended, so its size it's determined by
the first occurence of a <code>\x00</code> in the memory space, while a buffer has
to be accompanied by an integer, as I mentioned before. A <code>\x00</code> cannot
occur in a string (the trailing one is not always considered as part of
the string <em>per se</em>), while it can occur several times in a buffer. In
fact, a buffer can be entirely full of <code>\x00</code>'s.</p>
<p>So what <code>ctypes</code> does here is to convert our buffer into a string. Any
occurence of a <code>\x00</code> in the original data will make <code>c_char_p</code> end the
string and forget about the rest of the data, ignoring the real size of
the buffer. Even more, if the original data has no <code>\x00</code> in it,
<code>ctypes</code> might cause a segmentation fault trying to find one beyond the
process' memory space. This not only corrupts data, but might even crash
the app!</p>
<p>The solution is simple, luckly enough. You just neet to treat your
buffer as a <code>void *</code> instead of a <code>char *</code>. So the declaration ends up
being:</p>
<pre><code>write_t = CFUNCTYPE(c_void_p, c_void_p, c_size_t)
</code></pre>
<p>The later, in our callback, we can convert that buffer into a
<code>str()</code>[1] to manipulate it as such:</p>
<pre><code>def write(buf, size):
data = string_at(buf, size)
</code></pre>
<p>The <code>size</code> parameter is again important; if not, <code>string_at()</code> will
again think in terms of string and not of buffer. I think this has to be
improved a little. Maybe <a href="http://www.python.com.ar/moin/PyCamp/2009">next
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../posts/pycamp/">PyCamp</a></a> I'll file a bug and
develope a patch, either for the code or the documentation; maybe both.</p>
<hr />
<p>[1] This is Python 2.5</p>
<p><a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/python/">python</a> <a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/c/">c</a></p>
kde-arhttp://grulicueva.homelinux.net/~mdione/glob//tags/kde-ar/2010-01-27T22:55:55Z2009-03-06T04:01:19Z
<div class="inlinepage">
<div class="inlineheader">
<span class="header">
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../posts/kde-cba-primera-reunion/">kde-cba-primera-reunion</a>
</span>
</div>
<div class="inlinecontent">
<p>No somos muchos en Córdoba. Tal vez uno 10, tal vez menos. Pero tenemos
un objetivo común: hacer KDE, y hacerlo una mejor plataforma para
nosotros, y para todo el mundo. Este objetivo tan amplio incluye desde
desarrollar aplicaciones o simples features, arreglar bugs, hasta
reportarlos, difundir un poco su potencia y <em>lindura</em> (no me pidan
redacción a esta hora de la noche).</p>
<p>Por eso nos juntamos esta noche a tomar unas cervezas y ver en qué parte
de este objetivo quiere estar cada uno, y hasta dónde cree llegar hoy
día y <em>slogan-de-una-empresa-gigantesca-de-software</em>.
<a href="http://grulicueva.homelinux.net/~mdione/gallerpy/index.py/pictures/kde-ar/M01CBA/IMG_5571.JPG">Estuvimos</a>
Emanuel
<em>emanuel</em> Sartori, Franco <em>frapell</em> Pellegrini, Manuel <em>elpreto</em> Ramírez
y yo. Tomamos unos cafecitos, comimos unos tostaditos y charlamos.</p>
<p>Cosas concretas aún no tenemos; somos pocos, y si bien eso parece
simplificar la organización, hace que sea difícil que pensemos en
exactamente lo mismo. Lo que sí sabemos que ésta no es la última
reunión, y que en las siguientes vamos a estar viendo de hacer lo que
cada uno quiere aprovechando lo que el otro sabe. Esto puede parecer
poco, pero la idea es fortalecernos con el tiempo.</p>
<p>Aún no hay fecha fija; queremos que sea la semana que viene, pero
empiezan las clases y eso significa cambios de horarios para muchos. Ya
avisaremos con anticipación en <a href="https://listas.usla.org.ar/cgi-bin/mailman/listinfo/kde-ar">la lista
kde-ar</a>.</p>
<p><a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/kde/">kde</a> <a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/kde-ar/">kde-ar</a></p>
</div>
<div class="inlinefooter">
<span class="pagedate">
Posted <span class="date">Fri 06 Mar 2009 04:45:30 AM CET</span>
</span>
<span class="tags">
Tags:
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/kde/" rel="tag">kde</a>
<a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/kde-ar/" rel="tag">kde-ar</a>
</span>
</div>
</div>
kde-cba-primera-reunionhttp://grulicueva.homelinux.net/~mdione/glob//posts/kde-cba-primera-reunion/2010-01-27T22:55:54Z2009-03-06T03:45:30Z
<p>No somos muchos en Córdoba. Tal vez uno 10, tal vez menos. Pero tenemos
un objetivo común: hacer KDE, y hacerlo una mejor plataforma para
nosotros, y para todo el mundo. Este objetivo tan amplio incluye desde
desarrollar aplicaciones o simples features, arreglar bugs, hasta
reportarlos, difundir un poco su potencia y <em>lindura</em> (no me pidan
redacción a esta hora de la noche).</p>
<p>Por eso nos juntamos esta noche a tomar unas cervezas y ver en qué parte
de este objetivo quiere estar cada uno, y hasta dónde cree llegar hoy
día y <em>slogan-de-una-empresa-gigantesca-de-software</em>.
<a href="http://grulicueva.homelinux.net/~mdione/gallerpy/index.py/pictures/kde-ar/M01CBA/IMG_5571.JPG">Estuvimos</a>
Emanuel
<em>emanuel</em> Sartori, Franco <em>frapell</em> Pellegrini, Manuel <em>elpreto</em> Ramírez
y yo. Tomamos unos cafecitos, comimos unos tostaditos y charlamos.</p>
<p>Cosas concretas aún no tenemos; somos pocos, y si bien eso parece
simplificar la organización, hace que sea difícil que pensemos en
exactamente lo mismo. Lo que sí sabemos que ésta no es la última
reunión, y que en las siguientes vamos a estar viendo de hacer lo que
cada uno quiere aprovechando lo que el otro sabe. Esto puede parecer
poco, pero la idea es fortalecernos con el tiempo.</p>
<p>Aún no hay fecha fija; queremos que sea la semana que viene, pero
empiezan las clases y eso significa cambios de horarios para muchos. Ya
avisaremos con anticipación en <a href="https://listas.usla.org.ar/cgi-bin/mailman/listinfo/kde-ar">la lista
kde-ar</a>.</p>
<p><a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/kde/">kde</a> <a href="http://grulicueva.homelinux.net/~mdione/glob//archives/2009/03/../../../tags/kde-ar/">kde-ar</a></p>