Warren Falk

Back to Linux

December 4th, 2007 by Warren Falk

Ubuntu IconOver two years ago I shed Windows from my desktop and built a Gentoo desktop. At the time, I was working from home only and had lots of extra time to tweak, compile and troubleshoot. When I changed jobs again, the lack of time, and compatibility issues with being back in a Microsoft environment at work forced me to abandon my Gentoo and go back to Windows.

Well, I’m still in a Microsoft environment at work, and I still don’t have any time, but now I’m trying to make a go of it again. This time, however, noting my lack of available tinker time, I’m going with the flow and have installed Ubuntu. (I love Gentoo but just don’t have the time to deal with its idiosyncrasies right now).

PHP Class Autoload

August 31st, 2006 by Warren Falk

It’s been a long time since I posted.  I just wanted to write up a quick post today to say how much I like the new __autoload() function in PHP.  For those not familiar with it, the function gets called when a class is used in PHP that has not been defined.  This gives the developer a chance to allow the script to find the include file it needs and include it to define the class.

The function’s not all that new, but I’m just getting around to using it and it’s changing the way I design my sites.

So now I don’t use ever need to manually include a file anymore.  I don’t use any global functions.  I make all my otherwise-global functions static functions of some class and call them that way.  I never have to remember to include the file at the top of the page, I never have to worry about including it twice because of the quirks of include_once(), and I don’t have a bunch of orphaned include()s at the top of the script anymore from removing a function but leaving it’s include.

I’m sure there’s someone out there that thinks this isn’t a good idea for whatever reason.  I’m all ears, but for now, this has made my PHP development much easier.

Stupid Standards

June 1st, 2006 by Warren Falk

I’m all for standards in web browsers. But it really bugs me when the standards-compliant behavior is worse than the non-compliant browsers’ behavior. So here we have made a standard protocol, and to follow the protocol means making your browser behave poorly. This isn’t always the case. Quite often the standard is better, and for the most part a standard is almost always better than no standard.

It’s almost strange how little agreement there is between browser makers on the best way to implement what’s known as the box model. The box model refers to the dimensions and spacing given to html tags. For instance, a box in html has the main body where the text goes, surrounded by the padding which is filled with the object’s background color but is otherwise empty of text. That is surrounded by the border, which is surrounded by the margin, which is more empty space which is transparent and collapses against (is allowed to overlap) margins of other elements. The confusion comes when it’s time to set the width of the element. To which part of the box model does/should the width refer?

The standard apparently says that the width refers to the body part, not the padding. Internet Explorer, on the other hand, says that the width refers to the body plus the padding plus the border. Oddly, in standards compliant mode, IE still says that the width refers to the body plus the padding. IE’s “quirks” way makes the most sense to me. The standard way does not. Why? Because the standard way makes certain things impossible, whereas, IE’s way does not.

Take for instance a table of data. In one column of the table, you have an input field in each row so that the user can edit information. You want the input field to expand horizontally in size to fill the cell it’s in. So you set its width to 100% and that works perfectly, except you notice that the text seems to butt up against the left edge too closely, so you add padding to the left (about five pixels (5px) or so). Ah, that seems to work fine in IE, but in Firefox, now, the right edge of your input field has encroached five pixels into the neighboring cell on the right. Why? Because the 100% width you set doesn’t apply to the padding. So how do you take the padding into account? You can’t, because you can’t do math in CSS. Otherwise 100% – 5px would be nice. Or it might be nice to be able to actually specify which part of the box model you want width to affect.

Now IE gets a lot of flack when it doesn’t adhere to the standard, and for the most part it should. And I like that IE can be switched into “compliance” mode with a DOCTYPE declaration (even though it is only a little more compliant). However, I often find that it is the standard which is most annoying.

Development in Variable Width (follow up)

May 30th, 2006 by Warren Falk

I am still using variable width for my development. I still have not noticed any more annoyances besides those I had already noted in my first post (space character too thin, developers that try to line stuff up too often etc.). I have corrected the space-too-thin problem by editing the font. I took the liberty of merging the monospace versions of the parentheses, angle brackets, and curly braces (I used Bitstream Vera Mono for that) into my favorite proportional font so far (Verdana – like Tahoma, but with wider spacing between letters).

I also fixed some other annoyances, such as the tiny margin on either side of single and double quotes. This made it very hard to read, and made things such as a single quote, wrapped in double quotes, a very hard thing to decipher. So I increased that margin significantly.

Then I did a couple more things. I made the parentheses (that I copied in from the monospace font) to be more concave. I like that much better. I also made their footprints wider to compensate. Then I added a dot in the middle of the zero, and even put a very thin line through the seven, just because.

I even adjusted the kerning between certain characters to make operators easier to read. I made >>, => and -> spaced closer together, but when I tested them out, I found that my development environment does not seem to take advantage of kerning. If it had, I might have also added some more operator kerning.

So for anyone who is interested, here is the font: WF-Programmer Postscript Font file

DOM Builder Shortcut Function

May 16th, 2006 by Warren Falk

I’ve created a library to aid in the creation of DOM trees from within Javascript using a json-like syntax. If you’ve ever createElemented or appendChilded your way to a DOM tree, you know why this might be handy.

I like having a standardized DOM, but the language is so incredibly verbose that to build even the most rudimentary DOM tree in javascript takes long line after long line of code. Take the following HTML excerpt for example:

<div class="player">
	<img class="icon" src="img/p1.gif"/>
	<p class="playername">
		<span class="name">Warren</span> (next to move)
	</p>
	<p class="actions">
		[ <a href="lastmove.php">last move</a> ]
	</p>
	<br class="clear"/>
</div>

Now if we want to do this in raw standard DOM javascript code, it will look like this:

var div_player = document.createElement('div');
div_player.className = 'player';
var img_icon = div_player.appendChild(document.createElement('img'));
img_icon.className = 'icon';
img_icon.setAttribute('src', 'img/p1.gif');
var p_playername = div_player.appendChild(document.createElement('p'));
p_playername.className = 'playername';
var span_name = p_playername.appendChild(document.createElement('span'));
span_name.className = 'name';
span_name.appendChild(document.createTextNode('Warren'));
p_playername.appendChild(document.createTextNode(' (next to move)'));
var p_actions = div_player.appendChild(document.createElement('p'));
p_actions.className = 'actions';
p_actions.appendChild(document.createTextNode('[ '));
var a_lastmove = p_actions.appendChild(document.createElement('a'));
a_lastmove.setAttribute('href', 'lastmove.php');
a_lastmove.appendChild(document.createTextNode('last move'));
p_actions.appendChild(document.createTextNode(' ]'));
br_clear = div_player.appendChild(document.createElement('br'));
br_clear.className = 'clear';

And to be fair, I even took advantage of the .className property available for HTML instead of the DOM’s more verbose setAttribute method. The resulting code is much harder to read or debug and is horribly bulky in an environment where code is actually transmitted to the client over a network.

To solve the problem, I created a function called jcreate(). The function takes a single parameter and returns a single node. But the range of parameters it can take is its power. If you pass a string, it will return a DOMTextNode containing that string. If you pass in an array, the first element of the array becomes the “tag descriptor,” and the following elements become the child nodes (becoming parameters, themselves to recursive calls to jcreate()). The descriptor format is simply “tagname.classname#idname” and so it works like this:

jcreate('Warren'); // creates a text node
jcreate(['div']); // creates a div element
jcreate(['div.test#name']); // creates a div element with attributes class="test" and id="name"
jcreate(['div.test#name', 'Warren']); // identical div, but with a child text node
jcreate(['div.test#name, ['p.text', 'Warren'], ['p.subtext', 'super genius']]); // here the div contains two paragraphs
// now let's format that with indents
jcreate(
	['div.test#name,
		['p.text', 'Warren'],
		['p.subtext', 'super genius'],
		]);

In addition to the CSS-like descriptor above, you can also have an attribute descriptor of the format “@attrname.” An attribute is coded then as ['@href', '#help'] and so a link is coded as ['a', ['@href', '#help'], 'click for help'].

You can also use DOM nodes in the json-syntax instead of the json-like alternative. Why would you? Because it can give you a reference variable to that node that you can use later in your code to change the contents. It looks like this:

jcreate(
	['div.test#name,
		x = jcreate(['p.text', 'Warren']),
		['p.subtext', 'super genius'],
		]);
	.
	.
	.
	x.className = 'text highlight';

The HTML code at the beginning of this article can be then built dynamically using the following code:

x = jcreate(
['div.player',
	['img.icon', ['@src', 'img/p1.gif']],
	['p.playername', ['span.name', 'Warren'], ' (next to move)'],
	['p.actions',
		'[ ',
		['a', ['@href', 'lastmove.php'], 'last move'],
		' ]',
		]
	['br.clear']]);

The overhead for all this convenience is a few functions:

function create(n,c,i) { var e = document.createElement(n); if(c) e.className = c; if(i) e.id = i; return e; }
function attr(n,v) { var a = document.createAttribute(n); a.value = v; return a; }
function nodecreate(n) { return create(n.tagName, n.className, n.id); }
function text(s) { return document.createTextNode(s); }

function jid(s)
{
	a = s.split('#');
	b = a[0].split('.');
	return {tagName: b[0], className: b[1], id: a[1]};
}
function jcreate(j)
{
	if (j.nodeType) return j;
	if (typeof(j) == 'string') return text(j);
	if (j[0])
	{
		var id = j[0];
		if (id.substring(0,1) == '@') return attr(id.substring(1), j[1]);
		var e = nodecreate(jid(id));
		for (var i = 1; i < j.length; i++)
		{
			c = jcreate(j[i]);
			c && ((c.nodeType == 2) ? e.setAttributeNode(c) : e.appendChild(c));
		}
		return e;
	}
	return null;
}

In the future, I might extend this to allow javascript objects more complex than arrays (more like json syntax). But so far, I haven't really found a good reason to.

I've tested this, so far, in IE, Mozilla, Opera, and Konqueror. I am confident it works in Safari also but if someone could verify that and comment here, I'd be grateful.

Development in Variable Width

May 10th, 2006 by Warren Falk

The traditional font family for use in writing computer code is monospace. Partly this is because monospace was all that was available when computer programming began and remained largely the only choice until relatively recently. Mostly, though, monospace is used because coders use spacing to line up their code to make it more readable.

I visited a website which listed some favorite programming fonts and described the properties of each font which made it suitable for programming. All the fonts were monospace as one would assume. However a commentor on the site said that he began using a variable width font a few years previously and never looked back.

So I’ve decided to give it a try, and so far, I like it. Variable width fonts are just easier on the eyes after a while. Still, you need a decent programming font. I would like one where the parentheses (and brackets) have wider than average spacing, and similar characters such as zero and the letter ‘O’ are distinguishable. Interestingly, I’ve found that when I don’t intentionally line my code up, I actually don’t want it to line up. I have found that it is actually easier to read the code when all the characters in the line below do not line up directly under characters in the line above. My left margin is always clean because the spaces and tabs are always the same size. For the most part, I don’t see spacing as a problem. In my particular font, I wish the space character was bigger, though. Another “pro” is that I can fit a whole lot more on one line without using a small font or a harder to read, narrow font.

There are some “cons” though. That narrow font means that people who wrap their comments to more than one line seem to wrap them way too soon. And using a variable width font means I will, likewise, tend to wrap mine later than would be readable for a monospace-font developer. My left margin is always clean, but every once in a great while, I find that code that was intended to line up does not. However, this hasn’t been a problem for me. Coders, I think, often over-format their code, even reducing readability to some degree.

What I would like to see is an editor that can mitigate the downsides of variable width fonts by manipulating the whitespace and recognizing the language syntax. For instance, the editor should be able to detect when a monospace-font developer adds superfluous whitespace for the purpose of lining up code and then expand the variable width whitespace as necessary to make sure the code is lined up. Though this can’t ever be perfect, it can be perfected to a reasonable degree. Also, comment blocks that are obviously wrapped intentionally could be “unwrapped” then “rewrapped.” There are email applications that do this with email text wrapped to the standard 80-or-so lines.  The editor can then automatically wrap comments back to monospace width when saving.

I am currently using KDevelop, KDE’s development environment, for my C++ development.  I might just try to find out where the editor code is and see if I can implement something like this.  In the mean time, though, I think I’ll keep experimenting with different variable width fonts anyway.

No 64bit Flash Player [updated]

April 20th, 2006 by Warren Falk

And so it goes, one of the first problems I am running into while using linux is that there is no 64 bit flash player for linux. In fact, there might not be a 64 bit flash player at all. This surprises me. I hear people argue that there just isn’t that much demand for it, but part of the benefit of flash was supposedly its wide adoption and cross-platform availability, giving a developer a way to code without worrying about browser incompatibilities. If nobody on a 64 bit system is going to be able to use it, then that seems like a rather big deal. As far as I can tell, there are no official plans to create a 64 bit version.

What does this mean? No google video in linux, was the first thing I noticed.

[UPDATE] You can actually download the video as an AVI reportedly by pasting the following address in the address bar in mozilla (or by making it a bookmark):

javascript:if(document.getElementById('macdownloadlink')!=null){window.location.href=document.getElementById('macdownloadlink')}else{alert('Go to Google Video to download videos as AVI.')};

[UPDATE2] Also, if you can figure out how to download the FLV file, you can install ffmpeg which comes with ffplay, that can play flv files. It should be possible to write a quick plugin or something to do this easily. Of course, I don’t have time to be bothered with that.

It works …mostly

April 20th, 2006 by Warren Falk

Well after a lot of pain, I finally got a good linux system up and running on my AMD64 with ATI x850. It seems to work alright for the most part, though there are a couple glitches. Currently my entire system locks up if I try to quit X. I have not been able to determine if this is a problem with ATI’s drivers or the kernel, or some combination of both. It only seemed to have happened when I got dual monitors working (finally).

The dual monitors works much like Windows once it works. The basic dual monitor or multi-monitor technology in linux is usually referred to as Xinerama, though it isn’t always the exact same technology. What I found out was that KDE had to be recompiled to become “xinerama aware” before it would work correctly in the dual monitor system. Before being recompiled, the system behaved exactly like I had one double wide monitor. That means things maximized across both screens, and dialog boxes popped up centered between the screens. I don’t know, yet, if other applications have to be xinerama aware or not, or if it was enough that KDE and its window manager are now. I will find out soon enough. If it isn’t, I’ll be sure to post a complaint about that here.

Note that recompiling KDE to be xinerama aware is a gentoo thing. Most common (binary) distributions will probably have this already built-in.

3D accelleration does not seem to be working either. DRI is apparently enabled, but when I run the glxgears test, I get 450fps or so. I see other people reporting 8000fps or higher, so I know that mine is not working correctly. I may, therefore, move to the open source radeon driver since it is rumored to be more stable. If 3d accelleration is all I have to sacrifice, then I haven’t lost anything.

Trouble With Dual Monitors

April 12th, 2006 by Warren Falk

So yet another thing I have to deal with when trying to make a switch from Windows to Linux. In Windows, we simply right click the desktop, go to properties, settings, where I see my second monitor, which I can move to where I want it to be, relative to my primary monitor, and it even prompts me to extend the desktop onto it. How nice.

My single monitor “mirror” or “clone” works fine, but if I want to try to do dual monitors, the secondary goes into power save mode and the primary just stays blank (and, of course in true X fashion freezes and takes no more input).

I followed ATI’s instructions, but it seems to be that the second monitor has a different BusID which has a different chip id and that it isn’t in the list of supported chip ids in ATI’s driver. I’d heard of this happening before for primary monitors where companies like Asus where “branding” their chips and changing the chip ids. ATI fixed that, as I understood it, yet my primary is in the list and my secondary is not. The thing is that I don’t really see any secondaries in there and I don’t know if I should. But I do know that it doesn’t recognize mine.

Here is the list, from my log file:

RADEON 9000/9000 PRO (RV250 4966), RADEON 9000 LE (RV250 4967),
MOBILITY FireGL 9000 (M9 4C64), MOBILITY RADEON 9000 (M9 4C66),
RADEON 9000 PRO (D9 4C67), RADEON 9250 (RV280 5960),
RADEON 9200 (RV280 5961), RADEON 9200 SE (RV280 5964),
MOBILITY RADEON 9200 (M9+ 5C61), MOBILITY RADEON 9200 (M9+ 5C63),
FireGL 8800 (R200 5148), RADEON 8500 (R200 514C),
RADEON 9100 (R200 514D), RADEON 8500 AIW (R200 4242),
RADEON 9600 (RV350 4150), RADEON 9600 SE (RV350 4151),
RADEON 9600 PRO (RV360 4152), RADEON 9600 (RV350 4E51),
MOBILITY RADEON 9600/9700 (M10/M11 4E50),
MOBILITY RADEON 9550 (M12 4E56), RADEON 9500 (R300 4144),
RADEON 9600 TX (R300 4146), FireGL Z1 (R300 4147),
RADEON 9700 PRO (R300 4E44), RADEON 9500 PRO/9700 (R300 4E45),
RADEON 9600 TX (R300 4E46), FireGL X1 (R300 4E47),
RADEON 9800 SE (R350 4148), RADEON 9550 (RV350 4153),
FireGL T2 (RV350 4154), RADEON 9800 PRO (R350 4E48),
RADEON 9800 (R350 4E49), RADEON 9800 XT (R360 4E4A),
FireGL X2-256/X2-256t (R350 4E4B),
MOBILITY FireGL T2/T2e (M10/M11 4E54), RADEON X300 (RV370 5B60),
RADEON X600 (RV380 5B62), RADEON X550 (RV370 5B63),
FireGL V3100 (RV370 5B64), MOBILITY RADEON X300 (M22 5460),
MOBILITY RADEON X600 (M24 5462), MOBILITY FireGL V3100 (M22 5464),
RADEON X600 (RV380 3E50), FireGL V3200 (RV380 3E54),
MOBILITY RADEON X600 (M24 3150), MOBILITY RADEON X300 (M22 3152),
MOBILITY FireGL V3200 (M24 3154), RADEON X800 (R420 4A48),
RADEON X800 PRO (R420 4A49), RADEON X800 SE (R420 4A4A),
RADEON X800 XT (R420 4A4B), RADEON X800 (R420 4A4C),
FireGL X3-256 (R420 4A4D), MOBILITY RADEON 9800 (M18 4A4E),
RADEON X800 XT Platinum Edition (R420 4A50), RADEON X800 (R423 5548),
RADEON X800 PRO (R423 5549),
RADEON X800 XT Platinum Edition (R423 554A),
RADEON X800 SE (R423 554B), RADEON X800 XT (R423 5D57),
FireGL V7100 (R423 5550), FireGL V5100 (R423 5551),
MOBILITY RADEON X800 XT (M28 5D48), MOBILITY FireGL V5100 (M28 5D49),
RADEON X800 XL (R430 554D), RADEON X800 (R430 554F),
RADEON X850 XT Platinum Edition (R480 5D4D),
RADEON X850 PRO (R480 5D4F), RADEON X850 XT (R480 5D52),
MOBILITY FireGL V5000 (M26 564A), MOBILITY FireGL V5000 (M26 564B),
FireGL V5000 (RV410 5E48), FireGL V3300 (RV410 5E49),
RADEON X700 XT (RV410 5E4A), RADEON X700 PRO (RV410 5E4B),
RADEON X700 SE (RV410 5E4C), RADEON X700 (RV410 5E4D),
RADEON X700 (RV410 5E4F), MOBILITY RADEON X700 (M26 5652),
MOBILITY RADEON X700 (M26 5653), MOBILITY RADEON X700 XL,
RADEON 9100 IGP (RS300 5834),
RADEON 9000 PRO/9100 PRO IGP (RS350 7834),
MOBILITY RADEON 9000/9100 IGP (RS300M 5835),
RADEON XPRESS 200 (RS400 5A41), RADEON XPRESS 200M (RS400 5A42),
RADEON XPRESS 200 (RS480 5954), RADEON XPRESS 200M (RS480 5955),
RADEON XPRESS 200 (RS482 5974), RADEON XPRESS 200M (RS482 5975),
RADEON XPRESS 200 (RC410 5A61), RADEON XPRESS 200M (RC410 5A62),
RADEON 9000 (RV280 5962), MOBILITY RADEON 9500 (M11 4E52),
RADEON 9500 (R350 4149), RADEON 9600 (RV351 4155),
MOBILITY RADEON X300 (M22 5461), RADEON X800 SE (R420 4A4F),
RADEON X800 VE (R420 4A54), RADEON X800 GT (R423 554B),
MOBILITY RADEON X800 (M28 5D4A), RADEON X800 GT (R430 554E),
RADEON X800 GTO (R430 554F), RADEON X800 GTO (R480 5D4F),
RADEON X850 (R481 4B48), RADEON X850 XT (R481 4B49),
RADEON X850 SE (R481 4B4A), RADEON X850 PRO (R481 4B4B),
RADEON X850 XT Platinum Edition (R481 4B4C)

My card is in bold. Here is what I get from lspci -v and lspci -n (relevant sections in bold):

02:00.0 VGA compatible controller: ATI Technologies Inc R480 [Radeon X800 GTO (PCIE)] (prog-if 00 [VGA])
Subsystem: ATI Technologies Inc Unknown device 0112
Flags: bus master, fast devsel, latency 0, IRQ 50
Memory at d0000000 (64-bit, prefetchable) [size=256M]
Memory at e3000000 (64-bit, non-prefetchable) [size=64K]
I/O ports at a000 [size=256]
[virtual] Expansion ROM at e2000000 [disabled] [size=128K]
Capabilities: [50] Power Management version 2
Capabilities: [58] Express Endpoint IRQ 0
Capabilities: [80] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
Capabilities: [100] Advanced Error Reporting
02:00.1 Display controller: ATI Technologies Inc R480 [Radeon X800 GTO (PCIE)] (Secondary)
Subsystem: ATI Technologies Inc Unknown device 0113
Flags: bus master, fast devsel, latency 0
Memory at e3010000 (64-bit, non-prefetchable) [size=64K]
Capabilities: [50] Power Management version 2
Capabilities: [58] Express Endpoint IRQ 0

02:00.0 0300: 1002:5d4f
02:00.1 0380: 1002:5d6f

Notice that 5D4F is the primary display, and it is in the list (I bolded it). Notice that 5D6F is not. And this is the message I get in the log:

(WW) fglrx: No matching Device section for instance (BusID PCI:2:0:1) found

ATI x850 Working, but not with X11R7

April 11th, 2006 by Warren Falk

Well, I went back through /var/log/emerge.log to find all the stuff that was merged to setup Modular X and I unmerged it all. I should have binaries of them to make remerging them easier if I change my mind again later. I emerged Xorg 6.8.2 again and got the card working. I’m using version 8.23.7 of the proprietary ATI driver (x11-drivers/ati-driver in portage).

It wasn’t perfect from the start, though. I ran X -configure and it exited on signal 11. I moved all the modules out of /usr/lib64/modules/drivers into a temporary directory except fglrx and vesa, but still, signal 11. However, the xorg.conf.new file was written, so I ran aticonfig on that one and then tried X -config xorg.conf.new and, to my surprise, it started up. I copied that config file to /etc/X11/xorg.conf and started everything up with /etc/init.d/xdm start

I’ll probably look into seeing if it is possible to get it running with X11R7 later on, but in the mean time, I’m going to poke around in KDE 3.5.2 and see how things work.

.
Entries (RSS) and Comments (RSS).