TweetFollow Us on Twitter

Print Incompatible
Volume Number:6
Issue Number:6
Column Tag:Resource Roundup

20 Steps to Printing Incompatibility

By Joel West, Palomar Software, Oceanside, CA

20 Steps to Printing Incompatibility

Incompatible printing code. Based on what I’ve seen, this a popular pastime among Macintosh software developers.

First, some background. I’d like to apologize to MacTutor readers for the long delay between articles. Things were pretty busy in 1988 as we worked on our printer drivers, culminating in the January announcement at Macworld Expo of drivers we developed for the HP PaintJet and the Howtek PixelMaster.

For an application writer, the two drivers represent two more examples of output devices to be compatible with. The PaintJet 1.0 supports 2, 8, and 256 (fixed) colors with bitmap fonts, while the PixelMaster 1.0 is an 8-color and 24-bit color driver with the Mirus/URW outline fonts.

There are many other Chooser-level printer drivers being offered out there. If you count just those drivers that are sold with a printer (see Table 1), the number has exploded from two years ago, when there were two Apple printers and no third-party solutions. There are many more (I’ve never been able to keep up) independent drivers, from companies like Phoenix (née Softstyle) and GDT.

Of course, it’s not possible for every application to test with every printer driver for incompatibilities, which brings me to one of the main points of this article.

Device Independence

Many programmers think you have to know what printer you’re sending to. Each printer has its own characteristics, the argument goes, and it’s important to optimize for those characteristics.

Nine times out of ten, that’s plain wrong. The Macintosh printing architecture is designed to be device-independent, and, though it has its weaknesses, in that regard it is pretty successful.

I’m certainly not part of a Thought Police that forbids you from such practices. It’s just that one of the largest areas of application/printing incompatibility comes from device-dependencies.

It’s particularly frustrating because these problems are almost always unnecessary. Perfectly good driver-independent solutions are available for rotated text, smoothed polygons, custom line layout, determining paper size, and other problems described later on.

And there is no question that the problems introduced by such device-dependencies, on the balance, outweigh the benefits of same.

Read the Documentation

The second easy way to avoid problems is to restudy the documentation, beginning with the “Printing Manager” chapters of Inside Macintosh. Too many people don’t even understand these basics, as evidenced by some of the problems below.

A sample printing loop is shown in Example 1. Using such a loop (or something very similar) will, unfortunately, rule out at least five of the incompatibility opportunities below.

When doing your basic research, don’t forget that the rules have changed over the years.

There’s PrGeneral functionality in Inside Macintosh, Volume V. Among the tech notes, I’d recommend #92, 118, 125, 149, 161 and 192 for compatibility, and #72, 73 ,91 and 95 for extra functionality.

There are many applications that want to get the printing code to do something that is not in the published interfaces. I understand this problem well and am certainly sympathetic; perhaps three years ago I got into this debate on Usenet, arguing the plight of the application developer. One of the examples I used was for a painting program to set the Imagewriter (or other drivers) to “square pixels” or the equivalent.

Unfortunately, if you’re not following the documented interfaces, how can you pull it off? Usually the answer is trial and error iteration. It may work with the two drivers you try, but there will be 10 or 20 more that do don’t try, and many of these will break.

Today, one of the better solutions is to provide preformatted stationery with configured print records for specific printer drivers. Another approach would be to allow the user to set a default print record once, and then use that print record from then on out.

If you’re not sure your approach is compatible, I’m sure ZZ or Luke at tech support would be glad to offer advice on a specific trick or approach. As always, link to MacDTS.

20 Easy Steps

However, you may decide that you really want printer incompatibilities. Perhaps you’re trying to sell a particular brand of printer. Or maybe you need a crisis to convince management to hire a large tech support staff.

Or maybe if your sales are poor enough, your publisher will go bankrupt and you can reclaim your copyright to market a better version of your application.

Based on Palomar’s research, and with assistance from other driver writers, we’ve found that such incompatibility is very easy for you to achieve.

To make things more complete, I’ve decided to mention specific examples where I had them. This is not to reward these particular programmers or companies, but just note the ones that happen to be on my list.

To my knowledge, all of these problems are known to the application developer and most are either fixed in later releases, or in the process of being fixed.

The list is heavily skewed to the major applications, because those are the ones Palomar tests with most extensively. This doesn’t mean that these applications are more successful in obtaining incompatibility; nay, we expect that there are many more unheralded applications on the second 50 of a top 100 list that are equally worthy.

Finally, in defense of my fellow programmers, it should be noted that the Macintosh printer architecture has evolved in a somewhat ad hoc fashion since the Imagewriter was introduced in 1984. As such, most of the decisions listed below reflect reasonable guesses based on an incomplete specification; many would qualify as outdated assumptions more than deliberate perversions.

With that, let’s get on to the list of easy incompatibilities.

1. Assume only two printers

Example: FullPaint

To my knowledge, only one application checks the wDev field and puts up the alert “could not find the print driver.” This unique code looks something like this:

/* 1 */

if (wDev>>8 == bDevLaser)
{/* print one way */
}
else if (wDev>>8 == bDevCItoh)
{/* print another */
}
else
{Alert(ALRT_YouLoseSucka, NULL);
}

However, many (usually older) applications have code that looks like:

if (wDev>>8 == bDevLaser)
{/* do nice printing */
}
else
{/* do cruddy 144 dpi printing */
}

There have been more than 20 different printer drivers allocated a distinct wDev value. Just because it isn’t a LaserWriter, doesn’t mean that it will produce cruddy output.

2. Special case on printers

Example: Digital Darkroom 1.0, XPress 2.0

This is slightly more subtle than the previous approach, and offers many opportunities for incompatibilities:

1. If new printers are introduced, you get lousy results with them.

2. If existing drivers are improved, you get the same results as with the old driver.

3. If the implementation of the driver changes, you will likely break if you use device-specific information (such as the layout of the print record).

There is one common special casing that has produced less incompatibilities than most:

/* 2 */

if (wDevv>>8 == bDevLaser)
{/* send PostScript stuff */
}
else
{/* send QuickDraw stuff */
}

However, this will cause problems with a save-now, print-later utility like Glue or OpenIt.

Many, many applications go well beyond this PostScript/non-PostScript distinction to achieve printing incompatibility. They use all sorts of intimate details about the driver, what comments its supports, etc., etc. In several leading applications, the author has gone to the trouble of building tables with device-specific information so all sorts of things will be handled differently.

As will be examined below, in most cases there are other ways to accomplish the same thing. For example, you can special case the paper size based on the wDev (incompatible) or read the prInfo.rPage and rPaper fields of the print record (compatible).

For many applications, this is the preferred approach to printing incompatibility. I’ve picked Digital Darkroom because the incompatible and compatible approaches are about the same difficulty.

In particular, DD has a better halftoning mechanism that it only makes available to the LaserWriter, LaserWriter SC, and GCC PLP. This means that any other high-resolution black & white printer is out of luck.

One better approach would be to always make this advanced halftone available. A second, more restrictive approach, would be to pick a threshold resolution, (say 220 or 300 dpi), and if a PrGeneral()/getRsl call returns the maximum or device resolution as higher than that, then make the option available.

3. Bypass printer dialogs

Examples: HyperCard 1.2, MPW 3.0

This is the last of the items that every printer driver writer mentions.

It is the bane of our existence, because every time we add functionality to a driver, the application takes it away (or makes it difficult to find). Many printers have a print quality selection, or paper feed option; some have a spool for later printing options; our drivers include a preview before printing options. Try addressing a fax without the fax dialog some time.

HyperCard and MPW are two applications that do not show the job dialog for the “Print” command.

I should also note that Word 3.0 makes it a challenge to get at the dialogs (something that is fixed in 4.0.) PageMaker 3.0 has a non-standard interface that only gives you the style (“Page Setup”) dialog after you select printing.

From a personal standpoint, I find the hierarchical menus in Cricket Presents 2.0 to be somewhat frustrating and confusing. On the other hand, I’ve long bitched that MORE 1.0 should print bullet charts in landscape and outline views of the same document in portrait, so I guess Cricket has a creative (if unusual) way to provide needed functionality.

4. Spool-a-page, print-a-page

Example: MacWrite 5.0, XPress 2.0

Once upon a time, people tried to print large files from floppy-based systems. Thus, some applications would submit print jobs to the printer one page at a time.

This is no longer necessary, but it does achieve incompatibility by defeating the functionality of many printer drivers. As noted in Macintosh Technical Note #125 this is a good way, for example, to confuse print spoolers.

The counter approach is for the driver to lie and always claim it is “draft” printing. Unfortunately, this reduces the performance of more normal applications, which may not be expecting to free much memory for draft printing.

5. Directly change GrafPort fields

Example: SuperPaint 1.0, FullWrite 1.0

There are several reasons why this is a great way to achieve incompatibility just on general principles.

But we found that when you supply a CGrafPort for color printing to an application, there are a few “bit bashers” that provide frequent introduction to “la bomba.”

For example, if you directly change grafptr>bkPat (as does SuperPaint 1.0) then, on a CGrafPort, you are clobbering the cgrafptr>bkPixPat handle. If the address is weird enough, like 0xFFFFFFFF (can you say “black”), you will get a bus error.

Those GrafPort fields that are used for other fields in a CGrafPort include:

portBits
bkPat
fillPat
pnPat

Change any of these directly and you’re almost certain to achieve that desired level of incompatibility.

The bottom line to achieving incompatibility is to make sure your field manipulation will be invalid on either a GrafPort, Color QuickDraw CGrafPort , or a 32-Bit QuickDraw CGrafPort. The 6.0 LaserWriter driver is one way to test this, as are various drivers from Tek, Palomar and the film recorder companies.

6. Send bitmaps instead of text

Example: CricketDraw 1.1, FreeHand 1.0, HyperCard 1.2

This one actually is more work than working compatibly. After all, the Font Manager knows how to draw text, if you just use DrawText() and DrawString() instead of CopyBits().

Also, no one is going to do this on the LaserWriter - every customer will notice it immediately - so you must special case out this approach on the LaserWriter. Thus, it’s even more work to do CopyBits() for just the other printers.

My favorite example is the Cricket Expressions drivers with built-in URW outline fonts. Because CricketDraw sends only bitmaps, those fonts are not available and you get those lovely low-res bitmaps.

This one is a real opportunity to put your worst foot forward. Can you imagine how lousy 72 dpi text looks on a 4,000-line film recorder or 300 dpi printer? Can you imagine any serious business professional using your application on such an output device? Your place in incompatibility heaven is assured.

7. Send bitmaps instead of rotated text

Example: MacDraw II 1.0

In this case, it’s easier to be incompatible than compatible, but it’s not strictly necessary.

The original designers of MacDraw (1.9) came up with a clever way of hiding both the bitmap and text representations of rotated text. This means that a smart printer driver (e.g., the LaserWriter) can get at the actual text and its angle, while a dumb printer driver (e.g., ImageWriter 2.7) will automatically print the bitmap representation.

The compatible way is to use the picTextBegin and picTextEnd comments, as documented by Macintosh Technical Note #91.

How does this work? You send both the bitmap and text representations, using an empty clipping rectangle to “hide” the text from any dumb printer drivers, as below:

/* 3 */

PicComment(picTextBegin, begh);
PicComment(picTextCenter, ctrh);
GetClip(saveclip);
ClipRect(gZeroRect);
DrawString (theText);
SetClip(saveclip);
CopyBits(theBits);
PicComment (picTextBegin, NULL)

MacDraw 1.9.5 did it this way, but the MacDraw II assumed that any printer that’s not a LaserWriter is brain-dead. However, the good folks at Claris don’t seem to appreciate incompatibilities, so it’s back to the compatible approach with MacDraw II 1.1.

8. Smooth polygons instead of comment

Example: FullWrite 1.0, MacDraw II 1.0

Again, the incompatible way is much easier, but there is a clever MacDraw/LaserWriter convention for compatibility with all drivers.

The approach is very similar to the rotated text case: you can provide both types of information and let the driver decide.

One piece of information is the smoothed polygon decomposed into individual line segments at a specific resolution. The other is the set of original inflection points, so that the polygon can be re-rendered at any resolution.

9. Send bitmaps instead of objects

Example: Excel 1.5

The final example along these lines is sending screen-resolution bitmap shapes instead of their QuickDraw equivalents.

This is a great way, for example, to avoid drawing a circle marker on a line plot at the actual resolution of the printer. You can output a 72 dpi bitmap instead of a 300 dpi shape, thus helping the user to conclude that $6,000 on a laser printer was money down the drain.

10. Secretly do own line layout

Example: ReadySetGo 4.5, PageMaker 3.0

Some applications want to do their own line layout. There are certainly good reasons to do that, although I would hope someday to have a standard system routine to handle this the same way for every application and printer driver

The incompatibility opportunity is to do your own line layout secretly. Don’t send a picLineLayoutOff comment (#155), as described by Macintosh Technical Note #91. Then your application can fight the printer driver for control of the text placement.

11. Assume paper size

Example: PowerPoint 2.0, MacWrite 4.1

There are lots of assumptions that can be made about “paper” size, many of them offering incompatibilities.

PowerPoint assumes that the top and bottom margins are the same, so it centers things within the imageable area. If the printer has a larger top or left margin, then the output will not be centered on the physical page.

The original MacWrite assumed that a piece of paper could not be wider than, say, 8" or so. This achieves incompatibility many oddball choices, such as printing in landscape mode.

12. Use large drawing coordinates

Example: Studio Session

QuickDraw helps with this incompatibility, since it limits drawing coordinates to 16 bits, or ±32,767. But it does take a little unusual cleverness to find this one.

Suppose you’re drawing a horizontal line on a page of a 300 dpi QuickDraw printer. You could draw from (72,0) to (72,576), say, to draw an 8" line. When scaled up to 300 dpi resolution, this maps to (300,0) to (300,2400).

Of course, you could also draw the same line as (72,0) to (72,28800). After all, everything outside the page will get clipped, right?

At 300 dpi, this gets scaled to (300,0) to (300,120000). Since 16 bits won’t hold the latter coordinate, you get (300,11072), and your line magically disappears! Neat, huh?

13. Hog or fragment memory

Example: Excel 1.5

Excel has its own unusual memory management; others may also be unusual, but none so among the Top 10 best-sellers.

The current Excel asks for a large amount of nonrelocatable memory, not leaving much memory available for the printer driver. This is the single reason many printer drivers are aggressive about demanding memory from an application.

Taking lots of memory, or allocating large nonrelocatable blocks are reasonable ways to achieve printing incompatibility.

At the same time, the driver may create fragmentation problems for your application that also show up for incompatibilities.

If you want to be incompatible, then assume that SetPtrSize() will always work on a nonrelocatable block. It will often fail due to heap fragmentation, such as a call to MoreMasters() during printing or even an open desk accessory.

If SetPtrSize() does fail, you could instead allocate a new nonrelocatable block and then BlockMove() the data over.

14. Barf when memory stolen

Example: Full Impact 1.0

Nowadays, drivers that use QuickDraw imaging require lots of memory. At 300 dpi, a black & white 8" by 10" page requires 879K, while 240 dpi x 8" x 10" by 24 bits of color requires 13 Mb. And, of course, outline fonts require lots of code, temporary memory and decent caches for adequate performance.

With some the memory management scheme of some applications, such a driver/application combinations produces wonderful incompatibilities.

They may very well push your grow zone procedure and request more memory than currently available in the heap, particularly in light of item 13 above.

For a draft-mode printer, this may come at the time of PrClosePage() or PrCloseDoc(). For a spool-mode printer, this normally comes at the time of PrPicFile().

Delightfully, some applications immediately panic if their grow zone procedure is called. Many are following the advice from page 64 of the first edition of How to Write Macintosh Software says that

In the worst case, when your grow zone gets a memory request that you can’t fulfill, even by eliminating the monitor object, you should force the user to save any work in memory and then quit the application.

Since Scott Knaster never articulated a goal of printing incompatibility, it may be assumed that this is an outdated approach to compatibility rather than part of a deliberate incompatibility strategy.

If you’re not after incompatibility, then a reasonable algorithm to use is the following:

1. Stash some memory for later use by the grow zone.

2. If the grow zone is asked for memory during printing, give it up; if you can’t satisfy the request, just say “no” (i.e., return a size of 0).

3. At the end of the printing loop, try to reallocate the memory reserve.

4. If you then have no reserve, complain and quit.

15. PrOpen() at beginning of application

Example: MacDraw 1.9.5

This historically correct approach is now a great way to achieve incompatibility. In particular, it causes nifty problems with the Chooser and MultiFinder.

If you’re trying to be boring and compatible, then do your PrOpen()/PrClose() around each group of printing calls, as shown in the example and recommended by Macintosh Technical Note #161 .

16. Change print record directly

Example: PixelPaint 1.1

The print record structure is fairly well-documented and well-hacked. (I should know: I contributed to the documentation with by March 1987 “Printer Sleuthing” article.)

However, every driver treats these fields slightly differently, offering many opportunities for incompatibilities. A trick that will fool one driver may break another.

The one I found most effective was in the original Pixel Paint, which (as with some other incompatibilities) forces print record values to fix one bug in one version of a printer driver. The end result was to prevent landscape printing for most drivers.

Many applications obtain incompatibility by forcing paper sizes directly by changing the print record. This is usually quite effective, because you usually don’t know what you’re doing, and the driver won’t either.

17. Send fake handles

By “fake” handle, I mean a pointer to another pointer that is not a master pointer.

I don’t have the specific application example in front of me, but this is just as useful with the Printing Manager and printer drivers as it is with the entire Toolbox. Such a synthetic handle will effectively confuse the Memory Manager if the printer driver should be so foolish as to pass it to the Memory Manager.

Macintosh Technical Note #117 gives you lots of great ideas on how to do this and why this works.

18. Don’t call PrPicFile

For this one I don’t have the application either; however, it’s very easy to explain.

The standard print loop includes a check for spool-mode printing:

/* 4 */

PrCloseDoc(myprport);
if ((**ph).PrJob.bJDocLoop ==
 bSpoolLoop && PrError()== noErr)
{GetRidOfLotsMoreMemory();
 PrPicFile(ph, NULL, NULL, NULL, status);
};

For some reason, some applications achieve incompatibility by not calling PrPicFile() all the time. This is, after all, a needless step for the LaserWriter and other draft-mode printers.

If you don’t call PrPicFile(), then no output will be produced; the effect can be quite mystifying and is usually good for one phone call per customer.

19. Ignore printing errors

Example: Reflections, Cricket Presents 2.0

If you want your program to halt and crash unpredictably, you can just blindly ignore Memory Manager and Resource Manager errors. Similarly, printing incompatibility can be achieved by ignoring printing errors.

There are many different places that an error can occur during printing, such that a compatible program would call PrError() after every Printing Manager call.

The most common errors an application will see are:

128 iPrAbort user cancelled printing

-27 iIOAbort cancelled after printer not responding

-108 iMemFullErr not enough memory to print

There are several other errors you can get. For example, many File Manager errors are possible while spooling to disk.

Cricket Presents is very creative in using this to achieve incompatibility: it crashes if the disk fills up when spooling to disk. Cancelling or other errors returned by PrPicFile() are just fine.

One error you probably won’t see is iIOAbort, since the printer driver resets iIOAbort to noErr after PrPicFile(). This means that if you try to decode error messages before the end of the printing loop, you’ll have the opportunity to display a few spurious error messages.

20. Ignore page number selection

Example: Persuasion 1.0

The original Inside Macintosh explains the standard suboptimization for imaging only those pages that are necessary. As explained on page II-156, look at the page numbers in the print record, pass only those to the printer driver, and convince the driver to print all the pages you pass it.

Almost all of the commercial applications do this. For example, this approach is built into MacApp.

What are the incompatibility opportunities here? Your application may end up imaging 20 or 30 complex pages in order to print just one. Not only can you tax the patience of the poor saps who bought your software, but you can also fill up their hard disk, preventing them from running it at all if they don’t own a brand-new 80 Mb drive.

Credits and Disclaimer

I’ll take the blame for divulging secrets but I can’t take all the credit for finding problems.

The rest of the development team at Palomar deserves credit for much of what we found: Neil Rhodes, Mark Anderson, Michael Phil Ogawa and Marshall Clow. Our testing expert, Julie McKeehan, found many of the problems for the first time.

The folks at HP did a lot of pounding, too. Although full names are not HP policy, credit goes to Bill, Terri, Cindi, Bob, Robin, Dave and Marty, among others.

There are quite a few other driver writers out there who helped me, but they seemed less interested than I in awarding examples of incompatibility, probably because some dunderhead managers at the various application houses won’t realize that this whole article was a tongue-in-cheek look at a serious problem. So to Scott, Mark, Jacques and Seth, thank you for your support - and refer any irate calls to me when this hits the stands.

Example 1: Standard printing loop
PrOpen();
err = DoPrinting(docprinthand);
PrClose();
...
OSErr DoPrinting(THPrint ph)
{Integer firstpage,lastpage,numpages;
 Boolean isspool;
 GrafPtr saveport;

if (!PrJobDialog(printh)) return kDidNotPrint;

GetPort(&saveport);
/* Suboptimize page nos. */
firstpage = (**ph).PrJob.iFstPage;
lastpage = (**ph).PrJob.iLstPage;
numpages = lastpage - firstpage + 1;
/* fool printer driver */
(**ph).PrJob.iFstPage = 1;
(**ph).PrJob.iLstPage = numpages;

isspool = (**ph).PrJob.bJDocLoop == bSpoolLoop;
if (isspool) numpasses = 1
else numpasses = (**ph).PrJob.iCopies;

FreeUpSomeMemory();
myprport = PrOpenDoc(ph, NULL, NULL);
for (copyno=1; copyno<numpasses; copyno++)
 for (pageno=firstpage;
 pageno<lastpage && PrError()==noErr;
 pageno++);
 { PrOpenPage(myprport, NIL);
 If (PrError() == noErr)
 DrawAPage(pageno);
 PrClosePage(myprport);
 }; /*each page*/
PrCloseDoc(myprport);
 
/* Now print spooled document */
if (isspool && PrError()== noErr)
{GetRidOfLotsMoreMemory();
 PrPicFile(ph, NULL, NULL, NULL, status);
};

SetPort(saveport);
TakeBackSomeMemory();
/* Now see if there were any errors */
errno = PrError();
if ((errno <> noErr) &&
 (errno <> iPrAbort)) /* ignore command-period */
{CallErrorHandler(errno);
 return errno;
}
else
 return noErr;
}

Manufacturer Printer

Apple AppleFax

Apple ImageWriter LQ

Apple ImageWriter

Apple LaserWriter II SC

Apple LaserWriterÝ

GCC PLP

GCC WriteMove

Hewlett-Packard PaintJet

Howtek PixelMaster

Mirus FilmPrinter

Presentation Tech. Montage FR1

Tektronix 4693D

Tektronix ColorQuick

Ý Many other PostScript® devices are also supported by this driver.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Yasu 4.0.0 β - System maintenance app; p...
Yasu was created with System Administrators who service large groups of workstations in mind, Yasu (Yet Another System Utility) was made to do a specific group of maintenance tasks quickly within a... Read more
Skype 7.37.0.178 - Voice-over-internet p...
Skype allows you to talk to friends, family and co-workers across the Internet without the inconvenience of long distance telephone charges. Using peer-to-peer data transmission technology, Skype... Read more
EtreCheck 3.0.5 - For troubleshooting yo...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
Amadeus Pro 2.3.1 - Multitrack sound rec...
Amadeus Pro lets you use your Mac computer for any audio-related task, such as live audio recording, digitizing tapes and records, converting between a variety of sound formats, etc. Thanks to its... Read more
NeoFinder 6.9.3 - Catalog your external...
NeoFinder (formerly CDFinder) rapidly organizes your data, either on external or internal disks, or any other volumes. It catalogs all your data, so you stay in control of your data archive or disk... Read more
WhatsApp 0.2.1880 - Desktop client for W...
WhatsApp is the desktop client for WhatsApp Messenger, a cross-platform mobile messaging app which allows you to exchange messages without having to pay for SMS. WhatsApp Messenger is available for... Read more
Hazel 4.0.6 - Create rules for organizin...
Hazel is your personal housekeeper, organizing and cleaning folders based on rules you define. Hazel can also manage your trash and uninstall your applications. Organize your files using a familiar... Read more
Apple iBooks Author 2.5 - Create and pub...
Apple iBooks Author helps you create and publish amazing Multi-Touch books for iPad. Now anyone can create stunning iBooks textbooks, cookbooks, history books, picture books, and more for iPad. All... Read more
MYStuff Pro 2.0.26 - $39.99
MYStuff Pro is the most flexible way to create detail-rich inventories for your home or small business. Add items to MYStuff by dragging and dropping existing information, uploading new images, or... Read more
MarsEdit 3.7.8 - Quick and convenient bl...
MarsEdit is a blog editor for OS X that makes editing your blog like writing email, with spell-checking, drafts, multiple windows, and even AppleScript support. It works with with most blog services... Read more

How to get past Vulture Island's tr...
Vulture Island is a colorful and quirky mish-mash of platforming and puzzles. It’s creative and fresh, but sometimes the game can throw a curveball at you, leaving you stuck as to how you should progress. These tips will help you explore smoothly... | Read more »
The new Clash of Kings is just for Weste...
If you’ve played the original Clash of Kings, you’ll probably recognise the city building, alliance forging and strategic battles in Clash of Kings: The West. What sets this version apart is that it’s tailor made for a Western audience and the... | Read more »
Frost - Survival card game (Games)
Frost - Survival card game 1.12.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.12.1 (iTunes) Description: *Warning: the game will work on iPhone 5C and above and iPad Pro / 4. Other devices are not supported* | Read more »
How to build and care for your team in D...
Before you hit the trail and become a dog sledding legend, there’s actually a fair bit of prep work to be done. In Dog Sled Saga, you’re not only racing, you’re also building and caring for a team of furry friends. There’s a lot to consider—... | Read more »
How to win every race in Dog Sled Saga
If I had to guess, I’d say Dog Sled Saga is the most adorable racing game on the App Store right now. It’s a dog sled racing sim full of adorable, loyal puppies. Just look at those fluffy little tails wagging. Behind that cute, pixelated facade is... | Read more »
Let the war games commence in Gunship Ba...
Buzz Lightyear famously said, “This isn’t flying, this is falling – with style!” In the case of Gunship Battle: Second War, though, this really is flying - with style! The flight simulator app from Joycity puts you in control of 20 faithfully... | Read more »
How to get a high score in Fired Up
Fired Up is Noodlecake Games’ high score chasing, firefighting adventure. You take control of a wayward firefighter who propels himself up the side of a highrise with blasts of water. Sound silly? It is. It’s also pretty difficult. You can’t... | Read more »
NBA 2K17 (Games)
NBA 2K17 1.0 Device: iOS iPhone Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: Following the record-breaking launch of NBA 2K16, the NBA 2K franchise continues to stake its claim as the most authentic sports video... | Read more »
Dog Sled Saga (Games)
Dog Sled Saga 1.0.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.1 (iTunes) Description: A game by Dan + Lisa As a rookie musher, foster a dogsledding team whose skills will grow if they're treated right. Week by... | Read more »
60 Seconds! Atomic Adventure (Games)
60 Seconds! Atomic Adventure 1.2 Device: iOS Universal Category: Games Price: $2.99, Version: 1.2 (iTunes) Description: 60 Seconds! is a dark comedy atomic adventure of scavenge and survival. Collect supplies and rescue your family... | Read more »

Price Scanner via MacPrices.net

21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $120 off MSRP including free shipping plus NY sales tax only: - 21″ 3.1GHz iMac 4K: $1379 $120 off MSRP - 21″ 2.8GHz iMac: $1199.99 $100 off MSRP - 21″ 1... Read more
13-inch 2.7GHz/256GB Retina MacBook Pro on sa...
Amazon.com has the 13″ 2.7GHz/256GB Retina Apple MacBook Pro on sale for $151 off MSRP including free shipping: - 13″ 2.7GHz/256GB Retina MacBook Pro (sku MF840LL/A): $1348 $151 off MSRP Read more
Apple TVs on sale for up to $50 off MSRP
Best Buy has 32GB and 64GB Apple TVs on sale for $40-$50 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Sale prices for online orders only, in-store... Read more
Apple refurbished 13-inch Retina MacBook Pros...
Apple has Certified Refurbished 13″ Retina MacBook Pros available for up to $270 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 13″ 2.7GHz... Read more
Duplicate Sweeper Free On Mac App Store For O...
To celebrate the launch of Apple’s latest macOS Sierra, Stafford, United Kingdom based Wide Angle Software has announced that its duplicate file finder software, Duplicate Sweeper, is now available... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has 13″ Retina Apple MacBook Pros on sale for up to $150 off MSRP. Shipping is free, and B&H charges NY tax only: - 13″ 2.7GHz/128GB Retina MacBook Pro: $1174.99 $125 off MSRP - 13... Read more
Evidence Surfaces Pointing To New A10X Chip F...
Citing a job description for a Project Lead position at Apple’s Austin, Texas engineering labs, Motley Fool’s Ashraf Eassa deduces that development is progressing well on Apple’s next-generation in-... Read more
Check Print’R for macOS Allows Anyone to Easi...
Delaware-based Match Software has announced the release and immediate availability of Check Print’R 3.21, an important update to their easy-to-use check printing application for macOS. Check Print’R... Read more
Apple refurbished 11-inch MacBook Airs availa...
Apple has Certified Refurbished 11″ MacBook Airs (the latest models), available for up to $170 off the cost of new models. An Apple one-year warranty is included with each MacBook, and shipping is... Read more
Apple refurbished 15-inch Retina MacBook Pros...
Apple has Certified Refurbished 2015 15″ Retina MacBook Pros available for up to $380 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 15″ 2... Read more

Jobs Board

Sr. *Apple* Mac Engineer - Net2Source Inc....
…staffing, training and technology. We have following position open with our client. Sr. Apple Mac Engineer6+ Months CTH Start date : 19th Sept Travelling Job If Read more
*Apple* Retail - Multiple Positions-Norfolk,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Restaurant Manager (Neighborhood Captain) - A...
…in every aspect of daily operation. WHY YOU'LL LIKE IT: You'll be the Big Apple . You'll solve problems. You'll get to show your ability to handle the stress and Read more
Lead *Apple* Solutions Consultant - Apple (...
# Lead Apple Solutions Consultant Job Number: 51829230 Detroit, Michigan, United States Posted: Sep. 19, 2016 Weekly Hours: 40.00 **Job Summary** The Lead ASC is an Read more
US- *Apple* Store Leader Program - Apple (Un...
…Summary Learn and grow as you explore the art of leadership at the Apple Store. You'll master our retail business inside and out through training, hands-on Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.