<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-203063759820106893</id><updated>2012-01-28T02:14:06.307-05:00</updated><category term='cooking'/><category term='xaml'/><category term='debugging'/><category term='books'/><category term='gmime'/><category term='community'/><category term='ximian'/><category term='algorithms'/><category term='tips+tricks'/><category term='banshee'/><category term='evolution'/><category term='gnome'/><category term='lazyweb'/><category term='git'/><category term='opengl'/><category term='searching'/><category term='zen'/><category term='kung fu'/><category term='cycling'/><category term='moonlight'/><category term='usability'/><category term='monodevelop'/><category term='laptop'/><category term='humor'/><category term='pulseaudio'/><category term='linux'/><category term='emacs'/><category term='global warming'/><category term='photography'/><category term='backpacking'/><category term='politics'/><category term='programming'/><category term='monotouch'/><category term='sorting'/><category term='graphics'/><category term='rants'/><category term='philosophy'/><category term='gaming'/><category term='life'/><category term='ooxml'/><category term='visual studio'/><category term='art of possibility'/><category term='free software'/><category term='monodroid'/><category term='android'/><category term='outdoors'/><category term='optimization'/><category term='microsoft'/><category term='anime'/><category term='version control'/><category term='mono'/><title type='text'>A Moment of Zen</title><subtitle type='html'>The Ramblings of Jeffrey Stedfast</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default?start-index=101&amp;max-results=100'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>137</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1119600459894198570</id><published>2011-10-31T21:31:00.008-04:00</published><updated>2011-11-01T07:13:58.753-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><category scheme='http://www.blogger.com/atom/ns#' term='zen'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>So you think that money is the root of all evil?</title><content type='html'>&lt;p&gt;Have you ever asked what is the root of money? Money is a tool of exchange, which can't exist unless there are goods produced and men able to produce them. Money is the material shape of the principle that men who wish to deal with one another must deal by trade and give value for value. Money is not the tool of the moochers, who claim your product by tears, or of the looters, who take it from you by force. Money is made possible only by the men who produce. Is this what you consider evil?&lt;/p&gt;
&lt;p&gt;When you accept money in payment for your effort, you do so only on the conviction that you will exchange it for the product of the effort of others. It is not the moochers or the looters who give value to money. Not an ocean of tears not all the guns in the world can transform those pieces of paper in your wallet into the bread you will need to survive tomorrow. Those pieces of paper, which should have been gold, are a token of honor--your claim upon the energy of the men who produce. Your wallet is your statement of hope that somewhere in the world around you there are men who will not default on that moral principle which is the root of money. Is this what you consider evil?&lt;/p&gt;
&lt;p&gt;Have you ever looked for the root of production? Take a look at an electric generator and dare tell yourself that it was created by the muscular effort of unthinking brutes. Try to grow a seed of wheat without the knowledge left to you by men who had to discover it for the first time. Try to obtain your food by means of nothing but physical motions--and you'll learn that man's mind is the root of all the goods produced and of all the wealth that has ever existed on earth.&lt;/p&gt;
&lt;p&gt;But you say that money is made by the strong at the expense of the weak? What strength do you mean? It is not the strength of guns or muscles. Wealth is the product of man's capacity to think. Then is money made by the man who invents a motor at the expense of those who did not invent it? Is money made by the intelligent at the expense of the fools? By the able at the expense of the incompetent? By the ambitious at the expense of the lazy? Money is &lt;i&gt;made&lt;/i&gt;--before it can be looted or mooched--made by the effort of every honest man, each to the extent of his ability. An honest man is one who knows that he can't consume more than he has produced.&lt;/p&gt;
&lt;p&gt;To trade by means of money is the code of the men of good will. Money rests on the axiom that every man is the owner of his mind and his effort. Money allows no power to prescribe the value of your effort except the voluntary choice of the man who is willing to trade you his effort in return. Money permits you to obtain for your goods and your labor that which they are worth to the men who buy them, but no more. Money permits no deals except those to mutual benefit by the unforced judgment of the traders. Money demands of you the recognition that men must work for their own benefit, not for their own injury, for their gain, not their loss--the recognition that they are not beasts of burden, born to carry the weight of your misery--that you must offer them values, not wounds--that the common bond among men is not the exchange of suffering, but the exchange of goods. Money demands that you sell, not your weakness to men's stupidity, but your talent to their reason; it demands that you buy, not the shoddiest they offer, but the best that your money can find. And when men live by trade--with reason, not force, as their final arbiter--it is the best product that wins, the best performance, the man of best judgment and highest ability--and the degree of a man's productiveness is the degree of his reward. This is the code of existence whose tool and symbol is money. Is this what you consider evil?&lt;/p&gt;
&lt;p&gt;But money is only a tool. It will take you wherever you wish, but it will not replace you as the driver. It will give you the means for the satisfaction of your desires, but it will not provide you with desires. Money is the scourge of the men who attempt to reverse the law of causality--the men who seek to replace the mind by seizing the products of the mind.&lt;/p&gt;
&lt;p&gt;Money will not purchase happiness for the man who has no concept of what he wants: money will not give him a code of values, if he's evaded the knowledge of what to value, and it will not provide him with a purpose, if he's evaded the choice of what to seek. Money will not buy intelligence for the fool, or admiration for the coward, or respect for the incompetent. The man who attempts to purchase the brains of his superiors to serve him, with his money replacing his judgment, ends up by becoming the victim of his inferiors. The men of intelligence desert him, but the cheats and the frauds come flocking to him, drawn by a law which he has not discovered: that no man may be smaller than his money. Is this the reason why you call it evil?&lt;/p&gt;
&lt;p&gt;Only the man who does not need it, is fit to inherit wealth--the man who would make his own fortune no matter where he started. If an heir is equal to his money, it serves him; if not, it destroys him. But you look on and you cry that money corrupted him. Did it? Or did he corrupt his money? Do not envy a worthless heir; his wealth is not yours and you would have done no better with it. Do not think that it should have been distributed among you; loading the world with fifty parasites instead of one, would not bring back the dead virtue which was the fortune. Money is a living power that dies without its root. Money will not serve the mind that cannot match it. Is this the reason why you call it evil?&lt;/p&gt;
&lt;p&gt;Money is your means of survival. The verdict you pronounce upon the source of your livelihood is the verdict you pronounce upon your life. If the source is corrupt, you have damned your own existence. Did you get your money by fraud? By pandering to men's vices or men's stupidity? By catering to fools, in the hope of getting more than your ability deserves? By lowering your standards? By doing work you despise for purchasers you scorn? If so, then your money will not give you a moment's or a penny's worth of joy. Then all the things you buy will become, not a tribute to you, but a reproach; not an achievement, but a reminder of shame. Then you'll scream that money is evil. Evil, because it would not pinch-hit for your self-respect? Evil, because it would not let you enjoy your depravity? Is this the root of your hatred of money?&lt;/p&gt;
&lt;p&gt;Money will always remain an effect and refuse to replace you as the cause. Money is the product of virtue, but it will not give you virtue and it will not redeem your vices. Money will not give you the unearned, neither in matter nor in spirit. Is this the root of your hatred of money?&lt;/p&gt;
&lt;p&gt;Or did you say it's the &lt;i&gt;love&lt;/i&gt; of money that's the root of all evil? To love a thing is to know and love its nature. To love money is to know and love the fact that money is the creation of the best power within you, and your passkey to trade your effort for the effort of the best among men. It's the person who would sell his soul for a nickel, who is loudest in proclaiming his hatred of money--and he has good reason to hate it. The lovers of money are willing to work for it. They know they are able to deserve it.&lt;/p&gt;
&lt;p&gt;Let me give you a tip on a clue to men's characters: the man who damns money has obtained it dishonorably; the man who respects it has earned it.&lt;/p&gt;
&lt;p&gt;Run for your life from any man who tells you that money is evil. That sentence is the leper's bell of an approaching looter. So long as men live together on earth and need means to deal with one another--their only substitute, if they abandon money, is the muzzle of a gun.&lt;/p&gt;
&lt;p&gt;But money demands of you the highest virtues, if you wish to make it or to keep it. Men who have no courage, pride or self-esteem, men who have no moral sense of their right to their money and are not willing to defend it as they defend their life, men who apologize for being rich--will not remain rich for long. They are the natural bait for the swarms of looters that stay under rocks for centuries, but come crawling out at the first smell of a man who begs to be forgiven for the guilt of owning wealth. They will hasten to relieve him of the guilt--and of his life, as he deserves.&lt;/p&gt;
&lt;p&gt;Then you will see the rise of the men of the double standard--the men who live by force, yet count on those who live by trade to create the value of their looted money--the men who are the hitchhikers of virtue. In a moral society, these are the criminals, and the statutes are written to protect you against them. But when a society establishes criminals-by-right and looters-by-law--men who use force to seize the wealth of &lt;i&gt;disarmed&lt;/i&gt; victims--then money becomes its creators' avenger. Such looters believe it safe to rob defenseless men, once they've passed a law to disarm them. But their loot becomes the magnet for other looters, who get it from them as they got it. Then the race goes, not to the ablest at production, but to those most ruthless at brutality. When force is the standard, the murderer wins over the pickpocket. And then that society vanishes, in a spread of ruins and slaughter.&lt;/p&gt;
&lt;p&gt;Do you wish to know whether that day is coming? Watch money. Money is the barometer of a society's virtue. When you see that trading is done, not by consent, but by compulsion--when you see that in order to produce, you need to obtain permission from men who produce nothing--when you see that money is flowing to those who deal, not in goods, but in favors--when you see that men get richer by graft and by pull than by work, and your laws don't protect you against them, but protect them against you--when you see corruption being rewarded and honesty becoming a self-sacrifice--you may know that your society is doomed. Money is so noble a medium that it does not compete with guns and it does not make terms with brutality. It will not permit a country to survive as half-property, half-loot.&lt;/p&gt;
&lt;p&gt;Whenever destroyers appear among men, they start by destroying money, for money is men's protection and the base of a moral existence. Destroyers seize gold and leave to its owners a counterfeit pile of paper. This kills all objective standards and delivers men into the arbitrary power of an arbitrary setter of values. Gold was an objective value, an equivalent of wealth produced. Paper is a mortgage on wealth that does not exist, backed by a gun aimed at those who are expected to produce it. Paper is a check drawn by legal looters upon an account which is not theirs: upon the virtue of the victims. Watch for the day when it bounces, marked, "Account overdrawn."&lt;/p&gt;
&lt;p&gt;When you have made evil the means of survival, do not expect men to remain good. Do not expect them to stay moral and lose their lives for the purpose of becoming the fodder of the immoral. Do not expect them to produce, when production is punished and looting rewarded. Do not ask, "Who is destroying the world?" You are.&lt;/p&gt;
&lt;p&gt;You stand in the midst of the greatest achievements of the greatest productive civilization and you wonder why it's crumbling around you, while you're damning its life-blood--money. You look upon money as the savages did before you, and you wonder why the jungle is creeping back to the edge of your cities. Throughout men's history, money was always seized by looters of one brand or another, whose names changed, but whose method remained the same: to seize wealth by force and to keep the producers bound, demeaned, defamed, deprived of honor. That phrase about the evil of money, which you mouth with such righteous recklessness, comes from a time when wealth was produced by the labor of slaves--slaves who repeated the motions once discovered by somebody's mind and left unimproved for centuries. So long as production was ruled by force, and wealth was obtained by conquest, there was little to conquer, Yet through all the centuries of stagnation and starvation, men exalted the looters, as aristocrats of the sword, as aristocrats of birth, as aristocrats of the bureau, and despised the producers, as slaves, as traders, as shopkeepers--as industrialists.&lt;/p&gt;
&lt;p&gt;To the glory of mankind, there was, for the first and only time in history, a &lt;i&gt;country of money&lt;/i&gt;--and I have no higher, more reverent tribute to pay to America, for this means: a country of reason, justice, freedom, production, achievement. For the first time, man's mind and money were set free, and there were no fortunes-by-conquest, but only fortunes-by-work, and instead of swordsmen and slaves, there appeared the real maker of wealth, the greatest worker, the highest type of human being--the self-made man--the American industrialist.&lt;/p&gt;
&lt;p&gt;If you ask me to name the proudest distinction of Americans, I would choose--because it contains all the others--the fact that they were the people who created the phrase "to &lt;i&gt;make&lt;/i&gt; money." No other language or nation had ever used these words before; men had always thought of wealth as a static quantity--to be seized, begged, inherited, shared, looted or obtained as a favor. Americans were the first to understand that wealth has to be created. The words "to make money" hold the essence of human morality.&lt;/p&gt;
&lt;p&gt;Yet these were the words for which Americans were denounced by the rotted cultures of the looters' continents. Now the looters' credo has brought you to regard your proudest achievements as a hallmark of shame, your prosperity as guilt, your greatest men, the industrialists, as blackguards, and your magnificent factories as the product and property of muscular labor, the labor of whip-driven slaves, like the pyramids of Egypt. The rotter who simpers that he sees no difference between the power of the dollar and the power of the whip, ought to learn the difference on his own hide-- as, I think, he will.&lt;/p&gt;
&lt;p&gt;Until and unless you discover that money is the root of all good, you ask for your own destruction. When money ceases to be the tool by which men deal with one another, then men become the tools of men. Blood, whips and guns--or dollars. Take your choice--there is no other--and your time is running out.&lt;/p&gt;
&lt;p align="right"&gt;&lt;i&gt;-- Francisco d'Anconia&lt;br&gt;&lt;a href="http://www.amazon.com/gp/product/0452011876?ie=UTF8&amp;tag=amoofze-20&amp;linkCode=shr&amp;camp=213733&amp;creative=393185&amp;creativeASIN=0452011876&amp;ref_=sr_1_1&amp;qid=1320111116&amp;sr=8-1"&gt;Atlas Shrugged by Ayn Rand&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1119600459894198570?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1119600459894198570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1119600459894198570' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1119600459894198570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1119600459894198570'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/10/so-you-think-that-money-is-root-of-all.html' title='So you think that money is the root of all evil?'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7442937733906858484</id><published>2011-09-15T17:01:00.000-04:00</published><updated>2011-09-15T17:01:47.436-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monotouch'/><category scheme='http://www.blogger.com/atom/ns#' term='tips+tricks'/><title type='text'>MonoTouch Tips &amp; Tricks: Updating the Location of an MKAnnotation</title><content type='html'>&lt;p&gt;I just spent a day figuring this out, so figured I'd share it with the world because I'm &lt;i&gt;sure&lt;/i&gt; other people are going to want to know how to do this...&lt;/p&gt;
&lt;p&gt;So the question is,&lt;/p&gt;
&lt;p&gt;&lt;h3&gt;How can I get my MKMapView to respond to coordinate changes in my custom MKAnnotations?&lt;/h3&gt;&lt;/p&gt;
&lt;p&gt;As it turns out, this is incredibly simple. In your MKAnnotation subclass, whenever you want to change your Coordinate property value, you need to do the following:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
void UpdateCoordinate (CLLocationCoordinate2D newCoordinate)
{
    this.WillChangeValue ("coordinate");
    this.Coordinate = newCoordinate;
    this.DidChangeValue ("coordinate");
}
&lt;/pre&gt;
&lt;p&gt;That's it! It really is that simple...&lt;/p&gt;
&lt;p&gt;The reason this works is because MKMapView observes changes in its list of MKAnnotations, you just need to signal to it that changes are about to happen (and did happen).&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7442937733906858484?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7442937733906858484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7442937733906858484' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7442937733906858484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7442937733906858484'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/09/monotouch-tips-tricks-updating-location.html' title='MonoTouch Tips &amp; Tricks: Updating the Location of an MKAnnotation'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-852880104225063524</id><published>2011-08-14T15:40:00.002-04:00</published><updated>2011-08-14T15:55:56.169-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>GMime 2.5.10: A Call For Testers</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;a href="http://www.lolcats.com/images/u/07/25/lolcatsdotcom9cryvuajyxzz31eu.jpg" imageanchor="1" style="clear:right; float:right;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="175" width="174" src="http://www.lolcats.com/images/u/07/25/lolcatsdotcom9cryvuajyxzz31eu.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;I've just released &lt;a href="http://spruce.sourceforge.net/gmime/"&gt;GMime&lt;/a&gt; &lt;a href="http://download.gnome.org/sources/gmime/2.5/gmime-2.5.10.tar.bz2"&gt;2.5.10&lt;/a&gt; which I hope to be the last of the 2.5 releases before I release 2.6.0. I feel that I've stretched the development of 2.6.0 out for far too long (2.5 development began at the end of April, 2009) and even though I didn't get around to doing everything I had hoped to do, I feel that the latest 2.5.x releases are such an improvement over 2.4.x that I just want to get it out there for developers to start using. But before I make a 2.6.0 release, I'm hoping to get some feedback and some testing.&lt;/p&gt;
&lt;h3&gt;What's new?&lt;/h3&gt;
&lt;p&gt;New for the release of 2.5.10 is &lt;b&gt;GMimePartIter&lt;/b&gt; which replaces the need for &lt;i style="font-family: courier new; font-size: 85%"&gt;g_mime_object_foreach()&lt;/i&gt;and its awkward callback requirement, instead allowing you to take the far nicer iterator approach that is popular in the C# and Java worlds (known as &lt;i&gt;IEnumerator&lt;/i&gt; in C#). This new iterator, like the foreach function it replaces, iterates over the MIME tree structure in &lt;a href="http://en.wikipedia.org/wiki/Depth-first"&gt;depth-first&lt;/a&gt; order.&lt;/p&gt;
&lt;p&gt;Inspired by &lt;a href="http://www.ietf.org/rfc/rfc2060.txt"&gt;IMAP&lt;/a&gt;'s FETCH body part-specifier syntax, I've implemented a method allowing you to jump to a part based on a part-specifier string (aka a path): &lt;i style="font-family: courier new; font-size: 85%"&gt;g_mime_part_iter_jump_to()&lt;/i&gt;. Also implemented is a function called &lt;i style="font-family: courier new; font-size: 85%"&gt;g_mime_part_iter_get_path()&lt;/i&gt;, which can be used to tell you the current part-specifier path of the iterator.&lt;/p&gt;
&lt;p&gt;For example, if you had the following MIME message structure:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
multipart/related
  multipart/alternative
    text/plain
    text/html
  image/jpeg
&lt;/pre&gt;
&lt;p&gt;The body part-specifier paths would be:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
1    multipart/alternative
1.1  text/plain
1.2  text/html
2    image/jpeg
&lt;/pre&gt;
&lt;p&gt;This means that &lt;i style="font-family: courier new; font-size: 85%"&gt;g_mime_part_iter_jump_to(iter, "1.2")&lt;/i&gt; would jump to the part specified by the path "1.2" which, as we can see above, would be the text/html part. Calling &lt;i style="font-family: courier new; font-size: 85%"&gt;g_mime_part_iter_next(iter)&lt;/i&gt; would iterate to the next part, being the image/jpeg, while calling &lt;i style="font-family: courier new; font-size: 85%"&gt;g_mime_part_iter_prev(iter)&lt;/i&gt; would iterate backwards to the text/plain part and calling it again would iterate backwards to the multipart/alternative.&lt;/p&gt;
&lt;h3&gt;What I Need From Testers&lt;/h3&gt;
&lt;p&gt;My feeling is that developers will want to use this cool new body part-specifier path functionality for aiding them in implementing IMAP servers and/or clients. Because of this, it would be great if GMime's implementation matched IMAP's specification exactly. The problem is that I don't have the time or energy to verify that the paths work out to be identical in all cases. So... if you are one of those developers who is interested in using this functionality and need it to be identical to IMAP's syntax (or would really like it to be), I'm hoping that you could test it out and make sure that it matches. Especially worthwhile of testing, I'd imagine, is having message/rfc822 parts in the tree. I suspect that, if anywhere, this is where differences may be.&lt;/p&gt;
&lt;p&gt;If body part-specifier paths aren't something you care about, don't fret; the rest of the iterator API needs testing as well and if you have no interest in the iterator API at all, perhaps you'd be willing to test the S/MIME functionality (especially since I haven't figured out &lt;i&gt;how&lt;/i&gt; to test it myself, given that I don't have an S/MIME cert nor have I figured out how to generate one or add one to my gpgsm keyring).&lt;/p&gt;
&lt;p&gt;Your help will be greatly appreciated.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-852880104225063524?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/852880104225063524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=852880104225063524' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/852880104225063524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/852880104225063524'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/08/gmime-2510-call-for-testers.html' title='GMime 2.5.10: A Call For Testers'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-8222765658798000553</id><published>2011-08-03T11:42:00.007-04:00</published><updated>2011-08-03T15:39:01.829-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monodevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='monotouch'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='tips+tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Debugging Your MonoTouch Apps: The Future</title><content type='html'>&lt;p&gt;One of the "paper cuts" developers have been having with developing their &lt;a href="http://ios.xamarin.com/"&gt;MonoTouch&lt;/a&gt; 4.0.x (and earlier) applications is that for some networking setups, the IP of the developer's workstation detected by &lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt; and given to the &lt;a href="http://is.gd/Nr2hD4"&gt;iPhone&lt;/a&gt; or &lt;a href="http://is.gd/DiYoT5"&gt;iPad&lt;/a&gt; device for debugging purposes is not correct. This often happens if the WiFi is a different network than the network that the developer's machine is connected to (although there are other scenarios as well).&lt;/p&gt;
&lt;div class="separator" style="clear: both;"&gt;
&lt;a href="http://3.bp.blogspot.com/-I_zA4pkHMSk/TjlsF448kKI/AAAAAAAAAq0/CIMEoSvm6D8/s1600/MonoTouchiPhoneDebugSettings.png" imageanchor="1" style="clear:right; float:left;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="400" width="206" src="http://3.bp.blogspot.com/-I_zA4pkHMSk/TjlsF448kKI/AAAAAAAAAq0/CIMEoSvm6D8/s400/MonoTouchiPhoneDebugSettings.png" /&gt;&lt;/a&gt;
&lt;p&gt;Since it does not seem to be widely known about, allow me to point out that current versions of MonoTouch allow developers to modify the IP that the runtime should connect to for debugging via the iOS &lt;b&gt;Settings&lt;/b&gt; app found on any iPhone or iPad (or Simulator). You can see a screenshot of this per-App Settings page in the screenshot to the left. Each of these fields are editable, allowing you to override the defaults filled-in by MonoDevelop.&lt;/p&gt;
&lt;/p&gt;For our upcoming 4.1 release, &lt;a href="https://twitter.com/#!/rolfkvinge"&gt;Rolf Kvinge&lt;/a&gt; and I (but mostly Rolf) have been working on improving this. Rolf has modified the code to check the value of the IP provided in the per-App Settings and if it is set to nil or "automatic", the debugger falls back to checking for a file bundled with the app called MonoTouchDebugConfiguration.txt which can list any number of IP's to try and connect to, each one being on a separate line prefixed with "IP: ". For example:&lt;/p&gt;
&lt;pre&gt;
IP: 10.0.1.31
IP: 192.168.1.31
IP: 204.11.102.79
&lt;/pre&gt;
&lt;p&gt;The runtime will then attempt to connect to each of these IPs asynchronously until it establishes a connection to one of them (at which point it aborts the other waiting connections). This config file solution will hopefully help simplify things for developers a bit by allowing them to pre-configure which IPs to try for their local network configuration w/o having to manually override the iPhone debug settings on the device or simulator.
&lt;/div&gt;
&lt;p&gt;For &lt;i&gt;Phase 2&lt;/i&gt; of our plan for World Domination, Rolf is hard at work adding support to MonoDevelop and the runtime to allow for USB debugging which will obsolete the above functionality in future versions where the developer has a MonoDevelop which supports USB debugging. For developers stuck on an older MonoDevelop (like 2.4), the solution illustrated above requires no changes to MonoDevelop and so will be available for use.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-8222765658798000553?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/8222765658798000553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=8222765658798000553' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8222765658798000553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8222765658798000553'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/08/debugging-your-monotouch-apps-future.html' title='Debugging Your MonoTouch Apps: The Future'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-I_zA4pkHMSk/TjlsF448kKI/AAAAAAAAAq0/CIMEoSvm6D8/s72-c/MonoTouchiPhoneDebugSettings.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5331854533895224758</id><published>2011-04-14T20:49:00.005-04:00</published><updated>2011-04-15T12:10:01.614-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='monodroid'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='free software'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Moonlight on Android</title><content type='html'>&lt;p&gt;For the past week, the Moonlight team has been busy porting &lt;a href="http://www.mono-project.com/Moonlight"&gt;Moonlight&lt;/a&gt; to Android devices and today, showed it off at &lt;a href="http://live.visitmix.com/"&gt;Mix 11&lt;/a&gt;.&lt;/p&gt;
&lt;iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/41tul6sUttc" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;The video shows Moonlight running on both a &lt;a href="http://amzn.to/eNM5V3"&gt;Motorola Xoom&lt;/a&gt; tablet and a &lt;a href="http://amzn.to/eep05y"&gt;Nexus S&lt;/a&gt; phone.&lt;/p&gt;
&lt;p&gt;Keep in mind that we're still in the early phases of porting and there's still a lot of work left to do before we can ship a product, but it's still exciting!&lt;/p&gt;
&lt;p&gt;Update: For those of you reading my blog from Planet GNOME (or some other planet that doesn't show the video above), you can find it &lt;a href="http://www.youtube.com/watch?v=41tul6sUttc"&gt;here, on YouTube&lt;/a&gt;.
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Now you can see &lt;a href="http://www.youtube.com/watch?v=gzQ3R3mCdrg"&gt;Moonlight rendering video with 3D transforms&lt;/a&gt;, too!&lt;/p&gt;
&lt;iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/gzQ3R3mCdrg" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5331854533895224758?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5331854533895224758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5331854533895224758' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5331854533895224758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5331854533895224758'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/04/moonlight-on-android.html' title='Moonlight on Android'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/41tul6sUttc/default.jpg' height='72' width='72'/><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4447604531618177791</id><published>2011-04-07T21:45:00.007-04:00</published><updated>2011-05-18T14:59:57.601-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='sorting'/><title type='text'>Optimizing Merge Sort</title><content type='html'>&lt;p&gt;A number of years ago I wrote about the &lt;a href="/2007/02/merge-sort.html"&gt;Merge Sort&lt;/a&gt; algorithm. One of the advantages of &lt;i&gt;Merge Sort&lt;/i&gt; is that it is a stable sort, meaning that elements that compare as being equal remain in their original order after being sorted.&lt;/p&gt;
&lt;p&gt;Well, today I had need of employing a stable sorting routine for sorting elements by a ZIndex in &lt;a href="http://www.moonlight-project.com"&gt;Moonlight&lt;/a&gt;. Up until today, we had been using &lt;i style="font-family: courier new; font-size: 85%"&gt;qsort()&lt;/i&gt; which, while not guaranteed to be a stable sort on any platform, happens to be implemented in &lt;i&gt;glibc&lt;/i&gt; as a stable sort except in out-of-memory conditions. Since we'd like Moonlight to work on platforms other than Linux+glibc (such as Mac OS or BSD), it has become important enough to implement properly.&lt;/p&gt;
&lt;p&gt;To start, I dusted off my generic &lt;i style="font-family: courier new; font-size: 85%"&gt;MergeSort()&lt;/i&gt; implementation from years ago when I was writing articles about various sorting algorithms. This is what I had to start with:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
#define MID(lo, hi) (lo + ((hi - lo) &gt;&gt; 1))

static void
msort (void *array, void *buf, size_t low, size_t high, size_t size,
       int (* compare) (const void *, const void *))
{
    register char *lo, *hi, *b;
    char *al, *am, *ah;
    size_t mid;
    
    mid = MID (low, high);
    
    if (mid + 1 &amp;lt; high)
        msort (array, buf, mid + 1, high, size, compare);
    
    if (mid &gt; low)
        msort (array, buf, low, mid, size, compare);
    
    ah = ((char *) array) + ((high + 1) * size);
    am = ((char *) array) + ((mid + 1) * size);
    al = ((char *) array) + (low * size);
    
    b = (char *) buf;
    lo = al;
    hi = am;
    
    while (lo &amp;lt; am &amp;&amp; hi &amp;lt; ah) {
        if (compare (lo, hi) &amp;lt;= 0) {
            memcpy (b, lo, size);
            lo += size;
        } else {
            memcpy (b, hi, size);
            hi += size;
        }
        
        b += size;
    }
    
    if (lo &amp;lt; am)
        memcpy (b, lo, am - lo);
    else if (hi &amp;lt; ah)
        memcpy (b, hi, (ah + size) - hi);
    
    memcpy (al, buf, ah - al);
}

int
MergeSort (void *base, size_t nmemb, size_t size,
           int (* compare) (const void *, const void *))
{
    void *tmp;
    
    if (nmemb &amp;lt; 2)
        return 0;
    
    if (!(tmp = malloc (nmemb * size))) {
        errno = ENOMEM;
        return -1;
    }
    
    msort (base, tmp, 0, nmemb - 1, size, compare);
    
    free (tmp);
    
    return 0;
}
&lt;/pre&gt;
&lt;p&gt;Since performance is very important, I clocked this implementation against &lt;i style="font-family: courier new; font-size: 85%"&gt;qsort()&lt;/i&gt; and got the following results on my Intel Core2 Quad Q6600 2.4 GHz machine using arrays of 10 million ints:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Randomized input: 14.13s vs qsort()'s 6.77s&lt;/li&gt;
&lt;li&gt;Sorted input: 4.41s vs qsort()'s 1.54s&lt;/li&gt;
&lt;li&gt;Reversed input: 4.26s vs qsort()'s 1.90s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clearly the above &lt;i style="font-family: courier new; font-size: 85%"&gt;MergeSort()&lt;/i&gt; implementation did not fare well against glibc's &lt;i style="font-family: courier new; font-size: 85%"&gt;qsort()&lt;/i&gt; on my system, so it was time to look at what I could do to improve the performance.&lt;/p&gt;
&lt;p&gt;The most obvious optimization I could see was to try and batch my &lt;i style="font-family: courier new; font-size: 85%"&gt;memcpy()&lt;/i&gt; calls. In other words, instead of calling &lt;i style="font-family: courier new; font-size: 85%"&gt;memcpy()&lt;/i&gt; to copy each and every element into our temporary buffer, it'd be more efficient to copy blocks of elements at a time:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
static void
msort (void *array, void *buf, size_t low, size_t high, size_t size,
       int (* compare) (const void *, const void *))
{
    char *al, *am, *ah, *ls, *hs, *lo, *hi, *b;
    size_t mid;
    
    mid = MID (low, high);
    
    if (mid + 1 &amp;lt; high)
        msort (array, buf, mid + 1, high, size, compare);
    
    if (mid &gt; low)
        msort (array, buf, low, mid, size, compare);
    
    ah = ((char *) array) + ((high + 1) * size);
    am = ((char *) array) + ((mid + 1) * size);
    al = ((char *) array) + (low * size);
    
    b = (char *) buf;
    lo = al;
    hi = am;
    
    do {
        ls = lo;
        hs = hi;
        
        if (lo &gt; al || hi &gt; am) {
            /* our last loop already compared lo &amp; hi and found lo &lt;= hi */
            lo += size;
        }
        
        while (lo &amp;lt; am &amp;&amp; compare (lo, hi) &amp;lt;= 0)
            lo += size;
 
        if (lo &gt; ls) {
            memcpy (b, ls, lo - ls);
            b += (lo - ls);
        }
 
        if (lo &amp;lt; am) {
            /* our last compare tells us hi &amp;lt; lo */
            hi += size;
            
            while (hi &amp;lt; ah &amp;&amp; compare (hi, lo) &amp;lt; 0)
                hi += size;
            
            memcpy (b, hs, hi - hs);
            b += (hi - hs);
        }
    } while (lo &amp;lt; am &amp;&amp; hi &amp;lt; ah);
    
    if (lo &amp;lt; am)
        memcpy (b, lo, am - lo);
    else if (hi &amp;lt; ah)
        memcpy (b, hi, ah - hi);
    
    memcpy (al, buf, ah - al);
}
&lt;/pre&gt;
&lt;p&gt;The results were promising. For the exact same inputs (including the exact same random array), we now get:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Randomized input: 10.45s&lt;/li&gt;
&lt;li&gt;Sorted input: 2.08s&lt;/li&gt;
&lt;li&gt;Reversed input: 2.03s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only other way that we can reduce the number of &lt;i style="font-family: courier new; font-size: 85%"&gt;memcpy()&lt;/i&gt; calls we make is to avoid copying leading and trailing elements into our temporary buffer if it's not necessary to merge them. Here's the solution I came up with:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
static void
msort (void *array, void *buf, size_t low, size_t high, size_t size,
       int (* compare) (const void *, const void *))
{
    char *a1, *al, *am, *ah, *ls, *hs, *lo, *hi, *b;
    size_t copied = 0;
    size_t mid;
    
    mid = MID (low, high);
    
    if (mid + 1 &amp;lt; high)
        msort (array, buf, mid + 1, high, size, compare);
    
    if (mid &gt; low)
        msort (array, buf, low, mid, size, compare);
    
    ah = ((char *) array) + ((high + 1) * size);
    am = ((char *) array) + ((mid + 1) * size);
    a1 = al = ((char *) array) + (low * size);
    
    b = (char *) buf;
    lo = al;
    hi = am;
    
    do {
        ls = lo;
        hs = hi;
        
        if (lo &gt; al || hi &gt; am) {
            /* our last loop already compared lo &amp; hi and found lo &amp;lt;= hi */
            lo += size;
        }
        
        while (lo &amp;lt; am &amp;&amp; compare (lo, hi) &amp;lt;= 0)
            lo += size;
        
        if (lo &amp;lt; am) {
            if (copied == 0) {
                /* avoid copying the leading items */
                a1 = lo;
                ls = lo;
            }
            
            /* our last compare tells us hi &amp;lt; lo */
            hi += size;
            
            while (hi &amp;lt; ah &amp;&amp; compare (hi, lo) &amp;lt; 0)
                hi += size;
            
            if (lo &gt; ls) {
                memcpy (b, ls, lo - ls);
                copied += (lo - ls);
                b += (lo - ls);
            }
            
            memcpy (b, hs, hi - hs);
            copied += (hi - hs);
            b += (hi - hs);
        } else if (copied) {
            memcpy (b, ls, lo - ls);
            copied += (lo - ls);
            b += (lo - ls);
            
            /* copy everything we needed to re-order back into array */
            memcpy (a1, buf, copied);
            return;
        } else {
            /* everything already in order */
            return;
        }
    } while (hi &amp;lt; ah);
    
    if (lo &amp;lt; am) {
        memcpy (b, lo, am - lo);
        copied += (am - lo);
    }
    
    memcpy (a1, buf, copied);
}
&lt;/pre&gt;
&lt;p&gt;Once again, reducing the amount of copying paid off:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Randomized input: 9.80s&lt;/li&gt;
&lt;li&gt;Sorted input: 0.95s&lt;/li&gt;
&lt;li&gt;Reversed input: 2.05s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;Update 2011-05-18:&lt;/b&gt; One final optimization that can be tried is pre-calculating the optimum way to copy elements between buffers. This calculation, while not terribly expensive itself, adds up with every call to &lt;i style="font-family: courier new; font-size: 85%"&gt;memcpy()&lt;/i&gt;. Let's start off by writing some handy macros:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
#define COPYBY(TYPE, a, b, n) {         \
    long __n = (n) / sizeof (TYPE);     \
    register TYPE *__a = (TYPE *) (a);  \
    register TYPE *__b = (TYPE *) (b);  \
                                        \
    do {                                \
        *__a++ = *__b++;                \
    } while (--__n &gt; 0);                \
}

#define MEMCOPY(dest, src, n) {                 \
    switch (copy_mode) {                        \
    case 1: COPYBY (long, dest, src, n); break; \
    case 2: COPYBY (int, dest, src, n); break;  \
    default: memcpy (dest, src, n);             \
    }                                           \
}
&lt;/pre&gt;
&lt;p&gt;Now that these handy macros are written, we can plug them into our &lt;i&gt;Merge Sort&lt;/i&gt; implementation:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
static void
msort (void *array, void *buf, size_t low, size_t high, size_t size,
       int copy_mode, int (* compare) (const void *, const void *))
{
    char *a1, *al, *am, *ah, *ls, *hs, *lo, *hi, *b;
    size_t copied = 0;
    size_t mid;
    
    mid = MID (low, high);
    
    if (mid + 1 &amp;lt; high)
        msort (array, buf, mid + 1, high, size, compare);
    
    if (mid &gt; low)
        msort (array, buf, low, mid, size, compare);
    
    ah = ((char *) array) + ((high + 1) * size);
    am = ((char *) array) + ((mid + 1) * size);
    a1 = al = ((char *) array) + (low * size);
    
    b = (char *) buf;
    lo = al;
    hi = am;
    
    do {
        ls = lo;
        hs = hi;
        
        if (lo &gt; al || hi &gt; am) {
            /* our last loop already compared lo &amp; hi and found lo &amp;lt;= hi */
            lo += size;
        }
        
        while (lo &amp;lt; am &amp;&amp; compare (lo, hi) &amp;lt;= 0)
            lo += size;
        
        if (lo &amp;lt; am) {
            if (copied == 0) {
                /* avoid copying the leading items */
                a1 = lo;
                ls = lo;
            }
            
            /* our last compare tells us hi &amp;lt; lo */
            hi += size;
            
            while (hi &amp;lt; ah &amp;&amp; compare (hi, lo) &amp;lt; 0)
                hi += size;
            
            if (lo &gt; ls) {
                MEMCOPY (b, ls, lo - ls);
                copied += (lo - ls);
                b += (lo - ls);
            }
            
            MEMCOPY (b, hs, hi - hs);
            copied += (hi - hs);
            b += (hi - hs);
        } else if (copied) {
            MEMCOPY (b, ls, lo - ls);
            copied += (lo - ls);
            b += (lo - ls);
            
            /* copy everything we needed to re-order back into array */
            MEMCOPY (a1, buf, copied);
            return;
        } else {
            /* everything already in order */
            return;
        }
    } while (hi &amp;lt; ah);
    
    if (lo &amp;lt; am) {
        MEMCOPY (b, lo, am - lo);
        copied += (am - lo);
    }
    
    MEMCOPY (a1, buf, copied);
}

int
MergeSort (void *base, size_t nmemb, size_t size,
           int (* compare) (const void *, const void *))
{
    int copy_mode;
    void *tmp;
    
    if (nmemb &amp;lt; 2)
        return 0;
    
    if (!(tmp = malloc (nmemb * size))) {
        errno = ENOMEM;
        return -1;
    }
    
    if ((((char *) base) - ((char *) 0)) % sizeof (long) == 0 &amp;&amp; (size % sizeof (long)) == 0)
        copy_mode = 1;
    else if ((((char *) base) - ((char *) 0)) % sizeof (int) == 0 &amp;&amp; (size % sizeof (int)) == 0)
        copy_mode = 2;
    else
        copy_mode = 0;
    
    msort (base, tmp, 0, nmemb - 1, size, copy_mode, compare);
    
    free (tmp);
    
    return 0;
}
&lt;/pre&gt;
&lt;p&gt;This handy trick seems to have worked out rather well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Randomized input: 7.79s&lt;/li&gt;
&lt;li&gt;Sorted input: 0.99s&lt;/li&gt;
&lt;li&gt;Reversed input: 1.69s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point, I can't think of any other obvious optimizations so I'm going to call it a day.&lt;/p&gt;
&lt;p&gt;For a recap, here are the results of all 4 implementations compared side-by-side with the results from &lt;i style="font-family: courier new; font-size: 85%"&gt;qsort()&lt;/i&gt;:&lt;/p&gt;
&lt;table border="1"&gt;
 &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;qsort()&lt;/td&gt;&lt;td&gt;msort() v1&lt;/td&gt;&lt;td&gt;msort() v2&lt;/td&gt;&lt;td&gt;msort() v3&lt;/td&gt;&lt;td&gt;msort() v4&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;random:&lt;/td&gt;&lt;td&gt;6.77&lt;/td&gt;&lt;td&gt;14.13&lt;/td&gt;&lt;td&gt;10.45&lt;/td&gt;&lt;td&gt;9.80&lt;/td&gt;&lt;td&gt;7.79&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;sorted:&lt;/td&gt;&lt;td&gt;1.54&lt;/td&gt;&lt;td&gt;4.41&lt;/td&gt;&lt;td&gt;2.08&lt;/td&gt;&lt;td&gt;0.95&lt;/td&gt;&lt;td&gt;0.99&lt;/td&gt;&lt;/tr&gt;
 &lt;tr&gt;&lt;td&gt;reversed:&lt;/td&gt;&lt;td&gt;1.90&lt;/td&gt;&lt;td&gt;4.26&lt;/td&gt;&lt;td&gt;2.03&lt;/td&gt;&lt;td&gt;2.05&lt;/td&gt;&lt;td&gt;1.69&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4447604531618177791?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4447604531618177791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4447604531618177791' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4447604531618177791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4447604531618177791'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/04/optimizing-merge-sort.html' title='Optimizing Merge Sort'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-9003367599228732800</id><published>2011-04-03T13:52:00.000-04:00</published><updated>2011-04-03T13:52:51.178-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cooking'/><title type='text'>Low-Fat Turkey Sausage Recipe</title><content type='html'>&lt;p&gt;Just made my own home-made turkey sausage and figured I'd share my recipe with my fellow hackers.&lt;br /&gt;
&lt;p&gt;What you'll need:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;1.3 lbs ground turkey (I use 93/7)&lt;/li&gt;
&lt;li&gt;1 teaspoon ground black pepper&lt;/li&gt;
&lt;li&gt;1/4 teaspoon cayenne pepper&lt;/li&gt;
&lt;li&gt;1/2 teaspoon salt&lt;/li&gt;
&lt;li&gt;1/2 teaspoon ground ginger&lt;/li&gt;
&lt;li&gt;1/2 teaspoon dried sage&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Mix it all up real good and make a bunch of patties and brown in a frying pan at medium heat, over the grille, or where ever and you are done.&lt;/p&gt;&lt;p&gt;The result is very tasty and low fat.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-9003367599228732800?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/9003367599228732800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=9003367599228732800' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/9003367599228732800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/9003367599228732800'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/04/low-fat-turkey-sausage-recipe.html' title='Low-Fat Turkey Sausage Recipe'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5019693528813052470</id><published>2011-01-24T21:16:00.003-05:00</published><updated>2011-04-03T19:26:52.066-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cooking'/><title type='text'>Habanero Heat Chili</title><content type='html'>&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/5386402626/" title="photo sharing"&gt;&lt;img src="http://farm6.static.flickr.com/5219/5386402626_eaf661a138.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/5386402626/"&gt;Habanero Heat Wave&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/jstedfast/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;p&gt;Spiced up a traditional chili recipe with a handful of habanero peppers to keep me warm in this extremely cold Boston weather we've been having.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5019693528813052470?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5019693528813052470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5019693528813052470' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5019693528813052470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5019693528813052470'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/01/habanero-heat-chili.html' title='Habanero Heat Chili'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5219/5386402626_eaf661a138_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6854451314902561035</id><published>2011-01-22T19:44:00.004-05:00</published><updated>2011-01-23T10:57:14.720-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips+tricks'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Installing A Custom ROM on your Samsung Captivate</title><content type='html'>&lt;p&gt;Like a lot of people, I'm tired of waiting for AT&amp;T to get their acts together to release the &lt;a href="http://www.examiner.com/gadgets-in-san-francisco/samsung-galaxy-s-froyo-update-will-hit-u-s-by-end-of-november"&gt;long-awaited Froyo update&lt;/a&gt; for my &lt;a href="http://amzn.to/hOdcUw"&gt;Samsung Captivate&lt;/a&gt; phone.&lt;/p&gt;&lt;p&gt;I'm about to take matters into my own hands... but where do I begin?&lt;/p&gt;&lt;p&gt;Many of the forum threads out there contain the information needed to install a custom ROM, but the information is scattered about here and there which is confusing and not exactly confidence-inspiring. That's all about to change...&lt;/p&gt;&lt;p&gt;&lt;h3&gt;&lt;b&gt;Step 1: Rooting Your Phone&lt;/b&gt;&lt;/h3&gt;&lt;/p&gt;&lt;p&gt;The first step to installing a custom ROM is rooting your phone. This allows you to gain access to protected bits of your phone that you'll need in order to backup your existing data and the ability to install that custom ROM.&lt;/p&gt;&lt;p&gt;The easiest way to do this is to use the &lt;b&gt;One-Click Root&lt;/b&gt; application for the Captivate, but before you can do that, first you need to download and install the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992&amp;displaylang=en"&gt;Microsoft .NET Framework 4.0&lt;/a&gt; and the &lt;a href="http://forum.xda-developers.com/showthread.php?t=728929"&gt;Samsung USB drivers&lt;/a&gt; onto your computer.&lt;/p&gt;&lt;p&gt;Once you install those two pieces of software on your computer, the next step is to download the &lt;a href="http://theunlockr.com/down/Captivate%20One%20Click%20Root.zip"&gt;One-Click Root zip&lt;/a&gt; containing the easiest program I could find to root your phone for you.&lt;/p&gt;&lt;p&gt;Now you'll need to configure your Captivate's USB debug settings. To do this, first make sure you are at your phone's &lt;b&gt;Home&lt;/b&gt; screen. Then tap the &lt;b&gt;Menu&lt;/b&gt; button on the lower left-hand side of your phone and select &lt;b&gt;Settings&lt;/b&gt;. Scroll down and tap on the &lt;b&gt;Applications&lt;/b&gt; item. You should see a &lt;b&gt;Development&lt;/b&gt; option. Select that and then enable the &lt;b&gt;USB debugging&lt;/b&gt; checkbox at the top.&lt;/p&gt;&lt;p&gt;Now connect your Captivate phone to your computer via a USB cable.&lt;/p&gt;&lt;p&gt;Unzip the zip file and run the One-Click Root program. This will pop up a window with the Samsung Galaxy S logo and two buttons on the right ("One-Click Root" and "One-Click Unroot"). Click the button that says "One-Click Root".&lt;/p&gt;&lt;p&gt;This will cause your phone to reboot into a mode allowing you to to use your phone's volume buttons to navigate a text-mode screen of menu options up and down. Follow the directions in the blue text-mode window on your computer screen and select the &lt;b&gt;reinstall packages&lt;/b&gt; menu item on your phone. Press the Power button to start the process.&lt;/p&gt;&lt;p&gt;After the process is complete, your phone will reboot again - this time it will boot you back into the normal mode that you are familiar with.&lt;/p&gt;&lt;p&gt;At this point, it is safe to disconnect your phone from your computer.&lt;/p&gt;&lt;p&gt;For an extremely helpful video to walk you through the process of rooting your phone, &lt;a href="http://theunlockr.com/2010/08/02/how-to-root-the-samsung-vibrant-captivate/"&gt;watch this video&lt;/a&gt;.&lt;br /&gt;
&lt;p&gt;&lt;h3&gt;&lt;b&gt;Step 2: Backing Up Your Phone&lt;/b&gt;&lt;/h3&gt;&lt;/p&gt;&lt;p&gt;It is always a good idea to make a backup of your phone before proceeding any further, so here's how to do that:&lt;/p&gt;&lt;p&gt;Open the Android Marketplace application and search for and install "Titanium Backup", the free version is fine.&lt;/p&gt;&lt;p&gt;Once that finishes downloading, run the Titanium Backup program and tap on the &lt;b&gt;Backup/Restore&lt;/b&gt; button at the top of the screen.&lt;/p&gt;&lt;p&gt;Select each of the apps you'd like to backup and click the &lt;b&gt;Backup!&lt;/b&gt; button for each. Next, tap the &lt;b&gt;Menu&lt;/b&gt; button, select &lt;b&gt;More&lt;/b&gt; and then &lt;b&gt;Create "update.zip"...&lt;/b&gt; and follow the directions on the next screen before finally clicking the button to create the update.zip file.&lt;/p&gt;&lt;p&gt;At this point, you'll want to copy that &lt;b&gt;update.zip&lt;/b&gt; file along with the folder named &lt;b&gt;TitaniumBackup&lt;/b&gt; off your phone and onto your computer. To do this, first go back to your phone's &lt;b&gt;Home&lt;/b&gt; screen and then click &lt;b&gt;Menu&lt;/b&gt;. Select &lt;b&gt;Settings&lt;/b&gt;, &lt;b&gt;Applications&lt;/b&gt;, and then &lt;b&gt;USB settings&lt;/b&gt; (if this pops up a menu saying you'll need to disable USB debugging, just click OK). Now select &lt;b&gt;Mass storage&lt;/b&gt; and then click &lt;b&gt;Home&lt;/b&gt; again.&lt;/p&gt;&lt;p&gt;Re-connect your phone to your computer via the USB cable and then pull down the notification tray from the top of the screen on your phone.&lt;/p&gt;&lt;p&gt;Select the &lt;b&gt;USB connected&lt;/b&gt; item which will pop up a dialog box with two buttons: Mount and Unmount. Select &lt;b&gt;Mount&lt;/b&gt;. This will allow your computer to view the contents on each of your phone's internal memory drives.&lt;/p&gt;&lt;p&gt;On your phone's main drive, you should find a file named &lt;b&gt;update.zip&lt;/b&gt; and a folder named &lt;b&gt;TitaniumBackup&lt;/b&gt;. Copy them over to your computer for safe keeping.&lt;/p&gt;&lt;p&gt;&lt;h3&gt;&lt;b&gt;Step 3: Install A Custom ROM&lt;/b&gt;&lt;/h3&gt;&lt;/p&gt;&lt;p&gt;Keeping your phone connected to the computer from the previous step, download the &lt;a href="http://www.mediafire.com/?ve234hbg64ctcu0"&gt;ClockWork Recovery&lt;/a&gt; zip and then copy it over to your phone, renaming it to &lt;b&gt;update.zip&lt;/b&gt; (overwriting Titanium Backup's update.zip if it is still there from Step 2).&lt;/p&gt;&lt;p&gt;Once you've downloaded the zip file containing your chosen custom ROM (I'll be installing the &lt;a href="http://www.ponack.net/designgears/cognition/"&gt;latest version of Cognition&lt;/a&gt;), you'll need to copy the downloaded zip over to your phone's internal memory drive.&lt;/p&gt;&lt;p&gt;Once you've done that, disconnect your phone from your computer and turn off your phone. Next, hold down both volume buttons and the power button at the same time. This should boot you into an Android system menu.&lt;/p&gt;&lt;p&gt;Select &lt;b&gt;reinstall packages&lt;/b&gt; using the volume-down button to select it and then pressing the power button to activate. This will install ClockWork Recovery and then bring you back to a green text-mode menu screen (if it doesn't, select &lt;b&gt;reboot system now&lt;/b&gt;, turn off your phone and try the procedure again).&lt;/p&gt;&lt;p&gt;Select the &lt;b&gt;install zip from sdcard&lt;/b&gt; option using your phone's volume buttons and press the power button.&lt;/p&gt;&lt;p&gt;At the next green menu screen, select &lt;b&gt;choose zip from sdcard&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Navigate the file system to select your ROM zip file and then press the power button.&lt;/p&gt;&lt;p&gt;Finally, confirm that you want to install the ROM by selecting the &lt;b&gt;Yes&lt;/b&gt; menu option.&lt;/p&gt;&lt;p&gt;At this point, your phone should be installing the custom ROM that you've chosen. This will take a few minutes, so go watch some TV, update your &lt;a href="http://www.facebook.com"&gt;Facebook page&lt;/a&gt;, or go &lt;a href="http://twitter.com"&gt;tweet&lt;/a&gt; about how you're installing your custom ROM on your Captivate phone (make that a few dozen tweets, because installing will take a while).&lt;/p&gt;&lt;p&gt;Note: If the "Installing..." screen stays at "Finding update package..." for more than a minute or two (this always seems to happen to me), something is probably wrong. Simply pop out the battery and then boot the phone into recovery mode and try again.&lt;/p&gt;&lt;p&gt;Once the install is complete, you'll find yourself back at a green menu. Select &lt;b&gt;+++++Go Back+++++&lt;/b&gt;. At the next green menu screen, select &lt;b&gt;reboot system now&lt;/b&gt; and press the power button.&lt;/p&gt;&lt;p&gt;The first boot up will likely take longer than normal (Cognition's ROM gives you cool female computer voice updates explaining what it is doing), so don't be discouraged if it takes a good 5 minutes or so to boot up.&lt;/p&gt;&lt;p&gt;Congratulations, you've just installed your custom ROM!&lt;/p&gt;&lt;p&gt;&lt;h3&gt;&lt;b&gt;Step 4: Restoring Your Applications&lt;/b&gt;&lt;/h3&gt;&lt;/p&gt;&lt;p&gt;The first thing you'll need to do is open up the Android Market application and install Titanium Backup again (or you could connect your phone to your computer and copy the update.zip that was created by Titanium Backup program back onto your phone and reboot it into recovery mode to install the update.zip that way).&lt;/p&gt;&lt;p&gt;If you installed Cognition, like I did, then it will come pre-bundled with Titanium Backup so you'll have everything you need.&lt;/p&gt;&lt;p&gt;Launch Titanium Backup and tap &lt;b&gt;Backup/Restore&lt;/b&gt;. Next, press your phone's &lt;b&gt;Menu&lt;/b&gt; button and select &lt;b&gt;Batch&lt;/b&gt;. This will bring you to a menu of actions with a "Run" button next to each one. Scroll down to &lt;b&gt;Restore missing apps with data&lt;/b&gt; and then tap the &lt;b&gt;Run&lt;/b&gt; button next to it, following the instructions that follow.&lt;/p&gt;&lt;p&gt;At this point you may need to reboot your phone in order for some of your apps to be seen by the phone (since some may need to be there at boot-up), so go ahead and do that.&lt;/p&gt;&lt;p&gt;You are now finished!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6854451314902561035?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6854451314902561035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6854451314902561035' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6854451314902561035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6854451314902561035'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/01/installing-custom-rom-on-your-samsung.html' title='Installing A Custom ROM on your Samsung Captivate'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-8226632738298388664</id><published>2011-01-18T14:10:00.006-05:00</published><updated>2011-01-18T17:53:24.728-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='rants'/><title type='text'>I am Disappoint: No Love for Froyo on Galaxy S</title><content type='html'>&lt;p&gt;Based on an anonymous post on the &lt;a href="http://forum.xda-developers.com/showthread.php?t=913045"&gt;XDA Developer Forums&lt;/a&gt;, the reason behind the lack of a Froyo update for Samsung Galaxy S phones in the US appears to be because Samsung is greedy.&lt;/p&gt;&lt;p&gt;The following quote is the entirety of the message as it appears on the forums for your convenience (with added emphasis by me).&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Hello,&lt;/p&gt;&lt;p&gt;I’m going to step across the NDAs and explain the issues behind the Android Froyo update to Samsung Galaxy S phones in the United States. I think most of you have come to this realization yourself now: the withholding of the Froyo update is a largely political one, not a technological one: Froyo runs quite well on Galaxy S phones, as those of you that have run leaked updates may have noticed.&lt;/p&gt;&lt;p&gt;To explain the political situation, first, a primer on how phone firmware upgrades work for carriers. When a carrier decides to sell a phone, a contract is usually written between the phone manufacturer and the carrier. In this contract, the cost of updates (to the carrier) is usually outlined. Updates are usually broken into several types: critical updates, maintenance updates, and feature updates. Critical updates are those that resolve a critical bug in the phone, such as the phone overheating. Maintenance updates involve routine updates to resolve bugs and other issues reported by the carrier. Finally, feature updates add some new feature in software that wasn’t present before. Critical updates are usually free, maintenance updates have some maintenance fee associated with them, and feature updates are usually costly.&lt;/p&gt;&lt;p&gt;In the past, most phone updates would mainly consist of critical and maintenance updates. Carriers almost never want to incur the cost of a feature update because it is of little benefit to them, adds little to the device, and involves a lot of testing on the carrier end. Android has changed the playing field, however – since the Android Open Source Project is constantly being updated, and that information being made widely available to the public, there is pressure for the phone to be constantly updated with the latest version of Android. With most manufacturers, such as HTC, Motorola, etc. This is fine and considered a maintenance upgrade. &lt;b&gt;&lt;i&gt;Samsung, however, considers it a feature update, and requires carriers to pay a per device update fee for each incremental Android update.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Now, here’s where the politics come in: &lt;b&gt;&lt;i&gt;most U.S. carriers aren’t very happy with Samsung’s decision to charge for Android updates as feature updates, especially since they are essentially charging for the Android Open Source Project’s efforts, and the effort on Samsung’s end is rather minimal. As a result of perhaps, corporate collusion, all U.S. carriers have decided to refuse to pay for the Android 2.2 update, in hopes that the devaluation of the Galaxy S line will cause Samsung to drop their fees and give the update to the carriers.&lt;/i&gt;&lt;/b&gt; The situation has panned out differently in other parts of the world, but this is the situation in the United States.&lt;/p&gt;&lt;p&gt;Some of you might have noticed Verion’s Fascinate updated, but without 2.2 : This is a result of a maintenance agreement Samsung must honor combined with Verizon’s unwillingness to pay the update fees. &lt;b&gt;&lt;i&gt;In short, Android 2.2 is on hold for Galaxy S phones until the U.S. carriers and Samsung reach a consensus.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Some might wonder why I didn’t deliver this over a more legitimate news channel – the short answer: I don’t want to lose my job. I do, however, appreciate transparency, which is why I'm here.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Having bought a Samsung Galaxy S phone back in August with the expectation that it would get the Froyo update &lt;i&gt;soon&lt;/i&gt;, I am disappoint.&lt;/p&gt;&lt;p&gt;This is just one more annoyance added to my growing list of annoyances about Android-based phones and my Galaxy S phone in particular.&lt;/p&gt;&lt;p&gt;Bitch and moan about Apple being evil all you want, but even Apple doesn't do this to their users. I will never ever buy another Samsung Android phone again. This really rubs me the wrong way.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; People have been commenting that Android devices have gotten better OS update support than iPhones. This is simply not the case. The iPhone 3G came out ~6 months before the Android G1 and the G1 stopped getting updates (latest update was Android 1.6) &lt;i&gt;looooooooong&lt;/i&gt; before the iPhone 3G stopped getting updates. Apple at least kept providing updates to the 3G through iOS 4.1.x, latest update being this past fall. So even though the iPhone 3G is &lt;i&gt;older&lt;/i&gt; than the G1, it got OS updates until long after updates stopped coming for the G1. My point is that to even compare the G1 to the iPhone 3G in terms of time supported by new OS upgrades, the G1 would have to at least have Android 2.2 (which came out how long ago?? I mean, even 2.3 is out now). In other words: Apple pushes all OS upgrades for their iPhones for at least 2 years (length of a contract) while no Android handset maker ever has - the G1 got OS upgrades for what? 6 months?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-8226632738298388664?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/8226632738298388664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=8226632738298388664' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8226632738298388664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8226632738298388664'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2011/01/i-am-disappoint-no-love-for-froyo-on.html' title='I am Disappoint: No Love for Froyo on Galaxy S'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3418460394924190119</id><published>2010-12-19T21:36:00.000-05:00</published><updated>2010-12-19T21:36:01.904-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='art of possibility'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='zen'/><title type='text'>The Unfettered Mind</title><content type='html'>&lt;p&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/4732404889/" title="IMG_1879 by jstedfast, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1428/4732404889_ae42e5b5c2.jpg" width="500" height="333" alt="IMG_1879" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;/p&gt;&lt;p&gt;During the past month or so, I've been reading books like &lt;a href="http://en.wikipedia.org/wiki/Sun_tzu"&gt;Sun Tzu&lt;/a&gt;'s &lt;a href="http://amzn.to/emPq1a"&gt;The Art of War&lt;/a&gt; and Benjamin Zander's &lt;a href="http://amzn.to/gG9pSr"&gt;The Art of Possibility&lt;/a&gt;. Reading the Art of War gave me a much deeper appreciation for Eastern philosophy and I find myself recognizing a lot of those same philosophical ideas in The Art of Possibility as well which has gotten me even more interested in continuing on with this reading trend.&lt;/p&gt;&lt;p&gt;From what I understand, &lt;a href="http://en.wikipedia.org/wiki/Miyamoto_Musashi"&gt;Miyamoto Musashi&lt;/a&gt;, like Sun Tzu, is another man who many consider to have been a "Zen Master" and so I'll be reading his book over the holiday: &lt;a href="http://amzn.to/dLDRJi"&gt;The Book of Five Rings&lt;/a&gt;. But before I read that, I plan on first reading &lt;a href="http://amzn.to/gdQy1R"&gt;The Lone Samurai: The Life of Miyamoto Musashi&lt;/a&gt; to get a broader understanding of the man. What I really liked about the copy of The Art of War that I picked up (Understanding the Art of War by Robert Cantrell) is that the author not only included the English translation of the original text but also explanations of the history pertinent to understanding the text allowing me to soak up quite a bit more value than I would have just reading the raw English translation. Likewise, I suspect that starting with The Lone Samurai might help me later in understanding Miyamoto Musashi's Book of Five Rings.&lt;/p&gt;&lt;p&gt;A third book that caught my eye for the holiday is &lt;a href="http://amzn.to/dWusyk"&gt;The Unfettered Mind&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/Takuan_S%C5%8Dh%C5%8D"&gt;Takuan Sōhō&lt;/a&gt;, another famous Zen Master who is rumored to have advised Miyomoto Musashi among others.&lt;/p&gt;&lt;p&gt;Maybe one day I, too, will have an unfettered mind (right now it is quite fettered).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3418460394924190119?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3418460394924190119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3418460394924190119' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3418460394924190119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3418460394924190119'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/12/unfettered-mind.html' title='The Unfettered Mind'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1428/4732404889_ae42e5b5c2_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5005175660632052550</id><published>2010-12-13T09:49:00.002-05:00</published><updated>2010-12-16T08:03:55.476-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='art of possibility'/><category scheme='http://www.blogger.com/atom/ns#' term='pulseaudio'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><category scheme='http://www.blogger.com/atom/ns#' term='zen'/><title type='text'>Assignment: Apologize to someone you have wronged</title><content type='html'>&lt;p&gt;This past Friday, on our walk back from lunch, &lt;a href="http://tirania.org/blog"&gt;Miguel&lt;/a&gt; told me about the latest assignment given to him by his teacher and mentor, &lt;a href="http://www.benjaminzander.com/"&gt;Benjamin Zander&lt;/a&gt;, the conductor of the &lt;a href="http://www.bostonphil.org/"&gt;Boston Philharmonic&lt;/a&gt;. The assignment was to pick someone you have wronged and apologize to them.&lt;/p&gt;&lt;p&gt;For those who don't know, Benjamin Zander is the author of the book, &lt;a href="http://amzn.to/fi53Qj"&gt;The Art of Possibility&lt;/a&gt;, a book which I have been reading the past week or so. The idea of this book is to change your perspective on life by teaching you to see things in a positive light and thus present you with a world of possibility where you can accomplish anything you set your mind to because you are no longer held back by negative thinking (fear of failure, criticism from others, and most importantly, criticism from yourself).&lt;/p&gt;&lt;p&gt;To continue on with my story, as I was laying in bed last night after having read a few more chapters in The Art of Possibility, I was reminded of Miguel's assignment and I began to wonder: if I was given this assignment, who would &lt;i&gt;I&lt;/i&gt; apologize to?&lt;/p&gt;&lt;p&gt;I thought of 1 person in particular and a community of users and decided to apologize to them all.&lt;/p&gt;&lt;p&gt;&lt;h3&gt;Lennart Poettering&lt;/h3&gt;&lt;/p&gt;&lt;p&gt;Some of you might recall a series of rants about PulseAudio that I wrote a couple of years back. While it was not my intention to insult Lennart personally, it is obvious that I did. I had let my anger and frustration rule my actions and ended up attacking PulseAudio in ways I should not have. I should have, instead, been more respectful, more understanding and more patient. Attacking someone's project often results in that person feeling personally attacked. I should know this as well or better than anyone because I'm one of the authors of the most widely attacked projects in the Free Software community: &lt;a href="http://projects.gnome.org/evolution/"&gt;Evolution&lt;/a&gt;, &lt;a href="http://www.mono-project.com/"&gt;Mono&lt;/a&gt;, and &lt;a href="http://www.go-mono.com/moonlight/"&gt;Moonlight&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;These days PulseAudio has been working well for me and that is a testament to how hard working Lennart and the other PulseAudio developers are.&lt;/p&gt;&lt;p&gt;Thank you, Lennart, for your hard work on Pulse Audio and please accept my sincerest apology for attacking your project and in so doing, insulting you. I was wrong. I should have, instead, come to you (or the bug tracker) and explained the problems I was experiencing in a polite and respectful manner rather than unleashing my frustrations on the project.&lt;br /&gt;
&lt;p&gt;I hope we can meet in person at a future Linux or GNOME conference where I can give you a hug (and who knows, maybe even a beer).&lt;/p&gt;&lt;p&gt;&lt;h3&gt;Evolution Users&lt;/h3&gt;&lt;/p&gt;&lt;p&gt;In the course of the 6+ years that I worked on Evolution, there were a number of occasions where I took criticisms in bug reports and the mailing-list as personal insults and lost my temper, attacking back. At one point, &lt;a href="http://nat.org"&gt;Nat Friedman&lt;/a&gt; reminded me that I should not take criticism of Evolution so personally and that the reason users criticized Evolution was because they &lt;i&gt;cared&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;In the early part of 2007 I moved over to the Mono team, giving me a fresh start. I decided that I was going to be a new me and really take Nat Freidman's words to heart. I'm happy to report that not only have I been successful in not taking criticism as personally and seeing criticism of projects I work on in a new, more positive light, but I have also been a much happier person because of it.&lt;/p&gt;&lt;p&gt;For those Evolution users out there who I have mistreated, I am truly sorry and I hope that my actions over the past 3 years has demonstrated my sincerity.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5005175660632052550?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5005175660632052550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5005175660632052550' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5005175660632052550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5005175660632052550'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/12/assignment-apologize-to-someone-you.html' title='Assignment: Apologize to someone you have wronged'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2423627810797909730</id><published>2010-10-27T22:31:00.001-04:00</published><updated>2010-10-27T22:32:24.971-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kung fu'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><title type='text'>Lessons in Freedom</title><content type='html'>&lt;p&gt;In the first episode of the second season of Kung Fu, there exists a dialog between a young Kwai Chang Caine and one of his instructors, Master Po which I think teaches an important lesson in freedom and what it means. I think there are a number of people in the Free Software community who are in desperate need of learning this particular lesson.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;b&gt;Master Po:&lt;/b&gt; &lt;i&gt;What have you found?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Young Kwai Chang Caine:&lt;/b&gt; &lt;i&gt;A spider, master. It has trapped the fly. Should I destroy his web?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Master Po:&lt;/b&gt; &lt;i&gt;Why?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Young Kwai Chang Caine:&lt;/b&gt; &lt;i&gt;So that it will not make a prison for other living things that were free.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Master Po:&lt;/b&gt; &lt;i&gt;Look more closely, grasshopper. Were you to destroy this web, would not the spider, knowing no other way, build another?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Young Kwai Chang Caine:&lt;/b&gt; &lt;i&gt;Yes, but I cannot kill the spider.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Master Po:&lt;/b&gt; &lt;i&gt;Look more closely still. Is not the spider also trapped by its own web?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Young Kwai Chang Caine:&lt;/b&gt; &lt;i&gt;Yes, but if I do nothing, it will capture more living things, make them prisoner, and kill them.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Master Po:&lt;/b&gt; &lt;i&gt;You are concerned, then, with the fly to which nature has given wings so that it might move around freely?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Young Kwai Chang Caine:&lt;/b&gt; &lt;i&gt;It is cruel to see it made a prisoner.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Master Po:&lt;/b&gt; &lt;i&gt;Ha ha ha. Still you do not see. Which is truly the prisoner? The fly, which, moving freely enters unknown danger? Or the spider, which, having spun its web, remains, never knowing the pleasure or the danger of the fly?&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2423627810797909730?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2423627810797909730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2423627810797909730' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2423627810797909730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2423627810797909730'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/10/lessons-in-freedom.html' title='Lessons in Freedom'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1370791452683555904</id><published>2010-09-02T14:12:00.001-04:00</published><updated>2010-09-02T15:10:04.730-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>Microsoft Double Rainbow!</title><content type='html'>&lt;p&gt;Microsoft has just created a new commercial for its Windows Live Photo Gallery software that plays on the "Double Rainbow!" stoner guy. I have to give them props for trying to be hip and cool, but I'm too busy laughing my butt off right now. You've got to see this:&lt;/p&gt;&lt;object width="640" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/8jXz7NrfzsI?fs=1&amp;amp;hl=en_US"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/8jXz7NrfzsI?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;p&gt;What I want to know is what kind of camera is that guy using? Never seen anything like it. A friend suggested it was &lt;a href="http://tinyurl.com/26tetkz"&gt;this antique digital camera&lt;/a&gt;, but I'm not convinced. If you have any idea what that camera is, let me know in the comments - it is gonna bug me for days until I know what that was!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1370791452683555904?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1370791452683555904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1370791452683555904' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1370791452683555904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1370791452683555904'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/09/microsoft-double-rainbow.html' title='Microsoft Double Rainbow!'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-840680849620753091</id><published>2010-08-17T16:36:00.001-04:00</published><updated>2010-08-17T18:59:48.866-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>One Week With Android</title><content type='html'>&lt;p&gt;Well, it's been just over a week since I got my &lt;a href="http://www.amazon.com/gp/product/B003TLMQG8?ie=UTF8&amp;amp;tag=amoofze-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B003TLMQG8"&gt;Samsung Captivate&lt;/a&gt; (which is selling for $50 right now!) and I figured I'd share my experiences switching to it from my old iPhone 3G. Sadly, I have to say it's still a bit rough around the edges. I've had a number of problems with it, but none of them have been insurmountable.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;font size=+1&gt;The Good&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Even though I'm still on Android 2.1 (FroYo, aka 2.2, won't be pushed on my phone until September or so), I've had no problems at all with performance. Everything starts up pretty quickly for the most part (occasional lag spikes, but I got those on my old iPhone as well). The 2.2 update will supposedly make my phone even faster, so I'm excited about that.&lt;/p&gt;&lt;p&gt;All the apps I cared about are available in the Android Market (things like a twitter client, Amazon shopping app, Google Maps (duh), Fandango and a handful of others). I was also able to find apps like Adobe Reader and Quickoffice for loading pdfs and MS Office documents (which is handy and something that I never found on iPhone).&lt;/p&gt;&lt;p&gt;Likely due to a higher-resolution screen, the YouTube video quality on my &lt;a href="http://www.amazon.com/gp/product/B003TLMQG8?ie=UTF8&amp;amp;tag=amoofze-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B003TLMQG8"&gt;Samsung Captivate&lt;/a&gt; also exceeds that of my old iPhone 3G. Not sure how it compares to the iPhone 4.&lt;/p&gt;&lt;p&gt;What I &lt;i&gt;really&lt;/i&gt; like about the Android is that editing my Google Contacts auto-updates my phone within seconds of making the changes which is really nice. I didn't pay for the MobileMe service for iPhone (which supposedly adds this feature), so it's a nice bonus that has saved me a bit of time and trouble already.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;&lt;font size=+1&gt;The Bad&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;While the music player on Android isn't bad (it's quite usable), it lacks some finishing touches that Apple put into theirs. For example, iPhone's music player remembers the most recent audio track and position you were listening to when you launch it. No amount of browsing your music collection will confuse it. This is not true with Android's. A "Go back 30 seconds" button would also be a really nice addition to Android's music player that iPhone has and I've found to be quite useful over the past 2 years.&lt;/p&gt;&lt;p&gt;When making a call, the iPhone's display is much much nicer than Android's and the Contacts app itself is more intuitive. I don't even understand what most of the tabs are in Android's Contacts app, for instance.&lt;/p&gt;&lt;img border="0" src="http://digitaldaily.allthingsd.com/files/2007/06/iphone_calling_johnapplesee.jpg" width="225" height="300"&gt;&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/_CrWGagj8HJU/TGsSr71rHdI/AAAAAAAAAnU/VBhhflaA4QU/s1600/android-call-screen.jpg" imageanchor="1"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_CrWGagj8HJU/TGsSr71rHdI/AAAAAAAAAnU/VBhhflaA4QU/s320/android-call-screen.jpg" width="225" height="300"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;font size=+1&gt;The Ugly&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The following 2 problems are the absolute worst usability problems I have encountered, and they are pretty bad.&lt;/p&gt;&lt;p&gt;It took me a while to figure this out, but when you plug your Android phone into your PC, the PC won't see your Android device over USB Mass Storage at all until you open up your phone's "Notifications" area and tap on the notification saying something about connecting via USB. Once you do that, it opens up a dialog with the option to mount the drives. Only after you take these steps does the Android device show up as a USB Mass Storage device on your PC. This is just awful. Why are these manual steps even needed at all? If I have edited my phone's settings and selected "USB Mass Storage", it should just assume that's what I want to do when I plug it into a PC. There's no good reason for it to make me manually go through those steps. It also seems I'm not the first to be confused by this as there are a number of users complaining about this on various Android forums. From what I've seen, things have gotten better in Android 2.2 (it no longer makes you navigate to the "Notifications" area, but it still requires you to interact with a Mount/Cancel dialog).&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_CrWGagj8HJU/TGP34q-U3hI/AAAAAAAAAms/jguK8NO484c/s1600/p1010079.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_CrWGagj8HJU/TGP34q-U3hI/AAAAAAAAAms/jguK8NO484c/s320/p1010079.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;The above photograph is what happened when I tried to place a call to about half the people in my contacts list. Yea, that's right, it crashed. After a bit of fiddling, I was able to figure out what it was about those contacts which caused the problem and &lt;a href="http://code.google.com/p/android/issues/detail?id=10377"&gt;submitted a bug report&lt;/a&gt;. Luckily, the workaround that I found was trivial and so I just loaded a web browser and edited the Birthday field info for those contacts and waited a second or two for the Android to auto-sync. Had I not been able to find a solution to this problem, I would have returned my phone and gone back to iPhone.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;font size=+1&gt;TL;DR&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Android has a lot of room for improvement (buggy, unpolished), but if you are a Linux Desktop user like myself, you'll probably feel right at home.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-840680849620753091?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/840680849620753091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=840680849620753091' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/840680849620753091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/840680849620753091'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/08/one-week-with-android.html' title='One Week With Android'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CrWGagj8HJU/TGsSr71rHdI/AAAAAAAAAnU/VBhhflaA4QU/s72-c/android-call-screen.jpg' height='72' width='72'/><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1325240526349405505</id><published>2010-08-10T16:24:00.006-04:00</published><updated>2010-08-10T16:34:18.616-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monodevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Using Git</title><content type='html'>&lt;center&gt;&lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/0596520123?ie=UTF8&amp;tag=amoofze-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596520123"&gt;&lt;img src="http://lh3.ggpht.com/_CrWGagj8HJU/TGG2uf3gyyI/AAAAAAAAAlk/L_bqw5R3mv0/41FOKkFFJZL._SL160_.jpg" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;
&lt;p&gt;Now that &lt;a href="http://tirania.org/blog/archive/2010/Jul-22.html"&gt;Mono has moved to GitHub&lt;/a&gt;, a number of contributors (including myself) have been somewhat lost, not knowing how to properly use Git. So today, I'm recommending a book to help all the lost souls out there get comfortable with using Git.&lt;/p&gt;&lt;p&gt;As many long-time programmers probably know, O'Reilly books are top notch. Most probably also would not be surprised that O'Reilly has a book covering Git: &lt;a href="http://www.amazon.com/gp/product/0596520123?ie=UTF8&amp;tag=amoofze-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596520123"&gt;Version Control with Git: Powerful Tools and Techniques for Collaborative Software Development&lt;/a&gt;.&lt;br /&gt;
&lt;p&gt;Don't let the bat scare you.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1325240526349405505?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1325240526349405505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1325240526349405505' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1325240526349405505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1325240526349405505'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/08/using-git.html' title='Using Git'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_CrWGagj8HJU/TGG2uf3gyyI/AAAAAAAAAlk/L_bqw5R3mv0/s72-c/41FOKkFFJZL._SL160_.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4409178095131764212</id><published>2010-08-06T08:15:00.001-04:00</published><updated>2010-08-06T08:16:32.309-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monodroid'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>New Phone (Android)</title><content type='html'>&lt;p&gt;Ever since the first Android phones came out back in October 2008, I've been keeping an eye on their progress. I didn't care for the original HTC Hero, but the newest phones based on Android 2.1/2.2 look very impressive. Now that my iPhone 3G contract is up, I decided I'd get one. Since I'm on AT&amp;T and wanted to stay with that provider, I went with the &lt;a href="http://www.amazon.com/gp/product/B003TLMQG8?ie=UTF8&amp;tag=amoofze-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B003TLMQG8"&gt;Samsung Captivate&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=amoofze-20&amp;l=as2&amp;o=1&amp;a=B003TLMQG8" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; and a &lt;a href="http://www.amazon.com/gp/product/B003WK8YX0?ie=UTF8&amp;tag=amoofze-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B003WK8YX0"&gt;screen protector&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=amoofze-20&amp;l=as2&amp;o=1&amp;a=B003WK8YX0" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; for it. My friend/co-worker, &lt;a href="http://mjhutchinson.com/"&gt;Michael Hutchinson&lt;/a&gt;, recently bought a &lt;a href="http://www.amazon.com/gp/product/B003TXSKNE?ie=UTF8&amp;tag=amoofze-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B003TXSKNE"&gt;Samsung Vibrant&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=amoofze-20&amp;l=as2&amp;o=1&amp;a=B003TXSKNE" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; (he's on T-Mobile) and has been very happy with it. Another friend/co-worker, &lt;a href="http://gonzalo.name/blog"&gt;Gonzalo&lt;/a&gt; has also been happy with his switch to the Captivate on AT&amp;T, so I expect that I'll be pleased as well.&lt;/p&gt;&lt;p&gt;One of the reasons I decided to get an Android phone is that the Mono team is working on &lt;a href="http://tirania.org/blog/archive/2010/May-21.html"&gt;MonoDroid&lt;/a&gt;, a port of Mono to Android phones. While I'm not on the team working on the port, I &lt;i&gt;am&lt;/i&gt; interested as a potential Android developer in using MonoDroid to write some of my own applications for Android phones.&lt;/p&gt;&lt;p&gt;10 years ago, when I first started working for Helix Code on the GNOME desktop for Linux to help make Linux usable for average Joes, I never expected that I'd ever have a &lt;i&gt;phone&lt;/i&gt; that ran Linux! Especially a Linux-based phone that is &lt;a href="http://www.reuters.com/article/idUSN0410592620100805"&gt;taking the smart-phone market by storm!&lt;/a&gt; These are very exciting times for me, and I'm &lt;i&gt;sure&lt;/i&gt; for the Google folks working on the Android project!&lt;/p&gt;&lt;p&gt;After I get my feet wet for a week or so with using my new Captivate phone, I'll try to write up a review of what I think, so stay tuned!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4409178095131764212?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4409178095131764212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4409178095131764212' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4409178095131764212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4409178095131764212'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/08/new-phone-android.html' title='New Phone (Android)'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-408273727662906154</id><published>2010-08-04T10:27:00.001-04:00</published><updated>2010-08-04T13:38:31.650-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='outdoors'/><category scheme='http://www.blogger.com/atom/ns#' term='backpacking'/><category scheme='http://www.blogger.com/atom/ns#' term='lazyweb'/><title type='text'>Sleeping Bags for Backpacking</title><content type='html'>&lt;p&gt;Some friends and I have been talking about going on a multi-day backpacking trip (first one will likely be an "easy" trip, where we'll almost be able to drive up to the camp site, just to test everything out, etc). Most of us don't have the proper equipment (anymore) and things have changed a lot since the last time (in my boy scout days, oh-so-long ago) I've been out on a multi-day camping trip (never really done the backpacking thing before), so I've been doing a bit of research.&lt;/p&gt;&lt;p&gt;First and foremost, I knew I'd need a sleeping bag so the first step was deciding what kind of temperature rating I'd need my bag to meet. Did a bit of reading and discovered that starting this year, most sleeping bag makers in the US have switched over to the &lt;a href="http://en.wikipedia.org/wiki/EN_13537"&gt;European standard&lt;/a&gt; for rating sleeping bags. This was comforting news (hah, bad joke) in that comparing sleeping bag temperature ratings would be a lot more like comparing apples to apples (previously each manufacturer had their own method of measuring this, so comparing bags from different makers was impossible to do).&lt;/p&gt;&lt;p&gt;Since my friends and I will likely be sticking to the North East, and probably in the late-spring to early-fall time frame, I estimated that I wouldn't want a bag rated for anything warmer than 30 degrees. Even in mid-summer, the North East can get down to the low 50's and so a 40-degree bag would barely be warm enough. Note that the temperature rating on a sleeping bag is often the "survivability" rating as opposed to the "comfort" rating, and I prefer to be comfortable! Since I'm prepping for the possibility of backpacking trips in the spring and fall as well, I figured a 20-degree bag would be a safer bet.&lt;/p&gt;&lt;p&gt;Next, I had to decide on the type of filling so I read up on the difference between synthetic and down filling. To sum up, here's what I learned:&lt;ul&gt;&lt;li&gt;Down is often lighter, especially the higher the fill rating (e.g. you might see things like 650-fill or 800-fill - the higher the fill rating, the less down you need to occupy the same space, resulting in a lighter weight bag).&lt;/li&gt;
&lt;li&gt;For down-filled sleeping bags, duck vs goose doesn't really matter, what matters is the fill rating.&lt;/li&gt;
&lt;li&gt;For damp environments, synthetic is often a better choice because synthetic-filled sleeping bags only lose 15% of their effective warmth when wet, while down-filled would lose 100%.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;I wanted to keep my expenses below $200 if I could, so with that in mind I did some searching to find some sleeping bags in that price range with good reviews and I came up with the following bags:&lt;ul&gt;&lt;li&gt;Down: &lt;a href="http://www.amazon.com/gp/product/B002YXUWP4?ie=UTF8&amp;tag=amoofze-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B002YXUWP4"&gt;Kelty Light Year 20-Degree Sleeping Bag&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=amoofze-20&amp;l=as2&amp;o=1&amp;a=B002YXUWP4" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;/li&gt;
&lt;li&gt;Synthetic: &lt;a href="http://www.rei.com/product/763623"&gt;The North Face Cat's Meow 20-Degree Sleeping Bag&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Both bags were very highly rated in various magazines and online reviews that I had seen and both were around $160 for the Regular size (up to 6') and $170 for Long (fitting up to 6'6", which is what I needed). There are some cheaper bags, but most of them aren't as lightweight (under 3 lbs!) as either of these 2 bags and/or they didn't get as good a review (or didn't have any review that I could find). If you want cheap, you could go to Walmart and find &lt;a href="http://www.walmart.com/search/search-ng.do?search_constraint=0&amp;ic=48_0&amp;search_query=sleeping+bag&amp;Find.x=0&amp;Find.y=0&amp;Find=Find"&gt;sleeping bags for as cheap as $10&lt;/a&gt;, but I'm not sure I personally trust that any of those bags will be a good long-term investment. Maybe I've just been bitten once too many times by the lure of the uber-cheap.&lt;/p&gt;&lt;p&gt;In the end, I decided to go with the Kelty Light Year as it was a little lighter (4 oz) and packed a little smaller. While the dampness drawback did/does concern me a little, there are easy ways around that. Wrapping your sleeping bag in a plastic (or otherwise waterproof) bag while it is packed away in your backpack and not pulling it out until it is inside the tent should suffice in preventing it from getting wet, even if you have to pitch your tent in the rain.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-408273727662906154?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/408273727662906154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=408273727662906154' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/408273727662906154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/408273727662906154'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/08/sleeping-bags-for-backpacking.html' title='Sleeping Bags for Backpacking'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-551519726275278996</id><published>2010-07-29T21:12:00.002-04:00</published><updated>2010-07-30T12:11:40.538-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='free software'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Re: Red Hat, 16%. Canonical, 1%.</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://trollcats.com/2010/07/best-teammate-ever-trollcat/" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" width="204" height="300" src="http://trollcats.com/wp-content/uploads/2010/07/be_a_dick_point_out_the_obvious_trollcat.jpg"/&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;While some people are busy &lt;a href="http://gregdekspeaks.wordpress.com/2010/07/29/red-hat-16-canonical-1/"&gt;complaining that Canonical doesn't contribute as much as others&lt;/a&gt;, I'd like for everyone to take a step back and ask themselves, &lt;i&gt;"what would &lt;a href="http://www.rleeermey.com/"&gt;Gunny&lt;/a&gt; say?"&lt;/i&gt;&lt;/p&gt;&lt;p&gt;I'll tell you what he'd say. He'd say,&lt;/p&gt;&lt;blockquote&gt;Hmm, that's interesting. Do you know what makes &lt;i&gt;me&lt;/i&gt; sad? &lt;i&gt;&lt;b&gt;YOU DO!&lt;/b&gt;&lt;/i&gt; Maybe we should chug on over to mamby-pamby land where &lt;i&gt;maybe&lt;/i&gt; we can find some self-confidence for you, you jack-wagon! Want a tissue?&lt;/blockquote&gt;&lt;p&gt;After he finished ripping someone a new one, he'd point out that in that very same &lt;a href="http://www.slideshare.net/nearyd/gnome-census"&gt;GNOME Census slide deck&lt;/a&gt;, I am ranked #8 in the top contributors list and I haven't contributed much of anything to any of the core GNOME components in about 5 years.&lt;/p&gt;&lt;p&gt;Yeah, that's right you cry babies, I put &lt;i&gt;all y'all&lt;/i&gt; to shame.&lt;/p&gt;&lt;p&gt;On a more serious note, for better or worse, we all knew what we were getting into when we decided to take up the Free Software baton and start running with it. This is just how Free Software works. Don't like it? &lt;a href="http://www.youtube.com/watch?v=DksSPZTZES0"&gt;Cry me a river&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;tl;dr&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://trollcats.com/2010/06/just-keeping-it-real-amigo-trollcat/" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" width="265" height="199" src="http://trollcats.com/wp-content/uploads/2010/05/youre_a_great_friend_but_if_the_zombies_chase_us_im_tripping_you_trollcat.jpg"/&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; It seems my post here has been misinterpreted. Allow me to try and rectify this. I'm not pissed off at Greg for voicing his opinion. We all do it. I'm just making a mockery of the whole situation because I was itching to trollcat and because I wanted to pat myself on the back for being #8 on the individual contributors list in terms of commits (as meaningless as that is). Also because I was up late last night and saw that &lt;a href="http://www.youtube.com/watch?v=XfmVBmDKLZI"&gt;Geico commercial&lt;/a&gt; with R. Lee Ermey which just cracks me up every time I see it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-551519726275278996?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/551519726275278996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=551519726275278996' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/551519726275278996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/551519726275278996'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/07/re-red-hat-16-canonical-1.html' title='Re: Red Hat, 16%. Canonical, 1%.'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-480719879320447717</id><published>2010-06-28T11:39:00.002-04:00</published><updated>2010-06-28T11:46:59.516-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Early Morning Sunrays</title><content type='html'>&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/4733896943/" title="photo sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1025/4733896943_dc51d9c276.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/4733896943/"&gt;IMG_1886&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/jstedfast/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;p&gt;Took this photograph around 6:30 in the morning on June 18th. The way the sunlight could be seen streaking through the trees and the complete stillness of the water was surreal, so I had to take a photograph of it ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-480719879320447717?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/480719879320447717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=480719879320447717' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/480719879320447717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/480719879320447717'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/06/early-morning-sunrays.html' title='Early Morning Sunrays'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1025/4733896943_dc51d9c276_t.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3016913139278488124</id><published>2010-06-25T12:58:00.000-04:00</published><updated>2010-06-25T12:58:33.170-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Dawns of June</title><content type='html'>&lt;center&gt;&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/jstedfast/4670643144/" title="IMG_1092 by jstedfast, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1277/4670643144_08d056322a.jpg" width="333" height="500" alt="IMG_1092" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;Dawn at Wollaston Beach, MA on June 4th.&lt;/span&gt;&lt;br /&gt;
&lt;br&gt;&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/jstedfast/4732353835/" title="IMG_1180 by jstedfast, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1432/4732353835_afce93daa2.jpg" width="500" height="333" alt="IMG_1180" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;Dawn at Core Creek Park in Bucks County, PA on June 7th.&lt;/span&gt;&lt;br /&gt;
&lt;br&gt;&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/jstedfast/4732405335/" title="IMG_1880 by jstedfast, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1251/4732405335_78b4e5d4fa.jpg" width="500" height="333" alt="IMG_1880" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;Dawn at Milton Pond, NH on June 17th.&lt;/span&gt;&lt;br /&gt;
&lt;br&gt;&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/jstedfast/4732404889/" title="IMG_1879 by jstedfast, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1428/4732404889_ae42e5b5c2.jpg" width="500" height="333" alt="IMG_1879" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;Dawn at Milton Pond, NH on June 17th.&lt;/span&gt;&lt;br /&gt;
&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3016913139278488124?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3016913139278488124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3016913139278488124' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3016913139278488124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3016913139278488124'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/06/dawns-of-june.html' title='Dawns of June'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1277/4670643144_08d056322a_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4005049403949780514</id><published>2010-05-22T18:27:00.002-04:00</published><updated>2010-05-22T18:29:54.854-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='ximian'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Reflecting on 10 Years at Ximian</title><content type='html'>&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/4629316661/" title="photo sharing"&gt;&lt;img src="http://farm5.static.flickr.com/4061/4629316661_4f8ce37586.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/4629316661/"&gt;IMG_1047&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/jstedfast/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Today marks my 10th anniversary since I was hired at Helix Code to work on Evolution.&lt;/p&gt;
&lt;p&gt;In that time I've gotten to work closely with and learn from some of the most talented developers in the Free Software community including Michael Zucchi, Miguel de Icaza, Federico Mena-Quintero, Chris Toshok, Larry Ewing, Michael Meeks, Dan Winship, Radek Doulik, Joe Shaw, Vlad Vukićević, Dave Camp, Dan Mills, and many others (too many to name!).&lt;/p&gt;
&lt;p&gt;Back in the early days of Helix Code/Ximian, we all worked tirelessly to put together the very best GNOME distribution we could and make Evolution the very best groupware client we could.&lt;/p&gt;
&lt;p&gt;We had big dreams and I like to think we succeeded. GNOME has become mainstream and the Linux Desktop can most definitely be measured as a success.&lt;br /&gt;&lt;br /&gt;Of course, we couldn't have done it without all the help and hard work from the entire GNOME community.&lt;/p&gt;
&lt;p&gt;Today, a younger generation of hackers are taking up the reigns to make GNOME awesome with things like the Paper Cuts project by David Siegel's team at Canonical and the work being done by Red Hat on the new GNOME-Shell.&lt;/p&gt;
&lt;p&gt;I'm still working with a couple of my old Evolution teammates like Larry Ewing and Chris Toshok on the Moonlight project in the hopes of making it possible for Linux Desktop users to view Silverlight content on the web. We've been making great progress with implementing Silverlight 3.0 and 4.0 features in svn and I've got some accomplishments on that front that I should really blog about but I've just been so busy.&lt;/p&gt;
&lt;p&gt;Much love to all you GNOMEies and thanks for all the support and love over the past decade!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4005049403949780514?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4005049403949780514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4005049403949780514' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4005049403949780514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4005049403949780514'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/05/reflecting-on-10-years-at-ximian.html' title='Reflecting on 10 Years at Ximian'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4061/4629316661_4f8ce37586_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6047908038502277979</id><published>2010-05-19T11:56:00.002-04:00</published><updated>2010-05-19T11:57:04.960-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><title type='text'>Sundown over the Charles River</title><content type='html'>&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/4613572267/" title="photo sharing"&gt;&lt;img src="http://farm4.static.flickr.com/3544/4613572267_2297529940.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/jstedfast/4613572267/"&gt;IMG_1022&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/jstedfast/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6047908038502277979?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6047908038502277979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6047908038502277979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6047908038502277979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6047908038502277979'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/05/sundown-over-charles-river.html' title='Sundown over the Charles River'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3544/4613572267_2297529940_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5436797640449651593</id><published>2010-01-30T11:05:00.015-05:00</published><updated>2010-02-01T09:22:54.363-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Weird bugs due to gcc 4.4 and strict aliasing</title><content type='html'>&lt;p&gt;I was just running the unit tests for GMime and I got a couple of failures on my openSUSE 11.2 machine that I have never gotten before. I started debugging and I noticed something &lt;i&gt;very&lt;/i&gt; odd. One of my functions that returned a linked-list of 'word' tokens was returning NULL for something that it should not be returning NULL from, especially since I had just stepped through that method and seen with my own eyes that it was creating and appending nodes to my linked list as it should!&lt;/p&gt;
&lt;p&gt;At this point I split out a tiny test case:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
#include &amp;lt;stdio.h&gt;
#include &amp;lt;stdlib.h&gt;

typedef struct _node {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;struct _node *next;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int value;
} Node;

int main (int argc, char **argv)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Node *list, *node, *tail;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;list = NULL;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tail = (Node *) &amp;list;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (i = 0; i &amp;lt; 10; i++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;node = malloc (sizeof (Node));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;node-&gt;next = NULL;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;node-&gt;value = i;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tail-&gt;next = node;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tail = node;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (list == NULL)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf ("oops, list is null???\n");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;
}
&lt;/pre&gt;
&lt;p&gt;I then built this test program using &lt;b&gt;gcc -Wall -g -o list-test list-test.c&lt;/b&gt;. When I ran the program, no error.&lt;/p&gt;
&lt;p&gt;Huh.&lt;/p&gt;
&lt;p&gt;Luckily I thought to rebuild with -O2. This time when I ran my test program, it printed out the error I expected. The list was NULL.&lt;/p&gt;
&lt;p&gt;Doing a bit of research suggests that gcc 4.4 has decided to enforce strict aliasing for -O2 and higher, which explains why it works without -O2.
&lt;p&gt;Oddly enough, I get no strict aliasing warnings from gcc even when I use &lt;b&gt;-Wall -O2&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;So be warned... gcc 4.4 may break your perfectly valid code in mysterious ways.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Looks like MySQL had similar problems and according to &lt;a href="http://davmac.wordpress.com/2010/01/08/gcc-strict-aliasing-c99/"&gt;this article&lt;/a&gt;, it is suggested that the gcc developers have interpreted the c99 specification far too strictly.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update 2:&lt;/b&gt; Josh's comment had an excellent explanation of the problem this code hits, so I thought I'd add it to my blog post for anyone who may otherwise miss his comment:&lt;/p&gt;
&lt;blockquote&gt;I imagine that gcc's aliasing thinks that dereferencing a Node* can only write to Node objects, so it won't have any effect on Node*s like list. Thus it thinks that list is never modified in that function, and it propagates the NULL constant throughout.&lt;/blockquote&gt;
&lt;p&gt;I also liked Josh's explanation of why the above code works (since a number of people have been confused by it already, I'll post that too):&lt;/p&gt;
&lt;blockquote&gt;The only reason it "works" in the -O0 case is because the next field happens to be the first field, as Fabian pointed out. The first time you write to tail-&gt;next, you're writing to &amp;list with no offset, so list happens to get the value of node. When next does have an offset, then the value of list is not changed, but something else on the stack after it will be clobbered.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5436797640449651593?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5436797640449651593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5436797640449651593' title='33 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5436797640449651593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5436797640449651593'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2010/01/weird-bugs-due-to-gcc-44-and-strict.html' title='Weird bugs due to gcc 4.4 and strict aliasing'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>33</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4259122142279023755</id><published>2009-10-24T15:52:00.009-04:00</published><updated>2009-10-24T16:20:44.952-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Trolls</title><content type='html'>&lt;p&gt;Thanks go out to &lt;a href="http://www.stormyscorner.com/"&gt;Stormy Peters&lt;/a&gt; and &lt;a href="http://www2.apebox.org/wordpress/"&gt;Jo Shields&lt;/a&gt; for tweeting a link to &lt;a href="http://sethgodin.typepad.com/"&gt;Seth Godin&lt;/a&gt;'s blog post entitled: &lt;a href="http://sethgodin.typepad.com/seths_blog/2009/10/trolls.html"&gt;Trolls&lt;/a&gt;. Had they not tweeted it, I likely would have missed these marvelous words of wisdom:&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;
&lt;p&gt;Lots of things about work are hard. Dealing with trolls is one of them. Trolls are critics who gain perverse pleasure in relentlessly tearing you and your ideas down. Here's the thing(s):&lt;ol&gt;
&lt;li&gt;trolls will always be trolling&lt;/li&gt;
&lt;li&gt;critics rarely create&lt;/li&gt;
&lt;li&gt;they live in a tiny echo chamber, ignored by everyone except the trolled and the other trolls&lt;/li&gt;
&lt;li&gt;professionals (that's you) get paid to ignore them. It's part of your job.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;"Can't please everyone," isn't just an aphorism, it's the secret of being remarkable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thanks, Seth. I needed to be reminded of this fact.
&lt;p&gt;And yea, Team Mono &lt;i&gt;is&lt;/i&gt; remarkable ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4259122142279023755?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4259122142279023755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4259122142279023755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4259122142279023755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4259122142279023755'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/10/trolls.html' title='Trolls'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6790485974135601736</id><published>2009-10-19T20:37:00.006-04:00</published><updated>2009-10-19T20:57:59.724-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='ximian'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Looking Back: 10 Years of Ximian</title><content type='html'>&lt;p&gt;&lt;a href="http://nat.org/"&gt;Nat&lt;/a&gt; and &lt;a href="http://tirania.org/blog/archive/2009/Oct-19.html"&gt;Miguel&lt;/a&gt; both reflected on the incorporation of Ximian which has made me a bit nostalgic myself. I've only been with Ximian for about 9 and a half years, but they have been pretty awesome years! I'm very thankful for having had the chance to be a part of something great and for having been able to work with both Nat and Miguel, 2 of my heroes.
&lt;p&gt;The things I respect most about both Nat and Miguel are their positive attitudes and energy. They both have an amazing ability to inspire the people around them to do great things, and we did. From &lt;a href="http://www.linuxplanet.com/linuxplanet/reviews/3301/1/"&gt;Ximian Desktop&lt;/a&gt; and &lt;a href="http://projects.gnome.org/evolution/"&gt;Evolution&lt;/a&gt; to &lt;a href="http://www.mono-project.com/"&gt;Mono&lt;/a&gt;, &lt;a href="http://www.mono-project.com/Moonlight"&gt;Moonlight&lt;/a&gt; and &lt;a href="http://susestudio.com/"&gt;SuSE Studio&lt;/a&gt;. Nat and Miguel have set out to change the Linux Desktop for the better, and I believe they (and we, together with the rest of the GNOME and Mono communities) have accomplished that. So congratulations Nat &amp; Miguel on 10 years of Awesome(tm)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6790485974135601736?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6790485974135601736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6790485974135601736' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6790485974135601736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6790485974135601736'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/10/looking-back-10-years-of-ximian.html' title='Looking Back: 10 Years of Ximian'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6011814930271075320</id><published>2009-09-27T17:28:00.006-04:00</published><updated>2009-09-28T17:08:43.244-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Mono not Chasing Tail Lights</title><content type='html'>&lt;p&gt;I've been on vacation and just got back and heard about this whole Richard Stallman spouting nonsense about Miguel being a traitor thing and saw that OSNews had an article criticizing Stallman for such ridiculous statements, so figured I'd skim the comments. Unsurprisingly someone attacked Miguel and Mono for "always chasing tail lights" which is a common logical fallacy that the anti-Mono folks love to argue, but in response there was, what I thought, a pretty good &lt;a href="http://www.osnews.com/thread?386046"&gt;post by elanthis&lt;/a&gt; that rings fairly accurately as far as I remember events happening back in 2001 while I was at Ximian so figured I would quote it in order to share.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;This "Mono is just chasing tail lights" crap is getting silly.&lt;/p&gt;
&lt;p&gt;If you take Mono to mean "a project whose sole goal is to enable running Windows .NET apps on Linux" then yes, Mono will always be behind.&lt;/p&gt;
&lt;p&gt;If you take Mono for what it actually is meant to be and what it is actually freaking used for, which is "a project that provides a clean, modern language on which to more efficiently develop and deliver Linux applications" then you realize that Mono isn't chasing anything, it's actually 20 steps _ahead_ of anything else on the Linux front.&lt;/p&gt;
&lt;p&gt;If Microsoft came along and said, "we're going to assert some mythical patents and Mono can't be compatible with the ECMA CLR or class library anymore," Linux and Mono would not be devastated in the least by it. Mono would drop the offending bits and it would _still_ be a clean, modern language with a helluva-efficient runtime library providing a ton of brand-new non-Microsoft-derived Linux-focused APIs and libraries (from POSIX to dbus to GTK to OpenGL and so on) that real applications like Tomboy or Banshee or iFolder or MonoDevelop or Unity3D or SunUO or Landell and countless others can continue to be built on top of, taking full advantage of the features of C# (or even a "very similar to C#" language, if some change were forced on Mono by MS), the high quality Mono runtime implementation, and the quality APIs and tools developed by the Mono community.&lt;/p&gt;
&lt;p&gt;There's no difference in theory behind a project like Mono and a project like Python, other than that Mono leisurely follows a language specification for the sake of being compatible __as a nice side benefit__ while Python just makes shit up as it goes. Oh, and Mono is way faster, has significantly better documentation, has better tools, and is already used in large-scale commercial apps (that have NO dependency on being Microsoft .NET compatible) despite having been around for a far shorter amount of time.&lt;/p&gt;
&lt;p&gt;Honestly look around and see how many people try to use or even _care_ about using Mono as a way to run apps developed for Microsoft .NET. You just don't see it. Mainsoft makes a business out of making it easy to get ASP.NET apps running on Linux servers and that's about the end of it. All of the really cool users of Mono are people that are using it either because it provides a top-notch embeddable VM that blows away every other FOSS scripting engine (e.g., Unity3D) or because it provides some of the best APIs around for creating brand-new Linux-specific applications (e.g. Beagle).&lt;/p&gt;
&lt;p&gt;The only people who are even remotely hung up on chasing Microsoft's taillights are the people who don't understand what the purpose of Mono is and use their misconception as a strawman argument against the Mono project.&lt;/p&gt;
&lt;p&gt;Mono was conceived by the Ximian folks because of their experience with Evolution. They were writing big Linux desktop apps. Writing them in C sucked. Writing them in C++ sucked slightly less. Writing them in Python sucked far less in some ways and far more in other ways. Writing them in any FOSS-friendly language available was a nightmare. They saw C#. They saw it was like Java, except it fixed many of the things that sucked about Java. They thought, "it would be sweet if we had a language like that to develop in." They thought, "we could write a language like that to develop in." They thought, "we could write a totally new language, but then we have to solve a bunch of problems that have already been solved over and over and over" and they knew that good engineers don't waste time resolving old problems. They thought, "if we make a C# compiler and runtime for Linux, not only do we get what we want, but what the heck maybe it'll help bring more ex-Windows developers over to the Linux side and make the world a better place." And, instead of sitting around bitching about all the hard work other people are doing, they went ahead and made the project. Their lives got easier, the lives of quite a few Linux developers got easier, the lives of even a number of Windows developers got easier, and the regular users started seeing some cool software that none of the Linux developers were making pre-Mono because it was such a time-consuming pain in the ass to do it before, and Windows users even started seeing more cool software because now there was this awesome tool for embedding high-performance reliable easy-to-write scripts into larger applications which made the applications more awesome.&lt;/p&gt;
&lt;p&gt;Everyone has won because of Mono, and because Miguel and the many other awesome contributors to Mono have done something FOSS never did before. The only thing the FOSS world has that even comes close to Mono is Java, and that was only just recently Open Sourced, and Sun's Java is actually already way behind Mono despite being far older.&lt;/p&gt;
&lt;p&gt;So, seriously, quit with the taillight chasing crap. The Microsoft specification is largely irrelevant to just about all users of Mono, it's not even a priority for the Mono developers, and Mono has far surpassed anything else the FOSS community has in the same field.&lt;/p&gt;
&lt;p&gt;C/C++ are a pain in the ass to work with and are light years behind modern languages in ease of use and features, and modern VM technology is already more or less on par with C/C++, and upcoming VM technology is quite likely to exceed the performance of C/C++. Python, Ruby, Perl, and so on are all great languages for some tasks but are total whores to work in for a great deal of other tasks, and they'll never be able to match Mono in speed (simple fact -- even if you implement the same VM technology in something like Parrot as you have in Mono, dynamic typing will always be slower; even if you use the same tracing optimizing JIT to compiler both C# and Python to machine code, the C# result will need far less type guards than the Python result would... which you can even prove by just using IronPython on Mono).&lt;/p&gt;
&lt;p&gt;The point of Mono is NOT CLR compatibility. It's not even C# the language. The point of Mono is having a runtime and multiple languages that make developing real-world applications easy and making those applications more reliable, which frees up more developer time to work on actual features and performance rather than working on endless layers of complicated framework code or debugging stupid bugs that only exist because of poor language design.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;As always, you have the typical know-it-alls who attacked the response saying that C# doesn't have many advantages over C++/Qt, but as usual, they neglect to consider the fact that not everyone wants to program using C++ or Qt.&lt;/p&gt;
&lt;p&gt;As one of the developers involved in the development of Evolution, neither C++ nor Qt were tools that would have helped to solve our problems. First off, Evolution was a GNOME program (thus making Qt useless) and C++ was plagued with problems in those days. I'm also not sure that the C++ bindings for Gtk+ were even mature enough to use at the time. Even had these not been problems, none of us wanted to use C++ anyway.&lt;/p&gt;
&lt;p&gt;Even today, with the surviving members of the original Evolution team now working on Moonlight (Chris Toshok, Larry Ewing and myself) which is partially written in C++, we have stuck with a very minimal subset and have gotten frustrated with a number of idiosyncrasies in C++ that were not a problem in C.&lt;/p&gt;
&lt;p&gt;As a contributor to the Mono project (along with MonoDevelop and Moonlight), I feel that the Mono detractors are woefully uninformed and seem unwilling to educate themselves, but I guess that's their loss. The Mono Project will continue whether they call us traitors or not, whether they approve of the project or not, and whether they go on making fools of themselves across the internet or not.&lt;/p&gt;
&lt;p&gt;We're not interested in childish popularity contests, we're interested in making great cross-platform development tools and making the Linux Desktop more inviting to a wider audience of both users and developers.&lt;/p&gt;
&lt;p&gt;And we are succeeding.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6011814930271075320?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6011814930271075320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6011814930271075320' title='63 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6011814930271075320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6011814930271075320'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/09/mono-not-chasing-tail-lights.html' title='Mono not Chasing Tail Lights'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>63</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4746051417869501468</id><published>2009-08-13T22:53:00.013-04:00</published><updated>2009-08-14T15:01:24.936-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='gaming'/><title type='text'>QuakeLight in Moonlight</title><content type='html'>&lt;p&gt;As we approach Moonlight 2.0 beta, more and more cool websites are starting to work under Moonlight. This week the team got &lt;a href="http://www.innoveware.com/ql3/QuakeLight.html"&gt;QuakeLight&lt;/a&gt; working!&lt;/p&gt;&lt;p&gt;Here is a screenshot of QuakeLight under Moonlight in action:&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CrWGagj8HJU/SoTST08rpCI/AAAAAAAAAKM/76xx1wMLx88/s1600-h/quakelight.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://1.bp.blogspot.com/_CrWGagj8HJU/SoTST08rpCI/AAAAAAAAAKM/76xx1wMLx88/s400/quakelight.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5369647893804983330" /&gt;&lt;/a&gt;
&lt;p&gt;Please note that there appears to be a bug in the version of Cairo that we embed into Moonlight which prevents the graphics from displaying on some NVidia and ATI cards (at least depending on which drivers you use?). It works fine on my Intel i965 graphics chipset, though.
&lt;p&gt;There's also a bug where it runs out of file descriptors after a while (which I'll be looking into shortly since it crops up for &lt;a href="http://www.bluerosegames.com/brg/free-web-games/bubble-breaker.aspx"&gt;DrPopper&lt;/a&gt; as well).&lt;/p&gt;&lt;p&gt;Stay tuned for more exciting updates!&lt;/p&gt;&lt;p&gt;&lt;small&gt;&lt;b&gt;Note:&lt;/b&gt; More information about QuakeLight (and GPL source code!) can be found at &lt;a href="http://www.innoveware.com/quakelight.html"&gt;http://www.innoveware.com/quakelight.html&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4746051417869501468?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4746051417869501468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4746051417869501468' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4746051417869501468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4746051417869501468'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/08/quakelight-in-moonlight.html' title='QuakeLight in Moonlight'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CrWGagj8HJU/SoTST08rpCI/AAAAAAAAAKM/76xx1wMLx88/s72-c/quakelight.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4782691284462685185</id><published>2009-07-23T10:35:00.010-04:00</published><updated>2009-08-14T15:04:06.823-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='free software'/><title type='text'>The Faux-pen Source Fundamentalists</title><content type='html'>&lt;p&gt;I was just reading Linux-Mag's &lt;a href="http://www.linux-mag.com/id/7439/"&gt;interview with Linus Torvalds&lt;/a&gt; with regards to Microsoft's latest GPL'd contributions to the Linux kernel.&lt;/p&gt;
&lt;p&gt;In it, I found this fabulous quote from Linus which I think echoes David "Lefty" Schlesinger's latest blog posting about the &lt;a href="http://opensourcetogo.blogspot.com/2009/07/real-floss-community-and-faux-floss.html"&gt;The Real FLOSS Community and the "Faux FLOSS Fundamentalists"&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;I may make jokes about Microsoft at times, but at the same time, I think the Microsoft hatred is a disease. I believe in open development, and that very much involves not just making the source open, but also not shutting other
people and companies out.&lt;/p&gt;
&lt;p&gt;There are ‘extremists’ in the free software world, but that’s one major reason why I don’t call what I do ‘free software’ any more. I don’t want to be associated with the people for whom it’s about exclusion and hatred.”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;It is good to see such prominent FLOSS contributors speaking out against the "Faux-pen Source Fundamentalists" that go around attacking the real FLOSS community members, even going so far as &lt;a href="http://opensourcetogo.blogspot.com/2009/06/when-zeal-becomes-zealotry-tawdry-tale.html"&gt;trying to get FLOSS developers/contributors fired&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These zealots may think they are "helping" the FLOSS community, but they are only having a negative effect. A &lt;i&gt;destructive&lt;/i&gt; effect.&lt;/p&gt;
&lt;p&gt;These people are not interested in improving Linux, they are only interested in stroking their own egos. They want &lt;i&gt;power&lt;/i&gt; more than anything else. Power over other people. Power to &lt;i&gt;destroy&lt;/i&gt; any&lt;i&gt;one&lt;/i&gt; or any&lt;i&gt;thing&lt;/i&gt; that does not do what they demand.&lt;/p&gt;
&lt;p&gt;These people claim that they are protecting our Freedoms, but they are only trying to become dictators. They have no interest in Freedom unless it is their own version of Freedom, where they reign as supreme dictator and where anyone who disagrees with them is labeled as a "shill" or otherwise demonized.&lt;/p&gt;
&lt;p&gt;As Linus puts it, these people are about "exclusion and hatred."&lt;/p&gt;
&lt;p&gt;This is &lt;i&gt;not&lt;/i&gt; Freedom.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4782691284462685185?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4782691284462685185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4782691284462685185' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4782691284462685185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4782691284462685185'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/07/faux-pen-source-fundamentalists.html' title='The Faux-pen Source Fundamentalists'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5671985129294983028</id><published>2009-07-11T18:32:00.015-04:00</published><updated>2009-07-13T10:56:09.731-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Re: Let's All Say It Together.</title><content type='html'>&lt;p&gt;I wasn't at the Gran Canaria Desktop Summit 2009, so I'm learning about this second hand from people like &lt;a href="http://opensourcetogo.blogspot.com/2009/07/good-gcds-beginning-with-significant.html"&gt;David Schlesinger&lt;/a&gt;, &lt;a href="http://natanyellin.com/2009/07/11/regarding-richard-stallman/"&gt;Natin Yellin&lt;/a&gt; and a number of people I know personally who attended the conference. It is important for us to respect all of our peers no matter their skin color, their religion or other beliefs, their gender, or any other factor. And that goes for respecting people outside of our community as well.&lt;/p&gt;
&lt;p&gt;Because of this, I am casting my vote:&lt;/p&gt;
&lt;img src="http://farm1.static.flickr.com/134/375964525_c401716e14.jpg"&gt;
&lt;em&gt;&lt;a href="http://flickr.com/photos/caseywest/375964525/"&gt;STOP sexism&lt;/a&gt; by &lt;a href=""&gt;Casey West&lt;/a&gt;. License: &lt;a href="http://creativecommons.org/licenses/by-sa/2.0/"&gt;&lt;img title="used under a Creative Commons Attribution-ShareAlike License" src="http://i.creativecommons.org/l/by-sa/2.0/80x15.png" alt="" width="80" border="0" height="15" /&gt;&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;blockquote&gt;"I want the [...] open source [...] communities [I participate in] to be a dignified, respectful, inclusive, and welcoming place. &amp;#8230; We&amp;#8217;ve all been witnesses to off-color jokes, misogynistic back channel chatter, questionable imagery and unnecessary, trolling comments. I pledge to do better to stand up and call this behavior out when I see it in conferences, online and other public settings. I don&amp;#8217;t expect it to go away but I&amp;#8217;m not going to tacitly condone it any longer."&lt;/blockquote&gt;&lt;br&gt;&lt;br&gt;
(From &lt;a href="http://blog.nicksieger.com/articles/2009/04/30/stand-and-be-counted"&gt;Nick&lt;/a&gt; via &lt;a href="http://tieguy.org/blog/2009/04/30/thoughtlessness-in-open-source/"&gt;Luis&lt;/a&gt; via &lt;a href="http://opensourcetogo.blogspot.com/2009/07/lets-all-say-it-together.html"&gt;David&lt;/a&gt;)&lt;br&gt;
&lt;b&gt;Update:&lt;/b&gt; As Natan Yellin has commented below, he was not actually at the conference - it was my mistake in thinking he was.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5671985129294983028?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5671985129294983028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5671985129294983028' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5671985129294983028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5671985129294983028'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/07/re-lets-all-say-it-together.html' title='Re: Let&apos;s All Say It Together.'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm1.static.flickr.com/134/375964525_c401716e14_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2009132209916202637</id><published>2009-07-10T18:27:00.004-04:00</published><updated>2009-07-10T18:29:39.181-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>I am not afraid</title><content type='html'>&lt;a href="http://desrt.ca/blog-items/on-the-topic-of-mono.png"&gt;&lt;img src="http://desrt.ca/blog-items/on-the-topic-of-mono.png"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2009132209916202637?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2009132209916202637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2009132209916202637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2009132209916202637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2009132209916202637'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/07/i-am-not-afraid.html' title='I am not afraid'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5949287346644371945</id><published>2009-04-28T22:49:00.006-04:00</published><updated>2009-08-14T15:05:51.566-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>Making GMime Even More Awesome</title><content type='html'>&lt;p&gt;I've started working on GMime 2.6, which unfortunately will need to break API with 2.4 in order to achieve the next level of awesome.&lt;/p&gt;
&lt;p&gt;If you use GMime (or are thinking of using it) in your project and have some suggestions on how GMime can improve, don't hesitate to fire an email off to gmime-devel-list@lists.gnome.org (preferably after subscribing to the mailing-list first).&lt;/p&gt;
&lt;p&gt;These are my current plans:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replace all uses of g_signals with my own event stuff. None of this needs to be public and my events are a lot more performant. [ DONE ]&lt;/li&gt;
&lt;li&gt;Need to add a Changed event to GMimeHeaderList so that GMimeMessage can listen to changes in the toplevel mime_part's headers. When they change, we need to unset the cached header stream on the GMimeMessage. (see the "Note:" comments in message_write_to_stream and message_get_headers, while this hack works, it'd be nicer if we did it based on event callbacks)&lt;/li&gt;
&lt;li&gt;Get rid of GMimeSession and replace it with GMimePassphraseRequestFunc or something. See GpgMe's passphrase request callback signature for ideas. [ DONE ]&lt;/li&gt;
&lt;li&gt;Consider optionally using GpgMe so that we can support S/MIME?&lt;/li&gt;
&lt;li&gt;Consider GCancellable and GError for GMimeStreams and GMimeParser&lt;/li&gt;
&lt;li&gt;Add GIO-based GMimeStream and bump glib dep to 2.16 [ DONE ]&lt;/li&gt;
&lt;li&gt;Add a g_mime_part_get_best_content_encoding()? [ DONE ]&lt;/li&gt;
&lt;li&gt;Rename GMimeBestEncoding enum to GMimeEncodingConstraint? This might be a better name for the enum to reflect what it's actually meant for. Maybe also move it from gmime-filter-best.h to gmime-encodings.h?&lt;/li&gt;
&lt;li&gt;How about a g_mime_part_get_best_charset()? This one could be awkward since it depends on the content being UTF-8 text&lt;/li&gt;
&lt;li&gt;Should either rename g_mime_filter_best_encoding() to get_encoding() or else make sure that GMime.metadata 'fixes' the method name to be GetEncoding so that it will appear as a C# property getter.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5949287346644371945?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5949287346644371945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5949287346644371945' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5949287346644371945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5949287346644371945'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/04/making-gmime-even-more-awesome.html' title='Making GMime Even More Awesome'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3888480726786867107</id><published>2009-04-04T15:05:00.004-04:00</published><updated>2009-08-14T15:06:50.318-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='community'/><title type='text'>Follow me on twitter</title><content type='html'>&lt;p&gt;Over the past few months I'm having an even harder time motivating myself to actually make blog posts due to the convenience of microblogging on &lt;a href="http://twitter.com"&gt;twitter.com&lt;/a&gt;, so this is just a note to say that if you are interested in the things I do or say, you might want to consider &lt;a href="http://twitter.com/jstedfast"&gt;following me on twitter&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3888480726786867107?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3888480726786867107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3888480726786867107' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3888480726786867107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3888480726786867107'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/04/follow-me-on-twitter.html' title='Follow me on twitter'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5867254757444984305</id><published>2009-04-02T08:22:00.025-04:00</published><updated>2009-08-14T15:08:47.335-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visual studio'/><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>Building GMime in Visual Studio</title><content type='html'>&lt;p&gt;&lt;b&gt;Installing the Necessary Dependencies&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;First, install GNU's iconv library for Windows. You can get a nice msi installer from &lt;a href="http://gnuwin32.sourceforge.net/packages/libiconv.htm"&gt;http://gnuwin32.sourceforge.net/packages/libiconv.htm&lt;/a&gt;. Unfortunately, they only offer a Win32 installer, so hopefully that's the platform you intend to target.
&lt;p&gt;Next, you'll want to grab the GLib headers and libraries for Windows. The easiest way to do that is to go to &lt;a href="http://www.gtk.org/download.html"&gt;http://www.gtk.org/download.html&lt;/a&gt; and download the All-in-One pre-built bundle for Win32. Once downloaded, extract the zip file (the docs suggest not using WinZip due to a bug) and place them wherever you want (I put mine into C:\Users\jeff\Documents).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Configuring Visual Studio&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Now that the libiconv and glib headers/libraries are installed, you'll want to configure Visual Studio to know where to find those headers and libraries.&lt;/p&gt;
&lt;p&gt;First, go to the &lt;b&gt;Tools&lt;/b&gt; menu and select &lt;b&gt;Options...&lt;/b&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CrWGagj8HJU/SdS0Mr4cZAI/AAAAAAAAAH0/F7shTHi-muQ/s1600-h/vs-tools-options.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 303px; height: 279px;" src="http://1.bp.blogspot.com/_CrWGagj8HJU/SdS0Mr4cZAI/AAAAAAAAAH0/F7shTHi-muQ/s400/vs-tools-options.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5320075189862294530" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;b&gt;Options&lt;/b&gt; dialog, expand the &lt;b&gt;Projects and Solutions&lt;/b&gt; tree item and then select &lt;b&gt;VC++ Directories&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;Make sure Win32 is selected in the &lt;b&gt;Platform&lt;/b&gt; option menu and then select &lt;b&gt;Executable files&lt;/b&gt; under &lt;b&gt;Show directories for:&lt;/b&gt;, like so:&lt;/p&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CrWGagj8HJU/SdS2h-ZZNlI/AAAAAAAAAH8/Pkf14pZrkeg/s1600-h/vs-options-exe-paths.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 232px;" src="http://3.bp.blogspot.com/_CrWGagj8HJU/SdS2h-ZZNlI/AAAAAAAAAH8/Pkf14pZrkeg/s400/vs-options-exe-paths.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5320077754632844882" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Scroll to the bottom of the listbox and add the bin paths for your installed libiconv and Gtk+ bundle just like in the above screenshot.&lt;/p&gt;
&lt;p&gt;After you've added the bin paths, you'll need to add the #include paths. Select &lt;b&gt;Include files&lt;/b&gt; under &lt;b&gt;Show directories for:&lt;/b&gt; and, like you did for the Executable paths you added above, add the paths to the include files.&lt;/p&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_CrWGagj8HJU/SdS4PcSlMUI/AAAAAAAAAIE/pJS23F_Tt9M/s1600-h/vs-options-include-paths.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 232px;" src="http://1.bp.blogspot.com/_CrWGagj8HJU/SdS4PcSlMUI/AAAAAAAAAIE/pJS23F_Tt9M/s400/vs-options-include-paths.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5320079635263074626" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, you'll need to ad the library paths. Under &lt;b&gt;Show directories for:&lt;/b&gt;, select &lt;b&gt;Library files&lt;/b&gt; and add the appropriate paths to the bottom of the list.&lt;/p&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CrWGagj8HJU/SdS5WH9DFjI/AAAAAAAAAIM/-NM61YtfLDo/s1600-h/vs-options-library-paths.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 231px;" src="http://2.bp.blogspot.com/_CrWGagj8HJU/SdS5WH9DFjI/AAAAAAAAAIM/-NM61YtfLDo/s400/vs-options-library-paths.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5320080849574762034" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And that's it! You are now ready to start building GMime!&lt;/p&gt;
&lt;p style="font-size: 75%"&gt;Note: I've been using &lt;a href="http://www.microsoft.com/Express/"&gt;Microsoft Visual C++ 2008 Express Edition&lt;/a&gt; which you can download for free from Microsoft.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5867254757444984305?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5867254757444984305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5867254757444984305' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5867254757444984305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5867254757444984305'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/04/building-gmime-in-visual-studio.html' title='Building GMime in Visual Studio'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_CrWGagj8HJU/SdS0Mr4cZAI/AAAAAAAAAH0/F7shTHi-muQ/s72-c/vs-tools-options.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-390603207566926503</id><published>2009-03-31T08:48:00.005-04:00</published><updated>2009-08-14T15:09:20.794-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>GMime Ported to Windows</title><content type='html'>&lt;p&gt;The other day someone asked me about GMime on Windows and I didn't have anything to tell her other than that I thought people had built it successfully on Windows but beyond that, I didn't have any sort of VS project files or anything.&lt;/p&gt;
&lt;p&gt;Then, last night, she poked me again asking for advice about some of the problems she was having building on Windows (which were mostly removing extraneous unistd.h includes from files that didn't need them and dropping source files that required them).&lt;/p&gt;
&lt;p&gt;After a short while of back and forth, I decided I'd just boot into Windows myself and she helped me get my system setup (installing GNU Libiconv, grabbing the Gtk+ Windows dev packages, configuring VS to know where to look for those headers/libs, etc) so that I could more easily get instant feedback as to whether my source changes fixed the compile errors.&lt;/p&gt;
&lt;p&gt;After a few hours of #include fixage and slight reworkings of some unix-specific code, we had a successful build of GMime.dll, woohoo!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-390603207566926503?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/390603207566926503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=390603207566926503' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/390603207566926503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/390603207566926503'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/03/gmime-ported-to-windows.html' title='GMime Ported to Windows'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7052710650892739271</id><published>2009-03-11T08:14:00.006-04:00</published><updated>2009-08-14T15:10:38.693-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><title type='text'>Taking Over the World</title><content type='html'>&lt;p&gt;I've just been informed that Moonlight has made it into the following distributions: openSUSE (obviously), Mandriva, Ubuntu, Debian, Gentoo, and FreeBSD.&lt;/p&gt;
&lt;p&gt;These are exciting times. One of the things that keeps me hacking on Free Software is the joy I feel when other people use my software because I know I'm helping to improve their Linux computing experience, even if only a little bit ;-)&lt;/p&gt;
&lt;p&gt;On that note, Moonlight 1.0.1 has just been released the other day with fixes for the bugs people reported to us about the 1.0.0 release.&lt;/p&gt;
&lt;p&gt;Jo Shields has also done the work to port Moonlight to ARM:&lt;/p&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www2.apebox.org/wordpress/wp-content/gallery/00-single/armless.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 640px; height: 480px;" src="http://www2.apebox.org/wordpress/wp-content/gallery/00-single/armless.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; &lt;a href="http://dieter.plaetinck.be/"&gt;Dieter&lt;/a&gt; has just informed me that &lt;a href="http://www.archlinux.org/"&gt;Arch Linux&lt;/a&gt; also provides Moonlight packages in their distribution! Awesome, guys!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7052710650892739271?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7052710650892739271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7052710650892739271' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7052710650892739271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7052710650892739271'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/03/taking-over-world.html' title='Taking Over the World'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7367253369777334516</id><published>2009-02-28T08:59:00.008-05:00</published><updated>2009-08-14T15:12:18.945-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Text Layout Engines</title><content type='html'>&lt;p&gt;As many of my loyal followers know, I wrote a really fast text layout engine for Moonlight 1.0 which was able to layout text in more-or-less a single pass over the string. Hard to do better than that, especially with my &lt;i&gt;superbly&lt;/i&gt; (I'm allowed to stroke my own ego, right?) designed font/glyph caches.&lt;/p&gt;
&lt;p&gt;That said, the code had also been &lt;i&gt;superbly&lt;/i&gt; disgusting and unmaintainable. Made worse when I had to add hacks to render text selection (Silverlight 1.0's TextBlock is like a GtkLabel in that it just renders text, but Silverlight 2.0's TextBox supports editing and selection and so is therefor more akin to a multi-line GtkEntry widget).&lt;/p&gt;
&lt;p&gt;Well, Thursday night, as I was watching House on &lt;a href="http://www.hulu.com"&gt;Hulu&lt;/a&gt;, I had one of those "House moments" where he suddenly realizes what the patient is suffering from and how to solve the problem (usually when his friend, Wilson, is talking to him about something random).&lt;/p&gt;
&lt;p&gt;I spent all day yesterday (and I mean &lt;i&gt;all&lt;/i&gt; day, until 11pm last night) putting together my thoughts for a new design and working out the details and I think I now have a vastly improved solution that not only uses less memory in all but the pathological cases (I now use a UTF-8 string instead of a UCS4 string), but also doesn't require:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a pass over the text to break on CR/LF to construct a list of text runs which were what the old TextLayout engine I wrote used instead of a char* (because the layout engine now handles CR/LFs)&lt;/li&gt;
&lt;li&gt;a whole new set of text runs every time selection boundaries change in a TextBox (because selection is no longer represented by text runs)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, the same brilliance of the old design still apply: no need to re-layout when most text properties (underline, foreground, background, etc) change (obviously we still have to re-layout if font properties change because they change the metrics).&lt;/p&gt;
&lt;p&gt;With my new design, my TextLayout class has a Select() method which allows the consumer to change the selected region of text. When you change the selection, my new logic can simply clear the cached glyph clusters for the affected area(s).&lt;/p&gt;
&lt;p&gt;A "glyph cluster" is a cached (sub)run of glyphs in a particular text run. A "text run" is a substring of text that share all the same text attributes which does not span across line boundaries.&lt;/p&gt;
&lt;p&gt;To break it down, a layout contains a list of lines. Each line contains a list of runs. Each run contains a list of glyph clusters.&lt;/p&gt;
&lt;p&gt;Normally, a run will consist of only a single glyph cluster unless it overlaps the selection.&lt;/p&gt;
&lt;p&gt;For example, if the first half of the run is within the selection, then the run will contain 2 glyph clusters (one for the selected portion and one for the non-selected portion). However, if the selection is fully contained within a single run but doesn't span the entire run, then it's possible to have up to 3 glyph clusters for that run: pre-selection, selection, post-selection.&lt;/p&gt;
&lt;p&gt;The brilliance of doing it this way is that it simplifies keeping track of kerning between selected regions, so that as you drag your selection across some text, the text following your mouse cursor doesn't appear to "jump" to the left or right as you move between characters that are kerned.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7367253369777334516?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7367253369777334516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7367253369777334516' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7367253369777334516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7367253369777334516'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/02/text-layout-engines.html' title='Text Layout Engines'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1133125912264303284</id><published>2009-02-14T14:12:00.005-05:00</published><updated>2009-08-14T15:13:29.116-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>More Exciting Updates on Mono/Android</title><content type='html'>&lt;p&gt;Looks like &lt;a href="http://www.koushikdutta.com/"&gt;Koushik Dutta&lt;/a&gt; has been kicking butt getting Mono onto Google's Android platform:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.koushikdutta.com/2009/01/compiling-mono-under-android-build.html"&gt;Compiling Mono under the Android Build Environment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.koushikdutta.com/2009/01/microsoft-dlr-and-mono-bring-python-and.html"&gt;Microsoft's DLR and Mono bring Python and Ruby to Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.koushikdutta.com/2009/02/monodalvik-interop.html"&gt;Mono/Dalvik Interop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keep up the awesome hacking, Koushik!&lt;/p&gt;
&lt;p&gt;Also of interest is his article on why JNI sucks compared to doing the same thing in .NET: &lt;a href="http://www.koushikdutta.com/2009/01/jni-in-android-and-foreword-of-why-jni.html"&gt;JNI in Android (and a foreword about why JNI sucks)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I never actually used JNI back when I was doing Java development in school, so when people told me it sucked I just took their word for it, but always wondered just how bad it was. Now I know. All I can say is: &lt;i&gt;Ugh&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Hopefully the Java community replaces JNI with something as clean and elegant as what we find in .NET.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1133125912264303284?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1133125912264303284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1133125912264303284' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1133125912264303284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1133125912264303284'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/02/more-exciting-updates-on-monoandroid.html' title='More Exciting Updates on Mono/Android'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1430481102602659741</id><published>2009-02-13T20:56:00.005-05:00</published><updated>2009-08-14T15:14:04.707-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Mono 2.0 Wins Developer.com's Product of the Year Award</title><content type='html'>&lt;p&gt;I'd just like to congratulate the Mono team on their &lt;a href="http://www.jupitermedia.com/corporate/releases/09.02.13-IC_DevPOYawards.html"&gt;Product of the Year Award&lt;/a&gt; and for a job well done!&lt;/p&gt;
&lt;p&gt;Congratulations guys, you deserved this award! You guys kicked ass this past year and we all get to benefit from your awesomeness.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1430481102602659741?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1430481102602659741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1430481102602659741' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1430481102602659741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1430481102602659741'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/02/mono-20-wins-developercoms-product-of.html' title='Mono 2.0 Wins Developer.com&apos;s Product of the Year Award'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1819928094620077671</id><published>2009-02-13T09:24:00.017-05:00</published><updated>2009-08-14T15:15:15.777-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='banshee'/><title type='text'>Epic Weekly News for the week of Feb 8th</title><content type='html'>&lt;p&gt;A lot has happened this week, in particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://tirania.org/blog/archive/2009/Feb-11.html"&gt;Moonlight 1.0 goes live!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.digitaljournal.com/article/267071"&gt;Female FBI Agent Used Sex to Torture Mumbai Attack Suspect&lt;/a&gt;. Anonymous sources have suggested that video stream evidence will become available this weekend.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://abock.org/2009/02/11/announcing-moonshine-the-project-never-formerly-known-as-pornilus/"&gt;Announcing Moonshine, the project &lt;strike&gt;never formerly&lt;/strike&gt; &lt;i&gt;formally&lt;/i&gt; known as Pornilus&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For those in the Cambridge/Boston area, we now give you a word from our &lt;a href="http://abock.org"&gt;sponsor&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_CrWGagj8HJU/SZWKn02RobI/AAAAAAAAAHs/9thow59wl5Y/s1600-h/napkins.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_CrWGagj8HJU/SZWKn02RobI/AAAAAAAAAHs/9thow59wl5Y/s400/napkins.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5302296553104449970" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1819928094620077671?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1819928094620077671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1819928094620077671' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1819928094620077671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1819928094620077671'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/02/epic-weekly-news-for-week-of-feb-8th.html' title='Epic Weekly News for the week of Feb 8th'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CrWGagj8HJU/SZWKn02RobI/AAAAAAAAAHs/9thow59wl5Y/s72-c/napkins.jpg' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7222843914521740899</id><published>2009-02-08T13:56:00.004-05:00</published><updated>2009-08-14T15:15:58.103-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Alleyoop 0.9.4 released</title><content type='html'>&lt;p&gt;It's been ages since the last release of Alleyoop, but an update has finally arrived. I've just fixed up Alleyoop to build on openSUSE 11.1 (some libbfd stuff has changed, apparently) and so I've dropped the need for libbfd and libiberty completely. The code that used those libraries didn't really gain us any extra information that Valgrind wasn't already giving us anyway, so it as rather pointless.&lt;/p&gt;
&lt;p&gt;It looks like a year and a half or so ago I fixed some parser bugs too and just never made a new release with those fixes.&lt;/p&gt;
&lt;p&gt;So now Freedom Lovers who prefer a GUI can once again Valgrind their applications 'til their heart is content.&lt;/p&gt;
&lt;p&gt;You can download the new Alleyoop 0.9.4 package &lt;a href="http://prdownloads.sourceforge.net/alleyoop/alleyoop-0.9.4.tar.gz?download"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Oh, also, if there are any bored web developers out there, I'd appreciate it if someone could make a less-ugly website than what is currently at &lt;a href="http://alleyoop.sourceforge.net"&gt;http://alleyoop.sourceforge.net&lt;/a&gt;. In case you couldn't tell, I'm horrible at website design.&lt;/p&gt;
&lt;p&gt;As another fabulous example of my webdesign prowess, take a gander at &lt;a href="http://spruce.sourceforge.net/gmime"&gt;GMime's website&lt;/a&gt;. So yea, that site could also use a make-over.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Thanks to Akos Kemives for his improved website design for Alleyoop!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7222843914521740899?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7222843914521740899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7222843914521740899' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7222843914521740899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7222843914521740899'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/02/alleyoop-094-released.html' title='Alleyoop 0.9.4 released'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-8933096649142766273</id><published>2009-01-23T22:32:00.006-05:00</published><updated>2009-08-14T15:14:39.279-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Epic Weekly News</title><content type='html'>&lt;p&gt;A lot of cool stuff happened this past week:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mono-project.com/Release_Notes_Mono_2.2"&gt;Mono 2.2 was released with the new SIMD and LinearIR optimizations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.go-mono.com/moonlight/"&gt;Moonlight 1.0 was released&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Obama sworn in as the US President, &lt;a href="http://tirania.org/blog/archive/2009/Jan-20.html"&gt;streamed live via Moonlight&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;...and &lt;a href="http://www.computerworld.com/action/article.do?command=viewArticleBasic&amp;taxonomyName=Software&amp;articleId=9126619&amp;taxonomyId=18&amp;pageNumber=5"&gt;Linus Torvalds switches to GNOME&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-8933096649142766273?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/8933096649142766273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=8933096649142766273' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8933096649142766273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8933096649142766273'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/01/epic-weekly-news.html' title='Epic Weekly News'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-8765331021692385494</id><published>2009-01-20T14:13:00.004-05:00</published><updated>2009-08-14T15:17:04.799-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><title type='text'>Watched Obama via Moonlight</title><content type='html'>&lt;p&gt;Found out about Larry's, Aaron's, Rusty's, and Geoff's work at making a Moonlight 1.0 release that could view the Obama Inauguration this morning, so I absolutely &lt;i&gt;had&lt;/i&gt; to use Moonlight today to watch it and it was great. Flawless.&lt;/p&gt;
&lt;p&gt;Way to go guys!&lt;/p&gt;
&lt;p&gt;Once again proving that the Mono team is unstoppable!&lt;/p&gt;
&lt;p&gt;GO MONO! GO!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-8765331021692385494?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/8765331021692385494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=8765331021692385494' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8765331021692385494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8765331021692385494'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/01/watched-obama-via-moonlight.html' title='Watched Obama via Moonlight'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-8058076935213215713</id><published>2009-01-18T14:16:00.004-05:00</published><updated>2009-08-14T15:17:41.459-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Moonlight TextBox</title><content type='html'>&lt;p&gt;This past week I've been furiously hacking away on my reimplementation of the Silverlight TextBox control for Moonlight. I never realized just how much work goes into writing such a simple text-entry widget before this past week, even after having written Moonlight's text layout and rendering engine for the 1.0 release.&lt;/p&gt;
&lt;p&gt;Keyboard input, keyboard navigation, keyboard selection, mouse selection &amp; cursor positioning, key repeat, cursor blink, etc. The list goes on.&lt;/p&gt;
&lt;p&gt;Most of it isn't hard, it's just time consuming.&lt;/p&gt;
&lt;p&gt;At the same time, it's also fun in the sense that it's a new challenge for me to overcome (I love a good challenge). It makes you think a lot about designing for performance because you just don't know how much text you'll be rendering. It could be a short sentence or it could be an entire document, and the way you design your layout/rendering engine could mean the difference between taking 5 minutes to render or a fraction of a second.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-8058076935213215713?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/8058076935213215713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=8058076935213215713' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8058076935213215713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/8058076935213215713'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/01/moonlight-textbox.html' title='Moonlight TextBox'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1778238896953608995</id><published>2009-01-09T12:13:00.005-05:00</published><updated>2009-08-14T15:18:30.770-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs'/><category scheme='http://www.blogger.com/atom/ns#' term='tips+tricks'/><title type='text'>GNU/Emacs font-lock suckage</title><content type='html'>&lt;p&gt;For months now, my GNU/Emacs has decided to sometimes not syntax highlight my source or ChangeLog files and I didn't know why.&lt;/p&gt;
&lt;p&gt;The other day, emacs' failure to syntax highlight xaml.cpp was the final straw. I decided enough was enough with having to &lt;i&gt;M-x font-lock-fontify-buffer&lt;/i&gt; everytime I opened a handful of source files, especially ones that I often find need to edit and/or to refer to.&lt;/p&gt;
&lt;p&gt;A little digging later and I discovered that GNU/Emacs must have added a feature that disabled font-lock (even if you've specified &lt;i&gt;(setq font-lock-support-mode t)&lt;/i&gt; in your ~/.emacs) if the buffer was over some arbitrary size. Either that, or they lowered the arbitrary size to something ridiculously small.&lt;/p&gt;
&lt;p&gt;The solution seems to be to add the following line to your ~/.emacs file: &lt;i&gt;(setq font-lock-maximum-size 1000000)&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Feel free to append a few more 0's to that number if you find that Emacs still fails to syntax highlight any of your source files.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Another Emacs annoyance can be turned off by adding &lt;i&gt;(setq inhibit-startup-message t)&lt;/i&gt; to your ~/.emacs file. I'm not sure why this isn't inhibited by default.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1778238896953608995?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1778238896953608995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1778238896953608995' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1778238896953608995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1778238896953608995'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2009/01/gnuemacs-font-lock-suckage.html' title='GNU/Emacs font-lock suckage'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5317135556346879751</id><published>2008-12-15T23:55:00.004-05:00</published><updated>2009-08-14T15:19:30.554-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><title type='text'>Quick Review of Microsoft's Seadragon</title><content type='html'>&lt;p&gt;Just got around to installing Seadragon on my iPhone and took it for a quick spin. First impressions are that it rocks. If I load the map views, for example, zooming seems far far smoother than Google Maps. Zooming in on the articles in the Library of Congress Set was amazingly smooth as well.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5317135556346879751?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5317135556346879751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5317135556346879751' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5317135556346879751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5317135556346879751'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/12/quick-review-of-microsofts-seadragon.html' title='Quick Review of Microsoft&apos;s Seadragon'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4124356037696349724</id><published>2008-12-15T17:14:00.003-05:00</published><updated>2009-08-14T15:19:52.696-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Herding Code: Episode 29 w/ Miguel de Icaza (Part 2)</title><content type='html'>&lt;p&gt;Part 2 of the Herding Code podcast w/ Miguel de Icaza is up: &lt;a href="http://herdingcode.com/?p=114"&gt;http://herdingcode.com/?p=114&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'll be listening to this tonight when I get home.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4124356037696349724?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4124356037696349724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4124356037696349724' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4124356037696349724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4124356037696349724'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/12/herding-code-episode-29-w-miguel-de.html' title='Herding Code: Episode 29 w/ Miguel de Icaza (Part 2)'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-9068940273837697689</id><published>2008-12-14T09:40:00.012-05:00</published><updated>2009-08-14T15:21:51.186-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='searching'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Fun with Tries</title><content type='html'>&lt;p&gt;A number of years ago, Michael Zucchi introduced me to the &lt;a href="http://en.wikipedia.org/wiki/Aho-Corasick_algorithm"&gt;Aho-Corasick algorithm&lt;/a&gt; which he implemented in Evolution for the "Find in Message" feature. Later, I ended up extracting that logic out and refactoring it a bit into the &lt;a href="http://svn.gnome.org/viewvc/evolution-data-server/trunk/libedataserver/e-trie.c?revision=9011&amp;view=markup"&gt;ETrie&lt;/a&gt; class which I ended up using to replace the regex logic (which is common among most GNOME apps that do this) to scan for urls in the message body (in order to insert hyperlinks, etc). This turned out to be an order of magnitude faster.&lt;/p&gt;
&lt;p&gt;For those who aren't in the know, the Aho-Corasick algorithm is for searching for multiple strings in a given input. In other words, it searches for one of multiple needles in a single haystack.&lt;/p&gt;
&lt;p&gt;The pseudocode for the search itself would look something like this:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
q = root
FOR i = 1 TO n
  WHILE q != fail AND g(q, text[i]) == fail
    q = h(q)
  ENDWHILE
  IF q == fail
    q = root
  ELSE
    q = g(q, text[i])
  ENDIF
  IF isElement(q, final)
    RETURN TRUE
  ENDIF
ENDFOR
RETURN FALSE
&lt;/pre&gt;
&lt;p&gt;Of course, ETrie has a slight modification to the above algorithm, which is that instead of returning TRUE or FALSE, it returns a pointer to the beginning of the match or NULL if it find no matches.&lt;/p&gt;
&lt;p&gt;The problem with this particular implementation, though, is that it would simply return a pointer to the offset into the string of the first match found. But what if you had multiple pattern strings that started with identical characters?&lt;/p&gt;
&lt;p&gt;Like the ETrie implementation, the traditional Aho-Corasick algorithm (if I am remembering correctly) stops searching as soon as it finds any match. The difference, of course, is that given access to the current to the state / tree structure, a programmer could choose to continue matching to see if there is a more greedy match. With ETrie, however, in the interest of simplicity, it just returned the first / shortest match it got to.&lt;/p&gt;
&lt;p&gt;In case I'm explaining this badly, say our search patterns are "the", "there", and "therefor". In the case of ETrie, it would always return that it matched "the" even when the "the" that it matched was the starting substring of the larger string, "therefor".&lt;/p&gt;
&lt;p&gt;In something I was working on more recently (in c++), I wanted a greedier match (e.g. I wanted it to match "therefor" instead of "the").&lt;/p&gt;
&lt;p&gt;In order to achieve this, I modified the implementation a slight bit:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
const char *
Trie::Search (const char *buf, size_t buflen, int *matched_id)
{
    const char *inptr, *inend, *prev, *pat;
    size_t matched = 0;
    TrieMatch *m = 0;
    TrieState *q;
    char c;
    
    inend = buf + buflen;
    inptr = buf;
    
    q = &amp;root;
    pat = prev = inptr;
    while (inptr &amp;lt; inend) {
        c = *inptr++;
        
        if (icase &amp;&amp; (c &gt;= 'A' &amp;&amp; c &amp;lt;= 'Z'))
            c += 0x20;
        
        while (q != 0 &amp;&amp; (m = g (q, c)) == 0 &amp;&amp; matched == 0)
            q = q-&gt;fail;
        
        if (q == &amp;root) {
            if (matched)
                return pat;
            
            pat = prev;
        }
        
        if (q == 0) {
            if (matched)
                return pat;
            
            q = &amp;root;
            pat = inptr;
        } else if (m != 0) {
            q = m-&gt;state;
            
            if (q-&gt;final &gt; matched) {
                if (matched_id)
                    *matched_id = q-&gt;id;
                
                matched = q-&gt;final;
            }
        }
        
        prev = inptr;
    }
    
    return matched ? pat : 0;
}
&lt;/pre&gt;
&lt;p&gt;I have published the full source code for &lt;a href="http://www.gnome.org/~fejj/code/trie.cpp"&gt;trie.cpp&lt;/a&gt; and &lt;a href="http://www.gnome.org/~fejj/code/trie.h"&gt;trie.h&lt;/a&gt; on my website for your perusal.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-9068940273837697689?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/9068940273837697689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=9068940273837697689' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/9068940273837697689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/9068940273837697689'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/12/fun-with-tries.html' title='Fun with Tries'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5138909082049920586</id><published>2008-12-13T08:44:00.003-05:00</published><updated>2009-08-14T15:22:25.549-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Herding Code: Episode 28 w/ Miguel de Icaza</title><content type='html'>&lt;p&gt;Been waiting to listen to this for a few days now. Figured others might also be interested: &lt;a href="http://herdingcode.com/?p=109"&gt;Herding Code: Episode 28&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Discussion of the history of Mono and some of the new features that have been added recently.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5138909082049920586?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5138909082049920586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5138909082049920586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5138909082049920586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5138909082049920586'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/12/herding-code-episode-28-w-miguel-de.html' title='Herding Code: Episode 28 w/ Miguel de Icaza'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1634568462384043192</id><published>2008-12-03T20:47:00.003-05:00</published><updated>2009-08-14T15:23:55.675-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><title type='text'>Moonlight 1.0 beta 1</title><content type='html'>&lt;p&gt;As most of you have probably heard by now, the first Beta release of Moonlight 1.0 has been announced, you can install it from &lt;a href="http://www.go-mono.com/moonlight/"&gt;http://www.go-mono.com/moonlight/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Miguel's got a &lt;a href="http://tirania.org/blog/archive/2008/Dec-02.html"&gt;great post&lt;/a&gt; explaining how the multimedia stack works in Moonlight in case that sort of thing interests you.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1634568462384043192?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1634568462384043192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1634568462384043192' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1634568462384043192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1634568462384043192'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/12/moonlight-10-beta-1.html' title='Moonlight 1.0 beta 1'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5543518765059260083</id><published>2008-11-03T10:29:00.004-05:00</published><updated>2009-08-14T15:24:24.770-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>Re: Black and White</title><content type='html'>&lt;p&gt;I've just finished reading Linus' blog post entitled &lt;a href="http://torvalds-family.blogspot.com/2008/11/black-and-white.html"&gt;Black and White&lt;/a&gt; and I have to agree.&lt;/p&gt;
&lt;p&gt;It's not productive to be &lt;i&gt;anti&lt;/i&gt;-something, it is much healthier and more productive to be &lt;i&gt;for&lt;/i&gt; something.&lt;/p&gt;
&lt;p&gt;I think Linus' article ties back into the &lt;a href="http://jeffreystedfast.blogspot.com/2008/06/how-to-survive-poisonous-people.html"&gt;How To Survive Poisonous People&lt;/a&gt; presentation I linked to and commented on back in June.&lt;/p&gt;
&lt;p&gt;Very often times, the poisonous people in a community are those who try to make everything black and white and typically take the &lt;i&gt;anti&lt;/i&gt; approach to things.&lt;/p&gt;
&lt;p&gt;We all do it from time to time (myself included, *cough*), but the truly poisonous people are the ones that can't ever let things go.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5543518765059260083?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5543518765059260083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5543518765059260083' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5543518765059260083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5543518765059260083'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/11/re-black-and-white.html' title='Re: Black and White'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6512650650673728316</id><published>2008-10-31T13:18:00.004-04:00</published><updated>2009-08-14T15:25:16.722-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Mono @ PDC 2008</title><content type='html'>&lt;p&gt;For those who weren't able to attend Microsoft's Professional Developer's Conference this past week, Miguel gave a presentation (&lt;a href="http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/PC54.wmv"&gt;wmv&lt;/a&gt;) about Mono detailing some exciting new developments.&lt;/p&gt;
&lt;p&gt;For example, Mono 2.2 (slated for the first week of December) will have a C# shell which Miguel and Marek have been working on and which Microsoft has announced will be part of C# version 5, slated for release sometime in 2012 (yes, that means Mono is ahead of Microsoft!).&lt;/p&gt;
&lt;p&gt;Also presented was Mono in video games, such as those on the Wii and iPhone platforms (which are both supported targets of the Unity3D game development studio). Some game studios are apparently also using Mono on the PlayStation3, Xbox360, Windows, and Mac platforms. The main interest here was that Unity3D has been rewritten from Objective-C (on the Mac platform) to C# which should make it eventually portable to Linux (C# version now runs on Windows and Mac).&lt;/p&gt;
&lt;p&gt;Another interesting development that came about because of interest in using Mono for video games (since some game development studios are now writing games in fully managed code), was that it was important for Mono to get SIMD support which has now been implemented and will be available in Mono 2.2. This has made Mono extremely fast (up to 10x faster) with respect to 3D vector math and other areas that benefit from SIMD.&lt;/p&gt;
&lt;p&gt;This is really exciting!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6512650650673728316?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6512650650673728316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6512650650673728316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6512650650673728316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6512650650673728316'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/10/mono-pdc-2008.html' title='Mono @ PDC 2008'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6957841600307585048</id><published>2008-10-31T12:50:00.005-04:00</published><updated>2009-08-14T15:26:11.888-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Optimizing Moonlight's InkPresenter</title><content type='html'>&lt;p&gt;This past week I started out staring at endless amounts of javascript trying to figure out what it was supposed to do so that I could figure out what Moonlight was breaking on in order to fix some bugs. As you can imagine, this is a slow and boring process where one's eyes go dry and it feels like you are getting nowhere fast.&lt;/p&gt;
&lt;p&gt;As occasionally happens, I give up and move onto the next bug hoping that the next bug will be easier to fix and/or give me some insight into the previous bug. As it turned out, I moved onto &lt;a href="https://bugzilla.novell.com/show_bug.cgi?id=409793"&gt;bug #409793&lt;/a&gt; which was a performance bug on sites like &lt;a href="http://www.thedatafarm.com/silverlight/journalsample"&gt;Ink Journal&lt;/a&gt; and &lt;a href="http://silverlight.net/samples/1.0/Ink-Tattoo-Studio/default.html"&gt;Ink Tattoo Studio&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What was happening on these sites was that as more points got added to the stroke, rendering would get slower and slower (thus causing the line to lag behind the mouse cursor) because Moonlight was invalidating the entire InkPresenter canvas on each frame and so having to render the entire thing even though it was unnecessary.&lt;/p&gt;
&lt;p&gt;To optimize this, I added a 'dirty' rectangle that kept track of the actual regions we needed to redraw. As points got added to the collection between frames, I added the bounds of the new point plus the region between the new point and the previous/next points (the 'next' point is obviously only needed if the newly added point was an insertion). The result for sites like InkJournal and InkTattooStudio was that we only invalidated the newly appended points at each frame render, vastly improving our performance which now matches Microsoft's Silverlight performance for these sites afaict.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6957841600307585048?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6957841600307585048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6957841600307585048' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6957841600307585048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6957841600307585048'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/10/optimizing-moonlights-inkpresenter.html' title='Optimizing Moonlight&apos;s InkPresenter'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6164546575195533414</id><published>2008-10-29T08:54:00.004-04:00</published><updated>2009-08-14T15:27:37.320-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='community'/><title type='text'>Re: It's Time for a FOSS Community Code of Conduct</title><content type='html'>&lt;p&gt;Bruce Byfield's article, &lt;a href="http://itmanagement.earthweb.com/osrc/article.php/12068_3781026_1"&gt;It's Time for a FOSS Community Code of Conduct&lt;/a&gt;, has sadly made me aware that this particular problem is more widespread than I thought.&lt;/p&gt;
&lt;p&gt;To Aaron Saigo &amp; the rest of the KDE team: just keep rocking, dudes. Eventually these donkeys will either give up or be committed to mental institutions (or better yet, they'll cross paths with someone &lt;i&gt;just&lt;/i&gt; like them and get what's coming around).&lt;/p&gt;
&lt;p&gt;To the people out there attacking developers/projects:&lt;/p&gt;
&lt;p&gt;Like I blogged a few years ago, rampant fanboyism is fine so long as you can keep it positive. You aren't doing the project you support any favors when you badmouth the other projects.&lt;/p&gt;
&lt;p&gt;For example, GNOME devs aren't pleased when they see GNOME fanboys attack KDE all over forums or on news sites.&lt;/p&gt;
&lt;p&gt;I'm sure the KDE devs feel the same way.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6164546575195533414?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6164546575195533414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6164546575195533414' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6164546575195533414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6164546575195533414'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/10/re-its-time-for-foss-community-code-of.html' title='Re: It&apos;s Time for a FOSS Community Code of Conduct'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-427412441534418789</id><published>2008-10-23T16:47:00.006-04:00</published><updated>2009-08-14T15:28:18.005-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>QuakeLight: A Silverlight Port of Quake</title><content type='html'>&lt;p&gt;Looks like &lt;a href="http://channel9.msdn.com"&gt;Channel9&lt;/a&gt; has just put up a &lt;a href="http://channel9.msdn.com/shows/Continuum/QuakeLightPreview/"&gt;video screen cast of QuakeLight&lt;/a&gt;, the Silverlight port of Quake - probably the game I lost the most amount of productivity to back in the late 90's.&lt;/p&gt;
&lt;p&gt;I'd love to play with this under Moonlight to see how well we fare...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Here's a handy link to an &lt;a href="http://adamkinney.com/blog/374/default.aspx"&gt;interview with the developer&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-427412441534418789?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/427412441534418789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=427412441534418789' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/427412441534418789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/427412441534418789'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/10/quakelight-silverlight-port-of-quake.html' title='QuakeLight: A Silverlight Port of Quake'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4336892432293418735</id><published>2008-10-05T12:26:00.003-04:00</published><updated>2009-08-14T15:29:31.164-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Parallel-Installable Gtk-Docs</title><content type='html'>&lt;p&gt;I recently release GMime 2.4.0 but missed the fact that the gtk-docs would install into the same location as the old 2.2 docs, namely ${prefix}/share/gtk-doc/html/gmime. Thwe problem is clear, since GMime 2.4 changed API (rather than just extending the 2.0/2.2 API), GMime 2.4 really needs to be fully parallel installable.&lt;/p&gt;
&lt;p&gt;Thanks to Gilles Dartiguelongue from the Gentoo community for discovering this and &lt;a href="http://bugzilla.gnome.org/show_bug.cgi?id=554121"&gt;bringing it to my attention&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As I tried to figure out how to accomplish what I needed, I discovered that Gtk-Doc needed some fixes so I did a quick hack and &lt;a href="http://bugzilla.gnome.org/show_bug.cgi?id=554718"&gt;submitted it upstream&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, my original fix was broken in that I didn't realize that a simple version extension to the install directory wouldn't be enough because GNOME's devhelp program expected the .devhelp and .devhelp2 files would be named with the same version extension, or they would not be detected.&lt;/p&gt;
&lt;p&gt;After that was pointed out to me, I looked deeper into the problem and discovered it wasn't such a terribly hard fix afterall, just a little &lt;a href="http://bugzilla.gnome.org/attachment.cgi?id=119898&amp;action=view"&gt;shell scripting magic&lt;/a&gt; was all that was needed ;-)&lt;/p&gt;
&lt;p&gt;Since Stefan Kost (the gtk-doc maintainer) and myself were both interested in such a solution, I figured there must be other library maintainers who would be interested in this and so thought I would blog about it.&lt;/p&gt;
&lt;p&gt;For those interested in packaging GMime 2.4.x for the various distros, I'll be releasing a 2.4.2 release in the next day or so (going to wait a little longer just in case anyone finds any other last minute parallel-install bugs in the &lt;a href="http://www.gnome.org/~fejj/gmime-2.4.1.1.tar.gz"&gt;gmime-2.4.1.1&lt;/a&gt; tarball I put together for testing; it's bad enough that I've already released a gmime-2.4.1 with nothing but parallel install fixes and that 2.4.2 will be more of the same, I'd rather not have to issue a 2.4.3).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4336892432293418735?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4336892432293418735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4336892432293418735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4336892432293418735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4336892432293418735'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/10/parallel-installable-gtk-docs.html' title='Parallel-Installable Gtk-Docs'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7332191207690318990</id><published>2008-10-03T12:23:00.006-04:00</published><updated>2009-08-14T15:31:00.923-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><title type='text'>Setting Up a Multi-Tabbed GNOME-Terminal Development Environment</title><content type='html'>&lt;p&gt;For many developers (such as myself), the first thing we tend to do when we login to our desktops, is to launch gnome-terminal (or similar) with a number of tabs and then will typically have to setup a bunch of environment variables in each tab.&lt;/p&gt;
&lt;p&gt;Most of us have probably simplified this at least somewhat by creating a file that sets our environment variables for us when we do &lt;pre style="courier new; size=85%"&gt;. ~/project.env&lt;/pre&gt; or something to that effect.&lt;/p&gt;
&lt;p&gt;The problem is that if we have multiple tabs that we've got to source our project.env files in, this gets tedious.&lt;/p&gt;
&lt;p&gt;This morning, Rolf shared with me a way to spawn gnome-terminal and have it automatically cd into a list of specified working-directories... but I wanted to take it a step further and have gnome-terminal auto-magically source my project environment variables.&lt;/p&gt;
&lt;p&gt;Here's how I solved this problem:&lt;/p&gt;
&lt;p&gt;* Step 1: Create a &lt;b&gt;&lt;i&gt;~/bin/devterms&lt;/i&gt;&lt;/b&gt; shell script:&lt;/p&gt;
&lt;pre style="courier new; size=85%"&gt;#!/bin/bash -e

MONO_ENV="/bin/bash --rcfile ~/.devtermsrc -i"

gnome-terminal \
  --tab --working-directory=/cvs/moon --command="$MONO_ENV" \
  --tab --working-directory=/cvs/moon/test --command="$MONO_ENV" \
  --tab --working-directory=/cvs/mono --command="$MONO_ENV" \
  --tab --working-directory=/cvs/monodevelop --command="$MONO_ENV" \
  &amp;&lt;/pre&gt;
&lt;p&gt;* Step 2: Create &lt;b&gt;&lt;i&gt;~/.devtermsrc&lt;/i&gt;&lt;/b&gt; rc file for bash:&lt;/p&gt;
&lt;pre style="courier new; size=85%"&gt;# Load ~/.bashrc to setup all of my standard environment variables and aliases
test -s ~/.bashrc &amp;&amp; . ~/.bashrc || true

# Load Mono-specific development environment variables
test -s ~/mono.env &amp;&amp; . ~/mono.env || true
&lt;/pre&gt;
&lt;p&gt;* Step 3: Create a launcher (in my case, I made &lt;b&gt;&lt;i&gt;~/Desktop/Development Environment.desktop&lt;/i&gt;&lt;/b&gt;):&lt;/p&gt;
&lt;pre style="courier new; size=85%"&gt;[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Name[en_US]=Development Environment
Exec=/home/fejj/bin/devterms
Name=Development Environment
Icon=gnome-terminal
&lt;/pre&gt;
&lt;p&gt;Hopefully this will help other people make their own lives a little simpler.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7332191207690318990?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7332191207690318990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7332191207690318990' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7332191207690318990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7332191207690318990'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/10/setting-up-multi-tabbed-gnome-terminal.html' title='Setting Up a Multi-Tabbed GNOME-Terminal Development Environment'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3857731350959439252</id><published>2008-09-18T23:29:00.003-04:00</published><updated>2009-08-14T15:32:40.618-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Light Bot</title><content type='html'>&lt;p&gt;A friend of mine sent me a link to &lt;a href="http://www.gameroo.nl/games/light-bot"&gt;Light Bot&lt;/a&gt;, a game for programmers. I'm already addicted.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3857731350959439252?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3857731350959439252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3857731350959439252' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3857731350959439252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3857731350959439252'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/09/light-bot.html' title='Light Bot'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1867709256433008433</id><published>2008-08-28T17:44:00.013-04:00</published><updated>2008-08-29T11:18:13.912-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='banshee'/><title type='text'>Banshee "Now Playing" Animations</title><content type='html'>&lt;p&gt;&lt;a href="http://abock.org"&gt;Aaron&lt;/a&gt; has been complaining lately that writing fancy graphics hacks for Banshee by hand using low-level &lt;a href="http://www.cairographics.org"&gt;Cairo&lt;/a&gt; calls is too "hard" and too tiresome to do.
&lt;p&gt;Wimp.
&lt;p&gt;For Hack Week, this week, I've been fixing up the GtkSharp Moonlight widget (aka GtkSilver) to work again so that The Great Bocky can write fancy graphics hacks using XAML instead.
&lt;p&gt;One area that Aaron has mentioned that he'd love to do fancier animations in is the "Now Playing" view which currently is limited to a fade-in and a fade-out of the current track info (album cover w/ a reflection), track title, artist, and album name.
&lt;p&gt;It took him far too long to write the code that displays that view (+ time spent optimizing it to get better than 11 FPS) and if he ever gets around to implementing anything fancier, he'll be popping those Excedrin pills like candy.
&lt;p&gt;Lucky for him, I mocked up a slightly improved version of his "Now Playing" view in XAML (no code required except to update the text, album art, and to invoke the animations). All animations and graphics are represented in just 70 lines of XAML.
&lt;p&gt;The great thing about designing this view in XAML is that it is easy to change the layout or adjust the animations without having to write any new code. Users can customize their "Now Playing" screens in any way they want to, all they have to do is keep the names of the controls and animations consistent with what the application expects. It's a lot like Glade XML files, only it allows the user to do fancy things like animations as well.
&lt;p&gt;The demo I hacked up uses the following XAML:
&lt;pre style="font-family: courier new; font-size: 75%"&gt;
&amp;lt;Canvas xmlns="http://schemas.microsoft.com/client/2007"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Background="Black" Width="700" Height="550"&gt;
  &amp;lt;Canvas x:Name="Display"&gt;
    &amp;lt;TextBlock Canvas.Left="10" Canvas.Top="200" x:Name="TrackInfo" Width="280"
               FontFamily="Sans" FontSize="14" TextAlignment="Right" Foreground="White"&gt;
      &amp;lt;Run x:Name="Title" FontSize="24"&gt;Wonderboy&amp;lt;/Run&gt;&amp;lt;LineBreak/&gt;
      &amp;lt;Run x:Name="By" FontSize="12" Foreground="Gray"&gt;by&amp;lt;/Run&gt;
      &amp;lt;Run x:Name="Artist"&gt;Tenacious D&amp;lt;/Run&gt;&amp;lt;LineBreak/&gt;
      &amp;lt;Run x:Name="From" FontSize="12" Foreground="Gray"&gt;from&amp;lt;/Run&gt;
      &amp;lt;Run x:Name="Album"&gt;Tenacious D&amp;lt;/Run&gt;
    &amp;lt;/TextBlock&gt;
    &amp;lt;Rectangle x:Name="AlbumArt" Canvas.Left="300" Canvas.Top="50" Width="300" Height="300"&gt;
      &amp;lt;Rectangle.Fill&gt;
        &amp;lt;ImageBrush x:Name="AlbumArtBrush" Stretch="Fill" ImageSource="tenaciousd.jpg"/&gt;
      &amp;lt;/Rectangle.Fill&gt;
    &amp;lt;/Rectangle&gt;
    &amp;lt;Rectangle x:Name="AlbumArtReflection" Canvas.Left="300" Canvas.Top="50" Width="300" Height="300"
               RenderTransformOrigin="0,1"&gt;
      &amp;lt;Rectangle.Fill&gt;
        &amp;lt;ImageBrush x:Name="AlbumArtReflectionBrush" Stretch="Fill" ImageSource="tenaciousd.jpg"/&gt;
      &amp;lt;/Rectangle.Fill&gt;
      &amp;lt;Rectangle.OpacityMask&gt;
        &amp;lt;LinearGradientBrush StartPoint="0,1" EndPoint="0,0"&gt;
          &amp;lt;LinearGradientBrush.GradientStops&gt;
            &amp;lt;GradientStop Color="#8f8f8f8f" Offset="0"/&gt;
            &amp;lt;GradientStop Color="#00000000" Offset="0.75"/&gt;
            &amp;lt;GradientStop Color="#00000000" Offset="1"/&gt;
          &amp;lt;/LinearGradientBrush.GradientStops&gt;
        &amp;lt;/LinearGradientBrush&gt;
      &amp;lt;/Rectangle.OpacityMask&gt;
      &amp;lt;Rectangle.RenderTransform&gt;
        &amp;lt;TransformGroup&gt;
          &amp;lt;ScaleTransform ScaleX="1" ScaleY="-0.35"/&gt;
          &amp;lt;SkewTransform x:Name="SkewTransform" AngleX="45" AngleY="0"/&gt;
        &amp;lt;/TransformGroup&gt;
      &amp;lt;/Rectangle.RenderTransform&gt;
    &amp;lt;/Rectangle&gt;
    &amp;lt;Canvas.Resources&gt;
      &amp;lt;Storyboard x:Name="ReflectionAnimation"&gt;
        &amp;lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="AlbumArtReflection"
         Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)"&gt;
          &amp;lt;SplineDoubleKeyFrame KeyTime="00:00:00" Value="-45" KeySpline="0.25,0.00 0.75,0.75"/&gt;
          &amp;lt;SplineDoubleKeyFrame KeyTime="00:00:02" Value="45" KeySpline="0.25,0.75 0.75,1.0"/&gt;
        &amp;lt;/DoubleAnimationUsingKeyFrames&gt;
      &amp;lt;/Storyboard&gt;
      &amp;lt;Storyboard x:Name="FadeIn"&gt;
        &amp;lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Display"
         Storyboard.TargetProperty="Opacity"&gt;
          &amp;lt;SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/&gt;
          &amp;lt;SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/&gt;
        &amp;lt;/DoubleAnimationUsingKeyFrames&gt;
      &amp;lt;/Storyboard&gt;
      &amp;lt;Storyboard x:Name="FadeOut"&gt;
        &amp;lt;DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Display"
         Storyboard.TargetProperty="Opacity"&gt;
          &amp;lt;SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/&gt;
          &amp;lt;SplineDoubleKeyFrame KeyTime="00:00:01" Value="0"/&gt;
        &amp;lt;/DoubleAnimationUsingKeyFrames&gt;
      &amp;lt;/Storyboard&gt;
    &amp;lt;/Canvas.Resources&gt;
  &amp;lt;/Canvas&gt;
&amp;lt;/Canvas&gt;&lt;/pre&gt;
&lt;p&gt;To see this in action, you'll need to grab Moonlight out of SVN (I ended up using some Silverlight 2.0 TextBlock features like &lt;i&gt;TextAlignment="Right"&lt;/i&gt; so that no code was needed to align the text like what Aaron has to calculate manually in the current code). Once you have that installed, you should be able to view my Banshee "Now Playing" mockup in the iframe below. Mousing over the iframe should cause the fade-in effect to start and mousing out of the iframe area should cause the fade-out to take effect.
&lt;center&gt;
&lt;iframe src="http://www.gnome.org/~fejj/banshee-now-playing.html" width="700" height="550"&gt;&lt;/iframe&gt;
&lt;/center&gt;
&lt;p&gt;Oh, XAML, what is the secret of your power? Won't you take me far away from the mucky-muck man?
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; It has been pointed out that the above iframe could have been done in pure XAML using EventTriggers for MouseEnter/Leave events to trigger the animations, however I designed the XAML to be used by Banshee where Aaron will likely want to be able to control when the animations start/stop programatically and not based on mouse hover events ;-)
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; The XAML should now work with Silverlight (apparently it didn't like my LineStackingStrategy or LineHeight property on the TextBlock).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1867709256433008433?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1867709256433008433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1867709256433008433' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1867709256433008433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1867709256433008433'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/08/banshee-now-playing-animations.html' title='Banshee &quot;Now Playing&quot; Animations'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4029062502434122798</id><published>2008-08-16T11:17:00.004-04:00</published><updated>2009-08-14T15:34:24.109-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>GMime Devel List</title><content type='html'>&lt;p&gt;The GNOME admins have just approved and created a mailing list for discussing GMime development (meant both for contributors to the GMime library as well as developers using GMime).&lt;/p&gt;
&lt;p&gt;You can subscribe to the mailing-list at &lt;a href="http://mail.gnome.org/mailman/listinfo/gmime-devel-list"&gt;http://mail.gnome.org/mailman/listinfo/gmime-devel-list&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4029062502434122798?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4029062502434122798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4029062502434122798' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4029062502434122798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4029062502434122798'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/08/gmime-devel-list.html' title='GMime Devel List'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1694127435226545648</id><published>2008-08-15T19:13:00.003-04:00</published><updated>2009-08-14T15:35:31.745-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><title type='text'>Moonlight 0.8 Released</title><content type='html'>&lt;p&gt;The Moonlight team has just released &lt;a href="ftp://ftp.novell.com/pub/mono/sources/moon/moon-0.8.tar.bz2"&gt;moon-0.8.tar.bz2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also get a pre-built Firefox plugins at &lt;a href="http://go-mono.com/moonlight"&gt;http://go-mono.com/moonlight&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1694127435226545648?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1694127435226545648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1694127435226545648' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1694127435226545648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1694127435226545648'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/08/moonlight-08-released.html' title='Moonlight 0.8 Released'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5539003612042279654</id><published>2008-08-14T20:12:00.004-04:00</published><updated>2009-08-14T15:36:29.736-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Moonlight Performance Enhancements</title><content type='html'>&lt;p&gt;Spent today working with Sebastien "Master Profiler" Pouliot on finding and resolving one of our longest outstanding performance bottlenecks in Moonlight for which the &lt;a href="http://www.wynapse.com/Silverlight/Silverlight_GlyphMap_Utility.aspx"&gt;GlyphMap Utility&lt;/a&gt; is a perfect test case.&lt;/p&gt;
&lt;p&gt;Months ago, I had rewritten the font caching a bit so that we prevented (in most cases) the loading of the same font file that were shared between multiple textual XAML elements (Glyphs and TextBlock). At the time, font loading was at the top of the performance profile. While this fix did help a little as far as rendering speed went, it was barely noticeable visually. It wasn't a waste, however, because it greatly reduced memory overhead and later allowed for some better font scaling optimization tricks that I implemented.&lt;/p&gt;
&lt;p&gt;Next up, I rewrote the Glyphs XAML element's ::ComputeBounds() routine such that not only did it calculate the rendering extents of the Glyphs element, but also cached the glyph string layout in a Cairo path such that later calls to ::Render() could simply blit the path rather than having to do its own layout.&lt;/p&gt;
&lt;p&gt;Still, visual rendering performance seemed barely affected.&lt;/p&gt;
&lt;p&gt;Then, today, Sebastien decided to take a look into the problem again and had discovered that sorting UIElements based on ZIndex was toward the top of the list as far as time-eaters went. The fix for this was to delay sorting the newly added UIElements until the engine went to render the next frame.&lt;/p&gt;
&lt;p&gt;This bumped the sorting code right out of the time-eaters list but still no visual improvement :(&lt;/p&gt;
&lt;p&gt;Sebastien reported back to me that we seemed to be idling between Glyphs draws which immediately made me recall that our Downloaders asyncronously download the referenced font files that each Glyphs element references and that at each render tick, we only popped a single request from our async queue.&lt;/p&gt;
&lt;p&gt;I immediately went to work and fixed the async queue logic to pop as many frames as we could in 1/30th of a second (this value may need to be tweaked a slight bit, but it should typically be acceptable).&lt;/p&gt;
&lt;p&gt;The GlyphMap table now renders instantly.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5539003612042279654?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5539003612042279654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5539003612042279654' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5539003612042279654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5539003612042279654'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/08/moonlight-performance-enhancements.html' title='Moonlight Performance Enhancements'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3873340883674808128</id><published>2008-08-13T14:10:00.003-04:00</published><updated>2009-08-14T15:38:09.330-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><title type='text'>Moonlighting the Olympics</title><content type='html'>&lt;p&gt;There's been a lot of interest in Moonlight lately, largely by people who hope to use it to watch the Olympics at &lt;a href="http://www.nbcolympics.com"&gt;http://nbcolympics.com&lt;/a&gt;, unfortunately Moonlight isn't quite ready to view this content :-(&lt;/p&gt;
&lt;p&gt;The good news is that we are furiously hacking away on Moonlight 2.0 in the hopes of making it usable as quickly as we can.&lt;/p&gt;
&lt;p&gt;The first roadblock is that NBC Olympics site is using an old Silverlight.js initialization script and currently requires one of the following browser/OS combinations to work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Internet Explorer 6, 7 for Windows (Vista, XP SP2 or greater and 2003)&lt;/li&gt;
&lt;li&gt;Firefox 1.5, 2, 3 for Windows (Vista, XP SP2 or greater and 2003)&lt;/li&gt;
&lt;li&gt;Firefox 1.5, 2, 3 for Mac (OS 10.4.8 or greater, Intel only)&lt;/li&gt;
&lt;li&gt;Safari 2 &amp; 3 for Mac (OS 10.4.8 or greater, Intel only)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get past this roadblock for use with Moonlight, you first need to download and install the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/59"&gt;User Agent Switcher Add-On&lt;/a&gt;. Once you install that and restart your Firefox browser, you'll need to go to &lt;i&gt;Tools/User Agent Switcher/Options/Options&lt;/i&gt;. This will bring up a configuration dialog allowing you to add custom User Agent strings. You'll want to click on the &lt;i&gt;Add...&lt;/i&gt; button and enter the following information:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Description:&lt;/b&gt; Firefox 3.0 (Mac)&lt;br&gt;
&lt;b&gt;User Agent:&lt;/b&gt; Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9) Gecko/2008061004 Firefox/3.0&lt;br&gt;
&lt;b&gt;App Name:&lt;/b&gt; Firefox&lt;br&gt;
&lt;b&gt;App Version:&lt;/b&gt; 3.0 [en] (Intel Mac OS X 10.5; U)&lt;br&gt;
&lt;b&gt;Platform:&lt;/b&gt; Macintosh&lt;/p&gt;
&lt;p&gt;I think the only required field is the &lt;i&gt;User Agent&lt;/i&gt;, the other fields can probably be set to whatever you want (thanks to Larry Ewing for the User-Agent string and for explaining to me how to do this).&lt;/p&gt;
&lt;p&gt;Now that you have a Firefox 3.0/Mac User-Agent string, you'll need to select the "Firefox 3.0 (Mac)" radio button in the &lt;i&gt;Tools/User Agent Switcher&lt;/i&gt; Firefox menu. Once you've done that, you should be able to navigate to the NBC Olympics video pages (although you still won't be able to view the video content quite yet... we're still working on writing the code to make that work).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3873340883674808128?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3873340883674808128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3873340883674808128' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3873340883674808128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3873340883674808128'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/08/moonlighting-olympics.html' title='Moonlighting the Olympics'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-583642208546239100</id><published>2008-08-08T17:08:00.004-04:00</published><updated>2009-08-14T15:38:55.353-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><category scheme='http://www.blogger.com/atom/ns#' term='cycling'/><title type='text'>Time-off This Past Week</title><content type='html'>&lt;p&gt;Took this week off from work to go visit family and did a bit of cycling in my quest to "get back into shape" (or some semblance of shape, anyway).&lt;/p&gt;
&lt;p&gt;Started off doing an 8.5-mile hill climb to the top of the eastern hill at Blue Hills Reservation in Milton, Mass which is about a 6% grade or so. Nothing awe-inspiring, but a bit of a workout for me. On Monday I continued with a 10-mile ride accompanied by relatives up in Rochester, NH - no major hills this time but quite a bit of ups and downs, so it was still a workout since I pushed fairly hard. Tuesday and Wednesday I did some 21-mile rides pushing hard and by the end of Wednesday's ride (in the pouring rain, btw) my legs could push no farther so I decided to take Thursday off. Traveled back home and cleaned as much of the sand/grit out of my bike as I could, de-greased and re-lubed my chain and derailleurs (looks like I picked up a little rust on my chain, but nothing major). Then today I went out to take on Blue Hills again, this time managing to push farther, so ended up climbing the eastern hill twice, once from each side. Coming from the west, the incline averages a good 7 or 8% iirc, so not too shabby. That puts me at about 70 miles so far this week.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-583642208546239100?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/583642208546239100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=583642208546239100' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/583642208546239100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/583642208546239100'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/08/time-off-this-past-week.html' title='Time-off This Past Week'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2870318831443139723</id><published>2008-07-29T12:24:00.004-04:00</published><updated>2009-08-14T15:39:38.978-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lazyweb'/><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>Tachikoma 3D Model?</title><content type='html'>&lt;p&gt;Dear lazy web,&lt;/p&gt;
&lt;p&gt;I'm hoping someone might have some handy links to a (preferably free) 3D CG model of a tachikoma that I'd be able to use in a s3kr3t side-project of mine (oops, I guess it's not so secret anymore, huh?). Since I'm planning on animating the tachikoma, it would preferably have hooks for this or be componentized or something (not sure how 3D CG models are "built" to allow animation, so... excuse my ignorance).&lt;/p&gt;
&lt;p&gt;Failing that, a technical blueprint would be greatly helpful if I am forced to model my own.&lt;/p&gt;
&lt;p&gt;Credit will be given to the modeler (or draftsman) in my project if it ever reaches the point where I release it to the public (which I'll do if/when it becomes more than a pipedream... currently just in the planning stages and the project is likely beyond my abilities, but we'll see).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2870318831443139723?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2870318831443139723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2870318831443139723' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2870318831443139723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2870318831443139723'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/tachikoma-3d-model.html' title='Tachikoma 3D Model?'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2943626000052403212</id><published>2008-07-24T08:01:00.005-04:00</published><updated>2009-08-14T15:40:30.290-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><title type='text'>Moonlight 2.0 Hackathon</title><content type='html'>&lt;p&gt;Starting this past Monday, we've begun a 2-week Moonlight 2.0 Hackathon to try and get as much of the 2.0 API implemented as we can (1.0 is basically done, but could still use some performance optimizations).&lt;/p&gt;
&lt;p&gt;I've been reworking our c++ Collection implementation to support the Silverlight 2.0 collections of doubles and Points (Silverlight 1.0 only allowed collections of DependencyObjects) and I'll then move on to updating the c++-side code that used to use generic double and Point arrays to use my new DoubleCollection and PointCollection classes respectively.&lt;/p&gt;
&lt;p&gt;I've also taken the liberty to implement some of the additional functionality that Silverlight 2.0 has added to the base Collection class (aka PresentationFrameworkCollection` on the .NET-side of things) like Contains() and IndexOf() (we used to get these 2 for free with my c++ List implementation, but I'm no longer using that as the base) as well as changing the way collection change-notification is done.&lt;/p&gt;
&lt;p&gt;Once that is finished, I'll be binding them in managed land.&lt;/p&gt;
&lt;p&gt;Meanwhile, Chris Toshok and Rolf have been refactoring the way DependencyProperties get registered since Silverlight 2.0 allows the programmer to create new DependencyObject derivatives and register new DependencyProperty's on those objects.&lt;/p&gt;
&lt;p&gt;They'll also be making the type-system per-AppDomain rather than global like it is right now and will be looking into allowing each AppDomain to have multiple Surfaces so that applications like LunarEclipse will be able to work.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2943626000052403212?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2943626000052403212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2943626000052403212' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2943626000052403212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2943626000052403212'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/moonlight-20-hackathon.html' title='Moonlight 2.0 Hackathon'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2646849220283822918</id><published>2008-07-18T12:44:00.004-04:00</published><updated>2009-08-14T15:46:29.581-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pulseaudio'/><title type='text'>PulseAudio: My Last Post On The Topic?</title><content type='html'>&lt;p&gt;I wasn't going to post anymore on PulseAudio now that Lennart has fixed the core issue that was breaking audio for me on my system (there was a deadlock condition in PulseAudio - my libesd and libgnome fixes were merely a fix to make those libs handle the PA deadlock more gracefully).&lt;/p&gt;
&lt;p&gt;But, since Lennart has now attacked me, I guess I should respond:&lt;/p&gt;
&lt;p&gt;A few comments:&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;1. Not directly related to PulseAudio itself. Also, finding errors in code that is related to esd is not exactly the most difficult thing in the world.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;Considering that the GNOME desktop and many other applications speak to pulseaudio via libesd, it is still relevant. Until all applications are ported to use PulseAudio directly, libesd is still a part of the "PulseAudio stack".&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;OK, Jeffrey found a real bug, but I wouldn't say this is really enough to make all the fuss about. Or is it?&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;Actually, I believe you mean &lt;i&gt;three&lt;/i&gt; in the PulseAudio code itself (granted, the pavucontrol bug was already fixed and in a public release - shame on my distro for shipping 0.9.5 instead of 0.9.6, but I don't remember even flaming you about this one - I only reported it as a bug to try and help you make PA better). Yes, the deadlock one was fixed a while ago (assuming the deadlock you fixed is the same one I am experiencing, which it probably is) but it is not in any released version of PA. Nor is the "won't play short sound clips" bug fix.&lt;/p&gt;
&lt;p&gt;Hence, not mine nor my distro's fault.&lt;/p&gt;
&lt;p&gt;You also completely fail to grasp how frustrating that deadlock bug (which was really the core of my issues) was for anyone using GNOME on a system where that deadlock occurs. Because when that deadlock happens, the &lt;i&gt;entire system locks up!&lt;/i&gt; You cannot launch firefox, you cannot start any new GNOME apps, etc. You can't even close gnome-terminal.&lt;/p&gt;
&lt;p&gt;Now, I will grant you that part of the blame certainly lies in libesd (hence why I fixed it), but to say it is completely unrelated is bologna. My ESD fixes were not random fixes so I could point fingers, they were fixes so that my system didn't hang whenever PA did.&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;5. A valid bug, but not really in PulseAudio. Mostly caused because the ALSA API and PA API don't really match 100%.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;This seems like a design failure - if the plan is to make applications that use ALSA directly "Just Work(tm)" through PA, then shouldn't PA have been designed to map better to ALSA?&lt;/p&gt;
&lt;p&gt;I still consider this to be a PA "bug" even if the fix was in ALSA(?).&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;Many people (like Jeffrey) wonder why have software mixing at all if you have hardware mixing?&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;Actually, that's not at all what I was wondering. I had wondered why PA was needed at all because ALSA already did mixing for me.&lt;/p&gt;
&lt;p&gt;Now, I will admit to being naieve about the full list of goals that PA is trying to achieve (which are worthy goals), but I think they all take a backseat to having sound actually work reliably in a basic setup (apps playing audio through local speakers).&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;Jeffrey thinks that audio mixing is nothing for userspace. Which is basically what OSS4 tries to do: mixing in kernel space. However, the future of PCM audio is floating points. Mixing them in kernel space is problematic because (at least on Linux) FP in kernel space is a no-no. Also, the kernel people made clear more than once that maths/decoding/encoding like this should happen in userspace. Quite honestly, doing the mixing in kernel space is probably one of the primary reasons why I think that OSS4 is a bad idea. The fancier your mixing gets (i.e. including resampling, upmixing, downmixing, DRC, ...) the more difficulties you will have to move such a complex, time-intensive code into the kernel.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;Fair enough.&lt;/p&gt;
&lt;p&gt;I still don't like it (but I guess there's nothing you can do about it if the kernel folk are holding you back), but so long as it Just Works(tm), in the end I don't care.&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;Not every time your audio breaks it is alone PulseAudio's fault. For example, the original flame of Jeffrey's was about the low volume that he experienced when running PA. This is mostly due to the suckish way we initialize the default volumes of ALSA sound cards. Most distributions have simple scripts that initialize ALSA sound card volumes to fixed values like 75% of the available range, without understanding what the range or the controls actually mean. This is actually a very bad thing to do. Integrated USB speakers for example tend export the full amplification range via the mixer controls. 75% for them is incredibly loud. For other hardware (like apparently Jeffrey's) it is too low in volume. How to fix this has been discussed on the ALSA mailing list, but no final solution has been presented yet. Nonetheless, the fact that the volume was too low, is completely unrelated to PulseAudio.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;This is actually partly also openSUSE's fault in 2 ways:&lt;/p&gt;
&lt;p&gt;1. the volume control in the panel launches pavucontrol instead of gnome-volume-control. Since I need to use gnome-volume-control in order to adjust the master volume of the ALSA device, and the fact that the volume shown in pavucontrol was set to MAX, led me to be confused.&lt;/p&gt;
&lt;p&gt;2. the keyboard volume controls do not properly adjust the master volume (I think I may have wrongly blamed this on PA in one of my posts, but don't feel like re-reading my posts to confirm - if I did, apologies).&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;OTOH Ubuntu didn't exactly do a stellar job. They didn't do their homework. Adopting PA in a distribution is a fair amount of work, given that it interfaces with so many different things at so many different places. The integration with other systems is crucial. The information was all out there, communicated on the wiki, the mailing lists and on the PA IRC channel. But if you join and hang around on neither, then you won't get the memo.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;If distros are getting this wrong, then maybe there needs to be better communication so that things like what happened to Ubuntu don't keep happening.&lt;/p&gt;
&lt;p&gt;FWIW, I have personally read over the "The Perfect PulseAudio Setup" wiki page and afaict, openSUSE 11 followed the recommended setup but there were still problems (obviously).&lt;/p&gt;
&lt;p&gt;(Although the problems I experienced were bugs in code rather than bugs in setup...mostly)&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;[2] In fact, Flash 9 can not be made fully working on PulseAudio. This is because the way Flash destructs it's driver backends is racy. Unfixably racy, from external code. Jeffrey complained about Flash instability in his second post. This is unfair to PulseAudio, because I cannot fix this. This is like complaining that X crashes when you use binary-only fglrx.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;Sort of like it's unfair that Evolution users complain when Evolution doesn't work with some broken server. But users don't care that it's a broken server if other clients work with it, so it's still on the Evolution developer's shoulders to work around those bugs.&lt;/p&gt;
&lt;p&gt;Sort of like how historically, hardware makers haven't been giving Linux kernel devs the specifications to make their hardware work, and so it is left up to F/LOSS developers to bear the burden of making it work &lt;i&gt;anyway&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;No one ever said life was fair and unfortunately, a LOT of users are going to expect Flash to work. If/when it doesn't, they &lt;i&gt;will&lt;/i&gt; complain and in a manner of speaking, it &lt;i&gt;is&lt;/i&gt; PulseAudio's fault because it &lt;i&gt;did&lt;/i&gt; work pre-PA.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2646849220283822918?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2646849220283822918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2646849220283822918' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2646849220283822918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2646849220283822918'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/pulseaudio-my-last-post-on-topic.html' title='PulseAudio: My Last Post On The Topic?'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3561252880770819595</id><published>2008-07-16T20:33:00.004-04:00</published><updated>2009-08-14T15:48:29.680-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Gtk+ 3.0: The Things That Make You Go "Hmmm?"</title><content type='html'>&lt;p&gt;Lots of discussion about Gtk+ 3.0 lately, unfortunately there's no real discussion going on (heh).&lt;/p&gt;
&lt;p&gt;There's the camp that is excited about API/ABI breakage and there's the camp that isn't so enthused.&lt;/p&gt;
&lt;p&gt;I have to take the side of the "not so enthused", alongside Miguel de Icaza[&lt;a href="http://tirania.org/blog/archive/2008/Jul-14.html"&gt;1&lt;/a&gt;][&lt;a href="http://tirania.org/blog/archive/2008/Jul-15.html"&gt;2&lt;/a&gt;], &lt;a href="http://log.ometer.com/2008-07.html#16"&gt;Havoc Pennington&lt;/a&gt; and &lt;a href="http://blogs.gnome.org/mortenw/2008/07/16/applications/"&gt;Morten Welinder&lt;/a&gt;: it's crazy insane to go breaking API/ABI for the sake of cleaning up the API without adding new functionality that could not be achieved by simply extending the current 2.x series.&lt;/p&gt;
&lt;p&gt;There are definitely things that can be done to the current gtk code base without having to break the current API/ABI to achieve them, so in my humble opinion that's what should be done. Granted, eventually there will have to be a Gtk+ 3.0 which breaks API/ABI in order to add some new functionality that isn't possible to implement in 2.x, but that road can be crossed when we get there. No sense breaking it now if it isn't absolutely &lt;i&gt;needed&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Even more worrying is the lack of promise to not break API/ABI &lt;i&gt;again&lt;/i&gt; after 3.0. In fact, I've read on one of the mailing lists or somewhere that they plan on breaking API/ABI every 4-5 years after 3.0, ripping out any API's they marked as deprecated in the meantime. This is crazy. One-Flew-Over-the-Cukoo's-Nest crazy (or, if you prefer, I'm-Cukoo-For-Cocoa-Puffs crazy).&lt;/p&gt;
&lt;p&gt;For large applications (Gnumeric, Evolution, Mozilla, Eclipse, etc), porting from 1.2 to 2.0 was a huge PITA but we all did it because (besides being young and stupid) 2.0 made a long-term commitment to maintain API/ABI compatibility going forward in addition to the fact that it added a ton of much-needed functionality (accessibility, UTF-8, model/view, and really good text layout w/ support for RTL and CJK).&lt;/p&gt;
&lt;p&gt;If 2.0 was just 1.2 + sealed structs and the removal of some deprecated APIs, no one would have bothered with 2.0.&lt;/p&gt;
&lt;p&gt;To respond to a point on &lt;a href="http://blogs.gnome.org/timj/2008/07/16/16072008-guadec-2008-wrapup/"&gt;Tim Janik's blog&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;3.0 will ABI-incompatibly remove all deprecated and private APIs. Of course, the above described deprecation scheme only scales well if deprecated APIs are really removed from the code base at some point.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;One reason that ISV's are typically on-board with Microsoft is that Microsoft has gone to great lengths to maintain backward compatibility with their old APIs. Joel Spolsky talks about it a bit in &lt;a href="http://www.joelonsoftware.com/articles/APIWar.html"&gt;How Microsoft Lost the API War&lt;/a&gt; (specifically, the section &lt;b&gt;The Two Forces at Microsoft&lt;/b&gt;).&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;The Windows testing team is huge and one of their most important responsibilities is guaranteeing that everyone can safely upgrade their operating system, no matter what applications they have installed, and those applications will continue to run, even if those applications do bad things or use undocumented functions or rely on buggy behavior that happens to be buggy in Windows n but is no longer buggy in Windows n+1.&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt;I'm not going to argue that Gtk/GNOME should go to these extensive lengths to make sure buggy apps continue to work, but there's no reason that G*_DISABLE_DEPRECATED can't simply mean "we're not going to bugfix these anymore, what you see is what you get". You don't have to ever remove them, especially since it likely doesn't require much maintenance to keep them around. The port to Gtk+ 3.0 would require some work to make sure all the internals of things like GtkCList use accessor methods to anything that they use internally, but after that the job should be done and over with.&lt;/p&gt;
&lt;p&gt;(ABI might not be a bit hard, but you could maintain API - thus meaning a simple recompile would work)&lt;/p&gt;
&lt;p&gt;On the &lt;i&gt;*giggle* *giggle* You should be using Mono/Gtk# *giggle* *giggle*&lt;/i&gt;-side, any application built against Gtk# 2.x will still work with Gtk# 3.x w/o any changes :-)&lt;/p&gt;
&lt;p&gt;Oh, and Gtk# has DataBinding support (which, btw, does not require API/ABI breakage to Gtk+ nor sealed structs like some people seem to think on this morning's #gnome-hacker's discussion *cough* *cough*).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3561252880770819595?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3561252880770819595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3561252880770819595' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3561252880770819595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3561252880770819595'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/gtk-30-things-that-make-you-go-hmmm.html' title='Gtk+ 3.0: The Things That Make You Go &quot;Hmmm?&quot;'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6391009235931864292</id><published>2008-07-16T19:52:00.008-04:00</published><updated>2009-08-14T15:50:19.094-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pulseaudio'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>PulseAudio: I Told You So</title><content type='html'>&lt;p&gt;To those who told me that my PulseAudio problems were my fault and/or my distro's fault, you were wrong[&lt;a href="http://bugzilla.gnome.org/show_bug.cgi?id=542296"&gt;1&lt;/a&gt;][&lt;a href="http://bugzilla.gnome.org/show_bug.cgi?id=542391"&gt;2&lt;/a&gt;][&lt;a href="http://www.pulseaudio.org/ticket/320"&gt;3&lt;/a&gt;][&lt;a href="http://www.pulseaudio.org/ticket/322"&gt;4&lt;/a&gt;][&lt;a href="http://www.pulseaudio.org/ticket/323"&gt;5&lt;/a&gt;]*. I told you so.&lt;/p&gt;
&lt;p&gt;The first 2 bugs were fixed by me last week (libgnome and libesd) and simply worked around the 4th bug linked above. On that note, I released &lt;a href="http://ftp.gnome.org/pub/GNOME/sources/esound/0.2/esound-0.2.39.tar.gz"&gt;esound-0.2.39&lt;/a&gt; with my fixes (along with a number of other patches that had been sitting in bugzilla god-knows how long collecting dust).
&lt;p&gt;The 3rd bug is just a crash in the pavucontrol which is apparently fixed in a new version (fairly minor annoyance since by the time I tried to use pavucontrol, pulseaudio was already deadlocked iirc).&lt;/p&gt;
&lt;p&gt;The 4th bug (which was the most serious of the ones I've been experiencing) was a deadlock in the pulseaudio daemon (it is supposedly fixed now, but it is not in any public release yet). Just because &lt;i&gt;you&lt;/i&gt; didn't experience it, doesn't mean the bug was my fault or my distro's fault ;-)&lt;/p&gt;
&lt;p&gt;The 5th bug was found by Geoff Norton, Rolf Kvinge, and myself today while trying to get moonlight to work well with PulseAudio after much head scratching wondering why sound wasn't playing for certain short mp3's (turns out that it's reproducible with any mp3 player if you try to play a short enough audio stream where the decoded stream is less than ~22 kilobytes iirc, but we didn't notice that until just after filing the bug).&lt;/p&gt;
&lt;p&gt;So the good news is that the PulseAudio devs have fixed the more serious issues I've found so far, but I'm still annoyed by the attitude of the people pushing PulseAudio of "well, we are forcing people to use PulseAudio so that bugs get found by the users".&lt;/p&gt;
&lt;p&gt;For normal applications, this is less annoying... but when it is something as low-level/fundamental as PulseAudio (or heaven forbid, the linux kernel), it should be QA'd thoroughly before dumping it on the users.&lt;/p&gt;
&lt;p&gt;Anywho, hopefully openSUSE/Ubuntu/Fedora will push my patches and the PA dev's patches soonish, so that should really help minimize more unnecessary user suffering.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;* there are other bugs that I filed as well, but I'm too lazy to go digging for them since the "My Bugs" link on the PulseAudio Trac doesn't actually work.&lt;/small&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6391009235931864292?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6391009235931864292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6391009235931864292' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6391009235931864292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6391009235931864292'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/pulseaudio-i-told-you-so.html' title='PulseAudio: I Told You So'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6550801365599709570</id><published>2008-07-13T22:20:00.005-04:00</published><updated>2009-08-14T15:51:04.859-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><title type='text'>Good News on the Evolution Front</title><content type='html'>&lt;p&gt;Novell has just recently (end of last week) announced that &lt;a href="http://mail.gnome.org/archives/evolution-hackers/2008-July/msg00004.html"&gt;Evolution will no longer require copyright assignment&lt;/a&gt;. This is awesome news that I've been hoping would happen for a quite a while now.&lt;/p&gt;
&lt;p&gt;Evolution's license is also changing to be dual-licensed under the LGPLv2 and LGPLv3.&lt;/p&gt;
&lt;p&gt;Thanks to Michael Meeks and Srini for making this happen!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6550801365599709570?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6550801365599709570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6550801365599709570' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6550801365599709570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6550801365599709570'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/good-news-on-evolution-front.html' title='Good News on the Evolution Front'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6662857793651987299</id><published>2008-07-10T16:02:00.005-04:00</published><updated>2009-08-14T15:52:18.507-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pulseaudio'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>PulseAudio Again...</title><content type='html'>&lt;p&gt;Just had another exciting PulseAudio crash where my sound card got continually spammed until my ears bled and then it spammed the sound card some more.&lt;/p&gt;
&lt;p&gt;Seriously though, my coworkers were a bit annoyed by my laptop blaring really loud and obnoxious noise for the past hour (made worse because my keyboard volume control keys do not actually work with pulseaudio which is apparently a known issue with Lenovo T61 laptops I'm told).&lt;/p&gt;
&lt;p&gt;However, this did provide me with a most excellent opportunity to test the patches I posted in my previous blog entry about my pain and suffering at the hands of PulseAudio.&lt;/p&gt;
&lt;p&gt;Yet again, I was unable to launch any new apps - though instead of blocking in esd_open_sound(), they blocked in esd_send_auth(), so I went and patched that up to use non-blocking IO, build new packages, installed them, and tested and HALLELUJAH! they work!&lt;/p&gt;
&lt;p&gt;Yes, ladies and gentlemen, I can now actually use my system even when PulseAudio takes a proverbial dump on my desktop.&lt;/p&gt;
&lt;p&gt;I've submitted my patches upstream:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://bugzilla.gnome.org/show_bug.cgi?id=542391"&gt;bug #542391&lt;/a&gt;: libesd should not block if the daemon dies/hangs/whatever&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bugzilla.gnome.org/show_bug.cgi?id=542296"&gt;bug #542296&lt;/a&gt;: gnome_sound needs to handle pa hangs more gracefully&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unfortunately, these patches do not solve the root problem (pulseaudio suckage), but at least they allow me to get work done when pulseaudio craps out on me (which only happens every few hours if I'm lucky).&lt;/p&gt;
&lt;p&gt;Oh, and if you are on 32bit x86 openSUSE 11 systems, you can grab some packages I made up at &lt;a href="http://www.gnome.org/~fejj/pulseaudio/"&gt;http://www.gnome.org/~fejj/pulseaudio/&lt;/a&gt;. I've also uploaded the raw patches in case anyone wants to push them in their own distro packages.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6662857793651987299?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6662857793651987299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6662857793651987299' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6662857793651987299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6662857793651987299'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/pulseaudio-again.html' title='PulseAudio Again...'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6310291622884311805</id><published>2008-07-10T13:00:00.004-04:00</published><updated>2009-08-14T15:52:55.444-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Sex With Dead People Deemed Illegal</title><content type='html'>&lt;p&gt;Ok, so as I'm riding the MBTA in to work this morning reading my Metro newspaper, I come across the article "Court: Sex with corpses is illegal"&lt;/p&gt;
&lt;p&gt;Apparently until yesterday's ruling, sex with dead people was technically legal in the state of Wisconsin.&lt;/p&gt;
&lt;p&gt;The last sentence of the article was, in my humble opinion, the most hilarious sentence I've ever read in my life:&lt;/p&gt;
&lt;p&gt;&lt;i&gt;In yesterday's &lt;b&gt;5-2 decision&lt;/b&gt;, the high court said Wisconsin law makes sex acts with dead people illegal because &lt;b&gt;they are unable to give consent.&lt;/b&gt;&lt;/i&gt;
&lt;p&gt;Yes folks, it was a 5-2 ruling. So 2 people ruled in favor of allowing sex with dead people. W. T. F.&lt;/p&gt;
&lt;p&gt;But to make it even more hilarious, the &lt;i&gt;reason&lt;/i&gt; they decided it was not kosher was that the dead people could not give consent. L. O. L.&lt;/p&gt;
&lt;p&gt;We live in a funny world...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6310291622884311805?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6310291622884311805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6310291622884311805' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6310291622884311805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6310291622884311805'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/sex-with-dead-people-deemed-illegal.html' title='Sex With Dead People Deemed Illegal'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-990483167993301442</id><published>2008-07-09T20:39:00.011-04:00</published><updated>2009-08-14T15:54:45.739-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pulseaudio'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>More PulseAudio Problems</title><content type='html'>&lt;p&gt;I reinstalled PulseAudio to try and resolve the plethora of problems I've been having with it (that and openSUSE 11 doesn't actually ship th esound daemon anymore, so if I want full audio support I have no choice but to get the pulse-esound-compat package working short of forking the distro and maintaining my own set of esound/gnome/etc packages which is not my idea of fun).&lt;/p&gt;
&lt;p&gt;Unfortunately, this has resulted in countless hours of frustration. After having read and followed the instructions at &lt;a href="http://www.pulseaudio.org/wiki/PerfectSetup"&gt;http://www.pulseaudio.org/wiki/PerfectSetup&lt;/a&gt;, it turns out that is exactly how my system was already configured. So no help there.&lt;/p&gt;
&lt;p&gt;I don't know what the deal is, but I &lt;i&gt;constantly&lt;/i&gt; have problems with PulseAudio.&lt;/p&gt;
&lt;p&gt;For example, earlier today I was having an IM conversation with a friend in Pidgin and it locked up. I restarted Pidgin, but I wasn't getting audio events anymore. *shrug* Oh well.&lt;/p&gt;
&lt;p&gt;At some point later I navigated my firefox window over to youtube to link a friend to some video. No surprise here, I get no sound and in fact, the flash video pauses as soon as the sound was supposed to start (which is a few seconds into the video).&lt;/p&gt;
&lt;p&gt;At this point I close firefox and decide to reload it, thinking maybe that will solve it. Nope, I was wrong. Instead, firefox hangs before any windows pop up. Great.&lt;/p&gt;
&lt;p&gt;Since I got flamed last time I blogged about PulseAudio for issuing a `killall -9 pulseaudio` command (btw, pulseaudio appears to have a --kill command-line option), I figured I'd log out and log back in again instead... but this was not to be. Instead, my desktop locks up (presumably because of the logout.wav).&lt;/p&gt;
&lt;p&gt;Ok... so I Ctrl+Alt+F1 to the console, login as root, `init 3; init 5`. Since my system is configured to auto-login, when X came back up it tried to log me in. Instead, I get a hang.&lt;/p&gt;
&lt;p&gt;Good grief, I guess I have no option but to reboot so that's what I do.&lt;/p&gt;
&lt;p&gt;In the interest of saving other people from this catastrophe, I grabbed libgnome out of svn and wrote up the following patch to prevent it from hanging whenever PulseAudio decides to misbehave (which it seems quite prone to do).&lt;/p&gt;
&lt;pre style="Courier New 8pt"&gt;
Index: libgnome/gnome-sound.c
===================================================================
--- libgnome/gnome-sound.c (revision 3750)
+++ libgnome/gnome-sound.c (working copy)
@@ -30,8 +30,12 @@
 
 #include &amp;lt;stdio.h&gt;
 #include &amp;lt;stdlib.h&gt;
+#include &amp;lt;sys/types.h&gt;
 #include &amp;lt;unistd.h&gt;
+#include &amp;lt;fcntl.h&gt;
+#include &amp;lt;errno.h&gt;
 #include &amp;lt;time.h&gt;
+#include &amp;lt;poll.h&gt;
 
 #ifdef HAVE_ESD
 #include &amp;lt;esd.h&gt;
@@ -413,6 +417,55 @@
 }
 #endif
 
+#ifdef HAVE_ESD
+static int
+send_all (int fd, const char *buf, size_t buflen)
+{
+ struct pollfd pfd[1];
+ size_t nwritten = 0;
+ int flags, rv;
+ ssize_t n;
+ 
+ if ((flags = fcntl (fd, F_GETFL)) == -1)
+  return -1;
+ 
+ fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+ 
+ pfd[0].events = POLLOUT;
+ pfd[0].fd = fd;
+ 
+ do {
+  do {
+   pfd[0].revents = 0;
+   rv = poll (pfd, 1, 100);
+  } while (rv == -1 &amp;&amp; errno == EINTR);
+  
+  if (pfd[0].revents &amp; POLLOUT) {
+   /* socket is ready for writing */
+   do {
+    n = write (fd, buf + nwritten, buflen - nwritten);
+   } while (n == -1 &amp;&amp; errno == EINTR);
+   
+   if (n &gt; 0)
+    nwritten += n;
+  } else if (pfd[0].revents &amp; (POLLERR | POLLHUP)) {
+   /* we /just/ lost the esd connection */
+   esd_close (fd);
+   fd = -1;
+   break;
+  } else if (rv == -1 &amp;&amp; errno == EBADF) {
+   /* socket is bad */
+   fd = -1;
+   break;
+  }
+ } while (nwritten &amp;lt; buflen);
+ 
+ if (fd != -1 &amp;&amp; flags != -1)
+  fcntl (fd, F_SETFL, flags);
+ 
+ return fd;
+}
+#endif
 
 /**
  * gnome_sound_sample_load:
@@ -469,21 +522,23 @@
     * file, or event type, for later identification */
    s-&gt;id = esd_sample_cache (gnome_sound_connection, s-&gt;format, s-&gt;rate,
         size, (char *)sample_name);
-   write (gnome_sound_connection, s-&gt;data, size);
-   confirm = esd_confirm_sample_cache (gnome_sound_connection);
+   
+   gnome_sound_connection = send_all (gnome_sound_connection, (const char *) s-&gt;data, size);
+   if (gnome_sound_connection != -1)
+     confirm = esd_confirm_sample_cache (gnome_sound_connection);
+   
    if (s-&gt;id &amp;lt;= 0 || confirm != s-&gt;id)
      {
        g_warning ("error caching sample &amp;lt;%d&gt;!\n", s-&gt;id);
        s-&gt;id = 0;
      }
-   g_free (s-&gt;data);
-   s-&gt;data = NULL;
  }
     }
 
   sample_id = s-&gt;id;
 
-  g_free(s-&gt;data); g_free(s);
+  g_free(s-&gt;data);
+  g_free(s);
 
   return sample_id;
 #else
@@ -521,9 +576,12 @@
 
   sample = gnome_sound_sample_load (buf, filename);
 
-  esd_sample_play(gnome_sound_connection, sample);
-  fsync (gnome_sound_connection);
-  esd_sample_free(gnome_sound_connection, sample);
+  if (gnome_sound_connection != -1 &amp;&amp; sample &gt; 0)
+    {
+      esd_sample_play(gnome_sound_connection, sample);
+      fsync (gnome_sound_connection);
+      esd_sample_free(gnome_sound_connection, sample);
+    }
 #endif
 }
&lt;/pre&gt;
&lt;p&gt;This patch should hopefully help prevent the typical gnome apps from hanging when trying to play audio, but I don't really have any surefire way of testing that it actually works.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update 2008-07-10 10:42am&lt;/b&gt; I've now also written the following patch for libesd so that it doesn't hang for god knows how long when trying to open a connection to the sound server (in my case, pulse-esound-compat):&lt;/p&gt;
&lt;pre style="Courier New 8pt"&gt;
diff -up esound-0.2.38.orig/esdlib.c esound-0.2.38/esdlib.c
--- esound-0.2.38.orig/esdlib.c 2008-07-10 10:10:31.000000000 -0400
+++ esound-0.2.38/esdlib.c 2008-07-10 10:32:23.000000000 -0400
@@ -20,9 +20,11 @@
 #include &amp;lt;arpa/inet.h&gt;
 #include &amp;lt;errno.h&gt;
 #include &amp;lt;sys/wait.h&gt;
+#include &amp;lt;poll.h&gt;
 
 #include &amp;lt;sys/un.h&gt;
 
+
 #ifndef SUN_LEN
 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)-&gt;sun_path)  \
                      + strlen ((ptr)-&gt;sun_path))
@@ -408,6 +410,43 @@ int esd_resume( int esd )
     return ok;
 }
 
+static int
+connect_timeout (int sockfd, const struct sockaddr *serv_addr, size_t addrlen, int timeout)
+{
+ struct pollfd pfd[1];
+ int flags, rv;
+ 
+ if ((flags = fcntl (sockfd, F_GETFL)) == -1)
+  return -1;
+ 
+ fcntl (sockfd, F_SETFL, flags | O_NONBLOCK);
+ 
+ if (connect (sockfd, serv_addr, addrlen) == 0) {
+  fcntl (sockfd, F_SETFL, flags);
+  return 0;
+ }
+ 
+ if (errno != EINPROGRESS)
+  return -1;
+ 
+ pfd[0].fd = sockfd;
+ pfd[0].events = POLLIN | POLLOUT;
+ 
+ do {
+  pfd[0].revents = 0;
+  rv = poll (pfd, 1, timeout);
+ } while (rv == -1 &amp;&amp; errno == EINTR);
+ 
+ if (pfd[0].revents &amp; (POLLIN | POLLOUT)) {
+  /* success, we are now connected */
+  fcntl (sockfd, F_SETFL, flags);
+  return 0;
+ }
+ 
+ /* took too long / error connecting, either way: epic fail */
+ return -1;
+}
+
 /**
  * esd_connect_tcpip: make a TCPIP connection to ESD
  * @host: specifies hostname and port to connect to as "hostname:port"
@@ -512,7 +551,7 @@ esd_connect_tcpip(const char *host)
            goto error_out;
          }
 
-         if ( connect( socket_out, res-&gt;ai_addr, res-&gt;ai_addrlen ) != -1 ) 
+         if ( connect_timeout ( socket_out, res-&gt;ai_addr, res-&gt;ai_addrlen, 1000 ) != -1 ) 
            break;
 
          close ( socket_out );
@@ -596,9 +635,9 @@ esd_connect_tcpip(const char *host)
     socket_addr.sin_family = AF_INET;
     socket_addr.sin_port = htons( port );
   
-    if ( connect( socket_out,
-    (struct sockaddr *) &amp;socket_addr,
-    sizeof(struct sockaddr_in) ) &amp;lt; 0 )
+    if ( connect_timeout ( socket_out,
+      (struct sockaddr *) &amp;socket_addr,
+      sizeof(struct sockaddr_in), 1000 ) &amp;lt; 0 )
  goto error_out;
 
     }
@@ -650,8 +689,7 @@ esd_connect_unix(void)
     socket_unix.sun_family = AF_UNIX;
     strncpy(socket_unix.sun_path, ESD_UNIX_SOCKET_NAME, sizeof(socket_unix.sun_path));
   
-    if ( connect( socket_out,
-    (struct sockaddr *) &amp;socket_unix, SUN_LEN(&amp;socket_unix) ) &amp;lt; 0 )
+    if ( connect_timeout ( socket_out, (struct sockaddr *) &amp;socket_unix, SUN_LEN(&amp;socket_unix), 100 ) &amp;lt; 0 )
  goto error_out;
   
     return socket_out;
&lt;/pre&gt;
&lt;p&gt;Hopefully after these 2 patches get applied, my system at least won't become unusably hung when pulseaudio decides to crap out on me, but these patches doesn't solve the root of the problem :(&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-990483167993301442?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/990483167993301442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=990483167993301442' title='42 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/990483167993301442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/990483167993301442'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/more-pulseaudio-problems.html' title='More PulseAudio Problems'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>42</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3384957652497191611</id><published>2008-07-07T12:46:00.004-04:00</published><updated>2009-08-14T15:57:08.373-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>4th of July Fireworks from VMWare Office</title><content type='html'>&lt;p&gt;I watched the 4th of July fireworks from the 11th Floor offices of VMWare in Cambridge this year with some friends.&lt;/p&gt;
&lt;br&gt;
&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2646676540/" title="photo sharing"&gt;&lt;img src="http://farm4.static.flickr.com/3270/2646676540_ff08646840.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2646676540/"&gt;dscn0265.jpg&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/27477131@N07/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;
&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2646652004/" title="photo sharing"&gt;&lt;img src="http://farm4.static.flickr.com/3046/2646652004_931b33f67b.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2646652004/"&gt;dscn0343.jpg&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/27477131@N07/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;
&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2646653420/" title="photo sharing"&gt;&lt;img src="http://farm4.static.flickr.com/3152/2646653420_1496721aaa.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2646653420/"&gt;dscn0349.jpg&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/27477131@N07/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;
&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2645835237/" title="photo sharing"&gt;&lt;img src="http://farm4.static.flickr.com/3190/2645835237_b2441442fb.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2645835237/"&gt;dscn0400.jpg&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/27477131@N07/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;
&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2645835471/" title="photo sharing"&gt;&lt;img src="http://farm4.static.flickr.com/3137/2645835471_941c09081d.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2645835471/"&gt;dscn0401.jpg&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/27477131@N07/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; I should note that these photos were made possible thanks to Alan McGovern's 256 MB CF card he mailed me last week. So thanks, Alan! ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3384957652497191611?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3384957652497191611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3384957652497191611' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3384957652497191611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3384957652497191611'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/07/4th-of-july-fireworks-from-vmware.html' title='4th of July Fireworks from VMWare Office'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3270/2646676540_ff08646840_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6331822742424257285</id><published>2008-06-25T16:21:00.007-04:00</published><updated>2008-06-26T14:08:07.356-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Ohloh Stats</title><content type='html'>&lt;p&gt;So, I was told this morning that I'm on Ohloh.net's top 15 "Most Experienced C Programmers" list.&lt;br /&gt;&lt;p&gt;Sure enough, there I am:&lt;br /&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CrWGagj8HJU/SGKqvS0IMYI/AAAAAAAAADg/i1OUMbFpbB0/s1600-h/top15.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_CrWGagj8HJU/SGKqvS0IMYI/AAAAAAAAADg/i1OUMbFpbB0/s400/top15.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5215919047929508226" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;Updated:&lt;/b&gt; Turns out, after I had consolidated my accounts, I'm now #9 on the list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6331822742424257285?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6331822742424257285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6331822742424257285' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6331822742424257285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6331822742424257285'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/ohloh-stats.html' title='Ohloh Stats'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CrWGagj8HJU/SGKqvS0IMYI/AAAAAAAAADg/i1OUMbFpbB0/s72-c/top15.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6001703431671753025</id><published>2008-06-25T08:54:00.010-04:00</published><updated>2009-05-27T10:30:45.511-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pulseaudio'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='rants'/><title type='text'>PulseAudio: A Solution In Search of a Problem</title><content type='html'>&lt;p&gt;I upgraded the Linux OS on my laptop yesterday so that I had a more up-to-date GNOME installation such that I could actually build Evolution from SVN and hack it a bit to solve some annoyances I've been having. However, this is for another blog post.
&lt;p&gt;So... PulseAudio. W. T. F.
&lt;p&gt;All day yesterday I'd been wondering why my sound volume was so low even though I had cranked it all the way up to 100%. Since I was mostly focused getting work done yesterday, I didn't spend any time investigating until last night when I was forced to do so.
&lt;p&gt;I don't remember the exact order of things, but I did watch an episode of Harsh Realm in Xine while also IM'ing some friends in Pidgin, but the sound was so low I could barely hear anything. So a friend on IRC suggested I kill pulseaudio and restart it as this supposedly would help fix the "wonkyness" (evidently I'm not the only one with PulseAudio problems).
&lt;p&gt;This worked for a while, long enough to play the DVD iirc, but afterward I had no sound. So I thought "well, I guess this is just more PulseAudio 'wonkyness', so let me kill pulseaudio again". This time when I killed it, my sound card got flooded with every audio event that had happened over the hour or so I was running Xine. &lt;i&gt;Yay.&lt;/i&gt; (that was a sarcastic yay in case you couldn't tell)
&lt;p&gt;Audio worked again for a bit. At one point, a friend IM's me a link so I clicked it and no browser started up (which seemed a bit odd). Tried it again, still nothing. So I figured "ok, I'll just launch firefox from my gnome-terminal and see if that prints any errors". No errors, but it did just hang. &lt;i&gt;Oh goodie&lt;/i&gt;. Ctrl-C'd and killed pulseaudio again. At this point my friend IM'd me again which made Pidgin completely lock up:
&lt;pre&gt;
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
26422 fejj      20   0 3054m 1.3g  27m D  198 33.2  18:55.68 pidgin
&lt;/pre&gt;
&lt;p&gt;So the issues of memory usage are perfect for another rant blog post, but the point is that pidgin is completely locked. I can't even kill -9 it (I tried multiple times).
&lt;p&gt;I had to Ctrl+Alt+F1, login as root, and `init 3`
&lt;p&gt;At this point I was so frustrated that I uninstalled each and every package with pulseaudio in the name before going back to X.
&lt;p&gt;Low and behold, after that my audio works flawlessly (well, the Pidgin IM audio events make some crackling which I don't recall happening before I reinstalled, but I can live with it - especially since other audio seems crisp).
&lt;p&gt;So yea... the stuff that the &lt;a href="http://linuxhaters.blogspot.com/"&gt;Linux Hater&lt;/a&gt; says is all true. He even complained about audio under Linux a while back (couldn't remember which entry it was with a quick look over the entry names).
&lt;p&gt;The point of this story is that PulseAudio appears to be a solution in search of a problem (quite common in the land of Linux afaict).
&lt;p&gt;As I was bitching about this to a hacker friend of mine, he asked me "isn't PulseAudio for sound mixing or something? So multiple programs can all play audio at the same time?".
&lt;p&gt;Nope, because ALSA seemed to do mixing just fine for me in the past.
&lt;p&gt;A quick Google search for PulseAudio reveals that it is supposed to allow fancy stuff like redirecting sound to another host machine for playing.
&lt;p&gt;...just as I suspected: a solution in search of a problem.
&lt;p&gt;Seriously though, who the hell needs that feature on their desktop/laptop machines? No one, that's who. The only people who might need that are thin clients - so why install it by default? Why not just have the sysadmins for those thin-client networks set this up?
&lt;p&gt;PulseAudio is a clusterfuck for basic desktop audio needs afaict.
&lt;p&gt;&lt;i&gt;Sigh.&lt;/i&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Apparently I offended the PulseAudio developer with my "it's a solution in search of a problem" statement. For that, I apologize. A number of people have explained what exactly it is supposed to be solving. Unfortunately, none of the problems it is solving seem to be problems I need solved (maybe my sound cards in all my machines have hardware mixing support? I don't know. Or maybe dmix is plenty good enough for me).
&lt;p&gt;However, I still get the feeling that PA is not quite ready for wide desktop adoption because people on other distros are having some of the same problems I had and this is not good.
&lt;p&gt;I'd expect a similar rant from people if Evolution's current IMAP provider was replaced with my IMAP4 provider. As nice as my IMAP4 provider replacement is for my usage, there are no doubt new problems that it might currently have over the old implementation that would break things for some people. (Hence why I have not pushed for it to replace the old IMAP provider until I'm sure it is ready.)
&lt;p&gt;Also, this was tagged as a rant. I had every right to be frustrated because things weren't working like they have worked Just Fine(tm) for me for years. I've had to put up with far worse &lt;i&gt;personal&lt;/i&gt; attacks on myself and software I've been involved with over the years than anything I said on this blog (and lets face it, this was not a personal attack aimed at the PA devs - it was just me venting my frustration with a piece of software), so I think some people took this post way too personally.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6001703431671753025?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6001703431671753025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6001703431671753025' title='60 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6001703431671753025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6001703431671753025'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/pulseaudio-solution-in-search-of.html' title='PulseAudio: A Solution In Search of a Problem'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>60</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7627338854618322863</id><published>2008-06-24T07:54:00.002-04:00</published><updated>2009-08-14T15:58:17.531-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Novell SLED 10 on Wind Netbooks</title><content type='html'>&lt;p&gt;This is some pretty exciting news:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://practical-tech.com/infrastructure/novell-enters-the-umpc-linux-market/"&gt;http://practical-tech.com/infrastructure/novell-enters-the-umpc-linux-market/&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7627338854618322863?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7627338854618322863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7627338854618322863' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7627338854618322863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7627338854618322863'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/novell-sled-10-on-wind-netbooks.html' title='Novell SLED 10 on Wind Netbooks'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3687332594231924020</id><published>2008-06-20T22:55:00.001-04:00</published><updated>2008-06-20T22:55:01.102-04:00</updated><title type='text'>It's a Beautiful Evening...</title><content type='html'>&lt;div style="text-align: left; padding: 3px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2595969419/" title="photo sharing"&gt;&lt;img src="http://farm4.static.flickr.com/3079/2595969419_831c4206a9.jpg" style="border: solid 2px #000000;" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: 0.8em; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/27477131@N07/2595969419/"&gt;A Rainbow Over the Church&lt;/a&gt;, originally uploaded by &lt;a href="http://www.flickr.com/people/27477131@N07/"&gt;jstedfast&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;p&gt;Looked up just after a thunderstorm tonight and caught this rainbow - just had to take a picture of it ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3687332594231924020?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3687332594231924020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3687332594231924020' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3687332594231924020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3687332594231924020'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/it-beautiful-evening.html' title='It&amp;#39;s a Beautiful Evening...'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3079/2595969419_831c4206a9_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5584529038998540257</id><published>2008-06-14T16:12:00.010-04:00</published><updated>2008-06-16T10:41:37.834-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Calculating the Nearest Power of 2</title><content type='html'>&lt;p&gt;The typical implementation for finding the nearest power of 2 for a given value is as follows:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
static uint32_t
nearest_pow (uint32_t num)
{
    uint32_t n = 1;

    while (n &lt; num)
        n &lt;&lt;= 1;

    return n;
}
&lt;/pre&gt;
&lt;p&gt;This implementation's performance, unfortunately, suffers as the value of &lt;i&gt;num&lt;/i&gt; increases. Luckily there is another approach that takes a constant time no matter how large the value:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
static uint32_t
nearest_pow (uint32_t num)
{
    uint32_t n = num &gt; 0 ? num - 1 : 0;

    n |= n &gt;&gt; 1;
    n |= n &gt;&gt; 2;
    n |= n &gt;&gt; 4;
    n |= n &gt;&gt; 8;
    n |= n &gt;&gt; 16;
    n++;

    return n;
}
&lt;/pre&gt;
&lt;p&gt;A simple performance test might be:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
int main (int argc, char **argv)
{
    uint32_t i, n = 0;

    for (i = 0; i &lt; INT_MAX / 10; i++)
        n += nearest_pow (i);

    return n &gt; 0 ? 1 : 0;
}
&lt;/pre&gt;
&lt;p&gt;The run-time difference between the two implementations on my AMD Athlon (/proc/cpuinfo reports AMD Athlon(TM) XP 3200+ @ 2200.141 MHz) is impressive. For performance testing, I compiled with &lt;i&gt;gcc -O2&lt;/i&gt; which I figure is the typical default for most packaged software on Linux distributions.
&lt;p&gt;The brain-dead approach has the following results:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
[fejj@serenity cvs]$ time ./pow

real 0m12.034s
user 0m11.809s
sys 0m0.032s
&lt;/pre&gt;
&lt;p&gt;The bitwise implementation is insanely fast:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
[fejj@serenity cvs]$ time ./pow2

real 0m1.361s
user 0m1.304s
sys 0m0.008s
&lt;/pre&gt;
&lt;p&gt;Now... to be fair, the if you are using small values for &lt;i&gt;num&lt;/i&gt;, then it's possible that the brain-dead approach might be faster. Let's try the same main() for-loop again, but this time let's request nearest_pow() with a value of &lt;i&gt;1&lt;/i&gt; each time. Since it is likely that the results will be far too fast to really compare, let's also bump up the number of iterations to &lt;i&gt;UINT_MAX&lt;/i&gt;.
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
[fejj@serenity cvs]$ time ./pow

real 0m0.003s
user 0m0.000s
sys 0m0.004s
[fejj@serenity cvs]$ time ./pow2

real 0m0.002s
user 0m0.000s
sys 0m0.000s
&lt;/pre&gt;
&lt;p&gt;Unfortunately, both are still far too fast to really compare performance. Let's try bumping up the value of &lt;i&gt;num&lt;/i&gt; to see if we can find the point at which the while-loop approach starts to fall behind the bitwise approach. To start, let's try passing the value of &lt;i&gt;2&lt;/i&gt; as the &lt;i&gt;num&lt;/i&gt; argument:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
[fejj@serenity cvs]$ time ./pow

real 0m0.002s
user 0m0.000s
sys 0m0.004s
[fejj@serenity cvs]$ time ./pow2

real 0m0.002s
user 0m0.000s
sys 0m0.000s
&lt;/pre&gt;
&lt;p&gt;It &lt;i&gt;looks&lt;/i&gt; like the bitwise approach may be faster than the while-loop approach for the value of 2, but it's a bit hard to tell for sure with only &lt;i&gt;UINT_MAX&lt;/i&gt; loops. We'd have to switch to using a 64bit &lt;i&gt;i&lt;/i&gt; to know for sure and I'm not sure it's that important. Let's try &lt;i&gt;3&lt;/i&gt; and see what we get:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
[fejj@serenity cvs]$ time ./pow

real 0m6.053s
user 0m5.968s
sys 0m0.004s
[fejj@serenity cvs]$ time ./pow2

real 0m0.003s
user 0m0.000s
sys 0m0.004s
&lt;/pre&gt;
&lt;p&gt;Well, hot diggity... I think we have ourselves a winner. This suggests that for all values of &lt;i&gt;num&lt;/i&gt; larger than 2, the performance of the while-loop approach will be outmatched by the bitwise approach and that for values less-than-or-equal to 2, the performance is nearly identical.
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Thanks to the anonymous commenter that noticed that my original &lt;i&gt;main()&lt;/i&gt; program was allowing the compiler to optimize out the call to nearest_pow() in the bitwise implementation. As suggested, I updated the for-loop to accumulate the output and then used it after the loop to avoid this problem. It only seemed to change the results for the bitwise implementation in the first test, however (before the change, it reported 0.002s). Still, on my machine it is approx. 10x faster for the first test case and seems to lose no performance even in the optimal conditions for the while-loop implementation.
&lt;p&gt;&lt;b&gt;Update2:&lt;/b&gt; I was just pointed to the &lt;a href="http://lxr.linux.no/linux+v2.6.25/include/asm-x86/bitops_32.h#L134"&gt;Linux kernel's &lt;i&gt;fls()&lt;/i&gt;&lt;/a&gt; implementation for x86. Here is a new implementation using inline assembler for x86:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
static uint32_t
nearest_pow (uint32_t num)
{
    int bit;

    __asm__("bsrl %1,%0\n\t"
            "jnz 1f\n\t"
            "movl $-1,%0\n"
            "1:" : "=r" (bit) : "rm" (num));

    return (1 &lt;&lt; (bit + 1));
}
&lt;/pre&gt;
&lt;p&gt;The results for the original &lt;i&gt;INT_MAX / 10&lt;/i&gt; iterations using &lt;i&gt;i&lt;/i&gt; as the &lt;i&gt;num&lt;/i&gt; argument yields the following results:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
[fejj@serenity cvs]$ time ./pow3

real 0m1.335s
user 0m1.296s
sys 0m0.004s
&lt;/pre&gt;
&lt;p&gt;The results seem negligibly faster than the C bitwise implementation and obviously less portable :(
&lt;p&gt;&lt;b&gt;Update3:&lt;/b&gt; A friend of mine, Stephane Delcroix, has just pointed me at a solution to this problem that he came up the other day:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
static uint32_t
nearest_pow (uint32_t num)
{
    uint32_t j, k;
    (j = num &amp; 0xFFFF0000) || (j = num);
    (k = j &amp; 0xFF00FF00) || (k = j);
    (j = k &amp; 0xF0F0F0F0) || (j = k);
    (k = j &amp; 0xCCCCCCCC) || (k = j);
    (j = k &amp; 0xAAAAAAAA) || (j = k);
    return j &lt;&lt; 1;
}
&lt;/pre&gt;
&lt;p&gt;The results of this implementation are as follows:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
[fejj@serenity cvs]$ time ./pow4

real 0m1.249s
user 0m1.204s
sys 0m0.004s
&lt;/pre&gt;
&lt;p&gt;This is actually &lt;i&gt;faster&lt;/i&gt; than both the bitwise and the assembler implementations above!
&lt;p&gt;There are two things to be aware of, though:
&lt;ul&gt;
&lt;li&gt;When num is 0, the value of 0 is returned (which may not be desirable depending on what you are doing with it)&lt;/li&gt;
&lt;li&gt;If &lt;i&gt;num&lt;/i&gt; is a power of 2, then instead of returning &lt;i&gt;num&lt;/i&gt;, this implementation will return the next higher power of 2&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5584529038998540257?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5584529038998540257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5584529038998540257' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5584529038998540257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5584529038998540257'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/calculating-nearest-power-of-2.html' title='Calculating the Nearest Power of 2'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4225765747433600610</id><published>2008-06-13T20:08:00.004-04:00</published><updated>2009-08-14T15:59:55.392-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Linux Haters</title><content type='html'>&lt;p&gt;Okay, I have to join in and say that I, too, have been enjoying &lt;a href="http://linuxhaters.blogspot.com/"&gt;Linux Hater's Blog&lt;/a&gt; these past few days.&lt;/p&gt;
&lt;p&gt;He makes a lot of good points and I like his humor ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4225765747433600610?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4225765747433600610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4225765747433600610' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4225765747433600610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4225765747433600610'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/linux-haters.html' title='Linux Haters'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3721960420607258675</id><published>2008-06-07T12:18:00.006-04:00</published><updated>2008-06-08T14:09:19.974-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>GMime 2.3.2</title><content type='html'>&lt;p&gt;Just released GMime 2.3.2 last night which took some comments about the &lt;i&gt;GMimeHeaderIter&lt;/i&gt; API into consideration (like allowing iters to be on the stack).
&lt;p&gt;It also now has support for multipart/encrypted PGP/MIME parts that have been both signed and encrypted in a single pass (support for this exists for both encrypting and decrypting).
&lt;p&gt;Many more .NET API improvements as well.
&lt;p&gt;Check it out!
&lt;p&gt;&lt;b&gt;Updated:&lt;/b&gt; Just released 2.3.3 after a weekend of hacking.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3721960420607258675?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3721960420607258675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3721960420607258675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3721960420607258675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3721960420607258675'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/gmime-232.html' title='GMime 2.3.2'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4815412173962703426</id><published>2008-06-04T19:40:00.005-04:00</published><updated>2009-08-14T16:00:51.032-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Netscape Plugin Tips &amp; Tricks</title><content type='html'>&lt;p&gt;If your Firefox plugin is scriptable, you should probably be validating the NPVariant arguments that you are passed in your &lt;i&gt;invoke()&lt;/i&gt; callback. Unfortunately, this gets tedious and error-prone if you allow arguments to your methods to be of more than a single type (e.g. you accept a date as either a string or integer) or if you have optional arguments.&lt;/p&gt;
&lt;p&gt;As I was debugging a crash in Moonlight, I discovered that we weren't properly checking argument-types properly in all cases (this particular bug was caused because the javascript had passed a bad argument to one of our methods which accepted either a string or null). To protect against this in a more robust way, I came up with the following helper functions:&lt;/p&gt;
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
typedef enum {
    MethodArgTypeNone   = (0),
    MethodArgTypeVoid   = (1 &amp;lt;&amp;lt; NPVariantType_Void),
    MethodArgTypeNull   = (1 &amp;lt;&amp;lt; NPVariantType_Null),
    MethodArgTypeBool   = (1 &amp;lt;&amp;lt; NPVariantType_Bool),
    MethodArgTypeInt32  = (1 &amp;lt;&amp;lt; NPVariantType_Int32),
    MethodArgTypeDouble = (1 &amp;lt;&amp;lt; NPVariantType_Double),
    MethodArgTypeString = (1 &amp;lt;&amp;lt; NPVariantType_String),
    MethodArgTypeObject = (1 &amp;lt;&amp;lt; NPVariantType_Object),
    MethodArgTypeAny    = (0xff)
} MethodArgType;

static MethodArgType
decode_arg_ctype (char c)
{
    switch (c) {
    case 'v': return MethodArgTypeVoid;
    case 'n': return MethodArgTypeNull;
    case 'b': return MethodArgTypeBool;
    case 'i': return MethodArgTypeInt32;
    case 'd': return MethodArgTypeDouble;
    case 's': return MethodArgTypeString;
    case 'o': return MethodArgTypeObject;
    case '*': return MethodArgTypeAny;
    default:
        return MethodArgTypeNone;
    }
}

static MethodArgType
decode_arg_type (const char **in)
{
    MethodArgType type = MethodArgTypeNone;
    register const char *inptr = *in;
    
    if (*inptr == '(') {
        inptr++;
        while (*inptr &amp;&amp; *inptr != ')') {
            type |= decode_arg_ctype (*inptr);
            inptr++;
        }
    } else {
        type = decode_arg_ctype (*inptr);
    }
    
    inptr++;
    *in = inptr;
    
    return type;
}

/**
 * check_arg_list:
 * @arglist: a string representing an arg-list token (see grammar below)
 * @args: NPVariant argument count
 * @argv: NPVariant argument vector
 *
 * Checks that the NPVariant arguments satisfy the argument count and
 * types expected (provided via @typestr).
 *
 * The @typestr argument should follow the following syntax:
 *
 * simple-arg-type ::= "v" / "n" / "b" / "i" / "d" / "s" / "o" / "*"
 *                     ; each char represents one of the following
 *                     ; NPVariant types: Void, Null, Bool, Int32,
 *                     ; Double, String, Object and wildcard
 *
 * arg-type        ::= simple-arg-type / "(" 1*(simple-arg-type) ")"
 *
 * optional-args   ::= "[" *(arg-type) "]"
 *
 * arg-list        ::= *(arg-type) (optional-args)
 *
 *
 * Returns: %true if @argv matches the arg-list criteria specified in
 * @arglist or %false otherwise.
 **/
static bool
check_arg_list (const char *arglist, uint32_t argc, const NPVariant *argv)
{
    const char *inptr = arglist;
    MethodArgType mask;
    uint32_t i = 0;
    
    /* check all of the required arguments */
    while (*inptr &amp;&amp; *inptr != '[' &amp;&amp; i &amp;lt; argc) {
        mask = decode_arg_type (&amp;inptr);
        if (!(mask &amp; (1 &amp;lt;&amp;lt; argv[i].type))) {
            /* argv[i] does not match any of the expected types */
            return false;
        }
        
        i++;
    }
    
    if (*inptr &amp;&amp; *inptr != '[' &amp;&amp; i &amp;lt; argc) {
        /* we were not provided enough arguments */
        return false;
    }
    
    /* now check all of the optional arguments */
    inptr++;
    while (*inptr &amp;&amp; *inptr != ']' &amp;&amp; i &amp;lt; argc) {
        mask = decode_arg_type (&amp;inptr);
        if (!(mask &amp; (1 &amp;lt;&amp;lt; argv[i].type))) {
            // argv[i] does not match any of the expected types
            return false;
        }
        
        i++;
    }
    
    if (i &amp;lt; argc) {
        /* we were provided too many arguments */
        return false;
    }
    
    return true;
}
&lt;/pre&gt;
&lt;p&gt;An example usage might be &lt;i&gt;check_arg_list ("(so)i(nso)[bb]", argc, argv)&lt;/i&gt;. In this example, the first argument is expected to be either a string or object. The second argument would be an int32. The third argument would be null, a string, or an object. The 4th and 5th arguments are both of type bool if they are present.&lt;/p&gt;
&lt;p&gt;Since the NPVariant struct is a widely-used concept in C programming, you might find my hack useful for other projects as well.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4815412173962703426?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4815412173962703426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4815412173962703426' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4815412173962703426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4815412173962703426'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/netscape-plugin-tips-tricks.html' title='Netscape Plugin Tips &amp; Tricks'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-587268200245454549</id><published>2008-06-01T19:08:00.008-04:00</published><updated>2008-06-01T19:27:25.449-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>How To Survive Poisonous People</title><content type='html'>&lt;p&gt;This is an interesting Google Tech Talk about how to survive poisonous people in F/LOSS communities. I probably find it interesting at least in part because there are a couple of very loud poisonous people constantly attacking the GNOME and Mono projects (both of which I'm involved with), but it's a great talk to listen to anyway.
&lt;p&gt;&lt;embed id="VideoPlayback" style="width:400px;height:326px" allowFullScreen="true" flashvars="fs=true" src="http://video.google.com/googleplayer.swf?docid=-4216011961522818645&amp;hl=en" type="application/x-shockwave-flash"&gt; &lt;/embed&gt;
&lt;p&gt;I personally love the "Hostility" slide at around 29 minutes into the talk:
&lt;blockquote&gt;&lt;b&gt;Hostility&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;Insults the status quo&lt;/li&gt;
&lt;li&gt;Angrily demands help&lt;/li&gt;
&lt;li&gt;Attempts to blackmail&lt;/li&gt;
&lt;li&gt;Attempts to deliberately rile&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;Makes accusations of conspiracy (paranoia)&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt;&lt;p&gt;The bold/italic bit is a big hint-hint to the handful of people (not that they aren't also guilty of some of the others points) I'm referring to as the poisonous people around GNOME and Mono ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-587268200245454549?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/587268200245454549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=587268200245454549' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/587268200245454549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/587268200245454549'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/06/how-to-survive-poisonous-people.html' title='How To Survive Poisonous People'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7620488507526823891</id><published>2008-05-31T21:59:00.002-04:00</published><updated>2009-08-14T16:01:52.336-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Interesting link of the day</title><content type='html'>&lt;p&gt;&lt;a href="http://www.oreillynet.com/xml/blog/2008/05/what_ironruby_running_rails_re.html"&gt;What IronRuby Running Rails *REALLY* Means and Why Miguel de Icaza Deserves The Credit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Grats to Miguel ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7620488507526823891?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7620488507526823891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7620488507526823891' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7620488507526823891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7620488507526823891'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/05/interesting-link-of-day.html' title='Interesting link of the day'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-131885090285413557</id><published>2008-05-31T19:09:00.011-04:00</published><updated>2008-05-31T19:43:49.373-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>GMime 2.3.1</title><content type='html'>&lt;p&gt;I've been continuing to make improvements to the API over the past few days and have just made a 2.3.1 release.
&lt;p&gt;The main focus of this release has been a redesign of the header API which has been nagging at me for quite a while now. To fix it, I've done the following:
&lt;ul&gt;
&lt;li&gt;Renamed &lt;i&gt;GMimeHeader&lt;/i&gt; to &lt;i&gt;GMimeHeaderList&lt;/i&gt;, GMimeHeader felt more like it should be a single header (name/value pair).&lt;/li&gt;
&lt;li&gt;Introduced a new &lt;i&gt;GMimeHeader&lt;/i&gt;, altho it is internal only at the moment. I had originally planned on making it public (hence the rename of the old GMimeHeader struct).&lt;/li&gt;
&lt;li&gt;Introduced a &lt;i&gt;GMimeHeaderIter&lt;/i&gt; which can be used to iterate forward and backward over the headers, allowing you to change header values (but not names). It also allows removal of headers which makes it possible to remove any header you want, whereas the old API would only let you remove a header by name (which was a problem if there was more than 1 by the same name).&lt;/li&gt;
&lt;li&gt;Got rid of &lt;i&gt;g_mime_header_foreach()&lt;/i&gt; because that API sucked and has been replaced by the far more useful &lt;i&gt;GMimeHeaderIter&lt;/i&gt; API.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;i&gt;GMimeHeaderIter&lt;/i&gt; API looks like this:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
GMimeHeaderIter *g_mime_header_iter_copy (GMimeHeaderIter *iter);
void g_mime_header_iter_free (GMimeHeaderIter *iter);

bool g_mime_header_iter_equal (GMimeHeaderIter *iter1, GMimeHeaderIter *iter2);

bool g_mime_header_iter_is_valid (GMimeHeaderIter *iter);

bool g_mime_header_iter_first (GMimeHeaderIter *iter);
bool g_mime_header_iter_last (GMimeHeaderIter *iter);

bool g_mime_header_iter_next (GMimeHeaderIter *iter);
bool g_mime_header_iter_prev (GMimeHeaderIter *iter);

gint64 g_mime_header_iter_get_offset (GMimeHeaderIter *iter);
const char *g_mime_header_iter_get_name (GMimeHeaderIter *iter);
bool g_mime_header_iter_set_value (GMimeHeaderIter *iter, const char *value);
const char *g_mime_header_iter_get_value (GMimeHeaderIter *iter);

/* if the iter is valid, removes the current header and advances 
   to the next - returns TRUE on success or FALSE otherwise */
bool g_mime_header_iter_remove (GMimeHeaderIter *iter);
&lt;/pre&gt;
&lt;p&gt;Currently, the way to get a GMimeHeaderIter is to call &lt;i&gt;g_mime_header_list_get_iter()&lt;/i&gt; which returns a newly allocated iter. I'm not sure if this is the best API or not tho... some other thoughts I've had are:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
GMimeHeaderIter *g_mime_header_iter_new (void);
bool g_mime_header_list_get_iter (GMimeHeaderList *list, GMimeHeaderIter *iter);
&lt;/pre&gt;
&lt;p&gt;The second function would initialize &lt;i&gt;iter&lt;/i&gt; and return &lt;i&gt;TRUE&lt;/i&gt;, or, if &lt;i&gt;list&lt;/i&gt; was empty, it could return &lt;i&gt;FALSE&lt;/i&gt;.
&lt;p&gt;Another option would be to just have:
&lt;pre style="font-family: courier new; font-size: 85%"&gt;
GMimeHeaderIter *g_mime_header_iter_new (GMimeHeaderList *list);
&lt;/pre&gt;
&lt;p&gt;Then, if &lt;i&gt;list&lt;/i&gt; is empty you'd just get back an invalidated iter. If, later, headers were added to &lt;i&gt;list&lt;/i&gt;, then perhaps the iter could auto-magically become valid again. This would more-or-less work the same as the current code - except that the way to instantiate a GMimeHeaderIter is different.
&lt;p&gt;To be honest, now that I've written these 2 ideas down, I think I prefer the first idea.
&lt;p&gt;So... iterators. Since you can have multiple iterators for the same GMimeHeaderList, it is important to invalidate them on at least two occasions:
&lt;ul&gt;
&lt;li&gt;when the GMimeHeaderList is destroyed&lt;/li&gt;
&lt;li&gt;when the header that an iter points to is removed; either by a call to &lt;i&gt;g_mime_header_list_remove()&lt;/i&gt; or via a call to &lt;i&gt;g_mime_header_iter_remove()&lt;/i&gt; on another iter instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You'll be pleased to note that only iters that reference a header that got removed are invalidated. This fact seems to be an argument in favor of my first idea above, as it would allow re-use of iters once they get invalidated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-131885090285413557?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/131885090285413557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=131885090285413557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/131885090285413557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/131885090285413557'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/05/gmime-231.html' title='GMime 2.3.1'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4454268289190566677</id><published>2008-05-29T09:17:00.003-04:00</published><updated>2009-08-14T16:03:28.466-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>GMime 2.3.0</title><content type='html'>&lt;p&gt;GMime 2.3.0 has been released which marks the first development release of GMime since 2002. A new age has begun.&lt;/p&gt;
&lt;p&gt;This new development release gets rid of &lt;i&gt;off_t&lt;/i&gt; from all public interfaces, replacing them with &lt;i&gt;gint64&lt;/i&gt; instead so that there is no API/ABI breakage when building it with Large File support. But more importantly (to me), it also fixes a number of the API inconsistencies/uglyness that I discovered while looking over the GMime-Sharp bindings.&lt;/p&gt;
&lt;p&gt;The GMime-Sharp bindings still have a long way to go to be beautiful, but they are becoming more of a priority as I am more interested in using GMime-Sharp myself. If you are a user of the GMime-Sharp bindings, I'd love for you to try out GMime 2.3.0 and give me some feedback and how to improve the API even more. I, myself, will continue to scrutinize the API and make adjustments as I go - in the end, I hope to have the most beautiful MIME .NET API ever created.&lt;/p&gt;
&lt;p&gt;At first, I was only going to fix GMime's public interfaces to use gint64 instead of off_t and save the rest of my changes for a "3.0" or at least a "2.6", but I decided that since I was breaking the ABI anyway - I might as well do some cleanup and I think developers worldwide will thank me after their initial pain of porting their software to the new API (for which I hope to write a script to help in their troubles).&lt;/p&gt;
&lt;p&gt;Largely these changes are renaming of functions, sometimes shuffling them to become methods on a base class, etc.&lt;/p&gt;
&lt;p&gt;I got rid of GMimePartEncodingType and created a GMimeContentEncoding enum instead, complete with a g_mime_content_encoding_to_string() and g_mime_content_encoding_from_string(). I also created a new state object called GMimeEncoding (may rename to GMimeEncoder?) which simplifies the base64/QuotedPrintable/UU encoder/decoder APIs a little in that it handles initializing the state variables for you as you encode or decode to any of those encodings.&lt;/p&gt;
&lt;p&gt;As I was updating code to use these new enums/structs, I was able to simplify GMimeFilterBasic to not need its own GMimeFilterBasicType struct - instead, you pass the encoding and a bool to encode vs decode to the new g_mime_filter_basic_new() constructor. This has helped simplify a lot of code inside GMime and I'm sure it will help simply everyone elses code as well, because there is no longer a need to map GMIME_PART_ENCODING_BASE64 to GMIME_FILTER_BASIC_TYPE_BASE64_ENC or GMIME_FILTER_BASIC_TYPE_BASE64_DEC.&lt;/p&gt;
&lt;p&gt;I've also fixed GMimeContentType and GMimeContentDisposition to notify their parent GMimeObject when they are changed so that the following C#ism becomes possible:&lt;/p&gt;
&lt;p&gt;part.ContentType.SetParameter ("name", "fubar.txt");&lt;/p&gt;
&lt;p&gt;Previously, you'd have to use the GMimeObject's Content-Type helper methods instead of using the Content-Type's methods directly, like so:&lt;/p&gt;
&lt;p&gt;part.SetContentTypeParameter ("name", "fubar.txt");&lt;/p&gt;
&lt;p&gt;There are quite a few other improvements like this that I've added to the GMime-Sharp API as well. Sure, they may be minor, but they make the API much more polished.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4454268289190566677?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4454268289190566677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4454268289190566677' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4454268289190566677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4454268289190566677'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/05/gmime-230.html' title='GMime 2.3.0'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-6307349896979255412</id><published>2008-05-28T11:25:00.004-04:00</published><updated>2008-05-28T11:33:36.219-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='life'/><title type='text'>A Moment of Zen</title><content type='html'>&lt;p&gt;And here it is, your Moment of Zen:
&lt;p&gt;&lt;i&gt;Those who assume the worst in other people, are by their very nature among the worst people.&lt;/i&gt;
&lt;p&gt;&lt;i&gt;Those who assume the best in other people, are by their very nature among the best people.&lt;/i&gt;
&lt;p&gt; -- Jeffrey Stedfast&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-6307349896979255412?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/6307349896979255412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=6307349896979255412' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6307349896979255412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/6307349896979255412'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/05/moment-of-zen.html' title='A Moment of Zen'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7924015203590954586</id><published>2008-05-17T16:28:00.021-04:00</published><updated>2009-08-14T16:07:48.267-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Debian Language Benchmarks - SumFile</title><content type='html'>&lt;p&gt;Since someone brought it up the other day on IRC, I figured I'd take a look at some of the Java vs C# benchmarks where Java was claimed to be faster than C#.
&lt;p&gt;Scrolling through the list, there were 3 tests where Java was supposedly more than 2x faster than C# on Mono.
&lt;p&gt;The &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcol&amp;lang=all"&gt;SumFile&lt;/a&gt; test looked fairly simple and I figured the bottleneck there might be related to something silly being done with StandardInput (Miguel &lt;a href="http://tirania.org/blog/archive/2007/Nov-13.html"&gt;replaced the Int.Parse() routines&lt;/a&gt; with my more optimal implementations a while back, so I figured that was probably ok).
&lt;p&gt;The first thing I tried to do was reproduce their findings, so I grabbed the &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcol&amp;lang=java&amp;id=2"&gt;Java&lt;/a&gt; and &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcol&amp;lang=csharp"&gt;C#&lt;/a&gt; sources from the Debian site and compiled them.
&lt;p&gt;Both programs read from StandardInput an integer value per line, so I wrote a simple program to generate some input for the test:
&lt;pre&gt;
#include &amp;lt;stdio.h&gt;
#include &amp;lt;stdlib.h&gt;

int main (int argc, char **argv)
{
    unsigned int max, i;
    int sum = 0;

    max = atoi (argv[1]);

    for (i = 0; i &amp;lt;= max; i++) {
        printf ("%u\n", i);
        sum += i;
    }

    fprintf (stderr, "master value: %d\n", sum);

    return 0;
}
&lt;/pre&gt;
&lt;p&gt;As you can see above, the program outputs the real sum of all the digits it is outputting to stderr so that we can compare the results of the C# and Java programs to make sure they are correct for 32bit signed integers.
&lt;p&gt;Then I compiled the Java and C# versions using the same compile options mentioned on the Debian Language Shootout pages for each language:
&lt;p&gt;javac -classpath '.' sumcol.java
&lt;p&gt;and
&lt;p&gt;gmcs sumcol.cs
&lt;p&gt;I then ran each program using the following commands (using the same java and mono command-line options):
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 5000000 | java -server -Xbatch sumcol
master value: 1647668640
2147483647

real    0m4.606s
user    0m5.264s
sys     0m0.276s
[fejj@moonlight benchmarks]$ time ./output 5000000 | mono sumcol.exe
master value: 1647668640
1647668640

real    0m1.415s
user    0m2.136s
sys     0m0.228s
&lt;/pre&gt;
&lt;p&gt;As you can see above, there's no way that Java is 2.3x faster than Mono... so I'm not sure where they are getting these results from. &lt;b&gt;Not only that, but Java is getting the wrong answer!&lt;/b&gt;
&lt;p&gt;My best guess is that Java does not allow integer wrapping, so I suppose that that is okay... but it's a bit odd.
&lt;p&gt;For comparison's sake, here's what I get with the c implementation of sumfile:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 5000000 | ./sumcol
master value: 1647668640
1647668640

real    0m1.043s
user    0m1.604s
sys     0m0.188s
&lt;/pre&gt;
&lt;p&gt;Thinking that Java might be taking a performance hit from the bounds checking, I changed my original number-generating program to always print '1' on each line:
&lt;pre&gt;
#include &amp;lt;stdio.h&gt;
#include &amp;lt;stdlib.h&gt;

int main (int argc, char **argv)
{
    unsigned int i, max;
    int sum = 0;

    max = atoi (argv[1]);

    for (i = 0; i &amp;lt; max; i++) {
        printf ("1\n");
        sum++;
    }

    fprintf (stderr, "master value: %d\n", sum);

    return 0;
}
&lt;/pre&gt;
&lt;p&gt;Running the C, Mono, and Java versions again, I get the following results:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 5000000 | ./sumcol
master value: 5000000
5000000

real    0m0.601s
user    0m0.828s
sys     0m0.032s
[fejj@moonlight benchmarks]$ time ./output 5000000 | mono sumcol.exe
master value: 5000000
5000000

real    0m0.774s
user    0m0.876s
sys     0m0.064s
[fejj@moonlight benchmarks]$ time ./output 5000000 | java -server -Xbatch sumcol
master value: 5000000
5000000

real    0m0.751s
user    0m0.824s
sys     0m0.096s
&lt;/pre&gt;
&lt;p&gt;Here we can see that Java is slightly faster than Mono when comparing the 'real' and 'user' times.
&lt;p&gt;I figured that in order to get a more accurate reading, I should re-run using a larger value, so...
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 21474836 | java sumcol
master value: 21474836
21474836

real    0m2.625s
user    0m3.236s
sys     0m0.304s
[fejj@moonlight benchmarks]$ time ./output 21474836 | mono sumcol.exe 
master value: 21474836
21474836

real    0m3.225s
user    0m3.712s
sys     0m0.272s
&lt;/pre&gt;
&lt;p&gt;Again, Java is faster according to 'real' and 'user' times.
&lt;p&gt;What have we learned?
&lt;p&gt;The Java program appears to be slightly faster if and only if we do not overflow the signed integer, otherwise Mono takes the prize.
&lt;p&gt;If we revert back to using the original program I wrote to generate input and re-run using our most recent 'max' value, we find:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 21474836 | java sumcol
master value: 370655678
2147483647

real    0m19.157s
user    0m22.757s
sys     0m0.568s
[fejj@moonlight benchmarks]$ time ./output 21474836 | mono sumcol.exe
master value: 370655678
370655678

real    0m6.004s
user    0m9.513s
sys     0m0.940s
&lt;/pre&gt;
&lt;p&gt;Here we see that Mono clearly outperforms Java, no matter how you slice it.
&lt;p&gt;Conclusion?
&lt;p&gt;You can't compare the performance of the Java and C# programs without first understanding the implications of the input provided to them.
&lt;p&gt;Had the Debian Language Shootout used a different input, the performance tests might have instead shown Java getting raped by Mono for this particular test. Basically, Java just got lucky that the inputs were in their favor.
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; Oops, I forgot to give specifics of my Mono/Java versions and the specs of my laptop:
&lt;p&gt;Mono: JIT compiler version 1.9 (/trunk/ r103228)
&lt;p&gt;java -version gives the following output:
&lt;p&gt;java version "1.6.0_06"&lt;br&gt;
Java(TM) SE Runtime Environment (build 1.6.0_06-b02)&lt;br&gt;
Java HotSpot(TM) Server VM (build 10.0-b22, mixed mode)&lt;br&gt;
&lt;p&gt;The hardware used was my Lenovo T61 Core2Duo @ 2.4GHz
&lt;p&gt;This was running on OpenSuSE 10.3 with the latest updates.
&lt;p&gt;&lt;b&gt;Update 2:&lt;/b&gt; I was pointed to &lt;a href="http://shootout.alioth.debian.org/download/sumcol-input.txt"&gt;http://shootout.alioth.debian.org/download/sumcol-input.txt&lt;/a&gt; to use as input for this SumFile test. Below I've pasted the results:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time java -server -Xbatch sumcol &amp;lt; ~/sumcol-input.txt 
500

real    0m0.137s
user    0m0.052s
sys     0m0.028s
[fejj@moonlight benchmarks]$ time mono sumcol.exe &amp;lt; ~/sumcol-input.txt 
500

real    0m0.078s
user    0m0.060s
sys     0m0.012s
&lt;/pre&gt;
&lt;p&gt;Sorry guys, but even with this input, Java is not 2x faster than Mono.
&lt;p&gt;&lt;b&gt;Update 3:&lt;/b&gt; Since the above comparisons were all done using the StreamTokenizer version of the Java implementation, I figured I should go back and get the run times of the &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcol&amp;lang=java&amp;id=0"&gt;original Java implementation&lt;/a&gt;.
&lt;p&gt;Using my original implementation of output.c, each line having a value 1 larger than the previous line, we get:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 5000000 | java -server -Xbatch sumcol
master value: 1647668640
1647668640

real    0m1.492s
user    0m2.272s
sys     0m0.168s
&lt;/pre&gt;
&lt;p&gt;Interesting note: this Java implementation does not get the wrong answer...
&lt;p&gt;The results for "1" on ever line gives the following results:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 5000000 | java -server -Xbatch sumcol
master value: 5000000
5000000

real    0m0.924s
user    0m0.984s
sys     0m0.176s
&lt;/pre&gt;
&lt;p&gt;Repeating the trial run that totally killed Java's performance with the Tokenizer implementation, we get:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 21474836 | java -server -Xbatch sumcol
master value: 370655678
370655678

real    0m6.564s
user    0m9.893s
sys     0m0.688s
&lt;/pre&gt;
&lt;p&gt;And finally, the results for the sumcol-input.txt, we get:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time java -server -Xbatch sumcol &amp;lt; ~/sumcol-input.txt 
500

real    0m0.107s
user    0m0.056s
sys     0m0.032s
&lt;/pre&gt;
&lt;p&gt;Conclusion:
&lt;p&gt;The original Java implementation gets much better results than the StreamTokenizer implementation which was supposedly faster according to the Benchmarks table, however, it's still not 2x faster than the Mono implementation (in fact, this version of the Java implementation is roughly on par with the C# implementation).
&lt;p&gt;&lt;b&gt;Update 4:&lt;/b&gt; One of the comments to this blog post requested I try the Java6 SumCol #3 program which includes its own buffering/tokenizer implementation.
&lt;p&gt;Since this program "cheats" a bit, I figured I'd pit it against my own implementation of equal craftyness ;-)
&lt;p&gt;You can find my C# implementation &lt;a href="http://www.gnome.org/~fejj/sumcol2.cs"&gt;here&lt;/a&gt;.
&lt;p&gt;The results are as follows:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time ./output 21474836 | mono sumcol2.exe
master value: 370655678
370655678

real    0m4.996s
user    0m4.904s
sys     0m0.676s
[fejj@moonlight benchmarks]$ time ./output 21474836 | java -server -Xbatch sumcol3
master value: 370655678
370655678

real    0m5.117s
user    0m5.748s
sys     0m1.088s
&lt;/pre&gt;
&lt;p&gt;Am I a crafty bugger or what? ;-)
&lt;p&gt;Running these implementations against sumcol-input.txt, I get the following results:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time mono sumcol2.exe &lt; ~/sumcol-input.txt 
500

real    0m0.076s
user    0m0.064s
sys     0m0.016s
[fejj@moonlight benchmarks]$ time java -server -Xbatch sumcol3 &lt; ~/sumcol-input.txt 
500

real    0m0.108s
user    0m0.064s
sys     0m0.040s
&lt;/pre&gt;
&lt;p&gt;Damn I'm good! ;-)
&lt;p&gt;&lt;b&gt;Update 5:&lt;/b&gt; It's been suggested that the -server and -Xbatch args might make Java slower, so I've redone the tests (this time using sumcol-input.txt repeated 100,000 times)
&lt;p&gt;Here are the results:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time java -server sumcol &lt; sumcol-input100000.txt 
50000000

real    0m19.025s
user    0m18.657s
sys     0m0.412s
[fejj@moonlight benchmarks]$ time java sumcol &lt; sumcol-input100000.txt 50000000

real    0m20.643s
user    0m20.269s
sys     0m0.364s
[fejj@moonlight benchmarks]$ time mono sumcol.exe &lt; sumcol-input100000.txt 
50000000

real    0m18.884s
user    0m18.245s
sys     0m0.604s
&lt;/pre&gt;
&lt;p&gt;In the case of Java, it looks like using the -server flag performs a little bit better on this particular test than without.
&lt;p&gt;Overall, the Java and Mono performance for this test are remarkably close.
&lt;p&gt;In the end, I think I can feel pretty confidant that Mono's performance on this test is acceptable and it's not worth wasting any more time on it for now.
&lt;p&gt;&lt;b&gt;Update 6:&lt;/b&gt; Okay, one last update to show that a fully managed C# implementation can outperform the fastest &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=sumcol&amp;lang=gcc&amp;id=3"&gt;C implementation&lt;/a&gt; submitted to the Debian Language Benchmarks:
&lt;pre&gt;
[fejj@moonlight benchmarks]$ time mono sumcol2.exe &lt; sumcol-input100000.txt 
50000000

real    0m2.906s
user    0m2.572s
sys     0m0.308s
[fejj@moonlight benchmarks]$ time ./sumcol &lt; sumcol-input100000.txt 
50000000

real    0m13.967s
user    0m13.277s
sys     0m0.668s
&lt;/pre&gt;
&lt;p&gt;Yes, ladies and gentlemen, that is C# wiping the floor with C.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7924015203590954586?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7924015203590954586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7924015203590954586' title='79 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7924015203590954586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7924015203590954586'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/05/debian-language-benchmarks-sumfile.html' title='Debian Language Benchmarks - SumFile'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>79</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2242048895043945677</id><published>2008-05-10T17:49:00.006-04:00</published><updated>2009-08-14T16:09:16.487-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><title type='text'>Wouldn't it be nice if...</title><content type='html'>&lt;p&gt;Over the past week, I've been spending some time hacking on Evolution again because of my frustration with the current IMAP backend. This got me to wondering... why hasn't anyone stepped up to the plate and rewritten Evolution's IMAP code yet?
&lt;p&gt;I think the reason can be summed up with the following 2 problems:
&lt;p&gt;1. IMAP is hard
&lt;p&gt;2. Coding something complicated like a multithreaded multiplexed IMAP client library in C is harder.
&lt;p&gt;That got me and Michael Hutchinson wondering... wouldn't it be nice if we could write Camel provider plugins in C# or in any other managed language that we might prefer?
&lt;p&gt;I think Camel, like Evolution itself, should allow developers to implement plugins in C# as well. I really think this might help lessen the burden of implementing new mail protocol backends for Camel/Evolution.
&lt;p&gt;On that note, I've created a new svn module called camel-imap4 which can be built against your installed evolution-data-server devel packages.
&lt;p&gt;Currently, however, it'll probably only work with e-d-s &gt;= 2.23.x because some things (and assumptions) in Camel have changed recently.
&lt;p&gt;One problem I'm having is that the symbol camel_folder_info_new() used to not exist in older versions of e-d-s, but recently that symbol was added and makes use of g_slice_alloc0(). The problem is that the way providers used to allocate CamelFolderInfo structures before was using g_new0() themselves. Why does this pose a problem? There's no guarantee that I'm aware of that you can mix and match g_malloc/g_slice_free or g_slice_alloc/g_free.
&lt;p&gt;This makes it difficult for me to implement a plugin that builds and works with my installed version of Evolution (2.12) and also work with Evolution svn (2.23). This is quite unfortunate :(
&lt;p&gt;While I'm at it, allow me to also propose some changes to the GChecksum API. Please, please, please make it so that we ned not allocate/free a GChecksum variable each time we need to checksum something?
&lt;p&gt;I propose the ability to do the following:
&lt;p&gt;GChecksum checksum;
&lt;p&gt;g_checksum_init (&amp;checksum, G_CHECKSUM_MD5);&lt;br&gt;
g_checksum_update (&amp;checksum, data, len);&lt;br&gt;
g_checksum_get_digest (&amp;checksum, digest, &amp;len);&lt;br&gt;
&lt;p&gt;Then I'd like to be able to either call g_checksum_init() on checksum &lt;i&gt;again&lt;/i&gt; or maybe have another function to clear state, maybe g_checksum_clear() which would allow me to once again use the same checksum variable for calculating the md5 of some other chunk of data.
&lt;p&gt;Camel generates md5sums for a lot of data, sometimes in loops. Having to alloc/free every iteration is inefficient and tedious.
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; It now builds and works with Evolution 2.12 (I haven't tested anything else). But the new and improved IMAP back-end for Evolution is now actually working. Whoohoo!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2242048895043945677?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2242048895043945677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2242048895043945677' title='43 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2242048895043945677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2242048895043945677'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/05/wouldnt-it-be-nice-if.html' title='Wouldn&apos;t it be nice if...'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>43</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-5647695931009015203</id><published>2008-04-21T22:42:00.004-04:00</published><updated>2009-08-14T16:10:03.293-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ooxml'/><title type='text'>Interesting...</title><content type='html'>&lt;p&gt;Marc Maurer makes &lt;a href="http://uwog.net/news/?p=10"&gt;an interesting observation&lt;/a&gt; about OOXML vs ODF. Aparently, not a single GSoC applicant proposed to improve upon the ODF implementation in AbiWord, while they had numerous applicants that wanted to work on OOXML support.&lt;/p&gt;
&lt;p&gt;I wonder what the ODF vs OOXML proposal stats are for some of the other free software office applications.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-5647695931009015203?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/5647695931009015203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=5647695931009015203' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5647695931009015203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/5647695931009015203'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/04/interesting.html' title='Interesting...'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2756391105255505362</id><published>2008-03-21T15:04:00.021-04:00</published><updated>2009-08-14T16:14:07.039-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>Moonlight Text Rendering</title><content type='html'>&lt;p&gt;For those who haven't been following Moonlight development, I'm the guy that has been implementing all the text layout and rendering.
&lt;p&gt;Let me start off by saying that text is hard. &lt;i&gt;Really&lt;/i&gt; hard. Especially layout.
&lt;p&gt;&lt;b&gt;Font Hinting&lt;/b&gt;
&lt;p&gt;The aspect of text rendering that I've been thinking a lot about lately is &lt;a href="http://en.wikipedia.org/wiki/Font_hinting"&gt;hinting&lt;/a&gt;. For an example of the difference that hinting makes with text rendering, see the following screenshot:
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_CrWGagj8HJU/R-QUbEe8kZI/AAAAAAAAADA/mnlE7YNvUH4/s1600-h/moonlight-vs-pango.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_CrWGagj8HJU/R-QUbEe8kZI/AAAAAAAAADA/mnlE7YNvUH4/s320/moonlight-vs-pango.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5180287926675476882" /&gt;&lt;/a&gt;
&lt;p&gt;In the screenshot above, I've posted side-by-side text renderings produced by both Moonlight and Pango (courtesy of Michael Dominic K.) for Arial, Verdana and Times New Roman fonts. You'll notice that especially at the smaller font sizes, Moonlight's text rendering gets a bit fuzzy and hard to read. On the contrary, Pango's rendering, using hinting, has improved readability over Moonlight.
&lt;p&gt;Why don't I just use hinting, you ask?
&lt;p&gt;The problem is that hinting changes the font metrics in such a way that as you scale to larger sizes, the metrics do not scale uniformly (you'll notice that as the font sizes increase, the width of the line gets uniformly wider using Moonlight, but not so with Pango). This causes a bit of a problem for Moonlight (and Silverlight) because:
&lt;ul&gt;
&lt;li&gt;with hinting enabled, scaling the font size in an animation would look jumpy&lt;/li&gt;
&lt;li&gt;this is made even worse when you consider line wrapping and how changing font metrics would mean that line wrapping would also change with the changing font size&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In most applications, the text in each UI element is unlikely to change size (unless the user manually changes the font settings), and so enabling the use of hinting has no adverse side effects. Silverlight (and thus Moonlight), however, are meant to do all sorts of animations which may apply matrix transforms (such as scaling) to any item in the canvas (even text!).
&lt;p&gt;Since scaling has to look smooth, it's hard to use hinting because of the way it changes the metrics.&lt;br /&gt;&lt;br /&gt;Hopefully I can find a way to improve rendering quality at the smaller sizes without getting the side effects I mentioned above, or at least have them be far less noticeable.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Line Breaking&lt;/b&gt;
&lt;p&gt;While not thinking about the render quality of the text, the bane of my existence has been implementing layout algorithms for the 3 different TextWrapping modes used in Silverlight (Wrap, NoWrap, and WrapWithOverflow).
&lt;p&gt;I've mostly been focusing on TextWrapping=Wrap lately as it's probably the hardest one to implement, especially if I want to emulate the Silverlight wrapping behavior (from what I can gather by reading the Pango source code, there are ambiguities in the &lt;a href="http://www.unicode.org/unicode/reports/tr14/#ConfAlgorithm"&gt;Unicode specification for line-breaking&lt;/a&gt;, so I've been having to familiarize myself with the rules for line-breaking lately).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Going Forward&lt;/b&gt;
&lt;p&gt;In the future, I hope to replace my text layout/rendering code with the use of Pango but in order for that to happen, Pango will need a few new features:
&lt;ul&gt;
&lt;li&gt;The ability to specify fonts outside of the configured font directories (e.g. a way to bypass FontConfig). From what I understand, this is already happening so I expect to be able to cross this off the list soon ;-)&lt;/li&gt;
&lt;li&gt;The ability to mark the beginning/end of a sub-run of text. Silverlight's &lt;i&gt;&amp;lt;TextBlock&amp;gt;&lt;/i&gt; element supports child &lt;i&gt;&amp;lt;Run&amp;gt;&lt;/i&gt; elements. This normally wouldn't be a big deal, but Silverlight uses the joint between two runs as a possible break opportunity. For example, &amp;lt;Run Text="abcdefg"/&amp;gt;&amp;lt;Run Text="hijklmn"/&amp;gt; might line-wrap differently than &amp;lt;Run Text="abcdefghijklmn"/&amp;gt; even though there are no spaces between the two runs. Currently, when rendering a string of text using Pango, you combine all runs into a single string to pass to a PangoLayout, so the layout engine doesn't have a way of knowing that a position mid-word should be treated as a break opportunity.&lt;/li&gt;
&lt;li&gt;Pango will need a way to specify alternative text wrapping modes (so that it would be possible to emulate Silverlight's TextWrapping behavior). Apparently Owen and Behdad have already discussed the desire to have this sort of feature, so I'm looking forward to working with them on designing a suitable API.&lt;/li&gt;
&lt;li&gt;A way to specify that font metrics should scale uniformly as the font size changes. &lt;b&gt;Update:&lt;/b&gt; Behdad has notified me that this feature is actively being worked on and that I can enable it via &lt;i&gt;CAIRO_HINT_METRICS_OFF&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;The last thing that I can think of at the moment that Pango will need is a way to reset the Foreground brush for each run and each time each of those runs line-breaks. For example, the following screenshot consists of a single TextBlock with two Run elements which share their parent's font and foreground brush properties. This means that the prepare_run() virtual method for the subclassed PangoRenderer will need to know the extents of the next sub-run of text to be rendered so that it can properly setup the custom foreground brush.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_CrWGagj8HJU/R-QnG0e8kaI/AAAAAAAAADI/5JxN26rlZuA/s1600-h/moonlight-brush-runs.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_CrWGagj8HJU/R-QnG0e8kaI/AAAAAAAAADI/5JxN26rlZuA/s320/moonlight-brush-runs.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5180308469504053666" /&gt;&lt;/a&gt;
&lt;p&gt;In the meantime, having to write my own layout/rendering engine for text has taught me a lot more about text and fonts than I ever wanted to know and I'm continuing to learn more every day.
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; With all of these custom changes that I'll need in order to move to Pango, I'm beginning to wonder if it's really worth it? The only thing that it &lt;i&gt;could&lt;/i&gt; get me is the Unicode line-breaking logic, but the thing is... if I have to implement my own pluggable TextWrapping modes, then wouldn't I still essentially be implementing my own line-breaking logic? This makes me very sad :(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2756391105255505362?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2756391105255505362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2756391105255505362' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2756391105255505362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2756391105255505362'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/03/moonlight-text-rendering.html' title='Moonlight Text Rendering'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_CrWGagj8HJU/R-QUbEe8kZI/AAAAAAAAADA/mnlE7YNvUH4/s72-c/moonlight-vs-pango.png' height='72' width='72'/><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4092782828122773734</id><published>2008-02-26T08:17:00.013-05:00</published><updated>2009-08-14T16:15:23.169-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Lots of GNOME/Mono FUD Lately</title><content type='html'>&lt;p&gt;It would seem that lately there are a lot of FUD-spreading trolls crawling out of the woodwork trying to frighten people into thinking that GNOME somehow depends on Mono.

&lt;p&gt;Let's take a look at their most widely repeated claims:

&lt;p&gt;&lt;b&gt;GNOME depends on Mono&lt;/b&gt;

&lt;p&gt;This is simply untrue... to see for yourself, try removing Mono from your Linux system using yum, zypper, or apt (or whatever) and you will plainly see that it does not remove GNOME - it &lt;i&gt;may&lt;/i&gt; remove Tomboy, F-Spot, Banshee and/or Beagle (if you have any of them installed), but it will not remove any core components of your GNOME system.

&lt;p&gt;Now that we've proven that GNOME does not depend on Mono, let's move on to their next claim:

&lt;p&gt;&lt;b&gt;GNOME depends on libbeagle, a Mono program&lt;/b&gt;

&lt;p&gt;Again, false. GNOME's help browser has an optional dependency on a &lt;i&gt;C-library&lt;/i&gt; called libbeagle which can be used to make search queries via IPC (Inter-Process-Communication) to the Beagle daemon &lt;i&gt;if and only if&lt;/i&gt; Beagle is installed. I.E., Yelp does &lt;i&gt;not&lt;/i&gt; depend on Beagle, it is simply able to take advantage of Beagle if it is available. As far as I'm aware, there are plans to replace libbeagle with a more generic library able to communicate with either Beagle or Tracker via IPC, depending on which one the user has installed.

&lt;p&gt;&lt;b&gt;NDesk-DBus is replacing DBus in GNOME&lt;/b&gt;

&lt;p&gt;There was a big stink about this a while ago by a very angry person who didn't understand how libraries or software development in general works.

&lt;p&gt;GNOME continues to depend on the C-implementation of DBus (called libdbus) and that is unlikely to change unless DBus itself (the technology, not the C-library) gets replaced.

&lt;p&gt;NDesk-DBus, written by the famous Alp Toker, is a replacement for the current DBus-Sharp .NET &lt;i&gt;binding&lt;/i&gt; around libdbus, the C-implementation. The main difference between NDesk-DBus and DBus-Sharp is that DBus-Sharp wraps libdbus while NDesk-DBus is a fully managed implementation of the DBus wire protocol.

&lt;p&gt;GNOME not only does not, but it cannot, replace DBus with NDesk-DBus - any half-way competent programmer would know and understand why this is so. Native C programs cannot easily call into managed code.

&lt;p&gt;&lt;b&gt;Someday soon it will be practically impossible to write any app for GNOME without being forced to use MONO&lt;/b&gt;

&lt;p&gt;Considering that in order for this to happen, core GNOME libraries would have to be rewritten in a .NET language, this is unlikely to ever happen, never mind anytime soon.

&lt;p&gt;As you can plainly see, these types of claims are being made by people who do not understand the most basic concepts of software development.

&lt;p&gt;&lt;b&gt;GNOME is riddled with Mono applications&lt;/b&gt;

&lt;p&gt;If by "riddled" they mean "not", then yes. ;-)

&lt;p&gt;There is currently only one official GNOME application that uses Mono and that application is Tomboy. Tomboy, as useful a tool as it is, is not even arguably a core component of the GNOME desktop in that removing it will not somehow make your GNOME desktop useless.

&lt;p&gt;&lt;b&gt;Novell is forcing GNOME to include Mono&lt;/b&gt;

&lt;p&gt;Ask any core GNOME developer and he or she will tell you that this is absurd. To the best of my knowledge, Novell has not even once &lt;i&gt;requested&lt;/i&gt; that any of its Mono-based applications be accepted as core GNOME applications, never mind &lt;i&gt;forced&lt;/i&gt; one to be accepted. I should also note that Tomboy, the &lt;i&gt;only&lt;/i&gt; Mono application in GNOME currently, was not a Novell project at the time it as accepted for inclusion in GNOME.

&lt;p&gt;This post has been brought to you by the letters G and M and the number 2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4092782828122773734?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4092782828122773734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4092782828122773734' title='70 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4092782828122773734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4092782828122773734'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/02/lots-of-gnomemono-fud-lately.html' title='Lots of GNOME/Mono FUD Lately'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>70</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-1430453759849959622</id><published>2008-02-23T18:40:00.004-05:00</published><updated>2009-08-14T16:16:26.561-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monodevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='usability'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><title type='text'>Speaking of Hack Week Projects...</title><content type='html'>&lt;p&gt;I didn't really have any ideas for Hack Week this year, so I had started off working with Paolo and Zoltan on optimizing Mono's RegEx engine. Unfortunately 1 week wasn't enough to accomplish what I had hoped to accomplish - luckily, Paolo and Zoltan were able to improve Mono's RegEx performance significantly without the need for the hacks I had planned to implement (and in fact did some a terrific job, I'm not sure my ideas would have made much of a difference).

&lt;p&gt;That said, I'd like to jot down a few ideas I just had for the next Hack Week:
&lt;ul&gt;
&lt;li&gt;Implement an "Evolution Plugin" project type for MonoDevelop which would setup everything you need to start writing plugins for Evolution in C#. This would include things like templating the E-Plug xml files, pulling in appropriate Evolution# bindings and the like.&lt;/li&gt;
&lt;li&gt;Implement an Evolution Plugin in C# that would filter spam messages based on charset information. Most of the spam I get seems to use a russian or asian charset, so a filter like this would be extremely valuable to me.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My biggest interest is in templating out an Evolution Plugin project type for MonoDevelop because I'd really like to see more outside developers writing plugins for Evolution and I think that this would be a great way to lower the bar, so to speak.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-1430453759849959622?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/1430453759849959622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=1430453759849959622' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1430453759849959622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/1430453759849959622'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/02/speaking-of-hack-week-projects.html' title='Speaking of Hack Week Projects...'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-4523457213268012053</id><published>2008-02-06T19:41:00.001-05:00</published><updated>2009-08-14T16:18:16.210-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='laptop'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Optimizing GMime's UUEncoder</title><content type='html'>&lt;p&gt;This past weekend I was talking with Andreia about how &lt;a href="http://pan.rebelbase.com/"&gt;Pan&lt;/a&gt; is built on top of GMime and takes advantage of my awesomely speedy uuencode/uudecode routines which reminded me that I had done some performance comparisons of GMime's uuencode program vs. the one in the GNU sharutils package a number of years ago.
&lt;p&gt;I had compared GMime 1.90.0 (which was a pre-release of GMime 2.0) and GNU sharutils 4.2.0 and the results were pretty impressive... GMime's uuencoder was on the order of 3 times faster than the one in sharutils and produced exactly the same results.
&lt;p&gt;The uudecoder and the base64 encoder/decoder were all roughly on the order of 7 times faster than those in GNU sharutils, so all around GMime outperformed GNU sharutils by quite a bit.
&lt;p&gt;Anyways, re-reading my test results got me thinking that my uuencode routines could probably be optimized a bit more as they were lagging a bit behind the base64 encoder routine and there's really no reason it should be that far off.
&lt;p&gt;Well, tonight I finally got off my butt and decided to take a look and figure out why. Upon scrolling down to my uuencode_step() routine, I immediately saw why:
&lt;p&gt;Each loop would collect up to 3 bytes from the input and bit shift them into a 32bit 'saved' variable (which is a state variable used for incremental uuencoding an input stream). Then, if I had successfully extracted 3 bytes from the input, I would extract them out of 'saved' into 3 unsigned char variables. At this point I would then &lt;i&gt;encode&lt;/i&gt; them into a temporary output buffer. When this output buffer ('uubuf') grew to 60 bytes, I'd flush it to the real output buffer with a memcpy().
&lt;p&gt;All of this extra copying of data around adds up after a while and really begins to impact performance.
&lt;p&gt;Before making any changes, I timed how long it took the original version of my uuencode_step() function to encode linux-2.6.24.tar.gz on my system[1]. An average result over numerous runs was as follows:
&lt;pre&gt;
[fejj@localhost ~]$ time `gmime-uuencode linux-2.6.24.tar.gz linux-2.6.24.tar.gz &gt; /dev/null`
real    0m0.470s
user    0m0.412s
sys     0m0.052s
&lt;/pre&gt;
&lt;p&gt;After my rewrite, my new results were closer to:
&lt;pre&gt;
[fejj@localhost ~]$ time `gmime-uuencode linux-2.6.24.tar.gz linux-2.6.24.tar.gz &gt; /dev/null`
real    0m0.291s
user    0m0.252s
sys     0m0.024s
&lt;/pre&gt;
&lt;p&gt;For the sake of comparison, the &lt;i&gt;best&lt;/i&gt; time I could manage to get from GNU sharutils 4.6.2 was as follows:
&lt;pre&gt;
[fejj@localhost ~]$ time `uuencode linux-2.6.24.tar.gz linux-2.6.24.tar.gz &gt; /dev/null`
real    0m1.386s
user    0m1.276s
sys     0m0.092s
&lt;/pre&gt;
&lt;p&gt;The new implementation of uuencode_step() in gmime/gmime-utils.c has been committed to the gmime svn module on GNOME's subversion server, revision 1216 - this change should appear in the next release of GMime which will likely be 2.2.17.
&lt;small&gt;
&lt;p&gt;Notes:
&lt;p&gt;1. The system I tested this on was my Lenovo T61 laptop w/ a 7200 RPM harddrive running OpenSuSE 10.3 with various updates. The kernel was version 2.6.22.13-0.3-bigsmp.
&lt;p&gt;From /proc/cpuinfo:
&lt;p&gt;model name      : Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz&lt;br&gt;
cpu MHz         : 800.000
&lt;p&gt;(e.g. my cpu was scaled down at the time of testing)
&lt;p&gt;2. The GMime uuencode implementation uses a GMimeStreamFs for input as well as output. This stream class is a wrapper around the POSIX I/O system functions which unfortunately has a sub-optimal need to perform an lseek() before each read() or write() call in order to make sure that the underlying file descriptor is in the expected position. This is necessary because it is possible for multiple streams to re-use the same fd.
&lt;p&gt;I mention this because an obvious rebuttal to GMime's superior performance might be to suspect that GMime's uuencode implementation "cheated" by using an mmap()'d input buffer where the GNU sharutils implementation might not.
&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-4523457213268012053?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/4523457213268012053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=4523457213268012053' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4523457213268012053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/4523457213268012053'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/02/optimizing-gmimes-uuencoder.html' title='Optimizing GMime&apos;s UUEncoder'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2028903190607092156</id><published>2008-02-04T22:36:00.001-05:00</published><updated>2009-08-14T16:18:54.704-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Re: DBus OOM handling</title><content type='html'>&lt;p&gt;I didn't find a way to comment on &lt;a href="http://log.ometer.com/2008-02.html#4.2"&gt;Havoc's insights on OOM error handling&lt;/a&gt;, so I'm posting here.
&lt;p&gt;Havoc, thanks for your first hand experience on the topic! A 30-40% increase in lines of code is insane, but not far from what I expected. The fact that you discovered that most of your original OOM handling code was broken was also not a surprise (and I don't mean to suggest that your code is sub-par, but rather that it's not easy to get right unless you have test cases for each code path).
&lt;p&gt;I'll have to check out the code when my eyes are a bit less strained (to the point where they are beginning to tear up), I'm am now very interested!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2028903190607092156?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2028903190607092156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2028903190607092156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2028903190607092156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2028903190607092156'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/02/re-dbus-oom-handling.html' title='Re: DBus OOM handling'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3478188950153323423</id><published>2008-02-03T20:26:00.001-05:00</published><updated>2009-08-14T16:20:20.272-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Worse is Better in the form of Autosave</title><content type='html'>&lt;p&gt;There's recently been some talk about how GLib is poorly designed software because g_malloc() abort()s when the underlying malloc implementation returns NULL (suggesting an OOM condition) and therefor should never be used to write real-world applications because your calling code doesn't have a chance to do proper error checking (altho it was brought up that you can actually use g_try_malloc() and/or plug in your own malloc implementation underneath g_malloc() which could trivially notify the application that an OOM condition was met before returning to g_malloc()).
&lt;p&gt;While at first, this argument seems correct and you begin to think "oh my god, the sky is falling", it's important to actually stop and &lt;i&gt;think&lt;/i&gt; about the issue a bit first.
&lt;p&gt;GLib was originally a utility library written as part of the Gtk+ widget toolkit in order to make their lives easier. When designing a widget toolkit (Gtk+ in this case) for real-world programmers to use, simplicity is key. If your widget toolkit is hard to use because it offers a way to notify the application developer of every conceivable error condition, then no one would use it because it would be "too hard".
&lt;p&gt;What good is a library that is too hard to use that nobody uses it? It's no good, that's what.
&lt;p&gt;The problem is that the idealists complaining about glib's g_malloc() have only considered being able to check g_strdup()'s return for NULL or maybe as far as gtk_foo_new() and have not considered that the render pipeline may require allocating memory as it renders the widget which might not have an ideal way to pass the OOM error back up to the application because the top of the call stack may in fact be gtk_main() and not some callback function implemented in the application's code itself.
&lt;p&gt;The idealists argue that without the ability to check every malloc() for a NULL return and chain it back up to a high enough level in the call stack to handle properly means that users could lose their unsaved document if the application is, for example, a word processor. They argue that a properly designed application will always properly handle all error conditions and pass errors back up the stack where an emergency buffer can be used to show the user an "Out of memory" error dialog and/or save all of the user's unsaved work.
&lt;p&gt;The problem with this school of thought is that the simple act of rendering your error dialog may require memory that you do not have available (if we are truly OOM as opposed to simply being unable to allocate that ~4GB buffer that the application tried to allocate due to poor arithmetic).
&lt;p&gt;There is one thing that they are correct on, however, and that is that losing a user's document is a Bad Thing(tm).
&lt;p&gt;What they haven't considered, however, is that it's possible to prevent data loss without the need   to implement their really complex OOM handling code:
&lt;p&gt;I dub thee, auto-save.
&lt;p&gt;Yes, I will assert that auto-save is our savior and that it is, in fact, the &lt;i&gt;only&lt;/i&gt; feasible solution in what I affectionately refer to as: &lt;i&gt;The Real World&lt;/i&gt;.
&lt;p&gt;In the Real World, applications are built on top of other people's code that you do not control and do not have time nor luxury to audit, you simply have to trust that they work as advertised.
&lt;p&gt;Let's imagine, for a minute, that you write a word processor application using some toolkit (other than Gtk+, obviously) that upholds your idealist design principles in that it is designed in such a way as to be able to notify your word processor application about OOM conditions that it experienced way down in the deep dark places of the rendering pipeline. And let's, for argument's sake, assume that your application is flawlessly written - because you are an idealist and thus your code is perfectly implemented in all aspects, obviously.
&lt;p&gt;Now imagine that a user is using your word processor application and the version of the widget toolkit (s)he's using has a bug in some error handling case that is unexpectedly hit and the error &lt;i&gt;doesn't&lt;/i&gt; properly get passed up the call stack, but instead crashes the application because the toolkit's bug corrupts some memory.
&lt;p&gt;Oops.
&lt;p&gt;All the hard work you did, making sure that every possible error condition in &lt;i&gt;your&lt;/i&gt; code properly handles the error, never gets hit because the application crashed in a library you trusted to be implemented flawlessly, so the user loses his/her document that they were writing.
&lt;p&gt;Your effort was all for naught in this particular case.
&lt;p&gt;What's the solution? Auto-save.
&lt;p&gt;What have we learned from this? Auto-save is needed even &lt;i&gt;if&lt;/i&gt; your toolkit is sufficiently designed to pass all errors (including OOM errors) back up the stack.
&lt;p&gt;Once you've implemented auto-save, though, what are all those custom OOM-checks for each and every malloc() call in your application really worth?
&lt;p&gt;Zilch.
&lt;p&gt;So why &lt;i&gt;not&lt;/i&gt; use something like g_malloc() at this point?
&lt;p&gt;Once your system is OOM, the only reasonable thing you can do is save any state you don't already have saved and then abort the application (not necessarily using the abort() call). But if you already have all your important state pre-saved, then all you have left to do is shut down the application (because you don't have enough memory resources to continue running).
&lt;p&gt;Where does &lt;b&gt;Worse is Better&lt;/b&gt; come in, you ask?
&lt;p&gt;Well, arguably, the auto-save approach isn't as ideal as implementing proper fallback code for every possible error condition.
&lt;p&gt;Auto-save is, however, &lt;i&gt;Better&lt;/i&gt; because it works in the Real World and is &lt;i&gt;Good Enough&lt;/i&gt; in that it achieves the goal of preventing the loss of your user's document(s) &lt;i&gt;and&lt;/i&gt; because it is far easier to implement with a lot fewer points of failure.
&lt;p&gt;Fewer points of failure means that it is a lot more likely to work properly. By using the auto-save approach, you can focus on making that code robust against every conceivable error condition with far less developer time and resources meaning you are able to keep both cost and data loss down which makes everyone happy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3478188950153323423?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3478188950153323423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3478188950153323423' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3478188950153323423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3478188950153323423'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/02/worse-is-better-in-form-of-autosave.html' title='Worse is Better in the form of Autosave'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-9185356432158302179</id><published>2008-01-10T12:45:00.001-05:00</published><updated>2009-08-14T16:21:25.628-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><title type='text'>Inkscape to support XAML</title><content type='html'>&lt;p&gt;&lt;a href="http://www.beyondfocus.com/home.aspx"&gt;Joseph Hill&lt;/a&gt;, our new Mono PM here at Novell, just noted to me that &lt;a href="http://www.inkscape.org"&gt;Inkscape&lt;/a&gt; is &lt;a href="http://timheuer.com/blog/archive/2008/01/08/inkscape-svg-xaml-conversion-scale.aspx"&gt;adding XAML support&lt;/a&gt;.
&lt;p&gt;A quick google search found Jon Galloway's nice &lt;a href="http://weblogs.asp.net/jgalloway/archive/2008/01/10/inkscape-to-support-xaml-export.aspx"&gt;summary&lt;/a&gt; of why this is exciting.
&lt;p&gt;I'd also like to add that while Inkscape might not support all of the Silverlight XAML, it's still an excellent tool for artists used to using it to create Silverlight websites.
&lt;p&gt;Hopefully at some point in the future, we will have time to continue work on LunarEclipse to make it a more full-featured and viable option for creating Silverlight content, but for the time being, it's nice to know that users have other Free Software options.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-9185356432158302179?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/9185356432158302179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=9185356432158302179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/9185356432158302179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/9185356432158302179'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/01/inkscape-to-support-xaml.html' title='Inkscape to support XAML'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-2191579557368935896</id><published>2008-01-04T17:23:00.001-05:00</published><updated>2009-08-14T16:22:06.789-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='moonlight'/><title type='text'>Moonlight-powered Slide Show</title><content type='html'>&lt;p&gt;Nikhil Kothari posted about &lt;a href="http://www.nikhilk.net/Entry.aspx?id=184"&gt;Slide.Show&lt;/a&gt;, an application written by &lt;a href="http://www.vertigo.com/"&gt;Vertigo Software&lt;/a&gt; for Silverlight 1.0, that we Moonlight developers have recently been using as another test sample. Well, it now works under Moonlight too!
&lt;p&gt;Perhaps I am a simpleton, but I have to say that this slide show program is pretty sweet ;-)
&lt;p&gt;Very beautifully done.
&lt;p&gt;Also, as many Silverlight 1.0 and 2.0 developers have been doing, this application is free software (MS-PL)!
&lt;p&gt;Kudos to Vertigo Software!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-2191579557368935896?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/2191579557368935896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=2191579557368935896' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2191579557368935896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/2191579557368935896'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/01/moonlight-powered-slide-show.html' title='Moonlight-powered Slide Show'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-3497307164299927388</id><published>2008-01-03T10:54:00.002-05:00</published><updated>2009-08-14T16:22:39.481-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='community'/><title type='text'>Bruce Byfield on Conspiracy Theorists</title><content type='html'>&lt;p&gt;Bruce Byfield has made a recent post entitled &lt;a href="http://brucebyfield.wordpress.com/2008/01/02/conspiracy-theorists-and-free-software/"&gt;Conspiracy theorists and free software&lt;/a&gt;.
&lt;p&gt;Bruce, I absolutely agree with you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-3497307164299927388?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/3497307164299927388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=3497307164299927388' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3497307164299927388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/3497307164299927388'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2008/01/bruce-byfield-on-conspiracy-theorists.html' title='Bruce Byfield on Conspiracy Theorists'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-203063759820106893.post-7732974606906769744</id><published>2007-12-27T09:41:00.001-05:00</published><updated>2009-08-14T16:23:31.851-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><category scheme='http://www.blogger.com/atom/ns#' term='gmime'/><title type='text'>Christmas Vacation Hacks</title><content type='html'>&lt;p&gt;&lt;b&gt;Evolution&lt;/b&gt;
&lt;p&gt;There's been discussion about Evolution not handling some brokenly rfc2047 encoded message headers recently, so I ported some workaround logic from GMime to Camel yesterday. I think this should turn a lot of frowns upside down when Evolution 2.22 is released. The new rfc2047 header decoder in Evolution is now more accepting than Thunderbird's decoder[1], so I hope this will satisfy everyone.
&lt;p&gt;The new rfc2047 decoder will now handle the following cases:
&lt;ul&gt;
&lt;li&gt;encoded-words embedded inside other tokens (e.g n=?iso-8859-1?q?a=EF?=ve)&lt;/li&gt;
&lt;li&gt;encoded-words with LWSP in the encoded-text section (e.g. =?iso-8859-1?q?Look ma! there's spaces!?=)&lt;/li&gt;
&lt;li&gt;some encoded-word tokens with unencoded special chars in the encoded-text section (such as ? marks and other specials - obviously this can't always work if a special sequence occurrs)&lt;/li&gt;
&lt;li&gt;encoded-word tokens with no LWSP between them&lt;/li&gt;
&lt;li&gt;no longer aborts if the encoded-text cannot be completely converted to UTF-8 from the charset provided, instead it will attempt to find a more suitable charset to use for conversion and/or replace invalid byte sequences with a '?'&lt;/li&gt;
&lt;/ul&gt;
This should fix all of the more common broken-mailer cases, or at least all of the ones that are worth even bothering to try and work around.
&lt;p&gt;&lt;b&gt;GMime&lt;/b&gt;
&lt;p&gt;Did some digging and discovered how to document more things using gtk-doc, so GMime's documentation has been getting improved. All of the public functions in GMime now appear in the documentation (I had forgotten to add some of the newer API additions to the gmime-sections.txt file) as well as began writing documentation for each of the doc sections (which I hadn't known how to document previously).
&lt;p&gt;You can find up-to-the-minute GMime documentation &lt;a href="http://spruce.sourceforge.net/gmime/doc/"&gt;here&lt;/a&gt; as I continue to chug away at expanding it.
&lt;p&gt;While porting GMime's rfc2047 decoding logic to Evolution, I discovered some areas I could improve in GMime too.
&lt;br&gt;
&lt;br&gt;
&lt;small&gt;
&lt;p&gt;1. After having ported my GMime decoder logic to Camel, I was curious to see how Thunderbird handled broken rfc2047 encoded headers and so had myself a peek at mozilla/netwerk/mime/src/nsMIMEHeaderParamImpl.cpp and noted that my new logic in Camel would handle everything that Thunderbird would handle &lt;i&gt;and more&lt;/i&gt;.
&lt;p&gt;I also took a peek at KMail's rfc2047 header decoding logic and discovered Evolution is now more flexible than it as well (again, Evolution now handles everything that KMail's decoder handles &lt;i&gt;and more&lt;/i&gt;).&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/203063759820106893-7732974606906769744?l=jeffreystedfast.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreystedfast.blogspot.com/feeds/7732974606906769744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=203063759820106893&amp;postID=7732974606906769744' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7732974606906769744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/203063759820106893/posts/default/7732974606906769744'/><link rel='alternate' type='text/html' href='http://jeffreystedfast.blogspot.com/2007/12/christmas-vacation-hacks.html' title='Christmas Vacation Hacks'/><author><name>Jeffrey Stedfast</name><uri>http://www.blogger.com/profile/12271561115384429651</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>
