Wednesday, September 16, 2009

Asynchronous Events Using Timers

Recently I was had an issue with Timer Call back function not working on Windows. I registered a simple call back function after 1 second, and it wasn't getting called, I was wondering how can it happen like that.

Then I did some study and found that, the windows will only send messages to your application that the timer is expired, and that message contains all the details such as the registered call back function etc, its the duty of the application to process these events and the call the windows API, DispatchMessage() which does the job of calling the call back function.

Here is the sample code, which works this way,
#include <windows.h>
#include <stdio.h>

int flag = 1;

void CALLBACK TimerProc(HWND, UINT, UINT, DWORD);

int main()
{
UINT_PTR id;
MSG msg;

id = SetTimer(NULL,
0,
3000,
(TIMERPROC) TimerProc);

while(flag)
{
GetMessage(&msg, NULL, 0, 0);
DispatchMessage(&msg);
}

KillTimer(NULL, id);

return 0;
}

void CALLBACK TimerProc(HWND hwnd,
UINT uMsg,
UINT idEvent,
DWORD dwTime)
{
flag = 0;
printf("I am in Timer Call Back Function \n");
}
So, if You are having the same problem as mine, please do follow this, and hope your problem is resolved, and do get back to me if you need any assistance.

The reason I think windows has been designed like this, is to make sure the call is made from the application context, hope that make sense, and I could not think of any other reason for doing it this way.

Friday, September 11, 2009

Inter-working with C/ C++ files

There are some times in the product development, especially in porting projects, and where we need to use the existing source codes, we may have to co-work with both C and C++ files, then we need to make them inter-work. Here I will show you how you can achieve that,

Accessing the C functions and data in C++ files.

supposed assume there is function func_c in a C file, my_file.c

void func_c(void)
{
    printf("I am a C function!");
}

to access this inside a C++ file, we need to declare it as shown below.

extern "C" void func_c(void);

The same methods can be followed for accessing all kind of data structures and variables.

Accessing C++ functions and Data Structures in C files.

Here things are other way round, just because C files does not take the key word extern "C", so all things need to be inside the C++ files, for C files its just another extern function or data.

So if I have a function func_cpp(void) as shown below, in my_file.cpp, it needs to be decalred as shown below

extern "C" void func_cpp(void)
{
    cout << "I am in C++ function";
}

To access this function inside the C file, just declare it as extern as you would normally do.

extern void func_cpp(void)

Hope it helps!

Tuesday, May 5, 2009

Windows DLL Programming

Creating a DLL is very simple, There are two files you need to create. The first is a DEF (define) file. The second is the CPP (C++ source) file. Add these lines in the CPP file of the DLL.

extern
"C" __declspec(dllexport) double AddNumbers(double a, double b)
{
return a + b;
}

and in the DEF file, add the following lines, in the EXPORT section. If more than one functions are there continue the numbering, (this is optional as we have already used __declspec(dllexport), but better to add here too.)

AddNumbers @1

Once the DLL is compiled it will create .lib, and .dll files in the debug folder, we need to add the .lib to the project in which we want to use that DLL, else we will get linking error. Once the linking is done, this .lib is not needed anymore, but we need to have the DLL in the same folder as that of our EXE, else the application wont be able to find the DLL, and will fail to load.

When we use a function from the DLL, the .lib file of that DLL need to be added to the project, and also the function need to be declared as extern as shown below.

extern __declspec(dllimport) double
AddNumbers(double a, double b);

Monday, January 12, 2009

Type Kannada in Ubuntu

Open synaptic Package Manager (System -> Administration -> Synaptic Package Manager) and check mark the following items, if already checked leave it as it is, and then say apply.
  • scim
  • sicm-m17
  • scim-gtk2-immodule
  • m17-db
Once they are all installed, Now SCIM input method is available on your ubuntu, you can use this to configure kannada input.

Open SCIM Input Method Setup.
Front end -> Global Setup -> Trigger
Add the keyboard short-cut ctrl + alt + space

If you want to make SCIM the default Input Method, create 75scim file under /etc/X11/Xsession.d/ with following lines (if you have 90im-switch, better to remove it for this setup)
 export XMODIFIERS="@im=SCIM"
export XIM_PROGRAM="/usr/bin/scim -d"
export GTK_IM_MODULE=scim
export QT_IM_MODULE=scim
Now logout and login again so that SCIM configurations are reloaded. When you login, you can see a keyboard icon in the tray, which is for SCIM. Open any editor such as gedit, and then click on this keyboard icon in the tray and select kannada-itrans.

Now you are set to type kannada, to switch between english and kannada use the short cut setup above (ctrl + alt + space)

Sunday, January 11, 2009

QEMU TAP network setup

This is one of the toughest task I have ever achieved, Its really complex, even though there are many post explaining how to setup the Virtual network, I feel most of them lack the complete information, and you end up getting frustrated. So after I achieved tun/tap networking up on PC, I thought of sharing the same.

When you run qemu normally without network options specified, automatically user mode network is setup between host OS and guest OS. In user mode networking, QEmu manages network interface internally in the user mode emulator application. QEmu provides DHCP host which assigns a dynamic IP for the guest OS. TCP and UDP ports can be redirected from the host OS to the guest OS using QEmu command line parameters. Easy to set up but, Only TCP and UDP connections are available by default. Ping command, for example, doesn't work inside the guest OS

In TAP networking, QEmu connects the guest OS ethernet to the host OS using TAP network bridge. Linux creates a virtual network interface (tap0) which appears in ifconfig listing as other network interfaces.

First off all you need to configure a network bridge. Which requires the bridge-utils package. For the TUN/TAP you need to check your kernel config file for CONFIG_TUN=m or CONFIG_TUN=y.

$ grep CONFIG_TUN= /boot/config-`uname -r`

Also you need to make sure /dev/net/tun exists. To make it:

$ mknod /dev/net/tun c 10 200


You need to have bridge utils installed. But then its safe to install these two packages, and I have installed these two and my network is working fine.

$ sudo apt-get install uml_utilities
$ sudo apt-get install bridge-utils


Once this is done, We can start setting up the network. I assume that Windows XP is installed on QEMU and KQEMU accelerator is being already used for the speed up purpose. Please refer to my other post for doing this.

For setting up the network qemu calls /etc/qemu-ifup script when -net nic -net tap option is given, It expects you to write the qemu-ifup script to setup bridge network. So first lets do that.

$ sudo vim /etc/qemu-ifup

#!/bin/sh
#
# script to bring up the tun device in QEMU in bridged mode
# first parameter is name of tap device (e.g. tap0)
#
# Prasad Shetty
# http://shettyprasad.blogspot.com
#
ETH0IP=192.168.0.3
GATEWAY=192.168.0.1
BROADCAST=192.168.0.255

# First take eth0 down, Add bridge, then bring it up with IP 0.0.0.0
ifconfig eth0 down
brctl addbr br0
ifconfig eth0 0.0.0.0 up

# Configure the bridge, create bridge between eth0 and br0
# and add the default route
ifconfig br0 $ETH0IP netmask 255.255.255.0 broadcast $BROADCAST
brctl addif br0 eth0
route add default gw $GATEWAY

# Bring the TAP bridge network up, and intereface with br0
ifconfig $1 up
brctl addif br0 $1

when qemu shuts down, it will call /etc/qemu-ifdown script, in which we can add functionality to bring down the bridge, and bring up the ethernet in normal mode.

$ sudo vim /etc/qemu-ifdown

#!/bin/sh
#
# Script to bring down and delete bridge br0 when QEMU exits
#
# Prasad Shetty
# http://shettyprasad.blogspot.com
#
# Bring down eth0 and br0
ifconfig eth0 down
ifconfig br0 down

# Delete the bridge
brctl delbr br0

# bring up eth0 in "normal" mode
ifconfig eth0 0.0.0.0 -promisc up

Once all this is done, we just need to specify which tap device to use for bridge to qemu, we can use tunctl to setup a TUN TAP device and then pass the retun value to qemu to use it with qemu-ifup and qemu-ifdown script.

I add some more functionality to this script to take care of setting up basic things before calling the qemu to run windows with network options. The comments itself explain the details of it. This is called wrapper script. All these things work with root and setting up the same for user is possible but it has lot of complexities and most possibly may not work properly.

$ sudo vim winxp.sh

#!/bin/sh
# insert the tuntap module
sudo modprobe tun
#
# insert the bridge module
sudo modprobe bridge
#
# insert the kqemu module
sudo modprobe kqemu major=0
#
iface=`sudo tunctl -b`
sudo qemu -m 256 -boot c -hda xp.img -snapshot -kernel-kqemu -localtime
-net nic -net tap,ifname=$iface
sudo tunctl -d $iface &>/dev/null

Now you can run this wrapper script and your QEMU comes up with windows xp with network up. Enjoy browsing under windows running on QEMU.

I sometimes get bus error, which I dont think is because of any errors in the network setup, If I fix it I will update here.

Install and Configure Samba Server for Ubuntu

Samba server is a utility for linux where in Linux filesystem folders can be exported over nfs and can be shared with the network machines. This is very helpful, when you have some of your work setup in linux and some in Windows, One of such situation is when you have to use a linux machine for your code compilation and use powerful source browsers such as source insight to develope and study/modify the code.

The Samba server setting up is an easy task, especially with the Ubuntu, things have become very easy. First install Samba server with following command.

$ sudo apt-get install samba

Once you are done with the istallation, you can export any directory to share over NFS. Assume that I have an user account with name prasad in Ubuntu machine, with my home directory at, /home/prasad. Do the following to share my home directory to me from my windows machine.

Edit the Samba configuration file (smb.conf) to add your share folder and permissions.

$ sudo vim /etc/samba/smb.conf

In vim editor, browse through this file, and find out where is the setting for home folder sharing. Enable home folder sharing, when you open the file you will understand what needs to be done, you just need to un-comment few lines. And add few lines at the end of the file to enable sharing of your home directory. These are the few lines needs to be added

[prasad]
path = /home/prasad
browseable = yes
valid users = prasad

Now your home directory is shared as //server-ip/prasad
You also need to create user 'prasad' for samba server access, linux user name and password does not work for this. To do that do that type these commands

$ sudo smbpasswd -a prasad

Give the password more than six char and confirm password and you are done. Restart the samba server.

$ sudo /etc/init.d/samba restart

If you find any problem feel free to ask me.

Saturday, January 10, 2009

How to Install Windows Xp on QEMU

QEMU is an emulator, which can be setup on both windows and linux, installing it on linux is simple and straight forward, but little complex and tricky on windows and most of the times. So I prefer to use it on linux. QEMU can emulate an x86 machine, (i.e your PC), so it can be treated as a vitual pc, with an hard disc image you are ready to install any OS on that virtual machine. KQEMU is an accelerator which increases the speed of emulation to close to native speed when host and guest OS are running on the same machine, i.e Target machine is same as host machine, This is achived by emulating only the kernel, and running the user code directly on the machine, Recent machines also support Virtulization at the hardware level, but that is out of scope of this document, in that case you can get native speeds on guest OS also.

I assume that you have setup the QEMU and KQEMU on your Linux. To install these refer to Installing QEMU and KQEMU. Once you are done with the above step. Please follow the following steps.

Create a hard disk image for windows xp, be it be of size 3-4GB size. Create a folder somewhere for windows xp image, and then use 'dd' command to create an image of 4GB size.

$ mkdir winxp
$ cd winxp
$ dd of=xp.img bs=1024 seek=4000000 count=0

Now a Image file (xp.img) of size 4GB is created, which can be used as hard disk for installing windows xp on QEMU. Run the below command.

$ qemu -m 384 -boot d -cdrom /dev/cdrom -hda xp.img

This command says to run QEMU with 384MB of Ram, and to use xp.img as hard disk, and to boot from cdrom. I assume that you have inserted the windows-xp bootable disk into the cdrom. If you have bootable cd image of windows xp (cdimagefile.iso), then use the below command to use that image instead of CD.

$ qemu -m 384 -boot d -cdrom cdimagefile.iso -hda xp.img

After this step, its windows setup, on any other PC, just follow the instructions on screen and it will install windows on the hard disc image specified. Partition as per your requirement, but since you have only 4GB hard disc better to keep only one drive (C:\)

Many of then say that it gets hanged at the end of installation, seem to be a problem with windows xp itself, but it did not happen to me, it got installed without any issues.

Once installed you can use the below command, to boot from hard disk image xp.img instead of CD, which is meant only for setup windows-xp. Now you can enable kqemu also, which is an accelerator for qemu, which makes your guest OS run at close speed to the actula OS, which is achived, by emulating only kernel, and the user threads are run directly on the machine, as both host and guest OS are running on the same machine.

follow these steps to enable kqemu, you should have root permission to do this, or use sudo to achieve the same.

$ modprobe kqemu major=0
$ chmod 755 /dev/kqemu [optional - only if you want to run without root]
$ chown root:$prasad /dev/kqemu [optional - prasad is my user name]

Once all this is done run the below command, windows-xp should boot with out any issues, if you find any difficulty feel free to ask me, I will be there to help you out. I have documented this, as it might help some of you, or may be to myself after long time, if I had forgotton everything.

$ qemu -m 256 -boot c -hda xp.img -snapshot -kernel-kqemu -localtime

(-snapshot is optional if given your xp.image is not modified, it also implies you work is not saved. drop it if you want)
(
-localtime is to get the time from the host system - useful, so dont drop this)

Now your windows is setup, and you can shut down the machine, and make a copy of xp.img somewhere safe, so that when your windows crash just replace the hard disc image xp.img with the backup image. You are done, no need to reinstall windows. You are done with Windows installation, but networking is not setup, user mode network is setup automatically, but I dont think you can browse internet with that, so you need to setup TUN/TAP networking with Bridge utils. I will post how to do it in my next post.

References:
  1. xp-under-debian-with-qemu
  2. http://ubuntuforums.org/showthread.php?t=179472
  3. https://help.ubuntu.com/community/WindowsXPUnderQemuHowTo

Installing QEMU, KQEMU

QEMU is an emulator, which can be setup on both windows and linux, installing it on linux is simple and straight forward, but little complex and tricky on windows and most of the times. So I prefer to use it on linux. QEMU can emulate an x86 machine, (i.e your PC), so it can be treated as a vitual pc, with an hard disc image you are ready to install any OS on that virtual machine. KQEMU is an accelerator which increases the speed of emulation to close to native speed when host and guest OS are running on the same machine, i.e Target machine is same as host machine, This is achived by emulating only the kernel, and running the user code directly on the machine, Recent machines also support Virtulization at the hardware level, but that is out of scope of this document, in that case you can get native speeds on guest OS also.

Download QEMU source code from this link (http://bellard.org/qemu/qemu-0.9.1.tar.gz) and save it in some directory(qemu), unzip the same, and configure and install it. For installing you need root permissions, you can use sudo instead of that. I assume that you have setup gcc 3.4 and some basic C libraries needed for development work. If not please do that first, use following commands to do that,

$ sudo apt-get install gcc-3.4
$ sudo apt-get install build-essential

$ cd qemu
$ tar zxvf qemu.x.y.z.tar.gz
$ cd qemu.x.y.z
$ ./configure
$ make
$ sudo make install

You are done, it is possible that you may not have LibSDL setup, and zlib, if not please install libSDB with the following command and try again.

$ sudo apt-get install libsdl1.2-dev
$ sudo apt-get install zlib1g-dev

Download KQEMU souce code from the this link (http://bellard.org/qemu/kqemu-1.3.0pre11.tar.gz), and save in in the same directory as above, unzip and configure and install it, for installing you need to have root permision or else use sudo. Since all libs are setup already for QEMU, you wont get any missing library or missing .h file errors here.

$ cd qemu
$ tar zxvf kqemu-1.3.0pre11.tar.gz
$ cd kqemu-1.3.0pre11
$ ./configure
$ make
$ sudo make install

You are done with kqemu installation. And ready to emulate any of the machines supported by QEMU, if you know qemu, you can develope your own machines or embedded targets also. I am developing an emulator for Our Target phone.

Tuesday, January 6, 2009

Kannada Fonts on Ubuntu Firefox

Many of you may wish to use Kannada in Ubuntu, may it be the web pages in firefox or typing in kannada to write some articles or your blog post. I have recently installed Ubuntu 8.04 and faces issues with Kannada fonts, the kannada fonts are not rendered properly on firefox. I resolved the issue after lots of googling, am posting here what I have done to enable kannada fonts which might help a few of you.

The fonts can be made rendered correctly on Firefox by using the following methods

  1. Uninstall the free fonts that come with Ubuntu, which is main cause for most of the font problems. May be you need to change the name of the directory if its installed on a different directory.

    cd /usr/share/fonts/truetype
    sudo rm -rf free-fonts


  2. First install the kannada fonts which may or may not have installed on your Ubuntu by default. Even if its installed it does not harm reinstalling it. To do that type the following command in shell

    sudo apt-get install ttf-kannada-fonts

  3. Mallige fonts will be installed in ttf-kannada-fonts directory, which does not render properly, remaining fonts will be enough for working with kannada on Ubuntu. So removed Mallige fonts.

    cd /usr/share/fonts/truetype/ttf-kannada-fonts
    rm -f Malige-*.*

Now everything is setup fine, Just update the font cache by running the below command and restart firefox everything should work fine.

sudo fc-cache -fv

Feel free to ask me if you still facing any problems with Kannada fonts. Some web pages might be talking about MOZ_DISABLE_PANGO, which does not help anything, infact all that tweeks mentioned in those sites are already present in Ubuntu 8.04. I have explained how to enable direct typing in Kannada on Ubuntu in this post : (link not yet added).
.