More menus

As we saw in the last post, I was struggling to use the newer style GtkBuilder methods to start replacing bits of the application kludge3d. But my simple minded approach was giving me some grief:

 #include <gtk/gtk>
int main(int argc, char **argv)
{
    gtk_init(&argc,&argv);
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkBuilder* builder = gtk_builder_new_from_file ("test.ui");
    GtkWidget* menubar = GTK_WIDGET(gtk_builder_get_object (builder, "menubar"));
    gtk_container_remove(GTK_CONTAINER(gtk_builder_get_object (builder, "mainvbox")), menubar);
    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
    gtk_box_pack_start(GTK_BOX(vbox), menubar, TRUE, TRUE, 2);
    gtk_container_add(GTK_CONTAINER(window), vbox);
    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

This isn’t so promising:
kludge3d_gtk3.x_02
and the runtime warning isn’t clear (though as we’ll see, it’s correct)

(a.out:5940): Gtk-CRITICAL **: gtk_box_pack: assertion ‘gtk_widget_get_parent (child) == NULL’ failed

ToGoogle! Ok, consensus is that my menubar widget already has a parent and so the mainvbox is complaining when I try to add the menubar.

Memories of making my own container widgets in Windows and Gtk+2.x, I need to reparent my menubar.

but:

gtk_widget_reparent has been deprecated since version 3.14 and should not be used in newly-written code.

Use gtk_container_remove() and gtk_container_add().

Great, at least I know to add :

gtk_container_remove(GTK_CONTAINER(gtk_builder_get_object (builder, "mainvbox")), menubar);

And, it works:

kludge3d_gtk3.x_03

GTK+3.x and menus

So, having got kludge3d to the “starts, but doesn’t work” stage, I need to start implementing all the bits that got commented out along the way. For example, there are no menus because the method that was being used (GtkItemFactory) is deprecated (and so is a pain to compile) – time to move to the current methods.

Which would be great if the docs were clear for my use case.

See, I don’t want to just move the whole application over to a Glade designed interface, or use GtkApplication. The sane choice (I thought) was bring things over in a working, if minimal state.

So, I can use glade to build a menubar, save the result to xml. Then I’m failing to add the GObject I load out of the GtkBuilder to the application window I’ve created manually. And every tutorial assumes that I plan to just move everything to glade.

Frustrated, and considering my options…

Porting to GTK+3

For a long time I’ve used kludge3d as the basis for a geometry editing front end to my DPS program. kludge3d is a GTK+2.x app using gtkglext for OpenGL access and I regularly used it under windows and Linux.

Now, kludge3d hasn’t had much upstream development (last release 22/8/2004). That said, I’ve been able to keep it useful against the GTK+2.x series. However recently, getting a GTK+2.x bundle and adding gtkglext to is under windows has become too hard.

Its time to move to GTK+3.0.

First up, oh no, GTK has picked gtkglarea instead of gtkglext. More code churn.

However, though there is lots of code just stubbed out, I at least have a kludge3d binary launching under Linux:

kludge3d_gtk3.x_01

building glade-3.8.1 on windows

With the arrival of my daughter in 2009, spare time became a lot more restricted (why didn’t anyone tell me? 😉 OK, so getting back in the saddle, time to rebuild my development environment. As always I like to have GTK+ stuff working on both Linux and Windows. So what does the setup look like now?

Install mingw (as I write this we have gcc 4.6.2)

Install a GTK+ bundle (gtk+-bundle_2.24.10-20120208_win32.zip)

Then, I need Glade. Since we are still on the 2.4 series of GTK+ we need Glade 3.8.x. The last Glade Windows binary offered is 3.6.7 (from 2009!), so lets build from source. Of course we need a few dependencies:

intltool-0.50.1
./configure –prefix=/c/apps/gtk-2.24.10
make
make install

libxml2-2.7.8
./configure –prefix=/c/apps/gtk-2.24.10 –without-threads
make
make install

glade3-3.8.1
./configure –prefix=/c/apps/gtk-2.24.10 –disable-python
make
make install
glade-3.exe

Oh dear, something is broken with the icon loader I guess:

At this stage I’ve done no investigation. But given the GTK+ stack is always a bit fragile on windows, I guess I expected this.

Downloading Glade 3.6.7 installer (incorporating GTK+ 2.16.2) gave:

At least the icons are loaded properly, but it wants to be a “system”. Therefore it modifies various environment variables without asking (GTK_HOME, INCLUDE, LIB) and it installs a shortcut to the start menu with the wrong version number (3.6.6 vs 3.6.7)…

On the philosophy side, I wonder if I should care about this. For reasons of work, I mainly write for Windows when I’m getting paid. For a period, some apps were written with a separate display layer so that GTK+/Win32 were both supported. But since I was the sole user on GTK+, eventually I stopped. One app might get ported to Qt as a learning exercise, but honestly, the poor state of the business makes this a “for the love, not the money” project.

In the past, I’ve hacked about in the GTK+ internals (trying to get GTK+ to integrate with VTK for example, eventually this was the catalyst to go win32 for new projects by default). Internally, GTK+ is a bit hard to get a handle on when your main job is numerical simulation and analysis. So while I’d like GTK+ on windows to work better, that whole available time thing kicks in again. I guess the general slow progress in that department really shows that there are relatively few people interested in Windows/GTK+ as a platform.

 

Fedora14

Fedora 14 is out, so what are the initial impressions? Sigh. Look I use Fedora in a lot of situations (compuational cluster, laptop, mythbox), but its the little things that get me down.

Install F14 from the liveCD. During installation, tell it to use UTC and ntp. Once we login we find:

Would have thought they might notice that in testing.Yes, I should file a bug report. And it would have been better to do it during beta. But in about 10 minutes I’ll disable SELinux like everyone else does….

later…

Browse CD, hit button on drive, remove CD. Oh its still mounted on the desktop. Right click icon (so I can try and force and unmount) poof Nautilus crashed. Helpfully the system asked if I wanted to report the crash. Perhaps it should warn its going to download and install all the debug packages…

Notice that there is no option to change your mind once you realise your mistake?

OpenGL and GTK+: Have I learned anything?

So looking through the codebases for gtkglarea and gtkglext the contrast in approaches is pretty stark:

gtkglext gtkglarea
large codebase small code
separates platform specific code ifdefs everywhere
dead maintained for the moment

For my purposes, I think I’m best to port back to gtkglarea. It is maintained for now (not to slight the current maintainers, just we’ve been through this dance before).

update:

I’ve done the port.  Since kludge3d used gtkglarea in the past it wasn’t really that hard. So for now I’d say unless you need gtkglext’s extra features, use gtkglarea.

OpenGL and GTK+

DSC_0345

Once upon a time, kludge3d (and g3d before it) implemented OpenGL rendering via gtkglarea. gtkglarea (developed by J. Löf and originally hosted at http://www.student.oulu.fi/~jlof/gtkglarea/ – now a dead site) it provided a gtkdrawingarea like widget. Then some time goes by and gtkglarea seems to have gone unmaintained.

In the meantime, gtkglext had come into existence. So by the kludge3d 2003-07-18 release, gtkglext was the display option of choice. gtkglext offered the possibility of placing an OpenGL view onto any GTK+ widget. (Though I’ve never been convinced that you need to do that very often).

So then in 2008, I get my first Vista based laptop. At work, I’ve been internally maintaining a version of kludge3d for many years. I was disappointed that kludge3d only worked properly with desktop compositing turned off. It is not the end of the world sure, but it looks bad, and anyway, it should be fixable right? A quick look at the gtkglext source made it clear I didn’t really have the understanding of how gdk actually does anything on win32. With deadlines looming and the fact that my users were all on XP, I shelved further investigation.

Fastforward to now. Vista or Windows7 is in our corporate future. So while trawling the gtkglext mailing lists I see a post from Mike Farrell. He suggested enabling PFD_SUPPORT_COMPOSITION based on the information at OpenGL.org. Unfortunately the suggested patch didn’t work for me, but did get me digging into the gtkglext source code again. I worked out some of the path from GTK to the screen. gtkglext looks like it is violating the assumptions that DWM has about GDI and the OpenGL context.

Enter a new gtkglarea. (http://www.mono-project.com/GtkGLArea). It looks like it is being maintained again. And hey, it builds properly on windows with mingw out of the box. And better yet, all of the examples run properly with desktop compositing enabled. Woohoo.

So now the question is:

  • fix gtkglext
  • port kludge3d back to gtkglarea?
2003-07-18

Building kqemu

qemu is enough to run tinycore without acceleration, but more is better right?

Get the source: kqemu-1.4.0pre1.tar.gz

$ tar zxf ../Downloads/kqemu-1.4.0pre1.tar.gz
$ cd kqemu-1.4.0.pre1

Edit Makefile.winnt, change

CROSS_PREFIX=i386-mingw32-

to

CROSS_PREFIX=

then apply the patch from here:

$ patch -p0 ../../Downloads/kqemu-mingw.diff
patching file `common/Makefile'
patching file `common/genmon.c'
patching file `common/i386/monitor-win32.ld'
patching file `common/i386/monitor_asm.S'
patching file `common/i386/nexus_asm.S'
patching file `common/kqemu_int.h'
Hunk #1 succeeded at 1057 (offset -6 lines).
patching file `common/x86_64/monitor-win32.ld'
patching file `common/x86_64/monitor_asm.S'
$ make -f Makefile.winnt
$ cp kqemu.sys kqemu.inf /c/apps/qemu-0.10.5

Now you need to do some surgery on kqemu.sys. Using the guide from here.

  • [DefaultInstall.NT] –> [DefaultInstall]
  • [DefaultInstall.NT.Services] –> [DefaultInstall.Services]
  • [Uninstall.NT] –> [Uninstall]
  • [Uninstall.NT.Services] –> [Uninstall.Services]

Then right click on kqemu.inf -> install

Hand over UAC permission, then start an Administrator command shell, cd to the installation directory and:

c:appsqemu-0.10.5>net start kqemu

The KQEMU virtualisation module for QEMU service was started successfully.

Now when you start qemu, it goes faster! yay.

$ qemu -cdrom /c/Users/dpinson/Downloads/tinycore_2.2.iso -hda tinycore.img -m256 -boot d

Building qemu for a change

I’ve played with qemu on and off for as long as I can remember (and I remember struggling with Bochs on DEC OSF/1). These days life is Vista orientated for work reasons and by and by I’ve ended up with win32 as my main development environment, even when I work on GTK+ code (the beauty of cross platform libraries I guess).

Nowadays we are blessed with lots of good virtualisation software (VirtualPC, VMWare, VirtualBox). While I have a regular rotation of VirtualBox setups, I thought I could see how well qemu was going, but it seems that the win32 binaries are a bit on the stale side (0.9.0 vs 0.10.6). So lets try to build it under mingw/msys….

Preliminaries

Download and install zlib.

$ tar zxf ../Downloads/zlib-1.2.3.tar.gz
$ cd zlib-1.2.3
$ make -f win32/Makefile.gcc
$ cp zlib.h zconf.h /usr/include
$ cp libz.a /usr/lib

Download and install SDL

$ tar zxf ../Downloads/SDL-1.2.13.tar.gz
$ cd SDL-1.2.13
$ ./configure --prefix=/usr
$ make

Which only gets to:

windres ./src/main/win32/version.rc build/version.o
/bin/sh ./libtool --mode=link gcc -o build/libSDL.la build/SDL.lo build/SDL_error.lo build/SDL_fatal.lo build/SDL_audio.lo build/SDL_audiocvt.lo build/SDL_audiodev.lo build/SDL_mixer.lo build/SDL_mixer_MMX.lo build/SDL_mixer_MMX_VC.lo build/SDL_mixer_m68k.lo build/SDL_wave.lo build/SDL_cdrom.lo build/SDL_cpuinfo.lo build/SDL_active.lo build/SDL_events.lo build/SDL_expose.lo build/SDL_keyboard.lo build/SDL_mouse.lo build/SDL_quit.lo build/SDL_resize.lo build/SDL_rwops.lo build/SDL_getenv.lo build/SDL_iconv.lo build/SDL_malloc.lo build/SDL_qsort.lo build/SDL_stdlib.lo build/SDL_string.lo build/SDL_thread.lo build/SDL_timer.lo build/SDL_RLEaccel.lo build/SDL_blit.lo build/SDL_blit_0.lo build/SDL_blit_1.lo build/SDL_blit_A.lo build/SDL_blit_N.lo build/SDL_bmp.lo build/SDL_cursor.lo build/SDL_gamma.lo build/SDL_pixels.lo build/SDL_stretch.lo build/SDL_surface.lo build/SDL_video.lo build/SDL_yuv.lo build/SDL_yuv_mmx.lo build/SDL_yuv_sw.lo build/SDL_joystick.lo build/SDL_nullevents.lo build/SDL_nullmouse.lo build/SDL_nullvideo.lo build/SDL_diskaudio.lo build/SDL_dummyaudio.lo build/SDL_sysevents.lo build/SDL_sysmouse.lo build/SDL_syswm.lo build/SDL_wingl.lo build/SDL_dibevents.lo build/SDL_dibvideo.lo build/SDL_dibaudio.lo build/SDL_mmjoystick.lo build/SDL_syscdrom.lo build/SDL_sysmutex.lo build/SDL_syssem.lo build/SDL_systhread.lo build/SDL_syscond.lo build/SDL_systimer.lo build/SDL_sysloadso.lo build/version.o  -lm -luser32 -lgdi32 -lwinmm -no-undefined -rpath /usr/lib -release 1.2 -version-info 11:2:11
libtool: link: cannot build libtool library `build/libSDL.la' from non-libtool objects on this host: build/version.o
make: *** [build/libSDL.la] Error 1

Then we need to use the magic pointed to here:

$ ./libtool --tag=RC --mode=compile windres src/main/win32/version.rc -o build/version.o
then edit Makefile and change “$(objects)/version.o” to “$(objects)/version.lo”

and finally we can do:

$ make
$ make install

Now for qemu

$ tar zxf ../Downloads/qemu-0.10.5.tar.gz
$ cd qemu-0.10.5
$ ./configure --prefix=/c/apps/qemu-0.10.5 --disable-kvm
Error: zlib check failed
Make sure to have the zlib libs and headers installed.

I couldn’t resolve this in a nice way… I just edited the configure file to add OS_FLAGS to the MINGW32 section:

MINGW32*)
OS_CFLAGS="-I/usr/include -L/usr/lib"
mingw32="yes"
if [ "$cpu" = "i386" ] ; then
    kqemu="yes"
fi

Then

$ ./configure --prefix=/c/apps/qemu-0.10.5 --disable-kvm
$ make
...
c:/apps/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../../mingw32/bin/ld.exe: cannot find -lz
collect2: ld returned 1 exit status
make: *** [qemu-img.exe] Error 1

It seems that zlib still isn’t found. So to be expedient, add it to the Makefile:

change

LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS)

to

LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS) -L/usr/lib

and we are away…

$ make
$ make install

Almost there…

$ ./qemu-img.exe create -f qcow2 tinycore.img 1G
Formatting ‘tinycore.img’, fmt=qcow2, size=1048576 kB

$ qemu -cdrom /c/Users/dpinson/Downloads/tinycore_2.2.iso -hda tinycore.img -m 256 -boot d
Could not open ‘\.kqemu’ – QEMU acceleration layer not activated: 2

Next time we will build kqemu.