Sunday, October 18, 2009

Android Phone Home

Getting Started

As some of you know, I've been playing with a new toy.

Android is a new operating system from Google. It's designed for cell phones and other small computers. I've been learning to program it.

For the first couple of months I was mostly working with the Android Software Development Kit (SDK) and the Android emulator. With the emulator you can write and test Android applications (Aps) from the comfort of your computer. As learning Android is like drinking from a fire hose, I wasn't going to invest any money on hardware until I knew I could get something done with it.

I'm at the stage now where I can generate simple programs and I have some definite ideas where to go, so I decided to bite the bullet and buy an Android developer phone.

I ordered my phone and a very few days it showed up. Good job Google!

I fired it up. It munches away for a few seconds, then it tells me "No SIM" and just sits there. Wha?

I know what a SIM is. It's a Subscriber Identity Module, which is a little piece of plastic that modern cell phones use to keep track of who you are. Take a SIM out of one phone and put it into another, and the new phone now has the old phone's number. Neat huh?

I'm using this as a development platform. I don't want to use it to make calls, so I don't need a SIM for it, right? I'm sure that Google has provided an easy work around for this. I'll just check the Internet tubes and find it. Oy! 2 days later I had real access to my phone.

The rest of this blog is designed to save the next poor swine the aggravation I went through in registering my phone.

After checking around I found out that Google not only wants you to have a SIM card, but you also need a data plan on that SIM card! I don't want a data plan, I don't need a data plan, And, at the rate the phone company rapes at, I can't afford a data plan!

Then it just gets silly. You only need the data plan for about 5 minutes, just long enough to connect to Google and register your phone. After that you can chuck it out the window. Oh, did I mention that the phone has WiFi?

You need a data plan to register a phone to get to the WiFi, which you could use, if you could get to it, to register your phone! You're killing me Google. Your just killing me.

Fortunately, if you have a regular SIM card (say from your current phone) and you're already running the Android SDK then it's not too hard to fire up WiFi on your phone and bypass the data plan requirement.

Away We Go!

First we'll get your Linux box to see the phone via the USB cable. I'm running CentOS 5, which is like Red Hat 5. There are other guides out there for Windows and Ubuntu. This guide is for CentOS.

First install the Android SDK on your system. Look around on the Internet for instructions. You don't need everything under the sun, but you do need the "adb" (Android Debug Bridge) command.

Plug your USB cable into your computer and your phone.

Open a root shell on your computer.

After a couple of seconds type "lsusb". You should see a list of the devices attached via USB to your computer. Somewhere in the list should be an entry for "High Tech Computer Corp." "High Tech Computer" is HTC. HTC makes your phone. If you see it then you know that USB is up and running and can see your phone.

The next question is does it see it as a phone or just a very expensive jump drive?

Type "adb devices". If you see an entry that begins with "HT" followed by a bunch of characters and the word "device", then skip to the next section. If adb can't see your phone, then we need to tweak the USB daemon so that it does.

This part took me a long time to get working. Apparently CentOS is using an older version of udevd, which is the program that scans the computer looking for new USB toys being plugged in.

Go in to /etc/udev/rules.d and look for a file named something like "90-android.rules". The leading number varies. It probably isn't there. No problem. You need to create/edit it until it looks like this. Make sure it has the same permissions as the other files in the directory.

# This file lets Linux recognise my Android Developer Phone in
# a way that the adb command can handle.
# Uncomment one of the lines below and run:
# udevcontrol reload_rules
# adb devices
# If it lists your phone, you're done. If not comment out the
# current line, uncomment the next line and run udevcontrol again.
#
# The 3rd line (usb_device) was the charm for me.
#
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666"
# SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
# SUBSYSTEM=="usb_device", SYSFS{idVendor}=="0bb4", MODE="0666"

Follow the instructions in "90-android.rules" and you should end up with a visible Android phone.

Connecting to the Phone

From the command line type: adb shell

After a moment or two you should get a "$" prompt. This means that you're in the phone talking as a regular user.

Type "su".

If the prompt changes from "$" to "#", then you're in as root.

Type "exit" to return to a regular user.

Bypassing the SIM check

There are two ways to do this:

The first, and easiest, is to plug in a SIM card. It doesn't matter that it doesn't have a data plan. This is just to get past the check.

The second, and I haven't tried this myself, is to fool the phone into thinking it passed the check. Check out http://forum.xda-developers.com/showthread.php?t=452316 for instructions.

Note, for the second technique, if you have a developer phone then you don't need to root break it. Just type "su" at the adb shell prompt and you're root.

Registering with out the Data Plan

At this point your phone should be at the registration screen.

From adb, as a regular user, type:

am start -a android.intent.action.MAIN -n com.android.settings/.Settings

In a couple of seconds the "settings" screen should pop up on your phone.

Set up your WiFi and hit the back arrow. You're back at the registration, which you can now do via WiFi.

If for some reason the settings screen doesn't pop up, try

setprop persist.service.adb.enable 1

and then try the settings command again.

Once you're registered you may want to go to the Android market place and pull down an ap called "APNdroid". It screws with the data plan APN so that your phone can't connect no matter how hard it tries. Bite me AT&T.

Using your Phone as a Jump Drive

One last thing, did you notice that your computer can see your phone as a jump drive but can't access it? That's easy to fix.

When you plug in your phone via USB, you'll notice a little USB forky type icon shows up in the upper left hand of the phone screen. This is the notification area. Pull it down with your finger. Click on the USB notification and then click on "mount". You're good to go!

Monday, September 7, 2009

Spanking Dawkins's Weasel

One of the problems with learning a new programming language is coming up with interesting "beginner" programs. Most beginning programs do something exciting like printing out "Howdy, Howdy, Howdy, Joe". Heart stopping stuff ain't it?

To ease this a bit, whenever I come up with an interesting idea for a beginner program, I'll write it up and you can give it a shot.

My hands down favorite simple program is something called Dawkins's Weasel.

Richard Dawkins is a evolutionary biologist from Oxford. He wanted to come up with a program to show the difference between a random mutation and a random mutation with selection. The result is a simple, straight forward program called "Dawkins's Weasel".

Note: Whenever I say "letter" below, I mean letters and/or spaces. Saying letter and/or space all over the place makes for a tedious read.

First we start with a target sentence, which we'll call "Target". This is what all good little sentences want to be when they grow up. Dawkins used "methinks it is like a weasel" and so will we.

Next we create a parent sentence called "Parent". This is a gibberish sentence of random letters that is the same length as Target. "y ksqmjwepqtgtyylmfexstvktpa" will work, as will "aaaaaaaaaaaaaaaaaaaaaaaaaaaa".

Our goal is going to be to evolve Parent into Target.

Parent will produce a litter of children. The fittest of the litter will then become the next parent. This continues until we produce a Parent that equals Target. It's survival of the fittest and all that jazz.

Unfortunately the sex life of a sentence is pretty dull. The way a sentence has a baby sentence is by copying itself and then changing a single letter at random. Not exactly the stuff of pornos. We'll call the baby sentence "Child".

As for who's the fittest? We'll use something simple. We'll count the number of letters in Child that match Target. For example, the sentence "aaaaaaaaaaaaaaaaaaaaaaaaaaa" would score a 2. "methinks it is like a measel" would score 27. If there is more than one pick of the litter, choose one. It doesn't matter how.

That's pretty much it. The only real variable you get to play with is the size of the litter. If you start with a litter of 50 then you tend to finish in less that 100 generations. Once you get the code working, starting dialing playing with the litter size to see how it effects the generation count.

I'll try to keep my eye out for other interesting algorithms worthy of posting. If you know of any that are fun, the add a comment.

Monday, July 20, 2009

Back to (Paranoia) High School

Whelp, I'm back from vacation and all in one piece. I'm a bit shell shocked, but all in all it was a good time.

I'm not one of those people who really gos on vacation. I more survive them. My home life is driven from project to project so when I hit a vacation that I can't spend in front of the computer I'm kind of at a loss.

However, my dearly beloved explained to me that my mother in-law put a lot of work into setting up this vacation, so my other option was to be in kind of a wheelchair, so vacate I did.

The big problem was, we vacated to a dead zone. No phones, no lights no motorcars, and no Internet. That means no real way to do any writing.

I hate writing with a pen. My hand writing is a scrawl and it's sooo slow! And once I'm back amongst the living, I have to transcribe it back into the computer.

With writing on mashed up trees as a failure, I tried using a small laptop. That kind of dominates the landscape and emphasized how much I'm ignoring my family. Not smart for this wheelchair phobic. I needed something sneaker.

How about my phone? It's got a 2 gig chip, supports text messaging and can hide in my hand. Could I use that?

Nope! My phone does allow memos, but they have to be less than 100 characters. Let me repeat that. My crappy phone, with 2 gig available, won't even let you save a memo as long as a Twitter "tweet"! Thrilling.

I know! I could use it as a voice recorder! Yea, I could do that. When I write I tend to talk out what I'm writing anyway. I'll just talk into my phone and record everything!

Unfortunately, with my current phone I have to shout to be heard. Every time inspiration hit, my in-laws would hear me shouting to my invisible friend who hides in my hand.

Now my in-laws think I'm nuts.

I can live with that, but I also got to play with writer's block. Such fun.

Actually, it a weird sort of way I don't mind writer's block. At least I don't mind having it once I've overcome it. It's kind of like the old saw about smacking yourself with a hammer because it feels so good once you stop. I sorta go through that.

As you may or may not know, I used to write for a comic strip called "Paranoia High" (Check it out.) It was a lot of fun and Dave (the artist) is a friend of mine.

After a while Dave took over the writing and I went on to fame as a geek blogger on them Internet tubes.

To make a long story short, we fade the mics and queue the organ and it's a year or so later and I'm back to writing the strip. Huzzah! The only problem is, can I still write the strip? Not May I, Can I?

Ya see, when Dave consolidated the strip, I gave him a list of the ideas I had at the time. No big deal, I have the list around somewhere and Dave has it too. But old ideas aren't enough. Can I come up with new ones?

I could feel the tightening grip of initial dread. What if my last creative idea was really my LAST CREATIVE IDEA!?!? You civilians don't savvy the pain we creative types go through when we birth forth art and stuff.

How can I explain it? It's like Paris Hilton waking up and finding out her butt has run off and joined the Peace Corps. No tush? No job! Writing is like that, except Paris's butt is our ideas.

Hopefully that image will help you develop an appreciation for the written word.

That analogy would have worked much better if it were a breast joke, but I couldn't think of any famous current women who are know for their big racks. Maybe Micheal Jackson, but he's dead.

Ms Proust is know for her rack, but she's a character in "Paranoia High". You really should check it out. (Note the reoccurring motif, that's the art baby!)

So I started running through ideas. Film strips? I think that's from the old list. Standardized tests? Nope, the old list. How about exploding frogs? Damn! School Principal Mike Ducacus? Whoa! Wrong decade!

It was looking pretty bleak for new strips, but I stayed with it. Football? Feral students? Sentient lunch meat? Damn! Damn! Damn! How about Hall Monitors?

Hall Monitors? Not on the old list. Hmm. Uniforms, Tazers, RoboCop, Juntas? Yea. Add "Hall Monitor" to the new list.

After that things started to roll. Walmart vs the school store? New! Texting NORAD? Brand spanking new! "Shakespeare: The Musical!" Oh yea baby. We're back in action!

Why are the in-laws looking at me?

Oh yea, I'm shouting at my fist.

They really think I'm nuts.

I gotta get a new phone.

Tuesday, July 7, 2009

A Window In The Ghetto.

One of the more baffling elements of Linux distributions is their constant relegation of scripting languages to the command line ghetto.

On one side you have the all the wowwie zowie windowy programs, most of which are written, for no good technical reason, in C. On the other hand you have thousands of useful Perl/Python/Java programs that rarely get used because they have command line interfaces.

If we really want to harness the power of Gnome, then we need to make it easier to write Gnome programs in the most popular languages that Gnome supports. These languages are scripting languages.

Scripting exclusively for the command line almost made sense 10 years ago. Old versions of scripting languages didn't really interface well with the Graphic User Interface (GUI) and Text User Interface (TUI) libraries. You often had to have completely separate interpreters for GUI and non GUI interfaces. Anyone remember perlx?

Now days that's bunk. Perl, Python and Java all have officially supported interfaces to GTK, and, in case you don't know, they're *MUCH* easier to use than the C interface. I'm talking an order of magnitude!

As for the TUI, how many tasks do server administrators do that would be made much easier with a simple curses interface?

Python includes a Curses interface by default (it's why I learned Python). Perl isn't too far behind with a very stable Curses package on CPAN. This could be added to any distribution in a matter of minutes. I'm not sure about Java, but if it doesn't exist it wouldn't take long to make one.

The point being, that we have to start pushing distributions to include text and graphic interface libraries with the languages they support, and give them the same status as the language. If the language is included by default, so are the GUI and TUI libraries. Don't let your hot Molly Ringwald fantasies blind you. The '80s are over. We need better interfaces.

Once the user base can depend on the libraries being there, we're going to open up Gnome to a whole to set of ideas. These new programmers greatly out number the current set of Gnome C programmers. They'll be able to fix user level problems that we hardcore programmers don't even know exist.

If you're convinced at this point, then start pestering Ubuntu. I think they're the closest to having all the pieces. Then we can go after Debian and then we'll gang up on Red Hat.

If you're not convinced, then let me over make my point with sort of a preemptive FAQ.

* We didn't do it last time, why do it now?


OK, you lead with an Ace.

First of all, modern bindings to the major scripting languages are dependable and stable. This wasn't true before.

Also, we're in a much more graphical time. Most users consider dropping to the command line a failure of the interface.

We need a bridge between the two.

* What if the bindings disappear?

The odds of the supported bindings disappearing any time soon is negligible. As for other bindings, if more people start using them, the more dependable they become. Does anyone really expect "vim" or "sendmail" to disappear any time soon?

* What's wrong with C?

Nothing, in it's place. If I were to suggest dropping all the scripting languages and doing everything in C, I'd be laughed off the Internet. Somehow we're supposed to believe that the argument is less absurd when you pop up a window.

* Distribution X has the bindings in the "Extras" section. What's wrong with that?


In the business world getting managers to allow "extras" on a system is a hard sell. Damn few middle managers get fired for failing to innovate.

Besides, if it's in it's own section then there must be something wrong with it. Right? Can I get back to you on that?

* You can get all those bindings at site X.com.

If the "Extra" argument is a hard sell, then the 3rd party site is a no-sale. They're right on this one.

A company pays for Red Hat license instead of using the free CentOs because it gives them someone to yell at if things go boom. If you depend on 3rd party software then you get sent to finger pointing hell.

I currently have a problem with my CentOS box at home. I'm using CentOS repositories and a few other reliable sites. Two sites depend on different versions of the same library. I can't upgrade until I find and remove the conflicting programs.

Run that past a manager and you'll be a Microsoft shop by the end of the day.

Besides, if the software is trustworthy and useful then it would be include with the distribution. Feel free to repeat this until your head explodes. It's what they do in corporateland.

* If you want to use the OS, learn the commands!

If you want to make me learn a bunch of esoteric commands, I'm using another OS!

Let's use the "chage" command as an example. It's a pretty simple command which I use about once a year. Every time I use it I have to look up the command flags, because I only use it once a year.

Now wrap it in a curses interface. I no longer have to use the man page. "chage-curses" pops up the user's info, lets me change it. It even uses a calendar to help me change the dates. It then munches up the interface changes into a command line call which make the actual changes.

Take it one step farther. I am a hot shot l33t Hax0r. I shouldn't be doing this peasant crap at all. I create "chage-gtk" in 30 lines of Perl, and now my helper monkey does all the chaging while I hack the cosmos.

* Surly you don't mean every scripting language?


Yep I do. For server admins the command line will live on forever. It's the easiest way to make bulk or automated changes.

Your average user isn't a server admin. We need to stop dressing them up like one and making them dance for us.

Every general purpose language that has a stable GUI and/or TUI and is already included in a distribution needs to have those bindings included. We need to show non-Linux users, and other programmers that we're serious bout getting out of the 1980s. That means that any general purpose language that can help us out needs to be embraced.

* What about languages that don't have stable GUI/TUI bindings?

Most of the popular languages have had stable bindings for years. Perl, Python and Java all have officially supported GTK/Gnome bindings.

If a language only has a stable TUI, but not GUI binding, then just include the TUI. If it has no stable bindings at all, then it remains command line only until it gets it's act together.

* Some languages have GUI/TUI bindings that are a bitch to make into packages.


Let the developer of both the bindings and the language know that that's the reason the binding isn't being included. Most will gladly fix their code or provide the distributions with packages.

* Jeez, our distribution is getting awfully big.

One: The graphic libraries shouldn't really be that big, they're just interfaces to existing libraries.

Two: This move is important! If going from a command line interface to a graphic interface is only being held back by a pack of Luddites, then Linux doesn't deserve to play with the big boys.

Three: This is also an advantage that we seem to be afraid to exploit. Does any other OS come with, by default, an easy way to create useful window based programs just using a text editor? We shouldn't be hiding this feature, we should be shoving it down peoples throats!

* Why should we include fooscript when real programmers use barscript?

You're an idiot.

This isn't about the size of your digital penis, it's about removing completely artificial barriers from the users. Gnome doesn't really serve the clever user well. This problem is trivial to fix. We need to do so in the most inclusive way.

If Perl gets the job done for you, great! If you like Python, no problem. Someone at the Guile compound must have got laid because it's perked right up in the last few months. Guess what? It has both a curses and Gnome interface. Welcome to the club Guile! (Assuming your bindings don't suck.)

* Real programmer program in C.

Actually they don't. Most casual programmers start by looking at a program that almost does what they want, and then pick at it. If the program is a script, it's much easier to play with.

For the inquisitive user, in real terms, modern computers are less powerful then they were in the days of Dos and Unix. Back then a curious user who had an itch, could scratch it with a batch file or shell script. This new command was on par with anything else on the system. If it was generally useful they could email it to anyone else and they could use the new command too. Now days a clever user has to either waste monkey cycles writing in C or they have to have other users download the script-gui library package.

Pithy Summary


This is a stupid pointless wall, and it needs to come down!

Tuesday, June 23, 2009

Emacs: P3 Separate But Equal.

In the first post, we went over some basic theory. In the second post we calibrated Emacs's concept of terminal color with the reality of our terminal program. We also created a file called "color_test.el" which is useful for showing the common "faces" used in programming.

I this part we'll explain what a "face" is and show to get terminal faces and display faces to play nice.

Faces

A "face", in Emacs parlance, is all the characteristics of a piece of text. This includes it's font, size, whether it's bold or italics and it's color.

In the olden days, faces were created by hand. They're not too bad once you get a hold of them and they're surprisingly flexible.

Emacs faces can do all sorts of snazzy things like auto-detect whether they're on a terminal, change their color if the background color changes and invert themselves if they're on a black and white screen. Here's an example taken from the Emacs Elisp manual, section "Elisp/Display/Faces/Defining Faces".

(defface region
`((((type tty) (class color))
(:background "blue" :foreground "white"))
(((type tty) (class mono))
(:inverse-video t))
(((class color) (background dark))
(:background "blue"))
(((class color) (background light))
(:background "lightblue"))
(t (:background "gray")))
"Basic face for highlighting the region."
:group 'basic-faces)

Alas, you young punks don't wanna do it by hand. You'd rather use Emacs's built in customizer. Fair enough.

The Customizer.

I'm not going into a lot of detail here as there are other web resources dedicated to customizing Emacs.

For the sake of this article we need to know:

  • "M-x list-faces-display" shows you all the faces Emacs knows about.
  • Pressing when your cursor is on the face name will let you edit it.
  • In programming mode, all the fonts we care about begin with the wildly intuitive name "font-lock-".
  • When you're customizing in terminal mode don't forget about "Weight Bold" and "Weight Light". In most terminal emulators they give you extra colors to play with.


Multiple Customs.

If you're using a new version of Emacs, you can go into the customizer, click on the "state" button and select "Show All Display Specs". Then click on "Display" and choose "Check List". This lets you select the modes that you want the changes for. If this gets the job done, then you're done. I've had trouble with edits in TTY mode stomping on my edits in display mode, so I like to keep the variables separate.

After much (and I do mean multiple days) experimenting, I've chosen a more robust solution that is easier to maintain and is a lot harder to stomp on.

Whenever you customize a face and save it, Emacs replaces the function "custom-set-faces" with a new version that has your changes in it. The change is written into your custom file. This file could be the end of your ~/.emacs file or the file named in the "custom-file" variable. I'll use the generic "custom file" because I don't care where it actually is.

The way I handle multiple customizations is to customize them via the customizer. Then load the custom file back into Emacs and rename the custom-set-faces function so it only fires when you're in either terminal or display mode, but not both.

It's very easy to do and it's mostly cut and paste.

Load your Emacs custom file. Before any "custom-set-faces" commands, add these 2 functions:

(defun my-custom-set-faces-display (&rest faces)
"Load these faces if Emacs is in windows mode."
(when window-system
(apply 'custom-set-faces faces)))
(defun my-custom-set-faces-terminal (&rest faces)
"Load these faces if Emacs is in terminal mode."
(when (not window-system)
(apply 'custom-set-faces faces)))

Now look at your current "custom-set-faces" command. Is it set up for display mode? Then rename it to "custom-set-faces-display". If it's for the terminal then rename it "custom-set-faces-terminal". Now add an empty function call for the "other" function. If you set custom-set-faces-display, then add "(custom-set-faces-terminal)". If you set custom-set-faces-terminal, then add "(custom-set-faces-display)".

Mine looks like this:

(custom-set-faces-terminal
'(font-lock-function-name-face
((t :foreground "LightlyDepressed" :weight bold)))
'(font-lock-comment-face ((t :foreground "cyan"))))

(custom-set-faces-display)

Now fire up Emacs in terminal mode (emacs -nw) and edit a face. I'll make the font-lock-comment-face "Naval" colored for this example. Then save the change. Take a look at your custom file and you should see the color change in the function "custom-set-faces". Here's my example:

(custom-set-faces-terminal
`(font-lock-function-name-face
((t :foreground "LightlyDepressed" :weight bold)))
`(font-lock-comment-face ((t :foreground "cyan"))))
(custom-set-faces-display)
(custom-set-faces
;; custom-set-faces was added by Custom -- don't edit or cut/paste it!
;; Your init file should contain only one such instance.
'(font-lock-comment-face ((t (:foreground "naval"))))
'(font-lock-function-name-face
((t :foreground "LightlyDepressed" :weight bold))))

Delete the old custom-set-faces-terminal. Rename custom-set-faces to custom-set-faces-terminal, save your work and you're done.

If you wish to edit your display faces, just fire Emacs up in display mode and run through the same process.

There's no limit to the number of face sets you can add. You can have a different face set for every day of the week if you want. Just create a "my-custom-set-faces-" for any discriminator you want and rename custom-set-faces to match it.

Hopefully my absurd 10 day journey into Emacs's faces has been rendered down into something useful for you. Let me know if you found this helpful.

Monday, June 22, 2009

Emacs: P2 Color Me LightlyDepressed.

Now that we have some color theory under our belt, let's calibrate Emacs's concept of color with the reality of the terminal's.

First we have to get the real colors being displayed. I'm using gnome-terminal which has a built in color picker. If you're using a terminal that doesn't have it's own color picker, fire up "emacs -nw", do "M-X list-colors-display", then use something like "xmag" or gimp to get the color values.

My Color List.

From a gnome-terminal, select "Edit/Current Profile" from the menu. From the "Default" screen, click on the "Colors" tab. At the bottom of the screen you should see 2 rows of 8 colors. The first row is the 8 colors that make up the terminal's pallet. Left most is entry 0, right most is 7. The second row are the colors you get when you print the first row using "bold". Gnome-terminal has a 3rd row of colors that are the first row in "dark" mode, but you can't edit them.

If Emacs was smarter about terminal colors you could tell it about all 3 rows of colors and it could use "bold" and "dark" version to increase the chance of it's making a good color choice. Alas, were stuck with our one row of 8 colors.

Click on each color in order, and write down their Red, Green and Blue (RGB) values. For example, the 4th color in my pallet is kind of brown, with yellow below it. It's RGB value is 170/85/0, so pallet entry 3 is 170/85/0.

This is my list:

0 0 0 0
1 170 0 0
2 0 170 0
3 170 85 0
4 0 0 170
5 170 0 170
6 0 170 170
7 170 170 170

Once you have all 8 values, ask Emacs (in a terminal) for help on the variable "color-name-rgb-alist" (C-hv color-name-rgb-alist). The help should list all the color names that Emacs knows and their RGB values.

Scan the list for colors that match the gnome-terminal colors. If you find a *perfect* match, put the color's name besides it's color in your list. Only use the name if it's a perfect match. 0/0/0 was the only match for me. I labeled color 0 "Black".

For the rest of the colors, give them descriptive names that are not in color-name-rgb-list. The last thing we need is 1 name for 2 colors.

Here's my final list.

Black 0 0 0 0
Brick 1 170 0 0
Greeny 2 0 170 0
Brownish 3 170 85 0
Naval 4 0 0 170
DarkishMagenta 5 170 0 170
NeonPee 6 0 170 170
LightlyDepressed 7 170 170 170

Now we have to get the colors into Emacs. It turns out that that's pretty easy.

RCS

First, make a backup of your ~/.emacs, just to be safe. As an aside, because this series isn't nearly long enough, consider using RCS to backup any config files that you hand edit. Under Emacs RCS is trivial to set up and use. It's saved my monkey boy butt more times than I care to remember.

To set up RCS for your ~/.emacs, make a directory called ~/RCS. Then load your ~/.emacs file into Emacs. Hit C-xvv. That's it. You're done. Your ~/.emacs is now write protected and checked into ~/RCS. To check out your file so you can edit it, load it into Emacs and hit C-xvv.

Back to work.

Edit your ~/.emacs, and add the following code. If your ~/.emacs has a custom-set-variables or custom-set-faces function, place this code before either. Obviously you should use your own colors and names for the my-tty-color-define-8 commands.


;; Code for handling term based Emacs.
(defun my-tty-color-define-8 (name index rgb8)
"Set the tty pallet using 8 bit rgb values."
(tty-color-define name index
(mapcar (lambda (x) (+ x (* x 256))) rgb8)))

(if (and (not window-system) (= 8 (length (tty-color-alist))))
(progn
(tty-color-clear)
(my-tty-color-define-8 "Black" 0 '(0 0 0))
(my-tty-color-define-8 "Brick" 1 '(170 0 0))
(my-tty-color-define-8 "Greeny" 2 '(0 170 0))
(my-tty-color-define-8 "Brownish" 3 '(170 85 0))
(my-tty-color-define-8 "Naval" 4 '(0 0 170))
(my-tty-color-define-8 "DarkishMagenta" 5 '(170 0 170))
(my-tty-color-define-8 "NeonPee" 6 '(0 170 170))
(my-tty-color-define-8 "LightlyDepressed" 7 '(170 170 170))))

Save your ~/.emacs file and exit. Restart with "emacs -nw" Type "M-x list-colors-display". You should see your color names listed with the colors.

This might not seem like much of an achievement, but you've actually taken a pretty big step.

To check our your results, create a file called color_test.el in Emacs (-nw). It should put you into "Emacs Lisp" mode automatically. Now type in this program:


;; Comments are in 'comment-face'.
;; defun and defvar are in keyword-face.
(defun function-name-face (&optional is-in-type-face)
"string-face `constant-face' string-face"
:builtin-face
(error "warning-face"))
(defvar variable-name-face)

;; To see the "doc-face" go into "perl-mode".
=pod
This should be in doc-face.
=cut


The program itself doesn't work. It's not even syntactically valid. All it exists for is you show all various "faces" that Emacs uses when coloring code.

To see doc-face, use "M-x perl-mode".

How do you like them colors? If you're happy happy, then you can skip post 3 of this series. If, however, you're like me and think that Red is a horrible color for comment text, then await with baited breath the last installment of the Emacs color saga.

Sunday, June 21, 2009

Emacs: P1: What Color Is My Painbow?

Last week I had a classic "Monkey Boy" moment. I decided to adjust the colors in my text editor. 10 days later I'm finishing a 3 post blog on it.

I worry myself some days.

This first post is going to be mostly theory work. Post 2 and 3 are more hands on.

Laying the Ground Work.

I use an editor called Emacs for most of my programming. It's an old editor, but its one of the most powerful editors out there. It also lets you edit files in display (windows) mode and from the shell (command.com for you Windows folks).

Now days most of the editing is done in display mode. No real surprise there. However, there are times when working from the shell makes more sense.

I routinely log into distant machines across slow connections. I could pop up a virtual session and wait for the window in the virtual session and then wait for the editor in the window in the virtual session and then wait for the file in the editor in the window in the virtual session, or I can use text mode, where are complete screen refresh is around 2000 bytes.

I hate waiting. Its a no brainer.

The down side of terminal mode is that you can only use characters to draw and you have a limited number of colors. Both of these could be overcome with modern technology, but it ain't going to happen so we have to get used to it.

Why do you have limited colors? Well, the underling technology differences between a terminal from 20 years ago and a modern graphic display is pretty significant.

RGB

Colors are made by mixing various amounts of Red, Green and Blue (RGB) together. If you crank up the RGB, you get bright colors, dial it down and you get dark. Wikipedia has a nice write up on color depth so I won't go into it here. The only thing you need to know is that by adjusting the RGB values you can change colors.

On modern display you have absolute control of every dot on the screen. Each one has it's own RGB setting which is independent of it's neighbor.

Old school color terminals were more like "paint by numbers" projects. You were given a pallet of colors (usually 8) that were hard wired into slots. If you set the color to pallet slot 0 and then printed, you got black text. If you printed in color 4 you might get blue. Unfortunately for us, these are the terminals that most terminal emulators emulate.

We have two problems when we want use Emacs in both terminal and display mode: First is that Emacs's support of terminal colors is functional, but not much more. The second is that the friendly Emacs customizers don't like it when you're a switch hitter. In fact they gets down right medieval on your monkey butt. Well, this ain't monkey butt, this is monkey boy butt. Accept no substitutions.

Terminal Colors


As I said before, most terminal emulators model the old style, 8 color pallets. There are ways for a program to ask the emulator for the number of colors available, but there isn't any way to get the actual RGB of each color.

What does Emacs do? It guesses! If you don't tell it otherwise Emacs assumes that you have an 8 color pallet with the following colors:


Slot Name Red Green Blue
---- ------- --- ----- ----
0 black 0 0 0
1 red 255 0 0
2 green 0 255 0
3 yellow 255 255 0
4 blue 0 0 255
5 magenta 255 0 255
6 cyan 0 255 255
7 white 255 255 255


The numbers after the colors are how much Red Green and Blue that each color is supposed to have. 255 is the largest number you can express in 8 bits (1 byte) of data. There are places internally where Emacs uses 16 bit (2 byte) RGB values which go from 0 to 65535. I got bit by this more than a few times so I'll try to point them out, or gloss over them when I can.

Emacs cares about the RGB values because you (the user) set colors by name not slot values. If you set the color of something to "CadetBlue1" 152/245/255, then run in terminal mode, Emacs needs to figure out which of the eight colors CadetBlue1 is closest to. It uses the RGB values to figure it out.

Oh, by the way, the name "CadetBlue1" comes from a variable called "color-name-rgb-alist". To see it's contents, fire up Emacs in display mode and type "M-x list-colors-display". You'll see the colors and their names.

Let's do some hands on. From a terminal, type "emacs -nw". It should start an Emacs session in the terminal. In Emacs type "M-x list-colors-display". You'll get a listing of the 8 colors that Emacs knows about. Note: On some systems you get more than eight. Lucky you. The theory is still the same.

If you're like me, you notice one thing first off. These colors look nothing like their names! The Red might be brick colored. Yellow may look brown. And my white has tattle tale gray! What happened?

Easy. Emacs has no idea what colors your terminal's pallet is set to and it's guess stinks. How do we handle the miss-match?

One option is to change our terminal to Emacs's pallet. Then we can vomit and claw our eyes out. Basic colors tend to be rather harsh on the psyche.

The second option is to tell Emacs what our terminal is really packing. That's the subject of the next post.