Archive for July, 2009

New windowing and input features

July 31, 2009

In my original schedule, I set next week as a target for the first Libwm release. This week I intended to write the last remaining features that go in to the release and write some documentation. I didn’t get very far with the documentation but for the coding part I had good progress. One week remaining before the release, I’d say I’m doing pretty fine. If all goes well, the release will be next week.

I started the week by improving my Extended Window Manager Hints (EWMH) code on Xlib. I also discovered a bug that caused some key press events to be duplicated. The bug originated when I was refactoring the event reading code a while ago and had gone unnoticed for a while (I really do too little testing). It took two attempts to fix the bug but now the key events work correctly.

Next I went on to add some useful input features. I started by detecting repeated keyboard events. After that, I wrote functions for warping the mouse and hiding the mouse cursor. While working on the mouse cursor I also figured out how to detect when the mouse pointer enters a window on Win32. I used TrackMouseEvent, WM_MOUSELEAVE and WM_MOUSEMOVE and a simple state machine to send MouseOverEvents and hide/show the mouse cursor to limit the effect of cursor hiding to one Window. Doing all this I found another bug. All the sudden I started getting “class already exists” errors from Win32 RegisterClassExW. I used a simple generator to make unique string identifiers from pointer addresses. The code has a simple operator precedence mistake that made my hexadecimal string conversion give same strings for different pointsrs. A pair of parens fixed the problem.

Finally I went on to add size limits to windows. Now a window can have a minimum and a maximum size and the window style is switched to make the window non-resizable if the lower and upper size limits are equal and non-zero.

Next week there won’t be any new features, only small additions and clean up. I will probably rename or add a function or two, but the coding stuff will be minimal. Most of next week’s work will probably be doing the documentation. I need to write a tutorial, building instructions for the library and a howto on using Libwm in projects. The API docs are already complete, but there’s a lot of room for improvement.

Last week’s blog post

July 27, 2009

Last week was pretty solid coding time. I made some good progress, added a few new features, fixed some bugs I found and tweaked the CMake build system.

I started out with hacking my CMakeFiles to have configure options for controlling the build type (Debug/Release/etc, the default is Debug) and handle building shared libraries properly. I added a config header file to sort out __declspec(dllexport) issues when building shared libraries on Windows, using a config.hpp.in template file and CMake’s configure_file-command to generate the compile time configuration file, GNU Autoconf style.

I also experimented creating Debian .deb packages with CMake and CPack. However, I soon figured out that building separate .deb packages for runtime and development files was hard and decided not to make .deb packages at all. I might do Mac OS X framework bundles later on.

Next, I went on to write non-blocking event reading/handling/queueing code. For Xlib I used XCheckMaskEvent and XCheckTypedEvent for ClientMessages, on Windows I used PeekMessageW with PM_NOREMOVE. A new test application was needed to test the non-blocking event i/o, so I whipped up a small new test app with a little rotating triangle. I used Boost threads and date_time to do timing for the animation. I tried to have a small model-view-controller-type design with a game-like update main loop with a fixed frame rate, independent for redrawing and model updates.

I also added an issue about synchronizing the event code for multithread applications. I’ve already separated the per-display and per-window event handling using a queue and a dispatcher utility that calls the event handlers. The event queue and the dispatcher should be easy to synchronize, but the hard part is getting along with the Xlib and Win32 API’s that are not exactly multithread friendly. I hope a little select(2)-based unix hackery will make the problem go away. Using XCB instead of Xlib would solve a lot of problems too. However, the synchronization will not make the first 0.1 release and is not my concern at the moment, for now we’ll be fine off single threaded.

Next I decided to tackle two issues I’ve had the most negative feedback about. First up was supporting GLX 1.2 and second was adding full screen windows. There’s still a lot of platforms that don’t support GLX 1.3, so backward compatibility for older API versions was needed. I used dlopen(NULL, RTLD_NOW) to dynamically link to the GLX 1.3 functions and #ifdefs to leave out GLX 1.3 stuff if it’s not available in the compile time environment. I then pieced together the configuration query code using XVisualInfos instead of GLXFBConfigs in a builder pattern-type design I also used with WGL_ARB_pixel_format/DescribePixelFormat on Windows. The rest was pretty easy, there was only about 6 GLX function calls to begin with, the pixel format query being the hardest part. For other minute GLX1.2/GLX1.3 api differences I just added a few good old if’s. I was very glad to see libwm running on a 2007 MacBook with only GLX 1.2 available, now I can test with OSX/X11 again.

Next up was full screen support. On Xlib I used Extended Window Manager Hints (EWHM) to switch to full screen and back. It worked fluently on my Linux desktop but on the MacBook it failed leaving the window unusable. I decided not to try to fix the MacBook bug because it seemed like it just failed trying to do what I wanted it to do, so it’s probably a graphics driver (go Intel!) or an X implementation bug. On Windows I used window styles, extended styles and moving and resizing the window to make it borderless and fill the entire screen. It worked pretty nice. Currently the window does not return to it’s original size when switched back from fullscreen to windowed, but I decided it’s not an issue.

I’ve had good experiences using Google Code with Mercurial. The on-line issue tracker is quite simple and perfect for little projects. I really like the Project Updates page, which is particularly helpful when writing long blog entries about coding progress.

This week, I intend to focus on small and useful features like handling keyboard repeat and hiding the mouse cursor. It’s also time for getting the documentation in shape for next week’s scheduled Release 0.1.

Rewriting and bug squishing

July 17, 2009

I started this week by adding all coding tasks I could come up with to the libwm issue tracker in Google Code. I could only come up with a few dozen issues to start with, but I’ve been adding new ones as I come up with them. I found it hard to convert some ideas to issue tickets and trying to select which tasks to complete before the upcoming release. So far, I’ve only marked the critical ones with the “Release 0.1” milestone label.

I had originally scheduled setting up Doxygen and CMake to generate API documentation, but I had already done this last week, so I had nothing but coding time at my hands.

I started out with adding support for keyboard modifiers (shift, alt, ctrl, num lock, etc)  and mouse motion events, I spent monday and tuesday doing that and everything went pretty fluently. When hacking with the event reading routines I realized that they are in need of a clean up. So after I had added the keymods and motion events I spent a day re-organizing and rewriting the event reading code that listens to event messages from the windowing system, interprets the events and passes them on to the libwm event queue.

When I was fixing the event reading parts I found a bug that had gone unnoticed for quite a while. To work around an incompatibility in window initialization-configuration query order between Xlib and Win32, I had used an extra subwindow in the Xlib implementation. When setting up a drawing surface I added a child window that was the X window that actually got drawn into. When clicking the client area of my window, I got X events that informed the mouse cursor leaving the parent window, entering the subwindow, then a click and leave/enter from the child to the parent. I decided to get rid of the subwindow hack altogether and use a dummy window to query the device configuration on Windows. A third alternative would have been to use some kind of creational design pattern to do delayed window initialization in the Xlib implementation.

So I went on and rewrote the window initialization, configuration query, drawing surface and context set up. On Windows I used a dummy window and device context when using DescribePixelFormat or WGL_ARB_pixel_format to query available pixel formats. On Xlib/GLX no hacks are required. The only hard part was trying to arrange the internal communication between the Window and PixelFormat class. I try to keep Xlib separated from GLX (and WGL separated from the Win32 stuff), so that adding support for EGL and OpenGL ES would be easier in the future.

Sometime during the week I realized I had another bug. I had previously used boost::scoped_ptr to handle the cleanup of my pimpl idiom pointers. I figured out that using scoped_ptr in a .dll on Windows was difficult because of __declspec(dllexport) issues so I switched to using plain old pointers and delete in destructors to get a dynamic library built on Win32. I forgot to take care of the destruction of the “pimpl objects” in case of exceptions in constructors. So I wired an std::auto_ptr inside the constructor to take care of the clean up. I release() the auto_ptr in the end of the constructor and let the destructor handle the final clean up.

Next week I’ll get writing some example applications that use libwm. I’ll focus on trying to set up a testing platform that I can use to debug non-blocking event i/o. I’ll also try to improve my build system to generate package files and handle building static libs optionally.

New project: libwm

July 10, 2009

My new project got approved. From now on I’ll be working on Libwm, a cross platform Windowing and Context management library for OpenGL. I am delighted that I got this chance to work on the library. Next up, I’ll start to work to get the first release of Libwm out.

I already started with a nice coding spree, I did a major rewrite of the wgl and glx parts of the library and also got some things done that had been left hanging since the spring when I last had the time to work on Libwm. I did major improvements in the framebuffer pixel format setup and keyboard event handling code. I also did some documentation and clean up.

Here’s my new project plan and from next week on I’ll get hacking.

Project plan – Libwm

Introduction

Libwm is a cross-platform C++ library to help with windowing, event handling and context creation in OpenGL applications. It’s target audience is OpenGL application and game developers. Libwm provides an abstraction to platform specific windowing systems like the X Window System and OpenGL context set-up API’s like GLX on X Windows or wgl on Win32. The Libwm project was started in February 2009 and, as of July 2009, weighs in at about 7000 lines of code. With an established solid code base, the project is heading for it’s first release.

Task – Finalize and release Libwm

To survive, an open source project must attract the attention of users and developers. To do this, a project must have a easily accessible release distributions, complete with libraries, developer files, examples and documentation. “Release early, release often” is the motto and the key to success.

The Libwm code base is already quite stable, but other aspects like documentation, examples and distribution files need a lot of work. A software distribution, especially a library, must have these things sorted out to be appealing to developers and users alike. Some project management work is also required, the project web site must be set up and maintained and an issue tracker should be employed.

The goal of the Kesäkoodi project is to relase the first version of Libwm, complete with good documentation,
source and binary distribution tarballs, Windows binaries, Debian packages and Mac OS X framework bundles and nice examples.

Schedule

I’ve got seven week of time remaining and my goal is to get in shape for release in four weeks. It is an ambitious schedule, but luckily there’s a couple weeks of time left if I don’t make it. If and when I get the release done, Libwm is far from finished. There’s plenty of new features to be added and lots of different OpenGL extensions, versions and platforms to support. The work will be about 50% of coding and 50% of project management and janitorial tasks.

Week 1

Issue tracker

In order to document and keep track of the project’s progress, an issue tracker should be set up. Google code offers a nice issue tracker that can be used. All planned tasks and features should be added to the issue tracker. With only a few weeks of coding time before the planned release date, a small set of tasks is chosen to be implemented in the first release, others will be saved for later versions.

Doxygen

Doxygen will be used to generate a nice API documentation. Doxygen should be set up and integrated to the build system to get documentation easily generated, installed and distributed. Doxygen annotation comments in the source code should be improved.

Code

The first few weeks will mostly consist of coding the missing parts of Libwm. This includes better handling of mouse events, especially on the Windows platform, improved event listening routines and better error handling. As soon as the release feature set is determined, I should get coding right away.

Week 2

CMake/CPack

Libwm is built using CMake, a cross platform build configurator/generator. CMake is pretty nice, it handles finding dependancies and configuring the build system as well as building documentation, installing and generating distribution packages with CPack. The CMake build system is working pretty fluently, but the build system still needs some fine tuning. CMake and CPack should be configured to generate distribution packages for runtime and development libraries and the documentation separately, in various formats from tarballs to Debian packages and Mac OS X frameworks. This should go pretty fluently with CMake and CPack, after all, that’s what they are designed for.

Example apps

A good library needs a good suite of example applications. The example applications also serve as a testing platform for the library. A few example applications should be written using various features of the Libwm library in different ways.

Code

Keep on coding the features that should be included in the release, there should be plenty of time and plenty of work to do.

Week 3

Code

Most of the features that should end up in the first release should be finished by the end of this week. It’s time to code hard to get things in shape for the pre-release code freeze. If all goes well, all the coding tasks for the release should be done by the end of the week.

Documentation

As the code base becomes more stable, it’s time to document it. The API docs should be done by now, but a good documentation is more than that. Add a high level description about the library, a tutorial and a lot of examples in the documentation.

Bug fixes

As the release gets closer, the code should be cleaned of nasty bugs. It’s time to fix all known bugs so far and hunt for new ones by hacking with the example and test applications. Also try to work on handling incorrect use of the library gracefully.

Week 4

Code review

The final week before the release should concentrate on code review, cleanup and fixing. It’s time to read through the entire source code, find and correct bugs and comment tricky parts of the source code. Google Code has a nice code review feature where users can review, comment and grade the code and add remarks to individual lines of code as well as on a per-file basis. I’ll try to find a friend who would have the time to browse through the code and add review comments.

Bug fixes

The code review may expose new bugs, find and fix as many bugs as possible.

Unification of implementations

The Libwm library has separate implementations for Windows and Xlib. Ideally they should behave exactly the same way, but in practice there are minute differences. Test side-by-side with as many platforms as possible,
find the differences in the behavior and try to unify them. If there are features that are not portable, handle them in a sane manner or remove the features from Libwm altogether.

Release

It’s time to roll out the release. Create distribution packages for all platforms and verify that they install and work correctly. Digitally sign the packages and put them available for download on the project web site.

Week 5

Buffer time

It never hurts to have an extra few weeks in your project schedule. If the original release schedule isn’t met, try to finish the release as soon as possible.

Web site

The project web site also needs some work. The project page should be made informative and appealing, complete with screenshots and code examples. Google Code has a nice wiki that can be used for documentation.

Promotion and PR

When the release is out, it’s time to promote the project to other developers. Post announcements on relevant forums and mailing lists and IRC channels to attract the attention of potential users and contributors.

More features

When the first release is done, there’s still plenty of work to do and features to add. If there’s time left, it’s time to work on new features. Potential features include full screen support, OpenGL 3.x context creation using the ARB_create_context extensions, multisample antialiasing, shared exponent visuals, floating point pixel formats, etc.

Week 6

Buffer time

If the release isn’t out by now, it’s time to hurry up and get it done. Hopefully the release is already done and we have some extra time on our hands to work on new features.

More features

Keep on working on new features to the library.

Week 7

Final report

I will spare all of the last week to make my final Kesäkoodi report. I’m lousy at getting things like this done. Hopefully there will be some time left for coding too.

Risk analysis

Not finishing

The biggest threat of open source development is not finishing a project. To get the first release of Libwm out there, I should work consistently towards that goal. To meet my schedule, I will have to carefully choose the features I want to implement and what to leave out and stick with my plan. I feel that the Libwm project is on a solid base and the release can be done in schedule.

Killer bug

Before the release, Libwm is going to need a lot more testing. Surprising bugs may come up and fixing them might be hard. If a particularly difficult problem arises, the schedule may be delayed. If a real rogue bug strikes, it may be better to stick to the original release plan and document the bug to be fixed later. Overall, the Libwm code base is pretty simple and small and even major parts of the library can be quickly rewritten. Should a difficult bug come up, fixing it should be doable within the time frame.

Finishing off the documentation

July 5, 2009

I spent this week finishing off the XCB and OpenGL documentation in the XCB wiki. I also rewrote the OpenGL with XCB and Xlib sample code I had done previosly. The old code didn’t have any error handling or cleanup code and it was very dirty, so I wrote something a bit cleaner to put in the docs. I couldn’t upload any images to the XCB wiki and I still need to figure out uploading the diagrams I drew with someone who can administer the wiki. I also have the original Inkscape‘d SVG images around, but Firefox and Eye of Gnome had some problems rendering those images, so I decided to use exported PNG bitmaps instead. I should also figure out where to archive the SVG diagrams for future use.

I e-mailed my supervisors at COSS to discuss my work for the rest of the summer. I proposed a few projects and asked about the limitations I have in selecting a project.

The rest of the week I spent hacking libwm, a C++ OpenGL windowing library like GLUT, GLFW, SDL, et al. Libwm is one of the projects I proposed for my Kesäkoodi work, I hope the sponsors and supervisors approve it, because this is going to be a solid library. It would be really useful to get some paid time to work on this, in particular to do things like documentation, web site and project management. You know, the kind of stuff you’d rather not spend your free evening coding time on. Anyways, I got a few missing features done and a 700 LOC rewrite of the pixel format selection and context creation code. I ran into some bugs on Windows, but I hope to get them fixed soon.

Next week, I hope to hear from the supervisors and find a project that I can work for. I’ll probably need to write a new project plan too.