gunnar
Qt Jambi
Posted by gunnar
 in Qt Jambi
 on Friday, August 31, 2007 @ 16:09

Qt Jambi has been out for some weeks now and up until now there wasn’t a really good option for doing Database programming there. As an opensource developer you could go ahead and download the Qt source packages and build the database drivers from scratch, and the commercial owners that were curious got a special sourcepackage that let one build the database drivers from scratch. Now, this is all very painful, so one might be asking, why didn’t we provide binaries for those drivers in the first place…

Well… Its mostly because the C-API’s that those database drivers use are pretty much tied to the various versions of the database they connect to, so they have to be built by source using the right versions of the libraries for the right version of the database. *sigh*.

On the other hand… A solution arises… Java already has database support so it doesn’t really need Qt SQL C++ drivers. Instead we simply layered our database drivers on top of JDBC. I can’t take the credit for it, because it was mostly done by Harald, but at any rate, here it is.

Its a bit preliminary at this point, and we would love your feedback on bugs and suggestions. If we’re happy with the end result, this will be part of Qt Jambi 4.4.

Its available here:
http://labs.trolltech.com/page/Projects/QtJambi/JDBC

Enjoy

zack
Aggregated
Posted by zack
 in Aggregated
 on Friday, August 31, 2007 @ 15:09

Today was my last at Trolltech. Some of you already knew that, the others are likely getting mouth to mouth reciprocation right now while a heavy set man is charging defibrillator paddles next to them (breath, breath!).

Technically Qt is years ahead of all of its competition and with Trolltech’s amazing engineering team it will continue doing great. I felt that other parts of the Open Source graphics stack could use my work a little more at the moment.

We (Open Source community) move at an astounding pace but the lower parts of our graphics framework are lagging a little bit behind. I wanted to go back to working on those parts of the graphics stack and it made sense for me to join a company that would directly profit from my work on Mesa, DRI, drivers and X.

This Monday will mark my first day at Tungsten Graphics. The engineering team at TG includes the likes of Brian Paul, Keith Whitwell, Michel Dänzer, Alan Hourihane and others, which reads almost like “Who’s who in Open Source graphics”. Clearly the only thing that was missing there was someone who looks really good naked. That’s me. I also know a thing or two about this whole “graphics” thing which tends to help.

I’ll be living in London for the next ~2 months or so. In England, while mainly working on Mesa, I’ll be filling the void left by the departure of Victoria and David Beckham.

sroedal
Qt
Posted by sroedal
 in Qt
 on Friday, August 31, 2007 @ 10:25

I’ve been working on a new rasterizer to replace the Freetype rasterizer for aliased painting in the raster paint engine, which is used on Windows and when rendering to a QImage. The new rasterizer is scheduled to be part of Qt 4.4, and is already available in the snapshots.

The performance of rasterizing various paths with QRasterizer compared to the Freetype rasterizer can bee seen in the following figure:

Freetype rasterizer vs QRasterizer

And the same results in table form:

Freetype QRasterizer Improvement
A - Plain rectangle 25773.2 37174.72 1.44
B - Rotated rectangle 1 23201.86 27247.96 1.17
C - Rotated rectangle 2 23041.47 28735.63 1.25
D - Rect dash stroke 276.24 1754.39 6.35
E - Rect dot stroke 87.95 826.45 9.4
F - Ellipse 3558.72 6944.44 1.95
G - Ellipse dash stroke 141.64 1282.05 9.05
H - Ellipse dot stroke 83.54 800 9.58
I - Short text path 14285.71 17241.38 1.21
J - Long text path 1683.5 1930.5 1.15
K - Random path size 5 24523.81 30294.12 1.24
L - Random path size 50 778.15 1098.13 1.41
M - Random rects (5) 25750 39615.38 1.54
N - Random rects (50) 324.81 753.21 2.32

Note: the numbers are for generating spans only, not filling. The benchmark used to measure these results can be downloaded from here: rasterizerbench.tar.gz

These numbers are already quite impressive, but where the new rasterizer really shines is for rasterizing complex paths with a lot of elements and potentially many self intersections. I’ve created an example which generates a path representing the Dragon Curve fractal. A screenshot from the application is shown below:

Dragon Curve (fractal) rendered using QRasterizer

At the highest detail setting the path (which is a round-cap/round-join stroke of the dragon curve) contains 507913 path elements. In this specific case the frame rate is approximately 36 times higher with the new rasterizer (filling included) :)

The example is available for download from here: dragoncurve.tar.gz

Note: the new rasterizer only affects primitive rendering (polygons, paths, ellipses, strokes, etc), and does not replace the Freetype rasterizer for plain font rendering.

Bjørn Erik
Qt
KDE
News
Posted by Bjørn Erik
 in Qt, KDE, News
 on Thursday, August 30, 2007 @ 09:27

As a follow-up on Qt Invaded By Aliens — The End of All Flicker I’m pleased to inform that the alien branch was integrated into Qt main on Tuesday (2007/08/28).

To get use of aliens (a.k.a. windowless child widgets) simply go here and download the latest Qt 4.4 snapshot.

That’s it!

If you for some reason want to get back to the old behavior with native windows, here’s how you can do it:

1) Use ‘QT_USE_NATIVE_WINDOWS=1′ in your environment (PS! with today’s snapshot and earlier one must use ‘QT_NATIVE=1′ instead).
2) Set the Qt::AA_NativeWindows attribute on the application: All widgets are native.
3) Set the Qt::WA_NativeWindow attribute on widgets: The widget itself and all ancestors are native (unless Qt::WA_DontCreateNativeAncestors is set).
4) Calling QWidget::winId enforces a native window and implies 3).
5) Setting the Qt::WA_PaintOnScreen attribute enforces a native window and implies 3).

Enjoy!

lorn
Qt
Qtopia
KDE
Greenphone
Posted by lorn
 in Qt, Qtopia, KDE, Greenphone
 on Wednesday, August 29, 2007 @ 22:10

Code name: Gurgle.

a new baby troll in Australia! baby Girl , born just 6 hours shy of the full lunar eclipse! 3:35 am. August 29, 2007.. Is 50.5 cm (19.8 “) long and, 3.56 kg (7 lbs, 14 oz) of joy.

bub potter

Just in time for Fathers day here in Australia! :)
Took us exactly 9 months to code and 18 or so hours to compile.

[edit]
We came up with a release name! Jasmine Kiarra Vanessa Potter!

Bradley T. Hughes
Qt
KDE
Threads
 in Qt, KDE, Threads
 on Tuesday, August 28, 2007 @ 06:26

Yesterday, I closed task 168853, the “provide a cross-platform atomic API” task. After several rounds of API review (and literally hundreds of completely Qt rebuilds on every test machine), I added QAtomicInt and QAtomicPointer to the 4.4 snapshots. These classes provide atomic operations for integers and pointers, respectively. At the moment, each class supports atomic test-and-set, fetch-and-store, and fetch-and-add. QAtomicInt also supports atomic reference counting with the ref() and deref() functions.

In addition to the actual atomic API, QAtomicInt and QAtomicPointer also provide an API to check whether the hardware supports a particular operation natively, and if the implementation is wait-free. For example, there’s the monstrous Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NATIVELY_SUPPORTED and Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE macros for compile-time checking, and QAtomicInt::isReferenceCountingNative() and QAtomicInt::isReferenceCountingWaitFree() for run-time checking. Note that run-time checking is really only needed if Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE is defined. This gives us, for example, the possibility of building a generic ARM binary that runs on today’s Xscale processors (ARMv5) or an ARMv6 processor (which adds load-linked/store-conditional instructions to support multi-processor/multi-core devices).

So, go get the 4.4 snapshot and give it try. Any and all feedback is welcome :)

eskil
Qt
KDE
Qt Jambi
Posted by eskil
 in Qt, KDE, Qt Jambi
 on Friday, August 24, 2007 @ 12:35

Say you are a C++ programmer who has a heartfelt passion for writing plugin based applications in Qt. One day, during a brief loss of your senses, you decide that you want to expand the plugin support in your latest creation to include contributions from both C++ and Java programmers. Riddled with idealism and optimism, you cross out a week in your calendar, sit down and start reading the JNI specification. At some point during this week, you’ll probably realize that nothing is as easy as it seems, and that the road to hell is paved with the differences between C++ and Java. Next, you’ll either give up, set off an indefinite amount of time to write elaborate bindings for your interfaces, or you’ll read this blog and see that you were right all along and life still comes with happy endings.

All dramatic phrasing aside, in Qt Jambi we have already solved a bunch of the problems that arise when you are binding C++ with Java, and it’s actually pretty easy and convenient to use the Qt Jambi generator and framework to import classes and objects back and forth across the boundaries of the language. In this blog, I’d like to go through some simple code that allows you to make a custom widget in Java using Qt Jambi, instantiate this in C++, and then add it to a C++-based layout. I have a bit of a cold, and I didn’t really feel like putting together an example that makes any sense, but I’ve posted some code that you can download, which will create a window with a button and the Qt Jambi Colliding Mice example. The latter is written in Java, and can easily be replaced by any other Qt Jambi widget you might write. To get the same convience from your own classes and interfaces, you would simply use the Qt Jambi generator.

The prerequisites for compiling and using the code is: an installation of Qt Jambi, the JDK, and a Qt version matching your Qt Jambi version.

To build the code, set the JAVADIR environment variable to point to your JDK, the JAMBIDIR environment variable to point to your Qt Jambi installation and qmake away. You may have to tweak the .pro file a little for different platforms, because I’ve only tested it locally. Also make sure that you have both the Qt Jambi class files (e.g. in qtjambi.jar) and the root of the Qt Jambi installation in your CLASSPATH.

Building and running the javafromcpp application will show you a window with a push button on top and the colliding mice below it. The push button is a plain Qt/C++ widget, while the colliding mice are implemented in Qt Jambi, i.e. in Java. Here’s what it will look like, and following that is all the magic explained:

Java widget inside C++ widget

In the start of the main() function in the code, you’ll see the following function call:

    // Make sure the JVM is loaded
    qtjambi_initialize_vm();

This single line makes Qt Jambi search for your dynamic JVM library and instantiate a virtual machine for the process. Note that there is only space for a single VM in each process, so don’t expect this to work twice. (If there are problems in this call, you’ll get a warning. In that case we’d really like to know about it, plus which platform you are on, so we can figure out what’s failing.)

Anyway, initializing the VM is required to get access to JNI.

The code then sets up a window with a push button and some snacks, and it makes the function call which actually instantiates the java widget and returns a C++ pointer to it:

    QWidget *colliding_mice = qtjambi_instantiate_widget("com/trolltech/examples/CollidingMice");

The returned pointer is handled like any regular QWidget-pointer in Qt. We specify the fully qualified name of the class we wish to instantiate, in this case com.trolltech.examples.CollidingMice. In JVM syntax, the dots are replaced by forward slashes.

All the actual work is done inside qtjambi_instantiate_widget(), which I’ll now go through in detail.

The first paragraph of code retrieves a JNIEnv-pointer, which is your access point to JNI for the current thread and virtual machine.

    JNIEnv *env = qtjambi_current_environment();
    if (env == 0) {
        qWarning("Cannot get current JNI environment. Was the JVM loaded correctly?");

        // Make sure a possible exception is removed from the stack
        qtjambi_exception_check(env);
        return 0;
    }    

If we do not get a pointer to the JNI environment, we have to bail out. In case there is an exception on the stack, we call qtjambi_exception_check() which will print any pending exception and clear the stack. The next step is to create a frame for local references using JNIEnv::PushLocalFrame() (which will be pop’ed at the end of the function to make sure we don’t retain references to temporary objects.)

We go on by locating the class that was specified in the function call. The class will have to be available on the class path, or this call will return null.

    jclass clazz = qtjambi_find_class(env, qualified_name);

Using the same function, we find Qt Jambi’s QWidget-class, and use JNI to make sure the specified class is actually a QWidget subclass (this could help prevent some horrific crashes.)

Using some more JNI code, we get the ID of an assumed constructor in the specified class which takes a reference to a QWidget-parent:

    jmethodID constructor_id = env->GetMethodID(clazz, "<init>", "(Lcom/trolltech/qt/gui/QWidget;)V");

You have to design your classes by this convention in order to use the example code to instantiate them.

Next, we have to convert the supplied parent pointer to a Java object in order to pass it to the Java constructor.

    jobject java_parent = parent != 0 ? qtjambi_from_QWidget(env, parent) : 0;

The qtjambi_from_QWidget() call will either create a new Java widget if the parent widget was created in C++, or it will return the existing Java object if the parent was created in Java. If it has to create a new java object, the type of this will be the closest Java supertype known to Qt Jambi. If you have mapped your own C++ widgets and want to use them correctly in calls such as these, you have to make sure the initialization code of your generated library is called prior to the conversion takes place. Also note that in qtjambi_core.h you will find several other convenient conversion functions that can be used to convert back and forth between C++ and JNI, as well as other convenient, JNI-based code.

We instantiate our new widget using JNI, create a global reference to it to make sure it isn’t garbage collected before it can be hooked up to our hierarchy, and finally we convert the java object to C++ using the following call:

    return qobject_cast(qtjambi_to_qobject(env, java_widget));

And that does the trick. If the class was available, had the right supertype and constructor, then we will now return a fully operational C++ pointer to the object.

By the way, here’s another link to the downloadable code for those of you who skimmed everything up until the crazy screenshot.

Comments Off
Morten
Uncategorized
Qt
Posted by Morten
 in Uncategorized, Qt
 on Thursday, August 23, 2007 @ 12:10

Applications for Mac OS X are usually distributed as self-contained application bundles, which are installed by copying them into the “Applications” folder using drag-and-drop in Finder. As the mac deployment guide points out, creating said bundles involves copying in the Qt frameworks (and plugins), and then fiddling with the install names using otool and install_name_tool.

This is all well and good, but it’s really a procedure that begs to be automated since you typically have to do it over and over again until the final bugs have been ironed out. (just ask any release manager in your vicinity :) )

Therefore the Mac team proudly presents the deployqt utility, which turns what used to be a 10-minute command line exercise into a simple call to ./deployqt myapplication.app.

Enjoy!

Update: deployqt now supports the Mac binary packages.

trenton
Qt
Posted by trenton
 in Qt
 on Tuesday, August 21, 2007 @ 20:19

I must admit, I’m not the best blog writer out there. I always find it fun to read the new entries on labs.trolltech.com than write a new one myself. I enjoy writing articles for Qt Quarterly more, then I have something that is crunchy and I can put it on a shelf and collect space. I suppose I could invest in a printer for the blog, but that seems like more work. Anyway, I found a topic here that follows up on a previous Qt Quarterly article of mine and updates it to more modern Qt technologies, all in a short enough space for a blog entry (I hope).

A couple years ago, I quickly wrote the article, Fading Effects with Qt 4.1. It outlined a fader widget which you could drop on top of another widget (like a QTabWidget or a QStackedWidget) and have a fade transition. It was a quick job that showed off the neat effects you can do when you have a backing store. Since I wrote that article, there were some things added to Qt 4.2 that make the thing even easier to use. So, I thought I would point them out in case you missed them. Download the source code from the original article and you can make changes at home.

Here’s the header:
class FaderWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(QBrush fadeBrush READ fadeBrush WRITE setFadeBrush)
Q_PROPERTY(int fadeDuration READ fadeDuration WRITE setFadeDuration)
public:

FaderWidget(QWidget *parent);

QBrush fadeBrush() const { return startBrush; }
void setFadeBrush(const QBrush &newColor) { startBrush = newColor; }

int fadeDuration() const { return timeLine->duration(); }
void setFadeDuration(int milliseconds) { timeLine->setDuration(milliseconds); }

void start();

protected:
void paintEvent(QPaintEvent *event);

private:
QTimeLine *timeLine;
QBrush startBrush;
};

You’ll notice that we’ve eliminated some of the now needless variables and changed our QColor to a QBrush and our QTimer to a QTimeLine.

Now the changed parts of the source file, first the constructor:
FaderWidget::FaderWidget(QWidget *parent)
: QWidget(parent)
{
if (parent)
startBrush = parent->palette().window();
else
startBrush = Qt::white;

timeLine = new QTimeLine(333, this);
timeLine->setFrameRange(1000, 0);
connect(timeLine, SIGNAL(frameChanged(int)), this, SLOT(update()));

setAttribute(Qt::WA_DeleteOnClose);
resize(parent->size());
}

Here, we create our QTimeLine. QTimeLine is a class introduced in 4.2 that will take a time and a set number of frames and dish them out in regular intervals over that duration to make them appear animated. It helps keep animation constant, dropping frames if things end up getting behind and trying to ensure that an animation only lasts for the time alloted to it.
We set the time to be about a third of a second and give it a thousand frames to draw, starting at 1000 and ending at 0. Obviously, it won’t be drawing all of them in this time frame. We tell the timeline’s frameChanged() signal to trigger an update on the fader widget.

We also try to get the brush for the parent widget’s window role. This is a change from before where we only got the color and not the brush, since we couldn’t trivially alpha blend the an arbitrary pixmap in Qt 4.1.

void FaderWidget::start()
{
timeLine->start();
show();
}

Start remains similar to before, except it only needs to start the timeline.

void FaderWidget::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this);
qreal frame = timeLine->currentFrame();
painter.setOpacity(frame / 1000.);
painter.fillRect(rect(), startBrush);

if (frame < = 0.)
close();
}

Our paint event has probably changed the most (for the better). Instead of constantly calculating the new alpha color, we simply take the current frame of the timeline and divide it by our total frames, and use that as the opacity value for our QPainter. QPainter::setOpacity() was introduced in Qt 4.2 and sets the opacity for all drawing operations done with that painter. It’s easier than ever to get alpha blending effects with QPainter::setOpacity(). Then we simply fill the entire widget with the brush we got at the beginning.

That’s it! Feel free to make these changes to the code and see it in action. It will look much better than the previous version on platforms that have a pixmap for their window brush (like Mac OS X, XP, and Vista). I included a screen shot of a fade in action here below:

FaderWidget in action

Anyway, this is just an example with what you can do with Qt 4.2, not to mention 4.3. So, take a look at the classes like QTimeLine and new functions like QPainter::setOpacity(), see where you can use them in your existing apps to improve the user experience and make your maintenance easier.

Enjoy!

zack
Qt
WebKit
Aggregated
Posted by zack
 in Qt, WebKit, Aggregated
 on Monday, August 20, 2007 @ 09:20

I was on vacations last week but I’m being all jealous of my luggage. It got a free trip around the world. During my last 8 flights my luggage has been lost 5 times. Is that a record? Confetti anyone? It’s a celebration. If you’re going to meet me during any of the upcoming conferences I’ll be the outgoing and highly sarcastic naked guy with a sign on my chest saying “for my face look this way” and an arrow pointing up.

I neglected to mention that, as Simon said, QtWebKit is working on Windows. Simon did an amazing job of porting all the quirks of the build system but “amazing” is the default state for all of his code so it’s not a surprise at all. While he was doing that I’ve sat down and ported XML tokenizer to QXmlStream from LibXML. If you never wrote a web rendering tokenizer (and unless you’re crazy, the chances of that are pretty high, and if you did you’re crazy and won’t remember doing it anyway) you know that “fragile” is a term that nicely describes it. After it was ported Lars and I sat down to fix the regressions and they didn’t even know what hit them (ha! ninja reference).

In other news I’ve merged in FreeType2 rasterization algorithm patches in Qt. Our raster engine, uses the beauty that is FreeType’s rasterizer, with a few patches on top. Because they break BC in FreeType’s public interfaces we can’t merge them back at the moment. In any case the patches improve rendering speed in general antialiased paths of the raster engine (meaning on Windows, Qtopia Core and in general whenever rendering to a QImage) by about 10% which is gangsta awesome (”gangsta awesome” is a very high level of awesomeness, at least judging from MTV).

I’ve also optimized the path clipping code. Andreas uses the path clipping code in GraphicsView for collision detection, so when I say “path clipping code” you should read “path clipping and GraphicsView collision detection”. A lot of the time in that algorithm has been spent on vertex allocation for tested paths. I’ve used a few tricks to speed it up by about 15%. The code for that algorithm is the number two reason why baby seals die (the first is still undisputed). It’s not even the algorithm itself but the inherent complexity of the problem. I’m a big fan of computational geometry in computer graphics because it makes grown man cry, except me and I like feeling like the lean, mean, killing machine that I am. My favorite part of the path clipping problem is that there are two ways of solving the precision problems and neither of them really works. The trick is that paths operate in double coordinate system, efficient snap-rounding implementations that I’ve seen operate in fixed-point coordinate system which falls apart in this case because of absolutely random distribution of vertices across the full double spectrum. Tessellation and clipping itself can be done in a screen coordinate system, which makes it possible to consistently represent your coordinates with fixed-point representation. That doesn’t work for paths because, e.g. boolean operations on paths need to be done in native path coordinates not screen coordinates. So the algorithm forces an absolutely crazy mix of dynamic fixed-point size, reduced-predicates, magic and good-will to work. Aren’t you happy that I’m doing it for you? You better be.

Yours(1) Latino(2) Lover(3)

1) Not really “yours”, more “community”. I love “you” but “you” need to realize that I need to be seeing other people.
2) Not really “Latino”. Unless of course my Spanish or Brazilian friends would like to name me an “honorary Latino” or “Latino by association”. I’d be definitely down with that. The only food I can make that is eatable and doesn’t force the fire department to evacuate the building before are nachos. I’m a definition of grace in the kitchen. “Whatever you have in the kitchen I will make it burn” is my motto. Plus I’m sporting quite an attitude to boot. “Make Zack a Latino” campaign. We can make it work!
3) Not really “lover”. More “no feelings haver”. Though technically I’ve worked on software for so long that hate is, next to sarcasm, my primary export.