Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

scrottie (4167)

scrottie
  scott@slowass.net
http://slowass.net/

My email address is scott@slowass.net. Spam me harder! *moan*

Journal of scrottie (4167)

Friday March 06, 2009
03:34 AM

GUI app retargeted from SDL to Web with just a little glue

[ #38603 ]

I was doing some SDL stuff for work and wrote a little wrapper around SDL to make it a bit easier to use. SDL's blit() function wants four arguments, two of which want four more arguments. Really all it needs for the common case is the image to blit and the x, y coordinates to blit it to, called as a method in the target image.

I wrote this app for my own use. I wanted to be able to visualize where the buses were (or rather, where they're supposed to be) when I'm standing at a corner. That way, if I'm going north-west, for example, I know whether to expect a west bound bus first or a north bound bus, or whether I should just start walking. The bus system in Phoenix isn't great. A lot of the time, you'll get there sooner if you just walk a few miles. A previous post talks more about this. Short version is, I have an SDL based app that has a scrollable map with an adjustable "current time", that shows where all the buses are supposed to be at that time. I scraped their website and did my own geocoding. Bus locations are interpolated between stops on the time table.

Having that for myself, the next step was sharing it, and that meant Web, or possibly, an iPhone app or the like.

Turns out that it was easy to retarget it to the web, just by replacing my SDL wrapper. Rather than using SDL, it uses GD. I had to rework the original and the other wrapper a bit but the program is basically agnostic about which it works under.

The window gets output to the browser as one big inline, base64 encoded image with the ismap attribute set. You may have forgotten about this attribute. When an image is inside an anchor (a) tag, ismap causes the x, y location of the click on the image to be added to the URL in the a href.
Eg:

  <a href="foo.cgi"><img src="whatever" ismap"></a>

A click on that image might cause a hit to, for example, foo.cgi?10,20.

One of the handy things in the wrapper around SDL was a AWT 1.x-like click callback system. Any time a graphic gets blitted, it optionally includes a coderef to be called if the region it gets blitted to gets clicked. In the SDL version, mouse clicks were propogated to the correct callback. In the web version, these ismap clicks are. And of course, the thing was built on top of Continuity. At the end of the request loop, it does this:

        my $get_string = $request->request->url->as_string;
 
        if($get_string and $get_string =~ m/\?\d+,\d/) {
            $graphics->hit($get_string =~ m/\?(\d+),(\d+)/) or $draw_playfield->();
        } else {
            $draw_playfield->();
        }
 
        my $png = encode_base64($app->png, '');
 
        $request->print(qq{
            <a href="/"><img src="data:image/png;base64,$png" ismap border="0"></a>
 
        });
 
        $request->next;

That's inside of a while(1).

At first, I tried using the bmp dumping methods of SDL, but the images came up blank, and trying to call flip or anything like that made it coredump.

Actually, SDL has been a huge thorn in my side. I'm trying to think how I could finagle using GD as a graphics toolkit for an X window. Some X11::Protocol glue, maybe... or maybe I'll just pick Prima up again.

So, the thing is up at http://slowass.net:8445. Or at least it is sometimes.

It needs a few more things... some the geocoding is wrong, and I need to get another font going for display bus info when individual buses are clicked. It should default to the current time. Buses should indicate which way they're going, which means I need another graphic for them than little balls.

I also made a movie: slowass.net/~scott/bus.mpg.

That was a bit ago, but I thought I'd finally write this up and share.

If there's interest, I might fix up my wrappers and release them as a pair of modules with the same API, one for web, one for desktop, but I'm still hung up on a few things, such as SDL refusing to render anti-aliased text because it wasn't built with SDL_mixer (wtf?) and taking all available CPU when the event loop is called (gah!). And there's the temptation that if I'm going to release a GUI toolkit, it should be a bit more interesting than just smearing text and images around a pane with callbacks for clicks. Right now, there's no provision at all for data entry fields. The good, nice way to do this would be to add a Web backend to Prima.

-scott

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • I know you're doing your own thing, that's cool, but maybe it'd be simpler as a google map app? (If possible.) I guess the problem would be updating the data.

    What you're doing reminded me incidentally of using Processing [processing.org]. It's possible to export as either a Java app or as an applet for a browser. (The main problems for me with Processing are: 1) it's Java-based, 2) the IDE seems buggy in Linux (at least I had problems sketches, as it would freeze the IDE).)

    • Yeah, this should have been a Google Maps app. I looked at the API briefly but felt bogged down. Also, I don't have GPRS/EDGE any more, so I wanted something that worked off-line with the on-line version being an after thought. I have played with Processing a bit. Where I got stuck with it was CPU usage and the Flash-like fps thing, where it tries to draw so many frames per second regardless of whether anything has changed on the screen. It had some threads that were very CPU hungry that I really didn'