After working in a Windows environment for many years I find myself now coding from a Linux platform. You have to throw out a lot of what you have learned. Not so much the coding language itself, but lots of other details you don’t even realize you have thought of as cast in stone. In the past 6 months I have gone from feeling adrift in the Linux chasm to feeling that I can comfortably work in either operating system. To help some of you who are moving to Linux for the first time, I’m going to share my experiences during my first project from beginning to release of the first version. This GUI tool is designed to work on MID devices under a Linux OS. It is also a tool to demonstrate the usage of a set of APIs that are being developed by another team of people simultaneously.
The Linux I am using is Ubuntu 8.04. My development system is Anjuta IDE and Glade Interface Designer. I started using Gdk+ and C language and then “graduated” to C++ using Gdkmm. This seems to be somewhat rarified air as there are few internet pages or posts detailing problems and solutions. It feels like I’ve sort of kludged something together, but it works for me. The most interesting thing about this whole process has been the search for relevant information that combines one or more of the elements of my development environment. You can find lots of information about GTK + in the GNOME Documentation Library, but not so much about using the Glade Interface Designer with it. Of course, the Glade site has some documentation that helps with the program itself, but little on using it with Gtk. The Gdkmm documentation is excellent and has helped me the most. It even includes a section on Glade and libglademm which gives a lot of information.
Then there is C++ in Linux. It is basically the same as in Windows, but some things are different. When I tried to use itoa, it didn’t work. It turns out that itoa is not a C++ standard. You can use sprintf to accomplish the same thing. I have found some interesting ways to use strings in Linux. This site, C++ String class Examples and Tutorial is great! It contains all the things I’d forgotten that could be done with regular strings.
The application I’m developing is a four thread program. It has a main GUI thread that then spawns off three additional threads. One of these threads has a link back to the GUI class. When it is ready, it sends data to the GUI and changes the text in some widgets. The problem that I mentioned earlier was that although I was getting the information posted correctly, the GUI itself was not refreshing until the mouse was moved. Since my program sends new information every second, several changes could have occurred before a mouse move triggered the update. This just wasn’t going to work.
Then someone else pointed out that I was trying to update the GUI from another thread. In GDK, the main thread (which is the GUI) is considered “locked” by itself. If you want another thread to interact with the main thread, you must use gtk_threads_enter() and gtk_threads_leave() before and after the function that interacts with the main thread. Before you can use these two thread commands, you have to initialize gdk_threads in a non-main thread. Once you have done the initialization in one of the other threads, then all non-main threads can use them. By using this method, I got instantaneous updating in the main GUI thread.
Adventures at Moblin.org
To continue on my quest to move my application into the MID environment, I made moblin.org my new best friend. Since I originally wrote this section there have been many changes on the Moblin site. I have changed some of the names and links in order to be current. By opening the “Documentation” page I discovered some guides for getting a development system set up and for porting applications over to the MID. I started with Preparing for Development.
Installing the Moblin Image Creator was fairly simple. The Projects and Targets page showed me how to create a target environment and how to use Xephyr to test my target environment and applications. I had no trouble with creating the target or adding feature sets (fsets), but I hit a brick wall when I got to starting Xephyr. Every time I entered the “ume-xephyr-start” command, I would get the following and return to the prompt:
Setting screen resolution to 1024x600
DISPLAY already set to :0.0
* Starting system message bus dbus [ OK ]
* Starting network connection manager NetworkManager [ OK ]
* Starting network events dispatcher NetworkManagerDispatcher [ OK ]
* Starting System Tools Backends system-tools-backends [ OK ]
Starting UI in Xephyr
Extended Input Devices not yet supported. Implement it at line 625 in ../../../../hw/kdrive/src/kinput.c
Could not init font path element /usr/share/fonts/X11/cyrillic, removing from list!
Could not init font path element /var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType, removing from list!
waiting for X server to shut down FreeFontPath:
FPE "/usr/share/fonts/X11/misc" refcount is 2, should be 1; fixing.
In order to solve this, I ended up joining the Moblin mailing list and posting the problem there. The response took a while, but it turned out that this was a known issue and the fix is relatively simple. All you have to do is type “killall gconfd-2” at the target prompt (without the quotes). This will allow the screen to be displayed. Cool!
One of the worst things that can happen in coding (in my opinion) is a segmentation fault about which you can find little information. The error messages are less than illuminating and they can be erratic and difficult to pin down. That’s the situation I had now. A segmentation fault was driving me nuts.
One of the main features of my application was the use of the DBus system to receive information about the MID system. DBus is a system designed and used for interprocess communication in most Linux systems. There are defined calls to be made and quite a few tutorials on the web. The major tutorial seems to be D-Bus Tutorial. All of my DBus calls were made on one particular thread, which makes sense, except that sometimes when I was running the program it would have a segmentation fault and the program would crash. At first, it was happening about 1 out of every 3 or 4 times. I had a friend who is a long-time coder take a look at the code. He pointed out some areas I needed to tighten up and I gladly took his recommendations and made the changes. The segmentation fault was still there. I had some of the other software engineers take a look at the code. They also had some recommendations, most of which I agreed with and implemented. The segmentation fault still came and went at will (it seemed to almost take on a life of its own). We had a group look and talk session to see if together we could find it. Apparently, we couldn’t. The group did recommend that I load up a tool called Klocwork which is a bug analysis tool. Klocwork found 5 minor problems which I fixed, but the fixes did not result in the segmentation fault disappearing.
Finally, I took the code home with me and removed the DBus code from the threaded environment. I made a simple GUI and ran the DBus code in single thread mode. No segmentation fault over 80 iterations. Then I created a second thread and put the DBus code in the second thread. Guess what? The segmentation fault was back. Have you already figured out what the solution was? Yes, the gdk_threads_enter() and gdk_threads_leave() functions! By surrounding the DBus calls with those two functions, my program runs without any crashes at all. Looking back, most of the “code monkeys” I asked to look at my code had never written code in the Linux environment, so it is not too surprising that they weren’t familiar with GTK+ critical section needs.
After all that work, the code when through the inspection process fairly easily. I was finally able to load my application onto a MID and check it out. I definitely encourage you to do the same with any of your applications if you are developing them for MID. What I discovered from doing that was that all of the text in the tool was too small. I took a little extra time and made all of the text much larger. If you have need of such code yourself, here is an example of how to modify the text. Remember, this is using C++ and Glade with gktmm.
//In GUI class:
//In GUI class constructor:
// create a larger font for all the widgets to use
// connect the widget with the GUI button
glade_xml->get_widget( “ example_button”, m_pbtnExample );
// for buttons you have to get a pointer to the label which is a child of the button
Gtk::Widget *pwExample = m_pbtnExample->get_child();
// and then modify the font.
pwExample->modify_font( *m_ppfdSerif15 );
After changing the font and size of the text, the tool was much easier to see and use on the MID device.
Well, I hope that having read this you are a little more informed about some of the processes involved in moving your development from Windows to Linux. I have to say that there are some interesting differences in coding under the two operating systems. I was a die-hard windows programmer before this project but now I find myself comfortable in both environments. I certainly encourage you to go ahead and give Linux a try. You might be surprised!