biappi.nnva.org

Latest Entries Tagged "Coding"

This is the listing of all the posts that are have the "Coding" tag, if you want to read all entries, go to "Blog Index".

Twitter + Quicksilver = TwitterSilver!

3 september, no comments, mind to share your impressions?

I'm a HUGE fan of Quicksilver, i simply cannot use a pc that lacks it. Right now, i'm using for few things, app launcher, iTunes control ("pp" FTW), and to browse my contacts when i need to send an email.

On the other hand, i'm not that much an user of Twitter, but i know some really cool people there and once in a while i check it out. I tought, maybe i'll use it a bit more if i can use it the way i use the rest of software, like when the IM support was working, for example.

So, as an excuse to start editing some code, i brushed up my old post on Python, plugins and Adium and started VIM, my console-editor of choice (the other beings TextWrangler and Xcode).

Turns out that Quicksilver is an half-dead project, and docs is really non-existant, but i managed to found some good posts about Quicksilver plugins.

That, and what i've learnt from my previous approach, helped me to bake in roughly an hour TwitterSilver, the Quicksilver Plugin that Tweets!

Of course you can download and use it, and, surprise, i'm using it to introduce my brand new code repository at Google Code, where you can find lots of non working vapourware!

To get started, simply do in a Terminal window:

Xanthia:~ willy$ svn checkout http://biappi-repo.googlecode.com/svn/trunk/TwitterSilver TwitterSilver
[...]
Xanthia:~ willy$ cd TwitterSilver/
Xanthia:TwitterSilver willy$ python setup.py py2app
[... lots of input ...]
Xanthia:TwitterSilver willy$ echo "USERNAME PASSWORD" > ~/Library/Preferences/org.nnva.biappi.TwitterSilver 
Xanthia:TwitterSilver willy$ open dist/TwitterSilver.qsplugin/

then, open Quicksilver, press "." to input some text, then select "Send Tweet to Twitter" action!

I hope this can be useful to someone =), if you're using it, let me know! =).

Tags for this post: Coding, Python

I'm Really That Crazy

1 september, no comments, mind to share your impressions?

What you can do with no Internet connection, a compiler, and lots of spare time on vacation?

Yup, I managed to write a small and buggy blog editor for updating my blog via Zoe, my little iPhone!

This is, in fact, the first post i'm writing with this editor.

It uses the MetaBlog interface, so it would even work with other blog engines, but I do not trust my coding skills =).

However, I don't know what to do with this piece of code, maybe I'll refine it a little bit and put it as a freebie on the App Store, we'll see...

If that do not violate the FUCKING NDA, I can even think to publish the sources!

Anyway, back to coding =).

Ah, just to be clear 'bout that. FUCKING NDA.

Tags for this post: Coding, Apple, iPhone

Feed Couch, Revisited

4 july, no comments, mind to share your impressions?

Remember my feed reader?

Well, i had to add more eye-candiness to get my grade, and it seems Cisternis' liked it, i got 30/30 cum laude =)

This is a screencast:

The concept is quite simple, you get the last 5 entries of the Safari's subscribed feeds, and you navigate them with the Apple Remote.

The code has a little... ehm.. "shortcut" i don't like at all, but i had to do it really fast, and i didnt want to refactor the code 30 minutes before the exam, but...

You can downoad Feed Couch Source Code

It includes the MIT-Licensed Remote Control Wrapper by Martin Kahr. Thanks, Martin!

Tags for this post: Coding, Safari, Core Animation

First post from Mars Edit!

25 june, only one comment, mind to share your impressions?

I wanted to try this for a long time, but i never had the willings to implement the protocol bits. Don't know how, but i'm in a hack-my-blog mood, so here we are...

I've implemented a partially working Meta Weblog API that allows me to use a blogging client like Mars Edit to write my blog posts!

Working with Python is really a pleasure...

Right now my implementation lacks a proper authentication, i just check my credentials as "magic numbers", edit and tag support.

I don't think i'll ever address the auth thing, but if i'm in the mood of completing this thing, at least to allow basic post editing, i'll release the script...

Well, don't know if it will be useful to anyone, since it's tied to my model classes, but maybe it will be a good starting point, or an example, i don't know.

Of course, if you want it right now, just shout in the comments =).

Tags for this post: The Future, Coding, Django

On Memory Management And Garbage Collection

19 june, no comments, mind to share your impressions?

At WWDC i've had the chance to meet many different kinds of developers: the "shareware student", the indie "bigs", the employee of big companies, even some IT guys.

For me, with the little experience i have, it was a big chance to relate with others, and get inspired. I've realized that living in a rich environment stimulates you, it makes you more productive by putting you in "the right mood" to actually start and getting some things done!

Talking to some people, conversation naturally shifts to the tools we use, as computer programmers, developers and scientists. And as anyone knows, those topics are a rough equivalent of religion. Church of VIM, church of Emacs, the Ruby vs Emacs... you name it!

After the light fights of text editors, the turn of programming languages arrived, and i got really "ignited" when i've heard something in the line of "i hate objective-c because it lacks garbage collection, objective-c 2.0 is muuuuuuuuuuuuuuuuuch better.. why i have to manage my memory!".

Now, let me state that i love GC and i use it actively, BUT as i say, "as a programmer you've got to know every other byte in the address space your application run".

Now i really was the guy from the outer space, actually liking all that retain and release methods, malloc() and free() functions... i really had to be some strange, uncommon alien.

But now, let me exapand a little on this, which i meant to be this post's topic.

Of course you'll use GC, automatic memory managment and a whole set of tools to make your job easier and less error-prone, but you do not have to forget what you're actually doing, you've to carefully know what choices you've made, yourself or by using a determined set of tools.

A computer really is nothing more than a thing that computes things on memory, just that. Every other piece of software or hardware is just something that can be seen as piece of memory or piece of "something that computes".

The monitor you see this website is basically a matrix of pixel in memory, the mouse and keyboard are really a small number between other 2^32, disks, something more, but substance doesn't change that much.

It's not by chance that the kernel of an operating system simply is nothing but a manager for the computational resources - the scheduling part - and the memory resources - the virtual memory, paging on disk, et cetera.

Managing computational resources used to be simple, you take the processor do some work, then kindly release it so other can use it.

We know this is changing with time: we're heading at multicore machines, and bla bla bla.. all things you already know if you're not living inside a bunker.

Scaling used to be very easy too... just wait til intel or amd build a faster cpu and your program run faster.

Memory is really another beast.

First thing first, memory costs. Because of that cost we've designed a memory hierarchy, exploiting the fact that memory the slower is, the cheaper is, and usually at minus cost per bytes.

Because of that hierarchy we have introduced a bit of time delays in transferring chunks of memory between layers, if you do opengl stuff just look at texture management.

Sometimes when programming it's useful to have in mind that memory caching *does* affect performance. One notable example, the radix sort: despite being linear, it's execution time is often greater than comparison sorts, with their O(nlogn) scores. [The Influence of Caches on the Performance of Sorting - LaMarca and Ladner]

Translation: because of caching, a program theoretically blazing fast, is actually slower than a program theoretically fast, but not blazing.

Then, as a consequence of memory being costly, memory is small. And already packed up with code and resources. And our dataset. But that's an abstraction, in reality we have that our memory is shared between all the other programs, and we have to play nicely on that!

In particular, allocation and deallocation of memory are operations that take some time to do, so it's better to do it well.

Even if you're using garbage collection, you need to know what it does, and how. Like any other tool you have to know its strenght and weakness in order to master it.

Tags for this post: bla-bla, Coding

Runtime Dynamism With Objective-C

20 may, no comments, mind to share your impressions?

Ok, this blog is rarely updated, do i have to apologize every time? No, i don't. :P

With this new iPhone/iPod SDK some friends of mine began writing in Objective-C after ages of Java or C++. Yay for them!

I wanted to show 'em a lil bit of dynamism the objc runtime offers to us. Today, my fellow readers (do i have even one?), we'll try to instantiate an object of a class unknown at compile time.

So, let's start with a basic objc class (no cocoa there)

@interface UsefulClass : NSObject
{
}

-(void)doSomething;

@end;

@implementation UsefulClass

-(void)doSomething;
{
    NSLog(@"Hello, World!");
}

@end;

Indeed this class is really useful.

Let's instantiate it, shall we?

UsefulClass * uno = [[UsefulClass alloc] init];
[uno doSomething];

Nihil sub sole novum, that's just Obj-C 1-0-1, but what if we want to instantiate another object the same class of "uno"?

We can track "uno"'s type just by declaring a class variable, then just asking "uno" itself!

Class unknownClassToInstantiate = [uno class];
id trallalla = [[unknownClassToInstantiate alloc] init];

Yep, it's that simple!

We find out the class with the class message provided by all NSObject-compliant object, which appens to be all objects in a Cocoa environment, then we treat the class variable just like a "real" class name!

It's a matter of alloc/initing the new object!

Now just do that in C++ ;).

Tags for this post: Coding

Look ma, i'm on the news!

4 april, only one comment, mind to share your impressions?

"Pisa, 36 ore in diretta per iPhone" - Punto Informatico.

I feel so important now. =)

Tags for this post: Personal, Coding, Apple, iPhone

The Non Bug

5 march, no comments, mind to share your impressions?

I hate bugs.

But i hate the non-bugs more!.

I've spent the last two hours debugging a non-bug: i was inspecting my variable using the IDE tooltips, but gdb had really another version of the story.

The non bug

(click for the image in its full glory.)

Shit.

Tags for this post: Coding

Extending Adium With Python!

2 march, only one comment, mind to share your impressions?

My journey into Cocoa APIs continue, i've touched Core Audio's Audio Units, Core Animation, a little bit of reversing the Dock, i even tried to tie cocoa to gtk, without good results.

Now it's time for the pyobjc.

I'm a big fan of python, but i havent used it since i use os x as my main operating system. Say i've no time/will to code yet another vapourware, or say Cocoa and Objective C are as fun to use as python, whatever...

The idea of bridging Pyhton and Cocoa is wonderful, one can literally have the best of both worlds, so to speak.

It's plenty of python-cocoa tutorials out there, but i wanted to do a slightly more challenging thing. I'm Biappi, i like to make my life harder. The challenge was: it is possible to write a plugin for an existing Cocoa application, say Adium, with new custom python code, maybe for implementing a new protocol?

Well, it's amazing that the bridging script makes all this a no-brainer! The coolest part is: you don't have to modify the host program codebase, or to make an Objective C wrapper to the python code! It's all handled out-of-the-box by the pyobjc bridge!!!

Shocking!

My goal was to write a simple protocol for Cocoa that registers a few contacts and echoes back any message sent to them.

First you've got to familiarize with the cocoa to python naming conventions, which are very straightforward, then the first gotcha: how we make a python-written loadable bundle?

Enter py2app an amazing distutil script that addresses this very purpose.

Just set a setup.py file for your bundle that reads, more or less, like this:


from distutils.core import setup
import py2app

setup(
    plugin = ['Prova.py'],
    options = dict(py2app=dict(extension='.AdiumPlugin',
        plist=dict
            (NSPrincipalClass='Prova',
             CFBundleSignature='AdIM'),)),
)

This setup script tells distutil and py2app to create a bundle with the file Prova.py, with an extension of AdiumPlugin, then we have a way of writing into the Info.plist file for the bundle, in which we can specify the NSPrincipalClass and the CFBundleSignature fields.

I don't want to insult your intelligence by pointing out that if you want to do a plugin for something else than Adium, you'll have to change signature and extension :).

Now let the magic happen:


python setup.py py2app

This simple command will spit out a Cocoa bundle ready with a self-contained python interpreter, your own code, and a way to trasparently load the thing!!

Now we should have to write the code we'll be loading.

Writing code in Python for Cocoa is not really that different from writing pure python code, but there are a few gotchas.

Since we're writing a plugin, we'll probably want to extend some host's base class, like in the Adium case: we'll have to let python know about all the classes we want to extend. Python is an highly dynamic language, we don't need linking et cetera: for our little Adium plugin we'll need a few classes, let's say "AIPlugin", the base class we'll have to extend. It's as simple as:


class Prova(AIPlugin):
	pass

but we need a way to let Python know about the AIPlugin class. Well, the thing to do is:


AIPlugin = objc.lookUpClass("AIPlugin")

That is: we're looking up the objective-c "AIPlugin" class from the objective-c runtime, and getting a reference to it in the python runtime.

Since our script will run as a plugin inside Adium, the "AIPlugin" definition will be in the objc runtime support, and we subclass it at runtime.

That's dynamism.

Then you can override objc methods with python code. Now, gotcha no.2: let's say you want to call the super implementation: that's a bit different from python: we'll have to ask the objc runtime the super class reference, for example:


class ProvaAccount(AIAccount):
	def disconnect(self):
		objc.super(ProvaAccount, self).disconnect()
		self.setStatusObject_forKey_notify_(NSNumber.numberWithBool_(True), "Disconnecting", True)

The last gotcha i've found is how to obtain an instance variable: you've to explicitly tell the bridge you want an objc ivar.

Well, this is easy done, just:


python_var = objc.getInstanceVariable(self, "objcVariableName")

Maybe there are other ways to do it, but this one works well.

Now you know how to build a loadable bundle plugin in python for almost any expandable cocoa program!

Tags for this post: Coding, Leopard, Cocoa, Python

Feed Couch, My Front Row-esque Feed Reader

6 february, no comments, mind to share your impressions?

Computer Architecture, it's been a while, but now it's over, babe.

Now i'm banging my head against the GUI class: i'm coding a Front Row-like feed reader, with lotsa of Leopard juice in it!

Seriously, Core Animation really kicks ass, i've a couple of problems, but i'm pretty sure it's mine fault, i'm not really into graphics... i'd have to find what i'm doing worng.

On the other side, the Publication Subscription framework does its job nicely. It's really a joy to work with such easy and high level APIs, even for toy projects like this.

So, my fellow readers, what does it looks like, you might ask?! There you go, another youtube screencast! :)

Yep, it's pretty basic, but it does the job, however for my grade i need a bit more eyecandiness, i'm working on it, when i'll be done i'll post the sources.

And since we're talking about it, what features you'd like in a full-screen reader? I'm kinda short of ideas :).

Tags for this post: Coding, Leopard, Quartz, Core Animation

Handling Files in Audio Units

11 january, 3 comments, mind to share your impressions?

Alone in the uni's lab, who want to study?! :)

When coding that little thing of yesterday i found out that the documentation on audio units is really flacky, so i think could be useful to post about the thing i had troubles implementing.

The Audio Unit SDK comes with a bunch of base classes to help you developing your plugin, AUBase, AUEffectBase and so on. They provide a default implementation for parameter handling, scoping and persistance, and they're really good at it.

The main issue is: audio unit parametrs are only Floats, and i needed to store the sample file name string. First thing first i had to let the user select the file, this seems to require a custom UI, so i had to fire up Interface Builder and cook up that masterpiece you can see in txVtt. A button that trigger a NSOpenPanel is sufficient, at least fo me.

Then i had to communicate the filename from the UI to the AU itself. In the Audio Unit world a plugin and its ui are completely different things (like it should be with every software :P), and AUs and their UI talk via Properties.

I've assumed that both the AU and the UI run in the same address space, and i don't know if this will always the case, this means i've made a CustomProperty that holds only one pointer to a CFString.

ComponentResult	txVtt::GetPropertyInfo (AudioUnitPropertyID inID,
	AudioUnitScope	inScope,
	AudioUnitElement	inElement,
	UInt32 & 	outDataSize,
Boolean & 	outWritable)
{
	if (inScope == kAudioUnitScope_Global)
	{
		switch (inID)
		{
			case kFilenameProperty:
				outWritable = true;
				outDataSize = sizeof (CFStringRef);
				return noErr;
		}
	}
	
	return AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
}

That's how i've declared it in my GetPropertyInfo method, simple as that.

Once you've defined it, you have to write its accessors in the GetProperty and SetProperty, please forgive me if i don't copy and paste the code here, i'm noticing that my template isn't too much code-friendly :).

One improtant thing, tought. When declaring the SetProperty you can specify a ComponentError error code, that's theway to deal with errors such "File Not Found", "Permission Denied" etc...

Ok, we're half done now.

Persistence in Audio Unit is implemented by the required ClassInfo property, that represents the current state of the plugin instance as a plist dictionary. AU hosts that want to save the current state of the plugins simply dump the informations encoded in this property.

Oddly enough, you can't override the GetProperty to modify the state of the ClassInfo dictionary, because AUBase handles it all by itself before calling your GetProperty implementation.

Instead, one has to override the SaveState and LoadState methods. You can add items to the dictionary just like every CFDictionary. Keep in mind that you're adding items to a plist, you can only store only a few data types. (CFString, CFNumber, CFBoolean, CFDate, CFData, CFArray, and CFDictionary according to plist(5) man page.)

Notice that CFUrl is missing here, one has to use a CFString, and pray for not having encoding normalization issues :).

Here is the implementation i've used, hope it can be useful to someone.

ComponentResult txVtt::SaveState(CFPropertyListRef * outData)
{
	ComponentResult result = AUBase::SaveState(outData);
	
	if (result != noErr)
		return result;
	
	if (filename != NULL)
		CFDictionarySetValue((CFMutableDictionaryRef)*outData, kFilenameString, filename);

	return noErr;
}

ComponentResult txVtt::RestoreState(CFPropertyListRef plist)
{
	ComponentResult result = AUBase::RestoreState(plist);
	
	if (result != noErr)
		return result;

	CFStringRef newFile;
	if (CFDictionaryGetValueIfPresent((CFDictionaryRef)plist, kFilenameString, (const void **)&newFile))
		LoadFile(newFile);
	
	return noErr;
}

One final note: when adding key-value pairs in the ClassInfo dictionary, it is good practice to prepend your key string with something unique to you, to avoid name clashes. At least that's what the AU docs said, i don't know when or what is allowed to modify that dictionary :).

That's it, how to handle file parameters when writing Audio Unit plugins. I don't know if it's the right way to do it, it works for me, but there may be better ways to do it, surely there are much worse.

I hope you'll find this post useful, it would have helped me a lot in those days :).

Tags for this post: Coding, Apple, Audio, Recording, Audio Unit

A New Open Source Audio Unit!

10 january, no comments, mind to share your impressions?

Plugins are cool.

They're small, little pieces of code that hook into another application to enhance it, usually you can even chain different plugins to achieve even greater effect.

But the thing i like: they're small, little pieces of code!! Read: it's not too complicated to write one.

If the API is.. well.. doumented.

That's the story of my first Audio Unit plugin, and why it's cool to have its source code!

Back in the days, when linux was my only OS i've been fascinated by a great app: terminator X. It's a cool little app that makes you scratch your audio files like vinyl on a turntable, if you don't mind using the mouse for this.

Running it as-is it's a bit complicated on Os X, it involves using an X server because it's GTK, and it requires the Jack Audio Connetion Kit, which is really nice, but it doesn't really fit in the Apple's enviroment, at least for me.

So I took the opportunity and a bit of spare time to learn to use the Audio Unit API and to port a subset of terminator X.

Please keep in mind that this is a proof of concept thingy, so don't expect the usual polish of mac software. What I mean with "proof of concept" is "something i've done in a couple of days that kinda work but i don't really know..."

The AU demonstrates how to provide a Cocoa UI (even if mine currently is only a black rectangle), how to chain UI parameters to the DSP code, and few bits of cool stuff like storing custom properties in the Class Info dictionary, it was something i couldn't find any description online!

To use the AU compile it and place it in your ~/Library/Audio/Plug-Ins/Component folder.

The ui is quite spartan, you get two buttons, to load a sample and to trigger it, and a black rectangle. The sample keeps looping until you click on the black rectangle, then you can move the mouse to "scratch", then click again to return to the normal looping.

The thing for now supports only mono .wav, but one can easily link the wonderful libsndfile just in minutes.

That's it, at least for this pre-pre-pre-alpha version :). Also that's my first code "release" so maybe you have to work a bit on the XCode project file to strip my options :D

I've tested it with AU Lab and it passes the auval test suite.

I plan to work a bit on this little prog, drop a line if you're interested in it, or something! :)

Just don't expect a full fledged plugin in a couple of weeks.

One important note: all files whose name begin with "tX_" are by the original author of terminator X and are under the GPL license, the files that begin with "txVtt_" are by me and i have to choose a license, so for now consider them to be on public domain.

Get The Code

Tags for this post: Coding, Audio, Recording, Audio Unit

GTK-Quartz Integration Round Two

28 october, no comments, mind to share your impressions?

Ockay, i know, it's a long long time since i wrote something here, so blame me!

A while ago i had a bit of hacking in the gtk-quartz thing of mine, but i got stuck in debugger-land, and now i've really no time (and maybe no more interest :P) on going forward.

I left you with an half functioning GTK window in a Cocoa view; the widgets were there, but they were not drawing themselves.

I found a way to let the GDK_EVENT_EXPOSE event do its job by resetting the GDK_WINDOW_STATE_WITHDRAWN bit on the main GTK widget;

	gdk_synthesize_window_state (wid->window, GDK_WINDOW_STATE_WITHDRAWN, 0);

Now, as i told you, we're stuck in debugger land, in the nearings of Pango rendering: i got an EXC_BAD_ADDRESS exception in this function:

/* cairo path -> execute in context */
static cairo_status_t
_cairo_path_to_quartz_context_move_to (void *closure, cairo_point_t *point)
{
    //ND((stderr, "moveto: %f %f\n", _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y)));
    CGContextMoveToPoint ((CGContextRef) closure,
			  _cairo_fixed_to_double(point->x), _cairo_fixed_to_double(point->y));
    return CAIRO_STATUS_SUCCESS;
}

which renders the Pango glyphs using Core Graphics.

I had some strange ideas on making GTK using directly the string drawing functions of Core Graphics bypassing Pango directly, but it's a long way and i still have to graduate :P.

Here is a (really long) backtrace, if you have a clue let me know :).

(gdb) bt
#0  _cairo_path_to_quartz_context_move_to (closure=0xfcc6f10, point=0xf0b11074) at cairo-quartz-surface.c:143
#1  0x13551a52 in _cairo_path_fixed_interpret (path=0x142dd9f4, dir=CAIRO_DIRECTION_FORWARD, move_to=0x1357bafc <_cairo_path_to_quartz_context_move_to>, line_to=0x1357bb4a <_cairo_path_to_quartz_context_line_to>, curve_to=0x1357bbe8 <_cairo_path_to_quartz_context_curve_to>, close_path=0x1357bca3 <_cairo_path_to_quartz_context_close_path>, closure=0xfcc6f10) at cairo-path-fixed.c:477
#2  0x1357bd00 in _cairo_quartz_cairo_path_to_quartz_context (path=0x1, cgc=0xfcc6f10) at cairo-quartz-surface.c:201
#3  0x1357c367 in _cairo_quartz_surface_intersect_clip_path (abstract_surface=0x142dd580, path=0x142dd9f4, fill_rule=CAIRO_FILL_RULE_WINDING, tolerance=0.10000000000000001, antialias=CAIRO_ANTIALIAS_DEFAULT) at cairo-quartz-surface.c:1422
#4  0x12705758 in _cairo_surface_set_clip_path_recursive (surface=0x142dd580, clip_path=0x142dd9f0) at cairo-surface.c:1649
#5  0x12705831 in _cairo_surface_set_clip (surface=0x142dd580, clip=0x142ddc14) at cairo-surface.c:1688
#6  0x126fb594 in _cairo_gstate_show_glyphs (gstate=0x142ddb90, glyphs=0xbfffbbf0, num_glyphs=4) at cairo-gstate.c:1425
#7  0x126f6f7b in cairo_show_glyphs (cr=0x142dd790, glyphs=0xbfffbbf0, num_glyphs=4) at cairo.c:2539
#8  0x12640231 in pango_cairo_renderer_draw_glyphs (renderer=0x14345888, font=0x14199028, glyphs=0x14306060, x=0, y=0) at pangocairo-render.c:234
#9  0x1266e194 in pango_renderer_draw_glyphs (renderer=0x14345888, font=0x14199028, glyphs=0x14306060, x=0, y=0) at pango-renderer.c:595
#10 0x126406dc in _pango_cairo_do_glyph_string (cr=0x142dd790, font=0x14199028, glyphs=0x14306060, do_path=0) at pangocairo-render.c:440
#11 0x1266e194 in pango_renderer_draw_glyphs (renderer=0x141935d0, font=0x14199028, glyphs=0x14306060, x=10240, y=18432) at pango-renderer.c:595
#12 0x1266f417 in pango_renderer_draw_layout_line (renderer=0x141935d0, line=0x1417d9c8, x=10240, y=18432) at pango-renderer.c:526
#13 0x1266f7ab in pango_renderer_draw_layout (renderer=0x141935d0, layout=0x141fd9e0, x=10240, y=5120) at pango-renderer.c:183
#14 0x124ae7d8 in gdk_draw_layout_with_colors (drawable=0x13f2e160, gc=0x1417fb48, x=10, y=5, layout=0x141fd9e0, foreground=0x0, background=0x0) at gdkpango.c:951
#15 0x124aeaa3 in gdk_draw_layout (drawable=0x13f2e160, gc=0x1417fb48, x=10, y=5, layout=0x141fd9e0) at gdkpango.c:1013
#16 0x11a50524 in gtk_default_draw_layout (style=0x191c400, window=0x13f2e160, state_type=GTK_STATE_NORMAL, use_text=0, area=0xfa00bac, widget=0x14184010, detail=0x11b2df3c "label", x=10, y=5, layout=0x141fd9e0) at gtkstyle.c:5082
#17 0x119b8772 in gtk_label_expose (widget=0x14184010, event=0xfa00ba0) at gtklabel.c:2499
#18 0x118de5e0 in gtk_accel_label_expose_event (widget=0x14184010, event=0xfa00ba0) at gtkaccellabel.c:314
#19 0x119ccd2f in _gtk_marshal_BOOLEAN__BOXED (closure=0xfce10b0, return_value=0xbfffc5b4, n_param_values=2, param_values=0xbfffc6bc, invocation_hint=0xbfffc5a0, marshal_data=0x118de4a9) at gtkmarshalers.c:84
#20 0x1288afb2 in g_closure_invoke ()
#21 0x1289c6f0 in signal_emit_unlocked_R ()
#22 0x1289db61 in g_signal_emit_valist ()
#23 0x1289e482 in g_signal_emit ()
#24 0x11af3d56 in gtk_widget_event_internal (widget=0x14184010, event=0xfa00ba0) at gtkwidget.c:4136
#25 0x119345ea in gtk_container_propagate_expose (container=0x14181010, child=0x14184010, event=0xfa00b50) at gtkcontainer.c:2457
#26 0x11934620 in gtk_container_expose_child (child=0x14184010, client_data=0xbfffc9e8) at gtkcontainer.c:2345
#27 0x119326e0 in gtk_container_forall (container=0x14181010, callback=0x119345ec , callback_data=0xbfffc9e8) at gtkcontainer.c:1257
#28 0x11934248 in gtk_container_expose (widget=0x14181010, event=0xfa00b50) at gtkcontainer.c:2368
#29 0x119dce36 in gtk_menu_item_expose (widget=0x14181010, event=0xfa00b50) at gtkmenuitem.c:872
#30 0x119ccd2f in _gtk_marshal_BOOLEAN__BOXED (closure=0xfce10b0, return_value=0xbfffccb4, n_param_values=2, param_values=0xbfffcdbc, invocation_hint=0xbfffcca0, marshal_data=0x119dcd1c) at gtkmarshalers.c:84
#31 0x1288afb2 in g_closure_invoke ()
#32 0x1289c6f0 in signal_emit_unlocked_R ()
#33 0x1289db61 in g_signal_emit_valist ()
#34 0x1289e482 in g_signal_emit ()
#35 0x11af3d56 in gtk_widget_event_internal (widget=0x14181010, event=0xfa00b50) at gtkwidget.c:4136
#36 0x119345ea in gtk_container_propagate_expose (container=0x1417f008, child=0x14181010, event=0xbfffd794) at gtkcontainer.c:2457
#37 0x11934620 in gtk_container_expose_child (child=0x14181010, client_data=0xbfffd128) at gtkcontainer.c:2345
#38 0x119dfbde in gtk_menu_shell_forall (container=0x1417f008, include_internals=1, callback=0x119345ec , callback_data=0xbfffd128) at gtkmenushell.c:950
#39 0x119326e0 in gtk_container_forall (container=0x1417f008, callback=0x119345ec , callback_data=0xbfffd128) at gtkcontainer.c:1257
#40 0x11934248 in gtk_container_expose (widget=0x1417f008, event=0xbfffd794) at gtkcontainer.c:2368
#41 0x119daa15 in gtk_menu_bar_expose (widget=0x1417f008, event=0xbfffd794) at gtkmenubar.c:541
#42 0x119ccd2f in _gtk_marshal_BOOLEAN__BOXED (closure=0xfce10b0, return_value=0xbfffd394, n_param_values=2, param_values=0xbfffd49c, invocation_hint=0xbfffd380, marshal_data=0x119da8f6) at gtkmarshalers.c:84
#43 0x1288afb2 in g_closure_invoke ()
#44 0x1289c6f0 in signal_emit_unlocked_R ()
#45 0x1289db61 in g_signal_emit_valist ()
#46 0x1289e482 in g_signal_emit ()
#47 0x11af3d56 in gtk_widget_event_internal (widget=0x1417f008, event=0xbfffd794) at gtkwidget.c:4136
#48 0x119cb4bf in gtk_main_do_event (event=0xbfffd794) at gtkmain.c:1521
#49 0x124ca58e in -[GdkQuartzView drawRect:] (self=0x142ca790, _cmd=0x90aa7b6c, rect={origin = {x = 0, y = 0}, size = {width = 443, height = 27}}) at GdkQuartzView.c:101

Tags for this post: Coding, Cocoa, GTK+, Quartz

C++, Virtual Functions In Constructors, And Workarounds

20 august, no comments, mind to share your impressions?

Lately i've been coding in C++. I'm not used to this language, the very few times i've used it like a C enhancement whitout really enjoing the OO-ness.

One of the differences with the OO langages i've used in the near past (Python, Objective-C) was the static typing: the type of an object (or an object reference), and thus it's set of methods, is checked at compilation time, and not at runtime.

I suck at explanations, and writing in English (not my native language) does not help, so here's an example:

Consider this code:

#include <stdio.h>

class A
{
	public:
		void method()
		{
			printf("A\n");
		};
};

class B : A
{
	public:
		void method()
		{
			printf("B\n");
		};
};

int main()
{
        B * b = new B();
        b->method();
        A * a = (A *)b;
        a->method();
}

It's output will be:

B
A

which is a bit strange: one coming from dynamic languages would assume that the output will be:

B
B

since the object is the same, only called with another name.

Well, the C++ compiler isn't of the same idea, after all you casted the object to the A type, so you'll want methods from the A class :).

The trick here is to use the virtual keyword, that tells the C++ compiler to use dynamic binding for that symbol.

Again with an example:

#include <stdio.h>

class A {
	public:
		virtual void method()
		{
			printf("A\n");
		};
};

class B : A {
	public:
		void method()
		{
			printf("B\n");
		};
};

int main()
{
        B * b = new B();
        b->method();
        A * a = (A *)b;
        a->method();
}

It's output will be:

B
B

Oh! That's the output we expected before!

That's because the method() symbol is looked up dynamically at runtime for the effect of the virtual keyword of A::method(), that means that the program will actually check the type of the objects at runtime before calling the method: both b and a are B instances, actually they're the very same objects, so the program will call B::method() in both cases.

That should be enough dynamism for we, isn't it?

Well, there is a little gotcha's there: constructors can't be or can't call virtual functions.

Again, another example:

#include <stdio.h>

class A {
	public:
		A()
		{
			printf("A constructor\n");
			method();
		};
		
		virtual void method()
		{
			printf("A method\n");
		};
};

class B : A {
	public:
		B()
		{
			printf("B constructor\n");
		};
		
		void method()
		{
			printf("B method\n");
		};
};

int main()
{
        printf("Constructing A\n");
        A * a = new A();
        printf("Constructing B\n");
        B * b = new B();
}

It's output will be:

Constructing A
A constructor
A method
Constructing B
A constructor
A method
B constructor

Ouch: despite the fact that b is a B instance, and A::method() is virtual, so in a B instance it will be overridden by B::method(), when constructing a B instance the method() called is the base class's one! And not the B's one, as one (ok, i admit: as I) would expect.

That's because when the base class constructor is running, the type of this is that of the base class, and not the effective type of the object being built.

So, why one would call a virtual function in constructors? Easy: for extending in subclasses the creation of the object. And that seem impossible in C++? Only with this approach, of course.

There is an easy solution: a two-stage construction: in one stage one will call the constructor, which'll build the object, and then one "init" method that will initialize the object.

Why i tell you all this, my fellow reader? Well, i've spent two fucking days on this issue, and searching around for workarounds, maybe you'll find this information useful :).

Happy coding!

Tags for this post: Coding

GTK-Quartz and Cocoa Integration

19 july, no comments, mind to share your impressions?

Haej folks, long time no see!

I had a few issues but know it's all right :P. This night, however, instead of thinking about nothing under my air conditioner i've got my hands dirty with an old idea of mine.

I think Specimen is a great sampler: it's simple, but it works. And i like its source code too, Pete has done a really great job with this neat piece of software: i've enjoed it when i was a Linux user.

But then i switched and began to use Logic Express to do my little stuff, and however i still have an amazing hardware sampler and i put Specimen aside for a while.

Then i stumbled upon GTK+ Quartz backend and a weird idea came to my mind: it's possible to write a Specimen Audio Unit plugin?!

While the Specimen code is neatly organized and one can take rip apart the GUI code and make an Audio Unit player in a little time, i wanted to show the the ui for programming sounds directly from the Audio Unit host.

So, the challenge is: the Audio Unit framework wants a NSView * but all i have is a bunch of GtkWidget *. How in the hell we can do it?!

Here it comes the Imendio's GTK+ port.

I've compiled it and tried to compile a few linux-audio apps, to my surprise all worked like a charm, even that application that defined custom widgets all without the Apple's X11 server!!

So, at least somewhere in that code the GtkWidgets are drawed into an NSView!

I tought there should be a neat function for this conversion, and so, after a few greps i found this neat private function:

quartz/gdkquartz.h:NSView  *gdk_quartz_window_get_nsview  (GdkWindow *window);
quartz/gdkwindow-quartz.c:gdk_quartz_window_get_nsview (GdkWindow *window)

Oh, look at that! It wants a GdkWindow *, but i can surely take it by the "window" member of the GtkWidget structure.

But that code keep me segfaulting, and after a quick trip in debugger land i found out that the "window" member is NULL!

That's a bit weird. I found out that when you call gtk_widget_show() on a widget it wont do that much, the layout will be computed and the GdkWindow instantiated only when you'll call gtk_widget_show() on the toplevel window that contains that widget!

But i haven't a toplevel window for that widget! Digging in the GTK+ reference i found the notions of realizing and mapping a widget: realizing means (more or less) to calculate the layout and mapping is intended to map the Gdk primitive to the underlying backend primitive, being it X11, Quartz, Win32 ecc...

So, i did:

gtk_widget_realize(widget);
gtk_widget_map(widget);

and waaa!! i got a GdkWindow!!!

Now back on the original problem.

So it' just a matter of calling gdk_quartz_window_get_nsview() and then we're go?! I hope, but i don't think it'll work, at least it will not suffice.

After a few code written and some days spent in configuring an XCode project, i assembled a few Audio Unit example with the Specimen code in the quickiest and dirtiest way it's ever possible.

And when i mean quickiest and dirtiest it means that it will hurt your eyes looking at them, and if you'll try to understand what i've done your CS degree might come alive and spank you really, really hard.

However i got AU Lab to show a window that resembles a bit Specimen. I'll show you what i've got:

That strange looking usually means that the gui is not responding to the expose events, which actually makes lot of sense, since i still have no gtk main loop running :)

But this is the real problem of this integration: merging the runloops from Cocoa and GTK+!!

For the Cocoa side i found a cool approach, i can hook into the current thread main loop when the Audio Unit host is constructing the GUI, hoping that is not the audio processing thread, and install a CFRunLoopObserver that iterates the gtk main loop using gtk_main_iteration().

I came out with this neat code

void observer(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void * info)
{
	while (gtk_events_pending())
		gtk_main_iteration();	
}

void install_observer() {
	CFRunLoopRef runloop;
	CFRunLoopObserverRef runloop_observer;
	
	runloop = CFRunLoopGetCurrent();
	runloop_observer = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeWaiting, 1, 0, observer, NULL);
	CFRunLoopAddObserver(runloop, runloop_observer, kCFRunLoopCommonModes);
}

Unfortunately it does not work, because i have to create a GTK+ main loop first, and i dont know how to do!!

Btw, this night is over and i'll leave this issue for another time :).

If someone has any clue please leave a comment :) (however, twi, i'm waiting you on irc :D)

Tags for this post: Coding, Audio, Cocoa, GTK+, Quartz

Unobstrusive Last.fm AJAX Script

13 june, no comments, mind to share your impressions?

I've always said that i don't like ajax or the so-called "Web 2.0", but what i really mean is that i don't like the overuse of those technologies we have today. Actually, i think they're useful, if used moderately and with a bit of thought.

As an exercise, i've written my first "ajaxy" script: it fetches the "Recent Tracks Played" XML feed from Last.fm and parses it in the sidebar :).

I've used the jquery javascript library, it is really impressive! It makes all this DOM-work a kids' game.

I had a little showstopper, tough. I didn't know that XMLHttpRequest do not accept cross-domain request, so i had to do a local proxy in django, i could have used lighthttpd's mod-proxy, but i havent figured in 5 seconds how to do a single page proxy, and since i already knew how to do it using django views i took the easy way :)

So, i don't think it may be useful to anyone, but that's it!

The JavaScript file and a trivial proxy view for Django.

In order to use the script, you have to include first the "jquery.js", then the "recent_track.js", then call the function in your onload handler, that's how i did in this very page:

<script src="/media/js/jquery.js"></script>
<script src="/media/js/recent_tracks.js"></script>
<script>
    $(document).ready(fill_recent_tracks);
</script>

Also, you need to have in the html page a list with "recent_tracks_ul" class, i.e.:

<ul class="recent_tracks_ul">
</ul>

Use the code as you wish, but if you do write me a line! :)

Tags for this post: Coding, Django, Javascript, AJAX

All posts are licensed under the Creative Commons Attribution-Noncommercial-Share Alike 2.5 Italy License.
And, because i'm a nerd, i'll proudly tell you that this is a Django Joint!