in|the|office

I was getting a little agitated that my professional friends Sam and Ben seemed really into their personal programming projects recently. Where the hell was my personal programming project and why was I not working on it in my spare time like a proper adult person. Well, because I’m not a proper adult person. Not really. But then, of course, I remembered WangBot. It turns out you can be a little juvenile and work on interesting side-projects from work, which is really the greatest of both worlds. It’s not something I’ll be able to talk about in a job interview without a lot of lies of omission (“oh yeah, I created an interactive IRC bot called wangbot for our channel wangingout. some of its commands include ‘!wangme’, wherein it talks dirty at you, and ‘!greet’ wherein it mixes up topical political commentary with dick jokes and insults. hire me?”) but it is a way to keep busy and productive in my free time instead of mooching around the house burning through the entire Netflix back catalogue.

So, then; wangbot. I don’t really have an end-game with wangbot. Most of the time I am dicking about in the IRC channel with the boys and one of them will say something that stirs some inspiration. I’m pretty sure the bulk of wangbot’s voting code was implemented in one afternoon, after it was first discussed. Then a few subsequent days to iron out the bugs, and now we have the statute book online. Most of this was hacked together in TCL, the scripting language used by the eggdrop IRC bot. I am learning it as I go, which means a lot of browser tabs.

Another thing it can do is tweet to the @wangingout twitter account. That it cannot do in TCL. I guess? If it can, it’s easier to do it in python. I checked. Commandline tweeting was an aim of mine before I went for a four-month stay in China. I wanted a way to quickly SSH into my home server or access a very simple web page on it and I needed a suitable back-end to access twitter and bring its interface to me in the firewalled People’s Rep. But having a way for our IRC channel to shout at our twitter friends not present was a great little side-effect of this. So, there we go, it’s mostly TCL with a few external calls to python scripts to handle some of the modern stuff.

A work in progress is a way to link IRC nicks and twitter handles in wangbot’s memory, so when someone mentions a nickname in a tweet or topic or tabled motion, wangbot can throw in the @ symbol, map usernames and be better-integrated. Same in reverse. When @wangingout gets a mention, wangbot posts it in the channel. It would be good, for those whose IRC clients light up specifically at the sound of their name, to have those @ handles turned into nicks. Have to implement the stages of authentication, though, where the twitter user proves ownership of the IRC nick and the nick holder proves ownership of the twitter handle.

While thinking about all that, I decided to delve into sqlite too. It’s small and lightweight (liteweit?) and would be good for storing the small small number of mappings we’d ever need for that kind of stuff.

So that’s how wangbot got his backend. Python and sqlite.

One previous suggestion was to use the thatcan.be to generate novel greetings for users entering the IRC channel. Trouble is, the @wangingout account doesn’t really talk about that much. There’s no voice there to imitate. Occasionally one of us will !tweet a great out-of-context line, but amongst all the announcements that’s kind of lost. But there is a voice in the IRC channel. We all contribute to it. It’s us. We are #wangingout.

Right, so, let’s learn how to speak like us. First step: harvest the logs for all the words we say.

Next, the first iteration. Chain words together by counting the frequency of word pairs and using that as a probability to randomly generate from. chrysics pointed out that this was essentially a Markov chain of words. He’s right, but I don’t remember what things are called. Obviously some of that shit sank in though because here we are.

But mostly it was garbage! Thanks Markov, you douchebag. So I upgraded it today to word triplets. If possible, use the previous two words to pick the next one. If not, use the previous word to pick the next two. If that’s not possible, fall back to each word picking one next word. If THAT’s not possible, end the sentence and start a new one. Fun, right? I’ll post some highlights at the end.

But the thing this post is about, and that I wanted to talk about here, is not any of the stuff above. It’s the top 25 by frequency triplets of words (case insensitive, punctuation stripped). I thought it was some interesting data. This isn’t what my friends and I talk about, it’s what everyone says in between talking about stuff:

i|dont|know|114
you|have|to|103
im|going|to|102
i|dont|think|99
i|want|to|89
a|lot|of|89
i|have|a|89
i|need|to|84
one|of|the|79
one|of|those|78
i|have|to|77
im|not|sure|75
be|able|to|73
all|the|time|65
going|to|be|65
it|was|a|63
i|think|i|63
a|bunch|of|59
a|couple|of|58
the|end|of|57
i|have|no|55
it|would|be|55
that|would|be|53
in|the|office|52
to|be|a|52

This is how you get a bot to start sounding like a person. String some fucking triplets of words together. I have this now. It’s in a database. I can use it somehow to make my stupid bot make more effective dick jokes. Just got to figure out how!

Wangbot sentences!

  • cantona wearing a hat are too many letters to write spoilers.
  • joining the irc boys may be for something actually important ill handle this one really good quote on it she was ok i.
  • ill be more than one finger sarnie for supper for business continuity solutions.
  • u2 are rubbish but thats exactly how this is.
  • i would do 16million shades of gay porn film how did the system preferences just come in to.

Clubs

This boy showed promise. This boy showed the most promise that Chou-Ren had ever seen. It was with great excitement that he finally got to lay the fleck of burning ember on this young man’s forehead, thereby selecting him for the Rite which so many of his peers coveted. Chou-Ren knew by now the procedure by heart. Though never undergoing it himself, the Rite involved days of fasting and meditation, followed by an extreme physical test. The well-preparedness of the boy to undertake it would summon the presence of their God, who would assist with the boy’s challenge in return for the promise of a vessel to commandeer when the time was right for His return.

Chou-Ren had been selectively breeding for this day from the moment he arrived in Pinnyance. Armed with nothing but a burned staff and a religious ideology, Chou-Ren had sought the finest warriors in the land to form his new temple and monastic order. When their training regimen was complete, he would grant the most powerful monks the right to marry one another and bear children, as long as the children would enter into a lifetime of training at the temple.

Chou-Ren was looking at the fourth generation of child to be born under his watch. Yes, his students had to breed young, but he was just a man and would not live forever. There was no time for failure. They were old enough, by his judgement. All his God needed was a healthy framework; specifics, such as the vessel’s age, meant nothing to one as timeless as He. This latest child was a marvel, and Chou-Ren had great faith that finally, after so many years, he would sense the presence of his one true Lord and Master once more.

The Rite differed slightly from the one Chou-Ren’s former master officiated. For one, he now required that his best warriors pass on their genes before undergoing any trials. He was a great believer in hereditary greatness, but the trial was fatal to all who did not pass, a trend in outcomes so far unbroken. While he hoped this time would be different, Chou-Ren took no chances. This was the world’s most important endeavour.

After the boy’s union with the temple’s most gifted female warrior, he would begin his days of fasting and meditation. The other initiates would construct a wooden cage around him while he waited. And, when the time was due, Chou-Ren would ignite the cage and await his God’s arrival. If the boy should escape the burning prison, the others were ready; all the initiates would take up their clubs and attack the boy. If he truly did contain God’s Spirit, there would be no doubt as to the victor of this fight.

It had not happened. Four decades of trials and all Chou-Ren had to show for it was a pile of scorched bones. But this time, he knew. This boy showed promise. This boy showed promise.

Antideus

When the world was young, it had no features. There was just the earth; a round ball of iron and rock. Chenqin loved xyr creation greatly, but xe claimed no ownership over it. Instead, xe gave it to xyr daughter, Fengnu. She was at times a wild and unpredictable child but she took the earth and wrapped it up in a blanket of air to keep it safe.

She was pleased with her gift, and excitedly took the earth to show her favourite cousins, Shuizhu and Huoshi. They too wanted to add their colours to the earth. Huoshi, whose mother had made the sun, took some of the sun’s fire and lit the glowing centre of the earth. Its shell broke into pieces and some of the fire belched out onto the surfaces, leaving behind mountains and valleys. Shuizhu quenched the scalding earth with a cascade of beautiful blue water. His father made the moon, so these waters would be forever linked to the moon in the sky, and they would swell and sway with the moon’s position.

It was a thing of beauty, this blue and brown marble now. But Fengnu had two more cousins. Her fat, contemplative cousin was harmless. Xe was quiet and peaceful and would only speak in whispers. Guileless, honest Jingzhi would cause no harm to her toy. But the other… Hei’An was a dark child. She would brood and sulk and unmake the toys the other children played with. Fengnu did not want Hei’An to touch her earth.

She let Jingzhi play with the earth, after telling xem to be careful. Jingzhi was so happy to have Fengnu‘s trust that xe gave the earth a very special power. Xe breathed xyr most powerful whisper into the whole ball. Jingzhi filled the earth with aether. Later, xyr aunts and uncles would use this to fill the world with living things and people. But now, it just shined, so beautiful to behold to those who would look upon it.

But Hei’An learned about the earth anyway. Poor, simple Jingzhi would always tell Hei’An whatever she asked. And Hei’An was angry. Why should she not get to play with the earth, too? Hei’An hated Fengnu and Chenqin both, and vowed to use all her powers to break their little stupid shiny toy. But she was not powerful yet. They were all just children. So, in secret, she asked her parent, Emo to help her. Emo gave her life and all of her power, but xe also gave her xyr personality. Emo too was a dark power. Xe had already populated xyr own home with foul demons and creatures of evil. But with xyr daughter, xe was able to take four demons, four special demons, and steal away some of the other children’s power. Together they made four who would undo all the work of the other children. One who could dry up all of Shuizhu‘s water. One who could put out all of Huoshi‘s fire. One who could dissipate all Fengnu‘s air. And finally, one who could void all of stupid, fat Jingzhi‘s aether.

All at once did Emo and Hei’An unleash these four terrors on the earth. And at once they set to work taking apart everything of beauty and creation.

When Chenqin saw what Emo had done, xe was devastated! In alarm, xe went to xyr own siblings to beseech them for help reigning in the terrors set on destroying xyr creation.

Xyr sibling, Jieyi, who was Emo‘s cousin and opposed the dark god fully, agreed to help, and with the power of Chenqin, Jieyi, Fengnu, Huoshi, Shuizhu, and even Jingzhi combined, they were able to trap and banish the four demons into a realm far away.

Emo never forgot this betrayal by xyr family. But xe bade xyr time. When the others united to create life on the now-safe earth, Emo gave mortals one secret gift. Magic on earth was a joint power from both Emo and Jieyi, but Emo‘s magic was tainted. When Jieyi gave mortals free will, xe left xyr own power open to defiance. And Emo planted the powers in mortals to unlock the four barriers keeping xyr creations at bay. One need only attain enough power, and the antidei would walk again on the earth and swallow up all of creation into the endless void.

Not this shit again…

Our protagonist, W, sits quietly in a drinking establishment in southeast China. He is conversing with a local inhabitant, D, whom the drinking establishment employs. The context of the interaction is not business, however, but friendship.

Enter Whiteshirt 1 and Whiteshirt 2, a pair of D’s associates. Declining to patronise the drinking establishment by making any purchase, they take up a tabletop ball and cue game for what appears to be idle entertainment.

The night passes swiftly. The Whiteshirts depart. D receives a heated phone call demanding presence at some other location with the Whiteshirts. D is working. D explains to W that the Whiteshirts are drunk, and are frustrated at the apparent camaraderie that W and D share. The Whiteshirts, D explains, can be a little insular.

It is now nearing closing time. It is late, and W wishes to retire soon, so as not to be too tired at work the following day. However, a cluster of Whiteshirts has appeared in the street outside the premises. D approaches. W remains in the building, still believing the Whiteshirts to be merely a friendly gathering of cohorts.

When D returns, it is with a warning. “They want to cause you some trouble.” Some trouble? W is perplexed, and has no recollection of interacting with the Whiteshirts, let alone offending them. Indeed, given W’s lack of linguistic competence in the local tongue, it would be difficult to convey any ideas at all to the Whiteshirts.

Probing to clarify, W asks, “‘trouble’ meaning… they want to fight?” Yes. What, why? They don’t like that I’m friends with a foreigner.

Floored.

W is a white, Western, hetero, cis, able-bodied male and hasn’t had to deal with a great deal (or even any?) prejudice or discrimination on these grounds before. “This is an eye-opener,” thinks W, before beginning a complex thought process to search the decision tree for a favourable outcome of engaging with the Whiteshirts.

One Whiteshirt enters and requests D’s participation in another game of what is now obviously not idle entertainment. It does not progress far before a second Whiteshirt joins and sweeps a disruptive hand across the table. Eyes lock aggressively as Whiteshirt prepares to confront D. W stands up from his seat. There’s no fucking way anyone’s fighting here.

Voices become raised. One of the Whiteshirts is shouting at W and the other is shouting at D.

The proprietor of the establishment approaches. “You do not shout in this bar.” He directs them out. A frank discussion in slightly broken English takes place between the proprietor, W, and D. “What do you want to do here?” the proprietor asks D. “Do you want to go home?”. Some of the Whiteshirts inhabit the same residence as D. No decision is made. The proprietor confesses inexperience at owning and running a drinking establishment, particularly dealing with trouble. No help there, then. Fine.

At this moment, one Whiteshirt lurks outside the doorway. D has been doing some decision tree evaluation, too, and comes to the conclusion that it may be possible to talk down the aggressors long enough to leave. D exits the building and engages the cluster of four or five Whiteshirts. A Whiteshirt enters, and stands guard at the inside of the doorway. The external Whiteshirt observes, too. The interior watchman poorly feigns interest in some literature; the frequent glances in W’s direction leave nothing uncertain: you wait here while we take D with us.

For agonising minutes, W watches, hesitant to intervene lest the situation escalate. Taking stock of the environment, W is tensed for the possibility of physical conflict.

At one point it seems that D is returning after the discussion. But a Whiteshirt rapidly follows, grabbing D’s arm and steering them both out of eyeshot. The internal guard, bored of watching, retreats to the cluster outside. Emboldened, W eventually musters the courage to stand outside for a moment, beside the exterior post. D quickly gestures for W to go back inside. W complies. Waiting.

It is 3:30am. D reenters the premises and offers a strained smile. “You’ve sorted it?” W is impressed and a little relieved. Two Whiteshirts enter and offer handshakes. Is it over?

No. Some Whiteshirts remain resistant to the enlightenment of their peers. D and the friendly Whiteshirts try their best to assuage their grievances, but before long, D issues a frantic “you should go home, now.” Now? Now. Okay. W bids farewell to the proprietor and apologises for bringing this to his bar. “If I don’t make it back for my ‘leaving’ party tomorrow, I am in a ditch somewhere.”

It is 3:35am. The two allied Whiteshirts have intercepted some of the more aggressive Whiteshirts. They no longer appear to be pursuing W down the road as he walks home. W checks frequently, turning around or glancing over a shoulder, that no pursuant Whiteshirt is in sight. Corners are turned. Roads are crossed. Distances are traversed. A phone call from D. “I am sorry.” It’s okay, you’re not to blame for people being jerks.

W’s hands are busy tweeting this whole time. It offers comfort to post about the situation online, but it does not tell the whole story. W is having a bad time.

It is 4:10am. W arrives home. The morning’s alarm is set for 3.5 hours’ time. W increases it to 4. No time for a luxurious gradual awakening peppered by liberal snooze-button presses today.

Epilogue

7:00am. W partially awakens to groggily answer a phone call from D. “Where are you?” At home. “I’m coming.” Why? No strength to argue. Okay. 7:30am. “I’m here.” What, why? W staggers out of bed and throws on some clothes. Nearby, D and one converted Whiteshirt meet W. The Whiteshirt offers W a stick of gum. Ceasefire. The Whiteshirt departs. More apologies. “I didn’t want to go home and spend more time with them.” D and W return to W’s apartment. D crashes on the sofa and falls asleep instantly. Okay. W gets ready for work. There’s still an hour and a half before the need to catch the bus. Enjoy your sleep, friend, and thanks for talking your racist pals out of murdering me.

Jungle

Rav-Turai Bethel placed his flagpole up against one of the broad-leafed trees around which their camp had been erected. The colourful standard became entangled in the unfamiliar greenery and foreign fruits, the golden snake being consumed by the shiny, perpetually damp foliage. He let out a gentle scoff and began quietly grumbling to himself as he picked his way over undergrowth and guy ropes, around to the entrance of his pavilion.

The horrible jungle here was stifling him. He could stand the heat okay; his homeland was scorching and arid. But the humidity got in his lungs, made him feel like he was suffocating. And the noise… nobody had told him the jungle was so alive. He ceased his resentful muttering as he neared the entrance to the pavilion. He and seven others in his military section shared this living space, and had done for the past two months. Officially their mission was reconnaissance. But the deployment was so large, any experienced soldier knew what was going on. This was an invasion force.

Intelligence still needed to be gathered, though. So the bulk of the force had holed up in this godsforsaken dank little pit of a jungle while a select few were deployed in rotation to the landing site under cover of darkness, and picked up under darkness after a few days.

Everyone returned. There had not been a single casualty or compromise of cover. Each solider was given a fist full of gold and the name of a town and tasked with the easiest assignment ever: tourism. Posing as interested travellers, they’d stay in town for a few days, ask inquiring but innocent-sounding questions, while at the same time scoping out a settlement’s defences and layout. Bethel knew that in practice this meant an afternoon of mapping out the town garrisons and gates, and three days of bars, women, and music, and he had vowed to do whatever it took to get his section selected for the next intelligence deployment.

Of course, Bethel was not the only soldier here to dislike the jungle, and spots on the reconnaissance rotation were highly sought-after. It had taken two solid weeks of sucking up to the Rav-Aluf to get his section in the rotation. Now he’d come back to his pavilion to give the good news to his peers.

Straightening up and placing one hand on the gold-inlaid hilt of his sabre, Bethel strode through the loose tent flaps purposefully.

“Pack your things, men. We’re going to Alepia!”

The Soul Engine

Of all the fabled monstrous unholy weapons the mages utilise against the faith, none is more terrifying nor evil than the Soul Engine.

Disagreements of principle aside, not a one major religion denies the existence of the immortal soul. Even those most rigidly demanding purity and obedience from its followers knows that any punishment for transgressing ends with the soul. Whatever torment awaits sinners, whatever retribution rains down upon heretics… when it is over, if it is ever over, what remains is the immortal life force, a fundamental fragment of the universal energy. When the gods themselves are laid to rest, still will there permeate the grand reality an aether, a framework, an all-pervading ore of spirit from which life and death, joy and sorrow, youth and age can all be wrought. Each one of us remembers our life and those lives that have touched ours, and those lives remembered the lives that came before. Nobody is truly lost, no piece of their essence truly destroyed… except within the Soul Engine.

To rip that spectral organ from the body is of no moment to even the palest grey of Dark Wizards. To blacken a piece or a whole of a being’s spirit with unspeakable acts does nothing to lessen its potential. To die is simply to move on. To live is simply to be reborn. To transcend, to redeem, to condemn, all just states of existence of some part of us. When the Gods came together to make the world, They knew it would be fleeting, fragile. Even our bodies age and die in but the space it takes a God to blink. But They chose to make our mortal bodies vessels for immortal spirits, so that They may come to know us as They know One Another. We feel Their touch when we pray for courage. We feel Their absence in nights of blackest despair. The power They use to share Their Divine Grace works through our souls. And that power is being destroyed.

The magician is sinister. He is vile. He is an abomination before the Gods, both Dark and Light. He craves power outside the natural order, outside what is bestowed upon us by the keepers of that power. They use their black spells to suck our prayers out of the air and forge them into hateful creatures and flaming wrath. They steal away the shining remnants of the gift of creation to twist unto their own ends. Why is it that a wizard is unable to heal the sick? Why has no sorcerer cured a child’s fever, no mage restored a blind beggar’s sight? It is because their power knows only destruction. They steal the light of creation and undo the fabric holding this world in its divinely-mandated balance. And they must be stopped.

But this is, of course, why you are all here. The Aurac Inquisition does not indoctrinate. The Aurac Inquisition does not snatch children from their homes and put them though “Aurac school” like the wizards do. The Auracs seek not to fill new Auracs with daemons and cavort with unholy powers. We seek to stamp out the magician plague. We free their thralls, we burn their tomes, we smash their orbs and their staffs and their wands. We burn wizards with our holy fire and undo their heinous work. And we will not stop until the scourge has been eradicated.

Their blackest art, fellow Inquisitors… their greatest threat to us — not our bodies, but our immortal souls — is the Soul Engine. Nobody knows when it was made. Every history we have mentions it, and every history we have documents it as a ruin. But we who study these matters know that it is not a ruin. We who study the ancient magical debris littering the jungles know that the Engine is active. It is the powerhouse of the most evil mages, those who would take our very souls and destroy them, ground up to fuel their insatiable desire for power and dominion over both man and god. It is a great machine in the deepest, darkest valley of our green land. Surrounded by trees so tall as to obscure it from sight, and jungle creatures so vicious as to repel all intruders. It will be the privilege of the highest-ranking Auracs to venture into this dread vale and bring down all within. By safeguarding our immortal souls against the magicians’ vile intentions, those chosen to undertake this mission will not only aid the eradication of magic, but also accrue the favour of all the Gods and whatever boons They may see fit to grant.

Maserati

Last week I bought myself a Motorola Droid 4. When it came out, millions decried its locked bootloader and hundred decried its lack of GSM support.

It’s seven months later now and Verizon has released Android 4.0.4, Ice Cream Sandwich, and GSM support for the Droid 4. The community has released ways of working around the locked bootloader. So, here we are. I own one.

Droid 4

Coming from my G1, the very first Android phone, I really don’t have a lot to say about the things most of the world seems interested in with phones. The processor is: faster than the G1′s. The RAM and ROM: bigger than the G1′s. The version of Android: newer than the G1′s. The screen size is: bigger than the G1′s (and has more colours, too; the 65k palette being ditched by the model that immediately followed the G1). The things that matter to me and to seemingly nobody else are how many buttons there are.

I’ve managed to get over my hatred of soft buttons. My menu, home, back, and search keys are all those horrible fucking touch buttons that got really big just before touchscreens. But for all the heavy-duty typing one might want to do, no on-screen keyboard will suffice. Getting information from my brain to the screen quickly is important. I can’t hold on to thoughts long enough to flap them out on a smudgy mess of an on-screen keyboard that I have to be constantly gawping at like a fascinated chimp. I want to get on with things so I can go back to flinging my faeces about the place. Touchscreens are great for manipulating things you’re looking at with your hands, but for people whose brains process things in addition to just what they’re seeing — senses, concurrent thoughts, faeces-flinging, etc. — sometimes you want to get things from your mind to your fingers without needing constant feedback from your eyes.

It’s weird, I get it. You all love things that are shiny and move around and change like magic. My requirements seem a little provincial next to all that wonder-inducing prettiness. It limits innovation, too, or at least discards a branch of it. Things like Swype or 8pen are no good when I’m electing to stay rooted in button-land. But sometimes I want to text and cross the road, or email and watch TV, or type something that would fill the screen of the landscape text entry mode. If I could speak or point and click my ideas into electronic form in any better way than typing, not being able to type would be fine.

I think buttons are coming back, though, in one way or another. The Asus Transformer and the Microsoft Surface are the future of mobile computing, not the iPad. As soon as people start wanting to do things on their devices instead of just watching things, they’ll come right back around to buttons. And I like to be able to do things on my phone, which brings us back to the Droid 4.

The G1′s keyboard wasn’t perfect. By three years in the responsiveness of some keys was becoming unreliable. The layout was pretty good, though. There could have been some improvements: the apostrophe is something you have to press alt+L to get, rather than being its own button like on a desktop keyboard. There was a dedicated button for typing the @ symbol as well as it being on shift+2. You could move through text using the trackball which was atrocious; a few phones later came those little optical dots which I loved, though they seem to have disappeared now as well.

The Droid 4′s keyboard is not perfect either, but out of every device I’ve seen since the G1, it’s come the closest to being as good. My biggest gripe was the absence of easy-to-type symbol keys: the pipe, greater than and less than signs, the GBP symbol… These all had to be accessed through the “symbol” key which would launch an on-screen panel of keys. I would have to interrupt my typing in a linux terminal to jab at the screen to do a >. The worst thing, though, was that it didn’t even work in all applications.

But it’s Android, right? If something’s not to your liking, you can change it. Since Android version 3, it’s been easier than ever to change key layouts and key maps on devices. These things are compiled or read at boot. The key layout maps the keycode of a button press to an Android button. Built-in Android buttons include all the alphanumeric characters, plus support for the home, menu, and back buttons, camera button, all the directions of the trackball, optical dot, and in the case of the Droid 4, cursor keys. You can also map keycodes to modifier keys: shift, ctrl, alt and meta; just like on real keyboards. The keyboard character map file then takes these buttons and determines what action Android should take when they are pushed. For the button A, the default behaviour is to print the character ‘a’, unless the shift or caps lock modifier is on, in which case, print ‘A’. Simple enough, right? And you can map other default actions to keys as well. In the G1, the SYM key was activated by pressing alt+space. In the Droid 4 by default it’s its own key. Well, alt+anything in the Droid 4 was unused because there was no alt key on the keyboard. So that was my first change. The keycode for the SYM button was mapped to the ALT action in omap4-keypad.kl.

key 162   ALT_LEFT          WAKE_DROPPED

So I had to put the SYM functionality somehwere. In omap4-keypad.kcm, under SPACE, I added the label alt: and told it to use the default action for the SYM key.

key SPACE {
    label:                              ' '
    base:                               ' '
    ctrl:                               none
    alt, meta:                          fallback SYM
}

So now, here I was, armed with a whole paradigm of keyboard functionality the manufacturers had decided not to include. I had my alt key back. The next thing to do was to add all the shift+number functions to their alt+number counterparts. In the G1 I could use shift and alt interchangeably for this purpose, so I figured it would be a good starting point.

key 0 {
    label, number:                      '0'
    base:                               '0'
    shift, alt:                         ')'
    shift+alt:                          none
    ctrl, meta:                         none
}

key 1 {
    label, number:                      '1'
    base:                               '1'
    shift, alt:                         '!'
    shift+alt:                          none
    ctrl, meta:                         none
}

After this change, I found an odd little quirk. Whenever I would do shift+alt+cursorleft, the key for alt+3 would be printed. I had to insert an override in each number for shift+alt to perform ‘none’, as you can see in the .kcm snippet above.

On to the real stuff, then. Alt+L is the shortcut on the G1 for an apostrophe, and although the Droid 4 comes with a dedicated apostrophe key, alt+L is so ingrained that sometimes when I’m a bit tired I’ll try to do it on a desktop keyboard. So that was the first one I imported over. I figured that while I was here, I could do all my old favourite shortcuts. Touchtyping doesn’t require looking at the keys and if I’ve already learned a layout that I can keep across phones, I can minimise the stumbling over moved keys that I’m forced to do.

Keyboard of the HTC Dream

HTC Dream keyboard showing alt-keys.

The menu key in the G1 would occasionally act like a ctrl key; I could menu+c to copy and menu+v to paste. The Droid 4, above its shift key in the bottom left, has a caps lock key. Caps lock is probably in the five least-used keys on my keyboard. And since this version of Android (at least, and possibly the version my G1 was running) has support for an actual ctrl key, this was the next thing I changed.

key 222   CTRL_LEFT         WAKE_DROPPED

So now I am armed with a ctrl, shift, and alt key in the bottom left of my keyboard. I’ve got a bunch of awesome things I can do using these and the arrow keys in the right; ctrl+arrow can hop through words, alt+arrow can hop through lines. Adding shift can select words or lines and cut, copy, or delete them. Not only am I unhindered in typing but I’m also unhindered in editing what I’ve typed.

I did make one other change. There is no right-shift. There is no right-alt. If I want to type a capital A or do an exclamation mark, I have to press the shift and then press the button. There’s no hold+press. There is, however, an ‘OK’ button; a button that acts as the centre-press of a trackball or directional pad. This is probably the most controversial change as it is a button that I actually use. But the enter key practically emulates all the functions of the OK button when a selectable UI element is highlighted. So by mapping the OK function onto alt+OK and leaving unmodified OK as a right-shift, I can access the capital letters and number-row symbols of the left half of the keyboard much more easily.

key 232   SHIFT_RIGHT       WAKE_DROPPED

That’s that, so far. I’ll keep you all up to date with my attempts to wrangle CyanogenMod 10 onto the device which have so far proved a challenge.

The files I modified have been uploaded here, if you want to use them at all: omap4-keypad