Sunday, November 25, 2007

Hildonizing wxGTK

Last week-end I have somehow managed to find myself with a couple of hours of free time and, instead of spending them on fixing random wxWidgets bugs as usual, I wanted to actually do something new and different for once and so chose to check how wx applications look on a Nokia 770 tablet. Several people have talked about porting wxWidgets to this device in the past and at least one has apparently done some work but it was almost two years ago and nothing has happened since, so I felt it was time to do something about it myself; especially as I own a N770 tablet since quite some time but, instead of writing programs for it as originally planned, I've so far spent time just using it (I do feel ashamed).

For those who don't know about Nokia internet tablets line, which started with N770 but has been extended with N800 and N810 since then, they're small handheld non phone devices which run Linux and use a modified Gnome desktop version called Maemo. Maemo basically just adds another level of libraries, called Hildon on top of GTK+ itself. So, while GTK+ applications can mostly run on N770 without changing, they don't have the correct look and feel before they are hildonized, that is modified to use Hildon-specific functions instead of the generic GTK+ ones -- hence the somewhat barbaric adjective used in the title of this article.

This is the theory, anyhow. And I've decided to check how it was in practice. The first results were encouraging: after a few simple fixes, wxGTK did build for Maemo and I could run applications on my device. However they really didn't look like they belonged here as can be seen by comparing the dialogs sample:




with a native application, such as this one:




You can immediately see several differences:

  • The border of the window are not the same, the wx example doesn't fit into the desktop
  • The menus are completely different: the native applications don't show a menu bar but use the drop down menus attached to the window itself
  • The wx example shows a useless status bar with an even more useless resize grip (the window can't be resized anyhow)
So I set about fixing this and after a couple of hours of hacking here is what I got:




This is already much better: the points mentioned above were corrected and I also added a new class (which is available, and hopefully will be useful, under the other platforms too) called wxNotificationMessage and which is used by the small message in the upper right part of the window (such messages are often used in Maemo UI as notifications and also message box replacements)

Of course, there are a lot of other things to do. For one, wxToolBar needs to be changed in the same way wxMenuBar was. Next, as Maemo replaces almost all of the standard GTK+ dialogs with its own ones, we need to do it too. I did it for the colour selection dialog which looks like this now if wxWidgets was built with --with-hildon option:


And the same should be done for the file selection dialogs and several other ones.


There are also less trivial things to do, like to understand how can the size of the library (and of the applications using it) be reduced to be more in line with the embedded systems capabilities. But globally I think wxWidgets is perfectly viable for developing Maemo applications and is even more convenient for doing this than raw GTK+ (which is the native toolkit of the platform) because it transparently abstracts the differences between the desktop GTK+ and Maemo systems: the dialogs sample itself hasn't been modified at all (just extended to show the notification message) to use the correct menus and so on, everything is done inside the library so exactly the same code can be used for the desktop application without any loss in functionality. Of course, in practice you will need to adapt applications to the mobile devices by probably removing some functionality which doesn't make sense there and simplifying the user interface. But wxWidgets already does some of this for you and hopefully will do even more in the future.

Of course, I don't actually expect to have that much free time every week-end so the progress of wxMaemo depends on the help from others. So if you're interested in checking out wxMaemo for yourself, don't hesitate to grab the latest wx code from our svn and build it with the above-mentioned --with-hildon option under Scratchbox. If you are new to Maemo, notice that its web site has nice tutorial about setting up the development environment for this platform. And, of course, if you can contribute to this effort, don't hesitate to send us patches and join us in discussions on wx-dev.

Have fun!

27 comments:

dm said...

Hi Vadim: one of the forumites at codeblocks.org pointed me to this post. I'm expecting an N800 in the week or so and will probably start tinkering then. I hadn't considered developing for maemo with wxWidgets. As you state in your post the real power of using wxWidgets is the ability to make the transition from GTK+ to hildon seamless to the dev. I still worry about performance, but arguably that should be no worse than the Maemo SDK C++ bindings. Anyway, I'll keep an eye on the progress of wxMaemo and may even be able to help out in the future.

Hostman said...

Hi,

I'm very interested in wxWidgets for Maemo. I actually posted the current n800 (OS2007) library version on the wiki:
http://maemo.org/community/wiki/LibraryCatalog

I've recently upgraded to OS2008 on the n800 and would like to get wxWidgets running on there. Is it safe to assume this wxMaemo port will work with OS2008? Also, what configure flags would you use besides --with-hildon? Thanks.

-Robert

Anonymous said...

that's great! big thanks

Anonymous said...

can You please upload your version of wxWidgets for Nokia 770

Hostman said...

Hi,

I went through and compiled the latest SVN, but the widgets did not appear as in your examples. However, I did get an error during configure saying that 'libhildon' could not be found. I'm using OS2008 and Maemo 4.0 under scratchbox. Thanks.

-Robert

Hostman said...

Specifically:
checking for HILDON... configure: WARNING: libhildon_lgpl not found

GreatGazoo said...

It appears the the configure script might be 770(ITOS2006) specific. I do see a libhildon_1.so.0. Is there any way to change the script to check for this?

Hostman said...

Ok, apparently hildon-lgpl has been replaced by hildon-libs (I think hildon-1 in my version). I had to copy /usr/lib/pkgconfig/hildon-1.pc to /usr/lib/pkgconfig/hildon-lgpl.pc, and configure worked.

During compile, there was an error looking for the hildon-widgets include directory, so I did:
ln -s /usr/include/hildon-1/hildon /usr/include/hildon-widgets
and, within the hildon directory:
ln -s hildon-color-chooser.h hildon-color-selector.h

All references to Selector needed to be changed to Chooser in:
src/gtk/colordlg.cpp
I also had to change some function calls for compatibility with the new library - some places needed different arguments, some functions no longer needed arguments, etc.

Needed to reorder the words in a constant in:
src/gtk/msgdlg.cpp

Unfortunately, when I try to compile some of the examples (for example, dialogs), I get an error:

/home/maemo/wxWidgets/lib/libwx_gtk2u_core-2.9.so: undefined reference to `hildon_color_chooser_get_color(_HildonColorChooser*, _GdkColor*)'
/home/maemo/wxWidgets/lib/libwx_gtk2u_core-2.9.so: undefined reference to `hildon_color_chooser_new()'
/home/maemo/wxWidgets/lib/libwx_gtk2u_core-2.9.so: undefined reference to `hildon_color_chooser_set_color(_HildonColorChooser*, _GdkColor*)'
/home/maemo/wxWidgets/lib/libwx_gtk2u_core-2.9.so: undefined reference to `hildon_color_chooser_get_type()'

I've added all the hildon libraries I can find to the Makefile, but I don't remember how to figure out what file it should be in - perhaps the 'nm' command? Anyhow, that's where I'm at. Thanks.

-Robert

Hostman said...

Ok, so some of this was right, and some was wrong. First off:

root@maemo-sdk:/scratchbox/users/maemo/targets/CHINOOK_ARMEL/usr/lib# nm -D libhildon-1.so | grep color
U gdk_color_free
U gdk_color_get_type
U gdk_gc_set_rgb_fg_color
U gtk_style_lookup_color
U gtk_widget_get_colormap
00024861 T hildon_color_button_get_color
00024749 T hildon_color_button_get_popup_shown
00023ef9 T hildon_color_button_get_type
0002450d T hildon_color_button_new
00024525 T hildon_color_button_new_with_color
000247c5 T hildon_color_button_popdown
00024555 T hildon_color_button_set_color
00026025 T hildon_color_chooser_dialog_get_color
000248f9 T hildon_color_chooser_dialog_get_type
0002600d T hildon_color_chooser_dialog_new
00025795 T hildon_color_chooser_dialog_set_color
00023afd T hildon_color_chooser_get_color
00020cb9 T hildon_color_chooser_get_type
00023d55 T hildon_color_chooser_new
00021875 T hildon_color_chooser_set_color
00018f3d T hildon_helper_set_logical_color


Had forgotten the -D flag for the .so files. Would it be so hard for nm to detect? Anyhow, went to the hildon page, and read up on hildon 2:

http://live.gnome.org/Hildon/TwoPointZero/ChangesOverview

I've edited the configure file, swapping all occurrences of 'hildon_lgpl' with 'hildon_1' and 'hildon-lgpl' with 'hildon-1'. It now works without some of the other hacking. I also replaced all of the #include statements with the new recommended:
#include < hildon/hildon.h >

Now, it seems that the reason the color dialog is being an issue is that the code was moved from being a module to static code, as one of the major changes. I may need to rewrite further some of the edits to make this work.

-Robert

Hostman said...

Well, I realized that the C++ was looking for a C++ function, and the library only contained C functions, so:

extern "C" {
GType G_GNUC_CONST
hildon_color_chooser_get_type (void);

GtkWidget*
hildon_color_chooser_new (void);

void
hildon_color_chooser_set_color (HildonColorChooser *chooser,
GdkColor *color);

void
hildon_color_chooser_get_color (HildonColorChooser *chooser,
GdkColor *color);
}

And now everything compiles. However, the dialogs program crashes on accessing the color dialogs, so I think I need to use HildonColorChooserDialog...

-Robert

Hostman said...

Ok, so that worked, in the sense that the color dialogs come up. However, the menus are not working and I will get the following error from dialog boxes, and the dialog app will crash:

dialogs[2476]: GLIB CRITICAL ** GLib-GObject - g_object_ref: assertion `object->ref_count > 0' failed
dialogs[2476]: GLIB CRITICAL ** GLib-GObject - g_object_unref: assertion `object->ref_count > 0' failed

No idea. Perhaps someone knows what this is about?

-Robert

Unknown said...

YAAAAAAAY!

There are some great (!) apps waiting to be ported to the tablets that need wxwidgets.

You are a hero! Keep it up!

Hostman said...

Ok, so here are my findings:

Crashing issues were due to not running program with run-standalone.sh
Fixes to code were still necessary to work with CHINOOK; tried reinstalling targets and still no hildon-lgpl

I'll post compiled binaries once I'm happy everything has tested correctly. Note that some behavior is not consistent between sbox xephyr and the n800.

Thanks.

Anonymous said...

Hi,
I compiled wxMaxima 0.7.3a on CHINOOK_ARMEL platform with non hildonized wxGTK 2.8.6. everything goes well except the program crashes once I try to open or save a file.

It seems wxMaxima can't be compiled with wxgtk 2.9.0.

ps.the text size in the memu and button is adjusted by maemo,which makes some trouble.

Hostman said...

Hi,

Likely wxMaxima will need to be re-structured to work on Maemo, but to resolve the crashing issues, I propose:

Under scratchbox, make sure you run the executable as:
run-standalone.sh ./wxmaxima

Try running it directly on the tablet - sometimes this works a lot better than the emulator.

Thanks.

Hostman said...

Also, I posted some screenshots of the dialog example after porting to hildon-1 libs:
http://maemolibs.blogspot.com/2007/12/first-some-screenshots.html

Anonymous said...

oh, sorry, it seems some internel errors with my scratchbox cause my problem,not wxmaxima or libs. I will reinstall something and report later.

oo said...

Hi,

I've tested your changes by porting xchm (http://xchm.sourceforge.net/) to OS2008. This was quite straightforward.

To really "hidonize" it, I need to solve three problems:

* remove the menu bar and make the menu appear from the top left button. In your screenshots, you seem to have solved this problem. How did you achieve that?

* use a "native" toolbar

* implement a full-screen view

Any idea on how to solve these problems?

A great thanks for your work. It's really nice to be able to port applications to a new platform so easily!

Hostman said...

Sergio,

The menu should work if you use the SVN version. I have some directions posted here:

http://maemolibs.blogspot.com/

Make sure you're using run-standalone.sh to run the program. Thanks.

Anonymous said...

Good Job!: )

Anonymous said...

This is a great site. Thank you for your information. I THANK YOU I SALUTE YOU IT,S A AMZING SITE.

Anonymous said...

Might be of interest here:

...
Hello,
first, thanks to all for the good work.
I noticed a problem, when compiling for a Nokia N810 internet tablet (both --with-hildon and default):
Only the first couple of mouse pointer motion events are forwarded, when moving the pen on the touchscreen.
This is apparent for example in the samples/drawing.cpp example - it reports the mouse position in the status bar, but stops updating after three or four reports.

The GTK doc says [1] that it tries to reduce the number of events and flags later events as "hint". If the app wants more, it needs to request them.

Therefore, I added, in src/gtk/window.cpp, to gtk_window_motion_notification_callback, as the last lines:
if (gdk_event->is_hint)
gdk_event_request_motions(gdk_event)
and it works now.
Now the "scribble.wx.lua" example in wxlua works as expected, in other words I can draw with the pen on the screen.
Disclaimer,
- I haven't tested if this breaks anything on another platform etc
- I'm neither gdk/wxwidgets experts
Cheers

Markus
ref:
[1] http://library.gnome.org/devel/gdk/stable/gdk-Events.html#GdkEventMask

Anonymous said...

Hi,

I went through and compiled the latest SVN, but the widgets did not appear as in your examples. However, I did get an error during configure saying that 'libhildon' could not be found. I'm using OS2008 and Maemo 4.0 under scratchbox. Thanks.

Anonymous said...

Also, I posted some screenshots of the dialog example after porting to hildon-1 libs:

Anonymous said...

Good Work .. I will try Maemo 5 Alpha SDK on my VM. Thanks.

Anonymous said...

I luv this framework. Hi Just want to know if you're working yet on the new windows 7 native GUI and the ribbon. Will they be a wxRibbon class in wxWidget 3?

Unknown said...

Please, if you have SDK for Nokia 770, get it to me, because nokia links doesn't work.