TweetFollow Us on Twitter

OS/2
Volume Number:4
Issue Number:12
Column Tag:Progràmmer's Forum

OS/2 Presentation Manager

By Dan Weston, Portland, OR

The Good, the Bad, and the Ugly: OS/2 Presentation Manager for Mac Programmers

by Dan Weston

Nerdworks, Portland, Oregon

The Presentation Manager (PM) is Microsoft’s and IBM’s answer to the Macintosh user interface toolbox. Due out in late 1988 with OS/2 version 1.1, PM provides a set of new operating system functions for application programmers that is somewhat similar to the functions supplied in the Macintosh ROM. OS/2 programmers can access these functions to create windows and menus, use the mouse, and do all the things that Mac programmers have been doing for over four years now. PM is directly descended from Microsoft Windows, so programmers familiar with Windows will have little trouble making the switch to PM, although their Windows application source code must be substantially modified to work with PM.

This article will attempt to explain the main features of PM in terms that Macintosh programmers should be familiar with. I know that many people in the Mac community look at OS/2 with deep suspicion, but even if you feel that way, read on, and you may find that there are things to appreciate in PM.

Events and Messages

The foundation of any Macintosh program is the event loop. The Macintosh operating system watches the outside world, including the mouse, keyboard, and disk drives, and signals the application whenever an event occurs. Macintosh programs are event driven.

In a PM program, messages take the place of events. When mouse and keyboard events take place, PM tells the application by sending messages to it. This is conceptually very similar to the Macintosh event loop, but PM has a much richer set of messages and has made the message architecture more general and extensible so that it is very easy for applications to create new message types.

Many of the messages have direct anologs in Mac event types, such as mouse button down and up messages (although there can be up to three mouse buttons), activation and update messages, and keyboard messages. Macintosh programmers familiar with event-driven application architecture will not find it too hard to make the adjustment to a message driven system.

Windows

The main components of a PM program are windows. The system provides many predefined window types, including frame windows, push buttons, radio buttons, menus, and title bars. The predefined window types are know as “window classes”. Each window class defines an object that enclose a set of functionality that is available to the programmer simply by sending messages to a window with that type.

The messages in a PM system are actually sent to an application’s windows rather than the application itself. Each window has an associated window procedure that receives messages from the system and other windows. For example, when the user presses the mouse button, the system sends a mouse button down message to the window that is underneath the mouse at the time of the event. The window then processes the mouse down message as it sees fit. Different types of windows respond differently.

A standard PM window, with title bar, size border, and scroll bars, is actually made up of several different predefined window types. The most basic is the frame window. On top of the frame window sits the other windows, such as the title bar window and the scroll bar windows, that gives the window its distinctive look. The frame window “owns” the other windows, called control windows, that sit on top of it. The ownership relationship is important since it allows the control windows to communicate with the frame window.

For example, the title bar window class responds to a mouse down event by tracking the mouse and allowing the user to drag an outline of the frame window around the screen to position it, just like on the Mac. The way this works is that the title bar window handles all the tracking and the display of the window outline. When the mouse up message comes to the title bar window, the title bar window sends a message to the frame window telling it the new position on the screen. The frame window then sends messages to all the windows that it owns telling them to redraw themselves at the new position.

Typically, a programmer writing a PM program creates at least one new window class to make a program. In the terminology of PM, this is the “client window”. A client window corresponds to the content area of a Macintosh window. The client window is also owned by the frame window. Its main responsibility is to display data for the user. So while frame windows and their constituent control windows behave the same in most programs, it is the client window which gives each application its visual personality.

The operating system takes care of routing messages to the appropriate window. An application programmer never sees events that are handled by other windows. For example, when a normal Mac program gets a mouse down event, it must call FindWindow to determine what part of the window received the click and branch accordingly. In a PM program, the application programmer never sees a mouse down in the title bar or menus because those events are handled by the control windows at those locations. The application programmer only handles messages directed to those windows he or she creates, such as the client window mentioned above.

The Window Procedure

Each window has an associated window procedure that processes all messages for that window. The syntax for a window procedure is consistent for all windows, so all messages are essentially function calls to the window procedure of the window receiving the message. A very simple window procedure is shown below.

MRESULT MyWindowProc(hwnd,msg,mp1,mp2)
HWND hwnd;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
 HPS  hps;
 RECTL  rect;

 switch (msg){
 case WM_PAINT:
 hps = WinBeginPaint(hwnd,NULL,&rect);
 WinFillRect(hps,&rect,CLR_WHITE);
 WinEndPaint(hps);
 return (MRESULT)0L;
 default:
 break;
 }
 return WinDefWindowProc(hwnd,msg,mp1,mp2);
}

The window procedure is normally a long switch statement that decodes the message and responds appropriately. A key feature is that the window procedure calls WinDefWindowProc, for all messages that it does not handle it. WinDefWindowProc is the default window procedure supplied by the system. The default window procedure implements the default window behavior. Individual window classes handle only those window messages that they want to modify, passing the rest on to the system. This is a marvelous model for programmers because they can utilize all the default behavior without having to know how it works.

The arguments to a window procedure always follow the syntax given above, but the contents change depending on the particular message. The arguments are summarized below:

hwnd: a window handle to the window receiving the message. (Note: handle has a different meaning in PM than in the Mac. A PM handle is more like a token that the system knows how to use to find the window data structure.)

msg: a 16 bit integer that identifies the message type.

mp1: a 32 bit value whose interpretation depends on the message type.

mp2: a 32 bit value whose interpretation depends on the message type.

Creating Window Subclasses

Application programmers normally create their own window class and supply a window procedure for that class. They must register the class and its associated window procedure with the system. Once registered, the window class can be used to create multiple instances of windows of that class, all of which use the same window procedure. The window procedure created by an application for a new window class handles selected messages and passes the rest on to WinDefWindowProc to get the default behavior. This makes creating new classes very simple.

Another way to create a new window class is to subclass an existing class, using its window procedure as the default instead of WinDefWinProc. For example, suppose you wanted a new title bar type that drew its contents in italics instead or regular text. You could create a new class based on the standard title bar window class by subclassing the title bar class.

When you create a window subclass in PM, you get the address of the window procedure for the original, or parent, window class. You then construct a window procedure for the subclass that calls the parent’s window procedure instead of WinDefWinProc. That way, all messages that your window procedure doesn’t intercept are processed as they normally would be by the parent class. Going back to the example of a title bar that used italics, it would only be necessary for the subclass’s window procedure to respond to the WM_PAINT message by drawing the title bar as it saw fit. All other messages could be passed to the original title bar window procedure. You don’t have to reinvent the title bar, just change those parts you want to change.

Subclassing is a very elegant and simple way to extend or modify the behavior of the system. PM makes it easy to do.

Window Updating

Window drawing in the Mac environment is triggered by the update event. The Window Manager keeps track of the update region and generates an update event whenever a portion of the window needs to be redrawn. Smart Mac programmers utilize this mechanism by isolating all window drawing within the code that handles update events. In order to force a portion of the window to be redrawn, these programmers add that portion of the window to the update region and rely on the update event mechanism to call their drawing code.

The PM drawing architecture is very similar. All windows have an update region. When the update region is not empty, the system sends a WM_PAINT message to the window. All windows should respond to a paint message by drawing themselves.

Your client window procedure should respond to a paint message by drawing a representation of the current state of the data associated with the window. For a word processor, you would draw the text and graphics of the document.

Just like the Macintosh, PM clips all drawing in a window during the paint message so portions of the window which don’t need to be redrawn are not touched by graphics operations.

Mac programmers familiar with the update event mechanism on the Macintosh will have no problem adjusting to the PM method of painting windows.

Menus

Menus in PM are a special predefined window class that sit on top of a frame window just like the title bar and scroll bar. Each frame window can have its own set of menus. There is no system wide menu bar.

Since menus are actually windows, they know how to handle all sorts of messages, including user interaction with the mouse and keyboard. The menu window typically handles a mouse click by tracking the mouse until the user makes a final selection from the menu items. At that point, the menu window sends a command message to the frame window telling it what menu item was chosen. The frame window normally passes the command message on to the client window, where your window procedure receives the command message and reacts accordingly.

Thus, you are not responsible for dealing with menus until an item is actually chosen. The menu window, because it is an autonomous window object with built in functionality, is able to operate independently. You, as the programmer, are responsible for defining the contents of the menus and placing them in the frame window, but once they are in place they function on their own, notifying you only when an interesting event takes place.

PM menus are normally defined as resources, much like the Mac. The standard development tools from Microsoft include a resource compiler that processes resource definition files and creates resources which are then joined with the code to form the executable files. A menu resource definition includes the title of the menu, the text of each item, and the command number associated with each item. The command number for the item is sent as part of the command message when the item is selected.

One nice feature of PM’s resource compiler is that it will read the same C header files as the C compiler. Thus, you can include the same .h file in your source code and your resource definition file to define the constants that correspond to the command numbers for the menu items.

Graphics

The Macintosh has Quickdraw. PM has the Graphics Programming Interface (GPI). GPI is based on an IBM mainframe graphics system. It is big and complicated and powerful, offering many transformation functions and a store and playback mode similar to QuickDraw pictures.

Where Quickdraw has the GrafPort, GPI has the presentation space and device context. The device context is probably closest, conceptually, to the GrafPort, in that it is where the graphics functions are translated into the operations that actually twiddle the bits on the device, be it a screen or a printer. But GPI has a higher level gateway, called the presentation space, that routes graphics commands to the device context. The presentation space takes care of some of the advanced transformation operations and the stored graphic playback operations.

GPI is harder to use than Quickdraw, but it is more powerful. Mac programmers will have to start from scratch with GPI since there is little overlap between the two systems.

Multitasking

The current Macintosh model of multitasking implemented in MultiFinder is based on a non-preemptive model. The fundamental unit of multitasking in the Mac is an application. Basically, a application is allowed to run in the background whenever the active application is waiting for an event. This is a good way to provide multitasking and still be compatible with old software, and many programs are already taking advantage of this feature.

In PM, the basic unit of multitasking is a thread. A process (application) can be made up of one or more threads. All threads in the system share the processor by time-slicing, so they appear to execute concurrently. A thread is a very efficient unit of processing, since it shares global data and most of the machine state with its parent process. The thread has only its own stack and register set, so the time required to context switch between threads of the same process is very short.

The idea in PM is that you spin off a new thread whenever you need to do something that will take you away from the main user interface thread for more than 1/10th of a second. For example, if the user selects a menu item for a lengthy calculation or sorting operation, the application should create a new thread to do the operation. The user interface thread will continue to execute concurrently with the calculation thread so the user is not cut off from selecting other menu items or switching to another application while the computation progresses.

In essence this means that you should never have to put up a watch cursor.

OS/2 provides semaphores and other classic operating system mechanisms to help synchronize and protect shared resources in a multitasking environment. For example, in the previous example of a lengthy calculation, you would want to protect the data with a semaphore so that the user could not change the data as it was being used in a calculation.

I think that threads may be the neatest thing about OS/2. I wrote a small sample program on both the Macintosh and OS/2. The program continuously calculated the roots of a chaotic quadratic equation and displayed the results as a graph. On the Mac, I used null events to run in the background under MultiFinder. In PM, I created a calculation thread that sent a message to the graphing window each time it calculated a new point on the curve. The graphing window then plotted the point and waited for the next message. The PM version of the program ran quite a bit faster than the Mac version (Mac II versus Compaq 386/20). I don’t want to make this out to be some sort of benchmark, but I think that the ability to do real multitasking with threads will open up many new possibilities for programs.

Of course, multitasking also creates many new problems for programmers who are not used to protecting data and synchronizing multiple threads, but OS/2 provides the tools needed to solve these problems.

Interprocess Communication

PM provides a clipboard mechanism that is a superset of the Macintosh clipboard model. One nice feature of the PM clipboard is that an application can send several formats to the clipboard without actually rendering the data. The application only has to render the data in a particular format if another application makes a request for that format.

Beyond the clipboard, PM provides several other interprocess communication (IPC) mechanisms, including shared memory, pipes, and queues. In addition to these traditional methods, PM applications can communicate by sending messages back and forth between their respective windows. All in all, PM provides a richer set of IPC tools than the Macintosh, and because these capabilities are present from the start, it seems probable that many application developers will take advantage of them.

Development Tools

Microsoft strongly suggests that you write your PM programs in C. The standard development environment is their C 5.10 compiler and linker, combined with the editor of your choice. Microsoft also provides an editor, which is programmable and extensible and totally configurable and takes about two weeks to learn how to use. Once you get over the learning curve, the tools aren’t so bad, but friendly they aren’t. It made me appreciate how good Mac developers have it with Lightspeed and MPW.

The best part of the development environment, however, is CodeView, Microsoft’s source level debugger. CodeView will let you step through your code in source mode, mixed mode, or assembly language mode. It lets you look at variables and set break points and break conditions. It is truly a great tool. I spent many hours just watching messages flow into my window procedures while learning PM.

The other great part of the Microsoft development package is QuickHelp, which is an on-line reference to the system that can be integrated with the editor. It works like this: you type a function name or structure name or message name in your code and want to know more about it. Position the cursor somewhere in the name and press Alt-Q; you immediately get full information on the topic. Great tool!

I imagine that third party developers will eventually provide alternative development environments. The pre-release versions of Microsoft’s software development kit (SDK) cost $3000, although that price included incremental upgrades over a year-long period. Clearly, not too many people are willing to pay that much, but I am sure that final retail product will be cheaper by an order of magnitude.

The Good

I like the messaging architecture of PM. It is actually fun to program using window procedures and messages. This is the most painless object-oriented programming system I have encountered. It was easier for me to learn than MacApp. There are many similarities between MacApp, especially version 2.0, and PM. MacApp 2.0’s use of nested views is very similar to PM’s nested windows. MacApp, however, is a true object oriented environment while PM is only partly object oriented. I think that the design of PM benefitted from Microsoft’s experience with the Mac and two versions of Microsoft Windows.

Individual menu bars within windows are great. [See the November issue of MacTutor. -ed]

Even though the Z86 has a stupid 64K limit on segment size, the built-in memory management and protection between applications is nice.

The graphics are very powerful; in some ways reminding me of PostScript. (see also the graphics entry in The Bad).

The multitasking model is more advanced than the Macintosh, but that is understandable since Microsoft had the opportunity to design it in from the bottom up while the Mac folks had to graft it on top of an existing single-tasking OS.

CodeView and Quickhelp are incredible aids to learning PM. They beat anything I have ever seen on the Mac, although I haven’t seen Lightspeed C’s new debugger yet. If I had had the equivalent of CodeView when I started on the Mac I could have learned the Mac in half the time.

The Bad

The message-based, object oriented nature of PM has a downside. Much of the functionality of the system is hidden from the programmer. You inherit an enormous amount of default behavior. This is great until you decide that you want to change the default behavior. Then you need to know what to change. PM provides a clean way to change the system behavior by subclassing the predefined window classes, but the problem is that it is not always clear just which messages to intercept in order to change a behavior. With other object-oriented systems, such as MacApp, you get the source code for the system objects so you know exactly how they work and can use that code as the basis for your own subclasses of those objects. Microsoft does not provide source code for its standard window classes, so you must rely on the documentation to know how they work. This is a real problem if you want to do something that the documentation team didn’t think of.

The graphics functional interface is too complicated. It is hard to do simple things. It is not much harder to do really hard things. Some people will love this graphics library, others will hate it. It lacks the elegance of Quickdraw, plus there is no Palette Manager to arbitrate colors among windows sharing the screen.

The file system is compatible with DOS, so you are limited to xxxxxxxx.xxx file names. Ugh!

The Ugly

The Macintosh screen is beautiful. I think all Mac programmers have a deep visual response to the screen. The Mac has lots of little touches that make it easy to work at all day: drop shadows, proportional fonts, square pixels. The PM screen is pretty ugly. I think the difference is the lack of graphic artists on the design team. I think the visual look of the screen was designed by programmers who were thinking about how difficult it would be ( and looking over their shoulders at the schedule IBM is dictating for them) to implement the small touches that aren’t there such as drop shadows. Of course square pixels are out because of the pc hardware, so you can’t really blame the programmer’s for that one.

I get the impression that there is no Steve Jobs at Microsoft, telling folks that just because something is hard to do is no reason not to do it. Many of the little compromises made in the interface in the name of simplifying the coding have hurt the PM look-and-feel. PM just doesn’t feel as good as the Mac.

Another ugly point is that PM takes at least 2.5 megs of RAM; 3-4 megs is more realistic if you want to run several programs at once. Also, although PM will run on a 286 based machine, you really need a 386 to make it responsive.

Conclusions

PM is fun to program. The messaging architecture is well-designed and allows you to put together very powerful programs pretty quickly. One of the main people behind PM is Neil Konzen; a legendary hacker and the author of the original Microsoft Multiplan for the Mac; so a lot of good experience and thought has gone into it.

PM is big and complicated. Expect a learning curve at least as steep as the Mac, although your Macintosh experience puts you way ahead, conceptually, of the old line DOS programmer trying to make a transition. The windowing environment is every bit as rich as the Mac with the added complication of multitasking. Be prepared to have your head hurt sometimes.

As to how you can program in both environments, there seems to be some emerging products based on a common library idea. Basically, you write your program, or at least part of it, by calling functions from a library that can be expressed either in Mac ROM calls or PM functions. The library is a higher level expression of the common features of both operating systems. Such products exist for cross development between the Mac and Microsoft Windows, so I have no doubt that they will be developed for PM as well. But these libraries cannot hope to cover some of the more fundamental architectural differences between the two systems, such as the multitasking models. I believe that portions of your programs will have to be hand crafted for each operating system.

The bottom line is this,PM is a rich, full-featured, operating system that will allow programmers to write applications that are as powerful and easy to use as anything on the Macintosh. Do not count it out. I think it will be a year or more before it really catches on because of the expensive hardware requirements and the lack of significant applications, but eventually it will be a big factor in the microcomputer industry.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Capto 1.2.9 - $29.99
Capto (was Voila) is an easy-to-use app that takes capturing, recording, video and image editing to the next level. With an intelligent file manager and quick sharing options, Capto is perfect for... Read more
Opera 51.0.2830.40 - High-performance We...
Opera is a fast and secure browser trusted by millions of users. With the intuitive interface, Speed Dial and visual bookmarks for organizing favorite sites, news feature with fresh, relevant content... Read more
GarageSale 7.0.13 - Create outstanding e...
GarageSale is a slick, full-featured client application for the eBay online auction system. Create and manage your auctions with ease. With GarageSale, you can create, edit, track, and manage... Read more
1Password 6.8.7 - Powerful password mana...
1Password is a password manager that uniquely brings you both security and convenience. It is the only program that provides anti-phishing protection and goes beyond password management by adding Web... Read more
Evernote 7.0.1 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
MacUpdate Desktop 6.2.0 - $20.00
MacUpdate Desktop brings seamless 1-click app installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on... Read more
HoudahSpot 4.3.5 - Advanced file-search...
HoudahSpot is a versatile desktop search tool. Use HoudahSpot to locate hard-to-find files and keep frequently used files within reach. HoudahSpot will immediately feel familiar. It works just the... Read more
EtreCheck 4.0.4 - 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
WhatsApp 0.2.8361 - 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
iClock 4.2 - Customize your menubar cloc...
iClock is a menu-bar replacement for Apple's default clock but with 100x features. Have your Apple or Google calendar in the menubar. Have the day, date, and time in different fonts and colors in the... Read more

Latest Forum Discussions

See All

The best games like Florence
Florence is a great little game about relationships that we absolutely adored. The only problem with it is it's over a little too soon. If you want some other games with some emotional range like Florence, check out these suggestions: [Read more] | Read more »
Angry Birds Champions adds cash prizes t...
Collaborating with developer Rovio Entertainment, GSN Games has released a twist on the Angry Birds formula. Angry Birds Champions features the same bird-flinging gameplay, but now you can catapult Red and co for cash. | Read more »
Around the Empire: What have you missed...
148Apps is part of a family. A big family of sites that make sure you're always up to date with all the portable gaming news. Just like a real family, I guess. I don't know, my mum never told me anything about Candy Crush to be fair. [Read more] | Read more »
The Battle of Polytopia Guide - Tips for...
The addition of multiplayer to The Battle of Polytopia has catapulted the game from a fun enough time waster to a fully-fledged 4X experience on your phone. We've been playing quite a few matches over the past week or so, and we've put together a... | Read more »
All the best games on sale for iPhone an...
Hi there, and welcome to our round up of all the best games that are on sale for iOS at the moment. It's not a vintage week in terms of numbers, but I'm pretty sure that every single one of these is worth picking up if you haven't already played... | Read more »
Disc Drivin' 2 Guide - Tips for the...
We're all still playing quite a bit of Disc Drivin' 2 over here at 148Apps, and we've gotten pretty good at it. Now that we've spent some more time with the game and unlocked more powerups, check out some of these more advanced tips: | Read more »
Alto's Odyssey Guide - How to Tackl...
Alto’s Odyssey is a completely stunning and serene runner, but it can also be a bit tricky. Check out these to try and keep your cool while playing this endless runner: Don’t focus too much on tasks [Read more] | Read more »
Here's everything you need to know...
Alto's Odyssey is a really, really good game. If you don't believe me, you should definitely check out our review by clicking this link right here. It takes the ideas from the original Alto's Adventure, then subtly builds on them, creating... | Read more »
Alto's Odyssey (Games)
Alto's Odyssey 1.0.1 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.1 (iTunes) Description: Just beyond the horizon sits a majestic desert, vast and unexplored. Join Alto and his friends and set off on an endless... | Read more »
Vainglory 5v5: Everything you need to kn...
Vainglory just got bigger. [Read more] | Read more »

Price Scanner via MacPrices.net

Apple AirPods in stock today for $159, free s...
Adorama reports stock of Apple AirPods today for $159 including free shipping, plus pay no sales tax outside of NY & NJ. See our Apple AirPod Price Tracker for the latest prices and stock status... Read more
Saturday Sale: Amazon offers 12″ 1.3GHz MacBo...
Amazon has Silver and Gold 2017 12″ 1.3GHz Retina MacBooks on sale for $250 off MSRP. Shipping is free: – 12″ 1.3GHz Silver MacBook: $1349.99 $250 off MSRP – 12″ 1.3GHz Gold MacBook: $1349.99 $250... Read more
Use your Apple Education discount and save up...
Purchase a new Mac using Apple’s Education discount, and take up to $400 off MSRP. All teachers, students, and staff of any educational institution with a .edu email address qualify for the discount... Read more
Apple Canada offers 2017 21″ and 27″ iMacs fo...
 Canadian shoppers can save up to $470 on the purchase of a 2017 current-generation 21″ or 27″ iMac with Certified Refurbished models at Apple Canada. Apple’s refurbished prices are the lowest... Read more
9″ iPads available online at Walmart for $50...
Walmart has 9.7″ Apple iPads on sale for $50 off MSRP for a limited time. Sale prices are for online orders only, in-store prices may vary: – 9″ 32GB iPad: $279.99 $50 off – 9″ 128GB iPad: $379.99 $... Read more
15″ Apple MacBook Pros, Certified Refurbished...
Save $360-$420 on the purchase of a 2017 15″ MacBook Pro with Certified Refurbished models at Apple. Apple’s refurbished prices are the lowest available for each model from any reseller. An standard... Read more
Amazon restocks MacBook Pros with models avai...
Amazon has restocked 15″ and 13″ Apple MacBook Pros with models on sale for up to $251 off MSRP. Shipping is free. Note that stock of some Macs may come and go (and some sell out quickly), so check... Read more
Lowest price of the year: 15″ 2.8GHz Apple Ma...
Amazon has the 2017 Space Gray 15″ 2.8GHz MacBook Pro on sale today for $251 off MSRP. Shipping is free: – 15″ 2.8GHz Touch Bar MacBook Pro Space Gray (MPTR2LL/A): $2148, $251 off MSRP Their price is... Read more
Apple restocks full line of Certified Refurbi...
Apple has restocked a full line of Apple Certified Refurbished 2017 13″ MacBook Pros for $200-$300 off MSRP. A standard Apple one-year warranty is included with each MacBook, and shipping is free.... Read more
Lowest sale price available for 13″ 1.8GHz Ma...
Focus Camera has the 2017 13″ 1.8GHz/128GB Apple MacBook Air on sale today for $829 including free shipping. Their price is $170 off MSRP, and it’s the lowest price available for a current 13″... Read more

Jobs Board

*Apple* Media Products Commerce Engineering...
# Apple Media Products Commerce Engineering Manager Job Number: 56207285 Santa Clara Valley, California, United States Posted: 26-Jan-2018 Weekly Hours: 40.00 **Job Read more
Digital Platforms Lead, Today at *Apple* -...
# Digital Platforms Lead, Today at Apple Job Number: 56178747 Santa Clara Valley, California, United States Posted: 23-Feb-2018 Weekly Hours: 40.00 **Job Summary** Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description:SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description:SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.