When I arrived to pyCamp (I'm at pyCamp!) 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.

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 qdbus to ask hal directly we get this answer:

Error: org.freedesktop.Hal.NoSuchProperty
No property battery.remaining_time on device

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):

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

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.

The problem has shifted to another place. Now I don't get the signal when is_chaging goes false. With lshal -m I can see the event:

11:48:46.823: computer_power_supply_battery_BAT0 property battery.rechargeable.is_charging = false

but I keep getting "Charging" from this code:

battery_data.value()["State"].toString()

where battery is a powermanagement data engine. Interesting enough, if I close the applet and load it again (as anyone debugging plasmoids, I'm using plasmoidviewer), that line returns the correct value of "NoCharge", which is what's spected.

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.


Update: it ended being a bug in Solid, after all. I posted a fix.

kde

Posted Mon 23 Mar 2009 09:41:16 PM CET Tags:
c

I'm implementing a wrapper of a C library for Python. The obvious choice is to write some C linked to libpython, and the not so obvious but simpler one is to use ctypes. ctypes is really simple to use: it has ways to declare structures and function types, with several classes that represents the simple types: c_int, c_char, c_char_p, c_void_p, etc.

Now, this library has a function, write(), 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:

void (*write) (const char *buf, size_t size);

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 c_size_t is already declared with the correct type, the corresponding declaration in ctypes is:

write_t = CFUNCTYPE(c_void_p, c_char_p, c_size_t)

This is what the ctypes documentation calls a callback function.

The problem arises with the c_char_p there. With this class, ctypes 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 \x00 ended, so its size it's determined by the first occurence of a \x00 in the memory space, while a buffer has to be accompanied by an integer, as I mentioned before. A \x00 cannot occur in a string (the trailing one is not always considered as part of the string per se), while it can occur several times in a buffer. In fact, a buffer can be entirely full of \x00's.

So what ctypes does here is to convert our buffer into a string. Any occurence of a \x00 in the original data will make c_char_p 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 \x00 in it, ctypes 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!

The solution is simple, luckly enough. You just neet to treat your buffer as a void * instead of a char *. So the declaration ends up being:

write_t = CFUNCTYPE(c_void_p, c_void_p, c_size_t)

The later, in our callback, we can convert that buffer into a str()[1] to manipulate it as such:

def write(buf, size):
    data = string_at(buf, size)

The size parameter is again important; if not, string_at() will again think in terms of string and not of buffer. I think this has to be improved a little. Maybe next PyCamp I'll file a bug and develope a patch, either for the code or the documentation; maybe both.


[1] This is Python 2.5

python c

Posted Thu 12 Mar 2009 03:24:20 PM CET

Tags:

Posted Thu 12 Mar 2009 03:24:30 PM CET

I'm implementing a wrapper of a C library for Python. The obvious choice is to write some C linked to libpython, and the not so obvious but simpler one is to use ctypes. ctypes is really simple to use: it has ways to declare structures and function types, with several classes that represents the simple types: c_int, c_char, c_char_p, c_void_p, etc.

Now, this library has a function, write(), 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:

void (*write) (const char *buf, size_t size);

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 c_size_t is already declared with the correct type, the corresponding declaration in ctypes is:

write_t = CFUNCTYPE(c_void_p, c_char_p, c_size_t)

This is what the ctypes documentation calls a callback function.

The problem arises with the c_char_p there. With this class, ctypes 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 \x00 ended, so its size it's determined by the first occurence of a \x00 in the memory space, while a buffer has to be accompanied by an integer, as I mentioned before. A \x00 cannot occur in a string (the trailing one is not always considered as part of the string per se), while it can occur several times in a buffer. In fact, a buffer can be entirely full of \x00's.

So what ctypes does here is to convert our buffer into a string. Any occurence of a \x00 in the original data will make c_char_p 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 \x00 in it, ctypes 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!

The solution is simple, luckly enough. You just neet to treat your buffer as a void * instead of a char *. So the declaration ends up being:

write_t = CFUNCTYPE(c_void_p, c_void_p, c_size_t)

The later, in our callback, we can convert that buffer into a str()[1] to manipulate it as such:

def write(buf, size):
    data = string_at(buf, size)

The size parameter is again important; if not, string_at() will again think in terms of string and not of buffer. I think this has to be improved a little. Maybe next PyCamp I'll file a bug and develope a patch, either for the code or the documentation; maybe both.


[1] This is Python 2.5

python c

Posted Thu 12 Mar 2009 03:24:20 PM CET Tags:

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 lindura (no me pidan redacción a esta hora de la noche).

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 slogan-de-una-empresa-gigantesca-de-software. Estuvimos Emanuel emanuel Sartori, Franco frapell Pellegrini, Manuel elpreto Ramírez y yo. Tomamos unos cafecitos, comimos unos tostaditos y charlamos.

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.

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 la lista kde-ar.

kde kde-ar

Posted Fri 06 Mar 2009 04:45:30 AM CET

Tags:

Posted Fri 06 Mar 2009 05:01:19 AM CET

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 lindura (no me pidan redacción a esta hora de la noche).

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 slogan-de-una-empresa-gigantesca-de-software. Estuvimos Emanuel emanuel Sartori, Franco frapell Pellegrini, Manuel elpreto Ramírez y yo. Tomamos unos cafecitos, comimos unos tostaditos y charlamos.

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.

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 la lista kde-ar.

kde kde-ar

Posted Fri 06 Mar 2009 04:45:30 AM CET Tags: