Console2 and x64

Link. September 18, 2008. Comments [3]. Posted in: C++ | Tools

I recently mentioned that version 2.00b140 of the great Console utility had come out. Eddie Velasquez commented on that post that, unfortunately, Console didn't work correctly on Windows x64.

I had the opportunity to verify this during the last week. Console2 runs, but all text drawn on the console is invisible, which makes it a bit hard to read :-). I looked around the web, and although a few people mentioned seeing the same problem, no one offered any solutions. So I decided to take a look.

I installed Visual C++ 2008 on my x64 machine, downloaded the Console2 source code package and went hunting around for all dependencies needed to actually build it, which took a couple of hours. Off the top of my head, you need:

After a bit of tweaking the project files, I was able to build an x86 version of the code and started looking around the code to see where the problem might be. I checked a few things, like:

  • Was it possible that it was interacting incorrectly with the underlying system console and not picking up the text colors? Nope. Debugger showed me it was indeed picking up the right color for each character drawn.
  • Was it possible that it was mapping colors incorrectly? nope, not that either.
  • Was it possible it was drawing the text in the wrong locations? Didn't seem to be that either, as you could even copy paste the text from Console correctly, and the caret seemed to be at the right location either.
  • Could the off-screen surfaces be somehow invalid? Nope, a few calls to GetDeviceCaps() showed it had all the correct number of planes and bits per pixel that you'd expect.

After a few hours of tinkering, I was able to narrow it down to one issue: the use of the AlphaBlend() function when blitting between the off-screen and on-screen surfaces. In fact, I'm fairly confident that the issue Console2 is running into is the same one described on this newsgroup post. Unfortunately, that didn't seem to point to a good workaround for the issue.

Now, my GDI programming isn't very fresh on my mind, and frankly, I didn't want to sit around for a long time trying to get this fixed. However, I was able to make a quick change to the code that would make it work. The changes are setting up the BlendFunction for AlphaBlend slightly different.

The change I did was around line 1979, changing the setup before AlphaBlend like this:

blendFn.BlendOp               = AC_SRC_OVER;
blendFn.BlendFlags            = 0;
blendFn.SourceConstantAlpha   = 255;
blendFn.AlphaFormat           = AC_SRC_OVER;

Now, to be honest, this is just a hack, but it does the trick for now, using ClearType for font rendering and even alpha transparency on the entire window. I was not able (at least not in my quick look at the code) to fix the code path that gets executed when you're using an image as the console background, since that actually does require full alpha-blending to render the right output.

So it's not a great fix, but it means I can use Console2 on my x64 box now, which is good enough for me at this point. YMMV.

Console 2.00.140

Link. August 23, 2008. Comments [1]. Posted in: Tools

I just noticed that Console 2.00b140 was recently released on its SourceForge site. Downloaded it and started running right away and it's working pretty well so far. I can't tell for sure yet, but it appears to be a bit faster than b139.

The new version seems to built using VC++ 9.0 (2008), but the download zip file comes with the runtime libraries if you need them.

Console is a most excellent utility that I use everyday. Highly recommended if you're not using it yet.

NTFS Junction Points

Link. July 7, 2008. Comments [0]. Posted in: Tools | Vista

I spent some time this weekend organizing a few files and source code repositories. As part of this process, I wanted to take advantage of NTFS hard-links and junction points, both of which are supported on Windows Server 2003/8 and Vista.

I had no problems with hard-links at all. I'm using the ln.exe tool from http://www.flexhex.com/docs/articles/hard-links.phtml to create them, and it worked great right from the start (I could also use the "fsutil hardlink create" command).

Junction points, however, gave me quite a bit more trouble. I've used Junction points in the past very successfully. I work with some code bases that for many reasons expect to have certain directories in the C:\ drive, but I keep all my code in the E:\ drive.

For this I've used cross-drive junction points to have the folder in C:\ point to the real folder in E:\ and it's worked great for a couple of years. One other tool I've used for this sometimes is Junction Link Magic.

Yesterday, however, I discovered that on Windows Server 2003, if the junction folder was on the same drive as the target folder, it just wouldn't work correctly. I could create the junction just fine, and I could even see the contents of the directory through the junction using explorer, cmd.exe or PowerShell.

Actually trying to access any of the children through the junction would result in the error:

The filename, directory name, or volume label syntax is incorrect.

I tried both of the tools I mentioned before, and it just wouldn't work. I tried creating the junctions from WinServer2K8 (where they worked perfectly) and then using the drive from 2003, and it still wouldn't work. This was easy to test, by the way, since this is a VHD image I share between several virtual machines.

Eventually, fellow MVP Juan T. Libre insisted I tried the linkd.exe tool in the Windows Server 2003 Resource Kit. I was reluctant to it since the other tools could create working cross-drive junctions and I was starting to suspect an OS limitation, but I gave it a go.

Much to my surprised, linkd.exe was able to create working same-drive junction points on Windows Server 2003. My guess is that there's some (probably undocumented) detail about how the APIs need to be called that can affect whether this works correctly or not.

Looking at the junctions using the "fsutil reparsepoint query" command clearly shows that the Reparse Data is slightly different between cross and same drive junctions, but not sure what it means from the API point of view. Just something to watch out for.

The lesson: Use linkd.exe on Windows Server 2003 to create same-drive junctions.

Enabling Font Smoothing on NetBeans

Link. May 26, 2008. Comments [1]. Posted in: Tools

I've been working on some Java stuff lately and instead of using Eclipse as I usually do, I started working with NetBeans 6.1. It works reasonably well (much more than I expected).

However, I run into one really annoying issue: NetBeans looked great on my Ubuntu box; but when I tried running it in my Windows machine, it looked like crap. More specifically, fonts on the text editor surface were rendered without anti-aliasing so they looked horribly wrong.

I remembered then that NetBeans is a Swing app, which, until fairly recently, didn't even support using the platform's built-in sub-pixel rendering technologies (like ClearType on windows). On Java 1.5 (which I was using), however, it should support at least it's own smoothing mechanisms and those were not getting used at all on Windows.

A few searches on google turned up lots of people complaining about it and a few people saying it could be enabled (or would be fixed on Java 1.6) but no clear hints as to where to locate the actual option.

NetbeansOptions

After looking for a while finally figured out: You can enable font smoothing by going to the Tools -> Options dialog, then clicking on the Advanced Options button on the bottom left, and then selecting the Editor Settings category in the new dialog. There you'll find the elusive "Text Antialiasing" option.

I'm not sure why this was enabled by default on Linux but not on Windows, but, anyway, enabling it makes all the difference in the world.

One more thing to keep in mind: The way java renders fonts is a bit weird as well. I'm using DejaVu Sans Mono for the font and I need to use size 20 on NetBeans to get it to look around the same size of the size 15 I use on Vim (both on Windows and Linux).

Sharing dotfiles between Windows and Ubuntu

Link. May 9, 2008. Comments [1]. Posted in: Tools | Vim

I have several configuration files I keep on my home folder for several applications, most of which is what in Unix-speak is usually known as "dotfiles". This includes things like my VIM configuration and runtime files, my Unix and PowerShell profile scripts and so on.

Naturally, I want these to be available on all of my machines, and synchronizing them manually has always been a drag, but so far, I had not really looked too hard at how to avoid it.

The most natural way to do this was, of course, source control, which I wanted to have anyway. It was easy enough to use SVN or GIT for this, but one thing had prevented me from going this way: File name conventions.

A few weeks ago I ranted about how some cross-platform applications would use a different set of file/folder names when running on windows instead of Unix, and how this was a nasty legacy coming from the old FAT/FAT32 days, but was not so much of a problem with NTFS.

There was a point to that rant, very related to today's post: What prevented me from using simple source control to share my dotfiles between my Windows machines and my Ubuntu machines was exactly this issue with the renamed dotfiles.

In particular, one of the things that constantly nagged me was having to rename my _vimrc and vimfiles/ directories from Windows to .vimrc and .vim/ when synchronizing them to the Ubuntu machines. It was a royal pain, and one that source control wouldn't solve at all.

Fortunately, turns out there's an easy way to avoid this with GVim on Windows, so that I could use .vimrc and .vim/ there as well:

  1. It appears that .vimrc is natively supported in modern VIM versions. I don't know when this came to happen, but I just renamed my _vimrc to .vimrc and it just worked. Pure goodness.
  2. Renaming vimfiles/ to .vim didn't work right out. But, fortunately, you can change the set of folders that VIM will look into when loading runtime files by modifying the runtimepath option. So I just added this right at the top of my .vimrc file:
set runtimepath=~/.vim,$VIMRUNTIME,~/.vim/after

Restarted VIM, and it just worked. Fantastic! I'm now simply using git to keep my dotfiles in source control and synchronizing them between machines is simply a matter of doing git pull/push every once in a while. Very nice.

Syndicate

About

Tomas Restrepo is a software developer located in Colombia, South America. His interests include .NET, Connected Systems, PowerShell and lately dynamic programming languages. More...

tomasrestrepo @ twitter My Flickr photostream My saved links on delicious My Technorati Profile

email: tomas@winterdom.com
msn: tomasr@passport.com

View my profile on LinkedIn

MVP logo

Ads


Links

Categories

Statistics

Total Posts: 1032
This Year: 102
This Month: 1
This Week: 1
Comments: 801

Blogroll

Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 2.1.8139.823

Sign In