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

Minecraft 1.20.2 - Popular sandbox build...
Minecraft allows players to build constructions out of textured cubes in a 3D procedurally generated world. Other activities in the game include exploration, gathering resources, crafting, and combat... Read more
HoudahSpot 6.4.1 - 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 is a productivity tool. It is the hub where all the... Read more
coconutBattery 3.9.14 - Displays info ab...
With coconutBattery you're always aware of your current battery health. It shows you live information about your battery such as how often it was charged and how is the current maximum capacity in... Read more
Keynote 13.2 - Apple's presentation...
Easily create gorgeous presentations with the all-new Keynote, featuring powerful yet easy-to-use tools and dazzling effects that will make you a very hard act to follow. The Theme Chooser lets you... Read more
Apple Pages 13.2 - Apple's word pro...
Apple Pages is a powerful word processor that gives you everything you need to create documents that look beautiful. And read beautifully. It lets you work seamlessly between Mac and iOS devices, and... Read more
Numbers 13.2 - Apple's spreadsheet...
With Apple Numbers, sophisticated spreadsheets are just the start. The whole sheet is your canvas. Just add dramatic interactive charts, tables, and images that paint a revealing picture of your data... Read more
Ableton Live 11.3.11 - Record music usin...
Ableton Live lets you create and record music on your Mac. Use digital instruments, pre-recorded sounds, and sampled loops to arrange, produce, and perform your music like never before. Ableton Live... Read more
Affinity Photo 2.2.0 - Digital editing f...
Affinity Photo - redefines the boundaries for professional photo editing software for the Mac. With a meticulous focus on workflow it offers sophisticated tools for enhancing, editing and retouching... Read more
SpamSieve 3.0 - Robust spam filter for m...
SpamSieve is a robust spam filter for major email clients that uses powerful Bayesian spam filtering. SpamSieve understands what your spam looks like in order to block it all, but also learns what... Read more
WhatsApp 2.2338.12 - Desktop client for...
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

Latest Forum Discussions

See All

‘Resident Evil 4’ Remake Pre-Orders Are...
Over the weekend, Capcom revealed the Japanese price points for both upcoming iOS and iPadOS ports of Resident Evil Village and Resident Evil 4 Remake , in addition to confirming the release date for Resident Evil Village. Since then, pre-orders... | Read more »
Square Enix commemorates one of its grea...
One of the most criminally underused properties in the Square Enix roster is undoubtedly Parasite Eve, a fantastic fusion of Resident Evil and Final Fantasy that deserved far more than two PlayStation One Games and a PSP follow-up. Now, however,... | Read more »
Resident Evil Village for iPhone 15 Pro...
During its TGS 2023 stream, Capcom showcased the Following upcoming ports revealed during the Apple iPhone 15 event. Capcom also announced pricing for the mobile (and macOS in the case of the former) ports of Resident Evil 4 Remake and Resident Evil... | Read more »
The iPhone 15 Episode – The TouchArcade...
After a 3 week hiatus The TouchArcade Show returns with another action-packed episode! Well, maybe not so much “action-packed" as it is “packed with talk about the iPhone 15 Pro". Eli, being in a time zone 3 hours ahead of me, as well as being smart... | Read more »
TouchArcade Game of the Week: ‘DERE Veng...
Developer Appsir Games have been putting out genre-defying titles on mobile (and other platforms) for a number of years now, and this week marks the release of their magnum opus DERE Vengeance which has been many years in the making. In fact, if the... | Read more »
SwitchArcade Round-Up: Reviews Featuring...
Hello gentle readers, and welcome to the SwitchArcade Round-Up for September 22nd, 2023. I’ve had a good night’s sleep, and though my body aches down to the last bit of sinew and meat, I’m at least thinking straight again. We’ve got a lot to look at... | Read more »
TGS 2023: Level-5 Celebrates 25 Years Wi...
Back when I first started covering the Tokyo Game Show for TouchArcade, prolific RPG producer Level-5 could always be counted on for a fairly big booth with a blend of mobile and console games on offer. At recent shows, the company’s presence has... | Read more »
TGS 2023: ‘Final Fantasy’ & ‘Dragon...
Square Enix usually has one of the bigger, more attention-grabbing booths at the Tokyo Game Show, and this year was no different in that sense. The line-ups to play pretty much anything there were among the lengthiest of the show, and there were... | Read more »
Valve Says To Not Expect a Faster Steam...
With the big 20% off discount for the Steam Deck available to celebrate Steam’s 20th anniversary, Valve had a good presence at TGS 2023 with interviews and more. | Read more »
‘Honkai Impact 3rd Part 2’ Revealed at T...
At TGS 2023, HoYoverse had a big presence with new trailers for the usual suspects, but I didn’t expect a big announcement for Honkai Impact 3rd (Free). | Read more »

Price Scanner via MacPrices.net

New low price: 13″ M2 MacBook Pro for $1049,...
Amazon has the Space Gray 13″ MacBook Pro with an Apple M2 CPU and 256GB of storage in stock and on sale today for $250 off MSRP. Their price is the lowest we’ve seen for this configuration from any... Read more
Apple AirPods 2 with USB-C now in stock and o...
Amazon has Apple’s 2023 AirPods Pro with USB-C now in stock and on sale for $199.99 including free shipping. Their price is $50 off MSRP, and it’s currently the lowest price available for new AirPods... Read more
New low prices: Apple’s 15″ M2 MacBook Airs w...
Amazon has 15″ MacBook Airs with M2 CPUs and 512GB of storage in stock and on sale for $1249 shipped. That’s $250 off Apple’s MSRP, and it’s the lowest price available for these M2-powered MacBook... Read more
New low price: Clearance 16″ Apple MacBook Pr...
B&H Photo has clearance 16″ M1 Max MacBook Pros, 10-core CPU/32-core GPU/1TB SSD/Space Gray or Silver, in stock today for $2399 including free 1-2 day delivery to most US addresses. Their price... Read more
Switch to Red Pocket Mobile and get a new iPh...
Red Pocket Mobile has new Apple iPhone 15 and 15 Pro models on sale for $300 off MSRP when you switch and open up a new line of service. Red Pocket Mobile is a nationwide service using all the major... Read more
Apple continues to offer a $350 discount on 2...
Apple has Studio Display models available in their Certified Refurbished store for up to $350 off MSRP. Each display comes with Apple’s one-year warranty, with new glass and a case, and ships free.... Read more
Apple’s 16-inch MacBook Pros with M2 Pro CPUs...
Amazon is offering a $250 discount on new Apple 16-inch M2 Pro MacBook Pros for a limited time. Their prices are currently the lowest available for these models from any Apple retailer: – 16″ MacBook... Read more
Closeout Sale: Apple Watch Ultra with Green A...
Adorama haș the Apple Watch Ultra with a Green Alpine Loop on clearance sale for $699 including free shipping. Their price is $100 off original MSRP, and it’s the lowest price we’ve seen for an Apple... Read more
Use this promo code at Verizon to take $150 o...
Verizon is offering a $150 discount on cellular-capable Apple Watch Series 9 and Ultra 2 models for a limited time. Use code WATCH150 at checkout to take advantage of this offer. The fine print: “Up... Read more
New low price: Apple’s 10th generation iPads...
B&H Photo has the 10th generation 64GB WiFi iPad (Blue and Silver colors) in stock and on sale for $379 for a limited time. B&H’s price is $70 off Apple’s MSRP, and it’s the lowest price... Read more

Jobs Board

Housekeeper, *Apple* Valley Villa - Cassia...
Apple Valley Villa, part of a 4-star senior living community, is hiring entry-level Full-Time Housekeepers to join our team! We will train you for this position and Read more
Housekeeper, *Apple* Valley Village - Cassi...
Apple Valley Village Health Care Center, a 4-star rated senior care campus, is hiring a Part-Time Housekeeper to join our team! We will train you for this position! Read more
Optometrist- *Apple* Valley, CA- Target Opt...
Optometrist- Apple Valley, CA- Target Optical Date: Sep 23, 2023 Brand: Target Optical Location: Apple Valley, CA, US, 92308 **Requisition ID:** 796045 At Target Read more
Senior *Apple* iOS CNO Developer (Onsite) -...
…Offense and Defense Experts (CODEX) is in need of smart, motivated and self-driven Apple iOS CNO Developers to join our team to solve real-time cyber challenges. Read more
*Apple* Systems Administrator - JAMF - Activ...
…**Public Trust/Other Required:** None **Job Family:** Systems Administration **Skills:** Apple Platforms,Computer Servers,Jamf Pro **Experience:** 3 + years of Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.