Running an Apple 27″ LED Cinema Display on a standard PC

Posted by Ryan Uber | Gadgets,Hardware | Wednesday 23 November 2011 11:03 pm

During a trip to the local computer store, found myself walking through the Apple section. Normally I won’t be found in there as I generally run Linux for just about everything (desktop, server), but this time, the LED Cinema displays really caught my eye. Such a beautiful display, so bright and crisp, and so clean-looking. I had to have one for myself. (Of course I didn’t buy at the store. Ordered online and saved $100.)

Now then, first thing’s first: Connecting the thing to the PC. The Apple 27″ LED display that I purchased comes with *only* a mini displayport connection. No DVI, no HDMI. This actually didn’t bother me so much, since the mini displayport is present on a number of ATI cards. I set out to find a new graphics card. The first one I came across (and actually ended up purchasing alongside the monitor) was the Apple GeForce GT120. Yes, its an Apple product meant to be an upgrade to the Mac Pro’s from early 2009, but it was a PCI Express card, nothing out of the ordinary (probably just re-branded). Remembering back to my Hackintosh days, I figured that I probably had the best bet with this card. Apple makes it, so it should work right?

Wrong! While the DVI graphics worked just fine on an older monitor (Samsung P2350), the mini displayport would give me no video. I am guessing that Apple probes the card in some way that my PC does not. Also note, at this point I had still never seen the display even power on, since the new LED displays are controlled completely via the MDP, and thus there is not a single button on the entire monitor.

A little disgruntled, I removed the GT120 from my PC and moved on to the next solution: an ATI card with MDP. I found one at my local Fry’s Electronics, and ordered online for local pickup. It was the AMD HD 6870 XOC. All of the specifications looked correct on the site; 1x Dual-Link DVI, 1x Single-Link DVI, 1x HDMI, and 2x mini displayports. I picked the card up from the store and headed home for installation. To my surprise, when I pulled the card out of the box, it had 2x DVI ports and 1x displayport, not even a minidispalyport or any HDMI connections. It was identical to the item on the website in every other way, shape, and form, but the interface description on the left side of the box had a sticker over it with the downgraded specifications.

Needless to say, I had to return it. I didn’t want to run any displayport to mini-displayport adapters or any other nonsense like that.

I ended up finding the XFX version of the Radeon HD 6870 at MicroCenter for around the same price. This time I verified before walking out the door with the card.

While I was installing the card, I noticed the box sitting next to me mentioning the interface was PCI Express 2.1. I didn’t think anything of it, because I had done my homework beforehand and learned that any PCIE 2.1 card would work in a 2.0 slot.

To my surprise, after installing the card and connecting everything in my Gigabyte H55M-S2V, the card did not function at all! After further reading and research, I still did not find an answer as to why the card would not function in this particular motherboard. A BIOS update and still, nothing. Irritated and ready to just start using the darn monitor and stop fiddling with hardware, I went out and bought a new motherboard. My processor was LGA1156 based, so I had limited options. I ended up with an ASUS P7P55D-ELX. It had a few goodies that my old board didn’t, like 6GB/s SATA and USB 3.0. After further ripping apart/assembling my PC, I finally was able to boot up, and see the display work perfectly!

The BIOS POST showed up just fine, stretched to the size of the 2560×1440 native on the LED. Everything was all well and good. I did notice though, that the back light was looking pretty dim. I then realized that the factory default for the brightness setting is not set to the max, or even a reasonable brightness. It is in fact pretty dim, even with the ambient light detection/adjustment in the iSight. What I ended up doing to solve this was installing Windows 7, and on top of that, installing Boot Camp from a Snow Leopard DVD that I had. It is noteworthy though, that the version of Boot Camp that came on the Snow Leopard disk did not give me full access to the brightness control. Even with the slider all the way up to max, I still only had maybe 50% brightness. After running the Apple Software Update utility and getting the latest Boot Camp, and a subsequent reboot, I watched my Cinema Display come to life as I dragged the slider all the way up and the brightness began to burn my pupils!

After all of this fighting to get a Cinema Display to work sans the Mac, I would indeed say that it is worth it. After setting the brightness settings in Boot Camp, feel free to nuke your Windows installation and go back to using Ubuntu, Fedora, SuSE, or whatever it is you like using. The LED display will remember the settings internally and won’t need to set them again.

A note about the video card:
I found the XFX HD 6870 to be a bit noisy for my taste. Not overpowering noisy, but my tower sits right next to me on my desk and I don’t like the sound of fans for hours on end. Installing MSI Afterburner and setting an automatic fan profile like the following, the noise level is more than acceptable and the GPU remains relatively cool (~50-55C).

In conclusion: It is totally worth it. You should do it.

Word Wrapping in C

Posted by Ryan Uber | C Programming | Tuesday 22 November 2011 10:40 am

I recently ran into a situation where I needed to wrap text to a certain number of columns to support the standard 80×24 Linux console without making a complete mess of the screen. Since I found no standard way of doing this, I wrote this little function to handle it for me.

There are no dependencies on any external libraries. Pass in your storage, your string, and the number of columns to wrap to, and this will do the rest.

/*
 * This function will wrap large amounts of a text into a manageable and human-readable width
 * word by word. Just specify the number of columns you are working with and feed it a string,
 * and it will return a new string (including added line breaks) to accommodate the area you
 * are working with.
 *
 * {{{ proto( void ) wrap( char out, char str, int columns )
 */
void wrap( char *out, char *str, int columns )
{
    int len, n, w, wordlen=0, linepos=0, outlen=0;

    /*
     * Find length of string 'str' without using string.h
     */
    for( len=0; str[len]; ++len );

    /*
     * Allocate the full space of 'str' to 'word', so there is no possible way that the string
     * could contain a word that does not fit into the 'word' variable.
     */
    char word[len];

    /*
     * Loop through each individual character in the passed array (str) and detect white space
     * and word length to determine how to handle line wrapping.
     */
    for( n=0; n<=len; n++ )
    {
        /*
         * Detect spaces and newlines. We cannot gurantee that the passed string is null-
         * terminated, so we also need to handle cases where we reach the end of the string
         * without encountering wite space characters.
         */
        if( str[n] == ' ' || str[n] == '\n' || n == len )
        {
            /*
             * If the current word will not fit on the current line, add a newline.
             */
            if( linepos > columns )
            {
                out[outlen++] = '\n';
                linepos = wordlen;
            }

            /*
             * Append the found word to the output and reset the word character array in
             * preparation for accepting characters for the next word.
             */
            for( w=0; w<wordlen; w++ )
            {
                out[outlen++] = word[w];
                word[w] = '\0';
            }

            /*
             * If we reach the end of the string, add the null-terminator character.
             */
            if( n == len )
                out[outlen] = '\0';

            /*
             * If we encounter a newline character, append it to the string as usual, but
             * set the line position counter back to 0 (new line = start count from 0 again).
             */
            else if( str[n] == '\n' )
            {
                out[outlen] = str[n];
                linepos=0;
            }

            /*
             * If the word fits in the current line without trouble, just add the space.
             */
            else
            {
                out[outlen] = ' ';
                linepos++;
            }

            /*
             * Increment the final output length for the next loop, and set the word length
             * counter back to 0 (newline or space = new word).
             */
            outlen++;
            wordlen=0;
        }

        /*
         * If the current character is in the middle of a word somewhere, just append it and
         * move on, incrementing counters.
         */
        else
        {
            word[wordlen++] = str[n];
            linepos++;
        }
    }
}
/* }}} */

Examples

Wrap at 50 columns:

$ ./a.out
Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Maecenas pulvinar blandit diam nec mattis.
Sed a ipsum nec ante porttitor feugiat. Morbi
ipsum lacus, dignissim at bibendum in, consectetur
eget ipsum. Donec dolor nibh, scelerisque ac
sodales et, posuere ac nulla. Aliquam eget
tincidunt ante. Vestibulum justo leo, congue ut
luctus ut, venenatis non dui. Cras sapien risus,
blandit at semper eu, cursus eu est. In hac
habitasse platea dictumst. Fusce libero dolor,
commodo nec rhoncus eu, rutrum vel arcu. Vivamus
ultrices faucibus tellus ac feugiat. Ut imperdiet
metus sed erat feugiat sed porta lorem tristique.
Mauris quis erat vel ante cursus pretium.
Curabitur arcu erat, consequat ac ornare et,
venenatis eu diam.

Curabitur posuere dui vitae tortor cursus cursus.
Pellentesque adipiscing lobortis sem at varius.
Mauris pellentesque sollicitudin ultricies.
Maecenas in tellus turpis. Integer convallis
mollis elit eu placerat. Nunc volutpat consectetur
facilisis. Curabitur eros arcu, dapibus ut
convallis non, rhoncus non magna.

Wrap at 20 columns:

$ ./a.out
Lorem ipsum dolor
sit amet,
consectetur
adipiscing elit.
Maecenas pulvinar
blandit diam nec
mattis. Sed a ipsum
nec ante porttitor
feugiat. Morbi ipsum
lacus, dignissim at
bibendum in,
consectetur eget
ipsum. Donec dolor
nibh, scelerisque ac
sodales et, posuere
ac nulla. Aliquam
eget tincidunt ante.
Vestibulum justo
leo, congue ut
luctus ut, venenatis
non dui. Cras sapien
risus, blandit at
semper eu, cursus eu
est. In hac
habitasse platea
dictumst. Fusce
libero dolor,
commodo nec rhoncus
eu, rutrum vel arcu.
Vivamus ultrices
faucibus tellus ac
feugiat. Ut
imperdiet metus sed
erat feugiat sed
porta lorem
tristique. Mauris
quis erat vel ante
cursus pretium.
Curabitur arcu erat,
consequat ac ornare
et, venenatis eu
diam.

Curabitur posuere
dui vitae tortor
cursus cursus.
Pellentesque
adipiscing lobortis
sem at varius.
Mauris pellentesque
sollicitudin
ultricies. Maecenas
in tellus turpis.
Integer convallis
mollis elit eu
placerat. Nunc
volutpat consectetur
facilisis. Curabitur
eros arcu, dapibus
ut convallis non,
rhoncus non magna.

*Update 11/24/2011: This solution is useful if you need to word wrap inside of a C program. If you are shell scripting, you can use the “fold” command, which comes standard with the “coreutils” package in EL-based distributions.

Usage: fold [OPTION]... [FILE]...
Wrap input lines in each FILE (standard input by default), writing to
standard output.

Mandatory arguments to long options are mandatory for short options too.
  -b, --bytes         count bytes rather than columns
  -c, --characters    count characters rather than columns
  -s, --spaces        break at spaces
  -w, --width=WIDTH   use WIDTH columns instead of 80
      --help     display this help and exit
      --version  output version information and exit

Report bugs to <bug-coreutils@gnu.org>.