Tuesday, June 19, 2007

Public Key

You can find my key on the public servers. I specifically post it to hkp://keys.gnupg.net.

pub 4096R/77292AC1 2009-02-23 Eric Polino (aluink)
Key fingerprint = E516 191C 79D1 C904 CF5C B45A E9D3 1121 7729 2AC1

Friday, June 15, 2007


Finch now has sound. It took me only a couple hours to get it in too! Before you do thinking I'm some big genius for doing it so fast, just wait a minute. Sound works pretty much the same way as Pidgin sound works, or at least it should since I copied that code over. I know, I know copying code is one of the seven deadly since of coding. Let me talk about that for a bit.

As it stands, sound is directly in Finch. This isn't the optimal solution since many folk don't want sound in their console application. This is because remoting into a box and having sound go off can be rather unsettling for the parties in the same room as the serving machine. So as it stands the sound is directly in Finch, but will most likely be moved later to either a plugin or something to make it an optional feature. One could argue that all a user has to do is disable sound when they are remoting in, but that can get dicey and an unneeded extra the user has to worry about. This would diverge from the simple model which Pidgin tries to achieve. So a plugin sounds likely.

We are discussing options for how to deal with this on the mailing list right now. I'll provide an update later when a decision is reached.

Tuesday, June 12, 2007

New Projects

Sorry for having been quiet in the last few days. I've been busy here at home and haven't been working as hard as I was last week. The well here at home is having some issues, so we haven't had water the last two days and won't have any tomorrow. In any case, here are some bits of information on a few things I've been doing and a little info on what is to come.

The other developers have put a lot of work into building workspaces. I haven't had time to look at it yet, but I'm assuming that it's like having multiple desktops in a graphical environment. So they did lots of work on that and had merged all their work into the upcoming release branch. So I propagated those changes into my branch. That was a lot of work since there were many conflicts to resolve. Thanks to the help of meld, it wasn't too bad. The default conflict resolution tool is Vim and I'm glad I didn't use that. I might figure it out sometime later because I'm a Vim addict, but for now, I'm glad I had a nice graphical tool to do it with.

I have also received permission to create a few sub-branches to my branch. See I don't have commit access to the entire MTN tree. I'm only allowed to commit to my branch, im.pidgin.soc.2007.finchfeat. So I asked if I could create three sub-branches, .sound, .logging, and .bindings, so that I can work on the other parts of my project separate from eachother. In the end I will merge those changes together of course, but in the mean time if I get one working, those change can be pulled into another branch to be incorporated into a release without having to worry about the changes in the other projects affecting anything. When I start doing the little things I was hoping to do, I will either create another sub-branch for that or just do it in .finchfeat directly. I'll cross that bridge when I get to it.

So there is a little update on some work. I hope to start working on .sound in the next few days. I've already begun to do some research and think I know where I'm going with it. Having a good foundation on how things works already is allowing me to work faster now. A great feeling!!!

Friday, June 8, 2007

Object Orientation in C

If you ask a common programmer to list a few languages that are object oriented they will most likely list ones like, Java, SmallTalk, C++, Ruby, and so forth. You won't hear people say that C is an OO language, because it isn't. This doesn't mean it doesn't have the capability of doing it though. Working with libgnt, the console based graphical library Finch uses, I am using a lot of OO design built in C. I'd like to give just a short intro to how it all works because I think it's rather neat.

Classes are defined with structs. Thus all the member variables are simply put into a struct and methods that operate on a class are function pointers in a struct. Because C doesn't have a native concept of OO, if a class were declared with both member variables and member functions defined in the same struct, a waste of memory would ensue. Every time an instance of a class would be created, those pointers would be created again. So a separation of static members and instance members much be created. This can be done in many ways, but a common convention and the one used by libgnt is to create another struct called ${CLASSNAME}Class. This struct would contain all the function pointers for the given class, and would also hold any static variables.

The following is a simple example of a circle class that stores some basic circle information and a few methods that operate on circles.


#ifndef __circle_h__
#define __circle_h__

typedef struct _Circle Circle;
typedef struct _CircleClass CircleClass;

struct _Circle {
float radius;

struct _CircleClass {
float pi;
void (*draw) (Circle * c);
float (*get_circumference) (Circle * c);

void (*set_radius) (Circle *c,float r);
float (*get_radius) (Circle *c);

Circle * (*new) (float r, int c);
void (*destroy) (Circle *);

CircleClass * get_circle_class();


#include "circle.h"


static void circle_draw(Circle * c){
/* Do the drawing here */
printf("Drawing a circle with radius %f\n",c->radius);

static float circle_get_circumference(Circle * c){
return get_circle_class()->pi * c->radius * 2.00;

static void circle_set_radius(Circle *c, float r){
c->radius = r;
static float circle_get_radius(Circle *c){
return c->radius;
static Circle * circle_new(float r, int color){
Circle *c = (Circle *)malloc(sizeof(Circle));
c->radius = r;
return c;

static void circle_destroy(Circle *c){

* Exported Methods *

CircleClass * get_circle_class(){
static CircleClass * klass = NULL;

if(klass == NULL){
klass = (CircleClass *)malloc(sizeof(CircleClass));
klass->draw = circle_draw;
klass->get_circumference = circle_get_circumference;
klass->get_radius = circle_get_radius;
klass->set_radius = circle_set_radius;
klass->new = circle_new;
klass->destroy = circle_destroy;

klass->pi = 3.14;
return klass;


#include "circle.h"

int main(){

CircleClass * klass= get_circle_class();
Circle * c = klass->new(2.45,6);

float circum = klass->get_circumference(c);
float radius = klass->get_radius(c);

printf("Circle Data\n\tCircumference: %f\n\tRadius: %f\n",circum,radius);



return 0;

Object orientation wouldn't be worth much without some inheritance. So let's see how that's done. It's actually very simple. The first member of the struct is the parent struct. So if you cast an object to it's parent-type, you have a pointer to it's first member, and parent class instance. Isn't that just neat! The following shows how to add a Shape parent class to Circle.


#ifndef __shape_h__
#define __shape_h__

typedef struct _Shape Shape;
typedef struct _ShapeClass ShapeClass;

struct _Shape {
int color;
int border;

struct _ShapeClass {
void (*set_color) (Shape *c, int color);
int (*get_color) (Shape *c);

void (*set_border) (Shape *c, int border);
int (*get_border) (Shape *c);

void * shape_class_init(ShapeClass *sc);



#include "shape.h"

static void shape_get_border(Shape *s){
return r->border;
static void shape_set_border(Shape *s, int border){
s->border = border;

static void shape_set_color(Shape *s, int color){
s->color = color;
static int shape_get_color(Shape *s){
return s->color;

* Exported Methods *

void * shape_class_init(ShapeClass *sc ){
ShapeClass *sc = ShapeClass *)malloc(sizeof(ShapeClass));

sc->get_color = shape_get_color;
sc->set_color = shape_set_color;

sc->set_border = shape_set_border;
c->get_border = shape_get_border;
And a few changes to the first few files.

#include "shape.h"

struct _Circle{
Shape parent;
/* other members */

struct _CircleClass {
ShapeClass parent;
/* other members */
Circle * (*new) (float r, int color, int border);

static Circle * circle_new(float r, int color, int border){
Circle *c = (Circle *)malloc(sizeof(Circle));
Shape *s = (Shape *)c;
c->radius = r;
s->color = color;
s->border = border;
return c;

CircleClass * get_circle_class(){
static CircleClass * klass = NULL;
ShapeClass *sc;

if(klass == NULL){
klass = (CircleClass *)malloc(sizeof(CircleClass));
klass->draw = circle_draw;
klass->get_circumference = circle_get_circumference;
klass->get_radius = circle_get_radius;
klass->set_radius = circle_set_radius;
klass->new = circle_new;
klass->destroy = circle_destroy;

sc = (ShapeClass*)klass;
/* override anything here */
klass->pi = 3.14;
return klass;

So there you can see how things are inherited. A simple cast gets you the parent object. There should only be one instance of CircleClass and it should contain a unique instance of ShapeClass that will be shared among all circles.

This demonstration was very rough and dirty and probably has a few problems since I wrote it up pretty fast and had a baby to deal with while I was piecing it all together, but I'm sure the basic concept makes sense. With the help of GLib and its object instantiation framework this design works a lot better. GLib gives you abstract classes, interfaces and much more, but things are still all in C.

This probably isn't the recommended way of doing OO, but the point is that C can do it. Hope this was informative and it has encourages you to dig a little deeper. If this is case, I recommend you read this paper on OO in C.

Wednesday, June 6, 2007

Key Reassignment Done

After many hours of research and coding I finally got the key reassignment capabilities in. Though it turned out to be a simpler task than I had expected, it still had its own series of bumps and surprises along the way.

The first and obvious bump was for me to become familiar enough with how things work to be able to utilize and modify the current code to make it do what I want it to do. But like I said above, this was one of the simpler things in the end. The association of keys to actions is setup like this. Every GntWidget is a GntBindable. GntBindable is associated with GntBindableClass. GntBindableClass contains three hash tables. The first we won't bother talking about here, but the other two are of interest to us.

The first table contains (name,Action) key/value pairs. The names are strings like "gained-focus", "window-moved", "key-pressed", etc. The Actions are the the functions performed. The second table contains (key,ActionParam). The keys are simply strings that represent keystrokes entered by the user. Then the ActionParam contain an action and parameters that are passed to that action.

So now when a key is pressed, the associated ActionParam is looked up from the related hash table and it is executed, simple as that. Sure there are some tricky things to happen along the way as far as what gets to execute the action, the window manager, a window, or a widget inside that window, but that's beyond the scope of this post. Maybe someday when I have nothing to write about, I'll post some more information on that.

Now that you have a basic understanding of how actions are performed based on keystrokes, I can tell you how assigning new key combinations to actions is done. When the user types alt-/ or alt-\ for widget or window manager reassignments, respectively, a list of available actions are displayed. From there a user scrolls to the desired action and hits . The needed information is given to a new window. This information being, ActionName, original key combination, and the GntBindable being modified; keep in mind that the window manager is a GntBindable also. From there we can get the GntBindableClass. The user then types in a new keystroke and selects the Bind button.

To replace a key assignment, two reassignments need to be done. First we reassign the old keystrokes to activate a NULL action. The reassignment function treats this as a delete action and deletes the (oldKeys, ActionParam) entry in the table. Then a second call to the same function is made with the new key combination. From the name, an Action is retrieved from the (name,Action) hash table. An ActionParam is created by associating this action with the parameters passed in. At this point, no actions make use of parameters, so this process will have to be modified slightly later to pass along needed parameters. Then it simply puts an entry in the (key, ActionParam) table with the new keys and the new ActionParam.

Sure one could argue that a function that takes two key combinations could change the key from the old to the new combinations. But since this is done very seldom, there isn't much of a need for this function. Maybe someday, it will be added.

So there you have it, this is how key reassignment is done. Feel free to ask some questions if certain parts are unclear. I will give some updates in a while, since this process still has some refining to do, such as some windows have special keystrokes they handle.

Tuesday, June 5, 2007

Payment #1

This year Google has decided to pay us via Western Union (WU). I guess last year they were sending checks and doing wire transfers. They were having issues with a lot of the wire transfers and in some countries the checks would take weeks to clear. So they spent a lot of time this year looking for a better solution. This solution was to pay most of us with WU and to setup wire transfers for the rest of the student where WU wasn't a viable option for their country. So, needless to say, being in the US I am one of the students getting paid with WU.

The fun all started when I went to get my payment the first time. It was Monday evening. I went down to the local WU agent at the Rite Aid. So I had all the information and identification I needed with me. I had a bad feeling things were going to go sour when I told them I was there to receive. They asked me how much, so I told them $500. They immediately had this look like they weren't sure they had enough, but they checked things out and had enough. So now they tried to run it through and it wanted a phone number. I told them I didn't need one, but she persisted that she couldn't run it without. Somewhat annoyed I told her I'd go home and write to get a number. Well, I didn't need a number; she even tried it without after I left and it worked. I'll refrain from calling her names, but that really ticked me off that she did that. So when I came back the next day to tell her that I didn't have the number and to try it without, she then told me that I didn't need it. So I had wasted a whole day, remember I don't have a car, so I have to wait for Holly to come home with the car to run down there. So any delays in the evening and I have to wait another whole day.

Moving on to the second hurdle, my information was entered wrong by the sender. Yes, Google is capable of making mistakes. They had entered my city as Newport, Nebraska instead of Newport, New Hampshire. WU wouldn't let the payment go through cause I was in the wrong district. When I wrote Google about it, it took 6 hrs to get a reply...they learned quickly what didn't work. I guess there were a lot of mistakes on the first batch. All the sender had to do was call WU and have my address changed. For some reason I was told my payment would be ready on Friday. Not sure if that was because they would send my updated information along with the second batch or what, but that was the case. So I had to wait till Friday to get it.

Come Friday I went back to Rite Aid to try again. This was my 5th trip there, I was about done with any type of screwing around. This time I couldn't get paid cause they didn't have $500 to give me, mistake #2 by Rite Aid. WU pays by check, you can cash that check wherever you want. I didn't know that at the time. So I agreed and left. It was already late and I didn't want to head out to the next town to go to the other WU agent out there. So I had to wait till Sunday now.

Finally on Sunday, I went to the other town, found the other agent, and got paid. This was when I found out it was just a check and I could have gotten paid on Friday. I was happy enough to get cash in my hands that I wasn't able to be upset. But looking back on it now, I'm just ticked at the fact that Rite Aid wasted 3 days for me. The first time they wasted a day cause I could have tried it then to find out that my address was wrong. The second time they wasted two days, cause I could have gotten paid on Friday, but instead had to wait till Sunday. I HATE HAVING MY TIME WASTED!!

So there you have it, my story of how I got my first pay from Google Summer of Code. You can find proof with this receipt.

Monday, June 4, 2007

Label Issues

I spent a good deal of time yesterday trying to figure out why a simple piece of code wouldn't work. I was working on the key binding stuff again. The way I want it to work is for the rebinding window to display the key combination caught to the user. When the window is first drawn it displays a label that contains 'KEY:""' (the single quote are for the reader and the double quotes actually appear in the label). Then when the user types in a combination it should update to 'KEY:"comb"', where comb is a human readable representation of the key combination entered by the user. Well, it's a pretty easy setup, you have a key_pressed listener that gets the label as an argument. A quick lookup to convert the keys received to a nicer format. Then a quick update to the label text and it should work nicely.

After several hours of staring at the code, quite a bit of research into the underlying code. I simply couldn't figure out why the label wouldn't update. I tried printing the keys out to stderr but something weird was happening there too. When I printed out the ASCII values one at a time, they came out nicely, as I would expect. But when I tried printing them out as a string, it printed blank. Well, come to find out, the problems with fprintf and label updating weren't related, they just happened to yield the same result. When we tried a quick test by executing printf("%s\n","\033" "a"), the equivalent to Alt-a, only a newline would print. So it was just a nuance of printf behavior. The issue with the label was different.

I spoke with my mentor for about an hour about this issue and finally he decided to pull the code and have a look for himself. He was taking too long, so at about 0030 I went to bed. He wrote back at 0200 saying he figured out what was wrong. It seems that when gnt_label_draw() was being called, it would first set an INVISIBLE flag, but failed to unset it before returning. It was a quick fix that required a lot of digging. So he fixed it and pushed it upstream. This morning I did a pull and merged his changes into mine and it worked.

Now we have issues with the label not redrawing nicely. But at least it's redrawing now. So I get to continue hacking away at this project.

Friday, June 1, 2007

Key Reassignment

So the first part of my project this summer is to work into Finch the ability to (re)bind keys to actions. So far I haven't done much productive work because I'm still learning how the API works. As it stands now, I have built a window that flows from a window listing the actions available to the current widget and the key bindings associated with those actions.

When I started working, the window listing the key assignments and their associated actions was already created. The user was able to hit a key combination (Alt-/) and it would come up showing a listing for the widget currently in focus. The user was able to scroll up and down the list, but it was merely informational. I took this and added the ability to hit on a given keystroke/actions pair. Pressing on a pair triggers the creation of a new window that prompts the user to type in a new key combination to be bound to the action. It's a pretty simple concept, one that most who have dealt with modifying shortcuts for a window manager have seen before.

The hard part I'm still trying to figure out is how to gather all the needed information I'll need when the rebinding call occurs. I need the following information: key combination, the class object for the widget, callback function for the action, name for the action, and an optional list of parameters to pass to the callback function. The key combination is trivial, I grab it from the user and store it. The class of the widget I can get from the parent window that listed all the keystroke/action pairs. The callback function is tricky, I haven't figured out how to do that yet. The name of the action I can get from the keystroke/action listing window. The parameters I really don't know what to do here. I'm not even sure if any of the actions take parameters at this point. I get the feeling this is just a feature that is available but not being used yet. So I'll have to talk to Sadrul, my mentor.

So as can be seen, all the information I need for the reassignment is available at the start of this process. My only task is to gather it, grab a new key combination from the user and call a register_action method. Depending on how things are implemented, I might have to check to see if another action is bound to that key combination to prevent double assignments. This is another thing I'll have to talk to my mentor about.

I can't wait to get to a point where I can commit my code and have the other developers tell me what is good and what needs to change. I am often stressed about not knowing whether a way of doing something is bad and/or not liked by the Pidgin development team. On the other hand this is causing me to really think about how I do things. So that in the end, if they don't like something I did, I can at least have something to stand on and defend my method. This could possibly even bring a new concept to the team, thus offer change and benefit.

Thursday, May 31, 2007

Micro Merging

At first I thought to keep my code under both Mercurial, for MQ, and Monotone(MTN), because Pidgin is kept under MTN. But after a bit of work, I've found that it's really annoying. So, as much as I like MQ and think it's a fantastic idea, maintaining code under two DVCS's is too much work for what I want to get out of it. I won't be able to use patch queues until I either get Pidgin to convert to a DVCS that uses patch queues, or when MTN gets them incorporated.

So I am having to find alternate means of doing some of the things I could do with patch queues. So yesterday when I was working on incorporating the ability for Finch to reassign keys, I found that it required additional functionality before this could work. So I had a problem. I couldn't just make those changes then, because they would be incorporated into the same patch of adding reassignment capability, because that would create a messy/non-discrete patch. I also couldn't revert my code back to the previous revision, because that would lose all the changes I had already made. So I was caught. After a bit of thinking it became clear that the solution was simple, due to the power provided by the decentralized nature of MTN. The answer was a micro branch.

I won't bother going into too much detail because MTN micro branching is described well on the wiki. So I had my original revision (OR) that existed before I started any of my work, and I had a new revision that I was working on, we'll call it the reassign revision (RR). But I found that I had to write some code to temporarily ignore keystrokes at the window manager level and had to write code to do that before my RR could work. So I had to write an ignore keys revision (IR). So as it stood my DAG looked like this.

 ... OR --> RR

But for my RR to work properly I had to put in a revision between OR and RR. That's not possible due to the nature of VCS's. So I decided to apply the changes to start IR with OR as its parent. Thus my graph would look like this now.

... OR

Now IR doesn't happen after RR, which was the primary goal of this exercise. So all I have to do is make sure both IR and RR work well on their own and I can merge the branches when I'm done creating a new revision of both the changes called ignore keys and reassign revision (IRR), creating a DAG that looks like this.

/ \
... OR IRR
\ /

This same idea can be used quite nicely for bug fixes. The process is called daggy fixing. I find this method to be very nice and provides for a cleaner and more readable graph.

Friday, May 25, 2007

Patch Queues

The idea of Version Control Systems is awesome. A Decentralized Version Control System is an even greater idea for a distributed working environment such as the, and most, project I'm working on now.

Also a great idea is the idea of diff patches. To be able to take an original file and compare it to a modified version and get a representation of the changes is great for programming. Taking this idea a step further you get patch queues.

The idea of a patch queue is rather simple. Before you start working, you initialize a queue that will store a series of patches to be applied to a file or group of files. You then create a patch. Then you proceed as normal and work. At any point you can update the patch to reflect the changes that have been made since the start of the patch. So far so good right? Now comes the awesome part. After having updated a patch to reflect the changes, you can then start a new patch and push it on top of the first patch. This patch will reflect a series of other changes. After having updated this patch you can now do one of the following. You can either push a new patch on the queue or you can pop the new patch off the queue to modify the first patch. When you are satisfied with the changes you've made to the first patch you can then push the second patch back on top and continue working on it! Genius, pure genius!

A good friend of mine, you know who you are buddy, brought this concept to my attention minutes after I was accepted into GSoC saying, "You are going to need this.". I hadn't bothered to make it much available because one of the Pidgin developers told me that the project was too simple and we didn't need that kind of functionality. Well, after a bit of work I found that I didn't agree. It wasn't two days after I had started working on my first set of changes that I was looking for the ability to push multiple patches onto a queue as I worked. It's not that my work was very complicated, in fact the bit of work I was doing was only like 10 lines of new code. It was that midway in my work I wanted to go make a small change to a function somewhere else and I didn't want to confuse my current changeset. By being able to push a new patch, make those changes, and then come back to the first patch, it would have made it simple.

Now if this idea of patches queues doesn't blow you out of the water, how about I tell you that Mercurial has built into their system the ability to tie in both patch queues and a DVCS? Think of it, for as long as VCS's go back, once you commit a change, they are there forever, you can't take them back. Some allow you to disapprove changes, but this can get rather dicey. With the idea of patch queues into a DVCS, patches are treated as changesets. The only difference is that you can move up and down the graph with the use of a patch queue and modify a changeset after it was "committed". Mercurial has called them Mercurial Queues (MQ). I know rather little about project development, but I can see the beauty of this system. I encourage others to use it and lavish in its power.

Tuesday, May 22, 2007

Finally Some Code

Well after a lot of code reading and discussions in IRC I think I've gotten to a decent understanding of how Finch works and can start to code now. So before I get going on stuff I wanted to do something that wasn't too intensive but could get my feet wet. So I decided to scratch an itch and work around how Alt- doesn't send a meta for some terminals.

A little explanation is due here. When you type Alt-c two outcomes can result. If alt sends a meta character it sends an escape sequence. If it doesn't it sends something rather difference, but reversible. As an ESC sequence it sends {'\033', 'c', 0}. Then when it doesn't send an ESC sequence it sends {-'c', 0}. These are series of characters, so '\033' is the octal 33 ASCII character, decimal 27, ESC and 0 is the null character denoting the end of string in C. So the code to check and convert is as follows.

if(*k < 0){
    *(k + 1) = 128 - *k;
    *k = 27;
    *(k + 2) = 0;

The variable k is the sequence of characters sent from the terminal and rd is the number of characters received. I put this code very near to the beginning of key_pressed processing so that the rest of the code can still work based on the values being sent as escape sequences.

Then came time to commit this code to the repository. I've worked with decentralized version control systems(DVCS) before. Well, I've only used Mercurial, but it rocks. One quick note about it and I'll return to it later in another post. But I really like how Mercurial builds the concept of patch queues into it's client. An idea not born in Mercurial, but very powerful. More on that later. The basic idea of a DVCS is that instead of working with a central repository and committing to it all the time. You pull the entire codebase and revision DAG to your local machine and this becomes your working copy. From there you can work, commit locally and do all that a regular VCS does. But when you decide to, you can push your changes upstream and they are merged in with the central repository. Or, if you don't have commit privileges, you can notify a developer who does and they can verify your work and pull your changes upstream. The beauty about this is that a revision DAG can have many heads now and they can be merged in whenever you want.

So I had done my work locally and has committed them and was now ready to push my changes upstream. I have commit privileges to my very own branch, isn't that just nice! So I ran my push command and in a few short moments, they were up.

Then some fun came along shortly there after. A developer let me know of a few things I had done that weren't, the best lets say. For starters I had left some debugging code behind that I might have used later. I figured it wasn't a big deal because this was my own branch and I'd clean it up later when it would be merged back into the main branch, but I can see his point. If I make this into a habit of leaving stuff behind, when it comes time to merge back into central, I won't be able to remember all the stuff I have behind. So keep it clean to save work later.

Secondly, Pidgin develops under the C89 standard. I had put in a few comments that were C99. I was completely clueless as to what that was supposed to mean. So I did a bit of research and talked to a few guys in IRC and learned that C had a standard developed in 1989, called the C89 standard. Then in 1999, they created the C99 standard. To be fully compatible with new and old compilers we are implementing the C89 standard. So // comments aren't allowed. There are a few other things too. For instance you have to declare all your variables at the top of the method or namespace. You can't declare them wherever like in Java. I think this is a good practice in general and have always done that, so this isn't a big issue for me. In any case, I've ordered the famous K&R book that teaches C89.

So when all that was fixed I had committed my first bit of code. It was a nice feeling. Now I'm working on some more and hope to have it committed today.

Tuesday, May 15, 2007

...more tools...

Tools, tools and more tools...I've been hacking around Finch code all morning trying to understand key bindings. It's slow going, but I'm getting there. Though I haven't learned much to talk about in regards to Finch and its library libgnt, I have learned a lot of useful things that I will continue to use and encourage others to use.

GLib is a powerful library that I wish I had learned a long time ago. For documentation on the functions it has available check this site out. For years I've been writing code and using functions like the ones available here, but I always wrote my own. What a relief to find a library that has all this in it.

My favorite so far is the logging features it has. By calling g_log(), g_print(), or a few others that have different logging levels, it can log all sorts of stuff for you. The cool part is that you can define a method to handle the printing. If you call g_log with different logging levels it will alter where it prints, either to stdout or stderr.

It has many string utility functions. Many are in string.h, but a bunch aren't and I've had to write a few of them in the past. It's nice to have them all here.

It's very easy to use. All you have to do is include glib.h and when you compile you pass it pkg-config. So, "gcc `pkg-config --cflags --libs glib2.0` test.c test" and it works.

So this has been very useful, for future use and because Pidgin is filled with glib use.

Another useful thing I've learned is the use of ctags. Now I've used ctags a few times before. But with the help of my mentor and a few docs I stepped it up a bit. For those of who aren't too familiar with ctags here's a short run through getting things setup.

  1. Run "ctags -R" at the top of your source tree
  2. Open my favorite text editor, Vim, at the root of your source

That's it for getting setup. Now you have the capability to bounce from function call to function with a simple keystroke. Put your cursor over a function call and type CTRL-]. It will take you to the definition of the function. You can do this with variable and custom data types also. Vim stores the jumps you've made in a stack. To pop the last jump off the stack and return to where you were looking type CTRL-t. And voila, you've come back. This has made browsing code , and following it more importantly, a breeze.

The last thing I'd like to mention today is syntax highlighting. I've heard some complain about editors that apply syntax highlighting and say that it makes it more confusing for them to read and understand the code. Well, more power to them for not using this feature. I like it, I find it useful for reading code and I shall continue to love using it. But what I found today was a site that has a list of custom color schemes for a few languages. I'll focus on the link to the C schemes. I looked at a bunch of them, I found that I like the asmanian2 theme. Though, I don't like how it bolds a lot of things. So I'm still working on getting the bold out. :help colorscheme and :help hightlight-args has been a good help in modifying the theme.

Friday, May 11, 2007

Getting Ready

Well now that I've moved in. I've started to get going with my project. I've outlined a few things I want to get done before I can really start programming.

  • Scheduled Milestones
  • Understand Pidgin
  • Details of Implementation
  • Discuss details with Other Developers
  • Detailed Goals
  • Final Approval of Plans
  • Go
Scheduled Milestones

I went ahead and scoped out my deliverables and decided how long I think it should take me to accomplish each of them. Then I scheduled them into my summer. By clicking on the link to my Google calendar you can see what I've got there so far. It's very simple for now, but as I continue working I will add more details to it as I go.

Understand Pidgin

This is going to be a tough undertaking. Pidgin is a reasonably large application. I found a link to a diagram that outlines how Pidgin works. One of my current problems is knowing when to build something as a plugin and when not to. When I spoke with the other developers in IRC, they weren't able to give me a defined line that defined the difference between a plugin and non-plugin feature. I guess I'll have to learn that as I go, or it will become a feature by feature decision, which seems to be the most likely answer at this point.

On the other hand, I was able to get a better picture of how things work as I we spoke yesterday. The idea seems somewhat simple when you think about it for a while. The core manages all the internals that don't require external libraries. The core is made up of pure C functions. It connects to a group of prplInfo structs that give it the ability to communicate over multiple protocols. It is connected to a user interface(UI). Pidgin is a UI that uses GTK+ and Finch uses libgnt. Both the core and the UI can be added to by the use of plugins.

So now I think I have a decent understanding of the general system. I need to get working on understanding the inner workings of its components.

Details of Implementation

Once I have a good understanding of Pidgin, I will begin working on planning out the details of how I will implement my goals for Finch.

Discuss Details with Other Developers

Then after I've planned out the details of how I plan to achieve my goals, I'll discuss it with my mentor and the other developers. From here I hope to iron out things that wouldn't work, or find better ways of reaching my milestones.

Detailed Goals

Once all that is planned and ready to go. I'll break down my implementation into discrete goals. I'll take those goals and put them into my calendar. This will allow me to focus on small goals at a time. Furthermore, it will give me the ability to gauge how I'm doing, if I'm on schedule or running behind.

Final Approval of Plans

Just before I actually start working on things, I'll get a final approval of my plans and how I've laid out my timeline.


With all things ready, I shall set out to change the world...at least the world as it related to Finch.

Wednesday, May 9, 2007

Moved In

office, desk, computerWell I've made the move from Tennessee to New Hampshire where I'll be for the rest of the summer. I had to rearrange a storage room, but in the end it's become quite the little office I've created for myself. On the left here you can see what it looks like just outside the entrance. The house itself is very old, built back in 1836. The room itself is located on the other side of the garage.

office, desk, computer, programmerNext is my workstation. It's still not fully setup, I want to get some of the junk out of the way and put something more useful there. I'm thinking of either putting some useful books I'll be needing or maybe stocking up those shelves with some good junk food. Right now, I've only got some Cheez-It's and some Ramen. I've had my Logitech 5.1 sound system for a few years now and it's dying. My left channel is hurting, the front only comes in sometimes and the back is also somewhat shaky.

Here's a little walk-through of the place.

Tuesday, May 1, 2007

All Set

I have one final left, but it's not much to worry about at this point. So I've been working on getting all my paperwork setup for CPT and taxes. All that is done now, projects are in, I've got my stuff packed. I leave for NH in a few days. So today I relax cause it's my birthday so I'll be hanging with friends tonight.

So this is how I plan to set things up this summer. I am going to be staying in NH with a friend. But, since I'll only be there for the summer and he doesn't have Internet, I will be working at my ex-girlfriends place. Without going into too much details, she is also the mother of my daughter, so I'll be taking this opportunity to spend as much time with her, my daughter Hannah, as I can this summer. She's 5 months old, my daughter, on Friday.

So they have an extra room on the other side of their garage where I can set up my desk and run a network cable to and use their DSL. It should be cool, my own little office to work on Finch. I'll also set it up to be able to remote into my box from the outside. Since they aren't serving anything from their network, I'll be able to use standard ports again. That'll be awesome. I've been in a dorm this year where they limit outgoing ports to 90-99. So SSH has been 95 and HTTP has been 96, really annoying when trying to relay the link to my gallery. They always forget the ":96". So anyhow, I'll have my own little office, should be fun.

I am also thinking of using this summer and the free schedule it allows me to have to do polyphasic sleep cycles. More on this when I get going on that. But it should prove to be an interesting experiment.

Saturday, April 28, 2007

DBMS Complete

The title isn't a completely accurate statement, but close enough. I worked on it for three days, hammered out about 2000 lines of code, so at the end, I didn't test it as much as I should have, and the documentation for it isn't as complete as I want it to be. I might revisit it on Sunday to complete it. That would require me to run a few more test on the operations and to finish up the javadocs. I submitted it by the due date, but the prof said that if we happen to submit an update to it before he grades it, he'll consider the most recent version. So he's rather sport about that. I'm kind of ashamed at the fact that it's not to my full potential, so that in itself will most likely drive me to fix it up. So when I do that, I'll post a link to a jar file or something for those who are interested in it. The javadocs are already available here, though incomplete.

Thursday, April 26, 2007

Finishing Up School

I haven't done much of anything regarding GSoC in the past few weeks since I have been focusing my attention of getting final projects done for a few of my classes. So fear not, I am not leaving you out in the dark as to my progress with Finch.

I am though working on getting a logo for myself. Using Inkscape, a friend of mine was able to come up with the logo at the top of this blog. I'm not sure if I like it yet, well see.

I have been in contact with my mentor a little, but nothing to talk about. On the other hand, I just finished my research paper for my Organization of Programming Languages class. I researched the programming language D. I don't think I talked about enough of it, but after 10 pages, I got kinda tired of adding more to it. So if you are interested in knowing more about D, their website should provide quite a bit of stuff to munch on. If you are interested in reading my paper you can find it here.

Tomorrow I hope to complete my MiniDBMS engine that implements a few relational algebra operations. Fun times!!!

Friday, April 13, 2007


I have been a Pidgin user for several years now and have loved it, but I always wished it could be brought into the console. As a Linux user/programmer I live in the console and since I have everything in screen sessions, I rarely leave it. So with the advent of Finch I was in heaven. However, I'm wishing more of Pidgin's features were available in Finch. Over the course of the summer, I hope to become part of the team and bring some of my wishes to reality.


A prioritized list of deliverables is as follows:

1. Shortcut Keys Overhaul
2. Sound
3. Logging Improvements
4. Buddy List Options
5. Documentation of my changes
6. Crashing bug fixes (if time permits)

Shortcut Keys Overhaul

The shortcut keys need some serious work. I have yet to be able to use it without running into issues about it not catching keystrokes. I will build an independent interface that will be be made accessible via a command line option. This interface will prompt the user for the basic keystrokes to survive through the application. A tentative list of these basic keystrokes is:

Basic Alt commands

The key mappings would be stored in a file to be loaded by Finch upon initialization.

To continue on this idea of shortcut keys, I want to add the option to add your own shortcut keys on the fly. Through an interface inside of Finch , a user will have the option to bind keystrokes to a set of predefined actions. A list of actions will be available through a combo box. There will be a list of custom shortcuts already configured, and the option to edit those will be made available.

I will modify how Finch interprets keystrokes in order to be able to detect both 8-bit meta and ESC sequences. This will provide an abstraction to the user in the configuration file. For example, if a user sets the configuration file to bind the keystrokes C-M-a to an action, the program will be able to determine whether C-M-a was hit regardless of how they are being sent from the terminal.

I will also build into Finch the ability to detect when a user is unable to send commands. I'm still unsure exactly how this will be implemented. As of now, I'm thinking of either having it detect when a user has started the program, but hasn't been able to send any valid commands for a predefined amount of time. Another possibility is when a user has sent a series of invalid commands from the start of the execution, it will detect issues. Upon having detected an issue with commands, it will pop up a window that uses basic commands to catch the aforementioned list of basic keystrokes. Research will be done to determine the best way to implement this idea.


I frequently run Finch inside a screen session in the background, and it is very frustrating when I miss someone who tried to talk to me. Since it's not a GUI and doesn't have the ability to pop up a notification, the best way to resolve this problem is with the use of sound. I will add the ability to customize sounds for different events, similar to many existing IM programs. I will also make sounds customizable on a per-buddy basis similar to how you can program custom ring tones for different people in your cellphone.


The logging features are another feature I will improve. I will build on the same basic ideas found in Pidgin's logging tools. Though there are a few ideas I want to add.

I will add the option to search through all conversations instead of just searching them one by one, or even searching them over a range of dates. There will also be the option to search from a list of logs from different users. From there we can add an array of search capabilities to better search the logs.

Basic Buddy List Options

There are a few options to the buddy list that I think are missing. I will add the ability to hide/show empty groups and to hide/show buddy details.


Every good project is always backed up with good documentation. Firstly I will provide user documentation on how to use the features I have implemented. I will provide them in both man format and HTML format. If time allows, I will do some research in possibly putting the docs into LaTeX format, and thus offering centralized documentation that can be exported into multiple formats, ie: man page, HTML, pdf, etc.

Crashing Bug Fixes

A few current features of Finch cause it to crash. For instance, chatting with jabber over GoogleTalk has cause some strange crashes. I have found that sometimes, simply quitting the application causes it to crash. Though the desired result is still achieved, it would be better for it to quit cleanly than to segfault. Due to the inability to predict the amount of time required in researching these bugs and then fixing them, I have chosen to append this project to my plans with an "As time Allows" clause. If I am able to complete my other goals to my satisfaction and more importantly the satisfaction of my mentors, I shall then take on fixing the aforementioned bugs and some others.


My name is Eric Polino and am currently attending Southern Adventist University. Though this is only my second year, I am a junior. I am double majoring in Computer Science and Mathematics. Being self-motivated and having spent a few years teaching myself how to program with the help of a few friends, I was able to challenge several courses at the beginning of my freshman year. This allowed me to take advanced classes from the start. I was also named "Standout Freshman" by the School of Computing.

Last year, I was selected, along with two other students, to represent my school at a regional programming contest where we placed 3rd out of 18 teams. I also participated in a recent Programmer of the Month where I placed 8th in their LOAPS contest. http://dinsights.com/POTM/LOAPS/finals.php

Almost since the beginning of my programming career I have worked on large projects. My main project has been my suicide chess AI. I have also had experience working on large professional software projects. See my resume for more details on my work history. http://www.aluink.net:96/Resume.doc I have also used ncurses for various little projects along the way.

Being a Linux user/programmer I practically live in the console and have everything in screen. Thus having a console-based instant messaging application is music to my ears. Being familiar with Pidgin, Finch is a dream come true. Thus working on Finch personally will allow me to bring my own dream to reality. If I could watch movies and look at pictures in the console, I don't think I'd have much need for a gui. Sure, I like and enjoy pretty icons and nice Guifications, but I also believe that console applications are very powerful.

I am a firm believer that you must be committed to do what it takes to have what you want. When I decide to get something done, I'll do what it takes to make sure it gets done and it gets done well. Given the opportunity, I will live by this motto as I work with Finch this summer.

Google Summer of Code Begins

I am going to be posting here over the summer as I work with Google Summer of Code. Those of you not familiar with GSoC can check it out on their own. I submitted a proposal to work for Finch. Finch is a console based instant messaging client. It's part of the project called Pidgin, formerly known as Gaim. My accepted proposal can be read here.

So it's been rather exciting so far. I spent a week or two working on my proposal. With the help of some good friends of mine: Doug, Daniel, Andrew and Holly, it became what it became. When I was done with it, I was confident that I couldn't have done a better job with the time I had. So when I heard that there were 88 applicants to the Pidgin project and only 10 were going to be accepted, I was scared. But I went back and read my proposal and became confident that I couldn't have written it better, so in the event of it not being selected, I knew it wasn't from lack of effort.

So the accepted applicant list date was originally 4/9 but it was moved to 4/11. And Google was working as fast as they could and were able to finally release the list at 0230 UTC on 4/12.

It was a crazy day. I logged into irc.slashnet.org#summer-discuss about mid-day and started talking with a bunch of other applicants who, like me, were awaiting the release. By the end of the day, I wasn't saying much and just reading, they were going nuts. I was/am very new to IRC channels and some of the culture was just hilarious to me. Some guys were slapping each other with trout, that was just rotfl material. They were talking about all kinds of none-sense, finding the stupidest things to kill time.

Then there was the mailing list. It was a mailing list used by Google to communicate and receive information from the mentors/organizations/students. Some students started to spam it. Playing word games and such. Some mentors and Google officials were getting upset. It was both sad and funny to watch. So in the end I ended up passing time watching the mayhem ensue.

About 20 mins before the final results came out, all applications were labeled as 'Not selected'. My heart fell, I thought it was over. But just as I was about to leave, I saw a message in my inbox from the mailing list saying that it's not official and the results aren't out, all applications are labeled as so. So that made me feel better, but I was still shooken up. Then at about 0230 UTC, I refreshed the tab in Firefox with the page listing my application and it's status and it changed to "Application Accepted". I let out the loudest yell I've ever put out in the computer lab. No worries for those who aren't aware of this computer lab. It's the Advanced Lab for computing majors at my University. There were only three other people in there, and I knew them all personally. They all knew what was going on. In any case, I was/am the computing club president and am known for being off the wall from time to time, so it was fine. Anyhow, I was just flipping out. I ran out of the lab, called up two of my budding who were waiting for news and just couldn't contain myself.

My evening then proceeded to go hang out with a good friend celebrating by drinking sparkling grape juice and watching a good flick "Life is Beautiful", italian movie, amazing story.

Today, I was just getting my repo setup with monotone. Tonight, with the help of my mentor, I managed to compile it properly. There were some strange issues with the setup that I needed help with. So now, I'm lining up to start on stuff. It'll be slow going till I get up north. I'm at school for a while, and I've got some large projects I'm working on that are keeping my time busy. I'll still be getting started slowly.

Till next time...