Nerdworks logo "The nerd shall inherit the earth."

Nerdworks Blogorama

Nerdspeak

Fedora Linux - Not for the faint of heart!
Technobabble
7/29/2006 12:04:42 AM  

I happened to install the 64 bit edition of Fedora Core 5 on my computer a few days back. Here's a log of all that transpired during that time before I could finally wipe the sweat off my forehead, heave a sigh of quiet satisfaction and watch GNOME load in all its resplendent glory!

22nd July, 2006 - 15:00 hrs

Received Fedora Core 64 bit bootable DVD via courier that I'd ordered through Buylinuxdvd.com. This is a great site for buying Linux distros in India by the way. You will not find fancy shmancy payment gateways though. But the service is just great.

15:30 hrs

Step 1 was of course, to carve out some space on my hard drive where I could install Fedora. Since I had lots of free space on one of my partitions I decided to hew it out of that partition and thus began my search for a free disk parition tool that could create paritions out of free space on existing partitions.

I went ahead and burnt the GParted LiveCD ISO image onto a CD-ROM and rebooted, only to find GParted indefinitely scanning for hardware! Ran out of patience and tried to see if PartitionLogic was any better. Well it wasn't! It had an issue with crossing a certain line called A20 (whatever that is!).

But this time I read somewhere that while GParted might take a while scanning things it will eventually deliver. Deciding to give it another shot, I rebooted into GParted, got the scanning thing going and went to watch my favourite TV show. By the time I came back (around 30 mins later) it had managed to figure out where my hard drive was and how it was laid out. God bless GParted developers! From there on it was a piece of cake (creating the partitions that is).

The lesson learnt here is of course that, "GParted's mill grinds slow, but sure."!

20:00 hrs

After a failed attempt at getting Fedora's Anaconda installer to start in GUI mode I successfully got Fedora installed using the plain jane character mode interface! Hurray! I now had Fedora Linux installed and it didn't mess up my XP installation! The experience so far had been so smooth and bump free that the only way forward was - down!

It all started when I decided that I had to have a GUI!

23rd July, 2006 - 02:20 hrs

Still no GUI :(. Got a few Nvidia display drivers for Linux downloaded on my XP system and was wondering how to access them from Fedora (my Windows partitions are all NTFS formatted you see). Turns out that some brilliant folks have actually reverse engineered the NTFS file system and written drivers for Linux that'll let us mount NTFS partitions on Linux in read-only mode! These guys rock!

I happily issued the command:

yum install kmod-ntfs

Only to be informed that I needed to upgrade my kernel and must download and install a 21 MB package before even thinking about kmod-ntfs. I had already started using stilts by this time to prevent falling face down on the keyboard before I finally got the hint my body had been trying to give me all along, that I needed to grab some sleep and that getting X to work on Fedora could actually wait (what blasphemy)! I let the download progress however and fell into the closest bed that I could find, falling asleep long before actually hitting ground (or well, bed)!

11:00 hrs

No Sir. Still staring at the dang white blinking cursor on the black dang screen! I installed kmod-ntfs (finally!), copied the Nvidia drivers over and even got them to build and install. But doing an init 5 continued to cause X to go nuts! After scouring all over the internet and trying 20 different home-brewed solutions I was almost ready to give up and accede defeat when I suddenly decided to take took a look at /var/logs/Xorg.0.log.

As it turned out, X was having trouble locating where exactly the module "nvidia" was to be found. I searched for "nvidia_drv.so" and found it easily enough in /usr/X11R6/lib64/modules/drivers. What I really wanted to do then was to give X a thorough shake and beat it into its puny brain where the driver lived. Grrr.

24th July, 2006 - 00:00 hrs

While I was thus considering the modalities of how such a shake could be administered I suddenly noticed that X was loading keyboard and mouse drivers from a different location - /usr/lib64/xorg/modules! Voila! That was of course the problem! I immediately decided to copy the nvidia driver files from /usr/X11R6/lib64/modules to this location. I did that first, then checked whether xorg.conf was configured right, ran nvidia-xconfig again just to be sure, checked whether the planets were aligned just right and ran the command:

startx

No words can express the joy I experienced when a beautiful screen like this opened up in 16-bit splendour!

Fedora GNOME screenshot

Only then did I wipe the sweat off my brow, heave a sigh of quiet satisfaction and rest my weary head for well-deserved sleep.

Link Comment (4)
 
On Unicode
Technobabble
7/16/2006 4:47:58 PM  

There were some interesting Unicode related issues that cropped up recently in the project that I am working on that led to my doing a little research into what the fuss around unicode was all about. While I had some understanding of what Unicode was, there were a few things that I managed to learn anew. So, if you didn't know, here's the low down on the Unicode standard.

First, some basic facts

  • Firstly there are two parallel efforts aimed at standardizing the use of characters in computer programs! One is the ISO 10646 project called the Universal Character Set (UCS) and the other is of course, Unicode. Around 1991 however, participants from both the projects fortunately decided that it would probably not be a good idea to have two competing standards for solving the same problem and decided to make both of their specifications compatible.

  • The primary goal of the Unicode standard is the definition of a universal character set (!), i.e., a character set to replace all the other character sets. Further, it would also be able to accommodate characters from all the languages spoken/written in the world.

  • It achieves this by assigning unique numbers – called code points – to each character. The Kannada letter “ka” for example has been assigned the code point 3221. What this means is that 3221 is forever the code for the Kannada letter “ka” all over the planet! Numbers such as this are assigned for all characters in all languages.

  • Code points are always assigned from the range 0x000000 to 0x10FFFF. You’d need 21 bits to represent this information at most. Around 5% of this space (works out to about 50,000 characters) is currently in use, another 5% is in preparation, about 13% is reserved for private use and about 2% is just reserved and not to be used for representing characters. The remaining 75% (around 8,35,000 characters) is open for future use!

  • Interestingly, effort is underway for assigning code points to characters from imaginary languages as well! JRR Tolkien invented a whole slew of languages each with its own grammar and script for his epic trilogy – “The Lord of the Rings”. Languages spoken and written by elves, dwarves, hobbits and ents (large walking/talking trees!) including a language called “Black Speech” used by orcs and other such dark residents of Mordor!

Some caveats

  • You might have heard that Unicode characters can be represented by 2 byte unsigned integers. Well, this is not entirely true. While it is possible to represent all the Unicode characters that exist in the world today (which represents the most frequently used set of characters) using 2 byte unsigned integers (given that only around 50,000 characters exist and an unsigned short can have a maximum value of 65,535) it is possible that code points get created whose value is greater than the maximum that can be accommodated in an unsigned short. The most commonly used characters however have been assigned numbers within the range 0x0000 to 0xFFFF (this is called the Basic Multilingual Plane or BMP).

  • The closest data type in C/C++ that can be used to represent all the possible Unicode code points is a 4 byte integer. But this would also mean that 11 bits would get wasted for every character given that all the code points can be represented with just 21 bits. The size of the C/C++ wchar_t data-type is compiler dependent and the standard does not say anything on how big it must be.

  • Even while using 2 bytes per character you’ll immediately notice that using them is wasteful when you’re mostly dealing with characters belonging, for example to the ASCII character set (all the ASCII character code assignments have been retained in Unicode for ensuring backward compatibility by the way) since the second byte would always have the value zero for all the characters.

Encodings

  • To get around this problem some clever folks invented “encoding” schemes such as UTF-8 and UTF-16 that lay out how any Unicode code point from the entire spectrum can be represented using the least number of bytes. UTF-8 in particular is quite popular as it automatically ensures backward compatibility with older documents. All existing ASCII documents are already valid UTF-8 files. Here’s a nifty little table that specifies how Unicode code points will be represented in the UTF-8 encoding scheme.

    Unicode UTF-8
    00000000 - 0000007F 0xxxxxxx
    00000080 - 000007FF 110xxxxx 10xxxxxx
    00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
    00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

    The first column specifies the range of code points and the second column is a bitwise representation of how it will be denoted under UTF-8. Code points till 0x7F (ASCII character set) for instance will be represented using a single byte. For code points greater than 7F at least 2 bytes are needed and the number of contiguous bits set to 1 in the first byte till a zero is encountered indicates the number of bytes used to represent that code point. For example, 3 bytes are required for representing code points in the range 0x00000800 – 0x0000FFFF and this is indicated by the fact that the 3 most significant bits in the first byte is set to 1 followed by a zero bit.

  • UTF-8 is a “variable encoding” scheme where each character in the document can correspond to a varying number of bytes. Finding the size of such a document post encoding can be somewhat tricky.

Most of this information has been taken from the following great resources on this topic.

http://www.cl.cam.ac.uk/~mgk25/unicode.html
This is an FAQ on what it takes to support Unicode on Linux and has a lot of information on Unicode and UCS in general.

http://www-128.ibm.com/developerworks/library/codepages.html
Talks about various character sets. Good introduction to Unicode.

http://icu.sourceforge.net/docs/papers/unicode_wchar_t.html
Talks about issues relating to size of the C/C++ wchar_t data-type.

Link Comment
 
Dumb terrorists
Philosophical Crud
7/12/2006 11:01:19 AM  

Terrorists must be some of the dumbest people on the planet to believe that terror can somehow further their cause. I wonder if in all of history there has ever been a case where terror resulted in something positive for the terrorists. End of day such acts only contribute to fuelling a vicious cycle of hatred. The fundamental problem is that humans have a capacity for evil! That might sound naïve but is nevertheless true I think. There’s an apothegm by Friedrich Nietzsche that goes like –

In individuals, insanity is rare; but in groups, parties, nations and epochs, it is the rule.

What this would mean is that acts of terror are perpetrated by terrorist groups (which tend to be insane by nature given that they are groups of people) that are led by sober, cold and essentially evil individuals who do the thinking and the planning; who cleverly exploit and misdirect restless energy in disgruntled youths; who know the exact words and notions that will appeal to them and even lend an illusion of grandeur to what they are doing.

I have always suspected that there exists a suicidal streak in humans as a species. This is perhaps just one of the ways in which that instinct has manifested itself.

http://www.iht.com/articles/2006/07/12/asia/web.0712india.php
Link Comment (1)
 
Windows hooks & call sequence
Technobabble
7/6/2006 9:19:58 PM  

I ran into an interesting little issue at work the other day. There is this program that I am working on which happens to embed Office documents into a browser control hosted in a CHtmlView derived view window (that's right, we use MFC). The requirement was to popup a little toolbar with a save button whenever the user did some in-place editing on whatever's displayed in the browser control. We already knew how to detect whether at a given point in time the document currently displayed in the browser has been edited. This was done in this manner (error checks omitted for brevity):

bool IsDirty()
{
    //
    // get hold of the html view object somehow
    //
    CHtmlView *pView = GetViewSomehow();

    //
    // get a pointer to the HTML document object
    //
    CComPtr<IDispatch> spDocument( pView->GetHtmlDocument() );

    //
    // turns out that you can QI on the doc object to
    // get a "IPersistStorage" object which is directly linked
    // to whatever happens to be embedded in the browser
    //
    CComPtr<IPersistStorage> spStorage;
    HRESULT hr = spDocument->QueryInterface( IID_IPersistStorage, (void **)&spStorage );

    //
    // now we just call "IPersistStorage::IsDirty" to figure
    // out whether the doc's been edited
    //
    hr = spStorage->IsDirty();
    return ( hr == S_OK );
}

The question of course was to figure out when this routine will be invoked so we can display the toolbar. We first came up with an approach that involved continuously polling for changes by making some creative use of CWinApp::OnIdle. But that resulted in short bursts of CPU usage spikes and while the solution worked, it somehow didn't feel right!

The next thing we tried was to see if Windows hooks can be put to some use here. We quickly set up a system-wide keyboard and mouse hook which "phoned home" so to speak whenever an event occurred by posting a custom message to a window. Whenever this message is received by the window it would call our clever little IsDirty routine to check if the document has been modified and get the toolbar displayed if need be. I let out a satisfied little burp at this point and compiled, linked and hit Ctrl+F5.

I loaded up a PowerPoint file into the browser control and pressed a few keys and whopeeee(!) the toolbar appeared straightaway. On doing some additional testing however I discovered that the damn thing showed up only with the second key press and not immediately after the first one! As it turns out, Windows delivers messages to hooks before they are delivered to the target application. So my hook was getting the keyboard event before PowerPoint was getting it and the call to IsDirty was consequently returning false as PowerPoint hadn't had a chance to mark the file as having been modified yet.

This thing drove us a little nuts until of course we figured a way out. I even made a newsgroup post on this issue (with no response by the way). The solution in the end turned out to be quite simple.

Well-behaving hooks are required to call the CallNextHookEx function before returning from the hook routine. This is to let other hooks that are installed on the system have a go at the message. I had done a PostMessage to the application window before calling CallNextHookEx like so:


PostMessage( hwndNotify, WM_HOOK_NOTIFY_MOUSE, 0, 0 );
return CallNextHookEx( NULL, nCode, wParam, lParam );

I made a small change to the order of invocation in this manner:


LRESULT lResult = CallNextHookEx( NULL, nCode, wParam, lParam );
PostMessage( hwndNotify, WM_HOOK_NOTIFY_MOUSE, 0, 0 );
return lResult;

And voila! it started working! It must be pretty evident what the issue was by just looking at the change that was done. Looks like CallNextHookEx, apart from calling other hooks that may have been installed also actually delivers the message to the target application before returning. In this case, this was just what the doctor ordered :)!

Cool eh?!

Link Comment
 
blogorama home
about this blog
email the author
where on earth am i?
subscribe to mailing list
feeds Use these links for feed syndication
rss  |  atom
by category
technobabble (60)
philosophical crud (3)
irrelevant stuff (7)
archive
november, 2011 (2)
october, 2011 (1)
september, 2011 (7)
july, 2011 (3)
june, 2011 (2)
may, 2011 (3)
april, 2011 (1)
march, 2011 (1)
february, 2011 (1)
february, 2010 (1)
october, 2009 (1)
september, 2009 (1)
july, 2009 (5)
march, 2009 (2)
august, 2008 (2)
march, 2008 (1)
january, 2008 (1)
september, 2007 (2)
april, 2007 (1)
february, 2007 (2)
december, 2006 (1)
october, 2006 (1)
september, 2006 (4)
august, 2006 (3)
july, 2006 (4)
june, 2006 (3)
may, 2006 (6)
april, 2006 (2)
recent entries
Implementing variab...
Debugging existing...
Screen scraping wit...
Building an Instagr...
Building an Instagr...
Organizing your Jav...
298087 hits