Posts about kde (old posts, page 9)

2006-04-19 01:48

IUP/Qt shows a window

Of course you know that means nothing, but yes, after a few hours of hacking, I got enough of a Qt backend for IUP so a window can be displayed.

//ralsina.me/lateral/static/diup1.png

Of course those are all the widgets that are implemented currently.

If by implemented you accept "can't connect callbacks and 90% of the attributes are inaccessible", that is!

But after I get the callbacks working (that's the hairy part), the rest is simple monotonous repetitive work.

It's interesting that the Qt backend is, of course, looking quite simpler than the Motif one, and in fact, a fair bit simpler than the IUP programs look.

But hey, you get a sort of LUA bindings for Qt at the same price...

OTOH, the third step is a nicer OOP, D, wrapper around IUP.

Or something like that ;-)

2006-04-18 02:41

My first adventure in D-Land

Yesterday (or rather, like 10 hours ago?) I posted about my quest for a specific language, and mentioned one of the candidates, called D which I had found appealing.

Well, because I am a quick coder (not good, but quick) I decided, after looking around for about 5 minutes, to take as my first project giving the D community a UI toolkit.

My first choice would have been Qt, of course, but D doesn't interface well (or at all) with C++, and I was not about to hack a QtC binding, because it would be unusable.

So, I looked around the web for a small multiplatform C toolkit, and I found there are very few of those left!

You have Gtk+ and ... well, almost nothing else! I found IUP though, and decided to bind it.

Since binding C libs to D is quite simple, I did it mostly by hand. And 76 files and 8872 lines of code later, here is DIUP, a D binding for IUP.

Now, how do you use it?

Get IUP, then get DC, then get D, then get DIUP, then open it, and check the examples.

The binding modules themselves are in the binding folder, so you can compile examples like this:

[[email protected] iupbinding]$ cd examples/elem/iupbutton/
[[email protected] iupbutton]$ dmd -g -I../../../binding/ iupbutton.d  -L-liup -L-liupcontrols -L-L/usr/lib/iup -L-lcdiup ;
gcc iupbutton.o -o iupbutton -g -lphobos -lpthread -lm -Xlinker -liup -Xlinker -liupcontrols -Xlinker -L/usr/lib/iup -Xlinker -lcdiup
[[email protected] iupbutton]$ ls -lh iupbutton
-rwxrwxr-x  1 ralsina ralsina 217K Apr 18 02:30 iupbutton

You will probably be linking a few libs too many, but don't worry yet.

The good news:

  • IUP works on windows and Unix.
  • IUP is an order of magnitude smaller than WxWidgets.
  • Most of it seems to be working.

The bad news:

  • IUP looks ugly because it's motif on unix.
  • IUP is pretty limited.

Someday, when I have a free afternoon, I could write a Qt backend for IUP and avoid the suckage plus porting it to OSX in the process, but...

  • IUP is damn hard to build. Luckily they have binaries.

Mandatory screenshot!

So, enjoy and comment!

2006-04-11 00:50

A match made in heaven

So, RH pays 350 millions for JBoss.

And here are some quotes the guys at the register have digged up:

Our own talks with RH broke down, RH is NOT IN THE BUSINESS OF PAYING OPEN SOURCE DEVELOPERS, we are, that is why we created JBoss inc. RH wanted to keep the services revenues all to themselves. That is the dirty little secret, so for them to come out and claim they are the open source when we know the reality is distasteful.

Honestly? I have had my troubles with RH in the past about their positions on KDE, and everything, but hey... at least I didn't later sell my children to them ;-)

OTOH, Fleury is quite a character. Or a raving paranoid :

Daddy, why are you still working on a Sunday? Is IBM still after you?

My bet: you will not hear anything from Fleury for a while. Then, in some time (I put the over/ under at october) he will discreetly resign/be fired.

2006-04-02 22:33

What I learned moving my blog

  1. PyDS is good enough to let you change how you host your site and keep it just working.

I switched from pycs.net (thanks for all the good work!) to a static site hosted at my ISP.

Since PyDS simply generates a whole lot of static HTML, this worked pretty good!

I generate the site, and then upload using lftp. No fuss, again, it just works.

  1. Static hosting sucks.
On pycs.net I had referrer logs, stats, comments. The static template from PyDS doesn't have any of that, of course.
  1. You can work around the suckage.

No comments? Haloscan can host them for you.

No stats? statcounter can do them for you.

No spam-free mail webform? I haven't looked yet, but I bet it exists someplace :-)

  1. You learn stuff.

I now understand how PyDS's macros/templates/nuggets/uploadings work. I thought I did. Now I do.

For example, I like comments for longer articles. Before, I added the links by hand. Now I just hacked the templates and it's done automatically. I could have saved a few hours of my life if I had bothered to learn it.

  1. Switching your URL sucks.
Since noone knows where the hell my page is. Luckily soon clee will switch me at planetkde.org and things will start to flow again.
  1. Depending on free hosting's tech support is not a good idea.

I love pycs.net. I loved how it worked. Until it stopped working.

I have no right to whine, though, so I offered to help (got no response yet). Then I moved out.

Since moving is annoying, I will probably not be going back, even if I start loving it again :-(

I am getting and reposting all the comments, but then gain haloscan has a 4-month limit on the comments, so I will have to implement some sort of comment-archiving and closing mechanism.

2006-01-11 12:36

2006 resolution

I will make some of my work public.

The best candidate is one that will probably not appeal to anyone: my personal linux distro.

I have it, I use it all the time. It's not published yet, though, since it consists of a base CentOS + a lot of work.

So, I will try to make it systematic, call it an installer, and drop it on the unsuspecting audience.

Don't hold your breath, though.

Here are some of the features:

  • Server oriented. I use it for my clients' servers.
  • Qmail+courier+vpopmail+roundcube+spamassassin+clamav mail system.
  • Squid proxy+fwbuilder firewall
  • Smart for package management
  • runit-based boot/services.
  • KDE as a GUI. Accssible via FreeNX/secure VNC.
  • OpenVPN for simple VPN management.
  • Custom cherrypy-based admin tools
  • No SeLinux (sorry, it's a pain in the butt. Secure, but a pain).
  • Bacula for backups
  • Custom tool to back the whole disk to a bootable DVD (System Rescue DVD)
  • /etc in SVN+Trac (yes, really, and the admin tools force you to use it)
  • Probably djbdns for DNS.

All in all, it's a pretty ordinary CentOS-based thing, except that the switch to runit makes service management way simpler and regular ( you can do things like having a non-root user that can manage some services, yay!)

On the other hand, the cherrypy-based tools would probably need a bit of a rewrite, since some are pretty cruddy.

Mostly, I have been gathering these pieces over the last 6 years as I really don't like the way any of the Linux server distros are built.

I based it on CentOS because doing the whole distro by hand is way too much work.

I can probably show it around June, if I don't get too sidetracked. Hopefully, someone will read this list and tell me "but graxzst linux already does all that!" ;-)

2005-12-16 14:27

Bound by Smoke I

This is what I understood of Smoke so far. I may be way off, since it is C++ sorcery of a higher level than I'm used to, but I really think I am getting the hang of it (and a bunch of thanks to Richard Dale and Ashley Winters who are the ones that made me understand so far. Any mistakes a re my fault, any good thing is theirs ;-).

This piece is only half of the story, though. Maybe one third.

Concept

Since Smoke's goal is to help you write bindings for languages other than C++, it provides a way to access Qt's API. The original thing about Smoke is that it does so by providing you with a smaller, more dynamic API that maps onto Qt's.

You could write a Qt C++ program using Smoke as the API instead of using Qt's. In fact, you can see it here written by Ashley Winters.

I had to rename it hello.cpp to make it work because that looks like C but may not really be C ;-)

As you can see, the Smoke version is quite a bit more complex than the Qt one. But that's ok, remember that the goal is a binding, which means that what you need to make your life simpler is less API... which is what makes the program more verbose.

Let's examine the Smoke hello.cpp in detail.

One key point is callMethod:

// call obj->method(args)
void callMethod(Smoke *smoke, void *obj, Smoke::Index method, Smoke::Stack args) {
        Smoke::Method *m = smoke->methods + method;
        Smoke::ClassFn fn = smoke->classes[m->classId].classFn;
        fn(m->method, obj, args);
}

If you have programmed in Python or Ruby or a number of other dynamic languages you may guess what this does already.

It takes as arguments a number of things which still have to be explained but the main gist is there is an object, there is a method, there are args, and it ends calling obj->method(args).

The first argument is a Smoke pointer , which is the big object in the Smoke library, created in our program by the init_smoke function.

A Smoke object is a strange beast. It contains a description (in this case, because we got qt_smoke) for the whole Qt API.

You can find classes in it indexed by their names, and methods for each class indexed by their names and types of arguments.

That is why you can have a generic callMethod that will work for any kind of object and for any method in the class, because all of them are somewhere in the Smoke object.

The second argument is void *obj which is the object itself we are manipulating. So, if you are trying to call QLabel::setText, it will have to be a Qlabel* casted as void*.

In the hello.cpp example, we even create these objects using Smoke's API (see later).

The third argument is a Smoke::Index which is what Smoke uses to find the requested method in its method table. This Index we get using the getMethod function, which is the second key piece of code:

// given class-name and mangled function-name, return an unambiguous method ID
Smoke::Index getMethod(Smoke *smoke, const char* c, const char* m) {
        Smoke::Index method = smoke->findMethod(c, m);
        Smoke::Index i = smoke->methodMaps[method].method;
        if(i <= 0) {
                // ambiguous method have i < 0; it's possible to resolve them, see the other bindings
                fprintf(stderr, "%s method %s::%s\n",
                i ? "Ambiguous" : "Unknown", c, m);
                exit(-1);
        }
        return i;
}

Here is an example of a getMethod call, where we are getting QApplication::setMainWidget

Smoke::Index method = getMethod(smoke, "QApplication", "setMainWidget#");

As you can see, we search for the method using strings of the class name and method name. Excapt for that pesky # at the end of setMainWidget#.

That is a basic argument-type-mangling scheme, since there can be more than one QApplication::setMainWidget on the Qt side of the fence, we are saying we want the one that has an object as the first and only argument. Here is the key to the mangling taken from smoke.h:

* The munging works this way:
* $ is a plain scalar
* # is an object
* ? is a non-scalar (reference to array or hash, undef)
*
* e.g. QApplication(int &, char **) becomes QApplication$?

I am not yet completely clear on how this is enough to do all the work (for example, what happens if you have two methods that take different objects as only argument?) but it's what I saw :-)

The last argument, args is of Smoke::Stack type, and it's the tricky one, at least for me.

Here's how it's used in the previous example, QApplication::setMainWidget

// qapp->setMainWidget(l)
Smoke::Index method = getMethod(smoke, "QApplication", "setMainWidget#");
Smoke::StackItem args[2];
smokeCast(smoke, method, args, 1, l, "QLabel");
smokeCastThis(smoke, method, args, qapp, "QApplication");
callMethod(smoke, args[0].s_class, method, args);

A Smoke::Stack is a way to pass the arguments to be used with the method getMethod gave us.

We first create an array of 2 StackItems:

Smoke::StackItem args[2];

Then we assign a value to the second of them:

smokeCast(smoke, method, args, 1, l, "QLabel");

Here l is a pointer to a QLabel. ( Ok, it is really declared as a void* because, remember, we are not using the Qt API, so we have no clue what a QLabel is ;-) and what we are doing is storing in args[1] a casted version of l.

The exact details of why you have to pass smoke and method are not that important, and they seem pretty involved, so I won't try to go there, at least not yet. This has to be done for each argument for the method.

Then we have a similar, yet different line:

smokeCastThis(smoke, method, args, qapp, "QApplication");

This puts the qapp void * in args[0], casted to QApplication. There are tricky C++ reasons why this is done slightly different here than on smokeCast, which I am not 100% sure I get right, so I will keep quiet ;-)

This special case is only for the object to which the method belongs (the this object).

Here is the code for smokeCast and smokeCastThis

// cast argument pointer to the correct type for the specified method argument
// args[i].s_class = (void*)(typeof(args[i]))(className*)obj
void smokeCast(Smoke *smoke, Smoke::Index method, Smoke::Stack args, Smoke::Index i, void *obj, const char *className) {
        // cast obj from className to the desired type of args[i]
        Smoke::Index arg = smoke->argumentList[
                smoke->methods[method].args + i - 1
        ];
        // cast(obj, from_type, to_type)
        args[i].s_class = smoke->cast(obj, smoke->idClass(className), smoke->types[arg].classId);
}

// cast obj to the required type of this, which, dur to multiple-inheritance, could change the pointer-address
// from the one returned by new. Puts the pointer in args[0].s_class, even though smoke doesn't do it that way
void smokeCastThis(Smoke *smoke, Smoke::Index method, Smoke::Stack args, void *obj, const char *className) {
        args[0].s_class = smoke->cast(obj, smoke->idClass(className), smoke->methods[method].classId);
}

But where did we get l or qapp? You can use these same mechanisms to create an object:

void *qapp;
{
    // new QApplication(argc, argv)
    Smoke::Index method = getMethod(smoke, "QApplication", "QApplication$?");
    Smoke::StackItem args[3];
    args[1].s_voidp = (void*)&argc;
    args[2].s_voidp = (void*)argv;
    callMethod(smoke, 0, method, args);

    qapp = args[0].s_class;
}

You get QApplication::QApplication(scalar,undef) which should hopefully map to QApplication::QApplication(argc,argv). You create a Smoke::Stack of 3 items. The first is unset because this is a constructor, so it has no this yet, and the other two are argc and argv.

Then you call it through callMethod, and you get the resulting object via args[0].s_class.

Later you repeat this sort of operation for every method call you want, and you got yourself an application.

The binding side of things

So, how do you use this to bind your language to Qt?

Well, you will have to create an object in your language called, for example, QApplication, and map the "missing method" mechanism (your scripting language probably has one) which is used when a method is undefined so that somehow it finds the right Smoke method (mangling the name correctly should be the hard part), then create the Smoke::Stack with the passed arguments, call, get the result, wrap it in some language construct you can use of the side of your language, and pass it back.

It looks involved, and I am sure it's tricky, but at least it only has to be done once unlike on traditional bindings, where you had to do it for every class and for every method.

The traditional solution was to automatically generate the code for such wrapping (like SWIG does). I think Smoke is less error prone.

If I keep on understanding things, there may be a second part of this article, explaining the SmokeBinding class, and perhaps a short example of how to bind Qt into a language (Io is a strong candidate).

The regularity of Io's syntax is probably going to make the binding simpler than most.

2005-12-12 19:47

Ok, so, I am a lazy guy

I just realized I have not learned a whole new real language in almost 5 years.

I have learned a few dialects, some minor stuff to work around or through an obstacle in some project, but I have not written a whole program in anything but python since 2001.

So, since I don't want my brain to turn into muesli, I will now proceed to learn Io .

Nice OO language, prototype-based, which is something I haven't run into outside of JS, I think, a sort of LISPy flavor, with a dash of smalltalk for piquancy.

Maybe I will get really bored with it, maybe not :-)

And yes, the previous post was about having the idea of hacking a Qt binding for it, but it's probably not doable right now, since extending the language is pretty much undocumented, and extending it in C++ is unheard of.

To top that, it uses continuations, which probably cause all kinds of hell on Qt's memory management :-(

2005-12-12 12:30

PlanetKDE, point me in some direction, please!

I have been trying to figure out how to use libsmoke from kdebindings for a few hours.

So far, I have been unable to find any kind of documentation whatsoever.

If anyone knows of something (short of reading the ruby bindings, for instance ;-) I would be thrilled.

Addendum: I just found on google that there is a whole language with Qt bindings I had never heard of!

http://www.clifford.at/spl/

2005-10-17 17:30

A *real* programming challenge.

A long time ago, I wrote a piece about how I didn't like kcalc. It contained a very lame pyqt script showing a (IMHO) nicer calculator. Strangely, that lead to two very cool implementations of the concept!

One of them was written in Ruby, the other one in C++. I think that has some potential.

A few months later, I wrote a spreadsheet based on the same concept. Also based on PyQt.

This StupidSheet has some conceptual problems. Like, if you want to import Excel sheets, you would have to rewrite basic in python, so it's not a practical program, but it is a rather nice example showing programming using dynamic languages.

In fact, I used it as such last week at CafeConf.

Now, here's the challenge. If people that know how to write Ruby or Java apps using Qt (or KDE, why not) could write a similar application, we all could write a comparative guide to Qt/KDE programming on different languages.

Since we would all be starting with a not-too-complex, but really non-trivial example, and we would all do the same one, it should be pretty unbiased.

In fact, if you think this example is biased, please propose another one, and do this thing anyway.

You can find StupidSheet here

It has some small bugs (try setting B1 to A1+1 with no value in A1 ;-) but they are easy to fix.

We could remove some features (like the weird pasting stuff) to make the example more didactic.

I hope this gets some answers :-)

2005-08-02 19:17

Deployments and stuff

Have been reading the planets lately (I mean planetkde.org and planet.gnome.org, not astrology) and run into posts by Aaron Seigo and Luis Villa which are, let's say, interesting.

Luis' post took me to this page which is interesting too, and I would like to see something like it for KDE (and I am sure it is somewhere, but I can't seem to find it)

And I don't mean the page is interesting only for having Australia listed as an asian country ;-)

Some of the items talk about hundreds of thousands (or hundreds of millions) of desktops, and others talk about 11 seats.

Is there nothing in the middle, or is it just not reported?

I decided to put out another datapoint.

Here in Argentina, the best-selling OS has KDE as the default desktop. It's a Linux from Pixart , and is more or less what on other countries is sold as Xandros.

It seems Pixart made some development work for Corel, and then for Xandros when they bought the linux distro business. Their boss is the former (?) boss of Corel argentina, too.

Almost every whitebox clone is sold with one of their distros installed and preconfigured.

Oh, sure, most of them get wiped out and replaced with a stolen windows xp in 24 hours, but it's quite a number. Think 100K or 200K sold each year, at least.

Of some concern is that some of the GNOME deployments used to be KDE deployments. For example, the Sao Paulo telecentros used to be Conectiva boxes with KDE (and windows, in dualboot).

The City of Largo used KDE for quite a while.

But what the heck, we are both desktops squeezed into a ketchup bottle, there's a whole world outside to spread into ;-)

Contents © 2000-2018 Roberto Alsina