Posts for Sunday, March 7, 2010

avatar

Uzbl, monitoring, AIF talks

I recently did two talks, for which the videos are now online.

If all goes well, I'll be at ArchCon this summer, where I'll be doing these talks:

We're not sure yet if those talks will get videotaped.

Posts for Saturday, March 6, 2010

Clementine: looking great

Amarok is looking really good these days:

Clementine

Hold on, that's not Amarok! It's Clementine, a Qt4 port of Amarok 1.4, aka "my dreams finally come true", aka "what Amarok 2 should've been". It's functional right now, not quite as fully-featured as Amarok 1.4, but all the major bits are there, and it's being actively developed.

Once again I am amazed at and eternally grateful for the number of choices of media players there are in Linux. It seems like I write a new blog entry every other week saying how great some media player is. The reality is that there really are tons of great options. And this is yet another.

But Amarok 1.4 was special. And I really hope Clementine succeeds.

Advertising is devastating to my well-being

There's an interesting article on Ars Technica about how blocking ads is somehow unethical, and "devastating to the sites you love". The idea that I have a moral obligation to stare at an advertisment, the thought I have an ethical obligation to voluntarily annoy myself for the sake of a company's profits... it would be hilarious if it wasn't so repugnant.

Let's talk about ethics. How about some ethics for businesses?

  1. Stop making the world a garish and hideous place to live by flooding it with ads.
  2. Stop trying to grab my attention, evoke emotional responses in me, manipulate my mind, and trick me into spending money on crap I don't need. This is what advertisement is. Stop disrespecting me and insulting my intelligence. Stop viewing me as an anonymous, money-spending piece of cattle.
  3. Stop trying to track my every move online. How many people understand tracking cookies? How many companies make it clear that every click is being recorded and data-mined? How is this ethical?

Here's the state of the world today: I can't drive down the street without seeing billboards everywhere. The radio is literally 25 to 50% ads, which is why I don't listen to the radio. Television is what, 20 minutes of commercials per hour? Which is why I haven't had television in 6 years. Newspapers and magazines are saturated with ads, and of course I don't read them either. Even then, ads are nearly unavoidable.

(By contrast, books (for example) are awesome. I pay for a book, and then I read the book start-to-finish with no ads, no distractions. A few pages at the back maybe, but I can ignore those. Books are nice.)

The internet is also a wonderful thing. FIRST a person or company puts a lot of information somewhere that everyone can read it effortlessly for free, and THEN they sometimes expect me to look at their ads. And I can simply choose not to.

If you want to force me to look at your ads, make me sign a contract or consent to an agreement before you display your site to me. Otherwise I owe you nothing. If your business is about to go bankrupt, and your business is so important to me that I want it to stick around, I'll give you money. Real money. I've done it before. But I will never give you my attention for free. No business has a right to that.

Businesses are not your friends. Businesses are not ethical entities. Businesses do not deserve the benefit of the doubt. Businesses exist to milk you of as much of your money as possible. The only sane reaction for the average person is a similar one: I want to deprive businesses of my money. I want to get as much from them as I can, while giving up as little as possible.

If I politely suggested that it's "unfair" for a business to have such a huge profit margin, and "if they cared about their customers, they would lower all their prices", I'd be laughed at. Why would a company do anything less than the absolute most they can do to bleed money out of me, after all? I laugh at any business (e.g. Ars Technica) which says the same thing to me. I will bleed you of product, as far as it's legal to do so. It so happens that advertisements are devastating to my well-being. Up to this point I have rarely read Ars Technica, and from now on I'll make it a point not to. If I do read it, I will block ads with the greatest feeling of malice I can manage.

I run my own website(s) at a loss specifically because I'd rather pay out of my own pocket than force people to look at ads. Admittedly my sites are so small that it's not much money. But there you have it. If I had to generate revenue to keep my sites going, I would find a way other than advertising to do it. Or I'd shut them down.

I love my ad-blocker. The only thing better would be an internet where I didn't need to use it.

avatar

Lovely video showing nature in a garden – great colours, music, and attention to detail.

<object height="281" width="500"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9519939&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00ADEF&amp;fullscreen=1"><embed allowfullscreen="true" allowscriptaccess="always" height="281" src="http://vimeo.com/moogaloop.swf?clip_id=9519939&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" width="500"></embed></object>

Related posts:

  1. What separates music from sound is the ability to snapshot emotion, not events. True music is therefore not defined by its interpretation from listeners.
  2. A lovely little emoticon set from KDE.
  3. I missed this perfectly healthy rotating kitchen?

avatar

A scalable and adaptable standardised user file structure?

I’ve got two more mock exams to cover (both on Monday), some University applications progress has been made, more and more of the ThoughtScore project is inching its way into my WIPUP profile (starting to get to the interesting bit), and I’ve opened Blender again to do a quick animation favour which can be seen in my Uncategorised category.

But this post is nothing to do with those fun and amazing things. No. Today I want to talk about something that warrants 3-4 syllable words being used in the post title.

The ins and outs of operating systems aren’t exactly my speciality but I do know that they have a uniform file structure. In Windows, a lot of system stuff goes in C:\WINDOWS, your user files goes in Documents and Settings, and programs go into Program Files. In Windows inside your user file you automatically get a set of folders such as My Documents, My Pictures, etc. In Linux (and all UNIX I believe) your user’s folder is in /home/username/ and other than having hidden dotfiles to store local application settings it’s basically empty. At most your desktop environment or distro will add a "Desktop" folder.

The question is how should I archive and organise my files such that they’re easy to find, easy to transport, and easy to manage. Sure, the Microsoft approach works for some people, but most of the people I know completely ignore that structure. I’ve been thinking about it for a while and have isolated a few ways people normally try to manage it.

By file extension. It’s easy to find and easy to archive. However it’s difficult to manage once you start getting rare file extensions or files with no extensions. It also becomes a pain when your program output or save files require several files of different types to be grouped together. Files can become strewn all around the computer and projects which require hardlinking to files will easily get out of hand.

By file type. This one is only slightly different to file extension in that people group things by what files are, not their extensions. For example "Images" instead of "jpg", "gif", etc. Pros and cons are similar to above.

By file purpose. This is a project based approach. Files are grouped into their uses, such as "Homework", or "Movies", or "Project X". This is rather commonly used but often clashes occur when used in parallel with others such as File extension or file type, especially when the nature of the project requires hardlinking to file locations.

By file attribute. This is often a temporarily used file structure when people are sorting out files. Such examples include "bobs photos", "to be sorted", "jazz music", etc. The main use of this structure is to make it easier to transport the files or manage a bulk collection of files. The sad story is that these directories persist waaaay past their useful lifetime and prove to be effective cloggers.

By time. Useful for archiving, completely regardless of the content. Used for management and for finding, but rarely useful for transporting files.

By referenced location. Some files are put in locations regardless of semantic value and instead for technical convenience – for example dotfiles, plaintext, logs, tmp, backup files, and referenced files from other apps (scripts, programs, graphic projects).

By organised chaos. This is probably how almost every single Windows user’s desktop looks like. A complete mess of random rubbish used to dump stuff. Files are strewn regardless of any attribute and found through searching, indexed searches, and file manager filters.

Now of course searching for the zen of a users’ file structure will only end when a structure is able to accomodate a large number of files, a project-based workflow, technical restraints, archives, and miscellaneous files. In this case it’s useful to define what "accomodate" means, which is an ability to easily find a desired file, to sort and prune undesired or irrelevant files, to prevent duplication, to transport similar files easily (eg: all within one directory), to quickly break down a collection into manageable chunks, and to allow any newcomer to intuitively adapt to your filesystem.

I currently run a structure where my homefolder is where I dump active files, I have a primarily "file type" structure, archives are done through "file purpose" (I despise time), and projects have their own substructures which are completely dependent on referenced locations. For me the biggest inconvenience is referenced locations, where I find myself unable to bulk manage files simply because of the inconvenience of have to re-reference their location. The rest is chaos. All in all, miles away from my personal zen.

Anybody who’s achieved a personal zen are welcome to share.

Related posts:

  1. Tech tip #3: Rip audio from an .FLV file.
  2. Tech tip #4: Copy a random set of files from a directory.
  3. Progress on Eadrax

ogre 3d III

why ois did not work on my linux installation

what is ois? i quote [1]:

Object Oriented Input System (OIS) is meant to be a cross platform, simple solution for using all kinds of Input Devices (KeyBoards, Mice, Joysticks, etc) and feedback devices (e.g. forcefeedback). Written in C++ using Object Oriented Design patterns

i’ve finally found out why ois [1] does not work with my linux system. see this:

ls -la /dev/input
crw-r—–  1 root root 13, 73 Feb 28 12:46 event9
crw-r–r–  1 root root 13,  0 Feb 28 12:46 js0

as most linux users will instantly see: js0 can be read but not be written to. so is this bad? or does this degrade useage? probably it is not bad since a user might only have to write to a jsX device if it is a ‘force feedback’ supporting device. but for only reading from the device it should be useable  as expected. but the joystick/gamepad did not work with OIS at all, so i wondered why and i started to look at the code of OIS. i found a ReadMe.txt file with an obsolete autotools toggle – guess what – i hate autotools.

anyway, the ReadMe.txt states:

./configure –disable-joyevents — Uses /dev/input/jsX instead of /dev/input/eventX

so i tried –disable-joyevents but it seems that this option is not used anymore because ./configure complains with:

configure: WARNING: unrecognized options: –disable-joyevents

however, this made me think: what is that event9 device when plugging in the gamepad (still the ps3 controller). it is yet another interface to access the gamepad. so one can either use js0 or event9 (on my system, since the names are autogenerated by the system).

after changing the permissions of event9 (as root) with:

chmod 0777 /dev/input/event9

and trying the ois demo again it worked! no wonder but took me at least about  1h to find out. so why don’t they try to open the js0 device? why don’t they complain about permission issues? at least the console demo application could do that (it can’t since the input opening and handling is in the linux part of the library anyway) but what about some lines like:

event1: can’t open device for reading
event2: can’t open device for reading

event9: can’t open device for reading

this would be very handy for debugging the situation. or seen from a different point of view,  is this a gentoo issue? is this a udev issue? why does that device not have read permissions per default? maybe for securty? how knows…

ois and udev

thanks to [3] i found this handy udevadm command:

udevadm info -a -p  $(udevadm info -q path -n /dev/input/js0)

this can be combined to what i’ve written about udev already at [4]. in short (looking at the output of the above command we search for these two parameters):

  • ATTRS{idVendor}==”054c”
  • ATTRS{idProduct}==”0268″

these two parameters will do the work. so the new udev rule looks like this:

# cat /etc/udev/rules.d/99-myrules.rules
KERNEL==”event[0-9]*”, SYSFS{idVendor}==”054c”, SYSFS{idProduct}==”0268″, MODE=”0666″, GROUP=”games”, SYMLINK+=”eventPS3″
KERNEL==”js[0-9]*”, MODE=”0664′”, GROUP=”games”

WARNING: i named that file 11-myrules.rules with the result that the group was changed but never the mode so i wondered why. later i found out that there is some other rule which had overwritten the MODE but not the GROUP. (so i renamed it to 99-myrules.rules)
WARNING: using 0666 makes the GROUP=”games” useless since every user can attache that device now, you might want to add your local user to the ‘games’ group and change MODE=”0660″ instead

so after making changes to /etc/udev/rules.d one MUST NOT forget to do this:

udevadm trigger

this will reload the rules (and one of these rules we just changed). now replug your gamepad and see if the permissions were changed in /dev/input, probably with: ‘ls -la /dev/input’

ois packaging on gentoo

debugging ois is not easy if the software isn’t installed correctly. that is the case with the linux package since they don’t install

  • ConsoleApp – application to test input devices as (mouse/keyboard/gamepad/joystick)
  • FFConsoleTest – probably the same but this time with ‘force feedback’ support

this is again a complaint about package management…

ois concepts

ois is designed cross platform which is very good. ogre 3d can use ois and as far as i can tell the design of ois is sound. it does not detect my ps3 controller as a ‘force feedback’ device but i can live with that. what really bugs me is the fact that ois (same goes for libSDL) does not support device hotplugging – i’ve not tried on windows but i’m sure of linux and mac (since mac uses libSDL as backend currently).

every person who has once used a ps3 or a xbox knows how cool device hotplugging is!

there was a project for sdl to make device hot-plugging for linux work. however this was – if i recall correctly – not implemented into the library but instead the library was queried for a list of devices if the linux hardware abstraction layer (HAL) called a callback via dbus to notify of device changes. the new device was then opened as any normal joystick device using sdl.

what i want is different: i don’t want to use dbus in my application. and i don’t want to code like that. i just want to have a additional event which informs me about the state-change of currently opened joysticks (that is for instance js0 which is in use). right after it is unplugged my callback for new events (same goes if i poll the device every frame) i will receive the event that the device is now gone so i can close the device handler and the game could also react to it probably with a game pause or a screen showing: you don’t have any input device attached, can’t continue… please attache at least one device.

this way one could also switch from one player to two player mode or one could display a device manager dialog when plugging a second device… basically whatever you want to do.

device hotplugging is on the todo list for ’sdl 1.3′. i wonder when that is released… (according to [2])

links

[1] http://sourceforge.net/projects/wgois/

[2] http://lists.libsdl.org/pipermail/sdl-libsdl.org/2009-January/068344.html

[3] http://raftaman.net/?p=343

[4] http://lastlog.de/wiki/index.php/Udev_permission


Helaman : 1

Interesting that, again, the pride of one man seemed to be the reason of much wickedness and death.  If Paanchi would have just accepted the rule of his own brother because he was voted in by the majority, I'll bet the whole war with Coriantumr wouldn't have happened.

That being bad enough, doesn't hold a candle to what happened with Kishkumen.  The whole idea of the gadianton robbers began with Paanchi's followers...  And I believe the concept of the gadianton robbers was one of the major contributers to the falling of the entire Nephite nation.
avatar

why is list_head() defined the way it is ?

Recently, a friend of mine asked : Why does the struct list_head in the Linux kernel has no data field ?

In other words, what he means is this:

The way we are introduced to linked lists in high school is
struct linked_list
{
void *data;
struct linked_list *prev *next;
}

And assume, we have a user defined data structure:
struct user_data
{
int a;
char b;
}

The approach we usually use to create a list would be :
struct linked_list head;
struct user_data mydata1;
head.data = (void *)&mydata1
head.next = NULL;
head.prev = NULL;

And to add another node to the list :
struct linked_list newentry;
struct user_data mydata2;
newentry.data = (void *)&mydata2
newentry.prev = &head
newentry.next = NULL;

and so on..

However in the Linux kernel, a linked list structure is defined something like:
struct list_head
{
struct list_head *next, *prev;
}

and to do the same thing as we did above, we do something like :
struct user_data
{
int a;
char b;
struct list_head new_list;
}

/* Create head */
struct user_data head;
head.new_list.prev=NULL;
head.new_list.next=NULL;
...
/* Add a new node */
struct user_data newentry;
newentry.new_list.prev=&head.new_list;
head.new_list.next = &newentry.new_list;
...

So, in one case we have the data embedded into the linked list (high school style) and in the other, we have the linked list embedded into data. So, what's the advantage of the second over the first ?
I actually couldn't find any documentation justifying this design but these obvious reasons come to my mind.

One advantage is that the kernel programmer is relieved from the additional care he has to take during typecasting if she chooses the first approach. As we all know, typecasting is a necessary evil in C, but using it for linked lists that's invariably used almost everywhere in the kernel is likely to double the number of kernel bugs!

Second, with the first case, with each node created, we end up using more space compared to the second approach. This is because struct linked_list has an additional void *data defined thereby making the node larger in size. This is definitely an important issue in embedded systems if not on x86.

Last but not the least, an important advantage that this design offers is flexibility in list walking. For example, if you have the address of newentry (see above example), you can access newentry->new_list and then go back and forth. Then, using the container_of() macros, any of the associated user_data for any node could be accessed! Even if we just have the address of list_head somewhere in the middle of a linked list, we could jump to the associated data structure. With the first design, in order to do list walking and modifications, we always need the address of any of the node. This means that you always have to pass struct linked_list pointers even if all you really wanted to do is manipulate struct user_data.

read more

Posts for Friday, March 5, 2010

Alma : 63

Okay... I forgot that Alma had 63 chapters.

This chapter has always just kind of made me raise an eyebrow while reading it.  I must say, I felt the Spirit while reading it, and I know it's true, but I wonder why it was written.

Why did Mormon dedicate half a chapter to people "going northward"?  And what about the ships?  Hmm...  Maybe we'll find out later what happened to those people.  I wonder if they really were drown?

Anyway...  Didn't get too much out of this chapter.  Maybe next time.

Trying to Leave Catch-All E-Mail Behind

For the last 10 years, I’ve used zx2c4.com for my e-mail, and have had it forwarded to whichever provider I was using, which most recently happens to be gmail. Ten years ago, it seemed like a good idea to have “catch-all” e-mail, whereby anything you put at zx2c4.com would be sent to me. This was great for a while, and on every site I would visit that required an e-mail, I’d give them a new one. JasonHatesWhenNikeDotComSpamsHim [at] zx2c4.com I would use for nike.com, and then I’d know for certain if they ever sold my e-mail address. For more serious sites, I would just use their site name or something easy to remember about their site. For personal communications, all my friends knew this quality of zx2c4.com, and would send things to anything they wanted — YouAreAGoofBall [at] zx2c4.com, for example.

This was all fun and games and helped filter out some spam throughout the years, but it seems like it’s time I settle down on one e-mail address. I would also like to find a different domain than zx2c4.com for personal communications that’s much easier to remember (any suggestions?). The problem is – it’s very difficult to switch away from catch-all e-mail. My initial idea was to gather up all the e-mails of individuals who have sent e-mail to something other than my main e-mail address, and automate the process with a form letter sent via SMTP that says something like “Dear joe@shmoe.com, You have sent letters to asdfasf [at] zx2c4.com, thatthang [at] zx2c4.com, jojomojito [at] zx2c4.com. Please note that starting May 1, 2010, only whatIDecide [at] zx2c4.com will be valid. Thank you, Jason”. And then painstakingly go to all of the websites with logins and change my e-mail address for every.single.solitary.one one.by.one. At first this all seemed doable.

But then I started investigating…. Since I started using GMail in March of 2005, I have received e-mail from 1,299 different e-mail addresses on 267 different zx2c4.com e-mail addresses, not to mention lost e-mail from the 5 years prior. I built this python script to give me a good layout of what’s up:

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
from imaplib import IMAP4_SSL
from optparse import OptionParser
from email.parser import HeaderParser
from email.message import Message
from email.utils import getaddresses
import sys
import os.path
import os
 
def main():
	parser = OptionParser(usage="%prog --username/-u USERNAME --password/-p PASSWORD --mode/-m MODE [--domain/-d DOMAIN] [--cachedir/-c CACHEDIR]", description="Downloads gmail message headers and determines the set of all e-mail addresses on DOMAIN at which people have emailed you.")
	parser.add_option("-u", "--username", action="store", type="string", metavar="USERNAME", help="Gmail username")
	parser.add_option("-p", "--password", action="store", type="string", metavar="PASSWORD", help="Gmail password")
	parser.add_option("-d", "--domain", action="store", type="string", metavar="DOMAIN", help="Domain name")
	parser.add_option("-c", "--cachedir", action="store", type="string", metavar="CACHEDIR", help="The directory to cache fetched headers for subsequent runs")
	parser.add_option("-m", "--mode", action="store", type="string", metavar="SENDERSFILE", help="If the mode is \"to\", this prints a list of all the emails you've received email on. If the mode is \"from\" this prints a list of everyone who has sent you email. If the mode is \"frombyto\" this prints a list of all the addresses that have emailed you sorted by the address at which you received email. If the mode is \"tobyfrom\" this prints a of all the addresses you have received e-mail from sorted and duplicated by who sent the e-mail.")
	(options, args) = parser.parse_args()
	if options.username == None or options.password == None:
		parser.error("Username and password are all required.")
	if options.mode != "from" and options.mode != "to" and options.mode != "frombyto" and options.mode != "tobyfrom":
		parser.error("You must specify a mode.")
	if not options.username.lower().endswith("@gmail.com") and not options.username.lower().endswith("@googlemail.com"):
		options.username += "@gmail.com"
	if options.cachedir != None and not os.path.exists(options.cachedir):
		try:
			os.makedirs(options.cachedir)
		except:
			sys.stderr.write("Could not make cache dir. Skipping cache.\n")
			options.cachedir = None
 
	imap = IMAP4_SSL("imap.gmail.com")
	imap.login(options.username, options.password)
	imap.select("[Gmail]/All Mail", True)
	typ, data = imap.search(None, 'ALL')
	if typ != "OK":
		sys.exit(("Could not search properly: %s" % typ))
	emailAddresses = {}
	data = data[0].split()
	length = len(data)
	counter = 0
	parser = HeaderParser()
	for num in data:
		counter += 1
		if options.cachedir != None:
			cachePath = os.path.join(options.cachedir, num)
		else:
			cachePath = None
		if cachePath != None and os.path.exists(cachePath):
			message = parser.parse(open(cachePath, "r"))
		else:
			try:
				typ, data = imap.fetch(num, '(RFC822.HEADER)')
			except:
				sys.stderr.write("Failed to fetch ID %s\n" % num)
				continue
			if typ != "OK":
				sys.stderr.write("Failed to fetch ID %s: %s\n" % (num, typ))
				continue
			if cachePath != None:
				try:
					f = open(cachePath, "w")
					f.write(data[0][1])
					f.close()
				except:
					sys.stderr.write("Could not write cache for %s" % num)
			message = parser.parsestr(data[0][1], True)
		tos = message.get_all('to', [])
		ccs = message.get_all('cc', [])
		resent_tos = message.get_all('resent-to', [])
		resent_ccs = message.get_all('resent-cc', [])
		all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)
		for address in all_recipients:
			if len(address) == 2 and (options.domain == None or address[1].endswith(options.domain)):
				to = address[1].lower()
				fros = getaddresses(message.get_all('from', []))
				fro_addresses = set()
				for addr in fros:
					if len(addr) == 2:
						fro_addresses.add(addr[1].lower())
				if options.mode == "to" or options.mode == "tobyfrom":
					if to not in emailAddresses:
						emailAddresses[to] = set()
					emailAddresses[to] = emailAddresses[to].union(fro_addresses)
				elif options.mode == "from" or options.mode == "frombyto":
					for fro in fro_addresses:
						if fro not in emailAddresses:
							emailAddresses[fro] = set()
						emailAddresses[fro].add(to)
				sys.stderr.write("[%s of %s]: Message to %s from %s.\n" % (counter, length, address[1], fro_addresses))
		if len(all_recipients) == 0:
			sys.stderr.write("[%s of %s]: Message has empty To header.\n" % (counter, length))
	imap.close()
	imap.logout()
	if options.mode == "to" or options.mode == "from":
		for addr in emailAddresses.keys():
			print addr
	elif options.mode == "tobyfrom" or options.mode == "frombyto":
		for to, fro in emailAddresses.items():
			print to
			for f in fro:
				print "\t%s" % f
 
if __name__ == '__main__':
	main()

The situation seems daunting. That is so many email addresses, so many senders, so many website logins to change, so many people who have to update their address books. So what do I do? What will I do? How important is it to switch away from catch-all? I might just be locked in for life.

Posts for Thursday, March 4, 2010

Alma : 61, 62

Reading through Alma 60 and 61, I can vividly imagine what it would be like to live in times like those.  I imagine the cry for freedom being heard through the streets, as neighbors and friends decide to take up arms in defense of our right to worship how we want, and for the protection of our families, traditions, and way of life.  Putting myself in that position, I wonder if I would have the courage to put my life aside, and join the battalion of freedom fighters in the cause of maintaining our rights.

It's so good to read that thousands joined the cause, and when joined with the freemen and Pahoran's armies, they were easily able to re-take Zarahemla.

The shocking part of these chapters is 61, verse 10.  The enforcement of the law was pretty serious back then.  "You won't fight for your freedom?  I'm sorry, but if you won't fight, you'll be executed."  I imagine the situation back then was extremely dire, and of course and action like that in times like that must have been justified because it was the God fearing, commandment-keeping authorities who were making that call, one of them being Captain Moroni himself.  Still...  It was kind of shocking that it was written so it could not be misunderstood.  Penalties for not fighting for your freedom?  Death.

What a marvelous ending to a wonderful book in the Book of Mormon.

A few entries ago, I wrote that because of Amalickiah, these wars began and continued on for such a long time.  62 : 35 says that Teancum saw it the same way.  Unfortunately, he missed his mark, and was killed because of it.  I guess all it takes is one very wicked man to cause all sorts of hellish behavior, lasting years, and years.

Alma is pretty much the perfect "good guys vs. bad guys" novel.  I love how it ends.

Now.... On to Helaman.

2011 5.0 Mustang GT

Although I probably will never own one of these, it's just awesome that the pony cars are gettin' revved up again.  Ford is definitely gonna bring up the competition with this beast.  Bye-bye imports!

http://www.thefordstory.com/smart-technology/the-mustang-5-0-is-back/

Buyah!

Should update my Writing ebuilds HOWTO

Lately there has been a lot of posts on Planet Gentoo and Larry the Cow (and even !gentoo on identi.ca) about QA [1] [2] [3], the policy of introducing new developers and lately even the nifty solution of proxy maintainers [4].

So I decided that it might be high time to update my Writing ebuilds is easy! HOWTO. IMHO it would help a great heap, if we had a nice step-by-step tutorial on how to write and maintain ebuilds understandable enough for the average user to actually consider helping out.

Don't expect anything too soon or sudden, because I'm quite plastered with work right now — FSFE here, study there, small things all around, not to mention sleeping and eating.

À propos sleeping, I really should be sleeping more then 5h a day O_o

hook out >> drinking coffee in BiKoFe and preparing for the Fellowship Slovenia meeting later today; too bad the tea house Cha doesn't have WiFi :P

Gmail Search Operators

These operators will give you more precise search results.

1. from: - mails from the name of the sender
2. to: - mails sent/to be sent to to the recipient
3. subject: - search mails containing the specified words in the subject
4. OR - traditional OR operator
5. - (dash or hyphen) - exclude messages containing the specified words
6. label: - search messages by label
7. has:attachment - search mails with attachments
8. filename: - search mails by filename of the attachments
9. " " (double quotes) - traditional operator for filtering exact specified words
10. () - used for grouping search expressions
11. in:anywhere - search for mails anywhere in your account
12. in:inbox - search for mails in your inbox
13. in:trash - search for mails in your trash folder
14. in:spam - search for mails in your spam folder
15. is:starred - search for starred mails
16. is:unread - search for unread mails
17. is:read - search for read mails
18. cc: - search mails that were carbon copied to a specified recipient
19. bcc: - search mails that were blind carbon copied to a specified recipient
20. after: - search mails after a specified date in yyyy/MM/dd format
21. before: - search mails before a specified date in yyyy/MM/dd format

avatar

Acer Aspire 4530 – idling at 62c by design.

Related posts:WIPUP: (E2-Productions) Finished the site design. WIPUP: ATSC second mockup created – with a much lighter design. WIPUP: Big change to the ATSC design mockup because my initial idea was ugly. Related posts:
  1. WIPUP: (E2-Productions) Finished the site design.
  2. WIPUP: ATSC second mockup created – with a much lighter design.
  3. WIPUP: Big change to the ATSC design mockup because my initial idea was ugly.

Exherbo at Open Source Days

The danish open source conference, Open Source Days, will run this friday and saturday. Exherbo will be present both days with quite a few developers in attendance.

I'm sure there will be a (little) hacking on Exherbo and related projects like Genesis but it's also a very good, if somewhat rare, opportunity to meet some of the leading Exherbo developers and talk to them about the current status of Exherbo and what's in the future.

Personally I'm hoping to have some good discussions about the kind of problems people currently face when they use Linux in various business settings and ways that those problems might be solved. I'm also hoping that you can learn something from the way the Exherbo project is managed and get an idea how the project manages to move at such a fast pace.

And finally I'm looking forward to meeting lots of people and having a good time :)

Posts for Wednesday, March 3, 2010

The Nausea

Today on my way home from work I took the picture you can see here.
It's an all too common sight these days, temperatures rise and we actually see the sun every other day, the snow has melted and quickly becomes only a memory and underneath the snow remains of the winter appear: Parts from old Christmas trees, trash and single gloves.

The things we leave, the things we lose or drop and never get back … for some reason a lonely glove laying the dirt makes me sad. It's not about pollution or environment, it's probably not even about the specific person that lost it.

The single, lonely glove is a symbol for the absurdity and inherent fucked-upness of our world and I can't even explain why I feel that way. But it drowns me in a deep feeling of loneliness, sadness, cold and alienation, an item intended to keep you warm cast in the dirt devoid of its original purpose. And what is the thing without its purpose? A reminder for someone freezing on his or her way home. A person that gets cold even though one glove is still left.

But in that case 50% don't really cut it, do they? And I keep looking at the object and start freezing, start losing focus, start drifting. And then the guy behind me rings the bell on his bike so I cross the road. And it all crawls back into the back of my mind. But we'll meet again. Soon ...

Proper Spelling of "Ridiculous"

Okay...  I rarely ....  well..  I never have posted something like this before in my blog, but this is getting RIDICULOUS.  This is not getting REDICULOUS.  It is getting R-I-D-I-C-U-L-O-U-S

It seems like when ever I see that word spelled anywhere on the Internet, it's spelled consistently wrong, and I can't for the life of me figure out why, and it's beginning to grate on my nerves.

So... Just to set the record straight, the word ridiculous is spelled as such:
 
R-I-D-I-C-U-L-O-U-S
 
...and there ya have it!  Just in case you were wondering how to spell ridiculous, it's spelled "ridiculous".
Are we good now?
avatar

The "Delta" nightmare

My weekends usually go hibernating copious hours, catching up on lkml, cooking good food, watching a good movie or anything that doesn't make me drive for long hours or take a long flight (well, I used to drive to NYC over the weekends but that was out of sheer necessity). Since my fiancée moved to DC, I persuaded her to do all the traveling while I do the "not very difficult job" of doing nothing. That(persuasion), as everyone knows, is not very easy! So, finally, I decided to give her a break and got myself a round trip shuttle to DC for the (last) weekend.

Now, everyone has their airline horror stories and I tend to take them very seriously. Delta Airlines, fortunately is rarely a part of these stories and I was happy that I was flying with them. And so, with a smile on my face, I took a cab to the Logan airport. Everything was as expected: I had my usual dose of a 3 hour departure delay from Boston. And just like the buses at South Station, I actually saw that the Delta flights were on ground so that they could be filled up with passengers! This may be outright common or may be there was a genuine reason flights were getting delayed but at that moment, nothing seemed like it could be the reason. Finally, my flight took off (and landed in DC) and I was having a good time until Sunday happened. That was the day I took the DC metro to Vienna (suburbs) and had a really terrible motion sickness. My flight back to Boston was on Monday morning and I was optimistic that I would feel better by that time but my body didn't really care for my optimism. It was Monday morning at 8 am, and I had nausea, dizziness and everything unpleasant. That's when the Delta horror story started.

Seeing that I was not in a very good shape to fly, my fiancée called up the Delta customer service asking what it would take to reschedule my flight to Tuesday. She was told that we had to pay a $150 rescheduling fee which was probably fine but at that time it looked like too much for a "little less than" $200 fare. We gave up; still optimistic that I would magically feel better. An hour passed and things were still the same. So, we decided to make the final call and reschedule to Tuesday. Honestly, we still had our doubts that we wouldn't have to pay the difference in fare (which was $650 on Monday for a Tuesday flight!) and so to make sure we know what we are getting into, my fiancée explicitly asked : "Are there any other fees involved that we should know about ?" The answer she received was " No ma'am, you only have to pay a $150 fee rescheduling fee". My fiancée thought that we could probably save a bit more considering the fact that I am actually ill and so wished to talk to the supervisor to ask for a reduction in the rescheduling fee. After explaining the whole story to the supervisor again, what we heard from her completely bowled us over. The supervisor said "We do have to pay the rescheduling fee and *also* have to pay the difference in fair!" And when we confronted her saying that we spoke to two customer reps minutes before her who told us that there was no other fees involved, she didn't really care; in fact, she didn't even offer an apology. All she could offer us were statements like : "The system wouldn't allow such a transaction" or " the customer rep didn't mention anything like that".

At this point, my fiancée was furious and I realized it's probably best to end the call as it was going nowhere! We disconnected the call, and I tried my best to feel better(somehow) and finally took the flight. I actually wanted to feel worse so that I could throw up inside the aircraft but later realized that would be too evil of me and discomfort to fellow passengers. Again, as usual, the flight from DC was late by an hour because of some lame reason, the flight itself was very uncomfortable : my nausea was bad to the extent of being painful and I somehow passed one hour and 12 minutes and finally reached Boston.

So, what exactly am I whining about ?
We spoke to two customer service reps who had no idea that we had to pay the difference in fare along with the rescheduling fee. Does that mean they were irresponsible ? No, that means that Delta doesn't give a damn about customer service (and so is the case with any other airline). Once the ticket is sold, their liability becomes zero. And the way the supervisor handled the misinformation provided by the reps just shows how serious they are about the whole thing.

And Delta, this is what I have to say to you : I will probably fly with you again; because I would have no other option or I would get a really good deal but you really need to pick a role model for yourself and learn what customer service is all about. Here's one for a start.

read more

Clementine: The Player I’ve Been Looking For

Clementine is a half port half rewrite of Amarok 1.4, with its kdelibs dependencies stripped and all the code updated to use Qt4. Only in its 0.1 version, it works incredibly well. I’ve been looking for something like this since Juk became crusty and Amarok became too much and Exaile seemed slow and gtkish. Clementine is my new default player.

An ebuild is already available for Gentoo.

Posts for Tuesday, March 2, 2010

avatar

The WIPUP 21.02.10 stats are out.

It’s midweek, 3 mock exams later, and it’s been quite some time since the WIPUP 21.02.10a was released. Yep, that means it’s time to look at the statistics. The reason this didn’t happen earlier is because the WIPUP dashboard stats only update themselves at the beginning of the week in order to save server power (it’s quite strenuous you know). As a result the last pull was on the 22nd, which meant that it was quite likely that a few visitors could’ve been pulled over into the next week of statistics.

Anyways, here’s the image speaks a 1000:

As you can see I’ve been rather actively dogfooding WIPUP, especially noticable in the latest upsurge in update activity due to the porting over of The ThoughtScore project. The obvious thing this proves is that update quantity doesn’t necessarily mean update interest. Looking at the number of views optimistically realistically this update, even though even more feature packed and with a more mature system did on par with the 14.01.10a update. Pessimistically we could assume a division of views over all our updates and no rollover spectators in the next week and report that the 21.02.10a update was a complete failure. On the other extreme we could assume the complete opposite and say we achieved a modest increase in interest.

The obvious conclusion is that there are lies, damned lies, and statistics.

User-wise things are still slow with little of the feedback system in use – I’ve still got those 2 stalkers, hit a new high of 2 comments in a week (by 1 user, though) and it looks as though a kudos system was a good idea.

However of course this doesn’t mean that the future is completely bleak, WIPUP still has far to go, we’ve recruited a new contributor (Kamal) and we see a few interesting uses of WIPUP by the user Sandking, who shows us some rendering tests, by C0mBineD, who is apparently working on a painting, and jonas, who’s got one of his digital orchestra test pieces up.

Seeing as that they’re rather dormant this is a sign that WIPUP still isn’t ready for the crowds, but we invite anybody else interested to give it a spin as a regular user to do so!

Related posts:

  1. After the WIPUP release, the stats are in.
  2. WIPUP 14.01.10 released!
  3. Dogfooding WIPUP

Posts for Monday, March 1, 2010

When paying replaces the satisfaction of buying

Today Paule paid a visit to Oldenburg and we had some time to talk. Talking to him was inspiring as always not just cause he has usually thought about things a lot more in-depth than I have but also cause he has the talent to say things exactly the right way.

We talked about our jobs and that both of us now have more money than we used to have while we were still studying. We talked about how that makes life a lot more convenient cause you don't have to wait and plan and save money for that certain comic book, novel or boardgame coming out, you can just buy it. In our internet-driven economy it's just a click. Yay.

Sometimes things take some time to deliver and we talked about how sometimes you get surprised by stuff you ordered weeks ago and already forgot: You get a package, you look inside and you see that thing you ordered 4 weeks ago and it all comes back. Well kinda.

Paule said it quite right (I'm paraphrasing as well as translating from German to English ;-)):
"The act of paying had already fulfilled the desire that the object itself evoked."


This is a weird and actually somewhat fucked up thing. You want something you click it, you pay the 5 or 10 bucks it costs and you forget it. It doesn't stay in your mind. What does that say about you?

You, my dear reader, will probably not have that problem because you handle your money way better than I do (I'm terrible with money actually ;-)), but it kinda made me think.

Has my attention span gotten that short? That I cannot even keep stuff I "want" in mind? Is it just the amount of cash, the fact that 5 bucks don't really bother me that much? Is this me being a decadent fuck?

What does the act of paying really mean? Why does it satisfy a need?

AES and PHP

After receiving a warning in my PHP implementation of AES encryption (which is called Rijndael), I did a quick google, and found one match - and it happened to be in planet larry, so...  I clicked on the link to go to the blog which contained the fix, and found it wasn't there anymore...  So..  I thought I'd just copy the answer and keep it alive.  It was written in 2008, but apparently is still applicable today.  Here's the blog post.

PHP is sometimes really dumb.

While working on a library for Weave’s OAuth implementation (so 3rd party developers don’t have to understand the nitty-gritty of OAuth and can instead use a simple library in their favorite programming language), I ran across the need to do AES-256 decryption in PHP.

The best (and fastest) method would be to use PHP’s mcrypt extension, but mcrypt lists support for ‘Rijndael’ and not ‘AES’. They’re both practically the same, except for the very small difference of the IV (initialization vector) being different sizes. In Rijndael, the IV is always the same size as that of the key, but in AES, the IV is always 16 bytes.

Weave uses AES-256, which means we have a 32 byte key, and a 16 byte IV. mcrypt implements Rijndael, so my first try:
// $key is 32 bytes long$iv = 'sixteenbyteslong';$td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');mcrypt_generic_init($td, $key, $iv);

failed with:
Warning: mcrypt_generic_init(): Iv size incorrect; supplied length: 16, needed: 32 in aes.php on line 26

Here’s the workaround:
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');mcrypt_generic_init($td, $key, $iv);

That’s right - you call mcrypt_module_open with Rijndael-128 instead of 256, but still pass a 32 byte key to mcrypt_generic_init and be on your merry way.

WTF, but I’m happy that it atleast works.

There ya go!

New Cell: Future Phone

So my contract with my old mobile carrier (Fido) was up and they had no appealing phones so I switched to Rogers and got an LG Eve for $50 (with a 3 year contract). After, I walked over to Staples and then picked up an 8GB microSD card for $30 and I was set.

The LG Eve is an Android 1.5 (Google Linux) phone and it's sweet. I've been fairly pleased with it and the more I dig into it the more fun it is. Now, Android 1.5 is (in this fast paced cell phone OS world) a bit old, but there is word a 1.6 upgrade is in the pipe for spring, so that's cool too.

Anyways, the phone is dead sexy. It's a bit smaller than an iPhone, a full touch screen and more importantly a full pull-out keyboard that makes typing a breeze. It has a proper 3.5mm headphone jack for music and it charges off USB. It has a shocking 5 megapixel camera, wifi, and GPS.

It serves adequately well as an mp3 player so I finally got to chuck my tried and true 1GB iRiver that served me well for 3 years but was getting long in the tooth. It nicely also has some good podcast apps in the market that make getting podcasts on it automatic. I just check and the new ones are there.

It can do video, like mp4 and YouTube, but I haven't yet gotten DivX working on it, so on that front it is a bit limited which is a shame, but oh well.

Now, some of the killer apps for me (aside from replacing my mp3 player):

  • NewsRob: A wonderful Google Reader integrated RSS feed reader that means I can now read all my news on the go, which makes time spent on the bus a lot more productive. This is possibly the most important app for me.
  • Meebo IM: I can connect to all my IM accounts with this one client. There are a lot of IM clients for android, but not too many support proper Jabber. This one does, so awesome
  • ConnectBot: A ssh client that also supports ssh keys. This little app is a must for any sys admins toolkit as it allows me to do server administration on the go
  • Twitteroid: for keeping up with twitter
  • Google Listen: Podcast fetcher. Solid enough. Just wish it supported video feeds (TED talks)
  • Proxyoid: Simple web proxy that couple with the Android SDK allows web tethering (turn on Settings->Applications->Development->USB Debugging, plug in the phone to a computer, turn on proxyoid, and then run 'adb forward tcp:8080 tcp:8080' from the Android SDK and you have a web proxy on your computer on port 8080 through your phone over the cellular network!)
  • TasKiller: App management :)
  • Google Maps: Allows searches for things near you and navigation to them via transit from your location. Fantastic.
  • ShopSavvy and Barcode Scanner: Read barcodes and QR codes through the camera and do web search on products for information on them. Very cool
  • K-9 Email: Thanks to commenter TopperH I found K-9 Email which is a decent android email app. It can actually move messages between folders (lacking in the default email app!) so it will work for me :)

All of these apps make this little phone an incredibly handy tool. It suddenly gives me a lot more power on the go.

Now, the cons:

  • Battery life: Battery life is not fantastic, especially if you are using the phone a lot. I pretty much always need to charge it at the end of the day if I've been using it on the bus or for anything else. It's not fantastic. But because I can just charge it over USB it is at least easy to charge. And considering the power it gives me I can live with this. Also, handily, I have a USB battery pack charger I threw into my backpack, so I can charge it off that if I need while I'm on the go. It's a bit ad hoc but it works.
  • Stability: It's not the most stable phone/system I've ever seen. I seem to have to pull the battery maybe once a week due to lock ups. Some times it's a bit slow or unresponsive. It's not the end of the world, although it may be a bigger problem for other people. I'm happy with the trade off of having all this power and handheld Linux.
  • Wild West-y-ness: This slightly ties into the stability of it and the general app market and may also be somewhat prevalent on other phone OSs too but it feels like the good old DOS and early windows days when there was a glut of crazy random apps for everything before clear market winners were established.
  • Email

I suppose one thing that may get glossed over in comparisons to competitors like the iPhone is that Android can multi-task. That means I can have my IM client running in the background, have a music app playing, and have a text editor open with some text, but be browsing in a web browser that supports multiple pages. This is also amazing and beats the pants off the iPhone.

So on balance I am incredibly in favor of this phone and deeply happy to have it. I'm used to, from 9 years of using Linux and more years of other bleeding edge software, handling a few glitches to get the cutting edge and neatest features and most power. I just consider them part of the price of the overall awesome of the phone, which to be fair, I did name "glitch" only in part because of its occasionally sporadic behavior, and in part because of its portable utility, like Bob's key tool "glitch" from the 90s TV show Reboot.

Finally, I just discovered the coup de grace for this phone (I did say the more I dig, the better it gets): Android Scripting Environment.
It's an app that downloads scripting languages that have partial access to the android API and has a built in text editor. I supports amount other languages Python, JRuby, Lua and perl. I can now code on the go in several hot languages on my phone.

This really is the future phone running Linux I'd been dreaming of owning all last decade. I'm pretty stoked.

Posts for Sunday, February 28, 2010

avatar

A fresh set of mock exams coming right up!

No related posts. No related posts.
avatar

Searching for a new house

I’ve recently moved from Thessaloniki to Athens, Greece and of course the very first thing I had to do was to find a new house. To make my life easier (?) I tried to go a bit techie on that. Using tools/sites on the web and my Android. And here’s what I did and what I used for anyone who might be interested.

First of all I found some sites with real estate listings. The ones I found/used/tried to use were: Χρυσή Ευκαιρία, Rento, Spitogatos and aggelies ta nea.

Each one though has it own benefits and problems, apart from some who only have problems.
Aggelies Ta Nea:
pros
None. I can’t find anything innovative about this site.
Cons
i) It has very few listings of places to rent in the areas I liked (downtown Athens).
ii) It is full of listings by real estates agents who ask you as payment one full rent if they manage to find you a house.
iii) There’s no map showing where each house is.
iv) There are pics of very very few houses in the listings.

Spitogatos:
Pros:
This site has a really neat feature, price per square meter. It’s quite nice to have the site calculate it for you.
Cons:
i) It has very few listings of places to rent in the areas I liked (downtown Athens).
ii) It’s default drop down price filtering boxes are a bit weird. It goes from 150->200->300->500->750>1000 Euros. So if I choose a price range of 300-500 euros I get a url like this:

http://www.spitogatos.gr/gr/search/results/residential/rent/r100/m2011m/nd/all/300/500/nd/85/nd/nd/nd/nd/nd/nd/nd/nd/all/rankingScore_desc

If I change it to:

http://www.spitogatos.gr/gr/search/results/residential/rent/r100/m2011m/nd/all/350/450/nd/85/nd/nd/nd/nd/nd/nd/nd/nd/all/rankingScore_desc

I get exactly what I wanted.
Having drop down boxes might be fine for some people, but they don’t let me be as specific as I would like. A form to fill the price range by hand would be a lot more useful for me.
iii) There’s no map showing where each house is.

Rento:
Pros:
i) Rento is the most innovative site I found. Every house listing is on google maps and you can access its details by just clicking on a house.
ii) It also features a VERY innovative search bar. You actually type a sentence about the house you would like and it searches for it.
iii) Each listing has pictures
iv) You can contact the owner by email
v) There’s an option to note each listing you like so you get something like “bookmarks”.

Cons:
i) It has very few listings of places to rent in the areas I liked (downtown Athens).
ii) The search bar did not have a negation clause. You can’t search for “not something”. So since I didn’t want a ground flour house, I couldn’t filter them out.
iii) The search bar would sometimes filter more than you asked for. If I searched for a price range of 350-450 and got some houses, then if I search for a 40-60 sq. meters I got some others. If I searched for both the price range and the sq. meters I got very very few results.
iv) Many of the listings were quite outdated. Places had been rent weeks ago and the listings were still on the site. (I guess that’s a problem with real estate sites…owners don’t tell the sites whether the house has been sold/rented when that happends).
v) There’s no way to see the most recently placed listings.

The awkward thing about Rento was that I met the people who manage it in a Ruby meeting in Athens one week after I got the house. They were aware of these problems and they said that they have already corrected them and will push their changes to the site very soon. I sure hope so because the site is definitely worth it.

One suggestion for rento would be to have an option to export as kml the “bookmarked” houses.

Χρυσή Ευκαιρία:
Pros:
i) Many many houses listed.
ii) The filtering for the search works very well.

Cons:
i) Very few pics of the houses (if any)
ii) Not every house is listed on a map
iii) In order to get the owner’s telephone you have to send an sms, or call a number and pay some amount of money.
iv) Not every house has an address listed.

I ended up using Χρυσή Ευκαιρία due to it’s massive database with listed houses. I tried to use rento and spitogatos but I just couldn’t find what I wanted. (Maybe I’ll get luckier when I’ll try to move to a new house.)

I then created an unlisted google map called “new houses” and started placing marks on the houses from Χρυσή Ευκαιρία that I liked, sorted by date of last update, and were placed on a map in the site. Then I started calling the owners of the rest to find out where they were. If they were in a place that I liked I made an appointment to go and check the house.
I placed all the appointments at the “TagToDo List” application for my android.
Unfortunately I couldn’t use the “My maps Editor” by Google on my android due to some bug it stopped connecting to google maps. It would be really useful to have this app because I could have all the places I placed on “new houses” and have them with me. Instead I had to print the maps with the marks on them.

Finally in order to walk around the city and not get lost I used the Rmaps application. It’s so much better than the standard google maps because you can get many different maps, and with the addition of GPS Status you can copy paste your exact location to any notes applications you might be using on android to track new houses you find while walking.

Posts for Saturday, February 27, 2010

"Law"

Yesterday I released the new episode of the tentaclepr0n podcast. This time I talk to Matija Suklje about Law, check out the podcast, you can also subscribe to the feed in your favourite podcatcher.

Linking with style .... and speed!

So, I've been slowing going back to using  GNOME instead of using  KDE-4. I do this flip flop every once in a while as I'm never truely satisfied by either. Now, GNOME works quite happily on my  Gentoo/Linux machines, but this is not the case on my favoured  NetBSD ones. Or rather, parts of GNOME don't work as they should, like the  Evolution mail client.

Evolution suffers two problems on my NetBSD box. One, it takes over 5 minutes to load and two, once it has checked and downloaded mail from my server it closes without error. The 2nd problem is probably a programming error in Evolution or one of its many dependencies, but the first problem could be anywhere! Research led me to  this possible soltuion. If you look closely, you'll find an old post by me in that thread fixing it with ld --as-needed on Gentoo/FreeBSD, but that isn't a real solution for NetBSD / pkgsrc users. Anyway, at first glance the patch on that thread makes perfect sense. So I came up with better patches (one for glib, one for Evolution) and it now loaded in under 3 seconds! All was well :)

Well, not entirely. Other applications started to show isses as a result. So at least we know we're in the right area. I then spent a few hours wading through the Evolution build chain and came to the conclusion I still hate autotools as it obscures everything but was no better off fixing it. But I did come up with a test case that opened an evolution library and searched for a symbol that did not exist. This should 30 seconds, which is far too long and is also probably what the poster of the FreeBSD patch did in the mail thread.

Cutting to the chase, the  runtime linker on NetBSD was checking the same library for the same symbol over and over again. Going back to the FreeBSD linker, they have a patch which implements a negative cache which should solve this. But it doesn't, as it doesn't cache missed weak symbols. Luckily this is easy to rectify and you can  find my patch here and an updated one after performance testing elsewhere  here. Now Evolution loads in under 3 seconds and crashes right away - but that's an issue to fix another day :)

Posts for Friday, February 26, 2010

Me on Tentaclepr0n

No, I'm not featured in some bad ass XXX monster-infested hentai anime where thousands Cthulhus rape a whole spacescoolbus of highschoolers in torn mini skirts ...honestly, that's not me ...it's just some other good looking guy ...who ...looks ...a ...lot ...like ...bah, forget it :P

The real deal is that Tante has asked me to be featured on his podcast, that's called Tentaclepr0n. We talked a lot about law — how it all started, why it's interesting (to me), what are the basic differences, why lawyers are seem evil and how t o choose the right lawyer for you.

Well, if for some sick reason you're interested more in me talking about law for a little less then two hours then e.g. in watching hentai, listen to the 2nd episode of Tentaclepr0n.

hook out >> going to bed, lotsa lotsa stuff to do tomorrow

On Genesis commits

I've been asked a few times by different people whether they should push simple patches to genesis. The answer is a resounding 'Yes, please go ahead' but it seems like stating my policy towards other peoples contributions might not go entirely amiss.

My current policy (which will stay until genesis starts stabilising a lot more) is:
  • Any contribution is welcome so you just need to find somebody with push access (the usual Exherbo devs will do)
  • Large patches / feature contributions are also extremely welcome but you might want to contact me first and make sure I won't undo you hard work.

I'm not in any case going to complain about contributions (large or small) so don't hold back. And remember that I have a pressing need for people to play around with genesis scripts and tell me what you need from genesis. git://git.exherbo.org/genesis-scripts.git was created yesterday for this purpose.

And for those of you who don't have direct push access you can just cue your patches using the hacchi patch bot in #exherbo on irc://chat.freenode.net and I'm sure one of the friendly exherbo developers will help you :)
avatar

When an image is stuck in your head…

… you fire up The GIMP and whack it down. It isn’t the full image, but I don’t think I want to share the full image.

Or if you’re interested in zmobies:

I’ve really always wanted to try this style. Large scale version is available on the WIPUP update.

I will be having mock exams from the 1st to the 8th, and have a bunch of gerbloach booked up until the 12th, so updates will be sparse (which is probably a good thing, given the brainfart I’ve been having lately).

Related posts:

  1. GIMPup a Webdesign #2.
  2. The WIPUP 21.02.10 stats are out.
  3. Countdown to KDE 4.4 and the new KDE website: 2 days left

Posts for Thursday, February 25, 2010

Genesis just got internal events

One of the big problems with Genesis was that you'd get its coldplugging events in that the events wasn't necessarily delivered in a sane order. I briefly considered different ways of controlling the order of the events but quickly came to the conclusion that was madness.

The solution I decided upon instead is generating an internal event after coldplugging is finished and send that event to all event modules. This way we can simply trigger on the 'genesis-started' event and start mounting filesystems and whatever else is needed for bootup.

So how can you help? What I need right now from you is just playing around with some homegrown scripts, trying to catch some events and telling me about all the things that are absolutely impossible to do without. Testing Genesis is quite simple and can easily be done without interfering with the rest of your system.

How to test Genesis:
1. Clone the git://git.exherbo.org/genesis.git repository
2. Run ./autogen.sh in the genesis repository
3. Run ./configure
4. Run make
5. Run sudo make install (by default it installs to /usr/local and won't conflict with anything)
6. Write a /usr/local/etc/genesis/config file
My current config file looks like:
[genesis]
# Currently supported log destinations are file and console
logging = console
logfile = /var/log/genesis.log

[modules]
command = yes
netlink-uevent = yes
netlink-route = yes

[netlink-uevent]
coldplug = yes
coldplug_mounts_sysfs = no
log_matched_events = yes
log_unmatched_events = yes
 
 
Ignore all the options except the coldplug_* options. The other options might be necessary due to the rather haphazard way configuration is implemented currently but don't expect them to work right now. The coldplug option enables/disables coldplug events and the coldplyg_mounts_sysfs option controls whether the coldplugging part tries to mount and umount /sys. You want to keep this option disabled unless you're doing actual boot testing.

Stick one or more bash scripts in /usr/local/etc/genesis/netlink-uevent/ or /usr/local/etc/genesis/netlink-route/ and try running: sudo /usr/local/sbin/genesis

The test scripts I'm using currently looks like (from /usr/local/etc/genesis/netlink-uevent/foo.sh):

SUBSCRIPTIONS_add=vcs10

add()
{
    echo "netlink-uevent::add" >> /var/tmp/genesis.log
}

You can add any number of event subscriptions you like in a single script or spread subscriptions over several scripts. Each subscription is defined as SUBSCRIPTION_function=trigger

Trigger is simply a regex that matches the metadata from events in an internally serialized string format. Function denotes the function in the script called when matching that event. So all the above script does is triggering the add() function on all events matching the string 'vcs10'. Since I have coldplugging enabled I'm guaranteed to see that event.

And that's all there is to it.. One of the things high on my TODO list is to replace the regex matching with a udev like language where I can match on subsystem, MAC address or whatever other metadata events generate. I'd very much appreciate comments on what you think is needed in a simple language like that.

Posts for Wednesday, February 24, 2010

So why do you have a facebook account?

What you see here to the right is a screenshot of my Facebook account. Those of you able to read will see some rather clear hints on the fact that I don't "use" it for "proper" reasons: I don't "friend" people, I have no "posts" and there are no pictures of me drunk or showing my invisible man-boobs into the camera. You could say I fail at facebook.

It's not that I wouldn't know how to deal with that thing, far from it, it's just that I don't want to because I don't support what facebook is. "Why do you have an account then?" might be a question you are asking yourself my dear reader (and you wouldn't be the first, I get that question a lot after declining friendship requests by people I know) so let me answer that briefly.

Back when people started being "connected" with modems and such there were "Compuserve" and "AOL". (There were obviously other things but for simplicity's sake we'll leave it at that.) Both of these services provided chatrooms and pages and whatnot to their users, all but one thing: They didn't talk to each other. If you were in AOL land, you stayed in AOL land. That sucked and as soon as people saw that there was a huge internet out there with different and interesting people and content, that concept died (just like AOL and Compuserve).

Facebook is the new AOL. Instead of using email that is portable, platform-independent and a fucking standard people send facebook messages. That stay within facebook. That you can only send to other people in facebook. Do you see a similarity here?

Facebook might have a different idea about privacy than I have, on the other hand, I see that they are offering some sort of mechanism for you to make sure that the pictures of your naked genitals are only shown to your boss, or mom, or whoever needs to see that. I mean it's a bloody social network, privacy will always be just an added bonus. But that's not the big problem.

Calling it a cage would be wrong because people can go out and facebook is really good at pulling stuff in, it's not. It's like a country club of sorts but instead of membership fees you pay with your social network. But the point is that there is a guard at the door that does not let anyone in. If you wanna get in you need a membership card, which is free, if you tell me who you know. The problem, as I said, is not having to pay the price because we all know that there is no such thing as a free lunch, the problem is the guard at the door checking for membership.

"But anyone can join so stop complaining." Yes. So more and more stuff is being put into Facebook. At some point it will only be in facebook because "everybody is already in there and we don't want to publish this twice". And at some point someone will not be allowed to join anymore. Maybe cause his own government thinks that censorship and free communication ain't that keen or cause his provider thought that facebook just sucked and needed to be removed. And that's the problem: Even if you club takes everything and we should just enjoy whatever it can provide, at some point you'll not let someone join and then everything's fucked.

I have an account there so I can enter the "other internet" and get information there that some retard only put there. I don't really wanna be involved in the club and I'll not be moving my stuff into the clubhouse. Because I like an open and free internet.
avatar

Site review: BestWindowsMobileApps

This is a sponsored review by the owner of the website but all opinions are that of my own.

Windows Mobile 6.5.3 and below is widely regarded by many tech fads as a to-be-deprecated technology in favour of other smartphone OSes and possibly the upcoming Windows Mobile 7 OS, revealed just over a week ago. However much of the hidden credit behind the WM 6.x series lies in its ability to tweak and adjust the OS to such an amazing extent not really associated with Microsoft – all of these are found in 3rd party applications scattered around the internet that it takes such a long time to monitor the upcoming applications and find reliable ones. This gives the false impression that the system is underpowered. It wasn’t until almost a year ago that Microsoft released the Windows Marketplace, the equivalent of Apple’s App Store in order to solve this problem, but it’s a developer-initiative process to distribute using this system, and so many of the gems still remain hidden.

Those who have gone app-hunting would be familiar with sites such as freewarepocketpc, wm6software, pocketgear and the ever-so-reliable XDA-Developers forums. However we have a new kid on the block, BestWindowsMobileApps.com.

The site at first glance runs on Wordpress with an aesthetic design that leaves little to be desired. This Wordpress setup has all of the necessary plugins and additions which make the site appropriate to its purpose, including a featured application section, random apps, latest apps, social network sharing, related links (quite inaccurately labeled as a blog roll in our opinion), and the compulsory commenting system. It communicates its purpose extremely clearly and despite a seemingly random blank space on each sub-page near the header (probably for advertisements in the future), it looks extremely credible and up to date, which is a vital impression for such a site.

The site gives an unbiased review of applications submitted by developers and rates them on what I believe to be rather well-chosen sub categories: user interface, features, ease of use, and re-use value (if the app is a one-time use-and-forget or not), and for games graphics and sound ratings are also provided. Each of these are given a half-star rating out of 5 of which each rating is given a clear definition in their about page – 1 star for a application that wasn’t even worth the review and 5 stars for the perfect application that deserves recommendation to all WM users.

The site is two-tiered, splitting applications into two main categories, "Applications" and "Games", then further narrowing down the choice to your regular list of sub-categories such as communication, entertainment, lifestyle, media, etc. Although most of these portal sites have these categories this site is different in that it is completely centered around them instead of offering a more random browsing experience like others. Unfortunately there seems to be some navigation duplication in the main menu, such as Apps takes you to the same place as Categories -> App Store does, or we seem to have an unneeded single subcategory under Tools being Utilities, or that the supposedly macro-category of "games" is seen again inside Categories -> App Store, etc. Similarly we were shown this link to what seems like a "Games category" description page, but I haven’t been able to find a way to navigate to that page on the site. Perhaps because that page seems unfinished (some categories are not annotated) but this suggests a few fundamental navigation problems. This may serve to confuse newcomers but is a relatively easy problem to fix and on the whole provides a very instinctive navigational sitemap.

The list of applications is just as aesthetically pleasing as the rest of the site. It provides a quick snapshot of the name of the application, a dedicated icon (instead of other sites which rather badly autogenerate thumbnails) and a blurb. Although a little too much emphasis is placed on the date and reviewer than we’d like, we suppose it matches the feel of the site. Given that a one-liner summary of the app’s function is appended to its title it makes it really easy to find what you’re looking for.

An application’s review page does suffer from some visual glitches here and there that detract from the previous professional impression of the site. Some layout ideas could be rethought, such as placing the tags, post author and date and a rather large box with minimal information at the top instead of launching right into the review. However the review itself is presented in well-formatted narrative blog format not unlike this post and has plenty of app screenshots showing the app in action. It walks through the beginning impression, tours the features, and provides a consice summary to wrap up. The writing style is easy to understand and well-structured. Consistent throughout all reviews are a bullet pointed pros, cons and a possible improvements section at the end, your version number and price, the beforementioned star ranking system and an overall rating. A complementary link to the developer’s site is provided as well as a link to their sister site to download the product. The rest is taken up by social networking and comments which unlike most other review sites contribute quite intelligibly to the review.

Developers can submit their apps for review on quite ethical terms including unbiased reviews and understandable property rights. It’s a simple enough process and very appropriate.

Overall the site is quite polished with a few visual presentation quirks to work out. Some reviews are a little short (especially those with low rankings) but seem to communicate the message effectively enough. The duplicated navigation may be confusing, as well as some category structures needing to be rethought (for example, what is the "XDA dev" category?). The site is still quite immature in terms of content quantity (we’re predicting about 100 reviews, and we did notice some overlap in categories, which isn’t necessarily a bad thing) but from what exists, it’s some good quality reading for those on the hunt for the perfect application set. I must say I didn’t set my sights high given the existing cobbled and maze-worthy app portal sites but this one has potential.

Related posts:

  1. Windows Mobile 6.5 Review
  2. Review of Doteasy hosting.
  3. Google Wave Review

Remember Genesis? The oft mentioned new init system for Exherbo?

If not you might want to read this old exherbo-dev post to refresh your mind.

Genesis started out as me being rather frustrated with current init systems and their huge failures. My basic idea was that all the different init systems fail badly at solving any real problems for system administrators and that it was about time fixing that situation.

So as I started really thinking about the problems that init systems should solve I decided that writing a new init system from scratch was the approach..

A short while later I discussed most of my ideas in a talk at FOSS Aalborg and had a fair bit of positive feedback. It's worth noting that I haven't started writing any code at this point and consequently my problems hadn't started yet.

When I did start writing code I quickly got even more ideas for Genesis and it became an even more ambitious project. And then it changed radically.. again and again.

Due to all the changes and lack of direction I didn't want to publish the code and it was often compared to Duke Nukem Forever (for good reasons I might add). But now that I finally seem to be reasonably sure about the direction I've finally released the code for everybody to peruse and contribute to.

The current status of the code is quite messy and it's not yet usable as an init system at all. You can glean the basic ideas of it however and there's a TODO list that you're most welcome to take a swing at. A few people have already contributed some minor patches for the build system for which I am grateful. I'd get around to fixing those things myself but for now I'd rather focus more on Genesis design/architecture and make sure that development progresses quickly.

As for progress I'm trying to make sure I do at least one Genesis commit every day and tracking that on http://calendaraboutnothing.com/~kloeri. Some days might only see very small commits but I'm shooting for larger, daily updates.

My primary goals right now is getting Genesis to a state where it can boot a system as well as making the code more hacker friendly so more people can contribute.

As for booting I expect to set up a separate git repository for genesis scripts as soon as Genesis is ready for that. It's my hope that most scripts will be contributed by other Exherbo contributors and that I can keep my focus on Genesis itself.
avatar

How to Mount a VMware Virtual Disk in Windows

Here is handy tool that is part of VMware Workstation, but isnt as well know as some features but can be a real timesaver! Let’s say your working on a Virtual Machine however it is turned off but you quickly need to pull an important file from it to use or check something you would normally [...]

Posts for Tuesday, February 23, 2010

Book review: Python Testing: Beginner’s Guide

Recently a new book on software testing in Python projects was published by Packt Publishing, “Python Testing: Beginner’s Guide”. I’ll read the book the coming weeks (it didn’t arrive yet) and publish a review later on.

If you’re into Python software development, you might want to take a look at the book webpage, or download a free chapter (PDF) about the standard Python unittest package for now.

Since I’m not a big fan of extensive/exaggerated unit testing and rather believe in functional/component tests, I’m looking forward to read the book and learn some new things. Looking forward to the web application testing chapter, among others.

Disclaimer: I was invited by Packt Publishing to review this book, and they provide a free copy.

Posts for Sunday, February 21, 2010

Gentoo Mozilla Team meeting decisions

On Feb 21st, Sunday, the Gentoo Mozilla Team had an informal meeting to discuss some of the recent changes which have a large-ish impact on users. Below is a list of them and the decisions that were taken. After the list is a description of each decision.

SQLite with Firefox: Firefox will use the bundled sqlite by default. Users can select the system-wide sqlite by setting USE=system-sqlite.

Ebuilds for Extensions in-tree: The Gentoo Mozilla team will not ship ebuilds for extensions such as noscript and weave anymore. We will only have ebuilds for extensions which are linux-specific and compiled; such as enigmail.

Firefox and Thunderbird Alphas and Betas: In addition to the overlay, we are going to start placing alphas and betas of Firefox and Thunderbird in the tree with a package.mask and a big fat ewarn during installation. Adventurous users are encouraged try them out but report bugs only in the Gentoo bugzilla. Do not go to upstream unless we ask you.

NOTE: These ebuilds will not have language packs since upstream does not release packs for these.

NSS/NSPR Changes: This involves various cleanups to the ebuild, and moving of the libraries from ${libdir}/{nss/nspr} to ${libdir} and removal of the /etc/env.d/08{nss,nspr} LDPATH entries alongwith corresponding changes in firefox-bin and thunderbird-bin launchers. These changes should be completely transparent to the user.

Revival of #gentoo-moz @ FreeNode: The mozilla team has expanded in recent times, and with that we have decided to revive the ages-old #gentoo-moz irc channel. Users are welcome to idle, discuss, and ask for help on that channel. Come on over!


Why we made these decisions:

SQLite with Firefox: We've done flip-flops on using the system-installed sqlite for for XULRunner and Firefox. Initially, we used the internal one, but folks reported bugs about that (we prefer not to use bundled libraries), so we switched to the system sqlite.

Then with the next version of Firefox, people started reporting major bugs with using the system sqlite and we temporarily disabled it. Once the problems were resolved, we added USE=+sqlite to use the system-installed sqlite by default.

Recently, another issue cropped up: upstream mozilla was getting bug reports that the sqlite db was insecure, and trivial tools like grep could be used to get (private) deleted information from it. They traced that to distros using the system sqlite which didn't have support for SQLITE_SECURE_DELETE. They then made that a mandatory configure check with 3.6 (and we added a dep on the system sqlite for it). Soon, we started getting bug reports from people who did not want that enabled system-wide (since it zeroes out the data when deleting it, which has a performance penalty). Upstream made it clear that they would not make the check optional.

In the end, we decided to make firefox use the internal sqlite by default, and allow the user to select the system installed sqlite via USE=sytem-sqlite if they are ok with secure-delete being on system-wide.

Ebuilds for Extensions in-tree: We found that a number of extensions were being released at a very swift rate which meant two things:

  1. Bumping ebuilds was very tedious, which led to them becoming stale very quickly
  2. Judging whether an ebuild can go stable was not possible, and most often the extension developers just want the users to use the latest release.
This offset the benefit of users being able to install extensions system-wide and have it managed by portage. Users can still manually install and manage system-wide extensions if they so wish. They are also free to copy the old ebuilds to their local overlays and use them if they wish.

Firefox and Thunderbird Alphas and Betas: Mozilla Upstream has been complaining that their betas and release candidates don't get much testing on Linux since all the distros ship only the final releases. This means that bugs are caught very late, and aren't fixed till the next major version. To help with this, we've decided to revise our release strategy and give a bit more visibility to our alphas and betas (which are generally kept in the overlay) by pushing them to the tree under package.mask, and with large ewarns all over the place. Users are strongly advised NOT to report bugs with these directly to upstream. Please use the Gentoo Bugzilla.

NSS/NSPR Changes: the libraries for nss and nspr were installed in a prefix due to collisions with other packages (libssl.a for instance). Recently, Google decided to use portage for cross-compiling and managing ChromeOS. This combined with some bugs reported with NSS/NSPR led to some investigation, and a voluntary review of the ebuilds.

This led to a number of changes which included disabling static libraries for NSS and NSPR, and moving the rest to ${libdir}. Further details on the changes and their "why" are listed on the review bugs linked above.

Getting list of referers out of Apache logs

I use Google Analytics, but it has a noticeable lag in updating its information. When my site is being hammered, I'd like to see where all the traffic is coming from. It'd also be nice to see how many hits my RSS feed is getting, and how many images and static files are being direct-linked, which Google Analytics currently isn't tracking for me at all.

So this script will look in my Apache logs and print referers for some URL, thanks to ApacheLogRegex:

#!/usr/bin/ruby

require 'apachelogregex'

raise "USAGE: #{$0} log_filename desired_url" unless ARGV[0] and ARGV[1]

format = '%v:%p %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"'
parser = ApacheLogRegex.new(format)
pat = Regexp.new(ARGV[1])
refs = {}

File.readlines(ARGV[0]).each do |line|
  x = parser.parse(line)
  if pat.match(x["%r"])
    r = x["%{Referer}i"]
    refs[r] = (refs[r] || 0) + 1
  end
end
refs.sort_by{|k,v| -v}.each do |ref,count|
  puts "%s: %s" % [count,ref]
end

I used to use awstats for this, but it was too heavyweight and a hassle to set up and keep running. Google Analytics is a no-brainer to use, even though the accuracy isn't as good as parsing Apache logs. At least I get an idea of which of my blatherings people are most interested in.

The Gift of Attention

I cannot stress this enough. When someone asks you to listen, listen to them. When they ask you to listen to their favourite song, or to a song they think is beautiful, listen to them and listen to it. When they show you something that moves them, look at it and try to see how it moved them. They find it special, and are sharing it with you because they find something in you that is special. Don't squander that special gift away. Spend a little time. You'll understand them better.

a new workstation II

source hp.com

source hp.com

some updates about my laptop. i removed lvm and my ‘luks partition’ which seems to work much better now as i don’t have this massive io-wait issues anymore.

  • i’ve tried several schedulers: ‘noop anticipatory deadline cfq‘ but none did the trick. it seems the issue is somewhere else. i’ve made some benchmarks but i did not find the file where i stored them ;P
  • compiling ogre 3d 1.7rc1 crashed my computer a few days ago, maybe 2gb ram are not enough and/or my linux installation is somehow broken or a driver isn’t done right – i did not find out what causes that yet
  • compiling big packages in general often results in massive swapping which will shut down firefox (with probably 20tabs) soon and sometimes it kills xdm as well – does not happen too often
  • but i still use xfs and i did not have any further data loss although, coming to the next problem
  • my laptop crashes on ever 4th resume cycle and i have to ‘force power off’ with 5seconds pressing the pwr button this is because of nvidia.ko, i’m currently using: x11-drivers/nvidia-drivers-190.53-r1
  • the quality of the nvidia proprietary driver is currently very low and ….. yes you know the story
  • i tried to enable ‘vt’ for experimenting with virtual machines when i suddenly realized that all the issues with the nvidia.ko proprietary driver NOT starting X was caused by enabling this option. after i disabled it (in the bios) X resumed to work. i did not know that this was the cause for X not to start up. also the error logs did not show anything interesting?! strange, isn’t it?
  • since i’m nearly done with the ogre3d stuff i was doing i’m looking forward removing 3d support and experimenting with kms and the open source nouveau driver comming with kernel 2.6.33+
  • all other hardware-components seem to be working pretty well, i can’t complain about anything expect the bad graphic card drivers – i think that is the only proprietary module i’m currently using
  • and i’m not using any kde pim application anymore since they suffer from very low quality (did i mention this already?) for instance they crash, they duplicate my addressbooks, on updates .kde dir (which stores all configs) sometimes is renamed to .kde4 (might be gentoo specific), xfs crashed all my ‘open’ files in .kde about 2 times now. so i’m using psi, thunderbird and firefox which seems to be working.
  • i’m currently on kde 4.3 but i will try 4.4 soon
  • my windows xp migration stopped working, not sure why – probably because my installation of grub. i should probably try to install a more recent windows version since this xp installation requires to set my sata controller into ide compatibility mode (which might be bad?)
  • i’m now using smartd on all my computers, really a nice tool!
  • my sound support sometimes is broken and i can’t use skype for telephoning, also the composition of mics in this laptop somehow does not work well with alsa as i can’t really predict which alsamixer settings makes the mic work and which not. most often it is basically random clicking until something works – welcome to linux audio. also flash sometimes does not work with sound when i use different players to play audio

Making an RPG in Clojure (part one of many?)

What do you get when you combine old-school Final Fantasy-style RPGs with Clojure? Fun times for all. Well, for me at least.

I'm working on a sort of RPG engine in Clojure so I can make my own RPG. Click the thumbnail for a very preliminary video demo (6.5 MB) showing the engine in action.

RPG Demo

All I do in the video is walk around, and eventually start adding random NPCs to the map to test collision detection. Not all that exciting, but I'm proud nonetheless.

To forestall questions, yes I'll eventually post the source code, but no, not yet. It barely works. Just a proof of concept so far.

Right now I can walk around a map while NPCs also randomly walk around the map, not much more. So there isn't much to talk about. But not bad for 4 days and 600 lines of code (one tenth of which is ASCII art... more on that later). Keep in mind that I have no idea what I'm doing.

Collision detection works so people don't walk through walls or each other, and after endless tweaking I got all the animations to be very smooth, even when I add a few dozen NPCs to the map (as I do in the video). The video is a bit jerky but it looks better in person. All of the admittedly poor artwork is also created by myself, thanks to the GIMP and some hastily-read tutorials on pixel art.

It all runs on plain old Swing in Clojure. Here's some of what went right and what went wrong so far.

Background

I've played a lot of RPGs, but I've never programmed a game more complex than Pong. I knew what double-buffering is, and that's as far as my knowledge of game programming went when I started.

My first idea was to use a plain old Swing JFrame. I'd make a bunch of sprites saved as PNG files, read them all in and draw them on the JFrame, as many times per second as I could manage. Then there's some global state to keep track of where everything is. Simple enough.

(PS I have no idea what I'm doing.)

Failures

My first version used Clojure agents (i.e. threads) for everything. The game logic was a thread, the renderer ran in a thread, every NPC was its own thread. The world itself was a single ref that all of these agents banged on. So the NPCs would tell the ref "I want to move down one square", another thread might say "Brian just pushed 'left' on the keyboard, so start scrolling the map". The world-ref would kindly oblige while preventing two NPCs from standing on each other or letting the PC walk through the walls.

Clojure is awesome in letting you do this in a completely safe and coordinated way. Everything worked well. But even for the crappy 2D graphics I'm using, all those threads caused way too much lag. I could get a good framerate if everyone was standing still, but if I was walking while the NPCs were walking, I'd get lots of lag. It was even worse on a slower computer.

My best guess is that the reason for the lag was the constant restarting of canceled transactions due to multiple threads trying to edit the world ref 50+ times per second. My sucky 2-core CPU couldn't keep up. It isn't surprising that this failed, in hindsight.

OpenGL?

Next, I decided to try out OpenGL. There are multiple options for OpenGL in Java. One is JOGL and another is lwjgl.

I program in Linux, and my video card is ancient. I can barely get OpenGL to work in the best of times. Installing JOGL was a slight chore (Gentoo doesn't even include it in its repo). JOGL is not just a JAR you throw onto CLASSPATH, you need some native extensions, obviously. I got it running somehow, but I wouldn't want to explain to someone else how I did it.

I did get jwjgl to work too, eventually, which was nice. There is a really nice Java 2D game framework called Slick which uses lwjgl. Some good games were created using this, for example Stickvania, which recently hit Reddit recently. I got Slick up and running in short order.

Unfortunately Slick doesn't play nicely with a Clojure REPL. I could build and start a game, but once the game is stopped, it never runs properly again without restarting the REPL. Slick caches images to try to be speedy, and it seems like the cache is either corrupted or destroyed when you close down your game, for one thing. This is not conducive to Clojure REPL-style development, and I didn't want to spend a lot of time fixing it.

Another issue is that I'd really like this game to be cross-platform and available to non-hackers, and the thought of trying to tell the average gamer how to install JOGL or lwjgl was daunting, given the bullcrap I had to go through. Not sure if I can just throw JOGL into a JAR and distribute it, maybe I can, but I didn't want to bother reading about it. Swing on the other hand runs everywhere with no effort.

My main problem is that I know even less about OpenGL programming than I do about Swing, and don't have a month to learn. Back to the drawing board.

Success

It turns out I don't need OpenGL anyways. All I need is program more intelligently. (Did I mention I have no idea what I'm doing?) Instead of dozens of threads, my current (working) version has one thread. It updates the game logic, then renders the game, then waits 10 milliseconds or so, then repeats this (forever).

With the single-threaded version, the logic is actually more complex than the multi-threaded version. Agents and refs were really nice and braindead-easy to work with. But such is life.

Once I learned about keeping track of things in realtime by counting milliseconds instead of counting frames or using timeouts to do logic/render updates, things worked better. (Did I mention I have no idea what I'm doing?) The game loop looks like this now:

(defn game-loop [#^Canvas canvas]
  (loop [last-time (get-time)]
    (let [curr-time (get-time)
          delta (- curr-time last-time)]
      (do-logic delta)
      (do-render canvas)
      (when @RUNNING
        (Thread/sleep 10)
        (recur curr-time)))))

The code to actually start the game, to give you an idea:

(defn start-world [world]
  (let [#^JFrame frame (doto (JFrame. "Game")
                         (.addWindowListener (proxy [WindowAdapter] []
                                               (windowClosing [e] (stop)))))
        #^JPanel panel (doto (.getContentPane frame)
                         (.setPreferredSize (Dimension. REAL-WIDTH REAL-HEIGHT))
                         (.setLayout nil))
        #^Canvas canvas (Canvas.)]
    (doto canvas
      (.setBounds 0 0 REAL-WIDTH REAL-HEIGHT)
      (.setIgnoreRepaint true)
      (.addKeyListener (proxy [KeyAdapter] []
                         (keyPressed [e] (handle-keypress e))))
      (.addMouseListener (proxy [MouseAdapter] []
                           (mouseClicked [e] (handle-mouse e))))
      )
    (.add panel canvas)
    (doto frame
      (.pack)
      (.setResizable false)
      (.setVisible true))
    (.createBufferStrategy canvas 2)
    (dosync (ref-set RUNNING true)
            (ref-set PAINTER (agent canvas))
            (ref-set WORLD world))
    (send-off @PAINTER game-loop)))

That's about it for the Swing side of things, aside from scribbling on the Canvas in the render function.

The agent I wrap around the Canvas controls the thread that runs the game loop. The agent helpfully keeps track of any exceptions that happen during the loop, and I can view those exceptions via agent-error, which is handy for debugging.

Note how little code it is to set up a keyboard event handler, thanks to proxy:

    (doto canvas
      ...
      (.addKeyListener (proxy [KeyAdapter] []
                         (keyPressed [e] (handle-keypress e))))

A couple lines of Clojure for what would be a lot of senseless boilerplate in Java. Notice how you the keyboard handler calls a normal Clojure function handle-keypress. Clojure / Java interop really is seamless.

Maps

My maps are made using ASCII art. (Did I mention I have no id-... never mind.) Here's the code for the test map, for example. Map here is a deftype (available in bleeding-edge Clojure), which takes a map of tiles, a "pad" tile, the map, and then a mask showing walls / tiles where the player shouldn't be allowed to walk. My Map type acts like a Clojure hash-map most of the time, but it also lets me name the fields that all maps should share, and has a proper "type", among other things.

(deftype Map [tileset pad tiles walls]
  clojure.lang.IPersistentMap)

(def test-map (cache-map
               (Map {\  (tile "ground")
                     \/ (tile "ground-shadow-botright")
                     \< (tile "ground-shadow-left")
                     \d (tile "dirt")
                     \| (tile "wall_vertical")
                     \- (tile "wall_horizontal")
                     \1 (tile "wall_topleft")
                     \2 (tile "wall_topright")
                     \3 (tile "wall_bottomleft")
                     \4 (tile "wall_bottomright")
                     \u (tile "below-wall")
                     \v (tile "below-wall-shadow")
                     \w (tile "wood-floor")
                     \c (tile "cobble")
                     \b (tile "bush")}

                    (tile "ground")

                    ["                 1----2                            "
                     "                 |vuuu|                            "
                     "1----------------4<bbb3--------------------------2 "
                     "|vuuuuuuuuuuuuuuuu/   uuuuuuuuuuuuuuuuuuuuuuuuuuu|<"
                     "|<1------------2               cccccccc d        |<"
                     "|<|vuuuuuuuuuuu|<       d      c      c          |<"
                     "|<|<           |< cccccccccccccc    d ccccccc d  |<"
                     "|<3------ -----4< c                         ccccc|<"
                     "|<uuuuuuu/uuuuuu/ c  1-------2    1------------2 |<"
                     "|<1---2 bcb       c  |vuuuuuu|<   |vuuuuuuuuuuu|<|<"
                     "|<|vuu|< c  d     c  |< 1-- -4<   |<           |<|<"
                     "|<3- -4<bcb       c  |< |vucuu/   3------ -----4<|<"
                     "|<uu/uu/ c        c  3--4< c      uuuuuuu/uuuuuu/|<"
                     "|<  c  dbcb       c  uuuu/ cccc         bcb      |<"
                     "|<  cccccccccccccccccccccccc  cccccccc   c   d   |<"
                     "|<  d        d                     d ccccc       |<"
                     "|<                    1--------------------------4<"
                     "3---------------------4uuuuuuuuuuuuuuuuuuuuuuuuuuu/"
                     "uuuuuuuuuuuuuuuuuuuuuuu/                           "]

                    ["                 xxxxxx                            "
                     "                 x    x                            "
                     "xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
                     "x                                                x "
                     "x xxxxxxxxxxxxxx                                 x "
                     "x x            x                                 x "
                     "x x            x                                 x "
                     "x xxxxxxx xxxxxx                                 x "
                     "x                    xxxxxxxxx    xxxxxxxxxxxxxx x "
                     "x xxxxx x x          x       x    x            x x "
                     "x x   x              x  xxx xx    x            x x "
                     "x xx xx x x          x  x         xxxxxxx xxxxxx x "
                     "x                    xxxx                        x "
                     "x       x x                             x x      x "
                     "x                                                x "
                     "x                                                x "
                     "x                     xxxxxxxxxxxxxxxxxxxxxxxxxxxx "
                     "xxxxxxxxxxxxxxxxxxxxxxx                            "]
                    )))

This lets me make all of my tiles be simple PNG files with sane names. I could dork around with sprite sheets, but why bother? Emacs or Vim column-editing and overwrite modes make it easy enough to make a map this way. Swing thankfully handles transparency for me if I use PNGs, so it's a no-brainer to make multiple map layers later, which I'll need later. The code for reading in PNGs is brain-dead simple thanks to Java's ImageIO:

(defn tile [name]
  (ImageIO/read (File. (str "img/" name ".png"))))

The cache-map function (below) iterates over the ASCII art (via seqs on the Strings), using each character as a key into the map of real images, and builds a BufferedImage out of it. This is cached, since the renderer needs to re-draw the background every frame. In this function I'm also drawing a "padding" layer to sit under the background, so that I see endless fields of grass when I walk close to the edge of the map, instead of garbled, smeared-out graphical artifacts.

(defn cache-map [amap]
  (let [height (count (:tiles amap))
        width (count (first (:tiles amap)))

        #^BufferedImage img (BufferedImage. (tile-to-real width) (tile-to-real height) BufferedImage/TYPE_INT_ARGB)
        #^Graphics2D g (.createGraphics img)

        #^BufferedImage pad (BufferedImage. (tile-to-real width) (tile-to-real height) BufferedImage/TYPE_INT_ARGB)
        #^Graphics2D padg (.createGraphics pad)]
    (doseq [[y row] (cseq/indexed (:tiles amap))
            [x tile] (cseq/indexed row)]
      (.drawImage padg (:pad amap) (tile-to-real x) (tile-to-real y) REAL-TILE-SIZE REAL-TILE-SIZE nil)
      (if-let [#^Image img ((:tileset amap) tile)]
        (.drawImage g img (tile-to-real x) (tile-to-real y) REAL-TILE-SIZE REAL-TILE-SIZE nil)
        (throw (Exception. (str "Missing tile " tile ".")))))
    (assoc amap
      :map-image img
      :pad-image pad
      :max-map-x width
      :max-map-y height)))

This code is nasty, mostly due to converting between tile-based coordinates and pixel-based coordinates. This code needs to be cleaned up a bit. But that's about the most complex code you'll find in my program so far.

Who needs mutable state?

Clojure is a mostly functional language, in the sense of strongly discouraging unnecessary use of mutable state, and this program is no different. I'm sometimes amazed how far I can get before I need mutable state at all. The vast majority of my functions take a world value (a plain old hash-map) as an argument, and return a new world value after making changes to it. The current state of the world is whatever value is currently in the global WORLD ref.

The render loop grabs a snapshot of the world from the ref on each iteration, and then draws it. Thanks to Clojure refs, the snapshot of the world is guaranteed to be consistent (e.g. no NPC objects in the middle of mutating themselves) and persistent (the world value sticks around as long as the renderer needs it, even if the WORLD ref is changing in another thread). Once it's been drawn, the renderer throws the world snapshot away and it's garbage-collected later.

This all happens around 50-100 times per second in my game, and there's no noticeable lag. So that's a good thing.

Conclusion

That's about it. I'll post the full source code once it doesn't suck as much.

In my opinion, exploring a new area of study is some of the best fun a person can have. It's a flood of information and a surprise every 10 seconds.

Making a game has been like that. There's a huge wealth of knowledge about this kind of programming that I never knew existed. Everything I read on this topic is new to me and fascinating. The saddest(?) part of this whole thing is that I'm going to have more fun programming this game than I usually have playing games I buy in the store.

(World Famous) Audio Hacker offline??

This came as a shock — (World Famous) Audio Hacker seems to have disappeared from the face of the internet!

I've already posted about his music and interesting projects (Tron.FM being just one of many), but now that I wanted to download some of his tracks again, it's all gone — his website is gone, Tron.FM's website is gone, his Last.FM and MySpace profiles are almost empty, his Fairtilizer page is gone ...everything!

If there weren't any backups on Archive.org, you'd think it never was there in the first place ...very odd. It seems some people didn't like him making mashups O_o

hook out >> grieving for lost albums and tracks, trying to start the OpenHeads emoticon set
<!--break-->

Posts for Saturday, February 20, 2010

Windows7: Welcome to 1990

Approximately one in twenty times when I try to log on to my work computer (running Windows 7 Professional™), it lags for 2 minutes and then I see this:

Windows 7 crash

That's the Microsoft I know and love. (By "love", I mean the opposite of love.) Just like the good old days. I'm glad my employer bought this computer and I didn't have to spend my own money.

80% of the time on this machine I'm sitting in Virtualbox using Ubuntu, thankfully.

avatar

WIPUP 21.02.10 released and out in the wild.

WIPUP is a way to conveniently share progress on your projects. Given the mix of solutions used before such as work-in-progress forum threads, blog posts, mailing lists and microblogging, we’re creating a flexible and friendly solution to answer the question “what’s up?”.

People focus so much on the finished product they ignore the beauty of the creation process behind it.

Yep, it’s WIPUP 21.02.10a and it’s still (denoted by the postfix “a”) alpha. This means it’s unfinished and not yet ready for the general public. However despite this a huge amount of progress has been made since the first and a lot of polish along with it. I highly recommend those who’ve been edging towards trying WIPUP out to take the leap. The full details are given in the release notes (comments appreciated).

After you’ve skimmed through the release notes go check out the site. Or if you’re curious you can check out my profile, which serves as a pretty good demo of WIPUP in use.

As for potential developers, here’s a friendly reminder that WIPUP is open-source and I’d love to see a few new faces.

Time for a break.

Related posts:

  1. WIPUP 14.01.10 released!
  2. WIPUP February release date revealed. Ooooh.
  3. WIPUP on Trac

ogre 3d II

some updates about ogre 3d

  • 1.7 will have a samples browser
    i actually do hate the sample browser deployment as well as the concept it does implement. if one uses cmake and forgets to modify the ‘CMAKE_INSTALL_PREFIX’ but afterwars installs the library using ‘DESTDIR=/tmp make install’ nothing will work since all resources.cfg, plugins.cfg and media.cfg contain the wrong location and since the program is installed as root but executed as normal user it fails horribly when starting the SampleBrowser. but more important – since the sample browser loads the plugins as shared objects (for example ./lib/Sample_Water.so) the samples are degraded as ’showcase’ only but can’t be used to play with directly as it requires a complicated installation mechanism. i see two fixes: either create another CMakeLists.txt which can build standalone runners for each sample or write a standalone runner for this create .so files. but in general i don’t like what they did, it degrades the quality of the samples since you have to run the SampleBrowser, find the plugin you want to have a look at and next you have to search the soure directory for the plugin.
    let’s see how the trolls (authors of qt) did that in comparison: they build standalone examples; they give you the source-code and the binary in one directory; they do code documentation based on a comment system which parses the example code.
  • 1.7 will use cmake for the ogre library (instead of autotools) -> i absolutely love this! this still has some quirks but i think it’s very good work!
  • using ogre disabled ‘key repeat’ every time i start my application, i need to type: ‘xset r on‘ to re-enable it. did not find out why…
    UPDATE: seems to be fixed in 1.7rc1
  • ogre displays a configurator everytime i start my application which configures the ogre ‘ogre.cfg’. this window shows up and since 1.7rc1 i  CAN NOT press ‘return’ directly to continue with the default settings – instead i have to click the ‘accept’ button with the mouse.  every time! this is VERY ANNOYING! maybe this has something todo with my ‘focus widget’ policy but since all other programs on my system work and especially since ogre 1.6 did work that way i wonder why this ‘ogre configuration widget’ does not have focus after i start my application…?
  • freeimage issue: the old ogre 1.6 had devil support but they probably dropped it (i’m not sure about that but i tried to find ‘devil’ in the source code (1.7rc1) but came up with only a few references, most were in the documentation) and therefore one needs freeimage for which i don’t even have an ebuild. so i installed freeimage and afterwards – once again – ogre. i basically compiled and installed ogre a couple of times to find that out – since freeimage is very important and without it no sample works and all you can see is this yello/black textures all over the place and some errors in the log which don’t make much sense without massive googling.
    why does the cmake script not stop with a BIG WARNING: you have samples enabled but freeimage wasn’t found instead the whole library can be built without support for the Media/ archives coming with the samples but then the samples are completely useless.
    not to forget: since ogre installed into /usr/local i needed to alter my /etc/ld.so.conf to reflect the new libOgreMain.so location (and others) and afterwards i had to run ldconfig as root (this is now done by the ebuild i wrote automatically)
  • i wanted to have a look at the samples (despite of naming them samples instead of examples one thinks they are of help). however all samples share one giant resource system. this might make sense at first however if you – the newcomer – don’t have any clue about unique namespaces in material scripts and textures and compositing of texutres using various vertex and fragment shaders renders the samples are pretty useless because of their complexity.
    i want simple samples which have all they need in ONE folder with a clean structure and NOT having to rely on external files which are referenced in mystical ways.

i’m not the only person who has serious problems getting ogre to work, see [1] and [2]. [2] is exactly what i meant by low quality downstream support.

AND before anyone asked, NO i did not fill any bug tracker. if you like to do that, please feel free to do so. i hate to waste my time using email and ‘gray listening’ , then after i get a login. i’ve filled quite some bugs on bug trackers but as long as they don’t provide a frontend i consider ‘usable’ i won’t fill any bugs anymore. i often don’t even know where to fill the bugs anyway since they have lots of things you have to fill in… waste of time

right now i’m going back to ogre 1.6 since ogre 1.7 gave me this error when compiling my project:

An exception has occurred: OGRE EXCEPTION(5:ItemIdentityException): Cannot find a group named debugger in ResourceGroupManager::isResourceGroupInitialised at /home/joachim/Desktop/projects/space-game/ogre/OgreMain/src/OgreResourceGroupManager.cpp (line 1880)

i have absolutely no clue what could cause this, i did not edit OgreResourceGroupManager.cpp at all. googling didn’t reveal anything and the really nice ppl on irc.freenode.org#ogre3d couldn’t help me either.

summary: working with ogre 3d does not make much fun currently

nvidia cg support in ogre

actually i did get the cg (nvidia shader stuff) running. i noticed that in plugins.cfg i had*:

#Plugin=Plugin_CgProgramManager.so

why does ogre say:

WARNING: material shader/ring has no supportable Techniques and will be blank. Explanation:
Pass 0: Vertex program shader/gradientVP cannot be used – not supported.

instead of:

WARNING: you disabled cg support by not using any Plugin_CgProgramManager.so extension so no cg file will work for every use of cg

* this is because we use git and since the project was developed by me the nvidia user and seitz the ati user, he disabled the cg programmanger in his plugins.cfg, i probably updated the file without knowing that

ogre 3d 1.7rc1 ebuild

i’ve writte an ebuild for ogre 1.7rc1, it can be downloaded at [4], i copied some parts from [3] which was very helpful since i never did write an ebuild using cmake before.

i did not check the dependencies and they might probably be incomplete. if you want to use my ebuild you might just install ogre 1.6.5 with all use flags you want and then update to my package without cleaning ‘world dependencies’. also note that using my ebuild all samples will be built but the SampleBrowser binary and some others won’t be installed. i currently don’t understand why but the reason is that CMAKE_BUILD_TYPE=Gentoo is set but the CMakeLists.txt somehow expects CMAKE_BUILD_TYPE=RelWithDebInfo but i wasn’t able to overwrite that value with -D in the ebuild. i’ve asked in #gentoo-sunrise for support and they told me that this probably has to be fixed upstream. also don’t forget to install freeimage!

i did not upload that ebuild to bugs.gentoo.org – if you want to, please feel free to do so

links

[1] http://www.ogre3d.org/forums/viewtopic.php?f=2&t=54756&start=0

[2] http://gpnfn.blogspot.com/2010/01/building-cegui-ogre-renderer-in-gentoo.html

[3] http://aur.archlinux.org/packages/ogre/ogre/PKGBUILD

[4] http://lastlog.de/misc/ogre-1.7.0_rc1.ebuild

update

2010-02-20: my ebuild does not install the library as well (that is the .so files) so currently everything is built but both the library and the bin/* files are not installed

Documentation about this is in ‘/usr/portage/eclass/cmake-utils.eclass‘. About CMAKE_BUILD_TYPE=Gentoo i’d like to quote the cmake-utils.eclass comment:

# You usualy do *NOT* want nor need to set it as it pulls CMake default build-type
# specific compiler flags overriding make.conf.

My current fix is to overwrite that buildtype with:

CMAKE_BUILD_TYPE=RelWithDebInfo just before src_configure()

NOTE: i’ve also updated the ebuild at [4]


Posts for Friday, February 19, 2010

Endianness of Java

In Java, multibyte data items or streams are stored in big endian order. C sharp on the other hand adapts the endianness of its underlying platform.

Using Java to write bytes directly to the wire will require byte-order transformation if the recipient talks in little endian. The same is true if you are reading directly from the wire from a sender who talks in little endian.

If you are using a byte array wrapped in ByteBuffer,

byte[] data = new byte[] { 12, 19, 83, 05, -05,  55, -55 };
ByteBuffer byteBuffer = ByteBuffer.wrap(data);

Transforming from big endian to little endian is easy,

byteBuffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);

If you are unsure of the endianness of the underlying platform, just invoke the native order method.

java.nio.ByteOrder.nativeOrder();

Aside from streams, operands in classes that are above 1 byte in size are in big endian order.

Haruki Murakami

When I was a kid, in 2nd grade, my dad was posted in the Himalayas. Families weren't allowed there, so I used to live with my mother at her mother's house. Right above the bed where I used to sleep with my grandmother, was this strange painting of a house. The canvas was a dark cloth, and the painting was made of light-grey outlines of a hill with a house on it. It had a slanting roof and a chimney with a hand coming out of it. I used to stare at this terrifying picture every night while going to sleep. It was much later that I realised it was actually smoke that was coming out of the chimney. Smoke that looked very convincingly like a hand.

Whenever I think of this picture, feelings of horror are mixed with the beautiful memories of living with my grandmother. Listening to the watchman making his rounds around the houses, listening to tales spun by my grandma, peeking outside the vertical-tilting window to see the moonlit houses. That green Russian folktales book I had, and Baba-Yaga. Chasing dust-mites in beams of light, playing with a 1991 calendar; with faint memories of something big going on. The house in the painting itself must have featured in many of my dreams and my nightmares. All these memories mix and mingle to evoke feelings from every corner of my brain. I am left with tears in my eyes, heaviness in my heart, and regret in my mind that all of it is now gone.

And somehow, everytime I finish a short story by Haruki Murakami; all these feelings rush up to me. Whether the story had a happy ending, or challenged my stomach; the nostalgia, the beauty, the love, all rushes up to me. Each story reminds me of my love for thunderstorms. For stormy nights, that are spent alone. Loneliness that I cannot bear, but the feeling of which I love.

I remember so much that I just want to lose myself in my memories.

That is Haruki Murakami for me.

Planet Larry is not officially affiliated with Gentoo Linux. Original artwork and logos copyright Gentoo Foundation. Yadda, yadda, yadda.